Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 1392-2-2-15-attempting-to-draw-a-hud-graphic-with-the-same-lump-name-as-a-lua-script-crashes-the
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
  • 1168-accessing-an-invalid-variable-in-ticcmd_t-crashes-the-game
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • batocera
  • blend-locking
  • blentran
  • blockmap-links
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • few-kart-lua-changes
  • ffloorclip
  • fix-1183
  • fix-cvar-conflicts
  • fix-opengl-shear-roll
  • fix-slope-plane-distortion
  • fix-sw-polyobject-interpolation
  • fix-table-key-archiving
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • font_drawer
  • frictionrefactor
  • fruits-clipper
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • gitlab-ci
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • lugstuff
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
141 results
Show changes
Showing with 1303 additions and 609 deletions
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -298,283 +298,286 @@ enum actionnum
NUMACTIONS
};
struct mobj_s;
// IMPORTANT NOTE: If you add/remove from this list of action
// functions, don't forget to update them in deh_tables.c!
void A_Explode();
void A_Pain();
void A_Fall();
void A_MonitorPop();
void A_GoldMonitorPop();
void A_GoldMonitorRestore();
void A_GoldMonitorSparkle();
void A_Look();
void A_Chase();
void A_FaceStabChase();
void A_FaceStabRev();
void A_FaceStabHurl();
void A_FaceStabMiss();
void A_StatueBurst();
void A_FaceTarget();
void A_FaceTracer();
void A_Scream();
void A_BossDeath();
void A_SetShadowScale();
void A_ShadowScream(); // MARIA!!!!!!
void A_CustomPower(); // Use this for a custom power
void A_GiveWeapon(); // Gives the player weapon(s)
void A_RingBox(); // Obtained Ring Box Tails
void A_Invincibility(); // Obtained Invincibility Box
void A_SuperSneakers(); // Obtained Super Sneakers Box
void A_BunnyHop(); // have bunny hop tails
void A_BubbleSpawn(); // Randomly spawn bubbles
void A_FanBubbleSpawn();
void A_BubbleRise(); // Bubbles float to surface
void A_BubbleCheck(); // Don't draw if not underwater
void A_AwardScore();
void A_ExtraLife(); // Extra Life
void A_GiveShield(); // Obtained Shield
void A_GravityBox();
void A_ScoreRise(); // Rise the score logo
void A_AttractChase(); // Ring Chase
void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber
void A_FishJump(); // Fish Jump
void A_ThrownRing(); // Sparkle trail for red ring
void A_SetSolidSteam();
void A_UnsetSolidSteam();
void A_SignSpin();
void A_SignPlayer();
void A_OverlayThink();
void A_JetChase();
void A_JetbThink(); // Jetty-Syn Bomber Thinker
void A_JetgThink(); // Jetty-Syn Gunner Thinker
void A_JetgShoot(); // Jetty-Syn Shoot Function
void A_ShootBullet(); // JetgShoot without reactiontime setting
void A_MinusDigging();
void A_MinusPopup();
void A_MinusCheck();
void A_ChickenCheck();
void A_MouseThink(); // Mouse Thinker
void A_DetonChase(); // Deton Chaser
void A_CapeChase(); // Fake little Super Sonic cape
void A_RotateSpikeBall(); // Spike ball rotation
void A_SlingAppear();
void A_UnidusBall();
void A_RockSpawn();
void A_SetFuse();
void A_CrawlaCommanderThink(); // Crawla Commander
void A_SmokeTrailer();
void A_RingExplode();
void A_OldRingExplode();
void A_MixUp();
void A_RecyclePowers();
void A_BossScream();
void A_Boss2TakeDamage();
void A_GoopSplat();
void A_Boss2PogoSFX();
void A_Boss2PogoTarget();
void A_EggmanBox();
void A_TurretFire();
void A_SuperTurretFire();
void A_TurretStop();
void A_JetJawRoam();
void A_JetJawChomp();
void A_PointyThink();
void A_CheckBuddy();
void A_HoodFire();
void A_HoodThink();
void A_HoodFall();
void A_ArrowBonks();
void A_SnailerThink();
void A_SharpChase();
void A_SharpSpin();
void A_SharpDecel();
void A_CrushstaceanWalk();
void A_CrushstaceanPunch();
void A_CrushclawAim();
void A_CrushclawLaunch();
void A_VultureVtol();
void A_VultureCheck();
void A_VultureHover();
void A_VultureBlast();
void A_VultureFly();
void A_SkimChase();
void A_SkullAttack();
void A_LobShot();
void A_FireShot();
void A_SuperFireShot();
void A_BossFireShot();
void A_Boss7FireMissiles();
void A_Boss1Laser();
void A_FocusTarget();
void A_Boss4Reverse();
void A_Boss4SpeedUp();
void A_Boss4Raise();
void A_SparkFollow();
void A_BuzzFly();
void A_GuardChase();
void A_EggShield();
void A_SetReactionTime();
void A_Boss1Spikeballs();
void A_Boss3TakeDamage();
void A_Boss3Path();
void A_Boss3ShockThink();
void A_Shockwave();
void A_LinedefExecute();
void A_LinedefExecuteFromArg();
void A_PlaySeeSound();
void A_PlayAttackSound();
void A_PlayActiveSound();
void A_1upThinker();
void A_BossZoom(); //Unused
void A_Boss1Chase();
void A_Boss2Chase();
void A_Boss2Pogo();
void A_Boss7Chase();
void A_BossJetFume();
void A_SpawnObjectAbsolute();
void A_SpawnObjectRelative();
void A_ChangeAngleRelative();
void A_ChangeAngleAbsolute();
void A_RollAngle();
void A_ChangeRollAngleRelative();
void A_ChangeRollAngleAbsolute();
void A_PlaySound();
void A_FindTarget();
void A_FindTracer();
void A_SetTics();
void A_SetRandomTics();
void A_ChangeColorRelative();
void A_ChangeColorAbsolute();
void A_Dye();
void A_SetTranslation();
void A_MoveRelative();
void A_MoveAbsolute();
void A_Thrust();
void A_ZThrust();
void A_SetTargetsTarget();
void A_SetObjectFlags();
void A_SetObjectFlags2();
void A_RandomState();
void A_RandomStateRange();
void A_StateRangeByAngle();
void A_StateRangeByParameter();
void A_DualAction();
void A_RemoteAction();
void A_ToggleFlameJet();
void A_OrbitNights();
void A_GhostMe();
void A_SetObjectState();
void A_SetObjectTypeState();
void A_KnockBack();
void A_PushAway();
void A_RingDrain();
void A_SplitShot();
void A_MissileSplit();
void A_MultiShot();
void A_InstaLoop();
void A_Custom3DRotate();
void A_SearchForPlayers();
void A_CheckRandom();
void A_CheckTargetRings();
void A_CheckRings();
void A_CheckTotalRings();
void A_CheckHealth();
void A_CheckRange();
void A_CheckHeight();
void A_CheckTrueRange();
void A_CheckThingCount();
void A_CheckAmbush();
void A_CheckCustomValue();
void A_CheckCusValMemo();
void A_SetCustomValue();
void A_UseCusValMemo();
void A_RelayCustomValue();
void A_CusValAction();
void A_ForceStop();
void A_ForceWin();
void A_SpikeRetract();
void A_InfoState();
void A_Repeat();
void A_SetScale();
void A_RemoteDamage();
void A_HomingChase();
void A_TrapShot();
void A_VileTarget();
void A_VileAttack();
void A_VileFire();
void A_BrakChase();
void A_BrakFireShot();
void A_BrakLobShot();
void A_NapalmScatter();
void A_SpawnFreshCopy();
void A_FlickySpawn();
void A_FlickyCenter();
void A_FlickyAim();
void A_FlickyFly();
void A_FlickySoar();
void A_FlickyCoast();
void A_FlickyHop();
void A_FlickyFlounder();
void A_FlickyCheck();
void A_FlickyHeightCheck();
void A_FlickyFlutter();
void A_FlameParticle();
void A_FadeOverlay();
void A_Boss5Jump();
void A_LightBeamReset();
void A_MineExplode();
void A_MineRange();
void A_ConnectToGround();
void A_SpawnParticleRelative();
void A_MultiShotDist();
void A_WhoCaresIfYourSonIsABee();
void A_ParentTriesToSleep();
void A_CryingToMomma();
void A_CheckFlags2();
void A_Boss5FindWaypoint();
void A_DoNPCSkid();
void A_DoNPCPain();
void A_PrepareRepeat();
void A_Boss5ExtraRepeat();
void A_Boss5Calm();
void A_Boss5CheckOnGround();
void A_Boss5CheckFalling();
void A_Boss5PinchShot();
void A_Boss5MakeItRain();
void A_Boss5MakeJunk();
void A_LookForBetter();
void A_Boss5BombExplode();
void A_DustDevilThink();
void A_TNTExplode();
void A_DebrisRandom();
void A_TrainCameo();
void A_TrainCameo2();
void A_CanarivoreGas();
void A_KillSegments();
void A_SnapperSpawn();
void A_SnapperThinker();
void A_SaloonDoorSpawn();
void A_MinecartSparkThink();
void A_ModuloToState();
void A_LavafallRocks();
void A_LavafallLava();
void A_FallingLavaCheck();
void A_FireShrink();
void A_SpawnPterabytes();
void A_PterabyteHover();
void A_RolloutSpawn();
void A_RolloutRock();
void A_DragonbomberSpawn();
void A_DragonWing();
void A_DragonSegment();
void A_ChangeHeight();
void A_Explode(struct mobj_s *actor);
void A_Pain(struct mobj_s *actor);
void A_Fall(struct mobj_s *actor);
void A_MonitorPop(struct mobj_s *actor);
void A_GoldMonitorPop(struct mobj_s *actor);
void A_GoldMonitorRestore(struct mobj_s *actor);
void A_GoldMonitorSparkle(struct mobj_s *actor);
void A_Look(struct mobj_s *actor);
void A_Chase(struct mobj_s *actor);
void A_FaceStabChase(struct mobj_s *actor);
void A_FaceStabRev(struct mobj_s *actor);
void A_FaceStabHurl(struct mobj_s *actor);
void A_FaceStabMiss(struct mobj_s *actor);
void A_StatueBurst(struct mobj_s *actor);
void A_FaceTarget(struct mobj_s *actor);
void A_FaceTracer(struct mobj_s *actor);
void A_Scream(struct mobj_s *actor);
void A_BossDeath(struct mobj_s *actor);
void A_SetShadowScale(struct mobj_s *actor);
void A_ShadowScream(struct mobj_s *actor); // MARIA!!!!!!
void A_CustomPower(struct mobj_s *actor); // Use this for a custom power
void A_GiveWeapon(struct mobj_s *actor); // Gives the player weapon(s)
void A_RingBox(struct mobj_s *actor); // Obtained Ring Box Tails
void A_Invincibility(struct mobj_s *actor); // Obtained Invincibility Box
void A_SuperSneakers(struct mobj_s *actor); // Obtained Super Sneakers Box
void A_BunnyHop(struct mobj_s *actor); // have bunny hop tails
void A_BubbleSpawn(struct mobj_s *actor); // Randomly spawn bubbles
void A_FanBubbleSpawn(struct mobj_s *actor);
void A_BubbleRise(struct mobj_s *actor); // Bubbles float to surface
void A_BubbleCheck(struct mobj_s *actor); // Don't draw if not underwater
void A_AwardScore(struct mobj_s *actor);
void A_ExtraLife(struct mobj_s *actor); // Extra Life
void A_GiveShield(struct mobj_s *actor); // Obtained Shield
void A_GravityBox(struct mobj_s *actor);
void A_ScoreRise(struct mobj_s *actor); // Rise the score logo
void A_AttractChase(struct mobj_s *actor); // Ring Chase
void A_DropMine(struct mobj_s *actor); // Drop Mine from Skim or Jetty-Syn Bomber
void A_FishJump(struct mobj_s *actor); // Fish Jump
void A_ThrownRing(struct mobj_s *actor); // Sparkle trail for red ring
void A_SetSolidSteam(struct mobj_s *actor);
void A_UnsetSolidSteam(struct mobj_s *actor);
void A_SignSpin(struct mobj_s *actor);
void A_SignPlayer(struct mobj_s *actor);
void A_OverlayThink(struct mobj_s *actor);
void A_JetChase(struct mobj_s *actor);
void A_JetbThink(struct mobj_s *actor); // Jetty-Syn Bomber Thinker
void A_JetgThink(struct mobj_s *actor); // Jetty-Syn Gunner Thinker
void A_JetgShoot(struct mobj_s *actor); // Jetty-Syn Shoot Function
void A_ShootBullet(struct mobj_s *actor); // JetgShoot without reactiontime setting
void A_MinusDigging(struct mobj_s *actor);
void A_MinusPopup(struct mobj_s *actor);
void A_MinusCheck(struct mobj_s *actor);
void A_ChickenCheck(struct mobj_s *actor);
void A_MouseThink(struct mobj_s *actor); // Mouse Thinker
void A_DetonChase(struct mobj_s *actor); // Deton Chaser
void A_CapeChase(struct mobj_s *actor); // Fake little Super Sonic cape
void A_RotateSpikeBall(struct mobj_s *actor); // Spike ball rotation
void A_SlingAppear(struct mobj_s *actor);
void A_UnidusBall(struct mobj_s *actor);
void A_RockSpawn(struct mobj_s *actor);
void A_SetFuse(struct mobj_s *actor);
void A_CrawlaCommanderThink(struct mobj_s *actor); // Crawla Commander
void A_SmokeTrailer(struct mobj_s *actor);
void A_RingExplode(struct mobj_s *actor);
void A_OldRingExplode(struct mobj_s *actor);
void A_MixUp(struct mobj_s *actor);
void A_RecyclePowers(struct mobj_s *actor);
void A_BossScream(struct mobj_s *actor);
void A_Boss2TakeDamage(struct mobj_s *actor);
void A_GoopSplat(struct mobj_s *actor);
void A_Boss2PogoSFX(struct mobj_s *actor);
void A_Boss2PogoTarget(struct mobj_s *actor);
void A_EggmanBox(struct mobj_s *actor);
void A_TurretFire(struct mobj_s *actor);
void A_SuperTurretFire(struct mobj_s *actor);
void A_TurretStop(struct mobj_s *actor);
void A_JetJawRoam(struct mobj_s *actor);
void A_JetJawChomp(struct mobj_s *actor);
void A_PointyThink(struct mobj_s *actor);
void A_CheckBuddy(struct mobj_s *actor);
void A_HoodFire(struct mobj_s *actor);
void A_HoodThink(struct mobj_s *actor);
void A_HoodFall(struct mobj_s *actor);
void A_ArrowBonks(struct mobj_s *actor);
void A_SnailerThink(struct mobj_s *actor);
void A_SharpChase(struct mobj_s *actor);
void A_SharpSpin(struct mobj_s *actor);
void A_SharpDecel(struct mobj_s *actor);
void A_CrushstaceanWalk(struct mobj_s *actor);
void A_CrushstaceanPunch(struct mobj_s *actor);
void A_CrushclawAim(struct mobj_s *actor);
void A_CrushclawLaunch(struct mobj_s *actor);
void A_VultureVtol(struct mobj_s *actor);
void A_VultureCheck(struct mobj_s *actor);
void A_VultureHover(struct mobj_s *actor);
void A_VultureBlast(struct mobj_s *actor);
void A_VultureFly(struct mobj_s *actor);
void A_SkimChase(struct mobj_s *actor);
void A_SkullAttack(struct mobj_s *actor);
void A_LobShot(struct mobj_s *actor);
void A_FireShot(struct mobj_s *actor);
void A_SuperFireShot(struct mobj_s *actor);
void A_BossFireShot(struct mobj_s *actor);
void A_Boss7FireMissiles(struct mobj_s *actor);
void A_Boss1Laser(struct mobj_s *actor);
void A_FocusTarget(struct mobj_s *actor);
void A_Boss4Reverse(struct mobj_s *actor);
void A_Boss4SpeedUp(struct mobj_s *actor);
void A_Boss4Raise(struct mobj_s *actor);
void A_SparkFollow(struct mobj_s *actor);
void A_BuzzFly(struct mobj_s *actor);
void A_GuardChase(struct mobj_s *actor);
void A_EggShield(struct mobj_s *actor);
void A_SetReactionTime(struct mobj_s *actor);
void A_Boss1Spikeballs(struct mobj_s *actor);
void A_Boss3TakeDamage(struct mobj_s *actor);
void A_Boss3Path(struct mobj_s *actor);
void A_Boss3ShockThink(struct mobj_s *actor);
void A_Shockwave(struct mobj_s *actor);
void A_LinedefExecute(struct mobj_s *actor);
void A_LinedefExecuteFromArg(struct mobj_s *actor);
void A_PlaySeeSound(struct mobj_s *actor);
void A_PlayAttackSound(struct mobj_s *actor);
void A_PlayActiveSound(struct mobj_s *actor);
void A_1upThinker(struct mobj_s *actor);
void A_BossZoom(struct mobj_s *actor); //Unused
void A_Boss1Chase(struct mobj_s *actor);
void A_Boss2Chase(struct mobj_s *actor);
void A_Boss2Pogo(struct mobj_s *actor);
void A_Boss7Chase(struct mobj_s *actor);
void A_BossJetFume(struct mobj_s *actor);
void A_SpawnObjectAbsolute(struct mobj_s *actor);
void A_SpawnObjectRelative(struct mobj_s *actor);
void A_ChangeAngleRelative(struct mobj_s *actor);
void A_ChangeAngleAbsolute(struct mobj_s *actor);
void A_RollAngle(struct mobj_s *actor);
void A_ChangeRollAngleRelative(struct mobj_s *actor);
void A_ChangeRollAngleAbsolute(struct mobj_s *actor);
void A_PlaySound(struct mobj_s *actor);
void A_FindTarget(struct mobj_s *actor);
void A_FindTracer(struct mobj_s *actor);
void A_SetTics(struct mobj_s *actor);
void A_SetRandomTics(struct mobj_s *actor);
void A_ChangeColorRelative(struct mobj_s *actor);
void A_ChangeColorAbsolute(struct mobj_s *actor);
void A_Dye(struct mobj_s *actor);
void A_SetTranslation(struct mobj_s *actor);
void A_MoveRelative(struct mobj_s *actor);
void A_MoveAbsolute(struct mobj_s *actor);
void A_Thrust(struct mobj_s *actor);
void A_ZThrust(struct mobj_s *actor);
void A_SetTargetsTarget(struct mobj_s *actor);
void A_SetObjectFlags(struct mobj_s *actor);
void A_SetObjectFlags2(struct mobj_s *actor);
void A_RandomState(struct mobj_s *actor);
void A_RandomStateRange(struct mobj_s *actor);
void A_StateRangeByAngle(struct mobj_s *actor);
void A_StateRangeByParameter(struct mobj_s *actor);
void A_DualAction(struct mobj_s *actor);
void A_RemoteAction(struct mobj_s *actor);
void A_ToggleFlameJet(struct mobj_s *actor);
void A_OrbitNights(struct mobj_s *actor);
void A_GhostMe(struct mobj_s *actor);
void A_SetObjectState(struct mobj_s *actor);
void A_SetObjectTypeState(struct mobj_s *actor);
void A_KnockBack(struct mobj_s *actor);
void A_PushAway(struct mobj_s *actor);
void A_RingDrain(struct mobj_s *actor);
void A_SplitShot(struct mobj_s *actor);
void A_MissileSplit(struct mobj_s *actor);
void A_MultiShot(struct mobj_s *actor);
void A_InstaLoop(struct mobj_s *actor);
void A_Custom3DRotate(struct mobj_s *actor);
void A_SearchForPlayers(struct mobj_s *actor);
void A_CheckRandom(struct mobj_s *actor);
void A_CheckTargetRings(struct mobj_s *actor);
void A_CheckRings(struct mobj_s *actor);
void A_CheckTotalRings(struct mobj_s *actor);
void A_CheckHealth(struct mobj_s *actor);
void A_CheckRange(struct mobj_s *actor);
void A_CheckHeight(struct mobj_s *actor);
void A_CheckTrueRange(struct mobj_s *actor);
void A_CheckThingCount(struct mobj_s *actor);
void A_CheckAmbush(struct mobj_s *actor);
void A_CheckCustomValue(struct mobj_s *actor);
void A_CheckCusValMemo(struct mobj_s *actor);
void A_SetCustomValue(struct mobj_s *actor);
void A_UseCusValMemo(struct mobj_s *actor);
void A_RelayCustomValue(struct mobj_s *actor);
void A_CusValAction(struct mobj_s *actor);
void A_ForceStop(struct mobj_s *actor);
void A_ForceWin(struct mobj_s *actor);
void A_SpikeRetract(struct mobj_s *actor);
void A_InfoState(struct mobj_s *actor);
void A_Repeat(struct mobj_s *actor);
void A_SetScale(struct mobj_s *actor);
void A_RemoteDamage(struct mobj_s *actor);
void A_HomingChase(struct mobj_s *actor);
void A_TrapShot(struct mobj_s *actor);
void A_VileTarget(struct mobj_s *actor);
void A_VileAttack(struct mobj_s *actor);
void A_VileFire(struct mobj_s *actor);
void A_BrakChase(struct mobj_s *actor);
void A_BrakFireShot(struct mobj_s *actor);
void A_BrakLobShot(struct mobj_s *actor);
void A_NapalmScatter(struct mobj_s *actor);
void A_SpawnFreshCopy(struct mobj_s *actor);
void A_FlickySpawn(struct mobj_s *actor);
void A_FlickyCenter(struct mobj_s *actor);
void A_FlickyAim(struct mobj_s *actor);
void A_FlickyFly(struct mobj_s *actor);
void A_FlickySoar(struct mobj_s *actor);
void A_FlickyCoast(struct mobj_s *actor);
void A_FlickyHop(struct mobj_s *actor);
void A_FlickyFlounder(struct mobj_s *actor);
void A_FlickyCheck(struct mobj_s *actor);
void A_FlickyHeightCheck(struct mobj_s *actor);
void A_FlickyFlutter(struct mobj_s *actor);
void A_FlameParticle(struct mobj_s *actor);
void A_FadeOverlay(struct mobj_s *actor);
void A_Boss5Jump(struct mobj_s *actor);
void A_LightBeamReset(struct mobj_s *actor);
void A_MineExplode(struct mobj_s *actor);
void A_MineRange(struct mobj_s *actor);
void A_ConnectToGround(struct mobj_s *actor);
void A_SpawnParticleRelative(struct mobj_s *actor);
void A_MultiShotDist(struct mobj_s *actor);
void A_WhoCaresIfYourSonIsABee(struct mobj_s *actor);
void A_ParentTriesToSleep(struct mobj_s *actor);
void A_CryingToMomma(struct mobj_s *actor);
void A_CheckFlags2(struct mobj_s *actor);
void A_Boss5FindWaypoint(struct mobj_s *actor);
void A_DoNPCSkid(struct mobj_s *actor);
void A_DoNPCPain(struct mobj_s *actor);
void A_PrepareRepeat(struct mobj_s *actor);
void A_Boss5ExtraRepeat(struct mobj_s *actor);
void A_Boss5Calm(struct mobj_s *actor);
void A_Boss5CheckOnGround(struct mobj_s *actor);
void A_Boss5CheckFalling(struct mobj_s *actor);
void A_Boss5PinchShot(struct mobj_s *actor);
void A_Boss5MakeItRain(struct mobj_s *actor);
void A_Boss5MakeJunk(struct mobj_s *actor);
void A_LookForBetter(struct mobj_s *actor);
void A_Boss5BombExplode(struct mobj_s *actor);
void A_DustDevilThink(struct mobj_s *actor);
void A_TNTExplode(struct mobj_s *actor);
void A_DebrisRandom(struct mobj_s *actor);
void A_TrainCameo(struct mobj_s *actor);
void A_TrainCameo2(struct mobj_s *actor);
void A_CanarivoreGas(struct mobj_s *actor);
void A_KillSegments(struct mobj_s *actor);
void A_SnapperSpawn(struct mobj_s *actor);
void A_SnapperThinker(struct mobj_s *actor);
void A_SaloonDoorSpawn(struct mobj_s *actor);
void A_MinecartSparkThink(struct mobj_s *actor);
void A_ModuloToState(struct mobj_s *actor);
void A_LavafallRocks(struct mobj_s *actor);
void A_LavafallLava(struct mobj_s *actor);
void A_FallingLavaCheck(struct mobj_s *actor);
void A_FireShrink(struct mobj_s *actor);
void A_SpawnPterabytes(struct mobj_s *actor);
void A_PterabyteHover(struct mobj_s *actor);
void A_RolloutSpawn(struct mobj_s *actor);
void A_RolloutRock(struct mobj_s *actor);
void A_DragonbomberSpawn(struct mobj_s *actor);
void A_DragonWing(struct mobj_s *actor);
void A_DragonSegment(struct mobj_s *actor);
void A_ChangeHeight(struct mobj_s *actor);
extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION];
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 512
#define NUMMOBJFREESLOTS 1024
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
#define MAXSPRITENAME 64
// Hey, moron! If you change this table, don't forget about sprnames in info.c and the sprite lights in hw_light.c!
typedef enum sprite
......@@ -854,6 +857,8 @@ typedef enum sprite
SPR_XMS4, // Lamppost
SPR_XMS5, // Hanging Star
SPR_XMS6, // Mistletoe
SPR_SNTT, // Silver Shiver tree
SPR_SSTT, // Silver Shiver tree with snow
SPR_FHZI, // FHZ Ice
SPR_ROSY,
......@@ -887,6 +892,8 @@ typedef enum sprite
// Misc Scenery
SPR_STLG, // Stalagmites
SPR_DBAL, // Disco
SPR_GINE, // Crystalline Heights tree
SPR_PPAL, // Pristine Shores palm trees
// Powerup Indicators
SPR_ARMA, // Armageddon Shield Orb
......@@ -1073,14 +1080,14 @@ typedef enum sprite
SPR_GWLG,
SPR_GWLR,
// LJ Knuckles
SPR_OLDK,
SPR_FIRSTFREESLOT,
SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
NUMSPRITES
} spritenum_t;
// Make sure to be conscious of FF_FRAMEMASK and the fact sprite2 is stored as a UINT8 whenever you change this table.
// Currently, FF_FRAMEMASK is 0xff, or 255 - but the second half is used by FF_SPR2SUPER, so the limitation is 0x7f.
// Since this is zero-based, there can be at most 128 different SPR2_'s without changing that.
typedef enum playersprite
{
SPR2_STND = 0,
......@@ -1149,6 +1156,18 @@ typedef enum playersprite
SPR2_TALB,
SPR2_TALC,
// Misc slots
SPR2_MSC0,
SPR2_MSC1,
SPR2_MSC2,
SPR2_MSC3,
SPR2_MSC4,
SPR2_MSC5,
SPR2_MSC6,
SPR2_MSC7,
SPR2_MSC8,
SPR2_MSC9,
SPR2_CNT1, // continue disappointment
SPR2_CNT2, // continue lift
SPR2_CNT3, // continue spin
......@@ -1160,15 +1179,17 @@ typedef enum playersprite
SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?"
SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = 0x7f,
SPR2_LASTFREESLOT = 1024, // Do not make higher than SPR2F_MASK (currently 0x3FF) plus one
NUMPLAYERSPRITES
} playersprite_t;
// SPR2_XTRA
#define XTRA_LIFEPIC 0 // Life icon patch
#define XTRA_CHARSEL 1 // Character select picture
#define XTRA_CONTINUE 2 // Continue icon
#define XTRA_ENDING 3 // Ending finale patches
enum
{
XTRA_LIFEPIC,
XTRA_CHARSEL,
XTRA_CONTINUE,
XTRA_ENDING
};
typedef enum state
{
......@@ -1894,11 +1915,11 @@ typedef enum state
S_FANG_FIRE1,
S_FANG_FIRE2,
S_FANG_FIRE3,
S_FANG_FIRE4,
S_FANG_FIREREPEAT,
S_FANG_LOBSHOT0,
S_FANG_LOBSHOT1,
S_FANG_LOBSHOT2,
S_FANG_LOBSHOT3,
S_FANG_WAIT1,
S_FANG_WAIT2,
S_FANG_WALLHIT,
......@@ -1920,6 +1941,7 @@ typedef enum state
S_FANG_PINCHLOBSHOT2,
S_FANG_PINCHLOBSHOT3,
S_FANG_PINCHLOBSHOT4,
S_FANG_PINCHLOBSHOT5,
S_FANG_DIE1,
S_FANG_DIE2,
S_FANG_DIE3,
......@@ -3058,6 +3080,10 @@ typedef enum state
S_LAMPPOST2, // with snow
S_HANGSTAR,
S_MISTLETOE,
S_SSZTREE,
S_SSZTREE_BRANCH,
S_SSZTREE2,
S_SSZTREE2_BRANCH,
// Xmas GFZ bushes
S_XMASBLUEBERRYBUSH,
S_XMASBERRYBUSH,
......@@ -3065,11 +3091,9 @@ typedef enum state
// FHZ
S_FHZICE1,
S_FHZICE2,
S_ROSY_IDLE1,
S_ROSY_IDLE2,
S_ROSY_IDLE3,
S_ROSY_IDLE4,
S_ROSY_IDLE,
S_ROSY_JUMP,
S_ROSY_FALL,
S_ROSY_WALK,
S_ROSY_HUG,
S_ROSY_PAIN,
......@@ -3178,6 +3202,9 @@ typedef enum state
S_DBALL5,
S_DBALL6,
S_EGGSTATUE2,
S_GINE,
S_PPAL,
S_PPEL,
// Shield Orb
S_ARMA1,
......@@ -4062,6 +4089,7 @@ typedef enum state
S_MARIOBUSH2,
S_TOAD,
// Nights-specific stuff
S_NIGHTSDRONE_MAN1,
S_NIGHTSDRONE_MAN2,
......@@ -4366,6 +4394,12 @@ typedef enum state
S_NAMECHECK,
// LJ Knuckles
S_OLDK_STND,
S_OLDK_DIE0,
S_OLDK_DIE1,
S_OLDK_DIE2,
S_FIRSTFREESLOT,
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
NUMSTATES
......@@ -4380,11 +4414,12 @@ typedef struct
INT32 var1;
INT32 var2;
statenum_t nextstate;
UINT16 sprite2;
} state_t;
extern state_t states[NUMSTATES];
extern char sprnames[NUMSPRITES + 1][5];
extern char spr2names[NUMPLAYERSPRITES][5];
extern char sprnames[NUMSPRITES + 1][MAXSPRITENAME + 1];
extern char spr2names[NUMPLAYERSPRITES][MAXSPRITENAME + 1];
extern playersprite_t spr2defaults[NUMPLAYERSPRITES];
extern state_t *astate;
extern playersprite_t free_spr2;
......@@ -4856,6 +4891,10 @@ typedef enum mobj_type
MT_LAMPPOST2, // with snow
MT_HANGSTAR,
MT_MISTLETOE,
MT_SSZTREE,
MT_SSZTREE_BRANCH,
MT_SSZTREE2,
MT_SSZTREE2_BRANCH,
// Xmas GFZ bushes
MT_XMASBLUEBERRYBUSH,
MT_XMASBERRYBUSH,
......@@ -4935,6 +4974,9 @@ typedef enum mobj_type
// Misc scenery
MT_DBALL,
MT_EGGSTATUE2,
MT_GINE,
MT_PPAL,
MT_PPEL,
// Powerup Indicators
MT_ELEMENTAL_ORB, // Elemental shield mobj
......@@ -5163,6 +5205,8 @@ typedef enum mobj_type
MT_NAMECHECK,
MT_RAY, // General purpose mobj
MT_OLDK,
MT_FIRSTFREESLOT,
MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1,
NUMMOBJTYPES
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2025 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -44,6 +44,21 @@ return luaL_error(L, "HUD rendering code should not call this function!");\
else if (hook_cmd_running)\
return luaL_error(L, "CMD building code should not call this function!");
#define NOSPAWNNULL if (type >= NUMMOBJTYPES)\
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);\
else if (type == MT_NULL)\
{\
if (!nospawnnull_seen) {\
nospawnnull_seen = true;\
CONS_Alert(CONS_WARNING,"Spawning an \"MT_NULL\" mobj is deprecated and will be removed.\nUse \"MT_RAY\" instead.\n");\
}\
type = MT_RAY;\
}
static boolean nospawnnull_seen = false; // TODO: 2.3: Delete
// TODO: 2.3: Use the below NOSPAWNNULL define instead. P_SpawnMobj used to say "if MT_NULL, use MT_RAY instead", so the above define maintains Lua script compatibility until v2.3
/*#define NOSPAWNNULL if (type <= MT_NULL || type >= NUMMOBJTYPES)\
return luaL_error(L, "mobj type %d out of range (1 - %d)", type, NUMMOBJTYPES-1);*/
boolean luaL_checkboolean(lua_State *L, int narg) {
luaL_checktype(L, narg, LUA_TBOOLEAN);
return lua_toboolean(L, narg);
......@@ -169,8 +184,10 @@ static const struct {
{META_SKIN, "skin_t"},
{META_POWERS, "player_t.powers"},
{META_SOUNDSID, "skin_t.soundsid"},
{META_SKINSPRITES, "skin_t.sprites"},
{META_SKINSPRITESLIST, "skin_t.sprites[]"},
{META_SKINSPRITES, "skin_t.skinsprites"},
{META_SKINSPRITESLIST, "skin_t.skinsprites[]"},
{META_SKINSPRITESCOMPAT, "skin_t.sprites"}, // TODO: 2.3: Delete
{META_VERTEX, "vertex_t"},
{META_LINE, "line_t"},
......@@ -221,7 +238,10 @@ static const struct {
{META_LUABANKS, "luabanks[]"},
{META_KEYEVENT, "keyevent_t"},
{META_TEXTEVENT, "textevent_t"},
{META_MOUSE, "mouse_t"},
{META_INTERCEPT, "intercept_t"},
{NULL, NULL}
};
......@@ -330,6 +350,18 @@ static int lib_reserveLuabanks(lua_State *L)
return 1;
}
static int lib_tofixed(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
char *end;
float f = strtof(arg, &end);
if (*end != '\0')
lua_pushnil(L);
else
lua_pushnumber(L, FLOAT_TO_FIXED(f));
return 1;
}
// M_MENU
//////////////
......@@ -625,9 +657,8 @@ static int lib_pSpawnMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 4);
NOHUD
INLEVEL
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
NOSPAWNNULL
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ);
return 1;
}
......@@ -640,10 +671,9 @@ static int lib_pSpawnMobjFromMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 5);
NOHUD
INLEVEL
NOSPAWNNULL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ);
return 1;
}
......@@ -661,17 +691,15 @@ static int lib_pRemoveMobj(lua_State *L)
return 0;
}
// P_IsValidSprite2 technically doesn't exist, and probably never should... but too much would need to be exposed to allow this to be checked by other methods.
static int lib_pIsValidSprite2(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
UINT8 spr2 = (UINT8)luaL_checkinteger(L, 2);
UINT16 spr2 = (UINT16)luaL_checkinteger(L, 2);
//HUDSAFE
INLEVEL
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes)));
lua_pushboolean(L, mobj->skin && P_IsValidSprite2(mobj->skin, spr2));
return 1;
}
......@@ -708,10 +736,9 @@ static int lib_pSpawnMissile(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 3);
NOHUD
INLEVEL
NOSPAWNNULL
if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ);
return 1;
}
......@@ -726,10 +753,9 @@ static int lib_pSpawnXYZMissile(lua_State *L)
fixed_t z = luaL_checkfixed(L, 6);
NOHUD
INLEVEL
NOSPAWNNULL
if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ);
return 1;
}
......@@ -746,10 +772,9 @@ static int lib_pSpawnPointMissile(lua_State *L)
fixed_t z = luaL_checkfixed(L, 8);
NOHUD
INLEVEL
NOSPAWNNULL
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ);
return 1;
}
......@@ -764,10 +789,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L)
INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5);
NOHUD
INLEVEL
NOSPAWNNULL
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ);
return 1;
}
......@@ -795,10 +819,9 @@ static int lib_pSPMAngle(lua_State *L)
UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0);
NOHUD
INLEVEL
NOSPAWNNULL
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ);
return 1;
}
......@@ -810,10 +833,9 @@ static int lib_pSpawnPlayerMissile(lua_State *L)
UINT32 flags2 = (UINT32)luaL_optinteger(L, 3, 0);
NOHUD
INLEVEL
NOSPAWNNULL
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ);
return 1;
}
......@@ -844,8 +866,7 @@ static int lib_pWeaponOrPanel(lua_State *L)
{
mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
NOSPAWNNULL
lua_pushboolean(L, P_WeaponOrPanel(type));
return 1;
}
......@@ -888,8 +909,7 @@ static int lib_pSpawnParaloop(lua_State *L)
boolean spawncenter = lua_optboolean(L, 9);
NOHUD
INLEVEL
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
NOSPAWNNULL
if (nstate >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1);
P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter);
......@@ -924,13 +944,14 @@ static int lib_pSetScale(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t newscale = luaL_checkfixed(L, 2);
boolean instant = lua_optboolean(L, 3);
NOHUD
INLEVEL
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
if (newscale < FRACUNIT/100)
newscale = FRACUNIT/100;
P_SetScale(mobj, newscale);
P_SetScale(mobj, newscale, instant);
return 0;
}
......@@ -1712,12 +1733,11 @@ static int lib_pResetCamera(lua_State *L)
static int lib_pSuperReady(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean transform = (boolean)lua_opttrueboolean(L, 2);
//HUDSAFE
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushboolean(L, P_SuperReady(player, transform));
lua_pushboolean(L, P_SuperReady(player));
return 1;
}
......@@ -1762,10 +1782,9 @@ static int lib_pSpawnSpinMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 2);
NOHUD
INLEVEL
NOSPAWNNULL
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
P_SpawnSpinMobj(player, type);
return 0;
}
......@@ -1971,7 +1990,7 @@ static int lib_pLineIsBlocking(lua_State *L)
return LUA_ErrInvalid(L, "mobj_t");
if (!line)
return LUA_ErrInvalid(L, "line_t");
// P_LineOpening in P_LineIsBlocking sets these variables.
// We want to keep their old values after so that whatever
// map collision code uses them doesn't get messed up.
......@@ -1984,9 +2003,9 @@ static int lib_pLineIsBlocking(lua_State *L)
pslope_t *oldopenbottomslope = openbottomslope;
ffloor_t *oldopenfloorrover = openfloorrover;
ffloor_t *oldopenceilingrover = openceilingrover;
lua_pushboolean(L, P_LineIsBlocking(mo, line));
opentop = oldopentop;
openbottom = oldopenbottom;
openrange = oldopenrange;
......@@ -1996,7 +2015,7 @@ static int lib_pLineIsBlocking(lua_State *L)
openbottomslope = oldopenbottomslope;
openfloorrover = oldopenfloorrover;
openceilingrover = oldopenceilingrover;
return 1;
}
......@@ -2497,6 +2516,17 @@ static int lib_pDoSuperTransformation(lua_State *L)
return 0;
}
static int lib_pDoSuperDetransformation(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
P_DoSuperDetransformation(player);
return 0;
}
static int lib_pExplodeMissile(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
......@@ -2711,12 +2741,11 @@ static int lib_pFadeLight(lua_State *L)
static int lib_pIsFlagAtBase(lua_State *L)
{
mobjtype_t flag = luaL_checkinteger(L, 1);
mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE
INLEVEL
if (flag >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1);
lua_pushboolean(L, P_IsFlagAtBase(flag));
NOSPAWNNULL
lua_pushboolean(L, P_IsFlagAtBase(type));
return 1;
}
......@@ -3017,6 +3046,9 @@ static int lib_rFrame2Char(lua_State *L)
//HUDSAFE
c[0] = R_Frame2Char(ch);
if (c[0] == '\xFF')
return luaL_error(L, "frame %u cannot be represented by a character", ch);
c[1] = 0;
lua_pushstring(L, c);
......@@ -3024,6 +3056,9 @@ static int lib_rFrame2Char(lua_State *L)
return 2;
}
// R_SKINS
////////////
// R_SetPlayerSkin technically doesn't exist either, although it's basically just SetPlayerSkin and SetPlayerSkinByNum handled in one place for convenience
static int lib_rSetPlayerSkin(lua_State *L)
{
......@@ -3086,6 +3121,47 @@ static int lib_rSkinUsable(lua_State *L)
return 1;
}
static int lib_pGetStateSprite2(lua_State *L)
{
int statenum = luaL_checkinteger(L, 1);
if (statenum < 0 || statenum >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", statenum, NUMSTATES-1);
lua_pushinteger(L, P_GetStateSprite2(&states[statenum]));
return 1;
}
static int lib_pGetSprite2StateFrame(lua_State *L)
{
int statenum = luaL_checkinteger(L, 1);
if (statenum < 0 || statenum >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", statenum, NUMSTATES-1);
lua_pushinteger(L, P_GetSprite2StateFrame(&states[statenum]));
return 1;
}
static int lib_pIsStateSprite2Super(lua_State *L)
{
int statenum = luaL_checkinteger(L, 1);
if (statenum < 0 || statenum >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", statenum, NUMSTATES-1);
lua_pushboolean(L, P_IsStateSprite2Super(&states[statenum]));
return 1;
}
// Not a real function. Who cares? I know I don't.
static int lib_pGetSuperSprite2(lua_State *L)
{
int animID = luaL_checkinteger(L, 1) & SPR2F_MASK;
if (animID < 0 || animID >= NUMPLAYERSPRITES)
return luaL_error(L, "sprite2 %d out of range (0 - %d)", animID, NUMPLAYERSPRITES-1);
lua_pushinteger(L, animID | SPR2F_SUPER);
return 1;
}
// R_DATA
////////////
......@@ -3093,7 +3169,10 @@ static int lib_rCheckTextureNumForName(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
//HUDSAFE
lua_pushinteger(L, R_CheckTextureNumForName(name));
INT32 num = R_CheckTextureNumForName(name, TEXTURETYPE_TEXTURE);
if (num == -1)
num = R_CheckTextureNumForName(name, TEXTURETYPE_FLAT);
lua_pushinteger(L, num);
return 1;
}
......@@ -3107,17 +3186,25 @@ static int lib_rTextureNumForName(lua_State *L)
static int lib_rCheckTextureNameForNum(lua_State *L)
{
char s[9];
INT32 num = (INT32)luaL_checkinteger(L, 1);
//HUDSAFE
lua_pushstring(L, R_CheckTextureNameForNum(num));
M_Memcpy(s, R_CheckTextureNameForNum(num), 8);
s[8] = '\0';
lua_pushstring(L, s);
return 1;
}
static int lib_rTextureNameForNum(lua_State *L)
{
char s[9];
INT32 num = (INT32)luaL_checkinteger(L, 1);
//HUDSAFE
lua_pushstring(L, R_TextureNameForNum(num));
M_Memcpy(s, R_TextureNameForNum(num), 8);
s[8] = '\0';
lua_pushstring(L, s);
return 1;
}
......@@ -3804,7 +3891,7 @@ static int lib_gAddPlayer(lua_State *L)
player_t *newplayer;
SINT8 skinnum = 0, bot;
for (i = 0; i < MAXPLAYERS; i++)
for (i = 1; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
break;
......@@ -4273,6 +4360,7 @@ static luaL_Reg lib[] = {
{"userdataMetatable", lib_userdataMetatable},
{"IsPlayerAdmin", lib_isPlayerAdmin},
{"reserveLuabanks", lib_reserveLuabanks},
{"tofixed", lib_tofixed},
// m_menu
{"M_MoveColorAfter",lib_pMoveColorAfter},
......@@ -4450,6 +4538,7 @@ static luaL_Reg lib[] = {
{"P_VectorInstaThrust",lib_pVectorInstaThrust},
{"P_SetMobjStateNF",lib_pSetMobjStateNF},
{"P_DoSuperTransformation",lib_pDoSuperTransformation},
{"P_DoSuperDetransformation",lib_pDoSuperDetransformation},
{"P_ExplodeMissile",lib_pExplodeMissile},
{"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial},
{"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor},
......@@ -4490,7 +4579,13 @@ static luaL_Reg lib[] = {
{"R_Char2Frame",lib_rChar2Frame},
{"R_Frame2Char",lib_rFrame2Char},
{"R_SetPlayerSkin",lib_rSetPlayerSkin},
// r_skins
{"R_SkinUsable",lib_rSkinUsable},
{"P_GetStateSprite2",lib_pGetStateSprite2},
{"P_GetSprite2StateFrame",lib_pGetSprite2StateFrame},
{"P_IsStateSprite2Super",lib_pIsStateSprite2Super},
{"P_GetSuperSprite2",lib_pGetSuperSprite2},
// r_data
{"R_CheckTextureNumForName",lib_rCheckTextureNumForName},
......
......@@ -254,11 +254,10 @@ static int lib_searchBlockmap(lua_State *L)
}
else // mobj and function only - search around mobj's radius by default
{
fixed_t radius = mobj->radius + MAXRADIUS;
x1 = mobj->x - radius;
x2 = mobj->x + radius;
y1 = mobj->y - radius;
y2 = mobj->y + radius;
x1 = mobj->x - mobj->radius;
x2 = mobj->x + mobj->radius;
y1 = mobj->y - mobj->radius;
y2 = mobj->y + mobj->radius;
}
lua_settop(L, 2); // pop everything except function, mobj
......@@ -312,17 +311,12 @@ static int lib_searchBlockmap(lua_State *L)
continue; // our thing just found itself, so move on
funcret = lib_searchBlockmap_Objects(L, mobj, itmobj);
if (funcret == 2) {
lua_pushboolean(L, false);
return 1;
}
else if (funcret == 1)
retval = false;
if (P_MobjWasRemoved(mobj)) {
if (funcret == 2 || P_MobjWasRemoved(mobj)) {
retval = false;
break;
}
else if (funcret == 1)
retval = false;
}
}
while (itmobj != NULL);
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2021-2022 by "Lactozilla".
// Copyright (C) 2014-2023 by Sonic Team Junior.
// Copyright (C) 2021-2024 by Lactozilla.
// Copyright (C) 2014-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -593,7 +593,7 @@ static int extracolormap_set(lua_State *L)
|| exc->fadergba != old_fade_rgba
|| exc->fadestart != old_fade_start
|| exc->fadeend != old_fade_end)
R_GenerateLightTable(exc, true);
R_UpdateLightTable(exc, true);
return 0;
}
......
......@@ -31,11 +31,27 @@ return luaL_error(L, "HUD rendering code should not call this function!");
static consvar_t *this_cvar;
static void clear_lua_stack(void)
{
if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18
lua_settop(gL, 0); // clear stack
}
void Got_Luacmd(UINT8 **cp, INT32 playernum)
{
UINT8 i, argc, flags;
const char *argv[256];
char buf[256];
argc = READUINT8(*cp);
argv[0] = (const char*)*cp;
SKIPSTRINGN(*cp, 255);
for (i = 1; i < argc; i++)
{
argv[i] = (const char*)*cp;
SKIPSTRINGN(*cp, 255);
}
// don't use I_Assert here, goto the deny code below
// to clean up and kick people who try nefarious exploits
// like sending random junk lua commands to crash the server
......@@ -48,8 +64,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command
if (!lua_istable(gL, -1)) goto deny;
argc = READUINT8(*cp);
READSTRINGN(*cp, buf, 255);
strlcpy(buf, argv[0], 255);
strlwr(buf); // must lowercase buffer
lua_getfield(gL, -1, buf); // push command info table
if (!lua_istable(gL, -1)) goto deny;
......@@ -75,10 +90,17 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
lua_remove(gL, -2); // pop command info table
if (!lua_checkstack(gL, argc)) // player + command arguments
{
clear_lua_stack();
CONS_Alert(CONS_WARNING, "lua command stack overflow from %s (%d, need %d more)\n", player_names[playernum], lua_gettop(gL), argc);
return;
}
LUA_PushUserdata(gL, &players[playernum], META_PLAYER);
for (i = 1; i < argc; i++)
{
READSTRINGN(*cp, buf, 255);
strlcpy(buf, argv[i], 255);
lua_pushstring(gL, buf);
}
LUA_Call(gL, (int)argc, 0, 1); // argc is 1-based, so this will cover the player we passed too.
......@@ -86,8 +108,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
deny:
//must be hacked/buggy client
if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18
lua_settop(gL, 0); // clear stack
clear_lua_stack();
CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
if (server)
......@@ -173,6 +194,11 @@ void COM_Lua_f(void)
I_Assert(lua_isfunction(gL, -1));
lua_remove(gL, -2); // pop command info table
if (!lua_checkstack(gL, COM_Argc() + 1))
{
CONS_Alert(CONS_WARNING, "lua command stack overflow (%d, need %s more)\n", lua_gettop(gL), sizeu1(COM_Argc() + 1));
return;
}
LUA_PushUserdata(gL, &players[playernum], META_PLAYER);
for (i = 1; i < COM_Argc(); i++)
lua_pushstring(gL, COM_Argv(i));
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -67,13 +67,17 @@ automatically.
X (ViewpointSwitch),/* spy mode (no trickstabs) */\
X (SeenPlayer),/* MT_NAMECHECK */\
X (PlayerThink),/* P_PlayerThink */\
X (GameStart),\
X (GameQuit),\
X (GameEnd),\
X (PlayerCmd),/* building the player's ticcmd struct (Ported from SRB2Kart) */\
X (MusicChange),\
X (PlayerHeight),/* override player height */\
X (PlayerCanEnterSpinGaps),\
X (AddonLoaded),\
X (KeyDown),\
X (KeyUp),\
X (TextInput),\
#define STRING_HOOK_LIST(X) \
X (BotAI),/* B_BuildTailsTiccmd by skin name */\
......@@ -86,6 +90,8 @@ automatically.
X (title),/* titlescreen */\
X (titlecard),\
X (intermission),\
X (continue),\
X (playersetup),\
/*
I chose to access the hook enums through a macro as well. This could provide
......@@ -117,6 +123,13 @@ extern boolean hook_cmd_running;
void LUA_HookVoid(int hook);
void LUA_HookHUD(int hook, huddrawlist_h drawlist);
int LUA_HookCharacterHUD
(
int hook, huddrawlist_h drawlist, player_t *player,
fixed_t x, fixed_t y, fixed_t scale,
INT32 skinIndex, UINT8 sprite2, UINT8 frame, UINT8 rotation, skincolornum_t color,
INT32 ticker, boolean mode
);
int LUA_HookMobj(mobj_t *, int hook);
int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook);
......@@ -125,6 +138,7 @@ void LUA_HookBool(boolean value, int hook);
int LUA_HookPlayer(player_t *, int hook);
int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook);
int LUA_HookKey(event_t *event, int hook); // Hooks for key events
int LUA_HookText(event_t *event, int hook); // Hooks for text events
void LUA_HookPreThinkFrame(void);
void LUA_HookThinkFrame(void);
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -375,6 +375,17 @@ static boolean prepare_string_hook
return false;
}
static boolean prepare_hud_hook
(
Hook_State * hook,
int default_status,
int hook_type
){
return init_hook_type(hook, default_status,
hook_type, 0, NULL,
hudHookIds[hook_type].numHooks);
}
static void init_hook_call
(
Hook_State * hook,
......@@ -487,7 +498,40 @@ static int call_string_hooks(Hook_State *hook)
static int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
{
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
int numCalls = call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
if (numCalls > 0 && mobj_type == MT_NULL && (
hook->hook_type == MOBJ_HOOK(MobjThinker )
|| hook->hook_type == MOBJ_HOOK(MobjCollide )
|| hook->hook_type == MOBJ_HOOK(MobjLineCollide)
|| hook->hook_type == MOBJ_HOOK(MobjMoveCollide)
|| hook->hook_type == MOBJ_HOOK(MobjFuse )
|| hook->hook_type == MOBJ_HOOK(MobjThinker )
|| hook->hook_type == MOBJ_HOOK(BossThinker )
|| hook->hook_type == MOBJ_HOOK(MobjMoveBlocked)
|| hook->hook_type == MOBJ_HOOK(FollowMobj )
))
LUA_UsageWarning(L, va(
"%s hooks not attached to a specific mobj type are deprecated and will be removed.",
mobjHookNames[hook->hook_type])
);
return numCalls;
}
static void call_hud_hooks
(
Hook_State * hook,
int results,
Hook_Callback results_handler
){
hud_running = true; // local hook
init_hook_call(hook, results, results_handler);
call_mapped(hook, &hudHookIds[hook->hook_type]);
hud_running = false;
lua_pushnil(gL);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
}
static int call_hooks
......@@ -646,25 +690,52 @@ int LUA_HookKey(event_t *event, int hook_type)
return hook.status;
}
void LUA_HookHUD(int hook_type, huddrawlist_h list)
int LUA_HookText(event_t *event, int hook_type)
{
const hook_t * map = &hudHookIds[hook_type];
Hook_State hook;
if (map->numHooks > 0)
if (prepare_hook(&hook, false, hook_type))
{
start_hook_stack();
begin_hook_values(&hook);
LUA_PushUserdata(gL, event, META_TEXTEVENT);
call_hooks(&hook, 1, res_true);
}
return hook.status;
}
void LUA_HookHUD(int hook_type, huddrawlist_h list)
{
Hook_State hook;
if (prepare_hud_hook(&hook, 0, hook_type))
{
LUA_SetHudHook(hook_type, list);
call_hud_hooks(&hook, 0, res_none);
}
}
hud_running = true; // local hook
init_hook_call(&hook, 0, res_none);
call_mapped(&hook, map);
hud_running = false;
lua_pushnil(gL);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
int LUA_HookCharacterHUD
(
int hook_type, huddrawlist_h list, player_t *player,
fixed_t x, fixed_t y, fixed_t scale,
INT32 skinIndex, UINT8 sprite2, UINT8 frame, UINT8 rotation, skincolornum_t color,
INT32 ticker, boolean mode
){
Hook_State hook;
if (prepare_hud_hook(&hook, false, hook_type))
{
LUA_SetHudHook(hook_type, list);
LUA_PushUserdata(gL, player, META_PLAYER);
lua_pushfixed(gL, x);
lua_pushfixed(gL, y);
lua_pushfixed(gL, scale);
lua_pushstring(gL, skins[skinIndex]->name);
lua_pushinteger(gL, sprite2);
lua_pushinteger(gL, frame);
lua_pushinteger(gL, rotation);
lua_pushinteger(gL, color);
lua_pushinteger(gL, ticker);
lua_pushboolean(gL, mode);
call_hud_hooks(&hook, 1, res_true);
}
return hook.status;
}
/* =========================================================================
......@@ -709,7 +780,7 @@ static void hook_think_frame(int type)
PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src);
else if (type == 6)
PS_SetPostThinkFrameHookInfo(hook_index, time_taken, ar.short_src);
hook_index++;
}
}
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2014-2016 by John "JTE" Muniz.
// Copyright (C) 2014-2023 by Sonic Team Junior.
// Copyright (C) 2014-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -19,15 +19,22 @@ enum hud {
hud_stagetitle = 0,
hud_textspectator,
hud_crosshair,
hud_powerups,
hud_gameover,
hud_pause,
hud_cecho,
hud_chat,
// Singleplayer / Co-op
hud_score,
hud_time,
hud_rings,
hud_lives,
hud_input,
// Match / CTF / Tag / Ringslinger
hud_weaponrings,
hud_powerstones,
hud_teamscores,
hud_itemhunt,
// NiGHTS mode
hud_nightslink,
hud_nightsdrill,
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2014-2016 by John "JTE" Muniz.
// Copyright (C) 2014-2023 by Sonic Team Junior.
// Copyright (C) 2014-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -41,15 +41,22 @@ static const char *const hud_disable_options[] = {
"stagetitle",
"textspectator",
"crosshair",
"powerups",
"gameover",
"pause",
"cecho",
"chat",
"score",
"time",
"rings",
"lives",
"input",
"weaponrings",
"powerstones",
"teamscores",
"itemhunt",
"nightslink",
"nightsdrill",
......@@ -69,6 +76,10 @@ static const char *const hud_disable_options[] = {
"intermissionemeralds",
NULL};
// you know, let's actually make sure that the table is synced.
// because fuck knows how many times this has happened at this point. :v
I_StaticAssert(sizeof(hud_disable_options) / sizeof(*hud_disable_options) == hud_MAX+1);
enum hudinfo {
hudinfo_x = 0,
hudinfo_y,
......@@ -455,15 +466,29 @@ static int camera_set(lua_State *L)
static int libd_patchExists(lua_State *L)
{
HUDONLY
lua_pushboolean(L, W_LumpExists(luaL_checkstring(L, 1)));
return 1;
}
static int libd_cachePatch(lua_State *L)
{
HUDONLY
LUA_PushUserdata(L, W_CachePatchLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH);
const char *name = luaL_checkstring(L, 1);
patch_t *patch = W_CachePatchLongName(name, PU_PATCH);
#ifdef ROTSPRITE
if (lua_isnumber(L, 2))
{
angle_t rollangle = luaL_checkangle(L, 2);
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
patch_t *rotpatch = Patch_GetRotated(patch, rot, false);
LUA_PushUserdata(L, rotpatch, META_PATCH);
return 1;
}
}
#endif
LUA_PushUserdata(L, patch, META_PATCH);
return 1;
}
......@@ -475,7 +500,6 @@ static int libd_getSpritePatch(lua_State *L)
UINT8 angle = 0;
spritedef_t *sprdef;
spriteframe_t *sprframe;
HUDONLY
if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR_THOK
{
......@@ -486,9 +510,7 @@ static int libd_getSpritePatch(lua_State *L)
else if (lua_isstring(L, 1)) // sprite prefix name given, e.g. "THOK"
{
const char *name = lua_tostring(L, 1);
for (i = 0; i < NUMSPRITES; i++)
if (fastcmp(name, sprnames[i]))
break;
i = R_GetSpriteNumByName(name);
if (i >= NUMSPRITES)
return 0;
}
......@@ -550,8 +572,7 @@ static int libd_getSprite2Patch(lua_State *L)
UINT8 angle = 0;
spritedef_t *sprdef;
spriteframe_t *sprframe;
boolean super = false; // add FF_SPR2SUPER to sprite2 if true
HUDONLY
boolean super = false; // add SPR2F_SUPER to sprite2 if true
// get skin first!
if (lua_isnumber(L, 1)) // find skin by number
......@@ -577,11 +598,12 @@ static int libd_getSprite2Patch(lua_State *L)
if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR2_STND
{
j = lua_tonumber(L, 1);
if (j & FF_SPR2SUPER) // e.g. SPR2_STND|FF_SPR2SUPER
if (j & SPR2F_SUPER) // e.g. SPR2_STND|SPR2F_SUPER
{
super = true;
j &= ~FF_SPR2SUPER; // remove flag so the next check doesn't fail
j &= ~SPR2F_SUPER; // remove flag so the next check doesn't fail
}
if (j >= free_spr2)
return 0;
}
......@@ -600,17 +622,19 @@ static int libd_getSprite2Patch(lua_State *L)
if (lua_isboolean(L, 2)) // optional boolean for superness
{
super = lua_toboolean(L, 2); // note: this can override FF_SPR2SUPER from sprite number
super = lua_toboolean(L, 2); // note: this can override SPR2F_SUPER from sprite number
lua_remove(L, 2); // remove
}
// if it's not boolean then just assume it's the frame number
if (super)
j |= FF_SPR2SUPER;
j |= SPR2F_SUPER;
j = P_GetSkinSprite2(skins[i], j, NULL); // feed skin and current sprite2 through to change sprite2 used if necessary
// If there is no "super" variation of this sprite, try with the normal one.
if (!P_IsValidSprite2(skins[i], j))
j &= ~SPR2F_SUPER;
sprdef = &skins[i]->sprites[j];
sprdef = P_GetSkinSpritedef(skins[i], j);
// set frame number
frame = luaL_optinteger(L, 2, 0);
......@@ -638,7 +662,7 @@ static int libd_getSprite2Patch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), &skins[i]->sprinfo[j], rot);
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), P_GetSkinSpriteInfo(skins[i], j), rot);
LUA_PushUserdata(L, rotsprite, META_PATCH);
lua_pushboolean(L, false);
lua_pushboolean(L, true);
......@@ -1123,13 +1147,12 @@ static int libd_levelTitleHeight(lua_State *L)
static int libd_getColormap(lua_State *L)
{
HUDONLY
INT32 skinnum = TC_DEFAULT;
skincolornum_t color = luaL_optinteger(L, 2, 0);
UINT8* colormap = NULL;
int translation_id = -1;
HUDONLY
if (lua_isnoneornil(L, 1))
; // defaults to TC_DEFAULT
else if (lua_type(L, 1) == LUA_TNUMBER) // skin number
......@@ -1169,9 +1192,10 @@ static int libd_getColormap(lua_State *L)
static int libd_getStringColormap(lua_State *L)
{
HUDONLY
INT32 flags = luaL_checkinteger(L, 1);
UINT8* colormap = NULL;
HUDONLY
colormap = V_GetStringColormap(flags & V_CHARCOLORMASK);
if (colormap) {
LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use!
......@@ -1182,6 +1206,7 @@ static int libd_getStringColormap(lua_State *L)
static int libd_getSectorColormap(lua_State *L)
{
HUDONLY
boolean has_sector = false;
sector_t *sector = NULL;
if (!lua_isnoneornil(L, 1))
......@@ -1257,21 +1282,18 @@ static int libd_fadeScreen(lua_State *L)
static int libd_width(lua_State *L)
{
HUDONLY
lua_pushinteger(L, vid.width); // push screen width
return 1;
}
static int libd_height(lua_State *L)
{
HUDONLY
lua_pushinteger(L, vid.height); // push screen height
return 1;
}
static int libd_dup(lua_State *L)
{
HUDONLY
lua_pushinteger(L, vid.dup); // push integral scale (patch scale)
lua_pushfixed(L, vid.fdup); // push fixed point scale (position scale)
return 2;
......@@ -1279,7 +1301,6 @@ static int libd_dup(lua_State *L)
static int libd_renderer(lua_State *L)
{
HUDONLY
switch (rendermode) {
case render_opengl: lua_pushliteral(L, "opengl"); break; // OpenGL renderer
case render_soft: lua_pushliteral(L, "software"); break; // Software renderer
......@@ -1293,14 +1314,12 @@ static int libd_renderer(lua_State *L)
static int libd_RandomFixed(lua_State *L)
{
HUDONLY
lua_pushfixed(L, M_RandomFixed());
return 1;
}
static int libd_RandomByte(lua_State *L)
{
HUDONLY
lua_pushinteger(L, M_RandomByte());
return 1;
}
......@@ -1309,7 +1328,6 @@ static int libd_RandomKey(lua_State *L)
{
INT32 a = (INT32)luaL_checkinteger(L, 1);
HUDONLY
lua_pushinteger(L, M_RandomKey(a));
return 1;
}
......@@ -1319,7 +1337,6 @@ static int libd_RandomRange(lua_State *L)
INT32 a = (INT32)luaL_checkinteger(L, 1);
INT32 b = (INT32)luaL_checkinteger(L, 2);
HUDONLY
lua_pushinteger(L, M_RandomRange(a, b));
return 1;
}
......@@ -1327,7 +1344,6 @@ static int libd_RandomRange(lua_State *L)
// Macros.
static int libd_SignedRandom(lua_State *L)
{
HUDONLY
lua_pushinteger(L, M_SignedRandom());
return 1;
}
......@@ -1335,7 +1351,6 @@ static int libd_SignedRandom(lua_State *L)
static int libd_RandomChance(lua_State *L)
{
fixed_t p = luaL_checkfixed(L, 1);
HUDONLY
lua_pushboolean(L, M_RandomChance(p));
return 1;
}
......@@ -1344,7 +1359,6 @@ static int libd_RandomChance(lua_State *L)
// Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn
static int libd_getlocaltransflag(lua_State *L)
{
HUDONLY
lua_pushinteger(L, (10-st_translucency)*V_10TRANS);
return 1;
}
......@@ -1352,7 +1366,6 @@ static int libd_getlocaltransflag(lua_State *L)
// Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
static int libd_getusertransflag(lua_State *L)
{
HUDONLY
lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V
return 1;
}
......@@ -1445,6 +1458,26 @@ static luaL_Reg lib_hud[] = {
{"disable", lib_huddisable},
{"enabled", lib_hudenabled},
{"add", lib_hudadd},
{"patchExists", libd_patchExists},
{"cachePatch", libd_cachePatch},
{"getSpritePatch", libd_getSpritePatch},
{"getSprite2Patch", libd_getSprite2Patch},
{"width", libd_width},
{"height", libd_height},
{"scale", libd_dup},
{"renderer", libd_renderer},
{NULL, NULL}
};
// globalized client_side random functions.
static luaL_Reg lib_randomclient[] = {
// m_random
{"localFixed",libd_RandomFixed},
{"localByte",libd_RandomByte},
{"localKey",libd_RandomKey},
{"localRange",libd_RandomRange},
{"localSignedRandom",libd_SignedRandom}, // MACRO
{"localChance",libd_RandomChance}, // MACRO
{NULL, NULL}
};
......@@ -1471,6 +1504,7 @@ int LUA_HudLib(lua_State *L)
LUA_RegisterGlobalUserdata(L, "hudinfo", lib_getHudInfo, NULL, lib_hudinfolen);
luaL_register(L, "hud", lib_hud);
luaL_register(L, "random", lib_randomclient);
return 0;
}
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2014-2016 by John "JTE" Muniz.
// Copyright (C) 2014-2023 by Sonic Team Junior.
// Copyright (C) 2014-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -180,7 +180,8 @@ static const char *CopyString(huddrawlist_h list, const char* str)
const char *old_offset = list->strbuf;
size_t i;
if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
else list->strbuf_capacity *= 2;
while (list->strbuf_capacity <= list->strbuf_len + lenstr + 1)
list->strbuf_capacity *= 2;
list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL);
// align the string pointers to make sure old pointers don't point towards invalid addresses
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -88,12 +88,12 @@ static int lib_getSprname(lua_State *L)
else if (lua_isstring(L, 1))
{
const char *name = lua_tostring(L, 1);
for (i = 0; i < NUMSPRITES; i++)
if (fastcmp(name, sprnames[i]))
{
lua_pushinteger(L, i);
return 1;
}
i = R_GetSpriteNumByName(name);
if (i != NUMSPRITES)
{
lua_pushinteger(L, i);
return 1;
}
}
return 0;
}
......@@ -165,7 +165,7 @@ static int lib_getSpr2default(lua_State *L)
static int lib_setSpr2default(lua_State *L)
{
playersprite_t i;
UINT8 j = 0;
UINT16 j = 0;
if (hud_running)
return luaL_error(L, "Do not alter spr2defaults[] in HUD rendering code!");
......@@ -242,25 +242,13 @@ static int lib_getSpriteInfo(lua_State *L)
UINT32 i = NUMSPRITES;
lua_remove(L, 1);
if (lua_isstring(L, 1))
if (lua_type(L, 1) == LUA_TSTRING)
{
const char *name = lua_tostring(L, 1);
INT32 spr;
for (spr = 0; spr < NUMSPRITES; spr++)
{
if (fastcmp(name, sprnames[spr]))
{
i = spr;
break;
}
}
if (i == NUMSPRITES)
{
char *check;
i = strtol(name, &check, 10);
if (check == name || *check != '\0')
return luaL_error(L, "unknown sprite name %s", name);
}
INT32 spr = R_GetSpriteNumByName(name);
if (spr == NUMSPRITES)
return luaL_error(L, "unknown sprite name %s", name);
i = spr;
}
else
i = luaL_checkinteger(L, 1);
......@@ -359,8 +347,8 @@ static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk)
default:
TYPEERROR("pivot frame", LUA_TNUMBER, lua_type(L, stk+1));
}
if ((idx < 0) || (idx >= 64))
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, 63);
if ((idx < 0) || (idx >= MAXFRAMENUM))
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, MAXFRAMENUM - 1);
// the values in pivot[] are also tables
if (PopPivotSubTable(info->pivot, L, stk+2, idx))
info->available = true;
......@@ -555,7 +543,7 @@ static int pivotlist_set(lua_State *L)
static int pivotlist_num(lua_State *L)
{
lua_pushinteger(L, 64);
lua_pushinteger(L, MAXFRAMENUM);
return 1;
}
......@@ -1170,6 +1158,7 @@ enum mobjinfo_e
mobjinfo_activesound,
mobjinfo_flags,
mobjinfo_raisestate,
mobjinfo_name,
};
const char *const mobjinfo_opt[] = {
......@@ -1197,6 +1186,7 @@ const char *const mobjinfo_opt[] = {
"activesound",
"flags",
"raisestate",
"name",
NULL,
};
......@@ -1211,6 +1201,8 @@ static int mobjinfo_get(lua_State *L)
I_Assert(info != NULL);
I_Assert(info >= mobjinfo);
mobjtype_t id = info-mobjinfo;
switch (field)
{
case mobjinfo_doomednum:
......@@ -1285,6 +1277,21 @@ static int mobjinfo_get(lua_State *L)
case mobjinfo_raisestate:
lua_pushinteger(L, info->raisestate);
break;
case mobjinfo_name:
if (id < MT_FIRSTFREESLOT)
{
lua_pushstring(L, MOBJTYPE_LIST[id]+3);
return 1;
}
id -= MT_FIRSTFREESLOT;
if (id < NUMMOBJFREESLOTS && FREE_MOBJS[id])
{
lua_pushstring(L, FREE_MOBJS[id]);
return 1;
}
return 0;
default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));
......@@ -1747,7 +1754,7 @@ static int lib_setSkinColor(lua_State *L)
else if (i == 6 || (str && fastcmp(str,"accessible"))) {
boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum);
else
info->accessible = v;
}
......@@ -1842,7 +1849,7 @@ static int skincolor_set(lua_State *L)
else if (fastcmp(field,"accessible")) {
boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum);
else
info->accessible = v;
} else
......
......@@ -10,16 +10,19 @@
/// \brief input library for Lua scripting
#include "doomdef.h"
#include "doomstat.h"
#include "fastcmp.h"
#include "g_input.h"
#include "g_game.h"
#include "hu_stuff.h"
#include "i_system.h"
#include "console.h"
#include "lua_script.h"
#include "lua_libs.h"
boolean mousegrabbedbylua = true;
boolean textinputmodeenabledbylua = false;
boolean ignoregameinputs = false;
///////////////
......@@ -129,6 +132,20 @@ static int lib_getCursorPosition(lua_State *L)
return 2;
}
static int lib_setTextInputMode(lua_State *L)
{
textinputmodeenabledbylua = luaL_checkboolean(L, 1);
if (!(menuactive || CON_Ready() || chat_on))
I_SetTextInputMode(textinputmodeenabledbylua);
return 0;
}
static int lib_getTextInputMode(lua_State *L)
{
lua_pushinteger(L, textinputmodeenabledbylua);
return 1;
}
static luaL_Reg lib[] = {
{"gameControlDown", lib_gameControlDown},
{"gameControl2Down", lib_gameControl2Down},
......@@ -143,6 +160,8 @@ static luaL_Reg lib[] = {
{"getMouseGrab", lib_getMouseGrab},
{"setMouseGrab", lib_setMouseGrab},
{"getCursorPosition", lib_getCursorPosition},
{"setTextInputMode", lib_setTextInputMode},
{"getTextInputMode", lib_getTextInputMode},
{NULL, NULL}
};
......@@ -220,6 +239,28 @@ static int lib_lenGameKeyDown(lua_State *L)
return 1;
}
////////////////
// TEXT EVENT //
////////////////
static int textevent_get(lua_State *L)
{
event_t *event = *((event_t **)luaL_checkudata(L, 1, META_TEXTEVENT));
const char *field = luaL_checkstring(L, 2);
I_Assert(event != NULL);
if (fastcmp(field,"text"))
{
char s[2] = { event->key, 0 };
lua_pushstring(L, s);
}
else
return luaL_error(L, "textevent_t has no field named %s", field);
return 1;
}
///////////////
// KEY EVENT //
///////////////
......@@ -285,6 +326,7 @@ static int mouse_num(lua_State *L)
int LUA_InputLib(lua_State *L)
{
LUA_RegisterUserdataMetatable(L, META_TEXTEVENT, textevent_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_KEYEVENT, keyevent_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_MOUSE, mouse_get, NULL, mouse_num);
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2024-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_interceptlib.c
/// \brief intercept library for Lua scripting
#include "doomdef.h"
#include "fastcmp.h"
#include "p_local.h"
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
#define NOHUD if (hud_running)\
return luaL_error(L, "HUD rendering code should not call this function!");
enum intercept_e {
intercept_valid = 0,
intercept_frac,
intercept_thing,
intercept_line
};
static const char *const intercept_opt[] = {
"valid",
"frac",
"thing",
"line",
NULL};
static int intercept_fields_ref = LUA_NOREF;
static boolean Lua_PathTraverser(intercept_t *in)
{
boolean traverse = false;
I_Assert(in != NULL);
lua_settop(gL, 6);
lua_pushcfunction(gL, LUA_GetErrorMessage);
I_Assert(lua_isfunction(gL, -2));
lua_pushvalue(gL, -2);
LUA_PushUserdata(gL, in, META_INTERCEPT);
LUA_Call(gL, 1, 1, -3);
traverse = lua_toboolean(gL, -1);
lua_pop(gL, 1);
return !traverse; // Stay consistent with the MobjMoveCollide hook
}
static int intercept_get(lua_State *L)
{
intercept_t *in = *((intercept_t **)luaL_checkudata(L, 1, META_INTERCEPT));
enum intercept_e field = Lua_optoption(L, 2, intercept_valid, intercept_fields_ref);
if (!in)
{
if (field == intercept_valid) {
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed intercept_t doesn't exist anymore.");
}
switch(field)
{
case intercept_valid: // valid
lua_pushboolean(L, 1);
return 1;
case intercept_frac:
lua_pushfixed(L, in->frac);
return 1;
case intercept_thing:
if (in->isaline)
return 0;
LUA_PushUserdata(L, in->d.thing, META_MOBJ);
return 1;
case intercept_line:
if (!in->isaline)
return 0;
LUA_PushUserdata(L, in->d.line, META_LINE);
return 1;
}
return 0;
}
static int lib_pPathTraverse(lua_State *L)
{
fixed_t px1 = luaL_checkfixed(L, 1);
fixed_t py1 = luaL_checkfixed(L, 2);
fixed_t px2 = luaL_checkfixed(L, 3);
fixed_t py2 = luaL_checkfixed(L, 4);
INT32 flags = (INT32)luaL_checkinteger(L, 5);
luaL_checktype(L, 6, LUA_TFUNCTION);
NOHUD
INLEVEL
lua_pushboolean(L, P_PathTraverse(px1, py1, px2, py2, flags, Lua_PathTraverser));
return 1;
}
int LUA_InterceptLib(lua_State *L)
{
LUA_RegisterUserdataMetatable(L, META_INTERCEPT, intercept_get, NULL, NULL);
intercept_fields_ref = Lua_CreateFieldTable(L, intercept_opt);
lua_register(L, "P_PathTraverse", lib_pPathTraverse);
return 0;
}
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -13,6 +13,7 @@
extern lua_State *gL;
extern boolean mousegrabbedbylua;
extern boolean textinputmodeenabledbylua;
extern boolean ignoregameinputs;
#define MUTABLE_TAGS
......@@ -42,8 +43,9 @@ extern boolean ignoregameinputs;
#define META_SKIN "SKIN_T*"
#define META_POWERS "PLAYER_T*POWERS"
#define META_SOUNDSID "SKIN_T*SOUNDSID"
#define META_SKINSPRITES "SKIN_T*SPRITES"
#define META_SKINSPRITESLIST "SKIN_T*SPRITES[]"
#define META_SKINSPRITES "SKIN_T*SKINSPRITES"
#define META_SKINSPRITESLIST "SKIN_T*SKINSPRITES[]"
#define META_SKINSPRITESCOMPAT "SKIN_T*SPRITES" // TODO: 2.3: Delete
#define META_VERTEX "VERTEX_T*"
#define META_LINE "LINE_T*"
......@@ -68,11 +70,15 @@ extern boolean ignoregameinputs;
#ifdef MUTABLE_TAGS
#define META_SECTORTAGLIST "sector_t.taglist"
#endif
#define META_SECTORCUSTOMARGS "SECTOR_T*CUSTOMARGS"
#define META_SIDENUM "LINE_T*SIDENUM"
#define META_LINEARGS "LINE_T*ARGS"
#define META_LINESTRINGARGS "LINE_T*STRINGARGS"
#define META_LINECUSTOMARGS "LINE_T*CUSTOMARGS"
#define META_SIDECUSTOMARGS "SIDE_T*CUSTOMARGS"
#define META_THINGARGS "MAPTHING_T*ARGS"
#define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS"
#define META_THINGCUSTOMARGS "MAPTHING_T*CUSTOMARGS"
#define META_POLYOBJVERTICES "POLYOBJ_T*VERTICES"
#define META_POLYOBJLINES "POLYOBJ_T*LINES"
#ifdef HAVE_LUA_SEGS
......@@ -92,9 +98,12 @@ extern boolean ignoregameinputs;
#define META_LUABANKS "LUABANKS[]*"
#define META_TEXTEVENT "TEXTEVENT_T*"
#define META_KEYEVENT "KEYEVENT_T*"
#define META_MOUSE "MOUSE_T*"
#define META_INTERCEPT "INTERCEPT_T*"
boolean luaL_checkboolean(lua_State *L, int narg);
int LUA_EnumLib(lua_State *L);
......@@ -115,3 +124,4 @@ int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L);
int LUA_ColorLib(lua_State *L);
int LUA_InputLib(lua_State *L);
int LUA_InterceptLib(lua_State *L);
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -69,6 +69,7 @@ enum sector_e {
sector_triggerer,
sector_friction,
sector_gravity,
sector_customargs
};
static const char *const sector_opt[] = {
......@@ -112,6 +113,7 @@ static const char *const sector_opt[] = {
"triggerer",
"friction",
"gravity",
"customargs",
NULL};
static int sector_fields_ref = LUA_NOREF;
......@@ -147,6 +149,7 @@ enum line_e {
line_taglist,
line_args,
line_stringargs,
line_customargs,
line_sidenum,
line_frontside,
line_backside,
......@@ -173,6 +176,7 @@ static const char *const line_opt[] = {
"taglist",
"args",
"stringargs",
"customargs",
"sidenum",
"frontside",
"backside",
......@@ -213,7 +217,16 @@ enum side_e {
side_sector,
side_special,
side_repeatcnt,
side_text
side_light,
side_light_top,
side_light_mid,
side_light_bottom,
side_lightabsolute,
side_lightabsolute_top,
side_lightabsolute_mid,
side_lightabsolute_bottom,
side_text,
side_customargs
};
static const char *const side_opt[] = {
......@@ -241,7 +254,16 @@ static const char *const side_opt[] = {
"sector",
"special",
"repeatcnt",
"light",
"light_top",
"light_mid",
"light_bottom",
"lightabsolute",
"lightabsolute_top",
"lightabsolute_mid",
"lightabsolute_bottom",
"text",
"customargs",
NULL};
static int side_fields_ref = LUA_NOREF;
......@@ -658,6 +680,73 @@ static int sectorlines_num(lua_State *L)
return 1;
}
//////////////////
// customargs_t //
//////////////////
FUNCINLINE static ATTRINLINE int customargs_get(lua_State* L, const char* meta)
{
customargs_t *args = *((customargs_t**)luaL_checkudata(L, 1, meta));
const char* field = luaL_checkstring(L, 2);
if (args == NULL) {
lua_pushnil(L);
return 1;
}
customargs_t* current = args;
while (current != NULL)
{
if (!strcmp(current->name, field))
{
switch (current->type)
{
case UDMF_TYPE_STRING:
lua_pushstring(L, current->value.vstring);
break;
case UDMF_TYPE_NUMERIC:
lua_pushinteger(L, current->value.vint);
break;
case UDMF_TYPE_FIXED:
lua_pushfixed(L, current->value.vfloat);
break;
case UDMF_TYPE_BOOLEAN:
lua_pushboolean(L, current->value.vbool);
break;
default:
lua_pushnil(L);
}
return 1;
}
current = current->next;
}
lua_pushnil(L);
return 1;
}
static int sectorcustomargs_get(lua_State* L)
{
return customargs_get(L, META_SECTORCUSTOMARGS);
}
static int sidecustomargs_get(lua_State* L)
{
return customargs_get(L, META_SIDECUSTOMARGS);
}
static int linecustomargs_get(lua_State* L)
{
return customargs_get(L, META_LINECUSTOMARGS);
}
static int thingcustomargs_get(lua_State* L)
{
return customargs_get(L, META_THINGCUSTOMARGS);
}
//////////////
// sector_t //
//////////////
......@@ -819,6 +908,9 @@ static int sector_get(lua_State *L)
case sector_gravity: // gravity
lua_pushfixed(L, sector->gravity);
return 1;
case sector_customargs:
LUA_PushUserdata(L, sector->customargs, META_SECTORCUSTOMARGS);
return 1;
}
return 0;
}
......@@ -1114,6 +1206,9 @@ static int line_get(lua_State *L)
case line_stringargs:
LUA_PushUserdata(L, line->stringargs, META_LINESTRINGARGS);
return 1;
case line_customargs:
LUA_PushUserdata(L, line->customargs, META_LINECUSTOMARGS);
return 1;
case line_sidenum:
LUA_PushUserdata(L, line->sidenum, META_SIDENUM);
return 1;
......@@ -1311,6 +1406,33 @@ static int side_get(lua_State *L)
case side_repeatcnt:
lua_pushinteger(L, side->repeatcnt);
return 1;
case side_light:
lua_pushinteger(L, side->light);
return 1;
case side_light_top:
lua_pushinteger(L, side->light_top);
return 1;
case side_light_mid:
lua_pushinteger(L, side->light_mid);
return 1;
case side_light_bottom:
lua_pushinteger(L, side->light_bottom);
return 1;
case side_lightabsolute:
lua_pushboolean(L, side->lightabsolute);
return 1;
case side_lightabsolute_top:
lua_pushboolean(L, side->lightabsolute_top);
return 1;
case side_lightabsolute_mid:
lua_pushboolean(L, side->lightabsolute_mid);
return 1;
case side_lightabsolute_bottom:
lua_pushboolean(L, side->lightabsolute_bottom);
return 1;
case side_customargs:
LUA_PushUserdata(L, side->customargs, META_SIDECUSTOMARGS);
return 1;
// TODO: 2.3: Delete
case side_text:
{
......@@ -1330,6 +1452,7 @@ static int side_get(lua_State *L)
return 1;
}
}
return 0;
}
......@@ -1413,6 +1536,30 @@ static int side_set(lua_State *L)
case side_repeatcnt:
side->repeatcnt = luaL_checkinteger(L, 3);
break;
case side_light:
side->light = luaL_checkinteger(L, 3);
break;
case side_light_top:
side->light_top = luaL_checkinteger(L, 3);
break;
case side_light_mid:
side->light_mid = luaL_checkinteger(L, 3);
break;
case side_light_bottom:
side->light_bottom = luaL_checkinteger(L, 3);
break;
case side_lightabsolute:
side->lightabsolute = luaL_checkboolean(L, 3);
break;
case side_lightabsolute_top:
side->lightabsolute_top = luaL_checkboolean(L, 3);
break;
case side_lightabsolute_mid:
side->lightabsolute_mid = luaL_checkboolean(L, 3);
break;
case side_lightabsolute_bottom:
side->lightabsolute_bottom = luaL_checkboolean(L, 3);
break;
}
return 0;
}
......@@ -2997,9 +3144,12 @@ int LUA_MapLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_SECTORLINES, sectorlines_get, NULL, sectorlines_num);
LUA_RegisterUserdataMetatable(L, META_SECTOR, sector_get, sector_set, sector_num);
LUA_RegisterUserdataMetatable(L, META_SUBSECTOR, subsector_get, NULL, subsector_num);
LUA_RegisterUserdataMetatable(L, META_SECTORCUSTOMARGS, sectorcustomargs_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_LINE, line_get, NULL, line_num);
LUA_RegisterUserdataMetatable(L, META_LINEARGS, lineargs_get, NULL, lineargs_len);
LUA_RegisterUserdataMetatable(L, META_LINESTRINGARGS, linestringargs_get, NULL, linestringargs_len);
LUA_RegisterUserdataMetatable(L, META_LINECUSTOMARGS, linecustomargs_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SIDECUSTOMARGS, sidecustomargs_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SIDENUM, sidenum_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SIDE, side_get, side_set, side_num);
LUA_RegisterUserdataMetatable(L, META_VERTEX, vertex_get, NULL, vertex_num);
......@@ -3009,6 +3159,7 @@ int LUA_MapLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_VECTOR2, vector2_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_VECTOR3, vector3_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_MAPHEADER, mapheaderinfo_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_THINGCUSTOMARGS, thingcustomargs_get, NULL, NULL);
sector_fields_ref = Lua_CreateFieldTable(L, sector_opt);
subsector_fields_ref = Lua_CreateFieldTable(L, subsector_opt);
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -69,6 +69,7 @@ enum mobj_e {
mobj_color,
mobj_translation,
mobj_blendmode,
mobj_alpha,
mobj_bnext,
mobj_bprev,
mobj_hnext,
......@@ -150,6 +151,7 @@ static const char *const mobj_opt[] = {
"color",
"translation",
"blendmode",
"alpha",
"bnext",
"bprev",
"hnext",
......@@ -196,12 +198,12 @@ static int mobj_get(lua_State *L)
enum mobj_e field = Lua_optoption(L, 2, -1, mobj_fields_ref);
lua_settop(L, 2);
if (!mo || !ISINLEVEL) {
if (P_MobjWasRemoved(mo) || !ISINLEVEL) {
if (field == mobj_valid) {
lua_pushboolean(L, 0);
return 1;
}
if (!mo) {
if (P_MobjWasRemoved(mo)) {
return LUA_ErrInvalid(L, "mobj_t");
} else
return luaL_error(L, "Do not access an mobj_t field outside a level!");
......@@ -354,6 +356,9 @@ static int mobj_get(lua_State *L)
case mobj_blendmode:
lua_pushinteger(L, mo->blendmode);
break;
case mobj_alpha:
lua_pushfixed(L, mo->alpha);
break;
case mobj_bnext:
if (mo->blocknode && mo->blocknode->bnext) {
LUA_PushUserdata(L, mo->blocknode->bnext->mobj, META_MOBJ);
......@@ -564,7 +569,7 @@ static int mobj_set(lua_State *L)
mo->frame = (UINT32)luaL_checkinteger(L, 3);
break;
case mobj_sprite2:
mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), (UINT8)luaL_checkinteger(L, 3), mo->player);
mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), (UINT16)luaL_checkinteger(L, 3), mo->player);
break;
case mobj_anim_duration:
mo->anim_duration = (UINT16)luaL_checkinteger(L, 3);
......@@ -733,6 +738,16 @@ static int mobj_set(lua_State *L)
mo->blendmode = blendmode;
break;
}
case mobj_alpha:
{
fixed_t alpha = luaL_checkfixed(L, 3);
if (alpha < 0)
alpha = 0;
else if (alpha > FRACUNIT)
alpha = FRACUNIT;
mo->alpha = alpha;
break;
}
case mobj_bnext:
return NOSETPOS;
case mobj_bprev:
......@@ -762,7 +777,7 @@ static int mobj_set(lua_State *L)
return luaL_error(L, "mobj.type %d out of range (0 - %d).", newtype, NUMMOBJTYPES-1);
mo->type = newtype;
mo->info = &mobjinfo[newtype];
P_SetScale(mo, mo->scale);
P_SetScale(mo, mo->scale, false);
break;
}
case mobj_info:
......@@ -836,9 +851,7 @@ static int mobj_set(lua_State *L)
fixed_t scale = luaL_checkfixed(L, 3);
if (scale < FRACUNIT/100)
scale = FRACUNIT/100;
mo->destscale = scale;
P_SetScale(mo, scale);
mo->old_scale = scale;
P_SetScale(mo, scale, true);
break;
}
case mobj_destscale:
......@@ -960,6 +973,7 @@ enum mapthing_e {
mapthing_taglist,
mapthing_args,
mapthing_stringargs,
mapthing_customargs,
mapthing_mobj,
};
......@@ -981,6 +995,7 @@ const char *const mapthing_opt[] = {
"taglist",
"args",
"stringargs",
"customargs",
"mobj",
NULL,
};
......@@ -1059,6 +1074,9 @@ static int mapthing_get(lua_State *L)
case mapthing_stringargs:
LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS);
break;
case mapthing_customargs:
LUA_PushUserdata(L, mt->customargs, META_THINGCUSTOMARGS);
break;
case mapthing_mobj:
LUA_PushUserdata(L, mt->mobj, META_MOBJ);
break;
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -190,6 +190,7 @@ enum player_e
player_marelap,
player_marebonuslap,
player_marebegunat,
player_lastmaretime,
player_startedtime,
player_finishedtime,
player_lapbegunat,
......@@ -337,6 +338,7 @@ static const char *const player_opt[] = {
"marelap",
"marebonuslap",
"marebegunat",
"lastmaretime",
"startedtime",
"finishedtime",
"lapbegunat",
......@@ -725,6 +727,9 @@ static int player_get(lua_State *L)
case player_marebegunat:
lua_pushinteger(L, plr->marebegunat);
break;
case player_lastmaretime:
lua_pushinteger(L, plr->lastmaretime);
break;
case player_startedtime:
lua_pushinteger(L, plr->startedtime);
break;
......@@ -1219,6 +1224,9 @@ static int player_set(lua_State *L)
case player_marebegunat:
plr->marebegunat = (tic_t)luaL_checkinteger(L, 3);
break;
case player_lastmaretime:
plr->lastmaretime = (tic_t)luaL_checkinteger(L, 3);
break;
case player_startedtime:
plr->startedtime = (tic_t)luaL_checkinteger(L, 3);
break;
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -20,6 +20,7 @@
#include "r_state.h"
#include "r_sky.h"
#include "g_game.h"
#include "g_demo.h"
#include "g_input.h"
#include "f_finale.h"
#include "byteptr.h"
......@@ -62,6 +63,7 @@ static lua_CFunction liblist[] = {
LUA_HudLib, // HUD stuff
LUA_ColorLib, // general color functions
LUA_InputLib, // inputs
LUA_InterceptLib, // intercept_t
NULL
};
......@@ -394,6 +396,22 @@ int LUA_PushGlobals(lua_State *L, const char *word)
return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1;
// demos booleans
} else if (fastcmp(word, "demoplayback")) {
lua_pushboolean(L, demoplayback);
return 1;
} else if (fastcmp(word, "titledemo")) {
lua_pushboolean(L, titledemo);
return 1;
} else if (fastcmp(word, "demorecording")) {
lua_pushboolean(L, demorecording);
return 1;
} else if (fastcmp(word, "timingdemo")) {
lua_pushboolean(L, timingdemo);
return 1;
} else if (fastcmp(word, "demosynced")) {
lua_pushboolean(L, demosynced);
return 1;
} else if (fastcmp(word,"emeralds")) {
lua_pushinteger(L, emeralds);
return 1;
......@@ -622,9 +640,6 @@ static inline boolean LUA_LoadFile(MYFILE *f, char *name)
if (!gL) // Lua needs to be initialized
LUA_ClearState();
lua_pushinteger(gL, f->wad);
lua_setfield(gL, LUA_REGISTRYINDEX, "WAD");
lua_pushcfunction(gL, LUA_GetErrorMessage);
errorhandlerindex = lua_gettop(gL);
......@@ -1101,7 +1116,7 @@ static UINT8 GetUserdataArchType(int index)
return ARCH_NULL;
}
static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
static UINT8 ArchiveValue(save_t *save_p, int TABLESINDEX, int myindex)
{
if (myindex < 0)
myindex = lua_gettop(gL)+1+myindex;
......@@ -1109,34 +1124,34 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
case LUA_TNONE:
case LUA_TNIL:
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
break;
// This might be a problem. D:
case LUA_TLIGHTUSERDATA:
case LUA_TTHREAD:
case LUA_TFUNCTION:
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
return 2;
case LUA_TBOOLEAN:
WRITEUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE);
P_WriteUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE);
break;
case LUA_TNUMBER:
{
lua_Integer number = lua_tointeger(gL, myindex);
if (number >= INT8_MIN && number <= INT8_MAX)
{
WRITEUINT8(save_p, ARCH_INT8);
WRITESINT8(save_p, number);
P_WriteUINT8(save_p, ARCH_INT8);
P_WriteSINT8(save_p, number);
}
else if (number >= INT16_MIN && number <= INT16_MAX)
{
WRITEUINT8(save_p, ARCH_INT16);
WRITEINT16(save_p, number);
P_WriteUINT8(save_p, ARCH_INT16);
P_WriteINT16(save_p, number);
}
else
{
WRITEUINT8(save_p, ARCH_INT32);
WRITEFIXED(save_p, number);
P_WriteUINT8(save_p, ARCH_INT32);
P_WriteFixed(save_p, number);
}
break;
}
......@@ -1147,23 +1162,23 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
UINT32 i = 0;
// if you're wondering why we're writing a string to save_p this way,
// it turns out that Lua can have embedded zeros ('\0') in the strings,
// so we can't use WRITESTRING as that cuts off when it finds a '\0'.
// so we can't use P_WriteString as that cuts off when it finds a '\0'.
// Saving the size of the string also allows us to get the size of the string on the other end,
// fixing the awful crashes previously encountered for reading strings longer than 1024
// (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?)
// -- Monster Iestyn 05/08/18
if (len < 255)
{
WRITEUINT8(save_p, ARCH_SMALLSTRING);
WRITEUINT8(save_p, len); // save size of string
P_WriteUINT8(save_p, ARCH_SMALLSTRING);
P_WriteUINT8(save_p, len); // save size of string
}
else
{
WRITEUINT8(save_p, ARCH_LARGESTRING);
WRITEUINT32(save_p, len); // save size of string
P_WriteUINT8(save_p, ARCH_LARGESTRING);
P_WriteUINT32(save_p, len); // save size of string
}
while (i < len)
WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros
P_WriteChar(save_p, s[i++]); // write chars individually, including the embedded zeros
break;
}
case LUA_TTABLE:
......@@ -1189,13 +1204,13 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
if (t == 0)
{
CONS_Alert(CONS_ERROR, "Too many tables to archive!\n");
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
return 0;
}
}
WRITEUINT8(save_p, ARCH_TABLE);
WRITEUINT16(save_p, t);
P_WriteUINT8(save_p, ARCH_TABLE);
P_WriteUINT16(save_p, t);
if (!found)
{
......@@ -1211,25 +1226,25 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
case ARCH_MOBJINFO:
{
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_MOBJINFO);
WRITEUINT16(save_p, info - mobjinfo);
P_WriteUINT8(save_p, ARCH_MOBJINFO);
P_WriteUINT16(save_p, info - mobjinfo);
break;
}
case ARCH_STATE:
{
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_STATE);
WRITEUINT16(save_p, state - states);
P_WriteUINT8(save_p, ARCH_STATE);
P_WriteUINT16(save_p, state - states);
break;
}
case ARCH_MOBJ:
{
mobj_t *mobj = *((mobj_t **)lua_touserdata(gL, myindex));
if (!mobj)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_MOBJ);
WRITEUINT32(save_p, mobj->mobjnum);
P_WriteUINT8(save_p, ARCH_MOBJ);
P_WriteUINT32(save_p, mobj->mobjnum);
}
break;
}
......@@ -1237,10 +1252,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
player_t *player = *((player_t **)lua_touserdata(gL, myindex));
if (!player)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_PLAYER);
WRITEUINT8(save_p, player - players);
P_WriteUINT8(save_p, ARCH_PLAYER);
P_WriteUINT8(save_p, player - players);
}
break;
}
......@@ -1248,10 +1263,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
mapthing_t *mapthing = *((mapthing_t **)lua_touserdata(gL, myindex));
if (!mapthing)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_MAPTHING);
WRITEUINT16(save_p, mapthing - mapthings);
P_WriteUINT8(save_p, ARCH_MAPTHING);
P_WriteUINT16(save_p, mapthing - mapthings);
}
break;
}
......@@ -1259,10 +1274,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
vertex_t *vertex = *((vertex_t **)lua_touserdata(gL, myindex));
if (!vertex)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_VERTEX);
WRITEUINT16(save_p, vertex - vertexes);
P_WriteUINT8(save_p, ARCH_VERTEX);
P_WriteUINT16(save_p, vertex - vertexes);
}
break;
}
......@@ -1270,10 +1285,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
line_t *line = *((line_t **)lua_touserdata(gL, myindex));
if (!line)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_LINE);
WRITEUINT16(save_p, line - lines);
P_WriteUINT8(save_p, ARCH_LINE);
P_WriteUINT16(save_p, line - lines);
}
break;
}
......@@ -1281,10 +1296,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
side_t *side = *((side_t **)lua_touserdata(gL, myindex));
if (!side)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_SIDE);
WRITEUINT16(save_p, side - sides);
P_WriteUINT8(save_p, ARCH_SIDE);
P_WriteUINT16(save_p, side - sides);
}
break;
}
......@@ -1292,10 +1307,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
subsector_t *subsector = *((subsector_t **)lua_touserdata(gL, myindex));
if (!subsector)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_SUBSECTOR);
WRITEUINT16(save_p, subsector - subsectors);
P_WriteUINT8(save_p, ARCH_SUBSECTOR);
P_WriteUINT16(save_p, subsector - subsectors);
}
break;
}
......@@ -1303,10 +1318,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
sector_t *sector = *((sector_t **)lua_touserdata(gL, myindex));
if (!sector)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_SECTOR);
WRITEUINT16(save_p, sector - sectors);
P_WriteUINT8(save_p, ARCH_SECTOR);
P_WriteUINT16(save_p, sector - sectors);
}
break;
}
......@@ -1315,10 +1330,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
seg_t *seg = *((seg_t **)lua_touserdata(gL, myindex));
if (!seg)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_SEG);
WRITEUINT16(save_p, seg - segs);
P_WriteUINT8(save_p, ARCH_SEG);
P_WriteUINT16(save_p, seg - segs);
}
break;
}
......@@ -1326,10 +1341,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
node_t *node = *((node_t **)lua_touserdata(gL, myindex));
if (!node)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_NODE);
WRITEUINT16(save_p, node - nodes);
P_WriteUINT8(save_p, ARCH_NODE);
P_WriteUINT16(save_p, node - nodes);
}
break;
}
......@@ -1338,16 +1353,16 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
ffloor_t *rover = *((ffloor_t **)lua_touserdata(gL, myindex));
if (!rover)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
UINT16 i = P_GetFFloorID(rover);
if (i == UINT16_MAX) // invalid ID
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else
{
WRITEUINT8(save_p, ARCH_FFLOOR);
WRITEUINT16(save_p, rover->target - sectors);
WRITEUINT16(save_p, i);
P_WriteUINT8(save_p, ARCH_FFLOOR);
P_WriteUINT16(save_p, rover->target - sectors);
P_WriteUINT16(save_p, i);
}
}
break;
......@@ -1356,10 +1371,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
polyobj_t *polyobj = *((polyobj_t **)lua_touserdata(gL, myindex));
if (!polyobj)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_POLYOBJ);
WRITEUINT16(save_p, polyobj-PolyObjects);
P_WriteUINT8(save_p, ARCH_POLYOBJ);
P_WriteUINT16(save_p, polyobj-PolyObjects);
}
break;
}
......@@ -1367,10 +1382,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
if (!slope)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_SLOPE);
WRITEUINT16(save_p, slope->id);
P_WriteUINT8(save_p, ARCH_SLOPE);
P_WriteUINT16(save_p, slope->id);
}
break;
}
......@@ -1378,36 +1393,36 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
if (!header)
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_MAPHEADER);
WRITEUINT16(save_p, header - *mapheaderinfo);
P_WriteUINT8(save_p, ARCH_MAPHEADER);
P_WriteUINT16(save_p, header - *mapheaderinfo);
}
break;
}
case ARCH_SKINCOLOR:
{
skincolor_t *info = *((skincolor_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_SKINCOLOR);
WRITEUINT16(save_p, info - skincolors);
P_WriteUINT8(save_p, ARCH_SKINCOLOR);
P_WriteUINT16(save_p, info - skincolors);
break;
}
case ARCH_MOUSE:
{
mouse_t *m = *((mouse_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_MOUSE);
WRITEUINT8(save_p, m == &mouse ? 1 : 2);
P_WriteUINT8(save_p, ARCH_MOUSE);
P_WriteUINT8(save_p, m == &mouse ? 1 : 2);
break;
}
case ARCH_SKIN:
{
skin_t *skin = *((skin_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_SKIN);
WRITEUINT8(save_p, skin->skinnum); // UINT8 because MAXSKINS must be <= 256
P_WriteUINT8(save_p, ARCH_SKIN);
P_WriteUINT8(save_p, skin->skinnum); // UINT8 because MAXSKINS must be <= 256
break;
}
default:
WRITEUINT8(save_p, ARCH_NULL);
P_WriteUINT8(save_p, ARCH_NULL);
return 2;
}
break;
......@@ -1415,14 +1430,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
return 0;
}
static void ArchiveExtVars(void *pointer, const char *ptype)
static void ArchiveExtVars(save_t *save_p, void *pointer, const char *ptype)
{
int TABLESINDEX;
UINT16 i;
if (!gL) {
if (fastcmp(ptype,"player")) // players must always be included, even if no vars
WRITEUINT16(save_p, 0);
P_WriteUINT16(save_p, 0);
return;
}
......@@ -1438,7 +1453,7 @@ static void ArchiveExtVars(void *pointer, const char *ptype)
{ // no extra values table
lua_pop(gL, 1);
if (fastcmp(ptype,"player")) // players must always be included, even if no vars
WRITEUINT16(save_p, 0);
P_WriteUINT16(save_p, 0);
return;
}
......@@ -1450,20 +1465,20 @@ static void ArchiveExtVars(void *pointer, const char *ptype)
if (i == 0)
{
if (fastcmp(ptype,"player")) // always include players even if they have no extra variables
WRITEUINT16(save_p, 0);
P_WriteUINT16(save_p, 0);
lua_pop(gL, 1);
return;
}
if (fastcmp(ptype,"mobj")) // mobjs must write their mobjnum as a header
WRITEUINT32(save_p, ((mobj_t *)pointer)->mobjnum);
WRITEUINT16(save_p, i);
P_WriteUINT32(save_p, ((mobj_t *)pointer)->mobjnum);
P_WriteUINT16(save_p, i);
lua_pushnil(gL);
while (lua_next(gL, -2))
{
I_Assert(lua_type(gL, -2) == LUA_TSTRING);
WRITESTRING(save_p, lua_tostring(gL, -2));
if (ArchiveValue(TABLESINDEX, -1) == 2)
P_WriteString(save_p, lua_tostring(gL, -2));
if (ArchiveValue(save_p, TABLESINDEX, -1) == 2)
CONS_Alert(CONS_ERROR, "Type of value for %s entry '%s' (%s) could not be archived!\n", ptype, lua_tostring(gL, -2), luaL_typename(gL, -1));
lua_pop(gL, 1);
}
......@@ -1471,16 +1486,19 @@ static void ArchiveExtVars(void *pointer, const char *ptype)
lua_pop(gL, 1);
}
// FIXME: remove and pass as local variable
static save_t *lua_save_p;
static int NetArchive(lua_State *L)
{
int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L);
for (i = 1; i <= n; i++)
ArchiveValue(TABLESINDEX, i);
ArchiveValue(lua_save_p, TABLESINDEX, i);
return n;
}
static void ArchiveTables(void)
static void ArchiveTables(save_t *save_p)
{
int TABLESINDEX;
UINT16 i, n;
......@@ -1499,14 +1517,14 @@ static void ArchiveTables(void)
while (lua_next(gL, -2))
{
// Write key
e = ArchiveValue(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
e = ArchiveValue(save_p, TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
if (e == 1)
n++; // the table contained a new table we'll have to archive. :(
else if (e == 2) // invalid key type (function, thread, lightuserdata, or anything we don't recognise)
CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -2), luaL_typename(gL, -2), i);
// Write value
e = ArchiveValue(TABLESINDEX, -1);
e = ArchiveValue(save_p, TABLESINDEX, -1);
if (e == 1)
n++; // the table contained a new table we'll have to archive. :(
else if (e == 2) // invalid value type
......@@ -1514,7 +1532,7 @@ static void ArchiveTables(void)
lua_pop(gL, 1);
}
WRITEUINT8(save_p, ARCH_TEND);
P_WriteUINT8(save_p, ARCH_TEND);
// Write metatable ID
if (lua_getmetatable(gL, -1))
......@@ -1523,19 +1541,19 @@ static void ArchiveTables(void)
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_METATABLES);
lua_pushvalue(gL, -2);
lua_gettable(gL, -2);
WRITEUINT16(save_p, lua_isnil(gL, -1) ? 0 : lua_tointeger(gL, -1));
P_WriteUINT16(save_p, lua_isnil(gL, -1) ? 0 : lua_tointeger(gL, -1));
lua_pop(gL, 3);
}
else
WRITEUINT16(save_p, 0);
P_WriteUINT16(save_p, 0);
lua_pop(gL, 1);
}
}
static UINT8 UnArchiveValue(int TABLESINDEX)
static UINT8 UnArchiveValue(save_t *save_p, int TABLESINDEX)
{
UINT8 type = READUINT8(save_p);
UINT8 type = P_ReadUINT8(save_p);
switch (type)
{
case ARCH_NULL:
......@@ -1548,13 +1566,13 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
lua_pushboolean(gL, false);
break;
case ARCH_INT8:
lua_pushinteger(gL, READSINT8(save_p));
lua_pushinteger(gL, P_ReadSINT8(save_p));
break;
case ARCH_INT16:
lua_pushinteger(gL, READINT16(save_p));
lua_pushinteger(gL, P_ReadINT16(save_p));
break;
case ARCH_INT32:
lua_pushinteger(gL, READFIXED(save_p));
lua_pushinteger(gL, P_ReadFixed(save_p));
break;
case ARCH_SMALLSTRING:
case ARCH_LARGESTRING:
......@@ -1565,23 +1583,23 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
// See my comments in the ArchiveValue function;
// it's much the same for reading strings as writing them!
// (i.e. we can't use READSTRING either)
// (i.e. we can't use P_ReadString either)
// -- Monster Iestyn 05/08/18
if (type == ARCH_SMALLSTRING)
len = READUINT8(save_p); // length of string, including embedded zeros
len = P_ReadUINT8(save_p); // length of string, including embedded zeros
else
len = READUINT32(save_p); // length of string, including embedded zeros
len = P_ReadUINT32(save_p); // length of string, including embedded zeros
value = malloc(len); // make temp buffer of size len
// now read the actual string
while (i < len)
value[i++] = READCHAR(save_p); // read chars individually, including the embedded zeros
value[i++] = P_ReadChar(save_p); // read chars individually, including the embedded zeros
lua_pushlstring(gL, value, len); // push the string (note: this function supports embedded zeros)
free(value); // free the buffer
break;
}
case ARCH_TABLE:
{
UINT16 tid = READUINT16(save_p);
UINT16 tid = P_ReadUINT16(save_p);
lua_rawgeti(gL, TABLESINDEX, tid);
if (lua_isnil(gL, -1))
{
......@@ -1594,69 +1612,69 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
break;
}
case ARCH_MOBJINFO:
LUA_PushUserdata(gL, &mobjinfo[READUINT16(save_p)], META_MOBJINFO);
LUA_PushUserdata(gL, &mobjinfo[P_ReadUINT16(save_p)], META_MOBJINFO);
break;
case ARCH_STATE:
LUA_PushUserdata(gL, &states[READUINT16(save_p)], META_STATE);
LUA_PushUserdata(gL, &states[P_ReadUINT16(save_p)], META_STATE);
break;
case ARCH_MOBJ:
LUA_PushUserdata(gL, P_FindNewPosition(READUINT32(save_p)), META_MOBJ);
LUA_PushUserdata(gL, P_FindNewPosition(P_ReadUINT32(save_p)), META_MOBJ);
break;
case ARCH_PLAYER:
LUA_PushUserdata(gL, &players[READUINT8(save_p)], META_PLAYER);
LUA_PushUserdata(gL, &players[P_ReadUINT8(save_p)], META_PLAYER);
break;
case ARCH_MAPTHING:
LUA_PushUserdata(gL, &mapthings[READUINT16(save_p)], META_MAPTHING);
LUA_PushUserdata(gL, &mapthings[P_ReadUINT16(save_p)], META_MAPTHING);
break;
case ARCH_VERTEX:
LUA_PushUserdata(gL, &vertexes[READUINT16(save_p)], META_VERTEX);
LUA_PushUserdata(gL, &vertexes[P_ReadUINT16(save_p)], META_VERTEX);
break;
case ARCH_LINE:
LUA_PushUserdata(gL, &lines[READUINT16(save_p)], META_LINE);
LUA_PushUserdata(gL, &lines[P_ReadUINT16(save_p)], META_LINE);
break;
case ARCH_SIDE:
LUA_PushUserdata(gL, &sides[READUINT16(save_p)], META_SIDE);
LUA_PushUserdata(gL, &sides[P_ReadUINT16(save_p)], META_SIDE);
break;
case ARCH_SUBSECTOR:
LUA_PushUserdata(gL, &subsectors[READUINT16(save_p)], META_SUBSECTOR);
LUA_PushUserdata(gL, &subsectors[P_ReadUINT16(save_p)], META_SUBSECTOR);
break;
case ARCH_SECTOR:
LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_SECTOR);
LUA_PushUserdata(gL, &sectors[P_ReadUINT16(save_p)], META_SECTOR);
break;
#ifdef HAVE_LUA_SEGS
case ARCH_SEG:
LUA_PushUserdata(gL, &segs[READUINT16(save_p)], META_SEG);
LUA_PushUserdata(gL, &segs[P_ReadUINT16(save_p)], META_SEG);
break;
case ARCH_NODE:
LUA_PushUserdata(gL, &nodes[READUINT16(save_p)], META_NODE);
LUA_PushUserdata(gL, &nodes[P_ReadUINT16(save_p)], META_NODE);
break;
#endif
case ARCH_FFLOOR:
{
sector_t *sector = &sectors[READUINT16(save_p)];
UINT16 id = READUINT16(save_p);
sector_t *sector = &sectors[P_ReadUINT16(save_p)];
UINT16 id = P_ReadUINT16(save_p);
ffloor_t *rover = P_GetFFloorByID(sector, id);
if (rover)
LUA_PushUserdata(gL, rover, META_FFLOOR);
break;
}
case ARCH_POLYOBJ:
LUA_PushUserdata(gL, &PolyObjects[READUINT16(save_p)], META_POLYOBJ);
LUA_PushUserdata(gL, &PolyObjects[P_ReadUINT16(save_p)], META_POLYOBJ);
break;
case ARCH_SLOPE:
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE);
LUA_PushUserdata(gL, P_SlopeById(P_ReadUINT16(save_p)), META_SLOPE);
break;
case ARCH_MAPHEADER:
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
LUA_PushUserdata(gL, mapheaderinfo[P_ReadUINT16(save_p)], META_MAPHEADER);
break;
case ARCH_SKINCOLOR:
LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR);
LUA_PushUserdata(gL, &skincolors[P_ReadUINT16(save_p)], META_SKINCOLOR);
break;
case ARCH_MOUSE:
LUA_PushUserdata(gL, READUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
LUA_PushUserdata(gL, P_ReadUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
break;
case ARCH_SKIN:
LUA_PushUserdata(gL, skins[READUINT8(save_p)], META_SKIN);
LUA_PushUserdata(gL, skins[P_ReadUINT8(save_p)], META_SKIN);
break;
case ARCH_TEND:
return 1;
......@@ -1664,10 +1682,10 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
return 0;
}
static void UnArchiveExtVars(void *pointer)
static void UnArchiveExtVars(save_t *save_p, void *pointer)
{
int TABLESINDEX;
UINT16 field_count = READUINT16(save_p);
UINT16 field_count = P_ReadUINT16(save_p);
UINT16 i;
char field[1024];
......@@ -1680,8 +1698,8 @@ static void UnArchiveExtVars(void *pointer)
for (i = 0; i < field_count; i++)
{
READSTRING(save_p, field);
UnArchiveValue(TABLESINDEX);
P_ReadString(save_p, field);
UnArchiveValue(save_p, TABLESINDEX);
lua_setfield(gL, -2, field);
}
......@@ -1698,11 +1716,11 @@ static int NetUnArchive(lua_State *L)
int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L);
for (i = 1; i <= n; i++)
UnArchiveValue(TABLESINDEX);
UnArchiveValue(lua_save_p, TABLESINDEX);
return n;
}
static void UnArchiveTables(void)
static void UnArchiveTables(save_t *save_p)
{
int TABLESINDEX;
UINT16 i, n;
......@@ -1719,13 +1737,13 @@ static void UnArchiveTables(void)
lua_rawgeti(gL, TABLESINDEX, i);
while (true)
{
UINT8 e = UnArchiveValue(TABLESINDEX); // read key
UINT8 e = UnArchiveValue(save_p, TABLESINDEX); // read key
if (e == 1) // End of table
break;
else if (e == 2) // Key contains a new table
n++;
if (UnArchiveValue(TABLESINDEX) == 2) // read value
if (UnArchiveValue(save_p, TABLESINDEX) == 2) // read value
n++;
if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved)
......@@ -1737,7 +1755,7 @@ static void UnArchiveTables(void)
lua_rawset(gL, -3);
}
metatableid = READUINT16(save_p);
metatableid = P_ReadUINT16(save_p);
if (metatableid)
{
// setmetatable(table, registry.metatables[metatableid])
......@@ -1761,7 +1779,7 @@ void LUA_Step(void)
lua_gc(gL, LUA_GCSTEP, 1);
}
void LUA_Archive(void)
void LUA_Archive(save_t *save_p)
{
INT32 i;
thinker_t *th;
......@@ -1774,29 +1792,30 @@ void LUA_Archive(void)
if (!playeringame[i] && i > 0) // dedicated servers...
continue;
// all players in game will be archived, even if they just add a 0.
ArchiveExtVars(&players[i], "player");
ArchiveExtVars(save_p, &players[i], "player");
}
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
// archive function will determine when to skip mobjs,
// and write mobjnum in otherwise.
ArchiveExtVars(th, "mobj");
ArchiveExtVars(save_p, th, "mobj");
}
WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
P_WriteUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
lua_save_p = save_p;
LUA_HookNetArchive(NetArchive); // call the NetArchive hook in archive mode
ArchiveTables();
ArchiveTables(save_p);
if (gL)
lua_pop(gL, 1); // pop tables
}
void LUA_UnArchive(void)
void LUA_UnArchive(save_t *save_p)
{
UINT32 mobjnum;
INT32 i;
......@@ -1809,23 +1828,24 @@ void LUA_UnArchive(void)
{
if (!playeringame[i] && i > 0) // dedicated servers...
continue;
UnArchiveExtVars(&players[i]);
UnArchiveExtVars(save_p, &players[i]);
}
do {
mobjnum = READUINT32(save_p); // read a mobjnum
mobjnum = P_ReadUINT32(save_p); // read a mobjnum
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
if (((mobj_t *)th)->mobjnum != mobjnum) // find matching mobj
continue;
UnArchiveExtVars(th); // apply variables
UnArchiveExtVars(save_p, th); // apply variables
}
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker.
lua_save_p = save_p;
LUA_HookNetArchive(NetUnArchive); // call the NetArchive hook in unarchive mode
UnArchiveTables();
UnArchiveTables(save_p);
if (gL)
lua_pop(gL, 1); // pop tables
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2023 by Sonic Team Junior.
// Copyright (C) 2012-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -13,6 +13,7 @@
#ifndef LUA_SCRIPT_H
#define LUA_SCRIPT_H
#include "p_saveg.h"
#include "m_fixed.h"
#include "doomtype.h"
#include "d_player.h"
......@@ -52,8 +53,8 @@ void LUA_DumpFile(const char *filename);
#endif
fixed_t LUA_EvalMath(const char *word);
void LUA_Step(void);
void LUA_Archive(void);
void LUA_UnArchive(void);
void LUA_Archive(save_t *save_p);
void LUA_UnArchive(save_t *save_p);
int LUA_PushGlobals(lua_State *L, const char *word);
int LUA_CheckGlobals(lua_State *L, const char *word);
void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2014-2016 by John "JTE" Muniz.
// Copyright (C) 2014-2023 by Sonic Team Junior.
// Copyright (C) 2014-2025 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -54,7 +54,9 @@ enum skin {
skin_contspeed,
skin_contangle,
skin_soundsid,
skin_sprites,
skin_sprites, // TODO: 2.3: Delete
skin_skinsprites,
skin_supersprites,
skin_natkcolor
};
......@@ -94,7 +96,9 @@ static const char *const skin_opt[] = {
"contspeed",
"contangle",
"soundsid",
"sprites",
"sprites", // TODO: 2.3: Delete
"skinsprites",
"supersprites",
"natkcolor",
NULL};
......@@ -217,9 +221,15 @@ static int skin_get(lua_State *L)
case skin_soundsid:
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
break;
case skin_sprites:
case skin_sprites: // TODO: 2.3: Delete
LUA_PushUserdata(L, skin->sprites_compat, META_SKINSPRITESCOMPAT);
break;
case skin_skinsprites:
LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES);
break;
case skin_supersprites:
LUA_PushUserdata(L, skin->super.sprites, META_SKINSPRITES);
break;
case skin_natkcolor:
lua_pushinteger(L, skin->natkcolor);
break;
......@@ -333,34 +343,59 @@ static int soundsid_num(lua_State *L)
return 1;
}
enum spritesopt {
numframes = 0
};
static const char *const sprites_opt[] = {
"numframes",
NULL};
// skin.sprites[i] -> sprites[i]
// skin.skinsprites[i] -> sprites[i]
static int lib_getSkinSprite(lua_State *L)
{
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES)
return luaL_error(L, "skin sprites index %d out of range (0 - %d)", i, NUMPLAYERSPRITES-1);
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
return 1;
}
// #skin.skinsprites -> NUMPLAYERSPRITES
static int lib_numSkinsSprites(lua_State *L)
{
lua_pushinteger(L, NUMPLAYERSPRITES);
return 1;
}
// TODO: 2.3: Delete
// skin.sprites[i] -> sprites[i]
static int lib_getSkinSpriteCompat(lua_State *L)
{
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESCOMPAT);
INT32 i = luaL_checkinteger(L, 2) & (SPR2F_MASK | SPR2F_SUPER);
if (i & SPR2F_SUPER)
i = (i & ~SPR2F_SUPER) + NUMPLAYERSPRITES;
if (i < 0 || i >= NUMPLAYERSPRITES*2)
return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
return luaL_error(L, "skin sprites index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
return 1;
}
// TODO: 2.3: Delete
// #skin.sprites -> NUMPLAYERSPRITES*2
static int lib_numSkinsSprites(lua_State *L)
static int lib_numSkinsSpritesCompat(lua_State *L)
{
lua_pushinteger(L, NUMPLAYERSPRITES*2);
return 1;
}
enum spritesopt {
numframes = 0
};
static const char *const sprites_opt[] = {
"numframes",
NULL};
static int sprite_get(lua_State *L)
{
spritedef_t *sprite = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESLIST);
......@@ -382,6 +417,7 @@ int LUA_SkinLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_SOUNDSID, soundsid_get, NULL, soundsid_num);
LUA_RegisterUserdataMetatable(L, META_SKINSPRITES, lib_getSkinSprite, NULL, lib_numSkinsSprites);
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESLIST, sprite_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESCOMPAT, lib_getSkinSpriteCompat, NULL, lib_numSkinsSpritesCompat); // TODO: 2.3: Delete
skin_fields_ref = Lua_CreateFieldTable(L, skin_opt);
......