From 5eeef20d70fc978372058371d29821dc27b019a5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 27 Nov 2014 15:28:58 -0500 Subject: hexen: Store minotaur start time as little endian. The minotaur uses the first four bytes of the mobj_t args[] array to store its spawn time; after a certain amount of time has passed the minotaur self-destructs. But the level time was being copied from the leveltime variable without any endian conversion taking place. For compatibility with Vanilla Hexen savegames we need to store the start time in little endian format. This fixes the first issue noted in #477 (thanks Quasar). --- src/hexen/a_action.c | 7 ++++++- src/hexen/p_enemy.c | 30 ++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'src/hexen') diff --git a/src/hexen/a_action.c b/src/hexen/a_action.c index e25b4f84..c4c194e3 100644 --- a/src/hexen/a_action.c +++ b/src/hexen/a_action.c @@ -636,7 +636,12 @@ void A_Summon(mobj_t * actor) return; } - memcpy((void *) mo->args, &leveltime, sizeof(leveltime)); + // Store leveltime into mo->args. This must be stored in little- + // endian format for Vanilla savegame compatibility. + mo->args[0] = leveltime & 0xff; + mo->args[1] = (leveltime >> 8) & 0xff; + mo->args[2] = (leveltime >> 16) & 0xff; + mo->args[3] = (leveltime >> 24) & 0xff; master = actor->special1.m; if (master->flags & MF_CORPSE) { // Master dead diff --git a/src/hexen/p_enemy.c b/src/hexen/p_enemy.c index 9219f339..1ad87032 100644 --- a/src/hexen/p_enemy.c +++ b/src/hexen/p_enemy.c @@ -1108,16 +1108,33 @@ void A_MinotaurFade2(mobj_t * actor) void A_MinotaurLook(mobj_t * actor); -void A_MinotaurRoam(mobj_t * actor) +// Check the age of the minotaur and stomp it after MAULATORTICS of time +// have passed. Returns false if killed. +static boolean CheckMinotaurAge(mobj_t *mo) { - unsigned int *starttime = (unsigned int *) actor->args; + unsigned int starttime; + + // The start time is stored in the mobj_t structure, but it is stored + // in little endian format. For Vanilla savegame compatibility we must + // swap it to the native endianness. + memcpy(&starttime, mo->args, sizeof(unsigned int)); + + if (leveltime - LONG(starttime) >= MAULATORTICS) + { + P_DamageMobj(mo, NULL, NULL, 10000); + return false; + } + return true; +} + +void A_MinotaurRoam(mobj_t * actor) +{ actor->flags &= ~MF_SHADOW; // In case pain caused him to actor->flags &= ~MF_ALTSHADOW; // skip his fade in. - if ((leveltime - *starttime) >= MAULATORTICS) + if (!CheckMinotaurAge(actor)) { - P_DamageMobj(actor, NULL, NULL, 10000); return; } @@ -1231,14 +1248,11 @@ void A_MinotaurLook(mobj_t * actor) void A_MinotaurChase(mobj_t * actor) { - unsigned int *starttime = (unsigned int *) actor->args; - actor->flags &= ~MF_SHADOW; // In case pain caused him to actor->flags &= ~MF_ALTSHADOW; // skip his fade in. - if ((leveltime - *starttime) >= MAULATORTICS) + if (!CheckMinotaurAge(actor)) { - P_DamageMobj(actor, NULL, NULL, 10000); return; } -- cgit v1.2.3