Renamed some collision variables.

This commit is contained in:
Muzychenko Andrey 2022-05-20 11:51:00 +03:00
parent 5461483bb5
commit 97aea20586
57 changed files with 162 additions and 173 deletions

View File

@ -19,7 +19,7 @@
gdrv_bitmap8* DebugOverlay::dbScreen = nullptr; gdrv_bitmap8* DebugOverlay::dbScreen = nullptr;
int SDL_RenderDrawCircle(SDL_Renderer* renderer, int x, int y, int radius) static int SDL_RenderDrawCircle(SDL_Renderer* renderer, int x, int y, int radius)
{ {
int offsetx, offsety, d; int offsetx, offsety, d;
int status; int status;
@ -184,7 +184,7 @@ void DebugOverlay::DrawBallInfo()
SDL_RenderDrawCircle(winmain::Renderer, pt1.X, pt1.Y, 10); SDL_RenderDrawCircle(winmain::Renderer, pt1.X, pt1.Y, 10);
auto nextPos = ballPosition; auto nextPos = ballPosition;
maths::vector_add(nextPos, maths::vector_mul(ball->Acceleration, ball->Speed / 10.0f)); maths::vector_add(nextPos, maths::vector_mul(ball->Direction, ball->Speed / 10.0f));
auto pt2 = proj::xform_to_2d(nextPos); auto pt2 = proj::xform_to_2d(nextPos);
SDL_RenderDrawLine(winmain::Renderer, pt1.X, pt1.Y, pt2.X, pt2.Y); SDL_RenderDrawLine(winmain::Renderer, pt1.X, pt1.Y, pt2.X, pt2.Y);
} }
@ -223,7 +223,7 @@ void DebugOverlay::DrawEdge(TEdgeSegment* edge)
break; break;
} }
} }
if (refBall != nullptr && (refBall->FieldFlag & edge->CollisionGroup) == 0) if (refBall != nullptr && (refBall->CollisionMask & edge->CollisionGroup) == 0)
return; return;
} }

View File

@ -21,13 +21,11 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
CollisionComp = nullptr; CollisionComp = nullptr;
EdgeCollisionCount = 0; EdgeCollisionCount = 0;
TimeDelta = 0.0; TimeDelta = 0.0;
FieldFlag = 1; CollisionMask = 1;
CollisionFlag = 0; CollisionFlag = 0;
Speed = 0.0; Speed = 0.0;
Acceleration.Y = 0.0; Direction.Y = 0.0;
Acceleration.X = 0.0; Direction.X = 0.0;
InvAcceleration.Y = 1000000000.0;
InvAcceleration.X = 1000000000.0;
Position.X = 0.0; Position.X = 0.0;
Position.Y = 0.0; Position.Y = 0.0;
@ -117,23 +115,23 @@ int TBall::Message(int code, float value)
Position.Y = 0.0; Position.Y = 0.0;
ActiveFlag = 0; ActiveFlag = 0;
CollisionFlag = 0; CollisionFlag = 0;
FieldFlag = 1; CollisionMask = 1;
Acceleration.Y = 0.0; Direction.Y = 0.0;
Position.Z = Offset; Position.Z = Offset;
Acceleration.X = 0.0; Direction.X = 0.0;
Speed = 0.0; Speed = 0.0;
RayMaxDistance = 0.0; RayMaxDistance = 0.0;
} }
return 0; return 0;
} }
void TBall::throw_ball(TBall* ball, vector3* acceleration, float angleMult, float speedMult1, float speedMult2) void TBall::throw_ball(TBall* ball, vector3* direction, float angleMult, float speedMult1, float speedMult2)
{ {
ball->CollisionComp = nullptr; ball->CollisionComp = nullptr;
ball->Acceleration = *acceleration; ball->Direction = *direction;
float rnd = RandFloat(); float rnd = RandFloat();
float angle = (1.0f - (rnd + rnd)) * angleMult; float angle = (1.0f - (rnd + rnd)) * angleMult;
maths::RotateVector(ball->Acceleration, angle); maths::RotateVector(ball->Direction, angle);
rnd = RandFloat(); rnd = RandFloat();
ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1; ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
} }

View File

@ -14,19 +14,18 @@ public :
bool already_hit(TEdgeSegment* edge); bool already_hit(TEdgeSegment* edge);
int Message(int code, float value) override; int Message(int code, float value) override;
static void throw_ball(TBall* ball, vector3* acceleration, float angleMult, float speedMult1, static void throw_ball(TBall* ball, vector3* direction, float angleMult, float speedMult1,
float speedMult2); float speedMult2);
vector3 Position{}; vector3 Position{};
vector3 Acceleration{}; vector3 Direction{};
float Speed; float Speed;
float RayMaxDistance; float RayMaxDistance;
float TimeDelta; float TimeDelta;
float TimeNow; float TimeNow;
vector2 InvAcceleration{};
vector2 RampFieldForce{}; vector2 RampFieldForce{};
TCollisionComponent* CollisionComp; TCollisionComponent* CollisionComp;
int FieldFlag; int CollisionMask;
TEdgeSegment* Collisions[5]{}; TEdgeSegment* Collisions[5]{};
int EdgeCollisionCount; int EdgeCollisionCount;
vector3 CollisionOffset{}; vector3 CollisionOffset{};

View File

@ -100,7 +100,7 @@ int TBumper::Message(int code, float value)
return 0; return 0;
} }
void TBumper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TBumper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
if (DefaultCollision(ball, nextPosition, direction)) if (DefaultCollision(ball, nextPosition, direction))
{ {

View File

@ -14,7 +14,7 @@ public:
TBumper(TPinballTable* table, int groupIndex); TBumper(TPinballTable* table, int groupIndex);
~TBumper() override = default; ~TBumper() override = default;
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;

View File

@ -17,16 +17,16 @@ float TCircle::FindCollisionDistance(ray_type* ray)
return maths::ray_intersect_circle(*ray, Circle); return maths::ray_intersect_circle(*ray, Circle);
} }
void TCircle::EdgeCollision(TBall* ball, float coef) void TCircle::EdgeCollision(TBall* ball, float distance)
{ {
vector2 direction{}, nextPosition{}; vector2 direction{}, nextPosition{};
nextPosition.X = coef * ball->Acceleration.X + ball->Position.X; nextPosition.X = distance * ball->Direction.X + ball->Position.X;
nextPosition.Y = coef * ball->Acceleration.Y + ball->Position.Y; nextPosition.Y = distance * ball->Direction.Y + ball->Position.Y;
direction.X = nextPosition.X - Circle.Center.X; direction.X = nextPosition.X - Circle.Center.X;
direction.Y = nextPosition.Y - Circle.Center.Y; direction.Y = nextPosition.Y - Circle.Center.Y;
maths::normalize_2d(direction); maths::normalize_2d(direction);
CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this); CollisionComponent->Collision(ball, &nextPosition, &direction, distance, this);
} }
void TCircle::place_in_grid() void TCircle::place_in_grid()

View File

@ -11,6 +11,6 @@ public:
TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, vector2* center, TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, vector2* center,
float radius); float radius);
float FindCollisionDistance(ray_type* ray) override; float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override; void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override; void place_in_grid() override;
}; };

View File

@ -74,7 +74,7 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector2* nextPosition, ve
} }
void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2* direction, void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2* direction,
float coef, TEdgeSegment* edge) float distance, TEdgeSegment* edge)
{ {
int soundIndex; int soundIndex;

View File

@ -19,7 +19,7 @@ public:
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall); TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
~TCollisionComponent() override; ~TCollisionComponent() override;
void port_draw() override; void port_draw() override;
virtual void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, virtual void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge); TEdgeSegment* edge);
virtual int FieldEffect(TBall* ball, vector2* vecDst); virtual int FieldEffect(TBall* ball, vector2* vecDst);
int DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction); int DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction);

View File

@ -93,12 +93,12 @@ int TDemo::Message(int code, float value)
return 0; return 0;
} }
void TDemo::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TDemo::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
ball->not_again(edge); ball->not_again(edge);
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef; ball->RayMaxDistance -= distance;
switch (reinterpret_cast<size_t>(edge->WallValue)) switch (reinterpret_cast<size_t>(edge->WallValue))
{ {

View File

@ -7,7 +7,7 @@ class TDemo :
public: public:
TDemo(TPinballTable* table, int groupIndex); TDemo(TPinballTable* table, int groupIndex);
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void PlungerRelease(int timerId, void* caller); static void PlungerRelease(int timerId, void* caller);

View File

@ -28,7 +28,7 @@ int TDrain::Message(int code, float value)
return 0; return 0;
} }
void TDrain::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TDrain::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
ball->Message(1024, 0.0); ball->Message(1024, 0.0);
PinballTable->BallInSink = 1; PinballTable->BallInSink = 1;

View File

@ -7,7 +7,7 @@ class TDrain :
public: public:
TDrain(TPinballTable* table, int groupIndex); TDrain(TPinballTable* table, int groupIndex);
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void TimerCallback(int timerId, void* caller); static void TimerCallback(int timerId, void* caller);

View File

@ -74,7 +74,7 @@ int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeD
for (auto it = edgeBox->EdgeList.rbegin(); it != edgeBox->EdgeList.rend(); ++it) for (auto it = edgeBox->EdgeList.rbegin(); it != edgeBox->EdgeList.rend(); ++it)
{ {
auto edge = *it; auto edge = *it;
if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->FieldFlag)) if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->CollisionMask))
{ {
if (!ball->already_hit(edge)) if (!ball->already_hit(edge))
{ {
@ -104,7 +104,7 @@ void TEdgeManager::FieldEffects(TBall* ball, vector2* dstVec)
for (auto it = edgeBox->FieldList.rbegin(); it != edgeBox->FieldList.rend(); ++it) for (auto it = edgeBox->FieldList.rbegin(); it != edgeBox->FieldList.rend(); ++it)
{ {
auto field = *it; auto field = *it;
if (*field->Flag2Ptr && ball->FieldFlag & field->Mask) if (*field->ActiveFlag && ball->CollisionMask & field->CollisionGroup)
{ {
if (field->CollisionComp->FieldEffect(ball, &vec)) if (field->CollisionComp->FieldEffect(ball, &vec))
{ {

View File

@ -6,8 +6,8 @@ class TEdgeBox;
struct field_effect_type struct field_effect_type
{ {
char* Flag2Ptr; char* ActiveFlag;
int Mask; int CollisionGroup;
TCollisionComponent* CollisionComp; TCollisionComponent* CollisionComp;
}; };

View File

@ -22,7 +22,7 @@ public:
TEdgeSegment(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup); TEdgeSegment(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup);
virtual ~TEdgeSegment() = default; virtual ~TEdgeSegment() = default;
virtual void EdgeCollision(TBall* ball, float coef) = 0; virtual void EdgeCollision(TBall* ball, float distance) = 0;
virtual void port_draw(); virtual void port_draw();
virtual void place_in_grid() = 0; virtual void place_in_grid() = 0;
virtual float FindCollisionDistance(ray_type* ray) = 0; virtual float FindCollisionDistance(ray_type* ray) = 0;

View File

@ -72,12 +72,12 @@ int TFlagSpinner::Message(int code, float value)
return 0; return 0;
} }
void TFlagSpinner::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void TFlagSpinner::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) TEdgeSegment* edge)
{ {
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance = ball->RayMaxDistance - coef; ball->RayMaxDistance = ball->RayMaxDistance - distance;
ball->not_again(edge); ball->not_again(edge);
SpinDirection = 2 * (PrevCollider != edge) - 1; SpinDirection = 2 * (PrevCollider != edge) - 1;

View File

@ -7,7 +7,7 @@ class TFlagSpinner :
public: public:
TFlagSpinner(TPinballTable* table, int groupIndex); TFlagSpinner(TPinballTable* table, int groupIndex);
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;

View File

@ -128,7 +128,7 @@ void TFlipper::port_draw()
FlipperEdge->port_draw(); FlipperEdge->port_draw();
} }
void TFlipper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TFlipper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
} }

View File

@ -11,7 +11,7 @@ public:
~TFlipper() override; ~TFlipper() override;
int Message(int code, float value) override; int Message(int code, float value) override;
void port_draw() override; void port_draw() override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller); static void TimerExpired(int timerId, void* caller);

View File

@ -298,7 +298,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
return 1e+09; return 1e+09;
} }
void TFlipperEdge::EdgeCollision(TBall* ball, float coef) void TFlipperEdge::EdgeCollision(TBall* ball, float distance)
{ {
EdgeCollisionFlag = 1; EdgeCollisionFlag = 1;
if (!FlipperFlag || !CollisionFlag2 || CollisionFlag1) if (!FlipperFlag || !CollisionFlag2 || CollisionFlag1)
@ -308,11 +308,11 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
{ {
float dx = NextBallPosition.X - RotOrigin.X; float dx = NextBallPosition.X - RotOrigin.X;
float dy = NextBallPosition.Y - RotOrigin.Y; float dy = NextBallPosition.Y - RotOrigin.Y;
float distance = dy * dy + dx * dx; float distanceSq = dy * dy + dx * dx;
if (circlebase.RadiusSq * 1.01f < distance) if (circlebase.RadiusSq * 1.01f < distanceSq)
{ {
float v11; float v11;
float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult); float v20 = sqrt(distanceSq / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
float dot1 = maths::DotProduct(CollisionLinePerp, CollisionDirection); float dot1 = maths::DotProduct(CollisionLinePerp, CollisionDirection);
if (dot1 >= 0.0f) if (dot1 >= 0.0f)
v11 = dot1 * v20; v11 = dot1 * v20;
@ -337,9 +337,9 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
float elasticity; float elasticity;
float dx = NextBallPosition.X - RotOrigin.X; float dx = NextBallPosition.X - RotOrigin.X;
float dy = NextBallPosition.Y - RotOrigin.Y; float dy = NextBallPosition.Y - RotOrigin.Y;
float distance = dy * dy + dx * dx; float distanceSq = dy * dy + dx * dx;
if (circlebase.RadiusSq * 1.01f < distance) if (circlebase.RadiusSq * 1.01f < distanceSq)
elasticity = (1.0f - sqrt(distance / DistanceDivSq)) * Elasticity; elasticity = (1.0f - sqrt(distanceSq / DistanceDivSq)) * Elasticity;
else else
elasticity = Elasticity; elasticity = Elasticity;
maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, elasticity, Smoothness, 1000000000.0, 0.0); maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, elasticity, Smoothness, 1000000000.0, 0.0);

View File

@ -12,7 +12,7 @@ public:
float elasticity, float smoothness); float elasticity, float smoothness);
void port_draw() override; void port_draw() override;
float FindCollisionDistance(ray_type* ray) override; float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override; void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override; void place_in_grid() override;
void set_control_points(float timeNow); void set_control_points(float timeNow);
void build_edges_in_motion(); void build_edges_in_motion();

View File

@ -40,20 +40,20 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
} }
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2]; ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304))); CollisionMask = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
/*Full tilt hack - FieldFlag should be on*/ // Full tilt hack - CollisionMask should be 1
if (pb::FullTiltMode) if (pb::FullTiltMode)
FieldFlag = 1; CollisionMask = 1;
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2]; Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
circle.RadiusSq = Circle.RadiusSq; circle.RadiusSq = Circle.RadiusSq;
circle.Center.X = Circle.Center.X; circle.Center.X = Circle.Center.X;
circle.Center.Y = Circle.Center.Y; circle.Center.Y = Circle.Center.Y;
Field.Flag2Ptr = &ActiveFlag; Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this; Field.CollisionComp = this;
Field.Mask = visual.CollisionGroup; Field.CollisionGroup = visual.CollisionGroup;
TTableLayer::edges_insert_circle(&circle, nullptr, &Field); TTableLayer::edges_insert_circle(&circle, nullptr, &Field);
} }
@ -69,7 +69,7 @@ int THole::Message(int code, float value)
return 0; return 0;
} }
void THole::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void THole::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
if (!BallCapturedFlag) if (!BallCapturedFlag)
{ {
@ -79,7 +79,7 @@ void THole::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
ball->CollisionComp = this; ball->CollisionComp = this;
ball->Position.X = Circle.Center.X; ball->Position.X = Circle.Center.X;
ball->Position.Y = Circle.Center.Y; ball->Position.Y = Circle.Center.Y;
ball->Acceleration.Z = 0.0; ball->Direction.Z = 0.0;
// Ramp hole has no delay in FT. // Ramp hole has no delay in FT.
auto captureTime = pb::FullTiltMode ? 0 : 0.5f; auto captureTime = pb::FullTiltMode ? 0 : 0.5f;
@ -102,18 +102,18 @@ int THole::FieldEffect(TBall* ball, vector2* vecDst)
{ {
if (BallCapturedSecondStage) if (BallCapturedSecondStage)
{ {
ball->Acceleration.Z -= PinballTable->GravityDirVectMult * ball->TimeDelta * GravityMult; ball->Direction.Z -= PinballTable->GravityDirVectMult * ball->TimeDelta * GravityMult;
ball->Position.Z += ball->Acceleration.Z; ball->Position.Z += ball->Direction.Z;
if (ball->Position.Z <= ZSetValue) if (ball->Position.Z <= ZSetValue)
{ {
BallCapturedFlag = 0; BallCapturedFlag = 0;
BallCapturedSecondStage = 0; BallCapturedSecondStage = 0;
ball->Position.Z = ZSetValue; ball->Position.Z = ZSetValue;
ball->Acceleration.Z = 0.0; ball->Direction.Z = 0.0;
ball->FieldFlag = FieldFlag; ball->CollisionMask = CollisionMask;
ball->Acceleration.Y = 0.0; ball->Direction.Y = 0.0;
ball->CollisionComp = nullptr; ball->CollisionComp = nullptr;
ball->Acceleration.X = 0.0; ball->Direction.X = 0.0;
ball->Speed = 0.0; ball->Speed = 0.0;
loader::play_sound(SoftHitSoundId); loader::play_sound(SoftHitSoundId);
control::handler(58, this); control::handler(58, this);
@ -128,8 +128,8 @@ int THole::FieldEffect(TBall* ball, vector2* vecDst)
if (direction.X * direction.X + direction.Y * direction.Y <= Circle.RadiusSq) if (direction.X * direction.X + direction.Y * direction.Y <= Circle.RadiusSq)
{ {
maths::normalize_2d(direction); maths::normalize_2d(direction);
vecDst->X = direction.X * GravityPull - ball->Acceleration.X * ball->Speed; vecDst->X = direction.X * GravityPull - ball->Direction.X * ball->Speed;
vecDst->Y = direction.Y * GravityPull - ball->Acceleration.Y * ball->Speed; vecDst->Y = direction.Y * GravityPull - ball->Direction.Y * ball->Speed;
result = 1; result = 1;
} }
else else

View File

@ -9,7 +9,7 @@ class THole :
public: public:
THole(TPinballTable* table, int groupIndex); THole(TPinballTable* table, int groupIndex);
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
int FieldEffect(TBall* ball, vector2* vecDst) override; int FieldEffect(TBall* ball, vector2* vecDst) override;
@ -22,7 +22,7 @@ public:
float Unknown4; float Unknown4;
float GravityMult; float GravityMult;
float ZSetValue; float ZSetValue;
int FieldFlag; int CollisionMask;
float GravityPull; float GravityPull;
circle_type Circle{}; circle_type Circle{};
field_effect_type Field{}; field_effect_type Field{};

View File

@ -33,7 +33,7 @@ int TKickback::Message(int code, float value)
return 0; return 0;
} }
void TKickback::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void TKickback::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) TEdgeSegment* edge)
{ {
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)

View File

@ -7,7 +7,7 @@ class TKickback :
public: public:
TKickback(TPinballTable* table, int groupIndex); TKickback(TPinballTable* table, int groupIndex);
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller); static void TimerExpired(int timerId, void* caller);

View File

@ -47,16 +47,16 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
auto zAttr = loader::query_float_attribute(groupIndex, 0, 408); auto zAttr = loader::query_float_attribute(groupIndex, 0, 408);
CollisionBallSetZ = pb::FullTiltMode && !pb::FullTiltDemoMode ? zAttr[3] : zAttr[2]; CollisionBallSetZ = pb::FullTiltMode && !pb::FullTiltDemoMode ? zAttr[3] : zAttr[2];
ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f; ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
BallAcceleration = visual.Kicker.ThrowBallAcceleration; BallThrowDirection = visual.Kicker.ThrowBallDirection;
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult; ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
ThrowSpeedMult1 = visual.Kicker.Boost; ThrowSpeedMult1 = visual.Kicker.Boost;
circle.RadiusSq = Circle.RadiusSq; circle.RadiusSq = Circle.RadiusSq;
circle.Center.X = Circle.Center.X; circle.Center.X = Circle.Center.X;
circle.Center.Y = Circle.Center.Y; circle.Center.Y = Circle.Center.Y;
Field.Flag2Ptr = &ActiveFlag; Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this; Field.CollisionComp = this;
Field.Mask = visual.CollisionGroup; Field.CollisionGroup = visual.CollisionGroup;
TTableLayer::edges_insert_circle(&circle, nullptr, &Field); TTableLayer::edges_insert_circle(&circle, nullptr, &Field);
} }
@ -104,7 +104,7 @@ int TKickout::get_scoring(int index)
return index < 5 ? Scores[index] : 0; return index < 5 ? Scores[index] : 0;
} }
void TKickout::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TKickout::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
if (!KickFlag1) if (!KickFlag1)
{ {
@ -139,8 +139,8 @@ int TKickout::FieldEffect(TBall* ball, vector2* dstVec)
if (direction.Y * direction.Y + direction.X * direction.X > Circle.RadiusSq) if (direction.Y * direction.Y + direction.X * direction.X > Circle.RadiusSq)
return 0; return 0;
maths::normalize_2d(direction); maths::normalize_2d(direction);
dstVec->X = direction.X * FieldMult - ball->Acceleration.X * ball->Speed; dstVec->X = direction.X * FieldMult - ball->Direction.X * ball->Speed;
dstVec->Y = direction.Y * FieldMult - ball->Acceleration.Y * ball->Speed; dstVec->Y = direction.Y * FieldMult - ball->Direction.Y * ball->Speed;
return 1; return 1;
} }
@ -154,7 +154,7 @@ void TKickout::TimerExpired(int timerId, void* caller)
if (kick->Ball) if (kick->Ball)
{ {
kick->Ball->Position.Z = kick->OriginalBallZ; kick->Ball->Position.Z = kick->OriginalBallZ;
TBall::throw_ball(kick->Ball, &kick->BallAcceleration, kick->ThrowAngleMult, kick->ThrowSpeedMult1, TBall::throw_ball(kick->Ball, &kick->BallThrowDirection, kick->ThrowAngleMult, kick->ThrowSpeedMult1,
kick->ThrowSpeedMult2); kick->ThrowSpeedMult2);
kick->ActiveFlag = 0; kick->ActiveFlag = 0;
kick->Ball = nullptr; kick->Ball = nullptr;

View File

@ -11,7 +11,7 @@ public:
int Message(int code, float value) override; int Message(int code, float value) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
int FieldEffect(TBall* ball, vector2* vecDst) override; int FieldEffect(TBall* ball, vector2* vecDst) override;
@ -28,7 +28,7 @@ public:
float FieldMult; float FieldMult;
circle_type Circle{}; circle_type Circle{};
float OriginalBallZ{}; float OriginalBallZ{};
vector3 BallAcceleration{}; vector3 BallThrowDirection{};
float ThrowAngleMult; float ThrowAngleMult;
float ThrowSpeedMult1; float ThrowSpeedMult1;
float ThrowSpeedMult2; float ThrowSpeedMult2;

View File

@ -34,12 +34,12 @@ int TLightRollover::Message(int code, float value)
return 0; return 0;
} }
void TLightRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void TLightRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) TEdgeSegment* edge)
{ {
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef; ball->RayMaxDistance -= distance;
ball->not_again(edge); ball->not_again(edge);
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {

View File

@ -8,7 +8,7 @@ public:
TLightRollover(TPinballTable* table, int groupIndex); TLightRollover(TPinballTable* table, int groupIndex);
~TLightRollover() override = default; ~TLightRollover() override = default;
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void delay_expired(int timerId, void* caller); static void delay_expired(int timerId, void* caller);

View File

@ -41,13 +41,13 @@ float TLine::FindCollisionDistance(ray_type* ray)
return maths::ray_intersect_line(*ray, Line); return maths::ray_intersect_line(*ray, Line);
} }
void TLine::EdgeCollision(TBall* ball, float coef) void TLine::EdgeCollision(TBall* ball, float distance)
{ {
CollisionComponent->Collision( CollisionComponent->Collision(
ball, ball,
&Line.RayIntersect, &Line.RayIntersect,
&Line.PerpendicularC, &Line.PerpendicularC,
coef, distance,
this); this);
} }

View File

@ -12,6 +12,6 @@ public:
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start, const vector2& end); TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start, const vector2& end);
void Offset(float offset); void Offset(float offset);
float FindCollisionDistance(ray_type* ray) override; float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override; void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override; void place_in_grid() override;
}; };

View File

@ -40,14 +40,14 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
} }
} }
void TOneway::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TOneway::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
if (edge == Line) if (edge == Line)
{ {
ball->not_again(edge); ball->not_again(edge);
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef; ball->RayMaxDistance -= distance;
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {
if (HardHitSoundId) if (HardHitSoundId)

View File

@ -8,7 +8,7 @@ class TOneway : public TCollisionComponent
public: public:
TOneway(TPinballTable* table, int groupIndex); TOneway(TPinballTable* table, int groupIndex);
~TOneway() override = default; ~TOneway() override = default;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;

View File

@ -33,12 +33,12 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t
table->PlungerPositionY = floatArr[1]; table->PlungerPositionY = floatArr[1];
} }
void TPlunger::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TPlunger::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
Message(1017, 0.0); Message(1017, 0.0);
coef = RandFloat() * Boost * 0.1f + Boost; // it is intended that the passed in coef is never used! auto boost = RandFloat() * Boost * 0.1f + Boost;
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, coef); maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, boost);
} }
int TPlunger::Message(int code, float value) int TPlunger::Message(int code, float value)

View File

@ -7,7 +7,7 @@ class TPlunger :
public: public:
TPlunger(TPinballTable* table, int groupIndex); TPlunger(TPinballTable* table, int groupIndex);
~TPlunger() override = default; ~TPlunger() override = default;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
int Message(int code, float value) override; int Message(int code, float value) override;

View File

@ -62,7 +62,7 @@ int TPopupTarget::get_scoring(int index)
return index < 3 ? Scores[index] : 0; return index < 3 ? Scores[index] : 0;
} }
void TPopupTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void TPopupTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) TEdgeSegment* edge)
{ {
if (this->PinballTable->TiltLockFlag) if (this->PinballTable->TiltLockFlag)

View File

@ -9,7 +9,7 @@ public:
int Message(int code, float value) override; int Message(int code, float value) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller); static void TimerExpired(int timerId, void* caller);

View File

@ -116,9 +116,9 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
PinballTable->GravityDirVectMult; PinballTable->GravityDirVectMult;
} }
Field.Flag2Ptr = &ActiveFlag; Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this; Field.CollisionComp = this;
Field.Mask = visual.CollisionGroup; Field.CollisionGroup = visual.CollisionGroup;
auto x1 = xMax; auto x1 = xMax;
auto y1 = yMax; auto y1 = yMax;
@ -138,12 +138,12 @@ int TRamp::get_scoring(int index)
return index < 4 ? Scores[index] : 0; return index < 4 ? Scores[index] : 0;
} }
void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
ball->not_again(edge); ball->not_again(edge);
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef; ball->RayMaxDistance -= distance;
auto plane = static_cast<ramp_plane_type*>(edge->WallValue); auto plane = static_cast<ramp_plane_type*>(edge->WallValue);
if (plane) if (plane)
@ -156,7 +156,7 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
ball->RampFieldForce.Y = plane->FieldForce.Y; ball->RampFieldForce.Y = plane->FieldForce.Y;
ball->Position.Z = ball->Position.X * ball->CollisionOffset.X + ball->Position.Y * ball->CollisionOffset.Y + ball->Position.Z = ball->Position.X * ball->CollisionOffset.X + ball->Position.Y * ball->CollisionOffset.Y +
ball->Offset + ball->CollisionOffset.Z; ball->Offset + ball->CollisionOffset.Z;
ball->FieldFlag = CollisionGroup; ball->CollisionMask = CollisionGroup;
return; return;
} }
@ -173,13 +173,13 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
ball->CollisionFlag = 0; ball->CollisionFlag = 0;
if (edge == Line2) if (edge == Line2)
{ {
ball->FieldFlag = Wall1CollisionGroup; ball->CollisionMask = Wall1CollisionGroup;
if (BallZOffsetFlag) if (BallZOffsetFlag)
ball->Position.Z = ball->Offset + Wall1BallOffset; ball->Position.Z = ball->Offset + Wall1BallOffset;
} }
else else
{ {
ball->FieldFlag = Wall2CollisionGroup; ball->CollisionMask = Wall2CollisionGroup;
if (BallZOffsetFlag) if (BallZOffsetFlag)
ball->Position.Z = ball->Offset + Wall2BallOffset; ball->Position.Z = ball->Offset + Wall2BallOffset;
} }
@ -188,8 +188,8 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
int TRamp::FieldEffect(TBall* ball, vector2* vecDst) int TRamp::FieldEffect(TBall* ball, vector2* vecDst)
{ {
vecDst->X = ball->RampFieldForce.X - ball->Acceleration.X * ball->Speed * BallFieldMult; vecDst->X = ball->RampFieldForce.X - ball->Direction.X * ball->Speed * BallFieldMult;
vecDst->Y = ball->RampFieldForce.Y - ball->Acceleration.Y * ball->Speed * BallFieldMult; vecDst->Y = ball->RampFieldForce.Y - ball->Direction.Y * ball->Speed * BallFieldMult;
return 1; return 1;
} }

View File

@ -12,7 +12,7 @@ public:
TRamp(TPinballTable* table, int groupIndex); TRamp(TPinballTable* table, int groupIndex);
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
int FieldEffect(TBall* ball, vector2* vecDst) override; int FieldEffect(TBall* ball, vector2* vecDst) override;
void port_draw() override; void port_draw() override;

View File

@ -37,12 +37,12 @@ int TRollover::Message(int code, float value)
return 0; return 0;
} }
void TRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void TRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) TEdgeSegment* edge)
{ {
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef; ball->RayMaxDistance -= distance;
ball->not_again(edge); ball->not_again(edge);
gdrv_bitmap8* bmp = nullptr; gdrv_bitmap8* bmp = nullptr;
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)

View File

@ -10,7 +10,7 @@ public:
TRollover(TPinballTable* table, int groupIndex); TRollover(TPinballTable* table, int groupIndex);
~TRollover() override = default; ~TRollover() override = default;
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;

View File

@ -16,7 +16,7 @@ TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
MessageField = 0; MessageField = 0;
Timer = 0; Timer = 0;
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
BallAcceleration = visual.Kicker.ThrowBallAcceleration; BallThrowDirection = visual.Kicker.ThrowBallDirection;
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult; ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
ThrowSpeedMult1 = visual.Kicker.Boost; ThrowSpeedMult1 = visual.Kicker.Boost;
ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f; ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
@ -75,7 +75,7 @@ int TSink::get_scoring(int index)
return index < 3 ? Scores[index] : 0; return index < 3 ? Scores[index] : 0;
} }
void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
Timer = 0; Timer = 0;
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
@ -99,7 +99,7 @@ void TSink::TimerExpired(int timerId, void* caller)
ball->ActiveFlag = 1; ball->ActiveFlag = 1;
ball->Position.X = sink->BallPosition.X; ball->Position.X = sink->BallPosition.X;
ball->Position.Y = sink->BallPosition.Y; ball->Position.Y = sink->BallPosition.Y;
TBall::throw_ball(ball, &sink->BallAcceleration, sink->ThrowAngleMult, sink->ThrowSpeedMult1, TBall::throw_ball(ball, &sink->BallThrowDirection, sink->ThrowAngleMult, sink->ThrowSpeedMult1,
sink->ThrowSpeedMult2); sink->ThrowSpeedMult2);
if (sink->SoundIndex3) if (sink->SoundIndex3)
loader::play_sound(sink->SoundIndex3); loader::play_sound(sink->SoundIndex3);

View File

@ -10,7 +10,7 @@ public:
int Message(int code, float value) override; int Message(int code, float value) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller); static void TimerExpired(int timerId, void* caller);
@ -18,7 +18,7 @@ public:
int Timer; int Timer;
float TimerTime; float TimerTime;
vector2 BallPosition{}; vector2 BallPosition{};
vector3 BallAcceleration{}; vector3 BallThrowDirection{};
float ThrowAngleMult; float ThrowAngleMult;
float ThrowSpeedMult1; float ThrowSpeedMult1;
float ThrowSpeedMult2; float ThrowSpeedMult2;

View File

@ -64,7 +64,7 @@ int TSoloTarget::get_scoring(int index)
return index < 1 ? Scores[index] : 0; return index < 1 ? Scores[index] : 0;
} }
void TSoloTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void TSoloTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) TEdgeSegment* edge)
{ {
if (DefaultCollision(ball, nextPosition, direction)) if (DefaultCollision(ball, nextPosition, direction))

View File

@ -9,7 +9,7 @@ public:
int Message(int code, float value) override; int Message(int code, float value) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller); static void TimerExpired(int timerId, void* caller);

View File

@ -98,8 +98,8 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
visArrPtr += 2; visArrPtr += 2;
} }
Field.Mask = -1; Field.CollisionGroup = -1;
Field.Flag2Ptr = &ActiveFlag; Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this; Field.CollisionComp = this;
edges_insert_square(Unknown2F, Unknown1F, Unknown4F, Unknown3F, nullptr, edges_insert_square(Unknown2F, Unknown1F, Unknown4F, Unknown3F, nullptr,
&Field); &Field);
@ -113,9 +113,9 @@ TTableLayer::~TTableLayer()
int TTableLayer::FieldEffect(TBall* ball, vector2* vecDst) int TTableLayer::FieldEffect(TBall* ball, vector2* vecDst)
{ {
vecDst->X = GraityDirX - (0.5f - RandFloat() + ball->Acceleration.X) * vecDst->X = GraityDirX - (0.5f - RandFloat() + ball->Direction.X) *
ball->Speed * GraityMult; ball->Speed * GraityMult;
vecDst->Y = GraityDirY - ball->Acceleration.Y * ball->Speed * GraityMult; vecDst->Y = GraityDirY - ball->Direction.Y * ball->Speed * GraityMult;
return 1; return 1;
} }

View File

@ -10,12 +10,12 @@ TTripwire::TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, gr
{ {
} }
void TTripwire::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void TTripwire::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) TEdgeSegment* edge)
{ {
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef; ball->RayMaxDistance -= distance;
ball->not_again(edge); ball->not_again(edge);
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {

View File

@ -7,6 +7,6 @@ class TTripwire :
public: public:
TTripwire(TPinballTable* table, int groupIndex); TTripwire(TPinballTable* table, int groupIndex);
~TTripwire() override = default; ~TTripwire() override = default;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
}; };

View File

@ -24,7 +24,7 @@ int TWall::Message(int code, float value)
return 0; return 0;
} }
void TWall::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge) void TWall::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{ {
if (DefaultCollision(ball, nextPosition, direction)) if (DefaultCollision(ball, nextPosition, direction))
{ {

View File

@ -10,7 +10,7 @@ class TWall :
public: public:
TWall(TPinballTable* table, int groupIndex); TWall(TPinballTable* table, int groupIndex);
int Message(int code, float value) override; int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override; TEdgeSegment* edge) override;
void put_scoring(int index, int score) override; void put_scoring(int index, int score) override;
int get_scoring(int index) override; int get_scoring(int index) override;

View File

@ -390,7 +390,7 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker)
kicker->ThrowBallMult = *floatArr; kicker->ThrowBallMult = *floatArr;
break; break;
case 404: case 404:
kicker->ThrowBallAcceleration = *reinterpret_cast<vector3*>(floatArr); kicker->ThrowBallDirection = *reinterpret_cast<vector3*>(floatArr);
floatArr += 3; floatArr += 3;
index += 4; index += 4;
break; break;

View File

@ -25,7 +25,7 @@ struct visualKickerStruct
float Threshold; float Threshold;
float Boost; float Boost;
float ThrowBallMult; float ThrowBallMult;
vector3 ThrowBallAcceleration; vector3 ThrowBallDirection;
float ThrowBallAngleMult; float ThrowBallAngleMult;
int HardHitSoundId; int HardHitSoundId;
}; };

View File

@ -231,30 +231,35 @@ float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direct
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
auto proj = -DotProduct(*direction, ball->Acceleration); // Project ball direction on collision rebound direction
if (proj < 0) auto reboundProj = -DotProduct(*direction, ball->Direction);
if (reboundProj < 0)
{ {
proj = -proj; // Negative projection means no rebound, both direction vectors point the same way.
reboundProj = -reboundProj;
} }
else else
{ {
float dx1 = proj * direction->X; // Apply rebound to ball direction
float dy1 = proj * direction->Y; float dx1 = reboundProj * direction->X;
ball->Acceleration.X = (dx1 + ball->Acceleration.X) * smoothness + dx1 * elasticity; float dy1 = reboundProj * direction->Y;
ball->Acceleration.Y = (dy1 + ball->Acceleration.Y) * smoothness + dy1 * elasticity; ball->Direction.X = (dx1 + ball->Direction.X) * smoothness + dx1 * elasticity;
normalize_2d(ball->Acceleration); ball->Direction.Y = (dy1 + ball->Direction.Y) * smoothness + dy1 * elasticity;
normalize_2d(ball->Direction);
} }
float projSpeed = proj * ball->Speed; // Apply rebound to ball speed
float newSpeed = ball->Speed - (1.0f - elasticity) * projSpeed; float reboundSpeed = reboundProj * ball->Speed;
ball->Speed = newSpeed; ball->Speed -= (1.0f - elasticity) * reboundSpeed;
if (projSpeed >= threshold)
if (reboundSpeed >= threshold)
{ {
ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * boost; // Change ball direction if rebound speed is above threshold
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * boost; ball->Direction.X = ball->Speed * ball->Direction.X + direction->X * boost;
ball->Speed = normalize_2d(ball->Acceleration); ball->Direction.Y = ball->Speed * ball->Direction.Y + direction->Y * boost;
ball->Speed = normalize_2d(ball->Direction);
} }
return projSpeed; return reboundSpeed;
} }
float maths::Distance_Squared(const vector2& vec1, const vector2& vec2) float maths::Distance_Squared(const vector2& vec1, const vector2& vec2)

View File

@ -53,7 +53,7 @@ struct ray_type
float MinDistance; float MinDistance;
float TimeNow; float TimeNow;
float TimeDelta; float TimeDelta;
int FieldFlag; int CollisionMask;
}; };
struct line_type struct line_type

View File

@ -65,7 +65,6 @@ void nudge::nudge_up()
void nudge::_nudge(float xDiff, float yDiff) void nudge::_nudge(float xDiff, float yDiff)
{ {
vector2 accelMod; vector2 accelMod;
float invAccelX, invAccelY;
accelMod.X = xDiff * 0.5f; accelMod.X = xDiff * 0.5f;
accelMod.Y = yDiff * 0.5f; accelMod.Y = yDiff * 0.5f;
@ -73,20 +72,10 @@ void nudge::_nudge(float xDiff, float yDiff)
{ {
if (ball->ActiveFlag && !ball->CollisionComp) if (ball->ActiveFlag && !ball->CollisionComp)
{ {
ball->Acceleration.X = ball->Acceleration.X * ball->Speed; ball->Direction.X = ball->Direction.X * ball->Speed;
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed; ball->Direction.Y = ball->Direction.Y * ball->Speed;
maths::vector_add(ball->Acceleration, accelMod); maths::vector_add(ball->Direction, accelMod);
ball->Speed = maths::normalize_2d(ball->Acceleration); ball->Speed = maths::normalize_2d(ball->Direction);
if (ball->Acceleration.X == 0.0f)
invAccelX = 1000000000.0;
else
invAccelX = 1.0f / ball->Acceleration.X;
ball->InvAcceleration.X = invAccelX;
if (ball->Acceleration.Y == 0.0f)
invAccelY = 1000000000.0;
else
invAccelY = 1.0f / ball->Acceleration.Y;
ball->InvAcceleration.Y = invAccelY;
} }
} }

View File

@ -241,9 +241,9 @@ void pb::ballset(float dx, float dy)
// dx and dy are normalized to window, ideally in [-1, 1] // dx and dy are normalized to window, ideally in [-1, 1]
static constexpr float sensitivity = 7000; static constexpr float sensitivity = 7000;
TBall* ball = MainTable->BallList.at(0); TBall* ball = MainTable->BallList.at(0);
ball->Acceleration.X = dx * sensitivity; ball->Direction.X = dx * sensitivity;
ball->Acceleration.Y = dy * sensitivity; ball->Direction.Y = dy * sensitivity;
ball->Speed = maths::normalize_2d(ball->Acceleration); ball->Speed = maths::normalize_2d(ball->Direction);
} }
void pb::frame(float dtMilliSec) void pb::frame(float dtMilliSec)
@ -311,12 +311,10 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
TTableLayer::edge_manager->FieldEffects(ball, &vec2); TTableLayer::edge_manager->FieldEffects(ball, &vec2);
vec2.X = vec2.X * timeDelta; vec2.X = vec2.X * timeDelta;
vec2.Y = vec2.Y * timeDelta; vec2.Y = vec2.Y * timeDelta;
ball->Acceleration.X = ball->Speed * ball->Acceleration.X; ball->Direction.X = ball->Speed * ball->Direction.X;
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y; ball->Direction.Y = ball->Speed * ball->Direction.Y;
maths::vector_add(ball->Acceleration, vec2); maths::vector_add(ball->Direction, vec2);
ball->Speed = maths::normalize_2d(ball->Acceleration); ball->Speed = maths::normalize_2d(ball->Direction);
ball->InvAcceleration.X = ball->Acceleration.X == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.X;
ball->InvAcceleration.Y = ball->Acceleration.Y == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.Y;
} }
auto timeDelta2 = timeDelta; auto timeDelta2 = timeDelta;
@ -489,9 +487,9 @@ void pb::InputDown(GameInput input)
ball->Position.X = 1.0; ball->Position.X = 1.0;
ball->Position.Z = ball->Offset; ball->Position.Z = ball->Offset;
ball->Position.Y = 1.0; ball->Position.Y = 1.0;
ball->Acceleration.Z = 0.0; ball->Direction.Z = 0.0;
ball->Acceleration.Y = 0.0; ball->Direction.Y = 0.0;
ball->Acceleration.X = 0.0; ball->Direction.X = 0.0;
break; break;
case 'h': case 'h':
{ {
@ -607,9 +605,9 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
ball->TimeNow = timeNow; ball->TimeNow = timeNow;
ray.Origin = ball->Position; ray.Origin = ball->Position;
ray.Direction = ball->Acceleration; ray.Direction = ball->Direction;
ray.MaxDistance = maxDistance; ray.MaxDistance = maxDistance;
ray.FieldFlag = ball->FieldFlag; ray.CollisionMask = ball->CollisionMask;
ray.TimeNow = timeNow; ray.TimeNow = timeNow;
ray.TimeDelta = timeDelta; ray.TimeDelta = timeDelta;
ray.MinDistance = 0.0020000001f; ray.MinDistance = 0.0020000001f;
@ -621,8 +619,8 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
{ {
maxDistance = timeDelta * ball->Speed; maxDistance = timeDelta * ball->Speed;
ball->RayMaxDistance = maxDistance; ball->RayMaxDistance = maxDistance;
positionMod.X = maxDistance * ball->Acceleration.X; positionMod.X = maxDistance * ball->Direction.X;
positionMod.Y = maxDistance * ball->Acceleration.Y; positionMod.Y = maxDistance * ball->Direction.Y;
maths::vector_add(ball->Position, positionMod); maths::vector_add(ball->Position, positionMod);
} }
else else