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
|
|
|
|
2013-02-01 11:08:23 +00:00
|
|
|
Teams()->OnCharacterSpawn(GetPlayer()->GetCID());
|
|
|
|
|
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
|
|
|
|
2011-12-10 17:21:12 +00:00
|
|
|
// it is 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-12-10 17:21:12 +00:00
|
|
|
// it is not allowed to aim in the center
|
|
|
|
if(m_LatestInput.m_TargetX == 0 && m_LatestInput.m_TargetY == 0)
|
|
|
|
m_LatestInput.m_TargetY = -1;
|
|
|
|
|
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-12-29 13:58:39 +00:00
|
|
|
if (m_Paused)
|
|
|
|
return;
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-09 23:49:31 +00:00
|
|
|
void CCharacter::TickPaused()
|
|
|
|
{
|
|
|
|
++m_AttackTick;
|
|
|
|
++m_DamageTakenTick;
|
|
|
|
++m_Ninja.m_ActivationTick;
|
|
|
|
++m_ReckoningTick;
|
|
|
|
if(m_LastAction != -1)
|
|
|
|
++m_LastAction;
|
|
|
|
if(m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart > -1)
|
|
|
|
++m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart;
|
|
|
|
if(m_EmoteStop > -1)
|
|
|
|
++m_EmoteStop;
|
|
|
|
}
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
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()));
|
2013-02-01 11:08:23 +00:00
|
|
|
Teams()->OnCharacterDeath(GetPlayer()->GetCID());
|
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-12-31 12:54:29 +00:00
|
|
|
CPlayer* SnapPlayer = GameServer()->m_apPlayers[SnappingClient];
|
|
|
|
|
|
|
|
if((SnapPlayer->GetTeam() == TEAM_SPECTATORS || SnapPlayer->m_Paused) && SnapPlayer->m_SpectatorID != -1
|
|
|
|
&& !CanCollide(SnapPlayer->m_SpectatorID) && !SnapPlayer->m_ShowOthers)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( SnapPlayer->GetTeam() != TEAM_SPECTATORS && !SnapPlayer->m_Paused && SnapChar && !SnapChar->m_Super
|
|
|
|
&& !CanCollide(SnappingClient) && !SnapPlayer->m_ShowOthers)
|
2011-04-09 06:41:31 +00:00
|
|
|
return;
|
|
|
|
|
2011-12-29 13:58:39 +00:00
|
|
|
if (m_Paused)
|
|
|
|
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())
|
|
|
|
{
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
m_EmoteType = m_pPlayer->m_DefEmote;
|
2011-01-29 00:59:50 +00:00
|
|
|
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-10-08 13:33:42 +00:00
|
|
|
CPlayerData *pData = GameServer()->Score()->PlayerData(m_pPlayer->GetCID());
|
2013-03-18 11:58:29 +00:00
|
|
|
|
|
|
|
if(m_DDRaceState == DDRACE_STARTED && m_CpLastBroadcast != m_CpActive &&
|
|
|
|
m_CpActive > -1 && m_CpTick > Server()->Tick() && !m_pPlayer->m_IsUsingDDRaceClient &&
|
2011-06-05 11:56:04 +00:00
|
|
|
pData->m_BestTime && pData->m_aBestCpTime[m_CpActive] != 0)
|
2010-10-08 13:33:42 +00:00
|
|
|
{
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
char aBroadcast[128];
|
2011-06-05 11:56:04 +00:00
|
|
|
float Diff = m_CpCurrent[m_CpActive] - pData->m_aBestCpTime[m_CpActive];
|
2013-03-18 11:58:29 +00:00
|
|
|
dbg_msg("CHECKPOINT", "%f", Diff);
|
2011-06-05 11:56:04 +00:00
|
|
|
str_format(aBroadcast, sizeof(aBroadcast), "Checkpoint | Diff : %+5.2f", Diff);
|
|
|
|
GameServer()->SendBroadcast(aBroadcast, m_pPlayer->GetCID());
|
2013-03-18 11:58:29 +00:00
|
|
|
m_CpLastBroadcast = m_CpActive;
|
2011-06-05 11:56:04 +00:00
|
|
|
m_LastBroadcast = Server()->Tick();
|
2010-08-10 04:28:17 +00:00
|
|
|
}
|
2012-02-14 20:38:06 +00:00
|
|
|
else if ((m_pPlayer->m_TimerType == 1 || m_pPlayer->m_TimerType == 2) && m_DDRaceState == DDRACE_STARTED && m_LastBroadcast + Server()->TickSpeed() * g_Config.m_SvTimeInBroadcastInterval <= Server()->Tick())
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
{
|
|
|
|
char aBuftime[64];
|
|
|
|
int IntTime = (int)((float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed()));
|
|
|
|
str_format(aBuftime, sizeof(aBuftime), "%s%d:%s%d", ((IntTime/60) > 9)?"":"0", IntTime/60, ((IntTime%60) > 9)?"":"0", IntTime%60);
|
|
|
|
GameServer()->SendBroadcast(aBuftime, m_pPlayer->GetCID());
|
2013-03-18 11:58:29 +00:00
|
|
|
m_CpLastBroadcast = m_CpActive;
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
m_LastBroadcast = 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();
|
|
|
|
}
|
2012-04-11 13:36:11 +00:00
|
|
|
Die(GetPlayer()->GetCID(), WEAPON_WORLD);
|
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);
|
2011-09-02 22:55:15 +00:00
|
|
|
if(z && Controller->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;
|
2011-09-02 22:55:15 +00:00
|
|
|
int Num = Controller->m_TeleOuts[z-1].size();
|
|
|
|
m_Core.m_Pos = Controller->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);
|
2011-09-02 22:55:15 +00:00
|
|
|
if(evilz && !m_Super && Controller->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());
|
2011-09-02 22:55:15 +00:00
|
|
|
int Num = Controller->m_TeleOuts[evilz-1].size();
|
|
|
|
m_Core.m_Pos = Controller->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()
|
|
|
|
{
|
2013-03-18 11:58:29 +00:00
|
|
|
m_Time = (float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed());
|
|
|
|
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
if (m_pPlayer->m_DefEmoteReset >= 0 && m_pPlayer->m_DefEmoteReset <= Server()->Tick())
|
2011-01-29 23:58:47 +00:00
|
|
|
{
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
m_pPlayer->m_DefEmoteReset = -1;
|
|
|
|
m_EmoteType = m_pPlayer->m_DefEmote = EMOTE_NORMAL;
|
2011-01-29 23:58:47 +00:00
|
|
|
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-12-29 13:58:39 +00:00
|
|
|
void CCharacter::Pause(bool Pause)
|
|
|
|
{
|
|
|
|
m_Paused = Pause;
|
|
|
|
if(Pause)
|
|
|
|
{
|
|
|
|
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
|
|
|
|
GameServer()->m_World.RemoveEntity(this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-04-27 13:01:26 +00:00
|
|
|
m_Core.m_Vel = vec2(0,0);
|
2011-12-29 13:58:39 +00:00
|
|
|
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = &m_Core;
|
|
|
|
GameServer()->m_World.InsertEntity(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
void CCharacter::DDRaceInit()
|
2008-07-06 11:21:21 +00:00
|
|
|
{
|
2011-12-29 13:58:39 +00:00
|
|
|
m_Paused = false;
|
2011-01-29 00:59:50 +00:00
|
|
|
m_DDRaceState = DDRACE_NONE;
|
|
|
|
m_PrevPos = m_Pos;
|
|
|
|
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-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-02-14 18:36:30 +00:00
|
|
|
}
|