2010-05-29 07:25:38 +00:00
|
|
|
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
|
|
|
|
#include "gamecore.h"
|
2007-09-22 18:55:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
const char *CTuningParams::m_apNames[] =
|
2008-02-02 12:38:36 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
#define MACRO_TUNING_PARAM(Name,ScriptName,Value) #ScriptName,
|
|
|
|
#include "tuning.h"
|
2008-02-02 12:38:36 +00:00
|
|
|
#undef MACRO_TUNING_PARAM
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool CTuningParams::Set(int Index, float Value)
|
2008-02-02 12:38:36 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Index < 0 || Index >= Num())
|
2008-02-02 12:38:36 +00:00
|
|
|
return false;
|
2010-05-29 07:25:38 +00:00
|
|
|
((CTuneParam *)this)[Index] = Value;
|
2008-02-02 12:38:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool CTuningParams::Get(int Index, float *pValue)
|
2008-02-02 12:38:36 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Index < 0 || Index >= Num())
|
2008-02-02 12:38:36 +00:00
|
|
|
return false;
|
2010-05-29 07:25:38 +00:00
|
|
|
*pValue = (float)((CTuneParam *)this)[Index];
|
2008-02-02 12:38:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool CTuningParams::Set(const char *pName, float Value)
|
2008-02-02 12:38:36 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int i = 0; i < Num(); i++)
|
|
|
|
if(str_comp_nocase(pName, m_apNames[i]) == 0)
|
|
|
|
return Set(i, Value);
|
2008-02-02 12:38:36 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool CTuningParams::Get(const char *pName, float *pValue)
|
2008-02-02 12:38:36 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int i = 0; i < Num(); i++)
|
|
|
|
if(str_comp_nocase(pName, m_apNames[i]) == 0)
|
|
|
|
return Get(i, pValue);
|
2008-02-02 12:38:36 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float HermiteBasis1(float v)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
return 2*v*v*v - 3*v*v+1;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float VelocityRamp(float Value, float Start, float Range, float Curvature)
|
2008-03-16 22:32:17 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Value < Start)
|
|
|
|
return 1.0f;
|
|
|
|
return 1.0f/powf(Curvature, (Value-Start)/Range);
|
2008-03-16 22:32:17 +00:00
|
|
|
}
|
|
|
|
|
2010-08-30 12:13:43 +00:00
|
|
|
void CCharacterCore::Init(CWorldCore *pWorld, CCollision *pCollision, CTeamsCore* pTeams)
|
2008-03-16 22:32:17 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pWorld = pWorld;
|
|
|
|
m_pCollision = pCollision;
|
2010-08-30 12:13:43 +00:00
|
|
|
m_pTeams = pTeams;
|
2010-09-08 16:22:11 +00:00
|
|
|
m_Id = -1;
|
2008-03-16 22:32:17 +00:00
|
|
|
}
|
2008-02-24 18:41:02 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacterCore::Reset()
|
2008-02-24 18:41:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Pos = vec2(0,0);
|
|
|
|
m_Vel = vec2(0,0);
|
|
|
|
m_HookPos = vec2(0,0);
|
|
|
|
m_HookDir = vec2(0,0);
|
|
|
|
m_HookTick = 0;
|
|
|
|
m_HookState = HOOK_IDLE;
|
|
|
|
m_HookedPlayer = -1;
|
|
|
|
m_Jumped = 0;
|
|
|
|
m_TriggeredEvents = 0;
|
2008-02-24 18:41:02 +00:00
|
|
|
}
|
|
|
|
|
2010-09-17 11:26:06 +00:00
|
|
|
void CCharacterCore::HandleFly()
|
|
|
|
{
|
|
|
|
m_Vel.y = -m_pWorld->m_Tuning.m_AirJumpImpulse;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacterCore::Tick(bool UseInput)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float PhysSize = 28.0f;
|
2010-09-29 14:45:54 +00:00
|
|
|
int MapIndex = m_pCollision->GetPureMapIndex(m_Pos);;
|
|
|
|
int MapIndexL = m_pCollision->GetPureMapIndex(vec2(m_Pos.x + (28/2)+4,m_Pos.y));
|
|
|
|
int MapIndexR = m_pCollision->GetPureMapIndex(vec2(m_Pos.x - (28/2)-4,m_Pos.y));
|
|
|
|
int MapIndexT = m_pCollision->GetPureMapIndex(vec2(m_Pos.x,m_Pos.y + (28/2)+4));
|
|
|
|
int MapIndexB = m_pCollision->GetPureMapIndex(vec2(m_Pos.x,m_Pos.y - (28/2)-4));
|
|
|
|
//dbg_msg("","N%d L%d R%d B%d T%d",MapIndex,MapIndexL,MapIndexR,MapIndexB,MapIndexT);
|
|
|
|
m_TileIndex = m_pCollision->GetTileIndex(MapIndex);
|
|
|
|
m_TileIndexL = m_pCollision->GetTileIndex(MapIndexL);
|
|
|
|
m_TileIndexR = m_pCollision->GetTileIndex(MapIndexR);
|
|
|
|
m_TileIndexB = m_pCollision->GetTileIndex(MapIndexB);
|
|
|
|
m_TileIndexT = m_pCollision->GetTileIndex(MapIndexT);
|
|
|
|
m_TileFIndex = m_pCollision->GetFTileIndex(MapIndex);
|
|
|
|
m_TileFIndexL = m_pCollision->GetFTileIndex(MapIndexL);
|
|
|
|
m_TileFIndexR = m_pCollision->GetFTileIndex(MapIndexR);
|
|
|
|
m_TileFIndexB = m_pCollision->GetFTileIndex(MapIndexB);
|
|
|
|
m_TileFIndexT = m_pCollision->GetFTileIndex(MapIndexT);
|
|
|
|
m_TileSIndex = m_pCollision->GetDTileIndex(MapIndex, m_pTeams->Team(m_Id));
|
|
|
|
m_TileSIndexL = m_pCollision->GetDTileIndex(MapIndexL, m_pTeams->Team(m_Id));
|
|
|
|
m_TileSIndexR = m_pCollision->GetDTileIndex(MapIndexR, m_pTeams->Team(m_Id));
|
|
|
|
m_TileSIndexB = m_pCollision->GetDTileIndex(MapIndexB, m_pTeams->Team(m_Id));
|
|
|
|
m_TileSIndexT = m_pCollision->GetDTileIndex(MapIndexT, m_pTeams->Team(m_Id));
|
2010-05-29 07:25:38 +00:00
|
|
|
m_TriggeredEvents = 0;
|
2007-09-22 18:55:00 +00:00
|
|
|
|
2008-09-23 07:43:41 +00:00
|
|
|
// get ground state
|
2010-05-29 07:25:38 +00:00
|
|
|
bool Grounded = false;
|
2010-08-29 03:46:09 +00:00
|
|
|
if(m_pCollision->CheckPoint(m_Pos.x+PhysSize/2, m_Pos.y+PhysSize/2+5))
|
2010-05-29 07:25:38 +00:00
|
|
|
Grounded = true;
|
2010-08-29 03:46:09 +00:00
|
|
|
if(m_pCollision->CheckPoint(m_Pos.x-PhysSize/2, m_Pos.y+PhysSize/2+5))
|
2010-05-29 07:25:38 +00:00
|
|
|
Grounded = true;
|
2007-09-22 18:55:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 TargetDirection = normalize(vec2(m_Input.m_TargetX, m_Input.m_TargetY));
|
2007-09-22 18:55:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Vel.y += m_pWorld->m_Tuning.m_Gravity;
|
2007-09-22 18:55:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float MaxSpeed = Grounded ? m_pWorld->m_Tuning.m_GroundControlSpeed : m_pWorld->m_Tuning.m_AirControlSpeed;
|
|
|
|
float Accel = Grounded ? m_pWorld->m_Tuning.m_GroundControlAccel : m_pWorld->m_Tuning.m_AirControlAccel;
|
|
|
|
float Friction = Grounded ? m_pWorld->m_Tuning.m_GroundFriction : m_pWorld->m_Tuning.m_AirFriction;
|
2007-09-22 18:55:00 +00:00
|
|
|
|
2008-09-23 07:43:41 +00:00
|
|
|
// handle input
|
2010-05-29 07:25:38 +00:00
|
|
|
if(UseInput)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Direction = m_Input.m_Direction;
|
2008-09-23 07:43:41 +00:00
|
|
|
|
|
|
|
// setup angle
|
|
|
|
float a = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Input.m_TargetX == 0)
|
|
|
|
a = atanf((float)m_Input.m_TargetY);
|
2008-09-23 07:43:41 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
a = atanf((float)m_Input.m_TargetY/(float)m_Input.m_TargetX);
|
2008-09-23 07:43:41 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Input.m_TargetX < 0)
|
2008-09-23 07:43:41 +00:00
|
|
|
a = a+pi;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Angle = (int)(a*256.0f);
|
2008-09-23 07:43:41 +00:00
|
|
|
|
|
|
|
// handle jump
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Input.m_Jump)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!(m_Jumped&1))
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Grounded)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_TriggeredEvents |= COREEVENT_GROUND_JUMP;
|
|
|
|
m_Vel.y = -m_pWorld->m_Tuning.m_GroundJumpImpulse;
|
|
|
|
m_Jumped |= 1;
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(!(m_Jumped&2))
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_TriggeredEvents |= COREEVENT_AIR_JUMP;
|
|
|
|
m_Vel.y = -m_pWorld->m_Tuning.m_AirJumpImpulse;
|
|
|
|
m_Jumped |= 3;
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Jumped &= ~1;
|
2008-09-23 07:43:41 +00:00
|
|
|
|
|
|
|
// handle hook
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Input.m_Hook)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_HookState == HOOK_IDLE)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookState = HOOK_FLYING;
|
|
|
|
m_HookPos = m_Pos+TargetDirection*PhysSize*1.5f;
|
|
|
|
m_HookDir = TargetDirection;
|
|
|
|
m_HookedPlayer = -1;
|
|
|
|
m_HookTick = 0;
|
|
|
|
m_TriggeredEvents |= COREEVENT_HOOK_LAUNCH;
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookedPlayer = -1;
|
|
|
|
m_HookState = HOOK_IDLE;
|
|
|
|
m_HookPos = m_Pos;
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// add the speed modification according to players wanted direction
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Direction < 0)
|
|
|
|
m_Vel.x = SaturatedAdd(-MaxSpeed, MaxSpeed, m_Vel.x, -Accel);
|
|
|
|
if(m_Direction > 0)
|
|
|
|
m_Vel.x = SaturatedAdd(-MaxSpeed, MaxSpeed, m_Vel.x, Accel);
|
|
|
|
if(m_Direction == 0)
|
|
|
|
m_Vel.x *= Friction;
|
2007-09-22 18:55:00 +00:00
|
|
|
|
|
|
|
// handle jumping
|
2007-12-09 09:48:53 +00:00
|
|
|
// 1 bit = to keep track if a jump has been made on this input
|
|
|
|
// 2 bit = to keep track if a air-jump has been made
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Grounded)
|
|
|
|
m_Jumped &= ~2;
|
2007-12-09 09:48:53 +00:00
|
|
|
|
2008-09-23 07:43:41 +00:00
|
|
|
// do hook
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_HookState == HOOK_IDLE)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookedPlayer = -1;
|
|
|
|
m_HookState = HOOK_IDLE;
|
|
|
|
m_HookPos = m_Pos;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(m_HookState >= HOOK_RETRACT_START && m_HookState < HOOK_RETRACT_END)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookState++;
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(m_HookState == HOOK_RETRACT_END)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookState = HOOK_RETRACTED;
|
|
|
|
m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
|
|
|
m_HookState = HOOK_RETRACTED;
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(m_HookState == HOOK_FLYING)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 NewPos = m_HookPos+m_HookDir*m_pWorld->m_Tuning.m_HookFireSpeed;
|
|
|
|
if(distance(m_Pos, NewPos) > m_pWorld->m_Tuning.m_HookLength)
|
2008-03-22 13:03:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookState = HOOK_RETRACT_START;
|
|
|
|
NewPos = m_Pos + normalize(NewPos-m_Pos) * m_pWorld->m_Tuning.m_HookLength;
|
2010-08-21 02:20:01 +00:00
|
|
|
m_pReset = true;
|
2008-03-19 23:08:26 +00:00
|
|
|
}
|
2008-09-23 07:43:41 +00:00
|
|
|
|
|
|
|
// make sure that the hook doesn't go though the ground
|
2010-05-29 07:25:38 +00:00
|
|
|
bool GoingToHitGround = false;
|
|
|
|
bool GoingToRetract = false;
|
2010-08-21 02:20:01 +00:00
|
|
|
int Hit = m_pCollision->IntersectLine(m_HookPos, NewPos, &NewPos, 0,true);
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Hit)
|
2008-09-23 14:38:13 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Hit&CCollision::COLFLAG_NOHOOK)
|
|
|
|
GoingToRetract = true;
|
2008-09-23 14:38:13 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
GoingToHitGround = true;
|
2010-08-21 02:20:01 +00:00
|
|
|
m_pReset = true;
|
2008-09-23 14:38:13 +00:00
|
|
|
}
|
2010-08-30 19:25:04 +00:00
|
|
|
|
2008-09-23 07:43:41 +00:00
|
|
|
// Check against other players first
|
2010-08-29 12:28:21 +00:00
|
|
|
if(m_pWorld && m_pWorld->m_Tuning.m_PlayerHooking)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float Dist = 0.0f;
|
2010-10-02 12:04:39 +00:00
|
|
|
char aBuf[512];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "m_Id = %d", m_Id);
|
|
|
|
dbg_msg("GameCore", aBuf);
|
|
|
|
str_format(aBuf, sizeof(aBuf), "Teams: 0:%d 1:%d 2:%d 3:%d 4:%d 5:%d 6:%d 7:%d 8:%d 9:%d 10:%d 11:%d 12:%d 13:%d 14:%d 15:%d",
|
|
|
|
m_pTeams->Team(0),
|
|
|
|
m_pTeams->Team(1),
|
|
|
|
m_pTeams->Team(2),
|
|
|
|
m_pTeams->Team(3),
|
|
|
|
m_pTeams->Team(4),
|
|
|
|
m_pTeams->Team(5),
|
|
|
|
m_pTeams->Team(6),
|
|
|
|
m_pTeams->Team(7),
|
|
|
|
m_pTeams->Team(8),
|
|
|
|
m_pTeams->Team(9),
|
|
|
|
m_pTeams->Team(10),
|
|
|
|
m_pTeams->Team(11),
|
|
|
|
m_pTeams->Team(12),
|
|
|
|
m_pTeams->Team(13),
|
|
|
|
m_pTeams->Team(14),
|
|
|
|
m_pTeams->Team(15));
|
|
|
|
dbg_msg("GameCore", aBuf);
|
2007-09-22 18:55:00 +00:00
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CCharacterCore *p = m_pWorld->m_apCharacters[i];
|
2010-08-30 19:25:04 +00:00
|
|
|
|
|
|
|
|
2010-09-21 19:09:11 +00:00
|
|
|
if(!p || p == this || !m_pTeams->CanCollide(i, m_Id))
|
2007-09-22 18:55:00 +00:00
|
|
|
continue;
|
2010-08-30 19:25:04 +00:00
|
|
|
//char aBuf[512];
|
|
|
|
//str_format(aBuf, sizeof(aBuf), "ThisId = %d Id = %d TheSameTeam? = %d", ThisId, i, m_pTeams->SameTeam(i, ThisId));
|
|
|
|
//dbg_msg("GameCore", aBuf);
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 ClosestPoint = closest_point_on_line(m_HookPos, NewPos, p->m_Pos);
|
|
|
|
if(distance(p->m_Pos, ClosestPoint) < PhysSize+2.0f)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if (m_HookedPlayer == -1 || distance(m_HookPos, p->m_Pos) < Dist)
|
2009-01-09 22:41:26 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_TriggeredEvents |= COREEVENT_HOOK_ATTACH_PLAYER;
|
|
|
|
m_HookState = HOOK_GRABBED;
|
|
|
|
m_HookedPlayer = i;
|
|
|
|
Dist = distance(m_HookPos, p->m_Pos);
|
2009-01-09 22:41:26 +00:00
|
|
|
}
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
}
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_HookState == HOOK_FLYING)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
|
|
|
// check against ground
|
2010-05-29 07:25:38 +00:00
|
|
|
if(GoingToHitGround)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_TriggeredEvents |= COREEVENT_HOOK_ATTACH_GROUND;
|
|
|
|
m_HookState = HOOK_GRABBED;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(GoingToRetract)
|
2008-09-23 14:38:13 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_TriggeredEvents |= COREEVENT_HOOK_HIT_NOHOOK;
|
|
|
|
m_HookState = HOOK_RETRACT_START;
|
2008-09-23 14:38:13 +00:00
|
|
|
}
|
2008-09-23 07:43:41 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookPos = NewPos;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
}
|
2007-12-09 15:56:56 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_HookState == HOOK_GRABBED)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_HookedPlayer != -1)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-07-29 19:51:58 +00:00
|
|
|
CCharacterCore *p = m_pWorld->m_apCharacters[m_HookedPlayer];
|
|
|
|
//
|
|
|
|
if(p/*&&*/)
|
|
|
|
{
|
|
|
|
//CCharacter* pl = GameServer()->m_apPlayers[m_HookedPlayer]->GetCharacter();
|
|
|
|
//if (pl->m_RaceState != RACE_PAUSE)
|
|
|
|
m_HookPos = p->m_Pos;
|
|
|
|
}
|
2007-12-09 15:58:24 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// release hook
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookedPlayer = -1;
|
|
|
|
m_HookState = HOOK_RETRACTED;
|
|
|
|
m_HookPos = m_Pos;
|
2007-12-09 15:58:24 +00:00
|
|
|
}
|
2007-09-22 18:55:00 +00:00
|
|
|
|
|
|
|
// keep players hooked for a max of 1.5sec
|
2010-05-29 07:25:38 +00:00
|
|
|
//if(Server()->Tick() > hook_tick+(Server()->TickSpeed()*3)/2)
|
2007-09-22 18:55:00 +00:00
|
|
|
//release_hooked();
|
|
|
|
}
|
|
|
|
|
2007-12-15 10:49:47 +00:00
|
|
|
// don't do this hook rutine when we are hook to a player
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_HookedPlayer == -1 && distance(m_HookPos, m_Pos) > 46.0f)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 HookVel = normalize(m_HookPos-m_Pos)*m_pWorld->m_Tuning.m_HookDragAccel;
|
2007-09-22 18:55:00 +00:00
|
|
|
// the hook as more power to drag you up then down.
|
|
|
|
// this makes it easier to get on top of an platform
|
2010-05-29 07:25:38 +00:00
|
|
|
if(HookVel.y > 0)
|
|
|
|
HookVel.y *= 0.3f;
|
2007-09-22 18:55:00 +00:00
|
|
|
|
|
|
|
// the hook will boost it's power if the player wants to move
|
|
|
|
// in that direction. otherwise it will dampen everything abit
|
2010-05-29 07:25:38 +00:00
|
|
|
if((HookVel.x < 0 && m_Direction < 0) || (HookVel.x > 0 && m_Direction > 0))
|
|
|
|
HookVel.x *= 0.95f;
|
2007-09-22 18:55:00 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
HookVel.x *= 0.75f;
|
2007-09-22 18:55:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 NewVel = m_Vel+HookVel;
|
2008-01-29 21:39:41 +00:00
|
|
|
|
2007-09-22 18:55:00 +00:00
|
|
|
// check if we are under the legal limit for the hook
|
2010-05-29 07:25:38 +00:00
|
|
|
if(length(NewVel) < m_pWorld->m_Tuning.m_HookDragSpeed || length(NewVel) < length(m_Vel))
|
|
|
|
m_Vel = NewVel; // no problem. apply
|
2007-10-28 11:30:25 +00:00
|
|
|
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
2007-12-09 15:56:56 +00:00
|
|
|
|
2009-01-11 11:54:41 +00:00
|
|
|
// release hook (max hook time is 1.25
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookTick++;
|
|
|
|
if(m_HookedPlayer != -1 && (m_HookTick > SERVER_TICK_SPEED+SERVER_TICK_SPEED/5 || !m_pWorld->m_apCharacters[m_HookedPlayer]))
|
2007-12-09 15:56:56 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_HookedPlayer = -1;
|
|
|
|
m_HookState = HOOK_RETRACTED;
|
|
|
|
m_HookPos = m_Pos;
|
2007-12-09 15:56:56 +00:00
|
|
|
}
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
2010-08-30 12:13:43 +00:00
|
|
|
if(m_pWorld/* && m_pWorld->m_Tuning.m_PlayerCollision*/)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CCharacterCore *p = m_pWorld->m_apCharacters[i];
|
2007-09-22 18:55:00 +00:00
|
|
|
if(!p)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
//player *p = (player*)ent;
|
2010-09-21 19:09:11 +00:00
|
|
|
if(p == this || (m_Id != -1 && !m_pTeams->CanCollide(m_Id, i))) { // || !(p->flags&FLAG_ALIVE)
|
2007-09-22 18:55:00 +00:00
|
|
|
continue; // make sure that we don't nudge our self
|
2010-08-30 12:13:43 +00:00
|
|
|
}
|
2007-09-22 18:55:00 +00:00
|
|
|
// handle player <-> player collision
|
2010-05-29 07:25:38 +00:00
|
|
|
float d = distance(m_Pos, p->m_Pos);
|
|
|
|
vec2 Dir = normalize(m_Pos - p->m_Pos);
|
2010-08-30 19:25:04 +00:00
|
|
|
if (m_pWorld->m_Tuning.m_PlayerCollision) {
|
2007-12-15 10:49:47 +00:00
|
|
|
|
2010-07-29 05:21:18 +00:00
|
|
|
if(d < PhysSize*1.25f && d > 1.0f)
|
|
|
|
{
|
|
|
|
float a = (PhysSize*1.45f - d);
|
|
|
|
|
|
|
|
// make sure that we don't add excess force by checking the
|
|
|
|
// direction against the current velocity
|
|
|
|
vec2 VelDir = normalize(m_Vel);
|
|
|
|
float v = 1-(dot(VelDir, Dir)+1)/2;
|
|
|
|
m_Vel = m_Vel + Dir*a*(v*0.75f);
|
|
|
|
m_Vel = m_Vel * 0.85f;
|
|
|
|
}
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
// handle hook influence
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_HookedPlayer == i)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(d > PhysSize*1.50f) // TODO: fix tweakable variable
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float Accel = m_pWorld->m_Tuning.m_HookDragAccel * (d/m_pWorld->m_Tuning.m_HookLength);
|
|
|
|
float DragSpeed = m_pWorld->m_Tuning.m_HookDragSpeed;
|
2010-09-29 14:45:54 +00:00
|
|
|
vec2 Temp = p->m_Vel;
|
|
|
|
Temp.x = SaturatedAdd(-DragSpeed, DragSpeed, p->m_Vel.x, Accel*Dir.x*1.5f);
|
|
|
|
Temp.y = SaturatedAdd(-DragSpeed, DragSpeed, p->m_Vel.y, Accel*Dir.y*1.5f);
|
|
|
|
if(Temp.x > 0 && (p->m_TileIndex == TILE_STOPL || p->m_TileIndexL == TILE_STOPL || p->m_TileIndexL == TILE_STOPH || p->m_TileIndexL == TILE_STOPA || p->m_TileFIndex == TILE_STOPL || p->m_TileFIndexL == TILE_STOPL || p->m_TileFIndexL == TILE_STOPH || p->m_TileFIndexL == TILE_STOPA || p->m_TileSIndex == TILE_STOPL || p->m_TileSIndexL == TILE_STOPL || p->m_TileSIndexL == TILE_STOPH || p->m_TileSIndexL == TILE_STOPA))
|
|
|
|
Temp.x = 0;
|
|
|
|
if(Temp.x < 0 && (p->m_TileIndex == TILE_STOPR || p->m_TileIndexR == TILE_STOPR || p->m_TileIndexR == TILE_STOPH || p->m_TileIndexR == TILE_STOPA || p->m_TileFIndex == TILE_STOPR || p->m_TileFIndexR == TILE_STOPR || p->m_TileFIndexR == TILE_STOPH || p->m_TileFIndexR == TILE_STOPA || p->m_TileSIndex == TILE_STOPR || p->m_TileSIndexR == TILE_STOPR || p->m_TileSIndexR == TILE_STOPH || p->m_TileSIndexR == TILE_STOPA))
|
|
|
|
Temp.x = 0;
|
|
|
|
if(Temp.y < 0 && (p->m_TileIndex == TILE_STOPB || p->m_TileIndexB == TILE_STOPB || p->m_TileIndexB == TILE_STOPV || p->m_TileIndexB == TILE_STOPA || p->m_TileFIndex == TILE_STOPB || p->m_TileFIndexB == TILE_STOPB || p->m_TileFIndexB == TILE_STOPV || p->m_TileFIndexB == TILE_STOPA || p->m_TileSIndex == TILE_STOPB || p->m_TileSIndexB == TILE_STOPB || p->m_TileSIndexB == TILE_STOPV || p->m_TileSIndexB == TILE_STOPA))
|
|
|
|
Temp.y = 0;
|
|
|
|
if(Temp.y > 0 && (p->m_TileIndex == TILE_STOPT || p->m_TileIndexT == TILE_STOPT || p->m_TileIndexT == TILE_STOPV || p->m_TileIndexT == TILE_STOPA || p->m_TileFIndex == TILE_STOPT || p->m_TileFIndexT == TILE_STOPT || p->m_TileFIndexT == TILE_STOPV || p->m_TileFIndexT == TILE_STOPA || p->m_TileSIndex == TILE_STOPT || p->m_TileSIndexT == TILE_STOPT || p->m_TileSIndexT == TILE_STOPV || p->m_TileSIndexT == TILE_STOPA))
|
|
|
|
Temp.y = 0;
|
2007-12-15 10:49:47 +00:00
|
|
|
|
2010-09-29 14:45:54 +00:00
|
|
|
// add force to the hooked player
|
|
|
|
p->m_Vel = Temp;
|
|
|
|
Temp.x = SaturatedAdd(-DragSpeed, DragSpeed, m_Vel.x, -Accel*Dir.x*0.25f);
|
|
|
|
Temp.y = SaturatedAdd(-DragSpeed, DragSpeed, m_Vel.y, -Accel*Dir.y*0.25f);
|
|
|
|
if(Temp.x > 0 && (m_TileIndex == TILE_STOPL || m_TileIndexL == TILE_STOPL || m_TileIndexL == TILE_STOPH || m_TileIndexL == TILE_STOPA || m_TileFIndex == TILE_STOPL || m_TileFIndexL == TILE_STOPL || m_TileFIndexL == TILE_STOPH || m_TileFIndexL == TILE_STOPA || m_TileSIndex == TILE_STOPL || m_TileSIndexL == TILE_STOPL || m_TileSIndexL == TILE_STOPH || m_TileSIndexL == TILE_STOPA))
|
|
|
|
Temp.x = 0;
|
|
|
|
if(Temp.x < 0 && (m_TileIndex == TILE_STOPR || m_TileIndexR == TILE_STOPR || m_TileIndexR == TILE_STOPH || m_TileIndexR == TILE_STOPA || m_TileFIndex == TILE_STOPR || m_TileFIndexR == TILE_STOPR || m_TileFIndexR == TILE_STOPH || m_TileFIndexR == TILE_STOPA || m_TileSIndex == TILE_STOPR || m_TileSIndexR == TILE_STOPR || m_TileSIndexR == TILE_STOPH || m_TileSIndexR == TILE_STOPA))
|
|
|
|
Temp.x = 0;
|
|
|
|
if(Temp.y < 0 && (m_TileIndex == TILE_STOPB || m_TileIndexB == TILE_STOPB || m_TileIndexB == TILE_STOPV || m_TileIndexB == TILE_STOPA || m_TileFIndex == TILE_STOPB || m_TileFIndexB == TILE_STOPB || m_TileFIndexB == TILE_STOPV || m_TileFIndexB == TILE_STOPA || m_TileSIndex == TILE_STOPB || m_TileSIndexB == TILE_STOPB || m_TileSIndexB == TILE_STOPV || m_TileSIndexB == TILE_STOPA))
|
|
|
|
Temp.y = 0;
|
|
|
|
if(Temp.y > 0 && (m_TileIndex == TILE_STOPT || m_TileIndexT == TILE_STOPT || m_TileIndexT == TILE_STOPV || m_TileIndexT == TILE_STOPA || m_TileFIndex == TILE_STOPT || m_TileFIndexT == TILE_STOPT || m_TileFIndexT == TILE_STOPV || m_TileFIndexT == TILE_STOPA || m_TileSIndex == TILE_STOPT || m_TileSIndexT == TILE_STOPT || m_TileSIndexT == TILE_STOPV || m_TileSIndexT == TILE_STOPA))
|
|
|
|
Temp.y = 0;
|
2007-12-15 10:49:47 +00:00
|
|
|
// add a little bit force to the guy who has the grip
|
2010-09-29 14:45:54 +00:00
|
|
|
m_Vel = Temp;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-01-20 15:19:30 +00:00
|
|
|
|
|
|
|
// clamp the velocity to something sane
|
2010-05-29 07:25:38 +00:00
|
|
|
if(length(m_Vel) > 6000)
|
|
|
|
m_Vel = normalize(m_Vel) * 6000;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacterCore::Move()
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float RampValue = VelocityRamp(length(m_Vel)*50, m_pWorld->m_Tuning.m_VelrampStart, m_pWorld->m_Tuning.m_VelrampRange, m_pWorld->m_Tuning.m_VelrampCurvature);
|
2008-03-16 22:32:17 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Vel.x = m_Vel.x*RampValue;
|
|
|
|
m_pCollision->MoveBox(&m_Pos, &m_Vel, vec2(28.0f, 28.0f), 0);
|
|
|
|
m_Vel.x = m_Vel.x*(1.0f/RampValue);
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacterCore::Write(CNetObj_CharacterCore *pObjCore)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
pObjCore->m_X = round(m_Pos.x);
|
|
|
|
pObjCore->m_Y = round(m_Pos.y);
|
2008-11-16 22:07:46 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
pObjCore->m_VelX = round(m_Vel.x*256.0f);
|
|
|
|
pObjCore->m_VelY = round(m_Vel.y*256.0f);
|
|
|
|
pObjCore->m_HookState = m_HookState;
|
|
|
|
pObjCore->m_HookTick = m_HookTick;
|
|
|
|
pObjCore->m_HookX = round(m_HookPos.x);
|
|
|
|
pObjCore->m_HookY = round(m_HookPos.y);
|
|
|
|
pObjCore->m_HookDx = round(m_HookDir.x*256.0f);
|
|
|
|
pObjCore->m_HookDy = round(m_HookDir.y*256.0f);
|
|
|
|
pObjCore->m_HookedPlayer = m_HookedPlayer;
|
|
|
|
pObjCore->m_Jumped = m_Jumped;
|
|
|
|
pObjCore->m_Direction = m_Direction;
|
|
|
|
pObjCore->m_Angle = m_Angle;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacterCore::Read(const CNetObj_CharacterCore *pObjCore)
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Pos.x = pObjCore->m_X;
|
|
|
|
m_Pos.y = pObjCore->m_Y;
|
|
|
|
m_Vel.x = pObjCore->m_VelX/256.0f;
|
|
|
|
m_Vel.y = pObjCore->m_VelY/256.0f;
|
|
|
|
m_HookState = pObjCore->m_HookState;
|
|
|
|
m_HookTick = pObjCore->m_HookTick;
|
|
|
|
m_HookPos.x = pObjCore->m_HookX;
|
|
|
|
m_HookPos.y = pObjCore->m_HookY;
|
|
|
|
m_HookDir.x = pObjCore->m_HookDx/256.0f;
|
|
|
|
m_HookDir.y = pObjCore->m_HookDy/256.0f;
|
|
|
|
m_HookedPlayer = pObjCore->m_HookedPlayer;
|
|
|
|
m_Jumped = pObjCore->m_Jumped;
|
|
|
|
m_Direction = pObjCore->m_Direction;
|
|
|
|
m_Angle = pObjCore->m_Angle;
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacterCore::Quantize()
|
2007-09-22 18:55:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetObj_CharacterCore Core;
|
|
|
|
Write(&Core);
|
|
|
|
Read(&Core);
|
2007-09-22 18:55:00 +00:00
|
|
|
}
|