diff options
Diffstat (limited to 'src/game/client/components/players.cpp')
| -rw-r--r-- | src/game/client/components/players.cpp | 647 |
1 files changed, 366 insertions, 281 deletions
diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index e1fee3e8..8ad7b0cb 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -1,147 +1,269 @@ -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> - -#include <game/gamecore.hpp> // get_angle -#include <game/client/animstate.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/ui.hpp> -#include <game/client/render.hpp> - -#include <game/client/components/flow.hpp> -#include <game/client/components/skins.hpp> -#include <game/client/components/effects.hpp> -#include <game/client/components/sounds.hpp> -#include <game/client/components/controls.hpp> - -#include "players.hpp" - -void PLAYERS::render_hand(TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset) +#include <engine/graphics.h> +#include <engine/shared/config.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> + +#include <game/gamecore.h> // get_angle +#include <game/client/animstate.h> +#include <game/client/gameclient.h> +#include <game/client/ui.h> +#include <game/client/render.h> + +#include <game/client/components/flow.h> +#include <game/client/components/skins.h> +#include <game/client/components/effects.h> +#include <game/client/components/sounds.h> +#include <game/client/components/controls.h> + +#include "players.h" + +void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset) { // for drawing hand //const skin *s = skin_get(skin_id); - float basesize = 10.0f; + float BaseSize = 10.0f; //dir = normalize(hook_pos-pos); - vec2 hand_pos = center_pos + dir; - float angle = get_angle(dir); - if (dir.x < 0) - angle -= angle_offset; + vec2 HandPos = CenterPos + Dir; + float Angle = GetAngle(Dir); + if (Dir.x < 0) + Angle -= AngleOffset; else - angle += angle_offset; + Angle += AngleOffset; - vec2 dirx = dir; - vec2 diry(-dir.y,dir.x); + vec2 DirX = Dir; + vec2 DirY(-Dir.y,Dir.x); - if (dir.x < 0) - diry = -diry; + if (Dir.x < 0) + DirY = -DirY; - hand_pos += dirx * post_rot_offset.x; - hand_pos += diry * post_rot_offset.y; + HandPos += DirX * PostRotOffset.x; + HandPos += DirY * PostRotOffset.y; - //Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id); - Graphics()->TextureSet(info->texture); + //Graphics()->TextureSet(data->m_aImages[IMAGE_CHAR_DEFAULT].id); + Graphics()->TextureSet(pInfo->m_Texture); Graphics()->QuadsBegin(); - Graphics()->SetColor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a); + Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, pInfo->m_ColorBody.a); // two passes for (int i = 0; i < 2; i++) { - bool outline = i == 0; + bool OutLine = i == 0; - RenderTools()->select_sprite(outline?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0); - Graphics()->QuadsSetRotation(angle); - Graphics()->QuadsDraw(hand_pos.x, hand_pos.y, 2*basesize, 2*basesize); + RenderTools()->SelectSprite(OutLine?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0); + Graphics()->QuadsSetRotation(Angle); + IGraphics::CQuadItem QuadItem(HandPos.x, HandPos.y, 2*BaseSize, 2*BaseSize); + Graphics()->QuadsDraw(&QuadItem, 1); } Graphics()->QuadsSetRotation(0); Graphics()->QuadsEnd(); } -inline float normalize_angular(float f) +inline float NormalizeAngular(float f) { return fmod(f+pi*2, pi*2); } -inline float angular_mix_direction(float src, float dst) { return sinf(dst-src) >0?1:-1; } -inline float angular_distance(float src, float dst) { return asinf(sinf(dst-src)); } +inline float AngularMixDirection (float Src, float Dst) { return sinf(Dst-Src) >0?1:-1; } +inline float AngularDistance(float Src, float Dst) { return asinf(sinf(Dst-Src)); } -inline float angular_approach(float src, float dst, float amount) +inline float AngularApproach(float Src, float Dst, float Amount) { - float d = angular_mix_direction(src, dst); - float n = src + amount*d; - if(angular_mix_direction(n, dst) != d) - return dst; + float d = AngularMixDirection (Src, Dst); + float n = Src + Amount*d; + if(AngularMixDirection (n, Dst) != d) + return Dst; return n; } -void PLAYERS::render_player( - const NETOBJ_CHARACTER *prev_char, - const NETOBJ_CHARACTER *player_char, - const NETOBJ_PLAYER_INFO *prev_info, - const NETOBJ_PLAYER_INFO *player_info +void CPlayers::RenderHook( + const CNetObj_Character *pPrevChar, + const CNetObj_Character *pPlayerChar, + const CNetObj_PlayerInfo *pPrevInfo, + const CNetObj_PlayerInfo *pPlayerInfo ) { - NETOBJ_CHARACTER prev; - NETOBJ_CHARACTER player; - prev = *prev_char; - player = *player_char; + CNetObj_Character Prev; + CNetObj_Character Player; + Prev = *pPrevChar; + Player = *pPlayerChar; - NETOBJ_PLAYER_INFO info = *player_info; - TEE_RENDER_INFO render_info = gameclient.clients[info.cid].render_info; + CNetObj_PlayerInfo pInfo = *pPlayerInfo; + CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo; // check for teamplay modes - bool is_teamplay = false; - bool new_tick = gameclient.new_tick; - if(gameclient.snap.gameobj) - is_teamplay = (gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS) != 0; + bool IsTeamplay = false; + if(m_pClient->m_Snap.m_pGameobj) + IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; // check for ninja - if (player.weapon == WEAPON_NINJA) + if (Player.m_Weapon == WEAPON_NINJA) { // change the skin for the player to the ninja - int skin = gameclient.skins->find("x_ninja"); - if(skin != -1) + int Skin = m_pClient->m_pSkins->Find("x_ninja"); + if(Skin != -1) { - if(is_teamplay) - render_info.texture = gameclient.skins->get(skin)->color_texture; + if(IsTeamplay) + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture; else { - render_info.texture = gameclient.skins->get(skin)->org_texture; - render_info.color_body = vec4(1,1,1,1); - render_info.color_feet = vec4(1,1,1,1); + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture; + RenderInfo.m_ColorBody = vec4(1,1,1,1); + RenderInfo.m_ColorFeet = vec4(1,1,1,1); + } + } + } + + float IntraTick = Client()->IntraGameTick(); + + if(Player.m_Health < 0) // dont render dead players + return; + + // set size + RenderInfo.m_Size = 64.0f; + + + // use preditect players if needed + if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) + { + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) + { + } + else + { + // apply predicted results + m_pClient->m_PredictedChar.Write(&Player); + m_pClient->m_PredictedPrevChar.Write(&Prev); + IntraTick = Client()->PredIntraGameTick(); + } + } + + vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick); + + if(Prev.m_Health < 0) // Don't flicker from previous position + Position = vec2(Player.m_X, Player.m_Y); + + // draw hook + if (Prev.m_HookState>0 && Player.m_HookState>0) + { + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); + Graphics()->QuadsBegin(); + //Graphics()->QuadsBegin(); + + vec2 Pos = Position; + vec2 HookPos; + + if(pPlayerChar->m_HookedPlayer != -1) + { + if(m_pClient->m_Snap.m_pLocalInfo && pPlayerChar->m_HookedPlayer == m_pClient->m_Snap.m_pLocalInfo->m_ClientId) + { + if(Client()->State() == IClient::STATE_DEMOPLAYBACK) // only use prediction if needed + HookPos = vec2(m_pClient->m_LocalCharacterPos.x, m_pClient->m_LocalCharacterPos.y); + else + HookPos = mix(vec2(m_pClient->m_PredictedPrevChar.m_Pos.x, m_pClient->m_PredictedPrevChar.m_Pos.y), + vec2(m_pClient->m_PredictedChar.m_Pos.x, m_pClient->m_PredictedChar.m_Pos.y), Client()->PredIntraGameTick()); + } + else + HookPos = mix(vec2(pPrevChar->m_HookX, pPrevChar->m_HookY), vec2(pPlayerChar->m_HookX, pPlayerChar->m_HookY), Client()->IntraGameTick()); + } + else + HookPos = mix(vec2(Prev.m_HookX, Prev.m_HookY), vec2(Player.m_HookX, Player.m_HookY), IntraTick); + + float d = distance(Pos, HookPos); + vec2 Dir = normalize(Pos-HookPos); + + Graphics()->QuadsSetRotation(GetAngle(Dir)+pi); + + // render head + RenderTools()->SelectSprite(SPRITE_HOOK_HEAD); + IGraphics::CQuadItem QuadItem(HookPos.x, HookPos.y, 24,16); + Graphics()->QuadsDraw(&QuadItem, 1); + + // render chain + RenderTools()->SelectSprite(SPRITE_HOOK_CHAIN); + IGraphics::CQuadItem Array[1024]; + int i = 0; + for(float f = 24; f < d && i < 1024; f += 24, i++) + { + vec2 p = HookPos + Dir*f; + Array[i] = IGraphics::CQuadItem(p.x, p.y,24,16); + } + + Graphics()->QuadsDraw(Array, i); + Graphics()->QuadsSetRotation(0); + Graphics()->QuadsEnd(); + + RenderHand(&RenderInfo, Position, normalize(HookPos-Pos), -pi/2, vec2(20, 0)); + } +} + +void CPlayers::RenderPlayer( + const CNetObj_Character *pPrevChar, + const CNetObj_Character *pPlayerChar, + const CNetObj_PlayerInfo *pPrevInfo, + const CNetObj_PlayerInfo *pPlayerInfo + ) +{ + CNetObj_Character Prev; + CNetObj_Character Player; + Prev = *pPrevChar; + Player = *pPlayerChar; + + CNetObj_PlayerInfo pInfo = *pPlayerInfo; + CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo; + + // check for teamplay modes + bool IsTeamplay = false; + bool NewTick = m_pClient->m_NewTick; + if(m_pClient->m_Snap.m_pGameobj) + IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; + + // check for ninja + if (Player.m_Weapon == WEAPON_NINJA) + { + // change the skin for the player to the ninja + int Skin = m_pClient->m_pSkins->Find("x_ninja"); + if(Skin != -1) + { + if(IsTeamplay) + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture; + else + { + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture; + RenderInfo.m_ColorBody = vec4(1,1,1,1); + RenderInfo.m_ColorFeet = vec4(1,1,1,1); } } } // set size - render_info.size = 64.0f; + RenderInfo.m_Size = 64.0f; - float intratick = client_intratick(); + float IntraTick = Client()->IntraGameTick(); - if(player.health < 0) // dont render dead players + if(Player.m_Health < 0) // dont render dead players return; - float angle = mix((float)prev.angle, (float)player.angle, intratick)/256.0f; + float Angle = mix((float)Prev.m_Angle, (float)Player.m_Angle, IntraTick)/256.0f; //float angle = 0; - if(info.local && client_state() != CLIENTSTATE_DEMOPLAYBACK) + if(pInfo.m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK) { // just use the direct input if it's local player we are rendering - angle = get_angle(gameclient.controls->mouse_pos); + Angle = GetAngle(m_pClient->m_pControls->m_MousePos); } else { /* - float mixspeed = client_frametime()*2.5f; + float mixspeed = Client()->FrameTime()*2.5f; if(player.attacktick != prev.attacktick) // shooting boosts the mixing speed mixspeed *= 15.0f; // move the delta on a constant speed on a x^2 curve - float current = gameclient.clients[info.cid].angle; + float current = g_GameClient.m_aClients[info.cid].angle; float target = player.angle/256.0f; float delta = angular_distance(current, target); float sign = delta < 0 ? -1 : 1; @@ -153,342 +275,305 @@ void PLAYERS::render_player( else angle = angular_approach(current, target, fabs(delta-new_delta)); - gameclient.clients[info.cid].angle = angle;*/ + g_GameClient.m_aClients[info.cid].angle = angle;*/ } // use preditect players if needed - if(info.local && config.cl_predict && client_state() != CLIENTSTATE_DEMOPLAYBACK) + if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) { - if(!gameclient.snap.local_character || (gameclient.snap.local_character->health < 0) || (gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)) + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) { } else { // apply predicted results - gameclient.predicted_char.write(&player); - gameclient.predicted_prev_char.write(&prev); - intratick = client_predintratick(); - new_tick = gameclient.new_predicted_tick; + m_pClient->m_PredictedChar.Write(&Player); + m_pClient->m_PredictedPrevChar.Write(&Prev); + IntraTick = Client()->PredIntraGameTick(); + NewTick = m_pClient->m_NewPredictedTick; } } - vec2 direction = get_direction((int)(angle*256.0f)); - vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick); - vec2 vel = mix(vec2(prev.vx/256.0f, prev.vy/256.0f), vec2(player.vx/256.0f, player.vy/256.0f), intratick); + vec2 Direction = GetDirection((int)(Angle*256.0f)); + vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick); + vec2 Vel = mix(vec2(Prev.m_VelX/256.0f, Prev.m_VelY/256.0f), vec2(Player.m_VelX/256.0f, Player.m_VelY/256.0f), IntraTick); - gameclient.flow->add(position, vel*100.0f, 10.0f); + m_pClient->m_pFlow->Add(Position, Vel*100.0f, 10.0f); - render_info.got_airjump = player.jumped&2?0:1; + RenderInfo.m_GotAirJump = Player.m_Jumped&2?0:1; // detect events - if(new_tick) + if(NewTick) { // detect air jump - if(!render_info.got_airjump && !(prev.jumped&2)) - gameclient.effects->air_jump(position); + if(!RenderInfo.m_GotAirJump && !(Prev.m_Jumped&2)) + m_pClient->m_pEffects->AirJump(Position); } - if(prev.health < 0) // Don't flicker from previous position - position = vec2(player.x, player.y); + if(Prev.m_Health < 0) // Don't flicker from previous position + Position = vec2(Player.m_X, Player.m_Y); - bool stationary = player.vx < 1 && player.vx > -1; - bool inair = col_check_point(player.x, player.y+16) == 0; - bool want_other_dir = (player.direction == -1 && vel.x > 0) || (player.direction == 1 && vel.x < 0); + bool Stationary = Player.m_VelX <= 1 && Player.m_VelX >= -1; + bool InAir = !Collision()->CheckPoint(Player.m_X, Player.m_Y+16); + bool WantOtherDir = (Player.m_Direction == -1 && Vel.x > 0) || (Player.m_Direction == 1 && Vel.x < 0); // evaluate animation - float walk_time = fmod(position.x, 100.0f)/100.0f; - ANIMSTATE state; - state.set(&data->animations[ANIM_BASE], 0); - - if(inair) - state.add(&data->animations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here - else if(stationary) - state.add(&data->animations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here - else if(!want_other_dir) - state.add(&data->animations[ANIM_WALK], walk_time, 1.0f); - - if (player.weapon == WEAPON_HAMMER) + float WalkTime = fmod(Position.x, 100.0f)/100.0f; + CAnimState State; + State.Set(&g_pData->m_aAnimations[ANIM_BASE], 0); + + if(InAir) + State.Add(&g_pData->m_aAnimations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here + else if(Stationary) + State.Add(&g_pData->m_aAnimations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here + else if(!WantOtherDir) + State.Add(&g_pData->m_aAnimations[ANIM_WALK], WalkTime, 1.0f); + + if (Player.m_Weapon == WEAPON_HAMMER) { - float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime(); - state.add(&data->animations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f); + float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + State.Add(&g_pData->m_aAnimations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f); } - if (player.weapon == WEAPON_NINJA) + if (Player.m_Weapon == WEAPON_NINJA) { - float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime(); - state.add(&data->animations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f); + float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + State.Add(&g_pData->m_aAnimations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f); } // do skidding - if(!inair && want_other_dir && length(vel*50) > 500.0f) + if(!InAir && WantOtherDir && length(Vel*50) > 500.0f) { - static int64 skid_sound_time = 0; - if(time_get()-skid_sound_time > time_freq()/10) + static int64 SkidSoundTime = 0; + if(time_get()-SkidSoundTime > time_freq()/10) { - gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, position); - skid_sound_time = time_get(); + m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, Position); + SkidSoundTime = time_get(); } - gameclient.effects->skidtrail( - position+vec2(-player.direction*6,12), - vec2(-player.direction*100*length(vel),-50) + m_pClient->m_pEffects->SkidTrail( + Position+vec2(-Player.m_Direction*6,12), + vec2(-Player.m_Direction*100*length(Vel),-50) ); } - // draw hook - if (prev.hook_state>0 && player.hook_state>0) - { - Graphics()->TextureSet(data->images[IMAGE_GAME].id); - Graphics()->QuadsBegin(); - //Graphics()->QuadsBegin(); - - vec2 pos = position; - vec2 hook_pos; - - if(player_char->hooked_player != -1) - { - if(gameclient.snap.local_info && player_char->hooked_player == gameclient.snap.local_info->cid) - { - hook_pos = mix(vec2(gameclient.predicted_prev_char.pos.x, gameclient.predicted_prev_char.pos.y), - vec2(gameclient.predicted_char.pos.x, gameclient.predicted_char.pos.y), client_predintratick()); - } - else - hook_pos = mix(vec2(prev_char->hook_x, prev_char->hook_y), vec2(player_char->hook_x, player_char->hook_y), client_intratick()); - } - else - hook_pos = mix(vec2(prev.hook_x, prev.hook_y), vec2(player.hook_x, player.hook_y), intratick); - - float d = distance(pos, hook_pos); - vec2 dir = normalize(pos-hook_pos); - - Graphics()->QuadsSetRotation(get_angle(dir)+pi); - - // render head - RenderTools()->select_sprite(SPRITE_HOOK_HEAD); - Graphics()->QuadsDraw(hook_pos.x, hook_pos.y, 24,16); - - // render chain - RenderTools()->select_sprite(SPRITE_HOOK_CHAIN); - int i = 0; - for(float f = 24; f < d && i < 1024; f += 24, i++) - { - vec2 p = hook_pos + dir*f; - Graphics()->QuadsDraw(p.x, p.y,24,16); - } - - Graphics()->QuadsSetRotation(0); - Graphics()->QuadsEnd(); - - render_hand(&render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0)); - } - // draw gun { - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - Graphics()->QuadsSetRotation(state.attach.angle*pi*2+angle); + Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle*pi*2+Angle); // normal weapons - int iw = clamp(player.weapon, 0, NUM_WEAPONS-1); - RenderTools()->select_sprite(data->weapons.id[iw].sprite_body, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); + int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS-1); + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_pSpriteBody, Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); - vec2 dir = direction; - float recoil = 0.0f; + vec2 Dir = Direction; + float Recoil = 0.0f; vec2 p; - if (player.weapon == WEAPON_HAMMER) + if (Player.m_Weapon == WEAPON_HAMMER) { // Static position for hammer - p = position + vec2(state.attach.x, state.attach.y); - p.y += data->weapons.id[iw].offsety; + p = Position + vec2(State.GetAttach()->m_X, State.GetAttach()->m_Y); + p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety; // if attack is under way, bash stuffs - if(direction.x < 0) + if(Direction.x < 0) { - Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2); - p.x -= data->weapons.id[iw].offsetx; + Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2); + p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx; } else { - Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2); + Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2); } - RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size); + RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); } - else if (player.weapon == WEAPON_NINJA) + else if (Player.m_Weapon == WEAPON_NINJA) { - p = position; - p.y += data->weapons.id[iw].offsety; + p = Position; + p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety; - if(direction.x < 0) + if(Direction.x < 0) { - Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2); - p.x -= data->weapons.id[iw].offsetx; - gameclient.effects->powerupshine(p+vec2(32,0), vec2(32,12)); + Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2); + p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx; + m_pClient->m_pEffects->PowerupShine(p+vec2(32,0), vec2(32,12)); } else { - Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2); - gameclient.effects->powerupshine(p-vec2(32,0), vec2(32,12)); + Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2); + m_pClient->m_pEffects->PowerupShine(p-vec2(32,0), vec2(32,12)); } - RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size); + RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); // HADOKEN - if ((client_tick()-player.attacktick) <= (SERVER_TICK_SPEED / 6) && data->weapons.id[iw].num_sprite_muzzles) + if ((Client()->GameTick()-Player.m_AttackTick) <= (SERVER_TICK_SPEED / 6) && g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles) { - int itex = rand() % data->weapons.id[iw].num_sprite_muzzles; - float alpha = 1.0f; - if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex]) + int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles; + float Alpha = 1.0f; + if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX]) { - vec2 dir = vec2(player_char->x,player_char->y) - vec2(prev_char->x, prev_char->y); - dir = normalize(dir); - float hadokenangle = get_angle(dir); - Graphics()->QuadsSetRotation(hadokenangle); + vec2 Dir = vec2(pPlayerChar->m_X,pPlayerChar->m_Y) - vec2(pPrevChar->m_X, pPrevChar->m_Y); + Dir = normalize(Dir); + float HadOkenAngle = GetAngle(Dir); + Graphics()->QuadsSetRotation(HadOkenAngle ); //float offsety = -data->weapons[iw].muzzleoffsety; - RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], 0); - vec2 diry(-dir.y,dir.x); - p = position; - float offsetx = data->weapons.id[iw].muzzleoffsetx; - p -= dir * offsetx; - RenderTools()->draw_sprite(p.x, p.y, 160.0f); + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX], 0); + vec2 DirY(-Dir.y,Dir.x); + p = Position; + float OffsetX = g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx; + p -= Dir * OffsetX; + RenderTools()->DrawSprite(p.x, p.y, 160.0f); } } } else { // TODO: should be an animation - recoil = 0; - float a = (client_tick()-player.attacktick+intratick)/5.0f; + Recoil = 0; + float a = (Client()->GameTick()-Player.m_AttackTick+IntraTick)/5.0f; if(a < 1) - recoil = sinf(a*pi); - p = position + dir * data->weapons.id[iw].offsetx - dir*recoil*10.0f; - p.y += data->weapons.id[iw].offsety; - RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size); + Recoil = sinf(a*pi); + p = Position + Dir * g_pData->m_Weapons.m_aId[iw].m_Offsetx - Dir*Recoil*10.0f; + p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety; + RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); } - if (player.weapon == WEAPON_GUN || player.weapon == WEAPON_SHOTGUN) + if (Player.m_Weapon == WEAPON_GUN || Player.m_Weapon == WEAPON_SHOTGUN) { // check if we're firing stuff - if(data->weapons.id[iw].num_sprite_muzzles)//prev.attackticks) + if(g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles)//prev.attackticks) { - float alpha = 0.0f; - int phase1tick = (client_tick() - player.attacktick); - if (phase1tick < (data->weapons.id[iw].muzzleduration + 3)) + float Alpha = 0.0f; + int Phase1Tick = (Client()->GameTick() - Player.m_AttackTick); + if (Phase1Tick < (g_pData->m_Weapons.m_aId[iw].m_Muzzleduration + 3)) { - float t = ((((float)phase1tick) + intratick)/(float)data->weapons.id[iw].muzzleduration); - alpha = LERP(2.0, 0.0f, min(1.0f,max(0.0f,t))); + float t = ((((float)Phase1Tick) + IntraTick)/(float)g_pData->m_Weapons.m_aId[iw].m_Muzzleduration); + Alpha = mix(2.0f, 0.0f, min(1.0f,max(0.0f,t))); } - int itex = rand() % data->weapons.id[iw].num_sprite_muzzles; - if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex]) + int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles; + if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX]) { - float offsety = -data->weapons.id[iw].muzzleoffsety; - RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); - if(direction.x < 0) - offsety = -offsety; + float OffsetY = -g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsety; + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX], Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); + if(Direction.x < 0) + OffsetY = -OffsetY; - vec2 diry(-dir.y,dir.x); - vec2 muzzlepos = p + dir * data->weapons.id[iw].muzzleoffsetx + diry * offsety; + vec2 DirY(-Dir.y,Dir.x); + vec2 MuzzlePos = p + Dir * g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx + DirY * OffsetY; - RenderTools()->draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size); + RenderTools()->DrawSprite(MuzzlePos.x, MuzzlePos.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); } } } Graphics()->QuadsEnd(); - switch (player.weapon) + switch (Player.m_Weapon) { - case WEAPON_GUN: render_hand(&render_info, p, direction, -3*pi/4, vec2(-15, 4)); break; - case WEAPON_SHOTGUN: render_hand(&render_info, p, direction, -pi/2, vec2(-5, 4)); break; - case WEAPON_GRENADE: render_hand(&render_info, p, direction, -pi/2, vec2(-4, 7)); break; + case WEAPON_GUN: RenderHand(&RenderInfo, p, Direction, -3*pi/4, vec2(-15, 4)); break; + case WEAPON_SHOTGUN: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-5, 4)); break; + case WEAPON_GRENADE: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-4, 7)); break; } } // render the "shadow" tee - if(info.local && config.debug) + if(pInfo.m_Local && g_Config.m_Debug) { - vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick()); - TEE_RENDER_INFO ghost = render_info; - ghost.color_body.a = 0.5f; - ghost.color_feet.a = 0.5f; - RenderTools()->RenderTee(&state, &ghost, player.emote, direction, ghost_position); // render ghost + vec2 GhostPosition = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), Client()->IntraGameTick()); + CTeeRenderInfo Ghost = RenderInfo; + Ghost.m_ColorBody.a = 0.5f; + Ghost.m_ColorFeet.a = 0.5f; + RenderTools()->RenderTee(&State, &Ghost, Player.m_Emote, Direction, GhostPosition); // render ghost } - render_info.size = 64.0f; // force some settings - render_info.color_body.a = 1.0f; - render_info.color_feet.a = 1.0f; - RenderTools()->RenderTee(&state, &render_info, player.emote, direction, position); + RenderInfo.m_Size = 64.0f; // force some settings + RenderInfo.m_ColorBody.a = 1.0f; + RenderInfo.m_ColorFeet.a = 1.0f; + RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position); - if(player.player_state == PLAYERSTATE_CHATTING) + if(Player.m_PlayerState == PLAYERSTATE_CHATTING) { - Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); - RenderTools()->select_sprite(SPRITE_DOTDOT); - Graphics()->QuadsDraw(position.x + 24, position.y - 40, 64,64); + RenderTools()->SelectSprite(SPRITE_DOTDOT); + IGraphics::CQuadItem QuadItem(Position.x + 24, Position.y - 40, 64,64); + Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsEnd(); } - if (gameclient.clients[info.cid].emoticon_start != -1 && gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick()) + if (m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart != -1 && m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick()) { - Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); - int since_start = client_tick() - gameclient.clients[info.cid].emoticon_start; - int from_end = gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick(); + int SinceStart = Client()->GameTick() - m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart; + int FromEnd = m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick(); float a = 1; - if (from_end < client_tickspeed() / 5) - a = from_end / (client_tickspeed() / 5.0); + if (FromEnd < Client()->GameTickSpeed() / 5) + a = FromEnd / (Client()->GameTickSpeed() / 5.0); float h = 1; - if (since_start < client_tickspeed() / 10) - h = since_start / (client_tickspeed() / 10.0); + if (SinceStart < Client()->GameTickSpeed() / 10) + h = SinceStart / (Client()->GameTickSpeed() / 10.0); - float wiggle = 0; - if (since_start < client_tickspeed() / 5) - wiggle = since_start / (client_tickspeed() / 5.0); + float Wiggle = 0; + if (SinceStart < Client()->GameTickSpeed() / 5) + Wiggle = SinceStart / (Client()->GameTickSpeed() / 5.0); - float wiggle_angle = sin(5*wiggle); + float WiggleAngle = sinf(5*Wiggle); - Graphics()->QuadsSetRotation(pi/6*wiggle_angle); + Graphics()->QuadsSetRotation(pi/6*WiggleAngle); Graphics()->SetColor(1.0f,1.0f,1.0f,a); // client_datas::emoticon is an offset from the first emoticon - RenderTools()->select_sprite(SPRITE_OOP + gameclient.clients[info.cid].emoticon); - Graphics()->QuadsDraw(position.x, position.y - 23 - 32*h, 64, 64*h); + RenderTools()->SelectSprite(SPRITE_OOP + m_pClient->m_aClients[pInfo.m_ClientId].m_Emoticon); + IGraphics::CQuadItem QuadItem(Position.x, Position.y - 23 - 32*h, 64, 64*h); + Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsEnd(); } } -void PLAYERS::on_render() +void CPlayers::OnRender() { // render other players in two passes, first pass we render the other, second pass we render our self - for(int p = 0; p < 2; p++) + for(int p = 0; p < 4; p++) { for(int i = 0; i < MAX_CLIENTS; i++) { // only render active characters - if(!gameclient.snap.characters[i].active) + if(!m_pClient->m_Snap.m_aCharacters[i].m_Active) continue; - const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, i); - const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i); + const void *pPrevInfo = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_PLAYERINFO, i); + const void *pInfo = Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_PLAYERINFO, i); - if(prev_info && info) + if(pPrevInfo && pInfo) { // - bool local = ((const NETOBJ_PLAYER_INFO *)info)->local !=0; - if(p == 0 && local) continue; - if(p == 1 && !local) continue; + bool Local = ((const CNetObj_PlayerInfo *)pInfo)->m_Local !=0; + if((p % 2) == 0 && Local) continue; + if((p % 2) == 1 && !Local) continue; - NETOBJ_CHARACTER prev_char = gameclient.snap.characters[i].prev; - NETOBJ_CHARACTER cur_char = gameclient.snap.characters[i].cur; - - render_player( - &prev_char, - &cur_char, - (const NETOBJ_PLAYER_INFO *)prev_info, - (const NETOBJ_PLAYER_INFO *)info - ); + CNetObj_Character PrevChar = m_pClient->m_Snap.m_aCharacters[i].m_Prev; + CNetObj_Character CurChar = m_pClient->m_Snap.m_aCharacters[i].m_Cur; + + if(p<2) + RenderHook( + &PrevChar, + &CurChar, + (const CNetObj_PlayerInfo *)pPrevInfo, + (const CNetObj_PlayerInfo *)pInfo + ); + else + RenderPlayer( + &PrevChar, + &CurChar, + (const CNetObj_PlayerInfo *)pPrevInfo, + (const CNetObj_PlayerInfo *)pInfo + ); } } } |