2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2008-07-06 11:21:21 +00:00
|
|
|
#include <new>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/shared/config.h>
|
|
|
|
#include <game/server/gamecontext.h>
|
|
|
|
#include <game/mapitems.h>
|
2010-08-23 19:37:27 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "character.h"
|
|
|
|
#include "laser.h"
|
|
|
|
#include "projectile.h"
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <engine/server/server.h>
|
|
|
|
#include <game/server/gamemodes/DDRace.h>
|
|
|
|
#include <game/server/score.h>
|
|
|
|
#include "light.h"
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
//input count
|
|
|
|
struct CInputCount
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int m_Presses;
|
|
|
|
int m_Releases;
|
2008-07-06 11:21:21 +00:00
|
|
|
};
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CInputCount CountInput(int Prev, int Cur)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CInputCount c = {0, 0};
|
|
|
|
Prev &= INPUT_STATE_MASK;
|
|
|
|
Cur &= INPUT_STATE_MASK;
|
|
|
|
int i = Prev;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
while(i != Cur)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
|
|
|
i = (i+1)&INPUT_STATE_MASK;
|
|
|
|
if(i&1)
|
2010-05-29 07:25:38 +00:00
|
|
|
c.m_Presses++;
|
2008-07-06 11:21:21 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
c.m_Releases++;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2008-09-24 09:03:49 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS)
|
2008-09-24 09:03:49 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// Character, "physical" player's part
|
2010-05-29 07:25:38 +00:00
|
|
|
CCharacter::CCharacter(CGameWorld *pWorld)
|
2011-01-19 17:27:50 +00:00
|
|
|
: CEntity(pWorld, CGameWorld::ENTTYPE_CHARACTER)
|
2008-09-23 07:43:41 +00:00
|
|
|
{
|
2010-06-03 15:39:42 +00:00
|
|
|
m_ProximityRadius = ms_PhysSize;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Health = 0;
|
|
|
|
m_Armor = 0;
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::Reset()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Destroy();
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_EmoteStop = -1;
|
|
|
|
m_LastAction = -1;
|
|
|
|
m_ActiveWeapon = WEAPON_GUN;
|
|
|
|
m_LastWeapon = WEAPON_HAMMER;
|
|
|
|
m_QueuedWeapon = -1;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pPlayer = pPlayer;
|
|
|
|
m_Pos = Pos;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Core.Reset();
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Core.Init(&GameServer()->m_World.m_Core, GameServer()->Collision(), &((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core);
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Core.m_Pos = m_Pos;
|
|
|
|
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = &m_Core;
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ReckoningTick = 0;
|
|
|
|
mem_zero(&m_SendCore, sizeof(m_SendCore));
|
|
|
|
mem_zero(&m_ReckoningCore, sizeof(m_ReckoningCore));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_World.InsertEntity(this);
|
|
|
|
m_Alive = true;
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_pController->OnCharacterSpawn(this);
|
2011-01-29 00:59:50 +00:00
|
|
|
|
|
|
|
DDRaceInit();
|
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::Destroy()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
|
|
|
|
m_Alive = false;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::SetWeapon(int W)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(W == m_ActiveWeapon)
|
2008-07-06 11:21:21 +00:00
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_LastWeapon = m_ActiveWeapon;
|
|
|
|
m_QueuedWeapon = -1;
|
|
|
|
m_ActiveWeapon = W;
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SWITCH, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_ActiveWeapon < 0 || m_ActiveWeapon >= NUM_WEAPONS)
|
|
|
|
m_ActiveWeapon = 0;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool CCharacter::IsGrounded()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-08-29 03:46:09 +00:00
|
|
|
if(GameServer()->Collision()->CheckPoint(m_Pos.x+m_ProximityRadius/2, m_Pos.y+m_ProximityRadius/2+5))
|
2008-07-06 11:21:21 +00:00
|
|
|
return true;
|
2010-08-29 03:46:09 +00:00
|
|
|
if(GameServer()->Collision()->CheckPoint(m_Pos.x-m_ProximityRadius/2, m_Pos.y+m_ProximityRadius/2+5))
|
2008-07-06 11:21:21 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::HandleNinja()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_ActiveWeapon != WEAPON_NINJA)
|
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if ((Server()->Tick() - m_Ninja.m_ActivationTick) > (g_pData->m_Weapons.m_Ninja.m_Duration * Server()->TickSpeed() / 1000))
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
|
|
|
// time's up, return
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aWeapons[WEAPON_NINJA].m_Got = false;
|
|
|
|
m_ActiveWeapon = m_LastWeapon;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
SetWeapon(m_ActiveWeapon);
|
|
|
|
return;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// force ninja Weapon
|
|
|
|
SetWeapon(WEAPON_NINJA);
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Ninja.m_CurrentMoveTime--;
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if (m_Ninja.m_CurrentMoveTime == 0)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
// reset velocity
|
2011-03-13 18:00:00 +00:00
|
|
|
m_Core.m_Vel = m_Ninja.m_ActivationDir*m_Ninja.m_OldVelAmount;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if (m_Ninja.m_CurrentMoveTime > 0)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
// Set velocity
|
|
|
|
m_Core.m_Vel = m_Ninja.m_ActivationDir * g_pData->m_Weapons.m_Ninja.m_Velocity;
|
|
|
|
vec2 OldPos = m_Pos;
|
2010-06-03 15:39:42 +00:00
|
|
|
GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(m_ProximityRadius, m_ProximityRadius), 0.f);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
// reset velocity so the client doesn't predict stuff
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Core.m_Vel = vec2(0.f, 0.f);
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// check if we Hit anything along the way
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2011-01-19 17:27:50 +00:00
|
|
|
CCharacter *aEnts[MAX_CLIENTS];
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 Dir = m_Pos - OldPos;
|
2010-06-03 15:39:42 +00:00
|
|
|
float Radius = m_ProximityRadius * 2.0f;
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 Center = OldPos + Dir * 0.5f;
|
2011-01-19 17:27:50 +00:00
|
|
|
int Num = GameServer()->m_World.FindEntities(Center, Radius, (CEntity**)aEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for (int i = 0; i < Num; ++i)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if (aEnts[i] == this)
|
2008-07-06 11:21:21 +00:00
|
|
|
continue;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// make sure we haven't Hit this object before
|
|
|
|
bool bAlreadyHit = false;
|
|
|
|
for (int j = 0; j < m_NumObjectsHit; j++)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if (m_apHitObjects[j] == aEnts[i])
|
|
|
|
bAlreadyHit = true;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
if (bAlreadyHit)
|
2008-07-06 11:21:21 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// check so we are sufficiently close
|
2010-06-03 15:39:42 +00:00
|
|
|
if (distance(aEnts[i]->m_Pos, m_Pos) > (m_ProximityRadius * 2.0f))
|
2008-07-06 11:21:21 +00:00
|
|
|
continue;
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// Hit a player, give him damage and stuffs...
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(aEnts[i]->m_Pos, SOUND_NINJA_HIT, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2008-07-06 11:21:21 +00:00
|
|
|
// set his velocity to fast upward (for now)
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_NumObjectsHit < 10)
|
|
|
|
m_apHitObjects[m_NumObjectsHit++] = aEnts[i];
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-07-30 16:08:24 +00:00
|
|
|
aEnts[i]->TakeDamage(vec2(0, -10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA);
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
return;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
return;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::DoWeaponSwitch()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
// make sure we can switch
|
|
|
|
if(m_ReloadTimer != 0 || m_QueuedWeapon == -1 || m_aWeapons[WEAPON_NINJA].m_Got)
|
2008-07-06 11:21:21 +00:00
|
|
|
return;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// switch Weapon
|
|
|
|
SetWeapon(m_QueuedWeapon);
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::HandleWeaponSwitch()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int WantedWeapon = m_ActiveWeapon;
|
|
|
|
if(m_QueuedWeapon != -1)
|
|
|
|
WantedWeapon = m_QueuedWeapon;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-02-13 05:35:13 +00:00
|
|
|
bool Anything = false;
|
2011-02-08 23:03:42 +00:00
|
|
|
for(int i = 0; i < NUM_WEAPONS - 1; ++i)
|
|
|
|
if(m_aWeapons[i].m_Got)
|
|
|
|
Anything = true;
|
|
|
|
if(!Anything)
|
|
|
|
return;
|
2010-05-29 07:25:38 +00:00
|
|
|
// select Weapon
|
|
|
|
int Next = CountInput(m_LatestPrevInput.m_NextWeapon, m_LatestInput.m_NextWeapon).m_Presses;
|
|
|
|
int Prev = CountInput(m_LatestPrevInput.m_PrevWeapon, m_LatestInput.m_PrevWeapon).m_Presses;
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Next < 128) // make sure we only try sane stuff
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
while(Next) // Next Weapon selection
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
WantedWeapon = (WantedWeapon+1)%NUM_WEAPONS;
|
|
|
|
if(m_aWeapons[WantedWeapon].m_Got)
|
|
|
|
Next--;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Prev < 128) // make sure we only try sane stuff
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
while(Prev) // Prev Weapon selection
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
WantedWeapon = (WantedWeapon-1)<0?NUM_WEAPONS-1:WantedWeapon-1;
|
|
|
|
if(m_aWeapons[WantedWeapon].m_Got)
|
|
|
|
Prev--;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// Direct Weapon selection
|
|
|
|
if(m_LatestInput.m_WantedWeapon)
|
|
|
|
WantedWeapon = m_Input.m_WantedWeapon-1;
|
2008-07-06 11:21:21 +00:00
|
|
|
|
|
|
|
// check for insane values
|
2010-05-29 07:25:38 +00:00
|
|
|
if(WantedWeapon >= 0 && WantedWeapon < NUM_WEAPONS && WantedWeapon != m_ActiveWeapon && m_aWeapons[WantedWeapon].m_Got)
|
|
|
|
m_QueuedWeapon = WantedWeapon;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
DoWeaponSwitch();
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::FireWeapon()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
if(m_ReloadTimer != 0)
|
2008-07-06 11:21:21 +00:00
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
DoWeaponSwitch();
|
|
|
|
vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool FullAuto = false;
|
|
|
|
if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE)
|
|
|
|
FullAuto = true;
|
2008-07-06 11:21:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
// check if we gonna fire
|
2010-05-29 07:25:38 +00:00
|
|
|
bool WillFire = false;
|
|
|
|
if(CountInput(m_LatestPrevInput.m_Fire, m_LatestInput.m_Fire).m_Presses)
|
|
|
|
WillFire = true;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(FullAuto && (m_LatestInput.m_Fire&1) && m_aWeapons[m_ActiveWeapon].m_Ammo)
|
|
|
|
WillFire = true;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!WillFire)
|
2008-07-06 11:21:21 +00:00
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
// check for ammo
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!m_aWeapons[m_ActiveWeapon].m_Ammo)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2011-04-09 06:41:31 +00:00
|
|
|
/*// 125ms is a magical limit of how fast a human can click
|
2011-01-29 00:59:50 +00:00
|
|
|
m_ReloadTimer = 125 * Server()->TickSpeed() / 1000;
|
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO);*/
|
2011-04-09 06:41:31 +00:00
|
|
|
// Timer stuff to avoid shrieking orchestra caused by unfreeze-plasma
|
2010-11-04 23:52:37 +00:00
|
|
|
if(m_PainSoundTimer<=0)
|
|
|
|
{
|
|
|
|
m_PainSoundTimer = 1 * Server()->TickSpeed();
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2010-11-04 23:52:37 +00:00
|
|
|
}
|
2008-07-06 11:21:21 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-06-03 15:39:42 +00:00
|
|
|
vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
switch(m_ActiveWeapon)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
|
|
|
case WEAPON_HAMMER:
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
// reset objects Hit
|
|
|
|
m_NumObjectsHit = 0;
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2010-08-24 14:32:46 +00:00
|
|
|
|
2011-07-25 20:16:20 +00:00
|
|
|
if (m_Hit&DISABLE_HIT_HAMMER) break;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-19 17:27:50 +00:00
|
|
|
CCharacter *apEnts[MAX_CLIENTS];
|
2010-05-29 07:25:38 +00:00
|
|
|
int Hits = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts,
|
2011-01-19 17:27:50 +00:00
|
|
|
MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for (int i = 0; i < Num; ++i)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2011-01-09 19:53:19 +00:00
|
|
|
CCharacter *pTarget = apEnts[i];
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
//if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL))
|
|
|
|
if((pTarget == this || !CanCollide(pTarget->GetPlayer()->GetCID())))
|
2008-07-06 11:21:21 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// set his velocity to fast upward (for now)
|
2011-01-23 16:58:28 +00:00
|
|
|
if(length(pTarget->m_Pos-ProjStartPos) > 0.0f)
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateHammerHit(pTarget->m_Pos-normalize(pTarget->m_Pos-ProjStartPos)*m_ProximityRadius*0.5f, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2011-01-23 16:58:28 +00:00
|
|
|
else
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateHammerHit(ProjStartPos, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
vec2 Dir;
|
2011-04-10 13:07:36 +00:00
|
|
|
if (length(pTarget->m_Pos - m_Pos) > 0.0f)
|
|
|
|
Dir = normalize(pTarget->m_Pos - m_Pos);
|
|
|
|
else
|
|
|
|
Dir = vec2(0.f, -1.f);
|
2011-04-15 04:04:21 +00:00
|
|
|
/*pTarget->TakeDamage(vec2(0.f, -1.f) + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f, g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage,
|
|
|
|
m_pPlayer->GetCID(), m_ActiveWeapon);*/
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-04-15 04:04:21 +00:00
|
|
|
vec2 Temp = pTarget->m_Core.m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f;
|
2011-01-12 09:08:17 +00:00
|
|
|
if(Temp.x > 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_270) || (pTarget->m_TileIndexL == TILE_STOP && pTarget->m_TileFlagsL == ROTATION_270) || (pTarget->m_TileIndexL == TILE_STOPS && (pTarget->m_TileFlagsL == ROTATION_90 || pTarget->m_TileFlagsL ==ROTATION_270)) || (pTarget->m_TileIndexL == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_270) || (pTarget->m_TileFIndexL == TILE_STOP && pTarget->m_TileFFlagsL == ROTATION_270) || (pTarget->m_TileFIndexL == TILE_STOPS && (pTarget->m_TileFFlagsL == ROTATION_90 || pTarget->m_TileFFlagsL == ROTATION_270)) || (pTarget->m_TileFIndexL == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_270) || (pTarget->m_TileSIndexL == TILE_STOP && pTarget->m_TileSFlagsL == ROTATION_270) || (pTarget->m_TileSIndexL == TILE_STOPS && (pTarget->m_TileSFlagsL == ROTATION_90 || pTarget->m_TileSFlagsL == ROTATION_270)) || (pTarget->m_TileSIndexL == TILE_STOPA)))
|
2010-11-01 12:29:56 +00:00
|
|
|
Temp.x = 0;
|
2011-01-12 09:08:17 +00:00
|
|
|
if(Temp.x < 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_90) || (pTarget->m_TileIndexR == TILE_STOP && pTarget->m_TileFlagsR == ROTATION_90) || (pTarget->m_TileIndexR == TILE_STOPS && (pTarget->m_TileFlagsR == ROTATION_90 || pTarget->m_TileFlagsR == ROTATION_270)) || (pTarget->m_TileIndexR == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_90) || (pTarget->m_TileFIndexR == TILE_STOP && pTarget->m_TileFFlagsR == ROTATION_90) || (pTarget->m_TileFIndexR == TILE_STOPS && (pTarget->m_TileFFlagsR == ROTATION_90 || pTarget->m_TileFFlagsR == ROTATION_270)) || (pTarget->m_TileFIndexR == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_90) || (pTarget->m_TileSIndexR == TILE_STOP && pTarget->m_TileSFlagsR == ROTATION_90) || (pTarget->m_TileSIndexR == TILE_STOPS && (pTarget->m_TileSFlagsR == ROTATION_90 || pTarget->m_TileSFlagsR == ROTATION_270)) || (pTarget->m_TileSIndexR == TILE_STOPA)))
|
2010-11-01 12:29:56 +00:00
|
|
|
Temp.x = 0;
|
2011-01-12 09:08:17 +00:00
|
|
|
if(Temp.y < 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_180) || (pTarget->m_TileIndexB == TILE_STOP && pTarget->m_TileFlagsB == ROTATION_180) || (pTarget->m_TileIndexB == TILE_STOPS && (pTarget->m_TileFlagsB == ROTATION_0 || pTarget->m_TileFlagsB == ROTATION_180)) || (pTarget->m_TileIndexB == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_180) || (pTarget->m_TileFIndexB == TILE_STOP && pTarget->m_TileFFlagsB == ROTATION_180) || (pTarget->m_TileFIndexB == TILE_STOPS && (pTarget->m_TileFFlagsB == ROTATION_0 || pTarget->m_TileFFlagsB == ROTATION_180)) || (pTarget->m_TileFIndexB == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_180) || (pTarget->m_TileSIndexB == TILE_STOP && pTarget->m_TileSFlagsB == ROTATION_180) || (pTarget->m_TileSIndexB == TILE_STOPS && (pTarget->m_TileSFlagsB == ROTATION_0 || pTarget->m_TileSFlagsB == ROTATION_180)) || (pTarget->m_TileSIndexB == TILE_STOPA)))
|
2010-11-01 12:29:56 +00:00
|
|
|
Temp.y = 0;
|
2011-01-12 09:08:17 +00:00
|
|
|
if(Temp.y > 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_0) || (pTarget->m_TileIndexT == TILE_STOP && pTarget->m_TileFlagsT == ROTATION_0) || (pTarget->m_TileIndexT == TILE_STOPS && (pTarget->m_TileFlagsT == ROTATION_0 || pTarget->m_TileFlagsT == ROTATION_180)) || (pTarget->m_TileIndexT == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_0) || (pTarget->m_TileFIndexT == TILE_STOP && pTarget->m_TileFFlagsT == ROTATION_0) || (pTarget->m_TileFIndexT == TILE_STOPS && (pTarget->m_TileFFlagsT == ROTATION_0 || pTarget->m_TileFFlagsT == ROTATION_180)) || (pTarget->m_TileFIndexT == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_0) || (pTarget->m_TileSIndexT == TILE_STOP && pTarget->m_TileSFlagsT == ROTATION_0) || (pTarget->m_TileSIndexT == TILE_STOPS && (pTarget->m_TileSFlagsT == ROTATION_0 || pTarget->m_TileSFlagsT == ROTATION_180)) || (pTarget->m_TileSIndexT == TILE_STOPA)))
|
2010-11-01 12:29:56 +00:00
|
|
|
Temp.y = 0;
|
2011-01-20 14:10:32 +00:00
|
|
|
Temp -= pTarget->m_Core.m_Vel;
|
|
|
|
pTarget->TakeDamage(vec2(0.f, -1.f) + Temp, g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage,
|
2011-01-19 21:41:44 +00:00
|
|
|
m_pPlayer->GetCID(), m_ActiveWeapon);
|
2011-01-12 09:08:17 +00:00
|
|
|
pTarget->UnFreeze();
|
2010-05-29 07:25:38 +00:00
|
|
|
Hits++;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// if we Hit anything, we have to wait for the reload
|
|
|
|
if(Hits)
|
|
|
|
m_ReloadTimer = Server()->TickSpeed()/3;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case WEAPON_GUN:
|
|
|
|
{
|
2011-01-12 09:08:17 +00:00
|
|
|
CProjectile *pProj = new CProjectile
|
2011-04-09 06:41:31 +00:00
|
|
|
(
|
|
|
|
GameWorld(),
|
|
|
|
WEAPON_GUN,//Type
|
|
|
|
m_pPlayer->GetCID(),//Owner
|
|
|
|
ProjStartPos,//Pos
|
|
|
|
Direction,//Dir
|
|
|
|
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime),//Span
|
|
|
|
0,//Freeze
|
|
|
|
0,//Explosive
|
|
|
|
0,//Force
|
|
|
|
-1,//SoundImpact
|
|
|
|
WEAPON_GUN//Weapon
|
|
|
|
);
|
2010-08-24 14:32:46 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// pack the Projectile and send it to the client Directly
|
|
|
|
CNetObj_Projectile p;
|
2011-01-09 19:53:19 +00:00
|
|
|
pProj->FillInfo(&p);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
|
|
|
Msg.AddInt(1);
|
|
|
|
for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
|
|
|
|
Msg.AddInt(((int *)&p)[i]);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2008-07-06 11:21:21 +00:00
|
|
|
} break;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
{
|
2010-07-29 05:21:18 +00:00
|
|
|
/*int ShotSpread = 2;
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
|
|
|
Msg.AddInt(ShotSpread*2+1);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int i = -ShotSpread; i <= ShotSpread; ++i)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float Spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
|
|
|
|
float a = GetAngle(Direction);
|
|
|
|
a += Spreading[i+2];
|
|
|
|
float v = 1-(absolute(i)/(float)ShotSpread);
|
|
|
|
float Speed = mix((float)GameServer()->Tuning()->m_ShotgunSpeeddiff, 1.0f, v);
|
2011-01-09 19:53:19 +00:00
|
|
|
CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_SHOTGUN,
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pPlayer->GetCID(),
|
|
|
|
ProjStartPos,
|
|
|
|
vec2(cosf(a), sinf(a))*Speed,
|
2011-01-29 00:59:50 +00:00
|
|
|
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime),
|
2008-07-06 11:21:21 +00:00
|
|
|
1, 0, 0, -1, WEAPON_SHOTGUN);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// pack the Projectile and send it to the client Directly
|
|
|
|
CNetObj_Projectile p;
|
2011-01-09 19:53:19 +00:00
|
|
|
pProj->FillInfo(&p);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
|
|
|
|
Msg.AddInt(((int *)&p)[i]);
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2011-04-13 18:37:12 +00:00
|
|
|
Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID());
|
|
|
|
|
2010-07-29 05:21:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);*/
|
2011-07-25 20:16:20 +00:00
|
|
|
new CLaser(&GameServer()->m_World, m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID(), WEAPON_SHOTGUN);
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2008-07-06 11:21:21 +00:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case WEAPON_GRENADE:
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
CProjectile *pProj = new CProjectile
|
2011-04-09 06:41:31 +00:00
|
|
|
(
|
|
|
|
GameWorld(),
|
|
|
|
WEAPON_GRENADE,//Type
|
|
|
|
m_pPlayer->GetCID(),//Owner
|
|
|
|
ProjStartPos,//Pos
|
|
|
|
Direction,//Dir
|
|
|
|
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime),//Span
|
|
|
|
0,//Freeze
|
|
|
|
true,//Explosive
|
|
|
|
0,//Force
|
|
|
|
SOUND_GRENADE_EXPLODE,//SoundImpact
|
|
|
|
WEAPON_GRENADE//Weapon
|
|
|
|
);//SoundImpact
|
2010-08-24 14:32:46 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// pack the Projectile and send it to the client Directly
|
|
|
|
CNetObj_Projectile p;
|
|
|
|
pProj->FillInfo(&p);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
|
|
|
Msg.AddInt(1);
|
|
|
|
for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
|
|
|
|
Msg.AddInt(((int *)&p)[i]);
|
|
|
|
Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2008-07-06 11:21:21 +00:00
|
|
|
} break;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
case WEAPON_RIFLE:
|
|
|
|
{
|
2011-07-25 20:16:20 +00:00
|
|
|
new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID(), WEAPON_RIFLE);
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2008-07-06 11:21:21 +00:00
|
|
|
} break;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-10-08 18:36:30 +00:00
|
|
|
case WEAPON_NINJA:
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
// reset Hit objects
|
|
|
|
m_NumObjectsHit = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Ninja.m_ActivationDir = Direction;
|
|
|
|
m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
|
2011-03-13 18:00:00 +00:00
|
|
|
m_Ninja.m_OldVelAmount = length(m_Core.m_Vel);
|
2010-08-24 14:32:46 +00:00
|
|
|
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2011-01-29 00:59:50 +00:00
|
|
|
} break;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_AttackTick = Server()->Tick();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-04-13 23:27:49 +00:00
|
|
|
/*if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // -1 == unlimited
|
|
|
|
m_aWeapons[m_ActiveWeapon].m_Ammo--;*/
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!m_ReloadTimer)
|
|
|
|
m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::HandleWeapons()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
//ninja
|
|
|
|
HandleNinja();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(m_PainSoundTimer > 0)
|
2010-11-04 23:52:37 +00:00
|
|
|
m_PainSoundTimer--;
|
2008-10-08 18:36:30 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
// check reload timer
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_ReloadTimer)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ReloadTimer--;
|
|
|
|
return;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
// fire Weapon, if wanted
|
|
|
|
FireWeapon();
|
2011-01-29 00:59:50 +00:00
|
|
|
/*
|
2008-07-06 11:21:21 +00:00
|
|
|
// ammo regen
|
2010-05-29 07:25:38 +00:00
|
|
|
int AmmoRegenTime = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Ammoregentime;
|
|
|
|
if(AmmoRegenTime)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
|
|
|
// If equipped and not active, regen ammo?
|
2010-05-29 07:25:38 +00:00
|
|
|
if (m_ReloadTimer <= 0)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if (m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart < 0)
|
|
|
|
m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = Server()->Tick();
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if ((Server()->Tick() - m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart) >= AmmoRegenTime * Server()->TickSpeed() / 1000)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
|
|
|
// Add some ammo
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aWeapons[m_ActiveWeapon].m_Ammo = min(m_aWeapons[m_ActiveWeapon].m_Ammo + 1, 10);
|
|
|
|
m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = -1;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = -1;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
2011-04-13 23:27:49 +00:00
|
|
|
}*/
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CCharacter::GiveWeapon(int Weapon, int Ammo)
|
|
|
|
{
|
|
|
|
if(m_aWeapons[Weapon].m_Ammo < g_pData->m_Weapons.m_aId[Weapon].m_Maxammo || !m_aWeapons[Weapon].m_Got)
|
2011-04-13 18:37:12 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aWeapons[Weapon].m_Got = true;
|
2011-04-09 06:41:31 +00:00
|
|
|
if(!m_FreezeTime)
|
|
|
|
m_aWeapons[Weapon].m_Ammo = min(g_pData->m_Weapons.m_aId[Weapon].m_Maxammo, Ammo);
|
2010-05-29 07:25:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCharacter::GiveNinja()
|
|
|
|
{
|
|
|
|
m_Ninja.m_ActivationTick = Server()->Tick();
|
|
|
|
m_aWeapons[WEAPON_NINJA].m_Got = true;
|
2011-04-09 06:41:31 +00:00
|
|
|
if (!m_FreezeTime)
|
|
|
|
m_aWeapons[WEAPON_NINJA].m_Ammo = -1;
|
2011-06-26 11:17:56 +00:00
|
|
|
if (m_ActiveWeapon != WEAPON_NINJA)
|
2011-08-13 00:11:06 +00:00
|
|
|
m_LastWeapon = m_ActiveWeapon;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ActiveWeapon = WEAPON_NINJA;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(!m_aWeapons[WEAPON_NINJA].m_Got)
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_PICKUP_NINJA, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::SetEmote(int Emote, int Tick)
|
|
|
|
{
|
|
|
|
m_EmoteType = Emote;
|
|
|
|
m_EmoteStop = Tick;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
|
|
|
// check for changes
|
2010-05-29 07:25:38 +00:00
|
|
|
if(mem_comp(&m_Input, pNewInput, sizeof(CNetObj_PlayerInput)) != 0)
|
|
|
|
m_LastAction = Server()->Tick();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
// copy new input
|
2010-05-29 07:25:38 +00:00
|
|
|
mem_copy(&m_Input, pNewInput, sizeof(m_Input));
|
|
|
|
m_NumInputs++;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-07-06 11:21:21 +00:00
|
|
|
// or are not allowed to aim in the center
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Input.m_TargetX == 0 && m_Input.m_TargetY == 0)
|
2011-04-13 18:37:12 +00:00
|
|
|
m_Input.m_TargetY = -1;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
|
|
|
mem_copy(&m_LatestInput, pNewInput, sizeof(m_LatestInput));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-03 11:50:38 +00:00
|
|
|
if(m_NumInputs > 2 && m_pPlayer->GetTeam() != TEAM_SPECTATORS)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
HandleWeaponSwitch();
|
|
|
|
FireWeapon();
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2011-06-09 20:30:03 +00:00
|
|
|
void CCharacter::ResetInput()
|
|
|
|
{
|
|
|
|
m_Input.m_Direction = 0;
|
|
|
|
m_Input.m_Hook = 0;
|
|
|
|
// simulate releasing the fire button
|
|
|
|
if((m_Input.m_Fire&1) != 0)
|
|
|
|
m_Input.m_Fire++;
|
|
|
|
m_Input.m_Fire &= INPUT_STATE_MASK;
|
|
|
|
m_Input.m_Jump = 0;
|
|
|
|
m_LatestPrevInput = m_LatestInput = m_Input;
|
|
|
|
}
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
void CCharacter::Tick()
|
2010-09-17 11:26:06 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
/*if(m_pPlayer->m_ForceBalanced)
|
|
|
|
{
|
|
|
|
char Buf[128];
|
|
|
|
str_format(Buf, sizeof(Buf), "You were moved to %s due to team balancing", GameServer()->m_pController->GetTeamName(m_pPlayer->GetTeam()));
|
|
|
|
GameServer()->SendBroadcast(Buf, m_pPlayer->GetCID());
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_pPlayer->m_ForceBalanced = false;
|
|
|
|
}*/
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
DDRaceTick();
|
2010-08-28 20:53:42 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Core.m_Input = m_Input;
|
|
|
|
m_Core.Tick(true);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
/*// handle death-tiles and leaving gamelayer
|
2011-01-29 00:59:50 +00:00
|
|
|
if(GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameLayerClipped(m_Pos))
|
|
|
|
{
|
|
|
|
Die(m_pPlayer->GetCID(), WEAPON_WORLD);
|
2011-04-09 06:41:31 +00:00
|
|
|
}*/
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// handle Weapons
|
|
|
|
HandleWeapons();
|
2010-08-28 20:53:42 +00:00
|
|
|
|
2011-01-29 23:58:47 +00:00
|
|
|
DDRacePostCoreTick();
|
2010-08-28 20:53:42 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// Previnput
|
|
|
|
m_PrevInput = m_Input;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_PrevPos = m_Core.m_Pos;
|
|
|
|
return;
|
|
|
|
}
|
2010-08-28 20:53:42 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
void CCharacter::TickDefered()
|
|
|
|
{
|
|
|
|
// advance the dummy
|
|
|
|
{
|
|
|
|
CWorldCore TempWorld;
|
|
|
|
m_ReckoningCore.Init(&TempWorld, GameServer()->Collision(), &((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core);
|
2011-09-01 18:29:08 +00:00
|
|
|
m_ReckoningCore.m_Id = m_pPlayer->GetCID();
|
2011-01-29 00:59:50 +00:00
|
|
|
m_ReckoningCore.Tick(false);
|
|
|
|
m_ReckoningCore.Move();
|
|
|
|
m_ReckoningCore.Quantize();
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
//lastsentcore
|
|
|
|
vec2 StartPos = m_Core.m_Pos;
|
|
|
|
vec2 StartVel = m_Core.m_Vel;
|
|
|
|
bool StuckBefore = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-09-01 18:29:08 +00:00
|
|
|
m_Core.m_Id = m_pPlayer->GetCID();
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Core.Move();
|
|
|
|
bool StuckAfterMove = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
|
|
|
|
m_Core.Quantize();
|
|
|
|
bool StuckAfterQuant = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
|
|
|
|
m_Pos = m_Core.m_Pos;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(!StuckBefore && (StuckAfterMove || StuckAfterQuant))
|
|
|
|
{
|
|
|
|
// Hackish solution to get rid of strict-aliasing warning
|
|
|
|
union
|
2010-08-28 20:53:42 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
float f;
|
|
|
|
unsigned u;
|
|
|
|
}StartPosX, StartPosY, StartVelX, StartVelY;
|
|
|
|
|
|
|
|
StartPosX.f = StartPos.x;
|
|
|
|
StartPosY.f = StartPos.y;
|
|
|
|
StartVelX.f = StartVel.x;
|
|
|
|
StartVelY.f = StartVel.y;
|
|
|
|
|
|
|
|
char aBuf[256];
|
2011-04-13 18:37:12 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x",
|
2011-01-29 00:59:50 +00:00
|
|
|
StuckBefore,
|
|
|
|
StuckAfterMove,
|
|
|
|
StuckAfterQuant,
|
|
|
|
StartPos.x, StartPos.y,
|
|
|
|
StartVel.x, StartVel.y,
|
|
|
|
StartPosX.u, StartPosY.u,
|
|
|
|
StartVelX.u, StartVelY.u);
|
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Events = m_Core.m_TriggeredEvents;
|
|
|
|
//int Mask = CmaskAllExceptOne(m_pPlayer->GetCID());
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-02-05 04:33:11 +00:00
|
|
|
if(Events&COREEVENT_GROUND_JUMP) GameServer()->CreateSound(m_Pos, SOUND_PLAYER_JUMP, Teams()->TeamMask(Team(), m_pPlayer->GetCID()));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-09-02 18:04:18 +00:00
|
|
|
if(Events&COREEVENT_HOOK_ATTACH_PLAYER) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_PLAYER, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
|
|
|
if(Events&COREEVENT_HOOK_ATTACH_GROUND) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_GROUND, Teams()->TeamMask(Team(), m_pPlayer->GetCID(), m_pPlayer->GetCID()));
|
|
|
|
if(Events&COREEVENT_HOOK_HIT_NOHOOK) GameServer()->CreateSound(m_Pos, SOUND_HOOK_NOATTACH, Teams()->TeamMask(Team(), m_pPlayer->GetCID(), m_pPlayer->GetCID()));
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(m_pPlayer->GetTeam() == TEAM_SPECTATORS)
|
|
|
|
{
|
|
|
|
m_Pos.x = m_Input.m_TargetX;
|
|
|
|
m_Pos.y = m_Input.m_TargetY;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// update the m_SendCore if needed
|
|
|
|
{
|
|
|
|
CNetObj_Character Predicted;
|
|
|
|
CNetObj_Character Current;
|
|
|
|
mem_zero(&Predicted, sizeof(Predicted));
|
|
|
|
mem_zero(&Current, sizeof(Current));
|
|
|
|
m_ReckoningCore.Write(&Predicted);
|
|
|
|
m_Core.Write(&Current);
|
|
|
|
|
|
|
|
// only allow dead reackoning for a top of 3 seconds
|
|
|
|
if(m_Core.m_pReset || m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0)
|
|
|
|
{
|
|
|
|
m_ReckoningTick = Server()->Tick();
|
|
|
|
m_SendCore = m_Core;
|
|
|
|
m_ReckoningCore = m_Core;
|
|
|
|
m_Core.m_pReset = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CCharacter::IncreaseHealth(int Amount)
|
|
|
|
{
|
|
|
|
if(m_Health >= 10)
|
|
|
|
return false;
|
|
|
|
m_Health = clamp(m_Health+Amount, 0, 10);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CCharacter::IncreaseArmor(int Amount)
|
|
|
|
{
|
|
|
|
if(m_Armor >= 10)
|
|
|
|
return false;
|
|
|
|
m_Armor = clamp(m_Armor+Amount, 0, 10);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCharacter::Die(int Killer, int Weapon)
|
|
|
|
{
|
2011-03-26 21:38:05 +00:00
|
|
|
// we got to wait 0.5 secs before respawning
|
|
|
|
m_pPlayer->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
|
2011-01-29 00:59:50 +00:00
|
|
|
int ModeSpecial = GameServer()->m_pController->OnCharacterDeath(this, GameServer()->m_apPlayers[Killer], Weapon);
|
|
|
|
|
|
|
|
char aBuf[256];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "kill killer='%d:%s' victim='%d:%s' weapon=%d special=%d",
|
|
|
|
Killer, Server()->ClientName(Killer),
|
|
|
|
m_pPlayer->GetCID(), Server()->ClientName(m_pPlayer->GetCID()), Weapon, ModeSpecial);
|
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
|
|
|
|
|
|
|
// send the kill message
|
|
|
|
CNetMsg_Sv_KillMsg Msg;
|
|
|
|
Msg.m_Killer = Killer;
|
|
|
|
Msg.m_Victim = m_pPlayer->GetCID();
|
|
|
|
Msg.m_Weapon = Weapon;
|
|
|
|
Msg.m_ModeSpecial = ModeSpecial;
|
|
|
|
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1);
|
|
|
|
|
|
|
|
// a nice sound
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_DIE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// this is for auto respawn after 3 secs
|
|
|
|
m_pPlayer->m_DieTick = Server()->Tick();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Alive = false;
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_World.RemoveEntity(this);
|
2011-01-29 00:59:50 +00:00
|
|
|
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateDeath(m_Pos, m_pPlayer->GetCID(), Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2011-06-06 19:24:27 +00:00
|
|
|
if(!m_pPlayer->m_InfoSaved)
|
|
|
|
((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.SetForceCharacterTeam(m_pPlayer->GetCID(), 0);
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2011-04-09 06:41:31 +00:00
|
|
|
/*m_Core.m_Vel += Force;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(GameServer()->m_pController->IsFriendlyFire(m_pPlayer->GetCID(), From) && !g_Config.m_SvTeamdamage)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// m_pPlayer only inflicts half damage on self
|
|
|
|
if(From == m_pPlayer->GetCID())
|
|
|
|
Dmg = max(1, Dmg/2);
|
|
|
|
|
|
|
|
m_DamageTaken++;
|
|
|
|
|
|
|
|
// create healthmod indicator
|
|
|
|
if(Server()->Tick() < m_DamageTakenTick+25)
|
|
|
|
{
|
|
|
|
// make sure that the damage indicators doesn't group together
|
|
|
|
GameServer()->CreateDamageInd(m_Pos, m_DamageTaken*0.25f, Dmg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_DamageTaken = 0;
|
|
|
|
GameServer()->CreateDamageInd(m_Pos, 0, Dmg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Dmg)
|
|
|
|
{
|
|
|
|
if(m_Armor)
|
|
|
|
{
|
|
|
|
if(Dmg > 1)
|
|
|
|
{
|
|
|
|
m_Health--;
|
|
|
|
Dmg--;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(Dmg > m_Armor)
|
|
|
|
{
|
|
|
|
Dmg -= m_Armor;
|
|
|
|
m_Armor = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_Armor -= Dmg;
|
|
|
|
Dmg = 0;
|
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Health -= Dmg;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_DamageTakenTick = Server()->Tick();
|
|
|
|
|
|
|
|
// do damage Hit sound
|
|
|
|
if(From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From])
|
2011-06-02 09:44:35 +00:00
|
|
|
{
|
|
|
|
int Mask = CmaskOne(From);
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
|
|
|
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS && GameServer()->m_apPlayers[i]->m_SpectatorID == From)
|
|
|
|
Mask |= CmaskOne(i);
|
|
|
|
}
|
|
|
|
GameServer()->CreateSound(GameServer()->m_apPlayers[From]->m_ViewPos, SOUND_HIT, Mask);
|
|
|
|
}
|
2011-01-29 00:59:50 +00:00
|
|
|
|
|
|
|
// check for death
|
|
|
|
if(m_Health <= 0)
|
|
|
|
{
|
|
|
|
Die(From, Weapon);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// set attacker's face to happy (taunt!)
|
|
|
|
if (From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From])
|
|
|
|
{
|
|
|
|
CCharacter *pChr = GameServer()->m_apPlayers[From]->GetCharacter();
|
|
|
|
if (pChr)
|
|
|
|
{
|
|
|
|
pChr->m_EmoteType = EMOTE_HAPPY;
|
|
|
|
pChr->m_EmoteStop = Server()->Tick() + Server()->TickSpeed();
|
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Dmg > 2)
|
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG);
|
|
|
|
else
|
2011-04-09 06:41:31 +00:00
|
|
|
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_SHORT);*/
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_EmoteType = EMOTE_PAIN;
|
|
|
|
m_EmoteStop = Server()->Tick() + 500 * Server()->TickSpeed() / 1000;
|
2008-07-06 11:21:21 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
vec2 Temp = m_Core.m_Vel + Force;
|
|
|
|
if(Temp.x > 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_270) || (m_TileIndexL == TILE_STOP && m_TileFlagsL == ROTATION_270) || (m_TileIndexL == TILE_STOPS && (m_TileFlagsL == ROTATION_90 || m_TileFlagsL ==ROTATION_270)) || (m_TileIndexL == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_270) || (m_TileFIndexL == TILE_STOP && m_TileFFlagsL == ROTATION_270) || (m_TileFIndexL == TILE_STOPS && (m_TileFFlagsL == ROTATION_90 || m_TileFFlagsL == ROTATION_270)) || (m_TileFIndexL == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_270) || (m_TileSIndexL == TILE_STOP && m_TileSFlagsL == ROTATION_270) || (m_TileSIndexL == TILE_STOPS && (m_TileSFlagsL == ROTATION_90 || m_TileSFlagsL == ROTATION_270)) || (m_TileSIndexL == TILE_STOPA)))
|
|
|
|
Temp.x = 0;
|
|
|
|
if(Temp.x < 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_90) || (m_TileIndexR == TILE_STOP && m_TileFlagsR == ROTATION_90) || (m_TileIndexR == TILE_STOPS && (m_TileFlagsR == ROTATION_90 || m_TileFlagsR == ROTATION_270)) || (m_TileIndexR == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_90) || (m_TileFIndexR == TILE_STOP && m_TileFFlagsR == ROTATION_90) || (m_TileFIndexR == TILE_STOPS && (m_TileFFlagsR == ROTATION_90 || m_TileFFlagsR == ROTATION_270)) || (m_TileFIndexR == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_90) || (m_TileSIndexR == TILE_STOP && m_TileSFlagsR == ROTATION_90) || (m_TileSIndexR == TILE_STOPS && (m_TileSFlagsR == ROTATION_90 || m_TileSFlagsR == ROTATION_270)) || (m_TileSIndexR == TILE_STOPA)))
|
|
|
|
Temp.x = 0;
|
|
|
|
if(Temp.y < 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_180) || (m_TileIndexB == TILE_STOP && m_TileFlagsB == ROTATION_180) || (m_TileIndexB == TILE_STOPS && (m_TileFlagsB == ROTATION_0 || m_TileFlagsB == ROTATION_180)) || (m_TileIndexB == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_180) || (m_TileFIndexB == TILE_STOP && m_TileFFlagsB == ROTATION_180) || (m_TileFIndexB == TILE_STOPS && (m_TileFFlagsB == ROTATION_0 || m_TileFFlagsB == ROTATION_180)) || (m_TileFIndexB == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_180) || (m_TileSIndexB == TILE_STOP && m_TileSFlagsB == ROTATION_180) || (m_TileSIndexB == TILE_STOPS && (m_TileSFlagsB == ROTATION_0 || m_TileSFlagsB == ROTATION_180)) || (m_TileSIndexB == TILE_STOPA)))
|
|
|
|
Temp.y = 0;
|
|
|
|
if(Temp.y > 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_0) || (m_TileIndexT == TILE_STOP && m_TileFlagsT == ROTATION_0) || (m_TileIndexT == TILE_STOPS && (m_TileFlagsT == ROTATION_0 || m_TileFlagsT == ROTATION_180)) || (m_TileIndexT == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_0) || (m_TileFIndexT == TILE_STOP && m_TileFFlagsT == ROTATION_0) || (m_TileFIndexT == TILE_STOPS && (m_TileFFlagsT == ROTATION_0 || m_TileFFlagsT == ROTATION_180)) || (m_TileFIndexT == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_0) || (m_TileSIndexT == TILE_STOP && m_TileSFlagsT == ROTATION_0) || (m_TileSIndexT == TILE_STOPS && (m_TileSFlagsT == ROTATION_0 || m_TileSFlagsT == ROTATION_180)) || (m_TileSIndexT == TILE_STOPA)))
|
|
|
|
Temp.y = 0;
|
|
|
|
m_Core.m_Vel = Temp;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCharacter::Snap(int SnappingClient)
|
|
|
|
{
|
|
|
|
if(NetworkClipped(SnappingClient))
|
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
CCharacter* SnapChar = GameServer()->GetPlayerChar(SnappingClient);
|
2011-04-09 06:41:31 +00:00
|
|
|
if(SnapChar && !SnapChar->m_Super &&
|
2011-01-29 00:59:50 +00:00
|
|
|
GameServer()->m_apPlayers[SnappingClient]->GetTeam() != -1 &&
|
2011-04-09 06:41:31 +00:00
|
|
|
!CanCollide(SnappingClient) &&
|
|
|
|
(!GameServer()->m_apPlayers[SnappingClient]->m_IsUsingDDRaceClient ||
|
|
|
|
(GameServer()->m_apPlayers[SnappingClient]->m_IsUsingDDRaceClient &&
|
|
|
|
!GameServer()->m_apPlayers[SnappingClient]->m_ShowOthers
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return;
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
CNetObj_Character *pCharacter = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, m_pPlayer->GetCID(), sizeof(CNetObj_Character)));
|
|
|
|
if(!pCharacter)
|
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// write down the m_Core
|
|
|
|
if(!m_ReckoningTick || GameServer()->m_World.m_Paused)
|
|
|
|
{
|
|
|
|
// no dead reckoning when paused because the client doesn't know
|
|
|
|
// how far to perform the reckoning
|
|
|
|
pCharacter->m_Tick = 0;
|
|
|
|
m_Core.Write(pCharacter);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pCharacter->m_Tick = m_ReckoningTick;
|
|
|
|
m_SendCore.Write(pCharacter);
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
// set emote
|
|
|
|
if (m_EmoteStop < Server()->Tick())
|
|
|
|
{
|
|
|
|
m_EmoteType = m_DefEmote;
|
|
|
|
m_EmoteStop = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pCharacter->m_Emote = m_EmoteType;
|
|
|
|
|
|
|
|
pCharacter->m_AmmoCount = 0;
|
|
|
|
pCharacter->m_Health = 0;
|
|
|
|
pCharacter->m_Armor = 0;
|
2011-02-05 02:28:05 +00:00
|
|
|
|
|
|
|
if (m_DeepFreeze)
|
|
|
|
{
|
2011-08-14 15:23:57 +00:00
|
|
|
if (pCharacter->m_Emote == EMOTE_NORMAL)
|
|
|
|
pCharacter->m_Emote = EMOTE_PAIN;
|
2011-02-05 02:28:05 +00:00
|
|
|
pCharacter->m_Weapon = WEAPON_NINJA;
|
|
|
|
pCharacter->m_AmmoCount = 0;
|
|
|
|
}
|
|
|
|
else if (m_FreezeTime > 0 || m_FreezeTime == -1)
|
2011-01-29 00:59:50 +00:00
|
|
|
{
|
2011-08-14 15:23:57 +00:00
|
|
|
if (pCharacter->m_Emote == EMOTE_NORMAL)
|
|
|
|
pCharacter->m_Emote = EMOTE_BLINK;
|
2011-01-29 00:59:50 +00:00
|
|
|
pCharacter->m_Weapon = WEAPON_NINJA;
|
|
|
|
pCharacter->m_AmmoCount = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pCharacter->m_Weapon = m_ActiveWeapon;
|
|
|
|
pCharacter->m_AttackTick = m_AttackTick;
|
|
|
|
|
|
|
|
pCharacter->m_Direction = m_Input.m_Direction;
|
|
|
|
|
2011-06-19 09:28:39 +00:00
|
|
|
if(m_pPlayer->GetCID() == SnappingClient || SnappingClient == -1 ||
|
|
|
|
(!g_Config.m_SvStrictSpectateMode && m_pPlayer->GetCID() == GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID))
|
2011-01-29 00:59:50 +00:00
|
|
|
{
|
|
|
|
pCharacter->m_Health = m_Health;
|
|
|
|
pCharacter->m_Armor = m_Armor;
|
|
|
|
if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0)
|
2011-04-09 06:41:31 +00:00
|
|
|
//pCharacter->m_AmmoCount = m_aWeapons[m_ActiveWeapon].m_Ammo;
|
2011-01-29 00:59:50 +00:00
|
|
|
pCharacter->m_AmmoCount = (!m_FreezeTime)?m_aWeapons[m_ActiveWeapon].m_Ammo:0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(pCharacter->m_Emote == EMOTE_NORMAL)
|
|
|
|
{
|
|
|
|
if(250 - ((Server()->Tick() - m_LastAction)%(250)) < 5)
|
|
|
|
pCharacter->m_Emote = EMOTE_BLINK;
|
|
|
|
}
|
|
|
|
|
2011-03-01 17:31:20 +00:00
|
|
|
pCharacter->m_PlayerFlags = GetPlayer()->m_PlayerFlags;
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
2011-04-09 06:41:31 +00:00
|
|
|
|
|
|
|
// DDRace
|
|
|
|
|
2011-02-13 05:35:13 +00:00
|
|
|
bool CCharacter::CanCollide(int ClientID)
|
2011-01-29 00:59:50 +00:00
|
|
|
{
|
2011-02-13 05:35:13 +00:00
|
|
|
return Teams()->m_Core.CanCollide(GetPlayer()->GetCID(), ClientID);
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
2011-02-13 05:35:13 +00:00
|
|
|
bool CCharacter::SameTeam(int ClientID)
|
2011-01-29 00:59:50 +00:00
|
|
|
{
|
2011-02-13 05:35:13 +00:00
|
|
|
return Teams()->m_Core.SameTeam(GetPlayer()->GetCID(), ClientID);
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
|
|
|
|
2010-09-17 11:26:06 +00:00
|
|
|
int CCharacter::Team()
|
|
|
|
{
|
2011-07-21 22:01:12 +00:00
|
|
|
return Teams()->m_Core.Team(m_pPlayer->GetCID());
|
2010-08-28 20:53:42 +00:00
|
|
|
}
|
|
|
|
|
2010-09-17 11:26:06 +00:00
|
|
|
CGameTeams* CCharacter::Teams()
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
return &((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams;
|
2010-09-08 16:22:11 +00:00
|
|
|
}
|
2011-06-05 11:56:04 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
void CCharacter::HandleBroadcast()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2010-11-30 02:24:15 +00:00
|
|
|
char aBroadcast[128];
|
2010-10-08 13:33:42 +00:00
|
|
|
m_Time = (float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed());
|
|
|
|
CPlayerData *pData = GameServer()->Score()->PlayerData(m_pPlayer->GetCID());
|
2011-06-05 11:56:04 +00:00
|
|
|
|
|
|
|
if((m_DDRaceState == DDRACE_STARTED && Server()->Tick() - m_RefreshTime >= Server()->TickSpeed()) &&
|
|
|
|
m_CpActive != -1 && m_CpTick > Server()->Tick() && !m_pPlayer->m_IsUsingDDRaceClient &&
|
|
|
|
pData->m_BestTime && pData->m_aBestCpTime[m_CpActive] != 0)
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
2011-06-05 11:56:04 +00:00
|
|
|
float Diff = m_CpCurrent[m_CpActive] - pData->m_aBestCpTime[m_CpActive];
|
|
|
|
str_format(aBroadcast, sizeof(aBroadcast), "Checkpoint | Diff : %+5.2f", Diff);
|
|
|
|
GameServer()->SendBroadcast(aBroadcast, m_pPlayer->GetCID());
|
|
|
|
m_LastBroadcast = Server()->Tick();
|
2010-08-10 04:28:17 +00:00
|
|
|
}
|
2011-06-05 11:56:04 +00:00
|
|
|
m_RefreshTime = Server()->Tick();
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
2011-01-21 09:44:29 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
void CCharacter::HandleSkippableTiles(int Index)
|
|
|
|
{
|
2011-01-29 23:58:47 +00:00
|
|
|
|
|
|
|
// handle death-tiles and leaving gamelayer
|
|
|
|
if((GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetFCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetFCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetFCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
|
|
|
GameLayerClipped(m_Pos)) &&
|
2011-08-31 21:36:41 +00:00
|
|
|
!m_Super && !(Team() && Teams()->TeeFinished(m_pPlayer->GetCID())))
|
2011-01-29 23:58:47 +00:00
|
|
|
{
|
|
|
|
Die(m_pPlayer->GetCID(), WEAPON_WORLD);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Index < 0)
|
|
|
|
return;
|
|
|
|
|
2011-01-21 09:44:29 +00:00
|
|
|
// handle speedup tiles
|
2011-01-29 00:59:50 +00:00
|
|
|
if(GameServer()->Collision()->IsSpeedup(Index))
|
2010-06-11 09:39:32 +00:00
|
|
|
{
|
2011-01-21 09:44:29 +00:00
|
|
|
vec2 Direction, MaxVel, TempVel = m_Core.m_Vel;
|
|
|
|
int Force, MaxSpeed = 0;
|
|
|
|
float TeeAngle, SpeederAngle, DiffAngle, SpeedLeft, TeeSpeed;
|
2011-01-29 00:59:50 +00:00
|
|
|
GameServer()->Collision()->GetSpeedup(Index, &Direction, &Force, &MaxSpeed);
|
2011-01-21 09:44:29 +00:00
|
|
|
if(Force == 255 && MaxSpeed)
|
|
|
|
{
|
|
|
|
m_Core.m_Vel = Direction * (MaxSpeed/5);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(MaxSpeed > 0 && MaxSpeed < 5) MaxSpeed = 5;
|
|
|
|
//dbg_msg("speedup tile start","Direction %f %f, Force %d, Max Speed %d", (Direction).x,(Direction).y, Force, MaxSpeed);
|
|
|
|
if(MaxSpeed > 0)
|
|
|
|
{
|
|
|
|
if(Direction.x > 0.0000001f)
|
|
|
|
SpeederAngle = -atan(Direction.y / Direction.x);
|
|
|
|
else if(Direction.x < 0.0000001f)
|
|
|
|
SpeederAngle = atan(Direction.y / Direction.x) + 2.0f * asin(1.0f);
|
|
|
|
else if(Direction.y > 0.0000001f)
|
|
|
|
SpeederAngle = asin(1.0f);
|
|
|
|
else
|
|
|
|
SpeederAngle = asin(-1.0f);
|
|
|
|
|
|
|
|
if(SpeederAngle < 0)
|
|
|
|
SpeederAngle = 4.0f * asin(1.0f) + SpeederAngle;
|
|
|
|
|
|
|
|
if(TempVel.x > 0.0000001f)
|
|
|
|
TeeAngle = -atan(TempVel.y / TempVel.x);
|
|
|
|
else if(TempVel.x < 0.0000001f)
|
|
|
|
TeeAngle = atan(TempVel.y / TempVel.x) + 2.0f * asin(1.0f);
|
|
|
|
else if(TempVel.y > 0.0000001f)
|
|
|
|
TeeAngle = asin(1.0f);
|
|
|
|
else
|
|
|
|
TeeAngle = asin(-1.0f);
|
|
|
|
|
|
|
|
if(TeeAngle < 0)
|
|
|
|
TeeAngle = 4.0f * asin(1.0f) + TeeAngle;
|
|
|
|
|
|
|
|
TeeSpeed = sqrt(pow(TempVel.x, 2) + pow(TempVel.y, 2));
|
|
|
|
|
|
|
|
DiffAngle = SpeederAngle - TeeAngle;
|
|
|
|
SpeedLeft = MaxSpeed / 5.0f - cos(DiffAngle) * TeeSpeed;
|
|
|
|
//dbg_msg("speedup tile debug","MaxSpeed %i, TeeSpeed %f, SpeedLeft %f, SpeederAngle %f, TeeAngle %f", MaxSpeed, TeeSpeed, SpeedLeft, SpeederAngle, TeeAngle);
|
|
|
|
if(abs(SpeedLeft) > Force && SpeedLeft > 0.0000001f)
|
|
|
|
TempVel += Direction * Force;
|
|
|
|
else if(abs(SpeedLeft) > Force)
|
|
|
|
TempVel += Direction * -Force;
|
|
|
|
else
|
|
|
|
TempVel += Direction * SpeedLeft;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
TempVel += Direction * Force;
|
|
|
|
|
|
|
|
if(TempVel.x > 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_270) || (m_TileIndexL == TILE_STOP && m_TileFlagsL == ROTATION_270) || (m_TileIndexL == TILE_STOPS && (m_TileFlagsL == ROTATION_90 || m_TileFlagsL ==ROTATION_270)) || (m_TileIndexL == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_270) || (m_TileFIndexL == TILE_STOP && m_TileFFlagsL == ROTATION_270) || (m_TileFIndexL == TILE_STOPS && (m_TileFFlagsL == ROTATION_90 || m_TileFFlagsL == ROTATION_270)) || (m_TileFIndexL == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_270) || (m_TileSIndexL == TILE_STOP && m_TileSFlagsL == ROTATION_270) || (m_TileSIndexL == TILE_STOPS && (m_TileSFlagsL == ROTATION_90 || m_TileSFlagsL == ROTATION_270)) || (m_TileSIndexL == TILE_STOPA)))
|
|
|
|
TempVel.x = 0;
|
|
|
|
if(TempVel.x < 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_90) || (m_TileIndexR == TILE_STOP && m_TileFlagsR == ROTATION_90) || (m_TileIndexR == TILE_STOPS && (m_TileFlagsR == ROTATION_90 || m_TileFlagsR == ROTATION_270)) || (m_TileIndexR == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_90) || (m_TileFIndexR == TILE_STOP && m_TileFFlagsR == ROTATION_90) || (m_TileFIndexR == TILE_STOPS && (m_TileFFlagsR == ROTATION_90 || m_TileFFlagsR == ROTATION_270)) || (m_TileFIndexR == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_90) || (m_TileSIndexR == TILE_STOP && m_TileSFlagsR == ROTATION_90) || (m_TileSIndexR == TILE_STOPS && (m_TileSFlagsR == ROTATION_90 || m_TileSFlagsR == ROTATION_270)) || (m_TileSIndexR == TILE_STOPA)))
|
|
|
|
TempVel.x = 0;
|
|
|
|
if(TempVel.y < 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_180) || (m_TileIndexB == TILE_STOP && m_TileFlagsB == ROTATION_180) || (m_TileIndexB == TILE_STOPS && (m_TileFlagsB == ROTATION_0 || m_TileFlagsB == ROTATION_180)) || (m_TileIndexB == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_180) || (m_TileFIndexB == TILE_STOP && m_TileFFlagsB == ROTATION_180) || (m_TileFIndexB == TILE_STOPS && (m_TileFFlagsB == ROTATION_0 || m_TileFFlagsB == ROTATION_180)) || (m_TileFIndexB == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_180) || (m_TileSIndexB == TILE_STOP && m_TileSFlagsB == ROTATION_180) || (m_TileSIndexB == TILE_STOPS && (m_TileSFlagsB == ROTATION_0 || m_TileSFlagsB == ROTATION_180)) || (m_TileSIndexB == TILE_STOPA)))
|
|
|
|
TempVel.y = 0;
|
|
|
|
if(TempVel.y > 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_0) || (m_TileIndexT == TILE_STOP && m_TileFlagsT == ROTATION_0) || (m_TileIndexT == TILE_STOPS && (m_TileFlagsT == ROTATION_0 || m_TileFlagsT == ROTATION_180)) || (m_TileIndexT == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_0) || (m_TileFIndexT == TILE_STOP && m_TileFFlagsT == ROTATION_0) || (m_TileFIndexT == TILE_STOPS && (m_TileFFlagsT == ROTATION_0 || m_TileFFlagsT == ROTATION_180)) || (m_TileFIndexT == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_0) || (m_TileSIndexT == TILE_STOP && m_TileSFlagsT == ROTATION_0) || (m_TileSIndexT == TILE_STOPS && (m_TileSFlagsT == ROTATION_0 || m_TileSFlagsT == ROTATION_180)) || (m_TileSIndexT == TILE_STOPA)))
|
|
|
|
TempVel.y = 0;
|
|
|
|
m_Core.m_Vel = TempVel;
|
|
|
|
//dbg_msg("speedup tile end","(Direction*Force) %f %f m_Core.m_Vel%f %f",(Direction*Force).x,(Direction*Force).y,m_Core.m_Vel.x,m_Core.m_Vel.y);
|
|
|
|
//dbg_msg("speedup tile end","Direction %f %f, Force %d, Max Speed %d", (Direction).x,(Direction).y, Force, MaxSpeed);
|
|
|
|
}
|
2010-06-11 09:39:32 +00:00
|
|
|
}
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-10-08 13:33:42 +00:00
|
|
|
void CCharacter::HandleTiles(int Index)
|
2011-01-29 00:59:50 +00:00
|
|
|
{
|
2010-10-08 13:33:42 +00:00
|
|
|
CGameControllerDDRace* Controller = (CGameControllerDDRace*)GameServer()->m_pController;
|
|
|
|
int MapIndex = Index;
|
2011-01-23 19:23:04 +00:00
|
|
|
//int PureMapIndex = GameServer()->Collision()->GetPureMapIndex(m_Pos);
|
2011-01-29 23:58:47 +00:00
|
|
|
float Offset = 4.0f;
|
|
|
|
int MapIndexL = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x + (m_ProximityRadius / 2) + Offset, m_Pos.y));
|
|
|
|
int MapIndexR = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x - (m_ProximityRadius / 2) - Offset, m_Pos.y));
|
|
|
|
int MapIndexT = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x, m_Pos.y + (m_ProximityRadius / 2) + Offset));
|
|
|
|
int MapIndexB = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x, m_Pos.y - (m_ProximityRadius / 2) - Offset));
|
2010-10-08 13:33:42 +00:00
|
|
|
//dbg_msg("","N%d L%d R%d B%d T%d",MapIndex,MapIndexL,MapIndexR,MapIndexB,MapIndexT);
|
|
|
|
m_TileIndex = GameServer()->Collision()->GetTileIndex(MapIndex);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFlags = GameServer()->Collision()->GetTileFlags(MapIndex);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileIndexL = GameServer()->Collision()->GetTileIndex(MapIndexL);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFlagsL = GameServer()->Collision()->GetTileFlags(MapIndexL);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileIndexR = GameServer()->Collision()->GetTileIndex(MapIndexR);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFlagsR = GameServer()->Collision()->GetTileFlags(MapIndexR);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileIndexB = GameServer()->Collision()->GetTileIndex(MapIndexB);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFlagsB = GameServer()->Collision()->GetTileFlags(MapIndexB);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileIndexT = GameServer()->Collision()->GetTileIndex(MapIndexT);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFlagsT = GameServer()->Collision()->GetTileFlags(MapIndexT);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileFIndex = GameServer()->Collision()->GetFTileIndex(MapIndex);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFFlags = GameServer()->Collision()->GetFTileFlags(MapIndex);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileFIndexL = GameServer()->Collision()->GetFTileIndex(MapIndexL);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFFlagsL = GameServer()->Collision()->GetFTileFlags(MapIndexL);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileFIndexR = GameServer()->Collision()->GetFTileIndex(MapIndexR);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFFlagsR = GameServer()->Collision()->GetFTileFlags(MapIndexR);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileFIndexB = GameServer()->Collision()->GetFTileIndex(MapIndexB);
|
2010-11-01 01:51:17 +00:00
|
|
|
m_TileFFlagsB = GameServer()->Collision()->GetFTileFlags(MapIndexB);
|
2010-10-08 13:33:42 +00:00
|
|
|
m_TileFIndexT = GameServer()->Collision()->GetFTileIndex(MapIndexT);
|
2010-11-13 13:22:19 +00:00
|
|
|
m_TileFFlagsT = GameServer()->Collision()->GetFTileFlags(MapIndexT);//
|
2011-01-29 23:58:47 +00:00
|
|
|
m_TileSIndex = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndex)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileIndex(MapIndex) : 0 : 0;
|
|
|
|
m_TileSFlags = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndex)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileFlags(MapIndex) : 0 : 0;
|
|
|
|
m_TileSIndexL = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexL)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileIndex(MapIndexL) : 0 : 0;
|
|
|
|
m_TileSFlagsL = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexL)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileFlags(MapIndexL) : 0 : 0;
|
|
|
|
m_TileSIndexR = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexR)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileIndex(MapIndexR) : 0 : 0;
|
|
|
|
m_TileSFlagsR = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexR)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileFlags(MapIndexR) : 0 : 0;
|
|
|
|
m_TileSIndexB = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexB)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileIndex(MapIndexB) : 0 : 0;
|
|
|
|
m_TileSFlagsB = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexB)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileFlags(MapIndexB) : 0 : 0;
|
|
|
|
m_TileSIndexT = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexT)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileIndex(MapIndexT) : 0 : 0;
|
|
|
|
m_TileSFlagsT = (GameServer()->Collision()->m_pSwitchers && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetDTileNumber(MapIndexT)].m_Status[Team()])?(Team() != TEAM_SUPER)? GameServer()->Collision()->GetDTileFlags(MapIndexT) : 0 : 0;
|
2010-11-13 13:22:19 +00:00
|
|
|
//dbg_msg("Tiles","%d, %d, %d, %d, %d", m_TileSIndex, m_TileSIndexL, m_TileSIndexR, m_TileSIndexB, m_TileSIndexT);
|
2010-11-09 00:51:49 +00:00
|
|
|
//Sensitivity
|
2011-01-29 23:58:47 +00:00
|
|
|
int S1 = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x + m_ProximityRadius / 3.f, m_Pos.y - m_ProximityRadius / 3.f));
|
|
|
|
int S2 = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x + m_ProximityRadius / 3.f, m_Pos.y + m_ProximityRadius / 3.f));
|
|
|
|
int S3 = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x - m_ProximityRadius / 3.f, m_Pos.y - m_ProximityRadius / 3.f));
|
|
|
|
int S4 = GameServer()->Collision()->GetPureMapIndex(vec2(m_Pos.x - m_ProximityRadius / 3.f, m_Pos.y + m_ProximityRadius / 3.f));
|
2010-11-09 00:51:49 +00:00
|
|
|
int Tile1 = GameServer()->Collision()->GetTileIndex(S1);
|
|
|
|
int Tile2 = GameServer()->Collision()->GetTileIndex(S2);
|
|
|
|
int Tile3 = GameServer()->Collision()->GetTileIndex(S3);
|
|
|
|
int Tile4 = GameServer()->Collision()->GetTileIndex(S4);
|
|
|
|
int FTile1 = GameServer()->Collision()->GetFTileIndex(S1);
|
|
|
|
int FTile2 = GameServer()->Collision()->GetFTileIndex(S2);
|
|
|
|
int FTile3 = GameServer()->Collision()->GetFTileIndex(S3);
|
|
|
|
int FTile4 = GameServer()->Collision()->GetFTileIndex(S4);
|
2010-10-08 13:33:42 +00:00
|
|
|
//dbg_msg("","N%d L%d R%d B%d T%d",m_TileIndex,m_TileIndexL,m_TileIndexR,m_TileIndexB,m_TileIndexT);
|
|
|
|
//dbg_msg("","N%d L%d R%d B%d T%d",m_TileFIndex,m_TileFIndexL,m_TileFIndexR,m_TileFIndexB,m_TileFIndexT);
|
2011-02-01 12:01:05 +00:00
|
|
|
if(Index < 0)
|
|
|
|
return;
|
2010-10-08 13:33:42 +00:00
|
|
|
int cp = GameServer()->Collision()->IsCheckpoint(MapIndex);
|
2010-10-29 21:28:15 +00:00
|
|
|
if(cp != -1 && m_DDRaceState == DDRACE_STARTED && cp > m_CpActive)
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
|
|
|
m_CpActive = cp;
|
|
|
|
m_CpCurrent[cp] = m_Time;
|
2011-01-29 23:58:47 +00:00
|
|
|
m_CpTick = Server()->Tick() + Server()->TickSpeed() * 2;
|
2010-11-30 02:24:15 +00:00
|
|
|
if(m_pPlayer->m_IsUsingDDRaceClient) {
|
|
|
|
CPlayerData *pData = GameServer()->Score()->PlayerData(m_pPlayer->GetCID());
|
|
|
|
CNetMsg_Sv_DDRaceTime Msg;
|
|
|
|
Msg.m_Time = (int)m_Time;
|
|
|
|
Msg.m_Check = 0;
|
|
|
|
Msg.m_Finish = 0;
|
|
|
|
|
|
|
|
if(m_CpActive != -1 && m_CpTick > Server()->Tick())
|
|
|
|
{
|
|
|
|
if(pData->m_BestTime && pData->m_aBestCpTime[m_CpActive] != 0)
|
|
|
|
{
|
|
|
|
float Diff = (m_CpCurrent[m_CpActive] - pData->m_aBestCpTime[m_CpActive])*100;
|
|
|
|
Msg.m_Check = (int)Diff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID());
|
|
|
|
}
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
2010-10-30 18:48:30 +00:00
|
|
|
int cpf = GameServer()->Collision()->IsFCheckpoint(MapIndex);
|
|
|
|
if(cpf != -1 && m_DDRaceState == DDRACE_STARTED && cpf > m_CpActive)
|
|
|
|
{
|
|
|
|
m_CpActive = cpf;
|
|
|
|
m_CpCurrent[cpf] = m_Time;
|
|
|
|
m_CpTick = Server()->Tick() + Server()->TickSpeed()*2;
|
2010-11-30 02:24:15 +00:00
|
|
|
if(m_pPlayer->m_IsUsingDDRaceClient) {
|
|
|
|
CPlayerData *pData = GameServer()->Score()->PlayerData(m_pPlayer->GetCID());
|
|
|
|
CNetMsg_Sv_DDRaceTime Msg;
|
|
|
|
Msg.m_Time = (int)m_Time;
|
|
|
|
Msg.m_Check = 0;
|
|
|
|
Msg.m_Finish = 0;
|
|
|
|
|
|
|
|
if(m_CpActive != -1 && m_CpTick > Server()->Tick())
|
|
|
|
{
|
|
|
|
if(pData->m_BestTime && pData->m_aBestCpTime[m_CpActive] != 0)
|
|
|
|
{
|
|
|
|
float Diff = (m_CpCurrent[m_CpActive] - pData->m_aBestCpTime[m_CpActive])*100;
|
|
|
|
Msg.m_Check = (int)Diff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID());
|
|
|
|
}
|
2010-10-30 18:48:30 +00:00
|
|
|
}
|
2011-05-17 23:12:39 +00:00
|
|
|
int tcp = GameServer()->Collision()->IsTCheckpoint(MapIndex);
|
|
|
|
if(tcp)
|
|
|
|
m_TeleCheckpoint = tcp;
|
2010-12-19 03:48:16 +00:00
|
|
|
if(((m_TileIndex == TILE_BEGIN) || (m_TileFIndex == TILE_BEGIN) || FTile1 == TILE_BEGIN || FTile2 == TILE_BEGIN || FTile3 == TILE_BEGIN || FTile4 == TILE_BEGIN || Tile1 == TILE_BEGIN || Tile2 == TILE_BEGIN || Tile3 == TILE_BEGIN || Tile4 == TILE_BEGIN) && (m_DDRaceState == DDRACE_NONE || m_DDRaceState == DDRACE_FINISHED || (m_DDRaceState == DDRACE_STARTED && !Team())))
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
2010-11-06 22:54:35 +00:00
|
|
|
bool CanBegin = true;
|
2011-02-16 11:06:43 +00:00
|
|
|
if(g_Config.m_SvResetPickus)
|
|
|
|
{
|
|
|
|
for (int i = WEAPON_SHOTGUN; i < NUM_WEAPONS; ++i)
|
|
|
|
{
|
|
|
|
m_aWeapons[i].m_Got = false;
|
|
|
|
if(m_ActiveWeapon == i)
|
|
|
|
m_ActiveWeapon = WEAPON_GUN;
|
|
|
|
}
|
|
|
|
}
|
2011-02-14 21:34:46 +00:00
|
|
|
if(g_Config.m_SvTeam == 2 && (Team() == TEAM_FLOCK || Teams()->Count(Team()) <= 1))
|
2011-01-29 14:31:50 +00:00
|
|
|
{
|
|
|
|
if(m_LastStartWarning < Server()->Tick() - 3 * Server()->TickSpeed())
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"Server admin requires you to be in a team and with other tees to start");
|
|
|
|
m_LastStartWarning = Server()->Tick();
|
|
|
|
}
|
2010-11-06 22:54:35 +00:00
|
|
|
CanBegin = false;
|
|
|
|
}
|
2011-01-29 14:31:50 +00:00
|
|
|
if(CanBegin)
|
|
|
|
{
|
2011-02-14 21:34:46 +00:00
|
|
|
Teams()->OnCharacterStart(m_pPlayer->GetCID());
|
2010-11-06 22:54:35 +00:00
|
|
|
m_CpActive = -2;
|
|
|
|
} else {
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-11-06 22:54:35 +00:00
|
|
|
}
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
2010-11-09 00:51:49 +00:00
|
|
|
if(((m_TileIndex == TILE_END) || (m_TileFIndex == TILE_END) || FTile1 == TILE_END || FTile2 == TILE_END || FTile3 == TILE_END || FTile4 == TILE_END || Tile1 == TILE_END || Tile2 == TILE_END || Tile3 == TILE_END || Tile4 == TILE_END) && m_DDRaceState == DDRACE_STARTED)
|
2010-10-08 13:33:42 +00:00
|
|
|
Controller->m_Teams.OnCharacterFinish(m_pPlayer->GetCID());
|
2011-01-14 13:37:02 +00:00
|
|
|
if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Super && !m_DeepFreeze)
|
2011-01-25 09:34:14 +00:00
|
|
|
Freeze();
|
2011-01-14 13:37:02 +00:00
|
|
|
else if(((m_TileIndex == TILE_UNFREEZE) || (m_TileFIndex == TILE_UNFREEZE)) && !m_DeepFreeze)
|
2010-10-08 13:33:42 +00:00
|
|
|
UnFreeze();
|
2011-02-13 05:35:13 +00:00
|
|
|
if(((m_TileIndex == TILE_DFREEZE) || (m_TileFIndex == TILE_DFREEZE)) && !m_Super && !m_DeepFreeze)
|
2011-01-14 13:37:02 +00:00
|
|
|
m_DeepFreeze = true;
|
|
|
|
else if(((m_TileIndex == TILE_DUNFREEZE) || (m_TileFIndex == TILE_DUNFREEZE)) && !m_Super && m_DeepFreeze)
|
|
|
|
m_DeepFreeze = false;
|
2011-01-29 23:58:47 +00:00
|
|
|
if(((m_TileIndex == TILE_EHOOK_START) || (m_TileFIndex == TILE_EHOOK_START)) && !m_EndlessHook)
|
2011-01-16 22:13:21 +00:00
|
|
|
{
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Endless hook has been activated");
|
2011-01-16 22:13:21 +00:00
|
|
|
m_EndlessHook = true;
|
|
|
|
}
|
|
|
|
else if(((m_TileIndex == TILE_EHOOK_END) || (m_TileFIndex == TILE_EHOOK_END)) && m_EndlessHook)
|
|
|
|
{
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Endless hook has been deactivated");
|
2011-01-16 22:13:21 +00:00
|
|
|
m_EndlessHook = false;
|
|
|
|
}
|
2011-07-25 20:16:20 +00:00
|
|
|
if(((m_TileIndex == TILE_HIT_START) || (m_TileFIndex == TILE_HIT_START)) && m_Hit != HIT_ALL)
|
2011-07-19 21:33:12 +00:00
|
|
|
{
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can hit others");
|
2011-07-25 20:16:20 +00:00
|
|
|
m_Hit = HIT_ALL;
|
2011-07-19 21:33:12 +00:00
|
|
|
}
|
2011-07-25 20:16:20 +00:00
|
|
|
else if(((m_TileIndex == TILE_HIT_END) || (m_TileFIndex == TILE_HIT_END)) && m_Hit != (DISABLE_HIT_GRENADE|DISABLE_HIT_HAMMER|DISABLE_HIT_RIFLE|DISABLE_HIT_SHOTGUN))
|
2011-07-19 21:33:12 +00:00
|
|
|
{
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't hit others");
|
2011-07-25 20:16:20 +00:00
|
|
|
m_Hit = DISABLE_HIT_GRENADE|DISABLE_HIT_HAMMER|DISABLE_HIT_RIFLE|DISABLE_HIT_SHOTGUN;
|
2011-07-19 21:33:12 +00:00
|
|
|
}
|
2011-09-02 18:04:18 +00:00
|
|
|
if(((m_TileIndex == TILE_SOLO_START) || (m_TileFIndex == TILE_SOLO_START)) && !Teams()->m_Core.GetSolo(m_pPlayer->GetCID()))
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You are now in a solo part.");
|
|
|
|
Teams()->m_Core.SetSolo(m_pPlayer->GetCID(), true);
|
|
|
|
}
|
|
|
|
else if(((m_TileIndex == TILE_SOLO_END) || (m_TileFIndex == TILE_SOLO_END)) && Teams()->m_Core.GetSolo(m_pPlayer->GetCID()))
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You are now out of the solo part.");
|
|
|
|
Teams()->m_Core.SetSolo(m_pPlayer->GetCID(), false);
|
|
|
|
}
|
2011-02-07 02:22:13 +00:00
|
|
|
if(((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_270) || (m_TileIndexL == TILE_STOP && m_TileFlagsL == ROTATION_270) || (m_TileIndexL == TILE_STOPS && (m_TileFlagsL == ROTATION_90 || m_TileFlagsL ==ROTATION_270)) || (m_TileIndexL == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_270) || (m_TileFIndexL == TILE_STOP && m_TileFFlagsL == ROTATION_270) || (m_TileFIndexL == TILE_STOPS && (m_TileFFlagsL == ROTATION_90 || m_TileFFlagsL == ROTATION_270)) || (m_TileFIndexL == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_270) || (m_TileSIndexL == TILE_STOP && m_TileSFlagsL == ROTATION_270) || (m_TileSIndexL == TILE_STOPS && (m_TileSFlagsL == ROTATION_90 || m_TileSFlagsL == ROTATION_270)) || (m_TileSIndexL == TILE_STOPA)) && m_Core.m_Vel.x > 0)
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
2011-02-07 02:22:13 +00:00
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexL).x)
|
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexL).x < (int)m_Core.m_Pos.x)
|
2011-02-06 18:38:24 +00:00
|
|
|
m_Core.m_Pos = m_PrevPos;
|
2011-02-07 02:22:13 +00:00
|
|
|
m_Core.m_Vel.x = 0;
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
2011-02-07 02:22:13 +00:00
|
|
|
if(((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_90) || (m_TileIndexR == TILE_STOP && m_TileFlagsR == ROTATION_90) || (m_TileIndexR == TILE_STOPS && (m_TileFlagsR == ROTATION_90 || m_TileFlagsR == ROTATION_270)) || (m_TileIndexR == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_90) || (m_TileFIndexR == TILE_STOP && m_TileFFlagsR == ROTATION_90) || (m_TileFIndexR == TILE_STOPS && (m_TileFFlagsR == ROTATION_90 || m_TileFFlagsR == ROTATION_270)) || (m_TileFIndexR == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_90) || (m_TileSIndexR == TILE_STOP && m_TileSFlagsR == ROTATION_90) || (m_TileSIndexR == TILE_STOPS && (m_TileSFlagsR == ROTATION_90 || m_TileSFlagsR == ROTATION_270)) || (m_TileSIndexR == TILE_STOPA)) && m_Core.m_Vel.x < 0)
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
2011-02-07 02:22:13 +00:00
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexR).x)
|
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexR).x > (int)m_Core.m_Pos.x)
|
2011-02-06 18:38:24 +00:00
|
|
|
m_Core.m_Pos = m_PrevPos;
|
2011-02-07 02:22:13 +00:00
|
|
|
m_Core.m_Vel.x = 0;
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
2011-02-07 02:22:13 +00:00
|
|
|
if(((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_180) || (m_TileIndexB == TILE_STOP && m_TileFlagsB == ROTATION_180) || (m_TileIndexB == TILE_STOPS && (m_TileFlagsB == ROTATION_0 || m_TileFlagsB == ROTATION_180)) || (m_TileIndexB == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_180) || (m_TileFIndexB == TILE_STOP && m_TileFFlagsB == ROTATION_180) || (m_TileFIndexB == TILE_STOPS && (m_TileFFlagsB == ROTATION_0 || m_TileFFlagsB == ROTATION_180)) || (m_TileFIndexB == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_180) || (m_TileSIndexB == TILE_STOP && m_TileSFlagsB == ROTATION_180) || (m_TileSIndexB == TILE_STOPS && (m_TileSFlagsB == ROTATION_0 || m_TileSFlagsB == ROTATION_180)) || (m_TileSIndexB == TILE_STOPA)) && m_Core.m_Vel.y < 0)
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
2011-02-07 02:22:13 +00:00
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexB).y)
|
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexB).y > (int)m_Core.m_Pos.y)
|
2011-02-06 18:38:24 +00:00
|
|
|
m_Core.m_Pos = m_PrevPos;
|
2011-02-07 02:22:13 +00:00
|
|
|
m_Core.m_Vel.y = 0;
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
2011-02-07 02:22:13 +00:00
|
|
|
if(((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_0) || (m_TileIndexT == TILE_STOP && m_TileFlagsT == ROTATION_0) || (m_TileIndexT == TILE_STOPS && (m_TileFlagsT == ROTATION_0 || m_TileFlagsT == ROTATION_180)) || (m_TileIndexT == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_0) || (m_TileFIndexT == TILE_STOP && m_TileFFlagsT == ROTATION_0) || (m_TileFIndexT == TILE_STOPS && (m_TileFFlagsT == ROTATION_0 || m_TileFFlagsT == ROTATION_180)) || (m_TileFIndexT == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_0) || (m_TileSIndexT == TILE_STOP && m_TileSFlagsT == ROTATION_0) || (m_TileSIndexT == TILE_STOPS && (m_TileSFlagsT == ROTATION_0 || m_TileSFlagsT == ROTATION_180)) || (m_TileSIndexT == TILE_STOPA)) && m_Core.m_Vel.y > 0)
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
2011-02-07 02:22:13 +00:00
|
|
|
//dbg_msg("","%f %f",GameServer()->Collision()->GetPos(MapIndex).y,m_Core.m_Pos.y);
|
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexT).y)
|
|
|
|
if((int)GameServer()->Collision()->GetPos(MapIndexT).y < (int)m_Core.m_Pos.y)
|
2011-02-06 18:38:24 +00:00
|
|
|
m_Core.m_Pos = m_PrevPos;
|
2011-02-07 02:22:13 +00:00
|
|
|
m_Core.m_Vel.y = 0;
|
2010-10-08 13:33:42 +00:00
|
|
|
m_Core.m_Jumped = 0;
|
|
|
|
}
|
2010-11-13 13:22:19 +00:00
|
|
|
// handle switch tiles
|
2010-11-14 11:14:18 +00:00
|
|
|
if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_SWITCHOPEN && Team() != TEAM_SUPER)
|
2010-11-22 20:43:22 +00:00
|
|
|
{
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHOPEN;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_SWITCHTIMEDOPEN && Team() != TEAM_SUPER)
|
|
|
|
{
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + GameServer()->Collision()->GetSwitchDelay(MapIndex)*Server()->TickSpeed() ;
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDOPEN;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_SWITCHTIMEDCLOSE && Team() != TEAM_SUPER)
|
|
|
|
{
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + GameServer()->Collision()->GetSwitchDelay(MapIndex)*Server()->TickSpeed();
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDCLOSE;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_SWITCHCLOSE && Team() != TEAM_SUPER)
|
|
|
|
{
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
|
|
|
|
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHCLOSE;
|
|
|
|
}
|
2011-01-25 09:34:14 +00:00
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
|
|
|
|
{
|
|
|
|
Freeze(GameServer()->Collision()->GetSwitchDelay(MapIndex));
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
|
|
|
|
{
|
|
|
|
m_DeepFreeze = true;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER && GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
|
|
|
|
{
|
|
|
|
m_DeepFreeze = false;
|
|
|
|
}
|
2011-07-25 20:16:20 +00:00
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_START && m_Hit&DISABLE_HIT_HAMMER && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can hammer hit others");
|
|
|
|
m_Hit ^= DISABLE_HIT_HAMMER;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_END && !(m_Hit&DISABLE_HIT_HAMMER) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can't hammer hit others");
|
|
|
|
m_Hit |= DISABLE_HIT_HAMMER;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_START && m_Hit&DISABLE_HIT_SHOTGUN && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can shoot others with shotgun");
|
|
|
|
m_Hit ^= DISABLE_HIT_SHOTGUN;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_END && !(m_Hit&DISABLE_HIT_SHOTGUN) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can't shoot others with shotgun");
|
|
|
|
m_Hit |= DISABLE_HIT_SHOTGUN;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_START && m_Hit&DISABLE_HIT_GRENADE && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can shoot others with grenade");
|
|
|
|
m_Hit ^= DISABLE_HIT_GRENADE;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_END && !(m_Hit&DISABLE_HIT_GRENADE) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can't shoot others with grenade");
|
|
|
|
m_Hit |= DISABLE_HIT_GRENADE;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_START && m_Hit&DISABLE_HIT_RIFLE && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_RIFLE)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can shoot others with rifle");
|
|
|
|
m_Hit ^= DISABLE_HIT_RIFLE;
|
|
|
|
}
|
|
|
|
else if(GameServer()->Collision()->IsSwitch(MapIndex) == TILE_HIT_END && !(m_Hit&DISABLE_HIT_RIFLE) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_RIFLE)
|
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"You can't shoot others with rifle");
|
|
|
|
m_Hit |= DISABLE_HIT_RIFLE;
|
|
|
|
}
|
2010-10-08 13:33:42 +00:00
|
|
|
int z = GameServer()->Collision()->IsTeleport(MapIndex);
|
2010-11-14 09:04:13 +00:00
|
|
|
if(z && ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1].size())
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
|
|
|
m_Core.m_HookedPlayer = -1;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
|
|
|
m_Core.m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
2010-11-14 09:04:13 +00:00
|
|
|
int Num = (((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1].size());
|
|
|
|
m_Core.m_Pos = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1][(!Num)?Num:rand() % Num];
|
2010-10-08 13:33:42 +00:00
|
|
|
m_Core.m_HookPos = m_Core.m_Pos;
|
2010-10-10 23:46:13 +00:00
|
|
|
return;
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
|
|
|
int evilz = GameServer()->Collision()->IsEvilTeleport(MapIndex);
|
2010-11-14 09:04:13 +00:00
|
|
|
if(evilz && !m_Super && ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[evilz-1].size())
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
|
|
|
m_Core.m_HookedPlayer = -1;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
|
|
|
m_Core.m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
|
|
|
GameWorld()->ReleaseHooked(GetPlayer()->GetCID());
|
2010-11-14 09:04:13 +00:00
|
|
|
int Num = (((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[evilz-1].size());
|
|
|
|
m_Core.m_Pos = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[evilz-1][(!Num)?Num:rand() % Num];
|
2010-10-08 13:33:42 +00:00
|
|
|
m_Core.m_HookPos = m_Core.m_Pos;
|
|
|
|
m_Core.m_Vel = vec2(0,0);
|
2010-10-10 23:46:13 +00:00
|
|
|
return;
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
2011-05-17 23:12:39 +00:00
|
|
|
if(GameServer()->Collision()->IsCheckTeleport(MapIndex))
|
|
|
|
{
|
2011-09-02 22:42:01 +00:00
|
|
|
// first check if there is a TeleCheckOut for the current recorded checkpoint, if not check previous checkpoints
|
|
|
|
for(int k=m_TeleCheckpoint-1; k >= 0; k--)
|
2011-05-17 23:12:39 +00:00
|
|
|
{
|
2011-09-02 22:42:01 +00:00
|
|
|
if(Controller->m_TeleCheckOuts[k].size())
|
|
|
|
{
|
|
|
|
m_Core.m_HookedPlayer = -1;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
|
|
|
m_Core.m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
|
|
|
int Num = Controller->m_TeleCheckOuts[k].size();
|
|
|
|
m_Core.m_Pos = Controller->m_TeleCheckOuts[k][(!Num)?Num:rand() % Num];
|
|
|
|
m_Core.m_HookPos = m_Core.m_Pos;
|
|
|
|
return;
|
|
|
|
}
|
2011-05-17 23:12:39 +00:00
|
|
|
}
|
2011-09-02 22:42:01 +00:00
|
|
|
// if no checkpointout have been found (or if there no recorded checkpoint), teleport to start
|
2011-05-17 23:12:39 +00:00
|
|
|
vec2 SpawnPos;
|
|
|
|
if(GameServer()->m_pController->CanSpawn(m_pPlayer->GetTeam(), &SpawnPos))
|
|
|
|
{
|
|
|
|
m_Core.m_HookedPlayer = -1;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
|
|
|
m_Core.m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
|
|
|
m_Core.m_HookState = HOOK_RETRACTED;
|
|
|
|
m_Core.m_Pos = SpawnPos;
|
|
|
|
m_Core.m_HookPos = m_Core.m_Pos;
|
|
|
|
}
|
2011-09-02 22:42:01 +00:00
|
|
|
return;
|
2011-05-17 23:12:39 +00:00
|
|
|
}
|
2010-10-08 13:33:42 +00:00
|
|
|
}
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
void CCharacter::DDRaceTick()
|
2010-08-24 14:32:46 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Armor=(m_FreezeTime >= 0)?10-(m_FreezeTime/15):0;
|
|
|
|
if(m_Input.m_Direction != 0 || m_Input.m_Jump != 0)
|
|
|
|
m_LastMove = Server()->Tick();
|
2010-08-24 14:32:46 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(m_FreezeTime > 0 || m_FreezeTime == -1)
|
2010-05-29 07:25:38 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
if (m_FreezeTime % Server()->TickSpeed() == 0 || m_FreezeTime == -1)
|
2010-06-09 16:24:38 +00:00
|
|
|
{
|
2011-09-02 18:04:18 +00:00
|
|
|
GameServer()->CreateDamageInd(m_Pos, 0, m_FreezeTime / Server()->TickSpeed(), Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
|
|
|
if(m_FreezeTime > 0)
|
|
|
|
m_FreezeTime--;
|
|
|
|
else
|
|
|
|
m_Ninja.m_ActivationTick = Server()->Tick();
|
|
|
|
m_Input.m_Direction = 0;
|
|
|
|
m_Input.m_Jump = 0;
|
|
|
|
m_Input.m_Hook = 0;
|
|
|
|
if (m_FreezeTime == 1)
|
|
|
|
UnFreeze();
|
2008-09-23 07:43:41 +00:00
|
|
|
}
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
m_Core.m_Id = GetPlayer()->GetCID();
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2011-01-29 23:58:47 +00:00
|
|
|
|
|
|
|
void CCharacter::DDRacePostCoreTick()
|
|
|
|
{
|
|
|
|
if (m_DefEmoteReset >= 0 && m_DefEmoteReset <= Server()->Tick())
|
|
|
|
{
|
|
|
|
m_DefEmoteReset = -1;
|
|
|
|
m_EmoteType = m_DefEmote = EMOTE_NORMAL;
|
|
|
|
m_EmoteStop = -1;
|
|
|
|
}
|
|
|
|
|
2011-07-22 12:29:27 +00:00
|
|
|
if (m_EndlessHook || (m_Super && g_Config.m_SvEndlessSuperHook))
|
2011-01-29 23:58:47 +00:00
|
|
|
m_Core.m_HookTick = 0;
|
|
|
|
|
|
|
|
if (m_DeepFreeze && !m_Super)
|
|
|
|
Freeze();
|
|
|
|
|
|
|
|
if (m_Super && m_Core.m_Jumped > 1)
|
|
|
|
m_Core.m_Jumped = 1;
|
|
|
|
|
|
|
|
int CurrentIndex = GameServer()->Collision()->GetMapIndex(m_Pos);
|
|
|
|
HandleSkippableTiles(CurrentIndex);
|
|
|
|
|
|
|
|
// handle Anti-Skip tiles
|
|
|
|
std::list < int > Indices = GameServer()->Collision()->GetMapIndices(m_PrevPos, m_Pos);
|
|
|
|
if(!Indices.empty())
|
|
|
|
for(std::list < int >::iterator i = Indices.begin(); i != Indices.end(); i++)
|
|
|
|
{
|
|
|
|
HandleTiles(*i);
|
|
|
|
//dbg_msg("Running","%d", *i);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
HandleTiles(CurrentIndex);
|
|
|
|
//dbg_msg("Running","%d", CurrentIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
HandleBroadcast();
|
|
|
|
}
|
|
|
|
|
2011-01-25 09:34:14 +00:00
|
|
|
bool CCharacter::Freeze(int Seconds)
|
2010-08-24 14:32:46 +00:00
|
|
|
{
|
2011-01-25 09:34:14 +00:00
|
|
|
if ((Seconds <= 0 || m_Super || m_FreezeTime == -1 || m_FreezeTime > Seconds * Server()->TickSpeed()) && Seconds != -1)
|
2010-08-24 14:32:46 +00:00
|
|
|
return false;
|
2011-01-25 09:34:14 +00:00
|
|
|
if (m_FreezeTick < Server()->Tick() - Server()->TickSpeed() || Seconds == -1)
|
2010-07-29 05:21:18 +00:00
|
|
|
{
|
2011-01-25 09:34:14 +00:00
|
|
|
for(int i = 0; i < NUM_WEAPONS; i++)
|
2010-08-24 14:32:46 +00:00
|
|
|
if(m_aWeapons[i].m_Got)
|
|
|
|
{
|
|
|
|
m_aWeapons[i].m_Ammo = 0;
|
|
|
|
}
|
2011-01-25 09:34:14 +00:00
|
|
|
m_Armor = 0;
|
|
|
|
m_FreezeTime = Seconds == -1 ? Seconds : Seconds * Server()->TickSpeed();
|
|
|
|
m_FreezeTick = Server()->Tick();
|
2010-08-22 02:23:18 +00:00
|
|
|
return true;
|
2010-08-24 14:32:46 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CCharacter::Freeze()
|
|
|
|
{
|
2011-01-25 09:34:14 +00:00
|
|
|
return Freeze(g_Config.m_SvFreezeDelay);
|
2010-08-24 14:32:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CCharacter::UnFreeze()
|
|
|
|
{
|
2011-01-25 09:34:14 +00:00
|
|
|
if (m_FreezeTime > 0)
|
2010-08-22 02:23:18 +00:00
|
|
|
{
|
|
|
|
m_Armor=10;
|
2010-08-24 14:32:46 +00:00
|
|
|
for(int i=0;i<NUM_WEAPONS;i++)
|
|
|
|
if(m_aWeapons[i].m_Got)
|
|
|
|
{
|
|
|
|
m_aWeapons[i].m_Ammo = -1;
|
|
|
|
}
|
2010-11-04 23:52:37 +00:00
|
|
|
if(!m_aWeapons[m_ActiveWeapon].m_Got)
|
|
|
|
m_ActiveWeapon = WEAPON_GUN;
|
|
|
|
m_FreezeTime = 0;
|
|
|
|
m_FreezeTick = 0;
|
2010-11-14 11:14:18 +00:00
|
|
|
if (m_ActiveWeapon==WEAPON_HAMMER) m_ReloadTimer = 0;
|
2010-08-24 14:32:46 +00:00
|
|
|
return true;
|
2010-08-22 02:23:18 +00:00
|
|
|
}
|
2010-08-24 14:32:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCharacter::GiveAllWeapons()
|
|
|
|
{
|
|
|
|
for(int i=1;i<NUM_WEAPONS-1;i++)
|
|
|
|
{
|
|
|
|
m_aWeapons[i].m_Got = true;
|
|
|
|
if(!m_FreezeTime) m_aWeapons[i].m_Ammo = -1;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2010-07-29 05:21:18 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
void CCharacter::DDRaceInit()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
m_DDRaceState = DDRACE_NONE;
|
|
|
|
m_PrevPos = m_Pos;
|
|
|
|
m_EyeEmote = true;
|
|
|
|
m_LastBroadcast = 0;
|
|
|
|
m_TeamBeforeSuper = 0;
|
|
|
|
m_Core.m_Id = GetPlayer()->GetCID();
|
|
|
|
if(GetPlayer()->m_IsUsingDDRaceClient) ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.SendTeamsState(GetPlayer()->GetCID());
|
2011-02-14 21:34:46 +00:00
|
|
|
if(g_Config.m_SvTeam == 2)
|
2011-01-29 14:31:50 +00:00
|
|
|
{
|
|
|
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(),"Please join a team before you start");
|
|
|
|
m_LastStartWarning = Server()->Tick();
|
|
|
|
}
|
2011-01-29 00:59:50 +00:00
|
|
|
m_DefEmote = EMOTE_NORMAL;
|
|
|
|
m_DefEmoteReset = -1;
|
2011-05-17 23:12:39 +00:00
|
|
|
m_TeleCheckpoint = 0;
|
2011-07-22 12:29:27 +00:00
|
|
|
m_EndlessHook = g_Config.m_SvEndlessDrag;
|
2011-07-25 20:16:20 +00:00
|
|
|
m_Hit = g_Config.m_SvHit ? HIT_ALL : DISABLE_HIT_GRENADE|DISABLE_HIT_HAMMER|DISABLE_HIT_RIFLE|DISABLE_HIT_SHOTGUN;
|
2011-09-02 18:04:18 +00:00
|
|
|
Teams()->m_Core.SetSolo(m_pPlayer->GetCID(), false);
|
2011-02-14 18:36:30 +00:00
|
|
|
}
|