add teleport gun/grenade/laser

This commit is contained in:
Ryozuki 2018-02-14 16:27:26 +01:00
parent 498f2fe7ac
commit 50c84a60f7
13 changed files with 207 additions and 3 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 333 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 321 KiB

View file

@ -682,9 +682,9 @@ bool CCollision::TileExists(int Index)
if(Index < 0)
return false;
if(m_pTiles[Index].m_Index >= TILE_FREEZE && m_pTiles[Index].m_Index <= TILE_NPH_START)
if(m_pTiles[Index].m_Index >= TILE_FREEZE && m_pTiles[Index].m_Index <= TILE_TELE_LASER_DISABLE)
return true;
if(m_pFront && m_pFront[Index].m_Index >= TILE_FREEZE && m_pFront[Index].m_Index <= TILE_NPH_START)
if(m_pFront && m_pFront[Index].m_Index >= TILE_FREEZE && m_pFront[Index].m_Index <= TILE_TELE_LASER_DISABLE)
return true;
if(m_pTele && (m_pTele[Index].m_Type == TILE_TELEIN || m_pTele[Index].m_Type == TILE_TELEINEVIL || m_pTele[Index].m_Type == TILE_TELECHECKINEVIL ||m_pTele[Index].m_Type == TILE_TELECHECK || m_pTele[Index].m_Type == TILE_TELECHECKIN))
return true;

View file

@ -13,6 +13,9 @@ bool IsValidGameTile(int Index)
|| (Index >= TILE_CP && Index <= TILE_THROUGH_DIR)
|| (Index >= TILE_OLDLASER && Index <= TILE_UNLOCK_TEAM)
|| (Index >= TILE_NPC_END && Index <= TILE_NPH_END)
|| (Index >= TILE_TELE_GUN_ENABLE && Index <= TILE_NO_TELE_GUN)
|| (Index >= TILE_TELE_GRENADE_ENABLE && Index <= TILE_TELE_GRENADE_DISABLE)
|| (Index >= TILE_TELE_LASER_ENABLE && Index <= TILE_TELE_LASER_DISABLE)
|| (Index >= TILE_NPC_START && Index <= TILE_NPH_START)
|| (Index >= TILE_ENTITIES_OFF_1 && Index <= TILE_ENTITIES_OFF_2)
|| IsValidEntity(Index)
@ -32,6 +35,9 @@ bool IsValidFrontTile(int Index)
|| (Index >= TILE_CP && Index <= TILE_THROUGH_DIR)
|| (Index >= TILE_OLDLASER && Index <= TILE_UNLOCK_TEAM)
|| (Index >= TILE_NPC_END && Index <= TILE_NPH_END)
|| (Index >= TILE_TELE_GUN_ENABLE && Index <= TILE_NO_TELE_GUN)
|| (Index >= TILE_TELE_GRENADE_ENABLE && Index <= TILE_TELE_GRENADE_DISABLE)
|| (Index >= TILE_TELE_LASER_ENABLE && Index <= TILE_TELE_LASER_DISABLE)
|| (Index >= TILE_NPC_START && Index <= TILE_NPH_START)
|| IsValidEntity(Index)
);

View file

@ -149,10 +149,17 @@ enum
TILE_JETPACK_END,
TILE_NPH_END,
TILE_BONUS = 95,
TILE_TELE_GUN_ENABLE = 96,
TILE_TELE_GUN_DISABLE = 97,
TILE_NO_TELE_GUN = 98,
TILE_NPC_START = 104,
TILE_SUPER_START,
TILE_JETPACK_START,
TILE_NPH_START,
TILE_TELE_GRENADE_ENABLE = 112,
TILE_TELE_GRENADE_DISABLE = 113,
TILE_TELE_LASER_ENABLE = 128,
TILE_TELE_LASER_DISABLE = 129,
TILE_ENTITIES_OFF_1 = 190,
TILE_ENTITIES_OFF_2,
//End of higher tiles

View file

@ -42,6 +42,10 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
m_LastPenalty = false;
m_LastBonus = false;
m_HasTeleGun = false;
m_HasTeleLaser = false;
m_HasTeleGrenade = false;
m_pPlayer = pPlayer;
m_Pos = Pos;
@ -1622,6 +1626,40 @@ void CCharacter::HandleTiles(int Index)
m_LastRefillJumps = false;
}
// Teleport gun
if (((m_TileIndex == TILE_TELE_GUN_ENABLE) || (m_TileFIndex == TILE_TELE_GUN_ENABLE)) && !m_HasTeleGun)
{
m_HasTeleGun = true;
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Teleport gun enabled");
}
else if (((m_TileIndex == TILE_TELE_GUN_DISABLE) || (m_TileFIndex == TILE_TELE_GUN_DISABLE)) && m_HasTeleGun)
{
m_HasTeleGun = false;
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Teleport gun disabled");
}
if (((m_TileIndex == TILE_TELE_GRENADE_ENABLE) || (m_TileFIndex == TILE_TELE_GRENADE_ENABLE)) && !m_HasTeleGrenade)
{
m_HasTeleGrenade = true;
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Teleport grenade enabled");
}
else if (((m_TileIndex == TILE_TELE_GRENADE_DISABLE) || (m_TileFIndex == TILE_TELE_GRENADE_DISABLE)) && m_HasTeleGrenade)
{
m_HasTeleGrenade = false;
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Teleport grenade disabled");
}
if (((m_TileIndex == TILE_TELE_LASER_ENABLE) || (m_TileFIndex == TILE_TELE_LASER_ENABLE)) && !m_HasTeleLaser)
{
m_HasTeleLaser = true;
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Teleport laser enabled");
}
else if (((m_TileIndex == TILE_TELE_LASER_DISABLE) || (m_TileFIndex == TILE_TELE_LASER_DISABLE)) && m_HasTeleLaser)
{
m_HasTeleLaser = false;
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "Teleport laser disabled");
}
// stopper
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)
{

View file

@ -251,6 +251,9 @@ public:
bool m_LastRefillJumps;
bool m_LastPenalty;
bool m_LastBonus;
bool m_HasTeleGun;
bool m_HasTeleGrenade;
bool m_HasTeleLaser;
// Setters/Getters because i don't want to modify vanilla vars access modifiers
int GetLastWeapon() { return m_LastWeapon; };

View file

@ -20,6 +20,7 @@ CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEner
m_TelePos = vec2(0,0);
m_WasTele = false;
m_Type = Type;
m_TeleportCancelled = false;
m_TuneZone = GameServer()->Collision()->IsTune(GameServer()->Collision()->GetMapIndex(m_Pos));
m_TeamMask = GameServer()->GetPlayerChar(Owner) ? GameServer()->GetPlayerChar(Owner)->Teams()->TeamMask(GameServer()->GetPlayerChar(Owner)->Team(), -1, m_Owner) : 0;
GameWorld()->InsertEntity(this);
@ -164,6 +165,52 @@ void CLaser::DoBounce()
m_Energy = -1;
}
}
if (m_Owner >= 0 && m_Energy <= 0 && m_Pos && !m_TeleportCancelled)
{
CCharacter *pOwnerChar = GameServer()->GetPlayerChar(m_Owner);
if (pOwnerChar && pOwnerChar->IsAlive() && pOwnerChar->m_HasTeleLaser && m_Type == WEAPON_RIFLE)
{
int64_t TeamMask = pOwnerChar->Teams()->TeamMask(pOwnerChar->Team(), -1, m_Owner);
vec2 PossiblePos;
bool Found = false;
bool pDontHitSelf = g_Config.m_SvOldLaser || (m_Bounces == 0 && !m_WasTele);
vec2 At;
CCharacter *pHit;
if(pOwnerChar ? (!(pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_RIFLE) && m_Type == WEAPON_RIFLE) : g_Config.m_SvHit)
pHit = GameServer()->m_World.IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner);
else
pHit = GameServer()->m_World.IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner, pOwnerChar);
if(pHit)
Found = GetNearestAirPosPlayer(pHit->m_Pos, &PossiblePos);
else
Found = GetNearestAirPos(m_Pos, &PossiblePos);
if (Found && PossiblePos)
{
GameServer()->CreateDeath(pOwnerChar->Core()->m_Pos, pOwnerChar->GetPlayer()->GetCID(),
(m_Owner != -1) ? TeamMask : -1LL);
pOwnerChar->Core()->m_Pos = PossiblePos;
pOwnerChar->Core()->m_Vel = vec2(0, 0);
GameServer()->CreateDeath(m_Pos, pOwnerChar->GetPlayer()->GetCID(), (m_Owner != -1) ? TeamMask : -1LL);
GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SPAWN, (m_Owner != -1) ? TeamMask : -1LL);
}
}
}
else if(m_Owner >= 0 && m_Pos)
{
int MapIndex = GameServer()->Collision()->GetPureMapIndex(round_to_int(Coltile.x), round_to_int(Coltile.y));
int TileIndex = GameServer()->Collision()->GetTileIndex(MapIndex);
int TileFIndex = GameServer()->Collision()->GetFTileIndex(MapIndex);
if (m_Type == WEAPON_RIFLE && (TileIndex == TILE_NO_TELE_GUN || TileFIndex == TILE_NO_TELE_GUN))
m_TeleportCancelled = true;
}
//m_Owner = -1;
}

View file

@ -35,6 +35,7 @@ private:
vec2 m_PrevPos;
int m_Type;
int m_TuneZone;
bool m_TeleportCancelled;
};
#endif

View file

@ -106,7 +106,6 @@ vec2 CProjectile::GetPos(float Time)
return CalcPos(m_Pos, m_Direction, Curvature, Speed, Time);
}
void CProjectile::Tick()
{
float Pt = (Server()->Tick()-m_StartTick-1)/(float)Server()->TickSpeed();
@ -168,6 +167,61 @@ void CProjectile::Tick()
}
else if(pTargetChr && m_Freeze && ((m_Layer == LAYER_SWITCH && GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[pTargetChr->Team()]) || m_Layer != LAYER_SWITCH))
pTargetChr->Freeze();
if (pOwnerChar && ColPos && !GameLayerClipped(ColPos))
{
bool IsTeleValid = false;
switch (m_Type)
{
case WEAPON_GRENADE:
{
if (pOwnerChar->m_HasTeleGrenade)
IsTeleValid = true;
break;
}
case WEAPON_GUN:
{
if (pOwnerChar->m_HasTeleGun)
IsTeleValid = true;
break;
}
}
if (IsTeleValid)
{
int MapIndex = GameServer()->Collision()->GetPureMapIndex(round_to_int(pTargetChr ? pTargetChr->m_Pos.x : ColPos.x),
round_to_int(pTargetChr ? pTargetChr->m_Pos.y : ColPos.y));
int TileIndex = GameServer()->Collision()->GetTileIndex(MapIndex);
int TileFIndex = GameServer()->Collision()->GetFTileIndex(MapIndex);
bool IsTileValid = false;
if ((m_Type == WEAPON_GUN || m_Type == WEAPON_GRENADE) && (TileIndex != TILE_NO_TELE_GUN && TileFIndex != TILE_NO_TELE_GUN))
IsTileValid = true;
if (IsTileValid)
{
bool Found;
vec2 PossiblePos;
if (pTargetChr)
Found = GetNearestAirPosPlayer(pTargetChr->m_Pos, &PossiblePos);
else
Found = GetNearestAirPos(ColPos, &PossiblePos);
if (Found && PossiblePos)
{
GameServer()->CreateDeath(pOwnerChar->Core()->m_Pos, pOwnerChar->GetPlayer()->GetCID(),
(m_Owner != -1) ? TeamMask : -1LL);
pOwnerChar->Core()->m_Pos = PossiblePos;
pOwnerChar->Core()->m_Vel = vec2(0, 0);
GameServer()->CreateDeath(PossiblePos, pOwnerChar->GetPlayer()->GetCID(), (m_Owner != -1) ? TeamMask : -1LL);
GameServer()->CreateSound(PossiblePos, SOUND_WEAPON_SPAWN, (m_Owner != -1) ? TeamMask : -1LL);
}
}
}
}
if(Collide && m_Bouncing != 0)
{
m_StartTick = Server()->Tick();

View file

@ -54,3 +54,48 @@ bool CEntity::GameLayerClipped(vec2 CheckPos)
return round_to_int(CheckPos.x)/32 < -200 || round_to_int(CheckPos.x)/32 > GameServer()->Collision()->GetWidth()+200 ||
round_to_int(CheckPos.y)/32 < -200 || round_to_int(CheckPos.y)/32 > GameServer()->Collision()->GetHeight()+200 ? true : false;
}
bool CEntity::GetNearestAirPos(vec2 Pos, vec2* pOutPos)
{
vec2 PosInBlock = vec2(round_to_int(Pos.x) % 32, round_to_int(Pos.y) % 32);
vec2 BlockCenter = vec2(round_to_int(Pos.x), round_to_int(Pos.y)) - PosInBlock + vec2(16.0f, 16.0f);
float Size = 31.0f; // A bit less than the tile size
*pOutPos = vec2(BlockCenter.x + (PosInBlock.x < 16 ? -Size : Size), Pos.y);
if (!GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f)))
return true;
*pOutPos = vec2(BlockCenter.x + (PosInBlock.x < 16 ? -Size : Size), BlockCenter.y);
if (!GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f)))
return true;
*pOutPos = vec2(Pos.x, BlockCenter.y + (PosInBlock.y < 16 ? -Size : Size));
if (!GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f)))
return true;
*pOutPos = vec2(BlockCenter.x, BlockCenter.y + (PosInBlock.y < 16 ? -Size : Size));
if (!GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f)))
return true;
*pOutPos = vec2(BlockCenter.x + (PosInBlock.x < 16 ? -Size : Size),
BlockCenter.y + (PosInBlock.y < 16 ? -Size : Size));
if (!GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f)))
return true;
return false;
}
bool CEntity::GetNearestAirPosPlayer(vec2 PlayerPos, vec2* OutPos)
{
int dist = 5;
for (; dist >= -1; dist--)
{
*OutPos = vec2(PlayerPos.x, PlayerPos.y - dist);
if (!GameServer()->Collision()->TestBox(*OutPos, vec2(28.0f, 28.0f)))
{
return true;
}
}
return false;
}

View file

@ -163,6 +163,9 @@ public:
vec2 m_Pos;
// DDRace
bool GetNearestAirPos(vec2 Pos, vec2* OutPos);
bool GetNearestAirPosPlayer(vec2 PlayerPos, vec2* OutPos);
int m_Number;
int m_Layer;