mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-24 19:52:30 +01:00
TRollover, TOneway, TLightRollover, TTripwire, TEdgeManager ready.
This commit is contained in:
parent
9bd064bf15
commit
d19fb0476a
Binary file not shown.
@ -1,6 +1,10 @@
|
||||
#include "pch.h"
|
||||
#include "TCircle.h"
|
||||
|
||||
#include "TBall.h"
|
||||
#include "TCollisionComponent.h"
|
||||
#include "TTableLayer.h"
|
||||
|
||||
TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visualFlag, vector_type* center,
|
||||
float radius): TEdgeSegment(collComp, someFlagPtr, visualFlag)
|
||||
{
|
||||
@ -24,3 +28,8 @@ void TCircle::EdgeCollision(TBall* ball, float coef)
|
||||
maths::normalize_2d(&direction);
|
||||
CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this);
|
||||
}
|
||||
|
||||
void TCircle::place_in_grid()
|
||||
{
|
||||
TTableLayer::edges_insert_circle(&Circle, this, nullptr);
|
||||
}
|
||||
|
@ -12,8 +12,5 @@ public:
|
||||
float radius);
|
||||
float FindCollisionDistance(ray_type* ray) override;
|
||||
void EdgeCollision(TBall* ball, float coef) override;
|
||||
|
||||
void place_in_grid() override
|
||||
{
|
||||
}
|
||||
void place_in_grid() override;
|
||||
};
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "pch.h"
|
||||
#include "TCollisionComponent.h"
|
||||
#include "loader.h"
|
||||
#include "maths.h"
|
||||
#include "objlist_class.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "objlist_class.h"
|
||||
#include "TPinballComponent.h"
|
||||
|
||||
class objlist_class;
|
||||
struct vector_type;
|
||||
class TEdgeSegment;
|
||||
class TBall;
|
||||
@ -20,7 +20,7 @@ public:
|
||||
int SoundIndex1;
|
||||
|
||||
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
|
||||
~TCollisionComponent();
|
||||
~TCollisionComponent() override;
|
||||
void port_draw() override;
|
||||
virtual void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge);
|
||||
|
@ -1,7 +1,12 @@
|
||||
#include "pch.h"
|
||||
#include "TEdgeManager.h"
|
||||
|
||||
|
||||
#include "maths.h"
|
||||
#include "objlist_class.h"
|
||||
#include "TBall.h"
|
||||
#include "TEdgeBox.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "TTableLayer.h"
|
||||
|
||||
TEdgeManager::TEdgeManager(float posX, float posY, float width, float height)
|
||||
@ -137,9 +142,7 @@ float TEdgeManager::FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegme
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rayBoxX == rayEndBoxX)
|
||||
else if (rayBoxX == rayEndBoxX)
|
||||
{
|
||||
if (rayDirY == 1)
|
||||
{
|
||||
@ -262,7 +265,6 @@ float TEdgeManager::FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegme
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto edgePtr = EdgeArray; edgeIndex > 0; --edgeIndex, ++edgePtr)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "TCollisionComponent.h"
|
||||
#include "TEdgeSegment.h"
|
||||
|
||||
struct ray_type;
|
||||
class TEdgeBox;
|
||||
|
||||
struct field_effect_type
|
||||
|
@ -1,14 +1,17 @@
|
||||
#include "pch.h"
|
||||
#include "TEdgeSegment.h"
|
||||
|
||||
#include "objlist_class.h"
|
||||
#include "TCircle.h"
|
||||
#include "TCollisionComponent.h"
|
||||
#include "TLine.h"
|
||||
|
||||
TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned visualFlag)
|
||||
{
|
||||
this->CollisionComponent = collComp;
|
||||
this->PinbCompFlag2Ptr = someFlag;
|
||||
this->VisualFlag = visualFlag;
|
||||
this->ProcessedFlag = 0;
|
||||
CollisionComponent = collComp;
|
||||
PinbCompFlag2Ptr = someFlag;
|
||||
VisualFlag = visualFlag;
|
||||
ProcessedFlag = 0;
|
||||
}
|
||||
|
||||
void TEdgeSegment::port_draw()
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include "TCollisionComponent.h"
|
||||
#include "maths.h"
|
||||
#include "TBall.h"
|
||||
|
||||
class TBall;
|
||||
class TCollisionComponent;
|
||||
struct ray_type;
|
||||
|
||||
enum class wall_type : int
|
||||
{
|
||||
|
@ -1,2 +1,71 @@
|
||||
#include "pch.h"
|
||||
#include "TLightRollover.h"
|
||||
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "render.h"
|
||||
#include "TBall.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TLightRollover::TLightRollover(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, false)
|
||||
{
|
||||
RolloverFlag = 0;
|
||||
Timer = 0;
|
||||
if (ListBitmap != nullptr)
|
||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||
build_walls(groupIndex);
|
||||
FloatArr = *loader::query_float_attribute(groupIndex, 0, 407);
|
||||
}
|
||||
|
||||
int TLightRollover::Message(int code, float value)
|
||||
{
|
||||
if (code == 1024)
|
||||
{
|
||||
UnknownBaseFlag2 = 1;
|
||||
RolloverFlag = 0;
|
||||
if (Timer)
|
||||
timer::kill(Timer);
|
||||
Timer = 0;
|
||||
if (ListBitmap)
|
||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TLightRollover::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge)
|
||||
{
|
||||
ball->Position.X = nextPosition->X;
|
||||
ball->Position.Y = nextPosition->Y;
|
||||
ball->RayMaxDistance -= coef;
|
||||
ball->not_again(edge);
|
||||
if (!PinballTable->TiltLockFlag)
|
||||
{
|
||||
if (RolloverFlag)
|
||||
{
|
||||
timer::set(0.1f, this, TimerExpired);
|
||||
UnknownBaseFlag2 = 0;
|
||||
RolloverFlag = RolloverFlag == 0;
|
||||
if (Timer == 0)
|
||||
Timer = timer::set(FloatArr, this, delay_expired);
|
||||
}
|
||||
else
|
||||
{
|
||||
loader::play_sound(SoundIndex2);
|
||||
control::handler(63, this);
|
||||
RolloverFlag = RolloverFlag == 0;
|
||||
if (ListBitmap)
|
||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TLightRollover::delay_expired(int timerId, void* caller)
|
||||
{
|
||||
auto roll = static_cast<TLightRollover*>(caller);
|
||||
render::sprite_set_bitmap(roll->RenderSprite, nullptr);
|
||||
roll->Timer = 0;
|
||||
}
|
||||
|
@ -5,7 +5,14 @@ class TLightRollover :
|
||||
public TRollover
|
||||
{
|
||||
public:
|
||||
TLightRollover(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex)
|
||||
{
|
||||
}
|
||||
TLightRollover(TPinballTable* table, int groupIndex);
|
||||
~TLightRollover() override = default;
|
||||
int Message(int code, float value) override;
|
||||
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge) override;
|
||||
|
||||
static void delay_expired(int timerId, void* caller);
|
||||
|
||||
float FloatArr;
|
||||
int Timer;
|
||||
};
|
||||
|
@ -53,10 +53,11 @@ void TLine::EdgeCollision(TBall* ball, float coef)
|
||||
|
||||
void TLine::place_in_grid()
|
||||
{
|
||||
auto xBox0 = TTableLayer::edge_manager->box_x(X0);
|
||||
auto yBox0 = TTableLayer::edge_manager->box_y(Y0);
|
||||
auto xBox1 = TTableLayer::edge_manager->box_x(X1);
|
||||
auto yBox1 = TTableLayer::edge_manager->box_y(Y1);
|
||||
auto edgeMan = TTableLayer::edge_manager;
|
||||
auto xBox0 = edgeMan->box_x(X0);
|
||||
auto yBox0 = edgeMan->box_y(Y0);
|
||||
auto xBox1 = edgeMan->box_x(X1);
|
||||
auto yBox1 = edgeMan->box_y(Y1);
|
||||
|
||||
int dirX = X0 >= X1 ? -1 : 1;
|
||||
int dirY = Y0 >= Y1 ? -1 : 1;
|
||||
@ -66,12 +67,12 @@ void TLine::place_in_grid()
|
||||
if (dirX == 1)
|
||||
{
|
||||
while (xBox0 <= xBox1)
|
||||
TTableLayer::edge_manager->add_edge_to_box(xBox0++, yBox0, this);
|
||||
edgeMan->add_edge_to_box(xBox0++, yBox0, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (xBox0 >= xBox1)
|
||||
TTableLayer::edge_manager->add_edge_to_box(xBox0--, yBox0, this);
|
||||
edgeMan->add_edge_to_box(xBox0--, yBox0, this);
|
||||
}
|
||||
}
|
||||
else if (xBox0 == xBox1)
|
||||
@ -81,14 +82,14 @@ void TLine::place_in_grid()
|
||||
if (yBox0 <= yBox1)
|
||||
{
|
||||
do
|
||||
TTableLayer::edge_manager->add_edge_to_box(xBox0, yBox0++, this);
|
||||
edgeMan->add_edge_to_box(xBox0, yBox0++, this);
|
||||
while (yBox0 <= yBox1);
|
||||
}
|
||||
}
|
||||
else if (yBox0 >= yBox1)
|
||||
{
|
||||
do
|
||||
TTableLayer::edge_manager->add_edge_to_box(xBox0, yBox0--, this);
|
||||
edgeMan->add_edge_to_box(xBox0, yBox0--, this);
|
||||
while (yBox0 >= yBox1);
|
||||
}
|
||||
}
|
||||
@ -99,16 +100,15 @@ void TLine::place_in_grid()
|
||||
int bresIndexX = xBox0 + 1, bresIndexY = yBox0 + 1;
|
||||
auto bresDyDx = (Y0 - Y1) / (X0 - X1);
|
||||
auto bresXAdd = Y0 - bresDyDx * X0;
|
||||
TTableLayer::edge_manager->add_edge_to_box(xBox0, yBox0, this);
|
||||
edgeMan->add_edge_to_box(xBox0, yBox0, this);
|
||||
if (dirX == 1)
|
||||
{
|
||||
if (dirY == 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
yCoord = bresIndexY * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y;
|
||||
xCoord = (bresIndexX * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) *
|
||||
bresDyDx + bresXAdd;
|
||||
yCoord = bresIndexY * edgeMan->AdvanceY + edgeMan->Y;
|
||||
xCoord = (bresIndexX * edgeMan->AdvanceX + edgeMan->X) * bresDyDx + bresXAdd;
|
||||
if (xCoord >= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
@ -124,7 +124,7 @@ void TLine::place_in_grid()
|
||||
++indexX1;
|
||||
++bresIndexX;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
edgeMan->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
@ -132,9 +132,8 @@ void TLine::place_in_grid()
|
||||
{
|
||||
do
|
||||
{
|
||||
yCoord = indexY1 * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y;
|
||||
xCoord = (bresIndexX * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) *
|
||||
bresDyDx + bresXAdd;
|
||||
yCoord = indexY1 * edgeMan->AdvanceY + edgeMan->Y;
|
||||
xCoord = (bresIndexX * edgeMan->AdvanceX + edgeMan->X) * bresDyDx + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
@ -149,7 +148,7 @@ void TLine::place_in_grid()
|
||||
++indexX1;
|
||||
++bresIndexX;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
edgeMan->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
@ -160,9 +159,8 @@ void TLine::place_in_grid()
|
||||
{
|
||||
do
|
||||
{
|
||||
xCoord = bresIndexY * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y;
|
||||
yCoord = (indexX1 * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) *
|
||||
bresDyDx + bresXAdd;
|
||||
xCoord = bresIndexY * edgeMan->AdvanceY + edgeMan->Y;
|
||||
yCoord = (indexX1 * edgeMan->AdvanceX + edgeMan->X) * bresDyDx + bresXAdd;
|
||||
if (yCoord >= xCoord)
|
||||
{
|
||||
if (yCoord == xCoord)
|
||||
@ -174,7 +172,7 @@ void TLine::place_in_grid()
|
||||
{
|
||||
--indexX1;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
edgeMan->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
@ -182,9 +180,8 @@ void TLine::place_in_grid()
|
||||
{
|
||||
do
|
||||
{
|
||||
yCoord = indexY1 * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y;
|
||||
xCoord = (indexX1 * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) *
|
||||
bresDyDx + bresXAdd;
|
||||
yCoord = indexY1 * edgeMan->AdvanceY + edgeMan->Y;
|
||||
xCoord = (indexX1 * edgeMan->AdvanceX + edgeMan->X) * bresDyDx + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
@ -195,7 +192,7 @@ void TLine::place_in_grid()
|
||||
{
|
||||
--indexX1;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
edgeMan->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
|
@ -1,2 +1,86 @@
|
||||
#include "pch.h"
|
||||
#include "TOneway.h"
|
||||
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "TBall.h"
|
||||
#include "TLine.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||
{
|
||||
visualStruct visual{};
|
||||
vector_type linePt1{}, linePt2{};
|
||||
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
if (visual.FloatArrCount == 2)
|
||||
{
|
||||
linePt2.X = visual.FloatArr[0];
|
||||
linePt2.Y = visual.FloatArr[1];
|
||||
linePt1.X = visual.FloatArr[2];
|
||||
linePt1.Y = visual.FloatArr[3];
|
||||
|
||||
auto line = new TLine(this, &UnknownBaseFlag2, visual.Flag, &linePt2, &linePt1);
|
||||
if (line)
|
||||
{
|
||||
line->Offset(table->CollisionCompOffset);
|
||||
line->place_in_grid();
|
||||
EdgeList->Add(line);
|
||||
}
|
||||
|
||||
line = new TLine(this, &UnknownBaseFlag2, visual.Flag, &linePt1, &linePt2);
|
||||
Line = line;
|
||||
if (line)
|
||||
{
|
||||
line->Offset(-table->CollisionCompOffset * 0.8f);
|
||||
Line->place_in_grid();
|
||||
EdgeList->Add(Line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TOneway::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge)
|
||||
{
|
||||
if (edge == Line)
|
||||
{
|
||||
ball->not_again(edge);
|
||||
ball->Position.X = nextPosition->X;
|
||||
ball->Position.Y = nextPosition->Y;
|
||||
ball->RayMaxDistance -= coef;
|
||||
if (!PinballTable->TiltLockFlag)
|
||||
{
|
||||
if (SoundIndex1)
|
||||
loader::play_sound(SoundIndex1);
|
||||
control::handler(63, this);
|
||||
}
|
||||
}
|
||||
else if (PinballTable->TiltLockFlag)
|
||||
{
|
||||
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0);
|
||||
}
|
||||
else if (maths::basic_collision(
|
||||
ball,
|
||||
nextPosition,
|
||||
direction,
|
||||
UnknownC4F,
|
||||
UnknownC5F,
|
||||
MaxCollisionSpeed,
|
||||
CollisionMultiplier) > 0.2)
|
||||
{
|
||||
if (SoundIndex2)
|
||||
loader::play_sound(SoundIndex2);
|
||||
}
|
||||
}
|
||||
|
||||
void TOneway::put_scoring(int index, int score)
|
||||
{
|
||||
if (index < 6)
|
||||
Scores[index] = score;
|
||||
}
|
||||
|
||||
int TOneway::get_scoring(int index)
|
||||
{
|
||||
return index < 6 ? Scores[index] : 0;
|
||||
}
|
||||
|
@ -1,11 +1,18 @@
|
||||
#pragma once
|
||||
#include "TCollisionComponent.h"
|
||||
|
||||
class TOneway :
|
||||
public TCollisionComponent
|
||||
class TLine;
|
||||
|
||||
class TOneway : public TCollisionComponent
|
||||
{
|
||||
public:
|
||||
TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||
{
|
||||
}
|
||||
TOneway(TPinballTable* table, int groupIndex);
|
||||
~TOneway() override = default;
|
||||
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge) override;
|
||||
void put_scoring(int index, int score) override;
|
||||
int get_scoring(int index) override;
|
||||
|
||||
TLine* Line;
|
||||
int Scores[6];
|
||||
};
|
||||
|
@ -101,11 +101,11 @@ void TPinballComponent::port_draw()
|
||||
{
|
||||
}
|
||||
|
||||
void TPinballComponent::put_scoring(int scoreId, int value)
|
||||
void TPinballComponent::put_scoring(int index, int score)
|
||||
{
|
||||
}
|
||||
|
||||
int TPinballComponent::get_scoring(int score1)
|
||||
int TPinballComponent::get_scoring(int index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,8 +17,8 @@ public:
|
||||
virtual ~TPinballComponent();
|
||||
virtual int Message(int code, float value);
|
||||
virtual void port_draw();
|
||||
virtual void put_scoring(int scoreId, int value);
|
||||
virtual int get_scoring(int score1);
|
||||
virtual void put_scoring(int index, int score);
|
||||
virtual int get_scoring(int index);
|
||||
|
||||
__int8 UnknownBaseFlag1;
|
||||
__int8 UnknownBaseFlag2;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "memory.h"
|
||||
#include "objlist_class.h"
|
||||
#include "pb.h"
|
||||
#include "pinball.h"
|
||||
#include "render.h"
|
||||
|
@ -26,7 +26,7 @@ class TPinballTable : public TPinballComponent
|
||||
{
|
||||
public:
|
||||
TPinballTable();
|
||||
~TPinballTable();
|
||||
~TPinballTable() override;
|
||||
TPinballComponent* find_component(LPCSTR componentName);
|
||||
TPinballComponent* find_component(int groupIndex);
|
||||
int AddScore(int score);
|
||||
|
@ -6,6 +6,7 @@ class TPlunger :
|
||||
{
|
||||
public:
|
||||
TPlunger(TPinballTable* table, int groupIndex);
|
||||
~TPlunger() override = default;
|
||||
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge) override;
|
||||
int Message(int code, float value) override;
|
||||
|
@ -1,2 +1,99 @@
|
||||
#include "pch.h"
|
||||
#include "TRollover.h"
|
||||
|
||||
|
||||
#include "control.h"
|
||||
#include "gdrv.h"
|
||||
#include "loader.h"
|
||||
#include "render.h"
|
||||
#include "TBall.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TRollover::TRollover(TPinballTable* table, int groupIndex, bool createWall) : TCollisionComponent(
|
||||
table, groupIndex, createWall)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TRollover::TRollover(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||
{
|
||||
RolloverFlag = 0;
|
||||
if (ListBitmap)
|
||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||
build_walls(groupIndex);
|
||||
}
|
||||
|
||||
|
||||
int TRollover::Message(int code, float value)
|
||||
{
|
||||
if (code == 1024)
|
||||
{
|
||||
this->UnknownBaseFlag2 = 1;
|
||||
this->RolloverFlag = 0;
|
||||
if (this->ListBitmap)
|
||||
render::sprite_set_bitmap(this->RenderSprite, static_cast<gdrv_bitmap8*>(this->ListBitmap->Get(0)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TRollover::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge)
|
||||
{
|
||||
ball->Position.X = nextPosition->X;
|
||||
ball->Position.Y = nextPosition->Y;
|
||||
ball->RayMaxDistance -= coef;
|
||||
ball->not_again(edge);
|
||||
gdrv_bitmap8* bmp = nullptr;
|
||||
if (!PinballTable->TiltLockFlag)
|
||||
{
|
||||
if (RolloverFlag)
|
||||
{
|
||||
timer::set(0.1f, this, TimerExpired);
|
||||
UnknownBaseFlag2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
loader::play_sound(SoundIndex2);
|
||||
control::handler(63, this);
|
||||
}
|
||||
RolloverFlag = RolloverFlag == 0;
|
||||
if (ListBitmap)
|
||||
{
|
||||
if (!RolloverFlag)
|
||||
bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
render::sprite_set_bitmap(RenderSprite, bmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TRollover::put_scoring(int index, int score)
|
||||
{
|
||||
if (index < 2)
|
||||
Scores[index] = score;
|
||||
}
|
||||
|
||||
int TRollover::get_scoring(int index)
|
||||
{
|
||||
return index < 2 ? Scores[index] : 0;
|
||||
}
|
||||
|
||||
|
||||
void TRollover::build_walls(int groupIndex)
|
||||
{
|
||||
visualStruct visual{};
|
||||
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
float* arr1 = loader::query_float_attribute(groupIndex, 0, 600);
|
||||
TEdgeSegment::install_wall(arr1, this, &UnknownBaseFlag2, visual.Flag, 0.0, 600);
|
||||
float* arr2 = loader::query_float_attribute(groupIndex, 0, 603);
|
||||
TEdgeSegment::install_wall(arr2, this, &RolloverFlag, visual.Flag, 0.0, 603);
|
||||
}
|
||||
|
||||
void TRollover::TimerExpired(int timerId, void* caller)
|
||||
{
|
||||
auto roll = static_cast<TRollover*>(caller);
|
||||
roll->UnknownBaseFlag2 = 1;
|
||||
}
|
||||
|
@ -4,8 +4,20 @@
|
||||
class TRollover :
|
||||
public TCollisionComponent
|
||||
{
|
||||
protected:
|
||||
TRollover(TPinballTable* table, int groupIndex, bool createWall);
|
||||
public:
|
||||
TRollover(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
}
|
||||
TRollover(TPinballTable* table, int groupIndex);
|
||||
~TRollover() override = default;
|
||||
int Message(int code, float value) override;
|
||||
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge) override;
|
||||
void put_scoring(int index, int score) override;
|
||||
int get_scoring(int index) override;
|
||||
void build_walls(int groupIndex);
|
||||
|
||||
static void TimerExpired(int timerId, void* caller);
|
||||
|
||||
char RolloverFlag;
|
||||
int Scores[2];
|
||||
};
|
||||
|
@ -2,8 +2,10 @@
|
||||
#include "TTableLayer.h"
|
||||
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "proj.h"
|
||||
#include "render.h"
|
||||
#include "TBall.h"
|
||||
#include "TLine.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
@ -114,8 +116,8 @@ int TTableLayer::FieldEffect(TBall* ball, vector_type* vecDst)
|
||||
void TTableLayer::edges_insert_square(float y0, float x0, float y1, float x1, TEdgeSegment* edge,
|
||||
field_effect_type* field)
|
||||
{
|
||||
float widthM = edge_manager->AdvanceX * 0.001f;
|
||||
float heightM = edge_manager->AdvanceY * 0.001f;
|
||||
float widthM = static_cast<float>(static_cast<int>(edge_manager->AdvanceX * 0.001f)); // Sic
|
||||
float heightM = static_cast<float>(static_cast<int>(edge_manager->AdvanceY * 0.001f));
|
||||
float xMin = x0 - widthM;
|
||||
float xMax = x1 + widthM;
|
||||
float yMin = y0 - heightM;
|
||||
@ -127,10 +129,9 @@ void TTableLayer::edges_insert_square(float y0, float x0, float y1, float x1, TE
|
||||
int yMaxBox = edge_manager->box_y(yMax);
|
||||
|
||||
float boxX = static_cast<float>(xMinBox) * edge_manager->AdvanceX + edge_manager->X;
|
||||
float boxY = static_cast<float>(yMinBox) * edge_manager->AdvanceY + edge_manager->Y;
|
||||
|
||||
for (int indexX = xMinBox; indexX <= xMaxBox; ++indexX)
|
||||
{
|
||||
float boxY = static_cast<float>(yMinBox) * edge_manager->AdvanceY + edge_manager->Y;
|
||||
for (int indexY = yMinBox; indexY <= yMaxBox; ++indexY)
|
||||
{
|
||||
if (xMax >= boxX && xMin <= boxX + edge_manager->AdvanceX &&
|
||||
@ -150,3 +151,127 @@ void TTableLayer::edges_insert_square(float y0, float x0, float y1, float x1, TE
|
||||
boxX += edge_manager->AdvanceX;
|
||||
}
|
||||
}
|
||||
|
||||
void TTableLayer::edges_insert_circle(circle_type* circle, TEdgeSegment* edge, field_effect_type* field)
|
||||
{
|
||||
ray_type ray{};
|
||||
vector_type vec1{};
|
||||
|
||||
auto radiusM = sqrt(circle->RadiusSq) + edge_manager->AdvanceX * 0.001f;
|
||||
auto radiusMSq = radiusM * radiusM;
|
||||
|
||||
auto xMin = circle->Center.X - radiusM;
|
||||
auto yMin = circle->Center.Y - radiusM;
|
||||
auto xMax = radiusM + circle->Center.X;
|
||||
auto yMax = radiusM + circle->Center.Y;
|
||||
|
||||
auto xMinBox = edge_manager->box_x(xMin);
|
||||
auto yMinBox = edge_manager->box_y(yMin);
|
||||
auto xMaxBox = edge_manager->box_x(xMax);
|
||||
auto yMaxBox = edge_manager->box_y(yMax);
|
||||
|
||||
auto dirX = xMinBox - 1 <= 0 ? 0 : xMinBox - 1;
|
||||
auto dirY = yMinBox - 1 <= 0 ? 0 : yMinBox - 1;
|
||||
|
||||
xMaxBox = edge_manager->increment_box_x(xMaxBox);
|
||||
yMaxBox = edge_manager->increment_box_y(yMaxBox);
|
||||
|
||||
vec1.X = static_cast<float>(dirX) * edge_manager->AdvanceX + edge_manager->X;
|
||||
for (auto indexX = dirX; indexX <= xMaxBox; ++indexX)
|
||||
{
|
||||
vec1.Y = static_cast<float>(dirY) * edge_manager->AdvanceY + edge_manager->Y;
|
||||
for (int indexY = dirY; indexY <= yMaxBox; ++indexY)
|
||||
{
|
||||
auto vec1XAdv = vec1.X + edge_manager->AdvanceX;
|
||||
auto vec1YAdv = vec1.Y + edge_manager->AdvanceY;
|
||||
if (xMax >= vec1.X && xMin <= vec1XAdv &&
|
||||
yMax >= vec1.Y && yMin <= vec1YAdv)
|
||||
{
|
||||
bool collision = true;
|
||||
do
|
||||
{
|
||||
if (circle->Center.X <= vec1XAdv && circle->Center.X >= vec1.X &&
|
||||
circle->Center.Y <= vec1YAdv && circle->Center.Y >= vec1.Y)
|
||||
break;
|
||||
|
||||
auto vec2 = vec1;
|
||||
if (maths::Distance_Squared(vec1, circle->Center) <= radiusMSq)
|
||||
break;
|
||||
|
||||
vec2.X = vec2.X + edge_manager->AdvanceX;
|
||||
if (maths::Distance_Squared(vec2, circle->Center) <= radiusMSq)
|
||||
break;
|
||||
|
||||
vec2.Y = vec2.Y + edge_manager->AdvanceY;
|
||||
if (maths::Distance_Squared(vec2, circle->Center) <= radiusMSq)
|
||||
break;
|
||||
|
||||
vec2.X = vec2.X - edge_manager->AdvanceX;
|
||||
if (maths::Distance_Squared(vec2, circle->Center) <= radiusMSq)
|
||||
break;
|
||||
|
||||
ray.Origin = vec1;
|
||||
ray.Direction.X = 1.0;
|
||||
ray.Direction.Y = 0.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
ray.Direction.X = -1.0;
|
||||
ray.Origin.X = ray.Origin.X + edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
ray.Direction.X = 0.0;
|
||||
ray.Direction.Y = 1.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
ray.Direction.Y = -1.0;
|
||||
ray.Origin.Y = ray.Origin.Y + edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
ray.Direction.Y = 0.0;
|
||||
ray.Direction.X = -1.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
ray.Direction.X = 1.0;
|
||||
ray.Origin.X = ray.Origin.X - edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
ray.Direction.X = 0.0;
|
||||
ray.Direction.Y = -1.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
ray.Direction.Y = 1.0;
|
||||
ray.Origin.Y = ray.Origin.Y - edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
collision = false;
|
||||
}
|
||||
while (false);
|
||||
if (collision)
|
||||
{
|
||||
if (edge)
|
||||
{
|
||||
edge_manager->add_edge_to_box(indexX, indexY, edge);
|
||||
}
|
||||
if (field)
|
||||
{
|
||||
edge_manager->add_field_to_box(indexX, indexY, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
vec1.Y += edge_manager->AdvanceY;
|
||||
}
|
||||
vec1.X += edge_manager->AdvanceX;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "TEdgeManager.h"
|
||||
|
||||
|
||||
struct circle_type;
|
||||
class TPinballTable;
|
||||
class TEdgeManager;
|
||||
struct gdrv_bitmap8;
|
||||
@ -17,6 +18,7 @@ public:
|
||||
|
||||
static void edges_insert_square(float y0, float x0, float y1, float x1, TEdgeSegment* edge,
|
||||
field_effect_type* field);
|
||||
static void edges_insert_circle(circle_type* circle, TEdgeSegment* edge, field_effect_type* field);
|
||||
|
||||
gdrv_bitmap8* VisBmp;
|
||||
float Unknown1F;
|
||||
|
@ -1,2 +1,25 @@
|
||||
#include "pch.h"
|
||||
#include "TTripwire.h"
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "TBall.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TTripwire::TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, 1)
|
||||
{
|
||||
}
|
||||
|
||||
void TTripwire::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge)
|
||||
{
|
||||
ball->Position.X = nextPosition->X;
|
||||
ball->Position.Y = nextPosition->Y;
|
||||
ball->RayMaxDistance -= coef;
|
||||
ball->not_again(edge);
|
||||
if (!PinballTable->TiltLockFlag)
|
||||
{
|
||||
loader::play_sound(SoundIndex2);
|
||||
control::handler(63, this);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ class TTripwire :
|
||||
public TRollover
|
||||
{
|
||||
public:
|
||||
TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex)
|
||||
{
|
||||
}
|
||||
TTripwire(TPinballTable* table, int groupIndex);
|
||||
~TTripwire() override = default;
|
||||
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge) override;
|
||||
};
|
||||
|
@ -836,10 +836,32 @@ void control::RightKickerGateControl(int code, TPinballComponent* caller)
|
||||
|
||||
void control::DeploymentChuteToEscapeChuteOneWayControl(int code, TPinballComponent* caller)
|
||||
{
|
||||
char Buffer[64];
|
||||
if (code == 63)
|
||||
{
|
||||
int count = control_skill_shot_lights_tag.Component->Message(37, 0.0);
|
||||
if (count)
|
||||
{
|
||||
static_cast<TSound*>(control_soundwave3_tag.Component)->Play();
|
||||
int score = TableG->AddScore(caller->get_scoring(count - 1));
|
||||
sprintf_s(Buffer, pinball::get_rc_string(21, 0), score);
|
||||
static_cast<TTextBox*>(control_info_text_box_tag.Component)->Display(Buffer, 2.0);
|
||||
if (!light_on(&control_lite56_tag))
|
||||
{
|
||||
control_l_trek_lights_tag.Component->Message(34, 0.0);
|
||||
control_l_trek_lights_tag.Component->Message(20, 0.0);
|
||||
control_r_trek_lights_tag.Component->Message(34, 0.0);
|
||||
control_r_trek_lights_tag.Component->Message(20, 0.0);
|
||||
}
|
||||
control_skill_shot_lights_tag.Component->Message(44, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void control::DeploymentChuteToTableOneWayControl(int code, TPinballComponent* caller)
|
||||
{
|
||||
if (code == 63)
|
||||
control_skill_shot_lights_tag.Component->Message(20, 0.0);
|
||||
}
|
||||
|
||||
void control::DrainBallBlockerControl(int code, TPinballComponent* caller)
|
||||
|
@ -299,3 +299,8 @@ float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type
|
||||
}
|
||||
return projSpeed;
|
||||
}
|
||||
|
||||
float maths::Distance_Squared(vector_type vec1, vector_type vec2)
|
||||
{
|
||||
return (vec1.Y - vec2.Y) * (vec1.Y - vec2.Y) + (vec1.X - vec2.X) * (vec1.X - vec2.X);
|
||||
}
|
||||
|
@ -59,5 +59,7 @@ public:
|
||||
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
|
||||
static float magnitude(vector_type* vec);
|
||||
static void vector_add(vector_type* vec1Dst, vector_type* vec2);
|
||||
static float basic_collision(TBall* ball, struct vector_type* nextPosition, struct vector_type* direction, float a4, float a5, float maxSpeed, float multiplier);
|
||||
static float basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5,
|
||||
float maxSpeed, float multiplier);
|
||||
static float Distance_Squared(vector_type vec1, vector_type vec2);
|
||||
};
|
||||
|
@ -11,12 +11,14 @@
|
||||
#include "loader.h"
|
||||
#include "midi.h"
|
||||
#include "nudge.h"
|
||||
#include "objlist_class.h"
|
||||
#include "options.h"
|
||||
#include "timer.h"
|
||||
#include "winmain.h"
|
||||
#include "resource.h"
|
||||
#include "TBall.h"
|
||||
#include "TDemo.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "TLightGroup.h"
|
||||
#include "TPlunger.h"
|
||||
#include "TTableLayer.h"
|
||||
@ -623,6 +625,7 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
||||
|
||||
TEdgeSegment* edge = nullptr;
|
||||
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
|
||||
ball->EdgeCollisionCount = 0;
|
||||
if (distance >= 1000000000.0)
|
||||
{
|
||||
maxDistance = timeDelta * ball->Speed;
|
||||
|
Loading…
Reference in New Issue
Block a user