diff --git a/data/editor/tele.png b/data/editor/tele.png index 29ec67d31..5a046fb0b 100644 Binary files a/data/editor/tele.png and b/data/editor/tele.png differ diff --git a/src/game/collision.cpp b/src/game/collision.cpp index fecc75a32..6dad5f361 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -526,6 +526,19 @@ int CCollision::IsCheckTeleport(int Index) return 0; } +int CCollision::IsCheckEvilTeleport(int Index) +{ + if(Index < 0) + return 0; + if(!m_pTele) + return 0; + + if(m_pTele[Index].m_Type == TILE_TELECHECKINEVIL) + return m_pTele[Index].m_Number; + + return 0; +} + int CCollision::IsTCheckpoint(int Index) { if(Index < 0) @@ -684,7 +697,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_START) 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_TELECHECK || m_pTele[Index].m_Type == TILE_TELECHECKIN)) + 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; if(m_pSpeedup && m_pSpeedup[Index].m_Force > 0) return true; diff --git a/src/game/collision.h b/src/game/collision.h index 55f16a236..68b91b33f 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -78,6 +78,7 @@ public: int IsTeleport(int Index); int IsEvilTeleport(int Index); int IsCheckTeleport(int Index); + int IsCheckEvilTeleport(int Index); int IsTeleportWeapon(int Index); int IsTeleportHook(int Index); int IsTCheckpoint(int Index); diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index e06db4150..67c43ffb7 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -709,6 +709,8 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag ((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_TELECHECKINEVIL) + ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = TILE_TELECHECKINEVIL; else if(((CLayerTele*)pTiles)->m_pTeleTile[i].m_Type == TILE_TELECHECKOUT) ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = TILE_TELECHECKOUT; else if(((CLayerTele*)pTiles)->m_pTeleTile[i].m_Type == TILE_TELEINWEAPON) diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index badac3f78..493248594 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -180,7 +180,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 || 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 || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEINWEAPON || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEINHOOK) + 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_TELECHECKINEVIL || 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 || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEINWEAPON || pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Type == TILE_TELEINHOOK) m_pEditor->m_TeleNumber = pGrabbed->m_pTeleTile[y*pGrabbed->m_Width+x].m_Number; } pGrabbed->m_TeleNum = m_pEditor->m_TeleNumber; @@ -762,7 +762,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 || 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_TELEINWEAPON || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINHOOK) + 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_TELECHECKINEVIL || 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_TELEINWEAPON || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEINHOOK) { if(m_pEditor->m_TeleNumber != l->m_TeleNum) { diff --git a/src/game/mapitems.h b/src/game/mapitems.h index 6624fc5d9..1d8887911 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -123,6 +123,7 @@ enum TILE_STOP = 60, TILE_STOPS, TILE_STOPA, + TILE_TELECHECKINEVIL = 63, TILE_CP = 64, TILE_CP_F, TILE_OLDLASER = 71, diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 5fa289a71..1d0d1088f 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -1574,6 +1574,42 @@ void CCharacter::HandleTiles(int Index) } return; } + if(GameServer()->Collision()->IsCheckEvilTeleport(MapIndex)) + { + if (m_Super) + return; + // 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--) + { + 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]; + GameWorld()->ReleaseHooked(GetPlayer()->GetCID()); + m_Core.m_Vel = vec2(0,0); + m_Core.m_HookPos = m_Core.m_Pos; + return; + } + } + // if no checkpointout have been found (or if there no recorded checkpoint), teleport to start + 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; + GameWorld()->ReleaseHooked(GetPlayer()->GetCID()); + m_Core.m_Vel = vec2(0,0); + m_Core.m_HookPos = m_Core.m_Pos; + } + return; + } if(GameServer()->Collision()->IsCheckTeleport(MapIndex)) { if (m_Super)