diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp index 51c143a0a80..8e36abffe70 100644 --- a/src/game/client/components/mapimages.cpp +++ b/src/game/client/components/mapimages.cpp @@ -220,7 +220,7 @@ static bool IsValidTile(int LayerType, bool EntitiesAreMasked, EMapImageModType if(EntitiesModType == MAP_IMAGE_MOD_TYPE_DDNET || EntitiesModType == MAP_IMAGE_MOD_TYPE_DDRACE) { - if(EntitiesModType == MAP_IMAGE_MOD_TYPE_DDNET || TileIndex != TILE_BOOST) + if(EntitiesModType == MAP_IMAGE_MOD_TYPE_DDNET || TileIndex != TILE_SPEEDUP_OLD || TileIndex != TILE_SPEEDUP) { if(LayerType == MAP_IMAGE_ENTITY_LAYER_TYPE_ALL_EXCEPT_SWITCH && !IsValidGameTile(TileIndex) && diff --git a/src/game/client/prediction/entities/character.cpp b/src/game/client/prediction/entities/character.cpp index ddc188ff9ed..16e52c48932 100644 --- a/src/game/client/prediction/entities/character.cpp +++ b/src/game/client/prediction/entities/character.cpp @@ -641,56 +641,79 @@ void CCharacter::HandleSkippableTiles(int Index) if(Collision()->IsSpeedup(Index)) { vec2 Direction, TempVel = m_Core.m_Vel; - int Force, MaxSpeed = 0; - float TeeAngle, SpeederAngle, DiffAngle, SpeedLeft, TeeSpeed; - Collision()->GetSpeedup(Index, &Direction, &Force, &MaxSpeed); - if(Force == 255 && MaxSpeed) - { - m_Core.m_Vel = Direction * (MaxSpeed / 5); - } - else + int Force, Type, MaxSpeed = 0; + Collision()->GetSpeedup(Index, &Direction, &Force, &MaxSpeed, &Type); + + if(Type == TILE_SPEEDUP_OLD) // old buggy shitty spaghetti behavior { - if(MaxSpeed > 0 && MaxSpeed < 5) - MaxSpeed = 5; - if(MaxSpeed > 0) + float TeeAngle, SpeederAngle, DiffAngle, SpeedLeft, TeeSpeed; + if(Force == 255 && MaxSpeed) + { + m_Core.m_Vel = Direction * (MaxSpeed / 5); + } + else { - if(Direction.x > 0.0000001f) - SpeederAngle = -std::atan(Direction.y / Direction.x); - else if(Direction.x < 0.0000001f) - SpeederAngle = std::atan(Direction.y / Direction.x) + 2.0f * std::asin(1.0f); - else if(Direction.y > 0.0000001f) - SpeederAngle = std::asin(1.0f); + if(MaxSpeed > 0 && MaxSpeed < 5) + MaxSpeed = 5; + if(MaxSpeed > 0) + { + if(Direction.x > 0.0000001f) + SpeederAngle = -std::atan(Direction.y / Direction.x); + else if(Direction.x < 0.0000001f) + SpeederAngle = std::atan(Direction.y / Direction.x) + 2.0f * std::asin(1.0f); + else if(Direction.y > 0.0000001f) + SpeederAngle = std::asin(1.0f); + else + SpeederAngle = std::asin(-1.0f); + + if(SpeederAngle < 0) + SpeederAngle = 4.0f * std::asin(1.0f) + SpeederAngle; + + if(TempVel.x > 0.0000001f) + TeeAngle = -std::atan(TempVel.y / TempVel.x); + else if(TempVel.x < 0.0000001f) + TeeAngle = std::atan(TempVel.y / TempVel.x) + 2.0f * std::asin(1.0f); + else if(TempVel.y > 0.0000001f) + TeeAngle = std::asin(1.0f); + else + TeeAngle = std::asin(-1.0f); + + if(TeeAngle < 0) + TeeAngle = 4.0f * std::asin(1.0f) + TeeAngle; + + TeeSpeed = std::sqrt(std::pow(TempVel.x, 2) + std::pow(TempVel.y, 2)); + + DiffAngle = SpeederAngle - TeeAngle; + SpeedLeft = MaxSpeed / 5.0f - std::cos(DiffAngle) * TeeSpeed; + if(absolute((int)SpeedLeft) > Force && SpeedLeft > 0.0000001f) + TempVel += Direction * Force; + else if(absolute((int)SpeedLeft) > Force) + TempVel += Direction * -Force; + else + TempVel += Direction * SpeedLeft; + } else - SpeederAngle = std::asin(-1.0f); - - if(SpeederAngle < 0) - SpeederAngle = 4.0f * std::asin(1.0f) + SpeederAngle; + TempVel += Direction * Force; - if(TempVel.x > 0.0000001f) - TeeAngle = -std::atan(TempVel.y / TempVel.x); - else if(TempVel.x < 0.0000001f) - TeeAngle = std::atan(TempVel.y / TempVel.x) + 2.0f * std::asin(1.0f); - else if(TempVel.y > 0.0000001f) - TeeAngle = std::asin(1.0f); + m_Core.m_Vel = ClampVel(m_MoveRestrictions, TempVel); + } + } + else if(Type == TILE_SPEEDUP) + { + if(MaxSpeed == 0) + { + TempVel += Direction * Force; + } + else + { + // hardest to understand + float CurrentDirectionalSpeed = dot(Direction, m_Core.m_Vel); + float TempMaxSpeed = MaxSpeed / 5.0f; + if(CurrentDirectionalSpeed + Force > TempMaxSpeed) + TempVel += Direction * (TempMaxSpeed - CurrentDirectionalSpeed); else - TeeAngle = std::asin(-1.0f); - - if(TeeAngle < 0) - TeeAngle = 4.0f * std::asin(1.0f) + TeeAngle; - - TeeSpeed = std::sqrt(std::pow(TempVel.x, 2) + std::pow(TempVel.y, 2)); - - DiffAngle = SpeederAngle - TeeAngle; - SpeedLeft = MaxSpeed / 5.0f - std::cos(DiffAngle) * TeeSpeed; - if(absolute((int)SpeedLeft) > Force && SpeedLeft > 0.0000001f) TempVel += Direction * Force; - else if(absolute((int)SpeedLeft) > Force) - TempVel += Direction * -Force; - else - TempVel += Direction * SpeedLeft; } - else - TempVel += Direction * Force; m_Core.m_Vel = ClampVel(m_MoveRestrictions, TempVel); } } diff --git a/src/game/collision.cpp b/src/game/collision.cpp index 20ee5f188d9..bbaa101e851 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -741,12 +741,13 @@ int CCollision::IsTune(int Index) const return 0; } -void CCollision::GetSpeedup(int Index, vec2 *pDir, int *pForce, int *pMaxSpeed) const +void CCollision::GetSpeedup(int Index, vec2 *pDir, int *pForce, int *pMaxSpeed, int *pType) const { if(Index < 0 || !m_pSpeedup) return; float Angle = m_pSpeedup[Index].m_Angle * (pi / 180.0f); *pForce = m_pSpeedup[Index].m_Force; + *pType = m_pSpeedup[Index].m_Type; *pDir = direction(Angle); if(pMaxSpeed) *pMaxSpeed = m_pSpeedup[Index].m_MaxSpeed; diff --git a/src/game/collision.h b/src/game/collision.h index fef1b673a8b..4102063b026 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -93,7 +93,7 @@ class CCollision int IsTeleCheckpoint(int Index) const; int IsSpeedup(int Index) const; int IsTune(int Index) const; - void GetSpeedup(int Index, vec2 *pDir, int *pForce, int *pMaxSpeed) const; + void GetSpeedup(int Index, vec2 *pDir, int *pForce, int *pMaxSpeed, int *pType) const; int GetSwitchType(int Index) const; int GetSwitchNumber(int Index) const; int GetSwitchDelay(int Index) const; diff --git a/src/game/editor/explanations.cpp b/src/game/editor/explanations.cpp index f305e22cda8..0887231c899 100644 --- a/src/game/editor/explanations.cpp +++ b/src/game/editor/explanations.cpp @@ -137,13 +137,15 @@ const char *CEditor::ExplainDDNet(int Tile, int Layer) if(Layer == LAYER_TELE) return "TELEPORT TO: Destination tile for FROMs, WEAPON & HOOK TELEPORTs with the same numbers."; break; - case TILE_BOOST: + case TILE_SPEEDUP_OLD: if(Layer == LAYER_SPEEDUP) - return "SPEEDUP: Gives tee defined speed. Arrow shows direction and angle."; + return "OLD SPEEDUP: Gives tee defined speed. Arrow shows direction and angle. Deprecated."; break; - case TILE_TELECHECK: + case TILE_TELECHECK: // also TILE_SPEEDUP if(Layer == LAYER_TELE) return "CHECKPOINT TELEPORT: After having touched this tile, any CFRM will teleport you to CTO with the same number."; + if(Layer == LAYER_SPEEDUP) + return "SPEEDUP: Gives tee defined speed. Arrow shows direction and angle."; break; case TILE_TELECHECKOUT: if(Layer == LAYER_TELE) diff --git a/src/game/mapitems.cpp b/src/game/mapitems.cpp index 2abd7468e3f..e1f915f387d 100644 --- a/src/game/mapitems.cpp +++ b/src/game/mapitems.cpp @@ -78,7 +78,7 @@ bool IsTeleTileNumberUsedAny(int Index) bool IsValidSpeedupTile(int Index) { - return Index == TILE_BOOST; + return Index == TILE_SPEEDUP_OLD || Index == TILE_SPEEDUP; } bool IsValidSwitchTile(int Index) diff --git a/src/game/mapitems.h b/src/game/mapitems.h index 5ba34314d47..e718bf056fa 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -128,8 +128,9 @@ enum TILE_SWITCHCLOSE, TILE_TELEIN, TILE_TELEOUT, - TILE_BOOST, - TILE_TELECHECK, + TILE_SPEEDUP_OLD = 28, + TILE_SPEEDUP, + TILE_TELECHECK = 29, TILE_TELECHECKOUT, TILE_TELECHECKIN, TILE_REFILL_JUMPS = 32, diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 46f81054954..a6dd3d6be00 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -1417,57 +1417,79 @@ void CCharacter::HandleSkippableTiles(int Index) if(Collision()->IsSpeedup(Index)) { vec2 Direction, TempVel = m_Core.m_Vel; - int Force, MaxSpeed = 0; - float TeeAngle, SpeederAngle, DiffAngle, SpeedLeft, TeeSpeed; - Collision()->GetSpeedup(Index, &Direction, &Force, &MaxSpeed); - if(Force == 255 && MaxSpeed) - { - m_Core.m_Vel = Direction * (MaxSpeed / 5); - } - else + int Force, Type, MaxSpeed = 0; + Collision()->GetSpeedup(Index, &Direction, &Force, &MaxSpeed, &Type); + + if(Type == TILE_SPEEDUP_OLD) { - if(MaxSpeed > 0 && MaxSpeed < 5) - MaxSpeed = 5; - if(MaxSpeed > 0) + float TeeAngle, SpeederAngle, DiffAngle, SpeedLeft, TeeSpeed; + if(Force == 255 && MaxSpeed) + { + m_Core.m_Vel = Direction * (MaxSpeed / 5); + } + else { - if(Direction.x > 0.0000001f) - SpeederAngle = -std::atan(Direction.y / Direction.x); - else if(Direction.x < 0.0000001f) - SpeederAngle = std::atan(Direction.y / Direction.x) + 2.0f * std::asin(1.0f); - else if(Direction.y > 0.0000001f) - SpeederAngle = std::asin(1.0f); + if(MaxSpeed > 0 && MaxSpeed < 5) + MaxSpeed = 5; + if(MaxSpeed > 0) + { + if(Direction.x > 0.0000001f) + SpeederAngle = -std::atan(Direction.y / Direction.x); + else if(Direction.x < 0.0000001f) + SpeederAngle = std::atan(Direction.y / Direction.x) + 2.0f * std::asin(1.0f); + else if(Direction.y > 0.0000001f) + SpeederAngle = std::asin(1.0f); + else + SpeederAngle = std::asin(-1.0f); + + if(SpeederAngle < 0) + SpeederAngle = 4.0f * std::asin(1.0f) + SpeederAngle; + + if(TempVel.x > 0.0000001f) + TeeAngle = -std::atan(TempVel.y / TempVel.x); + else if(TempVel.x < 0.0000001f) + TeeAngle = std::atan(TempVel.y / TempVel.x) + 2.0f * std::asin(1.0f); + else if(TempVel.y > 0.0000001f) + TeeAngle = std::asin(1.0f); + else + TeeAngle = std::asin(-1.0f); + + if(TeeAngle < 0) + TeeAngle = 4.0f * std::asin(1.0f) + TeeAngle; + + TeeSpeed = std::sqrt(std::pow(TempVel.x, 2) + std::pow(TempVel.y, 2)); + + DiffAngle = SpeederAngle - TeeAngle; + SpeedLeft = MaxSpeed / 5.0f - std::cos(DiffAngle) * TeeSpeed; + if(absolute((int)SpeedLeft) > Force && SpeedLeft > 0.0000001f) + TempVel += Direction * Force; + else if(absolute((int)SpeedLeft) > Force) + TempVel += Direction * -Force; + else + TempVel += Direction * SpeedLeft; + } else - SpeederAngle = std::asin(-1.0f); - - if(SpeederAngle < 0) - SpeederAngle = 4.0f * std::asin(1.0f) + SpeederAngle; + TempVel += Direction * Force; - if(TempVel.x > 0.0000001f) - TeeAngle = -std::atan(TempVel.y / TempVel.x); - else if(TempVel.x < 0.0000001f) - TeeAngle = std::atan(TempVel.y / TempVel.x) + 2.0f * std::asin(1.0f); - else if(TempVel.y > 0.0000001f) - TeeAngle = std::asin(1.0f); + m_Core.m_Vel = ClampVel(m_MoveRestrictions, TempVel); + } + } + else if(Type == TILE_SPEEDUP) + { + if(MaxSpeed == 0) + { + TempVel += Direction * Force; + } + else + { + // hardest to understand + float CurrentDirectionalSpeed = dot(Direction, m_Core.m_Vel); + float TempMaxSpeed = MaxSpeed / 5.0f; + if(CurrentDirectionalSpeed + Force > TempMaxSpeed) + TempVel += Direction * (TempMaxSpeed - CurrentDirectionalSpeed); else - TeeAngle = std::asin(-1.0f); - - if(TeeAngle < 0) - TeeAngle = 4.0f * std::asin(1.0f) + TeeAngle; - - TeeSpeed = std::sqrt(std::pow(TempVel.x, 2) + std::pow(TempVel.y, 2)); - - DiffAngle = SpeederAngle - TeeAngle; - SpeedLeft = MaxSpeed / 5.0f - std::cos(DiffAngle) * TeeSpeed; - if(absolute((int)SpeedLeft) > Force && SpeedLeft > 0.0000001f) TempVel += Direction * Force; - else if(absolute((int)SpeedLeft) > Force) - TempVel += Direction * -Force; - else - TempVel += Direction * SpeedLeft; } - else - TempVel += Direction * Force; - m_Core.m_Vel = ClampVel(m_MoveRestrictions, TempVel); } }