diff --git a/Resources/Debug/Font.bin b/Resources/Debug/Font.bin new file mode 100644 index 0000000..ace9201 Binary files /dev/null and b/Resources/Debug/Font.bin differ diff --git a/Resources/Debug/Font.png b/Resources/Debug/Font.png new file mode 100644 index 0000000..e4542ec Binary files /dev/null and b/Resources/Debug/Font.png differ diff --git a/Resources/GameConfig.xml b/Resources/GameConfig.xml new file mode 100644 index 0000000..964cf8c --- /dev/null +++ b/Resources/GameConfig.xml @@ -0,0 +1,11 @@ + + + + + + + Stages/GHZ/Scene1.bin + + + + diff --git a/Resources/Music/1up.ogg b/Resources/Music/1up.ogg new file mode 100644 index 0000000..b44a620 Binary files /dev/null and b/Resources/Music/1up.ogg differ diff --git a/Resources/Music/ActClear.ogg b/Resources/Music/ActClear.ogg new file mode 100644 index 0000000..ce6e00e Binary files /dev/null and b/Resources/Music/ActClear.ogg differ diff --git a/Resources/Music/Drowning.ogg b/Resources/Music/Drowning.ogg new file mode 100644 index 0000000..097e2cd Binary files /dev/null and b/Resources/Music/Drowning.ogg differ diff --git a/Resources/Music/EncoreMenu.ogg b/Resources/Music/EncoreMenu.ogg new file mode 100644 index 0000000..164cafe Binary files /dev/null and b/Resources/Music/EncoreMenu.ogg differ diff --git a/Resources/Music/GameOver.ogg b/Resources/Music/GameOver.ogg new file mode 100644 index 0000000..866183e Binary files /dev/null and b/Resources/Music/GameOver.ogg differ diff --git a/Resources/Music/GreenHill1.ogg b/Resources/Music/GreenHill1.ogg new file mode 100644 index 0000000..2537723 Binary files /dev/null and b/Resources/Music/GreenHill1.ogg differ diff --git a/Resources/Music/GreenHill2.ogg b/Resources/Music/GreenHill2.ogg new file mode 100644 index 0000000..5fa28cc Binary files /dev/null and b/Resources/Music/GreenHill2.ogg differ diff --git a/Resources/Music/Super.ogg b/Resources/Music/Super.ogg new file mode 100644 index 0000000..2436816 Binary files /dev/null and b/Resources/Music/Super.ogg differ diff --git a/Resources/ObjectList.txt b/Resources/ObjectList.txt new file mode 100644 index 0000000..6fe2b10 --- /dev/null +++ b/Resources/ObjectList.txt @@ -0,0 +1,612 @@ +AIZEggRobo +AIZEncoreTutorial +AIZKingClaw +AIZRockPile +AIZSetup +AIZTornado +AIZTornadoPath +APICallback +Acetone +ActClear +AmoebaDroid +AnimalHBH +Animals +Announcer +Aquis +Armadiloid +BGSwitch +BSS_Collectable +BSS_Collected +BSS_HUD +BSS_Horizon +BSS_Message +BSS_Palette +BSS_Player +BSS_Setup +BadnikHelpers +Ball +BallCannon +BallHog +BarStool +Batbot +Batbrain +Beanstalk +BigSqueeze +BladePole +Blank Object +Blaster +Blastoid +Bloominator +Bomb +BouncePlant +BoundsMarker +BreakBar +BreakableWall +Bridge +Bubbler +BuckwildBall +Buggernaut +Bumpalo +Bungee +BurningLog +Button +ButtonDoor +BuzzBomber +BuzzSaw +COverlay +CPZ1Intro +CPZ2Outro +CPZBoss +CPZSetup +CPZShutter +CableWarp +Cactula +Camera +Canista +Caterkiller +CaterkillerJr +ChaosEmerald +CheckerBall +ChemBubble +ChemicalBall +ChemicalPool +Chopper +CircleBumper +Clapperboard +Clucker +CollapsingPlatform +CollapsingSand +ColorHelpers +Competition +CompetitionMenu +CompetitionSession +Constellation +ContinuePlayer +ContinueSetup +ConveyorBelt +ConveyorPlatform +ConveyorWheel +CorkscrewPath +Crabmeat +Crane +CrashTest +Crate +CreditsSetup +CrimsonEye +Current +CutsceneHBH +CutsceneRules +CutsceneSeq +Cylinder +DAControl +DASetup +DBTower +DCEvent +DDWrecker +DERobot +DNARiser +Dango +DashLift +Debris +DebugMode +Decoration +DemoMenu +DialogRunner +DirectorChair +DiveEggman +DoorTrigger +Dragonfly +DrawHelpers +Drillerdroid +DrillerdroidO +Dust +E3MenuSetup +ERZGunner +ERZKing +ERZMystic +ERZOutro +ERZRider +ERZSetup +ERZShinobi +ERZStart +EggJanken +EggJankenPart +EggLoco +EggPistonsMKII +EggPrison +EggTV +EggTower +Eggman +ElectroMagnet +EncoreGoodEnd +EncoreIntro +EncoreRoute +EscapeCar +Explosion +ExtrasMenu +FBZ1Outro +FBZ2Outro +FBZFan +FBZMissile +FBZSetup +FBZSinkTrash +FBZStorm +FBZTrash +FXExpandRing +FXFade +FXRuby +FXSpinRay +FXTrail +FXWaveRing +Fan +FarPlane +FernParallax +FilmProjector +FilmReel +Fireball +Fireflies +Firework +Fireworm +FlameSpring +Flamethrower +FlasherMKII +FlingRamp +Flipper +FlowerPod +FoldingPlatform +ForceSpin +ForceUnstick +FrostThrower +Funnel +GHZ2Outro +GHZCutsceneK +GHZCutsceneST +GHZSetup +Gachapandora +GameOver +GameProgress +GasPlatform +GenericTrigger +GiantPistol +GigaMetal +Gondola +Grabber +GreenScreen +GymBar +HCZ1Intro +HCZOneWayDoor +HCZSetup +HCZSpikeBall +HPZEmerald +HUD +HandLauncher +HangConveyor +HangGlider +HangPoint +Hatch +Hatterkiller +HeavyGunner +HeavyKing +HeavyMystic +HeavyRider +HeavyShinobi +HiLoSign +Honkytonk +Hotaru +HotaruHiWatt +HotaruMKII +Ice +IceBomba +IceSpring +ImageTrail +Ink +InkWipe +InvincibleStars +InvisibleBlock +ItemBox +Iwamodoki +JacobsLadder +Jawz +Jellygnite +JuggleSaw +JunctionWheel +Kabasira +Kanabun +KingAttack +KingClaw +KleptoMobile +LEDPanel +LRZ1Intro +LRZ1Introsize +LRZ1Outro +LRZ1Setup +LRZ2Setup +LRZ3Cutscene +LRZ3Outro +LRZ3OutroK +LRZ3Setup +LRZConvControl +LRZConvDropper +LRZConvItem +LRZConvSwitch +LRZConveyor +LRZFireball +LRZRockPile +LRZSpikeBall +LRZSpiral +LargeGear +LaunchSpring +Launcher +LaundroMobile +LavaFall +LavaGeyser +Letterboard +LevelSelect +LightBarrier +LightBulb +Localization +LocoSmoke +LogHelpers +LogoSetup +LottoBall +LottoMachine +LoveTester +MMZ2Outro +MMZLighning +MMZLightning +MMZSetup +MMZWheel +MSBomb +MSFactory +MSHologram +MSOrb +MSPanel +MSZ1KIntro +MSZ2Cutscene +MSZCutsceneK +MSZCutsceneST +MSZSetup +MSZSpotlight +MagPlatform +MagSpikeBall +MagnetSphere +MainMenu +ManiaModeMenu +MathHelpers +MatryoshkaBom +MechaBu +MegaChopper +MegaOctus +MenuParam +MenuSetup +MetalArm +MetalSonic +MeterDroid +MicDrop +Mine +MonarchBG +MonarchPlans +MonkeyDude +Motobug +Music +Newspaper +Newtron +NoSwap +OOZ1Outro +OOZ2Outro +OOZFlames +OOZSetup +Octus +OneWayDoor +Options +OptionsMenu +Orbinaut +OrbitSpike +PBL_Bumper +PBL_Camera +PBL_Crane +PBL_Flipper +PBL_HUD +PBL_Player +PBL_Ring +PBL_Sector +PBL_Setup +PBL_TargetBumper +PKingAttack +PSZ1Intro +PSZ1Setup +PSZ2Intro +PSZ2Outro +PSZ2Setup +PSZDoor +PSZEggman +PSZLauncher +PaintingEyes +Palette +PaperRoller +ParallaxSprite +ParticleHelpers +PathInverter +PauseMenu +Pendulum +PetalPile +PhantomEgg +PhantomGunner +PhantomHand +PhantomKing +PhantomMissile +PhantomMystic +PhantomRider +PhantomRuby +PhantomShield +PhantomShinobi +PimPom +Pinata +Piston +PlaneSeeSaw +PlaneSwitch +Platform +PlatformControl +PlatformNode +Player +PlayerHelpers +PlayerProbe +PohBee +Pointdexter +PopOut +PopcornKernel +PopcornMachine +Press +PrintBlock +Projectile +Propeller +PropellerShaft +PullChain +PullSwitch +PushSpring +PuyoAI +PuyoAttack +PuyoBean +PuyoGame +PuyoIndicator +PuyoLabel +PuyoLevelSelect +PuyoMatch +PuyoScore +RPlaneShifter +RTeleporter +Rattlekiller +Reagent +Redz +ReplayDB +ReplayRecorder +Rexon +Rhinobot +Ring +RingField +RisingLava +RockDrill +RockemSockem +RollerMKII +RotatingSpikes +RotatingStair +RubyPortal +SDashWheel +SP500 +SP500MkII +SPZ1Intro +SPZ1Setup +SPZ2Outro +SPZ2Setup +SSZ1Intro +SSZ1Outro +SSZ1Setup +SSZ2Setup +SSZ3Cutscene +SSZEggman +SSZSpikeBall +SSZSpotlight +SaveGame +Scarab +SchrodingersCapsule +ScoreBonus +ScrewMobile +SeeSaw +SeltzerBottle +SeltzerWater +SentryBug +Shield +Shiversaw +ShopWindow +Shuriken +Shutterbug +SideBarrel +SignPost +SilverSonic +SizeLaser +SkyTeleporter +Smog +Snowflakes +Sol +Soundboard +SparkRail +Spear +SpearBlock +SpecialClear +SpecialRing +SpeedBooster +SpeedGate +SpiderMobile +SpikeCorridor +SpikeCrusher +SpikeFlail +SpikeLog +Spikes +SpinBooster +SpinSign +Spiny +SpiralPlatform +Splats +Spring +Springboard +Staircase +Stalactite +StarPost +Stegway +StickyPlatform +Summary +SummaryEmerald +SuperSparkle +Sweep +SwingRope +SwitchDoor +Syringe +TAEmerald +TMZ1Outro +TMZ1Setup +TMZ2Outro +TMZ2Setup +TMZ3Setup +TMZAlert +TMZBarrier +TMZCable +TMZFlames +TTCutscene +TVFlyingBattery +TVPole +TVVan +TargetBumper +Technosqueek +TeeterTotter +TetherBall +ThanksSetup +ThoughtBubble +TilePlatform +TimeAttackData +TimeAttackGate +TimeAttackMenu +TimePost +TimeTravelSetup +TippingPlatform +Title3DSprite +TitleBG +TitleCard +TitleEggman +TitleLogo +TitleSetup +TitleSonic +Tornado +TornadoPath +Toxomister +TransportTube +TryAgain +TryAgainE +TubeSpring +Tubinaut +Tuesday +Turbine +TurboSpiker +TurboTurtle +Turntable +TurretSwitch +TwistedTubes +TwistingDoor +TwistingSlide +UFO_Camera +UFO_Circuit +UFO_Decoration +UFO_Dust +UFO_HUD +UFO_ItemBox +UFO_Message +UFO_Plasma +UFO_Player +UFO_Ring +UFO_Setup +UFO_Shadow +UFO_SpeedLines +UFO_Sphere +UFO_Springboard +UFO_Water +UIBackground +UIButton +UIButtonLabel +UIButtonPrompt +UICarousel +UICharButton +UIChoice +UIControl +UICreditsText +UIDialog +UIDiorama +UIHeading +UIInfoLabel +UIKeyBinder +UILeaderboard +UIMedallionPanel +UIModeButton +UIOptionPanel +UIPicture +UIPopover +UIRankButton +UIReplayCarousel +UIResPicker +UISaveSlot +UIShifter +UISlider +UISubHeading +UITABanner +UITAZoneModule +UIText +UITransition +UIUsernamePopup +UIVideo +UIVsCharSelector +UIVsResults +UIVsRoundPicker +UIVsScoreboard +UIVsZoneButton +UIWaitSpinner +UIWidgets +UIWinSize +UberCaterkiller +UncurlPlant +Valve +VanishPlatform +Vultron +WalkerLegs +WallBumper +WallCrawl +WarpDoor +Water +WaterGush +WaterfallSound +WeatherMobile +WeatherTV +Whirlpool +Wisp +WoodChipper +Woodrow +YoyoPulley +ZipLine +Zone \ No newline at end of file diff --git a/Resources/Objects/03601792.ibc b/Resources/Objects/03601792.ibc new file mode 100644 index 0000000..ab990b1 Binary files /dev/null and b/Resources/Objects/03601792.ibc differ diff --git a/Resources/Objects/098624C7.ibc b/Resources/Objects/098624C7.ibc new file mode 100644 index 0000000..9665142 Binary files /dev/null and b/Resources/Objects/098624C7.ibc differ diff --git a/Resources/Objects/19A3AF61.ibc b/Resources/Objects/19A3AF61.ibc new file mode 100644 index 0000000..271cc25 Binary files /dev/null and b/Resources/Objects/19A3AF61.ibc differ diff --git a/Resources/Objects/2B28B66A.ibc b/Resources/Objects/2B28B66A.ibc new file mode 100644 index 0000000..6850497 Binary files /dev/null and b/Resources/Objects/2B28B66A.ibc differ diff --git a/Resources/Objects/306FA262.ibc b/Resources/Objects/306FA262.ibc new file mode 100644 index 0000000..6e5085f Binary files /dev/null and b/Resources/Objects/306FA262.ibc differ diff --git a/Resources/Objects/38E82DB3.ibc b/Resources/Objects/38E82DB3.ibc new file mode 100644 index 0000000..0108295 Binary files /dev/null and b/Resources/Objects/38E82DB3.ibc differ diff --git a/Resources/Objects/3C93B321.ibc b/Resources/Objects/3C93B321.ibc new file mode 100644 index 0000000..14ee1a1 Binary files /dev/null and b/Resources/Objects/3C93B321.ibc differ diff --git a/Resources/Objects/514DFE47.ibc b/Resources/Objects/514DFE47.ibc new file mode 100644 index 0000000..eebc58a Binary files /dev/null and b/Resources/Objects/514DFE47.ibc differ diff --git a/Resources/Objects/583CC63F.ibc b/Resources/Objects/583CC63F.ibc new file mode 100644 index 0000000..5a18fd1 Binary files /dev/null and b/Resources/Objects/583CC63F.ibc differ diff --git a/Resources/Objects/5CA8305A.ibc b/Resources/Objects/5CA8305A.ibc new file mode 100644 index 0000000..f9860bb Binary files /dev/null and b/Resources/Objects/5CA8305A.ibc differ diff --git a/Resources/Objects/7679DA3E.ibc b/Resources/Objects/7679DA3E.ibc new file mode 100644 index 0000000..a733655 Binary files /dev/null and b/Resources/Objects/7679DA3E.ibc differ diff --git a/Resources/Objects/79B33065.ibc b/Resources/Objects/79B33065.ibc new file mode 100644 index 0000000..84dbb11 Binary files /dev/null and b/Resources/Objects/79B33065.ibc differ diff --git a/Resources/Objects/7A03DECE.ibc b/Resources/Objects/7A03DECE.ibc new file mode 100644 index 0000000..963de28 Binary files /dev/null and b/Resources/Objects/7A03DECE.ibc differ diff --git a/Resources/Objects/7A1D0A9C.ibc b/Resources/Objects/7A1D0A9C.ibc new file mode 100644 index 0000000..c52a0a2 Binary files /dev/null and b/Resources/Objects/7A1D0A9C.ibc differ diff --git a/Resources/Objects/7C2EFE99.ibc b/Resources/Objects/7C2EFE99.ibc new file mode 100644 index 0000000..859415f Binary files /dev/null and b/Resources/Objects/7C2EFE99.ibc differ diff --git a/Resources/Objects/7C8A09A0.ibc b/Resources/Objects/7C8A09A0.ibc new file mode 100644 index 0000000..49d95a5 Binary files /dev/null and b/Resources/Objects/7C8A09A0.ibc differ diff --git a/Resources/Objects/7D0C30B5.ibc b/Resources/Objects/7D0C30B5.ibc new file mode 100644 index 0000000..b84e996 Binary files /dev/null and b/Resources/Objects/7D0C30B5.ibc differ diff --git a/Resources/Objects/7D1CDB6F.ibc b/Resources/Objects/7D1CDB6F.ibc new file mode 100644 index 0000000..7f1445f Binary files /dev/null and b/Resources/Objects/7D1CDB6F.ibc differ diff --git a/Resources/Objects/7D85601D.ibc b/Resources/Objects/7D85601D.ibc new file mode 100644 index 0000000..9fcd220 Binary files /dev/null and b/Resources/Objects/7D85601D.ibc differ diff --git a/Resources/Objects/7DE32F77.ibc b/Resources/Objects/7DE32F77.ibc new file mode 100644 index 0000000..528dbb3 Binary files /dev/null and b/Resources/Objects/7DE32F77.ibc differ diff --git a/Resources/Objects/834349B5.ibc b/Resources/Objects/834349B5.ibc new file mode 100644 index 0000000..cd50b9f Binary files /dev/null and b/Resources/Objects/834349B5.ibc differ diff --git a/Resources/Objects/87EEB4D5.ibc b/Resources/Objects/87EEB4D5.ibc new file mode 100644 index 0000000..f7ee33f Binary files /dev/null and b/Resources/Objects/87EEB4D5.ibc differ diff --git a/Resources/Objects/8CF8256F.ibc b/Resources/Objects/8CF8256F.ibc new file mode 100644 index 0000000..755e190 Binary files /dev/null and b/Resources/Objects/8CF8256F.ibc differ diff --git a/Resources/Objects/8D2D1CF0.ibc b/Resources/Objects/8D2D1CF0.ibc new file mode 100644 index 0000000..451f6f2 Binary files /dev/null and b/Resources/Objects/8D2D1CF0.ibc differ diff --git a/Resources/Objects/8D32C414.ibc b/Resources/Objects/8D32C414.ibc new file mode 100644 index 0000000..e06d0f9 Binary files /dev/null and b/Resources/Objects/8D32C414.ibc differ diff --git a/Resources/Objects/9BB7B9CB.ibc b/Resources/Objects/9BB7B9CB.ibc new file mode 100644 index 0000000..9d273f8 Binary files /dev/null and b/Resources/Objects/9BB7B9CB.ibc differ diff --git a/Resources/Objects/B71EB5B4.ibc b/Resources/Objects/B71EB5B4.ibc new file mode 100644 index 0000000..cb99bb6 Binary files /dev/null and b/Resources/Objects/B71EB5B4.ibc differ diff --git a/Resources/Objects/BD56A483.ibc b/Resources/Objects/BD56A483.ibc new file mode 100644 index 0000000..18890aa Binary files /dev/null and b/Resources/Objects/BD56A483.ibc differ diff --git a/Resources/Objects/C11B7228.ibc b/Resources/Objects/C11B7228.ibc new file mode 100644 index 0000000..b83d198 Binary files /dev/null and b/Resources/Objects/C11B7228.ibc differ diff --git a/Resources/Objects/C21D5483.ibc b/Resources/Objects/C21D5483.ibc new file mode 100644 index 0000000..22100bf Binary files /dev/null and b/Resources/Objects/C21D5483.ibc differ diff --git a/Resources/Objects/C63B2ACF.ibc b/Resources/Objects/C63B2ACF.ibc new file mode 100644 index 0000000..00bf8d5 Binary files /dev/null and b/Resources/Objects/C63B2ACF.ibc differ diff --git a/Resources/Objects/CCB0CA00.ibc b/Resources/Objects/CCB0CA00.ibc new file mode 100644 index 0000000..ab950c7 Binary files /dev/null and b/Resources/Objects/CCB0CA00.ibc differ diff --git a/Resources/Objects/D32FA60F.ibc b/Resources/Objects/D32FA60F.ibc new file mode 100644 index 0000000..9bbd7c7 Binary files /dev/null and b/Resources/Objects/D32FA60F.ibc differ diff --git a/Resources/Objects/DB8016A5.ibc b/Resources/Objects/DB8016A5.ibc new file mode 100644 index 0000000..0b6577a Binary files /dev/null and b/Resources/Objects/DB8016A5.ibc differ diff --git a/Resources/Objects/E38C4817.ibc b/Resources/Objects/E38C4817.ibc new file mode 100644 index 0000000..9438533 Binary files /dev/null and b/Resources/Objects/E38C4817.ibc differ diff --git a/Resources/Objects/E42156EF.ibc b/Resources/Objects/E42156EF.ibc new file mode 100644 index 0000000..a352405 Binary files /dev/null and b/Resources/Objects/E42156EF.ibc differ diff --git a/Resources/Objects/EB4C56AD.ibc b/Resources/Objects/EB4C56AD.ibc new file mode 100644 index 0000000..bcf6f9f Binary files /dev/null and b/Resources/Objects/EB4C56AD.ibc differ diff --git a/Resources/Objects/F2B0BC8F.ibc b/Resources/Objects/F2B0BC8F.ibc new file mode 100644 index 0000000..3b432bc Binary files /dev/null and b/Resources/Objects/F2B0BC8F.ibc differ diff --git a/Resources/Objects/F8A2A5AB.ibc b/Resources/Objects/F8A2A5AB.ibc new file mode 100644 index 0000000..fb83ee9 Binary files /dev/null and b/Resources/Objects/F8A2A5AB.ibc differ diff --git a/Resources/PropertyList.txt b/Resources/PropertyList.txt new file mode 100644 index 0000000..74a7fa9 --- /dev/null +++ b/Resources/PropertyList.txt @@ -0,0 +1,482 @@ +act +actID +activation +activeNormal +activeOnLoad +affectPlayer +align +allowTubeInput +always +amplitude +angVel +angle +angleEnd +angleM +angleOffset +angleStart +angleVel +aniID +arrowWidth +assignsP1 +attribute +audioFile +autoGrip +automatic +auxFrameID +auxIcon +auxListID +b +behavior +behaviour +bezCtrlAngle +bezCtrlLength +bgColor1 +bgColor2 +bgColor3 +bgID +bias +boatID +bobDist +bombTime +boostAlways +boostPower +bossID +botAlignRight +botFrameID +botHidden +botListID +bottomSmash +bounceCount +boundsOffset +boundsSize +breakClimb +bumpable +burnable +buttonBehavior +buttonID +buttonTag +cableID +calibration +cameraOffset +chainCount +chainLength +characterID +charge +childCount +choiceCount +choiceDir +clipOffset +clipSize +close +colWidth +collision +color +color=COLOR +columnCount +controller +count +counter +craneID +dCharPartner +dCharPoint +dCharStock1 +dCharStock2 +dCharStock3 +data0 +data1 +data2 +data3 +deactivation +debugEncoreDraw +debugExpand +debugParticles +decorMode +definesBounds +delay +depth +dest +destinationTag +destroyOnTrigger +destructible +detectDirection +detectOffset +detectSize +dioramaID +dip +dir +dirMask +direction +disabled +dist +distDown +distUp +distX1 +distX2 +distance +drawFlag +drawOverTV +duration +durationA +durationB +easeToSpeed +effect +emeraldID +emitterMode +enabled +encoreMode +endAngleA +endAngleB +endLen +eventOnly +exit +extend +extendBottom +extendTop +fadeBlack +fadeOutBlack +fadeWhite +fanEnabled +fastMode +fbzAchievement +filter +finishLine +fireOrbs +flags +flashSpeed +flip +flipCount +flipFlag +flipVal +fluctuation +forKnux +force +forceEnd +forcePlayerState +forceSpeed +forwardOnly +frame +frameID +freeBindP2 +frequency +g +gap +globalControl +globeAlpha +go +gotoStage +groundVel +hDist +hVel +hasSaw +hasShape +hasTension +headingAnchor +headingID +height +hidden +hiddenAtStart +highlighted +hitCount +hitboxSize +holdDuration +iD +id +ignoreCliffs +initialSide +innerRadius +inputID +interval +intervalOffset +invisible +isFalling +isHeading +isPlayer2 +knuxSmash +layerDest +layerSrc +leafPattern +leftFanDir +leftFanDuration +leftFanLength +leftFanStrength +len +length +letter +letterID +limit +links +listID +lockCamera +loopPoint +lottoNum +lrzConvPhys +machQuota1 +machQuota2 +machQuota3 +manual +manualTrigger +master +matAngle +maxDist +maxSpeed +maxVal +maxY +mightyOnly +minCraneID +minDelay +minY +mode +motionType +moveType +moving +noChibi +noClamp +noCrush +noDeathSwap +noMove +noSwing +noText +noWidgets +noWrap +node +nodeCount +nodeFlag +numActive +numChildren +numDuds +numJumps +numRows +nummoves +obfuscate +off +offBottom +offL +offR +offRange +offTop +offset +offset1 +offset2 +offset3 +onGround +onPath +oneWay +onlyKnux +onlyMighty +open +orientation +origin +oscOff +oscillate +outerRadius +overHUD +p1Score +p2Score +paletteID +panelSize +paraOffset +paraPreview +paraYFactor +parallaxFactor +parentTag +passThrough +pathMovement +pathSize +period +phase512 +pileSize +pivotRadius +plane +planeFilter +playOnLoad +playSound +playerAni +playerID +playfieldA +playfieldB +power +preset +printDir +printRows +priority +prize +promptID +pullDir +quality +r +radius +rampCount +range +repeatSpacing +repeatTimes +resetSelection +respawn +retractable +reverse +reversible +rightFanDir +rightFanDuration +rightFanLength +rightFanStrength +ropeSize +rotDir +rotOffset +rotSpeed +rotation +row0Highlight +row0Label +row10Highlight +row10Label +row11Highlight +row11Label +row12Highlight +row12Label +row1Highlight +row1Label +row2Highlight +row2Label +row3Highlight +row3Label +row4Highlight +row4Label +row5Highlight +row5Label +row6Highlight +row6Label +row7Highlight +row7Label +row8Highlight +row8Label +row9Highlight +row9Label +rowCount +rowHeight +running +sawDelay +sawSpeed +scrollSpeed +selectable +seq0 +seq1 +seqCount +seqLoop +setActive +setID +sfx +shape +shatter +shieldRange +shift +shootOffset +shootSize +shotRange +showWinner +side +silhouette +size +skyAlpha +slope +slotID +smashSides +smashTop +snaps +soundTestTitle +spearDir +speed +speedIn +speedOut +spikeCount +spikeRadius +spinDirection +spinSpeed +sprayTime +spread +srcC +srcM +srcY +stageListCategory +stageListName +stagger +start +startAngleA +startAngleB +startDir +startNode +startOff +startType +startingID +startingRings +stationary +stepCount +steps +stopMusic +strength +strict +subFlip +subOff1 +subOff2 +subType +tag +targetLayer +targetPos +targetSpeed +text +text0 +text1 +text2 +text3 +text4 +text5 +text6 +text7 +throttle +tileLayer +tileOrigin +timeAttackFreeze +timeAttackOnly +timer +timerGroup +timerMode +topBoundary +topFrameID +topListID +trackFile +trackID +trackLoop +transition +triggerDir +triggerID +triggerMode +triggerSize +trophyCount +type +unbreakable +useStageConfig +val +videoFile1 +videoFile2 +vsBoundsOffset +vsBoundsSize +vsDisable +vsExtendBottom +vsExtendTop +vsRemove +wait +waitForTrigger +walkOnto +warpTag +warpToCenter +waterOnly +width +winnerID +xBoundaryPosL +xBoundaryPosR +xOut +yBoundaryPosB +yBoundaryPosT +yDir +yOffset +yVel +zoneID +zoneName +zonePalette \ No newline at end of file diff --git a/Resources/SoundFX/Global/BlueShield.wav b/Resources/SoundFX/Global/BlueShield.wav new file mode 100644 index 0000000..4b1975b Binary files /dev/null and b/Resources/SoundFX/Global/BlueShield.wav differ diff --git a/Resources/SoundFX/Global/BubbleBounce.wav b/Resources/SoundFX/Global/BubbleBounce.wav new file mode 100644 index 0000000..65a2843 Binary files /dev/null and b/Resources/SoundFX/Global/BubbleBounce.wav differ diff --git a/Resources/SoundFX/Global/BubbleShield.wav b/Resources/SoundFX/Global/BubbleShield.wav new file mode 100644 index 0000000..d7b2c40 Binary files /dev/null and b/Resources/SoundFX/Global/BubbleShield.wav differ diff --git a/Resources/SoundFX/Global/Charge.wav b/Resources/SoundFX/Global/Charge.wav new file mode 100644 index 0000000..ff6019d Binary files /dev/null and b/Resources/SoundFX/Global/Charge.wav differ diff --git a/Resources/SoundFX/Global/Destroy.wav b/Resources/SoundFX/Global/Destroy.wav new file mode 100644 index 0000000..15e6966 Binary files /dev/null and b/Resources/SoundFX/Global/Destroy.wav differ diff --git a/Resources/SoundFX/Global/DropDash.wav b/Resources/SoundFX/Global/DropDash.wav new file mode 100644 index 0000000..6a2a38e Binary files /dev/null and b/Resources/SoundFX/Global/DropDash.wav differ diff --git a/Resources/SoundFX/Global/FireDash.wav b/Resources/SoundFX/Global/FireDash.wav new file mode 100644 index 0000000..e7521db Binary files /dev/null and b/Resources/SoundFX/Global/FireDash.wav differ diff --git a/Resources/SoundFX/Global/FireShield.wav b/Resources/SoundFX/Global/FireShield.wav new file mode 100644 index 0000000..abb21d8 Binary files /dev/null and b/Resources/SoundFX/Global/FireShield.wav differ diff --git a/Resources/SoundFX/Global/Flying.wav b/Resources/SoundFX/Global/Flying.wav new file mode 100644 index 0000000..53eef8d Binary files /dev/null and b/Resources/SoundFX/Global/Flying.wav differ diff --git a/Resources/SoundFX/Global/Grab.wav b/Resources/SoundFX/Global/Grab.wav new file mode 100644 index 0000000..46a4538 Binary files /dev/null and b/Resources/SoundFX/Global/Grab.wav differ diff --git a/Resources/SoundFX/Global/Hurt.wav b/Resources/SoundFX/Global/Hurt.wav new file mode 100644 index 0000000..fe971e2 Binary files /dev/null and b/Resources/SoundFX/Global/Hurt.wav differ diff --git a/Resources/SoundFX/Global/HyperRing.wav b/Resources/SoundFX/Global/HyperRing.wav new file mode 100644 index 0000000..ceadf1a Binary files /dev/null and b/Resources/SoundFX/Global/HyperRing.wav differ diff --git a/Resources/SoundFX/Global/InstaShield.wav b/Resources/SoundFX/Global/InstaShield.wav new file mode 100644 index 0000000..28610c9 Binary files /dev/null and b/Resources/SoundFX/Global/InstaShield.wav differ diff --git a/Resources/SoundFX/Global/Jump.wav b/Resources/SoundFX/Global/Jump.wav new file mode 100644 index 0000000..fdc7b79 Binary files /dev/null and b/Resources/SoundFX/Global/Jump.wav differ diff --git a/Resources/SoundFX/Global/Land.wav b/Resources/SoundFX/Global/Land.wav new file mode 100644 index 0000000..f7f5548 Binary files /dev/null and b/Resources/SoundFX/Global/Land.wav differ diff --git a/Resources/SoundFX/Global/LightningJump.wav b/Resources/SoundFX/Global/LightningJump.wav new file mode 100644 index 0000000..9e0b40b Binary files /dev/null and b/Resources/SoundFX/Global/LightningJump.wav differ diff --git a/Resources/SoundFX/Global/LightningShield.wav b/Resources/SoundFX/Global/LightningShield.wav new file mode 100644 index 0000000..0815428 Binary files /dev/null and b/Resources/SoundFX/Global/LightningShield.wav differ diff --git a/Resources/SoundFX/Global/LoseRings.wav b/Resources/SoundFX/Global/LoseRings.wav new file mode 100644 index 0000000..3047264 Binary files /dev/null and b/Resources/SoundFX/Global/LoseRings.wav differ diff --git a/Resources/SoundFX/Global/MenuAccept.wav b/Resources/SoundFX/Global/MenuAccept.wav new file mode 100644 index 0000000..4dfc6d6 Binary files /dev/null and b/Resources/SoundFX/Global/MenuAccept.wav differ diff --git a/Resources/SoundFX/Global/MenuBleep.wav b/Resources/SoundFX/Global/MenuBleep.wav new file mode 100644 index 0000000..6596be1 Binary files /dev/null and b/Resources/SoundFX/Global/MenuBleep.wav differ diff --git a/Resources/SoundFX/Global/MenuWoosh.wav b/Resources/SoundFX/Global/MenuWoosh.wav new file mode 100644 index 0000000..ef72dce Binary files /dev/null and b/Resources/SoundFX/Global/MenuWoosh.wav differ diff --git a/Resources/SoundFX/Global/MightyDeflect.wav b/Resources/SoundFX/Global/MightyDeflect.wav new file mode 100644 index 0000000..1e398f0 Binary files /dev/null and b/Resources/SoundFX/Global/MightyDeflect.wav differ diff --git a/Resources/SoundFX/Global/MightyDrill.wav b/Resources/SoundFX/Global/MightyDrill.wav new file mode 100644 index 0000000..686b8cc Binary files /dev/null and b/Resources/SoundFX/Global/MightyDrill.wav differ diff --git a/Resources/SoundFX/Global/MightyLand.wav b/Resources/SoundFX/Global/MightyLand.wav new file mode 100644 index 0000000..c5357f7 Binary files /dev/null and b/Resources/SoundFX/Global/MightyLand.wav differ diff --git a/Resources/SoundFX/Global/MightyUnspin.wav b/Resources/SoundFX/Global/MightyUnspin.wav new file mode 100644 index 0000000..efe6d87 Binary files /dev/null and b/Resources/SoundFX/Global/MightyUnspin.wav differ diff --git a/Resources/SoundFX/Global/OuttaHere.wav b/Resources/SoundFX/Global/OuttaHere.wav new file mode 100644 index 0000000..5fb1cfb Binary files /dev/null and b/Resources/SoundFX/Global/OuttaHere.wav differ diff --git a/Resources/SoundFX/Global/PeelCharge.wav b/Resources/SoundFX/Global/PeelCharge.wav new file mode 100644 index 0000000..082d860 Binary files /dev/null and b/Resources/SoundFX/Global/PeelCharge.wav differ diff --git a/Resources/SoundFX/Global/PeelRelease.wav b/Resources/SoundFX/Global/PeelRelease.wav new file mode 100644 index 0000000..33aa456 Binary files /dev/null and b/Resources/SoundFX/Global/PeelRelease.wav differ diff --git a/Resources/SoundFX/Global/Push.wav b/Resources/SoundFX/Global/Push.wav new file mode 100644 index 0000000..cd2d139 Binary files /dev/null and b/Resources/SoundFX/Global/Push.wav differ diff --git a/Resources/SoundFX/Global/RayDive.wav b/Resources/SoundFX/Global/RayDive.wav new file mode 100644 index 0000000..fd483b8 Binary files /dev/null and b/Resources/SoundFX/Global/RayDive.wav differ diff --git a/Resources/SoundFX/Global/RaySwoop.wav b/Resources/SoundFX/Global/RaySwoop.wav new file mode 100644 index 0000000..398c245 Binary files /dev/null and b/Resources/SoundFX/Global/RaySwoop.wav differ diff --git a/Resources/SoundFX/Global/Recovery.wav b/Resources/SoundFX/Global/Recovery.wav new file mode 100644 index 0000000..a59f1f0 Binary files /dev/null and b/Resources/SoundFX/Global/Recovery.wav differ diff --git a/Resources/SoundFX/Global/Release.wav b/Resources/SoundFX/Global/Release.wav new file mode 100644 index 0000000..11f3469 Binary files /dev/null and b/Resources/SoundFX/Global/Release.wav differ diff --git a/Resources/SoundFX/Global/Ring.wav b/Resources/SoundFX/Global/Ring.wav new file mode 100644 index 0000000..9ed2670 Binary files /dev/null and b/Resources/SoundFX/Global/Ring.wav differ diff --git a/Resources/SoundFX/Global/Roll.wav b/Resources/SoundFX/Global/Roll.wav new file mode 100644 index 0000000..61587df Binary files /dev/null and b/Resources/SoundFX/Global/Roll.wav differ diff --git a/Resources/SoundFX/Global/ScoreAdd.wav b/Resources/SoundFX/Global/ScoreAdd.wav new file mode 100644 index 0000000..13a98a6 Binary files /dev/null and b/Resources/SoundFX/Global/ScoreAdd.wav differ diff --git a/Resources/SoundFX/Global/ScoreTotal.wav b/Resources/SoundFX/Global/ScoreTotal.wav new file mode 100644 index 0000000..29e847e Binary files /dev/null and b/Resources/SoundFX/Global/ScoreTotal.wav differ diff --git a/Resources/SoundFX/Global/SignPost.wav b/Resources/SoundFX/Global/SignPost.wav new file mode 100644 index 0000000..705de0d Binary files /dev/null and b/Resources/SoundFX/Global/SignPost.wav differ diff --git a/Resources/SoundFX/Global/SignPost2p.wav b/Resources/SoundFX/Global/SignPost2p.wav new file mode 100644 index 0000000..f08d5b2 Binary files /dev/null and b/Resources/SoundFX/Global/SignPost2p.wav differ diff --git a/Resources/SoundFX/Global/Skidding.wav b/Resources/SoundFX/Global/Skidding.wav new file mode 100644 index 0000000..aa558c2 Binary files /dev/null and b/Resources/SoundFX/Global/Skidding.wav differ diff --git a/Resources/SoundFX/Global/Slide.wav b/Resources/SoundFX/Global/Slide.wav new file mode 100644 index 0000000..f8dd9ed Binary files /dev/null and b/Resources/SoundFX/Global/Slide.wav differ diff --git a/Resources/SoundFX/Global/Sliding.wav b/Resources/SoundFX/Global/Sliding.wav new file mode 100644 index 0000000..70d5173 Binary files /dev/null and b/Resources/SoundFX/Global/Sliding.wav differ diff --git a/Resources/SoundFX/Global/SpecialRing.wav b/Resources/SoundFX/Global/SpecialRing.wav new file mode 100644 index 0000000..e4c285b Binary files /dev/null and b/Resources/SoundFX/Global/SpecialRing.wav differ diff --git a/Resources/SoundFX/Global/SpecialWarp.wav b/Resources/SoundFX/Global/SpecialWarp.wav new file mode 100644 index 0000000..502ec67 Binary files /dev/null and b/Resources/SoundFX/Global/SpecialWarp.wav differ diff --git a/Resources/SoundFX/Global/Spike.wav b/Resources/SoundFX/Global/Spike.wav new file mode 100644 index 0000000..52a40d3 Binary files /dev/null and b/Resources/SoundFX/Global/Spike.wav differ diff --git a/Resources/SoundFX/Global/SpikesMove.wav b/Resources/SoundFX/Global/SpikesMove.wav new file mode 100644 index 0000000..b4d0066 Binary files /dev/null and b/Resources/SoundFX/Global/SpikesMove.wav differ diff --git a/Resources/SoundFX/Global/Spring.wav b/Resources/SoundFX/Global/Spring.wav new file mode 100644 index 0000000..1fc00fc Binary files /dev/null and b/Resources/SoundFX/Global/Spring.wav differ diff --git a/Resources/SoundFX/Global/StarPost.wav b/Resources/SoundFX/Global/StarPost.wav new file mode 100644 index 0000000..9acd7e0 Binary files /dev/null and b/Resources/SoundFX/Global/StarPost.wav differ diff --git a/Resources/SoundFX/Global/Swap.wav b/Resources/SoundFX/Global/Swap.wav new file mode 100644 index 0000000..ead63e8 Binary files /dev/null and b/Resources/SoundFX/Global/Swap.wav differ diff --git a/Resources/SoundFX/Global/SwapFail.wav b/Resources/SoundFX/Global/SwapFail.wav new file mode 100644 index 0000000..6d1af88 Binary files /dev/null and b/Resources/SoundFX/Global/SwapFail.wav differ diff --git a/Resources/SoundFX/Global/Teleport.wav b/Resources/SoundFX/Global/Teleport.wav new file mode 100644 index 0000000..6cc7c3e Binary files /dev/null and b/Resources/SoundFX/Global/Teleport.wav differ diff --git a/Resources/SoundFX/Global/Tired.wav b/Resources/SoundFX/Global/Tired.wav new file mode 100644 index 0000000..c15d4cb Binary files /dev/null and b/Resources/SoundFX/Global/Tired.wav differ diff --git a/Resources/SoundFX/Global/Twinkle.wav b/Resources/SoundFX/Global/Twinkle.wav new file mode 100644 index 0000000..5b613ac Binary files /dev/null and b/Resources/SoundFX/Global/Twinkle.wav differ diff --git a/Resources/SoundFX/Global/Warp.wav b/Resources/SoundFX/Global/Warp.wav new file mode 100644 index 0000000..d4ccb66 Binary files /dev/null and b/Resources/SoundFX/Global/Warp.wav differ diff --git a/Resources/SoundFX/HCZ/BigFan.wav b/Resources/SoundFX/HCZ/BigFan.wav new file mode 100644 index 0000000..fa561b4 Binary files /dev/null and b/Resources/SoundFX/HCZ/BigFan.wav differ diff --git a/Resources/SoundFX/HCZ/EggMobile.wav b/Resources/SoundFX/HCZ/EggMobile.wav new file mode 100644 index 0000000..ec04b1b Binary files /dev/null and b/Resources/SoundFX/HCZ/EggMobile.wav differ diff --git a/Resources/SoundFX/HCZ/HCZButtonDoor.wav b/Resources/SoundFX/HCZ/HCZButtonDoor.wav new file mode 100644 index 0000000..a32786f Binary files /dev/null and b/Resources/SoundFX/HCZ/HCZButtonDoor.wav differ diff --git a/Resources/SoundFX/HCZ/PullChain.wav b/Resources/SoundFX/HCZ/PullChain.wav new file mode 100644 index 0000000..da43859 Binary files /dev/null and b/Resources/SoundFX/HCZ/PullChain.wav differ diff --git a/Resources/SoundFX/HCZ/Skim.wav b/Resources/SoundFX/HCZ/Skim.wav new file mode 100644 index 0000000..c5580b4 Binary files /dev/null and b/Resources/SoundFX/HCZ/Skim.wav differ diff --git a/Resources/SoundFX/HCZ/SmallFan.wav b/Resources/SoundFX/HCZ/SmallFan.wav new file mode 100644 index 0000000..97ff375 Binary files /dev/null and b/Resources/SoundFX/HCZ/SmallFan.wav differ diff --git a/Resources/SoundFX/HCZ/Spear.wav b/Resources/SoundFX/HCZ/Spear.wav new file mode 100644 index 0000000..30cc3b3 Binary files /dev/null and b/Resources/SoundFX/HCZ/Spear.wav differ diff --git a/Resources/SoundFX/HCZ/Wash.wav b/Resources/SoundFX/HCZ/Wash.wav new file mode 100644 index 0000000..58d1d4a Binary files /dev/null and b/Resources/SoundFX/HCZ/Wash.wav differ diff --git a/Resources/SoundFX/HCZ/WaterGush.wav b/Resources/SoundFX/HCZ/WaterGush.wav new file mode 100644 index 0000000..d6aa649 Binary files /dev/null and b/Resources/SoundFX/HCZ/WaterGush.wav differ diff --git a/Resources/SoundFX/HCZ/WaterLevel_L.wav b/Resources/SoundFX/HCZ/WaterLevel_L.wav new file mode 100644 index 0000000..f325667 Binary files /dev/null and b/Resources/SoundFX/HCZ/WaterLevel_L.wav differ diff --git a/Resources/SoundFX/HCZ/WaterLevel_R.wav b/Resources/SoundFX/HCZ/WaterLevel_R.wav new file mode 100644 index 0000000..f99da7c Binary files /dev/null and b/Resources/SoundFX/HCZ/WaterLevel_R.wav differ diff --git a/Resources/SoundFX/HCZ/Whirlpool.wav b/Resources/SoundFX/HCZ/Whirlpool.wav new file mode 100644 index 0000000..80b51b0 Binary files /dev/null and b/Resources/SoundFX/HCZ/Whirlpool.wav differ diff --git a/Resources/SoundFX/Stage/Assemble.wav b/Resources/SoundFX/Stage/Assemble.wav new file mode 100644 index 0000000..70442db Binary files /dev/null and b/Resources/SoundFX/Stage/Assemble.wav differ diff --git a/Resources/SoundFX/Stage/Beep.wav b/Resources/SoundFX/Stage/Beep.wav new file mode 100644 index 0000000..ef07234 Binary files /dev/null and b/Resources/SoundFX/Stage/Beep.wav differ diff --git a/Resources/SoundFX/Stage/Beep2.wav b/Resources/SoundFX/Stage/Beep2.wav new file mode 100644 index 0000000..2546c7a Binary files /dev/null and b/Resources/SoundFX/Stage/Beep2.wav differ diff --git a/Resources/SoundFX/Stage/Beep3.wav b/Resources/SoundFX/Stage/Beep3.wav new file mode 100644 index 0000000..0086a9c Binary files /dev/null and b/Resources/SoundFX/Stage/Beep3.wav differ diff --git a/Resources/SoundFX/Stage/Beep4.wav b/Resources/SoundFX/Stage/Beep4.wav new file mode 100644 index 0000000..c096831 Binary files /dev/null and b/Resources/SoundFX/Stage/Beep4.wav differ diff --git a/Resources/SoundFX/Stage/Bloop.wav b/Resources/SoundFX/Stage/Bloop.wav new file mode 100644 index 0000000..ccb2dd8 Binary files /dev/null and b/Resources/SoundFX/Stage/Bloop.wav differ diff --git a/Resources/SoundFX/Stage/BossHit.wav b/Resources/SoundFX/Stage/BossHit.wav new file mode 100644 index 0000000..77e678e Binary files /dev/null and b/Resources/SoundFX/Stage/BossHit.wav differ diff --git a/Resources/SoundFX/Stage/Breathe.wav b/Resources/SoundFX/Stage/Breathe.wav new file mode 100644 index 0000000..544734f Binary files /dev/null and b/Resources/SoundFX/Stage/Breathe.wav differ diff --git a/Resources/SoundFX/Stage/BulbPop.wav b/Resources/SoundFX/Stage/BulbPop.wav new file mode 100644 index 0000000..9a13047 Binary files /dev/null and b/Resources/SoundFX/Stage/BulbPop.wav differ diff --git a/Resources/SoundFX/Stage/Bumper.wav b/Resources/SoundFX/Stage/Bumper.wav new file mode 100644 index 0000000..488d0ce Binary files /dev/null and b/Resources/SoundFX/Stage/Bumper.wav differ diff --git a/Resources/SoundFX/Stage/Bumper2.wav b/Resources/SoundFX/Stage/Bumper2.wav new file mode 100644 index 0000000..6c03f59 Binary files /dev/null and b/Resources/SoundFX/Stage/Bumper2.wav differ diff --git a/Resources/SoundFX/Stage/Bumper3.wav b/Resources/SoundFX/Stage/Bumper3.wav new file mode 100644 index 0000000..e3404cc Binary files /dev/null and b/Resources/SoundFX/Stage/Bumper3.wav differ diff --git a/Resources/SoundFX/Stage/Button.wav b/Resources/SoundFX/Stage/Button.wav new file mode 100644 index 0000000..1ad7048 Binary files /dev/null and b/Resources/SoundFX/Stage/Button.wav differ diff --git a/Resources/SoundFX/Stage/Button2.wav b/Resources/SoundFX/Stage/Button2.wav new file mode 100644 index 0000000..242d62b Binary files /dev/null and b/Resources/SoundFX/Stage/Button2.wav differ diff --git a/Resources/SoundFX/Stage/Buzzsaw.wav b/Resources/SoundFX/Stage/Buzzsaw.wav new file mode 100644 index 0000000..6530725 Binary files /dev/null and b/Resources/SoundFX/Stage/Buzzsaw.wav differ diff --git a/Resources/SoundFX/Stage/CannonFire.wav b/Resources/SoundFX/Stage/CannonFire.wav new file mode 100644 index 0000000..d6073ab Binary files /dev/null and b/Resources/SoundFX/Stage/CannonFire.wav differ diff --git a/Resources/SoundFX/Stage/Chain.wav b/Resources/SoundFX/Stage/Chain.wav new file mode 100644 index 0000000..8bf5972 Binary files /dev/null and b/Resources/SoundFX/Stage/Chain.wav differ diff --git a/Resources/SoundFX/Stage/Chopper.wav b/Resources/SoundFX/Stage/Chopper.wav new file mode 100644 index 0000000..d81afd8 Binary files /dev/null and b/Resources/SoundFX/Stage/Chopper.wav differ diff --git a/Resources/SoundFX/Stage/Clack.wav b/Resources/SoundFX/Stage/Clack.wav new file mode 100644 index 0000000..e1a1aa9 Binary files /dev/null and b/Resources/SoundFX/Stage/Clack.wav differ diff --git a/Resources/SoundFX/Stage/Clack2.wav b/Resources/SoundFX/Stage/Clack2.wav new file mode 100644 index 0000000..0093b47 Binary files /dev/null and b/Resources/SoundFX/Stage/Clack2.wav differ diff --git a/Resources/SoundFX/Stage/Clacker.wav b/Resources/SoundFX/Stage/Clacker.wav new file mode 100644 index 0000000..d03ba49 Binary files /dev/null and b/Resources/SoundFX/Stage/Clacker.wav differ diff --git a/Resources/SoundFX/Stage/Clang.wav b/Resources/SoundFX/Stage/Clang.wav new file mode 100644 index 0000000..16a2920 Binary files /dev/null and b/Resources/SoundFX/Stage/Clang.wav differ diff --git a/Resources/SoundFX/Stage/Clang2.wav b/Resources/SoundFX/Stage/Clang2.wav new file mode 100644 index 0000000..8bf5972 Binary files /dev/null and b/Resources/SoundFX/Stage/Clang2.wav differ diff --git a/Resources/SoundFX/Stage/Clapperboard.wav b/Resources/SoundFX/Stage/Clapperboard.wav new file mode 100644 index 0000000..1c6819c Binary files /dev/null and b/Resources/SoundFX/Stage/Clapperboard.wav differ diff --git a/Resources/SoundFX/Stage/Click.wav b/Resources/SoundFX/Stage/Click.wav new file mode 100644 index 0000000..1428908 Binary files /dev/null and b/Resources/SoundFX/Stage/Click.wav differ diff --git a/Resources/SoundFX/Stage/Click2.wav b/Resources/SoundFX/Stage/Click2.wav new file mode 100644 index 0000000..cf19bec Binary files /dev/null and b/Resources/SoundFX/Stage/Click2.wav differ diff --git a/Resources/SoundFX/Stage/Drop.wav b/Resources/SoundFX/Stage/Drop.wav new file mode 100644 index 0000000..54d60b2 Binary files /dev/null and b/Resources/SoundFX/Stage/Drop.wav differ diff --git a/Resources/SoundFX/Stage/Drown.wav b/Resources/SoundFX/Stage/Drown.wav new file mode 100644 index 0000000..427a902 Binary files /dev/null and b/Resources/SoundFX/Stage/Drown.wav differ diff --git a/Resources/SoundFX/Stage/DrownAlert.wav b/Resources/SoundFX/Stage/DrownAlert.wav new file mode 100644 index 0000000..7a85494 Binary files /dev/null and b/Resources/SoundFX/Stage/DrownAlert.wav differ diff --git a/Resources/SoundFX/Stage/ElecCharge.wav b/Resources/SoundFX/Stage/ElecCharge.wav new file mode 100644 index 0000000..56e4acf Binary files /dev/null and b/Resources/SoundFX/Stage/ElecCharge.wav differ diff --git a/Resources/SoundFX/Stage/ElecPulse.wav b/Resources/SoundFX/Stage/ElecPulse.wav new file mode 100644 index 0000000..23e6577 Binary files /dev/null and b/Resources/SoundFX/Stage/ElecPulse.wav differ diff --git a/Resources/SoundFX/Stage/Electrify.wav b/Resources/SoundFX/Stage/Electrify.wav new file mode 100644 index 0000000..b4c19ed Binary files /dev/null and b/Resources/SoundFX/Stage/Electrify.wav differ diff --git a/Resources/SoundFX/Stage/Electrify2.wav b/Resources/SoundFX/Stage/Electrify2.wav new file mode 100644 index 0000000..38bbb10 Binary files /dev/null and b/Resources/SoundFX/Stage/Electrify2.wav differ diff --git a/Resources/SoundFX/Stage/Explosion.wav b/Resources/SoundFX/Stage/Explosion.wav new file mode 100644 index 0000000..5c53789 Binary files /dev/null and b/Resources/SoundFX/Stage/Explosion.wav differ diff --git a/Resources/SoundFX/Stage/Explosion2.wav b/Resources/SoundFX/Stage/Explosion2.wav new file mode 100644 index 0000000..8b89e7c Binary files /dev/null and b/Resources/SoundFX/Stage/Explosion2.wav differ diff --git a/Resources/SoundFX/Stage/Explosion3.wav b/Resources/SoundFX/Stage/Explosion3.wav new file mode 100644 index 0000000..62ebfbf Binary files /dev/null and b/Resources/SoundFX/Stage/Explosion3.wav differ diff --git a/Resources/SoundFX/Stage/Explosion4.wav b/Resources/SoundFX/Stage/Explosion4.wav new file mode 100644 index 0000000..713f4c4 Binary files /dev/null and b/Resources/SoundFX/Stage/Explosion4.wav differ diff --git a/Resources/SoundFX/Stage/Extend.wav b/Resources/SoundFX/Stage/Extend.wav new file mode 100644 index 0000000..f4ee45f Binary files /dev/null and b/Resources/SoundFX/Stage/Extend.wav differ diff --git a/Resources/SoundFX/Stage/Fail.wav b/Resources/SoundFX/Stage/Fail.wav new file mode 100644 index 0000000..4fbe83c Binary files /dev/null and b/Resources/SoundFX/Stage/Fail.wav differ diff --git a/Resources/SoundFX/Stage/FanStart.wav b/Resources/SoundFX/Stage/FanStart.wav new file mode 100644 index 0000000..bfaf20b Binary files /dev/null and b/Resources/SoundFX/Stage/FanStart.wav differ diff --git a/Resources/SoundFX/Stage/Fireball.wav b/Resources/SoundFX/Stage/Fireball.wav new file mode 100644 index 0000000..ee80c64 Binary files /dev/null and b/Resources/SoundFX/Stage/Fireball.wav differ diff --git a/Resources/SoundFX/Stage/Flame.wav b/Resources/SoundFX/Stage/Flame.wav new file mode 100644 index 0000000..037fa0c Binary files /dev/null and b/Resources/SoundFX/Stage/Flame.wav differ diff --git a/Resources/SoundFX/Stage/Flame2.wav b/Resources/SoundFX/Stage/Flame2.wav new file mode 100644 index 0000000..d4c2cdc Binary files /dev/null and b/Resources/SoundFX/Stage/Flame2.wav differ diff --git a/Resources/SoundFX/Stage/Flap.wav b/Resources/SoundFX/Stage/Flap.wav new file mode 100644 index 0000000..4242329 Binary files /dev/null and b/Resources/SoundFX/Stage/Flap.wav differ diff --git a/Resources/SoundFX/Stage/Flipper.wav b/Resources/SoundFX/Stage/Flipper.wav new file mode 100644 index 0000000..42b9bf8 Binary files /dev/null and b/Resources/SoundFX/Stage/Flipper.wav differ diff --git a/Resources/SoundFX/Stage/GoodFuture.wav b/Resources/SoundFX/Stage/GoodFuture.wav new file mode 100644 index 0000000..a2fd4af Binary files /dev/null and b/Resources/SoundFX/Stage/GoodFuture.wav differ diff --git a/Resources/SoundFX/Stage/HighFive.wav b/Resources/SoundFX/Stage/HighFive.wav new file mode 100644 index 0000000..faf8ed9 Binary files /dev/null and b/Resources/SoundFX/Stage/HighFive.wav differ diff --git a/Resources/SoundFX/Stage/Huff.wav b/Resources/SoundFX/Stage/Huff.wav new file mode 100644 index 0000000..7d56a34 Binary files /dev/null and b/Resources/SoundFX/Stage/Huff.wav differ diff --git a/Resources/SoundFX/Stage/HullClose.wav b/Resources/SoundFX/Stage/HullClose.wav new file mode 100644 index 0000000..637a741 Binary files /dev/null and b/Resources/SoundFX/Stage/HullClose.wav differ diff --git a/Resources/SoundFX/Stage/Impact2.wav b/Resources/SoundFX/Stage/Impact2.wav new file mode 100644 index 0000000..1a1b213 Binary files /dev/null and b/Resources/SoundFX/Stage/Impact2.wav differ diff --git a/Resources/SoundFX/Stage/Impact3.wav b/Resources/SoundFX/Stage/Impact3.wav new file mode 100644 index 0000000..c976aa1 Binary files /dev/null and b/Resources/SoundFX/Stage/Impact3.wav differ diff --git a/Resources/SoundFX/Stage/Impact4.wav b/Resources/SoundFX/Stage/Impact4.wav new file mode 100644 index 0000000..f54ce15 Binary files /dev/null and b/Resources/SoundFX/Stage/Impact4.wav differ diff --git a/Resources/SoundFX/Stage/Impact5.wav b/Resources/SoundFX/Stage/Impact5.wav new file mode 100644 index 0000000..191e4cc Binary files /dev/null and b/Resources/SoundFX/Stage/Impact5.wav differ diff --git a/Resources/SoundFX/Stage/Impact6.wav b/Resources/SoundFX/Stage/Impact6.wav new file mode 100644 index 0000000..4561b4f Binary files /dev/null and b/Resources/SoundFX/Stage/Impact6.wav differ diff --git a/Resources/SoundFX/Stage/Jump2.wav b/Resources/SoundFX/Stage/Jump2.wav new file mode 100644 index 0000000..4ee7d7b Binary files /dev/null and b/Resources/SoundFX/Stage/Jump2.wav differ diff --git a/Resources/SoundFX/Stage/Landing.wav b/Resources/SoundFX/Stage/Landing.wav new file mode 100644 index 0000000..dbf1639 Binary files /dev/null and b/Resources/SoundFX/Stage/Landing.wav differ diff --git a/Resources/SoundFX/Stage/Launch.wav b/Resources/SoundFX/Stage/Launch.wav new file mode 100644 index 0000000..8cda0bb Binary files /dev/null and b/Resources/SoundFX/Stage/Launch.wav differ diff --git a/Resources/SoundFX/Stage/Lava.wav b/Resources/SoundFX/Stage/Lava.wav new file mode 100644 index 0000000..0f7b567 Binary files /dev/null and b/Resources/SoundFX/Stage/Lava.wav differ diff --git a/Resources/SoundFX/Stage/LedgeBreak.wav b/Resources/SoundFX/Stage/LedgeBreak.wav new file mode 100644 index 0000000..2c38e64 Binary files /dev/null and b/Resources/SoundFX/Stage/LedgeBreak.wav differ diff --git a/Resources/SoundFX/Stage/LedgeBreak2.wav b/Resources/SoundFX/Stage/LedgeBreak2.wav new file mode 100644 index 0000000..37b12f1 Binary files /dev/null and b/Resources/SoundFX/Stage/LedgeBreak2.wav differ diff --git a/Resources/SoundFX/Stage/LedgeBreak3.wav b/Resources/SoundFX/Stage/LedgeBreak3.wav new file mode 100644 index 0000000..727fa3f Binary files /dev/null and b/Resources/SoundFX/Stage/LedgeBreak3.wav differ diff --git a/Resources/SoundFX/Stage/LetterTurn.wav b/Resources/SoundFX/Stage/LetterTurn.wav new file mode 100644 index 0000000..a4fea7d Binary files /dev/null and b/Resources/SoundFX/Stage/LetterTurn.wav differ diff --git a/Resources/SoundFX/Stage/LottoBounce.wav b/Resources/SoundFX/Stage/LottoBounce.wav new file mode 100644 index 0000000..e0e9f48 Binary files /dev/null and b/Resources/SoundFX/Stage/LottoBounce.wav differ diff --git a/Resources/SoundFX/Stage/MachineActivate.wav b/Resources/SoundFX/Stage/MachineActivate.wav new file mode 100644 index 0000000..119a2fc Binary files /dev/null and b/Resources/SoundFX/Stage/MachineActivate.wav differ diff --git a/Resources/SoundFX/Stage/Magnet.wav b/Resources/SoundFX/Stage/Magnet.wav new file mode 100644 index 0000000..72b5bca Binary files /dev/null and b/Resources/SoundFX/Stage/Magnet.wav differ diff --git a/Resources/SoundFX/Stage/Open.wav b/Resources/SoundFX/Stage/Open.wav new file mode 100644 index 0000000..b7e9c92 Binary files /dev/null and b/Resources/SoundFX/Stage/Open.wav differ diff --git a/Resources/SoundFX/Stage/PimPom.wav b/Resources/SoundFX/Stage/PimPom.wav new file mode 100644 index 0000000..c297882 Binary files /dev/null and b/Resources/SoundFX/Stage/PimPom.wav differ diff --git a/Resources/SoundFX/Stage/Plus.wav b/Resources/SoundFX/Stage/Plus.wav new file mode 100644 index 0000000..cd6f576 Binary files /dev/null and b/Resources/SoundFX/Stage/Plus.wav differ diff --git a/Resources/SoundFX/Stage/Pon.wav b/Resources/SoundFX/Stage/Pon.wav new file mode 100644 index 0000000..45db95a Binary files /dev/null and b/Resources/SoundFX/Stage/Pon.wav differ diff --git a/Resources/SoundFX/Stage/PopcornLaunch.wav b/Resources/SoundFX/Stage/PopcornLaunch.wav new file mode 100644 index 0000000..986de39 Binary files /dev/null and b/Resources/SoundFX/Stage/PopcornLaunch.wav differ diff --git a/Resources/SoundFX/Stage/PowerDown.wav b/Resources/SoundFX/Stage/PowerDown.wav new file mode 100644 index 0000000..2339292 Binary files /dev/null and b/Resources/SoundFX/Stage/PowerDown.wav differ diff --git a/Resources/SoundFX/Stage/PowerUp.wav b/Resources/SoundFX/Stage/PowerUp.wav new file mode 100644 index 0000000..cd92fb3 Binary files /dev/null and b/Resources/SoundFX/Stage/PowerUp.wav differ diff --git a/Resources/SoundFX/Stage/Pulley.wav b/Resources/SoundFX/Stage/Pulley.wav new file mode 100644 index 0000000..87813f4 Binary files /dev/null and b/Resources/SoundFX/Stage/Pulley.wav differ diff --git a/Resources/SoundFX/Stage/Push.wav b/Resources/SoundFX/Stage/Push.wav new file mode 100644 index 0000000..35b6b33 Binary files /dev/null and b/Resources/SoundFX/Stage/Push.wav differ diff --git a/Resources/SoundFX/Stage/Repel.wav b/Resources/SoundFX/Stage/Repel.wav new file mode 100644 index 0000000..cc8978f Binary files /dev/null and b/Resources/SoundFX/Stage/Repel.wav differ diff --git a/Resources/SoundFX/Stage/Retract.wav b/Resources/SoundFX/Stage/Retract.wav new file mode 100644 index 0000000..bc9c64b Binary files /dev/null and b/Resources/SoundFX/Stage/Retract.wav differ diff --git a/Resources/SoundFX/Stage/Rev.wav b/Resources/SoundFX/Stage/Rev.wav new file mode 100644 index 0000000..27fd2fd Binary files /dev/null and b/Resources/SoundFX/Stage/Rev.wav differ diff --git a/Resources/SoundFX/Stage/RockemSockem.wav b/Resources/SoundFX/Stage/RockemSockem.wav new file mode 100644 index 0000000..77754ac Binary files /dev/null and b/Resources/SoundFX/Stage/RockemSockem.wav differ diff --git a/Resources/SoundFX/Stage/RocketJet.wav b/Resources/SoundFX/Stage/RocketJet.wav new file mode 100644 index 0000000..3097148 Binary files /dev/null and b/Resources/SoundFX/Stage/RocketJet.wav differ diff --git a/Resources/SoundFX/Stage/Rotate.wav b/Resources/SoundFX/Stage/Rotate.wav new file mode 100644 index 0000000..0993946 Binary files /dev/null and b/Resources/SoundFX/Stage/Rotate.wav differ diff --git a/Resources/SoundFX/Stage/Rumble.wav b/Resources/SoundFX/Stage/Rumble.wav new file mode 100644 index 0000000..95794a6 Binary files /dev/null and b/Resources/SoundFX/Stage/Rumble.wav differ diff --git a/Resources/SoundFX/Stage/Satellite1.wav b/Resources/SoundFX/Stage/Satellite1.wav new file mode 100644 index 0000000..7776624 Binary files /dev/null and b/Resources/SoundFX/Stage/Satellite1.wav differ diff --git a/Resources/SoundFX/Stage/Satellite2.wav b/Resources/SoundFX/Stage/Satellite2.wav new file mode 100644 index 0000000..92ea474 Binary files /dev/null and b/Resources/SoundFX/Stage/Satellite2.wav differ diff --git a/Resources/SoundFX/Stage/Sega.wav b/Resources/SoundFX/Stage/Sega.wav new file mode 100644 index 0000000..de8c5e4 Binary files /dev/null and b/Resources/SoundFX/Stage/Sega.wav differ diff --git a/Resources/SoundFX/Stage/Sharp.wav b/Resources/SoundFX/Stage/Sharp.wav new file mode 100644 index 0000000..f358f39 Binary files /dev/null and b/Resources/SoundFX/Stage/Sharp.wav differ diff --git a/Resources/SoundFX/Stage/Shoot1.wav b/Resources/SoundFX/Stage/Shoot1.wav new file mode 100644 index 0000000..95549f1 Binary files /dev/null and b/Resources/SoundFX/Stage/Shoot1.wav differ diff --git a/Resources/SoundFX/Stage/Shot.wav b/Resources/SoundFX/Stage/Shot.wav new file mode 100644 index 0000000..3d9d2f7 Binary files /dev/null and b/Resources/SoundFX/Stage/Shot.wav differ diff --git a/Resources/SoundFX/Stage/SpeedBooster.wav b/Resources/SoundFX/Stage/SpeedBooster.wav new file mode 100644 index 0000000..169fcd9 Binary files /dev/null and b/Resources/SoundFX/Stage/SpeedBooster.wav differ diff --git a/Resources/SoundFX/Stage/SpewBall.wav b/Resources/SoundFX/Stage/SpewBall.wav new file mode 100644 index 0000000..f3f21ed Binary files /dev/null and b/Resources/SoundFX/Stage/SpewBall.wav differ diff --git a/Resources/SoundFX/Stage/Splash.wav b/Resources/SoundFX/Stage/Splash.wav new file mode 100644 index 0000000..5019447 Binary files /dev/null and b/Resources/SoundFX/Stage/Splash.wav differ diff --git a/Resources/SoundFX/Stage/Splash2.wav b/Resources/SoundFX/Stage/Splash2.wav new file mode 100644 index 0000000..2edbd1c Binary files /dev/null and b/Resources/SoundFX/Stage/Splash2.wav differ diff --git a/Resources/SoundFX/Stage/Strain.wav b/Resources/SoundFX/Stage/Strain.wav new file mode 100644 index 0000000..07046da Binary files /dev/null and b/Resources/SoundFX/Stage/Strain.wav differ diff --git a/Resources/SoundFX/Stage/Swing.wav b/Resources/SoundFX/Stage/Swing.wav new file mode 100644 index 0000000..29af8ff Binary files /dev/null and b/Resources/SoundFX/Stage/Swing.wav differ diff --git a/Resources/SoundFX/Stage/Targeting1.wav b/Resources/SoundFX/Stage/Targeting1.wav new file mode 100644 index 0000000..d629bbd Binary files /dev/null and b/Resources/SoundFX/Stage/Targeting1.wav differ diff --git a/Resources/SoundFX/Stage/Transform.wav b/Resources/SoundFX/Stage/Transform.wav new file mode 100644 index 0000000..e8a9b14 Binary files /dev/null and b/Resources/SoundFX/Stage/Transform.wav differ diff --git a/Resources/SoundFX/Stage/Transform2.wav b/Resources/SoundFX/Stage/Transform2.wav new file mode 100644 index 0000000..dfdb33c Binary files /dev/null and b/Resources/SoundFX/Stage/Transform2.wav differ diff --git a/Resources/SoundFX/Stage/Unravel.wav b/Resources/SoundFX/Stage/Unravel.wav new file mode 100644 index 0000000..bbe8ec1 Binary files /dev/null and b/Resources/SoundFX/Stage/Unravel.wav differ diff --git a/Resources/SoundFX/Stage/Wall.wav b/Resources/SoundFX/Stage/Wall.wav new file mode 100644 index 0000000..1c33c4b Binary files /dev/null and b/Resources/SoundFX/Stage/Wall.wav differ diff --git a/Resources/SoundFX/Stage/Warning.wav b/Resources/SoundFX/Stage/Warning.wav new file mode 100644 index 0000000..b8b5ffd Binary files /dev/null and b/Resources/SoundFX/Stage/Warning.wav differ diff --git a/Resources/SoundFX/Stage/Waterfall.wav b/Resources/SoundFX/Stage/Waterfall.wav new file mode 100644 index 0000000..36330f9 Binary files /dev/null and b/Resources/SoundFX/Stage/Waterfall.wav differ diff --git a/Resources/SoundFX/Stage/Waterfall2.wav b/Resources/SoundFX/Stage/Waterfall2.wav new file mode 100644 index 0000000..ad064ee Binary files /dev/null and b/Resources/SoundFX/Stage/Waterfall2.wav differ diff --git a/Resources/SoundFX/Stage/WaterfallLoop.wav b/Resources/SoundFX/Stage/WaterfallLoop.wav new file mode 100644 index 0000000..c754496 Binary files /dev/null and b/Resources/SoundFX/Stage/WaterfallLoop.wav differ diff --git a/Resources/SoundFX/Stage/Whack.wav b/Resources/SoundFX/Stage/Whack.wav new file mode 100644 index 0000000..1c6819c Binary files /dev/null and b/Resources/SoundFX/Stage/Whack.wav differ diff --git a/Resources/SoundFX/Stage/Win.wav b/Resources/SoundFX/Stage/Win.wav new file mode 100644 index 0000000..5aae06e Binary files /dev/null and b/Resources/SoundFX/Stage/Win.wav differ diff --git a/Resources/SoundFX/Stage/WindowShatter.wav b/Resources/SoundFX/Stage/WindowShatter.wav new file mode 100644 index 0000000..5d01633 Binary files /dev/null and b/Resources/SoundFX/Stage/WindowShatter.wav differ diff --git a/Resources/SoundFX/Stage/Zap.wav b/Resources/SoundFX/Stage/Zap.wav new file mode 100644 index 0000000..88c1730 Binary files /dev/null and b/Resources/SoundFX/Stage/Zap.wav differ diff --git a/Resources/Sprites/GHZ/AniTiles.gif b/Resources/Sprites/GHZ/AniTiles.gif new file mode 100644 index 0000000..ebd6e6f Binary files /dev/null and b/Resources/Sprites/GHZ/AniTiles.gif differ diff --git a/Resources/Sprites/GHZ/Ball.gif b/Resources/Sprites/GHZ/Ball.gif new file mode 100644 index 0000000..57a2b3c Binary files /dev/null and b/Resources/Sprites/GHZ/Ball.gif differ diff --git a/Resources/Sprites/GHZ/Batbrain.bin b/Resources/Sprites/GHZ/Batbrain.bin new file mode 100644 index 0000000..47ca19b Binary files /dev/null and b/Resources/Sprites/GHZ/Batbrain.bin differ diff --git a/Resources/Sprites/GHZ/Bridge.bin b/Resources/Sprites/GHZ/Bridge.bin new file mode 100644 index 0000000..85c5f6a Binary files /dev/null and b/Resources/Sprites/GHZ/Bridge.bin differ diff --git a/Resources/Sprites/GHZ/BurningLog.bin b/Resources/Sprites/GHZ/BurningLog.bin new file mode 100644 index 0000000..e0d18f2 Binary files /dev/null and b/Resources/Sprites/GHZ/BurningLog.bin differ diff --git a/Resources/Sprites/GHZ/BuzzBomber.bin b/Resources/Sprites/GHZ/BuzzBomber.bin new file mode 100644 index 0000000..8774ec8 Binary files /dev/null and b/Resources/Sprites/GHZ/BuzzBomber.bin differ diff --git a/Resources/Sprites/GHZ/CheckerBall.bin b/Resources/Sprites/GHZ/CheckerBall.bin new file mode 100644 index 0000000..a80031b Binary files /dev/null and b/Resources/Sprites/GHZ/CheckerBall.bin differ diff --git a/Resources/Sprites/GHZ/Chopper.bin b/Resources/Sprites/GHZ/Chopper.bin new file mode 100644 index 0000000..16ba1d0 Binary files /dev/null and b/Resources/Sprites/GHZ/Chopper.bin differ diff --git a/Resources/Sprites/GHZ/Crabmeat.bin b/Resources/Sprites/GHZ/Crabmeat.bin new file mode 100644 index 0000000..a5207ea Binary files /dev/null and b/Resources/Sprites/GHZ/Crabmeat.bin differ diff --git a/Resources/Sprites/GHZ/DDWrecker.bin b/Resources/Sprites/GHZ/DDWrecker.bin new file mode 100644 index 0000000..ed1cf8b Binary files /dev/null and b/Resources/Sprites/GHZ/DDWrecker.bin differ diff --git a/Resources/Sprites/GHZ/DDWrecker.gif b/Resources/Sprites/GHZ/DDWrecker.gif new file mode 100644 index 0000000..17f2655 Binary files /dev/null and b/Resources/Sprites/GHZ/DDWrecker.gif differ diff --git a/Resources/Sprites/GHZ/DERobot.bin b/Resources/Sprites/GHZ/DERobot.bin new file mode 100644 index 0000000..560c287 Binary files /dev/null and b/Resources/Sprites/GHZ/DERobot.bin differ diff --git a/Resources/Sprites/GHZ/DERobot.gif b/Resources/Sprites/GHZ/DERobot.gif new file mode 100644 index 0000000..8aea61a Binary files /dev/null and b/Resources/Sprites/GHZ/DERobot.gif differ diff --git a/Resources/Sprites/GHZ/Decoration.bin b/Resources/Sprites/GHZ/Decoration.bin new file mode 100644 index 0000000..2a9e234 Binary files /dev/null and b/Resources/Sprites/GHZ/Decoration.bin differ diff --git a/Resources/Sprites/GHZ/Fireball.bin b/Resources/Sprites/GHZ/Fireball.bin new file mode 100644 index 0000000..cdc793f Binary files /dev/null and b/Resources/Sprites/GHZ/Fireball.bin differ diff --git a/Resources/Sprites/GHZ/Motobug.bin b/Resources/Sprites/GHZ/Motobug.bin new file mode 100644 index 0000000..48c104a Binary files /dev/null and b/Resources/Sprites/GHZ/Motobug.bin differ diff --git a/Resources/Sprites/GHZ/Newtron.bin b/Resources/Sprites/GHZ/Newtron.bin new file mode 100644 index 0000000..77437e5 Binary files /dev/null and b/Resources/Sprites/GHZ/Newtron.bin differ diff --git a/Resources/Sprites/GHZ/Objects.gif b/Resources/Sprites/GHZ/Objects.gif new file mode 100644 index 0000000..b9bf7ed Binary files /dev/null and b/Resources/Sprites/GHZ/Objects.gif differ diff --git a/Resources/Sprites/GHZ/Objects2.gif b/Resources/Sprites/GHZ/Objects2.gif new file mode 100644 index 0000000..a07bff9 Binary files /dev/null and b/Resources/Sprites/GHZ/Objects2.gif differ diff --git a/Resources/Sprites/GHZ/Platform.bin b/Resources/Sprites/GHZ/Platform.bin new file mode 100644 index 0000000..b7b189f Binary files /dev/null and b/Resources/Sprites/GHZ/Platform.bin differ diff --git a/Resources/Sprites/GHZ/SpikeLog.bin b/Resources/Sprites/GHZ/SpikeLog.bin new file mode 100644 index 0000000..4508e76 Binary files /dev/null and b/Resources/Sprites/GHZ/SpikeLog.bin differ diff --git a/Resources/Sprites/GHZ/Splats.bin b/Resources/Sprites/GHZ/Splats.bin new file mode 100644 index 0000000..48a2fb4 Binary files /dev/null and b/Resources/Sprites/GHZ/Splats.bin differ diff --git a/Resources/Sprites/GHZ/ZipLine.bin b/Resources/Sprites/GHZ/ZipLine.bin new file mode 100644 index 0000000..9a6d998 Binary files /dev/null and b/Resources/Sprites/GHZ/ZipLine.bin differ diff --git a/Resources/Sprites/Global/Animals.bin b/Resources/Sprites/Global/Animals.bin new file mode 100644 index 0000000..d836514 Binary files /dev/null and b/Resources/Sprites/Global/Animals.bin differ diff --git a/Resources/Sprites/Global/Animals.gif b/Resources/Sprites/Global/Animals.gif new file mode 100644 index 0000000..33e5a4a Binary files /dev/null and b/Resources/Sprites/Global/Animals.gif differ diff --git a/Resources/Sprites/Global/Announcer.bin b/Resources/Sprites/Global/Announcer.bin new file mode 100644 index 0000000..df0ab99 Binary files /dev/null and b/Resources/Sprites/Global/Announcer.bin differ diff --git a/Resources/Sprites/Global/Display.gif b/Resources/Sprites/Global/Display.gif new file mode 100644 index 0000000..3ca9796 Binary files /dev/null and b/Resources/Sprites/Global/Display.gif differ diff --git a/Resources/Sprites/Global/Dust.bin b/Resources/Sprites/Global/Dust.bin new file mode 100644 index 0000000..8ed68e7 Binary files /dev/null and b/Resources/Sprites/Global/Dust.bin differ diff --git a/Resources/Sprites/Global/EggPrison.bin b/Resources/Sprites/Global/EggPrison.bin new file mode 100644 index 0000000..0db64b5 Binary files /dev/null and b/Resources/Sprites/Global/EggPrison.bin differ diff --git a/Resources/Sprites/Global/Explosions.bin b/Resources/Sprites/Global/Explosions.bin new file mode 100644 index 0000000..1a86da4 Binary files /dev/null and b/Resources/Sprites/Global/Explosions.bin differ diff --git a/Resources/Sprites/Global/Explosions.gif b/Resources/Sprites/Global/Explosions.gif new file mode 100644 index 0000000..93cd6c7 Binary files /dev/null and b/Resources/Sprites/Global/Explosions.gif differ diff --git a/Resources/Sprites/Global/HUD.bin b/Resources/Sprites/Global/HUD.bin new file mode 100644 index 0000000..38e719f Binary files /dev/null and b/Resources/Sprites/Global/HUD.bin differ diff --git a/Resources/Sprites/Global/Invincible.bin b/Resources/Sprites/Global/Invincible.bin new file mode 100644 index 0000000..b9efb9d Binary files /dev/null and b/Resources/Sprites/Global/Invincible.bin differ diff --git a/Resources/Sprites/Global/ItemBox.bin b/Resources/Sprites/Global/ItemBox.bin new file mode 100644 index 0000000..bacea1f Binary files /dev/null and b/Resources/Sprites/Global/ItemBox.bin differ diff --git a/Resources/Sprites/Global/Items.gif b/Resources/Sprites/Global/Items.gif new file mode 100644 index 0000000..9a8578c Binary files /dev/null and b/Resources/Sprites/Global/Items.gif differ diff --git a/Resources/Sprites/Global/Mobile Buttons.bin b/Resources/Sprites/Global/Mobile Buttons.bin new file mode 100644 index 0000000..2da84cb Binary files /dev/null and b/Resources/Sprites/Global/Mobile Buttons.bin differ diff --git a/Resources/Sprites/Global/Mobile Buttons.gif b/Resources/Sprites/Global/Mobile Buttons.gif new file mode 100644 index 0000000..8102381 Binary files /dev/null and b/Resources/Sprites/Global/Mobile Buttons.gif differ diff --git a/Resources/Sprites/Global/Objects.gif b/Resources/Sprites/Global/Objects.gif new file mode 100644 index 0000000..80990b2 Binary files /dev/null and b/Resources/Sprites/Global/Objects.gif differ diff --git a/Resources/Sprites/Global/Objects2.gif b/Resources/Sprites/Global/Objects2.gif new file mode 100644 index 0000000..d10a25a Binary files /dev/null and b/Resources/Sprites/Global/Objects2.gif differ diff --git a/Resources/Sprites/Global/Objects3.gif b/Resources/Sprites/Global/Objects3.gif new file mode 100644 index 0000000..9c0dac3 Binary files /dev/null and b/Resources/Sprites/Global/Objects3.gif differ diff --git a/Resources/Sprites/Global/Pause.bin b/Resources/Sprites/Global/Pause.bin new file mode 100644 index 0000000..95c2309 Binary files /dev/null and b/Resources/Sprites/Global/Pause.bin differ diff --git a/Resources/Sprites/Global/Pause.gif b/Resources/Sprites/Global/Pause.gif new file mode 100644 index 0000000..67159aa Binary files /dev/null and b/Resources/Sprites/Global/Pause.gif differ diff --git a/Resources/Sprites/Global/PhantomRuby.bin b/Resources/Sprites/Global/PhantomRuby.bin new file mode 100644 index 0000000..8bb1e99 Binary files /dev/null and b/Resources/Sprites/Global/PhantomRuby.bin differ diff --git a/Resources/Sprites/Global/PhantomRuby.gif b/Resources/Sprites/Global/PhantomRuby.gif new file mode 100644 index 0000000..e07ea2c Binary files /dev/null and b/Resources/Sprites/Global/PhantomRuby.gif differ diff --git a/Resources/Sprites/Global/PlaneSwitch.bin b/Resources/Sprites/Global/PlaneSwitch.bin new file mode 100644 index 0000000..d6ad86f Binary files /dev/null and b/Resources/Sprites/Global/PlaneSwitch.bin differ diff --git a/Resources/Sprites/Global/Ring.bin b/Resources/Sprites/Global/Ring.bin new file mode 100644 index 0000000..aff5653 Binary files /dev/null and b/Resources/Sprites/Global/Ring.bin differ diff --git a/Resources/Sprites/Global/ScoreBonus.bin b/Resources/Sprites/Global/ScoreBonus.bin new file mode 100644 index 0000000..627f810 Binary files /dev/null and b/Resources/Sprites/Global/ScoreBonus.bin differ diff --git a/Resources/Sprites/Global/Shields.bin b/Resources/Sprites/Global/Shields.bin new file mode 100644 index 0000000..d312620 Binary files /dev/null and b/Resources/Sprites/Global/Shields.bin differ diff --git a/Resources/Sprites/Global/Shields.gif b/Resources/Sprites/Global/Shields.gif new file mode 100644 index 0000000..fda54fc Binary files /dev/null and b/Resources/Sprites/Global/Shields.gif differ diff --git a/Resources/Sprites/Global/ShieldsOld.bin b/Resources/Sprites/Global/ShieldsOld.bin new file mode 100644 index 0000000..860d4dc Binary files /dev/null and b/Resources/Sprites/Global/ShieldsOld.bin differ diff --git a/Resources/Sprites/Global/ShieldsOld.gif b/Resources/Sprites/Global/ShieldsOld.gif new file mode 100644 index 0000000..bd8d518 Binary files /dev/null and b/Resources/Sprites/Global/ShieldsOld.gif differ diff --git a/Resources/Sprites/Global/SignPost.bin b/Resources/Sprites/Global/SignPost.bin new file mode 100644 index 0000000..dc17ed8 Binary files /dev/null and b/Resources/Sprites/Global/SignPost.bin differ diff --git a/Resources/Sprites/Global/SpecialRing.bin b/Resources/Sprites/Global/SpecialRing.bin new file mode 100644 index 0000000..37c9b84 Binary files /dev/null and b/Resources/Sprites/Global/SpecialRing.bin differ diff --git a/Resources/Sprites/Global/SpeedGate.bin b/Resources/Sprites/Global/SpeedGate.bin new file mode 100644 index 0000000..343bbd9 Binary files /dev/null and b/Resources/Sprites/Global/SpeedGate.bin differ diff --git a/Resources/Sprites/Global/Spikes.bin b/Resources/Sprites/Global/Spikes.bin new file mode 100644 index 0000000..f220bad Binary files /dev/null and b/Resources/Sprites/Global/Spikes.bin differ diff --git a/Resources/Sprites/Global/Springs.bin b/Resources/Sprites/Global/Springs.bin new file mode 100644 index 0000000..8a25f1b Binary files /dev/null and b/Resources/Sprites/Global/Springs.bin differ diff --git a/Resources/Sprites/Global/StarPost.bin b/Resources/Sprites/Global/StarPost.bin new file mode 100644 index 0000000..76dbe91 Binary files /dev/null and b/Resources/Sprites/Global/StarPost.bin differ diff --git a/Resources/Sprites/Global/SuperButtons.bin b/Resources/Sprites/Global/SuperButtons.bin new file mode 100644 index 0000000..6d5b21c Binary files /dev/null and b/Resources/Sprites/Global/SuperButtons.bin differ diff --git a/Resources/Sprites/Global/SuperButtons.gif b/Resources/Sprites/Global/SuperButtons.gif new file mode 100644 index 0000000..4dfedf9 Binary files /dev/null and b/Resources/Sprites/Global/SuperButtons.gif differ diff --git a/Resources/Sprites/Global/SuperSparkle.bin b/Resources/Sprites/Global/SuperSparkle.bin new file mode 100644 index 0000000..3a5d6bc Binary files /dev/null and b/Resources/Sprites/Global/SuperSparkle.bin differ diff --git a/Resources/Sprites/Global/TicMark.bin b/Resources/Sprites/Global/TicMark.bin new file mode 100644 index 0000000..b7a8799 Binary files /dev/null and b/Resources/Sprites/Global/TicMark.bin differ diff --git a/Resources/Sprites/Global/TitleCard.bin b/Resources/Sprites/Global/TitleCard.bin new file mode 100644 index 0000000..28ded8d Binary files /dev/null and b/Resources/Sprites/Global/TitleCard.bin differ diff --git a/Resources/Sprites/Global/TitleCardAltered.bin b/Resources/Sprites/Global/TitleCardAltered.bin new file mode 100644 index 0000000..b46b358 Binary files /dev/null and b/Resources/Sprites/Global/TitleCardAltered.bin differ diff --git a/Resources/Sprites/Global/Water.bin b/Resources/Sprites/Global/Water.bin new file mode 100644 index 0000000..d04c84c Binary files /dev/null and b/Resources/Sprites/Global/Water.bin differ diff --git a/Resources/Sprites/Global/Water.gif b/Resources/Sprites/Global/Water.gif new file mode 100644 index 0000000..5960100 Binary files /dev/null and b/Resources/Sprites/Global/Water.gif differ diff --git a/Resources/Sprites/LSelect/Icons.bin b/Resources/Sprites/LSelect/Icons.bin new file mode 100644 index 0000000..9738bd9 Binary files /dev/null and b/Resources/Sprites/LSelect/Icons.bin differ diff --git a/Resources/Sprites/LSelect/Objects.gif b/Resources/Sprites/LSelect/Objects.gif new file mode 100644 index 0000000..0365737 Binary files /dev/null and b/Resources/Sprites/LSelect/Objects.gif differ diff --git a/Resources/Sprites/LSelect/Text.bin b/Resources/Sprites/LSelect/Text.bin new file mode 100644 index 0000000..82e36e8 Binary files /dev/null and b/Resources/Sprites/LSelect/Text.bin differ diff --git a/Resources/Sprites/Players/CTailSprite.bin b/Resources/Sprites/Players/CTailSprite.bin new file mode 100644 index 0000000..90dfeae Binary files /dev/null and b/Resources/Sprites/Players/CTailSprite.bin differ diff --git a/Resources/Sprites/Players/ChibiKnux.bin b/Resources/Sprites/Players/ChibiKnux.bin new file mode 100644 index 0000000..1dc4ce8 Binary files /dev/null and b/Resources/Sprites/Players/ChibiKnux.bin differ diff --git a/Resources/Sprites/Players/ChibiKnux.gif b/Resources/Sprites/Players/ChibiKnux.gif new file mode 100644 index 0000000..ec59a14 Binary files /dev/null and b/Resources/Sprites/Players/ChibiKnux.gif differ diff --git a/Resources/Sprites/Players/ChibiKnux2.gif b/Resources/Sprites/Players/ChibiKnux2.gif new file mode 100644 index 0000000..f956639 Binary files /dev/null and b/Resources/Sprites/Players/ChibiKnux2.gif differ diff --git a/Resources/Sprites/Players/ChibiMighty.bin b/Resources/Sprites/Players/ChibiMighty.bin new file mode 100644 index 0000000..870e4d8 Binary files /dev/null and b/Resources/Sprites/Players/ChibiMighty.bin differ diff --git a/Resources/Sprites/Players/ChibiMighty.gif b/Resources/Sprites/Players/ChibiMighty.gif new file mode 100644 index 0000000..008c266 Binary files /dev/null and b/Resources/Sprites/Players/ChibiMighty.gif differ diff --git a/Resources/Sprites/Players/ChibiMighty2.gif b/Resources/Sprites/Players/ChibiMighty2.gif new file mode 100644 index 0000000..f956639 Binary files /dev/null and b/Resources/Sprites/Players/ChibiMighty2.gif differ diff --git a/Resources/Sprites/Players/ChibiRay.bin b/Resources/Sprites/Players/ChibiRay.bin new file mode 100644 index 0000000..5e6d7c8 Binary files /dev/null and b/Resources/Sprites/Players/ChibiRay.bin differ diff --git a/Resources/Sprites/Players/ChibiRay.gif b/Resources/Sprites/Players/ChibiRay.gif new file mode 100644 index 0000000..2f18128 Binary files /dev/null and b/Resources/Sprites/Players/ChibiRay.gif differ diff --git a/Resources/Sprites/Players/ChibiRay2.gif b/Resources/Sprites/Players/ChibiRay2.gif new file mode 100644 index 0000000..3ed0bed Binary files /dev/null and b/Resources/Sprites/Players/ChibiRay2.gif differ diff --git a/Resources/Sprites/Players/ChibiSonic.bin b/Resources/Sprites/Players/ChibiSonic.bin new file mode 100644 index 0000000..efc9095 Binary files /dev/null and b/Resources/Sprites/Players/ChibiSonic.bin differ diff --git a/Resources/Sprites/Players/ChibiSonic.gif b/Resources/Sprites/Players/ChibiSonic.gif new file mode 100644 index 0000000..1cb1aa7 Binary files /dev/null and b/Resources/Sprites/Players/ChibiSonic.gif differ diff --git a/Resources/Sprites/Players/ChibiTails.bin b/Resources/Sprites/Players/ChibiTails.bin new file mode 100644 index 0000000..fb306dc Binary files /dev/null and b/Resources/Sprites/Players/ChibiTails.bin differ diff --git a/Resources/Sprites/Players/ChibiTails.gif b/Resources/Sprites/Players/ChibiTails.gif new file mode 100644 index 0000000..4ce390c Binary files /dev/null and b/Resources/Sprites/Players/ChibiTails.gif differ diff --git a/Resources/Sprites/Players/ChibiTails2.gif b/Resources/Sprites/Players/ChibiTails2.gif new file mode 100644 index 0000000..0e1436e Binary files /dev/null and b/Resources/Sprites/Players/ChibiTails2.gif differ diff --git a/Resources/Sprites/Players/Continue.bin b/Resources/Sprites/Players/Continue.bin new file mode 100644 index 0000000..aa201c8 Binary files /dev/null and b/Resources/Sprites/Players/Continue.bin differ diff --git a/Resources/Sprites/Players/Continue.gif b/Resources/Sprites/Players/Continue.gif new file mode 100644 index 0000000..ee90e2f Binary files /dev/null and b/Resources/Sprites/Players/Continue.gif differ diff --git a/Resources/Sprites/Players/Continue2.gif b/Resources/Sprites/Players/Continue2.gif new file mode 100644 index 0000000..56abdf0 Binary files /dev/null and b/Resources/Sprites/Players/Continue2.gif differ diff --git a/Resources/Sprites/Players/CutsceneCPZ.bin b/Resources/Sprites/Players/CutsceneCPZ.bin new file mode 100644 index 0000000..86d8bde Binary files /dev/null and b/Resources/Sprites/Players/CutsceneCPZ.bin differ diff --git a/Resources/Sprites/Players/CutsceneTMZ.gif b/Resources/Sprites/Players/CutsceneTMZ.gif new file mode 100644 index 0000000..8ec4c3f Binary files /dev/null and b/Resources/Sprites/Players/CutsceneTMZ.gif differ diff --git a/Resources/Sprites/Players/Knux.bin b/Resources/Sprites/Players/Knux.bin new file mode 100644 index 0000000..bac94b8 Binary files /dev/null and b/Resources/Sprites/Players/Knux.bin differ diff --git a/Resources/Sprites/Players/Knux1.gif b/Resources/Sprites/Players/Knux1.gif new file mode 100644 index 0000000..a6c244c Binary files /dev/null and b/Resources/Sprites/Players/Knux1.gif differ diff --git a/Resources/Sprites/Players/Knux2.gif b/Resources/Sprites/Players/Knux2.gif new file mode 100644 index 0000000..7f5f252 Binary files /dev/null and b/Resources/Sprites/Players/Knux2.gif differ diff --git a/Resources/Sprites/Players/Knux3.gif b/Resources/Sprites/Players/Knux3.gif new file mode 100644 index 0000000..bb70139 Binary files /dev/null and b/Resources/Sprites/Players/Knux3.gif differ diff --git a/Resources/Sprites/Players/KnuxCutsceneAIZ.bin b/Resources/Sprites/Players/KnuxCutsceneAIZ.bin new file mode 100644 index 0000000..7c92d68 Binary files /dev/null and b/Resources/Sprites/Players/KnuxCutsceneAIZ.bin differ diff --git a/Resources/Sprites/Players/KnuxCutsceneAIZ.gif b/Resources/Sprites/Players/KnuxCutsceneAIZ.gif new file mode 100644 index 0000000..ef7b86d Binary files /dev/null and b/Resources/Sprites/Players/KnuxCutsceneAIZ.gif differ diff --git a/Resources/Sprites/Players/KnuxCutsceneCPZ.gif b/Resources/Sprites/Players/KnuxCutsceneCPZ.gif new file mode 100644 index 0000000..abc1cf7 Binary files /dev/null and b/Resources/Sprites/Players/KnuxCutsceneCPZ.gif differ diff --git a/Resources/Sprites/Players/KnuxCutsceneHPZ.bin b/Resources/Sprites/Players/KnuxCutsceneHPZ.bin new file mode 100644 index 0000000..2668aa1 Binary files /dev/null and b/Resources/Sprites/Players/KnuxCutsceneHPZ.bin differ diff --git a/Resources/Sprites/Players/KnuxCutsceneHPZ.gif b/Resources/Sprites/Players/KnuxCutsceneHPZ.gif new file mode 100644 index 0000000..36ae22f Binary files /dev/null and b/Resources/Sprites/Players/KnuxCutsceneHPZ.gif differ diff --git a/Resources/Sprites/Players/Mighty.bin b/Resources/Sprites/Players/Mighty.bin new file mode 100644 index 0000000..f2de070 Binary files /dev/null and b/Resources/Sprites/Players/Mighty.bin differ diff --git a/Resources/Sprites/Players/Mighty1.gif b/Resources/Sprites/Players/Mighty1.gif new file mode 100644 index 0000000..2186761 Binary files /dev/null and b/Resources/Sprites/Players/Mighty1.gif differ diff --git a/Resources/Sprites/Players/Mighty2.gif b/Resources/Sprites/Players/Mighty2.gif new file mode 100644 index 0000000..4ac515b Binary files /dev/null and b/Resources/Sprites/Players/Mighty2.gif differ diff --git a/Resources/Sprites/Players/Mighty3.gif b/Resources/Sprites/Players/Mighty3.gif new file mode 100644 index 0000000..1913841 Binary files /dev/null and b/Resources/Sprites/Players/Mighty3.gif differ diff --git a/Resources/Sprites/Players/MightyCutsceneCPZ.gif b/Resources/Sprites/Players/MightyCutsceneCPZ.gif new file mode 100644 index 0000000..b858f14 Binary files /dev/null and b/Resources/Sprites/Players/MightyCutsceneCPZ.gif differ diff --git a/Resources/Sprites/Players/Ray.bin b/Resources/Sprites/Players/Ray.bin new file mode 100644 index 0000000..03141e0 Binary files /dev/null and b/Resources/Sprites/Players/Ray.bin differ diff --git a/Resources/Sprites/Players/Ray1.gif b/Resources/Sprites/Players/Ray1.gif new file mode 100644 index 0000000..8b87f70 Binary files /dev/null and b/Resources/Sprites/Players/Ray1.gif differ diff --git a/Resources/Sprites/Players/Ray2.gif b/Resources/Sprites/Players/Ray2.gif new file mode 100644 index 0000000..21e23e5 Binary files /dev/null and b/Resources/Sprites/Players/Ray2.gif differ diff --git a/Resources/Sprites/Players/Ray3.gif b/Resources/Sprites/Players/Ray3.gif new file mode 100644 index 0000000..52838d6 Binary files /dev/null and b/Resources/Sprites/Players/Ray3.gif differ diff --git a/Resources/Sprites/Players/RayCutsceneCPZ.gif b/Resources/Sprites/Players/RayCutsceneCPZ.gif new file mode 100644 index 0000000..8c65a67 Binary files /dev/null and b/Resources/Sprites/Players/RayCutsceneCPZ.gif differ diff --git a/Resources/Sprites/Players/Sonic.bin b/Resources/Sprites/Players/Sonic.bin new file mode 100644 index 0000000..732e7ae Binary files /dev/null and b/Resources/Sprites/Players/Sonic.bin differ diff --git a/Resources/Sprites/Players/Sonic1.gif b/Resources/Sprites/Players/Sonic1.gif new file mode 100644 index 0000000..d66691d Binary files /dev/null and b/Resources/Sprites/Players/Sonic1.gif differ diff --git a/Resources/Sprites/Players/Sonic2.gif b/Resources/Sprites/Players/Sonic2.gif new file mode 100644 index 0000000..e4639a4 Binary files /dev/null and b/Resources/Sprites/Players/Sonic2.gif differ diff --git a/Resources/Sprites/Players/Sonic3.gif b/Resources/Sprites/Players/Sonic3.gif new file mode 100644 index 0000000..203a443 Binary files /dev/null and b/Resources/Sprites/Players/Sonic3.gif differ diff --git a/Resources/Sprites/Players/Sonic4.gif b/Resources/Sprites/Players/Sonic4.gif new file mode 100644 index 0000000..e103794 Binary files /dev/null and b/Resources/Sprites/Players/Sonic4.gif differ diff --git a/Resources/Sprites/Players/SonicCutsceneCPZ.gif b/Resources/Sprites/Players/SonicCutsceneCPZ.gif new file mode 100644 index 0000000..d1d5309 Binary files /dev/null and b/Resources/Sprites/Players/SonicCutsceneCPZ.gif differ diff --git a/Resources/Sprites/Players/SuperSonic.bin b/Resources/Sprites/Players/SuperSonic.bin new file mode 100644 index 0000000..bdfecab Binary files /dev/null and b/Resources/Sprites/Players/SuperSonic.bin differ diff --git a/Resources/Sprites/Players/TailSprite.bin b/Resources/Sprites/Players/TailSprite.bin new file mode 100644 index 0000000..93ae86b Binary files /dev/null and b/Resources/Sprites/Players/TailSprite.bin differ diff --git a/Resources/Sprites/Players/Tails.bin b/Resources/Sprites/Players/Tails.bin new file mode 100644 index 0000000..9c298ea Binary files /dev/null and b/Resources/Sprites/Players/Tails.bin differ diff --git a/Resources/Sprites/Players/Tails1.gif b/Resources/Sprites/Players/Tails1.gif new file mode 100644 index 0000000..183d620 Binary files /dev/null and b/Resources/Sprites/Players/Tails1.gif differ diff --git a/Resources/Sprites/Players/Tails2.gif b/Resources/Sprites/Players/Tails2.gif new file mode 100644 index 0000000..b4d7d3b Binary files /dev/null and b/Resources/Sprites/Players/Tails2.gif differ diff --git a/Resources/Sprites/Players/Tails3.gif b/Resources/Sprites/Players/Tails3.gif new file mode 100644 index 0000000..0b82287 Binary files /dev/null and b/Resources/Sprites/Players/Tails3.gif differ diff --git a/Resources/Sprites/Players/TailsCutsceneCPZ.gif b/Resources/Sprites/Players/TailsCutsceneCPZ.gif new file mode 100644 index 0000000..d96143c Binary files /dev/null and b/Resources/Sprites/Players/TailsCutsceneCPZ.gif differ diff --git a/Resources/Sprites/UI/ButtonLabel.bin b/Resources/Sprites/UI/ButtonLabel.bin new file mode 100644 index 0000000..d364c2d Binary files /dev/null and b/Resources/Sprites/UI/ButtonLabel.bin differ diff --git a/Resources/Sprites/UI/Buttons.bin b/Resources/Sprites/UI/Buttons.bin new file mode 100644 index 0000000..5e4ea25 Binary files /dev/null and b/Resources/Sprites/UI/Buttons.bin differ diff --git a/Resources/Sprites/UI/Buttons.gif b/Resources/Sprites/UI/Buttons.gif new file mode 100644 index 0000000..ab69d9e Binary files /dev/null and b/Resources/Sprites/UI/Buttons.gif differ diff --git a/Resources/Sprites/UI/Controllers.gif b/Resources/Sprites/UI/Controllers.gif new file mode 100644 index 0000000..743499b Binary files /dev/null and b/Resources/Sprites/UI/Controllers.gif differ diff --git a/Resources/Sprites/UI/CreditsText.bin b/Resources/Sprites/UI/CreditsText.bin new file mode 100644 index 0000000..6a34d3b Binary files /dev/null and b/Resources/Sprites/UI/CreditsText.bin differ diff --git a/Resources/Sprites/UI/CreditsText.gif b/Resources/Sprites/UI/CreditsText.gif new file mode 100644 index 0000000..245dfd1 Binary files /dev/null and b/Resources/Sprites/UI/CreditsText.gif differ diff --git a/Resources/Sprites/UI/DAGarden.bin b/Resources/Sprites/UI/DAGarden.bin new file mode 100644 index 0000000..b906aca Binary files /dev/null and b/Resources/Sprites/UI/DAGarden.bin differ diff --git a/Resources/Sprites/UI/DAGarden.gif b/Resources/Sprites/UI/DAGarden.gif new file mode 100644 index 0000000..150e443 Binary files /dev/null and b/Resources/Sprites/UI/DAGarden.gif differ diff --git a/Resources/Sprites/UI/Diorama.bin b/Resources/Sprites/UI/Diorama.bin new file mode 100644 index 0000000..eacd88f Binary files /dev/null and b/Resources/Sprites/UI/Diorama.bin differ diff --git a/Resources/Sprites/UI/Diorama.gif b/Resources/Sprites/UI/Diorama.gif new file mode 100644 index 0000000..6b8a0e6 Binary files /dev/null and b/Resources/Sprites/UI/Diorama.gif differ diff --git a/Resources/Sprites/UI/Diorama2.gif b/Resources/Sprites/UI/Diorama2.gif new file mode 100644 index 0000000..b6431d9 Binary files /dev/null and b/Resources/Sprites/UI/Diorama2.gif differ diff --git a/Resources/Sprites/UI/HeadingsEN.bin b/Resources/Sprites/UI/HeadingsEN.bin new file mode 100644 index 0000000..b82662e Binary files /dev/null and b/Resources/Sprites/UI/HeadingsEN.bin differ diff --git a/Resources/Sprites/UI/HeadingsEN.gif b/Resources/Sprites/UI/HeadingsEN.gif new file mode 100644 index 0000000..d7ac108 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsEN.gif differ diff --git a/Resources/Sprites/UI/HeadingsFR.bin b/Resources/Sprites/UI/HeadingsFR.bin new file mode 100644 index 0000000..1734452 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsFR.bin differ diff --git a/Resources/Sprites/UI/HeadingsFR.gif b/Resources/Sprites/UI/HeadingsFR.gif new file mode 100644 index 0000000..215f2ab Binary files /dev/null and b/Resources/Sprites/UI/HeadingsFR.gif differ diff --git a/Resources/Sprites/UI/HeadingsGE.bin b/Resources/Sprites/UI/HeadingsGE.bin new file mode 100644 index 0000000..ac23ff0 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsGE.bin differ diff --git a/Resources/Sprites/UI/HeadingsGE.gif b/Resources/Sprites/UI/HeadingsGE.gif new file mode 100644 index 0000000..6e06d97 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsGE.gif differ diff --git a/Resources/Sprites/UI/HeadingsIT.bin b/Resources/Sprites/UI/HeadingsIT.bin new file mode 100644 index 0000000..b92ff2c Binary files /dev/null and b/Resources/Sprites/UI/HeadingsIT.bin differ diff --git a/Resources/Sprites/UI/HeadingsIT.gif b/Resources/Sprites/UI/HeadingsIT.gif new file mode 100644 index 0000000..249b26a Binary files /dev/null and b/Resources/Sprites/UI/HeadingsIT.gif differ diff --git a/Resources/Sprites/UI/HeadingsJP.bin b/Resources/Sprites/UI/HeadingsJP.bin new file mode 100644 index 0000000..85a02e5 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsJP.bin differ diff --git a/Resources/Sprites/UI/HeadingsJP.gif b/Resources/Sprites/UI/HeadingsJP.gif new file mode 100644 index 0000000..4f0432e Binary files /dev/null and b/Resources/Sprites/UI/HeadingsJP.gif differ diff --git a/Resources/Sprites/UI/HeadingsKO.bin b/Resources/Sprites/UI/HeadingsKO.bin new file mode 100644 index 0000000..9f22abb Binary files /dev/null and b/Resources/Sprites/UI/HeadingsKO.bin differ diff --git a/Resources/Sprites/UI/HeadingsKO.gif b/Resources/Sprites/UI/HeadingsKO.gif new file mode 100644 index 0000000..a4062c9 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsKO.gif differ diff --git a/Resources/Sprites/UI/HeadingsSC.bin b/Resources/Sprites/UI/HeadingsSC.bin new file mode 100644 index 0000000..687be5c Binary files /dev/null and b/Resources/Sprites/UI/HeadingsSC.bin differ diff --git a/Resources/Sprites/UI/HeadingsSC.gif b/Resources/Sprites/UI/HeadingsSC.gif new file mode 100644 index 0000000..3b296b8 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsSC.gif differ diff --git a/Resources/Sprites/UI/HeadingsSP.bin b/Resources/Sprites/UI/HeadingsSP.bin new file mode 100644 index 0000000..8245250 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsSP.bin differ diff --git a/Resources/Sprites/UI/HeadingsSP.gif b/Resources/Sprites/UI/HeadingsSP.gif new file mode 100644 index 0000000..dbecc41 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsSP.gif differ diff --git a/Resources/Sprites/UI/HeadingsTC.bin b/Resources/Sprites/UI/HeadingsTC.bin new file mode 100644 index 0000000..6e86989 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsTC.bin differ diff --git a/Resources/Sprites/UI/HeadingsTC.gif b/Resources/Sprites/UI/HeadingsTC.gif new file mode 100644 index 0000000..611e4b2 Binary files /dev/null and b/Resources/Sprites/UI/HeadingsTC.gif differ diff --git a/Resources/Sprites/UI/MainIcons.bin b/Resources/Sprites/UI/MainIcons.bin new file mode 100644 index 0000000..6dd36e4 Binary files /dev/null and b/Resources/Sprites/UI/MainIcons.bin differ diff --git a/Resources/Sprites/UI/MainIcons.gif b/Resources/Sprites/UI/MainIcons.gif new file mode 100644 index 0000000..62e10ee Binary files /dev/null and b/Resources/Sprites/UI/MainIcons.gif differ diff --git a/Resources/Sprites/UI/MedallionPanel.bin b/Resources/Sprites/UI/MedallionPanel.bin new file mode 100644 index 0000000..3251647 Binary files /dev/null and b/Resources/Sprites/UI/MedallionPanel.bin differ diff --git a/Resources/Sprites/UI/PauseEN.gif b/Resources/Sprites/UI/PauseEN.gif new file mode 100644 index 0000000..6a85709 Binary files /dev/null and b/Resources/Sprites/UI/PauseEN.gif differ diff --git a/Resources/Sprites/UI/PauseEN_old.gif b/Resources/Sprites/UI/PauseEN_old.gif new file mode 100644 index 0000000..5a3b02f Binary files /dev/null and b/Resources/Sprites/UI/PauseEN_old.gif differ diff --git a/Resources/Sprites/UI/PauseFR.gif b/Resources/Sprites/UI/PauseFR.gif new file mode 100644 index 0000000..bf0c0f7 Binary files /dev/null and b/Resources/Sprites/UI/PauseFR.gif differ diff --git a/Resources/Sprites/UI/PauseGE.gif b/Resources/Sprites/UI/PauseGE.gif new file mode 100644 index 0000000..453e684 Binary files /dev/null and b/Resources/Sprites/UI/PauseGE.gif differ diff --git a/Resources/Sprites/UI/PauseIT.gif b/Resources/Sprites/UI/PauseIT.gif new file mode 100644 index 0000000..6e9eaac Binary files /dev/null and b/Resources/Sprites/UI/PauseIT.gif differ diff --git a/Resources/Sprites/UI/PauseJP.gif b/Resources/Sprites/UI/PauseJP.gif new file mode 100644 index 0000000..379ea16 Binary files /dev/null and b/Resources/Sprites/UI/PauseJP.gif differ diff --git a/Resources/Sprites/UI/PauseKO.gif b/Resources/Sprites/UI/PauseKO.gif new file mode 100644 index 0000000..0b48990 Binary files /dev/null and b/Resources/Sprites/UI/PauseKO.gif differ diff --git a/Resources/Sprites/UI/PauseSC.gif b/Resources/Sprites/UI/PauseSC.gif new file mode 100644 index 0000000..05209cf Binary files /dev/null and b/Resources/Sprites/UI/PauseSC.gif differ diff --git a/Resources/Sprites/UI/PauseSP.gif b/Resources/Sprites/UI/PauseSP.gif new file mode 100644 index 0000000..b0dc12b Binary files /dev/null and b/Resources/Sprites/UI/PauseSP.gif differ diff --git a/Resources/Sprites/UI/PauseTC.gif b/Resources/Sprites/UI/PauseTC.gif new file mode 100644 index 0000000..01a2c0d Binary files /dev/null and b/Resources/Sprites/UI/PauseTC.gif differ diff --git a/Resources/Sprites/UI/Picture.bin b/Resources/Sprites/UI/Picture.bin new file mode 100644 index 0000000..f55a663 Binary files /dev/null and b/Resources/Sprites/UI/Picture.bin differ diff --git a/Resources/Sprites/UI/SaveSelect.bin b/Resources/Sprites/UI/SaveSelect.bin new file mode 100644 index 0000000..a1c8263 Binary files /dev/null and b/Resources/Sprites/UI/SaveSelect.bin differ diff --git a/Resources/Sprites/UI/SaveSelectEN.gif b/Resources/Sprites/UI/SaveSelectEN.gif new file mode 100644 index 0000000..6471025 Binary files /dev/null and b/Resources/Sprites/UI/SaveSelectEN.gif differ diff --git a/Resources/Sprites/UI/SaveSelect_old.gif b/Resources/Sprites/UI/SaveSelect_old.gif new file mode 100644 index 0000000..e0776ab Binary files /dev/null and b/Resources/Sprites/UI/SaveSelect_old.gif differ diff --git a/Resources/Sprites/UI/SmallFont.bin b/Resources/Sprites/UI/SmallFont.bin new file mode 100644 index 0000000..42f7d27 Binary files /dev/null and b/Resources/Sprites/UI/SmallFont.bin differ diff --git a/Resources/Sprites/UI/SmallFont1.gif b/Resources/Sprites/UI/SmallFont1.gif new file mode 100644 index 0000000..a8abfdf Binary files /dev/null and b/Resources/Sprites/UI/SmallFont1.gif differ diff --git a/Resources/Sprites/UI/SmallFont2.gif b/Resources/Sprites/UI/SmallFont2.gif new file mode 100644 index 0000000..6a68e4b Binary files /dev/null and b/Resources/Sprites/UI/SmallFont2.gif differ diff --git a/Resources/Sprites/UI/TextEN.bin b/Resources/Sprites/UI/TextEN.bin new file mode 100644 index 0000000..0074d92 Binary files /dev/null and b/Resources/Sprites/UI/TextEN.bin differ diff --git a/Resources/Sprites/UI/TextEN.gif b/Resources/Sprites/UI/TextEN.gif new file mode 100644 index 0000000..642573e Binary files /dev/null and b/Resources/Sprites/UI/TextEN.gif differ diff --git a/Resources/Sprites/UI/TextEN_old.bin b/Resources/Sprites/UI/TextEN_old.bin new file mode 100644 index 0000000..a1ae298 Binary files /dev/null and b/Resources/Sprites/UI/TextEN_old.bin differ diff --git a/Resources/Sprites/UI/TextEN_old.gif b/Resources/Sprites/UI/TextEN_old.gif new file mode 100644 index 0000000..295f8a6 Binary files /dev/null and b/Resources/Sprites/UI/TextEN_old.gif differ diff --git a/Resources/Sprites/UI/TextFR.bin b/Resources/Sprites/UI/TextFR.bin new file mode 100644 index 0000000..e2a1a31 Binary files /dev/null and b/Resources/Sprites/UI/TextFR.bin differ diff --git a/Resources/Sprites/UI/TextFR.gif b/Resources/Sprites/UI/TextFR.gif new file mode 100644 index 0000000..ce0ea2a Binary files /dev/null and b/Resources/Sprites/UI/TextFR.gif differ diff --git a/Resources/Sprites/UI/TextGE.bin b/Resources/Sprites/UI/TextGE.bin new file mode 100644 index 0000000..a68d0bf Binary files /dev/null and b/Resources/Sprites/UI/TextGE.bin differ diff --git a/Resources/Sprites/UI/TextGE.gif b/Resources/Sprites/UI/TextGE.gif new file mode 100644 index 0000000..2f1d34c Binary files /dev/null and b/Resources/Sprites/UI/TextGE.gif differ diff --git a/Resources/Sprites/UI/TextIT.bin b/Resources/Sprites/UI/TextIT.bin new file mode 100644 index 0000000..30be595 Binary files /dev/null and b/Resources/Sprites/UI/TextIT.bin differ diff --git a/Resources/Sprites/UI/TextIT.gif b/Resources/Sprites/UI/TextIT.gif new file mode 100644 index 0000000..3b4900a Binary files /dev/null and b/Resources/Sprites/UI/TextIT.gif differ diff --git a/Resources/Sprites/UI/TextJP.bin b/Resources/Sprites/UI/TextJP.bin new file mode 100644 index 0000000..87a78bb Binary files /dev/null and b/Resources/Sprites/UI/TextJP.bin differ diff --git a/Resources/Sprites/UI/TextJP.gif b/Resources/Sprites/UI/TextJP.gif new file mode 100644 index 0000000..2791ae9 Binary files /dev/null and b/Resources/Sprites/UI/TextJP.gif differ diff --git a/Resources/Sprites/UI/TextKO.bin b/Resources/Sprites/UI/TextKO.bin new file mode 100644 index 0000000..d8809d4 Binary files /dev/null and b/Resources/Sprites/UI/TextKO.bin differ diff --git a/Resources/Sprites/UI/TextKO.gif b/Resources/Sprites/UI/TextKO.gif new file mode 100644 index 0000000..0f47c10 Binary files /dev/null and b/Resources/Sprites/UI/TextKO.gif differ diff --git a/Resources/Sprites/UI/TextPlusEN.gif b/Resources/Sprites/UI/TextPlusEN.gif new file mode 100644 index 0000000..47582f5 Binary files /dev/null and b/Resources/Sprites/UI/TextPlusEN.gif differ diff --git a/Resources/Sprites/UI/TextPlusFR.gif b/Resources/Sprites/UI/TextPlusFR.gif new file mode 100644 index 0000000..06975e5 Binary files /dev/null and b/Resources/Sprites/UI/TextPlusFR.gif differ diff --git a/Resources/Sprites/UI/TextPlusGE.gif b/Resources/Sprites/UI/TextPlusGE.gif new file mode 100644 index 0000000..1946a36 Binary files /dev/null and b/Resources/Sprites/UI/TextPlusGE.gif differ diff --git a/Resources/Sprites/UI/TextPlusIT.gif b/Resources/Sprites/UI/TextPlusIT.gif new file mode 100644 index 0000000..ccc42a4 Binary files /dev/null and b/Resources/Sprites/UI/TextPlusIT.gif differ diff --git a/Resources/Sprites/UI/TextPlusJP.gif b/Resources/Sprites/UI/TextPlusJP.gif new file mode 100644 index 0000000..3d67de6 Binary files /dev/null and b/Resources/Sprites/UI/TextPlusJP.gif differ diff --git a/Resources/Sprites/UI/TextPlusKO.gif b/Resources/Sprites/UI/TextPlusKO.gif new file mode 100644 index 0000000..49409ba Binary files /dev/null and b/Resources/Sprites/UI/TextPlusKO.gif differ diff --git a/Resources/Sprites/UI/TextPlusSC.gif b/Resources/Sprites/UI/TextPlusSC.gif new file mode 100644 index 0000000..b3b6982 Binary files /dev/null and b/Resources/Sprites/UI/TextPlusSC.gif differ diff --git a/Resources/Sprites/UI/TextPlusSP.gif b/Resources/Sprites/UI/TextPlusSP.gif new file mode 100644 index 0000000..033e0fd Binary files /dev/null and b/Resources/Sprites/UI/TextPlusSP.gif differ diff --git a/Resources/Sprites/UI/TextPlusTC.gif b/Resources/Sprites/UI/TextPlusTC.gif new file mode 100644 index 0000000..d6b2c47 Binary files /dev/null and b/Resources/Sprites/UI/TextPlusTC.gif differ diff --git a/Resources/Sprites/UI/TextSC.bin b/Resources/Sprites/UI/TextSC.bin new file mode 100644 index 0000000..308d8cb Binary files /dev/null and b/Resources/Sprites/UI/TextSC.bin differ diff --git a/Resources/Sprites/UI/TextSC.gif b/Resources/Sprites/UI/TextSC.gif new file mode 100644 index 0000000..b42647a Binary files /dev/null and b/Resources/Sprites/UI/TextSC.gif differ diff --git a/Resources/Sprites/UI/TextSP.bin b/Resources/Sprites/UI/TextSP.bin new file mode 100644 index 0000000..340eeee Binary files /dev/null and b/Resources/Sprites/UI/TextSP.bin differ diff --git a/Resources/Sprites/UI/TextSP.gif b/Resources/Sprites/UI/TextSP.gif new file mode 100644 index 0000000..1418e7f Binary files /dev/null and b/Resources/Sprites/UI/TextSP.gif differ diff --git a/Resources/Sprites/UI/TextTC.bin b/Resources/Sprites/UI/TextTC.bin new file mode 100644 index 0000000..387aa7a Binary files /dev/null and b/Resources/Sprites/UI/TextTC.bin differ diff --git a/Resources/Sprites/UI/TextTC.gif b/Resources/Sprites/UI/TextTC.gif new file mode 100644 index 0000000..ec65819 Binary files /dev/null and b/Resources/Sprites/UI/TextTC.gif differ diff --git a/Resources/Sprites/UI/UI.gif b/Resources/Sprites/UI/UI.gif new file mode 100644 index 0000000..3e38e87 Binary files /dev/null and b/Resources/Sprites/UI/UI.gif differ diff --git a/Resources/Sprites/UI/UIElements.bin b/Resources/Sprites/UI/UIElements.bin new file mode 100644 index 0000000..6ca7836 Binary files /dev/null and b/Resources/Sprites/UI/UIElements.bin differ diff --git a/Resources/Sprites/UI/WaitSpinner.bin b/Resources/Sprites/UI/WaitSpinner.bin new file mode 100644 index 0000000..7415fbf Binary files /dev/null and b/Resources/Sprites/UI/WaitSpinner.bin differ diff --git a/Resources/Sprites/UI/Zones.gif b/Resources/Sprites/UI/Zones.gif new file mode 100644 index 0000000..12c1d14 Binary files /dev/null and b/Resources/Sprites/UI/Zones.gif differ diff --git a/Resources/Stages/GHZ/16x16Tiles.gif b/Resources/Stages/GHZ/16x16Tiles.gif new file mode 100644 index 0000000..21c40d7 Binary files /dev/null and b/Resources/Stages/GHZ/16x16Tiles.gif differ diff --git a/Resources/Stages/GHZ/Scene1.bin b/Resources/Stages/GHZ/Scene1.bin new file mode 100644 index 0000000..0974c95 Binary files /dev/null and b/Resources/Stages/GHZ/Scene1.bin differ diff --git a/Resources/Stages/GHZ/Scene2.bin b/Resources/Stages/GHZ/Scene2.bin new file mode 100644 index 0000000..f4bc8ad Binary files /dev/null and b/Resources/Stages/GHZ/Scene2.bin differ diff --git a/Resources/Stages/GHZ/StageConfig.bin b/Resources/Stages/GHZ/StageConfig.bin new file mode 100644 index 0000000..5569ece Binary files /dev/null and b/Resources/Stages/GHZ/StageConfig.bin differ diff --git a/Resources/Stages/GHZ/TileConfig.bin b/Resources/Stages/GHZ/TileConfig.bin new file mode 100644 index 0000000..cbe4dca Binary files /dev/null and b/Resources/Stages/GHZ/TileConfig.bin differ diff --git a/Resources/Stages/LSelect/16x16Tiles.gif b/Resources/Stages/LSelect/16x16Tiles.gif new file mode 100644 index 0000000..f08590f Binary files /dev/null and b/Resources/Stages/LSelect/16x16Tiles.gif differ diff --git a/Resources/Stages/LSelect/Scene1.bin b/Resources/Stages/LSelect/Scene1.bin new file mode 100644 index 0000000..a06808d Binary files /dev/null and b/Resources/Stages/LSelect/Scene1.bin differ diff --git a/Resources/Stages/LSelect/StageConfig.bin b/Resources/Stages/LSelect/StageConfig.bin new file mode 100644 index 0000000..07c0c61 Binary files /dev/null and b/Resources/Stages/LSelect/StageConfig.bin differ diff --git a/Resources/Stages/LSelect/TileConfig.bin b/Resources/Stages/LSelect/TileConfig.bin new file mode 100644 index 0000000..7b3bbaf Binary files /dev/null and b/Resources/Stages/LSelect/TileConfig.bin differ diff --git a/Scripts/Effects/Debris.hsl b/Scripts/Effects/Debris.hsl new file mode 100644 index 0000000..4fd3c2d --- /dev/null +++ b/Scripts/Effects/Debris.hsl @@ -0,0 +1,71 @@ +class Debris { + event Create() { + this.AutoPhysics = false; + this.Sprite = Resources.LoadSprite("Sprites/Global/Explosions.bin", SCOPE_SCENE); + this.SetAnimation(0, 0); + + this.Gravity = 0.0; + this.Life = 0; + this.Wait = 0; + this.Rotation = 0.0; + this.RotationSpeed = 0.0; + this.ScaleXSpeed = 0.0; + this.ScaleYSpeed = 0.0; + this.ScaleX = 1.0; + this.ScaleY = 1.0; + + this.Status = null; + } + event Update() { + var wait = this.Wait; + if (wait <= 0) { + this.Debris_StatusNormal(); + + // Rotate if needed + var rspeed = this.RotationSpeed; + if (rspeed != 0.0) { + this.Rotation = (this.Rotation + rspeed) % Math_PI; + } + + // Scale if needed + var xspeed = this.ScaleXSpeed; + var yspeed = this.ScaleYSpeed; + if (xspeed != 0.0 || yspeed != 0.0) { + this.ScaleX = Math.Max(this.ScaleX + xspeed, 0.0); + this.ScaleY = Math.Max(this.ScaleY + yspeed, 0.0); + } + } + else { + this.Wait = wait - 1; + } + } + event Debris_StatusNormal() { + var yspeed = this.YSpeed; + + this.X += this.XSpeed; + this.Y += yspeed; + this.YSpeed = yspeed + this.Gravity; + + var life = this.Life; + if (life <= 0) { + // If Offscreen + if (!this.InView(0, this.X - 8.0, this.Y - 8.0, 16.0, 16.0)) { + this.Active = false; + return; + } + } + else { + this.Life = life - 1; + if (life == 1) + this.Active = false; + } + } + event Render() { + // Draw.SetBlendMode(BlendMode_ADD); + // Draw.SetTextureBlend(true); + // Draw.SetBlendColor(1.0, 1.0, 1.0, 0.5); + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), false, false); + // Draw.SetTextureBlend(false); + // Draw.SetBlendMode(BlendMode_NORMAL); + } +} diff --git a/Scripts/Effects/Explosion.hsl b/Scripts/Effects/Explosion.hsl new file mode 100644 index 0000000..948af80 --- /dev/null +++ b/Scripts/Effects/Explosion.hsl @@ -0,0 +1,17 @@ +class Explosion { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Global/Explosions.bin", SCOPE_SCENE); + this.SetAnimation(0, 0); + } + event OnAnimationFinish() { + this.Active = false; + } + event Render() { + // Draw.SetBlendMode(BlendMode_ADD); + // Draw.SetTextureBlend(true); + // Draw.SetBlendColor(1.0, 1.0, 1.0, 0.5); + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), false, false); + // Draw.SetTextureBlend(false); + // Draw.SetBlendMode(BlendMode_NORMAL); + } +} diff --git a/Scripts/Effects/ScoreBonus.hsl b/Scripts/Effects/ScoreBonus.hsl new file mode 100644 index 0000000..33a1f65 --- /dev/null +++ b/Scripts/Effects/ScoreBonus.hsl @@ -0,0 +1,26 @@ +class ScoreBonus { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Global/ScoreBonus.bin", SCOPE_SCENE); + this.SetAnimation(0, 0); + this.Life = 16; + } + event Update() { + this.Y -= 2.0; + + var life = this.Life; + if (life > 0) { + this.Life = life - 1; + if (life == 1) { + this.Active = false; + } + } + } + event Render() { + // Draw.SetBlendMode(BlendMode_ADD); + // Draw.SetTextureBlend(true); + // Draw.SetBlendColor(1.0, 1.0, 1.0, 0.5); + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), false, false); + // Draw.SetTextureBlend(false); + // Draw.SetBlendMode(BlendMode_NORMAL); + } +} diff --git a/Scripts/Logos/LogoSetup.hsl b/Scripts/Logos/LogoSetup.hsl new file mode 100644 index 0000000..f9c4b11 --- /dev/null +++ b/Scripts/Logos/LogoSetup.hsl @@ -0,0 +1,9 @@ +class LogoSetup { + event Create() { + // View.SetSize(0, 424.0, 240.0); + // Window.SetSize(848, 480); + } + event Render() { + // Draw.Sprite(this.LogoSprite, this.ListID, 0, this.X, this.Y, false, false); + } +} diff --git a/Scripts/Logos/UIPicture.hsl b/Scripts/Logos/UIPicture.hsl new file mode 100644 index 0000000..46d14cf --- /dev/null +++ b/Scripts/Logos/UIPicture.hsl @@ -0,0 +1,61 @@ +class UIPicture { + event Create() { + this.LogoSprite = Resources.LoadSprite("Sprites/Logos/Logos.bin", SCOPE_SCENE); + this.LogoSound = Resources.LoadSound("SoundFX/Stage/Sega.wav", SCOPE_SCENE); + this.ListID = 0; + this.RectY = 0.0; + + this.SEGATimer = 120; + this.Fade = 0; + this.FadeLength = 30; + + if (this.PropertyExists("listID")) + this.ListID = this.PropertyGet("listID"); + + if (this.ListID == 0) + this.RectY = 0.0; + else + this.RectY = 240.0; + + this.X -= (512.0 - 424.0) / 2.0; + // this.Y -= 240.0; + + if (this.ListID == 0) { + Sound.Play(this.LogoSound); + } + } + event Update() { + if (this.SEGATimer > 0) { + this.SEGATimer--; + return; + } + + if (this.Fade < this.FadeLength) { + this.Fade++; + if (this.Fade == this.FadeLength) { + + } + } + } + event Render() { + var vw = 424.0, vh = 240.0; + var eased = this.Fade * 1.0 / this.FadeLength; + // if (this.FadeIn) { + // eased = 1.0 - eased; + // } + eased = Ease.InOutQuad(eased); + + Draw.SetBlendColor(0.9375, 0.9375, 0.9375, 1.0); + Draw.Rectangle(0.0, this.RectY, vw, vh); + + Draw.Sprite(this.LogoSprite, this.ListID, 0, this.X, this.Y, false, false); + + Draw.SetBlendMode(BlendMode_SUBTRACT); + Draw.SetBlendColor( + Math.Clamp(eased * 3.0, 0.0, 1.0), + Math.Clamp(eased * 3.0 - 1.0, 0.0, 1.0), + Math.Clamp(eased * 3.0 - 2.0, 0.0, 1.0), 1.0); + Draw.Rectangle(0.0, this.RectY, vw, vh); + Draw.SetBlendMode(BlendMode_NORMAL); + } +} diff --git a/Scripts/Misc/MusicObject.hsl b/Scripts/Misc/MusicObject.hsl new file mode 100644 index 0000000..438f72e --- /dev/null +++ b/Scripts/Misc/MusicObject.hsl @@ -0,0 +1,36 @@ +class MusicObject { + event Create() { + /* + VERBOSE: Property Hash: 6672A69BU (trackFile) + VERBOSE: Property Hash: C1136580U (soundTestTitle) + VERBOSE: Property Hash: 6900C72EU (trackID) + VERBOSE: Property Hash: 6F88C82FU (trackLoop) + VERBOSE: Property Hash: ACD7EF2AU (playOnLoad) + //*/ + print "trackFile: " + this.PropertyGet("trackFile"); + print "soundTestTitle: " + this.PropertyGet("soundTestTitle"); + print "trackID: " + this.PropertyGet("trackID"); + print "trackLoop: " + this.PropertyGet("trackLoop"); + print "playOnLoad: " + this.PropertyGet("playOnLoad"); + + this.MusicIndex = Resources.LoadMusic("Music/" + this.PropertyGet("trackFile"), SCOPE_SCENE); + this.TrackLoop = this.PropertyGet("trackLoop"); + this.PlayOnLoad = this.PropertyGet("playOnLoad"); + + // this.MusicIndex = Resources.LoadMusic("Music/" + "EggReveriePinch.ogg", SCOPE_SCENE); + // this.TrackLoop = 1; + // this.PlayOnLoad = true; + + if (this.PlayOnLoad) + this.PlayMus(); + + this.Active = false; + } + + event PlayMus() { + if (this.TrackLoop > 0) + Music.Loop(this.MusicIndex, true, this.TrackLoop); + else + Music.Play(this.MusicIndex); + } +} diff --git a/Scripts/Other/InputManager.hsl b/Scripts/Other/InputManager.hsl new file mode 100644 index 0000000..fc5ac91 --- /dev/null +++ b/Scripts/Other/InputManager.hsl @@ -0,0 +1,250 @@ +var GLOBAL_KeyUp = Key_W; +var GLOBAL_KeyDown = Key_S; +var GLOBAL_KeyLeft = Key_A; +var GLOBAL_KeyRight = Key_D; +var GLOBAL_KeyPause = Key_RETURN; +var GLOBAL_KeyAccept = Key_J; +var GLOBAL_KeyDecline = Key_K; +var GLOBAL_KeyExtra1 = Key_L; +var GLOBAL_KeyExtra2 = Key_I; + +var GLOBAL_JoyUp = 11; +var GLOBAL_JoyDown = 12; +var GLOBAL_JoyLeft = 13; +var GLOBAL_JoyRight = 14; +var GLOBAL_JoyExtra1 = 0; +var GLOBAL_JoyExtra2 = 1; +var GLOBAL_JoyAction3 = 2; +var GLOBAL_JoyPause = 3; + +class InputManager { + event Create() { + this.Up = false; + this.Down = false; + this.Left = false; + this.Right = false; + this.Pause = false; + this.Accept = false; + this.Decline = false; + this.Extra1 = false; + this.Extra2 = false; + this.Any = false; + + this.UpPressed = false; + this.DownPressed = false; + this.LeftPressed = false; + this.RightPressed = false; + this.PausePressed = false; + this.AcceptPressed = false; + this.DeclinePressed = false; + this.Extra1Pressed = false; + this.Extra2Pressed = false; + this.AnyPressed = false; + + this.Pauseable = false; + + this.ListenIndex = 0; + + // Default Control Configs: + // NOTE: Up, Down, Left, Right, Pause, Accept, Decline, Extra1, Extra2 + + this.CTM_XInput_Controller = [ 11, 11, 11, 11, 7, 0, 1, 2, 3 ]; + /* + 0: A + 1: B + 2: X + 3: Y + 4: LB + 5: RB + 6: Back + 7: Pause + 8: LStick + 9: RStick + 10: Home + */ + this.CTM_Microsoft_XBox_360_Mac = [ 11, 12, 13, 14, 6, 0, 1, 2, 3 ]; + /* + 0: A + 1: B + 2: X + 3: Y + 4: Back + 5: Home + 6: Pause + 7: LStick + 8: RStick + 9: LB + 10: RB + 11: DUp + 12: DDown + 13: DLeft + 14: DRight + 15: + 16: + */ + this.CTM_SwitchNative = [ 13, 15, 12, 14, 6, 0, 1, 2, 3 ]; + + this.outKeys = Array.Create(32); + this.outJoys = Array.Create(32); + } + + event Update() { + this.GetInput(); + } + + event GetInput() { + var key = this.GetInputFromKeys(); + for (var i = 0; i < 9; i++) { + if (key[i]) { + this.ListenIndex = 0; + break; + } + } + + var joy = this.GetInputFromJoystick(); + for (var i = 0; i < 9; i++) { + if (joy[i]) { + this.ListenIndex = 1; + break; + } + } + + var listenTo = key; + if (this.ListenIndex == 1) + listenTo = joy; + + this.Up = listenTo[0]; + this.Down = listenTo[1]; + this.Left = listenTo[2]; + this.Right = listenTo[3]; + this.Pause = listenTo[4]; + this.Accept = listenTo[5]; + this.Decline = listenTo[6]; + this.Extra1 = listenTo[7]; + this.Extra2 = listenTo[8]; + + this.UpPressed = listenTo[9]; + this.DownPressed = listenTo[10]; + this.LeftPressed = listenTo[11]; + this.RightPressed = listenTo[12]; + this.PausePressed = listenTo[13]; + this.AcceptPressed = listenTo[14]; + this.DeclinePressed = listenTo[15]; + this.Extra1Pressed = listenTo[16]; + this.Extra2Pressed = listenTo[17]; + + this.Any = + this.Up | + this.Down | + this.Left | + this.Right | + this.Pause | + this.Accept | + this.Decline | + this.Extra1 | + this.Extra2; + this.AnyPressed = + this.UpPressed | + this.DownPressed | + this.LeftPressed | + this.RightPressed | + this.PausePressed | + this.AcceptPressed | + this.DeclinePressed | + this.Extra1Pressed | + this.Extra2Pressed; + } + event GetInputFromKeys() { + var out = this.outKeys; + out[0] = Input.IsKeyDown(GLOBAL_KeyUp); + out[1] = Input.IsKeyDown(GLOBAL_KeyDown); + out[2] = Input.IsKeyDown(GLOBAL_KeyLeft); + out[3] = Input.IsKeyDown(GLOBAL_KeyRight); + out[4] = Input.IsKeyDown(GLOBAL_KeyPause); + out[5] = Input.IsKeyDown(GLOBAL_KeyAccept); + out[6] = Input.IsKeyDown(GLOBAL_KeyDecline); + out[7] = Input.IsKeyDown(GLOBAL_KeyExtra1); + out[8] = Input.IsKeyDown(GLOBAL_KeyExtra2); + out[9] = Input.IsKeyPressed(GLOBAL_KeyUp); + out[10] = Input.IsKeyPressed(GLOBAL_KeyDown); + out[11] = Input.IsKeyPressed(GLOBAL_KeyLeft); + out[12] = Input.IsKeyPressed(GLOBAL_KeyRight); + out[13] = Input.IsKeyPressed(GLOBAL_KeyPause); + out[14] = Input.IsKeyPressed(GLOBAL_KeyAccept); + out[15] = Input.IsKeyPressed(GLOBAL_KeyDecline); + out[16] = Input.IsKeyPressed(GLOBAL_KeyExtra1); + out[17] = Input.IsKeyPressed(GLOBAL_KeyExtra2); + return out; + } + event GetInputFromJoystick() { + var out = this.outJoys; + out[0] = + out[1] = + out[2] = + out[3] = + out[4] = + out[5] = + out[6] = + out[7] = + out[8] = + out[9] = + out[10] = + out[11] = + out[12] = + out[13] = + out[14] = + out[15] = + out[16] = + out[17] = false; + + var controller_index = 0; + var controller_deadzone = 0.5; + + if (Input.GetControllerAttached(controller_index)) { + var controller_name = Input.GetControllerName(controller_index); + var up, down, left, right, pause, accept, decline, extra1, extra2; + + // Stick controls + out[0] = Input.GetControllerAxis(controller_index, 1) < -controller_deadzone; + out[1] = Input.GetControllerAxis(controller_index, 1) > controller_deadzone; + out[2] = Input.GetControllerAxis(controller_index, 0) < -controller_deadzone; + out[3] = Input.GetControllerAxis(controller_index, 0) > controller_deadzone; + // Hat controls + out[0] |= (Input.GetControllerHat(controller_index, 0) & 1) == 1; + out[1] |= (Input.GetControllerHat(controller_index, 0) & 4) == 4; + out[2] |= (Input.GetControllerHat(controller_index, 0) & 8) == 8; + out[3] |= (Input.GetControllerHat(controller_index, 0) & 2) == 2; + + // If XBOX360 Hats are mapped to buttons (XBox360 CD for MacOS) + if (controller_name == "Microsoft X-Box 360 pad") { + for (var i = 0; i < 9; i++) + out[i] |= Input.GetControllerButton(controller_index, this.CTM_Microsoft_XBox_360_Mac[i]); + } + else if (String.Contains(controller_name, "XInput Controller")) { + for (var i = 0; i < 9; i++) + out[i] |= Input.GetControllerButton(controller_index, this.CTM_XInput_Controller[i]); + } + // If on native Switch + else if (Device.GetPlatform() == Platform_Switch) { + for (var i = 0; i < 9; i++) + out[i] |= Input.GetControllerButton(controller_index, this.CTM_SwitchNative[i]); + } + else { + print "controller_name: " + controller_name; + } + + // Determine "pressed" state for buttons + out[9] = out[0] && !this.Up; + out[10] = out[1] && !this.Down; + out[11] = out[2] && !this.Left; + out[12] = out[3] && !this.Right; + out[13] = out[4] && !this.Pause; + out[14] = out[5] && !this.Accept; + out[15] = out[6] && !this.Decline; + out[16] = out[7] && !this.Extra1; + out[17] = out[8] && !this.Extra2; + } + + return out; + } +} diff --git a/Scripts/Other/PauseManager.hsl b/Scripts/Other/PauseManager.hsl new file mode 100644 index 0000000..65dd792 --- /dev/null +++ b/Scripts/Other/PauseManager.hsl @@ -0,0 +1,274 @@ +class PauseManager { + event Create() { + this.Priority = 15; + this.Pauseable = false; + + this.GamePaused = false; + this.Timer = 0; + this.Frame = 0; + + this.TextSprite = Resources.LoadSprite("Sprites/UI/TextEN.bin", SCOPE_GAME); + this.SelectedButton = 0; + this.LastSelectedButton = 0; + this.ButtonBounceTimers = [ 12, 12, 12 ]; + this.PauseDisabled = false; + + this.SFX_MenuAccept = Resources.LoadSound("SoundFX/Global/MenuAccept.wav", SCOPE_GAME); + this.SFX_MenuBleep = Resources.LoadSound("SoundFX/Global/MenuBleep.wav", SCOPE_GAME); + this.SFX_MenuWoosh = Resources.LoadSound("SoundFX/Global/MenuWoosh.wav", SCOPE_GAME); + } + + event SelectButton(b) { + this.LastSelectedButton = this.SelectedButton; + this.SelectedButton = (b + 3) % 3; + this.ButtonBounceTimers[this.SelectedButton] = 0; + Sound.Play(this.SFX_MenuBleep); + } + + event StartPause() { + if (Scene.IsPaused()) return; + if (this.PauseDisabled) return; + + Sound.PauseAll(); + + this.Timer = 0; + this.BounceTimer = 0; + this.GamePaused = true; + this.SelectButton(0); + Scene.SetPaused(true); + + Sound.Play(this.SFX_MenuAccept); + Sound.Stop(this.SFX_MenuBleep); + Music.Pause(); + } + + event StartUnpause() { + this.GamePaused = false; + this.Timer = 8; + + Sound.ResumeAll(); + Music.Resume(); + } + + event DoButtonAction() { + if (this.SelectedButton == 0) { + this.StartUnpause(); + Sound.Play(this.SFX_MenuAccept); + } + else if (this.SelectedButton == 1) { + Scene.Restart(); + Sound.Play(this.SFX_MenuAccept); + } + else if (this.SelectedButton == 2) { + Sound.StopAll(); + Music.Clear(); + + global.Level = (global.Level + 1) % Array.Length(global.LevelScenes); + Scene.Load(global.LevelScenes[global.Level]); + } + } + + event Update() { + this.Frame++; + + var input = Instance.GetNth("InputManager", 0); + if (!input) + return; + + if (input.PausePressed) { + if (!this.GamePaused) + this.StartPause(); + else + this.StartUnpause(); + } + + // this.InputUp = input.Up; + // this.InputDown = input.Down; + // this.InputLeft = input.Left; + // this.InputRight = input.Right; + // this.InputJump = input.Accept | input.Decline; + // this.InputJumpPressed = input.AcceptPressed | input.DeclinePressed; + + if (this.GamePaused) { + if (this.Timer < 16) + this.Timer++; + + // Key/joy selection + if (input.UpPressed) { + this.SelectButton(this.SelectedButton - 1); + } + if (input.DownPressed) { + this.SelectButton(this.SelectedButton + 1); + } + if (input.AcceptPressed) { + this.DoButtonAction(); + } + + // Mouse/touch selection + if (Input.IsMouseButtonDown(0) || Touch.IsDown(0)) { + if (this.SelectedButton != -1) + this.LastSelectedButton = this.SelectedButton; + + // Select based on Mouse/Touch Position here + var vw = View.GetWidth(0); + var vh = View.GetHeight(0); + var posX = Input.GetMouseX(); + var posY = Input.GetMouseY(); + if (Touch.IsDown(0)) { + posX = Touch.GetX(0); + posY = Touch.GetY(0); + } + + posX = posX * vw / Window.GetWidth(); + posY = posY * vh / Window.GetHeight(); + + var strt_x = vw / 2.0 + 106.0; + var strt_y = 140.0; + var seled = true; + for (var i = 0; i < 3; i++) { + var yuh_x = strt_x - i * 36.0 - 4.0; + var yuh_y = strt_y + i * 36.0 - 16.0; + + if (posX >= yuh_x && posY >= yuh_y && + posX < yuh_x + 128.0 && posY < yuh_y + 32.0) { + if (this.SelectedButton != i) { + this.SelectButton(i); + } + + seled = false; + // BUG: Breaking here breaking everything somehow + // break; + } + } + if (seled) { + this.SelectedButton = -1; + } + } + if (Input.IsMouseButtonReleased(0) || Touch.IsReleased(0)) { + if (this.SelectedButton == -1) { + this.SelectedButton = this.LastSelectedButton; + this.ButtonBounceTimers[this.SelectedButton] = 0; + } + else { + this.DoButtonAction(); + } + } + + for (var i = 0; i < 3; i++) { + if (i == this.SelectedButton) { + if (this.ButtonBounceTimers[i] < 12) + this.ButtonBounceTimers[i]++; + } + else { + if (this.ButtonBounceTimers[i] < 14) + this.ButtonBounceTimers[i]++; + } + } + } + else { + var timer = this.Timer - 1; + if (timer >= 0) { + this.Timer = timer; + if (timer == 0) { + Scene.SetPaused(false); + } + } + } + } + + event ClampNormal(v, a, b) { + return (Math.Clamp(v, a, b) - a) / (b - a); + } + event DrawWeirdRect(x, y, w, h) { + x = Number.AsInteger(x); + y = Number.AsInteger(y); + Draw.Triangle(x - h, y + h, + x, y, + x, y + h); + Draw.Rectangle(x, y, w, h); + Draw.Triangle(x + w + h, y, + x + w, y, + x + w, y + h); + } + event Render() { + var vc = View.GetCurrent(); + var vw = View.GetWidth(vc); + var vh = View.GetHeight(vc); + if (View.IsEnabled(3)) { + if (vc != 3) + return; + } + else if (vc != 0) + return; + + var _frame = this.Frame; + + if (Scene.IsPaused()) { + Draw.Save(); + Draw.Translate(Math.Floor(CameraX), Math.Floor(CameraY), 0.0); + // Dimming + Draw.SetBlendColor(0.0, 0.0, 0.0, 0.25); + Draw.Rectangle(0.0, 0.0, vw, vh); + + var vid_width = vw / 2.0; + var resultsTimer = this.Timer / 16.0; + var pauseRollIn = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.0, 0.5)) * vid_width - vid_width; + var pauseRollIn2 = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.1, 0.6)) * vid_width - vid_width - pauseRollIn; + Draw.Save(); + Draw.Translate(pauseRollIn, 0.0, 0.0); + // Red + Draw.SetBlendColor(0.93359375, 0.15625, 0.3515625, 1.0); + this.DrawWeirdRect(0.0, 0.0, 200.0, 60.0); + + // Paused + Draw.SetBlendColor(0.0, 0.0, 0.0, 1.0); + this.DrawWeirdRect(vid_width / 2.0 - 56.0 + pauseRollIn2, 18.0, 112.0, 24.0); + Draw.Sprite(this.TextSprite, 10, 3, vid_width / 2.0 + pauseRollIn2, 30.0, false, false); + Draw.Restore(); + + Draw.Save(); + Draw.Translate(vid_width - pauseRollIn, 0.0, 0.0); + // Yellow + Draw.SetBlendColor(0.96484375, 0.85546875, 0.03125, 1.0); + var tri_y = 10.0; + Draw.Triangle(vw - vid_width, tri_y, vw - (vh - tri_y) - vid_width, vh, vw - vid_width, vh); + + var strt_x = -pauseRollIn2 + 106.0; + var strt_y = 140.0; + + var col_b = Math.Sin(_frame / 32.0 * Math_PI_DOUBLE) * 0.353515625 + 0.353515625; + for (var i = 0; i < 3; i++) { + var yuh_x = strt_x - i * 36.0; + var yuh_y = strt_y + i * 36.0; + if (this.ButtonBounceTimers[i] <= 12) { + var factor = Math.Sin(this.ButtonBounceTimers[i] / 12.0 * Math_PI) * 1.5 + 1.0; + var bounce = 2 * factor; + + yuh_x += bounce; + yuh_y += bounce; + Draw.SetBlendColor(0.70703125, col_b, col_b, 1.0); + this.DrawWeirdRect(yuh_x - 4.0, yuh_y - 11.0, 80.0, 22.0); + + yuh_x -= bounce * 2; + yuh_y -= bounce * 2; + Draw.SetBlendColor(0.0, 0.0, 0.0, 1.0); + this.DrawWeirdRect(yuh_x - 4.0, yuh_y - 11.0, 80.0, 22.0); + + factor -= 1.0; + factor *= 2.0; + Draw.Sprite(this.TextSprite, 10, i, yuh_x - factor, yuh_y - factor * 2.0, false, false); + } + else { + var off = 14 - this.ButtonBounceTimers[i]; + Draw.SetBlendColor(0.70703125, col_b, col_b, 1.0); + this.DrawWeirdRect(yuh_x - 4.0 + off, yuh_y - 11.0 + off, 80.0, 22.0); + Draw.SetBlendColor(0.0, 0.0, 0.0, 1.0); + this.DrawWeirdRect(yuh_x - 4.0 - off, yuh_y - 11.0 - off, 80.0, 22.0); + Draw.Sprite(this.TextSprite, 10, i, yuh_x - off, yuh_y - off, false, false); + } + } + Draw.Restore(); + Draw.Restore(); + } + } +} diff --git a/Scripts/Other/WindowManager.hsl b/Scripts/Other/WindowManager.hsl new file mode 100644 index 0000000..cb1ff1e --- /dev/null +++ b/Scripts/Other/WindowManager.hsl @@ -0,0 +1,23 @@ +class WindowManager { + event Create() { + if (Device.IsMobile()) { + var w = Display.GetWidth(); + var h = Display.GetHeight(); + for (var i = 0; i < 8; i++) + View.SetSize(i, 240.0 * w / h, 240.0); + } + else { + this.SetScale(2); + // this.SetScale(3); + } + } + + event SetScale(screenScale) { + Window.SetSize(424.0 * screenScale, 240.0 * screenScale); + for (var i = 0; i < 8; i++) + View.SetSize(i, 424.0, 240.0); + } + event SetFullscreen(full) { + Window.SetFullscreen(full); + } +} diff --git a/Scripts/Player/DustPuff.hsl b/Scripts/Player/DustPuff.hsl new file mode 100644 index 0000000..9eb5cb2 --- /dev/null +++ b/Scripts/Player/DustPuff.hsl @@ -0,0 +1,17 @@ +class DustPuff { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Global/Dust.bin", SCOPE_SCENE); + this.SetAnimation(0, 0); + this.Flip = false; + } + event OnAnimationFinish() { + this.Active = false; + } + event Render() { + // Bigger viewbox for dropdash puffs + if (!this.InView(0, this.X - 40.0, this.Y - 40.0, 80.0, 80.0)) + return; + + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), this.Flip, false); + } +} diff --git a/Scripts/Player/Player.hsl b/Scripts/Player/Player.hsl new file mode 100644 index 0000000..f756204 --- /dev/null +++ b/Scripts/Player/Player.hsl @@ -0,0 +1,4187 @@ +// Enums +var Character_SONIC = 0; +var Character_TAILS = 1; +var Character_KNUCKLES = 2; +var Character_MIGHTY = 3; +var Character_RAY = 4; + +var ShieldType_NONE = 0; +var ShieldType_INSTA = -1; +var ShieldType_BASIC = 1; +var ShieldType_FIRE = 2; +var ShieldType_ELECTRIC = 3; +var ShieldType_BUBBLE = 4; + +var CollideSide_TOP = 1; +var CollideSide_RIGHT = 2; +var CollideSide_BOTTOM = 4; +var CollideSide_LEFT = 8; + +var Mode_MANIA = 3; +var Mode_ENCORE = 5; + +class Player { + // Create event + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Setup + if (this.PropertyExists("characterID")) { + if (!(this.PropertyGet("characterID") & (1 << global.SelectedCharacter))) { + this.Active = false; + return; + } + } + + if (this.X < 0.0 || + this.Y < 0.0 || + this.X >= Scene.GetWidth() * 16.0 || + this.Y >= Scene.GetHeight() * 16.0) { + this.Active = false; + return; + } + + this.AutoPhysics = false; + + this.SensorABCD_Ground_cos = [ 9, 0, -9, 0 ]; + this.SensorABCD_Ground_sin = [ 0, -9, 0, 9 ]; + this.SensorABCD_Air_cos = [ 7, 0, -7, 0 ]; + this.SensorABCD_Air_sin = [ 0, -7, 0, 7 ]; + this.SensorEF_cos = [ 10, 0, -10, 0 ]; + this.SensorEF_sin = [ 0, -10, 0, 10 ]; + this.simple_cos = [ 1, 0, -1, 0 ]; + this.simple_sin = [ 0, 1, 0, -1 ]; + this.simple_side = [ CollideSide_TOP, CollideSide_LEFT, CollideSide_BOTTOM, CollideSide_RIGHT ]; + + this.Priority = DrawGroup_FGLow_High; + + this.InputUp = false; + this.InputDown = false; + this.InputLeft = false; + this.InputRight = false; + this.InputAction = false; + this.InputJump = false; + this.InputJumpPressed = false; + this.InputPause = false; + + // if (GLOBAL_Checkpoint >= 0) { + // this.X = GLOBAL_CheckpointSpawnX; + // this.Y = GLOBAL_CheckpointSpawnY; + // } + // if (GLOBAL_SpecialWarpSpawnX >= 0) { + // this.X = GLOBAL_SpecialWarpSpawnX; + // this.Y = GLOBAL_SpecialWarpSpawnY; + // // Prevent further use as spawn point + // GLOBAL_SpecialWarpSpawnX = -1.0; + // GLOBAL_SpecialWarpSpawnY = -1.0; + // } + + this.SuperForm = false; + this.SuperFormLock = false; + + this.JumpHeights = [ 6.5, 6.5, 6.0, 6.5, 7.0 ]; + + this.sensorsAngle = [ 0, 0, 0 ]; + this.sensorsLength = [ 0.0, 0.0, 0.0 ]; + this.sensorsCollided = [ 0, 0, 0 ]; + + this.ShowingTailSprite = false; + this.DashDustSprite = Resources.LoadSprite("Sprites/Global/Dust.bin", SCOPE_SCENE); + this.DashDustTimer = 0; + // 0: Skidding + // 1: Spindash + // 2: Dropdash + // Create instance of tail sprite with it's own animation + this.TailObject = Instance.Create("TailObject", this.X, this.Y); + + this.FlipRevolutionsRemaining = 0; + this.DoSpriteRotation = false; + this.BadnikHitChain = 0; + + //////////// + this.Angle = 0; + this.Rotation = 0.0; + this.GroundSpeed = 0.0; + this.UseGroundSpeed = true; + this.Ground = true; + this.Flip = false; + // this.Priority + this.Visible = true; + this.PlaneIndex = 0; + this.AngleMode = 0; + this.Status = this.Player_StatusStanding; + // + this.LateUpdateGroundStatus = null; + this.LateUpdateAirStatus = null; + this.CameraPtr = null; + // this.MainPlayerAnimation + this.WalkThreshold = 4.0; + this.RunThreshold = 6.0; + this.DashThreshold = 12.0; + this.Unk_0xA4 = false; + this.TailRotation = 0.0; + this.TailFlip = false; + this.AnimationAfterSpring = 0; + this.PlayerID = 0; + this.DefaultH = 20.0; + this.HitboxHalfW = 10.0; + this.HitboxHalfH = this.DefaultH; + this.Character = global.SelectedCharacter; + this.Rings = 0; + this.RingExtraLifeLevel = 100; + this.Shield = ShieldType_NONE; + this.Lives = 3; + this.Score = 0; + this.ScoreToNextLife = 50000; + this.CombineRing = false; + this.WaitTimer = 0; + this.OuttaHereTimer = 0; + this.SpindashRev = 0.0; + this.Unk_0xEC = 0.0; + this.RayGlideTurnValue = 0.25; + this.UnderwaterAirTimer = 1800; + this.Invincibility = false; + this.SpeedShoesTimer = 1800; + this.InvincibilityTimer = 0; + this.CameraLockTimer = 0; + this.SkidTimer = 0; + this.PushingTimer = 0; + this.Underwater = false; + this.IsUpsideDown = false; + this.UseChibiSprite = false; + this.IsTransforming = false; + this.SuperForm = 0; + this.SuperForm_RingDrainTimer = 0; + this.SuperForm_PulseValue = 0; + this.SuperForm_PulseFlag = 0; + this.CannotLoseRings = false; + this.EnemyCombo = 0; + this.RollHitboxDelta = 0.0; + this.HorizontalCollisionFlag = 0; + this.VerticalCollisionFlag = 0; + this.TopSpeed = 6.0; + this.Acceleration = 0.046875; + this.Friction = 0.046875; + this.AirAcceleration = 0.09375; + this.Unk_0x158 = 0.0234375; + this.Slope = 0.125; + this.SlopeRollUp = 0.078125; + this.SlopeRollDown = 0.3125; + this.Deceleration = 0.5; + this.RollFriction = 0.0234375; + this.RollDeceleration = 0.125; + this.GravityRate = 0.21875; + this.JumpHeight = 6.8; + this.JumpReleaseSpeed = -4.0; + this.GroundSensorMask = 0; + this.SensorRightX = 10.0; + this.SensorRightShortX = 5.0; + this.SensorMiddleX = 0.0; + this.SensorLeftShortX = -5.0; + this.SensorLeftX = -10.0; + // this.HitboxHalfHCopy + this.Unk_0x194 = 0; + this.Unk_0x198 = 0; + this.Unk_0x19C = 0; + this.InputStatus = null; + this.ControllerID = 1; + this.InputLock = 0; + // + this.JumpAbility = 0; + this.MidAirFlag = 0; + this.JumpMovesetFunc = null; + this.GroundedUpFunc = null; + this.Unk_0x1D4 = 0; + this.Unk_0x1D8 = 0; + this.Unk_0x1DC = 0; + this.Unk_0x1E0 = 0; + this.Unk_0x1E4 = 0; + this.KillFlag = false; + this.Unk_0x1EC = 0; + this.IsGhost = false; + this.MaxGlideSpeed = 0; + this.Unk_0x1F8 = 0; + this.Unk_0x1FC = 0; + this.Unk_0x200 = 0; + this.Unk_0x204 = 0; + this.Unk_0x208 = 0; + this.Unk_0x20C = 0; + this.Unk_0x210 = 0; + this.RespawnDestinationX = 0.0; + this.RespawnDestinationY = 0.0; + this.Unk_0x21C = 0; + this.Unk_0x220 = 0; + this.Unk_0x224 = 0; + this.Unk_0x228 = 0; + this.Unk_0x22C = 0; + this.Unk_0x230 = 0; + this.Unk_0x234 = 0; + + this.HurtReboundTimer = 0; + this.InvulnTimer = 0; + this.InstashieldTimer = 0; + + this.TimerFrames = 0; + this.StopTimer = false; + + this.DoubleJumpFlag = 0; + this.KnucklesGlideFlag = 0; + this.KnucklesGlideState = 0; + this.KnucklesGlideAngle = 0; + this.KnucklesGlideAngleDirection = 0; + this.RayBoostCount = 0x100; + this.RayGlideSpeedStore = 0; + this.RayFacingUp = 0; + + this.ShieldObject = Instance.Create("ShieldObject", this.X, this.Y); + this.ShieldObject.Player = this; + // this.GiveShield(ShieldType_ELECTRIC, false); + + this.LevelWidth = Scene.GetWidth() * 16.0; + this.LevelHeight = Scene.GetHeight() * 16.0; + + this.CameraShakeTimer = 0; + this.CameraMinX = 0.0; + this.CameraMinY = 0.0; + this.CameraMaxX = this.LevelWidth - View.GetWidth(0); + this.CameraMaxY = this.LevelHeight - View.GetHeight(0); + + this.RingSoundFlipFlag = false; + + this.LoadSounds(); + this.MoveCameraImmediately(); + this.LoadCharacterSprites(); + this.Player_ResetSpeeds(); + + if (this.PropertyExists("Layer")) + this.PlaneIndex = this.PropertyGet("Layer"); + + + if (Instance.GetCount("Zone") == 0) { + Instance.Create("Zone", 0.0, 0.0); + } + + // this.X = 3309.0; + // this.Y = 1439.0; + // this.CombineRing = true; + } + event LoadSounds() { + this.SFX_Hurt = Resources.LoadSound("SoundFX/Global/Hurt.wav", SCOPE_GAME); + this.SFX_Jump = Resources.LoadSound("SoundFX/Global/Jump.wav", SCOPE_GAME); + this.SFX_Life = Resources.LoadSound("Music/1up.ogg", SCOPE_GAME); // Music/1up.ogg + this.SFX_Roll = Resources.LoadSound("SoundFX/Global/Roll.wav", SCOPE_GAME); + this.SFX_Skid = Resources.LoadSound("SoundFX/Global/Skidding.wav", SCOPE_GAME); + this.SFX_Death = Resources.LoadSound("SoundFX/Global/Hurt.wav", SCOPE_GAME); + this.SFX_Drown = Resources.LoadSound("SoundFX/Stage/Drown.wav", SCOPE_GAME); + this.SFX_Spike = Resources.LoadSound("SoundFX/Global/Spike.wav", SCOPE_GAME); + this.SFX_Flying = Resources.LoadSound("SoundFX/Global/Flying.wav", SCOPE_GAME); + this.SFX_FlyingFall = Resources.LoadSound("SoundFX/Global/Tired.wav", SCOPE_GAME); + this.SFX_GlideGrab = Resources.LoadSound("SoundFX/Global/Grab.wav", SCOPE_GAME); + this.SFX_GlideLand = Resources.LoadSound("SoundFX/Global/Land.wav", SCOPE_GAME); + this.SFX_GlideSlide = Resources.LoadSound("SoundFX/Global/Slide.wav", SCOPE_GAME); + this.SFX_SpinCharge = Resources.LoadSound("SoundFX/Global/Charge.wav", SCOPE_GAME); + this.SFX_SpinRelease = Resources.LoadSound("SoundFX/Global/Release.wav", SCOPE_GAME); + this.SFX_PeelRelease = Resources.LoadSound("SoundFX/Global/PeelRelease.wav", SCOPE_GAME); + + this.SFX_ShieldAction_Fire = Resources.LoadSound("SoundFX/Global/FireDash.wav", SCOPE_GAME); + this.SFX_ShieldAction_Electric = Resources.LoadSound("SoundFX/Global/LightningJump.wav", SCOPE_GAME); + this.SFX_ShieldAction_Bubble = Resources.LoadSound("SoundFX/Global/BubbleBounce.wav", SCOPE_GAME); + this.SFX_ShieldAction_Insta = Resources.LoadSound("SoundFX/Global/InstaShield.wav", SCOPE_GAME); + + this.SFX_ShieldObtain_Basic = Resources.LoadSound("SoundFX/Global/BlueShield.wav", SCOPE_GAME); + this.SFX_ShieldObtain_Fire = Resources.LoadSound("SoundFX/Global/FireShield.wav", SCOPE_GAME); + this.SFX_ShieldObtain_Electric = Resources.LoadSound("SoundFX/Global/LightningShield.wav", SCOPE_GAME); + this.SFX_ShieldObtain_Bubble = Resources.LoadSound("SoundFX/Global/BubbleShield.wav", SCOPE_GAME); + + this.SFX_WaterWarning = Resources.LoadSound("SoundFX/Stage/Warning.wav", SCOPE_GAME); + this.SFX_WaterSplash = Resources.LoadSound("SoundFX/Stage/Splash.wav", SCOPE_GAME); + this.SFX_BubbleGet = Resources.LoadSound("SoundFX/Stage/Breathe.wav", SCOPE_GAME); + + this.SFX_Impact3 = Resources.LoadSound("SoundFX/Stage/Impact3.wav", SCOPE_GAME); + + this.SFX_BadnikDestroy = Resources.LoadSound("SoundFX/Global/Destroy.wav", SCOPE_GAME); + this.SFX_BossHit = Resources.LoadSound("SoundFX/Stage/BossHit.wav", SCOPE_GAME); + + this.SFX_Spring = Resources.LoadSound("SoundFX/Global/Spring.wav", SCOPE_GAME); + this.SFX_Checkpoint = Resources.LoadSound("SoundFX/Global/StarPost.wav", SCOPE_GAME); + this.SFX_SpecialRing = Resources.LoadSound("SoundFX/Global/SpecialRing.wav", SCOPE_GAME); + this.SFX_SpecialWarp = Resources.LoadSound("SoundFX/Global/SpecialWarp.wav", SCOPE_GAME); + + this.SFX_DropDash = Resources.LoadSound("SoundFX/Global/DropDash.wav", SCOPE_GAME); + + this.SFX_RayDive = Resources.LoadSound("SoundFX/Global/RayDive.wav", SCOPE_GAME); + this.SFX_RaySwoop = Resources.LoadSound("SoundFX/Global/RaySwoop.wav", SCOPE_GAME); + + this.SFX_MightyUnspin = Resources.LoadSound("SoundFX/Global/MightyUnspin.wav", SCOPE_GAME); + this.SFX_MightyDrill = Resources.LoadSound("SoundFX/Global/MightyDrill.wav", SCOPE_GAME); + this.SFX_MightyLand = Resources.LoadSound("SoundFX/Global/MightyLand.wav", SCOPE_GAME); + this.SFX_PimPom = Resources.LoadSound("SoundFX/Stage/PimPom.wav", SCOPE_GAME); + + this.SFX_RingLeft = Resources.LoadSound("SoundFX/Global/Ring.wav", SCOPE_GAME); + this.SFX_RingRight = Resources.LoadSound("SoundFX/Global/Ring.wav", SCOPE_GAME); + this.SFX_RingSpill = Resources.LoadSound("SoundFX/Global/LoseRings.wav", SCOPE_GAME); + this.SFX_HyperRing = Resources.LoadSound("SoundFX/Global/HyperRing.wav", SCOPE_GAME); + + + this.BGM_Drowning = Resources.LoadMusic("Music/Drowning.ogg", SCOPE_SCENE); + } + event StopAllSounds() { + for (var i = this.SFX_Hurt; i <= this.SFX_RingSpill; i++) { + Sound.Stop(i); + } + } + event LoadCharacterSprites() { + var lastDefaultH = this.DefaultH; + + switch (this.Character) { + case 0: // Character_SONIC + this.Sprite = Resources.LoadSprite("Sprites/Players/Sonic.bin", SCOPE_SCENE); + if (this.SuperForm) + this.Sprite = Resources.LoadSprite("Sprites/Players/SuperSonic.bin", SCOPE_SCENE); + + this.DefaultH = 20.0; + this.RollHitboxDelta = 5.0; + this.JumpMovesetFunc = this.Player_MovesetSonic; + break; + case 1: // Character_TAILS + this.Sprite = Resources.LoadSprite("Sprites/Players/Tails.bin", SCOPE_SCENE); + + this.DefaultH = 16.0; + this.RollHitboxDelta = 0.0; + this.JumpMovesetFunc = this.Player_MovesetTails; + break; + case 2: // Character_KNUCKLES + this.Sprite = Resources.LoadSprite("Sprites/Players/Knux.bin", SCOPE_SCENE); + + this.DefaultH = 20.0; + this.RollHitboxDelta = 5.0; + this.JumpMovesetFunc = this.Player_MovesetKnuckles; + break; + case 3: // Character_MIGHTY + this.Sprite = Resources.LoadSprite("Sprites/Players/Mighty.bin", SCOPE_SCENE); + + this.DefaultH = 20.0; + this.RollHitboxDelta = 5.0; + this.JumpMovesetFunc = this.Player_MovesetMighty; + break; + case 4: // Character_RAY + this.Sprite = Resources.LoadSprite("Sprites/Players/Ray.bin", SCOPE_SCENE); + + this.DefaultH = 20.0; + this.RollHitboxDelta = 5.0; + this.JumpMovesetFunc = this.Player_MovesetRay; + break; + } + + this.Y -= this.DefaultH - lastDefaultH; + this.HitboxHalfH = this.DefaultH; + } + + // Update events + event GetInput() { + var input = Instance.GetNth("InputManager", 0); + if (input) { + this.InputUp = input.Up; + this.InputDown = input.Down; + this.InputLeft = input.Left; + this.InputRight = input.Right; + this.InputJump = input.Accept | input.Decline; + this.InputJumpPressed = input.AcceptPressed | input.DeclinePressed; + } + + if (Device.IsMobile()) { + var vw = View.GetWidth(0); + var vh = View.GetHeight(0); + var vsw = vw / Window.GetWidth(); + var vsh = vh / Window.GetHeight(); + var tx, ty, tD, tP, dist, angl; + var buttonY = vh - 64.0; + for (var t = 0; t < 2; t++) { + tx = Touch.GetX(t) * vsw; + ty = Touch.GetY(t) * vsh; + tD = Touch.IsDown(t); + tP = Touch.IsPressed(t); + + dist = Math.Distance(64.0, buttonY, tx, ty); + angl = Math.Direction(64.0, buttonY, tx, ty); + if (dist < 64.0 && tD) { + angl = this.GetAngleMode(Number.AsInteger(this.RadiansToHex(angl))); + if (angl == 0x00) + this.InputRight = true; + else if (angl == 0x40) + this.InputUp = true; + else if (angl == 0x80) + this.InputLeft = true; + else if (angl == 0xC0) + this.InputDown = true; + } + + dist = Math.Distance(vw - 64.0, buttonY, tx, ty); + if (dist < 48.0) { + this.InputJump |= tD; + this.InputJumpPressed |= tP; + } + + dist = Math.Distance(vw - 64.0, 24.0, tx, ty); + if (dist < 48.0 && tP) { + var pauseMan = Instance.GetNth("PauseManager", 0); + if (pauseMan) + pauseMan.StartPause(); + } + } + } + } + + event CreateSkidDust() { + if (Scene_Frame % 5 == 0) { + var dust = Instance.Create("DustPuff", this.X, this.Y + this.HitboxHalfH - 8.0); + dust.Priority = this.Priority; + dust.SetAnimation(0, 0); + } + } + + event ClearGlobals() { + GLOBAL_Checkpoint = -1; + GLOBAL_SpecialRings = 0; + GLOBAL_CheckpointSpawnX = -1.0; + GLOBAL_CheckpointSpawnY = -1.0; + GLOBAL_SpecialWarpSpawnX = -1.0; + GLOBAL_SpecialWarpSpawnY = -1.0; + } + event GiveShield(shield, doSound) { + this.Shield = shield; + + if (this.Character == Character_SONIC) { + this.InstashieldTimer = 0; + this.DoubleJumpFlag = 0; + } + + if (this.Shield == ShieldType_BASIC) { + this.ShieldObject.SetAnimation(0, 0); + if (doSound) + Sound.Play(this.SFX_ShieldObtain_Basic); + } + else if (this.Shield == ShieldType_FIRE) { + this.ShieldObject.SetAnimation(1, 0); + if (doSound) + Sound.Play(this.SFX_ShieldObtain_Fire); + } + else if (this.Shield == ShieldType_ELECTRIC) { + this.ShieldObject.SetAnimation(3, 0); + if (doSound) + Sound.Play(this.SFX_ShieldObtain_Electric); + } + else if (this.Shield == ShieldType_BUBBLE) { + this.ShieldObject.SetAnimation(5, 0); + if (doSound) + Sound.Play(this.SFX_ShieldObtain_Bubble); + } + } + event GainRings(rings) { + this.Rings += rings; + if (this.Rings >= this.RingExtraLifeLevel) { + this.GainLife(); + + this.RingExtraLifeLevel += 100; + } + } + event SpawnLostRings(rings, planeIndex) { + var t = 0; + var angle = 101.25 * Math_PI / 180.0; + var n = false; + var speed = 4.0; + + while (t < Math.Min(rings, 32)) { + var ring = Instance.Create("Ring", this.X, this.Y); + ring.RegatherTimer = 64; + ring.DeathTimer = 256; + ring.HSpeed = Math.Cos(angle) * speed; + ring.VSpeed = -Math.Sin(angle) * speed; + ring.Bounceable = true; + ring.Priority = this.Priority; + ring.PlaneIndex = this.PlaneIndex; + ring.Status = ring.Ring_StatusBounceable; + if (n) { + ring.HSpeed *= -1.0; + angle += 22.5 * Math_PI / 180.0; + } + n = !n; + t++; + if (t == 16) { + speed = 2.0; + angle = 101.25 * Math_PI / 180.0; + } + } + } + event SpawnLostCombineRings(rings, planeIndex) { + var ringsToSpawn = rings >> 2; + if (ringsToSpawn > 8) + ringsToSpawn = 8; + else if (ringsToSpawn < 1) + ringsToSpawn = 1; + + var ringIndex = 0; + var startAngle = 0xC0 - 0x10 * (ringsToSpawn & 0xFFFFFFFE); + var ringsWorth = rings / ringsToSpawn; + + if (ringsToSpawn & 1) + startAngle = startAngle + 0x10; + else + startAngle = startAngle - 0x10; + + while (ringIndex < ringsToSpawn) { + var ring = Instance.Create("Ring", this.X, this.Y); + ring.HitboxW = + ring.HitboxH = 32.0; + ring.HitboxHalfW = + ring.HitboxHalfH = 16.0; + ring.RegatherTimer = 64; + ring.DeathTimer = 256; + ring.GravityRate = 0.0703125; + ring.HSpeed = Static.HexCos(startAngle) * 3.0; + ring.VSpeed = Static.HexSin(startAngle) * 3.0; + ring.RingCount = ringsWorth; + ring.Bounceable = true; + ring.Priority = this.Priority; + ring.PlaneIndex = this.PlaneIndex; + ring.AngleSpeed = 0x180; + ring.Angle = 0; + ring.Status = ring.Ring_StatusBounceableCombine; + ring.SetAnimation(1, 0); + startAngle += 0x20; + ringIndex++; + } + } + event GetHurt(pain_x) { + var doKnockback = false; + var loseRings = false; + + if (this.CannotLoseRings) { + doKnockback = true; + } + else { + if (this.Shield != ShieldType_NONE) { + this.Shield = ShieldType_NONE; + doKnockback = true; + } + else if (this.Rings > 0) { + doKnockback = true; + loseRings = true; + } + else { + this.KillFlag = 1; + // 1: Normal death + // 2: Soundless + // 3: Drown death + return; + } + } + + if (doKnockback) { + this.Status = this.Player_StatusHurt; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(18, 0); + + // Custom + this.LateUpdateAirStatus = null; + this.XSpeed = -2.0; + if (this.X > pain_x) + this.XSpeed = 2.0; + + this.YSpeed = -4.0; + this.Ground = false; + this.UseGroundSpeed = true; + this.InvincibilityTimer = 120; + if (this.Underwater) { + this.XSpeed *= 0.5; + this.YSpeed = -2.0; + } + if (loseRings) + Sound.Play(this.SFX_RingSpill); + else + Sound.Play(this.SFX_Hurt); + } + if (loseRings) { + if (this.CombineRing) + this.SpawnLostCombineRings(this.Rings, this.PlaneIndex); + else + this.SpawnLostRings(this.Rings, this.PlaneIndex); + this.CombineRing = false; + this.Rings = 0; + this.RingExtraLifeLevel = 100; + } + } + event KillPlayer() { + this.KillFlag = true; + this.XSpeed = 0.0; + if (!this.Underwater) + this.YSpeed = -7.0; + this.GroundSpeed = 0.0; + this.Ground = false; + this.InvulnTimer = 0; + + this.StopAllSounds(); + + if (this.Underwater) + Sound.Play(this.SFX_Drown); + else + Sound.Play(this.SFX_Death); + } + event GainLife() { + this.Lives++; + Sound.Play(this.SFX_Life); + } + event GainScore(count) { + this.Score += count; + if (this.Score >= this.ScoreToNextLife) { + this.GainLife(); + this.ScoreToNextLife += 50000; + } + + if (this.Score > 9999999) + this.Score = 9999999; + } + event LoseLife() { + this.Lives--; + } + event DoVictory() { + if (!this.Victory) { + this.Victory = true; + + this.GroundSpeed = 0.0; + this.XSpeed = 0.0; + this.YSpeed = 0.0; + } + } + event IncreaseEnemyCombo() { + var score = 10; + switch (this.EnemyCombo) { + case 0: + score = 100; + break; + case 1: + score = 200; + break; + case 2: + score = 500; + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + score = 1000; + break; + case 15: + score = 10000; + break; + } + this.GainScore(score); + if (this.EnemyCombo < 15) + this.EnemyCombo++; + } + + event CheckCanDamage(badnik) { + var candamage = false; + + // When a character is curled, whether rolling, jumping, (or in Drop Dash) + candamage |= (this.Curled) && (!this.HurtReboundTimer); + // When a character is spindashed + candamage |= this.Spindash; + // Tails' tails + candamage |= this.Character == Character_TAILS && this.DoubleJumpFlag != 0 && this.Y > badnik.Y; + // Knuckles' knuckles + candamage |= this.Character == Character_KNUCKLES && this.KnucklesGlideFlag && this.KnucklesGlideState == 1 && ((this.X < badnik.X && !this.Flip) || (this.X > badnik.X && this.Flip)); + // Mighty's...mighty shell + candamage |= this.Character == Character_MIGHTY && this.DoubleJumpFlag == 1; + + if (badnik.Invulnerable) + candamage = false; + + candamage |= this.SuperForm; + return candamage; + } + event BadnikCollision(badnik) { + if (this.KillFlag) + return; + + if (this.CheckCanDamage(badnik)) { + if (!badnik.IsDead) { + badnik.Damaged(); + if (!(this.Character == Character_MIGHTY && this.DoubleJumpFlag == 1)) { + if (this.Y <= badnik.Y && this.YSpeed > 0.0) { + this.YSpeed = -this.YSpeed; + } + else { + this.YSpeed -= Math.Sign(this.YSpeed); + } + } + + this.BadnikHitChain++; + if (this.BadnikHitChain >= 16) { + this.BadnikHitChain = 16; + this.GainScore(10000); + } + else if (this.BadnikHitChain >= 4) + this.GainScore(1000); + else if (this.BadnikHitChain == 3) + this.GainScore(500); + else if (this.BadnikHitChain == 2) + this.GainScore(200); + else if (this.BadnikHitChain == 1) + this.GainScore(100); + + var animal = Instance.Create("Animal", badnik.X, badnik.Y); + animal.Priority = badnik.Priority; + animal.VSpeed = -4.0; + animal.SetAnimation(0, 0); + + var bonus = Instance.Create("ScoreBonus", badnik.X, badnik.Y); + bonus.SetAnimation(0, this.BadnikHitChain - 1); + } + } + else { + this.GetHurt(badnik.X); + } + } + event BossCollision(badnik) { + if (this.KillFlag) + return; + + if (this.CheckCanDamage(badnik)) { + if (!badnik.IsDead) { + badnik.Damaged(); + Sound.Play(this.SFX_BossHit); + + if (this.KnucklesGlideState == 1) + this.KnucklesGlideState = 2; + + if (!(this.Character == Character_MIGHTY && this.DoubleJumpFlag == 1)) { + if (this.Ground) { + this.GroundSpeed = -this.GroundSpeed; + } + else { + this.XSpeed = -this.XSpeed; + this.YSpeed = -this.YSpeed; + } + } + else { + this.DoubleJumpFlag = 2; + } + } + } + else if (!badnik.Invulnerable) { + this.GetHurt(badnik.X); + } + } + + // Camera movement function + event MoveCamera() { + // For looking up/down + // if (this.Status ) + // this.CameraLookTimer = Math.Max(-120, this.CameraLookTimer - 1); + // else if (this.Crouching) + // this.CameraLookTimer = Math.Min(120, this.CameraLookTimer + 1); + // else + // this.CameraLookTimer = 0; + // + // if (this.CameraLookTimer == -120) + // this.CameraLookOffset = Math.Max(-64.0, this.CameraLookOffset - 2.0); + // else if (this.CameraLookTimer == 120) + // this.CameraLookOffset = Math.Min(88.0, this.CameraLookOffset + 2.0); + // else + // this.CameraLookOffset -= Math.Sign(this.CameraLookOffset) * 2.0; + + // For a classic-styled slightly offset camera, use 0.0 for X and -16.0 for Y + var cameraFocusOffsetX = 0.0; + var cameraFocusOffsetY = -16.0; + + var cameraDestinationX = cameraFocusOffsetX + (this.X) - (View.GetWidth(0) / 2.0); + var cameraDestinationY = cameraFocusOffsetY + (this.Y) - (View.GetHeight(0) / 2.0) + this.CameraLookOffset; + + + // FIX: So the camera scrolls when Knuckles finishes ledge climb + if (this.KnucklesGlideState == 5) { + if (this.Flip) + cameraDestinationX -= Ease.InQuad(this.KnucklesGlideAngle / 15.0) * 20.0; + else + cameraDestinationX += Ease.InQuad(this.KnucklesGlideAngle / 15.0) * 20.0; + } + + // This prevents the camera from moving during a spindash or a flame shield action + // NOTE: Spindash sets it to 16 + // if (this.C ameraLockTimer > 0) { + // this.C ameraLockTimer--; + // } + // else { + // Horizontal camera movement + var displaceX = cameraDestinationX - CameraX; + var distanceX = Math.Abs(displaceX); + var signX = Math.Sign(displaceX); + + if (distanceX >= 8.0) + CameraX += Math.Min(distanceX - 8.0, 16.0) * signX; + + // Vertical camera movement + var displaceY = cameraDestinationY - CameraY; + var distanceY = Math.Abs(displaceY); + var signY = Math.Sign(displaceY); + + // this.Ground + if (this.VerticalCollisionFlag & 1) { + var maxCameraYSpeed = 6.0; + if (Math.Abs(this.GroundSpeed) >= 8.0) + maxCameraYSpeed = 16.0; + + // camera panning + if (CameraY < this.CameraMinY) { + CameraY += 2.0; + if (CameraY > this.CameraMinY) + CameraY = this.CameraMinY; + } + else if (CameraY > this.CameraMaxY) { + CameraY -= 2.0; + if (CameraY < this.CameraMaxY) + CameraY = this.CameraMaxY; + } + else { + // Smooth + CameraY += Math.Min(distanceY / 4.0, maxCameraYSpeed) * signY; + // Rigid + // CameraY += Math.Min(distanceY, maxCameraYSpeed) * signY; + } + } + else { + if (distanceY > 32.0) + CameraY += Math.Min(distanceY - 32.0, 16.0) * signY; + } + // } + + if (CameraX < this.CameraMinX) + CameraX = this.CameraMinX; + if (CameraX > this.CameraMaxX) + CameraX = this.CameraMaxX; + if (CameraY < this.CameraMinY) + CameraY = this.CameraMinY; + if (CameraY > this.CameraMaxY) + CameraY = this.CameraMaxY; + + if (this.CameraShakeTimer > 0) { + var val = (this.CameraShakeTimer / 4) + 1; + val *= ((this.CameraShakeTimer & 1) << 1) - 1; + + CameraY += val; + + this.CameraShakeTimer--; + } + + // Make sure the camera doesn't try to move out of bounds + CameraX = Math.Clamp(CameraX, 0.0, this.LevelWidth - View.GetWidth(0)); + CameraY = Math.Clamp(CameraY, 0.0, this.LevelHeight - View.GetHeight(0)); + } + event MoveCameraImmediately() { + var view_width = View.GetWidth(0); + var view_height = View.GetHeight(0); + + // For a classic-styled slightly offset camera, use 0.0 for X and -16.0 for Y + var cameraFocusOffsetX = 0.0; + var cameraFocusOffsetY = -16.0; + + var cameraDestinationX = cameraFocusOffsetX + this.X - (view_width / 2.0); + var cameraDestinationY = cameraFocusOffsetY + this.Y - (view_height / 2.0); + + if (cameraDestinationX < this.CameraMinX) + cameraDestinationX = this.CameraMinX; + if (cameraDestinationX > this.CameraMaxX) + cameraDestinationX = this.CameraMaxX; + if (cameraDestinationY < this.CameraMinY) + cameraDestinationY = this.CameraMinY; + if (cameraDestinationY > this.CameraMaxY) + cameraDestinationY = this.CameraMaxY; + + CameraX = Math.Clamp(cameraDestinationX, 0, this.LevelWidth - view_width); + CameraY = Math.Clamp(cameraDestinationY, 0, this.LevelHeight - view_height); + } + + //// Player + event Player_StatusNone() { } + event Player_StatusStanding() { + if (!this.Ground) { + this.Status = this.Player_StatusJumping; + this.Player_LateAirUpdate(); + return; + } + + var gspeed = this.GroundSpeed; + if (gspeed == 0.0) { + if (this.InputLeft) { + this.PushingTimer--; + } + else if (this.InputRight) { + this.PushingTimer++; + } + else { + this.PushingTimer = 0; + } + } + else if (this.InputLeft || this.InputRight) { + if (gspeed < 0) + gspeed = -gspeed; + if (gspeed > 1) + this.PushingTimer = 0; + } + else { + this.PushingTimer = 0; + } + + // If we are standing on the floor in regular gravity, + // or on the ceiling in flipped gravity. + var standingOnRelativeFloor = false; + if (this.IsUpsideDown) + standingOnRelativeFloor = this.AngleMode == 2; + else + standingOnRelativeFloor = this.AngleMode == 0; + if (!standingOnRelativeFloor) + this.PushingTimer = 0; + + this.Player_UpdateRotation(); + this.Player_HandleAcceleration(); + + if (this.CameraPtr) + this.CameraPtr.PlayerInAir = false; + + this.MidAirFlag = 0; + this.LateUpdateAirStatus = this.Player_StatusJumping; + if (this.SkidTimer <= 0) { + var pushingTimer = this.PushingTimer; + if (pushingTimer > -3 && pushingTimer < 3) { + var absGroundSpeed = Math.Abs(this.GroundSpeed); + var angle = this.Angle; + // Moving + if (absGroundSpeed != 0.0 || angle >= 0x20 && angle <= 0xE0 && !this.IsUpsideDown) { + this.WaitTimer = 0; + this.OuttaHereTimer = 0; + if (absGroundSpeed >= this.WalkThreshold) { + if (absGroundSpeed >= this.RunThreshold) { + var isCertainAnim = this.CurrentAnimation; + isCertainAnim = isCertainAnim < 8 || isCertainAnim > 9; + + if (absGroundSpeed < this.DashThreshold) { + this.AnimationSpeedMult = Math.Min((absGroundSpeed * 16.0 + 96.0), 512.0) / 128.0; + this.SetAnimation(8, isCertainAnim); + this.RunThreshold = 5.5; + this.DashThreshold = 12.0; + } + else { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(9, isCertainAnim); + this.DashThreshold = 11.5; + } + } + else { + if (this.CurrentAnimation != 5 || this.CurrentFrame == 3) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(7, 0); + } + this.AnimationSpeedMult = (absGroundSpeed * 12.0 + 64.0) / 96.0; + this.WalkThreshold = 3.5; + this.RunThreshold = 6.0; + } + } + else { + var anim = this.CurrentAnimation; + if (anim == 7) { + if (this.CurrentFrame == 9) + this.SetAnimation(5, 9); + } + else if (anim == 6) { + this.SetAnimation(5, this.CurrentFrame); + } + else { + this.SetAnimation(5, 0); + } + this.AnimationSpeedMult = (absGroundSpeed * 16.0 + 48.0) / 64.0; + this.WalkThreshold = 4.0; + } + } + // Standing + else { + this.WalkThreshold = 4.0; + this.RunThreshold = 6.0; + this.DashThreshold = 12.0; + + this.SensorRightX = 10.0; + this.SensorRightShortX = 5.0; + this.SensorMiddleX = 0.0; + this.SensorLeftShortX = -5.0; + this.SensorLeftX = -10.0; + this.SensorStartY = this.HitboxHalfH; + + // this.GroundSensorMask = 0; + this.GroundSensorMask |= 0x01 * this.Entity_CanFindTile(-69, 0, this.PlaneIndex, this.SensorRightX, this.SensorStartY, 10); + this.GroundSensorMask |= 0x02 * this.Entity_CanFindTile(-69, 0, this.PlaneIndex, this.SensorRightShortX, this.SensorStartY, 10); + this.GroundSensorMask |= 0x04 * this.Entity_CanFindTile(-69, 0, this.PlaneIndex, this.SensorMiddleX, this.SensorStartY, 10); + this.GroundSensorMask |= 0x08 * this.Entity_CanFindTile(-69, 0, this.PlaneIndex, this.SensorLeftShortX, this.SensorStartY, 10); + this.GroundSensorMask |= 0x10 * this.Entity_CanFindTile(-69, 0, this.PlaneIndex, this.SensorLeftX, this.SensorStartY, 10); + + var groundSensorMask = this.GroundSensorMask - 1; + if (groundSensorMask == 0x00 || groundSensorMask == 0x02) { + if (this.Flip || + this.UseChibiSprite == 1 || + this.Character == Character_SONIC && this.SuperForm == 2) { + this.Flip = true; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(21, 0); + } + else { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(22, 0); + } + } + else if (groundSensorMask == 0x0F || groundSensorMask == 0x17) { + if (!this.Flip || + this.UseChibiSprite == 1 || + this.Character == Character_SONIC && this.SuperForm == 2) { + this.Flip = false; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(21, 0); + } + else { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(22, 0); + } + } + else if (groundSensorMask == 0x6E || groundSensorMask == 0x73) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(21, 0); + } + else { + var v22; + // TODO: Make this simpler with an array in OnCreate + this.AnimationSpeedMult = 1.0; + if (this.Character == Character_SONIC) { + v22 = this.WaitTimer; + if (v22 != 720 || this.UseChibiSprite || this.SuperForm == 2) { + if (v22 < 240) { + this.WaitTimer = v22 + 1; + this.SetAnimation(0, 0); + } + else if (this.CurrentAnimation == 1) { + this.WaitTimer = v22 + 1; + if (this.CurrentFrame == 41) + this.WaitTimer = 0; + } + else { + this.WaitTimer = v22 + 1; + this.SetAnimation(1, 0); + } + } + else { + if (this.CurrentAnimation == 2) { + if (this.CurrentFrame == 67) + this.WaitTimer = 0; + } + else + this.SetAnimation(2, 0); + } + } + else if (this.Character == Character_TAILS) { + v22 = this.WaitTimer; + if (v22 < 240) { + this.WaitTimer = v22 + 1; + this.SetAnimation(0, 0); + } + else if (this.CurrentAnimation == 1) { + if (this.CurrentFrame == 45) + this.WaitTimer = 0; + } + else + this.SetAnimation(1, 0); + } + else if (this.Character == Character_KNUCKLES) { + v22 = this.WaitTimer; + if (v22 < 240) { + this.WaitTimer = v22 + 1; + this.SetAnimation(0, 0); + } + else if (this.CurrentAnimation == 1) { + if (this.CurrentFrame == 69) + this.WaitTimer = 0; + } + else + this.SetAnimation(1, 0); + } + else if (this.Character == Character_MIGHTY) { + v22 = this.WaitTimer; + if (v22 < 240) { + this.WaitTimer = v22 + 1; + this.SetAnimation(0, 0); + } + else if (this.CurrentAnimation == 1) { + if (this.CurrentFrame == 35) + this.WaitTimer = 0; + } + else + this.SetAnimation(1, 0); + } + else if (this.Character == Character_RAY) { + v22 = this.WaitTimer; + if (v22 < 240) { + this.WaitTimer = v22 + 1; + this.SetAnimation(0, 0); + } + else if (this.CurrentAnimation == 1) { + if (this.CurrentFrame == 55) + this.WaitTimer = 0; + } + else { + this.SetAnimation(1, 0); + } + } + + // LABEL_92: + if (this.OuttaHereTimer++ >= 72000000) { + this.SetAnimation(27, 0); + // this.Status = sub_4CCE90; + this.UseGroundSpeed = false; + this.Unk0x44 = 0; + this.LateUpdateAirStatus = null; + this.LateUpdateGroundStatus = null; + this.XSpeed = 0.0; + this.YSpeed = 0.0; + // Sound.Play(this.SFX_OuttaHere); + } + } + } + } + else { + if (pushingTimer > 3) + this.PushingTimer = 3; + if (pushingTimer < -3) + this.PushingTimer = -3; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(17, 0); + } + } + else { + var v5 = this.CurrentAnimation; + + // Custom + this.CreateSkidDust(); + + if (v5 == 13) { + if ((this.Flip && this.GroundSpeed >= 0) || + (!this.Flip && this.GroundSpeed <= 0)) { + // this.AnimationSpeedMult = 1.0; + this.SetAnimation(14, 0); + } + this.SkidTimer--; + } + else if (v5 == 14) { + this.FrameCount = 4; + if (this.CurrentFrame == this.FrameCount - 1) { + this.Flip = !this.Flip; + this.SkidTimer = 1; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(5, 0); + } + this.SkidTimer--; + } + else { + var v6 = Math.Abs(this.GroundSpeed); + this.SetAnimation(13, 0); + if (v6 >= 6.0) { + var v7 = 144.0; + if (v6 >= 10.0) + v7 = 64.0; + this.AnimationSpeedMult = v7 / 128.0; + } + else { + this.SkidTimer -= 8; + } + Sound.Play(this.SFX_Skid); + this.SkidTimer--; + } + } + + // LABEL_120: + if (this.InputJumpPressed) { + this.Player_DoJump(); + this.WaitTimer = 0; + } + else { + var absGroundSpeed = Math.Abs(this.GroundSpeed); + if (absGroundSpeed != 0.0) { + var rollThreshold = 0.53125; + if (this.Status == this.Player_StatusLookingDown) + rollThreshold = 1.0625; + + if (absGroundSpeed >= rollThreshold && !this.InputLeft && !this.InputRight && this.InputDown) { + // TODO: + this.Player_DoRoll(); + Sound.Play(this.SFX_Roll); + } + } + else { + var v28 = this.Angle; + if ((v28 < 0x20 || v28 > 0xE0) && !this.AngleMode || this.IsUpsideDown && v28 == 0x80) { + if (this.InputUp) { + this.ResetAnimation(3, 1); + this.WaitTimer = 0; + this.Status = this.Player_StatusLookingUp; + } + else if (this.InputDown) { + this.ResetAnimation(4, 1); + this.WaitTimer = 0; + this.Status = this.Player_StatusLookingDown; + } + } + } + } + } + event Player_StatusJumping() { + // TODO: + this.UseGroundSpeed = true; + this.Player_HandleAirAcceleration(); + if (this.Ground) { + this.Status = this.Player_StatusStanding; + + if (this.CameraPtr) + this.CameraPtr.PlayerInAir = false; + + this.MidAirFlag = 0; + return; + } + else { + this.Player_LateAirUpdate(); + + this.LateUpdateGroundStatus = this.Player_StatusStanding; + if (this.YSpeed > 0) { + var v4 = this.CurrentAnimation; + if (v4 >= 11) { + if (v4 <= 12) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(this.AnimationAfterSpring, 0); + } + else if (v4 == 23 && this.CurrentFrame == 0) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(6, 0); + } + } + } + + if (this.CurrentAnimation == 0 || + this.CurrentAnimation == 5) { + if (this.AnimationSpeedMult > 1.0) + this.AnimationSpeedMult = 1.0; + + this.SetAnimation(6, this.CurrentFrame); + } + else if ( + this.CurrentAnimation == 3 || + this.CurrentAnimation == 4 || + this.CurrentAnimation == 14) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(6, this.CurrentFrame); + } + else if (this.CurrentAnimation == 7) { + this.SetAnimation(6, 0); + } + else if (this.CurrentAnimation == 10) { + if (this.JumpMovesetFunc && this.YSpeed >= this.JumpReleaseSpeed) { + this.JumpMovesetFunc(); + } + } + else if (this.CurrentAnimation == 13) { + if (this.SkidTimer == 0) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(6, this.CurrentFrame % 12); + } + else + this.SkidTimer--; + } + else if (this.CurrentAnimation == 15) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + } + } + } + event Player_StatusJumping_WithInputLock() { + + } + event Player_StatusLookingDown() { + var v0, v1, v2, v3, v4, v5, v6; + + if (this.IsUpsideDown) + this.Rotation = Math_PI; + + this.InputLeft = false; + this.InputRight = false; + + this.Player_HandleAcceleration(); + + if (this.CameraPtr) + this.CameraPtr.PlayerInAir = false; + + this.MidAirFlag = 0; + this.LateUpdateAirStatus = this.Player_StatusJumping; + if (this.InputDown) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(4, 1); + if (this.CurrentFrame == 4) + this.AnimationSpeedMult = 0.0; + + if (this.WaitTimer < 60) { + this.WaitTimer++; + } + else { + v5 = this.CameraPtr; + if (v5) { + if (this.IsUpsideDown) { + if (v5.OffsetY > -96 ) + v5.OffsetY -= 2; + } + else { + if (v5.OffsetY < 96) + v5.OffsetY += 2; + } + } + } + if (this.InputJumpPressed) { + this.ResetAnimation(15, 0); + this.Status = this.Player_StatusSpinDash; + this.SpindashRev = 0.0; + this.SpindashPitch = 0; + Sound.Play(this.SFX_SpinCharge); + } + return; + } + + this.AnimationSpeedMult = 1.0; + if (this.CurrentFrame == 0 || this.InputLeft || this.InputRight) + this.Status = this.Player_StatusStanding; + + if (this.InputJumpPressed) + this.Player_DoJump(); + } + event Player_StatusLookingUp() { + if (this.IsUpsideDown) + this.Rotation = Math_PI; + + if (this.CameraPtr) + this.CameraPtr.PlayerInAir = false; + + this.MidAirFlag = 0; + this.LateUpdateAirStatus = this.Player_StatusJumping; + if (this.InputUp) { + this.SetAnimation(3, 1); + this.InputLeft = false; + this.InputRight = false; + + this.Player_HandleAcceleration(); + + if (this.CurrentFrame == 5) + this.AnimationSpeedMult = 0.0; + + if (this.WaitTimer < 60) { + this.WaitTimer++; + } + else { + var v6 = this.CameraPtr; + if (v6) { + if (this.IsUpsideDown) { + if (v6.OffsetY < 96.0) + v6.OffsetY += 2.0; + } + else { + if (v6.OffsetY > -96.0) + v6.OffsetY -= 2.0; + } + } + } + if (!this.InputJumpPressed) + return; + + if (this.GroundedUpFunc) + return this.GroundedUpFunc(); + + return this.Player_DoJump(); + } + + this.Player_HandleAcceleration(); + + this.AnimationSpeedMult = 1.0; + + if (this.CurrentFrame == 0 || this.InputLeft || this.InputRight) + this.Status = this.Player_StatusStanding; + + if (this.InputJumpPressed) + this.Player_DoJump(); + } + event Player_StatusSpinDash() { + // Custom + this.DashDustTimer = (this.DashDustTimer + 1) % 14; + + this.AnimationSpeedMult = 1.0; + if (this.InputJumpPressed) { + this.SpindashRev += 2.0; + if (this.SpindashRev > 9.0) + this.SpindashRev = 9.0; + + if (this.SpindashPitch < 12) + this.SpindashPitch++; + + this.ResetAnimation(15, 0); + Sound.Play(this.SFX_SpinCharge); + } + else { + this.SpindashRev -= this.SpindashRev / 32.0; + } + + if (!this.InputDown) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + if (this.CameraPtr) { + this.CameraLockTimer = 15; + this.CameraPtr.Status = this.CameraPtr.Camera_StatusNonFollow; + } + + var baseSpeed = 8.0; + if (this.SuperForm == 2) + baseSpeed = 11.0; + + this.GroundSpeed = this.SpindashRev / 2.0 + baseSpeed; + if (this.Flip) + this.GroundSpeed = -this.GroundSpeed; + + Sound.Stop(this.SFX_SpinCharge); + Sound.Play(this.SFX_SpinRelease); + + this.Player_DoRoll(); + } + } + event Player_StatusRoll() { + this.Player_UpdateRotation(); + this.Player_HandleRollingAcceleration(); + + this.JumpAbility = 0; + if (!this.Ground) { + this.Status = this.Player_StatusJumping; + this.Player_LateAirUpdate(); + return; + } + + if (this.Character == Character_TAILS) + this.AnimationSpeedMult = 0.5; + else + this.AnimationSpeedMult = 4.0 / Math.Max(1.0, 5.0 - Math.Abs(this.GroundSpeed)); + + if (this.CameraPtr) + this.CameraPtr.PlayerInAir = false; + + this.MidAirFlag = 0; + if (this.InputJumpPressed) + this.Player_DoJump(); + } + event Player_StatusRoll_WithInputLock() { + + } + event Player_StatusHurt() { + if (this.Ground) { + this.Status = this.Player_StatusStanding; + + var xspeed = this.XSpeed; + if (xspeed >= -2.0) { + if (xspeed <= 2.0) + this.GroundSpeed = 0.0; + else + this.GroundSpeed -= 2.0; + } + else { + this.GroundSpeed += 2.0; + } + + this.PushingTimer = 0; + this.InputLock = 0; + + if (this.CameraPtr) { + this.CameraPtr.PlayerInAir = false; + } + + this.MidAirFlag = 0; + this.SkidTimer = 0; + } + else { + if (this.CameraPtr) { + this.CameraPtr.PlayerInAir = true; + this.CameraPtr.SetOnJump = 32.0; + } + + this.SkidTimer = 0; + if (!this.Underwater) + this.YSpeed += 0.1875; + else + this.YSpeed += 0.05859375; + } + } + event Player_StatusDead() { + if (this.InvincibilityTimer) { + this.InvincibilityTimer = 0; + this.Visible = true; + } + + this.YSpeed += this.GravityRate; + this.XSpeed = 0.0; + + this.StopTimer = true; + + this.SetAnimation(19, 0); + if (!this.CannotLoseRings) { + var camera = this.CameraPtr; + if (camera) { + var maxY = camera.Y - camera.DestinationOffsetY + 384.0; + if (this.Y > maxY) + this.Y = maxY; + this.CameraLockTimer = 500; + } + } + + // if (this.YSpeed > 10.0) + if (this.YSpeed > 0.0) + Scene.Restart(); + } + event Player_StatusGimmick() { } + event Player_StatusGimmick2() { } + event Player_StatusHangingFromTails() { + var tails = null; + if (tails && tails.Status != tails.Player_StatusTails_Flying) + this.Status = this.Player_StatusJumping; + if (this.Unk_0x1D8 != this.Unk_0x1E0) + this.Status = this.Player_StatusJumping; + + if (this.Ground && this.YSpeed >= 0.0) + this.Status = this.Player_StatusStanding; + + if (this.Status == this.Player_StatusHangingFromTails) { + if (this.InputJumpPressed && this.InputDown) { + var yspeed = -4.0; + if (this.Underwater) + yspeed = -2.0; + this.YSpeed = yspeed; + this.Status = this.Player_StatusJumping; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + } + } + else if (tails) { + tails.Unk_0x1D4 = 30; + } + } + event Player_StatusSpiningTube_PGZ() { } + event Player_StatusFrozen_PGZ() { } + event Player_StatusSliding_OOZ() { } + event Player_StatusSwitchingToBG_MMZ() { } + event Player_StatusSwitchingToFG_MMZ() { } + event Player_StatusTurningSmall_MMZ() { } + event Player_StatusTurningBig_MMZ() { } + event Player_StatusFlyingIn() { } + event Player_StatusJumpingIn() { } + event Player_StatusSpringBasic() { } + event Player_StatusScoreCard() { } + event Player_StatusTransportTube_CPZ() { } + event Player_StatusTransforming() { } + // Sonic + event Player_StatusSonic_DropDash() { + var dashspeed; + var maxspeed; + if (this.Ground) { + if (this.CameraPtr) { + this.CameraPtr.PlayerInAir = false; + } + this.MidAirFlag = 0; + + if (this.InputRight) + this.Flip = false; + if (this.InputLeft) + this.Flip = true; + + if (this.SuperForm) { + dashspeed = 12.0; + maxspeed = 13.0; + this.CameraShakeTimer = 14; + } + else { + dashspeed = 8.0; + maxspeed = 12.0; + } + + if (this.Flip) { + if (this.XSpeed <= 0.0) + this.GroundSpeed = Math.Max(-maxspeed, -dashspeed + (this.GroundSpeed / 4.0)); + else if (this.Angle != 0x00) + this.GroundSpeed = -dashspeed + (this.GroundSpeed / 2.0); + else + this.GroundSpeed = -dashspeed; + } + else { + if (this.XSpeed >= 0.0) + this.GroundSpeed = Math.Min(maxspeed, dashspeed + (this.GroundSpeed / 4.0)); + else if (this.Angle != 0x00) + this.GroundSpeed = dashspeed + (this.GroundSpeed / 2.0); + else + this.GroundSpeed = dashspeed; + } + + // Set camera lag + this.CameraLockTimer = 8; + + // Spawn dust + var dust = Instance.Create("DustPuff", this.X, this.Y + this.HitboxHalfH + 1.0); + dust.SetAnimation(2, 0); + dust.Priority = this.Priority; + dust.Flip = this.Flip; + + // Stop sounds + Sound.Stop(this.SFX_DropDash); + Sound.Stop(this.SFX_SpinCharge); + if (this.SuperForm == 2) + Sound.Play(this.SFX_PeelRelease); + else + Sound.Play(this.SFX_SpinRelease); + + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + if (this.AngleMode == 0) + this.Y += this.RollHitboxDelta; + this.PushingTimer = 0; + this.Status = this.Player_StatusRoll; + return; + } + + if (this.InputJump) { + this.Player_HandleAirAcceleration(); + this.Player_LateAirUpdate(); + + this.AnimationSpeedMult = Math.Min(this.AnimationSpeedMult + 0.0625, 1.0); + } + else { + this.MidAirFlag = 0; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + this.Status = this.Player_StatusJumping; + } + } + event Player_StatusSonic_Peelout() { } + // Tails + event Player_StatusTails_Flying() { + this.Player_HandleAirAcceleration(); + if (this.Ground) { + this.Status = this.Player_StatusStanding; + this.Player_LateAirUpdate(); + return; + } + + var timeLen = 480; + // var timeLen = 80; + + var v2 = this.YSpeed; + if (v2 < -1.0) + this.RayGlideSpeedStore = 0.03125; + + if (v2 < 1.0) { + var val = this.RayGlideTurnValue; + if (val >= 60) + this.RayGlideSpeedStore = 0.03125; + else + this.RayGlideTurnValue = val + 1; + } + + this.YSpeed += this.RayGlideSpeedStore; + // if (!this.CannotLoseRings) + + if (this.WaitTimer >= timeLen) { + if (!this.Underwater) { + // if (this) + } + return; + } + + if (this.Underwater) { + this.SetAnimation(52, 0); + this.AnimationSpeedMult = 2.0; + if (this.YSpeed >= 0.0) + this.AnimationSpeedMult = 1.0; + } + else { + this.AnimationSpeedMult = 1.0; + if (this.Status != this.Player_StatusHangingFromTails || this.YSpeed >= 0.0) + this.SetAnimation(48, 0); + else + this.SetAnimation(52, 0); + + this.AnimationSpeedMult = 2.0; + if (this.YSpeed >= 0.0) + this.AnimationSpeedMult = 1.0; + } + + this.WaitTimer++; + if (this.WaitTimer == timeLen) { + if (!this.Underwater) { + // this.Underwater + this.AnimationSpeedMult = 1.0; + this.SetAnimation(49, 0); + } + else { + this.AnimationSpeedMult = 1.0; + if (this.Status == this.Player_StatusHangingFromTails) + this.SetAnimation(54, 0); + else + this.SetAnimation(53, 0); + } + } + + if (this.InputJumpPressed && (!this.Underwater)) { + if (this.InputDown) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + this.Status = this.Player_StatusJumping; + this.Player_LateAirUpdate(); + return; + } + this.RayGlideSpeedStore = -0.0625; + this.RayGlideTurnValue = 0; + } + } + event Player_StatusTails_Hanging() { } + // Knuckles + event Player_StatusKnuckles_GlidingLeft() { + var left = true; + var turnTimer, glideSpeedStore; + if (!this.Ground) { + if (this.InputJump) { + turnTimer = this.WaitTimer; + glideSpeedStore = this.RayGlideSpeedStore; + if (left ? turnTimer != 0x100 : turnTimer != 0) { + if (glideSpeedStore < 4.0) { + this.RayGlideSpeedStore = glideSpeedStore + 0.0625; + } + } + else if (glideSpeedStore < 24.0) { + this.RayGlideSpeedStore = glideSpeedStore + 0.015625; + } + + var yspeed = this.YSpeed; + if (yspeed <= 0.5) + this.YSpeed = yspeed + 0.125; + else + this.YSpeed = yspeed - 0.125; + + if (left ? turnTimer < 0x100 : turnTimer > 0) + this.WaitTimer = left ? turnTimer + 4 : turnTimer - 4; + + var check1Y, check2Y, v8, v10, v11; + if (this.UseChibiSprite) { + check1Y = -1.0; + check2Y = 3.0; + } + else { + check1Y = -2.0; + check2Y = 11.0; + } + + var postCheck1X = 0.0, postCheck2X = 0.0; + if (left ? this.WaitTimer < 0x80 : this.WaitTimer >= 0x80) { + v8 = 0; + v10 = 0; + } + else { + var initialX = this.X; + + if (left) { + this.X = initialX + this.XSpeed; + v8 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 3, this.PlaneIndex, -12.0, check1Y, true); + postCheck1X = this.X; + + this.X = initialX + this.XSpeed; + v10 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 3, this.PlaneIndex, -12.0, check2Y, true); + postCheck2X = this.X; + } + else { + this.X = initialX + this.XSpeed; + v8 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 1, this.PlaneIndex, 12.0, check1Y, true); + postCheck1X = this.X; + + this.X = initialX + this.XSpeed; + v10 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 1, this.PlaneIndex, 12.0, check2Y, true); + postCheck2X = this.X; + } + + this.X = initialX; + } + + var initXSpeed = this.XSpeed; + var outXSpeed = this.RayGlideSpeedStore * Static.HexCos(this.WaitTimer >> 1); + var v14 = initXSpeed; + this.XSpeed = outXSpeed; + + if (!initXSpeed && outXSpeed) { + v14 = 0.0; + this.RayGlideSpeedStore = 4.0; + this.XSpeed = this.RayGlideSpeedStore * Static.HexCos(this.WaitTimer >> 1); + } + + if (left ? this.InputRight : this.InputLeft) { + this.Status = left ? this.Player_StatusKnuckles_GlidingRight : this.Player_StatusKnuckles_GlidingLeft; + this.Flip = !left; + this.AnimationSpeedMult = 1.0; + this.ResetAnimation(this.CurrentAnimation, 0); + } + else if (v14 == 0.0 && this.WaitTimer == (left ? 0x100 : 0)) { + if (v8 || v10) { + this.WaitTimer = 0; + if (postCheck1X == postCheck2X) { + this.Status = this.Player_StatusKnuckles_Climbing; + this.GroundSpeed = 0.0; + this.XSpeed = 0.0; + this.YSpeed = 0.0; + Sound.Play(this.SFX_GlideGrab); + } + else { + // LABEL_32: + this.XSpeed *= 0.25; + this.RayGlideSpeedStore = 0.0; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(49, 0); + this.Status = this.Player_StatusKnuckles_Falling; + } + } + } + } + else { + // LABEL_31: + this.WaitTimer = 0; + // LABEL_32: + this.XSpeed *= 0.25; + this.RayGlideSpeedStore = 0.0; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(49, 0); + this.Status = this.Player_StatusKnuckles_Falling; + } + } + else { + if (this.AngleMode) { + this.Status = this.Player_StatusStanding; + + var camera = this.CameraPtr; + if (camera) + camera.PlayerInAir = false; + + this.MidAirFlag = 0; + this.SkidTimer = 0; + } + else { + this.WaitTimer = 0; + this.Status = this.Player_StatusKnuckles_Sliding; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(51, 0); + this.GroundSpeed = this.XSpeed; + this.CreateSkidDust(); + } + } + + // TODO: + // LABEL_38: + if (this.Y < 0.0 + 16.0) { + this.XSpeed = 0.0; + this.RayGlideSpeedStore = 0.0; + } + } + event Player_StatusKnuckles_GlidingRight() { + var left = false; + var turnTimer, glideSpeedStore; + if (!this.Ground) { + if (this.InputJump) { + turnTimer = this.WaitTimer; + glideSpeedStore = this.RayGlideSpeedStore; + if (left ? turnTimer != 0x100 : turnTimer != 0) { + if (glideSpeedStore < 4.0) { + this.RayGlideSpeedStore = glideSpeedStore + 0.0625; + } + } + else if (glideSpeedStore < 24.0) { + this.RayGlideSpeedStore = glideSpeedStore + 0.015625; + } + + var yspeed = this.YSpeed; + if (yspeed <= 0.5) + this.YSpeed = yspeed + 0.125; + else + this.YSpeed = yspeed - 0.125; + + if (left ? turnTimer < 0x100 : turnTimer > 0) + this.WaitTimer = left ? turnTimer + 4 : turnTimer - 4; + + var check1Y, check2Y, v8, v10, v11; + if (this.UseChibiSprite) { + check1Y = -1.0; + check2Y = 3.0; + } + else { + check1Y = -2.0; + check2Y = 11.0; + } + + var postCheck1X = 0.0, postCheck2X = 0.0; + if (left ? this.WaitTimer < 0x80 : this.WaitTimer >= 0x80) { + v8 = 0; + v10 = 0; + } + else { + var initialX = this.X; + + if (left) { + this.X = initialX + this.XSpeed; + v8 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 3, this.PlaneIndex, -12.0, check1Y, true); + postCheck1X = this.X; + + this.X = initialX + this.XSpeed; + v10 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 3, this.PlaneIndex, -12.0, check2Y, true); + postCheck2X = this.X; + } + else { + this.X = initialX + this.XSpeed; + v8 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 1, this.PlaneIndex, 12.0, check1Y, true); + postCheck1X = this.X; + + this.X = initialX + this.XSpeed; + v10 = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 1, this.PlaneIndex, 12.0, check2Y, true); + postCheck2X = this.X; + } + + this.X = initialX; + } + + var initXSpeed = this.XSpeed; + var outXSpeed = this.RayGlideSpeedStore * Static.HexCos(this.WaitTimer >> 1); + var v14 = initXSpeed; + this.XSpeed = outXSpeed; + + if (!initXSpeed && outXSpeed) { + v14 = 0.0; + this.RayGlideSpeedStore = 4.0; + this.XSpeed = this.RayGlideSpeedStore * Static.HexCos(this.WaitTimer >> 1); + } + + if (left ? this.InputRight : this.InputLeft) { + this.Status = left ? this.Player_StatusKnuckles_GlidingRight : this.Player_StatusKnuckles_GlidingLeft; + this.Flip = !left; + this.AnimationSpeedMult = 1.0; + this.ResetAnimation(this.CurrentAnimation, 0); + } + else if (v14 == 0.0 && this.WaitTimer == (left ? 0x100 : 0)) { + if (v8 || v10) { + this.WaitTimer = 0; + if (postCheck1X == postCheck2X) { + this.Status = this.Player_StatusKnuckles_Climbing; + this.GroundSpeed = 0.0; + this.XSpeed = 0.0; + this.YSpeed = 0.0; + Sound.Play(this.SFX_GlideGrab); + } + else { + // LABEL_32: + this.XSpeed *= 0.25; + this.RayGlideSpeedStore = 0.0; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(49, 0); + this.Status = this.Player_StatusKnuckles_Falling; + } + } + } + } + else { + // LABEL_31: + this.WaitTimer = 0; + // LABEL_32: + this.XSpeed *= 0.25; + this.RayGlideSpeedStore = 0.0; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(49, 0); + this.Status = this.Player_StatusKnuckles_Falling; + } + } + else { + if (this.AngleMode) { + this.Status = this.Player_StatusStanding; + + var camera = this.CameraPtr; + if (camera) + camera.PlayerInAir = false; + + this.MidAirFlag = 0; + this.SkidTimer = 0; + } + else { + this.WaitTimer = 0; + this.Status = this.Player_StatusKnuckles_Sliding; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(51, 0); + this.GroundSpeed = this.XSpeed; + this.CreateSkidDust(); + } + } + + // TODO: + // LABEL_38: + if (this.Y < 0.0 + 16.0) { + this.XSpeed = 0.0; + this.RayGlideSpeedStore = 0.0; + } + } + event Player_StatusKnuckles_Sliding() { + if (!this.Ground) { + this.WaitTimer = 0; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(49, 0); + this.Status = this.Player_StatusKnuckles_Falling; + return; + } + + var staticWorldInertia = 0.0; + if (this.GroundSpeed && !staticWorldInertia) { + if (!this.WaitTimer) + Sound.Play(this.SFX_GlideSlide); + + this.WaitTimer = (this.WaitTimer + 1) & 7; + if (this.CurrentFrame == 2) + this.AnimationSpeedMult = 0.0; + + var gsp = this.GroundSpeed; + if (Math.Abs(gsp) < 0.125 || !this.InputJump) { + this.ResetAnimation(this.CurrentAnimation, 3); + this.WaitTimer = 0; + this.GroundSpeed = 0.0; + } + else if (this.InputJump) { + if (gsp <= 0.0) + this.GroundSpeed = gsp + 0.125; + else + this.GroundSpeed = gsp - 0.125; + } + return; + } + + var camera = this.CameraPtr; + if (camera) + camera.PlayerInAir = false; + + this.MidAirFlag = 0; + this.AnimationSpeedMult = 1.0; + if (this.WaitTimer >= 16) { + this.Status = this.Player_StatusStanding; + this.SkidTimer = 0; + } + else { + this.WaitTimer++; + } + } + event Player_StatusKnuckles_Climbing() { + if (this.Ground) { + this.Status = this.Player_StatusStanding; + + var camera = this.CameraPtr; + if (camera) + camera.PlayerInAir = false; + + this.MidAirFlag = 0; + } + else { + if (this.InputUp) { + if (this.SuperForm == 2) + this.YSpeed = -2.0; + else + this.YSpeed = -1.0; + + var cameraMinY = 0.0 + 20.0; + if (this.Y < cameraMinY) + this.Y = cameraMinY; + } + else if (this.InputDown) { + if (this.SuperForm == 2) + this.YSpeed = 2.0; + else + this.YSpeed = 1.0; + } + else { + this.YSpeed = 0.0; + } + + if (this.InputJumpPressed) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + + this.Status = this.Player_StatusJumping; + this.JumpAbility = 0; + this.MidAirFlag = 1; + Sound.Play(this.SFX_Jump); + + if (this.Flip) { + this.XSpeed = 4.0; + this.GroundSpeed = 4.0; + this.Flip = false; + } + else { + this.XSpeed = -4.0; + this.GroundSpeed = -4.0; + this.Flip = true; + } + + this.YSpeed = -3.5; + if (this.Underwater) { + this.XSpeed *= 0.5; + this.GroundSpeed *= 0.5; + this.YSpeed = -1.75; + } + } + // TODO: + else { + this.AnimationSpeedMult = 1.0; + + this.GetHitboxFromSprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, 1); + + var checkTopY, checkWallY, offsetX, offsetY; + if (this.UseChibiSprite) { + checkTopY = -4.0; + checkWallY = 4.0; + offsetY = -12.0; + } + else { + checkTopY = -10.0; + checkWallY = 11.0; + offsetY = -20.0; + } + + var initialX = this.X; + var checkTop = false, checkWall = false; + var checkTopX = this.X; + + if (this.Flip) { + // Lfet + checkTop = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 3, this.PlaneIndex, -this.HitboxW / 2.0 - this.HitboxOffX - 1.0, checkTopY, true); + checkTopX = this.X; + + this.X = initialX; + checkWall = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 3, this.PlaneIndex, -this.HitboxW / 2.0 - this.HitboxOffX - 1.0, checkWallY, true); + + offsetX = -4.0; + if (this.YSpeed < 0.0 && this.X < checkTopX) + this.YSpeed = 0.0; + } + else { + // RIght + checkTop = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 1, this.PlaneIndex, this.HitboxW / 2.0 + this.HitboxOffX, checkTopY, true); + checkTopX = this.X; + + this.X = initialX; + checkWall = Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 1, this.PlaneIndex, this.HitboxW / 2.0 + this.HitboxOffX, checkWallY, true); + + offsetX = 4.0; + if (this.YSpeed < 0.0 && this.X > checkTopX) + this.YSpeed = 0.0; + } + + this.Y += this.YSpeed; + + // if (Static.Entity_CheckTileCollision_Move(this, 0xFFFF, 2, this.PlaneIndex, offsetX, offsetY, true)) + // this.YSpeed = 0.0; + + if (checkTop) { + if (checkWall) { + var yspeed = this.YSpeed; + if (yspeed < 0) { + this.SetAnimation(53, 0); + } + else if (yspeed > 0) { + this.SetAnimation(54, 0); + } + else { + this.SetAnimation(52, 0); + } + + this.YSpeed = 0.0; + } + else { + this.SetAnimation(49, 0); + this.YSpeed = 0.0; + this.Status = this.Player_StatusKnuckles_Falling; + } + } + else { + this.Y = Math.Floor(this.Y); + + if (this.UseChibiSprite) + this.Y -= 1.0; + else + this.Y += 2.0; + + this.YSpeed = 0.0; + this.X = initialX; + this.Status = this.Player_StatusKnuckles_GettingUp; + this.WaitTimer = 1; + this.UseGroundSpeed = false; + } + } + } + } + event Player_StatusKnuckles_GettingUp() { + this.InputLeft = false; + this.InputRight = false; + this.SetAnimation(16, 1); + + this.AutoAnimate = false; + this.Animate(); + + var frame = this.CurrentFrame; + if (this.WaitTimer != frame) { + var v7 = frame == 6; + if (frame < 6) { + this.WaitTimer = frame; + if (!this.UseChibiSprite) { + if (this.Flip) + this.X -= 5.0; + else + this.X += 5.0; + this.Y -= 8.0; + } + else { + if (this.Flip) + this.X -= 4.0; + else + this.X += 4.0; + this.Y -= 4.0; + } + } + } + if (frame == 6) { + this.Ground = true; + this.UseGroundSpeed = true; + } + if (frame == 9 - 1) { + this.WaitTimer = 0; + this.Status = this.Player_StatusStanding; + this.AutoAnimate = true; + } + } + event Player_StatusKnuckles_Falling() { + if (this.Ground) { + if (this.WaitTimer == 0) { + Sound.Play(this.SFX_GlideLand); + } + + var camera = this.CameraPtr; + if (camera) + camera.PlayerInAir = false; + + this.MidAirFlag = 0; + + var staticWorldInertia = 0.0; + if (Math.Abs(staticWorldInertia) > 2.0) { + if (staticWorldInertia <= 0.0) { + this.GroundSpeed = staticWorldInertia + 2.0; + } + else { + this.GroundSpeed = staticWorldInertia + 2.0; + } + this.XSpeed = this.GroundSpeed; + this.WaitTimer = 16; + } + else { + this.GroundSpeed = 0.0; + this.XSpeed = 0.0; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(50, 0); + } + + if (this.WaitTimer >= 16) { + this.Status = this.Player_StatusStanding; + this.SkidTimer = 0; + this.WaitTimer = 0; + } + else { + this.WaitTimer++; + } + } + else { + this.Player_HandleAirAcceleration(); + this.Player_LateAirUpdate(); + } + } + // Mighty + event Player_StatusMighty_HammerDrop() { } + event Player_StatusMighty_UnspinInvincible() { + this.Player_HandleAirAcceleration(); + if (this.Ground) { + this.Status = this.Player_StatusStanding; + if (this.CameraPtr) { + this.CameraPtr.PlayerInAir = false; + } + this.MidAirFlag = 0; + } + else { + this.InvincibilityTimer++; + if (this.CameraPtr) { + this.CameraPtr.PlayerInAir = true; + this.CameraPtr.SetOnJump = 32.0; + } + + this.Player_LateAirUpdate(); + // TODO: do this here + } + } + // Ray + event Player_StatusRay_Flying() { } + // ERSS + event Player_StatusEggReverieSuperForm() { + if (this.Character == Character_KNUCKLES) + this.SetAnimation(48, 6); + else + this.SetAnimation(8, 0); + this.Ground = false; + + // Vertical movement + if (this.InputUp) { + var yspeed = this.YSpeed; + if (yspeed > -this.TopSpeed) { + yspeed = yspeed - this.Acceleration; + if (yspeed > 0.0) + yspeed = yspeed - this.Acceleration; + this.YSpeed = yspeed; + } + } + else if (this.InputDown) { + var yspeed = this.YSpeed; + if (yspeed < this.TopSpeed) { + yspeed = yspeed + this.Acceleration; + if (yspeed < 0.0) + yspeed = yspeed + this.Acceleration; + this.YSpeed = yspeed; + } + } + else { + var absYspeed = Math.Abs(this.YSpeed); + var signYspeed = Math.Sign(this.YSpeed); + if (absYspeed < this.Friction) { + this.YSpeed = 0.0; + } + else { + this.YSpeed -= signYspeed * this.Friction; + } + } + + // Horizontal movement + if (this.InputLeft) { + var xspeed = this.XSpeed; + if (xspeed > -this.TopSpeed) { + xspeed = xspeed - this.Acceleration; + if (xspeed > 0.0) + xspeed = xspeed - this.Acceleration; + this.XSpeed = xspeed; + } + } + else if (this.InputRight) { + var xspeed = this.XSpeed; + if (xspeed < this.TopSpeed) { + xspeed = xspeed + this.Acceleration; + if (xspeed < 0.0) + xspeed = xspeed + this.Acceleration; + this.XSpeed = xspeed; + } + } + else { + var absYspeed = Math.Abs(this.YSpeed); + var signYspeed = Math.Sign(this.YSpeed); + if (absYspeed < this.Friction) { + this.YSpeed = 0.0; + } + else { + this.YSpeed -= signYspeed * this.Friction; + } + } + } + // Move Sets + event Player_MovesetSonic() { + if (this.MidAirFlag == 1) { + if (this.InputJumpPressed) { + if (this.Invincibility) { + this.MidAirFlag++; + } + else { + var shield = this.Shield; + if (shield == ShieldType_NONE) { + this.Invincibility = -8; + this.MidAirFlag = 0; + Sound.Play(this.SFX_ShieldAction_Insta); + + this.MidAirFlag++; + this.MidAirFlag++; + } + else if (shield == ShieldType_BASIC) { + this.MidAirFlag++; + } + else if (shield == ShieldType_BUBBLE) { + this.XSpeed *= 0.5; + this.YSpeed = 8.0; + // this.Status = + + + + Sound.Play(this.SFX_ShieldAction_Bubble); + } + else if (shield == ShieldType_FIRE) { + this.MidAirFlag = 0; + this.YSpeed = 0.0; + this.XSpeed = this.Flip ? -8.0 : 8.0; + + this.CameraLockTimer = 15; + + Sound.Play(this.SFX_ShieldAction_Fire); + } + else if (shield == ShieldType_ELECTRIC) { + this.MidAirFlag = 0; + this.YSpeed = -5.5; + + Sound.Play(this.SFX_ShieldAction_Electric); + } + } + } + return; + } + if (this.MidAirFlag >= 1 && this.InputJump) { + this.MidAirFlag++; + if (this.MidAirFlag > 21) { + this.Status = this.Player_StatusSonic_DropDash; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(16, 0); + Sound.Play(this.SFX_DropDash); + } + } + } + event Player_MovesetTails() { + if (this.InputJumpPressed && this.MidAirFlag == 1) { + // if (!this.IsUpsideDown) { + this.MidAirFlag = 0; + this.WaitTimer = 0; + this.RayGlideSpeedStore = 0.03125; + this.AnimationSpeedMult = 1.0; + if (!this.Underwater) + this.SetAnimation(48, 0); + else + this.SetAnimation(52, 0); + this.Status = this.Player_StatusTails_Flying; + this.LateUpdateGroundStatus = null; + this.LateUpdateAirStatus = null; + // } + } + } + event Player_MovesetKnuckles() { + if (this.InputJumpPressed && this.MidAirFlag == 1) { + // if (!this.IsUpsideDown) { + this.MidAirFlag = 0; + this.WaitTimer = 0; + this.RayGlideSpeedStore = 4.0; + if (this.YSpeed < 0.0) + this.YSpeed = 0.0; + + if (this.Flip) { + this.Status = this.Player_StatusKnuckles_GlidingLeft; + this.XSpeed = -4.0; + this.WaitTimer = 0x100; + } + else { + this.Status = this.Player_StatusKnuckles_GlidingRight; + this.XSpeed = 4.0; + this.WaitTimer = 0x0; + } + + this.LateUpdateGroundStatus = null; + this.LateUpdateAirStatus = null; + this.SetAnimation(48, 6); + // } + } + } + event Player_MovesetMighty() { } + event Player_MovesetRay() { } + event Player_MovesetERSS() { } + + // Handling + event Player_HandleFallOff() { + if (this.AngleMode != 0) { + if (this.Angle >= 0x40 && this.Angle <= 0xC0) { + if (this.GroundSpeed > -2.0 && this.GroundSpeed < 2.0) { + this.XSpeed = this.GroundSpeed * Static.HexCos(this.Angle); + this.YSpeed = this.GroundSpeed * Static.HexSin(this.Angle); + this.Ground = false; + this.Angle = 0; + this.AngleMode = 0; + } + } + } + } + event Player_HandleAcceleration() { + var inputLockTimer, + inputLeft, + inputRight; + + inputLockTimer = this.InputLock; + if (inputLockTimer > 0) { + this.InputLock = inputLockTimer - 1; + if (this.IsUpsideDown) + return; + + this.GroundSpeed += Static.HexSin(this.Angle) * 0.125; + return this.Player_HandleFallOff(); // goto LABEL_69; + } + else { + if (this.IsUpsideDown) { + inputLeft = this.InputRight; + inputRight = this.InputLeft; + } + else { + inputLeft = this.InputLeft; + inputRight = this.InputRight; + } + + if (inputLeft) { + if (this.GroundSpeed > -this.TopSpeed) { + // Going left + if (this.GroundSpeed <= 0.0) { + this.GroundSpeed -= this.Acceleration; + } + // Going right + else { + if (!this.AngleMode && this.GroundSpeed > 4.0) { // && !Zone_Info->dword154 + this.Flip = false; + this.SkidTimer = 24; + } + + if (this.GroundSpeed < this.Deceleration) + this.GroundSpeed = -this.Deceleration; + else + this.GroundSpeed -= this.Deceleration; + } + } + if (this.GroundSpeed <= 0.0 && this.SkidTimer < 1) + this.Flip = true; + } + if (inputRight) { + if (this.GroundSpeed < this.TopSpeed) { + // Going right + if (this.GroundSpeed >= 0.0) { + this.GroundSpeed += this.Acceleration; + } + // Going left + else { + if (!this.AngleMode && this.GroundSpeed < -4.0) { // && !Zone_Info->dword154 + this.Flip = true; + this.SkidTimer = 24; + } + + if (this.GroundSpeed > -this.Deceleration) + this.GroundSpeed = this.Deceleration; + else + this.GroundSpeed += this.Deceleration; + } + } + if (this.GroundSpeed >= 0.0 && this.SkidTimer < 1) + this.Flip = false; + } + + if (this.InputLeft || this.InputRight) { + if (this.IsUpsideDown) + return; + + // Slope + this.GroundSpeed += Static.HexSin(this.Angle) * 0.125; + + if (this.InputRight) { + if (!this.InputLeft) { + if (this.Angle > 0xC0 && this.Angle < 0xE4 && + this.GroundSpeed > -2.0 && this.GroundSpeed < 2.5) { + this.InputLock = 30; + } + } + } + else { + if (this.InputLeft) { + if (this.Angle > 0x1C && this.Angle < 0x40 && + this.GroundSpeed < 2.0 && this.GroundSpeed > -2.5) { + this.InputLock = 30; + } + } + } + + // LABEL_69: + return this.Player_HandleFallOff(); + } + + var spd; + if (this.GroundSpeed <= 0.0) { + spd = this.GroundSpeed + this.Friction; + if (spd > 0.0) + spd = 0.0; + this.GroundSpeed = spd; + } + else { + spd = this.GroundSpeed - this.Friction; + if (spd < 0.0) + spd = 0.0; + this.GroundSpeed = spd; + } + + if (!this.IsUpsideDown) { + if (this.GroundSpeed > 0.125 || this.GroundSpeed < -0.125) + this.GroundSpeed += Static.HexSin(this.Angle) * 0.125; + + if ((this.Angle <= 0xC0 || this.Angle >= 0xE4) && (this.Angle <= 0x1C || this.Angle >= 0x40)) + return this.Player_HandleFallOff(); + + if (this.GroundSpeed > -1.0 && this.GroundSpeed < 1.0) + this.InputLock = 30; + else + return this.Player_HandleFallOff(); + } + } + } + event Player_HandleRollingAcceleration() { + // var canMoveLeftRight = this.InputLock == 0; + + var rollDeceleration = this.RollDeceleration; + var rollFriction = this.RollFriction; + + // Rolling ground deceleration + if (this.InputLeft) { + if (this.GroundSpeed > 0.0) + this.GroundSpeed -= rollDeceleration; + } + else if (this.InputRight) { + if (this.GroundSpeed < 0.0) + this.GroundSpeed += rollDeceleration; + } + + // Rolling friction + if (Math.Abs(this.GroundSpeed) < rollFriction) + this.GroundSpeed = 0.0; + else + this.GroundSpeed -= Math.Sign(this.GroundSpeed) * rollFriction; + + // Rolling slope acceleration + var sin = -Static.HexSin(this.Angle); + if (Math.Sign(this.GroundSpeed) == Math.Sign(sin)) + sin = (this.SlopeRollUp * sin); + else + sin = (this.SlopeRollDown * sin); + + if (Math.Abs(this.GroundSpeed) < Math.Abs(sin)) + this.GroundSpeed = 0.0; + else + this.GroundSpeed -= sin; + + // Hard Roll Speed Cap in Mania + this.GroundSpeed = Math.Clamp(this.GroundSpeed, -18.0, 18.0); + + // Handle stopping and fall off + if (this.AngleMode == 0) { + if (this.Status == this.Player_StatusRoll_WithInputLock) { + if (Math.Abs(this.GroundSpeed) < 1.0) + this.GroundSpeed = this.Flip ? -4.0 : 4.0; + } + else { + if (Math.Abs(this.GroundSpeed) < rollFriction) { + this.Status = this.Player_StatusStanding; + this.GroundSpeed = 0.0; + } + } + } + else if (this.AngleMode == 2) { + if (this.IsUpsideDown) { + if (Math.Abs(this.GroundSpeed) < rollFriction) { + this.Status = this.Player_StatusStanding; + this.GroundSpeed = 0.0; + } + } + else { + this.Player_HandleFallOff(); + } + } + else { + this.Player_HandleFallOff(); + } + + + } + event Player_HandleAirAcceleration() { + if (this.YSpeed < 0.0 && this.YSpeed > -4.0) { + this.XSpeed -= this.XSpeed / 32.0; + } + + // Air acceleration + if (this.InputLeft) { + if (this.XSpeed > -this.TopSpeed) + this.XSpeed -= this.AirAcceleration; + this.Flip = true; + } + else if (this.InputRight) { + if (this.XSpeed < this.TopSpeed) + this.XSpeed += this.AirAcceleration; + this.Flip = false; + } + } + + event Player_DoJump() { + var v2, v3; + var jumpHeight = this.JumpHeight; + if (this.Underwater) + jumpHeight -= 3.0; + + v2 = this.GravityRate + jumpHeight; + this.InputLock = 0; + this.Ground = false; + // TODO: + if (this.AngleMode == 0 && this.Status != this.Player_StatusRoll) + this.Y += this.RollHitboxDelta; + + this.XSpeed = this.GroundSpeed * Static.HexCos(this.Angle); + this.YSpeed = this.GroundSpeed * Static.HexSin(this.Angle); + this.XSpeed -= jumpHeight * -Static.HexSin(this.Angle); + this.YSpeed -= jumpHeight * Static.HexCos(this.Angle); + + // TODO: + var camera; + if (camera = this.CameraPtr) { + camera.PlayerInAir = true; + camera.SetOnJump = 32.0; + } + this.SetAnimation(10, 0); + if (this.Character == Character_TAILS) { + this.AnimationSpeedMult = 0.5; + } + else { + this.AnimationSpeedMult = 4.0 / Math.Max(1.0, 5.0 - Math.Abs(this.GroundSpeed)); + } + + this.Angle = 0; + this.AngleMode = 0; + this.SkidTimer = 0; + this.JumpAbility = 1; + this.MidAirFlag = 1; + this.Status = this.Player_StatusJumping; + + Sound.Play(this.SFX_Jump); + } + event Player_DoRoll() { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + + this.PushingTimer = 0; + this.Status = this.Player_StatusRoll; + if (this.AngleMode == 0) { + this.Y += this.RollHitboxDelta; + } + } + event Player_DoMightyUnspin(speed, makeInvinc, entity, value) { + if (this.Character != Character_MIGHTY) + return false; + + var playerStatus = this.Status; + if (playerStatus == this.Player_StatusHurt || + playerStatus == this.Player_StatusDead || + // playerStatus == this.Player_ || + playerStatus == this.Invincibility || + playerStatus == this.InvincibilityTimer > 0) + return false; + + var anim = this.CurrentAnimation; + if (anim == 10 || anim == 15 || anim == 16) { + var angle = Math.Atan(this.X - entity.X, this.Y - entity.Y); + var xspeed = speed * Math.Cos(angle); + var yspeed = speed * Math.Sin(angle); + + if (anim != 48) { + this.XSpeed = xspeed; + this.GroundSpeed = xspeed; + } + this.YSpeed = yspeed; + + if (makeInvinc) { + if (this.Status == this.Player_StatusMighty_HammerDrop) { + this.Status = this.Player_StatusJumping; + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + } + + if (this.CurrentAnimation == 15) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(10, 0); + if (this.Status == this.Player_StatusSpinDash) { + if (this.Ground) + this.Status = this.Player_StatusRoll; + else + this.Status = this.Player_StatusJumping; + } + } + } + else { + this.YSpeed = -4.5; + if (!this.Flip) + this.XSpeed = -2.5; + else + this.XSpeed = 2.5; + + if (this.Underwater) { + this.XSpeed *= 0.5; + this.YSpeed = -2.25; + } + + this.InvincibilityTimer = 121; + this.Visible = 1; + + this.AnimationSpeedMult = 1.0; + this.SetAnimation(48, 0); + Sound.Play(this.SFX_MightyUnspin); + + this.Ground = false; + this.JumpAbility = 0; + this.MidAirFlag = 0; + this.Status = this.Player_StatusMighty_UnspinInvincible; + } + + this.JumpAbility = 0; + if (value < 1) { + if (this.CurrentAnimation != 48) + Sound.Play(this.SFX_PimPom); + + this.Unk_0x234 = 8; + } + return true; + } + + if (makeInvinc != 2 || anim != 4) + return false; + + if (this.Unk_0x234) + return true; + + Sound.Play(this.SFX_PimPom); + this.Unk_0x234 = 30; + + if (entity.X <= this.X) + this.GroundSpeed = 1.0; + else + this.GroundSpeed = -1.0; + + return true; + } + event Player_LateAirUpdate() { + if (this.CameraPtr) { + this.CameraPtr.SetOnJump = 32.0; + this.CameraPtr.PlayerInAir = true; + } + + this.YSpeed += this.GravityRate; + if (this.YSpeed < this.JumpReleaseSpeed && this.CurrentAnimation == 10 && !this.InputJump && this.JumpAbility == 1) { + this.YSpeed = this.JumpReleaseSpeed; + this.XSpeed = this.XSpeed - this.XSpeed / 32.0; + } + + this.AngleMode = 0; + this.PushingTimer = 0; + + var amount = Math_PI_DOUBLE * (4.0 / 0x200); + var rotation = this.Rotation; + if (rotation < 0.0) + this.Rotation += amount; + else if (rotation > 0.0) + this.Rotation -= amount; + if (Math.Abs(rotation) < amount) + this.Rotation = 0.0; + } + + event Player_UpdateRotation() { + var rot = this.HexToRadians((this.Angle + 0x10) & 0xE0); + // Classic rotation + if (false) { + this.Rotation = rot; + + if (this.GetAngleMode(this.Angle) == 0 && this.Ground) + this.Rotation = 0.0; + } + // Mania rotation + else { + var angle = this.Angle; + // print "angle: " + angle; + if (angle <= 0x04 || angle >= 0xFC) { + if (angle > 0x10 && angle < 0xE8) + this.Rotation = this.HexToRadians(angle); + else + this.Rotation = 0.0; + } + else { + rot = this.HexToRadians(angle); + if (angle <= 0x10 || angle >= 0xE8) + rot = 0.0; + + if (Math.Abs(this.GroundSpeed) <= 6.0) + this.Rotation += (((rot - this.Rotation + Math_PI_DOUBLE * 1.5) % Math_PI_DOUBLE) - Math_PI) / 4.0; + else + this.Rotation += (((rot - this.Rotation + Math_PI_DOUBLE * 1.5) % Math_PI_DOUBLE) - Math_PI) / 2.0; + } + } + + if (this.CurrentAnimation == 10) + this.Rotation = 0.0; + } + + event Player_ResetSpeeds() { + var gravity; + var isUnderwater = this.Underwater; + var speedShoesTimer = this.SpeedShoesTimer; + if (isUnderwater) { + gravity = 0.125; + if (speedShoesTimer >= 0) + gravity = 0.0625; + } + else { + gravity = 0.34375; + if (speedShoesTimer >= 0) + gravity = 0.21875; + } + this.GravityRate = gravity; + + var isSuper = this.SuperForm == 2; + var frictionMult = 1.0; + if (isSuper) { + frictionMult = 0.25; + } + if (speedShoesTimer > 0) { + frictionMult = 0.5; + } + // Custom: I don't want Speed Shoes /slowing/ down Super Forms + if (isSuper) { + frictionMult = 0.25; + } + + this.TopSpeed = 6.0; + this.Acceleration = 0.046875; + this.Friction = 0.046875 * frictionMult; + this.AirAcceleration = 0.09375; + this.Unk_0x158 = 0.0234375; + this.Slope = 0.125; + this.SlopeRollUp = 0.078125; + this.SlopeRollDown = 0.3125; + this.Deceleration = 0.5; + this.RollFriction = 0.0234375; + this.JumpHeight = this.JumpHeights[this.Character]; + this.JumpReleaseSpeed = -4.0; + this.RollDeceleration = 0.125; + + if (isUnderwater) { + this.TopSpeed *= 0.5; + this.Acceleration *= 0.5; + this.AirAcceleration *= 0.5; + this.Deceleration *= 0.5; + this.RollFriction *= 0.5; + } + + if (speedShoesTimer < 0) { + this.TopSpeed *= 0.5; + this.Acceleration *= 0.5; + this.AirAcceleration *= 0.5; + this.Deceleration *= 0.5; + this.RollFriction *= 0.5; + this.Unk_0x158 *= 0.5; + } + + if (this.UseChibiSprite) { + this.TopSpeed -= this.TopSpeed / 8.0; + this.Acceleration -= this.Acceleration / 16.0; + this.AirAcceleration -= this.AirAcceleration / 16.0; + this.JumpHeight -= this.JumpHeight / 8.0; + this.JumpReleaseSpeed -= this.JumpReleaseSpeed / 8.0; + } + } + + event UpdateHitbox(index) { + // if (this.StaticHitbox) { + // + // } + // else { + this.GetHitboxFromSprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, index); + // } + } + + // Entity + event CheckLeftWall(x, y) { + // -1.0, 0.0 + // -this.FloorDirection_Y, -this.FloorDirection_X + if (this.WallSensor_Collided = this.SenseTileCollision(x, y, CollideSide_RIGHT, -this.FloorDirection_Y, -this.FloorDirection_X, -8.0, 1.0)) { + this.WallSensor_X = Math.Floor(this.STC_X); + this.WallSensor_Y = this.STC_Y; + // this.WallSensor_Angle = this.STC_Angle; + this.WallSensor_Length = this.STC_Length; + } + return this.WallSensor_Collided; + } + event CheckRightWall(x, y) { + // Setting the end thing to 0.0 seems to make this work in air + // 1.0, 0.0 + // this.FloorDirection_Y, this.FloorDirection_X + if (this.WallSensor_Collided = this.SenseTileCollision(x, y, CollideSide_LEFT, this.FloorDirection_Y, this.FloorDirection_X, -8.0, 1.0)) { + this.WallSensor_X = Math.Floor(this.STC_X); + this.WallSensor_Y = this.STC_Y; + // this.WallSensor_Angle = this.STC_Angle; + this.WallSensor_Length = this.STC_Length; + } + return this.WallSensor_Collided; + } + event CheckCeilLeftSensor(x, y) { + if (this.LeftCeilSensor_Collided = this.SenseTileCollision(x, y, this.FloorSensor_Side ^ 5, this.FloorDirection_X, -this.FloorDirection_Y, -10.0, 0.0)) { + this.LeftCeilSensor_X = this.STC_X; + this.LeftCeilSensor_Y = this.STC_Y; + this.LeftCeilSensor_Angle = this.STC_Angle; + this.LeftCeilSensor_Length = this.STC_Length; + } + return this.LeftCeilSensor_Collided; + } + event CheckCeilRightSensor(x, y) { + if (this.RightCeilSensor_Collided = this.SenseTileCollision(x, y, this.FloorSensor_Side ^ 5, this.FloorDirection_X, -this.FloorDirection_Y, -10.0, 0.0)) { + this.RightCeilSensor_X = this.STC_X; + this.RightCeilSensor_Y = this.STC_Y; + this.RightCeilSensor_Angle = this.STC_Angle; + this.RightCeilSensor_Length = this.STC_Length; + } + return this.RightCeilSensor_Collided; + } + event CheckFloorLeftSensor(x, y, initialAngle) { + if (this.LeftSensor_Collided = this.SenseTileCollision(x, y, 0x10 | this.FloorSensor_Side, this.FloorDirection_X, this.FloorDirection_Y, -14.0, this.MaxTileCollision)) { + if (initialAngle != -1 && + Math.Abs(((initialAngle - this.STC_Angle + 0x80) & 0xFF) - 0x80) > 0x20) { + return this.LeftSensor_Collided = false; + } + if (this.STC_Length <= -14.0) + return this.LeftSensor_Collided = false; + this.LeftSensor_X = this.STC_X; + this.LeftSensor_Y = this.STC_Y; + this.LeftSensor_Angle = this.STC_Angle; + this.LeftSensor_Length = this.STC_Length; + } + return this.LeftSensor_Collided; + } + event CheckFloorMiddleSensor(x, y, initialAngle) { + if (this.MiddleSensor_Collided = this.SenseTileCollision(x, y, 0x10 | this.FloorSensor_Side, this.FloorDirection_X, this.FloorDirection_Y, -14.0, this.MaxTileCollision)) { + if (initialAngle != -1 && + Math.Abs(((initialAngle - this.STC_Angle + 0x80) & 0xFF) - 0x80) > 0x20) { + return this.MiddleSensor_Collided = false; + } + if (this.STC_Length <= -14.0) + return this.MiddleSensor_Collided = false; + this.MiddleSensor_X = this.STC_X; + this.MiddleSensor_Y = this.STC_Y; + this.MiddleSensor_Angle = this.STC_Angle; + this.MiddleSensor_Length = this.STC_Length; + } + return this.MiddleSensor_Collided; + } + event CheckFloorRightSensor(x, y, initialAngle) { + if (this.RightSensor_Collided = this.SenseTileCollision(x, y, 0x10 | this.FloorSensor_Side, this.FloorDirection_X, this.FloorDirection_Y, -14.0, this.MaxTileCollision)) { + if (initialAngle != -1 && + Math.Abs(((initialAngle - this.STC_Angle + 0x80) & 0xFF) - 0x80) > 0x20) { + return this.RightSensor_Collided = false; + } + if (this.STC_Length <= -14.0) + return this.RightSensor_Collided = false; + this.RightSensor_X = this.STC_X; + this.RightSensor_Y = this.STC_Y; + this.RightSensor_Angle = this.STC_Angle; + this.RightSensor_Length = this.STC_Length; + } + return this.RightSensor_Collided; + } + event SenseTileCollision(x, y, side, dirX, dirY, startLen, endLen) { + x += dirX * startLen; + y += dirY * startLen; + + var angle; + for (var i = startLen; i < endLen; i += 1.0) { + angle = TileCollision.PointExtended(x, y, this.PlaneIndex, side); + if (angle >= 0) { + this.STC_X = Math.Floor(x); + this.STC_Y = Math.Floor(y); + this.STC_Angle = angle; + this.STC_Length = i; + return true; + } + + x += dirX; + y += dirY; + } + return false; + } + event InitGroundSensors(initialX, initialY, initialAngle, angleMode) { + var floor_sensor_cos = this.SensorABCD_Ground_cos; + var floor_sensor_sin = this.SensorABCD_Ground_sin; + var wall_sensor_cos = this.SensorEF_cos; + var wall_sensor_sin = this.SensorEF_sin; + var simple_cos = this.simple_cos; + var simple_sin = this.simple_sin; + var simple_side = this.simple_side; + + this.FloorDirection_X = simple_sin[angleMode]; + this.FloorDirection_Y = simple_cos[angleMode]; + this.FloorSensor_Side = simple_side[angleMode]; + + var wall_x = initialX; + var wall_y = initialY + this.CheckCenterOffY; + // 1 | 3 + if (angleMode & 1) + wall_y = initialY; + + var foot_x = initialX + this.HitboxHalfH * this.FloorDirection_X; + var foot_y = initialY + this.HitboxHalfH * this.FloorDirection_Y; + this.LeftSensor_X = foot_x - floor_sensor_cos[angleMode]; + this.LeftSensor_Y = foot_y - floor_sensor_sin[angleMode]; + this.RightSensor_X = foot_x + floor_sensor_cos[angleMode]; + this.RightSensor_Y = foot_y + floor_sensor_sin[angleMode]; + this.MiddleSensor_X = foot_x; + this.MiddleSensor_Y = foot_y; + if (this.GroundSpeed <= 0.0) { + this.WallSensor_X = wall_x - wall_sensor_cos[angleMode] - 1.0; + this.WallSensor_Y = wall_y - wall_sensor_sin[angleMode]; + } + else { + this.WallSensor_X = wall_x + wall_sensor_cos[angleMode]; + this.WallSensor_Y = wall_y + wall_sensor_sin[angleMode]; + } + this.LeftSensor_Angle = + this.RightSensor_Angle = + this.MiddleSensor_Angle = initialAngle; + this.LeftSensor_Length = + this.RightSensor_Length = + this.MiddleSensor_Length = 0; + this.LeftSensor_Collided = + this.RightSensor_Collided = + this.MiddleSensor_Collided = + this.WallSensor_Collided = false; + } + event InitAirSensors(initialX, initialY) { + var floor_sensor_cos = this.SensorEF_cos; // this.SensorABCD_Air_cos; + var floor_sensor_sin = this.SensorEF_sin; // this.SensorABCD_Air_sin; + var wall_sensor_cos = this.SensorEF_cos; + var wall_sensor_sin = this.SensorEF_sin; + var simple_cos = this.simple_cos; + var simple_sin = this.simple_sin; + var simple_side = this.simple_side; + + this.FloorDirection_X = 0.0; + this.FloorDirection_Y = 1.0; + this.FloorSensor_Side = CollideSide_TOP; + + var wall_x = initialX; + var wall_y = initialY + this.CheckCenterOffY; + var foot_x = initialX; + var foot_y = initialY + this.HitboxHalfH; + var head_x = initialX; + var head_y = initialY - this.HitboxHalfH - 1.0; + + // Moving right + if (this.XSpeed >= 0.0) { + this.WallSensor_X = wall_x + wall_sensor_cos[0]; + this.WallSensor_Y = wall_y; + } + // Moving left + if (this.XSpeed <= 0.0) { + this.WallSensor_X = wall_x - wall_sensor_cos[0] - 1.0; + this.WallSensor_Y = wall_y; + } + + // Moving down + this.LeftSensor_X = foot_x - floor_sensor_cos[0] + 1; + this.LeftSensor_Y = foot_y; + this.RightSensor_X = foot_x + floor_sensor_cos[0] - 2; + this.RightSensor_Y = foot_y; + + this.LeftCeilSensor_X = head_x - floor_sensor_cos[0] + 1; + this.LeftCeilSensor_Y = head_y; + this.RightCeilSensor_X = head_x + floor_sensor_cos[0] - 2; + this.RightCeilSensor_Y = head_y; + + this.LeftSensor_Angle = + this.RightSensor_Angle = + this.LeftCeilSensor_Angle = + this.RightCeilSensor_Angle = 0; + this.LeftSensor_Collided = + this.RightSensor_Collided = + this.LeftCeilSensor_Collided = + this.RightCeilSensor_Collided = + this.WallSensor_Collided = false; + } + event Entity_GroundMovement() { + // NOTE: More parts = more precision & more CPU usage + // Mania uses 4.0, we will use 4.0 until otherwise. + var parts = 4.0; + + var groundSpeed = Math.Abs(this.GroundSpeed); + var speedPart = Math.Floor(groundSpeed / parts); + var speedFraction = groundSpeed - speedPart * parts; + var speedPartRemain = speedFraction; + + var angle, angleMode, gsp, cos, sin, deltaX, deltaY; + + var initialX = this.X; + var initialY = this.Y; + var initialAngle = this.Angle; + + var wall_sensor_cos = this.SensorEF_cos; + var wall_sensor_sin = this.SensorEF_sin; + + var sensorsAngle = this.sensorsAngle; + var sensorsLength = this.sensorsLength; + var sensorsCollided = this.sensorsCollided; + + gsp = this.GroundSpeed; + + this.InitGroundSensors(initialX, initialY, initialAngle, this.AngleMode); + + var count = 0; + while (speedPartRemain >= 0.0) { + angle = this.Angle; + angleMode = this.AngleMode; + cos = Static.HexCos(angle); + sin = Static.HexSin(angle); + if (speedPart > 0.0) { + deltaX = cos * parts; + deltaY = sin * parts; + speedPartRemain = speedPart - 1.0; + } + else { + deltaX = speedFraction * cos; + deltaY = speedFraction * sin; + speedPartRemain = -1.0; + } + + if (gsp < 0.0) { + deltaX = -deltaX; + deltaY = -deltaY; + } + + // if (!this.WallSensor_Collided) + this.InitGroundSensors(initialX, initialY, initialAngle, angleMode); + + initialX += deltaX; + initialY += deltaY; + + // TODO: Fix + // Check Walls here + if (gsp <= 0) { + // CheckLeftWall, max left 0xE past hitbox + if (angleMode == 0) + if (this.CheckLeftWall(this.WallSensor_X, this.WallSensor_Y)) { + speedPartRemain = -1; + if (!(angleMode & 1)) + deltaX = 0.0; + else + deltaY = 0.0; + if (angleMode == 0) + this.LeftSensor_X = this.WallSensor_X + 2.0; + } + } + else { + // CheckRightWall + if (angleMode == 0) + if (this.CheckRightWall(this.WallSensor_X, this.WallSensor_Y)) { + speedPartRemain = -1; + if (!(angleMode & 1)) + deltaX = 0.0; + else + deltaY = 0.0; + if (angleMode == 0) + this.RightSensor_X = this.WallSensor_X - 2.0; + } + } + + // if (angleMode != 0) { + // print "this.Angle: " + this.Angle; + // print "initialAngle: " + initialAngle; + // } + + // Check Floor here + this.LeftSensor_X += deltaX; + this.MiddleSensor_X += deltaX; + this.RightSensor_X += deltaX; + this.LeftSensor_Y += deltaY; + this.MiddleSensor_Y += deltaY; + this.RightSensor_Y += deltaY; + this.CheckFloorLeftSensor(this.LeftSensor_X, this.LeftSensor_Y, initialAngle); + this.CheckFloorMiddleSensor(this.MiddleSensor_X, this.MiddleSensor_Y, initialAngle); + this.CheckFloorRightSensor(this.RightSensor_X, this.RightSensor_Y, initialAngle); + + // Determine sensor to use + var highestSensor = -1; + sensorsAngle[0] = this.LeftSensor_Angle; + sensorsAngle[1] = this.MiddleSensor_Angle; + sensorsAngle[2] = this.RightSensor_Angle; + sensorsLength[0] = this.LeftSensor_Length; + sensorsLength[1] = this.MiddleSensor_Length; + sensorsLength[2] = this.RightSensor_Length; + sensorsCollided[0] = this.LeftSensor_Collided; + sensorsCollided[1] = this.MiddleSensor_Collided; + sensorsCollided[2] = this.RightSensor_Collided; + + // Get highest sensor + for (var i = 0; i < 3; i++) { + if (highestSensor == -1) { + if (sensorsCollided[i]) + highestSensor = i; + } + else if (sensorsCollided[i]) { + var currentLen = sensorsLength[i]; + var highestLen = sensorsLength[highestSensor]; + + // if (angleMode != 0) { + // print "sensorsAngle["+i+"]: " + sensorsAngle[i]; + // print "sensorsLength["+i+"]: " + sensorsLength[i]; + // } + + if (currentLen < highestLen) { + highestSensor = i; + } + else if (currentLen == highestLen) { + var currentAngle = sensorsAngle[i]; + if (angleMode == 0) { + if (currentAngle < 0x08 || currentAngle > 0xF8) + highestSensor = i; + } + else { + highestSensor = i; + } + } + } + } + + // Set future positions + var finalAngle = -1; + if (highestSensor == -1) { + finalAngle = initialAngle; + speedPartRemain = -1; + } + else { + finalAngle = sensorsAngle[highestSensor]; + initialX += sensorsLength[highestSensor] * this.FloorDirection_X; + initialY += sensorsLength[highestSensor] * this.FloorDirection_Y; + } + + // Change AngleMode + // For some reason the AngleMode used in Mania and 3K is so different + // if (3KBased) this.AngleMode = this.GetAngleMode(this.Angle ^ 0xFF) >> 6; + // var lastAngleMode = this.AngleMode; + if (this.AngleMode == 0) { // 0x00 +/- 0x22 + if (((finalAngle + 0x7F) & 0xFF) <= 0x5C) + this.AngleMode = 1; + if (((finalAngle - 0x23 + 0x100) & 0xFF) <= 0x5C) + this.AngleMode = 3; + } + else if (this.AngleMode == 1) { // 0xC0 +/- 0x22 + if (finalAngle > 0xE2) + this.AngleMode = 0; + if (finalAngle < 0x9E) + this.AngleMode = 2; + } + else if (this.AngleMode == 2) { // 0x80 +/- 0x22 + if (finalAngle > 0xA2) + this.AngleMode = 1; + if (finalAngle < 0x5E) + this.AngleMode = 3; + } + else if (this.AngleMode == 3) { // 0x40 +/- 0x22 + if (finalAngle > 0x62) + this.AngleMode = 2; + if (finalAngle < 0x1E) + this.AngleMode = 0; + } + + // if (this.AngleMode != lastAngleMode) { + // print "this.AngleMode: " + lastAngleMode + " -> " + this.AngleMode; + // } + + if (this.WallSensor_Collided) + break; + + // if (highestSensor != -1) { + this.Angle = finalAngle; + // } + + speedPart = speedPartRemain; + } + + // On floor? + if (this.LeftSensor_Collided || this.MiddleSensor_Collided || this.RightSensor_Collided) { + if (this.WallSensor_Collided) { + // TODO: Make these AngleMode agnostic + if (gsp < 0.0) { + this.X = this.WallSensor_X + wall_sensor_cos[angleMode] + 1.0; + this.Y = initialY; + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + } + else if (gsp > 0.0) { + this.X = this.WallSensor_X - wall_sensor_cos[angleMode]; + this.Y = initialY; + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + } + else { + this.Y = initialY; + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + } + } + else { + this.X = initialX; + this.Y = initialY; + } + } + // Not on floor + else { + this.Ground = false; + + this.XSpeed = this.GroundSpeed * Static.HexCos(this.Angle); + this.YSpeed = this.GroundSpeed * Static.HexSin(this.Angle); + + this.YSpeed = Math.Clamp(this.YSpeed, -16.0, 16.0); + + this.GroundSpeed = this.XSpeed; + this.Angle = 0; + this.AngleMode = 0; + if (this.WallSensor_Collided) { + if (this.XSpeed < 0.0) { + this.X = this.WallSensor_X + wall_sensor_cos[angleMode] + 1.0; + this.Y += this.YSpeed; + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + } + else if (this.XSpeed > 0.0) { + this.X = this.WallSensor_X - wall_sensor_cos[angleMode]; + this.Y += this.YSpeed; + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + } + else { + this.Y += this.YSpeed; + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + } + } + else { + this.X += this.XSpeed; + this.Y += this.YSpeed; + } + } + } + event Entity_AirMovement() { + var movingUp = false; + var movingDown = false; + var movingLeft = false; + var movingRight = false; + + var xspeed = this.XSpeed; + var yspeed = this.YSpeed; + + // NOTE: This is a custom addition + this.Angle = 0; + this.AngleMode = 0; + // this.HitboxHalfH = 15.0; + + // Determine if moving right + if (xspeed >= 0.0) { + movingRight = true; + } + if (xspeed <= 0.0) { + movingLeft = true; + } + if (yspeed >= 0.0) { + movingDown = true; + } + if (Math.Abs(xspeed) > 1.0 || yspeed <= 0.0) { + movingUp = true; + } + + // var doSensor; + var absXSpeed = Math.Abs(xspeed); + var absYSpeed = Math.Abs(yspeed); + var absMaxSpeed = Math.Max(absXSpeed, absYSpeed); + var speedDivisor = ((Number.AsInteger(absMaxSpeed) << 16) >> this.SpeedPartitionValue) + 1.0; + var xspeedPart = xspeed / speedDivisor; + var yspeedPart = yspeed / speedDivisor; + var xspeedFraction = xspeed - xspeedPart * (speedDivisor - 1.0); + var yspeedFraction = yspeed - yspeedPart * (speedDivisor - 1.0); + + var originalXSpeed = this.XSpeed; + + var speedPartRemain, deltaX, deltaY; + if (speedDivisor > 0) { + deltaX = deltaY = 0.0; + while (true) { + if (speedDivisor >= 2.0) { + deltaX += xspeedPart; + deltaY += yspeedPart; + } + else { + deltaX += xspeedFraction; + deltaY += yspeedFraction; + } + speedPartRemain = speedDivisor - 1.0; + + this.InitAirSensors(this.X + deltaX, this.Y + deltaY); + + // print "Y: " + (this.Y + deltaY); + // print "this.LeftSensor_Y: " + this.LeftSensor_Y; + // print "distance: " + (this.LeftSensor_Y - (this.Y + deltaY)); + + // Check for right wall collision + if (movingRight == 1) { + if (this.CheckRightWall(this.WallSensor_X, this.WallSensor_Y)) { + movingRight = 2; + } + else if (this.XSpeed < 2.0 && this.CheckCenterOffY > 0.0) { + if (this.CheckRightWall(this.WallSensor_X, this.WallSensor_Y - 2.0 * this.CheckCenterOffY)) + movingRight = 2; + } + } + + // Check for left wall collision + if (movingLeft == 1) { + if (this.CheckLeftWall(this.WallSensor_X, this.WallSensor_Y)) { + movingLeft = 2; + } + else if (this.XSpeed > -2.0 && this.CheckCenterOffY > 0.0) { + if (this.CheckLeftWall(this.WallSensor_X, this.WallSensor_Y - 2.0 * this.CheckCenterOffY)) + movingLeft = 2; + } + } + + // If there was a right wall collision + if (movingRight == 2) { + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + this.X = this.WallSensor_X - this.SensorEF_cos[0]; + this.LeftSensor_X = this.LeftCeilSensor_X = this.X - this.SensorEF_cos[0] + 1.0; + this.RightSensor_X = this.RightCeilSensor_X = this.X + this.SensorEF_cos[0] - 2.0; + // print "right wall (x: " + this.X + " wx: " + this.WallSensor_X + " ef: " + this.SensorEF_cos[0] + " rx: " + this.RightSensor_X + ")"; + movingRight = 3; + speedPartRemain = 0.0; + } + + // If there was a left wall collision + if (movingLeft == 2) { + this.XSpeed = 0.0; + this.GroundSpeed = 0.0; + this.X = this.WallSensor_X + this.SensorEF_cos[0] + 1.0; + this.LeftSensor_X = this.LeftCeilSensor_X = this.X - this.SensorEF_cos[0] + 1.0; + this.RightSensor_X = this.RightCeilSensor_X = this.X + this.SensorEF_cos[0] - 2.0; + movingLeft = 3; + speedPartRemain = 0.0; + } + + // If moving down + if (movingDown == 1) { + var gh = this.MaxTileCollision; + + this.MaxTileCollision = 0.0; + + var ls = this.LeftSensor_Y; + var rs = this.RightSensor_Y; + + if (this.CheckFloorLeftSensor(this.LeftSensor_X, this.LeftSensor_Y, -1)) { + movingDown = 2; + speedPartRemain = 0; + + // print "left side collision (x: " + this.LeftSensor_X + ", y: " + this.LeftSensor_Y + ", ang: " + Number.ToString(this.LeftSensor_Angle, 16) + ")"; + } + if (this.CheckFloorRightSensor(this.RightSensor_X, this.RightSensor_Y, -1)) { + movingDown = 2; + speedPartRemain = 0; + + // print "right side collision (x: " + this.RightSensor_X + ", y: " + this.RightSensor_Y + ", ang: " + Number.ToString(this.RightSensor_Angle, 16) + ")"; + } + + this.MaxTileCollision = gh; + } + + // If moving up + if (movingUp == 1) { + if (this.CheckCeilLeftSensor(this.LeftCeilSensor_X, this.LeftCeilSensor_Y)) { + movingUp = 2; + speedPartRemain = 0; + } + if (this.CheckCeilRightSensor(this.RightCeilSensor_X, this.RightCeilSensor_Y)) { + movingUp = 2; + speedPartRemain = 0; + } + } + + speedDivisor = speedPartRemain; + if (speedPartRemain <= 0.0) + break; + } + } + + if (movingLeft == 3) { + // print "hit left movingDown: " + movingDown + + // " xspeed: " + xspeed + + // " yspeed: " + yspeed; + } + + // If no collisions, just move + if (movingRight < 2 && movingLeft < 2) { + this.X += this.XSpeed; + } + if (movingDown < 2 && movingUp < 2) { + this.Y += this.YSpeed; + return; + } + + // If moving down and collided + if (movingDown == 2) { + this.Ground = true; + + var doSensor; + if (this.LeftSensor_Collided && this.RightSensor_Collided) + doSensor = this.LeftSensor_Length < this.RightSensor_Length ? -1 : 1; + else if (this.LeftSensor_Collided && !this.RightSensor_Collided) + doSensor = -1; + else + doSensor = 1; + + if (doSensor == -1) { + if (movingLeft == 3 || movingRight == 3) + this.XSpeed = originalXSpeed; + this.Y = this.LeftSensor_Y - this.HitboxHalfH; + this.Angle = this.LeftSensor_Angle; + this.Entity_AirMovementDownwards_Angles(); + } + else if (doSensor == 1) { + if (movingLeft == 3 || movingRight == 3) + this.XSpeed = originalXSpeed; + this.Y = this.RightSensor_Y - this.HitboxHalfH; + this.Angle = this.RightSensor_Angle; + this.Entity_AirMovementDownwards_Angles(); + } + } + + // If moving up and collided + if (movingUp == 2) { + var doSensor; + if (this.LeftCeilSensor_Collided && this.RightCeilSensor_Collided) + doSensor = this.LeftCeilSensor_Length < this.RightCeilSensor_Length ? -1 : 1; + else if (this.LeftCeilSensor_Collided && !this.RightCeilSensor_Collided) + doSensor = -1; + else + doSensor = 1; + + if (doSensor == -1) { + // if (movingLeft == 3 || movingRight == 3) + // this.XSpeed = originalXSpeed; + + this.Y = this.LeftCeilSensor_Y + this.HitboxHalfH + 1.0; + this.Entity_AirMovementUpwards_Angles(this.LeftCeilSensor_Angle); + } + else if (doSensor == 1) { + // if (movingLeft == 3 || movingRight == 3) + // this.XSpeed = originalXSpeed; + + this.Y = this.RightCeilSensor_Y + this.HitboxHalfH + 1.0; + this.Entity_AirMovementUpwards_Angles(this.RightCeilSensor_Angle); + } + } + } + event Entity_AirMovementDownwards_Angles() { + var angle = this.Angle; + var angleMode = this.AngleMode; + // Setting angle modes + if (angle > 0xA0 && angle < 0xDE && angleMode != 1) { + this.X -= 4.0; + this.AngleMode = 1; + } + if (angle > 0x22 && angle < 0x60 && angleMode != 3) { + this.X += 4.0; + this.AngleMode = 3; + } + + // + var xspeed = this.XSpeed; + var yspeed = this.YSpeed; + + // print "xspeed: " + xspeed; + + var gspeed = xspeed; + var absXSpeed = Math.Abs(xspeed); + var absYSpeed = Math.Abs(yspeed); + var absYSpeedHalf = absYSpeed * 0.5; + var sign = Math.Sign(Static.HexSin(angle)); + if (angle >= 0x80) { + // Full Steep + if (angle <= 0xE0) { + if (absXSpeed <= absYSpeed) + gspeed = -yspeed; + } + // Half Steep + else if (angle <= 0xF0) { + if (absXSpeed <= absYSpeedHalf) + gspeed = -yspeed * 0.5; + } + // Shallow + else { + gspeed = xspeed; + } + } + else { + // Full Steep + if (angle >= 0x20) { + if (absXSpeed <= absYSpeed) + gspeed = yspeed; + } + // Half Steep + else if (angle >= 0x10) { + if (absXSpeed <= absYSpeedHalf) + gspeed = yspeed * 0.5; + } + // Shallow + else { + gspeed = xspeed; + } + } + + // print "angle: " + angle; + // print "gspeed: " + gspeed; + + // Clamp Speeds + this.GroundSpeed = gspeed; + this.XSpeed = gspeed; + this.YSpeed = 0.0; + } + event Entity_AirMovementUpwards_Angles(angle) { + var xspeed = this.XSpeed; + var yspeed = this.YSpeed; + + var gspeed = xspeed; + var absXSpeed = Math.Abs(xspeed); + var absYSpeed = Math.Abs(yspeed); + + // Upward Slope (Right) + if (angle >= 0x9F && angle <= 0xC0) { + if (yspeed < -absXSpeed) { + this.X -= 4.0; + this.Y -= 2.0; + this.Ground = true; + this.Angle = angle; + this.AngleMode = 1; + + gspeed = -yspeed; + if (angle <= 0x9F) + gspeed *= 0.5; + + this.GroundSpeed = gspeed; + print "this.GroundSpeed: " + this.GroundSpeed; + } + } + // Upward Slope (Left) + else if (angle >= 0x40 && angle <= 0x61) { + if (yspeed < -absXSpeed) { + this.X += 4.0; + this.Y -= 2.0; + this.Ground = true; + this.Angle = angle; + this.AngleMode = 3; + + gspeed = yspeed; + if (angle >= 0x61) + gspeed *= 0.5; + + this.GroundSpeed = gspeed; + } + } + + if (this.YSpeed < 0.0) + this.YSpeed = 0.0; + } + + event Entity_ApplyPhysics() { + if (this.UseGroundSpeed) { + this.Angle &= 0xFF; + + if (Math.Abs(this.GroundSpeed) >= 6.0) + this.MaxTileCollision = 15; + else if (this.Angle != 0) + this.MaxTileCollision = 15; + else + this.MaxTileCollision = 8; + + this.CheckCenterOffY = 0.0; + if (this.HitboxHalfH >= 14.0) { + this.CheckCenterOffY = 4.0; + this.SpeedPartitionValue = 19; + } + else { + this.CheckCenterOffY = 0.0; + this.SpeedPartitionValue = 17; + this.MaxTileCollision = 15; + } + + if (this.Ground) + this.Entity_GroundMovement(); + else + this.Entity_AirMovement(); + + if (this.Ground) { + this.XSpeed = this.GroundSpeed * Static.HexCos(this.Angle); + this.YSpeed = this.GroundSpeed * Static.HexSin(this.Angle); + } + else { + this.GroundSpeed = this.XSpeed; + } + } + else { + this.X += this.XSpeed; + this.Y += this.YSpeed; + } + } + event Entity_CanFindTile(a2, sensorMode, planeIndex, x, y, len) { + var side = CollideSide_TOP; + if (sensorMode == 0) + side = CollideSide_TOP; + else if (sensorMode == 1) + side = CollideSide_LEFT; + else if (sensorMode == 2) + side = CollideSide_BOTTOM; + else if (sensorMode == 3) + side = CollideSide_RIGHT; + + var startX = Math.Floor(this.X + x); + var startY = Math.Floor(this.Y + y); + for (var i = 0; i < len; i++) { + if (TileCollision.PointExtended(startX, startY, planeIndex, side) >= 0) + return true; + + startY += 1.0; + } + return false; + } + + // Update functions + event Update() { + if (!this.CameraPtr) { + this.CameraPtr = Instance.GetNth("Camera", 0); + if (this.CameraPtr) { + this.CameraPtr.PlayerPtr = this; + } + else { + this.CameraPtr = Instance.Create("Camera", this.X, this.Y); + this.CameraPtr.PlayerPtr = this; + } + } + + this.GetInput(); + + var camera = this.CameraPtr; + if (camera) { + var blockCameraLookTimer = this.CameraLockTimer; + if (blockCameraLookTimer > 0) { + this.CameraLockTimer = blockCameraLookTimer - 1; + if (blockCameraLookTimer == 1) + camera.Status = camera.Camera_StatusNormal; + } + else { + var playerStatus = this.Status; + if (playerStatus != this.Player_StatusLookingUp && playerStatus != this.Player_StatusLookingDown) { + var cameraOffY = camera.OffsetY; + if (cameraOffY > 0.0) { + camera.OffsetY = cameraOffY - 2.0; + } + if (cameraOffY < 0.0) { + camera.OffsetY = cameraOffY + 2.0; + } + } + } + } + + var invincibility = this.Invincibility; + if (invincibility) { + if (invincibility < 0) { + this.Invincibility = invincibility + 1; + } + else { + this.Invincibility = invincibility - 1; + if (invincibility == 1) { + // + } + } + } + + var speedshoestimer = this.SpeedShoesTimer; + if (speedshoestimer > 0) { + this.SpeedShoesTimer = speedshoestimer - 1; + if (speedshoestimer == 1) { + + } + } + + if (this.Status != this.Player_StatusHurt) { + var invincibilityFrames = this.InvincibilityTimer; + if (invincibilityFrames > 0) { + invincibilityFrames--; + this.InvincibilityTimer = invincibilityFrames; + this.Visible = (invincibilityFrames & 4) == 0; + } + } + + // Is being crushed? + if (this.HorizontalCollisionFlag == 3 || this.VerticalCollisionFlag == 3) + this.KillPlayer(); + + this.HorizontalCollisionFlag = 0; + this.VerticalCollisionFlag = 0; + + // Run main code + this.Status(); + + // this.HitboxW = this.HitboxHalfW * 2.0; + // this.HitboxH = this.HitboxHalfH * 2.0; + + this.GetHitboxFromSprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, 1); + this.HitboxHalfH = this.HitboxOffY + this.HitboxH * 0.5; + + // if (true) { + this.GroundSensorMask = 0; + // this.IsUpsideDown = false; + // if (true) { + this.Entity_ApplyPhysics(); + // } + // else { + // + // } + + if (this.Ground && this.AngleMode == 0) + this.VerticalCollisionFlag |= 1; + // } + + // this.HitboxW = this.HitboxHalfW * 2.0; + // this.HitboxH = this.HitboxHalfH * 2.0; + + if (!this.StopTimer) + this.TimerFrames++; + } + event UpdateLate() { + if (this.KillFlag) { + this.MaxGlideSpeed = 0.0; + // TODO: + // if (this.GravityRate < 0.0) + // this.FlipFlag |= 2; + // else + // this.FlipFlag &= 1; + this.Visible = true; + this.Ground = false; + this.GroundSpeed = 0.0; + this.XSpeed = 0.0; + this.LateUpdateGroundStatus = null; + this.LateUpdateAirStatus = null; + this.UseGroundSpeed = false; + // + this.Shield = ShieldType_NONE; + this.HorizontalCollisionFlag = 0; + this.VerticalCollisionFlag = 0; + this.Underwater = false; + this.Player_ResetSpeeds(); + // + + this.CameraLockTimer = 1000000; + if (this.CameraPtr) + this.CameraPtr.Status = null; + this.KillFlag = false; + this.YSpeed = -6.5; + this.Status = this.Player_StatusDead; + } + + if (this.Ground) { + if (this.LateUpdateGroundStatus) { + this.Status = this.LateUpdateGroundStatus; + this.LateUpdateGroundStatus = null; + // + this.EnemyCombo = 0; + } + + var camera = this.CameraPtr; + if (camera) { + if (this.CurrentAnimation == 10) + camera.Camera_Unk_0x9C = this.RollHitboxDelta; + else + camera.Camera_Unk_0x9C = 0.0; + } + } + else if (this.LateUpdateAirStatus) { + this.Status = this.LateUpdateAirStatus; + this.LateUpdateAirStatus = null; + } + + // Do Tails Rotation Updating here if we have tailsprite + var tailObject = this.TailObject; + if (this.Character == Character_TAILS && tailObject) { + this.ShowingTailSprite = true; + switch (this.CurrentAnimation) { + case 0: + case 1: + case 3: + case 4: + // 0 + tailObject.SetAnimation(0, 0); + this.TailFlip = this.Flip; + this.TailRotation = this.Rotation; + break; + case 10: + // 1 + tailObject.SetAnimation(1, 0); + if (this.Ground) { + this.TailFlip = this.GroundSpeed <= 0.0; + this.TailRotation = Math.Atan(this.XSpeed, this.YSpeed); + if (this.TailFlip) + this.TailRotation -= Math_PI; + } + else { + this.TailFlip = this.Flip; + this.TailRotation = Math.Atan(this.XSpeed, this.YSpeed); + if (this.Flip) + this.TailRotation -= Math_PI; + } + break; + case 15: + // 2 + tailObject.SetAnimation(2, 0); + this.TailFlip = this.Flip; + break; + case 13: + case 17: + case 28: + // 3 + tailObject.SetAnimation(3, 0); + this.TailFlip = this.Flip; + break; + case 29: + // 4 + tailObject.SetAnimation(4, 0); + this.TailFlip = this.Flip; + break; + case 37: + // 5 + tailObject.SetAnimation(5, 0); + this.TailFlip = this.Flip; + this.TailRotation = this.Rotation; + if (this.Flip) + this.TailRotation += Math_PI_DOUBLE / 16.0; + else + this.TailRotation -= Math_PI_DOUBLE / 16.0; + break; + default: + this.ShowingTailSprite = false; + break; + } + tailObject.Animate(); + } + } + + // Render functions + event Render() { + var drawPlayer = (this.InvulnTimer % 6) < 3; + if (this.Visible) { + Draw.Save(); + Draw.Translate(Math.Floor(this.X), Math.Floor(this.Y), 0.0); + var shield = this.ShieldObject; + // Draw shield behind if behind + if (this.Shield != ShieldType_NONE && shield && shield.Behind && !shield.Hidden) { + Draw.SetBlendMode(shield.BlendMode); + Draw.SetTextureBlend(true); + Draw.SetBlendColor(1.0, 1.0, 1.0, shield.Alpha); + Draw.Sprite(shield.Sprite, shield.CurrentAnimation, shield.CurrentFrame, 0.0, 0.0, shield.Flip, false); + Draw.SetTextureBlend(false); + Draw.SetBlendMode(BlendMode_NORMAL); + } + + if (drawPlayer) { + // Draw tail sprites + if (this.Character == Character_TAILS && this.ShowingTailSprite && !this.KillFlag) { + var tails = this.TailObject; + + Draw.Save(); + Draw.Rotate(0.0, 0.0, this.TailRotation); + Draw.Sprite(tails.Sprite, tails.CurrentAnimation, tails.CurrentFrame, 0.0, 0.0, this.TailFlip, false); + Draw.Restore(); + } + + // Draw player sprite + Draw.Save(); + Draw.Rotate(0.0, 0.0, this.Rotation); + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, 0.0, 0.0, this.Flip, false); + Draw.Restore(); + } + + // Draw spindash dust + if (this.Status == this.Player_StatusSpinDash && !this.KillFlag) + Draw.Sprite(this.DashDustSprite, 1, this.DashDustTimer, 0.0, this.HitboxHalfH, this.Flip, false); + + // Draw shield in front if not behind + if (this.Shield != ShieldType_NONE && shield && !shield.Behind && !shield.Hidden) { + Draw.SetBlendMode(shield.BlendMode); + Draw.SetTextureBlend(true); + Draw.SetBlendColor(1.0, 1.0, 1.0, shield.Alpha); + Draw.Sprite(shield.Sprite, shield.CurrentAnimation, shield.CurrentFrame, 0.0, 0.0, shield.Flip, false); + Draw.SetTextureBlend(false); + Draw.SetBlendMode(BlendMode_NORMAL); + } + Draw.Restore(); + } + } + + event GetAngleMode(v) { + var angleMode; + if ((v + 0x20) & 0x80) { + angleMode = v; + if (angleMode & 0x80) { // if negative + angleMode--; + } + angleMode += 0x20; + } + else { + angleMode = v; + if (angleMode & 0x80) { // if negative + angleMode++; + } + angleMode += 0x1F; + } + angleMode &= 0xC0; + return angleMode; + } + event RadiansToHex(rad) { + return rad * 128.0 / Math_PI; + } + event HexToRadians(rad) { + return rad * Math_PI / 128.0; + } +} diff --git a/Scripts/Player/ShieldSpark.hsl b/Scripts/Player/ShieldSpark.hsl new file mode 100644 index 0000000..f25d790 --- /dev/null +++ b/Scripts/Player/ShieldSpark.hsl @@ -0,0 +1,36 @@ +class ShieldSpark { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Global/Shields.bin", SCOPE_SCENE); + this.SetAnimation(4, 0); + + this.Life = 22; + this.Gravity = 0.09375; + this.Flash = 0; + this.Frame = 0; + this.RotSpeed = 0.0; + this.Rotation = 0.0; + } + event Update() { + if (this.Life > 0) { + this.Life--; + if (this.Life == 0) + this.Active = false; + } + + if (this.Flash > 0) { + this.Frame = (this.Frame + 1) % (this.Flash + 1); + } + + this.Rotation += this.RotSpeed; + } + event Render() { + if (this.Flash > 0 && this.Frame / this.Flash == 0) + return; + + Draw.Save(); + Draw.Translate(Math.Floor(this.X), Math.Floor(this.Y)); + Draw.Rotate(this.Rotation); + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, 0.0, 0.0, false, false); + Draw.Restore(); + } +} diff --git a/Scripts/Player/TailObject.hsl b/Scripts/Player/TailObject.hsl new file mode 100644 index 0000000..1826a5c --- /dev/null +++ b/Scripts/Player/TailObject.hsl @@ -0,0 +1,16 @@ +class TailObject { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Players/TailSprite.bin", SCOPE_SCENE); + this.SetAnimation(0, 0); + this.Rotation = 0.0; + this.AutoAnimate = false; + } + event OnAnimationFinish() { + // this.Active = false; + } + event Render() { + // Player will be handling this object's Rendering + // Draw.SetBlendColor(1.0, 1.0, 1.0, 1.0); + // Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), false, false); + } +} diff --git a/Scripts/Player/WaterSplash.hsl b/Scripts/Player/WaterSplash.hsl new file mode 100644 index 0000000..cb83d17 --- /dev/null +++ b/Scripts/Player/WaterSplash.hsl @@ -0,0 +1,17 @@ +class WaterSplash { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Global/Water.bin", SCOPE_SCENE); + this.SetAnimation(1, 0); + } + event OnAnimationFinish() { + this.Active = false; + } + event Render() { + Draw.SetBlendMode(BlendMode_ADD); + Draw.SetTextureBlend(true); + Draw.SetBlendColor(1.0, 1.0, 1.0, 0.5); + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), false, false); + Draw.SetTextureBlend(false); + Draw.SetBlendMode(BlendMode_NORMAL); + } +} diff --git a/Scripts/Stage/BGSwitch.hsl b/Scripts/Stage/BGSwitch.hsl new file mode 100644 index 0000000..7807e57 --- /dev/null +++ b/Scripts/Stage/BGSwitch.hsl @@ -0,0 +1,172 @@ +class BGSwitch { + event Create() { + this.BGID = -1; + this.SizeX = 0.0; + this.SizeY = 0.0; + if (this.PropertyExists("size")) { + var size = this.PropertyGet("size"); + this.SizeX = size[0]; + this.SizeY = size[1]; + } + if (this.PropertyExists("bgID")) + this.BGID = this.PropertyGet("bgID"); + + this.HitboxW = this.SizeX * 2.0; + this.HitboxH = this.SizeY * 2.0; + this.OnScreenHitboxW = this.SizeX * 2.0; + this.OnScreenHitboxH = this.SizeY * 2.0; + this.FlipFlag = 0; + this.Status = null; + this.Act = 1; + + var sceneName = Scene.GetName(); + var start = String.IndexOf(sceneName, "/"); + var end = String.LastIndexOf(sceneName, "/"); + if (start < 0 || end < 0 || start == end) + return; + + if (String.Contains(sceneName, "Scene2.bin")) + this.Act = 2; + + var substring = String.Substring(sceneName, start + 1, end - (start + 1)); + switch (substring) { + case "GHZ": + this.Status = this.BGSwitch_Status_GHZSwitch; + break; + case "CPZ": + this.Status = this.BGSwitch_Status_CPZSwitch; + break; + case "FBZ": + this.Status = this.BGSwitch_Status_FBZSwitch; + break; + default: + print "BGSwitch Unhandled Zone: " + substring; + break; + } + } + + event Update() { + if (this.Status) { + with ("Camera") { + var camX = this.X; + var camY = this.Y; + var bgsX = other.X; + var bgsY = other.Y; + var bgsW = other.SizeX; + var bgsH = other.SizeY; + if (Math.Abs(camX - bgsX) <= bgsW && + Math.Abs(camY - bgsY) <= bgsH) { + other.Status(); + } + } + } + } + + event BGSwitch_Status_GHZSwitch() { + if (this.Act == 1) { + switch (this.BGID) { + case 0: + Scene.SetLayerVisible(0, true); + Scene.SetLayerVisible(1, false); + Scene.SetLayerVisible(2, false); + Scene.SetLayerVisible(5, false); + break; + case 1: + Scene.SetLayerVisible(0, false); + Scene.SetLayerVisible(1, true); + Scene.SetLayerVisible(2, true); + Scene.SetLayerVisible(5, false); + break; + } + } + else { + switch (this.BGID) { + case 0: + Scene.SetLayerVisible(0, true); + Scene.SetLayerVisible(1, true); + Scene.SetLayerVisible(2, false); + Scene.SetLayerVisible(3, false); + break; + case 1: + Scene.SetLayerVisible(0, false); + Scene.SetLayerVisible(1, false); + Scene.SetLayerVisible(2, true); + Scene.SetLayerVisible(3, true); + break; + } + } + } + event BGSwitch_Status_CPZSwitch() { + switch (this.BGID) { + case 0: + Scene.SetLayerVisible(0, true); + Scene.SetLayerVisible(1, true); + Scene.SetLayerVisible(2, true); + Scene.SetLayerVisible(3, false); + break; + case 1: + Scene.SetLayerVisible(0, false); + Scene.SetLayerVisible(1, false); + Scene.SetLayerVisible(2, false); + Scene.SetLayerVisible(3, true); + break; + } + } + event BGSwitch_Status_FBZSwitch() { + if (this.Act == 1) { + // VERBOSE: Layer 0 (Background Inside): Width (32) Height (56) DrawGroup (10) + // VERBOSE: Layer 1 (Background Outside): Width (32) Height (16) DrawGroup (0) + // VERBOSE: Layer 2 (FG Low): Width (1088) Height (192) DrawGroup (1) + // VERBOSE: Layer 3 (FG High): Width (1088) Height (192) DrawGroup (6) + // VERBOSE: Layer 4 (Exterior Overlay): Width (1088) Height (192) DrawGroup (10) + // VERBOSE: Layer 5 (Platform): Width (32) Height (16) DrawGroup (10) + // VERBOSE: Layer 6 (Scratch): Width (32) Height (16) DrawGroup (10) + + switch (this.BGID) { + case 0: + Scene.SetLayerVisible(0, false); + Scene.SetLayerVisible(1, true); + // Scene.SetLayerVisible(2, true); + // Scene.SetLayerVisible(3, false); + break; + case 1: + Scene.SetLayerVisible(0, true); + Scene.SetLayerVisible(1, false); + // Scene.SetLayerVisible(2, false); + // Scene.SetLayerVisible(3, true); + break; + } + } + else { + // 1 // VERBOSE: Layer 0 (BG Inside 1): Width (32) Height (32) DrawGroup (0) + // 1 // VERBOSE: Layer 1 (BG Inside 2): Width (32) Height (32) DrawGroup (0) + // 2 // VERBOSE: Layer 2 (Background Outside): Width (32) Height (16) DrawGroup (0) + // 0 // VERBOSE: Layer 3 (BG Storm): Width (32) Height (16) DrawGroup (10) + // VERBOSE: Layer 4 (FG Low): Width (1008) Height (496) DrawGroup (1) + // VERBOSE: Layer 5 (FG High): Width (1008) Height (496) DrawGroup (6) + // VERBOSE: Layer 6 (Exterior Overlay): Width (1008) Height (496) DrawGroup (6) + // VERBOSE: Layer 7 (Move): Width (32) Height (16) DrawGroup (10) + + switch (this.BGID) { + case 0: + Scene.SetLayerVisible(0, false); + Scene.SetLayerVisible(1, false); + Scene.SetLayerVisible(2, false); + Scene.SetLayerVisible(3, true); + break; + case 1: + Scene.SetLayerVisible(0, true); + Scene.SetLayerVisible(1, true); + Scene.SetLayerVisible(2, false); + Scene.SetLayerVisible(3, false); + break; + case 2: + Scene.SetLayerVisible(0, false); + Scene.SetLayerVisible(1, false); + Scene.SetLayerVisible(2, true); + Scene.SetLayerVisible(3, false); + break; + } + } + } +} diff --git a/Scripts/Stage/BoundsMarker.hsl b/Scripts/Stage/BoundsMarker.hsl new file mode 100644 index 0000000..da4a559 --- /dev/null +++ b/Scripts/Stage/BoundsMarker.hsl @@ -0,0 +1,78 @@ +class BoundsMarker { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + this.Type = 0; + this.Width = 0.0; + this.VSDisable = 0; + this.Offset = 0.0; + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("width")) + this.Width = this.PropertyGet("width") * 0.5; + if (this.PropertyExists("vsDisable")) + this.VSDisable = this.PropertyGet("vsDisable"); + if (this.PropertyExists("offset")) + this.Offset = this.PropertyGet("offset") * 1.0; + + if (this.Width == 0.0) + this.Width = 24.0; + this.OnScreenHitboxW = this.Width * 2.0; + + this.JumpToPlayer = true; + } + event Update() { + var player, boundsMarker, camera; + var jumpToPlayer = this.JumpToPlayer; + this.JumpToPlayer = false; + + with ("Player") { + player = this; + boundsMarker = other; + if (!player.Active) + continue; + + camera = player.CameraPtr; + if (!camera) + continue; + + if (player.Status == player.Player_StatusDead || + player.Status == player.Player_StatusFlyingIn || + player.Status == player.Player_StatusJumpingIn || + player.Status == player.Player_StatusTransforming) + continue; + + var distance = Math.Abs(player.X - boundsMarker.X); + if (distance >= boundsMarker.Width) + continue; + + var type = boundsMarker.Type; + switch (type) { + case 0: + camera.ToMaxY = boundsMarker.Y; + break; + case 1: + if (player.Y < boundsMarker.Y - boundsMarker.Offset) { + camera.ToMaxY = boundsMarker.Y; + } + break; + case 2: + if (player.Y > boundsMarker.Y + boundsMarker.Offset) { + camera.ToMinY = boundsMarker.Y; + } + break; + case 3: + camera.ToMinY = boundsMarker.Y; + break; + } + + if (jumpToPlayer) { + camera.MaxY = camera.ToMaxY; + camera.MinY = camera.ToMinY; + } + } + } +} diff --git a/Scripts/Stage/BreakableWall.hsl b/Scripts/Stage/BreakableWall.hsl new file mode 100644 index 0000000..7050fff --- /dev/null +++ b/Scripts/Stage/BreakableWall.hsl @@ -0,0 +1,353 @@ +class BreakableWall { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Pre + this.Priority = DrawGroup_FGHigh_High; + + // Load + this.Sprite = Resources.LoadSprite("Sprites/Global/TicMark.bin", SCOPE_GAME); + this.SFX_LedgeBreak = Resources.LoadSound("SoundFX/Stage/LedgeBreak.wav", SCOPE_GAME); + this.AutoPhysics = false; + this.Status = null; + + // Setup + this.Type = 0; + this.OnlyKnux = false; + this.OnlyMighty = false; + this.PriorityIndex = 0; + this.SizeX = 0.0; + this.SizeY = 0.0; + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("onlyKnux")) + this.OnlyKnux = this.PropertyGet("onlyKnux"); + if (this.PropertyExists("onlyMighty")) + this.OnlyMighty = this.PropertyGet("onlyMighty"); + if (this.PropertyExists("priority")) + this.PriorityIndex = this.PropertyGet("priority"); + if (this.PropertyExists("size")) { + var size = this.PropertyGet("size"); + this.SizeX = size[0]; + this.SizeY = size[1]; + } + + // Create + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + var sizeX = this.SizeX; + switch (this.Type) { + case 0: + this.Status = this.BreakableWall_StatusHorizontallyBreakable; + if (sizeX == 0.0) { + this.SizeX = 2.0; + this.SizeY = 4.0; + } + break; + case 1: + this.Status = this.BreakableWall_StatusTubeTopBreakable; + if (sizeX == 0.0) { + this.SizeX = 2.0; + this.SizeY = 2.0; + } + break; + case 2: + case 3: + this.Status = this.BreakableWall_StatusTopBreakable; + if (sizeX == 0.0) { + this.SizeX = 2.0; + } + break; + case 4: + this.Status = this.BreakableWall_StatusBottomBreakable; + if (sizeX == 0.0) { + this.SizeX = 2.0; + } + break; + case 5: + // this.Status = this.BreakableWall_StatusBottomBreakable; + if (sizeX == 0.0) { + this.SizeX = 2.0; + this.SizeY = 2.0; + } + break; + } + this.HitboxW = 16.0 * this.SizeX; + this.HitboxH = 16.0 * this.SizeY; + + // Initial Status + this.OnScreenHitboxHalfW = this.OnScreenHitboxW; + this.OnScreenHitboxHalfH = this.OnScreenHitboxH; + } + + event BreakableWall_StatusHorizontallyBreakable() { + var player, wall; + with ("Player") { + if (!this.Active) + continue; + + player = this; + wall = other; + + var characterFlag = player.Character; + var collideWithWall = false; + if (wall.OnlyKnux && characterFlag != Character_KNUCKLES) { + collideWithWall = true; + } + else if (wall.OnlyMighty && characterFlag != Character_MIGHTY) { + collideWithWall = true; + } + var absGSP = Math.Abs(player.GroundSpeed); + var canBreak = false; + canBreak |= absGSP >= 4.5 && player.Ground && player.CurrentAnimation == 10; + canBreak |= characterFlag == Character_KNUCKLES; + canBreak |= characterFlag == Character_SONIC && player.SuperForm == 2; + canBreak |= player.Status == player.Player_StatusFrozen_PGZ; + if (player.Shield == ShieldType_FIRE && false) + canBreak = true; + + if (!collideWithWall) { + if (canBreak && player.CannotLoseRings == 0) { + if (!player.IsGhost) { + if (Static.Entity_CollideWithObject(wall, player)) { + wall.BreakHorizontally(player.X > wall.X); + if (player.Character == Character_KNUCKLES) { + var anim = player.CurrentAnimation; + if (anim == 48) { + player.RayGlideSpeedStore *= 0.75; + player.XSpeed *= 0.75; + if (Math.Abs(player.XSpeed) <= 3.0) { + player.SetAnimation(49, 0); + player.Status = player.Player_StatusKnuckles_Falling; + } + } + else if (anim == 51) { + player.RayGlideSpeedStore *= 0.75; + player.XSpeed *= 0.75; + } + } + Sound.Play(wall.SFX_LedgeBreak); + wall.Active = false; + } + } + } + } + else { + Static.Entity_SolidCollideWithPlayer(wall, player); + } + } + } + event BreakableWall_StatusTubeTopBreakable() { + var player, wall; + with ("Player") { + if (!this.Active) + continue; + + player = this; + wall = other; + + var characterFlag = player.Character; + var collideWithWall = false; + if (wall.OnlyKnux && characterFlag != Character_KNUCKLES) { + collideWithWall = true; + } + else if (wall.OnlyMighty && characterFlag != Character_MIGHTY) { + collideWithWall = true; + } + // var absGSP = Math.Abs(player.GroundSpeed); + var canBreak = true; + // canBreak |= absGSP >= 4.5 && player.Ground && player.CurrentAnimation == 10; + // canBreak |= characterFlag == Character_KNUCKLES; + // canBreak |= characterFlag == Character_SONIC && player.SuperForm == 2; + // canBreak |= player.Status == player.Player_StatusFrozen_PGZ; + + if (!collideWithWall) { + if (canBreak && player.CannotLoseRings == 0) { + if (!player.IsGhost) { + if (Static.Entity_CollideWithObject(wall, player)) { + wall.BreakVertically(player.Y > wall.Y); + + player.Ground = false; + if (player.Status == player.Player_StatusMighty_HammerDrop) + player.YSpeed -= 1.0; + else + player.YSpeed = -3.0; + player.IncreaseEnemyCombo(); + + Sound.Play(wall.SFX_LedgeBreak); + wall.Active = false; + } + } + } + } + else { + Static.Entity_SolidCollideWithPlayer(wall, player); + } + } + } + event BreakableWall_StatusTopBreakable() { + var player, wall; + with ("Player") { + if (!this.Active) + continue; + + player = this; + wall = other; + + var characterFlag = player.Character; + var collideWithWall = false; + if (wall.OnlyKnux && characterFlag != Character_KNUCKLES) { + collideWithWall = true; + } + else if (wall.OnlyMighty && characterFlag != Character_MIGHTY) { + collideWithWall = true; + } + // var absGSP = Math.Abs(player.GroundSpeed); + var canBreak = true; + // canBreak |= absGSP >= 4.5 && player.Ground && player.CurrentAnimation == 10; + // canBreak |= characterFlag == Character_KNUCKLES; + // canBreak |= characterFlag == Character_SONIC && player.SuperForm == 2; + // canBreak |= player.Status == player.Player_StatusFrozen_PGZ; + + if (!collideWithWall) { + if (canBreak && player.CannotLoseRings == 0) { + if (!player.IsGhost) { + if (Static.Entity_CollideWithObject(wall, player)) { + wall.BreakVertically(player.Y > wall.Y); + + player.Ground = false; + if (player.Status == player.Player_StatusMighty_HammerDrop) + player.YSpeed -= 1.0; + else + player.YSpeed = 0.0; + player.IncreaseEnemyCombo(); + + Sound.Play(wall.SFX_LedgeBreak); + wall.Active = false; + } + } + } + } + else { + Static.Entity_SolidCollideWithPlayer(wall, player); + } + } + } + event BreakableWall_StatusBottomBreakable() { + var player, wall; + with ("Player") { + if (!this.Active) + continue; + + player = this; + wall = other; + + var characterFlag = player.Character; + var collideWithWall = false; + if (wall.OnlyKnux && characterFlag != Character_KNUCKLES) { + collideWithWall = true; + } + else if (wall.OnlyMighty && characterFlag != Character_MIGHTY) { + collideWithWall = true; + } + // var absGSP = Math.Abs(player.GroundSpeed); + var canBreak = true; + // canBreak |= absGSP >= 4.5 && player.Ground && player.CurrentAnimation == 10; + // canBreak |= characterFlag == Character_KNUCKLES; + // canBreak |= characterFlag == Character_SONIC && player.SuperForm == 2; + // canBreak |= player.Status == player.Player_StatusFrozen_PGZ; + + if (!collideWithWall) { + if (canBreak && player.CannotLoseRings == 0) { + if (!player.IsGhost) { + if (Static.Entity_CollideWithObject(wall, player)) { + wall.BreakVertically(player.Y > wall.Y); + Sound.Play(wall.SFX_LedgeBreak); + wall.Active = false; + } + } + } + } + else { + Static.Entity_SolidCollideWithPlayer(wall, player); + } + } + } + + event BreakHorizontally(toLeft) { + var highLayer = Scene.GetLayerIndex("FG High"); + if (this.PriorityIndex == 1) + highLayer = Scene.GetLayerIndex("FG Low"); + var tileStartX = (this.X - 8.0 * this.SizeX) / 16.0; + var tileStartY = (this.Y - 8.0 * this.SizeY) / 16.0; + var tileEndX = Number.AsInteger(tileStartX + this.SizeX); + var tileEndY = Number.AsInteger(tileStartY + this.SizeY); + tileStartX = Number.AsInteger(tileStartX); + tileStartY = Number.AsInteger(tileStartY); + + var piece, angle; + for (var x = tileStartX; x < tileEndX; x++) { + for (var y = tileStartY; y < tileEndY; y++) { + angle = Math.Atan(((x - tileStartX) * 16.0) + 8.0, (y * 16.0) + 8.0 - this.Y); + piece = Instance.Create("BreakableWallPiece", (x * 16.0) + 8.0, (y * 16.0) + 8.0); + piece.TileID = Scene.GetTileID(highLayer, x, y); + piece.TileFlipX = Scene.GetTileFlipX(highLayer, x, y); + piece.TileFlipY = Scene.GetTileFlipY(highLayer, x, y); + piece.TileX = x; + piece.TileY = y; + piece.TileLayer = highLayer; + piece.XSpeed = 3.5 * Math.Cos(angle); + piece.YSpeed = 3.5 * Math.Sin(angle); + if (toLeft) + piece.XSpeed = -piece.XSpeed; + piece.Gravity = 0.21875; + piece.Priority = this.Priority; + } + } + } + event BreakVertically(toLeft) { + var highLayer = Scene.GetLayerIndex("FG High"); + if (this.PriorityIndex == 1) + highLayer = Scene.GetLayerIndex("FG Low"); + var tileStartX = (this.X - 8.0 * this.SizeX) / 16.0; + var tileStartY = (this.Y - 8.0 * this.SizeY) / 16.0; + var tileEndX = Number.AsInteger(tileStartX + this.SizeX); + var tileEndY = Number.AsInteger(tileStartY + this.SizeY); + tileStartX = Number.AsInteger(tileStartX); + tileStartY = Number.AsInteger(tileStartY); + + var piece, angle; + for (var x = tileStartX; x < tileEndX; x++) { + for (var y = tileStartY; y < tileEndY; y++) { + angle = Math.Atan(((x * 16.0) + 8.0 - this.X) * 2.0, ((y - tileStartY) * 16.0) + 8.0); + piece = Instance.Create("BreakableWallPiece", (x * 16.0) + 8.0, (y * 16.0) + 8.0); + piece.TileID = Scene.GetTileID(highLayer, x, y); + piece.TileFlipX = Scene.GetTileFlipX(highLayer, x, y); + piece.TileFlipY = Scene.GetTileFlipY(highLayer, x, y); + piece.TileX = x; + piece.TileY = y; + piece.TileLayer = highLayer; + piece.XSpeed = -5.5 * Math.Cos(angle); + piece.YSpeed = 5.5 * Math.Sin(angle); + piece.YSpeed = -Math.Abs(piece.YSpeed); + if (toLeft) + piece.XSpeed = -piece.XSpeed; + piece.Gravity = 0.21875; + piece.Priority = this.Priority; + } + } + } + + event Update() { + this.SpriteOnScreen = false; + if (!this.InView(0, this.X - this.OnScreenHitboxHalfW, this.Y - this.OnScreenHitboxHalfH, this.OnScreenHitboxW, this.OnScreenHitboxH)) + return; + this.SpriteOnScreen = true; + + if (this.Status) + this.Status(); + } +} diff --git a/Scripts/Stage/Bridge.hsl b/Scripts/Stage/Bridge.hsl new file mode 100644 index 0000000..885c06f --- /dev/null +++ b/Scripts/Stage/Bridge.hsl @@ -0,0 +1,251 @@ +class Bridge { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Pre + this.Priority = DrawGroup_FGLow_Low; + + // Load + var sceneName = Scene.GetName(); + if (String.Contains(sceneName, "GHZ")) + this.Sprite = Resources.LoadSprite("Sprites/GHZ/Bridge.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "HCZ")) + this.Sprite = Resources.LoadSprite("Sprites/HCZ/Bridge.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "LRZ1")) + this.Sprite = Resources.LoadSprite("Sprites/LRZ1/Bridge.bin", SCOPE_SCENE); + this.AutoPhysics = false; + this.Status = null; + + // Setup + this.Length = 0; + this.Burnable = false; + this.Pressure = 0; + this.IsPlayerOnTop = false; + this.PlayerStandingAtop = -1; + this.BurnStartIndex = -1; + this.LogSine = 0.0; + this.MaxDepression = 0.0; + this.MinX = 0.0; + this.MaxX = 0.0; + this.PlayerRelativeX = 0.0; + if (this.PropertyExists("length")) + this.Length = this.PropertyGet("length"); + if (this.PropertyExists("burnable")) + this.Burnable = this.PropertyGet("burnable"); + + if (this.Burnable) { + print "this.Burnable: " + this.X + " " + this.Y; + } + + // Create + this.Length++; + + var len = this.Length * 8.0; + this.MinX = this.X - len; + this.MaxX = this.X + len; + + this.OnScreenHitboxW = this.Length * 16 + 64.0; + this.OnScreenHitboxH = 128.0; + + this.SetAnimation(0, 0); + + this.HitboxW = this.Length * 16; + this.HitboxH = 8.0; + this.HitboxOffX = 0.0; + this.HitboxOffY = -4.0; + this.FlipFlag = 0; + + // Initial Status + this.OnScreenHitboxHalfW = this.OnScreenHitboxW; + this.OnScreenHitboxHalfH = this.OnScreenHitboxH; + } + + event Update() { + var pressure = this.Pressure; + if (this.IsPlayerOnTop) { + if (pressure < 0x80) + this.Pressure = pressure + 8; + } + else if (pressure) { + this.PlayerStandingAtop = -1; + this.Pressure = pressure - 8; + } + else { + this.LogSine = 0.0; + } + + this.IsPlayerOnTop = false; + this.MaxDepression = this.LogSine * this.Pressure / 128.0; + + var player, bridge = this; + with ("Player") { + player = this; + player.UpdateHitbox(0); + if (player.Status == player.Player_StatusKnuckles_GettingUp) + continue; + + var playerX = player.X; + var bridgeMinX = bridge.MinX; + var bridgeMaxX = bridge.MaxX; + + if (playerX <= bridgeMinX || playerX >= bridgeMaxX) { + if (bridge.PlayerStandingAtop == player) { + bridge.Pressure = 0x20; + // LABEL_52: + bridge.PlayerStandingAtop = -2; + continue; + } + } + else { + if (bridge.PlayerStandingAtop != player) { + if (!bridge.IsPlayerOnTop) { + bridge.PlayerRelativeX = playerX - bridgeMinX; + } + if (player.YSpeed < 0.0) + continue; + + var playerRelativeX = bridge.PlayerRelativeX; + var playerBridgeX = playerX - bridgeMinX; + if (playerBridgeX > playerRelativeX) { + // Reverse them + playerBridgeX = bridgeMaxX - playerX; + playerRelativeX = bridgeMaxX - bridgeMinX - bridge.PlayerRelativeX; + } + var len = Number.AsInteger(playerBridgeX) << 7; + + var logOffY = bridge.MaxDepression * Static.HexSinMedPrec(len / playerRelativeX); + if (player.YSpeed >= 0.5) + bridge.HitboxOffY = -4.0 + logOffY; + else + bridge.HitboxOffY = -4.0 + logOffY - 8.0; + + if (player.IsGhost || !Static.Entity_CollideWithObject(bridge, player)) + continue; + + bridge.IsPlayerOnTop = true; + player.Y = logOffY + bridge.Y - 8.0 - (player.HitboxH * 0.5 + player.HitboxOffY); + + if (!player.Ground) { + player.Ground = true; + player.GroundSpeed = player.XSpeed; + } + player.GroundSensorMask = 0; + + var firstPlayer = player; + if (player == firstPlayer) { + var playerStandingAtop = bridge.PlayerStandingAtop; + if (playerStandingAtop != -1 && playerStandingAtop != -2) { + var playerRelativeX = playerX - bridgeMinX; + bridge.PlayerRelativeX = playerRelativeX; + playerRelativeX = Number.AsInteger(playerRelativeX); + var bridgeSize = Number.AsInteger(bridgeMaxX - bridgeMinX); + bridge.LogSine = bridge.Length * Static.HexSinMedPrec((playerRelativeX << 8) / bridgeSize); + bridge.MaxDepression = bridge.LogSine * bridge.Pressure / 128.0; + } + bridge.PlayerStandingAtop = player; + if (player.YSpeed < 1.0) { + bridge.Pressure = 0x80; + } + } + else { + if (bridge.PlayerStandingAtop == -1) { + bridge.PlayerStandingAtop = player; + if (player.YSpeed < 1.0) { + bridge.Pressure = 0x80; + } + } + if (bridge.PlayerStandingAtop == -2) { + bridge.PlayerStandingAtop = player; + } + } + + if (!player.Ground) { + player.Ground = true; + player.GroundSpeed = player.XSpeed; + } + player.YSpeed = 0.0; + if (player.Shield == ShieldType_FIRE && bridge.Burnable) + bridge.Bridge_StartBurn((player.X - bridge.MinX) / 16.0); + continue; + } + + var playerRelativeX = playerX - bridgeMinX; + bridge.PlayerRelativeX = playerRelativeX; + playerRelativeX = Number.AsInteger(playerRelativeX); + var bridgeSize = Number.AsInteger(bridgeMaxX - bridgeMinX); + bridge.LogSine = bridge.Length * Static.HexSinMedPrec((playerRelativeX << 8) / bridgeSize); + + if (player.Y > bridge.Y - 48.0) { + if (player.YSpeed >= 0.0) { + bridge.IsPlayerOnTop = true; + player.Y = bridge.MaxDepression + bridge.Y - 8.0 - (player.HitboxH * 0.5 + player.HitboxOffY); + + if (!player.Ground) { + player.Ground = true; + player.GroundSpeed = player.XSpeed; + } + player.GroundSensorMask = 0; + player.YSpeed = 0.0; + if (player.Shield == ShieldType_FIRE && bridge.Burnable) + bridge.Bridge_StartBurn((player.X - bridge.MinX) / 16.0); + continue; + } + + bridge.PlayerStandingAtop = -2; + continue; + } + } + } + } + + event Bridge_StartBurn(burnStartIndex) { + burnStartIndex = Number.AsInteger(burnStartIndex); + } + + event Render() { + var x = this.MinX + 8.0; + var y; + var bridgeY = this.Y; + var bridgeLength = this.Length; + var playerRelX = Number.AsInteger(this.PlayerRelativeX); + var playerRelXReverse = Number.AsInteger(this.MaxX - this.MinX - this.PlayerRelativeX); + var playerRelXToIndex = playerRelX / 16; + + var logWidthInUnits = 16 << 7; + var index = 0; + var len; + + var sprite = this.Sprite, anim = this.CurrentAnimation, frame = this.CurrentFrame; + + // Draw left side + for (len = logWidthInUnits >> 1; index < playerRelXToIndex; index++) { + y = this.MaxDepression * Static.HexSinMedPrec(len / playerRelX) + bridgeY; + + Draw.Sprite(sprite, anim, frame, x, y, false, false); + + x += 16.0; + len += logWidthInUnits; + } + + y = this.MaxDepression + bridgeY; + Draw.Sprite(sprite, anim, frame, x, y, false, false); + x += 16.0; + index++; + + x = this.MaxX - 8.0; + playerRelXToIndex = playerRelXReverse / 16; + for (len = logWidthInUnits >> 1; index < bridgeLength; index++) { + y = this.MaxDepression * Static.HexSinMedPrec(len / playerRelXReverse) + bridgeY; + + Draw.Sprite(sprite, anim, frame, x, y, false, false); + + x -= 16.0; + len += logWidthInUnits; + } + + // + } +} diff --git a/Scripts/Stage/Camera.hsl b/Scripts/Stage/Camera.hsl new file mode 100644 index 0000000..70858a4 --- /dev/null +++ b/Scripts/Stage/Camera.hsl @@ -0,0 +1,216 @@ +class Camera { + event Create() { + this.LastX = this.X; + this.LastY = this.Y; + this.PlayerInAir = false; + this.SetOnJump = 0.0; + this.Status = null; + this.PlayerPtr = null; + this.DestinationOffsetX = 0.0; + this.DestinationOffsetY = 0.0; + this.MinFollowDistanceX = 8.0; + this.OffsetX = 0.0; + this.OffsetY = 0.0; + this.ShakeX = 0; // These need to be integers + this.ShakeY = 0; // These need to be integers + this.ClampedShakenX = this.X; + this.ClampedShakenY = this.Y; + + this.CustomViewHeightHalf = 104.0; // 0x68 + + this.LevelWidth = Scene.GetWidth() * 16.0; + this.LevelHeight = Scene.GetHeight() * 16.0; + + this.Status = this.Camera_StatusNormal; + + this.BoundPanningSpeed = 2.0; + + this.MaxCameraXSpeed = 16.0; + this.MaxCameraYSpeed = 24.0; + + this.MinX = 0.0; + this.MinY = 0.0; + this.MaxX = this.LevelWidth; + this.MaxY = this.LevelHeight; + this.ToMinX = 0.0; + this.ToMinY = 0.0; + this.ToMaxX = this.LevelWidth; + this.ToMaxY = this.LevelHeight; + + this.Camera_Unk_0x9C = 0.0; + } + + event UpdateLate() { + this.LastX = this.X; + this.LastY = this.Y; + + if (this.Status) + this.Status(); + + this.XSpeed = this.X - this.LastX; + this.YSpeed = this.Y - this.LastY; + + this.MoveViewPosition(); + + var shake = this.ShakeX; + if (shake) { + if (shake <= 0) + this.ShakeX = -shake - 1; + else + this.ShakeX = -shake; + } + + shake = this.ShakeY; + if (shake) { + if (shake <= 0) + this.ShakeY = -shake - 1; + else + this.ShakeY = -shake; + } + + if (!this.PlayerInAir) { + var v4 = this.SetOnJump - this.SetOnJump / 8.0; + if (v4 < 0.0) + v4 = 0.0; + this.SetOnJump = v4; + } + } + + event Camera_MoveBoundsY() { + var minY, maxY; + var yspeed = this.YSpeed; + + minY = this.MinY; + if (this.ToMinY > minY) { + var viewY = CameraY; + if (viewY <= minY) + viewY = minY + this.BoundPanningSpeed; + this.MinY = viewY; + } + + minY = this.MinY; + if (this.ToMinY < minY) { + if (CameraY <= minY) { + this.MinY = minY - this.BoundPanningSpeed; + if (yspeed < 0.0) { + this.MaxY += yspeed; + if (this.MaxY < this.ToMaxY) + this.MaxY = this.ToMaxY; + } + } + else { + this.MinY = this.ToMinY; + } + } + + maxY = this.MaxY; + if (this.ToMaxY < maxY) { + var viewY = CameraY + View.GetHeight(0); + if (viewY >= maxY) + viewY = maxY - 2; // - this.BoundPanningSpeed; + this.MaxY = viewY; + } + + maxY = this.MaxY; + if (this.ToMaxY > maxY) { + if (CameraY + View.GetHeight(0) >= maxY) { + this.MaxY = maxY + 2; // + this.BoundPanningSpeed; + if (yspeed > 0.0) { + this.MaxY += yspeed; + if (this.MaxY > this.ToMaxY) + this.MaxY = this.ToMaxY; + } + } + else { + this.MaxY = this.ToMaxY; + } + } + } + event MoveViewPosition() { + var viewIndex = 0; + var width = View.GetWidth(viewIndex); + var height = View.GetHeight(viewIndex); + var widthHalf = width * 0.5; + var heightHalf = height * 0.5; + var finalX = this.X + this.OffsetX - widthHalf; + var finalY = this.Y + this.OffsetY - this.CustomViewHeightHalf; + + finalX = Math.Clamp(finalX, this.MinX, this.MaxX - width); + finalY = Math.Clamp(finalY, this.MinY, this.MaxY - height); + + // In Mania, shake position is incorrectly added here, not clamping it afterwards. + // Let's at least clamp it. + + finalX += this.ShakeX; + finalY += this.ShakeY; + finalX = Math.Clamp(finalX, 0.0, this.LevelWidth - width); + finalY = Math.Clamp(finalY, 0.0, this.LevelHeight - height); + this.ClampedShakenX = finalX + widthHalf; + this.ClampedShakenY = finalY + heightHalf; + + CameraX = finalX; + CameraY = finalY; + } + + event HandleVertMove() { + var player = this.PlayerPtr; + if (!player) + return; + + this.Camera_MoveBoundsY(); + + var offsetY = this.SetOnJump; + var initialY = this.Y; + var playerY = player.Y + this.DestinationOffsetY - 0.0 - this.Camera_Unk_0x9C; + var maxCameraYSpeed = this.MaxCameraYSpeed; + + if (playerY <= initialY + offsetY) { + if (playerY < initialY - offsetY) { + offsetY = playerY + offsetY - initialY; + if (offsetY < -maxCameraYSpeed) + offsetY = -maxCameraYSpeed; + this.Y = initialY + offsetY; + } + } + else { + offsetY = playerY - offsetY - initialY; + if (offsetY > maxCameraYSpeed) + offsetY = maxCameraYSpeed; + this.Y = initialY + offsetY; + } + } + + event Camera_StatusNormal() { + var player = this.PlayerPtr; + if (!player) + return; + + // this.Camera_MoveBoundsX(); + + var offsetX; + var initialX = this.X; + var playerX = player.X + this.DestinationOffsetX; + var minFollowDistanceX = this.MinFollowDistanceX; + var maxCameraXSpeed = this.MaxCameraXSpeed; + + if (playerX <= initialX + minFollowDistanceX) { + if (playerX < initialX - minFollowDistanceX) { + offsetX = playerX + minFollowDistanceX - initialX; + if (offsetX < -maxCameraXSpeed) + offsetX = -maxCameraXSpeed; + this.X = initialX + offsetX; + } + } + else { + offsetX = playerX - minFollowDistanceX - initialX; + if (offsetX > maxCameraXSpeed) + offsetX = maxCameraXSpeed; + this.X = initialX + offsetX; + } + + this.HandleVertMove(); + } + event Camera_StatusNonFollow() { + this.HandleVertMove(); + } +} diff --git a/Scripts/Stage/CollapsingPlatform.hsl b/Scripts/Stage/CollapsingPlatform.hsl new file mode 100644 index 0000000..755b4a9 --- /dev/null +++ b/Scripts/Stage/CollapsingPlatform.hsl @@ -0,0 +1,194 @@ +class CollapsingPlatform { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Pre + this.Priority = DrawGroup_FGLow_Low; + + // Load + this.Sprite = Resources.LoadSprite("Sprites/Global/TicMark.bin", SCOPE_GAME); + this.SFX_LedgeBreak = Resources.LoadSound("SoundFX/Stage/LedgeBreak.wav", SCOPE_GAME); + this.AutoPhysics = false; + this.Status = null; + + // Setup + this.Respawn = false; + this.TargetLayer = 0; + this.Type = 0; + this.Delay = 0; + this.EventOnly = false; + this.MightyOnly = false; + this.SizeX = 0.0; + this.SizeY = 0.0; + this.TileW = 0; + this.TileH = 0; + this.BreakTimer = 0; + this.PlayerX = 0.0; + if (this.PropertyExists("size")) { + var size = this.PropertyGet("size"); + this.SizeX = size[0]; + this.SizeY = size[1]; + } + if (this.PropertyExists("respawn")) + this.Respawn = this.PropertyGet("respawn"); + if (this.PropertyExists("targetLayer")) + this.TargetLayer = this.PropertyGet("targetLayer"); + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("delay")) + this.Delay = this.PropertyGet("delay"); + if (this.PropertyExists("eventOnly")) + this.EventOnly = this.PropertyGet("eventOnly"); + if (this.PropertyExists("mightyOnly")) + this.MightyOnly = this.PropertyGet("mightyOnly"); + this.TileBackup = Array.Create(256); + + this.TileW = Number.AsInteger(this.SizeX / 16.0); + this.TileH = Number.AsInteger(this.SizeY / 16.0); + + // Create + this.OnScreenHitboxW = 128.0 * 2.0; + this.OnScreenHitboxH = 128.0 * 2.0; + // Copy Tiles + // Set Hitbox + this.HitboxW = this.SizeX; + this.HitboxH = this.SizeY + 16.0; + this.HitboxOffX = 0.0; + this.HitboxOffY = -16.0; + this.FlipFlag = 0; + this.TargetLayerIndex = this.TargetLayer == 0 ? Scene.GetLayerIndex("FG Low") : Scene.GetLayerIndex("FG High"); + if (this.TargetLayer == 0) { + this.Priority = DrawGroup_FGLow_Low; + } + else { + this.Priority = DrawGroup_FGHigh_High; + } + + switch (this.Type) { + case 1: + this.Status = this.CollapsingPlatform_BreakStatusFromRight; + break; + case 2: + this.Status = this.CollapsingPlatform_BreakStatusFromLeft; + break; + case 3: + this.Status = this.CollapsingPlatform_BreakStatusFromLeft; + break; + case 4: + this.Status = this.CollapsingPlatform_BreakStatusFromLeft; + break; + default: + this.Status = this.CollapsingPlatform_BreakStatusFromLeft; + break; + } + } + + event Update() { + if (this.BreakTimer) { + this.BreakTimer--; + if (this.BreakTimer == 0) { + return this.CollapsingPlatform_RunBreak(); + } + return; + } + + var player, platform = this; + with ("Player") { + player = this; + if (!player.IsGhost) { + player.UpdateHitbox(0); + if (!Static.Entity_CollideWithObject(platform, player)) + continue; + + if (player.Character == Character_MIGHTY && player.MidAirFlag > 1) { + platform.CollapsingPlatform_RunBreak(); + continue; // break; // TODO: should be break here + } + + if ((!platform.MightyOnly || player.Character == Character_MIGHTY && player.MidAirFlag > 1) && + !player.CannotLoseRings && + player.Ground && + player.AngleMode == 0 && + !platform.EventOnly && + platform.Delay < 0xFFFF) { + platform.PlayerX = player.X; + } + } + } + + if (this.PlayerX) { + this.BreakTimer = this.Delay; + if (!this.Delay) + return this.CollapsingPlatform_RunBreak(); + } + } + + event CollapsingPlatform_BreakStatusFromLeft() { + var layer = this.TargetLayerIndex; + var minX = Number.AsInteger((this.X - this.SizeX * 0.5) / 16.0); + var maxX = minX + this.TileW; + var minY = Number.AsInteger((this.Y - this.SizeY * 0.5) / 16.0); + var maxY = minY + this.TileH; + var piece, tid; + var isOOZ = 0; + for (var x = minX; x < maxX; x++) { + for (var y = minY; y < maxY; y++) { + tid = Scene.GetTileID(layer, x, y); + if (tid == 1 + 0x3FF) + continue; + + piece = Instance.Create("BreakableWallPiece", (x * 16.0) + 8.0, (y * 16.0) + 8.0); + piece.TileID = tid; + piece.TileFlipX = Scene.GetTileFlipX(layer, x, y); + piece.TileFlipY = Scene.GetTileFlipY(layer, x, y); + piece.Wait = 3 * (this.TileH + 2 * ((x - minX) >> isOOZ) - ((y - minY) >> isOOZ) ); + piece.Gravity = 0.21875; + piece.Priority = this.Priority; + + Scene.SetTile(layer, x, y, 1 + 0x3FF, false, false, 0); + } + } + } + event CollapsingPlatform_BreakStatusFromRight() { + var layer = this.TargetLayerIndex; + var minX = Number.AsInteger((this.X - this.SizeX * 0.5) / 16.0); + var maxX = minX + this.TileW; + var minY = Number.AsInteger((this.Y - this.SizeY * 0.5) / 16.0); + var maxY = minY + this.TileH; + var piece, tid; + var isOOZ = 0; + for (var x = minX; x < maxX; x++) { + for (var y = minY; y < maxY; y++) { + tid = Scene.GetTileID(layer, x, y); + if (tid == 1 + 0x3FF) + continue; + + piece = Instance.Create("BreakableWallPiece", (x * 16.0) + 8.0, (y * 16.0) + 8.0); + piece.TileID = tid; + piece.TileFlipX = Scene.GetTileFlipX(layer, x, y); + piece.TileFlipY = Scene.GetTileFlipY(layer, x, y); + piece.TileX = x; + piece.TileY = y; + piece.TileLayer = layer; + piece.Wait = 3 * (this.TileH + 2 * ((maxX - x) >> isOOZ) - ((y - minY) >> isOOZ) ); + piece.Gravity = 0.21875; + piece.Priority = this.Priority; + } + } + } + + event CollapsingPlatform_RunBreak() { + this.Status(); + Sound.Play(this.SFX_LedgeBreak); + if (this.Respawn) { + this.BreakTimer = 0; + this.PlayerX = 0.0; + } + else { + this.Active = false; + } + } +} diff --git a/Scripts/Stage/Custom/BreakableWallPiece.hsl b/Scripts/Stage/Custom/BreakableWallPiece.hsl new file mode 100644 index 0000000..447b63f --- /dev/null +++ b/Scripts/Stage/Custom/BreakableWallPiece.hsl @@ -0,0 +1,39 @@ +/* +OpenMania Custom Object +*/ +class BreakableWallPiece { + event Create() { + this.TileID = 1; + this.TileFlipX = false; + this.TileFlipY = false; + this.TileX = 0; + this.TileY = 0; + this.TileLayer = 0; + this.HitboxW = this.HitboxH = 16.0; + this.HitboxHalfW = this.HitboxHalfH = 8.0; + this.Wait = 0; + this.AutoPhysics = false; + } + + event Update() { + if (this.Wait > 0) { + this.Wait--; + this.AutoPhysics = false; + } + else { + if (!this.InView(0, this.X - this.HitboxHalfW, this.Y - this.HitboxHalfH, this.HitboxW, this.HitboxH)) { + this.Active = false; + return; + } + } + + if (!this.AutoPhysics && this.Wait == 0) { + this.AutoPhysics = true; + Scene.SetTile(this.TileLayer, this.TileX, this.TileY, 1 + 0x3FF, false, false, 0); + } + } + + event Render() { + Draw.Tile(this.TileID, Math.Floor(this.X) - 8.0, Math.Floor(this.Y) - 8.0, this.TileFlipX, this.TileFlipY); + } +} diff --git a/Scripts/Stage/Custom/ShieldObject.hsl b/Scripts/Stage/Custom/ShieldObject.hsl new file mode 100644 index 0000000..86fbcbb --- /dev/null +++ b/Scripts/Stage/Custom/ShieldObject.hsl @@ -0,0 +1,65 @@ +class ShieldObject { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Global/Shields.bin", SCOPE_SCENE); + this.SetAnimation(0, 0); + this.BlendMode = BlendMode_NORMAL; + this.Flip = false; + this.Hidden = false; + this.Behind = false; + this.Alpha = 1.0; + this.AutoAnimate = false; + this.Player = null; + } + event Update() { + if (this.Player.Shield == ShieldType_NONE) + return; + + this.Animate(); + // Basic + if (this.CurrentAnimation == 0) { + this.Flip = this.CurrentFrame >= 4; + this.Hidden = false; + this.Behind = false; + this.BlendMode = BlendMode_ADD; + this.Alpha = 0.5; + } + // Fire + else if (this.CurrentAnimation == 1 || + this.CurrentAnimation == 2) { + // this.Flip = false; + this.Hidden = false; + this.Behind = this.CurrentFrame % 2 == 1; + this.BlendMode = BlendMode_NORMAL; + this.Alpha = 1.0; + } + // Lightning + else if (this.CurrentAnimation == 3) { + this.Flip = this.CurrentFrame % 2 == 0; + this.Hidden = false; + this.Behind = this.Flip; + this.BlendMode = BlendMode_NORMAL; + this.Alpha = 1.0; + } + // Bubble + else if (this.CurrentAnimation == 5) { + this.Flip = false; + this.Hidden = false; + this.Behind = false; + this.BlendMode = BlendMode_ADD; + this.Alpha = 1.0; + } + // Instashield + else if (this.CurrentAnimation == 10) { + this.Flip = false; + this.Hidden = false; + this.Behind = true; + this.BlendMode = BlendMode_ADD; + this.Alpha = 0.5; + } + } + event OnAnimationFinish() { + if (this.CurrentAnimation == 9) { + this.SetAnimation(5, 0); + } + } +} diff --git a/Scripts/Stage/ForceUnstick.hsl b/Scripts/Stage/ForceUnstick.hsl new file mode 100644 index 0000000..5b009e0 --- /dev/null +++ b/Scripts/Stage/ForceUnstick.hsl @@ -0,0 +1,64 @@ +class ForceUnstick { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + this.Priority = DrawGroup_FGHigh_High; + + this.Width = 0; + this.Height = 0; + this.BreakClimb = false; + if (this.PropertyExists("width")) + this.Width = this.PropertyGet("width"); + if (this.PropertyExists("height")) + this.Height = this.PropertyGet("height"); + if (this.PropertyExists("breakClimb")) + this.BreakClimb = this.PropertyGet("breakClimb"); + + this.HitboxW = 16.0 * this.Width + 16.0; + this.HitboxH = 16.0 * this.Height + 16.0; + this.HitboxHalfW = this.HitboxW / 2.0; + this.HitboxHalfH = this.HitboxH / 2.0; + + this.OnScreenHitboxW = this.HitboxW; + this.OnScreenHitboxH = this.HitboxH; + + this.Visible = false; + } + event Update() { + // Player detection + with ("Player") { + if (!this.Active) + continue; + + var relX = this.X - other.X; + var relY = this.Y - other.Y; + + if (Math.Abs(relX) > other.HitboxHalfW + this.HitboxHalfW) + continue; + if (Math.Abs(relY) > other.HitboxHalfH + this.HitboxHalfH) + continue; + + this.AngleMode = 0; + if (other.BreakClimb == 1 && this.Status == this.Player_StatusKnuckles_Climbing) { + this.AnimationSpeedMult = 1.0; + this.SetAnimation(49, 2); + this.Status = this.Player_StatusKnuckles_Falling; + } + } + } + event Render() { + if (!this.Visible) + return; + if (!this.OnScreen) + return; + + Draw.Save(); + Draw.Translate(Math.Floor(this.X), Math.Floor(this.Y), 0.0); + Draw.SetBlendColor(1.0, 0.0, 1.0, 0.7); + Draw.Rectangle(-this.HitboxHalfW, -this.HitboxHalfH, this.HitboxW, this.HitboxH); + Draw.Restore(); + } +} diff --git a/Scripts/Stage/HUD.hsl b/Scripts/Stage/HUD.hsl new file mode 100644 index 0000000..02b1ba2 --- /dev/null +++ b/Scripts/Stage/HUD.hsl @@ -0,0 +1,477 @@ +var GLOBAL_SeamlessActTransition = true; +var GLOBAL_SeamlessActTransitionFlag = false; + +class HUD { + event Create() { + this.Sprite = Resources.LoadSprite("Sprites/Global/HUD.bin", SCOPE_GAME); + this.Priority = DrawGroup_HUD; + this.Ticker = 0; + + this.ButtonsSprite = Resources.LoadSprite("Sprites/Global/Mobile Buttons.bin", SCOPE_SCENE); + + this.ShowHUD = true; + this.HUDTimer = 0.0; + + this.ShowMobileButtons = true; + this.ShowMobileButtonsTimer = 1.0; + + this.ResultsSprite = Resources.LoadSprite("Sprites/Global/HUD.bin", SCOPE_SCENE); + this.DoneSpinning = false; + this.ShowResults = false; + this.ShowResultsTimer = 0; + this.ShowResultsTimerTotal = 0; + this.ShowResultsRingsTotal = 0; + this.ShowResultsSummedTotal = 0; + this.ResultsCharacter = 0; + this.ResultsAct = 1; + + this.ShowGameOver = false; + this.GameOverTimer = 0; + + // this.SFX_ScoreAdd = Resources.LoadSound("Sounds/General/ScoreAdd.wav", SCOPE_GAME); + // this.SFX_ScoreTotal = Resources.LoadSound("Sounds/General/ScoreTotal.wav", SCOPE_GAME); + + this.BGM_ActClear = Resources.LoadMusic("Music/ActClear.ogg", SCOPE_GAME); + this.BGM_GameOver = Resources.LoadMusic("Music/GameOver.ogg", SCOPE_GAME); + } + + event Update() { + this.Ticker++; + + if (this.ShowHUD) + this.HUDTimer = Math.Clamp(this.HUDTimer - 1.0 / 16.0, 0.0, 1.0); + else + this.HUDTimer = Math.Clamp(this.HUDTimer + 1.0 / 16.0, 0.0, 1.0); + + if (this.ShowMobileButtons) + this.ShowMobileButtonsTimer = Math.Clamp(this.ShowMobileButtonsTimer + 1.0 / 20.0, 0.0, 1.0); + else + this.ShowMobileButtonsTimer = Math.Clamp(this.ShowMobileButtonsTimer - 1.0 / 20.0, 0.0, 1.0); + + if (this.ShowResults) { + var pauseMan = Instance.GetNth("PauseManager", 0); + if (pauseMan) { + pauseMan.PauseDisabled = true; + } + + if (this.ShowResultsTimer >= 300) { + // this.ControlsVisible = false; + if (!this.DoneSpinning) { + var tryingToSkip = false; + + tryingToSkip |= Touch.IsDown(0); + tryingToSkip |= Input.IsMouseButtonDown(0); + var input = Instance.GetNth("InputManager", 0); + if (input) { + tryingToSkip |= input.Pause; + } + + if (tryingToSkip) { + var amountToSubtract = 100; + while (this.ShowResultsTimerTotal > 0) { + amountToSubtract = 100; + if (amountToSubtract > this.ShowResultsTimerTotal) + amountToSubtract = this.ShowResultsTimerTotal; + + this.ShowResultsTimerTotal -= amountToSubtract; + this.ShowResultsSummedTotal += amountToSubtract; + } + + while (this.ShowResultsRingsTotal > 0) { + amountToSubtract = 100; + if (amountToSubtract > this.ShowResultsRingsTotal) + amountToSubtract = this.ShowResultsRingsTotal; + + this.ShowResultsRingsTotal -= amountToSubtract; + this.ShowResultsSummedTotal += amountToSubtract; + } + + this.DoneSpinning = true; + } + else { + if (this.Ticker % 3 == 0) { + Sound.Play(this.SFX_ScoreAdd); + } + + var amountToSubtract = 100; + if (this.ShowResultsTimerTotal > 0) { + amountToSubtract = 100; + if (amountToSubtract > this.ShowResultsTimerTotal) + amountToSubtract = this.ShowResultsTimerTotal; + + this.ShowResultsTimerTotal -= amountToSubtract; + this.ShowResultsSummedTotal += amountToSubtract; + } + if (this.ShowResultsRingsTotal > 0) { + amountToSubtract = 100; + if (amountToSubtract > this.ShowResultsRingsTotal) + amountToSubtract = this.ShowResultsRingsTotal; + + this.ShowResultsRingsTotal -= amountToSubtract; + this.ShowResultsSummedTotal += amountToSubtract; + } + + this.ShowResultsTimer--; + + if (this.ShowResultsTimerTotal == 0 && this.ShowResultsRingsTotal == 0) + this.DoneSpinning = true; + } + + if (this.DoneSpinning) { + Sound.Play(this.SFX_ScoreTotal); + var player = Instance.GetNth("Player", 0); + if (player) { + player.GainScore(this.ShowResultsSummedTotal); + } + } + } + } + + if (this.ShowResultsTimer < 300 + 2) { + with ("Player") { + if (this.Ground) { + // Lock player controls + this.InputFullLock = true; + this.DoVictory(); + } + } + } + + // 6.5 seconds + 1 + if (this.ShowResultsTimer >= 390 + 60) { + // this.ResultsScreenStart(); + var nextact = Instance.GetNth("NextAct", 0); + if (nextact) { + var player = Instance.GetNth("Player", 0); + if (player) { + if (GLOBAL_SeamlessActTransition) { + GLOBAL_SeamlessActTransitionFlag = true; + player.ClearGlobals(); + Scene.Load(nextact.ScenePath); + } + else { + var fadeMan = Instance.GetNth("FadeManager", 0); + if (fadeMan && !player.FadeStarted) { + fadeMan.StartFade(60, false, false); + fadeMan.FadeSupervisor = player; + + player.FadeState = 3; + player.NextAct = nextact.ScenePath; + player.FadeStarted = true; + } + } + } + } + + this.ShowResults = false; + if (pauseMan) { + pauseMan.PauseDisabled = false; + } + } + + this.ShowResultsTimer++; + } + if (this.ShowGameOver) { + if (this.GameOverTimer >= 480) { + var player = Instance.GetNth("Player", 0); + if (player) { + var fadeMan = Instance.GetNth("FadeManager", 0); + if (fadeMan && !player.FadeStarted) { + fadeMan.StartFade(60, false, false); + fadeMan.FadeSupervisor = player; + + player.FadeState = 3; + player.NextAct = "Scenes/SEGA.tmx"; + player.FadeStarted = true; + } + } + } + this.GameOverTimer++; + } + } + + event ResultsScreenStart() { + var time = 0; + var rings = 0; + var player = Instance.GetNth("Player", 0); + if (player) { + time = player.RealTime; + rings = player.Rings; + this.ResultsCharacter = player.Character; + } + + var titlecard = Instance.GetNth("TitleCard", 0); + if (titlecard) + this.ResultsAct = titlecard.Act; + + this.ShowMobileButtons = false; + this.DoneSpinning = false; + this.ShowResults = true; + this.ShowResultsTimer = 0; + this.ShowResultsRingsTotal = rings * 100; + this.ShowResultsSummedTotal = 0; + + Music.Clear(); + Music.Play(this.BGM_ActClear); + + // this.BGM_Miniboss = Resources.LoadMusic("Music/miniboss.ogg", SCOPE_GAME); + // Music.Loop(this.BGM_Miniboss, true, 115056); // 2.609 seconds + + if (time < 60 * 60) + this.ShowResultsTimerTotal = 50000; + else if (time < 90 * 60) + this.ShowResultsTimerTotal = 10000; + else if (time < 120 * 60) + this.ShowResultsTimerTotal = 5000; + else if (time < 150 * 60) + this.ShowResultsTimerTotal = 4000; + else if (time < 180 * 60) + this.ShowResultsTimerTotal = 3000; + else if (time < 210 * 60) + this.ShowResultsTimerTotal = 1000; + else if (time < 599 * 60) + this.ShowResultsTimerTotal = 100; + else + this.ShowResultsTimerTotal = 100000; + } + event GameOverScreenStart() { + this.ShowHUD = false; + this.ShowMobileButtons = false; + this.ShowGameOver = true; + this.GameOverTimer = 0; + + Music.Clear(); + Music.Play(this.BGM_GameOver); + } + + event ClampNormal(v, a, b) { + return (Math.Clamp(v, a, b) - a) / (b - a); + } + + event DrawNumber(x, y, value, anim) { + var spr = this.Sprite; + if (value != 0) { + while (value) { + Draw.Sprite(spr, anim, (value % 10), x, y, false, false); + x -= 8.0; + value /= 10; + } + } + else { + Draw.Sprite(spr, anim, 0, x, y, false, false); + } + } + event DrawNumberPadded(x, y, value, anim, pad) { + var spr = this.Sprite; + while (pad) { + Draw.Sprite(spr, anim, (value % 10), x, y, false, false); + x -= 8.0; + value /= 10; + pad--; + } + } + + event RenderHUD() { + var vid_width = View.GetWidth(0); + var vid_height = View.GetHeight(0); + var spr = this.Sprite; + + var hud_x = 16.0; + var hud_y = 12.0; + + var top_anim = 0; + var num_anim = 1; + var num2_anim = 9; + var lifepic_anim = 2; + var lifename_anim = 3; + + var score_frame = 0; + var time_frame = 1; + var rings_frame = 3; + var blink = ((this.Ticker >> 3) & 1); + + var player = Instance.GetNth("Player", 0); + if (player && !player.Active) + player = Instance.GetNth("Player", 1); + if (player && !player.Active) + player = Instance.GetNth("Player", 2); + if (player && player.Active) { + var character = Number.AsInteger(player.Character); + var score = player.Score; + var rings = player.Rings; + var time = player.TimerFrames; + var lives = player.Lives; + num2_anim = player.CombineRing ? 9 : 1; + + // Format time + if (time > 36000 - 1) // 9' 59''99 + time = 36000 - 1; + var cc = ((time * 100) / 60) % 100; + var ss = (time / 60) % 60; + var mm = ((time / 60) / 60) % 10; + + hud_x -= this.HUDTimer * 150.0; + // Score (Text) + Draw.Sprite(spr, 0, score_frame, hud_x, hud_y, false, false); + // Score (Value) + this.DrawNumber(hud_x + 100.0, hud_y + 14.0, score, num_anim); + + hud_y += 16.0; + // Time (Text) + Draw.Sprite(spr, 0, time < 32400 ? time_frame : time_frame + blink, hud_x, hud_y, false, false); + // Time (Value) + this.DrawNumberPadded(hud_x + 100.0, hud_y + 14.0, cc, num_anim, 2); + this.DrawNumberPadded(hud_x + 75.0, hud_y + 14.0, ss, num_anim, 2); + this.DrawNumberPadded(hud_x + 50.0, hud_y + 14.0, mm, num_anim, 1); + Draw.Sprite(spr, 0, 12, hud_x + 55.0, hud_y - 2.0, false, false); + + hud_y += 16.0; + // Rings (Text) + Draw.Sprite(spr, 0, rings > 0 ? rings_frame : rings_frame + blink, hud_x, hud_y, false, false); + // Rings (Value) + this.DrawNumber(hud_x + 100.0, hud_y + 14.0, rings, num2_anim); + if (player.CombineRing) { + var digits = 0; + var value = rings; + for (var i = 0; value > 0 || (value == 0 && i == 0); i++) { + value /= 10; + digits++; + } + + Draw.Sprite(spr, 9, 10, hud_x + 100.0 - 8.0 * digits - 8.0, hud_y + 14.0, false, false); + } + + hud_y = vid_height - 12.0; + if (Device.IsMobile()) { + hud_x = vid_width - 56.0 - 16.0; + hud_y = 12.0 + 18.0; + + hud_x += this.HUDTimer * 150.0; + } + + // Lives + Draw.Sprite(spr, lifepic_anim, character, hud_x, hud_y, false, false); + Draw.Sprite(spr, 0, 14, hud_x, hud_y, false, false); + + var value; + lives = Number.AsInteger(Math.Min(lives, 99)); + + // Calculate number of digits + var digits = 0; + value = lives; + for (var i = 0; value > 0 || (value == 0 && i == 0); i++) { + value /= 10; + digits++; + } + + this.DrawNumber(hud_x + 32.0 + (digits) * 8.0, hud_y, lives, num_anim); + + if (Device.IsMobile() && !Scene.IsPaused()) { + Draw.Save(); + Draw.Translate(0.0, 0.0, 0.0); + Draw.SetBlendColor(1.0, 1.0, 1.0, this.ShowMobileButtonsTimer); + Draw.SetTextureBlend(true); + if (player.InputUp) + Draw.Sprite(this.ButtonsSprite, 0, 1, 64.0, View.GetHeight(0) - 64.0, false, false); + else if (player.InputDown) + Draw.Sprite(this.ButtonsSprite, 0, 2, 64.0, View.GetHeight(0) - 64.0, false, false); + else if (player.InputLeft) + Draw.Sprite(this.ButtonsSprite, 0, 3, 64.0, View.GetHeight(0) - 64.0, true, false); + else if (player.InputRight) + Draw.Sprite(this.ButtonsSprite, 0, 3, 64.0, View.GetHeight(0) - 64.0, false, false); + else + Draw.Sprite(this.ButtonsSprite, 0, 0, 64.0, View.GetHeight(0) - 64.0, false, false); + Draw.Sprite(this.ButtonsSprite, 0, 4, vid_width - 64.0, View.GetHeight(0) - 64.0, false, false); + Draw.SetTextureBlend(false); + Draw.SetBlendColor(1.0, 1.0, 1.0, 1.0); + Draw.Restore(); + } + } + } + event RenderResults() { + var vid_width = View.GetWidth(0); + var vid_height = View.GetHeight(0); + + var resultsTimer = this.ShowResultsTimer / 60.0; + if (this.ShowResultsTimer > 390) + resultsTimer = (60 - (this.ShowResultsTimer - 390)) / 60.0; + + var value; + var anim_player_got = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.0, 0.4)) * vid_width - vid_width; + var anim_through_act = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.2, 0.6)) * -vid_width + vid_width; + var anim_time_bonus = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.5, 0.8)) * -vid_width + vid_width; + var anim_ring_bonus = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.6, 0.9)) * -vid_width + vid_width; + var anim_total = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.7, 1.0)) * -vid_width + vid_width; + + // Player Name + Draw.Sprite(this.ResultsSprite, 3, this.ResultsCharacter, vid_width / 2.0 + anim_player_got, 64.0, false, false); + // Got + Draw.Sprite(this.ResultsSprite, 4, 0, vid_width / 2.0 + anim_player_got, 64.0, false, false); + // Through + Draw.Sprite(this.ResultsSprite, 4, 1, vid_width / 2.0 + anim_through_act, 88.0, false, false); + // Act ? + Draw.Sprite(this.ResultsSprite, 5, this.ResultsAct - 1, vid_width / 2.0 + anim_through_act, 88.0, false, false); + + // Time Bonus + Draw.Sprite(this.ResultsSprite, 0, 1, vid_width / 2.0 - 128 + anim_time_bonus, 128, false, false); + Draw.Sprite(this.ResultsSprite, 0, 8, vid_width / 2.0 - 128 + 40 + anim_time_bonus, 128, false, false); + + // Ring Bonus + Draw.Sprite(this.ResultsSprite, 0, 5, vid_width / 2.0 - 128 + anim_ring_bonus, 144, false, false); + Draw.Sprite(this.ResultsSprite, 0, 8, vid_width / 2.0 - 128 + 40 + anim_ring_bonus, 144, false, false); + + // Total + Draw.Sprite(this.ResultsSprite, 0, 9, vid_width / 2.0 - 112 + anim_total, 176, false, false); + + // Time Bonus Value + value = this.ShowResultsTimerTotal; + for (var i = 0; i < 7 && (value > 0 || (value == 0 && i == 0)); i++) { + Draw.Sprite(this.ResultsSprite, 1, value % 10, vid_width / 2.0 + 112 - i * 8 - 4 + anim_time_bonus, 128 + 14, false, false); + value /= 10; + } + + // Ring Bonus Value + value = this.ShowResultsRingsTotal; + for (var i = 0; i < 7 && (value > 0 || (value == 0 && i == 0)); i++) { + Draw.Sprite(this.ResultsSprite, 1, value % 10, vid_width / 2.0 + 112 - i * 8 - 4 + anim_ring_bonus, 144 + 14, false, false); + value /= 10; + } + + // Total Value + value = this.ShowResultsSummedTotal; + for (var i = 0; i < 7 && (value > 0 || (value == 0 && i == 0)); i++) { + Draw.Sprite(this.ResultsSprite, 1, value % 10, vid_width / 2.0 + 112 - i * 8 - 4 + anim_total, 176 + 14, false, false); + value /= 10; + } + } + event RenderGameOver() { + var vid_width = View.GetWidth(0); + var vid_height = View.GetHeight(0); + var resultsTimer = this.GameOverTimer / 60.0; + + var anim_gameover = Ease.OutQuad(this.ClampNormal(resultsTimer, 0.0, 0.2)) * vid_width - vid_width; + + Draw.SetBlendColor(0.0, 0.0, 0.0, 1.0); + Draw.Rectangle(vid_width / 2.0 - 20.0 * 9.0 / 2.0 - 12 + anim_gameover, vid_height / 2.0, 20 * 9 + 8, 14.0); + + var lx; + for (var i = 0; i < 8; i++) { + anim_gameover = Ease.OutQuad(this.ClampNormal(resultsTimer, i * 0.2 + 0.4, i * 0.2 + 0.8)) * -vid_width + vid_width; + lx = vid_width / 2.0 - 20.0 * 9.0 / 2.0 + anim_gameover + i * 20; + + if (i >= 4) + lx += 20.0; + + Draw.Sprite(this.ResultsSprite, 6, i, lx, vid_height / 2.0, false, false); + } + } + + event Render() { + Draw.Save(); + Draw.Translate(Math.Floor(CameraX), Math.Floor(CameraY), 0.0); + this.RenderHUD(); + this.RenderResults(); + this.RenderGameOver(); + Draw.Restore(); + } +} diff --git a/Scripts/Stage/InvisibleBlock.hsl b/Scripts/Stage/InvisibleBlock.hsl new file mode 100644 index 0000000..43ce6a8 --- /dev/null +++ b/Scripts/Stage/InvisibleBlock.hsl @@ -0,0 +1,90 @@ +class InvisibleBlock { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + this.Priority = DrawGroup_FGHigh_High; + + this.Width = 0; + this.Height = 0; + this.PlaneFilter = 0; + this.NoCrush = false; + this.ActiveNormal = false; + this.TimeAttackOnly = false; + this.NoChibi = false; + if (this.PropertyExists("width")) + this.Width = this.PropertyGet("width"); + if (this.PropertyExists("height")) + this.Height = this.PropertyGet("height"); + if (this.PropertyExists("planeFilter")) + this.PlaneFilter = this.PropertyGet("planeFilter"); + if (this.PropertyExists("noCrush")) + this.NoCrush = this.PropertyGet("noCrush"); + if (this.PropertyExists("activeNormal")) + this.ActiveNormal = this.PropertyGet("activeNormal"); + if (this.PropertyExists("timeAttackOnly")) + this.TimeAttackOnly = this.PropertyGet("timeAttackOnly"); + if (this.PropertyExists("noChibi")) + this.NoChibi = this.PropertyGet("noChibi"); + + if (this.TimeAttackOnly && global.GameMode < 2) { + this.Active = false; + return; + } + + this.HitboxW = 16.0 * this.Width + 16.0; + this.HitboxH = 16.0 * this.Height + 16.0; + this.HitboxHalfW = this.HitboxW / 2.0; + this.HitboxHalfH = this.HitboxH / 2.0; + this.FlipFlag = false; + + this.Visible = false; + + this.OnScreenHitboxW = this.HitboxW; + this.OnScreenHitboxH = this.HitboxH; + } + event Update() { + // Player detection + var player, block = this; + with ("Player") { + player = this; + var planeFilter = block.PlaneFilter; + if (planeFilter <= 0 || player.PlaneIndex == ((planeFilter - 1) & 1)) { + if (!block.NoChibi || !player.UseChibiSprite) { + switch (Static.Entity_SolidCollideWithPlayer(block, player)) { + case 1: + if (!block.NoCrush) + player.VerticalCollisionFlag |= 1; + break; + case 2: + if (!block.NoCrush) + player.HorizontalCollisionFlag |= 1; + break; + case 3: + if (!block.NoCrush) + player.HorizontalCollisionFlag |= 2; + break; + case 4: + if (!block.NoCrush) + player.VerticalCollisionFlag |= 2; + break; + } + } + } + } + } + event Render() { + if (!this.Visible) + return; + if (!this.OnScreen) + return; + + Draw.Save(); + Draw.Translate(Math.Floor(this.X), Math.Floor(this.Y), 0.0); + Draw.SetBlendColor(1.0, 1.0, 1.0, 0.7); + Draw.Rectangle(-this.HitboxHalfW, -this.HitboxHalfH, this.HitboxW, this.HitboxH); + Draw.Restore(); + } +} diff --git a/Scripts/Stage/ItemBox.hsl b/Scripts/Stage/ItemBox.hsl new file mode 100644 index 0000000..c55c21e --- /dev/null +++ b/Scripts/Stage/ItemBox.hsl @@ -0,0 +1,455 @@ +class ItemBox { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Pre + this.Priority = DrawGroup_FGLow_Low; + this.HighPriority = DrawGroup_FGHigh_High; + + // Load + this.Sprite = Resources.LoadSprite("Sprites/Global/ItemBox.bin", SCOPE_GAME); + this.SFX_Destroy = Resources.LoadSound("SoundFX/Global/Destroy.wav", SCOPE_GAME); + this.SFX_Teleport = Resources.LoadSound("SoundFX/Global/Teleport.wav", SCOPE_GAME); + this.SFX_HyperRing = Resources.LoadSound("SoundFX/Global/HyperRing.wav", SCOPE_GAME); + this.SFX_PowerDown = Resources.LoadSound("SoundFX/Stage/PowerDown.wav", SCOPE_GAME); + this.SFX_Recovery = Resources.LoadSound("SoundFX/Global/Recovery.wav", SCOPE_GAME); + this.AutoPhysics = false; + this.Status = null; + + this.AutoAnimate = true; + + // Setup + this.Type = 0; + this.IsFalling = false; + this.Hidden = false; + this.Direction = 0; + this.PlaneFilter = 0; + this.LRZConvPhys = false; + this.Broken = false; + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("isFalling")) + this.IsFalling = this.PropertyGet("isFalling"); + if (this.PropertyExists("hidden")) + this.Hidden = this.PropertyGet("hidden"); + if (this.PropertyExists("direction")) + this.Direction = this.PropertyGet("direction"); + if (this.PropertyExists("planeFilter")) + this.PlaneFilter = this.PropertyGet("planeFilter"); + if (this.PropertyExists("lrzConvPhys")) + this.LRZConvPhys = this.PropertyGet("lrzConvPhys"); + + this.PowerupFrame = 0; + this.PowerupX = 0.0; + this.PowerupY = 0.0; + this.SnowTimer = 4; + this.NotFalling = 0; + + this.DeltaX = 0.0; + this.DeltaY = 0.0; + + // // OnCreate + if (this.Status == null) { + this.SetAnimation(4, 0); + + var type = this.Type; + var gamemode = 0; + switch (type) { + case 7: + case 8: + case 9: + case 15: + case 16: + if (gamemode == 2) { + this.Type = 0; + } + else if (gamemode == 1) { + this.Type = 17; + } + else { + var player, itemBox = this; + with ("Player") { + player = this; + if (!player.Active) + continue; + + if (player.Character == Character_SONIC) + itemBox.Type = 7; + else if (player.Character == Character_TAILS) + itemBox.Type = 8; + else if (player.Character == Character_KNUCKLES) + itemBox.Type = 9; + else if (player.Character == Character_MIGHTY) + itemBox.Type = 15; + else if (player.Character == Character_RAY) + itemBox.Type = 16; + + continue; + } + + this.PowerupFrame = itemBox.Type; + } + break; + case 12: + case 13: + if (gamemode != 1 && gamemode != 3) { + this.Active = false; + return; + } + break; + } + } + + var planeFilter = this.PlaneFilter; + if (planeFilter > 0 && (planeFilter - 1) & 2) + this.Priority = DrawGroup_FGHigh_High; + else + this.Priority = DrawGroup_FGLow_Low; + + if (this.Hidden) { + this.Status = null; + } + else if (this.IsFalling) { + this.Status = this.ItemBox_StatusFalling; + } + else if (this.LRZConvPhys) { + // this.Status = this.ItemBox_StatusLRZConvPhys; + } + else { + this.Status = this.ItemBox_StatusNormal; + } + + this.FlipFlag = this.Direction; + this.HitboxW = 30.0; + this.HitboxH = 32.0; + + this.OnScreenHitboxW = this.OnScreenHitboxH = 32.0; + } + + event OnAnimationFinish() { + if (!this.Broken) + this.AnimationSpeedMult = 0.0; + + if (this.Status == this.ItemBox_StatusWaitingForItemDisappear) { + this.AnimationSpeedMult = 0.0; + this.ResetAnimation(this.CurrentAnimation, 13); + } + } + + event Update() { + if (this.Status) + this.Status(); + + // TODO: Finish ItemBox_Update + if (this.Type == 17) { + // var animation = + } + } + + event ItemBox_StatusNormal() { + var flip = this.Direction == 0; + this.PowerupX = 0.0; + this.PowerupY = flip ? -3.0 : 3.0; + + this.ItemBox_DoCollideWithSolids(); + this.ItemBox_DoCollideWithPlayer(); + + if (this.Type == 17) { + + } + + var snowTimer = this.SnowTimer; + if (snowTimer > 0) { + this.SnowTimer = snowTimer - 1; + } + else { + this.SnowTimer = Number.AsInteger(Math.RandomRange(1, 15)); + this.AnimationSpeedMult = 1.0; + } + } + event ItemBox_StatusFalling() { + this.ItemBox_DoGravityAndSolidCollision(); + + if (this.NotFalling) + this.Status = this.ItemBox_StatusNormal; + + var flip = this.Direction == 0; + this.PowerupX = 0.0; + this.PowerupY = flip ? -3.0 : 3.0; + + this.ItemBox_DoCollideWithPlayer(); + + if (this.Type == 17) { + + } + + var snowTimer = this.SnowTimer; + if (snowTimer > 0) { + this.SnowTimer = snowTimer - 1; + } + else { + this.SnowTimer = Number.AsInteger(Math.RandomRange(1, 15)); + this.AnimationSpeedMult = 1.0; + } + } + event ItemBox_StatusLRZConvPhys() { + + } + event ItemBox_StatusPostBreakup() { + if (this.LRZConvPhys) { + } + else + this.ItemBox_DoGravityAndSolidCollision(); + + var yspeed = this.PowerupYSpeed; + if (yspeed < 0) { + this.PowerupY += yspeed; + this.PowerupYSpeed = yspeed + 0.09375; + } + + this.PowerupY -= this.DeltaY; + + this.OnScreenHitboxW = this.OnScreenHitboxH = 0.0; + + if (this.PowerupYSpeed >= 0.0) { + this.PowerupYSpeed = 0.0; + + this.ItemBox_SendItemToPlayer(); + + this.AnimationSpeedMult = 1.0; + this.SetAnimation(5, 0); + this.Status = this.ItemBox_StatusWaitingForItemDisappear; + } + } + event ItemBox_StatusWaitingForItemDisappear() { + if (this.LRZConvPhys) { + } + else + this.ItemBox_DoGravityAndSolidCollision(); + + this.PowerupY -= this.DeltaY; + + // In Mania, Animate() is called here + if (this.CurrentFrame == 14 - 1) { + this.AnimationSpeedMult = 0.0; + this.ResetAnimation(this.CurrentAnimation, 13); + // this.Status = null; + + this.OnScreenHitboxW = this.OnScreenHitboxH = 32.0; + } + } + + event ItemBox_SendItemToPlayer() { + // AYAYYAYA + var player = this.PlayerToReceivePowerup; + if (!player) + return; + + switch (this.Type) { + case 0: + player.GainRings(10); + Sound.Play(player.SFX_RingLeft); + Sound.Play(player.SFX_RingRight); + break; + case 1: + player.GiveShield(ShieldType_BASIC, true); + break; + case 2: + player.GiveShield(ShieldType_BUBBLE, true); + break; + case 3: + player.GiveShield(ShieldType_FIRE, true); + break; + case 4: + player.GiveShield(ShieldType_ELECTRIC, true); + break; + case 5: + // invinc + break; + case 6: + // speed + player.SpeedShoesTimer = 1320; // 22 seconds + player.Player_ResetSpeeds(); + break; + case 7: + case 8: + case 9: + case 15: + case 16: + player.GainLife(); + break; + case 10: + player.GetHurt(); + break; + case 11: + player.CombineRing = true; + Sound.Play(player.SFX_HyperRing); + break; + case 12: + // switch character + break; + case 13: + // random + break; + case 14: + player.SuperForm = 2; + break; + } + } + + event ItemBox_DoGravityAndSolidCollision() { + this.DeltaX = -this.X; + this.DeltaY = -this.Y; + if (this.YSpeed != 0.0) + this.NotFalling = 0; + + this.X += this.XSpeed; + this.Y += this.YSpeed; + this.YSpeed += 0.21875; + + this.ItemBox_DoCollideWithSolids(); + // TODO: + if (this.YSpeed >= 0.0 && (!this.Broken ? TileCollision.Point(this.X, this.Y + 16.0) : TileCollision.Point(this.X, this.Y + 16.0))) { + var itemBoxStatus = this.Status; + this.YSpeed = 0.0; + this.NotFalling = 1; + if (itemBoxStatus != this.ItemBox_StatusWaitingForItemDisappear && + itemBoxStatus != this.ItemBox_StatusPostBreakup) { + } + this.DeltaX += this.X; + this.DeltaY += this.Y; + } + else { + this.DeltaX += this.X; + this.DeltaY += this.Y; + } + } + + event ItemBox_DoCollideWithSolids() { } + event ItemBox_DoCollideWithPlayer() { + var itemBox = this, player; + with ("Player") { + player = this; + if (!player.Active) + continue; + + var planeFilter = itemBox.PlaneFilter; + if (planeFilter <= 0 || player.PlaneIndex == ((planeFilter - 1) & 1)) { + if (player.Character == Character_MIGHTY && player.MidAirFlag > 1 && !itemBox.NotFalling) { + + } + + var animation = player.CurrentAnimation; + var canBreakViaJump = animation == 10 && (player.YSpeed >= 0.0 || player.Ground || itemBox.Direction); + var canBreak = canBreakViaJump || player.Status == player.Player_StatusFrozen_PGZ; + if (player.Character == Character_SONIC) { + canBreak |= animation == 16; + } + else if (player.Character == Character_KNUCKLES) { + canBreak |= animation == 48 || animation == 51; + } + else if (player.Character == Character_MIGHTY) { + canBreak |= animation == 16 || player.MidAirFlag > 1; + } + + if (!canBreak) { + var initialPlayerX = player.X; + var initialPlayerY = player.Y; + var side = Static.Entity_SolidCollideWithPlayer(itemBox, player); + // Not top side + if (side != 1) { + // Bottom side + if (side == 4) { + if (!itemBox.LRZConvPhys) + itemBox.Status = itemBox.ItemBox_StatusFalling; + + itemBox.YSpeed = -2.0; + if (!player.Ground) + player.YSpeed = 2.0; + } + } + // Top side + else { + + } + + if (Static.Entity_SolidCollideWithPlayer(itemBox, player) == 4) { + if (player.Ground) { + player.X = initialPlayerX; + player.Y = initialPlayerY; + } + } + } + // TODO: Fix + else if (Static.CollideWithObject(itemBox, player) == 1) { + // If not Mighty or (implied Mighty and) Drill Dive + if (player.Character != Character_MIGHTY || player.CurrentAnimation != 16) + player.YSpeed = -(player.YSpeed + 2.0 * player.GravityRate); + else + player.YSpeed -= 1.0; + itemBox.PlayerToReceivePowerup = player; + itemBox.PowerupYSpeed = -3.0; + itemBox.YSpeed = -2.0; + itemBox.Broken = true; + itemBox.Status = itemBox.ItemBox_StatusPostBreakup; + // Custom + itemBox.AnimationSpeedMult = 1.0; + itemBox.SetAnimation(2, itemBox.Type); + + // Spawn Explosion + var expl = Instance.Create("Explosion", itemBox.X, itemBox.Y - 16.0); + expl.Priority = itemBox.Priority; // itemBox.HighPriority; + + // Spawn Debris + for (var i = 0; i < 6; i++) { + expl = Instance.Create("Debris", itemBox.X + Math.RandomRange(-8.0, 8.0), itemBox.Y + Math.RandomRange(-8.0, 8.0)); + // expl.Status = null; + expl.Gravity = 0.25; + expl.XSpeed = Math.RandomMax(2.0); + if (expl.X < itemBox.X) + expl.XSpeed = -expl.XSpeed; + expl.YSpeed = Math.RandomRange(-4.0, -1.0); + expl.Priority = itemBox.Priority; + expl.Sprite = itemBox.Sprite; + expl.ResetAnimation(6, Number.AsInteger(Math.RandomMax(4))); + } + + Sound.Play(itemBox.SFX_Destroy); + // break; + // return; + continue; + } + } + } + } + + event Render() { + if (!this.OnScreen) + return; + if (this.Hidden) + return; + + var flipX = (this.FlipFlag & 1); + var flipY = (this.FlipFlag & 2); + + var x = Math.Floor(this.X), y = Math.Floor(this.Y); + Draw.Sprite(this.Sprite, this.Broken, 0, x, y, flipX, flipY); + if (this.Broken) { + // Powerup + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, x + this.PowerupX, y + this.PowerupY, flipX, flipY); + } + else { + // Powerup + Draw.Sprite(this.Sprite, 2, this.Type, x + this.PowerupX, y + this.PowerupY, flipX, flipY); + + // Scanline + // Draw.Sprite(this.Sprite, 3, Scene_Frame & 1, x, y, flipX, flipY); + + // Snow + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, x, y, flipX, flipY); + } + } +} diff --git a/Scripts/Stage/MSZ/LightBulb.hsl b/Scripts/Stage/MSZ/LightBulb.hsl new file mode 100644 index 0000000..c638d5e --- /dev/null +++ b/Scripts/Stage/MSZ/LightBulb.hsl @@ -0,0 +1,95 @@ +class LightBulb { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Load + this.Sprite = Resources.LoadSprite("Sprites/MSZ/LightBulb.bin", SCOPE_GAME); + this.SFX_BulbPop = Resources.LoadSound("SoundFX/Stage/BulbPop.wav", SCOPE_GAME); + this.Status = null; + + // Setup + this.Respawn = 0; + this.PriorityFlag = 0; + if (this.PropertyExists("respawn")) + this.Respawn = this.PropertyGet("respawn"); + if (this.PropertyExists("priority")) + this.PriorityFlag = this.PropertyGet("priority"); + + if (this.PriorityFlag) + this.Priority = DrawGroup_FGLow_Low; + else + this.Priority = DrawGroup_FGHigh_High; + + // Initial Status + this.SetAnimation(0, 0); + this.HitboxW = this.HitboxH = 24.0; // Might be 24.0 for LightBulb + + this.OnScreenHitboxW = this.OnScreenHitboxH = 48.0; + } + + event Update() { + if (!this.InView(0, this.X - this.HitboxW / 2.0, this.Y - this.HitboxH / 2.0, this.HitboxW, this.HitboxH)) + return; + + if (this.CollidedWithObject("Player")) { + // Hurt + if (other.CurrentAnimation == 18) + return; + + // Spawn explosion here, grey smoke puff + // Spawn confetti particles + var playerAnim = other.CurrentAnimation; + if (playerAnim != 48 && playerAnim != 51) { + var playerStatus = other.Status; + if (playerStatus != other.Player_StatusTails_Flying) { + if (playerStatus != other.Player_StatusSonic_DropDash) { + other.Status = other.Player_StatusJumping; + } + if (playerAnim != 10 && playerAnim != 7 && playerAnim != 8 && playerAnim != 9) { + other.CurrentAnimation = 5; + } + } + } + + // TODO: + // Add "continue" to Compiler + // Add continue to "with" + // Add do while + // Add switch statements ("switch", "case") + // enums? + // + + if (other.CurrentAnimation != 48) + other.JumpAbility = 0; + other.YSpeed = -8.0; + other.Ground = false; + other.UseGroundSpeed = 1; + other.GainScore(10); // This needs to spawn a Score thing too + Sound.Play(this.SFX_BulbPop); + + this.Active = false; + } + } + event Render() { + if (!this.OnScreen) + return; + + var x = Math.Floor(this.X), y = Math.Floor(this.Y); + + Draw.Sprite(this.Sprite, 0, 0, x, y, false, false); + Draw.Sprite(this.Sprite, 0, 1, x, y, false, false); + Draw.SetBlendMode(BlendMode_ADD); + Draw.SetTextureBlend(true); + Draw.SetBlendColor(1.0, 1.0, 1.0, Static.HexSin(Scene_Frame << 2) * 0.25 + 0.75); + Draw.Sprite(this.Sprite, 0, 2, x, y, false, false); + Draw.SetBlendColor(1.0, 1.0, 1.0, 1.0); + Draw.SetTextureBlend(false); + Draw.SetBlendMode(BlendMode_NORMAL); + + // LightBulb is layered as: + // 0, then 1, then 2 as an additive blended sin wave alpha + } +} diff --git a/Scripts/Stage/MSZ/MSZSetup.hsl b/Scripts/Stage/MSZ/MSZSetup.hsl new file mode 100644 index 0000000..f7aba86 --- /dev/null +++ b/Scripts/Stage/MSZ/MSZSetup.hsl @@ -0,0 +1,5 @@ +class MSZSetup { + event Create() { + Scene.SetLayerVisible(4, false); + } +} diff --git a/Scripts/Stage/MSZ/Pinata.hsl b/Scripts/Stage/MSZ/Pinata.hsl new file mode 100644 index 0000000..4bb8b4e --- /dev/null +++ b/Scripts/Stage/MSZ/Pinata.hsl @@ -0,0 +1,118 @@ +class Pinata { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Pre + var index; + if ((index = Scene.GetLayerIndex("FG Low")) != -1) { + this.Priority = index * 4 + 1; + } + + // Load + this.Sprite = Resources.LoadSprite("Sprites/MSZ/Pinata.bin", SCOPE_GAME); + this.SFX_Pinata = Resources.LoadSound("SoundFX/MSZ/Pinata.wav", SCOPE_GAME); + this.Status = null; + + // Setup + this.Respawn = 0; + this.PriorityFlag = 0; + if (this.PropertyExists("respawn")) + this.Respawn = this.PropertyGet("respawn"); + if (this.PropertyExists("priority")) + this.PriorityFlag = this.PropertyGet("priority"); + + if (this.PriorityFlag) + this.Priority = DrawGroup_FGLow_Low; + else + this.Priority = DrawGroup_FGHigh_High; + + // Initial Status + this.SetAnimation(3, 0); + this.HitboxW = this.HitboxH = 32.0; // Might be 24.0 for LightBulb + + this.OnScreenHitboxW = this.OnScreenHitboxH = 48.0; + } + + event Update() { + var enti; + if (this.CollidedWithObject("Player")) { + // Hurt + if (other.CurrentAnimation == 18) + return; + + Sound.Play(this.SFX_Pinata); + + var playerStatus = other.Status; + if (playerStatus != other.Player_StatusMighty_HammerDrop) { + if (playerStatus == other.Player_StatusHangingFromTails) { + + } + + var playerAnim = other.CurrentAnimation; + if (playerAnim != 48 && playerAnim != 51) { + if (playerStatus != other.Player_StatusTails_Flying) { + if (playerStatus != other.Player_StatusSonic_DropDash) { + other.Status = other.Player_StatusJumping; + } + if (playerAnim != 10 && playerAnim != 7 && playerAnim != 8 && playerAnim != 9) { + other.SetAnimation(5, 0); + } + } + } + + if (other.CurrentAnimation != 48) + other.JumpAbility = 0; + + if (other.YSpeed > -8.0) + other.YSpeed = -8.0; + + other.Ground = false; + other.UseGroundSpeed = 1; + } + + // Spawn ScoreBonus + enti = Instance.Create("ScoreBonus", this.X, this.Y); + enti.Priority = this.Priority + 1; + enti.ResetAnimation(0, 16); + other.GainScore(10); // This needs to spawn a Score thing too + + // Spawn Explosion + enti = Instance.Create("Explosion", this.X, this.Y - 16.0); + enti.Priority = this.Priority; + enti.ResetAnimation(3, 0); + + // Spawn Debris + for (var i = 0; i < 6; i++) { + enti = Instance.Create("Debris", this.X + Math.RandomRange(-8.0, 8.0), this.Y + Math.RandomRange(-8.0, 8.0)); + // enti.Status = null; + enti.Gravity = 0.25; + enti.XSpeed = Math.RandomMax(2.0); + if (enti.X < this.X) + enti.XSpeed = -enti.XSpeed; + enti.YSpeed = Math.RandomRange(-4.0, -1.0); + enti.Priority = this.Priority; + enti.Sprite = this.Sprite; + // NOTE: Mania just uses the first confetti, the orange one + // enti.ResetAnimation(0, Number.AsInteger(Math.RandomMax(4))); + enti.ResetAnimation(Number.AsInteger(Math.RandomMax(3)), Number.AsInteger(Math.RandomMax(4))); + } + + + // TODO: + // Add switch statements ("switch", "case") + // enums? + // + + this.Active = false; + } + } + event Render() { + if (!this.OnScreen) + return; + + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), false, false); + } +} diff --git a/Scripts/Stage/PlaneSwitch.hsl b/Scripts/Stage/PlaneSwitch.hsl new file mode 100644 index 0000000..6eb2dfe --- /dev/null +++ b/Scripts/Stage/PlaneSwitch.hsl @@ -0,0 +1,184 @@ +class PlaneSwitch { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + this.Priority = DrawGroup_FGHigh_High; + + this.Angle = 0; + this.OnPath = false; + this.Flags = 0; + this.InLayer = 0; + this.InLayerVisual = 0; + this.OutLayer = 0; + this.OutLayerVisual = 0; + this.Size = 0; + + if (this.PropertyExists("angle")) + this.Angle = this.PropertyGet("angle"); + if (this.PropertyExists("onPath")) + this.OnPath = this.PropertyGet("onPath"); + if (this.PropertyExists("size")) + this.Size = 16.0 * this.PropertyGet("size"); + if (this.PropertyExists("flags")) { + var flags = this.PropertyGet("flags"); + this.InLayerVisual = !!(flags & 1); + this.InLayer = !!(flags & 2); + this.OutLayerVisual = !!(flags & 4); + this.OutLayer = !!(flags & 8); + this.Flags = flags; + } + + this.PlaneSprite = Resources.LoadSprite("Sprites/Global/PlaneSwitch.bin", SCOPE_SCENE); + + if (this.InLayerVisual) + this.InLayerVisual = DrawGroup_AboveTiles; + else + this.InLayerVisual = DrawGroup_FGLow_High; + + if (this.OutLayerVisual) + this.OutLayerVisual = DrawGroup_AboveTiles; + else + this.OutLayerVisual = DrawGroup_FGLow_High; + + // Set hitbox + if (this.Angle == 0) { + this.HitboxW = 32.0; + this.HitboxH = this.Size; + } + else { + var anX; + var anY; + var minX = 0.0; + var maxX = 0.0; + var minY = 0.0; + var maxY = 0.0; + var sizeMult = this.Size / -8.0; + var sinVal = Static.HexSin(this.Angle) * 16.0; + var cosVal = Static.HexCos(this.Angle) * 16.0; + anX = sizeMult * sinVal - cosVal; + anY = sizeMult * cosVal + sinVal; + minX = Math.Min(minX, anX); minY = Math.Min(minY, anY); + maxX = Math.Max(maxX, anX); maxY = Math.Max(maxY, anY); + minX = Math.Min(minX, -anX); minY = Math.Min(minY, -anY); + maxX = Math.Max(maxX, -anX); maxY = Math.Max(maxY, -anY); + anX = sizeMult * sinVal + cosVal; + anY = sizeMult * cosVal - sinVal; + minX = Math.Min(minX, anX); minY = Math.Min(minY, anY); + maxX = Math.Max(maxX, anX); maxY = Math.Max(maxY, anY); + minX = Math.Min(minX, -anX); minY = Math.Min(minY, -anY); + maxX = Math.Max(maxX, -anX); maxY = Math.Max(maxY, -anY); + + this.HitboxW = maxX - minX; + this.HitboxH = maxY - minY; + } + + this.HitboxHalfW = this.HitboxW / 2.0; + this.HitboxHalfH = this.HitboxH / 2.0; + + this.OnScreenHitboxW = this.HitboxW; + this.OnScreenHitboxH = this.HitboxH; + + this.CosVal = Static.HexCos(this.Angle); + this.SinVal = Static.HexSin(this.Angle); + this.RCosVal = Static.HexCos(-this.Angle + 0x100); + this.RSinVal = Static.HexSin(-this.Angle + 0x100); + + this.Visible = false; + } + event Update() { + // PlaneSwitch detection + with ("Player") { + if (other.OnPath && !this.Ground) + continue; + + var relX = this.X - other.X; + var relY = this.Y - other.Y; + + if (Math.Abs(relX) > other.HitboxHalfW) + continue; + if (Math.Abs(relY) > other.HitboxHalfH) + continue; + + var cos = other.RCosVal; + var sin = other.RSinVal; + + var projectedX = relY * sin + relX * cos; + var projectedY = relY * cos - relX * sin; + var projectedSpeed = this.YSpeed * sin + this.XSpeed * cos; + + if (Math.Abs(projectedX) >= 24.0) + continue; + if (Math.Abs(projectedY) >= other.Size / 2.0) + continue; + + if (projectedX + projectedSpeed >= 0.0) { + if (this.PlaneIndex != other.OutLayer) + // print "PlaneSwitch: " + this.PlaneIndex + " -> " + other.OutLayer + " (" + projectedX + ", " + projectedY + ")"; + + this.PlaneIndex = other.OutLayer; + this.Priority = other.OutLayerVisual; + } + else { + if (this.PlaneIndex != other.InLayer) + // print "PlaneSwitch: " + this.PlaneIndex + " -> " + other.InLayer + " (" + projectedX + ", " + projectedY + ")"; + + this.PlaneIndex = other.InLayer; + this.Priority = other.InLayerVisual; + } + } + } + event Render() { + if (!this.Visible) + return; + if (!this.OnScreen) + return; + + var cos = this.CosVal; + var sin = this.SinVal; + var cos16 = cos * 16.0; + var sin16 = sin * 16.0; + + var sx = Math.Floor(this.X), sy = Math.Floor(this.Y); + var x, y, frame, tempX, tempY; + + // Path In + x = sx - 8.0; + y = sy - this.Size / 2.0; + frame = (this.Flags & 3); + + tempX = y * sin + x * cos; + tempY = y * cos - x * sin; + x = tempX; y = tempY; + + for (var i = 0.0; i < this.Size; i += 16.0) { + Draw.Sprite(this.PlaneSprite, 0, frame, x, y, false, false); + x += sin16; + y += cos16; + } + + // Path Out + x = sx + 8.0; + y = sy - this.Size / 2.0; + frame = ((this.Flags >> 2) & 3); + + tempX = y * sin + x * cos; + tempY = y * cos - x * sin; + x = tempX; y = tempY; + + for (var i = 0.0; i < this.Size; i += 16.0) { + Draw.Sprite(this.PlaneSprite, 0, frame, x, y, false, false); + x += sin16; + y += cos16; + } + + // if (this.projectedX != 0.0) { + // Draw.Rotate(0.0, 0.0, this.Angle * -Math_PI / 128.0); + // Draw.SetBlendColor(1.0, 0.0, 0.0, 1.0); + // Draw.Rectangle(this.projectedX, this.projectedY, 64.0, 1.0); + // Draw.Rectangle(this.projectedX, this.projectedY - 32.0, 1.0, 64.0); + // } + } +} diff --git a/Scripts/Stage/Platform.hsl b/Scripts/Stage/Platform.hsl new file mode 100644 index 0000000..9baa225 --- /dev/null +++ b/Scripts/Stage/Platform.hsl @@ -0,0 +1,835 @@ +class Platform { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + this.Priority = DrawGroup_FGLow_Low + 1; + + this.Type = 0; + this.AmplitudeX = 0.0; + this.AmplitudeY = 0.0; + this.Speed = 0; + this.HasTension = 0; + this.FrameID = 0; + this.Collision = 0; + this.TileOriginX = 0.0; + this.TileOriginY = 0.0; + this.ChildCount = 0; + this.Angle = 0; + this.Rotation = 0; + this.Status = null; + this.CollisionStatus = null; + this.Visible = true; + + this.OnScreenHitboxW = 0.0; + this.OnScreenHitboxH = 0.0; + + this.StartX = this.X; + this.StartY = this.Y; + this.FinalX = this.X; + this.FinalY = this.Y; + this.TensionValue = 0; + this.PlayerAtop = false; + this.PlayerOnTopFlag = 0; + this.PlayerOnLeftFlag = 0; + this.PlayerOnRightFlag = 0; + this.PlayerOnBottomFlag = 0; + + this.DeltaX = 0.0; + this.DeltaY = 0.0; + this.PossibleTimerUntilDrop = 0; + + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("amplitude")) { + var amplitude = this.PropertyGet("amplitude"); + this.AmplitudeX = amplitude[0]; + this.AmplitudeY = amplitude[1]; + } + if (this.PropertyExists("speed")) + this.Speed = this.PropertyGet("speed"); + if (this.PropertyExists("hasTension")) + this.HasTension = this.PropertyGet("hasTension"); + if (this.PropertyExists("frameID")) + this.FrameID = this.PropertyGet("frameID"); + if (this.PropertyExists("collision")) + this.Collision = this.PropertyGet("collision"); + if (this.PropertyExists("tileOrigin")) { + var tileOrigin = this.PropertyGet("tileOrigin"); + this.TileOriginX = tileOrigin[0]; + this.TileOriginY = tileOrigin[1]; + } + if (this.PropertyExists("childCount")) + this.ChildCount = this.PropertyGet("childCount"); + if (this.PropertyExists("angle")) + this.Angle = this.PropertyGet("angle"); + + this.SFX_Push = Resources.LoadSound("SoundFX/Global/Push.wav", SCOPE_SCENE); + + // /* + var animation = 0; + var sceneName = Scene.GetName(); + if (String.Contains(sceneName, "SPZ1")) + this.Sprite = Resources.LoadSprite("Sprites/SPZ1/Platform.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "SPZ2")) + this.Sprite = Resources.LoadSprite("Sprites/SPZ2/Platform.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "GHZ")) { + this.Sprite = Resources.LoadSprite("Sprites/GHZ/Platform.bin", SCOPE_SCENE); + + if (animation == 0 && this.FrameID >= 4) { + animation++; this.FrameID -= 4; + } + } + else if (String.Contains(sceneName, "MMZ")) { + this.Sprite = Resources.LoadSprite("Sprites/MMZ/Platform.bin", SCOPE_SCENE); + + if (animation == 0 && this.FrameID >= 6) { + animation++; this.FrameID -= 6; + } + if (animation == 1 && this.FrameID >= 3) { + animation++; this.FrameID -= 3; + } + if (animation == 2 && this.FrameID >= 7) { + animation++; this.FrameID -= 7; + } + if (animation == 3 && this.FrameID >= 4) { + animation++; this.FrameID -= 4; + } + } + else if (String.Contains(sceneName, "CPZ")) { + this.Sprite = Resources.LoadSprite("Sprites/CPZ/Platform.bin", SCOPE_SCENE); + if (animation == 0 && this.FrameID >= 7) { + animation++; this.FrameID -= 7; + } + if (animation == 1 && this.FrameID >= 7) { + animation++; this.FrameID -= 7; + } + } + else if (String.Contains(sceneName, "FBZ")) { + this.Sprite = Resources.LoadSprite("Sprites/FBZ/Platform.bin", SCOPE_SCENE); + this.SFX_Clack2 = Resources.LoadSound("SoundFX/Stage/Clack2.wav", SCOPE_SCENE); + + if (animation == 0 && this.FrameID >= 6) { + animation++; this.FrameID -= 6; + } + if (animation == 1 && this.FrameID >= 9) { + animation++; this.FrameID -= 9; + } + if (animation == 2 && this.FrameID >= 5) { + animation++; this.FrameID -= 5; + } + if (animation == 3 && this.FrameID >= 3) { + animation++; this.FrameID -= 3; + } + if (animation == 4 && this.FrameID >= 4) { + animation++; this.FrameID -= 4; + } + if (animation == 5 && this.FrameID >= 6) { + animation++; this.FrameID -= 6; + } + } + else if (String.Contains(sceneName, "PSZ1")) { + this.Sprite = Resources.LoadSprite("Sprites/PSZ1/Platform.bin", SCOPE_SCENE); + + if (animation == 0 && this.FrameID >= 3) { + animation++; this.FrameID -= 3; + } + if (animation == 1 && this.FrameID >= 3) { + animation++; this.FrameID -= 3; + } + } + else if (String.Contains(sceneName, "PSZ2")) { + this.Sprite = Resources.LoadSprite("Sprites/PSZ2/Platform.bin", SCOPE_SCENE); + + if (animation == 0 && this.FrameID >= 3) { + animation++; this.FrameID -= 3; + } + if (animation == 1 && this.FrameID >= 3) { + animation++; this.FrameID -= 3; + } + } + else if (String.Contains(sceneName, "SSZ1")) { + this.Sprite = Resources.LoadSprite("Sprites/SSZ1/Platform.bin", SCOPE_SCENE); + if (animation == 0 && this.FrameID >= 1) { + animation++; this.FrameID -= 1; + } + } + else if (String.Contains(sceneName, "SSZ2")) { + this.Sprite = Resources.LoadSprite("Sprites/SSZ2/Platform.bin", SCOPE_SCENE); + if (animation == 0 && this.FrameID >= 1) { + animation++; this.FrameID -= 1; + } + } + else if (String.Contains(sceneName, "OOZ1") || String.Contains(sceneName, "OOZ2")) { + this.Sprite = Resources.LoadSprite("Sprites/OOZ/Platform.bin", SCOPE_SCENE); + } + else if (String.Contains(sceneName, "MSZ")) { + this.Sprite = Resources.LoadSprite("Sprites/MSZ/Platform.bin", SCOPE_SCENE); + + if (animation == 0 && this.FrameID >= 9) { + animation++; this.FrameID -= 9; + } + } + else if (String.Contains(sceneName, "HCZ")) { + this.Sprite = Resources.LoadSprite("Sprites/HCZ/Platform.bin", SCOPE_SCENE); + + if (animation == 0 && this.FrameID >= 7) { + animation++; this.FrameID -= 7; + } + if (animation == 1 && this.FrameID >= 6) { + animation++; this.FrameID -= 6; + } + } + else if (String.Contains(sceneName, "LRZ1")) + this.Sprite = Resources.LoadSprite("Sprites/LRZ1/Platform.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "LRZ2")) + this.Sprite = Resources.LoadSprite("Sprites/LRZ2/Platform.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "LRZ3")) + this.Sprite = Resources.LoadSprite("Sprites/LRZ2/Platform.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "TMZ1")) + this.Sprite = Resources.LoadSprite("Sprites/TMZ1/Platform.bin", SCOPE_SCENE); + else if (String.Contains(sceneName, "TMZ2")) + this.Sprite = Resources.LoadSprite("Sprites/TMZ1/Platform.bin", SCOPE_SCENE); + else + this.Sprite = Resources.LoadSprite("Sprites/AIZ/Platform.bin", SCOPE_SCENE); + + // print "(" + this.X + ", " + this.Y + ")"; + + this.CosVal = Math.Cos(this.Angle); + this.SinVal = Math.Sin(this.Angle); + + // Choose status + switch (this.Type) { + // Stationary + case 0: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + this.Status = this.Platform_Status_Stationary; + break; + // Timed Fall + case 1: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = (Math.Abs(this.AmplitudeY) + 128.0) * 2.0; + this.Status = this.Platform_Status_TimedFalling; + break; + // Oscillating Movement + case 2: + this.OnScreenHitboxW = Math.Abs(this.AmplitudeX) * 2.0 + 128.0; + this.OnScreenHitboxH = Math.Abs(this.AmplitudeY) * 2.0 + 128.0; + this.Status = this.Platform_Status_Moving; + this.Rotation = this.Angle; + this.Angle = 0; + break; + // Circular Movement + case 3: + this.OnScreenHitboxW = Math.Abs(this.AmplitudeX) * 2.0 + 128.0; + this.OnScreenHitboxH = Math.Abs(this.AmplitudeY) * 2.0 + 128.0; + this.Status = this.Platform_Status_MovingCircular; + break; + // Swinging Movement + case 4: + this.OnScreenHitboxW = this.OnScreenHitboxH = (Math.Abs(this.AmplitudeY) * 16.0 + 128.0) * 2.0; + animation = 1; this.FrameID = 0; + this.AmplitudeY *= 16.0; + this.SwingAngle = 4 * this.Angle; + this.Angle = this.SwingAngle + 0x100 + Number.AsInteger(this.AmplitudeX * Static.HexSinHighPrec(this.Speed * this.PossibleTimerUntilDrop) * 4.0); + this.FinalX = this.AmplitudeY * Static.HexCosHighPrec(this.Angle) + this.StartX; + this.FinalY = this.AmplitudeY * Static.HexSinHighPrec(this.Angle) + this.StartY; + this.Status = this.Platform_Status_Swinging; + break; + // PlatformController Controlled + case 5: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + this.Status = this.Platform_Status_PlatformControlledMovement; + break; + // Pushable + case 6: + this.Speed /= 32.0; + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + this.Status = this.Platform_Status_Pushable; + break; + // Back/Forth Hitting Walls + case 7: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + break; + // Rise on stand atop + case 8: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + break; + // FBZ Platform that lowers + case 9: + this.OnScreenHitboxW = this.OnScreenHitboxH = 128.0 + Math.Abs(this.AmplitudeX); + this.Status = this.Platform_Status_LowerAfterStand; + break; + // Platform move from hiding in wall + case 10: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + break; + case 11: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + this.Status = this.Platform_StatusNodeBasedMovement; + break; + // Clackers + case 14: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + break; + // Lower while player is atop (LRZ1 hidden springs) + case 16: + this.OnScreenHitboxW = 128.0; + this.OnScreenHitboxH = 128.0; + break; + default: + print "Unimplemented platform type: " + this.Type + " (" + Number.AsInteger(this.X) + ", " + Number.AsInteger(this.Y) + ")"; + break; + } + + // Choose collision status + var collisionHitbox = 0; + switch (this.Collision) { + case 0: + collisionHitbox = 0; + this.CollisionStatus = this.Platform_CollisionStatus_TopSolid; + break; + case 1: + collisionHitbox = 1; + this.CollisionStatus = this.Platform_CollisionStatus_Solid; + break; + case 3: + this.CollisionStatus = this.Platform_CollisionStatus_HarmfulSpike; + break; + case 4: + this.CollisionStatus = null; + break; + case 5: + // this.CollisionStatus = this.Platform_CollisionStatus_SidesHurt; + break; + case 6: + this.CollisionStatus = this.Platform_CollisionStatus_BottomHurt; + break; + case 7: + // this.CollisionStatus = this.Platform_CollisionStatus_TopHurt; + break; + // Rotating player + case 8: + collisionHitbox = 1; + this.CollisionStatus = this.Platform_CollisionStatus_Solid; + break; + case 15: + // this.CollisionStatus = this.Platform_CollisionStatus_FBZCircleThing; + break; + default: + print "Unimplemented platform collision type: " + this.Collision + " (" + Number.AsInteger(this.X) + ", " + Number.AsInteger(this.Y) + ")"; + this.CollisionStatus = this.Platform_CollisionStatus_Solid; + break; + } + + // Set hitbox + if (this.FrameID >= 0) { + this.GetHitboxFromSprite(this.Sprite, animation, this.FrameID, collisionHitbox); + this.SetAnimation(animation, this.FrameID); + } + else { + this.Visible = false; + } + this.HitboxHalfW = this.HitboxW / 2.0; + this.HitboxHalfH = this.HitboxH / 2.0; + this.FlipFlag = 0; + + this.SoundLooping = false; + this.OnScreenHitboxHalfW = this.OnScreenHitboxW * 0.5; + this.OnScreenHitboxHalfH = this.OnScreenHitboxH * 0.5; + } + event Update() { + // if (!this.InView(0, + // this.StartX - this.OnScreenHitboxHalfW, + // this.StartY - this.OnScreenHitboxHalfH, + // this.OnScreenHitboxW, this.OnScreenHitboxH)) + // return; + this.X = Math.Floor(this.FinalX); + this.Y = Math.Floor(this.FinalY); + if (this.HasTension) { + var tension = this.TensionValue; + if (this.PlayerAtop) { + if (tension < 0x40) + this.TensionValue = tension + 4; + } + else { + if (tension > 0x00) + this.TensionValue = tension - 4; + } + } + + this.DeltaX = -this.X; + this.DeltaY = -this.Y; + + if (this.Status) + this.Status(); + + if (true) { + this.PlayerAtop = false; + this.DeltaX += Math.Floor(this.FinalX); + this.DeltaY += Math.Floor(this.FinalY); + + // TODO: complete this + // if (this.Status != sub_XXX && this.Status != sub_XXX) { + if (this.CollisionStatus) + this.CollisionStatus(); + // } + + // this.X = this.StartX; + // this.Y = this.StartY; + } + } + + // Type 0 + event Platform_Status_Stationary() { + this.FinalX = this.StartX; + this.FinalY = this.StartY; + this.FinalY += Static.HexSin(this.TensionValue) * 4; + this.XSpeed = 0.0; + this.YSpeed = 0.0; + } + // Type 1 + event Platform_Status_TimedFalling() { + var time = this.PossibleTimerUntilDrop; + if (time) { + this.PossibleTimerUntilDrop = time - 1; + if (time == 1) { + this.OnScreenHitboxH = 0.0; + // this.Priority = 2; // ??? + this.Status = this.Platform_Status_TimedFalling_OnFall; + this.PossibleTimerUntilDrop = 30; + } + } + this.FinalX = this.StartX; + this.FinalY = this.StartY; + this.FinalY += Static.HexSin(this.TensionValue) * 4; + this.XSpeed = 0.0; + } + // Type 2 + event Platform_Status_Moving() { + var angle = Number.AsInteger(this.Speed * (this.Rotation + Scene_Frame)); + + var negOffsetX = -this.FinalX; + var negOffsetY = -this.FinalY; + this.FinalX = this.AmplitudeX * Static.HexSinHighPrec(angle) + this.StartX; + this.FinalY = this.AmplitudeY * Static.HexSinHighPrec(angle) + this.StartY; + this.FinalY += Static.HexSin(this.TensionValue) * 4; + this.XSpeed = this.FinalX + negOffsetX; + this.YSpeed = this.FinalY + negOffsetY; + } + // Type 3 + event Platform_Status_MovingCircular() { + var angle = Number.AsInteger(this.Speed * Scene_Frame + this.Angle * 4); + + var negOffsetX = -this.FinalX; + var negOffsetY = -this.FinalY; + this.FinalX = this.AmplitudeX * Static.HexCosHighPrec(angle) + this.StartX; + this.FinalY = this.AmplitudeY * Static.HexSinHighPrec(angle) + this.StartY; + this.FinalY += Static.HexSin(this.TensionValue) * 4; + this.XSpeed = this.FinalX + negOffsetX; + this.YSpeed = this.FinalY + negOffsetY; + } + // Type 4 + event Platform_Status_Swinging() { + var negOffsetX = -this.FinalX; + var negOffsetY = -this.FinalY; + + this.Angle = this.SwingAngle + 0x100 + Number.AsInteger(this.AmplitudeX * Static.HexSinHighPrec(this.Speed * Scene_Frame) * 4.0); + this.FinalX = this.AmplitudeY * Static.HexCosHighPrec(this.Angle) + this.StartX; + this.FinalY = this.AmplitudeY * Static.HexSinHighPrec(this.Angle) + this.StartY; + + this.XSpeed = this.FinalX + negOffsetX; + this.YSpeed = this.FinalY + negOffsetY; + } + // Type 5 + event Platform_Status_PlatformControlledMovement() { + this.XSpeed = this.YSpeed = 0.0; + } + // Type 6 + event Platform_Status_Pushable() { + this.XSpeed = this.YSpeed = 0.0; + + var player, platform, playerIndex, playerFlag; + + platform = this; + + playerIndex = -1; + with ("Player") { + playerIndex++; + if (!this.Active) + continue; + + playerFlag = 1 << playerIndex; + if (playerFlag & platform.PlayerOnLeftFlag) + platform.XSpeed += platform.Speed; + if (playerFlag & platform.PlayerOnRightFlag) + platform.XSpeed -= platform.Speed; + } + + if (this.XSpeed != 0.0) { + if (!this.SoundLooping) { + Sound.Loop(this.SFX_Push); + this.SoundLooping = true; + } + + var timeToDrop = this.PossibleTimerUntilDrop; + if (timeToDrop > 0) { + this.XSpeed = 0.0; + this.PossibleTimerUntilDrop = timeToDrop - 1; + } + } + else { + if (this.SoundLooping) { + Sound.Stop(this.SFX_Push); + this.SoundLooping = false; + } + if (this.PossibleTimerUntilDrop < 4) + this.PossibleTimerUntilDrop++; + } + + this.FinalX += this.XSpeed; + this.X = this.FinalX; + this.Y = this.FinalY; + + playerIndex = -1; + with ("Player") { + playerIndex++; + if (!this.Active) + continue; + + playerFlag = 1 << playerIndex; + if (playerFlag & platform.PlayerOnLeftFlag) + this.X = platform.FinalX + (-platform.HitboxHalfW - this.HitboxW / 2.0); + if (playerFlag & platform.PlayerOnRightFlag) + this.X = platform.FinalX + (platform.HitboxHalfW - (-this.HitboxW / 2.0) - 1.0); + } + + // TODO: the rest here + + // + this.FinalX = this.X; + this.FinalY = this.Y; + } + // Type 9 + event Platform_Status_LowerAfterStand() { + this.Rotation += 4; + var oscillate = Static.HexSinHighPrec(this.Rotation) * 8.0; + + this.FinalY = this.StartY + oscillate; + + if (this.PlayerAtop) { + if (this.HasTension) + this.PossibleTimerUntilDrop = 120; + + this.TileOriginX = this.FinalX - this.StartX; + this.StartX = this.FinalX; + + this.TileOriginY = oscillate; + this.StartY = this.FinalY; + + this.Status = this.Platform_Status_LowerAfterStand_OnStand; + } + + this.XSpeed = this.YSpeed = 0.0; + } + // Type 11 + event Platform_StatusNodeBasedMovement() { + + } + + // Post-statuses + event Platform_Status_TimedFalling_OnFall() { + this.PossibleTimerUntilDrop--; + if (this.PossibleTimerUntilDrop <= 0) { + this.PossibleTimerUntilDrop = 0; + + // this.Status = null; + + var player, platform, playerIndex, playerFlag; + + platform = this; + + playerIndex = -1; + with ("Player") { + playerIndex++; + if (!this.Active) + continue; + + playerFlag = 1 << playerIndex; + if (playerFlag & platform.PlayerOnTopFlag) + this.YSpeed = platform.YSpeed - 1.0; + } + } + + this.FinalY += this.YSpeed; + this.YSpeed += 0.21875; + this.XSpeed = 0; + } + event Platform_Status_LowerAfterStand_OnStand() { + this.FinalY += 1.0; + this.YSpeed = 1.0; + + this.Y = this.FinalY; + } + + // Collision 0 + event Platform_CollisionStatus_TopSolid() { + var onTopFlag = this.PlayerOnTopFlag; + + this.PlayerOnTopFlag = 0; + + var player, platform = this, playerIndex = -1; + with ("Player") { + playerIndex++; + player = this; + + var originalYSpeed = player.YSpeed; + if (platform.DeltaY < 0.0) + player.YSpeed = originalYSpeed - platform.DeltaY; + + if (Static.Entity_TopSolidCollideWithPlayer(platform, player)) { + platform.PlayerAtop = true; + // TODO: complete this + if (!((1 << playerIndex) & onTopFlag) && !player.CannotLoseRings && platform.Status == platform.Platform_Status_TimedFalling && platform.PossibleTimerUntilDrop == 0) { + if (player.Status == player.Player_StatusMighty_HammerDrop) + platform.PossibleTimerUntilDrop = 1; + else + platform.PossibleTimerUntilDrop = 30; + } + + platform.PlayerOnTopFlag |= 1 << playerIndex; + + player.X += platform.DeltaX; + player.Y += platform.DeltaY; + player.Y = Math.Floor(player.Y); + player.Ground = true; + } + else { + player.YSpeed = originalYSpeed; + } + } + } + // Collision 1 + event Platform_CollisionStatus_Solid() { + var onTopFlag = this.PlayerOnTopFlag; + + this.PlayerOnTopFlag = 0; + this.PlayerOnLeftFlag = 0; + this.PlayerOnRightFlag = 0; + + var player, platform = this, playerIndex = -1; + with ("Player") { + playerIndex++; + if (!this.Active) + continue; + + player = this; + + var platformHitboxH = platform.HitboxH; + var platformY = platform.Y; + + platform.HitboxH = 8.0; + platform.Y -= platformHitboxH / 2.0 - 4.0; + + Static.Entity_TopSolidCollideWithPlayer(platform, player); + + platform.HitboxH = platformHitboxH; + platform.Y = platformY; + + var val = Static.Entity_SolidCollideWithPlayer(platform, player); + switch (val) { + // Top + case 1: + platform.PlayerAtop = true; + // TODO: complete this + if (!((1 << playerIndex) & onTopFlag) && platform.PossibleTimerUntilDrop == 0) { + if (player.Status == player.Player_StatusMighty_HammerDrop) + platform.PossibleTimerUntilDrop = 1; + else + platform.PossibleTimerUntilDrop = 30; + } + + platform.PlayerOnTopFlag |= 1 << playerIndex; + + player.X += platform.DeltaX; + player.Y += platform.DeltaY; + player.Y = Math.Floor(player.Y); + if (platform.YSpeed <= 0.0) + player.VerticalCollisionFlag |= 1; + break; + // Left + case 2: + if (player.Ground && player.InputRight) { + platform.PlayerOnLeftFlag |= 1 << playerIndex; + } + + if (platform.XSpeed <= 0.0) { + if (player.InputLeft) { + player.GroundSpeed = platform.XSpeed; + player.XSpeed = player.GroundSpeed - player.Acceleration; + } + player.HorizontalCollisionFlag |= 1; + } + break; + // Right + case 3: + if (player.Ground && player.InputLeft) { + platform.PlayerOnRightFlag |= 1 << playerIndex; + } + + if (platform.XSpeed >= 0.0) { + if (player.InputRight) { + player.GroundSpeed = platform.XSpeed; + player.XSpeed = player.GroundSpeed + player.Acceleration; + } + player.HorizontalCollisionFlag |= 2; + } + break; + // Bottom + case 4: + if (platform.YSpeed >= 0.0) + player.VerticalCollisionFlag |= 2; + break; + } + } + } + // Collision 3 + event Platform_CollisionStatus_HarmfulSpike() { + var player, platform = this; + with ("Player") { + player = this; + if (player.IsGhost) + continue; + + player.UpdateHitbox(0); + + if (Static.Entity_CollideWithObject(platform, player)) { + if (!player.Player_DoMightyUnspin(4.0, false, platform, player.Unk_0x234)) + player.GetHurt(platform.X); // AttemptHurt + } + } + } + // Collision 6 + event Platform_CollisionStatus_BottomHurt() { + var onTopFlag = this.PlayerOnTopFlag; + + this.PlayerOnTopFlag = 0; + this.PlayerOnLeftFlag = 0; + this.PlayerOnRightFlag = 0; + + var player, platform = this, playerIndex = -1; + with ("Player") { + playerIndex++; + if (!this.Active) + continue; + + player = this; + + var platformHitboxH = platform.HitboxH; + var platformY = platform.Y; + + platform.HitboxH = 8.0; + platform.Y -= platformHitboxH / 2.0 - 4.0; + + Static.Entity_TopSolidCollideWithPlayer(platform, player); + + platform.HitboxH = platformHitboxH; + platform.Y = platformY; + + var val = Static.Entity_SolidCollideWithPlayer(platform, player); + switch (val) { + // Top + case 1: + platform.PlayerAtop = true; + // TODO: complete this + if (!((1 << playerIndex) & onTopFlag) && platform.PossibleTimerUntilDrop == 0) { + if (player.Status == player.Player_StatusMighty_HammerDrop) + platform.PossibleTimerUntilDrop = 1; + else + platform.PossibleTimerUntilDrop = 30; + } + + platform.PlayerOnTopFlag |= 1 << playerIndex; + + player.X += platform.DeltaX; + player.Y += platform.DeltaY; + player.Y = Math.Floor(player.Y); + if (platform.YSpeed <= 0.0) + player.VerticalCollisionFlag |= 1; + break; + // Left + case 2: + if (player.Ground && player.InputRight) { + platform.PlayerOnLeftFlag |= 1 << playerIndex; + } + + if (platform.XSpeed <= 0.0) { + if (player.InputLeft) { + player.GroundSpeed = platform.XSpeed; + player.XSpeed = player.GroundSpeed - player.Acceleration; + } + player.HorizontalCollisionFlag |= 1; + } + break; + // Right + case 3: + if (player.Ground && player.InputLeft) { + platform.PlayerOnRightFlag |= 1 << playerIndex; + } + + if (platform.XSpeed >= 0.0) { + if (player.InputRight) { + player.GroundSpeed = platform.XSpeed; + player.XSpeed = player.GroundSpeed + player.Acceleration; + } + player.HorizontalCollisionFlag |= 2; + } + break; + // Bottom + case 4: + if (platform.YSpeed >= 0.0) + player.VerticalCollisionFlag |= 2; + if (!player.Player_DoMightyUnspin(4.0, false, platform, player.Unk_0x234)) + player.GetHurt(platform.X); + break; + } + } + } + + event Render() { + if (!this.Visible) + return; + if (!this.OnScreen) + return; + + if (this.Status == this.Platform_Status_Swinging) { + var angle = this.Angle; + var cos = Static.HexCosHighPrec(angle) * 16.0; + var sin = Static.HexSinHighPrec(angle) * 16.0; + var x = Math.Floor(this.StartX); + var y = Math.Floor(this.StartY); + + Draw.Sprite(this.Sprite, this.CurrentAnimation, 2, x, y, false, false); + x += cos; + y += sin; + + for (var i = 16.0; i < this.AmplitudeY; i += 16.0) { + Draw.Sprite(this.Sprite, this.CurrentAnimation, 1, x, y, false, false); + x += cos; + y += sin; + } + } + + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.FinalX), Math.Floor(this.FinalY), false, false); + } +} diff --git a/Scripts/Stage/Ring.hsl b/Scripts/Stage/Ring.hsl new file mode 100644 index 0000000..bec2616 --- /dev/null +++ b/Scripts/Stage/Ring.hsl @@ -0,0 +1,251 @@ +class Ring { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + this.Priority = DrawGroup_FGHigh_High; + + this.Sprite = Resources.LoadSprite("Sprites/Global/Ring.bin", SCOPE_GAME); + this.SetAnimation(0, 0); + + this.PlaneFilter = 0; + if (this.PropertyExists("planeFilter")) + this.PlaneFilter = this.PropertyGet("planeFilter"); + + this.HitboxW = 16.0; + this.HitboxH = 16.0; + this.HitboxHalfW = this.HitboxW * 0.5; + this.HitboxHalfH = this.HitboxH * 0.5; + + this.Magnetized = false; + this.MagnetizedTo = null; + this.Collected = false; + this.RegatherTimer = 0; + this.DeathTimer = -1; + + this.AutoPhysics = false; + this.Bounceable = false; + this.HSpeed = 0.0; + this.VSpeed = 0.0; + this.GravityRate = 0.09375; + this.RingCount = 1; + this.PlaneIndex = 0; + this.ScaleX = 1.0; + this.ScaleY = 1.0; + + var planeFilter = this.PlaneFilter; + if (planeFilter > 0 && (planeFilter - 1) & 2) + this.Priority = DrawGroup_FGHigh_High; + else + this.Priority = DrawGroup_FGLow_Low; + + this.Status = this.Ring_StatusStatic; + + this.OnScreenHitboxW = this.OnScreenHitboxH = 80.0; + } + + event Ring_StatusStatic() { + var disCatch = 64.0 * 64.0; + var player, ring = this; + with ("Player") { + player = this; + if (player.Shield == ShieldType_ELECTRIC) { + var disX = player.X - ring.X; + disX *= disX; + var disY = player.Y - ring.Y; + disY *= disY; + if (disX + disY < disCatch) { + ring.Status = ring.Ring_StatusMagnetized; + ring.MagnetizedTo = player; + } + } + } + this.Ring_CheckCollect(); + } + event Ring_StatusMagnetized() { + var sx = Math.Sign(this.MagnetizedTo.X - this.X); + var sy = Math.Sign(this.MagnetizedTo.Y - this.Y); + + this.OnScreenHitboxW = this.OnScreenHitboxH = 0.0; + + if (Math.Sign(this.HSpeed) == sx) + this.HSpeed += 0.1875 * sx; + else + this.HSpeed += 0.75 * sx; + + if (Math.Sign(this.VSpeed) == sy) + this.VSpeed += 0.1875 * sy; + else + this.VSpeed += 0.75 * sy; + + if (this.MagnetizedTo.Shield != 3) { + this.Magnetized = false; + this.Status = this.Ring_StatusBounceable; + } + + this.X += this.HSpeed; + this.Y += this.VSpeed; + + this.Ring_CheckCollect(); + } + event Ring_StatusBounceable() { + this.OnScreenHitboxW = this.OnScreenHitboxH = 0.0; + + if (this.RegatherTimer > 0) { + this.RegatherTimer--; + } + + if (this.DeathTimer > 0) { + this.DeathTimer--; + if (this.DeathTimer == 0) { + this.Active = false; + return; + } + } + + this.X += this.HSpeed; + this.Y += this.VSpeed; + this.VSpeed += this.GravityRate; + + // Moving left + if (this.HSpeed < 0.0 && TileCollision.PointExtended(this.X - this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + while (TileCollision.PointExtended(this.X - this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + this.X += 1.0; + } + this.HSpeed = Math.Abs(this.HSpeed) * 0.25; + } + // Moving right + if (this.HSpeed > 0.0 && TileCollision.PointExtended(this.X + this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + while (TileCollision.PointExtended(this.X + this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + this.X -= 1.0; + } + this.HSpeed = Math.Abs(this.HSpeed) * -0.25; + } + + // Moving down + if (TileCollision.PointExtended(this.X, this.Y + this.HitboxHalfH, this.PlaneIndex, 15) >= 0) { + this.VSpeed *= -0.75; + } + // Moving upwards + if (this.VSpeed < 0.0 && TileCollision.PointExtended(this.X, this.Y - this.HitboxHalfH, this.PlaneIndex, 15) >= 0) { + this.VSpeed = 0.0; + } + + if (this.RegatherTimer == 0) + this.Ring_CheckCollect(); + } + event Ring_StatusBounceableCombine() { + this.OnScreenHitboxW = this.OnScreenHitboxH = 0.0; + + if (this.RegatherTimer > 0) { + this.RegatherTimer--; + } + + if (this.DeathTimer > 0) { + this.DeathTimer--; + if (this.DeathTimer == 0) { + this.Active = false; + return; + } + } + + this.X += this.HSpeed; + this.VSpeed += 0.0703125; + this.Y += this.VSpeed; + + var as = this.AngleSpeed; + this.Angle += as >> 6; + + if (this.DeathTimer > 16) { + var sin = Static.HexSin(this.Angle); + this.ScaleX = -sin * 0.25 + 0.75; + this.ScaleY = sin * 0.25 + 0.75; + } + else { + if (this.ScaleX > this.ScaleY) { + this.ScaleX += 0.015625; + this.ScaleY -= this.ScaleY / 8.0; + } + else { + this.ScaleX -= this.ScaleX / 8.0; + this.ScaleY += 0.015625; + } + } + + // Moving left + if (this.HSpeed < 0.0 && TileCollision.PointExtended(this.X - this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + while (TileCollision.PointExtended(this.X - this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + this.X += 1.0; + } + this.HSpeed = Math.Abs(this.HSpeed) * 0.25; + } + // Moving right + if (this.HSpeed > 0.0 && TileCollision.PointExtended(this.X + this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + while (TileCollision.PointExtended(this.X + this.HitboxHalfW, this.Y, this.PlaneIndex, 15) >= 0) { + this.X -= 1.0; + } + this.HSpeed = Math.Abs(this.HSpeed) * -0.25; + } + + // Moving down + if (TileCollision.PointExtended(this.X, this.Y + this.HitboxHalfH, this.PlaneIndex, 15) >= 0) { + this.VSpeed *= -0.75; + } + // Moving upwards + if (this.VSpeed < 0.0 && TileCollision.PointExtended(this.X, this.Y - this.HitboxHalfH, this.PlaneIndex, 15) >= 0) { + this.VSpeed = 0.0; + } + + if (this.RegatherTimer == 0) + this.Ring_CheckCollect(); + + // Spawn sparkles + if (!(this.Angle & 0xF)) { + + } + + var deathTimer = this.DeathTimer; + if (!(deathTimer & 7)) { + if (as > 0x80) + this.AngleSpeed = as - 8; + } + } + event Ring_CheckCollect() { + with ("Player") { + if (Static.Entity_CollideWithObject(other, this)) { + this.GainRings(other.RingCount); + Sound.Play(this.SFX_RingLeft); + other.Active = false; + } + } + } + + event Update() { + if (this.Status) + this.Status(); + } + event OnAnimationFinish() { + if (this.CurrentAnimation == 2) + this.Active = false; + } + event Render() { + if (!this.OnScreen) + return; + + if (this.DeathTimer >= 0 && this.DeathTimer < 64 && ((this.DeathTimer >> 1) & 1) == 0) + return; + + if (this.Status == this.Ring_StatusBounceableCombine) { + Draw.Save(); + Draw.Translate(Math.Floor(this.X), Math.Floor(this.Y)); + Draw.Scale(this.ScaleX, this.ScaleY, 1.0); + Draw.Sprite(this.Sprite, this.CurrentAnimation, (Scene_Frame >> 2) & 15, 0.0, 0.0, false, false); + Draw.Restore(); + } + else { + Draw.Sprite(this.Sprite, this.CurrentAnimation, (Scene_Frame >> 2) & 15, Math.Floor(this.X), Math.Floor(this.Y), false, false); + } + } +} diff --git a/Scripts/Stage/Spikes.hsl b/Scripts/Stage/Spikes.hsl new file mode 100644 index 0000000..03cc38f --- /dev/null +++ b/Scripts/Stage/Spikes.hsl @@ -0,0 +1,294 @@ +class Spikes { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Load + // TODO: PSZ2 and FBZ specific + this.Sprite = Resources.LoadSprite("Sprites/Global/Spikes.bin", SCOPE_GAME); + this.SFX_Spike = Resources.LoadSound("SoundFX/Global/Spike.wav", SCOPE_GAME); + this.SFX_SpikesMove = Resources.LoadSound("SoundFX/Global/SpikesMove.wav", SCOPE_GAME); + this.AutoPhysics = false; + this.Status = null; + + // Setup + this.Type = 0; + this.Moving = false; + this.Count = 0; + this.Stagger = 0; + this.Timer = 0; + this.PlaneFilter = 0; + this.Retracted = false; + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("moving")) + this.Moving = this.PropertyGet("moving"); + if (this.PropertyExists("count")) + this.Count = this.PropertyGet("count"); + if (this.PropertyExists("stagger")) + this.Stagger = this.PropertyGet("stagger"); + if (this.PropertyExists("timer")) + this.Timer = this.PropertyGet("timer"); + if (this.PropertyExists("planeFilter")) + this.PlaneFilter = this.PropertyGet("planeFilter"); + + this.Unk_0x70 = 0.0; + this.Unk_0x74 = 0.0; + this.Unk_0x78 = 0.0; + + // Create + var count = this.Count; + if (count < 2) + this.Count = count = 2; + + var type = this.Type; + var vertFlip = type & 1; + var horiFlip = (type >> 1) & 1; + + var planeFilter = this.PlaneFilter; + if (planeFilter > 0 && (planeFilter - 1) & 2) + this.Priority = DrawGroup_FGHigh_High; + else + this.Priority = DrawGroup_FGLow_Low; + + if (horiFlip) { + this.OnScreenHitboxW = 96.0; + this.OnScreenHitboxH = (count + 6) * 16.0; + this.FlipFlag = vertFlip; + if (vertFlip) { + this.XSpeed = -8.0; + this.Type = 2; + } + else { + this.XSpeed = 8.0; + this.Type = 3; + } + this.HitboxW = 32.0; + this.HitboxH = 16.0 * count; + } + else { + this.OnScreenHitboxW = (count + 6) * 16.0; + this.OnScreenHitboxH = 96.0; + this.FlipFlag = vertFlip << 1; + if (vertFlip) { + this.YSpeed = 8.0; + this.Type = 4; + } + else { + this.YSpeed = -8.0; + this.Type = 1; + } + this.HitboxW = 16.0 * count; + this.HitboxH = 32.0; + } + + if (this.Moving) { + this.X -= 4.0 * this.XSpeed; + this.Y -= 4.0 * this.YSpeed; + this.Retracted = 1; + } + + // Initial Status + this.OnScreenHitboxHalfW = this.OnScreenHitboxW; + this.OnScreenHitboxHalfH = this.OnScreenHitboxH; + + this.SpriteOnScreen = false; + } + + event LABEL_3(retracted) { + if ((Scene_Frame & 0x3F) == this.Timer) { + this.Retracted = retracted + 1; + if (this.SpriteOnScreen) { + Sound.Play(this.SFX_SpikesMove); + } + } + } + + event Update() { + this.SpriteOnScreen = false; + if (!this.InView(0, this.X - this.OnScreenHitboxHalfW, this.Y - this.OnScreenHitboxHalfH, this.OnScreenHitboxW, this.OnScreenHitboxH)) + return; + this.SpriteOnScreen = true; + + var v2; + var retracted = this.Retracted; + switch (retracted) { + case 1: + if ((this.Stagger << 6) == (Scene_Frame & 0x40)) + this.LABEL_3(retracted); + break; + case 2: + v2 = this.Unk_0x70; + if (v2 >= 32.0) { + this.Retracted = retracted + 1; + } + else { + this.Unk_0x70 = v2 + 8.0; + this.X += this.XSpeed; + this.Y += this.YSpeed; + } + break; + case 3: + this.LABEL_3(retracted); + break; + case 4: + v2 = this.Unk_0x70; + if (v2 <= 0.0) { + this.Retracted = 1; + } + else { + this.Unk_0x70 = v2 - 8.0; + this.X -= this.XSpeed; + this.Y -= this.YSpeed; + } + break; + + case 5: + v2 = this.Unk_0x70; + if (v2 >= 40.0) { + this.Retracted = 6; + } + else { + this.Unk_0x70 = v2 + 8.0; + this.X -= this.XSpeed; + this.Y -= this.YSpeed; + } + break; + } + + this.X -= this.Unk_0x74; + this.Y -= this.Unk_0x78; + + if (this.Retracted != 1) { + var player, spikes; + with ("Player") { + player = this; + spikes = other; + + var planeFilter = spikes.PlaneFilter; + if (planeFilter <= 0 || player.PlaneIndex == ((planeFilter - 1) & 1)) { + var playerXSpeed = player.XSpeed; + var playerYSpeed = player.YSpeed; + var collideSide = Static.Entity_SolidCollideWithPlayer(spikes, player); + if (collideSide) { + if (collideSide == 4) { + player.VerticalCollisionFlag |= 2; + } + if (collideSide == 1) { + player.VerticalCollisionFlag |= 1; + if (spikes.Unk_0x70 == 8.0) + player.Ground = false; + } + + var iceExists = false; + var pressExists = false; + + var willBreak = false; + // if (collideSide == 1 && + // player.Status == player.Player_StatusMighty_HammerDrop && + // iceExists && + // !pressExists) {} + + switch (collideSide) { + case 1: + player.VerticalCollisionFlag |= 1; + if (player.YSpeed >= 0.0 || spikes.Retracted == 2) { + player.X += spikes.Unk_0x74; + player.Y += spikes.Unk_0x78; + if (collideSide == spikes.Type) { + spikes.AttemptHurt(player); + } + } + break; + case 2: + player.HorizontalCollisionFlag |= 1; + if (player.XSpeed >= 0.0 || spikes.Retracted == 2) { + if (collideSide == spikes.Type) { + spikes.AttemptHurt(player); + } + } + break; + case 3: + player.HorizontalCollisionFlag |= 2; + if (player.XSpeed <= 0.0 || spikes.Retracted == 2) { + if (collideSide == spikes.Type) { + spikes.AttemptHurt(player); + } + } + break; + case 4: + player.VerticalCollisionFlag |= 2; + if (player.YSpeed <= 0.0 || spikes.Retracted == 2) { + if (collideSide == spikes.Type) { + spikes.AttemptHurt(player); + } + } + break; + + } + } + } + } + } + + this.X += this.Unk_0x74; + this.Y += this.Unk_0x78; + } + event AttemptHurt(player) { + // TODO: + if (player.KillFlag || + player.Status == player.Player_StatusHurt || + player.Status == player.Player_StatusDead || + // ??? || + player.Status == player.Player_StatusFlyingIn || + player.Status == player.Player_StatusJumpingIn || + player.Status == player.Player_StatusTransforming || + player.Invincibility || + player.InvincibilityTimer > 0) + return; + player.GetHurt(this.X); + } + + event Render() { + if (!this.OnScreen) + return; + + var xx = Math.Floor(this.X); + var yy = Math.Floor(this.Y); + var fX = (this.FlipFlag & 1); + var fY = (this.FlipFlag & 2); + + var type = this.Type; + var count = this.Count; + var countHalf = count >> 1; + var startX, startY; + switch (type) { + case 1: // Top side + case 4: // Bottom side + startX = xx + 16.0 - count * 8.0; + for (var x = startX; countHalf > 0; countHalf--) { + Draw.Sprite(this.Sprite, 0, 0, x, yy, fX, fY); + startX += 32.0; + x += 32.0; + } + if (count & 1) { + Draw.Sprite(this.Sprite, 0, 0, startX - 16.0, yy, fX, fY); + } + break; + case 2: // Left side + case 3: // Right side + startY = yy + 16.0 - count * 8.0; + for (var y = startY; countHalf > 0; countHalf--) { + Draw.Sprite(this.Sprite, 1, 0, xx, y, fX, fY); + startY += 32.0; + y += 32.0; + } + if (count & 1) { + Draw.Sprite(this.Sprite, 1, 0, xx, startY - 16.0, fX, fY); + } + break; + } + } +} diff --git a/Scripts/Stage/Spring.hsl b/Scripts/Stage/Spring.hsl new file mode 100644 index 0000000..93ba40b --- /dev/null +++ b/Scripts/Stage/Spring.hsl @@ -0,0 +1,321 @@ +class Spring { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Pre + var index; + if ((index = Scene.GetLayerIndex("FG Low")) != -1) { + this.Priority = index * 4 + 1; + } + + // Load + this.Sprite = Resources.LoadSprite("Sprites/Global/Springs.bin", SCOPE_GAME); + this.SFX_Spring = Resources.LoadSound("SoundFX/Global/Spring.wav", SCOPE_GAME); + this.AutoPhysics = false; + this.Status = null; + + // Setup + this.Type = 0; + this.FlipFlag = 0; + this.OnGround = 0; + this.PlaneFilter = 0; + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("flipFlag")) + this.FlipFlag = this.PropertyGet("flipFlag"); + if (this.PropertyExists("onGround")) + this.OnGround = this.PropertyGet("onGround"); + if (this.PropertyExists("planeFilter")) + this.PlaneFilter = this.PropertyGet("planeFilter"); + + // Initial Status + this.Type = this.Type % 6; + + this.SetAnimation(this.Type, 0); + this.Unk_0x4C = 4; + this.AnimationSpeedMult = 0.0; + this.OnScreenHitboxW = + this.OnScreenHitboxH = 64.0; + this.Unk_0x55 = 1; + this.SoundCooldown = 0; + + var planeFilter = this.PlaneFilter; + if (planeFilter > 0 && (planeFilter - 1) & 2) + this.Priority = DrawGroup_FGHigh_High; + else + this.Priority = DrawGroup_FGLow_Low; + + var typeIsRed = this.Type & 1; + var typeDirection = this.Type >> 1; + var flipFlag = this.FlipFlag; + + // Determine + switch (typeDirection) { + case 0: // Vertical + if (typeIsRed) + this.YSpeed = -16.0; + else + this.YSpeed = -10.0; + if (flipFlag) + this.YSpeed = -this.YSpeed; + this.HitboxW = 32.0; + this.HitboxH = 16.0; + this.Status = this.Spring_Update_Vertical; + break; + case 1: // Horizontal + if (typeIsRed) + this.XSpeed = 16.0; + else + this.XSpeed = 10.0; + this.HitboxW = 16.0; + this.HitboxH = 32.0; + if (flipFlag) + this.XSpeed = -this.XSpeed; + this.Status = this.Spring_Update_Horizontal; + break; + case 2: // Diagonal + if (typeIsRed) { + this.XSpeed = 11.25; + this.YSpeed = 11.25; + } + else { + this.XSpeed = 7.25; + this.YSpeed = 7.25; + } + + if (flipFlag & 1) + this.XSpeed = -this.XSpeed; + // if (!(flipFlag & 2)) + if (flipFlag < 2) + this.YSpeed = -this.YSpeed; + + this.HitboxW = 24.0; + this.HitboxH = 24.0; + this.Status = this.Spring_Update_Diagonal; + break; + } + } + + event Spring_Update_Vertical() { + var v3, v4; + var flipFlag = this.FlipFlag; + var spring = this, player; + with ("Player") { + if (!this.Active) + continue; + + player = this; + + var planeFilter = spring.PlaneFilter; + if (!planeFilter || player.PlaneIndex == ((planeFilter - 1) & 1)) { + if (flipFlag == 0) { + v3 = // spring.Type != 0xFF || + player.YSpeed >= -5.0 ? + Static.Entity_SolidCollideWithPlayer(spring, player) : + Static.Entity_SolidCollideWithPlayer(spring, player) == 1; + } + else { + v3 = Static.Entity_SolidCollideWithPlayer(spring, player) == 4; + } + + if (v3 == 1) { + if (flipFlag == 0) { + v4 = player.CurrentAnimation; + if (v4 == 5 || v4 > 6 && v4 <= 9) + player.AnimationAfterSpring = v4; + else + player.AnimationAfterSpring = 5; + + var playerStatus = player.Status; + if (playerStatus != player.Player_StatusFrozen_PGZ) { + if (playerStatus == player.Player_StatusJumping_WithInputLock || + playerStatus == player.Player_StatusRoll_WithInputLock) { + player.Status = player.Player_StatusJumping_WithInputLock; + } + else { + player.AnimationSpeedMult = 1.0; + player.SetAnimation(11, 0); + player.Status = this.Player_StatusJumping; + } + } + } + else { + var playerStatus = player.Status; + if (playerStatus != player.Player_StatusFrozen_PGZ) { + if (playerStatus == player.Player_StatusJumping_WithInputLock || + playerStatus == player.Player_StatusRoll_WithInputLock) { + player.Status = player.Player_StatusJumping_WithInputLock; + } + else { + player.Status = this.Player_StatusJumping; + } + } + } + + player.Ground = false; + player.YSpeed = spring.YSpeed; + player.UseGroundSpeed = true; + + spring.AnimationSpeedMult = 1.0; + spring.ResetAnimation(spring.CurrentAnimation, 1); + if (spring.SoundCooldown == 0) { + Sound.Play(this.SFX_Spring); + spring.SoundCooldown = 8; + } + } + } + } + } + event Spring_Update_Horizontal() { + var v3, v4; + var flipFlag = this.FlipFlag; + var spring = this, player; + with ("Player") { + if (!this.Active) + continue; + + player = this; + + var planeFilter = spring.PlaneFilter; + if (!planeFilter || player.PlaneIndex == ((planeFilter - 1) & 1)) { + if (flipFlag & 1) { + v3 = Static.Entity_SolidCollideWithPlayer(spring, player) == 2; + } + else { + v3 = Static.Entity_SolidCollideWithPlayer(spring, player) == 3; + } + + if (v3 == 1) { + var xspeed = spring.XSpeed; + if (player.AngleMode == 2) { + xspeed = -xspeed; + player.XSpeed = xspeed; + player.GroundSpeed = xspeed; + } + else { + player.XSpeed = xspeed; + player.GroundSpeed = xspeed; + } + + var playerStatus = player.Status; + if (playerStatus != player.Player_StatusFrozen_PGZ) { + if (playerStatus != player.Player_StatusRoll && + playerStatus != player.Player_StatusJumping_WithInputLock && + playerStatus != player.Player_StatusRoll_WithInputLock) { + if (player.Ground) + player.Status = player.Player_StatusStanding; + else + player.Status = player.Player_StatusJumping; + } + + var animation = player.CurrentAnimation; + if (!(animation == 10 || animation >= 7 && animation <= 9)) + player.SetAnimation(5, 0); + } + + player.InputLock = 16; + player.SkidTimer = 0; + player.PushingTimer = 0; + player.UseGroundSpeed = true; + player.Flip = (flipFlag & 1); + + spring.AnimationSpeedMult = 1.0; + spring.ResetAnimation(spring.CurrentAnimation, 1); + if (spring.SoundCooldown == 0) { + Sound.Play(this.SFX_Spring); + spring.SoundCooldown = 8; + } + } + } + } + } + event Spring_Update_Diagonal() { + var spring = this, player; + with ("Player") { + if (!this.Active) + continue; + player = this; + + var planeFilter = spring.PlaneFilter; + if (planeFilter && player.PlaneIndex != ((planeFilter - 1) & 1) || player.IsGhost) + continue; + + if (!Static.Entity_CollideWithObject(spring, player)) + continue; + + if (player.Ground) { + var yspeed = player.YSpeed; + if (yspeed < 0.0) { + var xspeed = player.XSpeed; + if (xspeed < 0.0) + xspeed = -xspeed; + if (xspeed <= -yspeed) + continue; + } + } + + var playerStatus = player.Status; + if (playerStatus != player.Player_StatusFrozen_PGZ) { + if (playerStatus == player.Player_StatusJumping_WithInputLock || + playerStatus == player.Player_StatusRoll_WithInputLock) { + player.Status = player.Player_StatusJumping_WithInputLock; + } + else { + player.Status = player.Player_StatusJumping; + var animation = player.CurrentAnimation; + if (!(animation == 5 || animation >= 7 && animation <= 9)) + player.SetAnimation(5, 0); + } + } + + playerStatus = player.Status; + if (!(spring.FlipFlag & 2)) { + if (playerStatus != player.Player_StatusJumping_WithInputLock && + playerStatus != player.Player_StatusRoll_WithInputLock) { + var animation = player.CurrentAnimation; + if (animation == 5 || animation >= 7 && animation <= 9) + player.AnimationAfterSpring = animation; + else + player.AnimationAfterSpring = 5; + player.AnimationSpeedMult = 1.0; + player.ResetAnimation(12, 0); + } + } + + player.Flip = spring.FlipFlag & 1; + player.Ground = false; + player.XSpeed = spring.XSpeed; + player.YSpeed = spring.YSpeed; + player.UseGroundSpeed = true; + + spring.AnimationSpeedMult = 1.0; + spring.ResetAnimation(spring.CurrentAnimation, 1); + if (spring.SoundCooldown == 0) { + Sound.Play(this.SFX_Spring); + spring.SoundCooldown = 8; + } + } + } + + event Update() { + var cooldown = this.SoundCooldown; + if (cooldown > 0) + this.SoundCooldown = cooldown - 1; + + if (this.Status) + this.Status(); + } + event OnAnimationFinish() { + this.AnimationSpeedMult = 0.0; + } + + event Render() { + if (!this.OnScreen) + return; + + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, Math.Floor(this.X), Math.Floor(this.Y), (this.FlipFlag & 1), (this.FlipFlag & 2)); + } +} diff --git a/Scripts/Stage/Water.hsl b/Scripts/Stage/Water.hsl new file mode 100644 index 0000000..c0bd86e --- /dev/null +++ b/Scripts/Stage/Water.hsl @@ -0,0 +1,203 @@ +class Water { + event Create() { + if (this.PropertyExists("filter") && !(this.PropertyGet("filter") & Mode_MANIA)) { + this.Active = false; + return; + } + + // Pre + var index; + if ((index = Scene.GetLayerIndex("FG Low")) != -1) { + this.Priority = index * 4 + 1; + } + + // Load + this.Sprite = Resources.LoadSprite("Sprites/Global/Water.bin", SCOPE_GAME); + this.AutoPhysics = false; + this.Status = null; + this.RenderStatus = null; + this.SFX_Splash = Resources.LoadSound("SoundFX/Stage/Splash.wav", SCOPE_GAME); + this.SFX_Breathe = Resources.LoadSound("SoundFX/Stage/Breathe.wav", SCOPE_GAME); + this.SFX_Warning = Resources.LoadSound("SoundFX/Stage/Warning.wav", SCOPE_GAME); + this.SFX_Drown = Resources.LoadSound("SoundFX/Stage/Drown.wav", SCOPE_GAME); + this.SFX_DrownAlert = Resources.LoadSound("SoundFX/Stage/DrownAlert.wav", SCOPE_GAME); + this.SFX_Skim = Resources.LoadSound("SoundFX/HCZ/Skim.wav", SCOPE_GAME); + + // Setup + this.Type = 0; + this.NumDuds = 0; + this.SizeX = 0.0; + this.SizeY = 0.0; + this.HeightX = 0.0; + this.HeightY = 0.0; + this.Speed = 0; + this.ButtonTag = 0; + this.R = 0.0; + this.G = 0.0; + this.B = 0.0; + this.A = 0.5; + this.PriorityIndex = 0; + this.DestroyOnTrigger = false; + this.Water_Unk_0x64 = null; + if (this.PropertyExists("type")) + this.Type = this.PropertyGet("type"); + if (this.PropertyExists("numDuds")) + this.NumDuds = this.PropertyGet("numDuds"); + if (this.PropertyExists("size")) { + var size = this.PropertyGet("size"); + this.SizeX = size[0]; + this.SizeY = size[1]; + } + if (this.PropertyExists("height")) { + var height = this.PropertyGet("height"); + this.HeightX = height[0]; + this.HeightY = height[1]; + } + if (this.PropertyExists("speed")) + this.Speed = this.PropertyGet("speed"); + if (this.PropertyExists("buttonTag")) + this.ButtonTag = this.PropertyGet("buttonTag"); + if (this.PropertyExists("r")) + this.R = Math.Max((this.PropertyGet("r") - 150.0) / 255.0, 0.0); + if (this.PropertyExists("g")) + this.G = Math.Max((this.PropertyGet("g") - 150.0) / 255.0, 0.0); + if (this.PropertyExists("b")) + this.B = Math.Max((this.PropertyGet("b") - 150.0) / 255.0, 0.0); + if (this.PropertyExists("priority")) + this.PriorityIndex = this.PropertyGet("priority"); + if (this.PropertyExists("destroyOnTrigger")) + this.DestroyOnTrigger = this.PropertyGet("destroyOnTrigger"); + + // Create + var sceneName = Scene.GetName(); + switch (this.Type) { + // Set water level + case 0: + if (global.GameMode == 3 && String.Contains(sceneName, "CPZ")) { + this.Active = false; + } + else { + this.A = String.Contains(sceneName, "CPZ") ? 0.375 : 0.875; + this.ResetAnimation(0, 0); + this.Status = this.Water_Status_GlobalWaterBlockController; + this.RenderStatus = null; + } + print "Water Controller at: " + this.X + ", " + this.Y; + break; + // Water block + case 1: + switch (this.PriorityIndex) { + case 0: + this.Priority = DrawGroup_FGLow_Low - 1; + break; + case 1: + this.Priority = DrawGroup_FGLow_High; + break; + case 2: + this.Priority = DrawGroup_AboveTiles; + break; + case 3: + this.Priority = DrawGroup_HUD - 1; + break; + } + // this.A = String.Contains(sceneName, "CPZ") ? 0.375 : 0.875; + this.PriorityIndex = 4; + this.OnScreenHitboxW = this.SizeX; + this.OnScreenHitboxH = this.SizeY; + this.HitboxW = this.SizeX; + this.HitboxH = this.SizeY; + this.HitboxOffX = 0.0; + this.HitboxOffY = 0.0; + this.FlipFlag = 0; + this.Status = null; + this.RenderStatus = this.Water_RenderStatus_WaterBlock; + break; + case 2: + case 4: + break; + // Trigger To Set Water Level + case 3: + break; + case 5: + break; + // Water splash + case 6: + break; + case 7: + break; + // Countdown Timer + case 8: + break; + default: + break; + } + } + + event Update() { + if (this.Status) + this.Status(); + } + + event Water_Status_GlobalWaterBlockController() { + var player, water, platform = this; + with ("Player") { + player = this; + with ("Water") { + water = this; + + var doSplash = true; + var changedUnderwaterness = false; + if (water.Type == 1) { + if (Static.Entity_CollideWithObject(water, player) && player.Y >= water.Y - water.HitboxH * 0.5) { + water.Water_Unk_0x64 = player; + if (!player.Underwater) + changedUnderwaterness = true; + player.Underwater = true; + } + else if (water.Water_Unk_0x64 == player) { + water.Water_Unk_0x64 = null; + if (player.Underwater) + changedUnderwaterness = true; + player.Underwater = false; + } + } + + if (changedUnderwaterness) { + player.Player_ResetSpeeds(); + if (doSplash && Math.Abs(player.YSpeed) >= 1.0) { + var splash = Instance.Create("WaterSplash", player.X, water.Y - water.HitboxH * 0.5); + splash.Priority = water.Priority; + Sound.Play(water.SFX_Splash); + } + + if (!player.Underwater) { + if (player.YSpeed >= -4.0) { + player.YSpeed *= 2.0; + if (player.YSpeed < -16.0) + player.YSpeed = -16.0; + } + } + else { + if (player.Invincibility <= 0) { + if (player.Shield == ShieldType_FIRE || player.Shield == ShieldType_ELECTRIC) { + player.Shield = ShieldType_NONE; + } + } + } + } + } + } + } + + event Render() { + if (this.RenderStatus) + this.RenderStatus(); + } + + event Water_RenderStatus_WaterBlock() { + Draw.SetBlendMode(BlendMode_ADD); + Draw.SetBlendColor(this.R, this.G, this.B, this.A); + Draw.Rectangle(this.X - this.SizeX * 0.5, this.Y - this.SizeY * 0.5, this.SizeX, this.SizeY); + Draw.SetBlendMode(BlendMode_NORMAL); + } +} diff --git a/Scripts/Stage/Zone.hsl b/Scripts/Stage/Zone.hsl new file mode 100644 index 0000000..c8e2554 --- /dev/null +++ b/Scripts/Stage/Zone.hsl @@ -0,0 +1,116 @@ +var DrawGroup_FGLow_Low = 2; +var DrawGroup_FGLow_High = 4; +var DrawGroup_FGHigh_Low = 6; +var DrawGroup_FGHigh_High = 8; +var DrawGroup_AboveTiles = 12; +var DrawGroup_HUD = 14; + +class Zone { + event Create() { + var sceneWidth = Scene.GetWidth() * 16.0; + var sceneHeight = Scene.GetHeight() * 16.0; + var maxPlayerCount = 8; + + this.StaticWorldInertia = 0.0; + this.MinPlayerX = Array.Create(maxPlayerCount); + this.MaxPlayerX = Array.Create(maxPlayerCount); + this.MinPlayerY = Array.Create(maxPlayerCount); + this.MaxPlayerY = Array.Create(maxPlayerCount); + this.BoundPlayerTop = Array.Create(maxPlayerCount); + this.BoundPlayerLeft = Array.Create(maxPlayerCount); + this.BoundPlayerRight = Array.Create(maxPlayerCount); + this.BoundPlayerBottom = Array.Create(maxPlayerCount); + + for (var i = 0; i < maxPlayerCount; i++) { + this.MinPlayerX[i] = 0.0; + this.MaxPlayerX[i] = sceneWidth; + this.MinPlayerY[i] = 0.0; + this.MaxPlayerY[i] = sceneHeight; + this.BoundPlayerTop[i] = true; + this.BoundPlayerLeft[i] = true; + this.BoundPlayerRight[i] = true; + this.BoundPlayerBottom[i] = true; + } + + + // this.SuperForm = 2; + + var sceneName = Scene.GetName(); + // "Stages/GHZ/Scene2.bin" + // "Stages/GHZ/TileConfig.bin" + + var ind = String.LastIndexOf(sceneName, "/"); + if (ind > -1) { + sceneName = String.Substring(sceneName, 0, ind) + "/TileConfig.bin"; + Scene.LoadTileCollisions(sceneName); + } + + if (String.Contains(sceneName, "MSZ")) { + Scene.SetLayerVisible(4, false); + } + + var scratchInd = -1; + if ((scratchInd = Scene.GetLayerIndex("Scratch")) != -1) { + Scene.SetLayerVisible(scratchInd, false); + } + scratchInd = -1; + if ((scratchInd = Scene.GetLayerIndex("Move")) != -1) { + Scene.SetLayerVisible(scratchInd, false); + } + } + event UpdateLate() { + var player, zone = this; + with ("Player") { + player = this; + + var index = 0; + var staticWorldInertia = zone.StaticWorldInertia; + + // Bound left + var zoneMinPlayerX = zone.MinPlayerX[index]; + var playerHitboxLeft = player.HitboxW * -0.5 + player.HitboxOffX; + if (player.X + playerHitboxLeft <= zoneMinPlayerX) { + player.X = -playerHitboxLeft + zoneMinPlayerX; + if (player.Ground) { + if (player.GroundSpeed < staticWorldInertia) { + player.XSpeed = + player.GroundSpeed = staticWorldInertia; + player.PushingTimer = 0; + } + } + else if (player.XSpeed < staticWorldInertia) { + player.XSpeed = staticWorldInertia; + player.GroundSpeed = 0.0; + } + } + + // Bound right + var zoneMaxPlayerX = zone.MaxPlayerX[index]; + var playerHitboxRight = player.HitboxW * 0.5 + player.HitboxOffX; + if (player.X + playerHitboxRight >= zoneMaxPlayerX) { + player.X = -playerHitboxRight + zoneMaxPlayerX; + if (player.Ground) { + if (player.GroundSpeed > staticWorldInertia) { + player.XSpeed = + player.GroundSpeed = staticWorldInertia; + player.PushingTimer = 0; + } + } + else if (player.XSpeed > staticWorldInertia) { + player.XSpeed = staticWorldInertia; + player.GroundSpeed = 0.0; + } + } + + // Bound top + var zoneMinPlayerY = zone.MinPlayerY[index]; + var playerHitboxTop = -20.0; // player.HitboxH * -0.5 + player.HitboxOffY; + if (player.Y + playerHitboxTop < zoneMinPlayerY) { + player.Y = -playerHitboxTop + zoneMinPlayerY; + if (player.YSpeed < 0.0) { + player.YSpeed = 0.0; + } + } + } + } +} diff --git a/Scripts/Static.hsl b/Scripts/Static.hsl new file mode 100644 index 0000000..e3c8577 --- /dev/null +++ b/Scripts/Static.hsl @@ -0,0 +1,509 @@ +class Static { + // This event is unique only to the Static object + event GameStart() { + global.SelectedCharacter = 2; + global.Level = 0; + global.LevelScenes = [ + "Stages/GHZ/Scene1.bin", + "Stages/GHZ/Scene2.bin", + "Stages/CPZ/Scene1.bin", + "Stages/CPZ/Scene2.bin", + "Stages/SPZ1/Scene1.bin", + "Stages/SPZ2/Scene1.bin", + "Stages/FBZ/Scene1.bin", + "Stages/FBZ/Scene2.bin", + "Stages/PSZ1/Scene1.bin", + "Stages/PSZ2/Scene2.bin", + "Stages/SSZ1/Scene1.bin", + "Stages/SSZ2/Scene1.bin", + "Stages/HCZ/Scene1.bin", + "Stages/HCZ/Scene2.bin", + "Stages/MSZ/Scene1K.bin", + "Stages/MSZ/Scene2.bin", + "Stages/OOZ1/Scene1.bin", + "Stages/OOZ2/Scene2.bin", + "Stages/LRZ1/Scene1.bin", + "Stages/LRZ2/Scene1.bin", + "Stages/MMZ/Scene1.bin", + "Stages/MMZ/Scene2.bin", + "Stages/TMZ1/Scene1.bin", + "Stages/TMZ2/Scene1.bin", + ]; + + global.GameMode = 0; + global.PlayerID = 0; + global.SpecialCleared = 0; + global.SpecialRingID = 0; + global.BlueSphereID = 0; + global.BlueSphereInit = 0; + global.SaveLoaded = 0; + global.SaveRAM = 0; + global.SaveSlotID = 0; + global.NoSaveSlot = 0; + global.MenuParam = 0; + global.ItemMode = 0; + global.SuppressTitlecard = 0; + global.SuppressAutoMusic = 0; + global.CompetitionSession = 0; + global.MedalMods = 0; + global.ParallaxOffset = 0; + global.EnableIntro = 0; + global.OptionsLoaded = 0; + global.OptionsRAM = 0; + global.PresenceID = 0; + global.MedallionDebug = 0; + global.NoSave = 0; + global.NotifiedAutosave = 0; + global.RecallEntities = 0; + global.RestartRings = 0; + global.Restart1UP = 0; + global.RestartShield = 0; + global.RestartPos = 0; + global.RestartSlot = 0; + global.RestartDir = 0; + global.RestartMinutes = 0; + global.RestartSeconds = 0; + global.RestartMilliseconds = 0; + global.TempMinutes = 0; + global.TempSeconds = 0; + global.TempMilliseconds = 0; + global.RestartScore = 0; + global.RestartScore1UP = 0; + global.RestartLives = 0; + global.RestartMusicID = 0; + global.RestartFlags = 0; + global.TempFlags = 0; + } + + event Entity_CollideWithObject(source, other) { + return source.CollideWithObject(other); + + /* + var sourceX = Math.Floor(source.X); + var sourceY = Math.Floor(source.Y); + var otherX = Math.Floor(other.X); + var otherY = Math.Floor(other.Y); + + var otherHitboxW = (other.HitboxW) * 0.5; + var otherHitboxH = (other.HitboxH) * 0.5; + var sourceHitboxW = (source.HitboxW) * 0.5; + var sourceHitboxH = (source.HitboxH) * 0.5; + + if (otherY + otherHitboxH < sourceY - sourceHitboxH || + otherY - otherHitboxH > sourceY + sourceHitboxH || + sourceX - sourceHitboxW > otherX + otherHitboxW || + sourceX + sourceHitboxW < otherX - otherHitboxW) + return false; + + return true; + //*/ + } + event Entity_SolidCollideWithPlayer(source, player) { + if (player.IsGhost) + return 0; + + var v6, v7; + // v6 = player.StaticHitbox; + // if (!v6) + // v6 = GetPlayerHitbox + + // playerHitbox = &unk_66B804; + // if (v6) + // playerHitbox = v6; + + player.GetHitboxFromSprite(player.Sprite, player.CurrentAnimation, player.CurrentFrame, 0); + + var value = Static.Entity_SolidCollideWithObject(source, player, 1); + switch (value) { + // Top Side + case 1: { + player.InputLock = 0; + player.AngleMode = 0; + + var leftSide, rightSide, halfW = source.HitboxW / 2.0; + if (source.FlipFlag & 1) { + leftSide = source.X - halfW; + rightSide = source.X + halfW; + } + else { + leftSide = source.X - halfW; + rightSide = source.X + halfW; + } + + var playerX = player.X; + var rightX = playerX + player.SensorRightX; + var rightShX = playerX + player.SensorRightShortX; + var middleX = playerX + player.SensorMiddleX; + var leftShX = playerX + player.SensorLeftShortX; + var leftX = playerX + player.SensorLeftX; + if (rightX >= leftSide && rightX <= rightSide) + player.GroundSensorMask |= 1; + if (rightShX >= leftSide && rightShX <= rightSide) + player.GroundSensorMask |= 2; + if (middleX >= leftSide && middleX <= rightSide) + player.GroundSensorMask |= 4; + if (leftShX >= leftSide && leftShX <= rightSide) + player.GroundSensorMask |= 8; + if (leftX >= leftSide && leftX <= rightSide) + player.GroundSensorMask |= 16; + + if (source.YSpeed <= 0.0) + player.VerticalCollisionFlag |= 1; + break; + } + // Left Side + case 2: { + player.InputLock = 0; + if (player.InputLeft && player.Ground) { + player.GroundSpeed = -0.5; + player.X = Math.Floor(player.X); + } + break; + } + // Right Side + case 3: { + player.InputLock = 0; + if (player.InputRight && player.Ground) { + player.GroundSpeed = 0.5; + player.X = Math.Floor(player.X); + } + break; + } + // Bottom Side + case 4: { + break; + } + // No collision + default: + value = 0; + } + return value; + } + event Entity_SolidCollideWithObject(source, other, flag) { + return source.SolidCollideWithObject(other, flag); + + /* + // NOTE: "flag" might be "UseGroundSpeed" + var initialOtherX = (other.X); + var initialOtherY = (other.Y); + var sourceX = Math.Floor(source.X); + var sourceY = Math.Floor(source.Y); + var otherX = Math.Floor(initialOtherX); + var otherY = Math.Floor(initialOtherY); + var otherNewX = initialOtherX; + var collideSideHori = 0; + var collideSideVert = 0; + + var otherHitboxW = (other.HitboxW) * 0.5; + var otherHitboxH = (other.HitboxH) * 0.5; + var otherHitboxWSq = (other.HitboxW - 2.0) * 0.5; + var otherHitboxHSq = (other.HitboxH - 2.0) * 0.5; + var sourceHitboxW = (source.HitboxW) * 0.5; + var sourceHitboxH = (source.HitboxH) * 0.5; + + // NOTE: Keep this. + // if ( other_X <= (sourceHitbox->Right + sourceHitbox->Left + 2 * source_X) >> 1 ) + // if ( other_X <= (sourceHitbox->Right + sourceHitbox->Left) / 2 + source_X ) + // if ( other_X <= source_X + (sourceHitbox->Right + sourceHitbox->Left) / 2 ) + // if other.X <= source.X + source.HitboxCenterX + + // Check squeezed vertically + if (sourceY - sourceHitboxH < initialOtherY + otherHitboxHSq && + sourceY + sourceHitboxH > initialOtherY - otherHitboxHSq) { + // if other.X <= source.X + source.HitboxCenterX + if (otherX <= sourceX) { + if (otherX + otherHitboxW >= sourceX - sourceHitboxW) { + collideSideHori = 2; + otherNewX = source.X + (-sourceHitboxW - otherHitboxW); + } + } + else { + if (otherX - otherHitboxW < sourceX + sourceHitboxW) { + collideSideHori = 3; + otherNewX = source.X + (sourceHitboxW - (-otherHitboxW)); + } + } + } + + // Check squeezed horizontally + if (sourceX - sourceHitboxW < initialOtherX + otherHitboxWSq && + sourceX + sourceHitboxW > initialOtherX - otherHitboxWSq) { + // if other.Y <= source.Y + source.HitboxCenterY + if (otherY <= sourceY) { + if (otherY + otherHitboxH >= sourceY - sourceHitboxH) { + collideSideVert = 1; + otherY = source.Y + (-sourceHitboxH - otherHitboxH); + } + } + else { + if (otherY - otherHitboxH < sourceY + sourceHitboxH) { + collideSideVert = 4; + otherY = source.Y + (sourceHitboxH - (-otherHitboxH)); + } + } + } + + var deltaSquaredX1 = otherNewX - other.X; + var deltaSquaredX2 = initialOtherX - other.X; + var deltaSquaredY1 = otherY - other.Y; + var deltaSquaredY2 = initialOtherY - other.Y; + + if (collideSideHori && collideSideVert) { + // print + // " deltaSquaredX1: " + deltaSquaredX1 + + // " deltaSquaredX2: " + deltaSquaredX2 + + // " deltaSquaredY1: " + deltaSquaredY1 + + // " deltaSquaredY2: " + deltaSquaredY2; + // print + // " collideSideHori: " + collideSideHori + + // " collideSideVert: " + collideSideVert; + } + + deltaSquaredX1 *= deltaSquaredX1; + deltaSquaredX2 *= deltaSquaredX2; + deltaSquaredY1 *= deltaSquaredY1; + deltaSquaredY2 *= deltaSquaredY2; + + var v47 = collideSideVert, v48; + var v46 = collideSideHori; + + if (collideSideHori != 0 || collideSideVert != 0) { + if (deltaSquaredX1 + deltaSquaredY2 >= deltaSquaredX2 + deltaSquaredY1) { + if (collideSideVert || !collideSideHori) { + other.X = initialOtherX; + other.Y = otherY; + if (flag == 1) { + if (collideSideVert != 1) { + if (collideSideVert == 4 && other.YSpeed < 0.0) { + other.YSpeed = 0.0; + return v47; + } + return v47; + } + + if (other.YSpeed > 0.0) + other.YSpeed = 0.0; + if (!other.Ground && other.YSpeed >= 0.0) { + other.GroundSpeed = other.XSpeed; + other.Angle = 0; + other.Ground = true; + } + } + return v47; + } + } + else { + if (collideSideVert && !collideSideHori) { + other.X = initialOtherX; + other.Y = otherY; + if (flag == 1) { + if (collideSideVert != 1) { + if (collideSideVert == 4 && other.YSpeed < 0.0) { + other.YSpeed = 0.0; + return v47; + } + return v47; + } + + if (other.YSpeed > 0.0) + other.YSpeed = 0.0; + if (!other.Ground && other.YSpeed >= 0.0) { + other.GroundSpeed = other.XSpeed; + other.Angle = 0; + other.Ground = true; + } + } + return v47; + } + } + + other.X = otherNewX; + other.Y = initialOtherY; + if (flag == 1) { + var v50; + if (other.Ground) { + v50 = other.GroundSpeed; + if (other.AngleMode == 2) + v50 = -v50; + } + else { + v50 = other.XSpeed; + } + + if (v46 == 2) { + if (v50 <= 0.0) + return v46; + } + else if (v46 != 3 || v50 >= 0.0) { + return v46; + } + + other.GroundSpeed = 0.0; + other.XSpeed = 0.0; + } + return v46; + } + return 0; + + //*/ + } + event Entity_TopSolidCollideWithPlayer(source, player) { + if (player.IsGhost) + return 0; + + var v6, v7; + // v6 = player.StaticHitbox; + // if (!v6) + // v6 = GetPlayerHitbox + + // playerHitbox = &unk_66B804; + // if (v6) + // playerHitbox = v6; + + player.GetHitboxFromSprite(player.Sprite, player.CurrentAnimation, player.CurrentFrame, 0); + + // var value = this.Entity_TopSolidCollideWithObject(source, player, playerHitbox, 1); + if (!Static.Entity_TopSolidCollideWithObject(source, player, 1)) + return 0; + + player.InputLock = 0; + player.AngleMode = 0; + + var leftSide, rightSide, halfW = source.HitboxW / 2.0; + if (source.FlipFlag & 1) { + leftSide = source.X - halfW; + rightSide = source.X + halfW; + } + else { + leftSide = source.X - halfW; + rightSide = source.X + halfW; + } + + var playerX = player.X; + var rightX = playerX + player.SensorRightX; + var rightShX = playerX + player.SensorRightShortX; + var middleX = playerX + player.SensorMiddleX; + var leftShX = playerX + player.SensorLeftShortX; + var leftX = playerX + player.SensorLeftX; + if (rightX >= leftSide && rightX <= rightSide) + player.GroundSensorMask |= 1; + if (rightShX >= leftSide && rightShX <= rightSide) + player.GroundSensorMask |= 2; + if (middleX >= leftSide && middleX <= rightSide) + player.GroundSensorMask |= 4; + if (leftShX >= leftSide && leftShX <= rightSide) + player.GroundSensorMask |= 8; + if (leftX >= leftSide && leftX <= rightSide) + player.GroundSensorMask |= 16; + + if (source.YSpeed <= 0.0) + player.VerticalCollisionFlag |= 1; + + return 1; + } + event Entity_TopSolidCollideWithObject(source, other, flag) { + return source.TopSolidCollideWithObject(other, flag); + + /* + + // NOTE: "flag" might be "UseGroundSpeed" + var initialOtherX = (other.X); + var initialOtherY = (other.Y); + var sourceX = Math.Floor(source.X); + var sourceY = Math.Floor(source.Y); + var otherX = Math.Floor(initialOtherX); + var otherY = Math.Floor(initialOtherY); + var otherYMinusYSpeed = Math.Floor(initialOtherY - other.YSpeed); + + var otherHitboxW = (other.HitboxW) * 0.5; + var otherHitboxH = (other.HitboxH) * 0.5; + var sourceHitboxW = (source.HitboxW) * 0.5; + var sourceHitboxH = (source.HitboxH) * 0.5; + + if (otherY + otherHitboxH < sourceY - sourceHitboxH || + otherYMinusYSpeed + otherHitboxH > sourceY + sourceHitboxH || + sourceX - sourceHitboxW >= otherX + otherHitboxW || + sourceX + sourceHitboxW <= otherX - otherHitboxW || + other.YSpeed < 0.0) + return false; + + other.Y = source.Y + ((-sourceHitboxH) - otherHitboxH); + if (flag) { + other.YSpeed = 0.0; + if (!other.Ground) { + other.GroundSpeed = other.XSpeed; + other.Angle = 0; + other.Ground = true; + } + } + return true; + // */ + } + + event Entity_CheckTileCollision_Move(entity, unused_layerCollisionMask, angleMode, planeIndex, offsetX, offsetY, moveEntity) { + var startX = entity.X + offsetX; + var startY = entity.Y + offsetY; + switch (angleMode) { + case 0: + return false; + // Checking to right + case 1: + if (Static.SenseTileCollision(entity, startX, startY, CollideSide_LEFT, 1.0, 0.0, -8.0, 14.0, planeIndex)) { + if (moveEntity) + entity.X = entity.STC_X - offsetX; + return true; + } + return false; + case 2: + return false; + // Checking to left + case 3: + if (Static.SenseTileCollision(entity, startX, startY, CollideSide_RIGHT, -1.0, 0.0, -8.0, 14.0, planeIndex)) { + if (moveEntity) + entity.X = entity.STC_X - offsetX; + return true; + } + return false; + } + return false; + } + event SenseTileCollision(entity, x, y, side, dirX, dirY, startLen, endLen, planeIndex) { + x += dirX * startLen; + y += dirY * startLen; + + var angle; + for (var i = startLen; i < endLen; i += 1.0) { + angle = TileCollision.PointExtended(x, y, planeIndex, side); + if (angle >= 0) { + entity.STC_X = Math.Floor(x); + entity.STC_Y = Math.Floor(y); + entity.STC_Angle = angle; + entity.STC_Length = i; + return true; + } + + x += dirX; + y += dirY; + } + return false; + } + + event HexSin(n) { + return Math.Sin((n & 0xFF) * Math_PI / 128.0); + } + event HexCos(n) { + return Math.Cos((n & 0xFF) * Math_PI / 128.0); + } + event HexSinMedPrec(n) { + return Math.Sin((n & 0x1FF) * Math_PI / 256.0); + } + event HexCosMedPrec(n) { + return Math.Cos((n & 0x1FF) * Math_PI / 256.0); + } + event HexSinHighPrec(n) { + return Math.Sin((n & 0x3FF) * Math_PI / 512.0); + } + event HexCosHighPrec(n) { + return Math.Cos((n & 0x3FF) * Math_PI / 512.0); + } +} diff --git a/Scripts/Title/TitleBG.hsl b/Scripts/Title/TitleBG.hsl new file mode 100644 index 0000000..4564458 --- /dev/null +++ b/Scripts/Title/TitleBG.hsl @@ -0,0 +1,25 @@ +class TitleBG { + event Create() { + this.Priority = 3 * 4; + this.Sprite = Resources.LoadSprite("Sprites/Title/Background.bin", SCOPE_SCENE); + this.SetAnimation(0, 0); + + this.Type = this.PropertyGet("type"); + if (this.Type == 4) + this.Active = false; + + this.SetAnimation(this.Type, 0); + } + + event Update() { + this.X += 2.0; + if (this.X > 640.0) + this.X -= 816.0; + } + + event Render() { + if (this.Sprite > -1) { + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, this.X, this.Y, false, false); + } + } +} diff --git a/Scripts/Title/TitleSonic.hsl b/Scripts/Title/TitleSonic.hsl new file mode 100644 index 0000000..f272772 --- /dev/null +++ b/Scripts/Title/TitleSonic.hsl @@ -0,0 +1,165 @@ +class TitleSonic { + event Create() { + this.Sprite = -1; + this.Priority = 99; + + this.ElectricSprite = Resources.LoadSprite("Sprites/Title/Electricity.bin", SCOPE_SCENE); + this.SonicSprite = Resources.LoadSprite("Sprites/Title/Sonic.bin", SCOPE_SCENE); + this.LogoSprite = Resources.LoadSprite("Sprites/Title/Logo.bin", SCOPE_SCENE); + /* + Anim: + 0: Logo Wings + 1: Ribbon Unfurl + 2: Ribbon Wave + 3: Ribbon Center + 4: Game Title + 5: Power LED + 6: Copyright + 7: Ring Bottom + 8: Press Button + */ + + /* + + Timeline: + 1. 120 of fade in, Power Button sprite drawn + 2. Play music, start animation + 3. At Frame 29 of animation, remove Power Button + 4. At Frame 31 of animation, draw Ring under elec, start Logo Unfurl animation (separate object under elec) + 5. After unfurl, start fade in from white (48 frames) + 6. After fade in, wait 16 frames, then start Sonic animation + + */ + + // for (var x = 0; x < 16; x++) { + // for (var y = 0; y < 16; y++) { + // Scene.SetTile(2, x, y, 0x400, false, false); + // } + // } + + this.FadeIn = true; + this.FadeToWhite = false; + this.Fade = 0; + this.FadeLength = 60; + this.State = 0; + + this.ShowPowerButton = true; + this.ShowLogoWings = false; + + this.Y += 16.0; + this.InitialY = this.Y; + } + + event Update() { + if (this.CurrentAnimation == 0 && this.CurrentFrame == 29) { + this.ShowPowerButton = false; + } + if (this.CurrentAnimation == 0 && this.CurrentFrame == 31) { + this.ShowLogoWings = true; + } + if (this.Sprite == this.SonicSprite && + this.CurrentAnimation == 0 && + this.CurrentFrame == 47) { + this.SetAnimation(1, 0); + this.State = 4; + } + + if (this.Fade < this.FadeLength) { + this.Fade++; + if (this.Fade == this.FadeLength) { + if (this.State == 0) { + this.Sprite = this.ElectricSprite; + this.SetAnimation(0, 0); + this.State = 1; + + var music = Instance.GetNth("MusicObject", 0); + if (music) music.PlayMus(); + } + } + } + } + event OnAnimationFinish() { + // this.Sprite = -1; + + // Switch to wing sprite + if (this.Sprite == this.ElectricSprite) { + this.Sprite = this.LogoSprite; + this.SetAnimation(1, 0); + // this.Y = 132.0; + this.Y = this.InitialY + 28.0; + } + // Switch to + else if (this.Sprite == this.LogoSprite && this.State == 1) { + this.FadeIn = true; + this.FadeToWhite = true; + this.Fade = 0; + this.FadeLength = 48; + this.State = 2; + + // this.SonicWaitTimer = 16; + this.Sprite = this.SonicSprite; + this.SetAnimation(0, 0); + this.Y = this.InitialY - 4.0; + // this.Y = 100.0; + this.State = 3; + } + } + + event Render() { + var vw = 424.0, vh = 240.0; + var eased = this.Fade * 1.0 / this.FadeLength; + if (this.FadeIn) { + eased = 1.0 - eased; + } + eased = Ease.InOutQuad(eased); + + if (this.State >= 3) { + Draw.Sprite(this.LogoSprite, 0, 0, this.X, this.InitialY, false, false); + Draw.Sprite(this.LogoSprite, 0, 0, this.X, this.InitialY, true, false); + + Draw.SetClip(0.0, 0.0, 424.0, this.InitialY + 16.0); + if (this.Sprite > -1) { + if (this.State == 4) + Draw.Sprite(this.Sprite, 0, 48, this.X, this.Y, false, false); + + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, this.X, this.Y, false, false); + } + Draw.ClearClip(); + + // Ribbon + Draw.Sprite(this.LogoSprite, 3, 0, this.X, this.InitialY + 28.0, false, false); + Draw.Sprite(this.LogoSprite, 2, (Scene_Frame >> 1) & 7, this.X, this.InitialY + 28.0, false, false); + Draw.Sprite(this.LogoSprite, 2, (Scene_Frame >> 1) & 7, this.X, this.InitialY + 28.0, true, false); + Draw.Sprite(this.LogoSprite, 4, 0, this.X, this.InitialY + 66.0, false, false); + } + else { + // Draw.SetBlendColor(0.9375, 0.9375, 0.9375, 1.0); + // Draw.SetBlendColor(0.0, 0.0, 0.0, 1.0); + // Draw.Rectangle(0.0, this.RectY, vw, vh); + + if (this.ShowPowerButton) { + Draw.Sprite(this.LogoSprite, 5, 0, this.X, this.InitialY + 44.0, false, false); + } + if (this.ShowLogoWings) { + Draw.Sprite(this.LogoSprite, 0, 0, this.X, this.InitialY, false, false); + Draw.Sprite(this.LogoSprite, 0, 0, this.X, this.InitialY, true, false); + } + + if (this.Sprite > -1) { + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, this.X, this.Y, false, false); + Draw.Sprite(this.Sprite, this.CurrentAnimation, this.CurrentFrame, this.X, this.Y, true, false); + } + } + + if (this.FadeToWhite) + Draw.SetBlendMode(BlendMode_ADD); + else + Draw.SetBlendMode(BlendMode_SUBTRACT); + Draw.SetBlendColor( + Math.Clamp(eased * 3.0, 0.0, 0.9375), + Math.Clamp(eased * 3.0 - 1.0, 0.0, 0.9375), + Math.Clamp(eased * 3.0 - 2.0, 0.0, 0.9375), 1.0); + Draw.Rectangle(0.0, 0.0, 512.0, vh); + Draw.SetBlendMode(BlendMode_NORMAL); + } +} diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..c24adba --- /dev/null +++ b/config.ini @@ -0,0 +1,23 @@ +[game] +modpacks = Mania.hatch + +[display] +vsync = true +multisample = 0 +retina = false +defaultMonitor = 1 + +[audio] +masterVolume = 100 +musicVolume = 50 +soundVolume = 100 + +[dev] +logLevel = -1 +renderer = opengl +viewPerformance = 0 +donothing = false +notiles = false +noobjectrender = false +debugCompiler = 0 +fastforward = 4