Adding a checkpoint system for teleporters :

* Player go through a Checkpoint tile (29 in tele layer)
* He fall in a Check-Teleporter tile (31 in tele layer)
* Player is teleported to the check-TO (30 in tele layer) that have the same number as the last Checkpoint.
Thus players are teleported to the last checkpoint he passed, regardless of whether he made ​​the map in the right direction or not.

Tele tileset may need some improvement.
Closes Pull Request #52
This commit is contained in:
Romain Labolle 2011-05-18 01:12:39 +02:00 committed by GreYFoX
parent 813f689957
commit 38f1db1c4f
12 changed files with 110 additions and 34 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -108,7 +108,7 @@ void CCollision::Init(class CLayers *pLayers)
}
// DDRace tiles
if(Index == TILE_THROUGH || (Index >= TILE_FREEZE && Index <= TILE_UNFREEZE) || (Index >= TILE_SWITCHOPEN && Index <= TILE_BOOST) || (Index >= TILE_BEGIN && Index <= TILE_STOPA) || Index == TILE_CP || Index == TILE_CP_F || (Index >= TILE_OLDLASER && Index <= TILE_NPH) || (Index >= TILE_EHOOK_START && Index <= TILE_EHOOK_END) || (Index >= TILE_DFREEZE && Index <= TILE_DUNFREEZE))
if(Index == TILE_THROUGH || (Index >= TILE_FREEZE && Index <= TILE_UNFREEZE) || (Index >= TILE_SWITCHOPEN && Index <= TILE_TELECHECKIN) || (Index >= TILE_BEGIN && Index <= TILE_STOPA) || Index == TILE_CP || Index == TILE_CP_F || (Index >= TILE_OLDLASER && Index <= TILE_NPH) || (Index >= TILE_EHOOK_START && Index <= TILE_EHOOK_END) || (Index >= TILE_DFREEZE && Index <= TILE_DUNFREEZE))
m_pFront[i].m_Index = Index;
}
}
@ -134,7 +134,7 @@ void CCollision::Init(class CLayers *pLayers)
}
// DDRace tiles
if(Index == TILE_THROUGH || (Index >= TILE_FREEZE && Index <= TILE_UNFREEZE) || (Index >= TILE_SWITCHOPEN && Index <= TILE_BOOST) || (Index >= TILE_BEGIN && Index <= TILE_STOPA) || Index == TILE_CP || Index == TILE_CP_F || (Index >= TILE_OLDLASER && Index <= TILE_NPH) || (Index >= TILE_EHOOK_START && Index <= TILE_EHOOK_END) || (Index >= TILE_DFREEZE && Index <= TILE_DUNFREEZE))
if(Index == TILE_THROUGH || (Index >= TILE_FREEZE && Index <= TILE_UNFREEZE) || (Index >= TILE_SWITCHOPEN && Index <= TILE_TELECHECKIN) || (Index >= TILE_BEGIN && Index <= TILE_STOPA) || Index == TILE_CP || Index == TILE_CP_F || (Index >= TILE_OLDLASER && Index <= TILE_NPH) || (Index >= TILE_EHOOK_START && Index <= TILE_EHOOK_END) || (Index >= TILE_DFREEZE && Index <= TILE_DUNFREEZE))
m_pTiles[i].m_Index = Index;
}
}
@ -408,6 +408,33 @@ int CCollision::IsEvilTeleport(int Index)
return 0;
}
int CCollision::IsCheckTeleport(int Index)
{
if(Index < 0)
return 0;
if(!m_pTele)
return 0;
if(m_pTele[Index].m_Type == TILE_TELECHECKIN)
return m_pTele[Index].m_Number;
return 0;
}
int CCollision::IsTCheckpoint(int Index)
{
if(Index < 0)
return 0;
if(!m_pTele)
return 0;
if(m_pTele[Index].m_Type == TILE_TELECHECK)
return m_pTele[Index].m_Number;
return 0;
}
int CCollision::IsSpeedup(int Index)
{
if(Index < 0 || !m_pSpeedup)
@ -481,28 +508,6 @@ int CCollision::IsMover(int x, int y, int* Flags)
return 0;
}
int CCollision::IsCheckpoint(int Index)
{
if(Index < 0)
return -1;
int z = m_pTiles[Index].m_Index;
if(z >= 35 && z <= 59)
return z-35;
return -1;
}
int CCollision::IsFCheckpoint(int Index)
{
if(Index < 0 || !m_pFront)
return -1;
int z = m_pFront[Index].m_Index;
if(z >= 35 && z <= 59)
return z-35;
return -1;
}
vec2 CCollision::CpSpeed(int Index, int Flags)
{
if(Index < 0)
@ -552,7 +557,7 @@ bool CCollision::TileExists(int Index)
return true;
if(m_pFront && m_pFront[Index].m_Index >= TILE_FREEZE && m_pFront[Index].m_Index <= TILE_NPH)
return true;
if(m_pTele && (m_pTele[Index].m_Type == TILE_TELEIN || m_pTele[Index].m_Type == TILE_TELEINEVIL))
if(m_pTele && (m_pTele[Index].m_Type == TILE_TELEIN || m_pTele[Index].m_Type == TILE_TELEINEVIL || m_pTele[Index].m_Type == TILE_TELECHECK || m_pTele[Index].m_Type == TILE_TELECHECKIN))
return true;
if(m_pSpeedup && m_pSpeedup[Index].m_Force > 0)
return true;
@ -950,3 +955,25 @@ int CCollision::IntersectAir(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pO
*pOutBeforeCollision = Pos1;
return 0;
}
int CCollision::IsCheckpoint(int Index)
{
if(Index < 0)
return -1;
int z = m_pTiles[Index].m_Index;
if(z >= 35 && z <= 59)
return z-35;
return -1;
}
int CCollision::IsFCheckpoint(int Index)
{
if(Index < 0 || !m_pFront)
return -1;
int z = m_pFront[Index].m_Index;
if(z >= 35 && z <= 59)
return z-35;
return -1;
}

View file

@ -71,6 +71,8 @@ public:
int GetFTileFlags(int Index);
int IsTeleport(int Index);
int IsEvilTeleport(int Index);
int IsCheckTeleport(int Index);
int IsTCheckpoint(int Index);
//int IsCheckpoint(int Index);
int IsSpeedup(int Index);
void GetSpeedup(int Index, vec2 *Dir, int *Force, int *MaxSpeed);

View file

@ -615,6 +615,12 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = TILE_TELEINEVIL;
else if(((CLayerTele*)pTiles)->m_pTeleTile[i].m_Type == TILE_TELEOUT)
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = TILE_TELEOUT;
else if(((CLayerTele*)pTiles)->m_pTeleTile[i].m_Type == TILE_TELECHECK)
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = TILE_TELECHECK;
else if(((CLayerTele*)pTiles)->m_pTeleTile[i].m_Type == TILE_TELECHECKIN)
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = TILE_TELECHECKIN;
else if(((CLayerTele*)pTiles)->m_pTeleTile[i].m_Type == TILE_TELECHECKOUT)
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = TILE_TELECHECKOUT;
else
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = 0;
}

View file

@ -173,7 +173,7 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
for(int x = 0; x < r.w; x++)
{
pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x] = ((CLayerTele*)this)->m_pTeleTile[(r.y+y)*m_Width+(r.x+x)];
if(pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEIN || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEOUT || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEINEVIL)
if(pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEIN || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEOUT || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEINEVIL || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELECHECK || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELECHECKOUT || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELECHECKIN)
m_pEditor->m_TeleNumber = pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Number;
}
pGrabbed->m_TeleNum = m_pEditor->m_TeleNumber;
@ -313,7 +313,7 @@ void CLayerTiles::BrushDraw(CLayer *pBrush, float wx, float wy)
continue;
// dont allow tele in/out, speedup and switch tiles in game layer
if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pGameLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINEVIL || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET)))
if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pGameLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINEVIL || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECK || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECKOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECKIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET)))
continue;
m_pTiles[fy*m_Width+fx] = l->m_pTiles[y*l->m_Width+x];
@ -697,7 +697,7 @@ void CLayerTele::BrushDraw(CLayer *pBrush, float wx, float wy)
if(fx<0 || fx >= m_Width || fy < 0 || fy >= m_Height)
continue;
if(l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINEVIL || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT)
if(l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINEVIL || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECK || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECKOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECKIN)
{
if(m_pEditor->m_TeleNumber != l->m_TeleNum)
{
@ -1159,7 +1159,7 @@ void CLayerFront::BrushDraw(CLayer *pBrush, float wx, float wy)
continue;
// dont allow tele in and out tiles... same with speedup tile and alot more in front
if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pFrontLayer && ((l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINEVIL || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET)) || l->m_pTiles[y*l->m_Width+x].m_Index == (TILE_SOLID) || l->m_pTiles[y*l->m_Width+x].m_Index == (TILE_NOHOOK) || l->m_pTiles[y*l->m_Width+x].m_Index ==TILE_CP || l->m_pTiles[y*l->m_Width+x].m_Index ==TILE_CP_F))
if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pFrontLayer && ((l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINEVIL || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECK || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECKOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELECHECKIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDOPEN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_SWITCHTIMEDCLOSE || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET)) || l->m_pTiles[y*l->m_Width+x].m_Index == (TILE_SOLID) || l->m_pTiles[y*l->m_Width+x].m_Index == (TILE_NOHOOK) || l->m_pTiles[y*l->m_Width+x].m_Index ==TILE_CP || l->m_pTiles[y*l->m_Width+x].m_Index ==TILE_CP_F))
continue;
m_pTiles[fy*m_Width+fx] = l->m_pTiles[y*l->m_Width+x];
}

View file

@ -103,6 +103,9 @@ enum
TILE_TELEIN,
TILE_TELEOUT,
TILE_BOOST,
TILE_TELECHECK,
TILE_TELECHECKOUT,
TILE_TELECHECKIN,
TILE_BEGIN = 33,
TILE_END,
TILE_STOP = 60,
@ -308,4 +311,4 @@ public:
int m_Number;
};
#endif
#endif

View file

@ -1338,6 +1338,9 @@ void CCharacter::HandleTiles(int Index)
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID());
}
}
int tcp = GameServer()->Collision()->IsTCheckpoint(MapIndex);
if(tcp)
m_TeleCheckpoint = tcp;
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())))
{
bool CanBegin = true;
@ -1481,6 +1484,30 @@ void CCharacter::HandleTiles(int Index)
m_Core.m_Vel = vec2(0,0);
return;
}
if(GameServer()->Collision()->IsCheckTeleport(MapIndex))
{
if(m_TeleCheckpoint && ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleCheckOuts[m_TeleCheckpoint-1].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 = (((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleCheckOuts[m_TeleCheckpoint-1].size());
m_Core.m_Pos = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleCheckOuts[m_TeleCheckpoint-1][(!Num)?Num:rand() % Num];
m_Core.m_HookPos = m_Core.m_Pos;
return;
}
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;
}
}
}
void CCharacter::DDRaceTick()
@ -1619,4 +1646,5 @@ void CCharacter::DDRaceInit()
}
m_DefEmote = EMOTE_NORMAL;
m_DefEmoteReset = -1;
m_TeleCheckpoint = 0;
}

View file

@ -165,6 +165,7 @@ public:
int m_StartTime;
int m_RefreshTime;
vec2 m_PrevPos;
int m_TeleCheckpoint;
int m_CpTick;
int m_CpActive;
float m_CpCurrent[25];

View file

@ -33,11 +33,16 @@ void CGameControllerDDRace::InitTeleporter()
for(int i = 0; i < Width*Height; i++)
{
if(GameServer()->Collision()->TeleLayer()[i].m_Number > 0
&& GameServer()->Collision()->TeleLayer()[i].m_Type == TILE_TELEOUT)
if(GameServer()->Collision()->TeleLayer()[i].m_Number > 0)
{
m_TeleOuts[GameServer()->Collision()->TeleLayer()[i].m_Number-1].push_back(vec2(i % GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16,
i/GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16));
if(GameServer()->Collision()->TeleLayer()[i].m_Type == TILE_TELEOUT)
{
m_TeleOuts[GameServer()->Collision()->TeleLayer()[i].m_Number-1].push_back(vec2(i % Width*32+16, i/Width*32+16));
}
else if(GameServer()->Collision()->TeleLayer()[i].m_Type == TILE_TELECHECKOUT)
{
m_TeleCheckOuts[GameServer()->Collision()->TeleLayer()[i].m_Number-1].push_back(vec2(i % Width*32+16, i/Width*32+16));
}
}
}
}

View file

@ -19,6 +19,7 @@ public:
CGameTeams m_Teams;
std::map < int , std::vector < vec2 > > m_TeleOuts;
std::map < int , std::vector < vec2 > > m_TeleCheckOuts;
void InitTeleporter();
virtual void Tick();

View file

@ -345,6 +345,7 @@ void CPlayer::LoadCharacter()
m_pCharacter->m_Super = m_PauseInfo.m_Super;
m_pCharacter->m_DeepFreeze = m_PauseInfo.m_DeepFreeze;
m_pCharacter->m_EndlessHook = m_PauseInfo.m_EndlessHook;
m_pCharacter->m_TeleCheckpoint = m_PauseInfo.m_TeleCheckpoint;
((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(GetCID(), m_PauseInfo.m_Team);
m_PauseInfo.m_Respawn = false;
m_InfoSaved = false;
@ -368,6 +369,7 @@ void CPlayer::SaveCharacter()
m_PauseInfo.m_EndlessHook = m_pCharacter->m_EndlessHook;
m_PauseInfo.m_Team = ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(GetCID());
m_PauseInfo.m_PauseTime = Server()->Tick();
m_PauseInfo.m_TeleCheckpoint = m_pCharacter->m_TeleCheckpoint;
//m_PauseInfo.m_RefreshTime = m_pCharacter->m_RefreshTime;
}

View file

@ -130,6 +130,7 @@ public:
bool m_EndlessHook;
int m_PauseTime;
int m_Team;
int m_TeleCheckpoint;
} m_PauseInfo;
bool m_InfoSaved;
void LoadCharacter();