mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-18 18:37:55 +01:00
TBlocker, TBumper, TFlagSpinner, TGate, THole, TKickback, TWall ready.
This commit is contained in:
parent
61fe0410b0
commit
ffd626fbc1
17 changed files with 812 additions and 23 deletions
Binary file not shown.
|
@ -1,2 +1,73 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TBlocker.h"
|
#include "TBlocker.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "TZmapList.h"
|
||||||
|
|
||||||
|
TBlocker::TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
|
{
|
||||||
|
visualStruct visual{};
|
||||||
|
|
||||||
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
|
SoundIndex4 = visual.SoundIndex4;
|
||||||
|
SoundIndex3 = visual.SoundIndex3;
|
||||||
|
Unknown0 = 55;
|
||||||
|
Unknown1 = 5;
|
||||||
|
MaxCollisionSpeed = 1000000000.0f;
|
||||||
|
Timer = 0;
|
||||||
|
MessageField = 0;
|
||||||
|
UnknownBaseFlag2 = 0;
|
||||||
|
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TBlocker::Message(int code, float value)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case 1011:
|
||||||
|
case 1020:
|
||||||
|
case 1024:
|
||||||
|
case 51:
|
||||||
|
if (Timer)
|
||||||
|
{
|
||||||
|
timer::kill(Timer);
|
||||||
|
Timer = 0;
|
||||||
|
}
|
||||||
|
MessageField = 0;
|
||||||
|
UnknownBaseFlag2 = 0;
|
||||||
|
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||||
|
if (code == 51)
|
||||||
|
loader::play_sound(SoundIndex3);
|
||||||
|
return 0;
|
||||||
|
case 52:
|
||||||
|
UnknownBaseFlag2 = 1;
|
||||||
|
loader::play_sound(SoundIndex4);
|
||||||
|
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||||
|
break;
|
||||||
|
case 59:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (Timer)
|
||||||
|
timer::kill(Timer);
|
||||||
|
|
||||||
|
float timerTime;
|
||||||
|
if (value <= 0.0)
|
||||||
|
timerTime = 0.0;
|
||||||
|
else
|
||||||
|
timerTime = value;
|
||||||
|
Timer = timer::set(timerTime, this, TimerExpired);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBlocker::TimerExpired(int timerId, void* caller)
|
||||||
|
{
|
||||||
|
auto blocker = static_cast<TBlocker*>(caller);
|
||||||
|
blocker->Timer = 0;
|
||||||
|
control::handler(60, blocker);
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,14 @@ class TBlocker :
|
||||||
public TCollisionComponent
|
public TCollisionComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TBlocker(TPinballTable* table, int groupIndex);
|
||||||
{
|
int Message(int code, float value) override;
|
||||||
}
|
|
||||||
|
static void TimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
|
int Unknown0;
|
||||||
|
int Unknown1;
|
||||||
|
int Timer;
|
||||||
|
int SoundIndex4;
|
||||||
|
int SoundIndex3;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,152 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TBumper.h"
|
#include "TBumper.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "TPinballTable.h"
|
||||||
|
#include "TZmapList.h"
|
||||||
|
|
||||||
|
TBumper::TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
|
{
|
||||||
|
visualStruct visual{};
|
||||||
|
|
||||||
|
BmpIndex = 0;
|
||||||
|
Timer = 0;
|
||||||
|
TimerTime = *loader::query_float_attribute(groupIndex, 0, 407);
|
||||||
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
|
SoundIndex4 = visual.SoundIndex4;
|
||||||
|
SoundIndex3 = visual.SoundIndex3;
|
||||||
|
MaxCollisionSpeed2 = MaxCollisionSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TBumper::Message(int code, float value)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case 11:
|
||||||
|
{
|
||||||
|
auto nextBmp = static_cast<int>(floor(value));
|
||||||
|
if (2 * nextBmp > ListBitmap->Count() - 1)
|
||||||
|
nextBmp = (ListBitmap->Count() - 1) / 2;
|
||||||
|
if (nextBmp < 0)
|
||||||
|
nextBmp = 0;
|
||||||
|
if (nextBmp != BmpIndex)
|
||||||
|
{
|
||||||
|
if (nextBmp >= BmpIndex)
|
||||||
|
loader::play_sound(SoundIndex4);
|
||||||
|
if (nextBmp < BmpIndex)
|
||||||
|
loader::play_sound(SoundIndex3);
|
||||||
|
BmpIndex = nextBmp;
|
||||||
|
Fire();
|
||||||
|
control::handler(11, this);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 12:
|
||||||
|
{
|
||||||
|
auto nextBmp = BmpIndex + 1;
|
||||||
|
auto maxBmp = ListBitmap->Count() - 1;
|
||||||
|
if (2 * nextBmp > maxBmp)
|
||||||
|
nextBmp = maxBmp / 2;
|
||||||
|
TBumper::Message(11, static_cast<float>(nextBmp));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 13:
|
||||||
|
{
|
||||||
|
auto nextBmp = BmpIndex - 1;
|
||||||
|
if (nextBmp < 0)
|
||||||
|
nextBmp = 0;
|
||||||
|
TBumper::Message(11, static_cast<float>(nextBmp));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1020:
|
||||||
|
{
|
||||||
|
auto playerPtr = &PlayerData[PinballTable->CurrentPlayer];
|
||||||
|
playerPtr->BmpIndex = BmpIndex;
|
||||||
|
playerPtr->MessageField = MessageField;
|
||||||
|
|
||||||
|
playerPtr = &PlayerData[static_cast<int>(floor(value))];
|
||||||
|
BmpIndex = playerPtr->BmpIndex;
|
||||||
|
MessageField = playerPtr->MessageField;
|
||||||
|
TBumper::Message(11, static_cast<float>(BmpIndex));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1024:
|
||||||
|
{
|
||||||
|
if (Timer)
|
||||||
|
{
|
||||||
|
timer::kill(Timer);
|
||||||
|
TimerExpired(Timer, this);
|
||||||
|
}
|
||||||
|
BmpIndex = 0;
|
||||||
|
MessageField = 0;
|
||||||
|
auto playerPtr = PlayerData;
|
||||||
|
for (auto index = 0; index < PinballTable->PlayerCount; ++index)
|
||||||
|
{
|
||||||
|
playerPtr->BmpIndex = 0;
|
||||||
|
playerPtr->MessageField = 0;
|
||||||
|
++playerPtr;
|
||||||
|
}
|
||||||
|
TimerExpired(0, this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBumper::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge)
|
||||||
|
{
|
||||||
|
if (DefaultCollision(ball, nextPosition, direction))
|
||||||
|
{
|
||||||
|
Fire();
|
||||||
|
control::handler(63, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBumper::put_scoring(int index, int score)
|
||||||
|
{
|
||||||
|
if (index < 4)
|
||||||
|
Scores[index] = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int TBumper::get_scoring(int index)
|
||||||
|
{
|
||||||
|
return index < 4 ? Scores[index] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBumper::TimerExpired(int timerId, void* caller)
|
||||||
|
{
|
||||||
|
auto bump = static_cast<TBumper*>(caller);
|
||||||
|
auto bmp = static_cast<gdrv_bitmap8*>(bump->ListBitmap->Get(bump->BmpIndex * 2));
|
||||||
|
auto zMap = static_cast<zmap_header_type*>(bump->ListZMap->Get(bump->BmpIndex * 2));
|
||||||
|
bump->Timer = 0;
|
||||||
|
render::sprite_set(
|
||||||
|
bump->RenderSprite,
|
||||||
|
bmp,
|
||||||
|
zMap,
|
||||||
|
bmp->XPosition - bump->PinballTable->XOffset,
|
||||||
|
bmp->YPosition - bump->PinballTable->YOffset);
|
||||||
|
bump->MaxCollisionSpeed = bump->MaxCollisionSpeed2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBumper::Fire()
|
||||||
|
{
|
||||||
|
int bmpIndex = 2 * BmpIndex + 1;
|
||||||
|
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(bmpIndex));
|
||||||
|
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(bmpIndex));
|
||||||
|
render::sprite_set(
|
||||||
|
RenderSprite,
|
||||||
|
bmp,
|
||||||
|
zMap,
|
||||||
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
bmp->YPosition - PinballTable->YOffset);
|
||||||
|
Timer = timer::set(TimerTime, this, TimerExpired);
|
||||||
|
MaxCollisionSpeed = 1000000000.0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,33 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "TCollisionComponent.h"
|
#include "TCollisionComponent.h"
|
||||||
|
|
||||||
|
struct TBumper_player_backup
|
||||||
|
{
|
||||||
|
int MessageField;
|
||||||
|
int BmpIndex;
|
||||||
|
};
|
||||||
|
|
||||||
class TBumper :
|
class TBumper :
|
||||||
public TCollisionComponent
|
public TCollisionComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TBumper(TPinballTable* table, int groupIndex);
|
||||||
{
|
~TBumper() 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 Fire();
|
||||||
|
|
||||||
|
static void TimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
|
int BmpIndex;
|
||||||
|
int Timer;
|
||||||
|
float TimerTime;
|
||||||
|
float MaxCollisionSpeed2;
|
||||||
|
int SoundIndex4;
|
||||||
|
int SoundIndex3;
|
||||||
|
int Scores[4];
|
||||||
|
TBumper_player_backup PlayerData[4];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,148 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TFlagSpinner.h"
|
#include "TFlagSpinner.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "TBall.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "TLine.h"
|
||||||
|
#include "TPinballTable.h"
|
||||||
|
#include "TZmapList.h"
|
||||||
|
|
||||||
|
TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||||
|
{
|
||||||
|
visualStruct visual{};
|
||||||
|
vector_type end{}, start{};
|
||||||
|
|
||||||
|
Timer = 0;
|
||||||
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
|
end.X = *visual.FloatArr;
|
||||||
|
end.Y = visual.FloatArr[1];
|
||||||
|
start.X = visual.FloatArr[2];
|
||||||
|
start.Y = visual.FloatArr[3];
|
||||||
|
auto line = new TLine(this, &UnknownBaseFlag2, visual.Flag, &start, &end);
|
||||||
|
if (line)
|
||||||
|
{
|
||||||
|
line->place_in_grid();
|
||||||
|
EdgeList->Add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
line = new TLine(this, &UnknownBaseFlag2, visual.Flag, &end, &start);
|
||||||
|
PrevCollider = line;
|
||||||
|
if (line)
|
||||||
|
{
|
||||||
|
line->place_in_grid();
|
||||||
|
EdgeList->Add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpeedDecrement = 0.64999998f;
|
||||||
|
MaxSpeed = 50000.0f;
|
||||||
|
MinSpeed = 5.0f;
|
||||||
|
auto speedDec = loader::query_float_attribute(groupIndex, 0, 1202);
|
||||||
|
if (speedDec)
|
||||||
|
SpeedDecrement = *speedDec;
|
||||||
|
auto maxSpeed = loader::query_float_attribute(groupIndex, 0, 1200);
|
||||||
|
if (maxSpeed)
|
||||||
|
MaxSpeed = *maxSpeed;
|
||||||
|
auto minSpeed = loader::query_float_attribute(groupIndex, 0, 1201);
|
||||||
|
if (minSpeed)
|
||||||
|
MinSpeed = *minSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TFlagSpinner::Message(int code, float value)
|
||||||
|
{
|
||||||
|
if (code == 1024)
|
||||||
|
{
|
||||||
|
if (Timer)
|
||||||
|
{
|
||||||
|
timer::kill(Timer);
|
||||||
|
Timer = 0;
|
||||||
|
}
|
||||||
|
BmpIndex = 0;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFlagSpinner::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 = ball->RayMaxDistance - coef;
|
||||||
|
ball->not_again(edge);
|
||||||
|
|
||||||
|
SpinDirection = 2 * (PrevCollider != edge) - 1;
|
||||||
|
if (ball->Speed == 0.0)
|
||||||
|
Speed = MinSpeed;
|
||||||
|
else
|
||||||
|
Speed = ball->Speed * 20.0f;
|
||||||
|
if (Speed < MinSpeed)
|
||||||
|
Speed = MinSpeed;
|
||||||
|
if (Speed > MaxSpeed)
|
||||||
|
Speed = MaxSpeed;
|
||||||
|
NextFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFlagSpinner::put_scoring(int index, int score)
|
||||||
|
{
|
||||||
|
if (index < 2)
|
||||||
|
Scores[index] = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TFlagSpinner::get_scoring(int index)
|
||||||
|
{
|
||||||
|
return index < 2 ? Scores[index] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFlagSpinner::NextFrame()
|
||||||
|
{
|
||||||
|
BmpIndex += SpinDirection;
|
||||||
|
int bmpIndex = BmpIndex;
|
||||||
|
int bmpCount = ListBitmap->Count();
|
||||||
|
if (bmpIndex >= bmpCount)
|
||||||
|
BmpIndex = 0;
|
||||||
|
else if (bmpIndex < 0)
|
||||||
|
BmpIndex = bmpCount - 1;
|
||||||
|
|
||||||
|
if (!PinballTable->TiltLockFlag)
|
||||||
|
{
|
||||||
|
control::handler(63, this);
|
||||||
|
if (SoundIndex2)
|
||||||
|
loader::play_sound(SoundIndex2);
|
||||||
|
if (!BmpIndex)
|
||||||
|
control::handler(62, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(BmpIndex));
|
||||||
|
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(BmpIndex));
|
||||||
|
render::sprite_set(
|
||||||
|
RenderSprite,
|
||||||
|
bmp,
|
||||||
|
zMap,
|
||||||
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
bmp->YPosition - PinballTable->YOffset);
|
||||||
|
|
||||||
|
Speed *= SpeedDecrement;
|
||||||
|
if (Speed >= MinSpeed)
|
||||||
|
{
|
||||||
|
timer::set(1.0f / Speed, this, SpinTimer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFlagSpinner::SpinTimer(int timerId, void* caller)
|
||||||
|
{
|
||||||
|
auto spinner = static_cast<TFlagSpinner*>(caller);
|
||||||
|
spinner->Timer = 0;
|
||||||
|
spinner->NextFrame();
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,24 @@ class TFlagSpinner :
|
||||||
public TCollisionComponent
|
public TCollisionComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
TFlagSpinner(TPinballTable* table, int groupIndex);
|
||||||
{
|
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 NextFrame();
|
||||||
|
|
||||||
|
static void SpinTimer(int timerId, void* caller);
|
||||||
|
|
||||||
|
float Speed;
|
||||||
|
float MaxSpeed;
|
||||||
|
float MinSpeed;
|
||||||
|
float SpeedDecrement;
|
||||||
|
int SpinDirection;
|
||||||
|
int BmpIndex;
|
||||||
|
int Timer;
|
||||||
|
TEdgeSegment* PrevCollider;
|
||||||
|
int Scores[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -446,7 +446,7 @@ int TFlipperEdge::is_ball_inside(float x, float y)
|
||||||
dy * dy + dx * dx <= CirclebaseRadiusSq ||
|
dy * dy + dx * dx <= CirclebaseRadiusSq ||
|
||||||
(T1.Y - y) * (T1.Y - y) + (T1.X - x) * (T1.X - x) < CircleT1RadiusSq)
|
(T1.Y - y) * (T1.Y - y) + (T1.X - x) * (T1.X - x) < CircleT1RadiusSq)
|
||||||
{
|
{
|
||||||
float flipperLR = AngleMax < 0.0 ? -1 : 1;
|
float flipperLR = AngleMax < 0.0 ? -1.0f : 1.0f;
|
||||||
if (FlipperFlag == 1)
|
if (FlipperFlag == 1)
|
||||||
testPoint = AngleMax < 0.0 ? B1 : B2;
|
testPoint = AngleMax < 0.0 ? B1 : B2;
|
||||||
else if (FlipperFlag == 2)
|
else if (FlipperFlag == 2)
|
||||||
|
|
|
@ -1,2 +1,42 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TGate.h"
|
#include "TGate.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "TZmapList.h"
|
||||||
|
|
||||||
|
TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
|
{
|
||||||
|
visualStruct visual{};
|
||||||
|
|
||||||
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
|
SoundIndex4 = visual.SoundIndex4;
|
||||||
|
SoundIndex3 = visual.SoundIndex3;
|
||||||
|
UnknownBaseFlag2 = 1;
|
||||||
|
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||||
|
control::handler(1024, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGate::Message(int code, float value)
|
||||||
|
{
|
||||||
|
if (code != 1020)
|
||||||
|
{
|
||||||
|
if (code == 53)
|
||||||
|
{
|
||||||
|
UnknownBaseFlag2 = 0;
|
||||||
|
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||||
|
loader::play_sound(SoundIndex3);
|
||||||
|
}
|
||||||
|
else if (code == 54 || code == 1024)
|
||||||
|
{
|
||||||
|
UnknownBaseFlag2 = 1;
|
||||||
|
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||||
|
if (code == 54)
|
||||||
|
loader::play_sound(SoundIndex4);
|
||||||
|
}
|
||||||
|
control::handler(code, this);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ class TGate :
|
||||||
public TCollisionComponent
|
public TCollisionComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TGate(TPinballTable* table, int groupIndex);
|
||||||
{
|
int Message(int code, float value) override;
|
||||||
}
|
|
||||||
|
int SoundIndex4;
|
||||||
|
int SoundIndex3;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,148 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "THole.h"
|
#include "THole.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
|
#include "TBall.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "TPinballTable.h"
|
||||||
|
#include "TTableLayer.h"
|
||||||
|
|
||||||
|
THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||||
|
{
|
||||||
|
visualStruct visual{};
|
||||||
|
circle_type circle{};
|
||||||
|
|
||||||
|
Unknown4 = 0.050000001f;
|
||||||
|
MessageField = 0;
|
||||||
|
Timer = 0;
|
||||||
|
BallCapturedFlag = 0;
|
||||||
|
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 407);
|
||||||
|
if (floatArr1)
|
||||||
|
Unknown3 = *floatArr1;
|
||||||
|
else
|
||||||
|
Unknown3 = 0.25;
|
||||||
|
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 701);
|
||||||
|
if (floatArr2)
|
||||||
|
GravityMult = *floatArr2;
|
||||||
|
else
|
||||||
|
GravityMult = 0.5;
|
||||||
|
GravityPull = *loader::query_float_attribute(groupIndex, 0, 305);
|
||||||
|
|
||||||
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
|
Circle.Center.X = visual.FloatArr[0];
|
||||||
|
Circle.Center.Y = visual.FloatArr[1];
|
||||||
|
Circle.RadiusSq = *loader::query_float_attribute(groupIndex, 0, 306) * visual.FloatArr[2];
|
||||||
|
if (Circle.RadiusSq == 0.0)
|
||||||
|
Circle.RadiusSq = 0.001f;
|
||||||
|
|
||||||
|
auto tCircle = new TCircle(this, &UnknownBaseFlag2, visual.Flag, reinterpret_cast<vector_type*>(visual.FloatArr),
|
||||||
|
Circle.RadiusSq);
|
||||||
|
if (tCircle)
|
||||||
|
{
|
||||||
|
tCircle->place_in_grid();
|
||||||
|
EdgeList->Add(tCircle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
|
||||||
|
FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
|
||||||
|
|
||||||
|
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
|
||||||
|
circle.RadiusSq = Circle.RadiusSq;
|
||||||
|
circle.Center.X = Circle.Center.X;
|
||||||
|
circle.Center.Y = Circle.Center.Y;
|
||||||
|
circle.Center.Z = Circle.Center.Z;
|
||||||
|
|
||||||
|
Field.Flag2Ptr = &UnknownBaseFlag2;
|
||||||
|
Field.CollisionComp = this;
|
||||||
|
Field.Mask = visual.Flag;
|
||||||
|
TTableLayer::edges_insert_circle(&circle, nullptr, &Field);
|
||||||
|
}
|
||||||
|
|
||||||
|
int THole::Message(int code, float value)
|
||||||
|
{
|
||||||
|
if (code == 1024 && BallCapturedFlag)
|
||||||
|
{
|
||||||
|
if (Timer)
|
||||||
|
timer::kill(Timer);
|
||||||
|
Timer = 0;
|
||||||
|
BallCapturedSecondStage = 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge)
|
||||||
|
{
|
||||||
|
if (!BallCapturedFlag)
|
||||||
|
{
|
||||||
|
BallCapturedSecondStage = 0;
|
||||||
|
MaxCollisionSpeed = 1000000000.0;
|
||||||
|
BallCapturedFlag = 1;
|
||||||
|
ball->CollisionComp = this;
|
||||||
|
ball->Position.X = Circle.Center.X;
|
||||||
|
ball->Position.Y = Circle.Center.Y;
|
||||||
|
ball->Acceleration.Z = 0.0;
|
||||||
|
Timer = timer::set(0.5f, this, TimerExpired);
|
||||||
|
if (!PinballTable->TiltLockFlag)
|
||||||
|
{
|
||||||
|
loader::play_sound(SoundIndex1);
|
||||||
|
control::handler(57, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int THole::FieldEffect(TBall* ball, vector_type* vecDst)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
vector_type direction{};
|
||||||
|
|
||||||
|
if (BallCapturedFlag)
|
||||||
|
{
|
||||||
|
if (BallCapturedSecondStage)
|
||||||
|
{
|
||||||
|
ball->Acceleration.Z -= PinballTable->GravityDirVectMult * ball->TimeDelta * GravityMult;
|
||||||
|
ball->Position.Z += ball->Acceleration.Z;
|
||||||
|
if (ball->Position.Z <= ZSetValue)
|
||||||
|
{
|
||||||
|
BallCapturedFlag = 0;
|
||||||
|
BallCapturedSecondStage = 0;
|
||||||
|
ball->Position.Z = ZSetValue;
|
||||||
|
ball->Acceleration.Z = 0.0;
|
||||||
|
ball->FieldFlag = FieldFlag;
|
||||||
|
ball->Acceleration.Y = 0.0;
|
||||||
|
ball->CollisionComp = nullptr;
|
||||||
|
ball->Acceleration.X = 0.0;
|
||||||
|
ball->Speed = 0.0;
|
||||||
|
loader::play_sound(SoundIndex2);
|
||||||
|
control::handler(58, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
direction.X = Circle.Center.X - ball->Position.X;
|
||||||
|
direction.Y = Circle.Center.Y - ball->Position.Y;
|
||||||
|
if (direction.X * direction.X + direction.Y * direction.Y <= Circle.RadiusSq)
|
||||||
|
{
|
||||||
|
maths::normalize_2d(&direction);
|
||||||
|
vecDst->X = direction.X * GravityPull - ball->Acceleration.X * ball->Speed;
|
||||||
|
vecDst->Y = direction.Y * GravityPull - ball->Acceleration.Y * ball->Speed;
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void THole::TimerExpired(int timerId, void* caller)
|
||||||
|
{
|
||||||
|
auto hole = static_cast<THole*>(caller);
|
||||||
|
hole->Timer = 0;
|
||||||
|
hole->BallCapturedSecondStage = 1;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "TCircle.h"
|
||||||
#include "TCollisionComponent.h"
|
#include "TCollisionComponent.h"
|
||||||
|
#include "TEdgeManager.h"
|
||||||
|
|
||||||
class THole :
|
class THole :
|
||||||
public TCollisionComponent
|
public TCollisionComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
THole(TPinballTable* table, int groupIndex);
|
||||||
{
|
int Message(int code, float value) override;
|
||||||
}
|
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||||
|
TEdgeSegment* edge) override;
|
||||||
|
int FieldEffect(TBall* ball, vector_type* vecDst) override;
|
||||||
|
|
||||||
|
static void TimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
|
int BallCapturedFlag;
|
||||||
|
int BallCapturedSecondStage;
|
||||||
|
int Timer;
|
||||||
|
float Unknown3;
|
||||||
|
float Unknown4;
|
||||||
|
float GravityMult;
|
||||||
|
float ZSetValue;
|
||||||
|
int FieldFlag;
|
||||||
|
float GravityPull;
|
||||||
|
circle_type Circle;
|
||||||
|
field_effect_type Field;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,95 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TKickback.h"
|
#include "TKickback.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "maths.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "TPinballTable.h"
|
||||||
|
#include "TZmapList.h"
|
||||||
|
|
||||||
|
TKickback::TKickback(TPinballTable* table, int groupIndex): TCollisionComponent(table, groupIndex, true)
|
||||||
|
{
|
||||||
|
MessageField = 0;
|
||||||
|
Timer = 0;
|
||||||
|
ActiveFlag = 0;
|
||||||
|
TimerTime = 0.69999999f;
|
||||||
|
TimerTime2 = 0.1f;
|
||||||
|
MaxCollisionSpeed = 1000000000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TKickback::Message(int code, float value)
|
||||||
|
{
|
||||||
|
if ((code == 1011 || code == 1024) && Timer)
|
||||||
|
{
|
||||||
|
timer::kill(Timer);
|
||||||
|
if (ListBitmap)
|
||||||
|
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||||
|
Timer = 0;
|
||||||
|
ActiveFlag = 0;
|
||||||
|
MaxCollisionSpeed = 1000000000.0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TKickback::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||||
|
TEdgeSegment* edge)
|
||||||
|
{
|
||||||
|
if (PinballTable->TiltLockFlag)
|
||||||
|
{
|
||||||
|
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 0.0,
|
||||||
|
CollisionMultiplier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ActiveFlag)
|
||||||
|
{
|
||||||
|
MaxCollisionSpeed = 1000000000.0;
|
||||||
|
ActiveFlag = 1;
|
||||||
|
Timer = timer::set(TimerTime, this, TimerExpired);
|
||||||
|
}
|
||||||
|
if (DefaultCollision(ball, nextPosition, direction))
|
||||||
|
ActiveFlag = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TKickback::TimerExpired(int timerId, void* caller)
|
||||||
|
{
|
||||||
|
auto kick = static_cast<TKickback*>(caller);
|
||||||
|
|
||||||
|
if (kick->ActiveFlag)
|
||||||
|
{
|
||||||
|
kick->MaxCollisionSpeed = 0.0;
|
||||||
|
kick->Timer = timer::set(kick->TimerTime2, kick, TimerExpired);
|
||||||
|
loader::play_sound(kick->SoundIndex1);
|
||||||
|
if (kick->ListBitmap)
|
||||||
|
{
|
||||||
|
auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(1));
|
||||||
|
auto zMap = static_cast<zmap_header_type*>(kick->ListZMap->Get(1));
|
||||||
|
render::sprite_set(
|
||||||
|
kick->RenderSprite,
|
||||||
|
bmp,
|
||||||
|
zMap,
|
||||||
|
bmp->XPosition - kick->PinballTable->XOffset,
|
||||||
|
bmp->YPosition - kick->PinballTable->YOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (kick->ListBitmap)
|
||||||
|
{
|
||||||
|
auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(0));
|
||||||
|
auto zMap = static_cast<zmap_header_type*>(kick->ListZMap->Get(0));
|
||||||
|
render::sprite_set(
|
||||||
|
kick->RenderSprite,
|
||||||
|
bmp,
|
||||||
|
zMap,
|
||||||
|
bmp->XPosition - kick->PinballTable->XOffset,
|
||||||
|
bmp->YPosition - kick->PinballTable->YOffset);
|
||||||
|
}
|
||||||
|
kick->Timer = 0;
|
||||||
|
control::handler(60, kick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,15 @@ class TKickback :
|
||||||
public TCollisionComponent
|
public TCollisionComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TKickback(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TKickback(TPinballTable* table, int groupIndex);
|
||||||
{
|
int Message(int code, float value) override;
|
||||||
}
|
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||||
|
TEdgeSegment* edge) override;
|
||||||
|
|
||||||
|
static void TimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
|
float TimerTime;
|
||||||
|
float TimerTime2;
|
||||||
|
int Timer;
|
||||||
|
int ActiveFlag;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,59 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TWall.h"
|
#include "TWall.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "TZmapList.h"
|
||||||
|
|
||||||
|
TWall::TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
|
{
|
||||||
|
if (RenderSprite)
|
||||||
|
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||||
|
if (ListBitmap)
|
||||||
|
BmpPtr = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||||
|
Timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TWall::Message(int code, float value)
|
||||||
|
{
|
||||||
|
if (code == 1024 && Timer)
|
||||||
|
{
|
||||||
|
timer::kill(Timer);
|
||||||
|
TimerExpired(Timer, this);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TWall::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge)
|
||||||
|
{
|
||||||
|
if (DefaultCollision(ball, nextPosition, direction))
|
||||||
|
{
|
||||||
|
if (BmpPtr)
|
||||||
|
{
|
||||||
|
render::sprite_set_bitmap(RenderSprite, BmpPtr);
|
||||||
|
Timer = timer::set(0.1f, this, TimerExpired);
|
||||||
|
}
|
||||||
|
control::handler(63, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TWall::put_scoring(int index, int score)
|
||||||
|
{
|
||||||
|
if (index < 1)
|
||||||
|
Scores[index] = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TWall::get_scoring(int index)
|
||||||
|
{
|
||||||
|
return index < 1 ? Scores[index] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TWall::TimerExpired(int timerId, void* caller)
|
||||||
|
{
|
||||||
|
auto wall = static_cast<TWall*>(caller);
|
||||||
|
render::sprite_set_bitmap(wall->RenderSprite, nullptr);
|
||||||
|
wall->Timer = 0;
|
||||||
|
wall->MessageField = 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "TCollisionComponent.h"
|
#include "TCollisionComponent.h"
|
||||||
|
|
||||||
|
struct gdrv_bitmap8;
|
||||||
|
|
||||||
class TWall :
|
class TWall :
|
||||||
public TCollisionComponent
|
public TCollisionComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TWall(TPinballTable* table, int groupIndex);
|
||||||
{
|
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;
|
||||||
|
|
||||||
|
static void TimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
|
int Timer;
|
||||||
|
gdrv_bitmap8* BmpPtr;
|
||||||
|
int Scores[1];
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ HCURSOR winmain::mouse_hsave;
|
||||||
int winmain::return_value = 0;
|
int winmain::return_value = 0;
|
||||||
int winmain::bQuit = 0;
|
int winmain::bQuit = 0;
|
||||||
int winmain::activated;
|
int winmain::activated;
|
||||||
int winmain::DispFrameRate = 1;
|
int winmain::DispFrameRate = 0;
|
||||||
int winmain::DispGRhistory = 0;
|
int winmain::DispGRhistory = 0;
|
||||||
int winmain::single_step = 0;
|
int winmain::single_step = 0;
|
||||||
int winmain::has_focus = 1;
|
int winmain::has_focus = 1;
|
||||||
|
|
Loading…
Reference in a new issue