#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" TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) { visualStruct visual{}; loader::query_visual(groupIndex, 0, &visual); Boost = 0.0; BallFeedTimer_ = 0; PullbackTimer_ = 0; SoundIndexP1 = visual.SoundIndex4; SoundIndexP2 = visual.SoundIndex3; HardHitSoundId = visual.Kicker.HardHitSoundId; Threshold = 1000000000.0; // FT:MaxPullback = 50; 3DPB: MaxPullback = 100, PullbackIncrement is floored. if (pb::FullTiltMode) { MaxPullback = 50; PullbackIncrement = MaxPullback / (ListBitmap->size() * 8.0f); } else { MaxPullback = 100; PullbackIncrement = std::floor(MaxPullback / (ListBitmap->size() * 8.0f)); } Elasticity = 0.5f; Smoothness = 0.5f; PullbackDelay = 0.025f; float* floatArr = loader::query_float_attribute(groupIndex, 0, 601); table->PlungerPosition = {floatArr[0], floatArr[1]}; } void TPlunger::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge) { if (PinballTable->TiltLockFlag || SomeCounter > 0) { auto boost = RandFloat() * MaxPullback * 0.1f + MaxPullback; maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 0, boost); if (SomeCounter) SomeCounter--; Message(MessageCode::PlungerInputReleased, 0.0); } else { auto boost = RandFloat() * Boost * 0.1f + Boost; maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, boost); } } int TPlunger::Message(MessageCode code, float value) { switch (code) { case MessageCode::PlungerInputPressed: if (!PullbackStartedFlag && (!pb::FullTiltMode || PinballTable->MultiballCount > 0 && !PinballTable-> TiltLockFlag)) { PullbackStartedFlag = true; Boost = 0.0; Threshold = 1000000000.0; loader::play_sound(HardHitSoundId, this, "TPlunger1"); PullbackTimer(0, this); } break; case MessageCode::PlungerFeedBall: { if (PinballTable->BallCountInRect(PinballTable->PlungerPosition, PinballTable->CollisionCompOffset * 1.2f)) { timer::set(1.0f, this, BallFeedTimer); } else { auto ball = PinballTable->AddBall(PinballTable->PlungerPosition); assertm(ball, "Failure to create ball in plunger"); PinballTable->MultiballCount++; PinballTable->BallInDrainFlag = 0; pb::tilt_no_more(); } break; } case MessageCode::PlungerStartFeedTimer: timer::set(0.95999998f, this, BallFeedTimer); loader::play_sound(SoundIndexP1, this, "TPlunger2"); break; case MessageCode::PlungerLaunchBall: PullbackStartedFlag = true; Boost = MaxPullback; Message(MessageCode::PlungerInputReleased, 0.0f); break; case MessageCode::PlungerRelaunchBall: SomeCounter++; timer::set(value, this, BallFeedTimer); loader::play_sound(SoundIndexP1, this, "TPlunger2_1"); PullbackStartedFlag = true; PullbackTimer(0, this); break; case MessageCode::PlayerChanged: PullbackStartedFlag = false; Boost = 0.0f; Threshold = 1000000000.0f; SomeCounter = 0; timer::kill(BallFeedTimer); timer::kill(PullbackTimer); timer::kill(ReleasedTimer); break; case MessageCode::SetTiltLock: SomeCounter = 0; timer::kill(BallFeedTimer); break; case MessageCode::PlungerInputReleased: case MessageCode::Resume: case MessageCode::LooseFocus: if (PullbackStartedFlag && !SomeCounter) { PullbackStartedFlag = false; Threshold = 0.0; if (PullbackTimer_) timer::kill(PullbackTimer_); PullbackTimer_ = 0; loader::play_sound(SoundIndexP2, this, "TPlunger3"); SpriteSet(0); timer::set(PullbackDelay, this, ReleasedTimer); } break; case MessageCode::Reset: { PullbackStartedFlag = false; Boost = 0.0f; Threshold = 1000000000.0f; SomeCounter = 0; timer::kill(BallFeedTimer); timer::kill(PullbackTimer); timer::kill(ReleasedTimer); SpriteSet(0); break; } default: break; } control::handler(code, this); return 0; } void TPlunger::BallFeedTimer(int timerId, void* caller) { auto plunger = static_cast(caller); plunger->Message(MessageCode::PlungerFeedBall, 0.0); } void TPlunger::PullbackTimer(int timerId, void* caller) { auto plunger = static_cast(caller); plunger->Boost += plunger->PullbackIncrement; if (plunger->Boost <= plunger->MaxPullback) { if (plunger->SomeCounter) { plunger->PullbackTimer_ = timer::set(plunger->PullbackDelay / 4.0f, plunger, PullbackTimer); } else { plunger->PullbackTimer_ = timer::set(plunger->PullbackDelay, plunger, PullbackTimer); } } else { plunger->PullbackTimer_ = 0; plunger->Boost = plunger->MaxPullback; } int index = static_cast(floor( static_cast(plunger->ListBitmap->size() - 1) * (plunger->Boost / plunger->MaxPullback))); plunger->SpriteSet(index); } void TPlunger::ReleasedTimer(int timerId, void* caller) { auto plunger = static_cast(caller); plunger->Threshold = 1000000000.0; plunger->Boost = 0.0; }