From 7e8f52c156e309b07c019ac473d7e7b6ecd0ce75 Mon Sep 17 00:00:00 2001 From: oz Date: Sun, 17 Jan 2021 18:26:03 +0300 Subject: [PATCH] TDrain, TKickout, TLightBargraph, TPopupTarget, TSoloTarget ready. --- Doc/FuncStats.xlsx | Bin 38666 -> 38832 bytes SpaceCadetPinball/TBall.cpp | 12 ++ SpaceCadetPinball/TBall.h | 7 +- SpaceCadetPinball/TDrain.cpp | 41 ++++++ SpaceCadetPinball/TDrain.h | 12 +- SpaceCadetPinball/TKickout.cpp | 172 ++++++++++++++++++++++ SpaceCadetPinball/TKickout.h | 32 ++++- SpaceCadetPinball/TLightBargraph.cpp | 132 +++++++++++++++++ SpaceCadetPinball/TLightBargraph.h | 14 +- SpaceCadetPinball/TLightGroup.h | 2 +- SpaceCadetPinball/TPinballTable.cpp | 8 +- SpaceCadetPinball/TPinballTable.h | 2 +- SpaceCadetPinball/TPlunger.cpp | 2 +- SpaceCadetPinball/TPopupTarget.cpp | 98 +++++++++++++ SpaceCadetPinball/TPopupTarget.h | 16 ++- SpaceCadetPinball/TSoloTarget.cpp | 82 +++++++++++ SpaceCadetPinball/TSoloTarget.h | 17 ++- SpaceCadetPinball/control.cpp | 206 ++++++++++++++++++++++++++- SpaceCadetPinball/control.h | 1 + SpaceCadetPinball/maths.cpp | 12 ++ SpaceCadetPinball/maths.h | 1 + 21 files changed, 840 insertions(+), 29 deletions(-) diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index 92c39db9c6b06e5471eb49506b1d2a644f670ddd..16587fca50188d0b211e2f461edc8a899b96d371 100644 GIT binary patch delta 30544 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 K4kY^W$o~VW1#!~= delta 30464 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 WM!twCollisionComp = nullptr; + ball->Acceleration = *acceleration; + float rnd = static_cast(rand()); + float angle = (1.0f - (rnd * 0.00003051850947599719f + rnd * 0.00003051850947599719f)) * angleMult; + maths::RotateVector(&ball->Acceleration, angle); + rnd = static_cast(rand()); + ball->Speed = (1.0f - (rnd * 0.00003051850947599719f + rnd * 0.00003051850947599719f)) * (speedMult1 * + speedMult2) + speedMult1; +} diff --git a/SpaceCadetPinball/TBall.h b/SpaceCadetPinball/TBall.h index f64366d..1ab6707 100644 --- a/SpaceCadetPinball/TBall.h +++ b/SpaceCadetPinball/TBall.h @@ -14,13 +14,16 @@ public : bool already_hit(TEdgeSegment* edge); int Message(int code, float value) override; + static void throw_ball(TBall* ball, struct vector_type* acceleration, float angleMult, float speedMult1, + float speedMult2); + vector_type Position; vector_type Acceleration; float Speed; float RayMaxDistance; float TimeDelta; float TimeNow; - vector_type InvAcceleration; + vector_type InvAcceleration; int Unknown13; int Unknown14; int Unknown15; @@ -32,5 +35,5 @@ public : int CollisionFlag; float Offset; int Unknown29; - float VisualZArray[50]; + float VisualZArray[50]; }; diff --git a/SpaceCadetPinball/TDrain.cpp b/SpaceCadetPinball/TDrain.cpp index 7d0207d..d78d961 100644 --- a/SpaceCadetPinball/TDrain.cpp +++ b/SpaceCadetPinball/TDrain.cpp @@ -1,2 +1,43 @@ #include "pch.h" #include "TDrain.h" + + +#include "control.h" +#include "loader.h" +#include "TBall.h" +#include "timer.h" +#include "TPinballTable.h" + +TDrain::TDrain(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + Timer = 0; + TimerTime = *loader::query_float_attribute(groupIndex, 0, 407); +} + +int TDrain::Message(int code, float value) +{ + if (code == 1024) + { + if (Timer) + { + timer::kill(Timer); + Timer = 0; + } + PinballTable->BallInSink = 0; + } + return 0; +} + +void TDrain::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ + ball->Message(1024, 0.0); + PinballTable->BallInSink = 1; + Timer = timer::set(TimerTime, this, TimerCallback); + control::handler(63, this); +} + +void TDrain::TimerCallback(int timerId, void* caller) +{ + auto drain = static_cast(caller); + control::handler(60, drain); +} diff --git a/SpaceCadetPinball/TDrain.h b/SpaceCadetPinball/TDrain.h index 5e530ee..cbfdf31 100644 --- a/SpaceCadetPinball/TDrain.h +++ b/SpaceCadetPinball/TDrain.h @@ -5,7 +5,13 @@ class TDrain : public TCollisionComponent { public: - TDrain(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TDrain(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 TimerCallback(int timerId, void* caller); + + float TimerTime; + int Timer; }; diff --git a/SpaceCadetPinball/TKickout.cpp b/SpaceCadetPinball/TKickout.cpp index 1900a17..5ae378c 100644 --- a/SpaceCadetPinball/TKickout.cpp +++ b/SpaceCadetPinball/TKickout.cpp @@ -1,2 +1,174 @@ #include "pch.h" #include "TKickout.h" + + +#include "control.h" +#include "loader.h" +#include "objlist_class.h" +#include "TBall.h" +#include "TCircle.h" +#include "timer.h" +#include "TPinballTable.h" +#include "TTableLayer.h" + +TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollisionComponent( + table, groupIndex, false) +{ + visualStruct visual{}; + circle_type circle{}; + + NotSomeFlag = !someFlag; + if (!someFlag) + UnknownBaseFlag2 = 0; + TimerTime1 = 1.5; + TimerTime2 = 0.05f; + MessageField = 0; + Timer = 0; + KickFlag1 = 0; + FieldMult = *loader::query_float_attribute(groupIndex, 0, 305); + loader::query_visual(groupIndex, 0, &visual); + SoundIndex2 = visual.SoundIndex2; + SoundIndex1 = visual.Kicker.SoundIndex; + + Circle.Center.X = *visual.FloatArr; + 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(visual.FloatArr), Circle.RadiusSq); + if (tCircle) + { + tCircle->place_in_grid(); + EdgeList->Add(tCircle); + } + + Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2]; + CollisionBallSetZ = loader::query_float_attribute(groupIndex, 0, 408)[2]; + ThrowSpeedMult2 = visual.Kicker.Unknown3F * 0.01f; + BallAcceleration.X = visual.Kicker.Unknown4F; + BallAcceleration.Y = visual.Kicker.Unknown5F; + BallAcceleration.Z = visual.Kicker.Unknown6F; + ThrowAngleMult = visual.Kicker.Unknown7F; + ThrowSpeedMult1 = visual.Kicker.Unknown2F; + + 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 TKickout::Message(int code, float value) +{ + switch (code) + { + case 55: + if (KickFlag1) + { + if (value < 0.0) + value = TimerTime1; + Timer = timer::set(value, this, TimerExpired); + } + break; + case 1011: + if (NotSomeFlag) + UnknownBaseFlag2 = 0; + break; + case 1024: + if (KickFlag1) + { + if (Timer) + timer::kill(Timer); + TimerExpired(0, this); + } + if (NotSomeFlag) + UnknownBaseFlag2 = 0; + break; + default: + break; + } + + return 0; +} + +void TKickout::put_scoring(int index, int score) +{ + if (index < 5) + Scores[index] = score; +} + +int TKickout::get_scoring(int index) +{ + return index < 5 ? Scores[index] : 0; +} + +void TKickout::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ + if (!KickFlag1) + { + Ball = ball; + MaxCollisionSpeed = 1000000000.0; + KickFlag1 = 1; + ball->CollisionComp = this; + ball->Position.X = Circle.Center.X; + ball->Position.Y = Circle.Center.Y; + ball->Position.Z = CollisionBallSetZ; + FieldBallZSet = ball->Position.Z; + if (PinballTable->TiltLockFlag) + { + Message(55, 0.1f); + } + else + { + loader::play_sound(SoundIndex2); + control::handler(63, this); + } + } +} + +int TKickout::FieldEffect(TBall* ball, vector_type* dstVec) +{ + vector_type direction{}; + + if (KickFlag1) + return 0; + direction.X = Circle.Center.X - ball->Position.X; + direction.Y = Circle.Center.Y - ball->Position.Y; + if (direction.Y * direction.Y + direction.X * direction.X > Circle.RadiusSq) + return 0; + maths::normalize_2d(&direction); + dstVec->X = direction.X * FieldMult - ball->Acceleration.X * ball->Speed; + dstVec->Y = direction.Y * FieldMult - ball->Acceleration.Y * ball->Speed; + return 1; +} + +void TKickout::TimerExpired(int timerId, void* caller) +{ + auto kick = static_cast(caller); + if (kick->KickFlag1) + { + kick->KickFlag1 = 0; + kick->Timer = timer::set(kick->TimerTime2, kick, ResetTimerExpired); + if (kick->Ball) + { + kick->Ball->Position.Z = kick->FieldBallZSet; + TBall::throw_ball(kick->Ball, &kick->BallAcceleration, kick->ThrowAngleMult, kick->ThrowSpeedMult1, + kick->ThrowSpeedMult2); + kick->UnknownBaseFlag2 = 0; + kick->Ball = nullptr; + loader::play_sound(kick->SoundIndex1); + } + } +} + +void TKickout::ResetTimerExpired(int timerId, void* caller) +{ + auto kick = static_cast(caller); + if (!kick->NotSomeFlag) + kick->UnknownBaseFlag2 = 1; + kick->Timer = 0; +} diff --git a/SpaceCadetPinball/TKickout.h b/SpaceCadetPinball/TKickout.h index d77512b..1079041 100644 --- a/SpaceCadetPinball/TKickout.h +++ b/SpaceCadetPinball/TKickout.h @@ -1,11 +1,37 @@ #pragma once +#include "maths.h" #include "TCollisionComponent.h" +#include "TEdgeManager.h" class TKickout : public TCollisionComponent { public: - TKickout(TPinballTable* table, int groupIndex, int vectorType) : TCollisionComponent(table, groupIndex, false) - { - } + TKickout(TPinballTable* table, int groupIndex, bool someFlag); + int Message(int code, float value) override; + void put_scoring(int index, int score) override; + int get_scoring(int index) 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); + static void ResetTimerExpired(int timerId, void* caller); + + int KickFlag1; + int NotSomeFlag; + int Timer; + float TimerTime1; + float TimerTime2; + float CollisionBallSetZ; + TBall* Ball; + float FieldMult; + circle_type Circle; + float FieldBallZSet; + vector_type BallAcceleration; + float ThrowAngleMult; + float ThrowSpeedMult1; + float ThrowSpeedMult2; + field_effect_type Field; + int Scores[5]; }; diff --git a/SpaceCadetPinball/TLightBargraph.cpp b/SpaceCadetPinball/TLightBargraph.cpp index 5b38f87..0fe720f 100644 --- a/SpaceCadetPinball/TLightBargraph.cpp +++ b/SpaceCadetPinball/TLightBargraph.cpp @@ -1,2 +1,134 @@ #include "pch.h" #include "TLightBargraph.h" + + +#include "control.h" +#include "loader.h" +#include "memory.h" +#include "objlist_class.h" +#include "timer.h" +#include "TPinballTable.h" + +TLightBargraph::TLightBargraph(TPinballTable* table, int groupIndex) : TLightGroup(table, groupIndex) +{ + TimerTimeArray = nullptr; + TLightBargraph::Reset(); + if (groupIndex > 0) + { + float* floatArr = loader::query_float_attribute(groupIndex, 0, 904); + if (floatArr) + { + int count = 2 * List->Count(); + TimerTimeArray = reinterpret_cast(memory::allocate(count * sizeof(float))); + if (TimerTimeArray) + { + for (int i = 0; i < count; ++floatArr) + TimerTimeArray[i++] = *floatArr; + } + } + } +} + +TLightBargraph::~TLightBargraph() +{ + if (TimerTimeArray) + memory::free(TimerTimeArray); +} + +int TLightBargraph::Message(int code, float value) +{ + switch (code) + { + case 37: + return TimeIndex; + case 45: + { + if (TimerBargraph) + { + timer::kill(TimerBargraph); + TimerBargraph = 0; + } + auto timeIndex = static_cast(floor(value)); + auto maxCount = 2 * List->Count(); + if (timeIndex >= maxCount) + timeIndex = maxCount - 1; + if (timeIndex >= 0) + { + TLightGroup::Message(45, static_cast(timeIndex / 2)); + if (!(timeIndex & 1)) + TLightGroup::Message(46, 0.0); + float* timeArray = TimerTimeArray; + if (timeArray) + TimerBargraph = timer::set(timeArray[timeIndex], this, BargraphTimerExpired); + TimeIndex = timeIndex; + } + else + { + TLightGroup::Message(20, 0.0); + TimeIndex = 0; + } + break; + } + case 1011: + Reset(); + break; + case 1020: + if (TimerBargraph) + { + timer::kill(TimerBargraph); + TimerBargraph = 0; + } + PlayerTimerIndexBackup[PinballTable->CurrentPlayer] = TimeIndex; + Reset(); + TimeIndex = PlayerTimerIndexBackup[static_cast(floor(value))]; + if (TimeIndex) + { + TLightBargraph::Message(45, static_cast(TimeIndex)); + } + break; + case 1024: + { + Reset(); + int* playerPtr = PlayerTimerIndexBackup; + for (auto index = 0; index < PinballTable->PlayerCount; ++index) + { + *playerPtr = TimeIndex; + + ++playerPtr; + } + TLightGroup::Message(1024, value); + break; + } + default: + TLightGroup::Message(code, value); + break; + } + return 0; +} + +void TLightBargraph::Reset() +{ + if (TimerBargraph) + { + timer::kill(TimerBargraph); + TimerBargraph = 0; + } + TimeIndex = 0; + TLightGroup::Reset(); +} + +void TLightBargraph::BargraphTimerExpired(int timerId, void* caller) +{ + auto bar = static_cast(caller); + bar->TimerBargraph = 0; + if (bar->TimeIndex) + { + bar->Message(45, static_cast(bar->TimeIndex - 1)); + control::handler(60, bar); + } + else + { + bar->Message(20, 0.0); + control::handler(47, bar); + } +} diff --git a/SpaceCadetPinball/TLightBargraph.h b/SpaceCadetPinball/TLightBargraph.h index d8fd59a..1db136d 100644 --- a/SpaceCadetPinball/TLightBargraph.h +++ b/SpaceCadetPinball/TLightBargraph.h @@ -5,7 +5,15 @@ class TLightBargraph : public TLightGroup { public: - TLightBargraph(TPinballTable* table, int groupIndex) : TLightGroup(table, groupIndex) - { - } + TLightBargraph(TPinballTable* table, int groupIndex); + ~TLightBargraph() override; + int Message(int code, float value) override; + void Reset() override; + + static void BargraphTimerExpired(int timerId, void* caller); + + float* TimerTimeArray; + int TimerBargraph; + int TimeIndex; + int PlayerTimerIndexBackup[4]; }; diff --git a/SpaceCadetPinball/TLightGroup.h b/SpaceCadetPinball/TLightGroup.h index dc0ec8d..623c7e7 100644 --- a/SpaceCadetPinball/TLightGroup.h +++ b/SpaceCadetPinball/TLightGroup.h @@ -18,7 +18,7 @@ public: TLightGroup(TPinballTable* table, int groupIndex); ~TLightGroup() override; int Message(int code, float value) override; - void Reset(); + virtual void Reset(); void reschedule_animation(float time); void start_animation(); int next_light_up(); diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp index 1805ff8..700bed1 100644 --- a/SpaceCadetPinball/TPinballTable.cpp +++ b/SpaceCadetPinball/TPinballTable.cpp @@ -53,7 +53,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false) CurScoreStruct = nullptr; ScoreBallcount = nullptr; ScorePlayerNumber1 = nullptr; - UnknownP10 = 0; + BallInSink = 0; UnknownBaseFlag2 = 1; TiltLockFlag = 0; EndGameTimeoutTimer = 0; @@ -124,7 +124,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false) new TBlocker(this, groupIndex); break; case 1012: - new TKickout(this, groupIndex, 1); + new TKickout(this, groupIndex, true); break; case 1013: new TGate(this, groupIndex); @@ -169,7 +169,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false) new TComponentGroup(this, groupIndex); break; case 1029: - new TKickout(this, groupIndex, 0); + new TKickout(this, groupIndex, false); break; case 1030: new TLightBargraph(this, groupIndex); @@ -299,7 +299,7 @@ void TPinballTable::ChangeBallCount(int count) void TPinballTable::tilt(float time) { - if (!TiltLockFlag && !UnknownP10) + if (!TiltLockFlag && !BallInSink) { pinball::InfoTextBox->Clear(); pinball::MissTextBox->Clear(); diff --git a/SpaceCadetPinball/TPinballTable.h b/SpaceCadetPinball/TPinballTable.h index 11d4bbf..b587c27 100644 --- a/SpaceCadetPinball/TPinballTable.h +++ b/SpaceCadetPinball/TPinballTable.h @@ -49,7 +49,7 @@ public: int SoundIndex1; int SoundIndex2; int SoundIndex3; - int UnknownP10; + int BallInSink; int CurScore; int CurScoreE9; int LightShowTimer; diff --git a/SpaceCadetPinball/TPlunger.cpp b/SpaceCadetPinball/TPlunger.cpp index 209910a..0c5e98b 100644 --- a/SpaceCadetPinball/TPlunger.cpp +++ b/SpaceCadetPinball/TPlunger.cpp @@ -84,7 +84,7 @@ int TPlunger::Message(int code, float value) ball->Position.X = PinballTable->PlungerPositionX; ball->Position.Y = PinballTable->PlungerPositionY; ball->UnknownBaseFlag2 = 1; - PinballTable->UnknownP10 = 0; + PinballTable->BallInSink = 0; pb::tilt_no_more(); control::handler(code, this); return 0; diff --git a/SpaceCadetPinball/TPopupTarget.cpp b/SpaceCadetPinball/TPopupTarget.cpp index 9b250ab..5f5cc57 100644 --- a/SpaceCadetPinball/TPopupTarget.cpp +++ b/SpaceCadetPinball/TPopupTarget.cpp @@ -1,2 +1,100 @@ #include "pch.h" #include "TPopupTarget.h" + + +#include "control.h" +#include "loader.h" +#include "render.h" +#include "timer.h" +#include "TPinballTable.h" +#include "TZmapList.h" + +TPopupTarget::TPopupTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + this->Timer = 0; + this->TimerTime = *loader::query_float_attribute(groupIndex, 0, 407); +} + +int TPopupTarget::Message(int code, float value) +{ + switch (code) + { + case 49: + this->UnknownBaseFlag2 = 0; + render::sprite_set_bitmap(this->RenderSprite, nullptr); + break; + case 50: + this->Timer = timer::set(this->TimerTime, this, TimerExpired); + break; + case 1020: + this->PlayerMessagefieldBackup[this->PinballTable->CurrentPlayer] = this->MessageField; + this->MessageField = this->PlayerMessagefieldBackup[static_cast(floor(value))]; + TPopupTarget::Message(50 - (MessageField != 0), 0.0); + break; + case 1024: + { + this->MessageField = 0; + int* playerPtr = this->PlayerMessagefieldBackup; + for (auto index = 0; index < this->PinballTable->PlayerCount; ++index) + { + *playerPtr = 0; + ++playerPtr; + } + + if (this->Timer) + timer::kill(this->Timer); + TimerExpired(0, this); + break; + } + default: + break; + } + return 0; +} + +void TPopupTarget::put_scoring(int index, int score) +{ + if (index < 3) + Scores[index] = score; +} + +int TPopupTarget::get_scoring(int index) +{ + return index < 3 ? Scores[index] : 0; +} + +void TPopupTarget::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) +{ + if (this->PinballTable->TiltLockFlag) + { + maths::basic_collision(ball, nextPosition, direction, this->UnknownC4F, this->UnknownC5F, 1000000000.0, 0.0); + } + else if (maths::basic_collision( + ball, + nextPosition, + direction, + this->UnknownC4F, + this->UnknownC5F, + this->MaxCollisionSpeed, + this->CollisionMultiplier) > this->MaxCollisionSpeed) + { + if (this->SoundIndex1) + loader::play_sound(this->SoundIndex1); + this->Message(49, 0.0); + control::handler(63, this); + } +} + +void TPopupTarget::TimerExpired(int timerId, void* caller) +{ + auto target = static_cast(caller); + target->Timer = 0; + target->UnknownBaseFlag2 = 1; + render::sprite_set_bitmap(target->RenderSprite, static_cast(target->ListBitmap->Get(0))); + if (timerId) + { + if (target->SoundIndex2) + loader::play_sound(target->SoundIndex2); + } +} diff --git a/SpaceCadetPinball/TPopupTarget.h b/SpaceCadetPinball/TPopupTarget.h index 13f1e71..208a3f2 100644 --- a/SpaceCadetPinball/TPopupTarget.h +++ b/SpaceCadetPinball/TPopupTarget.h @@ -5,7 +5,17 @@ class TPopupTarget : public TCollisionComponent { public: - TPopupTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TPopupTarget(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + void put_scoring(int index, int score) override; + int get_scoring(int index) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + + static void TimerExpired(int timerId, void* caller); + + int Timer; + float TimerTime; + int Scores[3]; + int PlayerMessagefieldBackup[4]; }; diff --git a/SpaceCadetPinball/TSoloTarget.cpp b/SpaceCadetPinball/TSoloTarget.cpp index 2c3036d..3f33dc5 100644 --- a/SpaceCadetPinball/TSoloTarget.cpp +++ b/SpaceCadetPinball/TSoloTarget.cpp @@ -1,2 +1,84 @@ #include "pch.h" #include "TSoloTarget.h" + + +#include "control.h" +#include "loader.h" +#include "render.h" +#include "timer.h" +#include "TPinballTable.h" +#include "TZmapList.h" + +TSoloTarget::TSoloTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + visualStruct visual{}; + + Timer = 0; + TimerTime = 0.1f; + loader::query_visual(groupIndex, 0, &visual); + SoundIndex4 = visual.SoundIndex4; + TSoloTarget::Message(50, 0.0); +} + +int TSoloTarget::Message(int code, float value) +{ + switch (code) + { + case 49: + case 50: + UnknownBaseFlag2 = code == 50; + break; + case 1024: + if (Timer) + timer::kill(Timer); + Timer = 0; + UnknownBaseFlag2 = 1; + break; + default: + return 0; + } + + if (ListBitmap) + { + auto index = 1 - UnknownBaseFlag2; + auto bmp = static_cast(ListBitmap->Get(index)); + auto zMap = static_cast(ListZMap->Get(index)); + render::sprite_set( + RenderSprite, + bmp, + zMap, + bmp->XPosition - PinballTable->XOffset, + bmp->YPosition - PinballTable->YOffset); + } + + return 0; +} + +void TSoloTarget::put_scoring(int index, int score) +{ + if (index < 1) + Scores[index] = score; +} + +int TSoloTarget::get_scoring(int index) +{ + return index < 1 ? Scores[index] : 0; +} + +void TSoloTarget::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) +{ + if (DefaultCollision(ball, nextPosition, direction)) + { + Message(49, 0.0); + Timer = timer::set(TimerTime, this, TimerExpired); + control::handler(63, this); + } +} + +void TSoloTarget::TimerExpired(int timerId, void* caller) +{ + auto target = static_cast(caller); + target->Message(50, 0.0); + target->Timer = 0; +} diff --git a/SpaceCadetPinball/TSoloTarget.h b/SpaceCadetPinball/TSoloTarget.h index 07cd27e..32813f9 100644 --- a/SpaceCadetPinball/TSoloTarget.h +++ b/SpaceCadetPinball/TSoloTarget.h @@ -5,7 +5,18 @@ class TSoloTarget : public TCollisionComponent { public: - TSoloTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TSoloTarget(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + void put_scoring(int index, int score) override; + int get_scoring(int index) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + + static void TimerExpired(int timerId, void* caller); + + int Unknown0; + int Timer; + float TimerTime; + int SoundIndex4; + int Scores[1]; }; diff --git a/SpaceCadetPinball/control.cpp b/SpaceCadetPinball/control.cpp index 26ad38d..b6df663 100644 --- a/SpaceCadetPinball/control.cpp +++ b/SpaceCadetPinball/control.cpp @@ -4,6 +4,7 @@ #include "objlist_class.h" #include "pb.h" #include "TLight.h" +#include "TLightGroup.h" #include "TPinballTable.h" #include "TSound.h" @@ -786,9 +787,9 @@ void control::pbctrl_bdoor_controller(int key) void control::table_add_extra_ball(float count) { ++TableG->ExtraBalls; - static_cast(control_soundwave28_tag.Component)->Play(); + dynamic_cast(control_soundwave28_tag.Component)->Play(); auto msg = pinball::get_rc_string(9, 0); - static_cast(control_info_text_box_tag.Component)->Display(msg, count); + dynamic_cast(control_info_text_box_tag.Component)->Display(msg, count); } int control::cheat_bump_rank() @@ -798,10 +799,26 @@ int control::cheat_bump_rank() BOOL control::light_on(component_tag* tag) { - auto light = static_cast(tag->Component); + auto light = dynamic_cast(tag->Component); return light->BmpIndex1 || light->FlasherFlag2 || light->FlasherActive; } +int control::SpecialAddScore(int score) +{ + int prevFlag1 = TableG->ScoreSpecial3Flag; + TableG->ScoreSpecial3Flag = 0; + int prevFlag2 = TableG->ScoreSpecial2Flag; + TableG->ScoreSpecial2Flag = 0; + int prevMult = TableG->ScoreMultiplier; + TableG->ScoreMultiplier = 0; + + int addedScore = TableG->AddScore(score); + TableG->ScoreSpecial2Flag = prevFlag2; + TableG->ScoreMultiplier = prevMult; + TableG->ScoreSpecial3Flag = prevFlag1; + return addedScore; +} + void control::FlipperRebounderControl1(int code, TPinballComponent* caller) { } @@ -842,10 +859,10 @@ void control::DeploymentChuteToEscapeChuteOneWayControl(int code, TPinballCompon int count = control_skill_shot_lights_tag.Component->Message(37, 0.0); if (count) { - static_cast(control_soundwave3_tag.Component)->Play(); + dynamic_cast(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(control_info_text_box_tag.Component)->Display(Buffer, 2.0); + dynamic_cast(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); @@ -1083,6 +1100,185 @@ void control::MultiplierTargetControl(int code, TPinballComponent* caller) void control::BallDrainControl(int code, TPinballComponent* caller) { + char Buffer[64]; + + if (code == 60) + { + if (control_lite199_tag.Component->MessageField) + { + TableG->Message(1022, 0.0); + if (pb::chk_highscore()) + { + dynamic_cast(control_soundwave3_tag.Component)->Play(); + TableG->LightGroup->Message(16, 3.0); + char* v11 = pinball::get_rc_string(177, 0); + dynamic_cast(control_mission_text_box_tag.Component)->Display(v11, -1.0); + } + } + else + { + control_plunger_tag.Component->Message(1016, 0.0); + } + } + else if (code == 63) + { + if (table_unlimited_balls) + { + control_drain_tag.Component->Message(1024, 0.0); + control_sink3_tag.Component->Message(56, 0.0); + } + else + { + if (TableG->TiltLockFlag) + { + control_lite200_tag.Component->Message(20, 0.0); + control_lite199_tag.Component->Message(20, 0.0); + } + if (light_on(&control_lite200_tag)) + { + dynamic_cast(control_soundwave27_tag.Component)->Play(); + control_lite200_tag.Component->Message(19, 0.0); + dynamic_cast(control_info_text_box_tag.Component)->Display( + pinball::get_rc_string(96, 0), -1.0); + dynamic_cast(control_soundwave59_tag.Component)->Play(); + } + else if (light_on(&control_lite199_tag)) + { + dynamic_cast(control_soundwave27_tag.Component)->Play(); + control_lite199_tag.Component->Message(20, 0.0); + control_lite200_tag.Component->Message(19, 0.0); + dynamic_cast(control_info_text_box_tag.Component)-> + Display(pinball::get_rc_string(95, 0), 2.0); + dynamic_cast(control_soundwave59_tag.Component)->Play(); + --TableG->UnknownP78; + } + else if (TableG->UnknownP75) + { + dynamic_cast(control_soundwave27_tag.Component)->Play(); + --TableG->UnknownP75; + } + else + { + if (!TableG->TiltLockFlag) + { + int time = SpecialAddScore(TableG->ScoreSpecial2); + sprintf_s(Buffer, pinball::get_rc_string(94, 0), time); + dynamic_cast(control_info_text_box_tag.Component)->Display(Buffer, 2.0); + } + if (TableG->ExtraBalls) + { + TableG->ExtraBalls--; + + char* shootAgainText; + dynamic_cast(control_soundwave59_tag.Component)->Play(); + switch (TableG->CurrentPlayer) + { + case 0: + shootAgainText = pinball::get_rc_string(97, 0); + break; + case 1: + shootAgainText = pinball::get_rc_string(98, 0); + break; + case 2: + shootAgainText = pinball::get_rc_string(99, 0); + break; + default: + case 3: + shootAgainText = pinball::get_rc_string(100, 0); + break; + } + dynamic_cast(control_info_text_box_tag.Component)->Display(shootAgainText, -1.0); + } + else + { + TableG->ChangeBallCount(TableG->BallCount - 1); + if (TableG->CurrentPlayer + 1 != TableG->PlayerCount || TableG->BallCount) + { + TableG->Message(1021, 0.0); + control_lite199_tag.Component->MessageField = 0; + } + else + { + control_lite199_tag.Component->MessageField = 1; + } + dynamic_cast(control_soundwave27_tag.Component)->Play(); + } + control_bmpr_inc_lights_tag.Component->Message(20, 0.0); + control_ramp_bmpr_inc_lights_tag.Component->Message(20, 0.0); + control_lite30_tag.Component->Message(20, 0.0); + control_lite29_tag.Component->Message(20, 0.0); + control_lite1_tag.Component->Message(20, 0.0); + control_lite54_tag.Component->Message(20, 0.0); + control_lite55_tag.Component->Message(20, 0.0); + control_lite56_tag.Component->Message(20, 0.0); + control_lite17_tag.Component->Message(20, 0.0); + control_lite18_tag.Component->Message(20, 0.0); + control_lite27_tag.Component->Message(20, 0.0); + control_lite28_tag.Component->Message(20, 0.0); + control_lite16_tag.Component->Message(20, 0.0); + control_lite20_tag.Component->Message(20, 0.0); + control_hyper_lights_tag.Component->Message(20, 0.0); + control_lite25_tag.Component->Message(20, 0.0); + control_lite26_tag.Component->Message(20, 0.0); + control_lite130_tag.Component->Message(20, 0.0); + control_lite19_tag.Component->Message(20, 0.0); + control_worm_hole_lights_tag.Component->Message(20, 0.0); + control_bsink_arrow_lights_tag.Component->Message(20, 0.0); + control_l_trek_lights_tag.Component->Message(20, 0.0); + control_r_trek_lights_tag.Component->Message(20, 0.0); + control_lite60_tag.Component->Message(20, 0.0); + control_lite59_tag.Component->Message(20, 0.0); + control_lite61_tag.Component->Message(20, 0.0); + control_bumber_target_lights_tag.Component->Message(20, 0.0); + control_top_target_lights_tag.Component->Message(20, 0.0); + control_top_circle_tgt_lights_tag.Component->Message(20, 0.0); + control_ramp_tgt_lights_tag.Component->Message(20, 0.0); + control_lchute_tgt_lights_tag.Component->Message(20, 0.0); + control_bpr_solotgt_lights_tag.Component->Message(20, 0.0); + control_lite110_tag.Component->Message(20, 0.0); + control_skill_shot_lights_tag.Component->Message(20, 0.0); + control_lite77_tag.Component->Message(20, 0.0); + control_lite198_tag.Component->Message(20, 0.0); + control_lite196_tag.Component->Message(20, 0.0); + control_lite195_tag.Component->Message(20, 0.0); + control_fuel_bargraph_tag.Component->Message(20, 0.0); + control_fuel_bargraph_tag.Component->Message(1024, 0.0); + GravityWellKickoutControl(1024, nullptr); + control_lite62_tag.Component->Message(20, 0.0); + control_lite4_tag.Component->MessageField = 0; + control_lite101_tag.Component->MessageField = 0; + control_lite102_tag.Component->MessageField = 0; + control_lite103_tag.Component->MessageField = 0; + control_ramp_tgt_lights_tag.Component->MessageField = 0; + control_outer_circle_tag.Component->Message(34, 0.0); + control_middle_circle_tag.Component->Message(34, 0.0); + control_attack_bump_tag.Component->Message(1024, 0.0); + control_launch_bump_tag.Component->Message(1024, 0.0); + control_gate1_tag.Component->Message(1024, 0.0); + control_gate2_tag.Component->Message(1024, 0.0); + control_block1_tag.Component->Message(1024, 0.0); + control_target1_tag.Component->Message(1024, 0.0); + control_target2_tag.Component->Message(1024, 0.0); + control_target3_tag.Component->Message(1024, 0.0); + control_target6_tag.Component->Message(1024, 0.0); + control_target5_tag.Component->Message(1024, 0.0); + control_target4_tag.Component->Message(1024, 0.0); + control_target9_tag.Component->Message(1024, 0.0); + control_target8_tag.Component->Message(1024, 0.0); + control_target7_tag.Component->Message(1024, 0.0); + if (control_lite199_tag.Component->MessageField) + control_lite198_tag.Component->MessageField = 32; + else + control_lite198_tag.Component->MessageField = 0; + MissionControl(66, nullptr); + TableG->Message(1012, 0.0); + if (light_on(&control_lite58_tag)) + control_lite58_tag.Component->Message(20, 0.0); + else + TableG->ScoreSpecial2 = 25000; + } + } + } } void control::table_control_handler(int code) diff --git a/SpaceCadetPinball/control.h b/SpaceCadetPinball/control.h index e4cc65f..b6f69e0 100644 --- a/SpaceCadetPinball/control.h +++ b/SpaceCadetPinball/control.h @@ -39,6 +39,7 @@ public: static void table_add_extra_ball(float count); static int cheat_bump_rank(); static BOOL light_on(struct component_tag* tag); + static int SpecialAddScore(int score); static void FlipperRebounderControl1(int code, TPinballComponent* caller); static void FlipperRebounderControl2(int code, TPinballComponent* caller); diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index 9aaf441..7df3583 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -408,3 +408,15 @@ float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2) } return 1000000000.0; } + +void maths::RotateVector(vector_type* vec, float angle) +{ + float s = sin(angle), c = cos(angle); + vec->X = c * vec->X - s * vec->Y; + vec->Y = s * vec->X + c * vec->Y; + /* Error in the original, should be: + * tmp = c * vec->X - s * vec->Y; + * vec->Y = s * vec->X + c * vec->Y; + * vec->X = tmp + */ +} diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index 092cfdd..82587ad 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -68,4 +68,5 @@ public: static void SinCos(float angle, float* sinOut, float* cosOut); static void RotatePt(vector_type* point, float sin, float cos, vector_type* origin); static float distance_to_flipper(ray_type* ray1, ray_type* ray2); + static void RotateVector(vector_type* vec, float angle); };