2006-04-13 20:47:06 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
2016-02-02 00:21:24 +00:00
|
|
|
Copyright (C) 2016 EDuke32 developers and contributors
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2010-05-25 10:56:00 +00:00
|
|
|
This file is part of EDuke32.
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
EDuke32 is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License version 2
|
|
|
|
as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2014-07-20 08:55:56 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2006-04-13 20:47:06 +00:00
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2016-02-02 00:21:24 +00:00
|
|
|
|
2018-11-18 18:09:48 +00:00
|
|
|
#include "anim.h"
|
2018-11-18 19:03:40 +00:00
|
|
|
#include "cmdline.h"
|
2017-06-24 09:21:03 +00:00
|
|
|
#include "colmatch.h"
|
2018-05-22 19:03:44 +00:00
|
|
|
#include "compat.h"
|
2018-11-18 18:09:48 +00:00
|
|
|
#include "debugbreak.h"
|
2016-02-07 02:38:03 +00:00
|
|
|
#include "duke3d.h"
|
2018-05-22 19:03:44 +00:00
|
|
|
#include "input.h"
|
|
|
|
#include "menus.h"
|
|
|
|
#include "osdcmds.h"
|
|
|
|
#include "savegame.h"
|
|
|
|
#include "scriplib.h"
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-06-03 15:45:59 +00:00
|
|
|
#ifdef LUNATIC
|
2012-11-10 20:59:00 +00:00
|
|
|
# include "lunatic_game.h"
|
2012-02-09 22:45:18 +00:00
|
|
|
#endif
|
|
|
|
|
2010-01-24 23:33:17 +00:00
|
|
|
#if KRANDDEBUG
|
|
|
|
# define GAMEEXEC_INLINE
|
|
|
|
# define GAMEEXEC_STATIC
|
|
|
|
#else
|
|
|
|
# define GAMEEXEC_INLINE inline
|
|
|
|
# define GAMEEXEC_STATIC static
|
|
|
|
#endif
|
|
|
|
|
2013-07-13 21:04:45 +00:00
|
|
|
vmstate_t vm;
|
|
|
|
|
|
|
|
#if !defined LUNATIC
|
2009-01-09 09:29:17 +00:00
|
|
|
int32_t g_tw;
|
2013-02-07 21:00:52 +00:00
|
|
|
int32_t g_errorLineNum;
|
2018-11-18 18:11:44 +00:00
|
|
|
int32_t g_currentEvent = -1;
|
2011-08-03 17:22:46 +00:00
|
|
|
|
2015-02-11 05:22:11 +00:00
|
|
|
intptr_t const *insptr;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int32_t g_returnVarID = -1; // var ID of "RETURN"
|
|
|
|
int32_t g_weaponVarID = -1; // var ID of "WEAPON"
|
|
|
|
int32_t g_worksLikeVarID = -1; // var ID of "WORKSLIKE"
|
|
|
|
int32_t g_zRangeVarID = -1; // var ID of "ZRANGE"
|
|
|
|
int32_t g_angRangeVarID = -1; // var ID of "ANGRANGE"
|
|
|
|
int32_t g_aimAngleVarID = -1; // var ID of "AUTOAIMANGLE"
|
|
|
|
int32_t g_lotagVarID = -1; // var ID of "LOTAG"
|
|
|
|
int32_t g_hitagVarID = -1; // var ID of "HITAG"
|
|
|
|
int32_t g_textureVarID = -1; // var ID of "TEXTURE"
|
|
|
|
int32_t g_thisActorVarID = -1; // var ID of "THISACTOR"
|
|
|
|
int32_t g_structVarIDs = -1;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-03-08 00:29:41 +00:00
|
|
|
// for timing events and actors
|
|
|
|
uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES];
|
|
|
|
double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES], g_actorMinMs[MAXTILES], g_actorMaxMs[MAXTILES];
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
GAMEEXEC_STATIC void VM_Execute(native_t loop);
|
2008-02-16 22:18:48 +00:00
|
|
|
|
2017-02-01 10:20:54 +00:00
|
|
|
# include "gamestructures.cpp"
|
2013-01-01 15:24:18 +00:00
|
|
|
#endif
|
2008-12-13 08:02:22 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
#define VM_CONDITIONAL(xxx) \
|
|
|
|
{ \
|
|
|
|
if ((xxx) || ((insptr = (intptr_t *)insptr[1]) && ((*insptr & VM_INSTMASK) == CON_ELSE))) \
|
|
|
|
{ \
|
|
|
|
insptr += 2; \
|
|
|
|
VM_Execute(0); \
|
|
|
|
} \
|
2014-10-29 17:05:46 +00:00
|
|
|
}
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2013-01-19 18:29:00 +00:00
|
|
|
#if !defined LUNATIC
|
2016-08-27 01:40:06 +00:00
|
|
|
void VM_ScriptInfo(intptr_t const *ptr, int range)
|
2016-05-23 04:47:22 +00:00
|
|
|
{
|
2018-11-18 18:11:44 +00:00
|
|
|
if (!apScript || (!vm.pSprite && !vm.pPlayer && g_currentEvent == -1))
|
2010-05-05 07:31:38 +00:00
|
|
|
return;
|
|
|
|
|
2016-01-07 03:30:07 +00:00
|
|
|
if (ptr)
|
2008-08-25 20:25:49 +00:00
|
|
|
{
|
2012-01-01 04:14:06 +00:00
|
|
|
initprintf("\n");
|
|
|
|
|
2018-10-16 06:09:54 +00:00
|
|
|
for (auto pScript = max<intptr_t const *>(ptr - (range >> 1), apScript),
|
|
|
|
p_end = min<intptr_t const *>(ptr + (range >> 1), apScript + g_scriptSize);
|
|
|
|
pScript < p_end;
|
|
|
|
++pScript)
|
2010-05-05 07:31:38 +00:00
|
|
|
{
|
2018-10-16 06:09:54 +00:00
|
|
|
initprintf("%5d: %3d: ", (int32_t)(pScript - apScript), (int32_t)(pScript - ptr));
|
2012-01-01 04:14:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (*pScript >> 12 && (*pScript & VM_INSTMASK) < CON_END)
|
2018-10-16 06:09:54 +00:00
|
|
|
initprintf("%5d %s\n", (int32_t)(*pScript >> 12), VM_GetKeywordForID(*pScript & VM_INSTMASK));
|
2015-01-11 04:56:10 +00:00
|
|
|
else
|
2018-10-16 06:09:54 +00:00
|
|
|
initprintf("%d\n", (int32_t)*pScript);
|
2010-05-05 07:31:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
initprintf("\n");
|
2008-08-25 20:25:49 +00:00
|
|
|
}
|
2010-05-05 07:31:38 +00:00
|
|
|
|
2016-01-07 03:30:07 +00:00
|
|
|
if (ptr == insptr)
|
|
|
|
{
|
2018-10-07 05:20:33 +00:00
|
|
|
if (vm.pUSprite)
|
2017-06-23 03:59:06 +00:00
|
|
|
initprintf("current actor: %d (%d)\n", vm.spriteNum, vm.pUSprite->picnum);
|
2010-05-05 07:31:38 +00:00
|
|
|
|
2016-01-07 03:30:07 +00:00
|
|
|
initprintf("g_errorLineNum: %d, g_tw: %d\n", g_errorLineNum, g_tw);
|
|
|
|
}
|
2008-08-25 20:25:49 +00:00
|
|
|
}
|
2016-05-23 04:47:22 +00:00
|
|
|
#endif
|
2008-08-25 20:25:49 +00:00
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static void VM_DeleteSprite(int const spriteNum, int const playerNum)
|
2013-02-21 18:54:07 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) spriteNum >= MAXSPRITES))
|
2013-08-06 23:51:51 +00:00
|
|
|
return;
|
2013-02-21 18:54:07 +00:00
|
|
|
|
2013-08-06 23:51:51 +00:00
|
|
|
// if player was set to squish, first stop that...
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(playerNum >= 0 && g_player[playerNum].ps->actorsqu == spriteNum))
|
|
|
|
g_player[playerNum].ps->actorsqu = -1;
|
2013-08-06 23:51:51 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_DeleteSprite(spriteNum);
|
2013-02-21 18:54:07 +00:00
|
|
|
}
|
|
|
|
|
2017-11-29 07:28:54 +00:00
|
|
|
intptr_t apScriptEvents[MAXEVENTS];
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2012-05-29 20:01:55 +00:00
|
|
|
// May recurse, e.g. through EVENT_XXX -> ... -> EVENT_KILLIT
|
2012-06-03 15:45:59 +00:00
|
|
|
#ifdef LUNATIC
|
2018-11-18 18:11:44 +00:00
|
|
|
static FORCE_INLINE int32_t VM_EventCommon__(int const &eventNum, int const &spriteNum, int const &playerNum, int const &playerDist, int32_t returnValue)
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
2018-04-12 21:02:51 +00:00
|
|
|
const double t = timerGetHiTicks();
|
2016-08-27 01:40:35 +00:00
|
|
|
int32_t ret = El_CallEvent(&g_ElState, eventNum, spriteNum, playerNum, playerDist, &returnValue);
|
2013-07-13 21:04:45 +00:00
|
|
|
|
2014-10-25 03:33:53 +00:00
|
|
|
// NOTE: the run times are those of the called event plus any events
|
|
|
|
// called by it, *not* "self" time.
|
2018-04-12 21:02:51 +00:00
|
|
|
g_eventTotalMs[eventNum] += timerGetHiTicks()-t;
|
2016-08-27 01:40:35 +00:00
|
|
|
g_eventCalls[eventNum]++;
|
2013-02-21 18:54:07 +00:00
|
|
|
|
2014-10-25 03:33:53 +00:00
|
|
|
if (ret == 1)
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_DeleteSprite(spriteNum, playerNum);
|
2014-11-22 12:29:25 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
return returnValue;
|
2014-11-22 12:29:25 +00:00
|
|
|
}
|
2013-02-21 18:54:07 +00:00
|
|
|
#else
|
2017-06-23 03:59:19 +00:00
|
|
|
// do not inline
|
|
|
|
static void VM_DummySprite(void)
|
|
|
|
{
|
|
|
|
static uspritetype dummy_sprite;
|
|
|
|
static actor_t dummy;
|
|
|
|
|
|
|
|
vm.pUSprite = &dummy_sprite;
|
|
|
|
vm.pActor = &dummy;
|
|
|
|
vm.pData = &dummy.t_data[0];
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
static FORCE_INLINE int32_t VM_EventCommon__(int const &eventNum, int const &spriteNum, int const &playerNum, int const &playerDist, int32_t returnValue)
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
2018-11-18 18:11:44 +00:00
|
|
|
double const t = timerGetHiTicks();
|
|
|
|
vmstate_t const tempvm = { spriteNum, playerNum, playerDist, 0, NULL, NULL, g_player[playerNum].ps, NULL };
|
2017-12-09 02:56:05 +00:00
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
auto & returnVar = aGameVars[g_returnVarID].global;
|
|
|
|
int const backupReturnVar = returnVar;
|
|
|
|
int const backupEvent = g_currentEvent;
|
2017-12-09 02:56:05 +00:00
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
returnVar = returnValue;
|
|
|
|
g_currentEvent = eventNum;
|
2014-11-22 12:29:25 +00:00
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const backupinsptr = insptr;
|
2018-11-18 18:11:44 +00:00
|
|
|
const vmstate_t vm_backup = vm;
|
2017-12-09 02:56:05 +00:00
|
|
|
|
|
|
|
insptr = apScript + apScriptEvents[eventNum];
|
|
|
|
vm = tempvm;
|
2014-11-22 12:29:25 +00:00
|
|
|
|
|
|
|
// check tempvm instead of vm... this way, we are not actually loading
|
|
|
|
// FROM vm anywhere until VM_Execute() is called
|
2017-06-23 03:59:19 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) tempvm.spriteNum >= MAXSPRITES))
|
|
|
|
VM_DummySprite();
|
2017-12-09 02:56:05 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
vm.pSprite = &sprite[spriteNum];
|
|
|
|
vm.pActor = &actor[spriteNum];
|
|
|
|
vm.pData = &actor[spriteNum].t_data[0];
|
|
|
|
}
|
2017-06-27 11:01:22 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if ((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers)
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pPlayer = g_player[0].ps;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2014-10-25 03:33:53 +00:00
|
|
|
VM_Execute(1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.flags & VM_KILL)
|
|
|
|
VM_DeleteSprite(vm.spriteNum, vm.playerNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-11-22 12:29:25 +00:00
|
|
|
// this needs to happen after VM_DeleteSprite() because VM_DeleteSprite()
|
|
|
|
// can trigger additional events
|
2012-05-16 00:45:10 +00:00
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
vm = vm_backup;
|
|
|
|
insptr = backupinsptr;
|
|
|
|
g_currentEvent = backupEvent;
|
|
|
|
returnValue = returnVar;
|
|
|
|
returnVar = backupReturnVar;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-04-12 21:02:51 +00:00
|
|
|
g_eventTotalMs[eventNum] += timerGetHiTicks()-t;
|
2018-03-08 00:29:41 +00:00
|
|
|
g_eventCalls[eventNum]++;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
return returnValue;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-11-22 12:29:25 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// the idea here is that the compiler inlines the call to VM_EventCommon_() and gives us a set of full functions
|
|
|
|
// which are not only optimized further based on lDist or iReturn (or both) having values known at compile time,
|
|
|
|
// but are called faster due to having less parameters
|
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
int32_t VM_OnEventWithBoth__(int const nEventID, int const spriteNum, int const playerNum, int const nDist, int32_t const nReturn)
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
2018-11-18 18:11:44 +00:00
|
|
|
return VM_EventCommon__(nEventID, spriteNum, playerNum, nDist, nReturn);
|
2014-11-22 12:29:25 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
int32_t VM_OnEventWithReturn__(int const nEventID, int const spriteNum, int const playerNum, int32_t const nReturn)
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
2018-11-18 18:11:44 +00:00
|
|
|
return VM_EventCommon__(nEventID, spriteNum, playerNum, -1, nReturn);
|
2014-11-22 12:29:25 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
int32_t VM_OnEventWithDist__(int const nEventID, int const spriteNum, int const playerNum, int const nDist)
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
2018-11-18 18:11:44 +00:00
|
|
|
return VM_EventCommon__(nEventID, spriteNum, playerNum, nDist, 0);
|
2014-11-22 12:29:25 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
int32_t VM_OnEvent__(int const nEventID, int const spriteNum, int const playerNum)
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
2018-11-18 18:11:44 +00:00
|
|
|
return VM_EventCommon__(nEventID, spriteNum, playerNum, -1, 0);
|
2014-11-22 12:29:25 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
static bool VM_CheckSquished(void)
|
2006-12-10 03:15:56 +00:00
|
|
|
{
|
2018-11-18 18:11:44 +00:00
|
|
|
auto const pSector = (usectortype *)§or[vm.pSprite->sectnum];
|
2006-12-10 03:15:56 +00:00
|
|
|
|
2018-11-18 18:11:44 +00:00
|
|
|
if (pSector->lotag == ST_23_SWINGING_DOOR || (vm.pSprite->picnum == APLAYER && ud.noclip) ||
|
2018-12-15 01:37:39 +00:00
|
|
|
(pSector->lotag == ST_1_ABOVE_WATER && !A_CheckNoSE7Water(vm.pUSprite, vm.pSprite->sectnum, pSector->lotag, NULL)))
|
2010-05-02 23:27:30 +00:00
|
|
|
return 0;
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int32_t floorZ = pSector->floorz;
|
|
|
|
int32_t ceilZ = pSector->ceilingz;
|
2011-10-03 17:44:06 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2016-03-14 00:07:12 +00:00
|
|
|
int16_t cb, fb;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
yax_getbunches(vm.pSprite->sectnum, &cb, &fb);
|
2011-10-03 17:44:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (cb >= 0 && (pSector->ceilingstat&512)==0) // if ceiling non-blocking...
|
2016-08-27 01:40:56 +00:00
|
|
|
ceilZ -= ZOFFSET5; // unconditionally don't squish... yax_getneighborsect is slowish :/
|
2016-08-27 01:40:35 +00:00
|
|
|
if (fb >= 0 && (pSector->floorstat&512)==0)
|
2016-08-27 01:40:56 +00:00
|
|
|
floorZ += ZOFFSET5;
|
2011-10-03 17:44:06 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (vm.pSprite->pal == 1 ? (floorZ - ceilZ >= ZOFFSET5 || (pSector->lotag & 32768u)) : (floorZ - ceilZ >= ZOFFSET4))
|
2018-11-18 18:11:27 +00:00
|
|
|
return 0;
|
2016-06-05 04:46:28 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
P_DoQuote(QUOTE_SQUISHED, vm.pPlayer);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckEnemySprite(vm.pSprite))
|
|
|
|
vm.pSprite->xvel = 0;
|
2006-12-10 03:15:56 +00:00
|
|
|
|
2018-11-18 18:11:27 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(vm.pSprite->pal == 1)) // frozen
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pActor->picnum = SHOTSPARK1;
|
|
|
|
vm.pActor->extra = 1;
|
2010-05-02 23:27:30 +00:00
|
|
|
return 0;
|
2006-12-10 03:15:56 +00:00
|
|
|
}
|
2018-11-18 18:11:27 +00:00
|
|
|
#endif
|
2010-05-02 23:27:30 +00:00
|
|
|
|
|
|
|
return 1;
|
2006-12-10 03:15:56 +00:00
|
|
|
}
|
|
|
|
|
2014-04-19 22:42:22 +00:00
|
|
|
#if !defined LUNATIC
|
2016-08-27 01:40:35 +00:00
|
|
|
GAMEEXEC_STATIC GAMEEXEC_INLINE void P_ForceAngle(DukePlayer_t *pPlayer)
|
2006-12-10 06:49:01 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int const nAngle = 128-(krand()&255);
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
pPlayer->q16horiz += F16(64);
|
2016-08-27 01:40:35 +00:00
|
|
|
pPlayer->return_to_center = 9;
|
|
|
|
pPlayer->rotscrnang = nAngle >> 1;
|
|
|
|
pPlayer->look_ang = pPlayer->rotscrnang;
|
2006-12-10 06:49:01 +00:00
|
|
|
}
|
2014-04-19 22:42:22 +00:00
|
|
|
#endif
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
// wow, this function sucks
|
2017-06-25 11:23:41 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C"
|
|
|
|
#endif
|
2018-11-18 18:11:27 +00:00
|
|
|
bool A_Dodge(spritetype * const);
|
|
|
|
bool A_Dodge(spritetype * const pSprite)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (A_CheckEnemySprite(pSprite) && pSprite->extra <= 0) // hack
|
2008-12-01 10:44:18 +00:00
|
|
|
return 0;
|
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
vec2_t const msin = { sintable[(pSprite->ang + 512) & 2047], sintable[pSprite->ang & 2047] };
|
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t nexti, SPRITES_OF_STAT_SAFE(STAT_PROJECTILE, i, nexti)) //weapons list
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (OW(i) == i)
|
2006-04-13 20:47:06 +00:00
|
|
|
continue;
|
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
vec2_t const b = { SX(i) - pSprite->x, SY(i) - pSprite->y };
|
2016-08-27 01:40:35 +00:00
|
|
|
vec2_t const v = { sintable[(SA(i) + 512) & 2047], sintable[SA(i) & 2047] };
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (((msin.x * b.x) + (msin.y * b.y) >= 0) && ((v.x * b.x) + (v.y * b.y) < 0))
|
2011-02-25 21:50:19 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (klabs((v.x * b.y) - (v.y * b.x)) < 65536 << 6)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pSprite->ang -= 512+(krand()&1024);
|
2011-02-25 21:50:19 +00:00
|
|
|
return 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2011-02-25 21:50:19 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2015-02-18 20:46:53 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:11:27 +00:00
|
|
|
int A_GetFurthestAngle(int spriteNum, int angDiv)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:11:27 +00:00
|
|
|
auto const pSprite = (uspritetype *)&sprite[spriteNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pSprite->picnum != APLAYER && (AC_COUNT(actor[spriteNum].t_data)&63) > 2)
|
|
|
|
return pSprite->ang + 1024;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-11-18 18:11:27 +00:00
|
|
|
int furthestAngle = 0;
|
2017-06-23 03:59:19 +00:00
|
|
|
int const angIncs = tabledivide32_noinline(2048, angDiv);
|
2018-11-18 18:11:27 +00:00
|
|
|
int32_t greatestDist = INT32_MIN;
|
2015-02-18 20:46:53 +00:00
|
|
|
hitdata_t hit;
|
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t j = pSprite->ang; j < (2048 + pSprite->ang); j += angIncs)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z -= ZOFFSET3;
|
2018-05-22 19:03:44 +00:00
|
|
|
hitscan((const vec3_t *)pSprite, pSprite->sectnum, sintable[(j + 512) & 2047], sintable[j & 2047], 0, &hit, CLIPMASK1);
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z += ZOFFSET3;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
int const hitDist = klabs(hit.pos.x-pSprite->x) + klabs(hit.pos.y-pSprite->y);
|
2015-02-18 20:46:53 +00:00
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
if (hitDist > greatestDist)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
greatestDist = hitDist;
|
|
|
|
furthestAngle = j;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2015-02-18 20:46:53 +00:00
|
|
|
|
2018-11-18 18:11:27 +00:00
|
|
|
return furthestAngle & 2047;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
int A_FurthestVisiblePoint(int const spriteNum, uspritetype * const ts, vec2_t * const vect)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (AC_COUNT(actor[spriteNum].t_data)&63)
|
2012-05-14 18:12:27 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
const uspritetype *const pnSprite = (uspritetype *)&sprite[spriteNum];
|
2015-02-18 20:46:53 +00:00
|
|
|
|
|
|
|
hitdata_t hit;
|
2016-08-27 01:40:06 +00:00
|
|
|
int const angincs = 128;
|
|
|
|
// ((!g_netServer && ud.multimode < 2) && ud.player_skill < 3) ? 2048 / 2 : tabledivide32_noinline(2048, 1 + (krand() & 1));
|
2015-02-18 20:46:53 +00:00
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t j = ts->ang; j < (2048 + ts->ang); j += (angincs /*-(krand()&511)*/))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-09-06 04:25:32 +00:00
|
|
|
ts->z -= ZOFFSET2;
|
2018-05-22 19:03:44 +00:00
|
|
|
hitscan((const vec3_t *)ts, ts->sectnum, sintable[(j + 512) & 2047], sintable[j & 2047], 16384 - (krand() & 32767), &hit, CLIPMASK1);
|
2016-09-06 04:25:32 +00:00
|
|
|
ts->z += ZOFFSET2;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (hit.sect < 0)
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-09-06 04:25:32 +00:00
|
|
|
int const d = FindDistance2D(hit.pos.x - ts->x, hit.pos.y - ts->y);
|
2016-08-27 01:40:06 +00:00
|
|
|
int const da = FindDistance2D(hit.pos.x - pnSprite->x, hit.pos.y - pnSprite->y);
|
2015-02-18 20:46:53 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (d < da)
|
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (cansee(hit.pos.x, hit.pos.y, hit.pos.z, hit.sect, pnSprite->x, pnSprite->y, pnSprite->z - ZOFFSET2, pnSprite->sectnum))
|
2015-02-18 20:46:53 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
vect->x = hit.pos.x;
|
|
|
|
vect->y = hit.pos.y;
|
2015-02-18 20:46:53 +00:00
|
|
|
return hit.sect;
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2015-02-18 20:46:53 +00:00
|
|
|
|
|
|
|
return -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static void VM_GetZRange(int const spriteNum, int32_t * const ceilhit, int32_t * const florhit, int const wallDist)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
uspritetype *const pSprite = (uspritetype *)&sprite[spriteNum];
|
2016-09-06 04:25:32 +00:00
|
|
|
int const ocstat = pSprite->cstat;
|
2009-01-19 06:41:28 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->cstat = 0;
|
|
|
|
pSprite->z -= ZOFFSET;
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
getzrange((vec3_t *)pSprite, pSprite->sectnum, &actor[spriteNum].ceilingz, ceilhit, &actor[spriteNum].floorz, florhit, wallDist, CLIPMASK0);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z += ZOFFSET;
|
|
|
|
pSprite->cstat = ocstat;
|
2015-02-18 20:46:53 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
void A_GetZLimits(int const spriteNum)
|
2015-02-18 20:46:53 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const pSprite = &sprite[spriteNum];
|
|
|
|
int32_t ceilhit, florhit;
|
2015-02-18 20:46:53 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_GetZRange(spriteNum, &ceilhit, &florhit, (pSprite->statnum == STAT_PROJECTILE) ? 4 : 127);
|
|
|
|
actor[spriteNum].flags &= ~SFLAG_NOFLOORSHADOW;
|
2012-01-12 20:48:00 +00:00
|
|
|
|
2015-02-18 20:46:53 +00:00
|
|
|
if ((florhit&49152) == 49152 && (sprite[florhit&(MAXSPRITES-1)].cstat&48) == 0)
|
2014-10-25 03:36:34 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const hitspr = (uspritetype *)&sprite[florhit&(MAXSPRITES-1)];
|
2011-12-21 18:42:49 +00:00
|
|
|
|
2015-02-18 20:46:53 +00:00
|
|
|
florhit &= (MAXSPRITES-1);
|
2011-12-21 18:42:49 +00:00
|
|
|
|
2015-02-18 20:46:53 +00:00
|
|
|
// If a non-projectile would fall onto non-frozen enemy OR an enemy onto a player...
|
2016-08-27 01:40:06 +00:00
|
|
|
if ((A_CheckEnemySprite(hitspr) && hitspr->pal != 1 && pSprite->statnum != STAT_PROJECTILE)
|
|
|
|
|| (hitspr->picnum == APLAYER && A_CheckEnemySprite(pSprite)))
|
2014-10-25 03:36:34 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
actor[spriteNum].flags |= SFLAG_NOFLOORSHADOW; // No shadows on actors
|
2016-08-27 01:40:06 +00:00
|
|
|
pSprite->xvel = -256; // SLIDE_ABOVE_ENEMY
|
2016-08-27 01:40:35 +00:00
|
|
|
A_SetSprite(spriteNum, CLIPMASK0);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (pSprite->statnum == STAT_PROJECTILE && hitspr->picnum == APLAYER && pSprite->owner==florhit)
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
actor[spriteNum].ceilingz = sector[pSprite->sectnum].ceilingz;
|
|
|
|
actor[spriteNum].floorz = sector[pSprite->sectnum].floorz;
|
2010-08-02 08:13:51 +00:00
|
|
|
}
|
2014-10-25 03:36:34 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
void A_Fall(int const spriteNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const pSprite = &sprite[spriteNum];
|
2016-08-27 01:40:35 +00:00
|
|
|
int spriteGravity = g_spriteGravity;
|
2015-02-18 20:46:53 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(G_CheckForSpaceFloor(pSprite->sectnum)))
|
2016-08-27 01:40:35 +00:00
|
|
|
spriteGravity = 0;
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (sector[pSprite->sectnum].lotag == ST_2_UNDERWATER || EDUKE32_PREDICT_FALSE(G_CheckForSpaceCeiling(pSprite->sectnum)))
|
2016-08-27 01:40:35 +00:00
|
|
|
spriteGravity = g_spriteGravity/6;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (pSprite->statnum == STAT_ACTOR || pSprite->statnum == STAT_PLAYER || pSprite->statnum == STAT_ZOMBIEACTOR
|
|
|
|
|| pSprite->statnum == STAT_STANDABLE)
|
2009-01-13 12:23:18 +00:00
|
|
|
{
|
2015-02-18 20:46:53 +00:00
|
|
|
int32_t ceilhit, florhit;
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_GetZRange(spriteNum, &ceilhit, &florhit, 127);
|
2009-01-13 12:23:18 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
actor[spriteNum].ceilingz = sector[pSprite->sectnum].ceilingz;
|
|
|
|
actor[spriteNum].floorz = sector[pSprite->sectnum].floorz;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2011-05-07 18:23:34 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2016-08-27 01:40:06 +00:00
|
|
|
int fbunch = (sector[pSprite->sectnum].floorstat&512) ? -1 : yax_getbunch(pSprite->sectnum, YAX_FLOOR);
|
2011-05-07 18:23:34 +00:00
|
|
|
#endif
|
2013-04-15 10:48:18 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pSprite->z < actor[spriteNum].floorz-ZOFFSET
|
2011-05-07 18:23:34 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2013-04-15 10:48:18 +00:00
|
|
|
|| fbunch >= 0
|
2011-05-07 18:23:34 +00:00
|
|
|
#endif
|
2012-05-14 18:12:27 +00:00
|
|
|
)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (sector[pSprite->sectnum].lotag == ST_2_UNDERWATER && pSprite->zvel > 3122)
|
|
|
|
pSprite->zvel = 3144;
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z += pSprite->zvel = min(6144, pSprite->zvel+spriteGravity);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2013-04-15 10:48:18 +00:00
|
|
|
|
2011-05-07 18:23:34 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
if (fbunch >= 0)
|
2016-08-27 01:40:35 +00:00
|
|
|
setspritez(spriteNum, (vec3_t *)pSprite);
|
2013-04-15 10:48:18 +00:00
|
|
|
else
|
2011-05-07 18:23:34 +00:00
|
|
|
#endif
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pSprite->z >= actor[spriteNum].floorz-ZOFFSET)
|
2012-05-14 18:12:27 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z = actor[spriteNum].floorz-ZOFFSET;
|
2016-08-27 01:40:06 +00:00
|
|
|
pSprite->zvel = 0;
|
2012-05-14 18:12:27 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:11:27 +00:00
|
|
|
int __fastcall G_GetAngleDelta(int currAngle, int newAngle)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
currAngle &= 2047;
|
|
|
|
newAngle &= 2047;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (klabs(currAngle-newAngle) < 1024)
|
2007-03-11 00:20:32 +00:00
|
|
|
{
|
2008-11-20 14:06:36 +00:00
|
|
|
// OSD_Printf("G_GetAngleDelta() returning %d\n",na-a);
|
2016-08-27 01:40:35 +00:00
|
|
|
return newAngle-currAngle;
|
2007-03-11 00:47:32 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (newAngle > 1024)
|
|
|
|
newAngle -= 2048;
|
|
|
|
if (currAngle > 1024)
|
|
|
|
currAngle -= 2048;
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
// OSD_Printf("G_GetAngleDelta() returning %d\n",na-a);
|
2016-08-27 01:40:35 +00:00
|
|
|
return newAngle-currAngle;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
GAMEEXEC_STATIC void VM_AlterAng(int32_t const moveFlags)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int const elapsedTics = (AC_COUNT(vm.pData))&31;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-02-07 21:00:48 +00:00
|
|
|
#if !defined LUNATIC
|
2011-12-21 18:40:47 +00:00
|
|
|
const intptr_t *moveptr;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)AC_MOVE_ID(vm.pData) >= (unsigned)g_scriptSize-1))
|
2012-03-11 17:37:50 +00:00
|
|
|
|
2010-08-07 22:52:58 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
AC_MOVE_ID(vm.pData) = 0;
|
2017-06-23 03:59:06 +00:00
|
|
|
OSD_Printf(OSD_ERROR "bad moveptr for actor %d (%d)!\n", vm.spriteNum, vm.pUSprite->picnum);
|
2010-08-07 22:59:46 +00:00
|
|
|
return;
|
2010-08-07 22:52:58 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
moveptr = apScript + AC_MOVE_ID(vm.pData);
|
2011-12-21 18:40:47 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->xvel += (moveptr[0] - vm.pSprite->xvel)/5;
|
|
|
|
if (vm.pSprite->zvel < 648)
|
|
|
|
vm.pSprite->zvel += ((moveptr[1]<<4) - vm.pSprite->zvel)/5;
|
2012-06-03 15:46:08 +00:00
|
|
|
#else
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pSprite->xvel += (vm.pActor->mv.hvel - vm.pSprite->xvel)/5;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->zvel < 648)
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pSprite->zvel += ((vm.pActor->mv.vvel<<4) - vm.pSprite->zvel)/5;
|
2012-06-03 15:46:08 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->extra <= 0) // hack
|
2008-12-01 10:44:18 +00:00
|
|
|
return;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (moveFlags&seekplayer)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int const spriteAngle = vm.pSprite->ang;
|
2017-06-23 03:58:54 +00:00
|
|
|
int const holoDukeSprite = vm.pPlayer->holoduke_on;
|
2008-09-03 04:20:46 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
// NOTE: looks like 'owner' is set to target sprite ID...
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
vm.pSprite->owner = (holoDukeSprite >= 0
|
|
|
|
&& cansee(sprite[holoDukeSprite].x, sprite[holoDukeSprite].y, sprite[holoDukeSprite].z, sprite[holoDukeSprite].sectnum,
|
|
|
|
vm.pSprite->x, vm.pSprite->y, vm.pSprite->z, vm.pSprite->sectnum))
|
2016-09-06 04:25:32 +00:00
|
|
|
? holoDukeSprite
|
|
|
|
: vm.pPlayer->i;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
int const goalAng = (sprite[vm.pSprite->owner].picnum == APLAYER)
|
2017-06-23 03:59:19 +00:00
|
|
|
? getangle(vm.pActor->lastv.x - vm.pSprite->x, vm.pActor->lastv.y - vm.pSprite->y)
|
2016-09-06 04:25:32 +00:00
|
|
|
: getangle(sprite[vm.pSprite->owner].x - vm.pSprite->x, sprite[vm.pSprite->owner].y - vm.pSprite->y);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->xvel && vm.pSprite->picnum != DRONE)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2017-06-23 03:58:54 +00:00
|
|
|
int const angDiff = G_GetAngleDelta(spriteAngle, goalAng);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (elapsedTics < 2)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (klabs(angDiff) < 256)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
int const angInc = 128-(krand()&256);
|
|
|
|
vm.pSprite->ang += angInc;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_GetHitscanRange(vm.spriteNum) < 844)
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pSprite->ang -= angInc;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (elapsedTics > 18 && elapsedTics < GAMETICSPERSEC) // choose
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (klabs(angDiff >> 2) < 128)
|
|
|
|
vm.pSprite->ang = goalAng;
|
|
|
|
else
|
|
|
|
vm.pSprite->ang += angDiff >> 2;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
else
|
|
|
|
vm.pSprite->ang = goalAng;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (elapsedTics < 1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (moveFlags&furthestdir)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->ang = A_GetFurthestAngle(vm.spriteNum, 2);
|
|
|
|
vm.pSprite->owner = vm.pPlayer->i;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (moveFlags&fleeenemy)
|
|
|
|
vm.pSprite->ang = A_GetFurthestAngle(vm.spriteNum, 2);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static inline void VM_AddAngle(int const shift, int const goalAng)
|
2012-06-07 17:38:01 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int angDiff = G_GetAngleDelta(vm.pSprite->ang, goalAng) >> shift;
|
2012-06-07 17:38:01 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((angDiff > -8 && angDiff < 0) || (angDiff < 8 && angDiff > 0))
|
|
|
|
angDiff <<= 1;
|
2012-06-07 17:38:01 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->ang += angDiff;
|
2012-06-07 17:38:01 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static inline void VM_FacePlayer(int const shift)
|
2012-06-07 17:38:01 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_AddAngle(shift, (vm.pPlayer->newowner >= 0) ? getangle(vm.pPlayer->opos.x - vm.pSprite->x, vm.pPlayer->opos.y - vm.pSprite->y)
|
|
|
|
: getangle(vm.pPlayer->pos.x - vm.pSprite->x, vm.pPlayer->pos.y - vm.pSprite->y));
|
2012-06-07 17:38:01 +00:00
|
|
|
}
|
|
|
|
|
2013-04-12 11:59:35 +00:00
|
|
|
////////// TROR get*zofslope //////////
|
|
|
|
// These rather belong into the engine.
|
|
|
|
|
2014-11-22 12:29:25 +00:00
|
|
|
static int32_t VM_GetCeilZOfSlope(void)
|
2013-04-12 11:59:35 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vec2_t const vect = *(vec2_t *)vm.pSprite;
|
|
|
|
int const sectnum = vm.pSprite->sectnum;
|
2014-11-22 12:29:25 +00:00
|
|
|
|
2013-04-12 11:59:35 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
if ((sector[sectnum].ceilingstat&512)==0)
|
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int const nsect = yax_getneighborsect(vect.x, vect.y, sectnum, YAX_CEILING);
|
2013-04-12 11:59:35 +00:00
|
|
|
if (nsect >= 0)
|
2016-08-27 01:40:06 +00:00
|
|
|
return getceilzofslope(nsect, vect.x, vect.y);
|
2013-04-12 11:59:35 +00:00
|
|
|
}
|
|
|
|
#endif
|
2016-08-27 01:40:06 +00:00
|
|
|
return getceilzofslope(sectnum, vect.x, vect.y);
|
2013-04-12 11:59:35 +00:00
|
|
|
}
|
|
|
|
|
2018-11-18 18:13:55 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2014-11-22 12:29:25 +00:00
|
|
|
static int32_t VM_GetFlorZOfSlope(void)
|
2013-04-12 11:59:35 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vec2_t const vect = *(vec2_t *)vm.pSprite;
|
|
|
|
int const sectnum = vm.pSprite->sectnum;
|
2014-11-22 12:29:25 +00:00
|
|
|
|
2013-04-12 11:59:35 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
if ((sector[sectnum].floorstat&512)==0)
|
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int const nsect = yax_getneighborsect(vect.x, vect.y, sectnum, YAX_FLOOR);
|
2013-04-12 11:59:35 +00:00
|
|
|
if (nsect >= 0)
|
2016-08-27 01:40:06 +00:00
|
|
|
return getflorzofslope(nsect, vect.x, vect.y);
|
2013-04-12 11:59:35 +00:00
|
|
|
}
|
|
|
|
#endif
|
2016-08-27 01:40:06 +00:00
|
|
|
return getflorzofslope(sectnum, vect.x, vect.y);
|
2013-04-12 11:59:35 +00:00
|
|
|
}
|
2018-11-18 18:13:55 +00:00
|
|
|
#endif
|
2013-04-12 11:59:35 +00:00
|
|
|
|
|
|
|
////////////////////
|
|
|
|
|
2015-02-05 16:30:13 +00:00
|
|
|
static int32_t A_GetWaterZOffset(int spritenum);
|
|
|
|
|
2010-05-02 23:27:30 +00:00
|
|
|
GAMEEXEC_STATIC void VM_Move(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-01-15 23:13:50 +00:00
|
|
|
auto const movflagsptr = &AC_MOVFLAGS(vm.pSprite, &actor[vm.spriteNum]);
|
|
|
|
// NOTE: test against -1 commented out and later revived in source history
|
|
|
|
// XXX: Does its presence/absence break anything? Where are movflags with all bits set created?
|
|
|
|
int const movflags = (*movflagsptr == (std::remove_pointer<decltype(movflagsptr)>::type)-1) ? 0 : *movflagsptr;
|
2016-08-27 01:40:35 +00:00
|
|
|
int const deadflag = (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->extra <= 0);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
AC_COUNT(vm.pData)++;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (AC_MOVE_ID(vm.pData) == 0 || movflags == 0)
|
2008-12-01 10:44:18 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
if (deadflag || (vm.pActor->bpos.x != vm.pSprite->x) || (vm.pActor->bpos.y != vm.pSprite->y))
|
2008-12-01 10:44:18 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pActor->bpos.x = vm.pSprite->x;
|
|
|
|
vm.pActor->bpos.y = vm.pSprite->y;
|
2016-08-27 01:40:35 +00:00
|
|
|
setsprite(vm.spriteNum, (vec3_t *)vm.pSprite);
|
2008-12-01 10:44:18 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-30 20:38:45 +00:00
|
|
|
if (deadflag)
|
|
|
|
goto dead;
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2013-06-30 20:38:45 +00:00
|
|
|
if (movflags&face_player)
|
2013-02-07 21:00:48 +00:00
|
|
|
VM_FacePlayer(2);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-06-30 20:38:45 +00:00
|
|
|
if (movflags&spin)
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->ang += sintable[((AC_COUNT(vm.pData)<<3)&2047)]>>6;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-06-30 20:38:45 +00:00
|
|
|
if (movflags&face_player_slow)
|
2013-02-07 21:00:48 +00:00
|
|
|
VM_FacePlayer(4);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-03-16 14:37:52 +00:00
|
|
|
if ((movflags&jumptoplayer_bits) == jumptoplayer_bits)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (AC_COUNT(vm.pData) < 16)
|
|
|
|
vm.pSprite->zvel -= (sintable[(512+(AC_COUNT(vm.pData)<<4))&2047]>>5);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2013-06-30 20:38:45 +00:00
|
|
|
if (movflags&face_player_smart)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
vec2_t const vect = { vm.pPlayer->pos.x + (vm.pPlayer->vel.x / 768), vm.pPlayer->pos.y + (vm.pPlayer->vel.y / 768) };
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_AddAngle(2, getangle(vect.x - vm.pSprite->x, vect.y - vm.pSprite->y));
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
dead:
|
2013-02-07 21:00:48 +00:00
|
|
|
#if !defined LUNATIC
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)AC_MOVE_ID(vm.pData) >= (unsigned)g_scriptSize-1))
|
2010-08-07 22:52:58 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
AC_MOVE_ID(vm.pData) = 0;
|
2017-06-23 03:59:06 +00:00
|
|
|
OSD_Printf(OSD_ERROR "clearing bad moveptr for actor %d (%d)\n", vm.spriteNum, vm.pUSprite->picnum);
|
2010-08-07 22:59:46 +00:00
|
|
|
return;
|
2010-08-07 22:38:15 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const moveptr = apScript + AC_MOVE_ID(vm.pData);
|
2011-12-21 18:40:47 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (movflags & geth)
|
|
|
|
vm.pSprite->xvel += ((moveptr[0]) - vm.pSprite->xvel) >> 1;
|
|
|
|
if (movflags & getv)
|
|
|
|
vm.pSprite->zvel += ((moveptr[1] << 4) - vm.pSprite->zvel) >> 1;
|
2012-06-03 15:46:08 +00:00
|
|
|
#else
|
2018-05-22 19:03:44 +00:00
|
|
|
if (movflags & geth)
|
|
|
|
vm.pSprite->xvel += (vm.pActor->mv.hvel - vm.pSprite->xvel) >> 1;
|
|
|
|
if (movflags & getv)
|
|
|
|
vm.pSprite->zvel += (16 * vm.pActor->mv.vvel - vm.pSprite->zvel) >> 1;
|
2012-06-03 15:46:08 +00:00
|
|
|
#endif
|
2011-03-04 08:50:58 +00:00
|
|
|
|
2013-06-30 20:38:45 +00:00
|
|
|
if (movflags&dodgebullet && !deadflag)
|
2016-08-27 01:40:35 +00:00
|
|
|
A_Dodge(vm.pSprite);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->picnum != APLAYER)
|
2013-06-30 20:38:45 +00:00
|
|
|
VM_AlterAng(movflags);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->xvel > -6 && vm.pSprite->xvel < 6)
|
|
|
|
vm.pSprite->xvel = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int badguyp = A_CheckEnemySprite(vm.pSprite);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->xvel || vm.pSprite->zvel)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:50 +00:00
|
|
|
int spriteXvel = vm.pSprite->xvel;
|
|
|
|
int angDiff = vm.pSprite->ang;
|
2012-06-07 17:38:01 +00:00
|
|
|
|
2018-11-18 18:13:55 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:35 +00:00
|
|
|
if (badguyp && vm.pSprite->picnum != ROTATEGUN)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((vm.pSprite->picnum == DRONE || vm.pSprite->picnum == COMMANDER) && vm.pSprite->extra > 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->picnum == COMMANDER)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int32_t nSectorZ;
|
2013-04-12 11:59:26 +00:00
|
|
|
// NOTE: COMMANDER updates both actor[].floorz and
|
|
|
|
// .ceilingz regardless of its zvel.
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pActor->floorz = nSectorZ = VM_GetFlorZOfSlope();
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->z > nSectorZ-ZOFFSET3)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->z = nSectorZ-ZOFFSET3;
|
|
|
|
vm.pSprite->zvel = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pActor->ceilingz = nSectorZ = VM_GetCeilZOfSlope();
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->z < nSectorZ+(80<<8))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->z = nSectorZ+(80<<8);
|
|
|
|
vm.pSprite->zvel = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int32_t nSectorZ;
|
2013-04-12 11:59:26 +00:00
|
|
|
// The DRONE updates either .floorz or .ceilingz, not both.
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->zvel > 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pActor->floorz = nSectorZ = VM_GetFlorZOfSlope();
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->z > nSectorZ-(30<<8))
|
|
|
|
vm.pSprite->z = nSectorZ-(30<<8);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pActor->ceilingz = nSectorZ = VM_GetCeilZOfSlope();
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->z < nSectorZ+(50<<8))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->z = nSectorZ+(50<<8);
|
|
|
|
vm.pSprite->zvel = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (vm.pSprite->picnum != ORGANTIC)
|
2018-11-18 18:13:55 +00:00
|
|
|
#else
|
|
|
|
if (badguyp)
|
|
|
|
{
|
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2015-02-18 20:46:49 +00:00
|
|
|
// All other actors besides ORGANTIC don't update .floorz or
|
|
|
|
// .ceilingz here.
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->zvel > 0)
|
2015-02-05 16:30:12 +00:00
|
|
|
{
|
2017-06-23 03:59:19 +00:00
|
|
|
if (vm.pSprite->z > vm.pActor->floorz)
|
|
|
|
vm.pSprite->z = vm.pActor->floorz;
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->z += A_GetWaterZOffset(vm.spriteNum);
|
2015-02-05 16:30:12 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (vm.pSprite->zvel < 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int const l = VM_GetCeilZOfSlope();
|
2015-02-18 20:46:49 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->z < l+(66<<8))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->z = l+(66<<8);
|
|
|
|
vm.pSprite->zvel >>= 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.playerDist < 960 && vm.pSprite->xrepeat > 16)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:50 +00:00
|
|
|
spriteXvel = -(1024 - vm.playerDist);
|
2016-08-27 01:40:35 +00:00
|
|
|
angDiff = getangle(vm.pPlayer->pos.x - vm.pSprite->x, vm.pPlayer->pos.y - vm.pSprite->y);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.playerDist < 512)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pPlayer->vel.x = 0;
|
|
|
|
vm.pPlayer->vel.y = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pPlayer->vel.x = mulscale16(vm.pPlayer->vel.x, vm.pPlayer->runspeed - 0x2000);
|
|
|
|
vm.pPlayer->vel.y = mulscale16(vm.pPlayer->vel.y, vm.pPlayer->runspeed - 0x2000);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2018-11-18 18:13:55 +00:00
|
|
|
else
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
if (vm.pSprite->picnum != DRONE && vm.pSprite->picnum != SHARK && vm.pSprite->picnum != COMMANDER)
|
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pPlayer->actorsqu == vm.spriteNum)
|
2013-06-30 20:38:48 +00:00
|
|
|
return;
|
2012-10-30 15:54:35 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (!A_CheckSpriteFlags(vm.spriteNum, SFLAG_SMOOTHMOVE))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (AC_COUNT(vm.pData) & 1)
|
2013-06-30 20:38:48 +00:00
|
|
|
return;
|
2016-08-27 01:41:50 +00:00
|
|
|
spriteXvel <<= 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (vm.pSprite->picnum == APLAYER)
|
2017-06-23 03:59:19 +00:00
|
|
|
if (vm.pSprite->z < vm.pActor->ceilingz+ZOFFSET5)
|
|
|
|
vm.pSprite->z = vm.pActor->ceilingz+ZOFFSET5;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
vec3_t const vect
|
|
|
|
= { (spriteXvel * (sintable[(angDiff + 512) & 2047])) >> 14, (spriteXvel * (sintable[angDiff & 2047])) >> 14, vm.pSprite->zvel };
|
2009-01-13 04:40:56 +00:00
|
|
|
|
2017-06-23 03:59:19 +00:00
|
|
|
vm.pActor->movflag = A_MoveSprite(vm.spriteNum, &vect, (A_CheckSpriteFlags(vm.spriteNum, SFLAG_NOCLIP) ? 0 : CLIPMASK0));
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2013-06-30 20:38:45 +00:00
|
|
|
if (!badguyp)
|
2012-06-07 17:38:01 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.pSprite->shade += (sector[vm.pSprite->sectnum].ceilingstat & 1) ? (sector[vm.pSprite->sectnum].ceilingshade - vm.pSprite->shade) >> 1
|
|
|
|
: (sector[vm.pSprite->sectnum].floorshade - vm.pSprite->shade) >> 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static void P_AddWeaponMaybeSwitch(DukePlayer_t * const ps, int const weaponNum)
|
2012-08-10 19:11:47 +00:00
|
|
|
{
|
2014-10-29 17:05:46 +00:00
|
|
|
if ((ps->weaponswitch & (1|4)) == (1|4))
|
2012-08-27 03:52:38 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int const playerNum = P_Get(ps->i);
|
2016-08-27 01:40:06 +00:00
|
|
|
int new_wchoice = -1;
|
|
|
|
int curr_wchoice = -1;
|
2012-08-27 03:52:38 +00:00
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=0; i<=FREEZE_WEAPON && (new_wchoice < 0 || curr_wchoice < 0); i++)
|
2012-08-27 03:52:38 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int w = g_player[playerNum].wchoice[i];
|
2012-08-27 03:52:38 +00:00
|
|
|
|
2013-12-26 19:44:56 +00:00
|
|
|
if (w == KNEE_WEAPON)
|
|
|
|
w = FREEZE_WEAPON;
|
2018-05-22 19:03:44 +00:00
|
|
|
else
|
|
|
|
w--;
|
2012-08-27 03:52:38 +00:00
|
|
|
|
|
|
|
if (w == ps->curr_weapon)
|
|
|
|
curr_wchoice = i;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (w == weaponNum)
|
2012-08-27 03:52:38 +00:00
|
|
|
new_wchoice = i;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
P_AddWeapon(ps, weaponNum, (new_wchoice < curr_wchoice));
|
2012-08-27 03:52:38 +00:00
|
|
|
}
|
|
|
|
else
|
2013-12-26 19:45:00 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
P_AddWeapon(ps, weaponNum, (ps->weaponswitch & 1));
|
2013-12-26 19:45:00 +00:00
|
|
|
}
|
2012-08-10 19:11:47 +00:00
|
|
|
}
|
|
|
|
|
2013-02-24 16:05:47 +00:00
|
|
|
#if defined LUNATIC
|
2018-05-22 19:03:44 +00:00
|
|
|
void P_AddWeaponMaybeSwitchI(int32_t snum, int32_t weap) { P_AddWeaponMaybeSwitch(g_player[snum].ps, weap); }
|
2013-02-24 16:05:47 +00:00
|
|
|
#else
|
2017-06-23 03:58:54 +00:00
|
|
|
static void P_AddWeaponAmmoCommon(DukePlayer_t * const pPlayer, int const weaponNum, int const nAmount)
|
2012-08-10 19:11:47 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
P_AddAmmo(pPlayer, weaponNum, nAmount);
|
2012-08-10 19:11:47 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (PWEAPON(vm.playerNum, pPlayer->curr_weapon, WorksLike) == KNEE_WEAPON && (pPlayer->gotweapon & (1 << weaponNum)))
|
|
|
|
P_AddWeaponMaybeSwitch(pPlayer, weaponNum);
|
2012-08-10 19:11:47 +00:00
|
|
|
}
|
|
|
|
|
2017-07-05 05:38:05 +00:00
|
|
|
static void VM_AddWeapon(DukePlayer_t * const pPlayer, int const weaponNum, int const nAmount)
|
2012-08-10 19:11:47 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)weaponNum >= MAX_WEAPONS))
|
2012-08-10 19:11:47 +00:00
|
|
|
{
|
2017-07-08 19:41:55 +00:00
|
|
|
CON_ERRPRINTF("invalid weapon %d\n", weaponNum);
|
2017-07-05 05:38:05 +00:00
|
|
|
return;
|
2012-08-10 19:11:47 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((pPlayer->gotweapon & (1 << weaponNum)) == 0)
|
2012-08-10 19:11:47 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
P_AddWeaponMaybeSwitch(pPlayer, weaponNum);
|
2012-08-10 19:11:47 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (pPlayer->ammo_amount[weaponNum] >= pPlayer->max_ammo_amount[weaponNum])
|
2012-08-10 19:11:47 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.flags |= VM_NOEXECUTE;
|
2017-07-05 05:38:05 +00:00
|
|
|
return;
|
2012-08-10 19:11:47 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
P_AddWeaponAmmoCommon(pPlayer, weaponNum, nAmount);
|
2017-07-05 05:38:05 +00:00
|
|
|
}
|
2012-08-10 19:11:47 +00:00
|
|
|
|
2017-07-05 05:38:05 +00:00
|
|
|
static void VM_AddAmmo(DukePlayer_t * const pPlayer, int const weaponNum, int const nAmount)
|
|
|
|
{
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)weaponNum >= MAX_WEAPONS))
|
|
|
|
{
|
2017-07-08 19:41:55 +00:00
|
|
|
CON_ERRPRINTF("invalid weapon %d\n", weaponNum);
|
2017-07-05 05:38:05 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pPlayer->ammo_amount[weaponNum] >= pPlayer->max_ammo_amount[weaponNum])
|
|
|
|
{
|
|
|
|
vm.flags |= VM_NOEXECUTE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
P_AddWeaponAmmoCommon(pPlayer, weaponNum, nAmount);
|
2012-08-10 19:11:47 +00:00
|
|
|
}
|
2017-07-05 05:38:02 +00:00
|
|
|
|
|
|
|
static void VM_AddInventory(DukePlayer_t * const pPlayer, int const itemNum, int const nAmount)
|
|
|
|
{
|
|
|
|
switch (itemNum)
|
|
|
|
{
|
|
|
|
case GET_STEROIDS:
|
|
|
|
case GET_SCUBA:
|
|
|
|
case GET_HOLODUKE:
|
|
|
|
case GET_JETPACK:
|
|
|
|
case GET_HEATS:
|
|
|
|
case GET_FIRSTAID:
|
|
|
|
case GET_BOOTS:
|
|
|
|
pPlayer->inven_icon = inv_to_icon[itemNum];
|
|
|
|
pPlayer->inv_amount[itemNum] = nAmount;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GET_SHIELD:
|
|
|
|
{
|
|
|
|
int16_t & shield_amount = pPlayer->inv_amount[GET_SHIELD];
|
|
|
|
shield_amount = min(shield_amount + nAmount, pPlayer->max_shield_amount);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GET_ACCESS:
|
|
|
|
switch (vm.pSprite->pal)
|
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
case 0: pPlayer->got_access |= 1; break;
|
|
|
|
case 21: pPlayer->got_access |= 2; break;
|
|
|
|
case 23: pPlayer->got_access |= 4; break;
|
2017-07-05 05:38:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
default: CON_ERRPRINTF("invalid inventory item %d\n", itemNum); break;
|
2017-07-05 05:38:02 +00:00
|
|
|
}
|
|
|
|
}
|
2013-01-01 15:24:18 +00:00
|
|
|
#endif
|
2012-08-10 19:11:47 +00:00
|
|
|
|
2018-11-18 18:11:27 +00:00
|
|
|
static int A_GetVerticalVel(actor_t const * const pActor)
|
2015-02-05 16:30:12 +00:00
|
|
|
{
|
|
|
|
#ifdef LUNATIC
|
2016-08-27 01:40:06 +00:00
|
|
|
return pActor->mv.vvel;
|
2015-02-05 16:30:12 +00:00
|
|
|
#else
|
2016-08-27 01:40:06 +00:00
|
|
|
int32_t moveScriptOfs = AC_MOVE_ID(pActor->t_data);
|
2015-02-05 16:30:12 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
return ((unsigned) moveScriptOfs < (unsigned) g_scriptSize - 1) ? apScript[moveScriptOfs + 1] : 0;
|
2015-02-05 16:30:12 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static int32_t A_GetWaterZOffset(int const spriteNum)
|
2015-02-05 16:30:12 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const pSprite = (uspritetype *)&sprite[spriteNum];
|
|
|
|
auto const pActor = &actor[spriteNum];
|
2015-02-05 16:30:12 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (sector[pSprite->sectnum].lotag == ST_1_ABOVE_WATER)
|
2015-02-05 16:30:12 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckSpriteFlags(spriteNum, SFLAG_NOWATERDIP))
|
2015-02-05 16:30:12 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
// fix for flying/jumping monsters getting stuck in water
|
2016-08-27 01:40:06 +00:00
|
|
|
if ((AC_MOVFLAGS(pSprite, pActor) & jumptoplayer_only) || (G_HaveActor(pSprite->picnum) && A_GetVerticalVel(pActor) != 0))
|
2015-02-05 16:30:12 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return ACTOR_ONWATER_ADDZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static void VM_Fall(int const spriteNum, spritetype * const pSprite)
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
2016-08-27 01:41:50 +00:00
|
|
|
int spriteGravity = g_spriteGravity;
|
2012-12-03 18:24:20 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
pSprite->xoffset = pSprite->yoffset = 0;
|
2012-12-03 18:24:20 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (sector[pSprite->sectnum].lotag == ST_2_UNDERWATER || EDUKE32_PREDICT_FALSE(G_CheckForSpaceCeiling(pSprite->sectnum)))
|
2016-08-27 01:41:50 +00:00
|
|
|
spriteGravity = g_spriteGravity/6;
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (EDUKE32_PREDICT_FALSE(G_CheckForSpaceFloor(pSprite->sectnum)))
|
2016-08-27 01:41:50 +00:00
|
|
|
spriteGravity = 0;
|
2012-12-03 18:24:20 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (!actor[spriteNum].cgg-- || (sector[pSprite->sectnum].floorstat&2))
|
2013-04-15 10:48:22 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_GetZLimits(spriteNum);
|
|
|
|
actor[spriteNum].cgg = 3;
|
2013-04-15 10:48:22 +00:00
|
|
|
}
|
2012-12-03 18:24:20 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pSprite->z < actor[spriteNum].floorz-ZOFFSET)
|
2013-04-15 10:48:22 +00:00
|
|
|
{
|
|
|
|
// Free fall.
|
2016-08-27 01:41:50 +00:00
|
|
|
pSprite->zvel = min(pSprite->zvel+spriteGravity, ACTOR_MAXFALLINGZVEL);
|
|
|
|
int newZ = pSprite->z + pSprite->zvel;
|
2015-02-05 16:30:12 +00:00
|
|
|
|
2012-12-03 18:24:20 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2018-05-22 19:03:44 +00:00
|
|
|
if (yax_getbunch(pSprite->sectnum, YAX_FLOOR) >= 0 && (sector[pSprite->sectnum].floorstat & 512) == 0)
|
2016-08-27 01:40:35 +00:00
|
|
|
setspritez(spriteNum, (vec3_t *)pSprite);
|
2013-04-15 10:48:22 +00:00
|
|
|
else
|
2012-12-03 18:24:20 +00:00
|
|
|
#endif
|
2016-08-27 01:40:35 +00:00
|
|
|
if (newZ > actor[spriteNum].floorz - ZOFFSET)
|
|
|
|
newZ = actor[spriteNum].floorz - ZOFFSET;
|
2015-02-05 16:30:12 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z = newZ;
|
2013-04-15 10:48:22 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-04-15 10:48:09 +00:00
|
|
|
|
2015-02-05 16:30:12 +00:00
|
|
|
// Preliminary new z position of the actor.
|
2016-08-27 01:41:50 +00:00
|
|
|
int newZ = actor[spriteNum].floorz - ZOFFSET;
|
2012-12-03 18:24:20 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (A_CheckEnemySprite(pSprite) || (pSprite->picnum == APLAYER && pSprite->owner >= 0))
|
2013-04-15 10:48:22 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pSprite->zvel > 3084 && pSprite->extra <= 1)
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
2013-04-15 10:48:22 +00:00
|
|
|
// I'm guessing this DRONE check is from a beta version of the game
|
|
|
|
// where they crashed into the ground when killed
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:06 +00:00
|
|
|
if (!(pSprite->picnum == APLAYER && pSprite->extra > 0) && pSprite->pal != 1 && pSprite->picnum != DRONE)
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_DoGuts(spriteNum,JIBS6,15);
|
|
|
|
A_PlaySound(SQUISHED,spriteNum);
|
|
|
|
A_Spawn(spriteNum,BLOODPOOL);
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
2018-06-09 20:36:31 +00:00
|
|
|
#endif
|
2016-08-27 01:40:35 +00:00
|
|
|
actor[spriteNum].picnum = SHOTSPARK1;
|
|
|
|
actor[spriteNum].extra = 1;
|
2016-08-27 01:40:06 +00:00
|
|
|
pSprite->zvel = 0;
|
2013-04-15 10:48:22 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (pSprite->zvel > 2048 && sector[pSprite->sectnum].lotag != ST_1_ABOVE_WATER)
|
2013-04-15 10:48:22 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int16_t newsect = pSprite->sectnum;
|
2013-04-15 10:48:09 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
pushmove((vec3_t *)pSprite, &newsect, 128, 4<<8, 4<<8, CLIPMASK0);
|
2013-04-15 10:48:22 +00:00
|
|
|
if ((unsigned)newsect < MAXSECTORS)
|
2016-08-27 01:40:35 +00:00
|
|
|
changespritesect(spriteNum, newsect);
|
2013-04-15 10:48:22 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(THUD, spriteNum);
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (sector[pSprite->sectnum].lotag == ST_1_ABOVE_WATER)
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z = newZ + A_GetWaterZOffset(spriteNum);
|
2012-12-03 18:24:20 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-02-07 21:00:48 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
pSprite->z = newZ;
|
2016-08-27 01:40:06 +00:00
|
|
|
pSprite->zvel = 0;
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t const resetFlags)
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
|
|
|
//AddLog("resetplayer");
|
2016-08-27 01:40:35 +00:00
|
|
|
if (!g_netServer && ud.multimode < 2 && !(resetFlags & 2))
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
2018-04-11 03:33:54 +00:00
|
|
|
if (g_quickload && g_quickload->isValid() && ud.recstat != 2 && !(resetFlags & 8))
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
2018-02-20 11:55:13 +00:00
|
|
|
if (resetFlags & 4)
|
|
|
|
{
|
|
|
|
KB_FlushKeyboardQueue();
|
|
|
|
KB_ClearKeysDown();
|
|
|
|
FX_StopAllSounds();
|
|
|
|
S_ClearSoundLocks();
|
2018-03-11 03:47:11 +00:00
|
|
|
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
|
|
|
|
{
|
|
|
|
g_quickload->reset();
|
|
|
|
goto QuickLoadFailure;
|
|
|
|
}
|
2018-02-20 11:55:13 +00:00
|
|
|
}
|
|
|
|
else if (!(resetFlags & 1))
|
|
|
|
{
|
|
|
|
Menu_Open(playerNum);
|
|
|
|
KB_ClearKeyDown(sc_Space);
|
|
|
|
I_AdvanceTriggerClear();
|
|
|
|
Menu_Change(MENU_RESETPLAYER);
|
|
|
|
}
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
2018-03-11 03:47:11 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
QuickLoadFailure:
|
|
|
|
g_player[playerNum].ps->gm = MODE_RESTART;
|
|
|
|
}
|
2013-07-13 21:04:45 +00:00
|
|
|
#if !defined LUNATIC
|
2016-08-27 01:40:35 +00:00
|
|
|
vmFlags |= VM_NOEXECUTE;
|
2013-07-13 21:04:45 +00:00
|
|
|
#endif
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (playerNum == myconnectindex)
|
2012-12-03 18:24:20 +00:00
|
|
|
{
|
2013-01-19 18:28:32 +00:00
|
|
|
CAMERADIST = 0;
|
|
|
|
CAMERACLOCK = totalclock;
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (g_fakeMultiMode)
|
2018-11-18 18:07:57 +00:00
|
|
|
P_ResetMultiPlayer(playerNum);
|
2012-12-09 13:24:44 +00:00
|
|
|
#ifndef NETCODE_DISABLE
|
2012-12-03 18:24:20 +00:00
|
|
|
if (g_netServer)
|
|
|
|
{
|
2018-11-18 18:07:57 +00:00
|
|
|
P_ResetMultiPlayer(playerNum);
|
2016-08-27 01:40:35 +00:00
|
|
|
Net_SpawnPlayer(playerNum);
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
2012-12-09 13:24:44 +00:00
|
|
|
#endif
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
2013-02-07 21:00:52 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
P_UpdateScreenPal(g_player[playerNum].ps);
|
2012-12-03 18:24:20 +00:00
|
|
|
//AddLog("EOF: resetplayer");
|
2013-02-07 21:00:52 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
return vmFlags;
|
2012-12-03 18:24:20 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 03:58:54 +00:00
|
|
|
void G_GetTimeDate(int32_t * const pValues)
|
2013-02-16 18:53:00 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
time_t timeStruct;
|
|
|
|
time(&timeStruct);
|
|
|
|
struct tm *pTime = localtime(&timeStruct);
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2013-02-16 18:53:00 +00:00
|
|
|
// initprintf("Time&date: %s\n",asctime (ti));
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
pValues[0] = pTime->tm_sec;
|
|
|
|
pValues[1] = pTime->tm_min;
|
|
|
|
pValues[2] = pTime->tm_hour;
|
|
|
|
pValues[3] = pTime->tm_mday;
|
|
|
|
pValues[4] = pTime->tm_mon;
|
|
|
|
pValues[5] = pTime->tm_year+1900;
|
|
|
|
pValues[6] = pTime->tm_wday;
|
|
|
|
pValues[7] = pTime->tm_yday;
|
2013-02-16 18:53:00 +00:00
|
|
|
}
|
|
|
|
|
2017-08-01 09:48:59 +00:00
|
|
|
static int G_StartTrackSlot(int const volumeNum, int const levelNum)
|
2013-02-16 18:53:18 +00:00
|
|
|
{
|
2017-08-01 09:48:59 +00:00
|
|
|
if ((unsigned)volumeNum <= MAXVOLUMES && (unsigned)levelNum < MAXLEVELS)
|
2013-02-16 18:53:18 +00:00
|
|
|
{
|
2017-08-01 09:48:59 +00:00
|
|
|
int trackNum = MAXLEVELS*volumeNum + levelNum;
|
2013-02-16 18:53:18 +00:00
|
|
|
|
2018-01-29 11:13:43 +00:00
|
|
|
return S_TryPlaySpecialMusic(trackNum);
|
2013-02-16 18:53:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-08-06 13:44:59 +00:00
|
|
|
#ifndef LUNATIC
|
2018-01-29 11:14:04 +00:00
|
|
|
static int G_StartTrackSlotWrap(int const volumeNum, int const levelNum)
|
2017-08-01 09:48:59 +00:00
|
|
|
{
|
|
|
|
if (EDUKE32_PREDICT_FALSE(G_StartTrackSlot(volumeNum, levelNum)))
|
2018-01-29 11:14:04 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid level %d or null music for volume %d level %d\n", levelNum, volumeNum, levelNum);
|
2018-01-29 11:14:04 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2017-08-01 09:48:59 +00:00
|
|
|
}
|
2017-08-06 13:44:59 +00:00
|
|
|
#else
|
2018-05-22 19:03:44 +00:00
|
|
|
int G_StartTrack(int const levelNum) { return G_StartTrackSlot(ud.volume_number, levelNum); }
|
2017-08-01 09:48:59 +00:00
|
|
|
#endif
|
|
|
|
|
2018-11-18 18:14:10 +00:00
|
|
|
LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int sect, int x1, int y1, int x2, int y2, bool unbiasedp)
|
2013-06-07 14:26:32 +00:00
|
|
|
{
|
|
|
|
if (g_screenCapture)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (offscreenrendering)
|
|
|
|
{
|
2018-04-12 21:02:51 +00:00
|
|
|
videoClearViewableArea(0);
|
2013-06-07 14:26:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (x1 > x2)
|
|
|
|
swaplong(&x1, &x2);
|
|
|
|
if (y1 > y2)
|
|
|
|
swaplong(&y1, &y2);
|
2013-06-07 14:26:32 +00:00
|
|
|
|
|
|
|
if (!unbiasedp)
|
|
|
|
{
|
|
|
|
// The showview command has a rounding bias towards zero,
|
|
|
|
// e.g. floor((319*1680)/320) == 1674
|
|
|
|
x1 = scale(x1,xdim,320);
|
|
|
|
y1 = scale(y1,ydim,200);
|
|
|
|
x2 = scale(x2,xdim,320);
|
|
|
|
y2 = scale(y2,ydim,200);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// This will map the maximum 320-based coordinate to the
|
|
|
|
// maximum real screen coordinate:
|
|
|
|
// floor((319*1679)/319) == 1679
|
|
|
|
x1 = scale(x1,xdim-1,319);
|
|
|
|
y1 = scale(y1,ydim-1,199);
|
|
|
|
x2 = scale(x2,xdim-1,319);
|
|
|
|
y2 = scale(y2,ydim-1,199);
|
|
|
|
}
|
|
|
|
|
2018-03-07 04:21:31 +00:00
|
|
|
horiz = fix16_clamp(horiz, F16(HORIZ_MIN), F16(HORIZ_MAX));
|
2013-06-07 14:26:32 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
int const onewaspect = newaspect_enable;
|
|
|
|
newaspect_enable = r_usenewaspect;
|
|
|
|
setaspect_new_use_dimen = 1;
|
2018-04-12 21:02:51 +00:00
|
|
|
videoSetViewableArea(x1,y1,x2,y2);
|
2016-08-27 01:40:06 +00:00
|
|
|
setaspect_new_use_dimen = 0;
|
|
|
|
newaspect_enable = onewaspect;
|
|
|
|
|
|
|
|
int const smoothratio = calc_smoothratio(totalclock, ototalclock);
|
2013-06-07 14:26:32 +00:00
|
|
|
G_DoInterpolations(smoothratio);
|
2015-03-24 00:40:55 +00:00
|
|
|
G_HandleMirror(vec.x, vec.y, vec.z, a, horiz, smoothratio);
|
2013-06-07 14:26:32 +00:00
|
|
|
#ifdef POLYMER
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() == REND_POLYMER)
|
2018-03-07 04:21:31 +00:00
|
|
|
polymer_setanimatesprites(G_DoSpriteAnimations, vec.x, vec.y, fix16_to_int(a), smoothratio);
|
2013-06-07 14:26:32 +00:00
|
|
|
#endif
|
|
|
|
yax_preparedrawrooms();
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawRoomsQ16(vec.x, vec.y, vec.z, a, horiz, sect);
|
2013-06-07 14:26:32 +00:00
|
|
|
yax_drawrooms(G_DoSpriteAnimations, sect, 0, smoothratio);
|
|
|
|
|
|
|
|
display_mirror = 2;
|
2018-03-07 04:21:31 +00:00
|
|
|
G_DoSpriteAnimations(vec.x, vec.y, fix16_to_int(a), smoothratio);
|
2013-06-07 14:26:32 +00:00
|
|
|
display_mirror = 0;
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawMasks();
|
2013-06-07 14:26:32 +00:00
|
|
|
G_RestoreInterpolations();
|
|
|
|
G_UpdateScreenArea();
|
|
|
|
}
|
|
|
|
|
2017-11-29 07:29:11 +00:00
|
|
|
void Screen_Play(void)
|
|
|
|
{
|
2018-11-18 18:11:27 +00:00
|
|
|
bool running = true;
|
2017-11-29 07:29:11 +00:00
|
|
|
|
|
|
|
I_ClearAllInput();
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
G_HandleAsync();
|
|
|
|
|
2018-02-12 02:32:39 +00:00
|
|
|
ototalclock = totalclock + 1; // pause game like ANMs
|
|
|
|
|
2018-02-10 22:58:34 +00:00
|
|
|
if (!G_FPSLimit())
|
|
|
|
continue;
|
|
|
|
|
2018-04-12 21:02:51 +00:00
|
|
|
videoClearScreen(0);
|
2017-11-29 07:29:11 +00:00
|
|
|
|
2018-11-18 18:11:27 +00:00
|
|
|
if (VM_OnEventWithReturn(EVENT_SCREEN, g_player[screenpeek].ps->i, screenpeek, I_CheckAllInput()))
|
|
|
|
running = false;
|
2017-11-29 07:29:11 +00:00
|
|
|
|
|
|
|
I_ClearAllInput();
|
|
|
|
} while (running);
|
|
|
|
}
|
|
|
|
|
2013-01-19 18:29:00 +00:00
|
|
|
#if !defined LUNATIC
|
2018-05-22 19:03:44 +00:00
|
|
|
GAMEEXEC_STATIC void VM_Execute(native_t loop)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-11-18 18:10:51 +00:00
|
|
|
native_t tw = *insptr;
|
2018-05-22 19:03:44 +00:00
|
|
|
DukePlayer_t *const pPlayer = vm.pPlayer;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
// jump directly into the loop, skipping branches during the first iteration
|
2018-12-15 01:36:21 +00:00
|
|
|
goto next_instruction;
|
2009-07-12 23:41:16 +00:00
|
|
|
|
2018-12-15 01:36:21 +00:00
|
|
|
while (loop && (vm.flags & (VM_RETURN|VM_KILL|VM_NOEXECUTE)) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2009-07-12 23:41:16 +00:00
|
|
|
tw = *insptr;
|
2007-02-08 04:19:39 +00:00
|
|
|
|
2018-12-15 01:36:21 +00:00
|
|
|
next_instruction:
|
2018-05-22 19:03:44 +00:00
|
|
|
g_errorLineNum = tw >> 12;
|
2018-12-15 01:36:21 +00:00
|
|
|
g_tw = tw &= VM_INSTMASK;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
|
|
|
if (tw == CON_LEFTBRACE)
|
|
|
|
{
|
2018-12-15 01:36:21 +00:00
|
|
|
tw = *(++insptr), loop++;
|
|
|
|
goto next_instruction;
|
2015-01-11 04:56:10 +00:00
|
|
|
}
|
|
|
|
else if (tw == CON_RIGHTBRACE)
|
|
|
|
{
|
2015-03-24 00:40:55 +00:00
|
|
|
insptr++, loop--;
|
2015-01-11 04:56:10 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (tw == CON_ELSE)
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
insptr = (intptr_t *)insptr[1];
|
2018-12-15 01:36:21 +00:00
|
|
|
tw = *insptr;
|
|
|
|
goto next_instruction;
|
2015-01-11 04:56:10 +00:00
|
|
|
}
|
|
|
|
else if (tw == CON_STATE)
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
auto tempscrptr = &insptr[2];
|
|
|
|
insptr = (intptr_t *)insptr[1];
|
2015-01-11 04:56:10 +00:00
|
|
|
VM_Execute(1);
|
|
|
|
insptr = tempscrptr;
|
|
|
|
continue;
|
|
|
|
}
|
2018-12-15 01:37:29 +00:00
|
|
|
else switch (tw)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETVAR:
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
2018-12-15 01:37:29 +00:00
|
|
|
if ((aGameVars[*insptr].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0)
|
2018-12-15 01:37:39 +00:00
|
|
|
aGameVars[*insptr].global = insptr[1];
|
2018-12-15 01:37:29 +00:00
|
|
|
else
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_SetVarX(*insptr, insptr[1]);
|
2018-12-15 01:37:29 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETVARVAR:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-12-15 01:36:21 +00:00
|
|
|
tw = *insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const nValue = Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
if ((aGameVars[tw].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0)
|
|
|
|
aGameVars[tw].global = nValue;
|
|
|
|
else
|
|
|
|
Gv_SetVarX(tw, nValue);
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDVARVAR:
|
|
|
|
insptr++;
|
2015-03-25 06:27:25 +00:00
|
|
|
tw = *insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_AddVar(tw, Gv_GetVarX(*insptr++));
|
2015-03-25 06:27:25 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SUBVARVAR:
|
|
|
|
insptr++;
|
2015-03-25 06:27:25 +00:00
|
|
|
tw = *insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SubVar(tw, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2015-03-25 06:27:25 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (tw == Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARN:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (tw != Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MULVARVAR:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_MulVar(tw, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DIVVARVAR:
|
|
|
|
insptr++;
|
2009-06-24 08:20:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
tw = *insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const nValue = Gv_GetVarX(*insptr++);
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(!nValue))
|
|
|
|
{
|
|
|
|
CON_CRITICALERRPRINTF("divide by zero!\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Gv_DivVar(tw, nValue);
|
|
|
|
continue;
|
2015-01-11 04:56:10 +00:00
|
|
|
}
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw == *insptr);
|
|
|
|
continue;
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARN:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw != *insptr);
|
|
|
|
continue;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_AddVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SUBVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_SubVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MULVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_MulVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DIVVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(insptr[1] == 0))
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_CRITICALERRPRINTF("divide by zero!\n");
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_DivVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARG:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (tw > Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARGE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (tw >= Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARL:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (tw < Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARLE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (tw <= Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2009-01-18 07:32:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARA:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = ((uint32_t)tw > (uint32_t)Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARAE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = ((uint32_t)tw >= (uint32_t)Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARB:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = ((uint32_t)tw < (uint32_t)Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARBE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = ((uint32_t)tw <= (uint32_t)Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARAND:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw &= Gv_GetVarX(*insptr++);
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2013-02-03 12:48:17 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVAROR:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw |= Gv_GetVarX(*insptr++);
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2013-06-30 20:38:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARVARXOR:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw ^= Gv_GetVarX(*insptr++);
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
2013-06-30 20:38:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARAND:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw & *insptr);
|
|
|
|
continue;
|
2012-03-11 17:37:50 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVAROR:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw | *insptr);
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARXOR:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw ^ *insptr);
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVAREITHER:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw || *insptr);
|
|
|
|
continue;
|
2013-05-23 18:28:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARBOTH:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw && *insptr);
|
|
|
|
continue;
|
2007-04-15 20:04:52 +00:00
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
case CON_IFRND:
|
|
|
|
VM_CONDITIONAL(rnd(*(++insptr)));
|
|
|
|
continue;
|
2007-04-15 20:04:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARG:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw > *insptr);
|
|
|
|
continue;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARGE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw >= *insptr);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFVARL:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw < *insptr);
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARLE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL(tw <= *insptr);
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARA:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL((uint32_t)tw > (uint32_t)*insptr);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFVARAE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL((uint32_t)tw >= (uint32_t)*insptr);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFVARB:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL((uint32_t)tw < (uint32_t)*insptr);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFVARBE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
VM_CONDITIONAL((uint32_t)tw <= (uint32_t)*insptr);
|
|
|
|
continue;
|
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
case CON_IFVARVAREITHER:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (Gv_GetVarX(*insptr++) || tw);
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFVARVARBOTH:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
tw = (Gv_GetVarX(*insptr++) && tw);
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_WHILEVARN:
|
|
|
|
{
|
|
|
|
auto const savedinsptr = &insptr[2];
|
|
|
|
do
|
|
|
|
{
|
|
|
|
insptr = savedinsptr;
|
|
|
|
tw = (Gv_GetVarX(insptr[-1]) != *insptr);
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
} while (tw);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_WHILEVARL:
|
|
|
|
{
|
|
|
|
auto const savedinsptr = &insptr[2];
|
|
|
|
do
|
|
|
|
{
|
|
|
|
insptr = savedinsptr;
|
|
|
|
tw = (Gv_GetVarX(insptr[-1]) < *insptr);
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
} while (tw);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_WHILEVARVARN:
|
|
|
|
{
|
|
|
|
auto const savedinsptr = &insptr[2];
|
|
|
|
do
|
|
|
|
{
|
|
|
|
insptr = savedinsptr;
|
|
|
|
tw = Gv_GetVarX(insptr[-1]);
|
|
|
|
tw = (tw != Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
} while (tw);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_WHILEVARVARL:
|
|
|
|
{
|
|
|
|
auto const savedinsptr = &insptr[2];
|
|
|
|
do
|
|
|
|
{
|
|
|
|
insptr = savedinsptr;
|
|
|
|
tw = Gv_GetVarX(insptr[-1]);
|
|
|
|
tw = (tw < Gv_GetVarX(*insptr++));
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
} while (tw);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MODVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(insptr[1] == 0))
|
2007-04-15 20:04:52 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_CRITICALERRPRINTF("mod by zero!\n");
|
2010-05-02 23:27:30 +00:00
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_ModVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ANDVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_AndVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ORVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_OrVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_XORVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_XorVar(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ANDVARVAR:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_AndVar(tw, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_XORVARVAR:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_XorVar(tw, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ORVARVAR:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_OrVar(tw, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SHIFTVARL:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_ShiftVarL(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SHIFTVARR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_ShiftVarR(*insptr, insptr[1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SHIFTVARVARL:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_ShiftVarL(tw, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SHIFTVARVARR:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_ShiftVarR(tw, Gv_GetVarX(*insptr++));
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MODVARVAR:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = *insptr++;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const nValue = Gv_GetVarX(*insptr++);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(!nValue))
|
|
|
|
{
|
|
|
|
CON_CRITICALERRPRINTF("mod by zero!\n");
|
|
|
|
continue;
|
|
|
|
}
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_ModVar(tw, nValue);
|
2009-07-15 01:26:38 +00:00
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETPLAYER:
|
2009-07-12 23:41:16 +00:00
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.playerNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
int const lParm2 = (PlayerLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
VM_SetPlayer(playerNum, labelNum, lParm2, Gv_GetVarX(*insptr++));
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_GETPLAYER:
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
2009-07-15 01:26:38 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.playerNum;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const labelNum = *insptr++;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const lParm2 = (PlayerLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0;
|
2018-05-22 19:03:44 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
Gv_SetVarX(*insptr++, VM_GetPlayer(playerNum, labelNum, lParm2));
|
2009-07-15 01:26:38 +00:00
|
|
|
continue;
|
|
|
|
}
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETWALL:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = *insptr++;
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
int const wallNum = Gv_GetVarX(tw);
|
|
|
|
int const labelNum = *insptr++;
|
|
|
|
int const newValue = Gv_GetVarX(*insptr++);
|
2018-12-15 01:37:29 +00:00
|
|
|
auto const &wallLabel = WallLabels[labelNum];
|
|
|
|
|
|
|
|
if (wallLabel.offset == -1 || wallLabel.flags & LABEL_WRITEFUNC)
|
|
|
|
{
|
|
|
|
VM_SetWall(wallNum, labelNum, newValue);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
VM_SetStruct(wallLabel.flags, (intptr_t *)((char *)&wall[wallNum] + wallLabel.offset), newValue);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_GETWALL:
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:29 +00:00
|
|
|
tw = *insptr++;
|
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
int const wallNum = Gv_GetVarX(tw);
|
|
|
|
int const labelNum = *insptr++;
|
2018-12-15 01:37:29 +00:00
|
|
|
auto const &wallLabel = WallLabels[labelNum];
|
|
|
|
|
|
|
|
Gv_SetVarX(*insptr++,
|
|
|
|
(wallLabel.offset != -1 && (wallLabel.flags & LABEL_READFUNC) != LABEL_READFUNC)
|
|
|
|
? VM_GetStruct(wallLabel.flags, (intptr_t *)((char *)&wall[wallNum] + wallLabel.offset))
|
|
|
|
: VM_GetWall(wallNum, labelNum));
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETACTORVAR:
|
|
|
|
case CON_GETACTORVAR:
|
|
|
|
insptr++;
|
2017-11-29 07:28:58 +00:00
|
|
|
{
|
2018-12-15 01:37:29 +00:00
|
|
|
int const lSprite = Gv_GetVarX(*insptr++);
|
|
|
|
int const lVar1 = *insptr++;
|
|
|
|
int const lVar2 = *insptr++;
|
2017-11-29 07:28:58 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)lSprite >= MAXSPRITES))
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-12-15 01:37:29 +00:00
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", lSprite);
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2017-11-29 07:28:58 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (tw == CON_SETACTORVAR)
|
|
|
|
Gv_SetVar(lVar1, Gv_GetVarX(lVar2), lSprite, vm.playerNum);
|
|
|
|
else
|
|
|
|
Gv_SetVarX(lVar2, Gv_GetVar(lVar1, lSprite, vm.playerNum));
|
2017-11-29 07:28:58 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-11-03 23:08:54 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETPLAYERVAR:
|
|
|
|
case CON_GETPLAYERVAR:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.playerNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const lVar1 = *insptr++;
|
|
|
|
int const lVar2 = *insptr++;
|
2011-11-03 23:08:54 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers))
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-12-15 01:37:29 +00:00
|
|
|
CON_ERRPRINTF("invalid player %d\n", playerNum);
|
|
|
|
continue;
|
|
|
|
}
|
2011-11-03 23:08:54 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (tw == CON_SETPLAYERVAR)
|
|
|
|
Gv_SetVar(lVar1, Gv_GetVarX(lVar2), vm.spriteNum, playerNum);
|
|
|
|
else
|
|
|
|
Gv_SetVarX(lVar2, Gv_GetVar(lVar1, vm.spriteNum, playerNum));
|
2018-05-22 19:03:44 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2011-11-03 23:08:54 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETACTOR:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
int const lParm2 = (ActorLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0;
|
|
|
|
auto const &actorLabel = ActorLabels[labelNum];
|
2006-09-30 06:51:48 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(((unsigned)spriteNum >= MAXSPRITES)
|
|
|
|
|| (actorLabel.flags & LABEL_HASPARM2 && (unsigned)lParm2 >= (unsigned)actorLabel.maxParm2)))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("%s[%d] invalid for sprite %d\n", actorLabel.name, lParm2, spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
VM_SetSprite(spriteNum, labelNum, lParm2, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_GETACTOR:
|
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
int const lParm2 = (ActorLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0;
|
|
|
|
auto const &actorLabel = ActorLabels[labelNum];
|
2008-12-13 21:01:33 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(((unsigned)spriteNum >= MAXSPRITES)
|
|
|
|
|| (actorLabel.flags & LABEL_HASPARM2 && (unsigned)lParm2 >= (unsigned)actorLabel.maxParm2)))
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-12-15 01:37:29 +00:00
|
|
|
CON_ERRPRINTF("%s[%d] invalid for sprite %d\n", actorLabel.name, lParm2, spriteNum);
|
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2018-12-15 01:37:29 +00:00
|
|
|
|
|
|
|
Gv_SetVarX(*insptr++, VM_GetSprite(spriteNum, labelNum, lParm2));
|
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2008-12-13 21:01:33 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETACTORSTRUCT:
|
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &actorLabel = ActorLabels[labelNum];
|
2012-08-10 19:11:47 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
VM_SetStruct(actorLabel.flags, (intptr_t *)((char *)&actor[spriteNum] + actorLabel.offset), Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2018-12-15 01:37:29 +00:00
|
|
|
|
|
|
|
case CON_GETACTORSTRUCT:
|
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &actorLabel = ActorLabels[labelNum];
|
2012-08-10 19:11:47 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2012-08-10 19:11:47 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
Gv_SetVarX(*insptr++, VM_GetStruct(actorLabel.flags, (intptr_t *)((char *)&actor[spriteNum] + actorLabel.offset)));
|
|
|
|
continue;
|
|
|
|
}
|
2008-12-13 21:01:33 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_SETSPRITESTRUCT:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &spriteLabel = ActorLabels[labelNum];
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
VM_SetStruct(spriteLabel.flags, (intptr_t *)((char *)&sprite[spriteNum] + spriteLabel.offset), Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_GETSPRITESTRUCT:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &spriteLabel = ActorLabels[labelNum];
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Gv_SetVarX(*insptr++, VM_GetStruct(spriteLabel.flags, (intptr_t *)((char *)&sprite[spriteNum] + spriteLabel.offset)));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
case CON_SETSPRITEEXT:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &spriteExtLabel = ActorLabels[labelNum];
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
VM_SetStruct(spriteExtLabel.flags, (intptr_t *)((char *)&spriteext[spriteNum] + spriteExtLabel.offset), Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_GETSPRITEEXT:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &spriteExtLabel = ActorLabels[labelNum];
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Gv_SetVarX(*insptr++, VM_GetStruct(spriteExtLabel.flags, (intptr_t *)((char *)&spriteext[spriteNum] + spriteExtLabel.offset)));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_SETTSPR:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &tsprLabel = TsprLabels[labelNum];
|
|
|
|
|
|
|
|
VM_SetStruct(tsprLabel.flags, (intptr_t *)((char *)spriteext[spriteNum].tspr + tsprLabel.offset), Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_GETTSPR:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const &tsprLabel = TsprLabels[labelNum];
|
|
|
|
|
|
|
|
Gv_SetVarX(*insptr++, VM_GetStruct(tsprLabel.flags, (intptr_t *)((char *)spriteext[spriteNum].tspr + tsprLabel.offset)));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_SETSECTOR:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const sectNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : sprite[vm.spriteNum].sectnum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const §Label = SectorLabels[labelNum];
|
|
|
|
int const newValue = Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
if (sectLabel.offset == -1 || sectLabel.flags & LABEL_WRITEFUNC)
|
|
|
|
{
|
|
|
|
VM_SetSector(sectNum, labelNum, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
VM_SetStruct(sectLabel.flags, (intptr_t *)((char *)§or[sectNum] + sectLabel.offset), newValue);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_GETSECTOR:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const sectNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : sprite[vm.spriteNum].sectnum;
|
2018-12-15 01:37:29 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
auto const §Label = SectorLabels[labelNum];
|
|
|
|
|
|
|
|
Gv_SetVarX(*insptr++,
|
|
|
|
(sectLabel.offset != -1 && (sectLabel.flags & LABEL_READFUNC) != LABEL_READFUNC)
|
|
|
|
? VM_GetStruct(sectLabel.flags, (intptr_t *)((char *)§or[sectNum] + sectLabel.offset))
|
|
|
|
: VM_GetSector(sectNum, labelNum));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_RETURN: vm.flags |= VM_RETURN; fallthrough__;
|
|
|
|
case CON_ENDSWITCH:
|
|
|
|
case CON_ENDA:
|
|
|
|
case CON_BREAK:
|
|
|
|
case CON_ENDS:
|
|
|
|
case CON_ENDEVENT: return;
|
|
|
|
|
|
|
|
case CON_JUMP: // this is used for event chaining
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
insptr = (intptr_t *)(tw + apScript);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_SWITCH:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
// command format:
|
|
|
|
// variable ID to check
|
|
|
|
// script offset to 'end'
|
|
|
|
// count of case statements
|
|
|
|
// script offset to default case (null if none)
|
|
|
|
// For each case: value, ptr to code
|
|
|
|
int const lValue = Gv_GetVarX(*insptr++);
|
|
|
|
int const endOffset = *insptr++;
|
|
|
|
int const numCases = *insptr++;
|
|
|
|
|
|
|
|
auto lpDefault = insptr++;
|
|
|
|
auto lpCases = insptr;
|
|
|
|
|
|
|
|
int left = 0;
|
|
|
|
int right = numCases - 1;
|
|
|
|
|
|
|
|
insptr += numCases << 1;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
int const lCheckCase = (left + right) >> 1;
|
|
|
|
|
|
|
|
if (lpCases[lCheckCase << 1] > lValue)
|
|
|
|
right = lCheckCase - 1;
|
|
|
|
else if (lpCases[lCheckCase << 1] < lValue)
|
|
|
|
left = lCheckCase + 1;
|
|
|
|
else if (lpCases[lCheckCase << 1] == lValue)
|
|
|
|
{
|
|
|
|
// fake a 2-d Array
|
|
|
|
insptr = (intptr_t *)(lpCases[(lCheckCase << 1) + 1] + &apScript[0]);
|
|
|
|
VM_Execute(1);
|
|
|
|
goto matched;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (right - left < 0)
|
|
|
|
break;
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
if (*lpDefault)
|
|
|
|
{
|
|
|
|
insptr = (intptr_t *)(*lpDefault + &apScript[0]);
|
|
|
|
VM_Execute(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
matched:
|
|
|
|
insptr = (intptr_t *)(endOffset + (intptr_t)&apScript[0]);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2018-12-15 01:37:39 +00:00
|
|
|
|
|
|
|
case CON_FOR: // special-purpose iteration
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const returnVar = *insptr++;
|
|
|
|
int const iterType = *insptr++;
|
|
|
|
int const nIndex = iterType <= ITER_DRAWNSPRITES ? 0 : Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
auto const pEnd = insptr + *insptr;
|
|
|
|
auto const pNext = ++insptr;
|
|
|
|
|
|
|
|
switch (iterType)
|
|
|
|
{
|
|
|
|
case ITER_ALLSPRITES:
|
|
|
|
for (native_t jj = 0; jj < MAXSPRITES; ++jj)
|
|
|
|
{
|
|
|
|
if (sprite[jj].statnum == MAXSTATUS)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_ALLSPRITESBYSTAT:
|
|
|
|
for (native_t statNum = 0; statNum < MAXSTATUS; ++statNum)
|
|
|
|
{
|
|
|
|
for (native_t jj = headspritestat[statNum]; jj >= 0;)
|
|
|
|
{
|
|
|
|
int const kk = nextspritestat[jj];
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
jj = kk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_ALLSPRITESBYSECT:
|
|
|
|
for (native_t sectNum = 0; sectNum < numsectors; ++sectNum)
|
|
|
|
{
|
|
|
|
for (native_t jj = headspritesect[sectNum]; jj >= 0;)
|
|
|
|
{
|
|
|
|
int const kk = nextspritesect[jj];
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
jj = kk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_ALLSECTORS:
|
|
|
|
for (native_t jj = 0; jj < numsectors; ++jj)
|
|
|
|
{
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_ALLWALLS:
|
|
|
|
for (native_t jj = 0; jj < numwalls; ++jj)
|
|
|
|
{
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_ACTIVELIGHTS:
|
|
|
|
#ifdef POLYMER
|
|
|
|
for (native_t jj = 0; jj < PR_MAXLIGHTS; ++jj)
|
|
|
|
{
|
|
|
|
if (!prlights[jj].flags.active)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ITER_DRAWNSPRITES:
|
|
|
|
{
|
|
|
|
for (native_t ii = 0; ii < spritesortcnt; ii++)
|
|
|
|
{
|
|
|
|
Gv_SetVarX(returnVar, ii);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ITER_SPRITESOFSECTOR:
|
|
|
|
if ((unsigned)nIndex >= MAXSECTORS)
|
|
|
|
goto badindex;
|
|
|
|
for (native_t jj = headspritesect[nIndex]; jj >= 0;)
|
|
|
|
{
|
|
|
|
int const kk = nextspritesect[jj];
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
jj = kk;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_SPRITESOFSTATUS:
|
|
|
|
if ((unsigned)nIndex >= MAXSTATUS)
|
|
|
|
goto badindex;
|
|
|
|
for (native_t jj = headspritestat[nIndex]; jj >= 0;)
|
|
|
|
{
|
|
|
|
int const kk = nextspritestat[jj];
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
jj = kk;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_WALLSOFSECTOR:
|
|
|
|
if ((unsigned)nIndex >= MAXSECTORS)
|
|
|
|
goto badindex;
|
|
|
|
for (native_t jj = sector[nIndex].wallptr, endwall = jj + sector[nIndex].wallnum - 1; jj <= endwall; jj++)
|
|
|
|
{
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_LOOPOFWALL:
|
|
|
|
if ((unsigned)nIndex >= (unsigned)numwalls)
|
|
|
|
goto badindex;
|
|
|
|
{
|
|
|
|
int jj = nIndex;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
jj = wall[jj].point2;
|
|
|
|
} while (jj != nIndex);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITER_RANGE:
|
|
|
|
for (native_t jj = 0; jj < nIndex; jj++)
|
|
|
|
{
|
|
|
|
Gv_SetVarX(returnVar, jj);
|
|
|
|
insptr = pNext;
|
|
|
|
VM_Execute(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
badindex:
|
|
|
|
OSD_Printf(OSD_ERROR "Line %d, for %s: index %d out of range!\n", g_errorLineNum, iter_tokens[iterType].token, nIndex);
|
|
|
|
vm.flags |= VM_RETURN;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
insptr = pEnd;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_REDEFINEQUOTE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const strIndex = *insptr++;
|
|
|
|
int const XstrIndex = *insptr++;
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((apStrings[strIndex] == NULL || apXStrings[XstrIndex] == NULL)))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid source quote %d or destination quote %d\n", XstrIndex, strIndex);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Bstrcpy(apStrings[strIndex], apXStrings[XstrIndex]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_GETTHISPROJECTILE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = *insptr++;
|
|
|
|
int const spriteNum = (tw != g_thisActorVarID) ? Gv_GetVarX(tw) : vm.spriteNum;
|
|
|
|
int const labelNum = *insptr++;
|
|
|
|
|
|
|
|
Gv_SetVarX(*insptr++, VM_GetActiveProjectile(spriteNum, labelNum));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_SETTHISPROJECTILE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = *insptr++;
|
|
|
|
int const spriteNum = (tw != g_thisActorVarID) ? Gv_GetVarX(tw) : vm.spriteNum;
|
|
|
|
int const labelNum = *insptr++;
|
|
|
|
|
|
|
|
VM_SetActiveProjectile(spriteNum, labelNum, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_IFCANSHOOTTARGET:
|
|
|
|
{
|
|
|
|
if (vm.playerDist > 1024)
|
|
|
|
{
|
|
|
|
int16_t temphit;
|
|
|
|
|
|
|
|
if ((tw = A_CheckHitSprite(vm.spriteNum, &temphit)) == (1 << 30))
|
|
|
|
{
|
|
|
|
VM_CONDITIONAL(1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int dist = 768;
|
|
|
|
int angDiff = 16;
|
|
|
|
|
|
|
|
if (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->xrepeat > 56)
|
|
|
|
{
|
|
|
|
dist = 3084;
|
|
|
|
angDiff = 48;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CHECK(x) \
|
|
|
|
if (x >= 0 && sprite[x].picnum == vm.pSprite->picnum) \
|
|
|
|
{ \
|
|
|
|
VM_CONDITIONAL(0); \
|
|
|
|
continue; \
|
|
|
|
}
|
|
|
|
#define CHECK2(x) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
vm.pSprite->ang += x; \
|
|
|
|
tw = A_CheckHitSprite(vm.spriteNum, &temphit); \
|
|
|
|
vm.pSprite->ang -= x; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
if (tw > dist)
|
|
|
|
{
|
|
|
|
CHECK(temphit);
|
|
|
|
CHECK2(angDiff);
|
|
|
|
|
|
|
|
if (tw > dist)
|
|
|
|
{
|
|
|
|
CHECK(temphit);
|
|
|
|
CHECK2(-angDiff);
|
|
|
|
|
|
|
|
if (tw > 768)
|
|
|
|
{
|
|
|
|
CHECK(temphit);
|
|
|
|
VM_CONDITIONAL(1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VM_CONDITIONAL(1);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
|
|
|
|
#undef CHECK
|
|
|
|
#undef CHECK2
|
|
|
|
|
|
|
|
case CON_IFCANSEETARGET:
|
|
|
|
tw = cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - ((krand() & 41) << 8), vm.pSprite->sectnum, pPlayer->pos.x, pPlayer->pos.y,
|
|
|
|
pPlayer->pos.z /*-((krand()&41)<<8)*/, sprite[pPlayer->i].sectnum);
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
if (tw)
|
|
|
|
vm.pActor->timetosleep = SLEEPTIME;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFACTION:
|
|
|
|
VM_CONDITIONAL(AC_ACTION_ID(vm.pData) == *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFACTIONCOUNT:
|
|
|
|
VM_CONDITIONAL(AC_ACTION_COUNT(vm.pData) >= *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFACTOR:
|
|
|
|
VM_CONDITIONAL(vm.pSprite->picnum == *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFACTORNOTSTAYPUT:
|
|
|
|
VM_CONDITIONAL(vm.pActor->stayput == -1);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFAI:
|
|
|
|
VM_CONDITIONAL(AC_AI_ID(vm.pData) == *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFBULLETNEAR:
|
|
|
|
VM_CONDITIONAL(A_Dodge(vm.pSprite) == 1);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFCEILINGDISTL:
|
|
|
|
VM_CONDITIONAL((vm.pSprite->z - vm.pActor->ceilingz) <= ((*(++insptr)) << 8));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFCLIENT:
|
|
|
|
VM_CONDITIONAL(g_netClient != NULL);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFCOUNT:
|
|
|
|
VM_CONDITIONAL(AC_COUNT(vm.pData) >= *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFDEAD:
|
|
|
|
VM_CONDITIONAL(vm.pSprite->extra <= 0);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFFLOORDISTL:
|
|
|
|
VM_CONDITIONAL((vm.pActor->floorz - vm.pSprite->z) <= ((*(++insptr)) << 8));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFGAPZL:
|
|
|
|
VM_CONDITIONAL(((vm.pActor->floorz - vm.pActor->ceilingz) >> 8) < *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFHITSPACE:
|
|
|
|
VM_CONDITIONAL(TEST_SYNC_KEY(g_player[vm.playerNum].inputBits->bits, SK_OPEN));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFHITWEAPON:
|
|
|
|
VM_CONDITIONAL(A_IncurDamage(vm.spriteNum) >= 0);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFINSPACE:
|
|
|
|
VM_CONDITIONAL(G_CheckForSpaceCeiling(vm.pSprite->sectnum));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFINWATER:
|
|
|
|
VM_CONDITIONAL(sector[vm.pSprite->sectnum].lotag == ST_2_UNDERWATER);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFONWATER:
|
|
|
|
VM_CONDITIONAL(sector[vm.pSprite->sectnum].lotag == ST_1_ABOVE_WATER
|
|
|
|
&& klabs(vm.pSprite->z - sector[vm.pSprite->sectnum].floorz) < ZOFFSET5);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFMOVE:
|
|
|
|
VM_CONDITIONAL(AC_MOVE_ID(vm.pData) == *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFMULTIPLAYER:
|
|
|
|
VM_CONDITIONAL((g_netServer || g_netClient || ud.multimode > 1));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFOUTSIDE:
|
|
|
|
VM_CONDITIONAL(sector[vm.pSprite->sectnum].ceilingstat & 1);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFPLAYBACKON:
|
|
|
|
VM_CONDITIONAL(0);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFPLAYERSL:
|
|
|
|
VM_CONDITIONAL(numplayers < *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFSERVER:
|
|
|
|
VM_CONDITIONAL(g_netServer != NULL);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFSQUISHED:
|
|
|
|
VM_CONDITIONAL(VM_CheckSquished());
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFSTRENGTH:
|
|
|
|
VM_CONDITIONAL(vm.pSprite->extra <= *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFSPAWNEDBY:
|
|
|
|
case CON_IFWASWEAPON:
|
|
|
|
VM_CONDITIONAL(vm.pActor->picnum == *(++insptr));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFPDISTL:
|
|
|
|
VM_CONDITIONAL(vm.playerDist < *(++insptr));
|
|
|
|
if (vm.playerDist > MAXSLEEPDIST && vm.pActor->timetosleep == 0)
|
|
|
|
vm.pActor->timetosleep = SLEEPTIME;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFPDISTG:
|
|
|
|
VM_CONDITIONAL(vm.playerDist > *(++insptr));
|
|
|
|
if (vm.playerDist > MAXSLEEPDIST && vm.pActor->timetosleep == 0)
|
|
|
|
vm.pActor->timetosleep = SLEEPTIME;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFRESPAWN:
|
|
|
|
if (A_CheckEnemySprite(vm.pSprite))
|
|
|
|
VM_CONDITIONAL(ud.respawn_monsters)
|
|
|
|
else if (A_CheckInventorySprite(vm.pSprite))
|
|
|
|
VM_CONDITIONAL(ud.respawn_inventory)
|
|
|
|
else
|
|
|
|
VM_CONDITIONAL(ud.respawn_items)
|
|
|
|
continue;
|
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
case CON_IFINOUTERSPACE:
|
|
|
|
VM_CONDITIONAL(G_CheckForSpaceFloor(vm.pSprite->sectnum));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFNOTMOVING:
|
|
|
|
VM_CONDITIONAL((vm.pActor->movflag & 49152) > 16384);
|
|
|
|
continue;
|
|
|
|
|
2018-12-15 01:37:29 +00:00
|
|
|
case CON_IFCANSEE:
|
|
|
|
{
|
|
|
|
auto pSprite = (uspritetype *)&sprite[pPlayer->i];
|
|
|
|
|
|
|
|
// select sprite for monster to target
|
|
|
|
// if holoduke is on, let them target holoduke first.
|
|
|
|
//
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
if (pPlayer->holoduke_on >= 0)
|
|
|
|
{
|
|
|
|
pSprite = (uspritetype *)&sprite[pPlayer->holoduke_on];
|
|
|
|
tw = cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - (krand() & (ZOFFSET5 - 1)), vm.pSprite->sectnum, pSprite->x, pSprite->y,
|
|
|
|
pSprite->z, pSprite->sectnum);
|
|
|
|
|
|
|
|
if (tw == 0)
|
|
|
|
{
|
|
|
|
// they can't see player's holoduke
|
|
|
|
// check for player...
|
|
|
|
pSprite = (uspritetype *)&sprite[pPlayer->i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// can they see player, (or player's holoduke)
|
|
|
|
tw = cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - (krand() & ((47 << 8))), vm.pSprite->sectnum, pSprite->x, pSprite->y,
|
|
|
|
pSprite->z - (24 << 8), pSprite->sectnum);
|
|
|
|
|
|
|
|
if (tw == 0)
|
|
|
|
{
|
|
|
|
// search around for target player
|
|
|
|
// also modifies 'target' x&y if found..
|
|
|
|
|
|
|
|
tw = (A_FurthestVisiblePoint(vm.spriteNum, pSprite, &vm.pActor->lastv) != -1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// else, they did see it.
|
|
|
|
// save where we were looking...
|
|
|
|
vm.pActor->lastv.x = pSprite->x;
|
|
|
|
vm.pActor->lastv.y = pSprite->y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tw && (vm.pSprite->statnum == STAT_ACTOR || vm.pSprite->statnum == STAT_STANDABLE))
|
|
|
|
vm.pActor->timetosleep = SLEEPTIME;
|
|
|
|
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_AI:
|
|
|
|
insptr++;
|
|
|
|
// Following changed to use pointersizes
|
|
|
|
AC_AI_ID(vm.pData) = *insptr++; // Ai
|
|
|
|
AC_ACTION_ID(vm.pData) = *(apScript + AC_AI_ID(vm.pData)); // Action
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
// NOTE: "if" check added in r1155. It used to be a pointer though.
|
|
|
|
if (AC_AI_ID(vm.pData))
|
|
|
|
AC_MOVE_ID(vm.pData) = *(apScript + AC_AI_ID(vm.pData) + 1); // move
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
vm.pSprite->hitag = *(apScript + AC_AI_ID(vm.pData) + 2); // move flags
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
AC_COUNT(vm.pData) = 0;
|
|
|
|
AC_ACTION_COUNT(vm.pData) = 0;
|
|
|
|
AC_CURFRAME(vm.pData) = 0;
|
2018-04-11 03:33:59 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (!A_CheckEnemySprite(vm.pSprite) || vm.pSprite->extra > 0) // hack
|
|
|
|
if (vm.pSprite->hitag & random_angle)
|
|
|
|
vm.pSprite->ang = krand() & 2047;
|
|
|
|
continue;
|
2018-04-11 03:33:59 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ACTION:
|
|
|
|
insptr++;
|
|
|
|
AC_ACTION_COUNT(vm.pData) = 0;
|
|
|
|
AC_CURFRAME(vm.pData) = 0;
|
|
|
|
AC_ACTION_ID(vm.pData) = *insptr++;
|
|
|
|
continue;
|
2018-04-11 03:33:59 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDSTRENGTH:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->extra += *insptr++;
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STRENGTH:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->extra = *insptr++;
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFGOTWEAPONCE:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((g_gametypeFlags[ud.coop] & GAMETYPE_WEAPSTAY) && (g_netServer || ud.multimode > 1))
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (*insptr == 0)
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int j = 0;
|
|
|
|
for (; j < pPlayer->weapreccnt; ++j)
|
|
|
|
if (pPlayer->weaprecs[j] == vm.pSprite->picnum)
|
|
|
|
break;
|
|
|
|
|
|
|
|
VM_CONDITIONAL(j < pPlayer->weapreccnt && vm.pSprite->owner == vm.spriteNum);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
else if (pPlayer->weapreccnt < MAX_WEAPONS)
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
pPlayer->weaprecs[pPlayer->weapreccnt++] = vm.pSprite->picnum;
|
|
|
|
VM_CONDITIONAL(vm.pSprite->owner == vm.spriteNum);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_CONDITIONAL(0);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETLASTPAL:
|
|
|
|
insptr++;
|
|
|
|
if (vm.pSprite->picnum == APLAYER)
|
|
|
|
vm.pSprite->pal = g_player[P_GetP(vm.pSprite)].ps->palookup;
|
|
|
|
else
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (vm.pSprite->pal == 1 && vm.pSprite->extra == 0) // hack for frozen
|
|
|
|
vm.pSprite->extra++;
|
|
|
|
vm.pSprite->pal = vm.pActor->tempang;
|
2007-12-20 19:14:38 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
vm.pActor->tempang = 0;
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_TOSSWEAPON:
|
|
|
|
insptr++;
|
|
|
|
// NOTE: assumes that current actor is APLAYER
|
|
|
|
P_DropWeapon(P_GetP(vm.pSprite));
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MIKESND:
|
|
|
|
insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE(((unsigned)vm.pSprite->yvel >= MAXSOUNDS)))
|
2008-08-10 10:53:55 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid sound %d\n", vm.pUSprite->yvel);
|
|
|
|
continue;
|
2008-08-10 10:53:55 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
if (!S_CheckSoundPlaying(vm.spriteNum, vm.pSprite->yvel))
|
|
|
|
A_PlaySound(vm.pSprite->yvel, vm.spriteNum);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_PKICK:
|
|
|
|
insptr++;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((g_netServer || ud.multimode > 1) && vm.pSprite->picnum == APLAYER)
|
2008-08-10 10:53:55 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (g_player[otherp].ps->quick_kick == 0)
|
|
|
|
g_player[otherp].ps->quick_kick = 14;
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
else if (vm.pSprite->picnum != APLAYER && pPlayer->quick_kick == 0)
|
|
|
|
pPlayer->quick_kick = 14;
|
|
|
|
continue;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SIZETO:
|
|
|
|
insptr++;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
tw = (*insptr++ - vm.pSprite->xrepeat) << 1;
|
|
|
|
vm.pSprite->xrepeat += ksgn(tw);
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((vm.pSprite->picnum == APLAYER && vm.pSprite->yrepeat < 36) || *insptr < vm.pSprite->yrepeat
|
|
|
|
|| ((vm.pSprite->yrepeat * (tilesiz[vm.pSprite->picnum].y + 8)) << 2) < (vm.pActor->floorz - vm.pActor->ceilingz))
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
tw = ((*insptr) - vm.pSprite->yrepeat) << 1;
|
|
|
|
if (klabs(tw))
|
|
|
|
vm.pSprite->yrepeat += ksgn(tw);
|
2008-08-10 10:53:55 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_SIZEAT:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->xrepeat = (uint8_t)*insptr++;
|
|
|
|
vm.pSprite->yrepeat = (uint8_t)*insptr++;
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SOUNDONCE:
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS))
|
2015-03-24 00:40:55 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr++);
|
2017-07-08 19:41:55 +00:00
|
|
|
continue;
|
2008-08-10 10:53:55 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (!S_CheckSoundPlaying(vm.spriteNum, *insptr++))
|
2018-12-15 01:37:39 +00:00
|
|
|
A_PlaySound(insptr[-1], vm.spriteNum);
|
2017-07-08 19:41:55 +00:00
|
|
|
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2008-12-19 00:53:54 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFACTORSOUND:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const soundNum = Gv_GetVarX(*insptr++);
|
2008-12-19 00:53:54 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sound %d\n", soundNum);
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(A_CheckSoundPlaying(spriteNum, soundNum));
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFSOUND:
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS))
|
2017-06-23 03:58:54 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr);
|
|
|
|
continue;
|
2017-06-23 03:58:54 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_CONDITIONAL(S_CheckSoundPlaying(vm.spriteNum, *insptr));
|
|
|
|
// VM_DoConditional(SoundOwner[*insptr][0].ow == vm.spriteNum);
|
2013-06-01 06:55:00 +00:00
|
|
|
continue;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STOPSOUND:
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS))
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
if (S_CheckSoundPlaying(vm.spriteNum, *insptr))
|
|
|
|
S_StopSound((int16_t)*insptr);
|
|
|
|
insptr++;
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STOPACTORSOUND:
|
|
|
|
insptr++;
|
2008-09-01 07:15:16 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const soundNum = Gv_GetVarX(*insptr++);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sound %d\n", soundNum);
|
|
|
|
continue;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (A_CheckSoundPlaying(spriteNum, soundNum))
|
|
|
|
S_StopEnvSound(soundNum, spriteNum);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ACTORSOUND:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.spriteNum;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const soundNum = Gv_GetVarX(*insptr++);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sound %d\n", soundNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
A_PlaySound(soundNum, spriteNum);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETACTORSOUNDPITCH:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const soundNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const newPitch = Gv_GetVarX(*insptr++);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sound %d\n", soundNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_ChangeSoundPitch(soundNum, spriteNum, newPitch);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GLOBALSOUND:
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (vm.playerNum == screenpeek || (g_gametypeFlags[ud.coop] & GAMETYPE_COOPSOUND)
|
|
|
|
#ifdef SPLITSCREEN_MOD_HACKS
|
|
|
|
|| (g_fakeMultiMode == 2)
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
A_PlaySound(*insptr, g_player[screenpeek].ps->i);
|
|
|
|
insptr++;
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SOUND:
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS))
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
A_PlaySound(*insptr++, vm.spriteNum);
|
|
|
|
continue;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_TIP:
|
|
|
|
insptr++;
|
|
|
|
pPlayer->tipincs = GAMETICSPERSEC;
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_FALL:
|
|
|
|
insptr++;
|
|
|
|
VM_Fall(vm.spriteNum, vm.pSprite);
|
|
|
|
continue;
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_NULLOP: insptr++; continue;
|
|
|
|
|
|
|
|
case CON_ADDAMMO:
|
|
|
|
insptr++;
|
2012-11-17 16:48:11 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const weaponNum = *insptr++;
|
|
|
|
int const addAmount = *insptr++;
|
|
|
|
|
|
|
|
VM_AddAmmo(pPlayer, weaponNum, addAmount);
|
|
|
|
|
2012-11-17 16:48:11 +00:00
|
|
|
continue;
|
|
|
|
}
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MONEY:
|
|
|
|
insptr++;
|
|
|
|
A_SpawnMultiple(vm.spriteNum, MONEY, *insptr++);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MAIL:
|
|
|
|
insptr++;
|
|
|
|
A_SpawnMultiple(vm.spriteNum, MAIL, *insptr++);
|
|
|
|
continue;
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SLEEPTIME:
|
|
|
|
insptr++;
|
|
|
|
vm.pActor->timetosleep = (int16_t)*insptr++;
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_PAPER:
|
|
|
|
insptr++;
|
|
|
|
A_SpawnMultiple(vm.spriteNum, PAPER, *insptr++);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDKILLS:
|
|
|
|
insptr++;
|
|
|
|
P_AddKills(pPlayer, *insptr++);
|
2018-11-18 18:07:38 +00:00
|
|
|
vm.pActor->stayput = -1;
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_LOTSOFGLASS:
|
|
|
|
insptr++;
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-05-22 19:03:44 +00:00
|
|
|
A_SpawnGlass(vm.spriteNum, *insptr++);
|
2018-06-09 20:36:31 +00:00
|
|
|
#else
|
|
|
|
insptr++;
|
|
|
|
#endif
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SPAWNWALLGLASS:
|
|
|
|
insptr++;
|
2014-08-31 11:15:22 +00:00
|
|
|
{
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-05-22 19:03:44 +00:00
|
|
|
int const wallNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const numShards = Gv_GetVarX(*insptr++);
|
|
|
|
A_SpawnWallGlass(vm.spriteNum, wallNum, numShards);
|
2018-06-09 20:36:31 +00:00
|
|
|
#else
|
|
|
|
Gv_GetVarX(*insptr++);
|
|
|
|
Gv_GetVarX(*insptr++);
|
|
|
|
#endif
|
2014-08-31 11:15:22 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2014-08-31 11:15:22 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SPAWNWALLSTAINEDGLASS:
|
|
|
|
insptr++;
|
2014-08-31 11:15:22 +00:00
|
|
|
{
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-05-22 19:03:44 +00:00
|
|
|
int const wallNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const numShards = Gv_GetVarX(*insptr++);
|
|
|
|
A_SpawnRandomGlass(vm.spriteNum, wallNum, numShards);
|
2018-06-09 20:36:31 +00:00
|
|
|
#else
|
|
|
|
Gv_GetVarX(*insptr++);
|
|
|
|
Gv_GetVarX(*insptr++);
|
|
|
|
#endif
|
2014-08-31 11:15:22 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2014-08-31 11:15:22 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SPAWNCEILINGGLASS:
|
|
|
|
insptr++;
|
2015-01-11 04:56:10 +00:00
|
|
|
{
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-05-22 19:03:44 +00:00
|
|
|
int const sectNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const numShards = Gv_GetVarX(*insptr++);
|
|
|
|
A_SpawnCeilingGlass(vm.spriteNum, sectNum, numShards);
|
2018-06-09 20:36:31 +00:00
|
|
|
#else
|
|
|
|
Gv_GetVarX(*insptr++);
|
|
|
|
Gv_GetVarX(*insptr++);
|
|
|
|
#endif
|
2006-12-18 08:37:12 +00:00
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_KILLIT:
|
|
|
|
insptr++;
|
|
|
|
vm.flags |= VM_KILL;
|
|
|
|
return;
|
2018-01-29 02:13:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDWEAPON:
|
|
|
|
insptr++;
|
2018-01-29 02:13:55 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const weaponNum = *insptr++;
|
|
|
|
VM_AddWeapon(pPlayer, weaponNum, *insptr++);
|
2018-01-29 02:13:55 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DEBUG:
|
|
|
|
insptr++;
|
|
|
|
buildprint(*insptr++, "\n");
|
2018-01-29 02:13:55 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ENDOFGAME:
|
|
|
|
case CON_ENDOFLEVEL:
|
|
|
|
insptr++;
|
|
|
|
pPlayer->timebeforeexit = *insptr++;
|
|
|
|
pPlayer->customexitsound = -1;
|
2018-12-15 01:37:29 +00:00
|
|
|
ud.eog = 1;
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_ADDPHEALTH:
|
|
|
|
insptr++;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (pPlayer->newowner >= 0)
|
|
|
|
G_ClearCameraView(pPlayer);
|
|
|
|
|
|
|
|
int newHealth = sprite[pPlayer->i].extra;
|
|
|
|
|
2018-11-18 18:13:55 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
if (vm.pSprite->picnum == ATOMICHEALTH)
|
|
|
|
{
|
|
|
|
if (newHealth > 0)
|
|
|
|
newHealth += *insptr;
|
|
|
|
if (newHealth > (pPlayer->max_player_health << 1))
|
|
|
|
newHealth = (pPlayer->max_player_health << 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (newHealth > pPlayer->max_player_health && *insptr > 0)
|
|
|
|
{
|
|
|
|
insptr++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (newHealth > 0)
|
|
|
|
newHealth += *insptr;
|
|
|
|
if (newHealth > pPlayer->max_player_health && *insptr > 0)
|
|
|
|
newHealth = pPlayer->max_player_health;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2014-03-16 14:37:54 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (newHealth < 0)
|
|
|
|
newHealth = 0;
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (ud.god == 0)
|
|
|
|
{
|
|
|
|
if (*insptr > 0)
|
2014-03-16 14:37:54 +00:00
|
|
|
{
|
2018-08-09 16:07:00 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((newHealth - *insptr) < (pPlayer->max_player_health >> 2) && newHealth >= (pPlayer->max_player_health >> 2))
|
|
|
|
A_PlaySound(DUKE_GOTHEALTHATLOW, pPlayer->i);
|
2018-08-09 16:07:00 +00:00
|
|
|
#endif
|
2018-05-22 19:03:44 +00:00
|
|
|
pPlayer->last_extra = newHealth;
|
2014-03-16 14:37:54 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
sprite[pPlayer->i].extra = newHealth;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
insptr++;
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MOVE:
|
|
|
|
insptr++;
|
|
|
|
AC_COUNT(vm.pData) = 0;
|
|
|
|
AC_MOVE_ID(vm.pData) = *insptr++;
|
|
|
|
vm.pSprite->hitag = *insptr++;
|
|
|
|
if (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->extra <= 0) // hack
|
|
|
|
continue;
|
|
|
|
if (vm.pSprite->hitag & random_angle)
|
|
|
|
vm.pSprite->ang = krand() & 2047;
|
|
|
|
continue;
|
2017-06-23 03:58:54 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDWEAPONVAR:
|
|
|
|
insptr++;
|
2017-06-23 03:58:54 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const weaponNum = Gv_GetVarX(*insptr++);
|
|
|
|
VM_AddWeapon(pPlayer, weaponNum, Gv_GetVarX(*insptr++));
|
2017-06-23 03:58:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETASPECT:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const xRange = Gv_GetVarX(*insptr++);
|
|
|
|
renderSetAspect(xRange, Gv_GetVarX(*insptr++));
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2017-07-08 19:41:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SSP:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const clipType = Gv_GetVarX(*insptr++);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
A_SetSprite(spriteNum, clipType);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ACTIVATEBYSECTOR:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const sectNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors))
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid sector %d\n", sectNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
G_ActivateBySector(sectNum, spriteNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2013-06-30 20:38:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_OPERATESECTORS:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const sectNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", sectNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
G_OperateSectors(sectNum, spriteNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_OPERATEACTIVATORS:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const nTag = Gv_GetVarX(*insptr++);
|
2018-12-15 01:37:39 +00:00
|
|
|
int const playerNum = (*insptr++ == g_thisActorVarID) ? vm.playerNum : Gv_GetVarX(insptr[-1]);
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid player %d\n", playerNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
G_OperateActivators(nTag, playerNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
case CON_CANSEESPR:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const nSprite1 = Gv_GetVarX(*insptr++);
|
|
|
|
int const nSprite2 = Gv_GetVarX(*insptr++);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)nSprite1 >= MAXSPRITES || (unsigned)nSprite2 >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", (unsigned)nSprite1 >= MAXSPRITES ? nSprite1 : nSprite2);
|
|
|
|
continue;
|
|
|
|
}
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const nResult = cansee(sprite[nSprite1].x, sprite[nSprite1].y, sprite[nSprite1].z, sprite[nSprite1].sectnum,
|
|
|
|
sprite[nSprite2].x, sprite[nSprite2].y, sprite[nSprite2].z, sprite[nSprite2].sectnum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(*insptr++, nResult);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_OPERATERESPAWNS:
|
|
|
|
insptr++;
|
|
|
|
G_OperateRespawns(Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2017-07-08 19:41:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_OPERATEMASTERSWITCHES:
|
|
|
|
insptr++;
|
|
|
|
G_OperateMasterSwitches(Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2017-07-08 19:41:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CHECKACTIVATORMOTION:
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_returnVarID].global = G_CheckActivatorMotion(Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2017-07-08 19:41:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_INSERTSPRITEQ:
|
|
|
|
insptr++;
|
|
|
|
A_AddToDeleteQueue(vm.spriteNum);
|
|
|
|
continue;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_QSTRLEN:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const gameVar = *insptr++;
|
|
|
|
int const quoteNum = Gv_GetVarX(*insptr++);
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[quoteNum] == NULL))
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("null quote %d\n", quoteNum);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(gameVar, Bstrlen(apStrings[quoteNum]));
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_QSTRDIM:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const widthVar = *insptr++;
|
|
|
|
int const heightVar = *insptr++;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t tileNum;
|
|
|
|
vec3_t vect;
|
|
|
|
int32_t blockAngle, quoteNum, orientation;
|
|
|
|
vec2_t offset, between;
|
|
|
|
int32_t f;
|
|
|
|
vec2_t bound[2];
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE(v.tileNum < 0 || v.tileNum + 127 >= MAXTILES))
|
|
|
|
CON_ERRPRINTF("invalid base tilenum %d\n", v.tileNum);
|
|
|
|
else if (EDUKE32_PREDICT_FALSE((unsigned)v.quoteNum >= MAXQUOTES || apStrings[v.quoteNum] == NULL))
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", v.quoteNum);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vec2_t dim = G_ScreenTextSize(v.tileNum, v.vect.x, v.vect.y, v.vect.z, v.blockAngle, apStrings[v.quoteNum], 2 | v.orientation,
|
|
|
|
v.offset.x, v.offset.y, v.between.x, v.between.y, v.f, v.bound[0].x, v.bound[0].y, v.bound[1].x,
|
|
|
|
v.bound[1].y);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(widthVar, dim.x);
|
|
|
|
Gv_SetVarX(heightVar, dim.y);
|
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_HEADSPRITESTAT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const gameVar = *insptr++;
|
|
|
|
int const statNum = Gv_GetVarX(*insptr++);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)statNum > MAXSTATUS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid status list %d\n", statNum);
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(gameVar, headspritestat[statNum]);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-24 08:20:10 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_PREVSPRITESTAT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const gameVar = *insptr++;
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
2017-07-27 10:08:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2016-10-20 06:26:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(gameVar, prevspritestat[spriteNum]);
|
|
|
|
continue;
|
|
|
|
}
|
2016-10-20 06:26:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_NEXTSPRITESTAT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const gameVar = *insptr++;
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
2006-11-22 01:25:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2016-02-07 02:38:32 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(gameVar, nextspritestat[spriteNum]);
|
|
|
|
continue;
|
|
|
|
}
|
2016-01-21 19:35:34 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_HEADSPRITESECT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const gameVar = *insptr++;
|
|
|
|
int const sectNum = Gv_GetVarX(*insptr++);
|
2009-01-18 07:32:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", sectNum);
|
|
|
|
continue;
|
|
|
|
}
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(gameVar, headspritesect[sectNum]);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_PREVSPRITESECT:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const gameVar = *insptr++;
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(gameVar, prevspritesect[spriteNum]);
|
2010-05-02 23:27:30 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_NEXTSPRITESECT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const gameVar = *insptr++;
|
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(gameVar, nextspritesect[spriteNum]);
|
2010-05-02 23:27:30 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETKEYNAME:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const quoteIndex = Gv_GetVarX(*insptr++);
|
|
|
|
int const gameFunc = Gv_GetVarX(*insptr++);
|
|
|
|
int const funcPos = Gv_GetVarX(*insptr++);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)quoteIndex >= MAXQUOTES || apStrings[quoteIndex] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", quoteIndex);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (EDUKE32_PREDICT_FALSE((unsigned)gameFunc >= NUMGAMEFUNCTIONS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid function %d\n", gameFunc);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (funcPos < 2)
|
|
|
|
Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][funcPos]));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][0]));
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (!*tempbuf)
|
|
|
|
Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][1]));
|
|
|
|
}
|
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (*tempbuf)
|
|
|
|
Bstrcpy(apStrings[quoteIndex], tempbuf);
|
2007-03-11 00:47:32 +00:00
|
|
|
|
2010-05-02 23:27:30 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_QSUBSTR:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t outputQuote, inputQuote, quotePos, quoteLength;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.outputQuote >= MAXQUOTES || apStrings[v.outputQuote] == NULL
|
|
|
|
|| (unsigned)v.inputQuote >= MAXQUOTES
|
|
|
|
|| apStrings[v.inputQuote] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", apStrings[v.outputQuote] ? v.inputQuote : v.outputQuote);
|
2015-01-11 04:56:10 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.quotePos >= MAXQUOTELEN))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid position %d\n", v.quotePos);
|
2015-01-11 04:56:10 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE(v.quoteLength < 0))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid length %d\n", v.quoteLength);
|
2015-01-11 04:56:10 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2007-02-13 01:28:50 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
char * pOutput = apStrings[v.outputQuote];
|
|
|
|
char const *pInput = apStrings[v.inputQuote];
|
|
|
|
|
|
|
|
while (*pInput && v.quotePos--)
|
|
|
|
pInput++;
|
|
|
|
while ((*pOutput = *pInput) && v.quoteLength--)
|
|
|
|
{
|
|
|
|
pOutput++;
|
|
|
|
pInput++;
|
|
|
|
}
|
|
|
|
*pOutput = '\0';
|
2015-02-11 05:22:07 +00:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_QSTRCMP:
|
|
|
|
insptr++;
|
2015-02-11 05:22:07 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const quote1 = Gv_GetVarX(*insptr++);
|
|
|
|
int const quote2 = Gv_GetVarX(*insptr++);
|
|
|
|
int const gameVar = *insptr++;
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[quote1] == NULL || apStrings[quote2] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("null quote %d\n", apStrings[quote1] ? quote2 : quote1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Gv_SetVarX(gameVar, strcmp(apStrings[quote1], apStrings[quote2]));
|
2015-02-11 05:22:07 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETPNAME:
|
|
|
|
case CON_QSTRNCAT:
|
|
|
|
case CON_QSTRCAT:
|
|
|
|
case CON_QSTRCPY:
|
|
|
|
case CON_QGETSYSSTR:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
int const q = Gv_GetVarX(*insptr++);
|
|
|
|
int j;
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw == CON_GETPNAME && *insptr == g_thisActorVarID)
|
|
|
|
{
|
|
|
|
j = vm.playerNum;
|
|
|
|
insptr++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
j = Gv_GetVarX(*insptr++);
|
2017-11-29 07:29:11 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
switch (tw)
|
|
|
|
{
|
|
|
|
case CON_GETPNAME:
|
2018-11-18 18:14:10 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)q >= MAXQUOTES || apStrings[q] == NULL))
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
CON_ERRPRINTF("invalid quote %d\n", q);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (g_player[j].user_name[0])
|
2018-11-18 18:14:10 +00:00
|
|
|
Bstrcpy(apStrings[q], g_player[j].user_name);
|
2018-05-22 19:03:44 +00:00
|
|
|
else
|
2018-11-18 18:14:10 +00:00
|
|
|
Bsprintf(apStrings[q], "%d", j);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
case CON_QGETSYSSTR:
|
2018-11-18 18:14:10 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)q >= MAXQUOTES || apStrings[q] == NULL))
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
CON_ERRPRINTF("invalid quote %d\n", q);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
switch (j)
|
|
|
|
{
|
|
|
|
case STR_MAPNAME:
|
|
|
|
case STR_MAPFILENAME:
|
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
int const levelNum = ud.volume_number * MAXLEVELS + ud.level_number;
|
2018-05-22 19:03:44 +00:00
|
|
|
const char *pName;
|
2014-10-25 03:36:34 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= ARRAY_SIZE(g_mapInfo)))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("out of bounds map number (vol=%d, lev=%d)\n", ud.volume_number, ud.level_number);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
pName = j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename;
|
2007-02-13 01:28:50 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(pName == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("attempted access to %s of non-existent map (vol=%d, lev=%d)",
|
|
|
|
j == STR_MAPNAME ? "name" : "file name", ud.volume_number, ud.level_number);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-11-18 18:14:10 +00:00
|
|
|
Bstrcpy(apStrings[q], j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case STR_PLAYERNAME:
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= (unsigned)g_mostConcurrentPlayers))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid player %d\n", vm.playerNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2018-11-18 18:14:10 +00:00
|
|
|
Bstrcpy(apStrings[q], g_player[vm.playerNum].user_name);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
case STR_VERSION:
|
|
|
|
Bsprintf(tempbuf, HEAD2 " %s", s_buildRev);
|
2018-11-18 18:14:10 +00:00
|
|
|
Bstrcpy(apStrings[q], tempbuf);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
2018-11-18 18:14:10 +00:00
|
|
|
case STR_GAMETYPE: Bstrcpy(apStrings[q], g_gametypeNames[ud.coop]); break;
|
2018-05-22 19:03:44 +00:00
|
|
|
case STR_VOLUMENAME:
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)ud.volume_number >= MAXVOLUMES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid volume %d\n", ud.volume_number);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2018-11-18 18:14:10 +00:00
|
|
|
Bstrcpy(apStrings[q], g_volumeNames[ud.volume_number]);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
2018-12-15 01:37:29 +00:00
|
|
|
case STR_YOURTIME: Bstrcpy(apStrings[q], G_PrintYourTime()); break;
|
|
|
|
case STR_PARTIME: Bstrcpy(apStrings[q], G_PrintParTime()); break;
|
|
|
|
case STR_DESIGNERTIME: Bstrcpy(apStrings[q], G_PrintDesignerTime()); break;
|
|
|
|
case STR_BESTTIME: Bstrcpy(apStrings[q], G_PrintBestTime()); break;
|
|
|
|
case STR_USERMAPFILENAME: Bstrcpy(apStrings[q], boardfilename); break;
|
2018-11-18 18:14:10 +00:00
|
|
|
default: CON_ERRPRINTF("invalid string index %d or %d\n", q, j); continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CON_QSTRCAT:
|
2018-11-18 18:14:10 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL || apStrings[j] == NULL))
|
2018-05-22 19:03:44 +00:00
|
|
|
goto nullquote;
|
2018-11-18 18:14:10 +00:00
|
|
|
Bstrncat(apStrings[q], apStrings[j], (MAXQUOTELEN - 1) - Bstrlen(apStrings[q]));
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
case CON_QSTRNCAT:
|
2018-11-18 18:14:10 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL || apStrings[j] == NULL))
|
2018-05-22 19:03:44 +00:00
|
|
|
goto nullquote;
|
2018-11-18 18:14:10 +00:00
|
|
|
Bstrncat(apStrings[q], apStrings[j], Gv_GetVarX(*insptr++));
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
case CON_QSTRCPY:
|
2018-11-18 18:14:10 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL || apStrings[j] == NULL))
|
2018-05-22 19:03:44 +00:00
|
|
|
goto nullquote;
|
2018-11-18 18:14:10 +00:00
|
|
|
if (q != j)
|
|
|
|
Bstrcpy(apStrings[q], apStrings[j]);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
nullquote:
|
2018-11-18 18:14:10 +00:00
|
|
|
CON_ERRPRINTF("invalid quote %d\n", apStrings[q] ? j : q);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2013-06-07 14:26:32 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CHANGESPRITESECT:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const sectNum = Gv_GetVarX(*insptr++);
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES || (unsigned)sectNum >= MAXSECTORS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid parameters: %d, %d\n", spriteNum, sectNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sprite[spriteNum].sectnum == sectNum)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
changespritesect(spriteNum, sectNum);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CHANGESPRITESTAT:
|
|
|
|
insptr++;
|
2018-03-07 12:02:03 +00:00
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
int const spriteNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const statNum = Gv_GetVarX(*insptr++);
|
2018-03-07 12:02:03 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES || (unsigned)statNum >= MAXSECTORS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid parameters: %d, %d\n", spriteNum, statNum);
|
|
|
|
continue;
|
|
|
|
}
|
2007-03-11 00:47:32 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (sprite[spriteNum].statnum == statNum)
|
|
|
|
continue;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
/* initialize actor data when changing to an actor statnum because there's usually
|
|
|
|
garbage left over from being handled as a hard coded object */
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (sprite[spriteNum].statnum > STAT_ZOMBIEACTOR && (statNum == STAT_ACTOR || statNum == STAT_ZOMBIEACTOR))
|
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
auto pActor = &actor[spriteNum];
|
|
|
|
auto pSprite = &sprite[spriteNum];
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
Bmemset(&pActor->t_data, 0, sizeof pActor->t_data);
|
2018-11-18 18:14:10 +00:00
|
|
|
|
|
|
|
pActor->lastv = { 0, 0 };
|
|
|
|
pActor->timetosleep = 0;
|
|
|
|
pActor->cgg = 0;
|
|
|
|
pActor->movflag = 0;
|
|
|
|
pActor->tempang = 0;
|
|
|
|
pActor->dispicnum = 0;
|
|
|
|
pActor->flags = 0;
|
|
|
|
pSprite->hitag = 0;
|
|
|
|
|
|
|
|
if (G_HaveActor(pSprite->picnum))
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-11-18 18:14:10 +00:00
|
|
|
auto actorptr = g_tile[pSprite->picnum].execPtr;
|
2018-05-22 19:03:44 +00:00
|
|
|
// offsets
|
|
|
|
AC_ACTION_ID(pActor->t_data) = actorptr[1];
|
|
|
|
AC_MOVE_ID(pActor->t_data) = actorptr[2];
|
2018-11-18 18:14:10 +00:00
|
|
|
AC_MOVFLAGS(pSprite, pActor) = actorptr[3]; // ai bits (movflags)
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
changespritestat(spriteNum, statNum);
|
|
|
|
continue;
|
|
|
|
}
|
2014-04-09 18:51:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STARTLEVEL:
|
|
|
|
insptr++; // skip command
|
2010-05-02 23:27:30 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
// from 'level' cheat in game.c (about line 6250)
|
|
|
|
int const volumeNum = Gv_GetVarX(*insptr++);
|
|
|
|
int const levelNum = Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)volumeNum >= MAXVOLUMES || (unsigned)levelNum >= MAXLEVELS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid parameters: %d, %d\n", volumeNum, levelNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ud.m_volume_number = ud.volume_number = volumeNum;
|
|
|
|
ud.m_level_number = ud.level_number = levelNum;
|
|
|
|
// if (numplayers > 1 && g_netServer)
|
|
|
|
// Net_NewGame(volnume,levnume);
|
|
|
|
//else
|
|
|
|
{
|
|
|
|
g_player[myconnectindex].ps->gm |= MODE_EOL;
|
|
|
|
ud.display_bonus_screen = 0;
|
|
|
|
} // MODE_RESTART;
|
|
|
|
|
|
|
|
continue;
|
2010-05-02 23:27:30 +00:00
|
|
|
}
|
2010-03-01 03:04:57 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MYOSX:
|
|
|
|
case CON_MYOSPALX:
|
|
|
|
case CON_MYOS:
|
|
|
|
case CON_MYOSPAL:
|
|
|
|
insptr++;
|
2011-10-30 19:46:51 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec2_t pos;
|
|
|
|
int32_t tilenum, shade, orientation;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
|
|
|
|
switch (tw)
|
|
|
|
{
|
|
|
|
case CON_MYOS: VM_DrawTile(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation); break;
|
|
|
|
case CON_MYOSPAL: VM_DrawTilePal(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation, Gv_GetVarX(*insptr++)); break;
|
|
|
|
case CON_MYOSX: VM_DrawTileSmall(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation); break;
|
|
|
|
case CON_MYOSPALX: VM_DrawTilePalSmall(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation, Gv_GetVarX(*insptr++)); break;
|
|
|
|
}
|
2011-10-30 19:46:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DISPLAYRAND:
|
|
|
|
insptr++;
|
|
|
|
Gv_SetVarX(*insptr++, system_15bit_rand());
|
2010-05-02 23:27:30 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DRAGPOINT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const wallNum = Gv_GetVarX(*insptr++);
|
|
|
|
vec2_t n;
|
|
|
|
Gv_FillWithVars(n);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)wallNum >= (unsigned)numwalls))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid wall %d\n", wallNum);
|
|
|
|
continue;
|
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
dragpoint(wallNum, n.x, n.y, 0);
|
2011-10-30 19:46:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_LDIST:
|
|
|
|
case CON_DIST:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const out = *insptr++;
|
|
|
|
vec2_t in;
|
|
|
|
Gv_FillWithVars(in);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)in.x >= MAXSPRITES || (unsigned)in.y >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d, %d\n", in.x, in.y);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Gv_SetVarX(out, (tw == CON_LDIST ? ldist : dist)(&sprite[in.x], &sprite[in.y]));
|
|
|
|
continue;
|
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETANGLE:
|
|
|
|
case CON_GETINCANGLE:
|
|
|
|
insptr++;
|
2011-10-30 19:46:51 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const out = *insptr++;
|
|
|
|
vec2_t in;
|
|
|
|
Gv_FillWithVars(in);
|
|
|
|
Gv_SetVarX(out, (tw == CON_GETANGLE ? getangle : G_GetAngleDelta)(in.x, in.y));
|
2011-10-30 19:46:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MULSCALE:
|
|
|
|
case CON_DIVSCALE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const out = *insptr++;
|
|
|
|
vec3_t in;
|
|
|
|
Gv_FillWithVars(in);
|
|
|
|
|
|
|
|
if (tw == CON_MULSCALE)
|
|
|
|
Gv_SetVarX(out, mulscale(in.x, in.y, in.z));
|
|
|
|
else
|
|
|
|
Gv_SetVarX(out, divscale(in.x, in.y, in.z));
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2013-06-01 06:55:00 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SCALEVAR:
|
|
|
|
insptr++;
|
2013-06-01 06:55:00 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const out = *insptr++;
|
|
|
|
vec3_t in;
|
|
|
|
Gv_FillWithVars(in);
|
|
|
|
Gv_SetVarX(out, scale(in.x, in.y, in.z));
|
2013-06-01 06:55:00 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_INITTIMER:
|
|
|
|
insptr++;
|
|
|
|
G_InitTimer(Gv_GetVarX(*insptr++));
|
2013-06-01 06:55:00 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_NEXTSECTORNEIGHBORZ:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t params[4];
|
|
|
|
Gv_FillWithVars(params);
|
|
|
|
aGameVars[g_returnVarID].global = nextsectorneighborz(params[0], params[1], params[2], params[3]);
|
2015-01-11 04:56:10 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2009-01-13 12:23:18 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MOVESECTOR:
|
|
|
|
insptr++;
|
|
|
|
A_MoveSector(Gv_GetVarX(*insptr++));
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_TIME: insptr += 2; continue;
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ESPAWNVAR:
|
|
|
|
case CON_EQSPAWNVAR:
|
|
|
|
case CON_QSPAWNVAR:
|
|
|
|
insptr++;
|
2010-09-27 21:52:04 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const tileNum = Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int const spriteNum = A_Spawn(vm.spriteNum, tileNum);
|
|
|
|
|
|
|
|
switch (tw)
|
|
|
|
{
|
|
|
|
case CON_EQSPAWNVAR:
|
|
|
|
if (spriteNum != -1)
|
|
|
|
A_AddToDeleteQueue(spriteNum);
|
|
|
|
fallthrough__;
|
|
|
|
case CON_ESPAWNVAR: aGameVars[g_returnVarID].global = spriteNum; break;
|
|
|
|
case CON_QSPAWNVAR:
|
|
|
|
if (spriteNum != -1)
|
|
|
|
A_AddToDeleteQueue(spriteNum);
|
|
|
|
break;
|
|
|
|
}
|
2010-09-27 21:52:04 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SHOOTVAR:
|
|
|
|
case CON_ESHOOTVAR:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int j = Gv_GetVarX(*insptr++);
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum);
|
|
|
|
continue;
|
|
|
|
}
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
j = A_Shoot(vm.spriteNum, j);
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw == CON_ESHOOTVAR)
|
|
|
|
aGameVars[g_returnVarID].global = j;
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_EZSHOOTVAR:
|
|
|
|
case CON_ZSHOOTVAR:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const zvel = (int16_t)Gv_GetVarX(*insptr++);
|
|
|
|
int j = Gv_GetVarX(*insptr++);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum);
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-27 09:13:21 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
j = A_ShootWithZvel(vm.spriteNum, j, zvel);
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw == CON_EZSHOOTVAR)
|
|
|
|
aGameVars[g_returnVarID].global = j;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2010-09-27 21:52:04 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CMENU:
|
|
|
|
insptr++;
|
|
|
|
Menu_Change(Gv_GetVarX(*insptr++));
|
2010-09-27 21:52:04 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SOUNDVAR:
|
|
|
|
case CON_STOPSOUNDVAR:
|
|
|
|
case CON_SOUNDONCEVAR:
|
|
|
|
case CON_GLOBALSOUNDVAR:
|
|
|
|
case CON_SCREENSOUND:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const soundNum = Gv_GetVarX(*insptr++);
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sound %d\n", soundNum);
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
switch (tw)
|
|
|
|
{
|
|
|
|
case CON_SOUNDONCEVAR:
|
|
|
|
if (!S_CheckSoundPlaying(vm.spriteNum, soundNum))
|
|
|
|
{
|
|
|
|
fallthrough__;
|
|
|
|
case CON_SOUNDVAR: A_PlaySound((int16_t)soundNum, vm.spriteNum);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
case CON_GLOBALSOUNDVAR: A_PlaySound((int16_t)soundNum, g_player[screenpeek].ps->i); continue;
|
|
|
|
case CON_STOPSOUNDVAR:
|
|
|
|
if (S_CheckSoundPlaying(vm.spriteNum, soundNum))
|
|
|
|
S_StopSound((int16_t)soundNum);
|
|
|
|
continue;
|
|
|
|
case CON_SCREENSOUND: A_PlaySound(soundNum, -1); continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STARTCUTSCENE:
|
|
|
|
case CON_IFCUTSCENE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const nQuote = Gv_GetVarX(*insptr++);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)nQuote >= MAXQUOTES || apStrings[nQuote] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d for anim!\n", nQuote);
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw == CON_IFCUTSCENE)
|
|
|
|
{
|
|
|
|
insptr--;
|
|
|
|
VM_CONDITIONAL(g_animPtr == Anim_Find(apStrings[nQuote]));
|
|
|
|
continue;
|
|
|
|
}
|
2010-09-27 21:52:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
tw = pPlayer->palette;
|
|
|
|
I_ClearAllInput();
|
|
|
|
Anim_Play(apStrings[nQuote]);
|
|
|
|
P_SetGamePalette(pPlayer, tw, 2 + 16);
|
2010-09-27 21:52:04 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STARTSCREEN:
|
|
|
|
insptr++;
|
|
|
|
I_ClearAllInput();
|
|
|
|
Screen_Play();
|
2010-09-27 21:52:04 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GUNIQHUDID:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXUNIQHUDID - 1))
|
|
|
|
CON_ERRPRINTF("invalid value %d\n", (int)tw);
|
|
|
|
else
|
|
|
|
guniqhudid = tw;
|
|
|
|
|
2015-01-11 04:56:10 +00:00
|
|
|
continue;
|
2009-01-13 12:23:18 +00:00
|
|
|
}
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SAVEGAMEVAR:
|
|
|
|
case CON_READGAMEVAR:
|
2008-08-09 10:43:27 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t nValue = 0;
|
|
|
|
insptr++;
|
|
|
|
if (ud.config.scripthandle < 0)
|
2009-01-13 12:23:18 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
switch (tw)
|
|
|
|
{
|
|
|
|
case CON_SAVEGAMEVAR:
|
|
|
|
nValue = Gv_GetVarX(*insptr);
|
|
|
|
SCRIPT_PutNumber(ud.config.scripthandle, "Gamevars", aGameVars[*insptr++].szLabel, nValue, FALSE, FALSE);
|
|
|
|
break;
|
|
|
|
case CON_READGAMEVAR:
|
|
|
|
SCRIPT_GetNumber(ud.config.scripthandle, "Gamevars", aGameVars[*insptr].szLabel, &nValue);
|
|
|
|
Gv_SetVarX(*insptr++, nValue);
|
|
|
|
break;
|
2009-01-13 12:23:18 +00:00
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2008-07-25 01:09:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SHOWVIEW:
|
|
|
|
case CON_SHOWVIEWUNBIASED:
|
|
|
|
case CON_SHOWVIEWQ16:
|
|
|
|
case CON_SHOWVIEWQ16UNBIASED:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec3_t vec;
|
|
|
|
int32_t params[3];
|
|
|
|
vec2_t scrn[2];
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(v.scrn[0].x < 0 || v.scrn[0].y < 0 || v.scrn[1].x >= 320 || v.scrn[1].y >= 200))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("incorrect coordinates\n");
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.params[2] >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", v.params[2]);
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw != CON_SHOWVIEWQ16 && tw != CON_SHOWVIEWQ16UNBIASED)
|
|
|
|
{
|
|
|
|
v.params[0] <<= 16;
|
|
|
|
v.params[1] <<= 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
G_ShowView(v.vec, v.params[0], v.params[1], v.params[2], v.scrn[0].x, v.scrn[0].y, v.scrn[1].x, v.scrn[1].y,
|
|
|
|
(tw != CON_SHOWVIEW && tw != CON_SHOWVIEWQ16));
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ROTATESPRITEA:
|
|
|
|
case CON_ROTATESPRITE16:
|
|
|
|
case CON_ROTATESPRITE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec3_t pos;
|
|
|
|
int32_t ang, tilenum, shade, pal, orientation;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t alpha = (tw == CON_ROTATESPRITEA) ? Gv_GetVarX(*insptr++) : 0;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
vec2_t bound[2];
|
|
|
|
Gv_FillWithVars(bound);
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw != CON_ROTATESPRITE16 && !(v.orientation & ROTATESPRITE_FULL16))
|
|
|
|
{
|
|
|
|
v.pos.x <<= 16;
|
|
|
|
v.pos.y <<= 16;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.tilenum >= MAXTILES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid tilenum %d\n", v.tilenum);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t blendidx = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
NEG_ALPHA_TO_BLEND(alpha, blendidx, v.orientation);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
rotatesprite_(v.pos.x, v.pos.y, v.pos.z, v.ang, v.tilenum, v.shade, v.pal, 2 | (v.orientation & (ROTATESPRITE_MAX - 1)), alpha,
|
|
|
|
blendidx, bound[0].x, bound[0].y, bound[1].x, bound[1].y);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2008-08-09 11:19:27 +00:00
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GAMETEXT:
|
|
|
|
case CON_GAMETEXTZ:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t tilenum;
|
|
|
|
vec2_t pos;
|
|
|
|
int32_t nQuote, shade, pal, orientation;
|
|
|
|
vec2_t bound[2];
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2006-12-18 08:37:12 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t const z = (tw == CON_GAMETEXTZ) ? Gv_GetVarX(*insptr++) : 65536;
|
2015-05-26 00:48:17 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum + 127 >= MAXTILES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum);
|
|
|
|
continue;
|
|
|
|
}
|
2015-05-26 00:48:17 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", v.nQuote);
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-24 00:40:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
G_PrintGameText(v.tilenum, v.pos.x >> 1, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1),
|
|
|
|
v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y, z, 0);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2008-08-09 10:43:27 +00:00
|
|
|
}
|
2015-05-26 00:48:17 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DIGITALNUMBER:
|
|
|
|
case CON_DIGITALNUMBERZ:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t tilenum;
|
|
|
|
vec2_t pos;
|
|
|
|
int32_t nQuote, shade, pal, orientation;
|
|
|
|
vec2_t bound[2];
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2015-05-26 00:48:17 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t const nZoom = (tw == CON_DIGITALNUMBERZ) ? Gv_GetVarX(*insptr++) : 65536;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
// NOTE: '-' not taken into account, but we have rotatesprite() bound check now anyway
|
|
|
|
if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum + 9 >= MAXTILES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
G_DrawTXDigiNumZ(v.tilenum, v.pos.x, v.pos.y, v.nQuote, v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1), v.bound[0].x,
|
|
|
|
v.bound[0].y, v.bound[1].x, v.bound[1].y, nZoom);
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MINITEXT:
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec2_t pos;
|
|
|
|
int32_t nQuote, shade, pal;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", v.nQuote);
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
minitextshade(v.pos.x, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, 2 + 8 + 16);
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SCREENTEXT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t tilenum;
|
|
|
|
vec3_t v;
|
|
|
|
int32_t blockangle, charangle, nQuote, shade, pal, orientation, alpha;
|
|
|
|
vec2_t spacing, between;
|
|
|
|
int32_t nFlags;
|
|
|
|
vec2_t bound[2];
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum + 127 >= MAXTILES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum);
|
|
|
|
continue;
|
|
|
|
}
|
2007-02-08 04:19:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", v.nQuote);
|
|
|
|
continue;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
G_ScreenText(v.tilenum, v.v.x, v.v.y, v.v.z, v.blockangle, v.charangle, apStrings[v.nQuote], v.shade, v.pal,
|
|
|
|
2 | (v.orientation & (ROTATESPRITE_MAX - 1)), v.alpha, v.spacing.x, v.spacing.y, v.between.x, v.between.y, v.nFlags,
|
|
|
|
v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y);
|
|
|
|
continue;
|
|
|
|
}
|
2006-12-19 20:31:40 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ANGOFF:
|
|
|
|
insptr++;
|
|
|
|
spriteext[vm.spriteNum].angoff = *insptr++;
|
|
|
|
continue;
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETZRANGE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
vec3_t vect;
|
|
|
|
int32_t sectNum;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
|
|
|
|
int const ceilzvar = *insptr++;
|
|
|
|
int const ceilhitvar = *insptr++;
|
|
|
|
int const florzvar = *insptr++;
|
|
|
|
int const florhitvar = *insptr++;
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t walldist, clipmask;
|
|
|
|
} v2;
|
|
|
|
Gv_FillWithVars(v2);
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", v.sectNum);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t ceilz, ceilhit, florz, florhit;
|
2007-01-05 22:30:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
getzrange(&v.vect, v.sectNum, &ceilz, &ceilhit, &florz, &florhit, v2.walldist, v2.clipmask);
|
|
|
|
Gv_SetVarX(ceilzvar, ceilz);
|
|
|
|
Gv_SetVarX(ceilhitvar, ceilhit);
|
|
|
|
Gv_SetVarX(florzvar, florz);
|
|
|
|
Gv_SetVarX(florhitvar, florhit);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SECTSETINTERPOLATION:
|
|
|
|
case CON_SECTCLEARINTERPOLATION:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const sectnum = Gv_GetVarX(*insptr++);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)sectnum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", sectnum);
|
|
|
|
continue;
|
|
|
|
}
|
2009-01-07 14:05:13 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw == CON_SECTSETINTERPOLATION)
|
|
|
|
Sect_SetInterpolation(sectnum);
|
|
|
|
else
|
|
|
|
Sect_ClearInterpolation(sectnum);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2017-12-18 11:24:53 +00:00
|
|
|
}
|
2017-06-22 22:49:22 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CALCHYPOTENUSE:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t returnVar = *insptr++;
|
|
|
|
vec2_t da;
|
|
|
|
Gv_FillWithVars(da);
|
|
|
|
int64_t const hypsq = (int64_t)da.x * da.x + (int64_t)da.y * da.y;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(returnVar, (hypsq > (int64_t)INT32_MAX) ? (int32_t)sqrt((double)hypsq) : ksqrt((uint32_t)hypsq));
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_LINEINTERSECT:
|
|
|
|
case CON_RAYINTERSECT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec3_t vec[2];
|
|
|
|
vec2_t vec2[2];
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const intxvar = *insptr++;
|
|
|
|
int const intyvar = *insptr++;
|
|
|
|
int const intzvar = *insptr++;
|
|
|
|
int const retvar = *insptr++;
|
|
|
|
vec3_t in;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int ret = ((tw == CON_LINEINTERSECT) ? lintersect : rayintersect)(v.vec[0].x, v.vec[0].y, v.vec[0].z, v.vec[1].x, v.vec[1].y,
|
|
|
|
v.vec[1].z, v.vec2[0].x, v.vec2[0].y, v.vec2[1].x, v.vec2[1].y,
|
|
|
|
&in.x, &in.y, &in.z);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(retvar, ret);
|
2015-03-04 02:15:15 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
Gv_SetVarX(intxvar, in.x);
|
|
|
|
Gv_SetVarX(intyvar, in.y);
|
|
|
|
Gv_SetVarX(intzvar, in.z);
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CLIPMOVE:
|
|
|
|
case CON_CLIPMOVENOSLIDE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int32_t w, f, c;
|
|
|
|
} vec3dist_t;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const returnVar = *insptr++;
|
|
|
|
int const xReturn = *insptr++;
|
|
|
|
int const yReturn = *insptr++;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr -= 2;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
vec3_t vec3;
|
|
|
|
int32_t sectNum32;
|
|
|
|
vec2_t vec2;
|
|
|
|
vec3dist_t dist;
|
|
|
|
int32_t clipMask;
|
|
|
|
} clipmoveparams_t;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t const sectReturn = insptr[offsetof(clipmoveparams_t, sectNum32) / sizeof(int32_t)];
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
clipmoveparams_t v;
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
int16_t sectNum = v.sectNum32;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", sectNum);
|
|
|
|
continue;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(
|
|
|
|
returnVar,
|
|
|
|
clipmovex(&v.vec3, §Num, v.vec2.x, v.vec2.y, v.dist.w, v.dist.f, v.dist.c, v.clipMask, (tw == CON_CLIPMOVENOSLIDE)));
|
|
|
|
Gv_SetVarX(sectReturn, v.sectNum32);
|
|
|
|
Gv_SetVarX(xReturn, v.vec3.x);
|
|
|
|
Gv_SetVarX(yReturn, v.vec3.y);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_HITSCAN:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec3_t origin;
|
|
|
|
int32_t sectnum;
|
|
|
|
vec3_t vect;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
|
|
|
|
int const sectReturn = *insptr++;
|
|
|
|
int const wallReturn = *insptr++;
|
|
|
|
int const spriteReturn = *insptr++;
|
|
|
|
int const xReturn = *insptr++;
|
|
|
|
int const yReturn = *insptr++;
|
|
|
|
int const zReturn = *insptr++;
|
|
|
|
int const clipType = Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.sectnum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", v.sectnum);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
hitdata_t hit;
|
|
|
|
hitscan(&v.origin, v.sectnum, v.vect.x, v.vect.y, v.vect.z, &hit, clipType);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(sectReturn, hit.sect);
|
|
|
|
Gv_SetVarX(wallReturn, hit.wall);
|
|
|
|
Gv_SetVarX(spriteReturn, hit.sprite);
|
|
|
|
Gv_SetVarX(xReturn, hit.pos.x);
|
|
|
|
Gv_SetVarX(yReturn, hit.pos.y);
|
|
|
|
Gv_SetVarX(zReturn, hit.pos.z);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CANSEE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec3_t vec1;
|
|
|
|
int32_t firstSector;
|
|
|
|
vec3_t vec2;
|
|
|
|
int32_t secondSector;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const returnVar = *insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.firstSector >= (unsigned)numsectors || (unsigned)v.secondSector >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", (unsigned)v.firstSector >= (unsigned)numsectors ? v.firstSector : v.secondSector);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(returnVar, cansee(v.vec1.x, v.vec1.y, v.vec1.z, v.firstSector, v.vec2.x, v.vec2.y, v.vec2.z, v.secondSector));
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2013-05-19 19:29:23 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ROTATEPOINT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec2_t point[2];
|
|
|
|
int32_t angle;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2017-08-06 13:45:02 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const xReturn = *insptr++;
|
|
|
|
int const yReturn = *insptr++;
|
|
|
|
vec2_t result;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
rotatepoint(v.point[0], v.point[1], v.angle, &result);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(xReturn, result.x);
|
|
|
|
Gv_SetVarX(yReturn, result.y);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_NEARTAG:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
// neartag(int32_t x, int32_t y, int32_t z, short sectnum, short ang, //Starting position & angle
|
|
|
|
// short *neartagsector, //Returns near sector if sector[].tag != 0
|
|
|
|
// short *neartagwall, //Returns near wall if wall[].tag != 0
|
|
|
|
// short *neartagsprite, //Returns near sprite if sprite[].tag != 0
|
|
|
|
// int32_t *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size)
|
|
|
|
// int32_t neartagrange, //Choose maximum distance to scan (scale: 1024=largest grid size)
|
|
|
|
// char tagsearch) //1-lotag only, 2-hitag only, 3-lotag&hitag
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
vec3_t point;
|
|
|
|
int32_t sectNum, nAngle;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2010-07-22 20:29:09 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const sectReturn = *insptr++;
|
|
|
|
int const wallReturn = *insptr++;
|
|
|
|
int const spriteReturn = *insptr++;
|
|
|
|
int const distReturn = *insptr++;
|
2010-07-22 20:29:09 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t tagRange, tagSearch;
|
|
|
|
} v2;
|
|
|
|
Gv_FillWithVars(v2);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("Invalid sector %d\n", v.sectNum);
|
|
|
|
continue;
|
|
|
|
}
|
2016-10-14 07:40:41 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int16_t neartagsector, neartagwall, neartagsprite;
|
|
|
|
int32_t neartaghitdist;
|
2014-01-31 21:13:00 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
neartag(v.point.x, v.point.y, v.point.z, v.sectNum, v.nAngle, &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist,
|
|
|
|
v2.tagRange, v2.tagSearch, NULL);
|
2012-02-20 19:54:24 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(sectReturn, neartagsector);
|
|
|
|
Gv_SetVarX(wallReturn, neartagwall);
|
|
|
|
Gv_SetVarX(spriteReturn, neartagsprite);
|
|
|
|
Gv_SetVarX(distReturn, neartaghitdist);
|
|
|
|
continue;
|
|
|
|
}
|
2014-01-31 21:13:00 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETTIMEDATE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int32_t values[8];
|
|
|
|
G_GetTimeDate(values);
|
2014-01-31 21:13:00 +00:00
|
|
|
|
2018-10-25 23:33:40 +00:00
|
|
|
for (int value : values)
|
|
|
|
Gv_SetVarX(*insptr++, value);
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_MOVESPRITE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t spriteNum;
|
|
|
|
vec3_t vect;
|
|
|
|
int32_t clipType;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", v.spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(*insptr++, A_MoveSprite(v.spriteNum, &v.vect, v.clipType));
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETSPRITE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t spriteNum;
|
|
|
|
vec3_t vect;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.spriteNum >= MAXSPRITES))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sprite %d\n", v.spriteNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
setsprite(v.spriteNum, &v.vect);
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETFLORZOFSLOPE:
|
|
|
|
case CON_GETCEILZOFSLOPE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int32_t sectNum;
|
|
|
|
vec2_t vect;
|
|
|
|
} v;
|
|
|
|
Gv_FillWithVars(v);
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", v.sectNum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Gv_SetVarX(*insptr++, (tw == CON_GETFLORZOFSLOPE ? getflorzofslope : getceilzofslope)(v.sectNum, v.vect.x, v.vect.y));
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_UPDATESECTOR:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
vec2_t vect = { 0, 0 };
|
|
|
|
Gv_FillWithVars(vect);
|
2017-11-29 07:29:14 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const returnVar = *insptr++;
|
|
|
|
int16_t sectNum = sprite[vm.spriteNum].sectnum;
|
2009-07-12 01:55:34 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
updatesector(vect.x, vect.y, §Num);
|
|
|
|
Gv_SetVarX(returnVar, sectNum);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_UPDATESECTORZ:
|
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
vec3_t vect = { 0, 0, 0 };
|
|
|
|
Gv_FillWithVars(vect);
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const returnVar = *insptr++;
|
|
|
|
int16_t sectNum = sprite[vm.spriteNum].sectnum;
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
updatesectorz(vect.x, vect.y, vect.z, §Num);
|
|
|
|
Gv_SetVarX(returnVar, sectNum);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SPAWN:
|
|
|
|
insptr++;
|
|
|
|
if ((unsigned)vm.pSprite->sectnum >= MAXSECTORS)
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
A_Spawn(vm.spriteNum, *insptr++);
|
|
|
|
continue;
|
2009-07-12 01:55:34 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_RESETACTIONCOUNT:
|
|
|
|
insptr++;
|
|
|
|
AC_ACTION_COUNT(vm.pData) = 0;
|
|
|
|
continue;
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DEBRIS:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-11-18 18:13:55 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-05-22 19:03:44 +00:00
|
|
|
int debrisTile = *insptr++;
|
2009-07-12 01:55:34 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((unsigned)vm.pSprite->sectnum < MAXSECTORS)
|
|
|
|
for (native_t cnt = (*insptr) - 1; cnt >= 0; cnt--)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int const tileOffset = (vm.pSprite->picnum == BLIMP && debrisTile == SCRAP1) ? 0 : (krand() % 3);
|
2009-07-15 01:26:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const spriteNum = A_InsertSprite(vm.pSprite->sectnum, vm.pSprite->x + (krand() & 255) - 128,
|
|
|
|
vm.pSprite->y + (krand() & 255) - 128, vm.pSprite->z - (8 << 8) - (krand() & 8191),
|
|
|
|
debrisTile + tileOffset, vm.pSprite->shade, 32 + (krand() & 15), 32 + (krand() & 15),
|
|
|
|
krand() & 2047, (krand() & 127) + 32, -(krand() & 2047), vm.spriteNum, 5);
|
2009-07-12 01:55:34 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
sprite[spriteNum].yvel = (vm.pSprite->picnum == BLIMP && debrisTile == SCRAP1) ? g_blimpSpawnItems[cnt % 14] : -1;
|
|
|
|
sprite[spriteNum].pal = vm.pSprite->pal;
|
2009-07-12 01:55:34 +00:00
|
|
|
}
|
2018-11-18 18:13:55 +00:00
|
|
|
#else
|
|
|
|
insptr++;
|
|
|
|
#endif
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
continue;
|
2008-08-09 12:42:02 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_COUNT:
|
|
|
|
insptr++;
|
|
|
|
AC_COUNT(vm.pData) = (int16_t)*insptr++;
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CSTATOR:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->cstat |= (int16_t)*insptr++;
|
|
|
|
continue;
|
2008-08-25 20:25:49 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CLIPDIST:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->clipdist = (int16_t)*insptr++;
|
|
|
|
continue;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CSTAT:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->cstat = (int16_t)*insptr++;
|
|
|
|
continue;
|
2007-02-08 04:19:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SAVENN:
|
|
|
|
case CON_SAVE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int32_t const requestedSlot = *insptr++;
|
2008-04-01 03:32:36 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((unsigned)requestedSlot >= 10)
|
|
|
|
continue;
|
2008-04-27 06:54:28 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
// check if we need to make a new file
|
|
|
|
if (strcmp(g_lastautosave.path, g_lastusersave.path) == 0 || requestedSlot != g_lastAutoSaveArbitraryID)
|
2008-04-27 06:54:28 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
g_lastautosave.reset();
|
2008-04-01 03:32:36 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
g_lastAutoSaveArbitraryID = requestedSlot;
|
|
|
|
|
|
|
|
if (tw == CON_SAVE || g_lastautosave.name[0] == 0)
|
2008-04-01 03:32:36 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
time_t timeStruct = time(NULL);
|
|
|
|
struct tm *pTime = localtime(&timeStruct);
|
|
|
|
|
|
|
|
strftime(g_lastautosave.name, sizeof(g_lastautosave.name), "%d %b %Y %I:%M%p", pTime);
|
2008-04-01 03:32:36 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
g_saveRequested = true;
|
|
|
|
|
|
|
|
continue;
|
2007-02-08 04:19:39 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
case CON_QUAKE:
|
2009-06-19 01:10:10 +00:00
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
g_earthquakeTime = Gv_GetVarX(*insptr++);
|
|
|
|
A_PlaySound(EARTHQUAKE, g_player[screenpeek].ps->i);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2015-03-25 06:27:25 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_RESETPLAYER:
|
|
|
|
insptr++;
|
|
|
|
vm.flags = VM_ResetPlayer(vm.playerNum, vm.flags, 0);
|
|
|
|
continue;
|
2015-03-25 06:27:25 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_RESETPLAYERFLAGS:
|
|
|
|
insptr++;
|
|
|
|
vm.flags = VM_ResetPlayer(vm.playerNum, vm.flags, Gv_GetVarX(*insptr++));
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_RESETCOUNT:
|
|
|
|
insptr++;
|
|
|
|
AC_COUNT(vm.pData) = 0;
|
|
|
|
continue;
|
2012-05-14 18:12:27 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDINVENTORY:
|
|
|
|
insptr += 2;
|
2012-05-14 18:12:27 +00:00
|
|
|
|
2018-12-15 01:37:39 +00:00
|
|
|
VM_AddInventory(pPlayer, insptr[-1], *insptr);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_HITRADIUSVAR:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int32_t params[5];
|
|
|
|
Gv_FillWithVars(params);
|
|
|
|
A_RadiusDamage(vm.spriteNum, params[0], params[1], params[2], params[3], params[4]);
|
2008-08-24 10:19:37 +00:00
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2008-12-19 00:53:54 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_HITRADIUS:
|
2018-12-15 01:37:39 +00:00
|
|
|
A_RadiusDamage(vm.spriteNum, insptr[1], insptr[2], insptr[3], insptr[4], insptr[5]);
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 6;
|
|
|
|
continue;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFP:
|
|
|
|
{
|
|
|
|
int const moveFlags = *(++insptr);
|
|
|
|
int nResult = 0;
|
|
|
|
int const playerXVel = sprite[pPlayer->i].xvel;
|
|
|
|
int const syncBits = g_player[vm.playerNum].inputBits->bits;
|
|
|
|
|
|
|
|
if (((moveFlags & pducking) && pPlayer->on_ground && TEST_SYNC_KEY(syncBits, SK_CROUCH))
|
|
|
|
|| ((moveFlags & pfalling) && pPlayer->jumping_counter == 0 && !pPlayer->on_ground && pPlayer->vel.z > 2048)
|
|
|
|
|| ((moveFlags & pjumping) && pPlayer->jumping_counter > 348)
|
|
|
|
|| ((moveFlags & pstanding) && playerXVel >= 0 && playerXVel < 8)
|
|
|
|
|| ((moveFlags & pwalking) && playerXVel >= 8 && !TEST_SYNC_KEY(syncBits, SK_RUN))
|
|
|
|
|| ((moveFlags & prunning) && playerXVel >= 8 && TEST_SYNC_KEY(syncBits, SK_RUN))
|
|
|
|
|| ((moveFlags & phigher) && pPlayer->pos.z < (vm.pSprite->z - (48 << 8)))
|
|
|
|
|| ((moveFlags & pwalkingback) && playerXVel <= -8 && !TEST_SYNC_KEY(syncBits, SK_RUN))
|
|
|
|
|| ((moveFlags & prunningback) && playerXVel <= -8 && TEST_SYNC_KEY(syncBits, SK_RUN))
|
|
|
|
|| ((moveFlags & pkicking)
|
|
|
|
&& (pPlayer->quick_kick > 0
|
|
|
|
|| (PWEAPON(vm.playerNum, pPlayer->curr_weapon, WorksLike) == KNEE_WEAPON && pPlayer->kickback_pic > 0)))
|
|
|
|
|| ((moveFlags & pshrunk) && sprite[pPlayer->i].xrepeat < 32)
|
|
|
|
|| ((moveFlags & pjetpack) && pPlayer->jetpack_on)
|
|
|
|
|| ((moveFlags & ponsteroids) && pPlayer->inv_amount[GET_STEROIDS] > 0 && pPlayer->inv_amount[GET_STEROIDS] < 400)
|
|
|
|
|| ((moveFlags & ponground) && pPlayer->on_ground)
|
|
|
|
|| ((moveFlags & palive) && sprite[pPlayer->i].xrepeat > 32 && sprite[pPlayer->i].extra > 0 && pPlayer->timebeforeexit == 0)
|
|
|
|
|| ((moveFlags & pdead) && sprite[pPlayer->i].extra <= 0))
|
|
|
|
nResult = 1;
|
|
|
|
else if ((moveFlags & pfacing))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
nResult
|
|
|
|
= (vm.pSprite->picnum == APLAYER && (g_netServer || ud.multimode > 1))
|
|
|
|
? G_GetAngleDelta(fix16_to_int(g_player[otherp].ps->q16ang),
|
|
|
|
getangle(pPlayer->pos.x - g_player[otherp].ps->pos.x, pPlayer->pos.y - g_player[otherp].ps->pos.y))
|
|
|
|
: G_GetAngleDelta(fix16_to_int(pPlayer->q16ang), getangle(vm.pSprite->x - pPlayer->pos.x, vm.pSprite->y - pPlayer->pos.y));
|
2018-01-31 04:13:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
nResult = (nResult > -128 && nResult < 128);
|
2008-08-24 06:17:09 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_CONDITIONAL(nResult);
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-24 08:20:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GUTS:
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-12-15 01:37:39 +00:00
|
|
|
A_DoGuts(vm.spriteNum, insptr[1], insptr[2]);
|
2018-06-09 20:36:31 +00:00
|
|
|
#endif
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 3;
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
2015-03-25 06:27:25 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_WACKPLAYER:
|
|
|
|
insptr++;
|
|
|
|
P_ForceAngle(pPlayer);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2018-02-26 20:19:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_FLASH:
|
|
|
|
insptr++;
|
|
|
|
sprite[vm.spriteNum].shade = -127;
|
|
|
|
pPlayer->visibility = -127;
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
2018-03-15 01:19:27 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SAVEMAPSTATE:
|
|
|
|
G_SaveMapState();
|
|
|
|
insptr++;
|
2018-03-15 01:19:27 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_LOADMAPSTATE:
|
|
|
|
G_RestoreMapState();
|
|
|
|
insptr++;
|
2018-03-15 01:19:27 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CLEARMAPSTATE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const levelNum = Gv_GetVarX(*insptr++);
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= MAXVOLUMES * MAXLEVELS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid map number %d\n", levelNum);
|
|
|
|
continue;
|
|
|
|
}
|
2018-02-26 20:19:55 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
G_FreeMapState(levelNum);
|
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2008-08-09 12:29:23 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STOPALLSOUNDS:
|
|
|
|
insptr++;
|
|
|
|
if (screenpeek == vm.playerNum)
|
|
|
|
FX_StopAllSounds();
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STOPALLMUSIC:
|
|
|
|
insptr++;
|
|
|
|
S_StopMusic();
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_OPERATE:
|
|
|
|
insptr++;
|
|
|
|
if (sector[vm.pSprite->sectnum].lotag == 0)
|
2008-08-09 12:29:23 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int16_t foundSect, foundWall, foundSprite;
|
|
|
|
int32_t foundDist;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
neartag(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - ZOFFSET5, vm.pSprite->sectnum, vm.pSprite->ang, &foundSect, &foundWall,
|
|
|
|
&foundSprite, &foundDist, 768, 4 + 1, NULL);
|
2017-07-27 09:13:21 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (foundSect >= 0 && isanearoperator(sector[foundSect].lotag))
|
|
|
|
if ((sector[foundSect].lotag & 0xff) == ST_23_SWINGING_DOOR || sector[foundSect].floorz == sector[foundSect].ceilingz)
|
|
|
|
if ((sector[foundSect].lotag & (16384u | 32768u)) == 0)
|
|
|
|
{
|
|
|
|
int32_t j;
|
2008-08-09 12:29:23 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
for (SPRITES_OF_SECT(foundSect, j))
|
|
|
|
if (sprite[j].picnum == ACTIVATOR)
|
|
|
|
break;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (j == -1)
|
|
|
|
G_OperateSectors(foundSect, vm.spriteNum);
|
|
|
|
}
|
|
|
|
}
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2007-02-08 04:19:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SPRITEPAL:
|
|
|
|
insptr++;
|
|
|
|
if (vm.pSprite->picnum != APLAYER)
|
|
|
|
vm.pActor->tempang = vm.pSprite->pal;
|
|
|
|
vm.pSprite->pal = *insptr++;
|
|
|
|
continue;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CACTOR:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->picnum = *insptr++;
|
|
|
|
continue;
|
2008-12-13 07:23:13 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_PALFROM:
|
|
|
|
insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= (unsigned)g_mostConcurrentPlayers))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid player %d\n", vm.playerNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
palette_t const pal = { uint8_t(insptr[1]), uint8_t(insptr[2]), uint8_t(insptr[3]), uint8_t(insptr[0]) };
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 4;
|
|
|
|
P_PalFrom(pPlayer, pal.f, pal.r, pal.g, pal.b);
|
|
|
|
}
|
2015-03-25 06:27:25 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SCREENPAL:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int32_t params[4];
|
|
|
|
Gv_FillWithVars(params);
|
|
|
|
videoFadePalette(params[0], params[1], params[2], params[3]);
|
|
|
|
}
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SECTOROFWALL:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_SetVarX(tw, sectorofwall(Gv_GetVarX(*insptr++)));
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2008-08-09 10:16:18 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_QSPRINTF:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const outputQuote = Gv_GetVarX(*insptr++);
|
|
|
|
int const inputQuote = Gv_GetVarX(*insptr++);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[inputQuote] == NULL || apStrings[outputQuote] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("null quote %d\n", apStrings[inputQuote] ? outputQuote : inputQuote);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-12-15 01:37:44 +00:00
|
|
|
auto &inBuf = apStrings[inputQuote];
|
|
|
|
|
|
|
|
int32_t arg[32];
|
|
|
|
char outBuf[MAXQUOTELEN];
|
|
|
|
|
|
|
|
int const quoteLen = Bstrlen(inBuf);
|
|
|
|
|
|
|
|
int inputPos = 0;
|
|
|
|
int outputPos = 0;
|
|
|
|
int argIdx = 0;
|
2015-02-11 05:22:11 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
while ((*insptr & VM_INSTMASK) != CON_NULLOP && argIdx < 32)
|
|
|
|
arg[argIdx++] = Gv_GetVarX(*insptr++);
|
2017-07-27 09:13:21 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int numArgs = argIdx;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++; // skip the NOP
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
argIdx = 0;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
do
|
|
|
|
{
|
2018-12-15 01:37:44 +00:00
|
|
|
while (inputPos < quoteLen && outputPos < MAXQUOTELEN && inBuf[inputPos] != '%')
|
|
|
|
outBuf[outputPos++] = inBuf[inputPos++];
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-12-15 01:37:44 +00:00
|
|
|
if (inBuf[inputPos] == '%')
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
|
|
|
inputPos++;
|
2018-12-15 01:37:44 +00:00
|
|
|
switch (inBuf[inputPos])
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
|
|
|
case 'l':
|
2018-12-15 01:37:44 +00:00
|
|
|
if (inBuf[inputPos + 1] != 'd')
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
|
|
|
// write the % and l
|
2018-12-15 01:37:44 +00:00
|
|
|
outBuf[outputPos++] = inBuf[inputPos - 1];
|
|
|
|
outBuf[outputPos++] = inBuf[inputPos++];
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
inputPos++;
|
|
|
|
fallthrough__;
|
|
|
|
case 'd':
|
|
|
|
{
|
|
|
|
if (argIdx >= numArgs)
|
|
|
|
goto finish_qsprintf;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
char buf[16];
|
|
|
|
Bsprintf(buf, "%d", arg[argIdx++]);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const bufLen = Bstrlen(buf);
|
2018-12-15 01:37:44 +00:00
|
|
|
Bmemcpy(&outBuf[outputPos], buf, bufLen);
|
|
|
|
outputPos += bufLen;
|
2018-05-22 19:03:44 +00:00
|
|
|
inputPos++;
|
|
|
|
}
|
|
|
|
break;
|
2016-01-02 01:56:29 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case 's':
|
|
|
|
{
|
|
|
|
if (argIdx >= numArgs)
|
|
|
|
goto finish_qsprintf;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const argLen = Bstrlen(apStrings[arg[argIdx]]);
|
2009-02-19 09:39:19 +00:00
|
|
|
|
2018-12-15 01:37:44 +00:00
|
|
|
Bmemcpy(&outBuf[outputPos], apStrings[arg[argIdx]], argLen);
|
|
|
|
outputPos += argLen;
|
2018-05-22 19:03:44 +00:00
|
|
|
argIdx++;
|
|
|
|
inputPos++;
|
|
|
|
}
|
|
|
|
break;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-12-15 01:37:44 +00:00
|
|
|
default: outBuf[outputPos++] = inBuf[inputPos - 1]; break;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
}
|
2018-12-15 01:37:44 +00:00
|
|
|
} while (inputPos < quoteLen && outputPos < MAXQUOTELEN);
|
2018-05-22 19:03:44 +00:00
|
|
|
finish_qsprintf:
|
2018-12-15 01:37:44 +00:00
|
|
|
outBuf[outputPos] = '\0';
|
2018-05-22 19:03:44 +00:00
|
|
|
Bstrncpyz(apStrings[outputQuote], outBuf, MAXQUOTELEN);
|
2012-12-13 02:33:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDLOG:
|
|
|
|
{
|
|
|
|
insptr++;
|
2017-07-08 05:18:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
initprintf(OSDTEXT_GREEN "CONLOG: L=%d\n", g_errorLineNum);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ADDLOGVAR:
|
|
|
|
insptr++;
|
2015-02-11 05:22:11 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t m = 1;
|
|
|
|
char szBuf[256];
|
|
|
|
int32_t lVarID = *insptr;
|
2009-02-19 09:39:19 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((lVarID >= g_gameVarCount) || lVarID < 0)
|
2017-07-27 09:13:21 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (*insptr == MAXGAMEVARS) // addlogvar for a constant? Har.
|
|
|
|
insptr++;
|
|
|
|
// else if (*insptr > g_gameVarCount && (*insptr < (MAXGAMEVARS<<1)+MAXGAMEVARS+1+MAXGAMEARRAYS))
|
|
|
|
else if (*insptr & (MAXGAMEVARS << 2))
|
|
|
|
{
|
|
|
|
int32_t index;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
lVarID ^= (MAXGAMEVARS << 2);
|
2017-07-28 08:27:35 +00:00
|
|
|
|
2018-11-18 18:10:57 +00:00
|
|
|
if (lVarID & GV_FLAG_NEGATIVE)
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
|
|
|
m = -m;
|
2018-11-18 18:10:57 +00:00
|
|
|
lVarID ^= GV_FLAG_NEGATIVE;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2017-07-08 19:41:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
2017-07-08 19:41:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
index = Gv_GetVarX(*insptr++);
|
|
|
|
if (EDUKE32_PREDICT_TRUE((unsigned)index < (unsigned)aGameArrays[lVarID].size))
|
|
|
|
{
|
|
|
|
initprintf(OSDTEXT_GREEN "CONLOGVAR: L=%d %s[%d] =%d\n", g_errorLineNum, aGameArrays[lVarID].szLabel, index,
|
|
|
|
(int32_t)(m * Gv_GetArrayValue(lVarID, index)));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid array index\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (*insptr & (MAXGAMEVARS << 3))
|
|
|
|
{
|
|
|
|
// FIXME FIXME FIXME
|
|
|
|
if ((lVarID & (MAXGAMEVARS - 1)) == g_structVarIDs + STRUCT_ACTORVAR)
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const oinsptr = insptr++;
|
|
|
|
int32_t index = Gv_GetVarX(*insptr++);
|
|
|
|
insptr = oinsptr;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXSPRITES - 1))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid array index\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
initprintf(OSDTEXT_GREEN "CONLOGVAR: L=%d %d %d\n", g_errorLineNum, index, Gv_GetVar(*insptr++, index, vm.playerNum));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2018-11-18 18:10:57 +00:00
|
|
|
else if (EDUKE32_PREDICT_TRUE(*insptr & GV_FLAG_NEGATIVE))
|
2017-07-28 08:27:35 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
m = -m;
|
2018-11-18 18:10:57 +00:00
|
|
|
lVarID ^= GV_FLAG_NEGATIVE;
|
2017-07-28 08:27:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
// invalid varID
|
|
|
|
CON_ERRPRINTF("invalid variable\n");
|
|
|
|
continue; // out of switch
|
2017-07-28 08:27:35 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
Bsprintf(tempbuf, "CONLOGVAR: L=%d %s ", g_errorLineNum, aGameVars[lVarID].szLabel);
|
2017-07-08 19:41:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (aGameVars[lVarID].flags & GAMEVAR_READONLY)
|
|
|
|
{
|
|
|
|
Bsprintf(szBuf, " (read-only)");
|
|
|
|
Bstrcat(tempbuf, szBuf);
|
2017-07-08 19:41:43 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
if (aGameVars[lVarID].flags & GAMEVAR_PERPLAYER)
|
|
|
|
{
|
|
|
|
Bsprintf(szBuf, " (Per Player. Player=%d)", vm.playerNum);
|
|
|
|
}
|
|
|
|
else if (aGameVars[lVarID].flags & GAMEVAR_PERACTOR)
|
|
|
|
{
|
|
|
|
Bsprintf(szBuf, " (Per Actor. Actor=%d)", vm.spriteNum);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Bsprintf(szBuf, " (Global)");
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
Bstrcat(tempbuf, szBuf);
|
|
|
|
Bsprintf(szBuf, " =%d\n", Gv_GetVarX(lVarID) * m);
|
|
|
|
Bstrcat(tempbuf, szBuf);
|
|
|
|
initprintf(OSDTEXT_GREEN "%s", tempbuf);
|
|
|
|
insptr++;
|
|
|
|
continue;
|
2017-07-08 19:41:43 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SQRT:
|
|
|
|
insptr++;
|
2015-02-11 05:22:11 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
// syntax sqrt <invar> <outvar>
|
|
|
|
int const sqrtval = ksqrt((uint32_t)Gv_GetVarX(*insptr++));
|
|
|
|
Gv_SetVarX(*insptr++, sqrtval);
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_FINDNEARACTORVAR:
|
|
|
|
case CON_FINDNEARSPRITEVAR:
|
|
|
|
case CON_FINDNEARACTOR3DVAR:
|
|
|
|
case CON_FINDNEARSPRITE3DVAR:
|
|
|
|
insptr++;
|
2017-07-08 19:41:43 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
// syntax findnearactorvar <type> <maxdistvar> <getvar>
|
|
|
|
// gets the sprite ID of the nearest actor within max dist
|
|
|
|
// that is of <type> into <getvar>
|
|
|
|
// -1 for none found
|
|
|
|
// <type> <maxdistvarid> <varid>
|
|
|
|
int const findPicnum = *insptr++;
|
|
|
|
int const maxDist = Gv_GetVarX(*insptr++);
|
|
|
|
int const returnVar = *insptr++;
|
|
|
|
|
|
|
|
int foundSprite = -1;
|
|
|
|
int findStatnum = STAT_ACTOR;
|
|
|
|
int spriteNum;
|
|
|
|
|
|
|
|
if (tw == CON_FINDNEARSPRITEVAR || tw == CON_FINDNEARSPRITE3DVAR)
|
|
|
|
findStatnum = MAXSTATUS - 1;
|
|
|
|
|
|
|
|
if (tw == CON_FINDNEARACTOR3DVAR || tw == CON_FINDNEARSPRITE3DVAR)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
spriteNum = headspritestat[findStatnum]; // all sprites
|
2017-07-08 19:41:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
while (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum
|
|
|
|
&& dist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist)
|
|
|
|
{
|
|
|
|
foundSprite = spriteNum;
|
|
|
|
spriteNum = MAXSPRITES;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
spriteNum = nextspritestat[spriteNum];
|
|
|
|
}
|
|
|
|
if (spriteNum == MAXSPRITES || tw == CON_FINDNEARACTOR3DVAR)
|
|
|
|
break;
|
|
|
|
} while (findStatnum--);
|
|
|
|
Gv_SetVarX(returnVar, foundSprite);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
spriteNum = headspritestat[findStatnum]; // all sprites
|
|
|
|
|
|
|
|
while (spriteNum >= 0)
|
|
|
|
{
|
|
|
|
if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum
|
|
|
|
&& ldist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist)
|
|
|
|
{
|
|
|
|
foundSprite = spriteNum;
|
|
|
|
spriteNum = MAXSPRITES;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
spriteNum = nextspritestat[spriteNum];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (spriteNum == MAXSPRITES || tw == CON_FINDNEARACTORVAR)
|
|
|
|
break;
|
|
|
|
} while (findStatnum--);
|
|
|
|
Gv_SetVarX(returnVar, foundSprite);
|
|
|
|
continue;
|
2017-07-08 19:41:43 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_FINDNEARACTORZVAR:
|
|
|
|
case CON_FINDNEARSPRITEZVAR:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
// syntax findnearactorvar <type> <maxdistvar> <getvar>
|
|
|
|
// gets the sprite ID of the nearest actor within max dist
|
|
|
|
// that is of <type> into <getvar>
|
|
|
|
// -1 for none found
|
|
|
|
// <type> <maxdistvarid> <varid>
|
|
|
|
int const findPicnum = *insptr++;
|
|
|
|
int const maxDist = Gv_GetVarX(*insptr++);
|
|
|
|
int const maxZDist = Gv_GetVarX(*insptr++);
|
|
|
|
int const returnVar = *insptr++;
|
|
|
|
|
|
|
|
int foundSprite = -1;
|
|
|
|
int findStatnum = MAXSTATUS - 1;
|
2010-03-18 09:10:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
int spriteNum = headspritestat[tw == CON_FINDNEARACTORZVAR ? STAT_ACTOR : findStatnum]; // all sprites
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (spriteNum == -1)
|
|
|
|
continue;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum)
|
|
|
|
{
|
|
|
|
if (ldist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist)
|
|
|
|
{
|
|
|
|
if (klabs(sprite[vm.spriteNum].z - sprite[spriteNum].z) < maxZDist)
|
|
|
|
{
|
|
|
|
foundSprite = spriteNum;
|
|
|
|
spriteNum = MAXSPRITES;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
spriteNum = nextspritestat[spriteNum];
|
|
|
|
} while (spriteNum >= 0);
|
|
|
|
|
|
|
|
if (tw == CON_FINDNEARACTORZVAR || spriteNum == MAXSPRITES)
|
|
|
|
break;
|
|
|
|
} while (findStatnum--);
|
|
|
|
Gv_SetVarX(returnVar, foundSprite);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_FINDPLAYER:
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t tw;
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_returnVarID].global = A_FindPlayer(&sprite[vm.spriteNum], &tw);
|
|
|
|
Gv_SetVarX(*insptr++, tw);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_FINDOTHERPLAYER:
|
2018-12-15 01:37:29 +00:00
|
|
|
{
|
|
|
|
int32_t tw;
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
2018-12-15 01:37:29 +00:00
|
|
|
aGameVars[g_returnVarID].global = P_FindOtherPlayer(vm.playerNum, &tw);
|
|
|
|
Gv_SetVarX(*insptr++, tw);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2015-05-25 18:58:31 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETINPUT:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.playerNum;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const labelNum = *insptr++;
|
2015-05-25 18:58:31 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(*insptr++, VM_GetPlayerInput(playerNum, labelNum));
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETINPUT:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.playerNum;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const labelNum = *insptr++;
|
2016-08-27 01:42:19 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_SetPlayerInput(playerNum, labelNum, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2009-02-19 09:39:19 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETUSERDEF:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const labelNum = *insptr++;
|
|
|
|
int const lParm2 = (UserdefsLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0;
|
2012-12-13 02:33:53 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(*insptr++, VM_GetUserdef(labelNum, lParm2));
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETTILEDATA:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const tileNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.pSprite->picnum;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const labelNum = *insptr++;
|
2012-12-13 02:33:53 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_SetVarX(*insptr++, VM_GetTileData(tileNum, labelNum));
|
2015-03-24 00:40:55 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETTILEDATA:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-12-15 01:37:39 +00:00
|
|
|
int const tileNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(insptr[-1]) : vm.pSprite->picnum;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const labelNum = *insptr++;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_SetTileData(tileNum, labelNum, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETUSERDEF:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const labelNum = *insptr++;
|
|
|
|
int const lParm2 = (UserdefsLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0;
|
2017-07-08 19:41:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_SetUserdef(labelNum, lParm2, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-08 19:41:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETPROJECTILE:
|
|
|
|
insptr++;
|
2017-07-08 19:41:43 +00:00
|
|
|
{
|
2018-11-18 18:10:39 +00:00
|
|
|
tw = Gv_GetVarX(*insptr++);
|
2018-05-22 19:03:44 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
Gv_SetVarX(*insptr++, VM_GetProjectile(tw, labelNum));
|
|
|
|
continue;
|
2017-07-08 19:41:43 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
case CON_SETPROJECTILE:
|
|
|
|
insptr++;
|
2012-12-13 02:33:53 +00:00
|
|
|
{
|
2018-11-18 18:10:39 +00:00
|
|
|
tw = Gv_GetVarX(*insptr++);
|
2018-05-22 19:03:44 +00:00
|
|
|
int const labelNum = *insptr++;
|
|
|
|
VM_SetProjectile(tw, labelNum, Gv_GetVarX(*insptr++));
|
|
|
|
continue;
|
2012-12-13 02:33:53 +00:00
|
|
|
}
|
2017-07-08 19:41:43 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETANGLETOTARGET:
|
2015-02-11 05:22:11 +00:00
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
// vm.pActor->lastvx and lastvy are last known location of target.
|
|
|
|
Gv_SetVarX(*insptr++, getangle(vm.pActor->lastv.x - vm.pSprite->x, vm.pActor->lastv.y - vm.pSprite->y));
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ANGOFFVAR:
|
2015-02-11 05:22:11 +00:00
|
|
|
insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
spriteext[vm.spriteNum].angoff = Gv_GetVarX(*insptr++);
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
2008-05-10 01:29:37 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_LOCKPLAYER:
|
|
|
|
insptr++;
|
|
|
|
pPlayer->transporter_hold = Gv_GetVarX(*insptr++);
|
|
|
|
continue;
|
2008-08-11 10:38:46 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CHECKAVAILWEAPON:
|
|
|
|
case CON_CHECKAVAILINVEN:
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr++;
|
|
|
|
int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*insptr) : vm.playerNum;
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers))
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_ERRPRINTF("invalid player %d\n", (int)playerNum);
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (tw == CON_CHECKAVAILWEAPON)
|
|
|
|
P_CheckWeapon(g_player[playerNum].ps);
|
|
|
|
else
|
|
|
|
P_SelectNextInvItem(g_player[playerNum].ps);
|
|
|
|
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETPLAYERANGLE:
|
|
|
|
insptr++;
|
|
|
|
Gv_SetVarX(*insptr++, fix16_to_int(pPlayer->q16ang));
|
|
|
|
continue;
|
2018-01-29 02:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETACTORANGLE:
|
|
|
|
insptr++;
|
|
|
|
Gv_SetVarX(*insptr++, vm.pSprite->ang);
|
|
|
|
continue;
|
2018-01-29 02:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETPLAYERANGLE:
|
|
|
|
insptr++;
|
|
|
|
pPlayer->q16ang = fix16_from_int(Gv_GetVarX(*insptr++) & 2047);
|
2018-01-29 02:14:04 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETACTORANGLE:
|
|
|
|
insptr++;
|
|
|
|
vm.pSprite->ang = Gv_GetVarX(*insptr++) & 2047;
|
|
|
|
continue;
|
2018-01-29 02:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_KLABS:
|
2018-12-15 01:37:39 +00:00
|
|
|
if ((aGameVars[insptr[1]].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0)
|
|
|
|
aGameVars[insptr[1]].global = klabs(aGameVars[insptr[1]].global);
|
2018-05-22 19:03:44 +00:00
|
|
|
else
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_SetVarX(insptr[1], klabs(Gv_GetVarX(insptr[1])));
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2018-01-29 02:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETARRAY:
|
|
|
|
insptr++;
|
2018-01-29 02:14:04 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
tw = *insptr++;
|
2018-01-29 02:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const arrayIndex = Gv_GetVarX(*insptr++);
|
|
|
|
int const newValue = Gv_GetVarX(*insptr++);
|
2018-01-29 02:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)tw >= (unsigned)g_gameArrayCount || (unsigned)arrayIndex >= (unsigned)aGameArrays[tw].size))
|
|
|
|
{
|
|
|
|
OSD_Printf(OSD_ERROR "Gv_SetVar(): tried to set invalid array %d or index out of bounds from "
|
|
|
|
"sprite %d (%d), player %d\n",
|
|
|
|
(int)tw, vm.spriteNum, TrackerCast(sprite[vm.spriteNum].picnum), vm.playerNum);
|
2018-11-18 18:10:45 +00:00
|
|
|
vm.flags |= VM_RETURN;
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
auto &arr = aGameArrays[tw];
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE(arr.flags & GAMEARRAY_READONLY))
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-11-18 18:10:51 +00:00
|
|
|
OSD_Printf(OSD_ERROR "Tried to set value in read-only array `%s'", arr.szLabel);
|
2018-11-18 18:10:45 +00:00
|
|
|
vm.flags |= VM_RETURN;
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
switch (arr.flags & GAMEARRAY_TYPE_MASK)
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-11-18 18:10:51 +00:00
|
|
|
case 0: arr.pValues[arrayIndex] = newValue; break;
|
|
|
|
case GAMEARRAY_INT16: ((int16_t *)arr.pValues)[arrayIndex] = newValue; break;
|
|
|
|
case GAMEARRAY_INT8: ((int8_t *)arr.pValues)[arrayIndex] = newValue; break;
|
|
|
|
case GAMEARRAY_UINT16: ((uint16_t *)arr.pValues)[arrayIndex] = newValue; break;
|
|
|
|
case GAMEARRAY_UINT8: ((int8_t *)arr.pValues)[arrayIndex] = newValue; break;
|
2018-05-22 19:03:44 +00:00
|
|
|
case GAMEARRAY_BITMAP:
|
|
|
|
{
|
|
|
|
uint32_t const mask = (1 << (arrayIndex & 7));
|
2018-11-18 18:10:51 +00:00
|
|
|
uint8_t &value = ((uint8_t *)arr.pValues)[arrayIndex >> 3];
|
|
|
|
value = (value & ~mask) | (-!!newValue & mask);
|
2018-05-22 19:03:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2009-07-12 23:41:16 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2008-09-07 12:36:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_READARRAYFROMFILE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const arrayNum = *insptr++;
|
|
|
|
int const quoteFilename = *insptr++;
|
2008-09-07 12:36:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[quoteFilename] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("null quote %d\n", quoteFilename);
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int kFile = kopen4loadfrommod(apStrings[quoteFilename], 0);
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (kFile < 0)
|
|
|
|
continue;
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
size_t const filelength = kfilelength(kFile);
|
|
|
|
size_t const numElements = Gv_GetArrayCountFromFile(arrayNum, filelength);
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (numElements > 0)
|
|
|
|
{
|
|
|
|
size_t const newBytes = Gv_GetArrayAllocSizeForCount(arrayNum, numElements);
|
|
|
|
size_t const readBytes = min(newBytes, filelength);
|
|
|
|
size_t const oldBytes = Gv_GetArrayAllocSize(arrayNum);
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
intptr_t *&pValues = aGameArrays[arrayNum].pValues;
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (newBytes != oldBytes)
|
|
|
|
{
|
|
|
|
Baligned_free(pValues);
|
|
|
|
pValues = (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, newBytes);
|
|
|
|
}
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
aGameArrays[arrayNum].size = numElements;
|
Adds the following keywords from M32script into CON: shiftvarvarl, shiftvarvarr, ifvarvarle, ifvarvarge, ifvarvarboth, whilevarl, and whilevarvarl.
This also adds the shorthand versions of some commands, like "set" for "setvarvar", "add" for "addvarvar", "ife" for "ifvarvare", etc. There are about 30 of these. Because some of these names may already be used in some projects as variable names, this revision also includes a somewhat large change in variable naming rules: gamevars may now have the same names as CON keywords, with the caveat that the masked keyword is no longer accessible. This results in a warning at compile time but should ensure nobody's project ever stops compiling due to the introduction of new keywords.
git-svn-id: https://svn.eduke32.com/eduke32@5499 1a8010ca-5511-0410-912e-c29ae57300e0
2016-01-02 01:56:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
uintptr_t const flags = aGameArrays[arrayNum].flags;
|
Adds the following keywords from M32script into CON: shiftvarvarl, shiftvarvarr, ifvarvarle, ifvarvarge, ifvarvarboth, whilevarl, and whilevarvarl.
This also adds the shorthand versions of some commands, like "set" for "setvarvar", "add" for "addvarvar", "ife" for "ifvarvare", etc. There are about 30 of these. Because some of these names may already be used in some projects as variable names, this revision also includes a somewhat large change in variable naming rules: gamevars may now have the same names as CON keywords, with the caveat that the masked keyword is no longer accessible. This results in a warning at compile time but should ensure nobody's project ever stops compiling due to the introduction of new keywords.
git-svn-id: https://svn.eduke32.com/eduke32@5499 1a8010ca-5511-0410-912e-c29ae57300e0
2016-01-02 01:56:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
switch (flags & GAMEARRAY_SIZE_MASK)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
#ifdef BITNESS64
|
|
|
|
{
|
|
|
|
void *const pArray = Xcalloc(1, newBytes);
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
kread(kFile, pArray, readBytes);
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (flags & GAMEARRAY_UNSIGNED)
|
|
|
|
{
|
|
|
|
for (unative_t i = 0; i < numElements; ++i)
|
|
|
|
pValues[i] = ((uint32_t *)pArray)[i];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (unative_t i = 0; i < numElements; ++i)
|
|
|
|
pValues[i] = ((int32_t *)pArray)[i];
|
|
|
|
}
|
2008-09-07 12:36:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Bfree(pArray);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
memset((char *)pValues + readBytes, 0, newBytes - readBytes);
|
|
|
|
kread(kFile, pValues, readBytes);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-09-07 12:36:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
kclose(kFile);
|
|
|
|
continue;
|
|
|
|
}
|
2008-09-07 12:36:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_WRITEARRAYTOFILE:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const arrayNum = *insptr++;
|
|
|
|
int const quoteFilename = *insptr++;
|
2006-04-18 02:01:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(apStrings[quoteFilename] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("null quote %d\n", quoteFilename);
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
char temp[BMAX_PATH];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(G_ModDirSnprintf(temp, sizeof(temp), "%s", apStrings[quoteFilename])))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("file name too long\n");
|
|
|
|
continue;
|
|
|
|
}
|
2017-08-01 09:48:59 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
FILE *const fil = Bfopen(temp, "wb");
|
2013-02-16 18:53:18 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(fil == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("couldn't open file \"%s\"\n", temp);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
switch (aGameArrays[arrayNum].flags & GAMEARRAY_SIZE_MASK)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
#ifdef BITNESS64
|
|
|
|
{
|
|
|
|
size_t const numElements = aGameArrays[arrayNum].size;
|
|
|
|
size_t const numDiskBytes = numElements * sizeof(int32_t);
|
|
|
|
int32_t *const pArray = (int32_t *)Xmalloc(numDiskBytes);
|
2018-01-29 11:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
for (unative_t k = 0; k < numElements; ++k)
|
|
|
|
pArray[k] = Gv_GetArrayValue(arrayNum, k);
|
2018-01-29 11:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Bfwrite(pArray, 1, numDiskBytes, fil);
|
|
|
|
Bfree(pArray);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
default: Bfwrite(aGameArrays[arrayNum].pValues, 1, Gv_GetArrayAllocSize(arrayNum), fil); break;
|
|
|
|
}
|
2018-01-29 11:14:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Bfclose(fil);
|
|
|
|
continue;
|
|
|
|
}
|
2015-01-17 00:28:49 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETARRAYSIZE:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_SetVarX(*insptr++, (aGameArrays[tw].flags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[tw].size) : aGameArrays[tw].size);
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_RESIZEARRAY:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = *insptr++;
|
2009-01-18 07:32:35 +00:00
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
auto &arr = aGameArrays[tw];
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int const newSize = Gv_GetVarX(*insptr++);
|
2018-11-18 18:10:51 +00:00
|
|
|
int const oldSize = arr.size;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2018-05-23 05:58:12 +00:00
|
|
|
if (newSize == oldSize || newSize < 0)
|
|
|
|
continue;
|
|
|
|
#if 0
|
|
|
|
OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n",
|
|
|
|
array.szLabel, array.size, newSize);
|
|
|
|
#endif
|
|
|
|
if (newSize == 0)
|
|
|
|
{
|
2018-11-18 18:10:51 +00:00
|
|
|
Baligned_free(arr.pValues);
|
|
|
|
arr.pValues = nullptr;
|
|
|
|
arr.size = 0;
|
2018-05-23 05:58:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-23 05:58:12 +00:00
|
|
|
size_t const oldBytes = Gv_GetArrayAllocSizeForCount(tw, oldSize);
|
|
|
|
size_t const newBytes = Gv_GetArrayAllocSizeForCount(tw, newSize);
|
2018-11-18 18:10:51 +00:00
|
|
|
|
|
|
|
auto const oldArray = arr.pValues;
|
|
|
|
auto const newArray = (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, newBytes);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-23 05:58:12 +00:00
|
|
|
if (oldSize != 0)
|
|
|
|
Bmemcpy(newArray, oldArray, min(oldBytes, newBytes));
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-23 05:58:12 +00:00
|
|
|
if (newSize > oldSize)
|
|
|
|
Bmemset((char *)newArray + oldBytes, 0, newBytes - oldBytes);
|
Adds the following keywords from M32script into CON: shiftvarvarl, shiftvarvarr, ifvarvarle, ifvarvarge, ifvarvarboth, whilevarl, and whilevarvarl.
This also adds the shorthand versions of some commands, like "set" for "setvarvar", "add" for "addvarvar", "ife" for "ifvarvare", etc. There are about 30 of these. Because some of these names may already be used in some projects as variable names, this revision also includes a somewhat large change in variable naming rules: gamevars may now have the same names as CON keywords, with the caveat that the masked keyword is no longer accessible. This results in a warning at compile time but should ensure nobody's project ever stops compiling due to the introduction of new keywords.
git-svn-id: https://svn.eduke32.com/eduke32@5499 1a8010ca-5511-0410-912e-c29ae57300e0
2016-01-02 01:56:20 +00:00
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
arr.pValues = newArray;
|
|
|
|
arr.size = newSize;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-23 05:58:12 +00:00
|
|
|
Baligned_free(oldArray);
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_COPY:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const srcArray = *insptr++;
|
|
|
|
int srcArrayIndex = Gv_GetVarX(*insptr++); //, vm.spriteNum, vm.playerNum);
|
|
|
|
int const destArray = *insptr++;
|
|
|
|
int destArrayIndex = Gv_GetVarX(*insptr++);
|
|
|
|
int numElements = Gv_GetVarX(*insptr++);
|
Adds the following keywords from M32script into CON: shiftvarvarl, shiftvarvarr, ifvarvarle, ifvarvarge, ifvarvarboth, whilevarl, and whilevarvarl.
This also adds the shorthand versions of some commands, like "set" for "setvarvar", "add" for "addvarvar", "ife" for "ifvarvare", etc. There are about 30 of these. Because some of these names may already be used in some projects as variable names, this revision also includes a somewhat large change in variable naming rules: gamevars may now have the same names as CON keywords, with the caveat that the masked keyword is no longer accessible. This results in a warning at compile time but should ensure nobody's project ever stops compiling due to the introduction of new keywords.
git-svn-id: https://svn.eduke32.com/eduke32@5499 1a8010ca-5511-0410-912e-c29ae57300e0
2016-01-02 01:56:20 +00:00
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
auto &src = aGameArrays[srcArray];
|
|
|
|
auto &dest = aGameArrays[destArray];
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
int const srcArraySize = (src.flags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(src.size) : src.size;
|
|
|
|
int const destArraySize = (dest.flags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(dest.size) : dest.size;
|
Adds the following keywords from M32script into CON: shiftvarvarl, shiftvarvarr, ifvarvarle, ifvarvarge, ifvarvarboth, whilevarl, and whilevarvarl.
This also adds the shorthand versions of some commands, like "set" for "setvarvar", "add" for "addvarvar", "ife" for "ifvarvare", etc. There are about 30 of these. Because some of these names may already be used in some projects as variable names, this revision also includes a somewhat large change in variable naming rules: gamevars may now have the same names as CON keywords, with the caveat that the masked keyword is no longer accessible. This results in a warning at compile time but should ensure nobody's project ever stops compiling due to the introduction of new keywords.
git-svn-id: https://svn.eduke32.com/eduke32@5499 1a8010ca-5511-0410-912e-c29ae57300e0
2016-01-02 01:56:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(srcArrayIndex > srcArraySize || destArrayIndex > destArraySize))
|
|
|
|
continue;
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((srcArrayIndex + numElements) > srcArraySize)
|
|
|
|
numElements = srcArraySize - srcArrayIndex;
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if ((destArrayIndex + numElements) > destArraySize)
|
|
|
|
numElements = destArraySize - destArrayIndex;
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
// Switch depending on the source array type.
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
int const srcInc = 1 << (int)!!(EDUKE32_PREDICT_FALSE(src.flags & GAMEARRAY_STRIDE2));
|
|
|
|
int const destInc = 1 << (int)!!(EDUKE32_PREDICT_FALSE(dest.flags & GAMEARRAY_STRIDE2));
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-23 05:58:09 +00:00
|
|
|
// matching array types, no BITMAPs, no STRIDE2 flag
|
2018-11-18 18:10:51 +00:00
|
|
|
if ((src.flags & GAMEARRAY_SIZE_MASK) == (dest.flags & GAMEARRAY_SIZE_MASK)
|
|
|
|
&& !((src.flags | dest.flags) & GAMEARRAY_BITMAP) && (srcInc & destInc) == 1)
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
2018-11-18 18:10:51 +00:00
|
|
|
Bmemcpy(dest.pValues + destArrayIndex, src.pValues + srcArrayIndex,
|
2018-05-22 19:03:44 +00:00
|
|
|
numElements * Gv_GetArrayElementSize(srcArray));
|
2018-11-18 18:10:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (dest.flags & GAMEARRAY_TYPE_MASK)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
for (; numElements > 0; --numElements)
|
|
|
|
{
|
|
|
|
dest.pValues[destArrayIndex] = Gv_GetArrayValue(srcArray, srcArrayIndex++);
|
|
|
|
destArrayIndex += destInc;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GAMEARRAY_INT16:
|
|
|
|
for (; numElements > 0; --numElements)
|
|
|
|
{
|
|
|
|
((int16_t *)dest.pValues)[destArrayIndex] = Gv_GetArrayValue(srcArray, srcArrayIndex++);
|
|
|
|
destArrayIndex += destInc;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GAMEARRAY_INT8:
|
|
|
|
for (; numElements > 0; --numElements)
|
|
|
|
{
|
|
|
|
((int8_t *)dest.pValues)[destArrayIndex] = Gv_GetArrayValue(srcArray, srcArrayIndex++);
|
|
|
|
destArrayIndex += destInc;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GAMEARRAY_UINT16:
|
|
|
|
for (; numElements > 0; --numElements)
|
|
|
|
{
|
|
|
|
((uint16_t *)dest.pValues)[destArrayIndex] = Gv_GetArrayValue(srcArray, srcArrayIndex++);
|
|
|
|
destArrayIndex += destInc;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GAMEARRAY_UINT8:
|
|
|
|
for (; numElements > 0; --numElements)
|
|
|
|
{
|
|
|
|
((uint8_t *)dest.pValues)[destArrayIndex] = Gv_GetArrayValue(srcArray, srcArrayIndex++);
|
|
|
|
destArrayIndex += destInc;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GAMEARRAY_BITMAP:
|
|
|
|
for (; numElements > 0; --numElements)
|
|
|
|
{
|
|
|
|
uint32_t const newValue = Gv_GetArrayValue(srcArray, srcArrayIndex++);
|
|
|
|
uint32_t const mask = 1 << (destArrayIndex & 7);
|
|
|
|
uint8_t & value = ((uint8_t *)dest.pValues)[destArrayIndex >> 3];
|
|
|
|
value = (value & ~mask) | (-!!newValue & mask);
|
|
|
|
destArrayIndex += destInc;
|
|
|
|
}
|
|
|
|
break;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
Adds the following keywords from M32script into CON: shiftvarvarl, shiftvarvarr, ifvarvarle, ifvarvarge, ifvarvarboth, whilevarl, and whilevarvarl.
This also adds the shorthand versions of some commands, like "set" for "setvarvar", "add" for "addvarvar", "ife" for "ifvarvare", etc. There are about 30 of these. Because some of these names may already be used in some projects as variable names, this revision also includes a somewhat large change in variable naming rules: gamevars may now have the same names as CON keywords, with the caveat that the masked keyword is no longer accessible. This results in a warning at compile time but should ensure nobody's project ever stops compiling due to the introduction of new keywords.
git-svn-id: https://svn.eduke32.com/eduke32@5499 1a8010ca-5511-0410-912e-c29ae57300e0
2016-01-02 01:56:20 +00:00
|
|
|
|
2018-05-23 05:58:21 +00:00
|
|
|
case CON_SWAPARRAYS:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-11-18 18:10:51 +00:00
|
|
|
auto &array1 = aGameArrays[*insptr++];
|
|
|
|
auto &array2 = aGameArrays[*insptr++];
|
2018-05-23 05:58:21 +00:00
|
|
|
|
2018-11-18 18:10:51 +00:00
|
|
|
swap(&array1.size, &array2.size);
|
|
|
|
swap(&array1.pValues, &array2.pValues);
|
2018-05-23 05:58:21 +00:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_RANDVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_SetVarX(*insptr, mulscale16(krand(), insptr[1] + 1));
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DISPLAYRANDVAR:
|
|
|
|
insptr++;
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_SetVarX(*insptr, mulscale15(system_15bit_rand(), insptr[1] + 1));
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
Adds the following keywords from M32script into CON: shiftvarvarl, shiftvarvarr, ifvarvarle, ifvarvarge, ifvarvarboth, whilevarl, and whilevarvarl.
This also adds the shorthand versions of some commands, like "set" for "setvarvar", "add" for "addvarvar", "ife" for "ifvarvare", etc. There are about 30 of these. Because some of these names may already be used in some projects as variable names, this revision also includes a somewhat large change in variable naming rules: gamevars may now have the same names as CON keywords, with the caveat that the masked keyword is no longer accessible. This results in a warning at compile time but should ensure nobody's project ever stops compiling due to the introduction of new keywords.
git-svn-id: https://svn.eduke32.com/eduke32@5499 1a8010ca-5511-0410-912e-c29ae57300e0
2016-01-02 01:56:20 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_CLAMP:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-11-18 18:10:45 +00:00
|
|
|
tw = *insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
int const min = Gv_GetVarX(*insptr++);
|
|
|
|
Gv_SetVarX(tw, clamp2(Gv_GetVarX(tw), min, Gv_GetVarX(*insptr++)));
|
|
|
|
}
|
|
|
|
continue;
|
2017-12-29 19:27:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETCLOSESTCOL:
|
|
|
|
insptr++;
|
|
|
|
{
|
2018-11-18 18:10:45 +00:00
|
|
|
tw = *insptr++;
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t const rgb = Gv_GetVarX(*insptr++);
|
|
|
|
Gv_SetVarX(tw, getclosestcol_lim(rgb & 0xFF, (rgb >> 8) & 0xFF, (rgb >> 16) & 0xFF, Gv_GetVarX(*insptr++)));
|
|
|
|
}
|
|
|
|
continue;
|
2016-02-02 00:21:24 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DRAWLINE256:
|
|
|
|
insptr++;
|
2016-02-02 00:21:24 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
struct
|
2018-01-31 04:13:31 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
vec2_t pos[2];
|
|
|
|
int32_t index;
|
|
|
|
} v;
|
2018-01-31 04:13:31 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
Gv_FillWithVars(v);
|
2016-02-02 00:21:24 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
renderDrawLine(v.pos[0].x, v.pos[0].y, v.pos[1].x, v.pos[1].y, v.index);
|
|
|
|
}
|
|
|
|
continue;
|
2016-02-02 00:21:24 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_DRAWLINERGB:
|
|
|
|
insptr++;
|
2016-02-02 00:21:24 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
struct
|
2016-02-02 00:21:24 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
vec2_t pos[2];
|
|
|
|
int32_t index, rgb;
|
|
|
|
} v;
|
|
|
|
|
|
|
|
Gv_FillWithVars(v);
|
|
|
|
|
|
|
|
palette_t const p
|
|
|
|
= { (uint8_t)(v.rgb & 0xFF), (uint8_t)((v.rgb >> 8) & 0xFF), (uint8_t)((v.rgb >> 16) & 0xFF), (uint8_t)v.index };
|
|
|
|
|
|
|
|
drawlinergb(v.pos[0].x, v.pos[0].y, v.pos[1].x, v.pos[1].y, p);
|
2016-02-02 00:21:24 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2016-02-02 00:21:24 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_INV:
|
2018-12-15 01:37:39 +00:00
|
|
|
if ((aGameVars[insptr[1]].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0)
|
|
|
|
aGameVars[insptr[1]].global = -aGameVars[insptr[1]].global;
|
2018-05-22 19:03:44 +00:00
|
|
|
else
|
2018-12-15 01:37:39 +00:00
|
|
|
Gv_SetVarX(insptr[1], -Gv_GetVarX(insptr[1]));
|
2018-05-22 19:03:44 +00:00
|
|
|
insptr += 2;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
case CON_RANDVARVAR:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_SetVarX(tw, mulscale16(krand(), Gv_GetVarX(*insptr++) + 1));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_DISPLAYRANDVARVAR:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_SetVarX(tw, mulscale15(system_15bit_rand(), Gv_GetVarX(*insptr++) + 1));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_GMAXAMMO:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAX_WEAPONS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid weapon %d\n", (int)tw);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Gv_SetVarX(*insptr++, pPlayer->max_ammo_amount[tw]);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_SMAXAMMO:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAX_WEAPONS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid weapon %d\n", (int)tw);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
pPlayer->max_ammo_amount[tw] = Gv_GetVarX(*insptr++);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
case CON_DIVR: // div round to nearest
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = *insptr++;
|
|
|
|
|
|
|
|
int const dividend = Gv_GetVarX(tw);
|
|
|
|
int const divisor = Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE(!divisor))
|
2016-02-02 00:21:24 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_CRITICALERRPRINTF("divide by zero!\n");
|
|
|
|
continue;
|
2016-02-02 00:21:24 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
2018-10-29 06:34:19 +00:00
|
|
|
Gv_SetVarX(tw, tabledivide32((dividend + ksgn(dividend) * klabs(divisor / 2)), divisor));
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case CON_DIVRU: // div round away from zero
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
tw = *insptr++;
|
|
|
|
|
|
|
|
int const dividend = Gv_GetVarX(tw);
|
|
|
|
int const divisor = Gv_GetVarX(*insptr++);
|
|
|
|
|
|
|
|
if (EDUKE32_PREDICT_FALSE(!divisor))
|
2016-02-02 00:21:24 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
CON_CRITICALERRPRINTF("divide by zero!\n");
|
|
|
|
continue;
|
2016-02-02 00:21:24 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
|
2018-10-29 06:34:19 +00:00
|
|
|
Gv_SetVarX(tw, tabledivide32((dividend + ksgn(dividend) * klabs(divisor) + 1), divisor));
|
2016-02-02 00:21:24 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SIN:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_SetVarX(tw, sintable[Gv_GetVarX(*insptr++) & 2047]);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_COS:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_SetVarX(tw, sintable[(Gv_GetVarX(*insptr++) + 512) & 2047]);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
case CON_SPGETLOTAG:
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_lotagVarID].global = vm.pSprite->lotag;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_SPGETHITAG:
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_hitagVarID].global = vm.pSprite->hitag;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_SECTGETLOTAG:
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_lotagVarID].global = sector[vm.pSprite->sectnum].lotag;
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SECTGETHITAG:
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_hitagVarID].global = sector[vm.pSprite->sectnum].hitag;
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETTEXTUREFLOOR:
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_textureVarID].global = sector[vm.pSprite->sectnum].floorpicnum;
|
|
|
|
continue;
|
2007-02-08 04:19:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STARTTRACK:
|
|
|
|
insptr++;
|
|
|
|
G_StartTrackSlotWrap(ud.volume_number, *(insptr++));
|
|
|
|
continue;
|
2008-07-16 09:27:08 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STARTTRACKVAR:
|
|
|
|
insptr++;
|
|
|
|
G_StartTrackSlotWrap(ud.volume_number, Gv_GetVarX(*(insptr++)));
|
|
|
|
continue;
|
2016-01-08 01:33:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_STARTTRACKSLOT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const volumeNum = Gv_GetVarX(*(insptr++));
|
|
|
|
int const levelNum = Gv_GetVarX(*(insptr++));
|
|
|
|
G_StartTrackSlotWrap(volumeNum == -1 ? MAXVOLUMES : volumeNum, levelNum);
|
|
|
|
}
|
|
|
|
continue;
|
2008-07-16 09:27:08 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SWAPTRACKSLOT:
|
|
|
|
insptr++;
|
|
|
|
{
|
|
|
|
int const volumeNum = Gv_GetVarX(*(insptr++));
|
|
|
|
int const levelNum = Gv_GetVarX(*(insptr++));
|
2016-01-08 01:33:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (volumeNum == ud.music_episode && levelNum == ud.music_level)
|
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
// This is the best ASS can do right now. Better implementation pending.
|
|
|
|
int32_t position = S_GetMusicPosition();
|
|
|
|
if (!G_StartTrackSlotWrap(volumeNum == -1 ? MAXVOLUMES : volumeNum, levelNum))
|
|
|
|
S_SetMusicPosition(position);
|
|
|
|
}
|
|
|
|
continue;
|
2016-01-08 01:33:39 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_PRELOADTRACKSLOTFORSWAP:
|
|
|
|
// ASS can't even handle this command right now.
|
|
|
|
insptr++;
|
|
|
|
Gv_GetVarX(*(insptr++));
|
|
|
|
Gv_GetVarX(*(insptr++));
|
|
|
|
continue;
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETMUSICPOSITION:
|
|
|
|
insptr++;
|
|
|
|
Gv_GetVarX(*(insptr++));
|
|
|
|
continue;
|
|
|
|
case CON_GETMUSICPOSITION: insptr += 2; continue;
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ACTIVATECHEAT:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*(insptr++));
|
|
|
|
if (EDUKE32_PREDICT_FALSE(numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME)))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("not in a single-player game.\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
osdcmd_cheatsinfo_stat.cheatnum = tw;
|
|
|
|
continue;
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SETGAMEPALETTE:
|
|
|
|
insptr++;
|
|
|
|
P_SetGamePalette(pPlayer, Gv_GetVarX(*(insptr++)), 2 + 16);
|
|
|
|
continue;
|
2018-01-31 05:23:48 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETTEXTURECEILING:
|
|
|
|
insptr++;
|
|
|
|
aGameVars[g_textureVarID].global = sector[vm.pSprite->sectnum].ceilingpicnum;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFPHEALTHL:
|
|
|
|
insptr++;
|
|
|
|
VM_CONDITIONAL(sprite[pPlayer->i].extra < *insptr);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_IFPINVENTORY:
|
|
|
|
insptr++;
|
2012-08-10 19:11:53 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
switch (*insptr++)
|
|
|
|
{
|
|
|
|
case GET_STEROIDS:
|
|
|
|
case GET_SHIELD:
|
|
|
|
case GET_SCUBA:
|
|
|
|
case GET_HOLODUKE:
|
|
|
|
case GET_HEATS:
|
|
|
|
case GET_FIRSTAID:
|
|
|
|
case GET_BOOTS:
|
2018-12-15 01:37:39 +00:00
|
|
|
case GET_JETPACK: tw = (pPlayer->inv_amount[insptr[-1]] != *insptr); break;
|
2018-05-22 19:03:44 +00:00
|
|
|
|
|
|
|
case GET_ACCESS:
|
|
|
|
switch (vm.pSprite->pal)
|
|
|
|
{
|
|
|
|
case 0: tw = (pPlayer->got_access & 1); break;
|
|
|
|
case 21: tw = (pPlayer->got_access & 2); break;
|
|
|
|
case 23: tw = (pPlayer->got_access & 4); break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default: tw = 0; CON_ERRPRINTF("invalid inventory item %d\n", (int32_t) * (insptr - 1));
|
2018-11-18 18:10:45 +00:00
|
|
|
continue;
|
2018-05-22 19:03:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VM_CONDITIONAL(tw);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case CON_PSTOMP:
|
|
|
|
insptr++;
|
|
|
|
if (pPlayer->knee_incs == 0 && sprite[pPlayer->i].xrepeat >= 40)
|
|
|
|
if (cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - ZOFFSET6, vm.pSprite->sectnum, pPlayer->pos.x, pPlayer->pos.y,
|
|
|
|
pPlayer->pos.z + ZOFFSET2, sprite[pPlayer->i].sectnum))
|
2015-01-11 04:56:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
int numPlayers = g_mostConcurrentPlayers - 1;
|
|
|
|
|
|
|
|
for (; numPlayers >= 0; --numPlayers)
|
|
|
|
{
|
|
|
|
if (g_player[numPlayers].ps->actorsqu == vm.spriteNum)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (numPlayers == -1)
|
|
|
|
{
|
|
|
|
if (pPlayer->weapon_pos == 0)
|
|
|
|
pPlayer->weapon_pos = -1;
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
pPlayer->actorsqu = vm.spriteNum;
|
|
|
|
pPlayer->knee_incs = 1;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2006-04-18 03:11:38 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFAWAYFROMWALL:
|
|
|
|
{
|
|
|
|
int16_t otherSectnum = vm.pSprite->sectnum;
|
|
|
|
tw = 0;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2015-02-11 05:22:11 +00:00
|
|
|
#define IFAWAYDIST 108
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
updatesector(vm.pSprite->x + IFAWAYDIST, vm.pSprite->y + IFAWAYDIST, &otherSectnum);
|
2016-08-27 01:40:35 +00:00
|
|
|
if (otherSectnum == vm.pSprite->sectnum)
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
updatesector(vm.pSprite->x - IFAWAYDIST, vm.pSprite->y - IFAWAYDIST, &otherSectnum);
|
2016-08-27 01:40:35 +00:00
|
|
|
if (otherSectnum == vm.pSprite->sectnum)
|
2009-06-19 01:10:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
updatesector(vm.pSprite->x + IFAWAYDIST, vm.pSprite->y - IFAWAYDIST, &otherSectnum);
|
2016-08-27 01:40:35 +00:00
|
|
|
if (otherSectnum == vm.pSprite->sectnum)
|
2018-05-22 19:03:44 +00:00
|
|
|
{
|
|
|
|
updatesector(vm.pSprite->x - IFAWAYDIST, vm.pSprite->y + IFAWAYDIST, &otherSectnum);
|
|
|
|
if (otherSectnum == vm.pSprite->sectnum)
|
|
|
|
tw = 1;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-07 02:37:50 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_CONDITIONAL(tw);
|
2016-02-07 02:37:50 +00:00
|
|
|
|
|
|
|
#undef IFAWAYDIST
|
2012-02-24 19:51:54 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
continue;
|
2012-02-24 19:51:54 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_QUOTE:
|
2009-06-19 01:10:10 +00:00
|
|
|
insptr++;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)(*insptr) >= MAXQUOTES) || apStrings[*insptr] == NULL)
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", (int32_t)(*insptr));
|
|
|
|
continue;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= MAXPLAYERS))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid player %d\n", vm.playerNum);
|
|
|
|
continue;
|
|
|
|
}
|
2012-02-24 19:51:54 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
P_DoQuote(*(insptr++) | MAXQUOTES, pPlayer);
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_USERQUOTE:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXQUOTES || apStrings[tw] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", (int)tw);
|
|
|
|
continue;
|
|
|
|
}
|
2012-03-05 07:24:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
G_AddUserQuote(apStrings[tw]);
|
2015-02-11 05:22:11 +00:00
|
|
|
continue;
|
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_ECHO:
|
|
|
|
insptr++;
|
|
|
|
tw = Gv_GetVarX(*insptr++);
|
2012-03-05 07:24:04 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXQUOTES || apStrings[tw] == NULL))
|
|
|
|
{
|
|
|
|
CON_ERRPRINTF("invalid quote %d\n", (int)tw);
|
|
|
|
continue;
|
|
|
|
}
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
OSD_Printf("%s\n", apStrings[tw]);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_RESPAWNHITAG:
|
|
|
|
insptr++;
|
|
|
|
switch (DYNAMICTILEMAP(vm.pSprite->picnum))
|
|
|
|
{
|
2018-11-18 18:13:55 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-05-22 19:03:44 +00:00
|
|
|
case FEM1__STATIC:
|
|
|
|
case FEM2__STATIC:
|
|
|
|
case FEM3__STATIC:
|
|
|
|
case FEM4__STATIC:
|
|
|
|
case FEM5__STATIC:
|
|
|
|
case FEM6__STATIC:
|
|
|
|
case FEM7__STATIC:
|
|
|
|
case FEM8__STATIC:
|
|
|
|
case FEM9__STATIC:
|
|
|
|
case FEM10__STATIC:
|
|
|
|
case PODFEM1__STATIC:
|
|
|
|
case NAKED1__STATIC:
|
|
|
|
case STATUE__STATIC:
|
|
|
|
if (vm.pSprite->yvel)
|
|
|
|
G_OperateRespawns(vm.pSprite->yvel);
|
|
|
|
break;
|
2018-11-18 18:13:55 +00:00
|
|
|
#endif
|
2018-05-22 19:03:44 +00:00
|
|
|
default:
|
|
|
|
if (vm.pSprite->hitag >= 0)
|
|
|
|
G_OperateRespawns(vm.pSprite->hitag);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
2006-08-28 19:18:05 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFSPRITEPAL:
|
|
|
|
insptr++;
|
|
|
|
VM_CONDITIONAL(vm.pSprite->pal == *insptr);
|
|
|
|
continue;
|
2006-08-28 19:18:05 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFANGDIFFL:
|
|
|
|
insptr++;
|
|
|
|
tw = klabs(G_GetAngleDelta(fix16_to_int(pPlayer->q16ang), vm.pSprite->ang));
|
|
|
|
VM_CONDITIONAL(tw <= *insptr);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_IFNOSOUNDS: VM_CONDITIONAL(!A_CheckAnySoundPlaying(vm.spriteNum)); continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_SPRITEFLAGS:
|
|
|
|
insptr++;
|
|
|
|
vm.pActor->flags = Gv_GetVarX(*insptr++);
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETTICKS:
|
|
|
|
insptr++;
|
|
|
|
Gv_SetVarX(*insptr++, timerGetTicks());
|
|
|
|
continue;
|
2009-06-19 01:10:10 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
case CON_GETCURRADDRESS:
|
|
|
|
insptr++;
|
|
|
|
tw = *insptr++;
|
|
|
|
Gv_SetVarX(tw, (intptr_t)(insptr - apScript));
|
|
|
|
continue;
|
|
|
|
|
|
|
|
default: // you aren't supposed to be here!
|
2018-10-25 23:29:44 +00:00
|
|
|
debug_break();
|
2018-05-22 19:03:44 +00:00
|
|
|
VM_ScriptInfo(insptr, 64);
|
|
|
|
G_GameExit("An error has occurred in the " APPNAME " virtual machine.\n\n"
|
|
|
|
"If you are an end user, please e-mail the file " APPBASENAME ".log\n"
|
|
|
|
"along with links to any mods you're using to development@voidpoint.com.\n\n"
|
|
|
|
"If you are a developer, please attach all of your script files\n"
|
|
|
|
"along with instructions on how to reproduce this error.\n\n"
|
|
|
|
"Thank you!");
|
|
|
|
break;
|
2009-01-18 07:32:35 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-11 17:38:27 +00:00
|
|
|
// NORECURSE
|
2016-08-27 01:40:35 +00:00
|
|
|
void A_LoadActor(int32_t spriteNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2017-06-27 02:24:02 +00:00
|
|
|
vm.spriteNum = spriteNum; // Sprite ID
|
|
|
|
vm.pSprite = &sprite[spriteNum]; // Pointer to sprite structure
|
|
|
|
vm.pActor = &actor[spriteNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (g_tile[vm.pSprite->picnum].loadPtr == NULL)
|
2012-06-10 18:56:24 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-27 02:24:02 +00:00
|
|
|
vm.pData = &actor[spriteNum].t_data[0]; // Sprite's 'extra' data
|
|
|
|
vm.playerNum = -1; // Player ID
|
|
|
|
vm.playerDist = -1; // Distance
|
|
|
|
vm.pPlayer = g_player[0].ps;
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2018-11-18 18:10:45 +00:00
|
|
|
vm.flags &= ~(VM_RETURN|VM_KILL|VM_NOEXECUTE);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((unsigned)vm.pSprite->sectnum >= MAXSECTORS)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_DeleteSprite(vm.spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
}
|
2007-02-08 04:19:39 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
insptr = g_tile[vm.pSprite->picnum].loadPtr;
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
VM_Execute(1);
|
2012-03-11 17:38:27 +00:00
|
|
|
insptr = NULL;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.flags & VM_KILL)
|
|
|
|
A_DeleteSprite(vm.spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2013-02-21 18:54:07 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:50 +00:00
|
|
|
void VM_UpdateAnim(int spriteNum, int32_t *pData)
|
|
|
|
{
|
|
|
|
#if !defined LUNATIC
|
2016-09-06 02:15:23 +00:00
|
|
|
size_t const actionofs = AC_ACTION_ID(pData);
|
2018-12-15 01:37:39 +00:00
|
|
|
auto const actionptr = (actionofs != 0 && actionofs + (ACTION_PARAM_COUNT-1) < (unsigned) g_scriptSize) ? &apScript[actionofs] : NULL;
|
2016-08-27 01:41:50 +00:00
|
|
|
|
|
|
|
if (actionptr != NULL)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
#if !defined LUNATIC
|
2016-09-06 02:15:23 +00:00
|
|
|
int const action_frames = actionptr[ACTION_NUMFRAMES];
|
|
|
|
int const action_incval = actionptr[ACTION_INCVAL];
|
|
|
|
int const action_delay = actionptr[ACTION_DELAY];
|
2016-08-27 01:41:50 +00:00
|
|
|
#else
|
|
|
|
int const action_frames = actor[spriteNum].ac.numframes;
|
|
|
|
int const action_incval = actor[spriteNum].ac.incval;
|
|
|
|
int const action_delay = actor[spriteNum].ac.delay;
|
|
|
|
#endif
|
2018-01-15 23:13:50 +00:00
|
|
|
auto actionticsptr = &AC_ACTIONTICS(&sprite[spriteNum], &actor[spriteNum]);
|
2016-08-27 01:41:50 +00:00
|
|
|
*actionticsptr += TICSPERFRAME;
|
|
|
|
|
|
|
|
if (*actionticsptr > action_delay)
|
|
|
|
{
|
|
|
|
*actionticsptr = 0;
|
|
|
|
AC_ACTION_COUNT(pData)++;
|
|
|
|
AC_CURFRAME(pData) += action_incval;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (klabs(AC_CURFRAME(pData)) >= klabs(action_frames * action_incval))
|
|
|
|
AC_CURFRAME(pData) = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-11 17:38:27 +00:00
|
|
|
// NORECURSE
|
2016-09-06 04:25:32 +00:00
|
|
|
void A_Execute(int spriteNum, int playerNum, int playerDist)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
vmstate_t tempvm
|
|
|
|
= { spriteNum, playerNum, playerDist, 0, &sprite[spriteNum], &actor[spriteNum].t_data[0], g_player[playerNum].ps, &actor[spriteNum] };
|
2014-11-22 12:29:25 +00:00
|
|
|
vm = tempvm;
|
|
|
|
|
2012-07-20 21:57:44 +00:00
|
|
|
#ifdef LUNATIC
|
2012-11-30 18:57:59 +00:00
|
|
|
int32_t killit=0;
|
2012-07-20 21:57:44 +00:00
|
|
|
#endif
|
2010-05-02 23:27:30 +00:00
|
|
|
|
2012-10-14 22:16:07 +00:00
|
|
|
/*
|
2016-08-27 01:40:35 +00:00
|
|
|
if (g_netClient && A_CheckSpriteFlags(spriteNum, SFLAG_NULL))
|
2009-12-14 20:14:12 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_DeleteSprite(spriteNum);
|
2009-12-14 20:14:12 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-10-14 22:16:07 +00:00
|
|
|
*/
|
2007-03-22 18:28:41 +00:00
|
|
|
|
2017-09-27 02:30:28 +00:00
|
|
|
if (g_netClient) // [75] The server should not overwrite its own randomseed
|
2009-12-05 09:22:43 +00:00
|
|
|
randomseed = ticrandomseed;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= MAXSECTORS))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckEnemySprite(vm.pSprite))
|
2017-07-05 05:37:58 +00:00
|
|
|
P_AddKills(vm.pPlayer, 1);
|
2014-11-22 12:29:25 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_DeleteSprite(vm.spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:50 +00:00
|
|
|
VM_UpdateAnim(vm.spriteNum, vm.pData);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-06-10 18:56:15 +00:00
|
|
|
#ifdef LUNATIC
|
2016-08-27 01:40:35 +00:00
|
|
|
int const picnum = vm.pSprite->picnum;
|
2012-07-20 21:57:44 +00:00
|
|
|
|
2015-01-11 04:56:10 +00:00
|
|
|
if (L_IsInitialized(&g_ElState) && El_HaveActor(picnum))
|
|
|
|
{
|
2018-04-12 21:02:51 +00:00
|
|
|
double t = timerGetHiTicks();
|
2013-07-13 21:04:45 +00:00
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
killit = (El_CallActor(&g_ElState, picnum, spriteNum, playerNum, playerDist)==1);
|
2012-12-29 15:21:32 +00:00
|
|
|
|
2018-04-12 21:02:51 +00:00
|
|
|
t = timerGetHiTicks()-t;
|
2015-01-11 04:56:10 +00:00
|
|
|
g_actorTotalMs[picnum] += t;
|
|
|
|
g_actorMinMs[picnum] = min(g_actorMinMs[picnum], t);
|
|
|
|
g_actorMaxMs[picnum] = max(g_actorMaxMs[picnum], t);
|
|
|
|
g_actorCalls[picnum]++;
|
2013-03-13 10:48:19 +00:00
|
|
|
}
|
2013-02-03 12:48:17 +00:00
|
|
|
#else
|
2018-04-12 21:02:51 +00:00
|
|
|
double t = timerGetHiTicks();
|
2018-03-08 00:29:41 +00:00
|
|
|
int const picnum = vm.pSprite->picnum;
|
2016-08-27 01:40:35 +00:00
|
|
|
insptr = 4 + (g_tile[vm.pSprite->picnum].execPtr);
|
2013-02-03 12:48:17 +00:00
|
|
|
VM_Execute(1);
|
|
|
|
insptr = NULL;
|
2018-03-08 00:29:41 +00:00
|
|
|
|
2018-04-12 21:02:51 +00:00
|
|
|
t = timerGetHiTicks()-t;
|
2018-03-08 00:29:41 +00:00
|
|
|
g_actorTotalMs[picnum] += t;
|
|
|
|
g_actorMinMs[picnum] = min(g_actorMinMs[picnum], t);
|
|
|
|
g_actorMaxMs[picnum] = max(g_actorMaxMs[picnum], t);
|
|
|
|
g_actorCalls[picnum]++;
|
2012-07-20 21:57:44 +00:00
|
|
|
#endif
|
|
|
|
|
2012-11-30 18:57:59 +00:00
|
|
|
#ifdef LUNATIC
|
2013-07-13 21:04:45 +00:00
|
|
|
if (killit)
|
|
|
|
#else
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.flags & VM_KILL)
|
2012-11-30 18:57:59 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_DeleteSprite(spriteNum, playerNum);
|
2008-08-24 19:09:17 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2010-05-02 23:27:30 +00:00
|
|
|
VM_Move();
|
2008-12-17 01:59:36 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->statnum != STAT_ACTOR)
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
2018-04-04 20:47:48 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->statnum == STAT_STANDABLE)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
switch (DYNAMICTILEMAP(vm.pSprite->picnum))
|
2014-11-22 12:29:25 +00:00
|
|
|
{
|
|
|
|
case RUBBERCAN__STATIC:
|
|
|
|
case EXPLODINGBARREL__STATIC:
|
|
|
|
case WOODENHORSE__STATIC:
|
|
|
|
case HORSEONSIDE__STATIC:
|
|
|
|
case CANWITHSOMETHING__STATIC:
|
|
|
|
case FIREBARREL__STATIC:
|
|
|
|
case NUKEBARREL__STATIC:
|
|
|
|
case NUKEBARRELDENTED__STATIC:
|
|
|
|
case NUKEBARRELLEAKED__STATIC:
|
|
|
|
case TRIPBOMB__STATIC:
|
|
|
|
case EGG__STATIC:
|
2017-06-23 03:59:19 +00:00
|
|
|
if (vm.pActor->timetosleep > 1)
|
|
|
|
vm.pActor->timetosleep--;
|
|
|
|
else if (vm.pActor->timetosleep == 1)
|
2016-08-27 01:40:35 +00:00
|
|
|
changespritestat(vm.spriteNum, STAT_ZOMBIEACTOR);
|
2015-01-11 04:56:10 +00:00
|
|
|
default: break;
|
2014-11-22 12:29:25 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2008-08-24 19:09:17 +00:00
|
|
|
return;
|
2014-11-22 12:29:25 +00:00
|
|
|
}
|
2008-08-24 19:09:17 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckEnemySprite(vm.pSprite))
|
2008-08-24 19:09:17 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (vm.pSprite->xrepeat > 60 || (ud.respawn_monsters == 1 && vm.pSprite->extra <= 0))
|
2014-11-22 12:29:25 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (EDUKE32_PREDICT_FALSE(ud.respawn_items == 1 && (vm.pSprite->cstat & 32768)))
|
2014-11-22 12:29:25 +00:00
|
|
|
return;
|
2008-08-24 19:09:17 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckSpriteFlags(vm.spriteNum, SFLAG_USEACTIVATOR) && sector[vm.pSprite->sectnum].lotag & 16384)
|
|
|
|
changespritestat(vm.spriteNum, STAT_ZOMBIEACTOR);
|
2017-06-23 03:59:19 +00:00
|
|
|
else if (vm.pActor->timetosleep > 1)
|
|
|
|
vm.pActor->timetosleep--;
|
|
|
|
else if (vm.pActor->timetosleep == 1)
|
2014-10-25 03:29:21 +00:00
|
|
|
{
|
2014-10-25 03:36:34 +00:00
|
|
|
// hack for 1.3D fire sprites
|
2018-04-04 20:47:48 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:35 +00:00
|
|
|
if (EDUKE32_PREDICT_FALSE(g_scriptVersion == 13 && (vm.pSprite->picnum == FIRE || vm.pSprite->picnum == FIRE2)))
|
2014-10-25 03:29:21 +00:00
|
|
|
return;
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2016-08-27 01:40:35 +00:00
|
|
|
changespritestat(vm.spriteNum, STAT_ZOMBIEACTOR);
|
2014-10-25 03:29:21 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2008-07-16 09:27:08 +00:00
|
|
|
|
2013-05-19 19:29:26 +00:00
|
|
|
void G_SaveMapState(void)
|
2008-07-16 09:27:08 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const levelNum = ud.volume_number * MAXLEVELS + ud.level_number;
|
|
|
|
map_t *const pMapInfo = &g_mapInfo[levelNum];
|
2013-05-19 19:29:26 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pMapInfo->savedstate == NULL)
|
2015-01-16 06:30:42 +00:00
|
|
|
{
|
2017-10-31 02:09:25 +00:00
|
|
|
pMapInfo->savedstate = (mapstate_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, sizeof(mapstate_t));
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemset(pMapInfo->savedstate, 0, sizeof(mapstate_t));
|
2015-01-16 06:30:42 +00:00
|
|
|
}
|
2016-06-05 04:46:28 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
mapstate_t *save = pMapInfo->savedstate;
|
2013-05-19 19:29:26 +00:00
|
|
|
|
2015-01-11 04:56:10 +00:00
|
|
|
if (save == NULL)
|
|
|
|
return;
|
2011-08-03 17:22:46 +00:00
|
|
|
|
2016-11-09 22:51:42 +00:00
|
|
|
save->numwalls = numwalls;
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->wall[0],&wall[0],sizeof(walltype)*MAXWALLS);
|
2016-11-09 22:51:42 +00:00
|
|
|
save->numsectors = numsectors;
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->sector[0],§or[0],sizeof(sectortype)*MAXSECTORS);
|
|
|
|
Bmemcpy(&save->sprite[0],&sprite[0],sizeof(spritetype)*MAXSPRITES);
|
|
|
|
|
|
|
|
// If we're in EVENT_ANIMATESPRITES, we'll be saving pointer values to disk :-/
|
2013-02-07 21:00:52 +00:00
|
|
|
#if !defined LUNATIC
|
2018-11-18 18:11:44 +00:00
|
|
|
if (g_currentEvent == EVENT_ANIMATESPRITES)
|
2015-01-11 04:56:10 +00:00
|
|
|
initprintf("Line %d: savemapstate called from EVENT_ANIMATESPRITES. WHY?\n", g_errorLineNum);
|
2013-02-07 21:00:52 +00:00
|
|
|
#endif
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->spriteext[0],&spriteext[0],sizeof(spriteext_t)*MAXSPRITES);
|
2017-06-25 11:23:53 +00:00
|
|
|
#ifndef NEW_MAP_FORMAT
|
|
|
|
Bmemcpy(&save->wallext[0],&wallext[0],sizeof(wallext_t)*MAXWALLS);
|
|
|
|
#endif
|
2015-01-11 04:56:10 +00:00
|
|
|
|
|
|
|
save->numsprites = Numsprites;
|
|
|
|
save->tailspritefree = tailspritefree;
|
|
|
|
Bmemcpy(&save->headspritesect[0],&headspritesect[0],sizeof(headspritesect));
|
|
|
|
Bmemcpy(&save->prevspritesect[0],&prevspritesect[0],sizeof(prevspritesect));
|
|
|
|
Bmemcpy(&save->nextspritesect[0],&nextspritesect[0],sizeof(nextspritesect));
|
|
|
|
Bmemcpy(&save->headspritestat[0],&headspritestat[0],sizeof(headspritestat));
|
|
|
|
Bmemcpy(&save->prevspritestat[0],&prevspritestat[0],sizeof(prevspritestat));
|
|
|
|
Bmemcpy(&save->nextspritestat[0],&nextspritestat[0],sizeof(nextspritestat));
|
2012-03-11 17:37:08 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2016-11-09 22:51:42 +00:00
|
|
|
save->numyaxbunches = numyaxbunches;
|
2013-04-09 17:35:11 +00:00
|
|
|
# if !defined NEW_MAP_FORMAT
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(save->yax_bunchnum, yax_bunchnum, sizeof(yax_bunchnum));
|
|
|
|
Bmemcpy(save->yax_nextwall, yax_nextwall, sizeof(yax_nextwall));
|
2013-04-09 17:35:11 +00:00
|
|
|
# endif
|
2012-03-11 17:37:08 +00:00
|
|
|
#endif
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->actor[0],&actor[0],sizeof(actor_t)*MAXSPRITES);
|
|
|
|
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_cyclerCnt = g_cyclerCnt;
|
2018-10-07 05:21:15 +00:00
|
|
|
Bmemcpy(save->g_cyclers, g_cyclers, sizeof(g_cyclers));
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->g_playerSpawnPoints[0],&g_playerSpawnPoints[0],sizeof(g_playerSpawnPoints));
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_animWallCnt = g_animWallCnt;
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->SpriteDeletionQueue[0],&SpriteDeletionQueue[0],sizeof(SpriteDeletionQueue));
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_spriteDeleteQueuePos = g_spriteDeleteQueuePos;
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->animwall[0],&animwall[0],sizeof(animwall));
|
2016-01-21 19:35:30 +00:00
|
|
|
Bmemcpy(&save->origins[0],&g_origins[0],sizeof(g_origins));
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->g_mirrorWall[0],&g_mirrorWall[0],sizeof(g_mirrorWall));
|
|
|
|
Bmemcpy(&save->g_mirrorSector[0],&g_mirrorSector[0],sizeof(g_mirrorSector));
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_mirrorCount = g_mirrorCount;
|
2015-01-11 04:56:10 +00:00
|
|
|
Bmemcpy(&save->show2dsector[0],&show2dsector[0],sizeof(show2dsector));
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_cloudCnt = g_cloudCnt;
|
2016-08-27 01:42:01 +00:00
|
|
|
Bmemcpy(&save->g_cloudSect[0],&g_cloudSect[0],sizeof(g_cloudSect));
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_cloudX = g_cloudX;
|
|
|
|
save->g_cloudY = g_cloudY;
|
|
|
|
save->pskyidx = g_pskyidx;
|
2016-08-27 01:42:01 +00:00
|
|
|
Bmemcpy(&save->g_animateGoal[0],&g_animateGoal[0],sizeof(g_animateGoal));
|
|
|
|
Bmemcpy(&save->g_animateVel[0],&g_animateVel[0],sizeof(g_animateVel));
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_animateCnt = g_animateCnt;
|
2016-08-27 01:42:01 +00:00
|
|
|
Bmemcpy(&save->g_animateSect[0],&g_animateSect[0],sizeof(g_animateSect));
|
2015-01-11 04:56:10 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
G_Util_PtrToIdx(g_animatePtr, g_animateCnt, sector, P2I_FWD);
|
|
|
|
Bmemcpy(&save->g_animatePtr[0],&g_animatePtr[0],sizeof(g_animatePtr));
|
|
|
|
G_Util_PtrToIdx(g_animatePtr, g_animateCnt, sector, P2I_BACK);
|
2011-07-29 22:07:49 +00:00
|
|
|
|
2015-01-11 04:56:10 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
EDUKE32_STATIC_ASSERT(sizeof(save->g_animatePtr) == sizeof(g_animatePtr));
|
2015-01-11 04:56:10 +00:00
|
|
|
}
|
|
|
|
|
2016-11-09 22:51:42 +00:00
|
|
|
save->g_playerSpawnCnt = g_playerSpawnCnt;
|
|
|
|
save->g_earthquakeTime = g_earthquakeTime;
|
|
|
|
save->lockclock = lockclock;
|
|
|
|
save->randomseed = randomseed;
|
|
|
|
save->g_globalRandom = g_globalRandom;
|
2013-10-28 21:26:32 +00:00
|
|
|
|
2013-01-20 21:17:06 +00:00
|
|
|
#if !defined LUNATIC
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=g_gameVarCount-1; i>=0; i--)
|
2015-01-11 04:56:10 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (aGameVars[i].flags & GAMEVAR_NORESET)
|
|
|
|
continue;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (aGameVars[i].flags & GAMEVAR_PERPLAYER)
|
2008-07-18 02:46:24 +00:00
|
|
|
{
|
2015-01-11 04:56:10 +00:00
|
|
|
if (!save->vars[i])
|
2017-10-31 02:09:25 +00:00
|
|
|
save->vars[i] = (intptr_t *)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
|
|
|
|
Bmemcpy(&save->vars[i][0], aGameVars[i].pValues, sizeof(intptr_t) * MAXPLAYERS);
|
2008-07-18 02:46:24 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (aGameVars[i].flags & GAMEVAR_PERACTOR)
|
2013-10-27 21:12:22 +00:00
|
|
|
{
|
2015-01-11 04:56:10 +00:00
|
|
|
if (!save->vars[i])
|
2017-10-31 02:09:25 +00:00
|
|
|
save->vars[i] = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
|
|
|
|
Bmemcpy(&save->vars[i][0], aGameVars[i].pValues, sizeof(intptr_t) * MAXSPRITES);
|
2013-10-27 21:12:22 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
else
|
|
|
|
save->vars[i] = (intptr_t *)aGameVars[i].global;
|
2015-01-11 04:56:10 +00:00
|
|
|
}
|
2016-08-27 01:41:50 +00:00
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=g_gameArrayCount-1; i>=0; i--)
|
2016-08-27 01:41:50 +00:00
|
|
|
{
|
|
|
|
if ((aGameArrays[i].flags & GAMEARRAY_RESTORE) == 0)
|
|
|
|
continue;
|
|
|
|
|
2017-10-31 02:09:25 +00:00
|
|
|
save->arraysiz[i] = aGameArrays[i].size;
|
|
|
|
Baligned_free(save->arrays[i]);
|
|
|
|
save->arrays[i] = (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, Gv_GetArrayAllocSize(i));
|
|
|
|
Bmemcpy(&save->arrays[i][0], aGameArrays[i].pValues, Gv_GetArrayAllocSize(i));
|
2016-08-27 01:41:50 +00:00
|
|
|
}
|
2015-01-11 04:56:10 +00:00
|
|
|
#else
|
|
|
|
int32_t slen;
|
2016-08-27 01:40:35 +00:00
|
|
|
const char *svcode = El_SerializeGamevars(&slen, levelNum);
|
2015-01-11 04:56:10 +00:00
|
|
|
|
|
|
|
if (slen < 0)
|
|
|
|
{
|
|
|
|
El_OnError("ERROR: savemapstate: serialization failed!");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *savecode = Xstrdup(svcode);
|
|
|
|
Bfree(save->savecode);
|
|
|
|
save->savecode = savecode;
|
2008-07-16 09:27:08 +00:00
|
|
|
}
|
2015-01-11 04:56:10 +00:00
|
|
|
#endif
|
|
|
|
ototalclock = totalclock;
|
2008-07-16 09:27:08 +00:00
|
|
|
}
|
|
|
|
|
2013-05-19 19:29:26 +00:00
|
|
|
void G_RestoreMapState(void)
|
2008-07-16 09:27:08 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const levelNum = ud.volume_number * MAXLEVELS + ud.level_number;
|
|
|
|
mapstate_t *pSavedState = g_mapInfo[levelNum].savedstate;
|
2013-05-19 19:29:26 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pSavedState != NULL)
|
2008-07-16 09:27:08 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int playerHealth[MAXPLAYERS];
|
2008-07-16 09:27:08 +00:00
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=0; i<g_mostConcurrentPlayers; i++)
|
2016-08-27 01:40:35 +00:00
|
|
|
playerHealth[i] = sprite[g_player[i].ps->i].extra;
|
2008-07-18 03:22:20 +00:00
|
|
|
|
2008-07-16 09:27:08 +00:00
|
|
|
pub = NUMPAGES;
|
|
|
|
pus = NUMPAGES;
|
2008-11-20 14:06:36 +00:00
|
|
|
G_UpdateScreenArea();
|
2008-07-16 09:27:08 +00:00
|
|
|
|
2016-11-09 22:51:42 +00:00
|
|
|
numwalls = pSavedState->numwalls;
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(&wall[0],&pSavedState->wall[0],sizeof(walltype)*MAXWALLS);
|
2017-06-25 11:23:53 +00:00
|
|
|
#ifndef NEW_MAP_FORMAT
|
|
|
|
Bmemcpy(&wallext[0],&pSavedState->wallext[0],sizeof(wallext_t)*MAXWALLS);
|
|
|
|
#endif
|
2016-11-09 22:51:42 +00:00
|
|
|
numsectors = pSavedState->numsectors;
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(§or[0],&pSavedState->sector[0],sizeof(sectortype)*MAXSECTORS);
|
|
|
|
Bmemcpy(&sprite[0],&pSavedState->sprite[0],sizeof(spritetype)*MAXSPRITES);
|
|
|
|
Bmemcpy(&spriteext[0],&pSavedState->spriteext[0],sizeof(spriteext_t)*MAXSPRITES);
|
2013-02-01 13:05:13 +00:00
|
|
|
|
|
|
|
// If we're restoring from EVENT_ANIMATESPRITES, all spriteext[].tspr
|
|
|
|
// will be overwritten, so NULL them.
|
2013-02-07 21:00:52 +00:00
|
|
|
#if !defined LUNATIC
|
2018-11-18 18:11:44 +00:00
|
|
|
if (g_currentEvent == EVENT_ANIMATESPRITES)
|
2013-02-01 13:05:13 +00:00
|
|
|
{
|
2011-08-03 17:22:46 +00:00
|
|
|
initprintf("Line %d: loadmapstate called from EVENT_ANIMATESPRITES. WHY?\n",g_errorLineNum);
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=0; i<MAXSPRITES; i++)
|
2011-08-03 17:22:46 +00:00
|
|
|
spriteext[i].tspr = NULL;
|
2013-02-01 13:05:13 +00:00
|
|
|
}
|
2013-02-07 21:00:52 +00:00
|
|
|
#endif
|
2016-08-27 01:40:35 +00:00
|
|
|
Numsprites = pSavedState->numsprites;
|
|
|
|
tailspritefree = pSavedState->tailspritefree;
|
|
|
|
Bmemcpy(&headspritesect[0],&pSavedState->headspritesect[0],sizeof(headspritesect));
|
|
|
|
Bmemcpy(&prevspritesect[0],&pSavedState->prevspritesect[0],sizeof(prevspritesect));
|
|
|
|
Bmemcpy(&nextspritesect[0],&pSavedState->nextspritesect[0],sizeof(nextspritesect));
|
|
|
|
Bmemcpy(&headspritestat[0],&pSavedState->headspritestat[0],sizeof(headspritestat));
|
|
|
|
Bmemcpy(&prevspritestat[0],&pSavedState->prevspritestat[0],sizeof(prevspritestat));
|
|
|
|
Bmemcpy(&nextspritestat[0],&pSavedState->nextspritestat[0],sizeof(nextspritestat));
|
2012-03-11 17:37:08 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2016-11-09 22:51:42 +00:00
|
|
|
numyaxbunches = pSavedState->numyaxbunches;
|
2013-04-09 17:35:11 +00:00
|
|
|
# if !defined NEW_MAP_FORMAT
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(yax_bunchnum, pSavedState->yax_bunchnum, sizeof(yax_bunchnum));
|
|
|
|
Bmemcpy(yax_nextwall, pSavedState->yax_nextwall, sizeof(yax_nextwall));
|
2013-04-09 17:35:11 +00:00
|
|
|
# endif
|
2012-03-11 17:37:08 +00:00
|
|
|
#endif
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(&actor[0],&pSavedState->actor[0],sizeof(actor_t)*MAXSPRITES);
|
|
|
|
|
2016-11-09 22:51:42 +00:00
|
|
|
g_cyclerCnt = pSavedState->g_cyclerCnt;
|
2018-10-07 05:21:15 +00:00
|
|
|
Bmemcpy(g_cyclers, pSavedState->g_cyclers, sizeof(g_cyclers));
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(&g_playerSpawnPoints[0],&pSavedState->g_playerSpawnPoints[0],sizeof(g_playerSpawnPoints));
|
2016-11-09 22:51:42 +00:00
|
|
|
g_animWallCnt = pSavedState->g_animWallCnt;
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(&SpriteDeletionQueue[0],&pSavedState->SpriteDeletionQueue[0],sizeof(SpriteDeletionQueue));
|
2016-11-09 22:51:42 +00:00
|
|
|
g_spriteDeleteQueuePos = pSavedState->g_spriteDeleteQueuePos;
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(&animwall[0],&pSavedState->animwall[0],sizeof(animwall));
|
|
|
|
Bmemcpy(&g_origins[0],&pSavedState->origins[0],sizeof(g_origins));
|
|
|
|
Bmemcpy(&g_mirrorWall[0],&pSavedState->g_mirrorWall[0],sizeof(g_mirrorWall));
|
|
|
|
Bmemcpy(&g_mirrorSector[0],&pSavedState->g_mirrorSector[0],sizeof(g_mirrorSector));
|
2016-11-09 22:51:42 +00:00
|
|
|
g_mirrorCount = pSavedState->g_mirrorCount;
|
2016-08-27 01:40:35 +00:00
|
|
|
Bmemcpy(&show2dsector[0],&pSavedState->show2dsector[0],sizeof(show2dsector));
|
2016-11-09 22:51:42 +00:00
|
|
|
g_cloudCnt = pSavedState->g_cloudCnt;
|
2016-08-27 01:42:01 +00:00
|
|
|
Bmemcpy(&g_cloudSect[0],&pSavedState->g_cloudSect[0],sizeof(g_cloudSect));
|
2016-11-09 22:51:42 +00:00
|
|
|
g_cloudX = pSavedState->g_cloudX;
|
|
|
|
g_cloudY = pSavedState->g_cloudY;
|
|
|
|
g_pskyidx = pSavedState->pskyidx;
|
2016-08-27 01:42:01 +00:00
|
|
|
Bmemcpy(&g_animateGoal[0],&pSavedState->g_animateGoal[0],sizeof(g_animateGoal));
|
|
|
|
Bmemcpy(&g_animateVel[0],&pSavedState->g_animateVel[0],sizeof(g_animateVel));
|
2016-11-09 22:51:42 +00:00
|
|
|
g_animateCnt = pSavedState->g_animateCnt;
|
2016-08-27 01:42:01 +00:00
|
|
|
Bmemcpy(&g_animateSect[0],&pSavedState->g_animateSect[0],sizeof(g_animateSect));
|
2016-08-27 01:40:35 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
Bmemcpy(&g_animatePtr[0],&pSavedState->g_animatePtr[0],sizeof(g_animatePtr));
|
|
|
|
G_Util_PtrToIdx(g_animatePtr, g_animateCnt, sector, P2I_BACK);
|
2011-07-29 22:07:49 +00:00
|
|
|
|
2016-11-09 22:51:42 +00:00
|
|
|
g_playerSpawnCnt = pSavedState->g_playerSpawnCnt;
|
|
|
|
g_earthquakeTime = pSavedState->g_earthquakeTime;
|
|
|
|
lockclock = pSavedState->lockclock;
|
|
|
|
randomseed = pSavedState->randomseed;
|
|
|
|
g_globalRandom = pSavedState->g_globalRandom;
|
|
|
|
|
2013-01-19 18:29:00 +00:00
|
|
|
#if !defined LUNATIC
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=g_gameVarCount-1; i>=0; i--)
|
2008-07-18 02:46:24 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (aGameVars[i].flags & GAMEVAR_NORESET)
|
|
|
|
continue;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (aGameVars[i].flags & GAMEVAR_PERPLAYER)
|
2009-12-05 09:22:43 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (!pSavedState->vars[i])
|
|
|
|
continue;
|
2017-10-31 02:09:25 +00:00
|
|
|
Bmemcpy(aGameVars[i].pValues, pSavedState->vars[i], sizeof(intptr_t) * MAXPLAYERS);
|
2009-12-05 09:22:43 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (aGameVars[i].flags & GAMEVAR_PERACTOR)
|
2009-12-05 09:22:43 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
if (!pSavedState->vars[i])
|
|
|
|
continue;
|
2017-10-31 02:09:25 +00:00
|
|
|
Bmemcpy(aGameVars[i].pValues, pSavedState->vars[i], sizeof(intptr_t) * MAXSPRITES);
|
2009-12-05 09:22:43 +00:00
|
|
|
}
|
2018-05-22 19:03:44 +00:00
|
|
|
else
|
|
|
|
aGameVars[i].global = (intptr_t)pSavedState->vars[i];
|
2008-07-18 02:46:24 +00:00
|
|
|
}
|
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=g_gameArrayCount-1; i>=0; i--)
|
2016-08-27 01:41:50 +00:00
|
|
|
{
|
2017-10-31 02:09:25 +00:00
|
|
|
if ((aGameArrays[i].flags & GAMEARRAY_RESTORE) == 0)
|
2016-08-27 01:41:50 +00:00
|
|
|
continue;
|
|
|
|
|
2017-10-31 02:09:25 +00:00
|
|
|
aGameArrays[i].size = pSavedState->arraysiz[i];
|
|
|
|
Baligned_free(aGameArrays[i].pValues);
|
|
|
|
aGameArrays[i].pValues = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, Gv_GetArrayAllocSize(i));
|
|
|
|
|
|
|
|
Bmemcpy(aGameArrays[i].pValues, pSavedState->arrays[i], Gv_GetArrayAllocSize(i));
|
2016-08-27 01:41:50 +00:00
|
|
|
}
|
2017-10-31 02:09:25 +00:00
|
|
|
|
|
|
|
Gv_RefreshPointers();
|
2013-10-27 21:12:20 +00:00
|
|
|
#else
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pSavedState->savecode)
|
2013-10-27 21:12:22 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
El_RestoreGamevars(pSavedState->savecode);
|
2013-10-27 21:12:22 +00:00
|
|
|
}
|
2013-01-01 15:24:18 +00:00
|
|
|
#endif
|
2013-10-25 21:57:09 +00:00
|
|
|
// Update g_player[].ps->i (sprite indices of players) to be consistent
|
|
|
|
// with just loaded sprites.
|
|
|
|
// Otherwise, crashes may ensue: e.g. WGR2 SVN r391, map spiderden:
|
|
|
|
// - walk forward (to door leading to other level "Shadowpine Forest")
|
|
|
|
// - in new level, walk backward to get back to the Spider Den
|
|
|
|
// - walk backward to the door leading to Shadowpine Forest --> crash.
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t SPRITES_OF(STAT_PLAYER, i))
|
2013-10-25 21:57:09 +00:00
|
|
|
{
|
2013-12-28 17:04:27 +00:00
|
|
|
int32_t snum = P_Get(i);
|
2013-10-25 21:57:09 +00:00
|
|
|
Bassert((unsigned)snum < MAXPLAYERS);
|
|
|
|
g_player[snum].ps->i = i;
|
|
|
|
}
|
|
|
|
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t i=0; i<g_mostConcurrentPlayers; i++)
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[g_player[i].ps->i].extra = playerHealth[i];
|
2008-07-18 03:22:20 +00:00
|
|
|
|
2008-07-16 09:27:08 +00:00
|
|
|
if (g_player[myconnectindex].ps->over_shoulder_on != 0)
|
|
|
|
{
|
2013-01-19 18:28:32 +00:00
|
|
|
CAMERADIST = 0;
|
|
|
|
CAMERACLOCK = 0;
|
2008-07-16 09:27:08 +00:00
|
|
|
g_player[myconnectindex].ps->over_shoulder_on = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
screenpeek = myconnectindex;
|
|
|
|
|
2018-11-18 18:13:55 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2012-01-05 20:48:37 +00:00
|
|
|
if (ud.lockout)
|
2008-07-16 09:27:08 +00:00
|
|
|
{
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t x=g_animWallCnt-1; x>=0; x--)
|
2012-01-28 14:38:23 +00:00
|
|
|
switch (DYNAMICTILEMAP(wall[animwall[x].wallnum].picnum))
|
2008-07-16 09:27:08 +00:00
|
|
|
{
|
2018-05-22 19:03:44 +00:00
|
|
|
case FEMPIC1__STATIC: wall[animwall[x].wallnum].picnum = BLANKSCREEN; break;
|
2008-07-16 09:27:08 +00:00
|
|
|
case FEMPIC2__STATIC:
|
2018-05-22 19:03:44 +00:00
|
|
|
case FEMPIC3__STATIC: wall[animwall[x].wallnum].picnum = SCREENBREAK6; break;
|
2008-07-16 09:27:08 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-05 20:48:37 +00:00
|
|
|
#if 0
|
|
|
|
else
|
|
|
|
{
|
2017-12-29 19:27:04 +00:00
|
|
|
for (native_t x=g_numAnimWalls-1; x>=0; x--)
|
2012-01-05 20:48:37 +00:00
|
|
|
if (wall[animwall[x].wallnum].extra >= 0)
|
|
|
|
wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra;
|
|
|
|
}
|
|
|
|
#endif
|
2018-11-18 18:13:55 +00:00
|
|
|
#endif
|
2012-03-11 17:37:08 +00:00
|
|
|
#ifdef YAX_ENABLE
|
|
|
|
sv_postyaxload();
|
|
|
|
#endif
|
2011-07-29 22:07:28 +00:00
|
|
|
G_ResetInterpolations();
|
2008-07-16 09:27:08 +00:00
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
Net_ResetPrediction();
|
2008-07-16 09:27:08 +00:00
|
|
|
|
2011-02-25 21:50:19 +00:00
|
|
|
G_ClearFIFO();
|
2013-07-04 19:38:46 +00:00
|
|
|
G_ResetTimers(0);
|
2008-07-16 09:27:08 +00:00
|
|
|
}
|
|
|
|
}
|
2012-12-03 18:24:25 +00:00
|
|
|
|
|
|
|
#ifdef LUNATIC
|
2018-05-22 19:03:44 +00:00
|
|
|
void VM_FallSprite(int32_t i) { VM_Fall(i, &sprite[i]); }
|
2012-12-03 18:24:25 +00:00
|
|
|
|
2018-05-22 19:03:44 +00:00
|
|
|
int32_t VM_ResetPlayer2(int32_t snum, int32_t flags) { return VM_ResetPlayer(snum, 0, flags); }
|
2013-04-05 17:52:59 +00:00
|
|
|
|
|
|
|
int32_t VM_CheckSquished2(int32_t i, int32_t snum)
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
vm.spriteNum = i;
|
|
|
|
vm.pSprite = &sprite[i];
|
|
|
|
vm.playerNum = snum;
|
|
|
|
vm.pPlayer = g_player[snum].ps;
|
2013-04-05 17:52:59 +00:00
|
|
|
|
|
|
|
return VM_CheckSquished();
|
|
|
|
}
|
2012-12-03 18:24:25 +00:00
|
|
|
#endif
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
// MYOS* CON commands.
|
2018-05-22 19:03:44 +00:00
|
|
|
LUNATIC_EXTERN void VM_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p)
|
2016-02-13 21:05:57 +00:00
|
|
|
{
|
|
|
|
orientation &= (ROTATESPRITE_MAX-1);
|
|
|
|
|
2016-10-09 00:15:18 +00:00
|
|
|
int const rotAngle = (orientation&4) ? 1024 : 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
|
|
|
if (!(orientation&ROTATESPRITE_FULL16))
|
|
|
|
{
|
|
|
|
x<<=16;
|
|
|
|
y<<=16;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
rotatesprite_win(x, y, zoom, rotAngle, tilenum, shade, p, 2|orientation);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined LUNATIC
|
|
|
|
void VM_DrawTile(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation)
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
DukePlayer_t *pPlayer = g_player[screenpeek].ps;
|
|
|
|
int32_t tilePal = pPlayer->cursectnum >= 0 ? sector[pPlayer->cursectnum].floorpal : 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_DrawTileGeneric(x, y, 65536, tilenum, shade, orientation, tilePal);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VM_DrawTilePal(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p)
|
|
|
|
{
|
|
|
|
VM_DrawTileGeneric(x, y, 65536, tilenum, shade, orientation, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VM_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation)
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
DukePlayer_t *const pPlayer = g_player[screenpeek].ps;
|
|
|
|
int32_t tilePal = pPlayer->cursectnum >= 0 ? sector[pPlayer->cursectnum].floorpal : 0;
|
2016-02-13 21:05:57 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
VM_DrawTileGeneric(x, y, 32768, tilenum, shade, orientation, tilePal);
|
2016-02-13 21:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VM_DrawTilePalSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p)
|
|
|
|
{
|
|
|
|
VM_DrawTileGeneric(x, y, 32768, tilenum, shade, orientation, p);
|
|
|
|
}
|
|
|
|
#endif
|