mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-17 15:20:17 +01:00
TPlunger ready. TEdgeManager v1.
This commit is contained in:
parent
1ea247e185
commit
9bd064bf15
28 changed files with 866 additions and 118 deletions
Binary file not shown.
|
@ -184,6 +184,7 @@
|
|||
<ClInclude Include="TComponentGroup.h" />
|
||||
<ClInclude Include="TDemo.h" />
|
||||
<ClInclude Include="TDrain.h" />
|
||||
<ClInclude Include="TEdgeBox.h" />
|
||||
<ClInclude Include="TEdgeManager.h" />
|
||||
<ClInclude Include="TEdgeSegment.h" />
|
||||
<ClInclude Include="TFlagSpinner.h" />
|
||||
|
@ -252,6 +253,7 @@
|
|||
<ClCompile Include="TComponentGroup.cpp" />
|
||||
<ClCompile Include="TDemo.cpp" />
|
||||
<ClCompile Include="TDrain.cpp" />
|
||||
<ClCompile Include="TEdgeBox.cpp" />
|
||||
<ClCompile Include="TEdgeManager.cpp" />
|
||||
<ClCompile Include="TEdgeSegment.cpp" />
|
||||
<ClCompile Include="TFlagSpinner.cpp" />
|
||||
|
|
|
@ -216,6 +216,9 @@
|
|||
<ClInclude Include="TEdgeManager.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TEdgeBox.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
|
@ -398,6 +401,9 @@
|
|||
<ClCompile Include="TEdgeManager.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TEdgeBox.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="NatvisFile.natvis" />
|
||||
|
|
|
@ -20,7 +20,7 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
|||
CollisionComp = nullptr;
|
||||
EdgeCollisionCount = 0;
|
||||
TimeDelta = 0.0;
|
||||
Unknown17F = 1;
|
||||
FieldFlag = 1;
|
||||
CollisionFlag = 0;
|
||||
Speed = 0.0;
|
||||
Acceleration.Y = 0.0;
|
||||
|
@ -83,8 +83,8 @@ void TBall::Repaint()
|
|||
RenderSprite,
|
||||
bmp,
|
||||
zDepth,
|
||||
bmp->Width / 2 - pos2D[0],
|
||||
bmp->Height / 2 - pos2D[1]);
|
||||
pos2D[0] - bmp->Width / 2,
|
||||
pos2D[1] - bmp->Height / 2);
|
||||
}
|
||||
|
||||
void TBall::not_again(TEdgeSegment* edge)
|
||||
|
@ -117,7 +117,7 @@ int TBall::Message(int code, float value)
|
|||
Position.Y = 0.0;
|
||||
UnknownBaseFlag2 = 0;
|
||||
CollisionFlag = 0;
|
||||
Unknown17F = 1;
|
||||
FieldFlag = 1;
|
||||
Acceleration.Y = 0.0;
|
||||
Position.Z = Offset;
|
||||
Acceleration.X = 0.0;
|
||||
|
|
|
@ -25,7 +25,7 @@ public :
|
|||
int Unknown14;
|
||||
int Unknown15;
|
||||
TCollisionComponent* CollisionComp;
|
||||
float Unknown17F;
|
||||
int FieldFlag;
|
||||
TEdgeSegment* Collisions[5];
|
||||
int EdgeCollisionCount;
|
||||
vector_type CollisionOffset;
|
||||
|
|
|
@ -8,7 +8,19 @@ TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visu
|
|||
Circle.Center = *center;
|
||||
}
|
||||
|
||||
double TCircle::FindCollisionDistance(ray_type* ray)
|
||||
float TCircle::FindCollisionDistance(ray_type* ray)
|
||||
{
|
||||
return maths::ray_intersect_circle(ray, &Circle);
|
||||
}
|
||||
}
|
||||
|
||||
void TCircle::EdgeCollision(TBall* ball, float coef)
|
||||
{
|
||||
vector_type direction{}, nextPosition{};
|
||||
|
||||
nextPosition.X = coef * ball->Acceleration.X + ball->Position.X;
|
||||
nextPosition.Y = coef * ball->Acceleration.Y + ball->Position.Y;
|
||||
direction.X = nextPosition.X - Circle.Center.X;
|
||||
direction.Y = nextPosition.Y - Circle.Center.Y;
|
||||
maths::normalize_2d(&direction);
|
||||
CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this);
|
||||
}
|
||||
|
|
|
@ -10,11 +10,8 @@ public:
|
|||
|
||||
TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned int visualFlag, vector_type* center,
|
||||
float radius);
|
||||
double FindCollisionDistance(ray_type* ray) override;
|
||||
|
||||
void EdgeCollision(TBall* ball, float coef) override
|
||||
{
|
||||
}
|
||||
float FindCollisionDistance(ray_type* ray) override;
|
||||
void EdgeCollision(TBall* ball, float coef) override;
|
||||
|
||||
void place_in_grid() override
|
||||
{
|
||||
|
|
|
@ -29,10 +29,10 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b
|
|||
}
|
||||
}
|
||||
|
||||
UnknownC7F = visual.Kicker.Unknown1F;
|
||||
MaxCollisionSpeed = visual.Kicker.Unknown1F;
|
||||
UnknownC4F = visual.Unknown2F;
|
||||
UnknownC5F = visual.Unknown1F;
|
||||
UnknownC6F = visual.Kicker.Unknown2F;
|
||||
CollisionMultiplier = visual.Kicker.Unknown2F;
|
||||
SoundIndex1 = visual.Kicker.SoundIndex;
|
||||
SoundIndex2 = visual.SoundIndex2;
|
||||
GroupIndex = groupIndex;
|
||||
|
@ -58,17 +58,17 @@ void TCollisionComponent::port_draw()
|
|||
}
|
||||
}
|
||||
|
||||
int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* ballPosition, vector_type* vec2)
|
||||
int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* nextPosition, vector_type* direction)
|
||||
{
|
||||
if (PinballTable->TiltLockFlag)
|
||||
{
|
||||
maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F, 1000000000.0, 0.0);
|
||||
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0);
|
||||
return 0;
|
||||
}
|
||||
auto projSpeed = maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F,
|
||||
UnknownC7F,
|
||||
UnknownC6F);
|
||||
if (projSpeed <= UnknownC7F)
|
||||
auto projSpeed = maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F,
|
||||
MaxCollisionSpeed,
|
||||
CollisionMultiplier);
|
||||
if (projSpeed <= MaxCollisionSpeed)
|
||||
{
|
||||
if (projSpeed > 0.2)
|
||||
{
|
||||
|
@ -82,25 +82,25 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* ballPosition
|
|||
return 1;
|
||||
}
|
||||
|
||||
void TCollisionComponent::Collision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2,
|
||||
float someVal, TEdgeSegment* edge)
|
||||
void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction,
|
||||
float coef, TEdgeSegment* edge)
|
||||
{
|
||||
int soundIndex;
|
||||
|
||||
if (PinballTable->TiltLockFlag)
|
||||
{
|
||||
maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F, 1000000000.0, 0.0);
|
||||
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0);
|
||||
return;
|
||||
}
|
||||
double projSpeed = maths::basic_collision(
|
||||
ball,
|
||||
ballPosition,
|
||||
vec2,
|
||||
nextPosition,
|
||||
direction,
|
||||
UnknownC4F,
|
||||
UnknownC5F,
|
||||
UnknownC7F,
|
||||
UnknownC6F);
|
||||
if (projSpeed <= UnknownC7F)
|
||||
MaxCollisionSpeed,
|
||||
CollisionMultiplier);
|
||||
if (projSpeed <= MaxCollisionSpeed)
|
||||
{
|
||||
if (projSpeed <= 0.2)
|
||||
return;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "objlist_class.h"
|
||||
#include "TPinballComponent.h"
|
||||
|
||||
struct vector_type;
|
||||
class TEdgeSegment;
|
||||
class TBall;
|
||||
|
||||
|
@ -13,16 +14,16 @@ public:
|
|||
__int16 UnknownC3;
|
||||
float UnknownC4F;
|
||||
float UnknownC5F;
|
||||
float UnknownC6F;
|
||||
float UnknownC7F;
|
||||
float CollisionMultiplier;
|
||||
float MaxCollisionSpeed;
|
||||
int SoundIndex2;
|
||||
int SoundIndex1;
|
||||
|
||||
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
|
||||
~TCollisionComponent();
|
||||
void port_draw() override;
|
||||
virtual void Collision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2, float someVal,
|
||||
virtual void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge);
|
||||
virtual int FieldEffect(TBall* ball, struct vector_type* vecDst);
|
||||
int DefaultCollision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2);
|
||||
virtual int FieldEffect(TBall* ball, vector_type* vecDst);
|
||||
int DefaultCollision(TBall* ball, vector_type* nextPosition, vector_type* direction);
|
||||
};
|
||||
|
|
16
SpaceCadetPinball/TEdgeBox.cpp
Normal file
16
SpaceCadetPinball/TEdgeBox.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "pch.h"
|
||||
#include "TEdgeBox.h"
|
||||
|
||||
#include "objlist_class.h"
|
||||
|
||||
TEdgeBox::TEdgeBox()
|
||||
{
|
||||
EdgeList = new objlist_class(0, 4);
|
||||
FieldList = new objlist_class(0, 1);
|
||||
}
|
||||
|
||||
TEdgeBox::~TEdgeBox()
|
||||
{
|
||||
delete EdgeList;
|
||||
delete FieldList;
|
||||
}
|
13
SpaceCadetPinball/TEdgeBox.h
Normal file
13
SpaceCadetPinball/TEdgeBox.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
class objlist_class;
|
||||
|
||||
class TEdgeBox
|
||||
{
|
||||
public:
|
||||
TEdgeBox();
|
||||
~TEdgeBox();
|
||||
|
||||
objlist_class* EdgeList;
|
||||
objlist_class* FieldList;
|
||||
};
|
||||
|
|
@ -1,16 +1,274 @@
|
|||
#include "pch.h"
|
||||
#include "TEdgeManager.h"
|
||||
|
||||
int TEdgeManager::FieldEffects(TBall* ball, vector_type* vecDst)
|
||||
#include "TEdgeBox.h"
|
||||
#include "TTableLayer.h"
|
||||
|
||||
TEdgeManager::TEdgeManager(float posX, float posY, float width, float height)
|
||||
{
|
||||
return 0;
|
||||
X = posX;
|
||||
Y = posY;
|
||||
MaxBoxX = 10;
|
||||
MaxBoxY = 15;
|
||||
AdvanceX = width / 10.0f;
|
||||
AdvanceY = height / 15.0f;
|
||||
AdvanceXInv = 1.0f / AdvanceX;
|
||||
AdvanceYInv = 1.0f / AdvanceY;
|
||||
BoxArray = new TEdgeBox[150];
|
||||
}
|
||||
|
||||
void TEdgeManager::edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6)
|
||||
TEdgeManager::~TEdgeManager()
|
||||
{
|
||||
delete[] BoxArray;
|
||||
}
|
||||
|
||||
int TEdgeManager::box_x(float x)
|
||||
{
|
||||
return static_cast<int>((max(0, min(floor((x - X) * AdvanceXInv), (MaxBoxX - 1)))));
|
||||
}
|
||||
|
||||
int TEdgeManager::box_y(float y)
|
||||
{
|
||||
return static_cast<int>((max(0, min(floor((y - Y) * AdvanceYInv), (MaxBoxY - 1)))));
|
||||
}
|
||||
|
||||
int TEdgeManager::increment_box_x(int x)
|
||||
{
|
||||
return min(x + 1, MaxBoxX - 1);
|
||||
}
|
||||
|
||||
int TEdgeManager::increment_box_y(int y)
|
||||
{
|
||||
return min(y + 1, MaxBoxY - 1);
|
||||
}
|
||||
|
||||
void TEdgeManager::add_edge_to_box(int x, int y, TEdgeSegment* edge)
|
||||
{
|
||||
BoxArray[x + y * MaxBoxX].EdgeList->Add(edge);
|
||||
}
|
||||
|
||||
void TEdgeManager::add_field_to_box(int x, int y, field_effect_type* field)
|
||||
{
|
||||
BoxArray[x + y * MaxBoxX].FieldList->Add(field);
|
||||
}
|
||||
|
||||
int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeDst, ray_type* ray, TBall* ball,
|
||||
int edgeIndex)
|
||||
{
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 15)
|
||||
{
|
||||
TEdgeBox* edgeBox = &BoxArray[x + y * MaxBoxX];
|
||||
TEdgeSegment** edgePtr = &EdgeArray[edgeIndex];
|
||||
for (auto index = edgeBox->EdgeList->Count() - 1; index >= 0; --index)
|
||||
{
|
||||
auto edge = static_cast<TEdgeSegment*>(edgeBox->EdgeList->Get(index));
|
||||
if (!edge->ProcessedFlag && *edge->PinbCompFlag2Ptr && (edge->VisualFlag & ray->FieldFlag))
|
||||
{
|
||||
if (!ball->already_hit(edge))
|
||||
{
|
||||
++edgeIndex;
|
||||
*edgePtr = edge;
|
||||
++edgePtr;
|
||||
edge->ProcessedFlag = 1;
|
||||
auto dist = edge->FindCollisionDistance(ray);
|
||||
if (dist < *distPtr)
|
||||
{
|
||||
*distPtr = dist;
|
||||
*edgeDst = edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return edgeIndex;
|
||||
}
|
||||
|
||||
void TEdgeManager::FieldEffects(TBall* ball, vector_type* dstVec)
|
||||
{
|
||||
vector_type vec{};
|
||||
TEdgeBox* edgeBox = &BoxArray[box_x(ball->Position.X) + box_y(ball->Position.Y) *
|
||||
MaxBoxX];
|
||||
|
||||
for (int index = edgeBox->FieldList->Count() - 1; index >= 0; --index)
|
||||
{
|
||||
auto field = static_cast<field_effect_type*>(edgeBox->FieldList->Get(index));
|
||||
if (*field->Flag2Ptr && ball->FieldFlag & field->Mask)
|
||||
{
|
||||
if (field->CollisionComp->FieldEffect(ball, &vec))
|
||||
{
|
||||
maths::vector_add(dstVec, &vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float TEdgeManager::FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge)
|
||||
{
|
||||
return 1000000000.0;
|
||||
auto distance = 1000000000.0f;
|
||||
auto edgeIndex = 0;
|
||||
|
||||
auto rayX = ray->Origin.X;
|
||||
auto rayY = ray->Origin.Y;
|
||||
auto rayBoxX = box_x(rayX);
|
||||
auto rayBoxY = box_y(rayY);
|
||||
|
||||
auto rayEndX = ray->Direction.X * ray->MaxDistance + ray->Origin.X;
|
||||
auto rayEndY = ray->Direction.Y * ray->MaxDistance + ray->Origin.Y;
|
||||
auto rayEndBoxX = box_x(rayEndX);
|
||||
auto rayEndBoxY = box_y(rayEndY);
|
||||
|
||||
auto rayDirX = rayX >= rayEndX ? -1 : 1;
|
||||
auto rayDirY = rayY >= rayEndY ? -1 : 1;
|
||||
|
||||
if (rayBoxY == rayEndBoxY)
|
||||
{
|
||||
if (rayDirX == 1)
|
||||
{
|
||||
for (auto indexX = rayBoxX; indexX <= rayEndBoxX; indexX++)
|
||||
{
|
||||
edgeIndex = TestGridBox(indexX, rayBoxY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto indexX = rayBoxX; indexX >= rayEndBoxX; indexX--)
|
||||
{
|
||||
edgeIndex = TestGridBox(indexX, rayBoxY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rayBoxX == rayEndBoxX)
|
||||
{
|
||||
if (rayDirY == 1)
|
||||
{
|
||||
for (auto indexY = rayBoxY; indexY <= rayEndBoxY; indexY++)
|
||||
{
|
||||
edgeIndex = TestGridBox(rayBoxX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto indexY = rayBoxY; indexY >= rayEndBoxY; indexY--)
|
||||
{
|
||||
edgeIndex = TestGridBox(rayBoxX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rayDyDX = (rayY - rayEndY) / (rayX - rayEndX);
|
||||
auto indexX = rayBoxX;
|
||||
auto indexY = rayBoxY;
|
||||
auto bresIndexX = rayBoxX + 1;
|
||||
auto bresIndexY = rayBoxY + 1;
|
||||
auto bresXAdd = rayY - rayDyDX * rayX;
|
||||
edgeIndex = TestGridBox(rayBoxX, rayBoxY, &distance, edge, ray, ball, 0);
|
||||
if (rayDirX == 1)
|
||||
{
|
||||
if (rayDirY == 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = bresIndexY * AdvanceY + Y;
|
||||
auto xCoord = (bresIndexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord >= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
++indexY;
|
||||
++bresIndexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX < rayEndBoxX || indexY < rayEndBoxY);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = indexY * AdvanceY + Y;
|
||||
auto xCoord = (bresIndexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
--indexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX < rayEndBoxX || indexY > rayEndBoxY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rayDirY == 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = bresIndexY * AdvanceY + Y;
|
||||
auto xCoord = (indexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord >= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
--indexX;
|
||||
++indexY;
|
||||
++bresIndexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
--indexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX > rayEndBoxX || indexY < rayEndBoxY);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = indexY * AdvanceY + Y;
|
||||
auto xCoord = (indexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
--indexX;
|
||||
--indexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
--indexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX > rayEndBoxX || indexY > rayEndBoxY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto edgePtr = EdgeArray; edgeIndex > 0; --edgeIndex, ++edgePtr)
|
||||
{
|
||||
(*edgePtr)->ProcessedFlag = 0;
|
||||
}
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
|
|
@ -2,22 +2,38 @@
|
|||
#include "TCollisionComponent.h"
|
||||
#include "TEdgeSegment.h"
|
||||
|
||||
class TEdgeBox;
|
||||
|
||||
struct field_effect_type
|
||||
{
|
||||
char* Flag2Ptr;
|
||||
int Unknown1;
|
||||
int Mask;
|
||||
TCollisionComponent* CollisionComp;
|
||||
};
|
||||
|
||||
class TEdgeManager
|
||||
{
|
||||
public:
|
||||
TEdgeManager(float a2, float a3, float a4, float a5)
|
||||
{
|
||||
}
|
||||
|
||||
int FieldEffects(TBall* ball, struct vector_type* vecDst);
|
||||
|
||||
static void edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6);
|
||||
TEdgeManager(float posX, float posY, float width, float height);
|
||||
~TEdgeManager();
|
||||
void FieldEffects(TBall* ball, struct vector_type* dstVec);
|
||||
int box_x(float x);
|
||||
int box_y(float y);
|
||||
int increment_box_x(int x);
|
||||
int increment_box_y(int y);
|
||||
void add_edge_to_box(int x, int y, TEdgeSegment* edge);
|
||||
void add_field_to_box(int x, int y, field_effect_type* field);
|
||||
int TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeDst, ray_type* ray, TBall* ball, int edgeIndex);
|
||||
float FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge);
|
||||
|
||||
float AdvanceX;
|
||||
float AdvanceY;
|
||||
float AdvanceXInv;
|
||||
float AdvanceYInv;
|
||||
int MaxBoxX;
|
||||
int MaxBoxY;
|
||||
float X;
|
||||
float Y;
|
||||
TEdgeBox* BoxArray;
|
||||
TEdgeSegment* EdgeArray[1000];
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsign
|
|||
this->CollisionComponent = collComp;
|
||||
this->PinbCompFlag2Ptr = someFlag;
|
||||
this->VisualFlag = visualFlag;
|
||||
this->Unknown3_0 = 0;
|
||||
this->ProcessedFlag = 0;
|
||||
}
|
||||
|
||||
void TEdgeSegment::port_draw()
|
||||
|
|
|
@ -14,7 +14,7 @@ class TEdgeSegment
|
|||
public:
|
||||
TCollisionComponent* CollisionComponent;
|
||||
char* PinbCompFlag2Ptr;
|
||||
char Unknown3_0;
|
||||
char ProcessedFlag;
|
||||
int WallValue;
|
||||
int VisualFlag;
|
||||
|
||||
|
@ -24,7 +24,7 @@ public:
|
|||
virtual void EdgeCollision(TBall* ball, float coef) = 0;
|
||||
virtual void port_draw();
|
||||
virtual void place_in_grid() = 0;
|
||||
virtual double FindCollisionDistance(ray_type* ray) = 0;
|
||||
virtual float FindCollisionDistance(ray_type* ray) = 0;
|
||||
|
||||
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr,
|
||||
unsigned int visual_flag, float offset, int someValue);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "TLight.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, -1, false)
|
||||
TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
|
||||
{
|
||||
List = new objlist_class(4, 4);
|
||||
Timer = 0;
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
#include "pch.h"
|
||||
#include "TLine.h"
|
||||
|
||||
#include "TTableLayer.h"
|
||||
|
||||
|
||||
TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1,
|
||||
float y1): TEdgeSegment(collCmp, flagPtr, visualFlag)
|
||||
{
|
||||
this->X0 = x0;
|
||||
this->Y0 = y0;
|
||||
this->X1 = x1;
|
||||
this->Y1 = y1;
|
||||
X0 = x0;
|
||||
Y0 = y0;
|
||||
X1 = x1;
|
||||
Y1 = y1;
|
||||
maths::line_init(&Line, x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start,
|
||||
struct vector_type* end) : TEdgeSegment(collCmp, flagPtr, visualFlag)
|
||||
{
|
||||
this->X0 = start->X;
|
||||
this->Y0 = start->Y;
|
||||
this->X1 = end->X;
|
||||
this->Y1 = end->Y;
|
||||
X0 = start->X;
|
||||
Y0 = start->Y;
|
||||
X1 = end->X;
|
||||
Y1 = end->Y;
|
||||
maths::line_init(&Line, X0, Y0, X1, Y1);
|
||||
}
|
||||
|
||||
|
@ -34,7 +36,169 @@ void TLine::Offset(float offset)
|
|||
maths::line_init(&Line, X0, Y0, X1, Y1);
|
||||
}
|
||||
|
||||
double TLine::FindCollisionDistance(ray_type* ray)
|
||||
float TLine::FindCollisionDistance(ray_type* ray)
|
||||
{
|
||||
return maths::ray_intersect_line(ray, &Line);
|
||||
}
|
||||
|
||||
void TLine::EdgeCollision(TBall* ball, float coef)
|
||||
{
|
||||
CollisionComponent->Collision(
|
||||
ball,
|
||||
&Line.RayIntersect,
|
||||
&Line.PerpendicularL,
|
||||
coef,
|
||||
this);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
int dirX = X0 >= X1 ? -1 : 1;
|
||||
int dirY = Y0 >= Y1 ? -1 : 1;
|
||||
|
||||
if (yBox0 == yBox1)
|
||||
{
|
||||
if (dirX == 1)
|
||||
{
|
||||
while (xBox0 <= xBox1)
|
||||
TTableLayer::edge_manager->add_edge_to_box(xBox0++, yBox0, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (xBox0 >= xBox1)
|
||||
TTableLayer::edge_manager->add_edge_to_box(xBox0--, yBox0, this);
|
||||
}
|
||||
}
|
||||
else if (xBox0 == xBox1)
|
||||
{
|
||||
if (dirY == 1)
|
||||
{
|
||||
if (yBox0 <= yBox1)
|
||||
{
|
||||
do
|
||||
TTableLayer::edge_manager->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);
|
||||
while (yBox0 >= yBox1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float yCoord, xCoord;
|
||||
int indexX1 = xBox0, indexY1 = yBox0;
|
||||
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);
|
||||
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;
|
||||
if (xCoord >= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
{
|
||||
++indexX1;
|
||||
++bresIndexX;
|
||||
}
|
||||
++indexY1;
|
||||
++bresIndexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
++indexX1;
|
||||
++bresIndexX;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
yCoord = indexY1 * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y;
|
||||
xCoord = (bresIndexX * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) *
|
||||
bresDyDx + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
{
|
||||
++indexX1;
|
||||
++bresIndexX;
|
||||
}
|
||||
--indexY1;
|
||||
}
|
||||
else
|
||||
{
|
||||
++indexX1;
|
||||
++bresIndexX;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dirY == 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
xCoord = bresIndexY * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y;
|
||||
yCoord = (indexX1 * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) *
|
||||
bresDyDx + bresXAdd;
|
||||
if (yCoord >= xCoord)
|
||||
{
|
||||
if (yCoord == xCoord)
|
||||
--indexX1;
|
||||
++indexY1;
|
||||
++bresIndexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
--indexX1;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
yCoord = indexY1 * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y;
|
||||
xCoord = (indexX1 * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) *
|
||||
bresDyDx + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
--indexX1;
|
||||
--indexY1;
|
||||
}
|
||||
else
|
||||
{
|
||||
--indexX1;
|
||||
}
|
||||
TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this);
|
||||
}
|
||||
while (indexX1 != xBox1 || indexY1 != yBox1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,7 @@ public:
|
|||
TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start,
|
||||
struct vector_type* end);
|
||||
void Offset(float offset);
|
||||
double FindCollisionDistance(ray_type* ray) override;
|
||||
|
||||
void EdgeCollision(TBall* ball, float coef) override
|
||||
{
|
||||
}
|
||||
|
||||
void place_in_grid() override
|
||||
{
|
||||
}
|
||||
float FindCollisionDistance(ray_type* ray) override;
|
||||
void EdgeCollision(TBall* ball, float coef) override;
|
||||
void place_in_grid() override;
|
||||
};
|
||||
|
|
|
@ -68,12 +68,12 @@ public:
|
|||
objlist_class* ComponentList;
|
||||
objlist_class* BallList;
|
||||
TLightGroup* LightGroup;
|
||||
float TableAngleMult;
|
||||
float TableAngle1;
|
||||
float TableAngle2;
|
||||
float GravityDirVectMult;
|
||||
float GravityAngleX;
|
||||
float GravityAnglY;
|
||||
float CollisionCompOffset;
|
||||
int UnknownP62;
|
||||
int UnknownP63;
|
||||
float PlungerPositionX;
|
||||
float PlungerPositionY;
|
||||
int ScoreMultiplier;
|
||||
int ScoreAdded;
|
||||
int ScoreSpecial1;
|
||||
|
|
|
@ -1,2 +1,171 @@
|
|||
#include "pch.h"
|
||||
#include "TPlunger.h"
|
||||
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "maths.h"
|
||||
#include "pb.h"
|
||||
#include "render.h"
|
||||
#include "TBall.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
visualStruct visual{};
|
||||
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
CollisionMultiplier = 0.0;
|
||||
BallFeedTimer_ = 0;
|
||||
PullbackTimer_ = 0;
|
||||
SoundIndexP1 = visual.SoundIndex4;
|
||||
SoundIndexP2 = visual.SoundIndex3;
|
||||
SoundIndex1 = visual.Kicker.SoundIndex;
|
||||
MaxCollisionSpeed = 1000000000.0;
|
||||
MaxPullback = 100;
|
||||
UnknownC4F = 0.5f;
|
||||
UnknownC5F = 0.5f;
|
||||
PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->Count() * 8.0));
|
||||
Unknown4F = 0.025f;
|
||||
float* floatArr = loader::query_float_attribute(groupIndex, 0, 601);
|
||||
table->PlungerPositionX = floatArr[0];
|
||||
table->PlungerPositionY = floatArr[1];
|
||||
}
|
||||
|
||||
void TPlunger::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge)
|
||||
{
|
||||
if (PinballTable->TiltLockFlag)
|
||||
Message(1017, 0.0);
|
||||
coef = static_cast<float>(rand()) * 0.00003051850947599719f * CollisionMultiplier * 0.1f + CollisionMultiplier;
|
||||
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, MaxCollisionSpeed, coef);
|
||||
}
|
||||
|
||||
int TPlunger::Message(int code, float value)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 1004:
|
||||
if (!PullbackTimer_)
|
||||
{
|
||||
CollisionMultiplier = 0.0;
|
||||
MaxCollisionSpeed = 1000000000.0;
|
||||
loader::play_sound(SoundIndex1);
|
||||
PullbackTimer(0, this);
|
||||
}
|
||||
return 0;
|
||||
case 1005:
|
||||
case 1009:
|
||||
case 1010:
|
||||
{
|
||||
MaxCollisionSpeed = 0.0;
|
||||
if (PullbackTimer_)
|
||||
timer::kill(PullbackTimer_);
|
||||
PullbackTimer_ = 0;
|
||||
if (code == 1005)
|
||||
loader::play_sound(SoundIndexP2);
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
zMap,
|
||||
bmp->XPosition - PinballTable->XOffset,
|
||||
bmp->YPosition - PinballTable->YOffset);
|
||||
|
||||
timer::set(Unknown4F, this, PlungerReleasedTimer);
|
||||
break;
|
||||
}
|
||||
case 1015:
|
||||
{
|
||||
auto ball = static_cast<TBall*>(PinballTable->ComponentList->Get(0));
|
||||
ball->Message(1024, 0.0);
|
||||
ball->Position.X = PinballTable->PlungerPositionX;
|
||||
ball->Position.Y = PinballTable->PlungerPositionY;
|
||||
ball->UnknownBaseFlag2 = 1;
|
||||
PinballTable->UnknownP10 = 0;
|
||||
pb::tilt_no_more();
|
||||
control::handler(code, this);
|
||||
return 0;
|
||||
}
|
||||
case 1016:
|
||||
if (BallFeedTimer_)
|
||||
timer::kill(BallFeedTimer_);
|
||||
BallFeedTimer_ = timer::set(0.95999998f, this, BallFeedTimer);
|
||||
loader::play_sound(SoundIndexP1);
|
||||
control::handler(code, this);
|
||||
return 0;
|
||||
case 1017:
|
||||
MaxCollisionSpeed = 0.0;
|
||||
CollisionMultiplier = static_cast<float>(MaxPullback);
|
||||
timer::set(0.2f, this, PlungerReleasedTimer);
|
||||
break;
|
||||
case 1024:
|
||||
{
|
||||
if (BallFeedTimer_)
|
||||
timer::kill(BallFeedTimer_);
|
||||
BallFeedTimer_ = 0;
|
||||
MaxCollisionSpeed = 0.0;
|
||||
if (PullbackTimer_)
|
||||
timer::kill(PullbackTimer_);
|
||||
PullbackTimer_ = 0;
|
||||
if (code == 1005)
|
||||
loader::play_sound(SoundIndexP2);
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
zMap,
|
||||
bmp->XPosition - PinballTable->XOffset,
|
||||
bmp->YPosition - PinballTable->YOffset);
|
||||
|
||||
timer::set(Unknown4F, this, PlungerReleasedTimer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TPlunger::BallFeedTimer(int timerId, void* caller)
|
||||
{
|
||||
auto plunger = static_cast<TPlunger*>(caller);
|
||||
plunger->PullbackTimer_ = 0;
|
||||
plunger->Message(1015, 0.0);
|
||||
}
|
||||
|
||||
void TPlunger::PullbackTimer(int timerId, void* caller)
|
||||
{
|
||||
auto plunger = static_cast<TPlunger*>(caller);
|
||||
plunger->CollisionMultiplier += static_cast<float>(plunger->PullbackIncrement);
|
||||
if (plunger->CollisionMultiplier <= static_cast<float>(plunger->MaxPullback))
|
||||
{
|
||||
plunger->PullbackTimer_ = timer::set(plunger->Unknown4F, plunger, PullbackTimer);
|
||||
}
|
||||
else
|
||||
{
|
||||
plunger->PullbackTimer_ = 0;
|
||||
plunger->CollisionMultiplier = static_cast<float>(plunger->MaxPullback);
|
||||
}
|
||||
int index = static_cast<int>(floor(
|
||||
static_cast<float>(plunger->ListBitmap->Count() - 1) *
|
||||
(plunger->CollisionMultiplier / static_cast<float>(plunger->MaxPullback))));
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(plunger->ListBitmap->Get(index));
|
||||
auto zMap = static_cast<zmap_header_type*>(plunger->ListZMap->Get(index));
|
||||
render::sprite_set(
|
||||
plunger->RenderSprite,
|
||||
bmp,
|
||||
zMap,
|
||||
bmp->XPosition - plunger->PinballTable->XOffset,
|
||||
bmp->YPosition - plunger->PinballTable->YOffset);
|
||||
}
|
||||
|
||||
void TPlunger::PlungerReleasedTimer(int timerId, void* caller)
|
||||
{
|
||||
auto plunger = static_cast<TPlunger*>(caller);
|
||||
plunger->MaxCollisionSpeed = 1000000000.0;
|
||||
plunger->CollisionMultiplier = 0.0;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,20 @@ class TPlunger :
|
|||
public TCollisionComponent
|
||||
{
|
||||
public:
|
||||
TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
}
|
||||
TPlunger(TPinballTable* table, int groupIndex);
|
||||
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge) override;
|
||||
int Message(int code, float value) override;
|
||||
|
||||
static void BallFeedTimer(int timerId, void* caller);
|
||||
static void PullbackTimer(int timerId, void* caller);
|
||||
static void PlungerReleasedTimer(int timerId, void* caller);
|
||||
|
||||
int PullbackTimer_;
|
||||
int BallFeedTimer_;
|
||||
int MaxPullback;
|
||||
int PullbackIncrement;
|
||||
float Unknown4F;
|
||||
int SoundIndexP1;
|
||||
int SoundIndexP2;
|
||||
};
|
||||
|
|
|
@ -36,32 +36,32 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
|||
auto tableAngleArr = loader::query_float_attribute(groupIndex, 0, 305);
|
||||
if (tableAngleArr)
|
||||
{
|
||||
PinballTable->TableAngleMult = tableAngleArr[0];
|
||||
PinballTable->TableAngle1 = tableAngleArr[1];
|
||||
PinballTable->TableAngle2 = tableAngleArr[2];
|
||||
PinballTable->GravityDirVectMult = tableAngleArr[0];
|
||||
PinballTable->GravityAngleX = tableAngleArr[1];
|
||||
PinballTable->GravityAnglY = tableAngleArr[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
PinballTable->TableAngleMult = 25.0f;
|
||||
PinballTable->TableAngle1 = 0.5f;
|
||||
PinballTable->TableAngle2 = 1.570796f;
|
||||
PinballTable->GravityDirVectMult = 25.0f;
|
||||
PinballTable->GravityAngleX = 0.5f;
|
||||
PinballTable->GravityAnglY = 1.570796f;
|
||||
}
|
||||
|
||||
auto table3 = PinballTable;
|
||||
Angle1 = cos(table3->TableAngle2) * sin(table3->TableAngle1) * table3->TableAngleMult;
|
||||
Angle2 = sin(table3->TableAngle2) * sin(table3->TableAngle1) * table3->TableAngleMult;
|
||||
GraityDirX = cos(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
||||
GraityDiY = sin(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
||||
auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701);
|
||||
if (angleMultArr)
|
||||
AngleMult = *angleMultArr;
|
||||
GraityMult = *angleMultArr;
|
||||
else
|
||||
AngleMult = 0.2f;
|
||||
GraityMult = 0.2f;
|
||||
|
||||
table->XOffset = bmp->XPosition;
|
||||
table->YOffset = bmp->YPosition;
|
||||
table->Width = bmp->Width;
|
||||
table->Height = bmp->Height;
|
||||
UnknownC7F = visual.Kicker.Unknown1F;
|
||||
UnknownC6F = 15.0f;
|
||||
MaxCollisionSpeed = visual.Kicker.Unknown1F;
|
||||
CollisionMultiplier = 15.0f;
|
||||
|
||||
auto visArrPtr = visual.FloatArr;
|
||||
Unknown1F = min(visArrPtr[0], min(visArrPtr[2], visArrPtr[4]));
|
||||
|
@ -90,11 +90,11 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
|||
visArrPtr += 2;
|
||||
}
|
||||
|
||||
Field.Unknown1 = -1;
|
||||
Field.Mask = -1;
|
||||
Field.Flag2Ptr = &UnknownBaseFlag2;
|
||||
Field.CollisionComp = this;
|
||||
TEdgeManager::edges_insert_square(Unknown2F, Unknown1F, Unknown4F, Unknown3F, nullptr,
|
||||
&Field);
|
||||
edges_insert_square(Unknown2F, Unknown1F, Unknown4F, Unknown3F, nullptr,
|
||||
&Field);
|
||||
}
|
||||
|
||||
TTableLayer::~TTableLayer()
|
||||
|
@ -102,3 +102,51 @@ TTableLayer::~TTableLayer()
|
|||
if (edge_manager)
|
||||
delete edge_manager;
|
||||
}
|
||||
|
||||
int TTableLayer::FieldEffect(TBall* ball, vector_type* vecDst)
|
||||
{
|
||||
vecDst->X = GraityDirX - (0.5f - static_cast<float>(rand()) * 0.00003051850947599719f + ball->Acceleration.X) *
|
||||
ball->Speed * GraityMult;
|
||||
vecDst->Y = GraityDiY - ball->Acceleration.Y * ball->Speed * GraityMult;
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 xMin = x0 - widthM;
|
||||
float xMax = x1 + widthM;
|
||||
float yMin = y0 - heightM;
|
||||
float yMax = y1 + heightM;
|
||||
|
||||
int xMinBox = edge_manager->box_x(xMin);
|
||||
int yMinBox = edge_manager->box_y(yMin);
|
||||
int xMaxBox = edge_manager->box_x(xMax);
|
||||
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)
|
||||
{
|
||||
for (int indexY = yMinBox; indexY <= yMaxBox; ++indexY)
|
||||
{
|
||||
if (xMax >= boxX && xMin <= boxX + edge_manager->AdvanceX &&
|
||||
yMax >= boxY && yMin <= boxY + edge_manager->AdvanceY)
|
||||
{
|
||||
if (edge)
|
||||
{
|
||||
edge_manager->add_edge_to_box(indexX, indexY, edge);
|
||||
}
|
||||
if (field)
|
||||
{
|
||||
edge_manager->add_field_to_box(indexX, indexY, field);
|
||||
}
|
||||
}
|
||||
boxY += edge_manager->AdvanceY;
|
||||
}
|
||||
boxX += edge_manager->AdvanceX;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,20 +10,24 @@ struct gdrv_bitmap8;
|
|||
class TTableLayer :
|
||||
public TCollisionComponent
|
||||
{
|
||||
public:
|
||||
static TEdgeManager* edge_manager;
|
||||
|
||||
public:
|
||||
TTableLayer(TPinballTable* table);
|
||||
~TTableLayer() override;
|
||||
int FieldEffect(TBall* ball, vector_type* vecDst) override;
|
||||
|
||||
static void edges_insert_square(float y0, float x0, float y1, float x1, TEdgeSegment* edge,
|
||||
field_effect_type* field);
|
||||
|
||||
gdrv_bitmap8* VisBmp;
|
||||
float Unknown1F;
|
||||
float Unknown2F;
|
||||
float Unknown3F;
|
||||
float Unknown4F;
|
||||
float Angle1;
|
||||
float Angle2;
|
||||
float GraityDirX;
|
||||
float GraityDiY;
|
||||
int Unknown7;
|
||||
float AngleMult;
|
||||
float GraityMult;
|
||||
field_effect_type Field;
|
||||
|
||||
static TEdgeManager* edge_manager;
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "objlist_class.h"
|
||||
#include "pb.h"
|
||||
#include "TLight.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TSound.h"
|
||||
|
||||
|
@ -795,6 +796,12 @@ int control::cheat_bump_rank()
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL control::light_on(component_tag* tag)
|
||||
{
|
||||
auto light = static_cast<TLight*>(tag->Component);
|
||||
return light->BmpIndex1 || light->FlasherFlag2 || light->FlasherActive;
|
||||
}
|
||||
|
||||
void control::FlipperRebounderControl1(int code, TPinballComponent* caller)
|
||||
{
|
||||
}
|
||||
|
@ -1013,6 +1020,35 @@ void control::HyperspaceKickOutControl(int code, TPinballComponent* caller)
|
|||
|
||||
void control::PlungerControl(int code, TPinballComponent* caller)
|
||||
{
|
||||
if (code == 1015)
|
||||
{
|
||||
MissionControl(67, nullptr);
|
||||
}
|
||||
else if (code == 1016)
|
||||
{
|
||||
table_unlimited_balls = 0;
|
||||
if (!control_middle_circle_tag.Component->Message(37, 0.0))
|
||||
control_middle_circle_tag.Component->Message(32, 0.0);
|
||||
if (!light_on(&control_lite200_tag))
|
||||
{
|
||||
control_skill_shot_lights_tag.Component->Message(20, 0.0);
|
||||
control_lite67_tag.Component->Message(19, 0.0);
|
||||
control_skill_shot_lights_tag.Component->Message(26, 0.25f);
|
||||
control_l_trek_lights_tag.Component->Message(20, 0.0);
|
||||
control_l_trek_lights_tag.Component->Message(32, 0.2f);
|
||||
control_l_trek_lights_tag.Component->Message(26, 0.2f);
|
||||
control_r_trek_lights_tag.Component->Message(20, 0.0);
|
||||
control_r_trek_lights_tag.Component->Message(32, 0.2f);
|
||||
control_r_trek_lights_tag.Component->Message(26, 0.2f);
|
||||
TableG->ScoreSpecial1 = 25000;
|
||||
MultiplierLightGroupControl(65, control_top_target_lights_tag.Component);
|
||||
control_fuel_bargraph_tag.Component->Message(19, 0.0);
|
||||
control_lite200_tag.Component->Message(19, 0.0);
|
||||
control_gate1_tag.Component->Message(53, 0.0);
|
||||
control_gate2_tag.Component->Message(53, 0.0);
|
||||
}
|
||||
control_lite200_tag.Component->MessageField = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void control::MedalTargetControl(int code, TPinballComponent* caller)
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
static void pbctrl_bdoor_controller(int key);
|
||||
static void table_add_extra_ball(float count);
|
||||
static int cheat_bump_rank();
|
||||
static BOOL light_on(struct component_tag* tag);
|
||||
|
||||
static void FlipperRebounderControl1(int code, TPinballComponent* caller);
|
||||
static void FlipperRebounderControl2(int code, TPinballComponent* caller);
|
||||
|
|
|
@ -216,9 +216,9 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
|||
/ perpDot);
|
||||
if (result >= -ray->MinDistance && result <= ray->MaxDistance)
|
||||
{
|
||||
line->CompTmp1 = result * ray->Direction.X + ray->Origin.X;
|
||||
line->RayIntersect.X = result * ray->Direction.X + ray->Origin.X;
|
||||
float v4 = result * ray->Direction.Y + ray->Origin.Y;
|
||||
line->Unknown10 = v4;
|
||||
line->RayIntersect.Y = v4;
|
||||
if (0.0 == line->Direction.X)
|
||||
{
|
||||
if (v4 >= line->OriginX)
|
||||
|
@ -230,9 +230,9 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
|||
return 1000000000.0;
|
||||
}
|
||||
}
|
||||
else if (line->OriginX <= line->CompTmp1)
|
||||
else if (line->OriginX <= line->RayIntersect.X)
|
||||
{
|
||||
float v7 = line->CompTmp1;
|
||||
float v7 = line->RayIntersect.X;
|
||||
v5 = v7 < line->OriginY;
|
||||
v6 = v7 == line->OriginY;
|
||||
if (v5 || v6)
|
||||
|
@ -268,20 +268,20 @@ void maths::vector_add(vector_type* vec1Dst, vector_type* vec2)
|
|||
vec1Dst->Y += vec2->Y;
|
||||
}
|
||||
|
||||
float maths::basic_collision(TBall* ball, vector_type* ballPosition, vector_type* vec2, float a4, float a5, float a6,
|
||||
float a7)
|
||||
float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, float maxSpeed,
|
||||
float multiplier)
|
||||
{
|
||||
ball->Position.X = ballPosition->X;
|
||||
ball->Position.Y = ballPosition->Y;
|
||||
float proj = -(vec2->Y * ball->Acceleration.Y + vec2->X * ball->Acceleration.X);
|
||||
ball->Position.X = nextPosition->X;
|
||||
ball->Position.Y = nextPosition->Y;
|
||||
float proj = -(direction->Y * ball->Acceleration.Y + direction->X * ball->Acceleration.X);
|
||||
if (proj < 0)
|
||||
{
|
||||
proj = -proj;
|
||||
}
|
||||
else
|
||||
{
|
||||
float dx1 = proj * vec2->X;
|
||||
float dy1 = proj * vec2->Y;
|
||||
float dx1 = proj * direction->X;
|
||||
float dy1 = proj * direction->Y;
|
||||
float v17 = dx1 + ball->Acceleration.X;
|
||||
float v18 = dy1 + ball->Acceleration.Y;
|
||||
ball->Acceleration.X = v17 * a5 + dx1 * a4;
|
||||
|
@ -291,10 +291,10 @@ float maths::basic_collision(TBall* ball, vector_type* ballPosition, vector_type
|
|||
float projSpeed = proj * ball->Speed;
|
||||
float newSpeed = ball->Speed - (1.0f - a4) * projSpeed;
|
||||
ball->Speed = newSpeed;
|
||||
if (projSpeed >= a6)
|
||||
if (projSpeed >= maxSpeed)
|
||||
{
|
||||
ball->Acceleration.X = newSpeed * ball->Acceleration.X + vec2->X * a7;
|
||||
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + vec2->Y * a7;
|
||||
ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * multiplier;
|
||||
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * multiplier;
|
||||
ball->Speed = normalize_2d(&ball->Acceleration);
|
||||
}
|
||||
return projSpeed;
|
||||
|
|
|
@ -32,7 +32,7 @@ struct __declspec(align(4)) ray_type
|
|||
float MinDistance;
|
||||
float TimeNow;
|
||||
float TimeDelta;
|
||||
float Unknown2;
|
||||
int FieldFlag;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) line_type
|
||||
|
@ -42,9 +42,7 @@ struct __declspec(align(4)) line_type
|
|||
float PreComp1;
|
||||
float OriginX;
|
||||
float OriginY;
|
||||
float CompTmp1;
|
||||
float Unknown10;
|
||||
float Unknown11;
|
||||
vector_type RayIntersect;
|
||||
};
|
||||
|
||||
|
||||
|
@ -61,5 +59,5 @@ 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* ballPosition, struct vector_type* vec2, float a4, float a5, float a6, float a7);
|
||||
static float basic_collision(TBall* ball, struct vector_type* nextPosition, struct vector_type* direction, float a4, float a5, float maxSpeed, float multiplier);
|
||||
};
|
||||
|
|
|
@ -518,8 +518,8 @@ void pb::launch_ball()
|
|||
|
||||
void pb::end_game()
|
||||
{
|
||||
int scores[4];
|
||||
int scoreIndex[4];
|
||||
int scores[4]{};
|
||||
int scoreIndex[4]{};
|
||||
char String1[200];
|
||||
|
||||
mode_change(2);
|
||||
|
@ -616,7 +616,7 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
|||
ray.Direction.Y = ball->Acceleration.Y;
|
||||
ray.Direction.Z = ball->Acceleration.Z;
|
||||
ray.MaxDistance = maxDistance;
|
||||
ray.Unknown2 = ball->Unknown17F;
|
||||
ray.FieldFlag = ball->FieldFlag;
|
||||
ray.TimeNow = timeNow;
|
||||
ray.TimeDelta = timeDelta;
|
||||
ray.MinDistance = 0.0020000001f;
|
||||
|
|
Loading…
Reference in a new issue