mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 01:24:18 +00:00
add teleport gun/grenade/laser
This commit is contained in:
parent
498f2fe7ac
commit
50c84a60f7
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 |
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ private:
|
|||
vec2 m_PrevPos;
|
||||
int m_Type;
|
||||
int m_TuneZone;
|
||||
bool m_TeleportCancelled;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue