FT collision part3: cleanup.

This commit is contained in:
Muzychenko Andrey 2023-03-05 14:16:07 +03:00
parent ba470e8727
commit 4b86fe2aa7
16 changed files with 144 additions and 202 deletions

View File

@ -211,7 +211,10 @@ void DebugOverlay::DrawBallInfo()
SDL_SetRenderDrawColor(winmain::Renderer, 0, 0, 255, 255);
auto pt1 = proj::xform_to_2d(ballPosition);
SDL_RenderDrawCircle(winmain::Renderer, pt1.X, pt1.Y, 10);
vector2 radVec1 = { 0, ballPosition.Y }, radVec2 = { ball->Radius, ballPosition.Y };
auto radVec1I = proj::xform_to_2d(radVec1), radVec2I = proj::xform_to_2d(radVec2);
auto radI = std::sqrt(maths::magnitudeSq(vector2i{ radVec1I.X - radVec2I.X ,radVec1I.Y - radVec2I.Y }));
SDL_RenderDrawCircle(winmain::Renderer, pt1.X, pt1.Y, static_cast<int>(std::round(radI)));
auto nextPos = ballPosition;
maths::vector_add(nextPos, maths::vector_mul(ball->Direction, ball->Speed / 10.0f));

View File

@ -41,7 +41,7 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
groupIndex = loader::query_handle(ballGroupName);
}
Offset = *loader::query_float_attribute(groupIndex, 0, 500);
Radius = *loader::query_float_attribute(groupIndex, 0, 500);
auto visualCount = loader::query_visual_states(groupIndex);
for (auto index = 0; index < visualCount; ++index)
@ -53,8 +53,8 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
VisualZArray[index] = zDepth;
}
RenderSprite = new render_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr);
PinballTable->CollisionCompOffset = Offset;
Position.Z = Offset;
PinballTable->CollisionCompOffset = Radius;
Position.Z = Radius;
GroupIndex = groupIndex;
}
@ -65,7 +65,7 @@ void TBall::Repaint()
Position.Z =
CollisionOffset.X * Position.X +
CollisionOffset.Y * Position.Y +
Offset + CollisionOffset.Z;
Radius + CollisionOffset.Z;
}
auto pos2D = proj::xform_to_2d(Position);
@ -120,7 +120,7 @@ int TBall::Message(MessageCode code, float value)
CollisionFlag = 0;
CollisionMask = 1;
Direction.Y = 0.0;
Position.Z = Offset;
Position.Z = Radius;
Direction.X = 0.0;
Speed = 0.0;
RayMaxDistance = 0.0;

View File

@ -32,10 +32,10 @@ public :
bool EdgeCollisionResetFlag{};
vector3 CollisionOffset{};
int CollisionFlag;
float Offset;
float Radius;
bool HasGroupFlag;
int SomeCounter1 = 0;
int time_ticks1{}, time_ticks2{};
int StuckCounter = 0;
int LastActiveTime{};
float VisualZArray[50]{};
bool AsEdgeCollisionFlag{};
};

View File

@ -126,19 +126,19 @@ void TFlipper::UpdateSprite()
SpriteSet(BmpIndex);
}
int TFlipper::GetFlipperAngleDistance(float dt, float* dst) const
int TFlipper::GetFlipperStepAngle(float dt, float* dst) const
{
if (!MessageField)
return 0;
auto deltaAngle = FlipperEdge->flipper_angle_delta(dt);
auto distance = std::fabs(std::ceil(FlipperEdge->DistanceDiv * deltaAngle * FlipperEdge->InvT1Radius));
if (distance > 3.0f)
distance = 3.0f;
if (distance >= 2.0f)
auto step = std::fabs(std::ceil(FlipperEdge->DistanceDiv * deltaAngle * FlipperEdge->InvT1Radius));
if (step > 3.0f)
step = 3.0f;
if (step >= 2.0f)
{
*dst = deltaAngle / distance;
return static_cast<int>(distance);
*dst = deltaAngle / step;
return static_cast<int>(step);
}
*dst = deltaAngle;
@ -152,7 +152,6 @@ void TFlipper::FlipperCollision(float deltaAngle)
ray_type ray{}, rayDst{};
ray.MinDistance = 0.002f;
auto deltaAngleNeg = -deltaAngle;
bool collisionFlag = false;
for (auto ball : pb::MainTable->BallList)
{
@ -167,7 +166,7 @@ void TFlipper::FlipperCollision(float deltaAngle)
float sin, cos;
auto ballPosRot = ray.Origin;
maths::SinCos(deltaAngleNeg, sin, cos);
maths::SinCos(-deltaAngle, sin, cos);
maths::RotatePt(ballPosRot, sin, cos, FlipperEdge->RotOrigin);
ray.Direction.X = ballPosRot.X - ray.Origin.X;
ray.Direction.Y = ballPosRot.Y - ray.Origin.Y;
@ -188,24 +187,18 @@ void TFlipper::FlipperCollision(float deltaAngle)
auto angleAdvance = deltaAngle / (std::fabs(FlipperEdge->MoveSpeed) * 5.0f);
FlipperEdge->CurrentAngle -= angleAdvance;
FlipperEdge->AngleRemainder += std::fabs(angleAdvance);
if (FlipperEdge->AngleRemainder <= 0.0001f)
{
FlipperEdge->CurrentAngle = FlipperEdge->AngleDst;
FlipperEdge->FlipperFlag = MessageCode::TFlipperNull;
MessageField = 0;
}
FlipperEdge->ControlPointDirtyFlag = true;
}
else
{
FlipperEdge->CurrentAngle += deltaAngle;
FlipperEdge->AngleRemainder -= std::fabs(deltaAngle);
if (FlipperEdge->AngleRemainder <= 0.0001f)
{
FlipperEdge->CurrentAngle = FlipperEdge->AngleDst;
FlipperEdge->FlipperFlag = MessageCode::TFlipperNull;
MessageField = 0;
}
FlipperEdge->ControlPointDirtyFlag = true;
}
if (FlipperEdge->AngleRemainder <= 0.0001f)
{
FlipperEdge->CurrentAngle = FlipperEdge->AngleDst;
FlipperEdge->FlipperFlag = MessageCode::TFlipperNull;
MessageField = 0;
}
FlipperEdge->ControlPointDirtyFlag = true;
}

View File

@ -14,7 +14,7 @@ public:
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
void UpdateSprite();
int GetFlipperAngleDistance(float dt, float* dst) const;
int GetFlipperStepAngle(float dt, float* dst) const;
void FlipperCollision(float deltaAngle);
int BmpIndex;

View File

@ -133,23 +133,24 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float distance)
return;
}
auto someProduct = (NextBallPosition.Y - T1.Y) * (RotOrigin.X - T1.X) -
(NextBallPosition.X - T1.X) * (RotOrigin.Y - T1.Y);
vector2 t1NextPos{NextBallPosition.X - T1.X, NextBallPosition.Y - T1.Y},
t1RotOrigin{RotOrigin.X - T1.X, RotOrigin.Y - T1.Y};
auto crossProduct = maths::cross(t1RotOrigin, t1NextPos);
bool someFlag = false;
if (someProduct <= 0)
bool frontCollision = false;
if (crossProduct <= 0)
{
if (AngleMax > 0)
someFlag = true;
frontCollision = true;
}
else if (AngleMax <= 0)
{
someFlag = true;
frontCollision = true;
}
if (FlipperFlag == MessageCode::TFlipperRetract)
{
someFlag ^= true;
frontCollision ^= true;
CollisionLinePerp = LineB.PerpendicularC;
}
else
@ -160,7 +161,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float distance)
auto dx = NextBallPosition.X - RotOrigin.X;
auto dy = NextBallPosition.Y - RotOrigin.Y;
auto distanceSq = dy * dy + dx * dx;
if (someFlag)
if (frontCollision)
{
float boost = 0;
if (circlebase.RadiusSq * 1.01f < distanceSq)
@ -204,7 +205,7 @@ void TFlipperEdge::place_in_grid(RectF* aabb)
TTableLayer::edges_insert_square(yMin, xMin, yMax, xMax, this, nullptr);
auto offset = 1.0f / InvT1Radius + pb::ball_min_smth;
auto offset = 1.0f / InvT1Radius + pb::BallHalfRadius;
XMin = xMin - offset;
YMin = yMin - offset;
XMax = xMax + offset;

View File

@ -611,7 +611,7 @@ TBall* TPinballTable::AddBall(float x, float y)
if (ball != nullptr)
{
ball->ActiveFlag = 1;
ball->Position.Z = ball->Offset;
ball->Position.Z = ball->Radius;
ball->Direction = {};
ball->Speed = 0;
ball->TimeDelta = 0;
@ -632,8 +632,8 @@ TBall* TPinballTable::AddBall(float x, float y)
ball->Position.X = x;
ball->Position.Y = y;
ball->PrevPosition = ball->Position;
ball->SomeCounter1 = 0;
ball->time_ticks1 = ball->time_ticks2 = pb::time_ticks;
ball->StuckCounter = 0;
ball->LastActiveTime = pb::time_ticks;
return ball;
}

View File

@ -144,7 +144,7 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
ball->RampFieldForce.X = plane->FieldForce.X;
ball->RampFieldForce.Y = plane->FieldForce.Y;
ball->Position.Z = ball->Position.X * ball->CollisionOffset.X + ball->Position.Y * ball->CollisionOffset.Y +
ball->Offset + ball->CollisionOffset.Z;
ball->Radius + ball->CollisionOffset.Z;
ball->CollisionMask = CollisionGroup;
return;
}
@ -164,13 +164,13 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
{
ball->CollisionMask = Wall1CollisionGroup;
if (BallZOffsetFlag)
ball->Position.Z = ball->Offset + Wall1BallOffset;
ball->Position.Z = ball->Radius + Wall1BallOffset;
}
else
{
ball->CollisionMask = Wall2CollisionGroup;
if (BallZOffsetFlag)
ball->Position.Z = ball->Offset + Wall2BallOffset;
ball->Position.Z = ball->Radius + Wall2BallOffset;
}
}
}

View File

@ -7,6 +7,7 @@
#include "render.h"
#include "TPinballTable.h"
#include "TBall.h"
#include "TDrain.h"
#include "timer.h"
TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
@ -59,7 +60,7 @@ void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
{
if (PinballTable->TiltLockFlag)
{
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
PinballTable->Drain->Collision(ball, nextPosition, direction, distance, edge);
}
else
{

View File

@ -1063,13 +1063,13 @@ void control::cheat_bump_rank()
}
}
void control::BallThrowOrDisable(TBall& ball, int dt)
void control::UnstuckBall(TBall& ball, int dt)
{
if (!CheckBallInControlBounds(ball, *flip1) &&
!CheckBallInControlBounds(ball, *flip2) &&
!CheckBallInControlBounds(ball, *plunger))
{
if (ball.SomeCounter1 <= 20)
if (ball.StuckCounter <= 20)
{
vector3 throwDir{0.0f, -1.0f, 0.0f};
ball.throw_ball(&throwDir, 90.0f, 1.0f, 0.0f);

View File

@ -89,7 +89,7 @@ public:
static void table_set_multiball(float time);
static void table_bump_ball_sink_lock();
static void table_set_replay(float value);
static void BallThrowOrDisable(TBall& ball, int dt);
static void UnstuckBall(TBall& ball, int dt);
static bool CheckBallInControlBounds(const TBall& ball, const TCollisionComponent& cmp);
static void cheat_bump_rank();
static int SpecialAddScore(int score);

View File

@ -222,6 +222,11 @@ float maths::magnitudeSq(const vector2& vec)
return vec.X * vec.X + vec.Y * vec.Y;
}
int maths::magnitudeSq(const vector2i& vec)
{
return vec.X * vec.X + vec.Y * vec.Y;
}
void maths::vector_add(vector2& vec1Dst, const vector2& vec2)
{
vec1Dst.X += vec2.X;

View File

@ -53,7 +53,6 @@ struct ray_type
float MaxDistance;
float MinDistance;
float TimeNow;
float TimeDelta;
int CollisionMask;
};
@ -115,6 +114,7 @@ public:
static float cross(const vector2& vec1, const vector2& vec2);
static float magnitude(const vector3& vec);
static float magnitudeSq(const vector2& vec);
static int magnitudeSq(const vector2i& vec);
static void vector_add(vector2& vec1Dst, const vector2& vec2);
static vector2 vector_sub(const vector2& vec1, const vector2& vec2);
static vector3 vector_sub(const vector3& vec1, const vector3& vec2);

View File

@ -33,7 +33,7 @@ DatFile* pb::record_table = nullptr;
int pb::time_ticks = 0;
GameModes pb::game_mode = GameModes::GameOver;
float pb::time_now = 0, pb::time_next = 0, pb::time_ticks_remainder = 0;
float pb::ball_speed_limit, pb::ball_min_smth, pb::ball_inv_smth, pb::ball_collision_dist;
float pb::BallMaxSpeed, pb::BallHalfRadius, pb::ball_collision_dist;
bool pb::FullTiltMode = false, pb::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false;
std::string pb::DatFileName, pb::BasePath;
ImU32 pb::TextBoxColor;
@ -104,10 +104,9 @@ int pb::init()
high_score::read();
auto ball = MainTable->BallList.at(0);
ball_speed_limit = ball->Offset * 200.0f;
ball_min_smth = ball->Offset * 0.5f;
ball_inv_smth = 1.0f / ball_min_smth;
ball_collision_dist = (ball->Offset + ball_min_smth) * 2.0f;
BallMaxSpeed = ball->Radius * 200.0f;
BallHalfRadius = ball->Radius * 0.5f;
ball_collision_dist = (ball->Radius + BallHalfRadius) * 2.0f;
int red = 255, green = 255, blue = 255;
auto fontColor = get_rc_string(Msg::TextBoxColor);
@ -272,6 +271,7 @@ void pb::ballset(float dx, float dy)
ball->Direction.X = dx * sensitivity;
ball->Direction.Y = dy * sensitivity;
ball->Speed = maths::normalize_2d(ball->Direction);
ball->LastActiveTime = time_ticks;
}
}
}
@ -320,158 +320,141 @@ void pb::frame(float dtMilliSec)
void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
{
vector2 vec1{}, vec2{};
for (auto ball : MainTable->BallList)
{
if (!ball->ActiveFlag || ball->HasGroupFlag || ball->CollisionComp || ball->Speed >= 0.8f)
{
if (ball->SomeCounter1 > 0)
if (ball->StuckCounter > 0)
{
vector2 dxy{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
auto offsetX2 = ball->Offset * 2.0f;
if (offsetX2 * offsetX2 < maths::magnitudeSq(dxy))
ball->SomeCounter1 = 0;
vector2 dist{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
auto radiusX2 = ball->Radius * 2.0f;
if (radiusX2 * radiusX2 < maths::magnitudeSq(dist))
ball->StuckCounter = 0;
}
ball->time_ticks1 = ball->time_ticks2 = time_ticks;
ball->LastActiveTime = time_ticks;
}
else if (time_ticks - ball->time_ticks2 > 500)
else if (time_ticks - ball->LastActiveTime > 500)
{
vector2 dxy{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
auto offsetD2 = ball->Offset / 2.0f;
vector2 dist{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
auto radiusD2 = ball->Radius / 2.0f;
ball->PrevPosition = ball->Position;
if (offsetD2 * offsetD2 < maths::magnitudeSq(dxy))
ball->SomeCounter1 = 0;
if (radiusD2 * radiusD2 < maths::magnitudeSq(dist))
ball->StuckCounter = 0;
else
ball->SomeCounter1++;
control::BallThrowOrDisable(*ball, time_ticks - ball->time_ticks1);
ball->StuckCounter++;
control::UnstuckBall(*ball, time_ticks - ball->LastActiveTime);
}
}
int distanceCoefArray[20]{-1};
float distanceArray[20]{}, distanceArrayX[20]{}, distanceArrayY[20]{};
int minDistanceCoef = -1;
int ballSteps[20]{-1};
float ballStepsDistance[20]{};
int maxStep = -1;
for (auto index = 0u; index < MainTable->BallList.size(); index++)
{
auto ball = MainTable->BallList[index];
if (ball->ActiveFlag != 0)
{
vector2 vecDst{};
ball->TimeDelta = timeDelta;
if (ball->TimeDelta > 0.01f && ball->Speed < 0.8f)
ball->TimeDelta = 0.01f;
ball->AsEdgeCollisionFlag = false;
if (ball->CollisionComp)
{
ball->CollisionComp->FieldEffect(ball, &vec1);
ball->CollisionComp->FieldEffect(ball, &vecDst);
}
else
{
if (MainTable->ActiveFlag)
{
vec2.X = 0.0;
vec2.Y = 0.0;
TTableLayer::edge_manager->FieldEffects(ball, &vec2);
vec2.X = vec2.X * timeDelta;
vec2.Y = vec2.Y * timeDelta;
ball->Direction.X = ball->Speed * ball->Direction.X;
ball->Direction.Y = ball->Speed * ball->Direction.Y;
maths::vector_add(ball->Direction, vec2);
ball->Speed = maths::normalize_2d(ball->Direction);
if (ball->Speed > ball_speed_limit)
ball->Speed = ball_speed_limit;
TTableLayer::edge_manager->FieldEffects(ball, &vecDst);
vecDst.X *= timeDelta;
vecDst.Y *= timeDelta;
ball->Direction.X *= ball->Speed;
ball->Direction.Y *= ball->Speed;
maths::vector_add(ball->Direction, vecDst);
ball->Speed = maths::normalize_2d(ball->Direction);
if (ball->Speed > BallMaxSpeed)
ball->Speed = BallMaxSpeed;
distanceArray[index] = ball->Speed * ball->TimeDelta;
auto distanceCoef = static_cast<int>(std::ceil(distanceArray[index] * ball_inv_smth)) - 1;
distanceCoefArray[index] = distanceCoef;
if (distanceCoef >= 0)
{
distanceArrayX[index] = ball->Direction.X * ball_min_smth;
distanceArrayY[index] = ball->Direction.Y * ball_min_smth;
if (distanceCoef > minDistanceCoef)
minDistanceCoef = distanceCoef;
}
}
ballStepsDistance[index] = ball->Speed * ball->TimeDelta;
auto ballStep = static_cast<int>(std::ceil(ballStepsDistance[index] / BallHalfRadius)) - 1;
ballSteps[index] = ballStep;
if (ballStep > maxStep)
maxStep = ballStep;
}
}
}
float deltaAngle[4]{};
int flipperSteps[4]{};
for (auto index = 0u; index < MainTable->FlipperList.size(); index++)
{
auto distanceCoef = MainTable->FlipperList[index]->GetFlipperAngleDistance(timeDelta, &deltaAngle[index]) - 1;
distanceArrayY[index] = static_cast<float>(distanceCoef);
if (distanceCoef > minDistanceCoef)
minDistanceCoef = distanceCoef;
auto flipStep = MainTable->FlipperList[index]->GetFlipperStepAngle(timeDelta, &deltaAngle[index]) - 1;
flipperSteps[index] = flipStep;
if (flipStep > maxStep)
maxStep = flipStep;
}
ray_type ray{};
ray.MinDistance = 0.002f;
for (auto index4 = 0; index4 <= minDistanceCoef; index4++)
for (auto step = 0; step <= maxStep; step++)
{
for (auto index5 = 0u; index5 < MainTable->BallList.size(); index5++)
for (auto ballIndex = 0u; ballIndex < MainTable->BallList.size(); ballIndex++)
{
auto ball = MainTable->BallList[index5];
if (!ball->AsEdgeCollisionFlag && index4 <= distanceCoefArray[index5])
auto ball = MainTable->BallList[ballIndex];
if (!ball->AsEdgeCollisionFlag && step <= ballSteps[ballIndex])
{
float distanceSum = 0.0f;
ray.CollisionMask = ball->CollisionMask;
ball->TimeNow = timeNow;
if (ball_min_smth > 0.0f)
for (auto distanceSum = 0.0f; distanceSum < BallHalfRadius;)
{
while (true)
ray.Origin = ball->Position;
ray.Direction = ball->Direction;
if (step >= ballSteps[ballIndex])
{
ray.Origin = ball->Position;
ray.Direction = ball->Direction;
if (index4 >= distanceCoefArray[index5])
{
ray.MaxDistance = distanceArray[index5] - distanceCoefArray[index5] * ball_min_smth;
}
else
{
ray.MaxDistance = ball_min_smth;
}
ray.TimeNow = ball->TimeNow;
ray.MaxDistance = ballStepsDistance[ballIndex] - ballSteps[ballIndex] * BallHalfRadius;
}
else
{
ray.MaxDistance = BallHalfRadius;
}
ray.TimeNow = ball->TimeNow;
TEdgeSegment* edge = nullptr;
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
if (distance > 0.0f)
{
// Todo: ball to ball collision
//distance = ball_to_ball_collision();
}
if (ball->EdgeCollisionResetFlag)
{
ball->EdgeCollisionResetFlag = false;
}
else
{
ball->EdgeCollisionCount = 0;
ball->EdgeCollisionResetFlag = true;
}
if (distance >= 1e9f)
{
ball->Position.X += ray.MaxDistance * ray.Direction.X;
ball->Position.Y += ray.MaxDistance * ray.Direction.Y;
break;
}
edge->EdgeCollision(ball, distance);
if (distance > 0.0f && !ball->AsEdgeCollisionFlag)
{
distanceSum += distance;
if (distanceSum < ball_min_smth)
continue;
}
TEdgeSegment* edge = nullptr;
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
if (distance > 0.0f)
{
// Todo: ball to ball collision
//distance = ball_to_ball_collision();
}
if (ball->EdgeCollisionResetFlag)
{
ball->EdgeCollisionResetFlag = false;
}
else
{
ball->EdgeCollisionCount = 0;
ball->EdgeCollisionResetFlag = true;
}
if (distance >= 1e9f)
{
ball->Position.X += ray.MaxDistance * ray.Direction.X;
ball->Position.Y += ray.MaxDistance * ray.Direction.Y;
break;
}
edge->EdgeCollision(ball, distance);
if (distance <= 0.0f || ball->AsEdgeCollisionFlag)
break;
distanceSum += distance;
}
}
}
for (auto index = 0u; index < MainTable->FlipperList.size(); index++)
for (auto flipIndex = 0u; flipIndex < MainTable->FlipperList.size(); flipIndex++)
{
if (distanceArrayY[index] >= index4)
MainTable->FlipperList[index]->FlipperCollision(deltaAngle[index]);
if (flipperSteps[flipIndex] >= step)
MainTable->FlipperList[flipIndex]->FlipperCollision(deltaAngle[flipIndex]);
}
}
@ -744,50 +727,6 @@ bool pb::chk_highscore()
return false;
}
float pb::collide(float timeNow, float timeDelta, TBall* ball)
{
ray_type ray{};
vector2 positionMod{};
if (ball->ActiveFlag && !ball->CollisionComp)
{
if (ball_speed_limit < ball->Speed)
ball->Speed = ball_speed_limit;
auto maxDistance = timeDelta * ball->Speed;
ball->TimeDelta = timeDelta;
ball->RayMaxDistance = maxDistance;
ball->TimeNow = timeNow;
ray.Origin = ball->Position;
ray.Direction = ball->Direction;
ray.MaxDistance = maxDistance;
ray.CollisionMask = ball->CollisionMask;
ray.TimeNow = timeNow;
ray.TimeDelta = timeDelta;
ray.MinDistance = 0.0020000001f;
TEdgeSegment* edge = nullptr;
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
ball->EdgeCollisionCount = 0;
if (distance >= 1000000000.0f)
{
maxDistance = timeDelta * ball->Speed;
ball->RayMaxDistance = maxDistance;
positionMod.X = maxDistance * ball->Direction.X;
positionMod.Y = maxDistance * ball->Direction.Y;
maths::vector_add(ball->Position, positionMod);
}
else
{
edge->EdgeCollision(ball, distance);
if (ball->Speed > 0.000000001f)
return fabs(distance / ball->Speed);
}
}
return timeDelta;
}
void pb::PushCheat(const std::string& cheat)
{
for (auto ch : cheat)

View File

@ -43,7 +43,7 @@ class pb
public:
static int time_ticks;
static float time_now, time_next, time_ticks_remainder;
static float ball_speed_limit, ball_min_smth, ball_inv_smth, ball_collision_dist;
static float BallMaxSpeed, BallHalfRadius, ball_collision_dist;
static GameModes game_mode;
static bool cheat_mode;
static DatFile* record_table;
@ -74,7 +74,6 @@ public:
static void high_scores();
static void tilt_no_more();
static bool chk_highscore();
static float collide(float timeNow, float timeDelta, TBall* ball);
static void PushCheat(const std::string& cheat);
static LPCSTR get_rc_string(Msg uID);
static int get_rc_int(Msg uID, int* dst);

View File

@ -786,6 +786,7 @@ void winmain::RenderUi()
ShowExitPopup = false;
pause(false);
ImGui::OpenPopup(exitText);
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
}
if (ImGui::BeginPopupModal(exitText, nullptr, ImGuiWindowFlags_AlwaysAutoResize))
{