mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
FT collision part3: cleanup.
This commit is contained in:
parent
ba470e8727
commit
4b86fe2aa7
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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{};
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user