Subversion Repositories eduke32

Rev

Rev 3802 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 Plagman 1
//-------------------------------------------------------------------------
2
/*
1652 terminx 3
Copyright (C) 2010 EDuke32 developers and contributors
5 Plagman 4
 
1652 terminx 5
This file is part of EDuke32.
5 Plagman 6
 
7
EDuke32 is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License version 2
9
as published by the Free Software Foundation.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 
15
See the GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
*/
21
//-------------------------------------------------------------------------
22
 
23
#include <time.h>
1458 terminx 24
#include <stdlib.h>
2985 helixhorne 25
#include <math.h>  // sqrt
5 Plagman 26
 
3170 helixhorne 27
#include "compat.h"
28
 
5 Plagman 29
#include "duke3d.h"
30
#include "gamedef.h"
1677 terminx 31
#include "gameexec.h"
5 Plagman 32
#include "scriplib.h"
1677 terminx 33
#include "savegame.h"
34
#include "premap.h"
968 terminx 35
#include "osdcmds.h"
5 Plagman 36
#include "osd.h"
1677 terminx 37
#include "menus.h"
5 Plagman 38
 
2721 helixhorne 39
#ifdef LUNATIC
3148 helixhorne 40
# include "lunatic_game.h"
2329 helixhorne 41
#endif
42
 
1595 helixhorne 43
#if KRANDDEBUG
44
# define GAMEEXEC_INLINE
45
# define GAMEEXEC_STATIC
46
#else
47
# define GAMEEXEC_INLINE inline
48
# define GAMEEXEC_STATIC static
49
#endif
50
 
3242 helixhorne 51
enum vmflags_t {
52
    VM_RETURN       = 0x00000001,
53
    VM_KILL         = 0x00000002,
54
    VM_NOEXECUTE    = 0x00000004,
55
};
56
 
1204 terminx 57
vmstate_t vm;
58
 
3460 helixhorne 59
#if !defined LUNATIC
60
int32_t g_tw;
1205 terminx 61
int32_t g_errorLineNum;
1956 helixhorne 62
int32_t g_currentEventExec = -1;
63
 
1909 terminx 64
GAMEEXEC_STATIC void VM_Execute(int32_t loop);
617 terminx 65
 
3354 helixhorne 66
# include "gamestructures.c"
67
#endif
1180 terminx 68
 
1909 terminx 69
#define VM_CONDITIONAL(xxx) { if ((xxx) || ((insptr = (intptr_t *)*(insptr+1)) && (((*insptr) & 0xfff) == CON_ELSE))) \
70
{ insptr += 2; VM_Execute(0); } }
71
 
1625 terminx 72
void VM_ScriptInfo(void)
1031 hnt_ts 73
{
3410 helixhorne 74
#if !defined LUNATIC
1631 terminx 75
    intptr_t *p;
76
 
77
    if (!script)
78
        return;
79
 
80
    if (insptr)
1031 hnt_ts 81
    {
2229 hendricks2 82
        initprintf("\n");
83
 
1631 terminx 84
        for (p=insptr-20; p<insptr+20; p++)
85
        {
2229 hendricks2 86
            initprintf("%5d: %3d: ",(int32_t)(p - script),(int32_t)(p - insptr));
87
 
1631 terminx 88
            if (*p>>12&&(*p&0xFFF)<CON_END)
2229 hendricks2 89
                initprintf("%5d %s",(int32_t)(*p>>12),keyw[*p&0xFFF]);
1631 terminx 90
            else
2229 hendricks2 91
                initprintf("%d",(int32_t)*p);
92
 
93
            initprintf("\n");
1631 terminx 94
        }
95
 
96
        initprintf("\n");
1031 hnt_ts 97
    }
1631 terminx 98
 
99
    if (vm.g_i)
3238 hendricks2 100
        initprintf_nowarn("current actor: %d (%d)\n",vm.g_i,TrackerCast(vm.g_sp->picnum));
1631 terminx 101
 
102
    initprintf("g_errorLineNum: %d, g_tw: %d\n",g_errorLineNum,g_tw);
3354 helixhorne 103
#endif
1031 hnt_ts 104
}
105
 
3514 helixhorne 106
static void VM_KillIt(int32_t iActor, int32_t iPlayer)
107
{
108
    if (iActor >= 0)
109
    {
110
        // if player was set to squish, first stop that...
111
        if (iPlayer >= 0 && g_player[iPlayer].ps->actorsqu == iActor)
112
            g_player[iPlayer].ps->actorsqu = -1;
113
 
114
        A_DeleteSprite(iActor);
115
    }
116
}
117
 
2709 helixhorne 118
// May recurse, e.g. through EVENT_XXX -> ... -> EVENT_KILLIT
2656 terminx 119
int32_t VM_OnEvent(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t lDist, int32_t iReturn)
5 Plagman 120
{
2721 helixhorne 121
#ifdef LUNATIC
2842 helixhorne 122
    const double t = gethitickms();
123
 
3345 helixhorne 124
    // TODO: handling of RETURN gamevar / iReturn / this function's return value
3148 helixhorne 125
    if (L_IsInitialized(&g_ElState) && El_HaveEvent(iEventID))
3526 helixhorne 126
        if (El_CallEvent(&g_ElState, iEventID, iActor, iPlayer, lDist, &iReturn)==1)
3514 helixhorne 127
            VM_KillIt(iActor, iPlayer);
3354 helixhorne 128
 
3514 helixhorne 129
    g_eventTotalMs[iEventID] += gethitickms()-t;
130
    g_eventCalls[iEventID]++;
131
#else
132
 
2923 helixhorne 133
    if (apScriptGameEvent[iEventID])
5 Plagman 134
    {
1204 terminx 135
        intptr_t *oinsptr=insptr;
136
        vmstate_t vm_backup;
2652 terminx 137
 
2166 helixhorne 138
        vmstate_t tempvm = { iActor, iPlayer, lDist,
139
                             iActor >= 0 ? &actor[iActor].t_data[0] : NULL,
140
                             iActor >= 0 ? &sprite[iActor] : NULL,
141
 
2655 terminx 142
 
143
        int32_t backupReturnVar = aGameVars[g_iReturnVarID].val.lValue;
144
        int32_t backupEventExec = g_currentEventExec;
484 terminx 145
 
2656 terminx 146
        aGameVars[g_iReturnVarID].val.lValue = iReturn;
1956 helixhorne 147
        g_currentEventExec = iEventID;
1807 terminx 148
        insptr = apScriptGameEvent[iEventID];
149
 
1204 terminx 150
        Bmemcpy(&vm_backup, &vm, sizeof(vmstate_t));
1625 terminx 151
        Bmemcpy(&vm, &tempvm, sizeof(vmstate_t));
433 terminx 152
 
1909 terminx 153
        VM_Execute(1);
5 Plagman 154
 
1625 terminx 155
        if (vm.g_flags & VM_KILL)
3514 helixhorne 156
            VM_KillIt(iActor, iPlayer);
1802 terminx 157
 
1204 terminx 158
        Bmemcpy(&vm, &vm_backup, sizeof(vmstate_t));
1802 terminx 159
        insptr = oinsptr;
1956 helixhorne 160
 
2655 terminx 161
        g_currentEventExec = backupEventExec;
2656 terminx 162
        iReturn = aGameVars[g_iReturnVarID].val.lValue;
2655 terminx 163
        aGameVars[g_iReturnVarID].val.lValue = backupReturnVar;
2923 helixhorne 164
    }
3354 helixhorne 165
#endif
2656 terminx 166
 
2923 helixhorne 167
    return iReturn;
5 Plagman 168
}
169
 
1802 terminx 170
static inline int32_t VM_CheckSquished(void)
5 Plagman 171
{
3640 helixhorne 172
    const sectortype *sc = &sector[vm.g_sp->sectnum];
395 terminx 173
 
3008 helixhorne 174
    if ((vm.g_sp->picnum == APLAYER && ud.noclip) || sc->lotag == ST_23_SWINGING_DOOR)
395 terminx 175
        return 0;
176
 
2071 helixhorne 177
    {
178
        int32_t fz=sc->floorz, cz=sc->ceilingz;
179
#ifdef YAX_ENABLE
180
        int16_t cb, fb;
181
 
182
        yax_getbunches(vm.g_sp->sectnum, &cb, &fb);
183
        if (cb >= 0 && (sc->ceilingstat&512)==0)  // if ceiling non-blocking...
3640 helixhorne 184
            cz -= (32<<8);  // unconditionally don't squish... yax_getneighborsect is slowish :/
2071 helixhorne 185
        if (fb >= 0 && (sc->floorstat&512)==0)
186
            fz += (32<<8);
187
#endif
188
 
189
        if (vm.g_sp->pal == 1 ?
190
            (fz - cz >= (32<<8) || (sc->lotag&32768)) :
191
            (fz - cz >= (12<<8)))
192
        return 0;
193
    }
194
 
1802 terminx 195
    P_DoQuote(QUOTE_SQUISHED, g_player[vm.g_p].ps);
395 terminx 196
 
3640 helixhorne 197
    if (A_CheckEnemySprite(vm.g_sp))
198
        vm.g_sp->xvel = 0;
1625 terminx 199
 
1909 terminx 200
    if (vm.g_sp->pal == 1) // frozen
1625 terminx 201
    {
202
        actor[vm.g_i].picnum = SHOTSPARK1;
203
        actor[vm.g_i].extra = 1;
204
        return 0;
395 terminx 205
    }
1625 terminx 206
 
207
    return 1;
395 terminx 208
}
209
 
1595 helixhorne 210
GAMEEXEC_STATIC GAMEEXEC_INLINE void P_ForceAngle(DukePlayer_t *p)
398 terminx 211
{
1205 terminx 212
    int32_t n = 128-(krand()&255);
398 terminx 213
 
214
    p->horiz += 64;
215
    p->return_to_center = 9;
1802 terminx 216
    p->look_ang = p->rotscrnang = n>>1;
398 terminx 217
}
218
 
3254 helixhorne 219
int32_t A_Dodge(spritetype *s)
395 terminx 220
{
1802 terminx 221
    int32_t bx,by,bxvect,byvect,i;
1205 terminx 222
    int32_t mx = s->x, my = s->y;
223
    int32_t mxvect = sintable[(s->ang+512)&2047];
224
    int32_t myvect = sintable[s->ang&2047];
5 Plagman 225
 
1171 terminx 226
    if (A_CheckEnemySprite(s) && s->extra <= 0) // hack
227
        return 0;
228
 
1229 terminx 229
    for (i=headspritestat[STAT_PROJECTILE]; i>=0; i=nextspritestat[i]) //weapons list
5 Plagman 230
    {
1802 terminx 231
        if (OW == i)
5 Plagman 232
            continue;
233
 
234
        bx = SX-mx;
235
        by = SY-my;
335 terminx 236
        bxvect = sintable[(SA+512)&2047];
237
        byvect = sintable[SA&2047];
5 Plagman 238
 
1802 terminx 239
        if ((mxvect * bx) + (myvect * by) >= 0 && (bxvect * bx) + (byvect * by) < 0)
240
        {
241
            if (klabs((bxvect * by) - (byvect * bx)) < 65536<<6)
5 Plagman 242
            {
1802 terminx 243
                s->ang -= 512+(krand()&1024);
244
                return 1;
5 Plagman 245
            }
1802 terminx 246
        }
5 Plagman 247
    }
248
    return 0;
249
}
250
 
1205 terminx 251
int32_t A_GetFurthestAngle(int32_t iActor,int32_t angs)
5 Plagman 252
{
432 terminx 253
    spritetype *s = &sprite[iActor];
5 Plagman 254
 
1625 terminx 255
    if (s->picnum != APLAYER && (actor[iActor].t_data[0]&63) > 2)
1048 terminx 256
        return(s->ang + 1024);
5 Plagman 257
 
258
    {
1205 terminx 259
        int32_t furthest_angle=0;
1208 terminx 260
        int32_t d;
1205 terminx 261
        int32_t greatestd = -(1<<30);
262
        int32_t angincs = 2048/angs,j;
2877 helixhorne 263
        hitdata_t hit;
5 Plagman 264
 
1229 terminx 265
        for (j=s->ang; j<(2048+s->ang); j+=angincs)
1048 terminx 266
        {
1208 terminx 267
            s->z -= (8<<8);
268
            hitscan((const vec3_t *)s, s->sectnum,
1048 terminx 269
                    sintable[(j+512)&2047],
270
                    sintable[j&2047],0,
2877 helixhorne 271
                    &hit,CLIPMASK1);
1208 terminx 272
            s->z += (8<<8);
2877 helixhorne 273
            d = klabs(hit.pos.x-s->x) + klabs(hit.pos.y-s->y);
5 Plagman 274
 
1048 terminx 275
            if (d > greatestd)
276
            {
277
                greatestd = d;
278
                furthest_angle = j;
279
            }
5 Plagman 280
        }
1048 terminx 281
        return (furthest_angle&2047);
5 Plagman 282
    }
283
}
284
 
1205 terminx 285
int32_t A_FurthestVisiblePoint(int32_t iActor,spritetype *ts,int32_t *dax,int32_t *day)
5 Plagman 286
{
2652 terminx 287
    if ((actor[iActor].t_data[0]&63))
288
        return -1;
289
 
5 Plagman 290
    {
1208 terminx 291
        int32_t d, da;//, d, cd, ca,tempx,tempy,cx,cy;
292
        int32_t j, angincs;
1048 terminx 293
        spritetype *s = &sprite[iActor];
2877 helixhorne 294
        hitdata_t hit;
5 Plagman 295
 
1587 terminx 296
        if ((!g_netServer && ud.multimode < 2) && ud.player_skill < 3)
1048 terminx 297
            angincs = 2048/2;
1143 terminx 298
        else angincs = 2048/(1+(krand()&1));
5 Plagman 299
 
1229 terminx 300
        for (j=ts->ang; j<(2048+ts->ang); j+=(angincs-(krand()&511)))
1048 terminx 301
        {
1208 terminx 302
            ts->z -= (16<<8);
303
            hitscan((const vec3_t *)ts, ts->sectnum,
1048 terminx 304
                    sintable[(j+512)&2047],
1143 terminx 305
                    sintable[j&2047],16384-(krand()&32767),
2877 helixhorne 306
                    &hit,CLIPMASK1);
1048 terminx 307
 
1208 terminx 308
            ts->z += (16<<8);
1048 terminx 309
 
2877 helixhorne 310
            d = klabs(hit.pos.x-ts->x)+klabs(hit.pos.y-ts->y);
311
            da = klabs(hit.pos.x-s->x)+klabs(hit.pos.y-s->y);
1208 terminx 312
 
2877 helixhorne 313
            if (d < da && hit.sect > -1)
314
                if (cansee(hit.pos.x,hit.pos.y,hit.pos.z,
315
                           hit.sect,s->x,s->y,s->z-(16<<8),s->sectnum))
1048 terminx 316
                {
2877 helixhorne 317
                    *dax = hit.pos.x;
318
                    *day = hit.pos.y;
319
                    return hit.sect;
1048 terminx 320
                }
321
        }
322
        return -1;
5 Plagman 323
    }
324
}
325
 
1205 terminx 326
void A_GetZLimits(int32_t iActor)
5 Plagman 327
{
432 terminx 328
    spritetype *s = &sprite[iActor];
5 Plagman 329
 
1677 terminx 330
//    if (s->statnum == STAT_PLAYER || s->statnum == STAT_STANDABLE || s->statnum == STAT_ZOMBIEACTOR || s->statnum == STAT_ACTOR || s->statnum == STAT_PROJECTILE)
5 Plagman 331
    {
2192 helixhorne 332
        int32_t hz,lz,zr = 127;
1217 terminx 333
        int32_t cstat = s->cstat;
428 terminx 334
 
1217 terminx 335
        s->cstat = 0;
336
 
1487 terminx 337
        if (s->statnum == STAT_PROJECTILE)
2192 helixhorne 338
            zr = 4;
5 Plagman 339
 
1677 terminx 340
        s->z -= ZOFFSET;
1625 terminx 341
        getzrange((vec3_t *)s,s->sectnum,&actor[iActor].ceilingz,&hz,&actor[iActor].floorz,&lz,zr,CLIPMASK0);
1677 terminx 342
        s->z += ZOFFSET;
5 Plagman 343
 
1217 terminx 344
        s->cstat = cstat;
345
 
2249 helixhorne 346
        actor[iActor].flags &= ~SPRITE_NOFLOORSHADOW;
347
 
333 terminx 348
        if ((lz&49152) == 49152 && (sprite[lz&(MAXSPRITES-1)].cstat&48) == 0)
5 Plagman 349
        {
2192 helixhorne 350
            const spritetype *hitspr = &sprite[lz&(MAXSPRITES-1)];
351
 
5 Plagman 352
            lz &= (MAXSPRITES-1);
2192 helixhorne 353
 
354
            if ((A_CheckEnemySprite(hitspr) && hitspr->pal != 1 && s->statnum != STAT_PROJECTILE)
355
                    || (hitspr->picnum == APLAYER && A_CheckEnemySprite(s)))
5 Plagman 356
            {
2249 helixhorne 357
                actor[iActor].flags |= SPRITE_NOFLOORSHADOW;  // No shadows on actors
5 Plagman 358
                s->xvel = -256;
1143 terminx 359
                A_SetSprite(iActor,CLIPMASK0);
5 Plagman 360
            }
2192 helixhorne 361
            else if (s->statnum == STAT_PROJECTILE && hitspr->picnum == APLAYER && s->owner==lz)
362
            {
363
                actor[iActor].ceilingz = sector[s->sectnum].ceilingz;
364
                actor[iActor].floorz   = sector[s->sectnum].floorz;
365
            }
5 Plagman 366
        }
367
    }
1677 terminx 368
    /*
369
        else
370
        {
371
            actor[iActor].ceilingz = sector[s->sectnum].ceilingz;
372
            actor[iActor].floorz   = sector[s->sectnum].floorz;
373
        }
374
    */
5 Plagman 375
}
376
 
1205 terminx 377
void A_Fall(int32_t iActor)
5 Plagman 378
{
432 terminx 379
    spritetype *s = &sprite[iActor];
1205 terminx 380
    int32_t hz,lz,c = g_spriteGravity;
1877 helixhorne 381
#ifdef YAX_ENABLE
382
    int16_t fbunch;
383
#endif
1143 terminx 384
    if (G_CheckForSpaceFloor(s->sectnum))
5 Plagman 385
        c = 0;
386
    else
387
    {
3073 helixhorne 388
        if (G_CheckForSpaceCeiling(s->sectnum) || sector[s->sectnum].lotag == ST_2_UNDERWATER)
1150 terminx 389
            c = g_spriteGravity/6;
5 Plagman 390
    }
391
 
1490 terminx 392
    if (s->statnum == STAT_ACTOR || s->statnum == STAT_PLAYER || s->statnum == STAT_ZOMBIEACTOR || s->statnum == STAT_STANDABLE)
1208 terminx 393
    {
1217 terminx 394
        int32_t cstat = s->cstat;
395
        s->cstat = 0;
1677 terminx 396
        s->z -= ZOFFSET;
1625 terminx 397
        getzrange((vec3_t *)s,s->sectnum,&actor[iActor].ceilingz,&hz,&actor[iActor].floorz,&lz,127L,CLIPMASK0);
1677 terminx 398
        s->z += ZOFFSET;
1217 terminx 399
        s->cstat = cstat;
1208 terminx 400
    }
5 Plagman 401
    else
402
    {
1625 terminx 403
        actor[iActor].ceilingz = sector[s->sectnum].ceilingz;
404
        actor[iActor].floorz   = sector[s->sectnum].floorz;
5 Plagman 405
    }
406
 
1877 helixhorne 407
#ifdef YAX_ENABLE
408
    if (sector[s->sectnum].floorstat&512)
409
        fbunch = -1;
410
    else
411
        fbunch = yax_getbunch(s->sectnum, YAX_FLOOR);
412
#endif
3682 helixhorne 413
 
414
    if (s->z < actor[iActor].floorz-ZOFFSET
1877 helixhorne 415
#ifdef YAX_ENABLE
3682 helixhorne 416
            || fbunch >= 0
1877 helixhorne 417
#endif
2652 terminx 418
       )
5 Plagman 419
    {
3073 helixhorne 420
        if (sector[s->sectnum].lotag == ST_2_UNDERWATER && s->zvel > 3122)
5 Plagman 421
            s->zvel = 3144;
1181 terminx 422
        s->z += s->zvel = min(6144, s->zvel+c);
5 Plagman 423
    }
3682 helixhorne 424
 
1877 helixhorne 425
#ifdef YAX_ENABLE
426
    if (fbunch >= 0)
427
        setspritez(iActor, (vec3_t *)s);
3682 helixhorne 428
    else
1877 helixhorne 429
#endif
3682 helixhorne 430
        if (s->z >= actor[iActor].floorz-ZOFFSET)
2652 terminx 431
        {
3682 helixhorne 432
            s->z = actor[iActor].floorz-ZOFFSET;
2652 terminx 433
            s->zvel = 0;
434
        }
5 Plagman 435
}
436
 
1205 terminx 437
int32_t G_GetAngleDelta(int32_t a,int32_t na)
5 Plagman 438
{
439
    a &= 2047;
440
    na &= 2047;
441
 
331 terminx 442
    if (klabs(a-na) < 1024)
521 terminx 443
    {
1143 terminx 444
//        OSD_Printf("G_GetAngleDelta() returning %d\n",na-a);
5 Plagman 445
        return (na-a);
522 terminx 446
    }
5 Plagman 447
 
428 terminx 448
    if (na > 1024) na -= 2048;
449
    if (a > 1024) a -= 2048;
450
 
1143 terminx 451
//    OSD_Printf("G_GetAngleDelta() returning %d\n",na-a);
428 terminx 452
    return (na-a);
5 Plagman 453
}
454
 
2709 helixhorne 455
GAMEEXEC_STATIC void VM_AlterAng(int32_t a)
5 Plagman 456
{
2745 helixhorne 457
    const int32_t ticselapsed = (vm.g_t[0])&31;
5 Plagman 458
 
3459 helixhorne 459
#if !defined LUNATIC
2185 helixhorne 460
    const intptr_t *moveptr;
2709 helixhorne 461
    if ((unsigned)vm.g_t[1] >= (unsigned)g_scriptSize-1)
2451 helixhorne 462
 
1685 terminx 463
    {
464
        vm.g_t[1] = 0;
3238 hendricks2 465
        OSD_Printf_nowarn(OSD_ERROR "bad moveptr for actor %d (%d)!\n", vm.g_i, TrackerCast(vm.g_sp->picnum));
1686 terminx 466
        return;
1685 terminx 467
    }
468
 
2185 helixhorne 469
    moveptr = script + vm.g_t[1];  // RESEARCH: what's with move 0 and >>> 1 <<<?
470
 
2864 helixhorne 471
    vm.g_sp->xvel += (*moveptr - vm.g_sp->xvel)/5;
472
    if (vm.g_sp->zvel < 648)
473
        vm.g_sp->zvel += ((*(moveptr+1)<<4) - vm.g_sp->zvel)/5;
2724 helixhorne 474
#else
2864 helixhorne 475
    vm.g_sp->xvel += (actor[vm.g_i].mv.hvel - vm.g_sp->xvel)/5;
476
    if (vm.g_sp->zvel < 648)
477
        vm.g_sp->zvel += ((actor[vm.g_i].mv.vvel<<4) - vm.g_sp->zvel)/5;
2724 helixhorne 478
#endif
5 Plagman 479
 
1204 terminx 480
    if (A_CheckEnemySprite(vm.g_sp) && vm.g_sp->extra <= 0) // hack
1171 terminx 481
        return;
482
 
331 terminx 483
    if (a&seekplayer)
5 Plagman 484
    {
1205 terminx 485
        int32_t aang = vm.g_sp->ang, angdif, goalang;
486
        int32_t j = g_player[vm.g_p].ps->holoduke_on;
1048 terminx 487
 
5 Plagman 488
        // NOTE: looks like 'owner' is set to target sprite ID...
489
 
1204 terminx 490
        if (j >= 0 && cansee(sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum,vm.g_sp->x,vm.g_sp->y,vm.g_sp->z,vm.g_sp->sectnum))
491
            vm.g_sp->owner = j;
492
        else vm.g_sp->owner = g_player[vm.g_p].ps->i;
5 Plagman 493
 
1204 terminx 494
        if (sprite[vm.g_sp->owner].picnum == APLAYER)
1625 terminx 495
            goalang = getangle(actor[vm.g_i].lastvx-vm.g_sp->x,actor[vm.g_i].lastvy-vm.g_sp->y);
5 Plagman 496
        else
1204 terminx 497
            goalang = getangle(sprite[vm.g_sp->owner].x-vm.g_sp->x,sprite[vm.g_sp->owner].y-vm.g_sp->y);
5 Plagman 498
 
1204 terminx 499
        if (vm.g_sp->xvel && vm.g_sp->picnum != DRONE)
5 Plagman 500
        {
1143 terminx 501
            angdif = G_GetAngleDelta(aang,goalang);
5 Plagman 502
 
331 terminx 503
            if (ticselapsed < 2)
5 Plagman 504
            {
333 terminx 505
                if (klabs(angdif) < 256)
5 Plagman 506
                {
1143 terminx 507
                    j = 128-(krand()&256);
1204 terminx 508
                    vm.g_sp->ang += j;
509
                    if (A_GetHitscanRange(vm.g_i) < 844)
510
                        vm.g_sp->ang -= j;
5 Plagman 511
                }
512
            }
1346 terminx 513
            else if (ticselapsed > 18 && ticselapsed < GAMETICSPERSEC) // choose
5 Plagman 514
            {
1204 terminx 515
                if (klabs(angdif>>2) < 128) vm.g_sp->ang = goalang;
516
                else vm.g_sp->ang += angdif>>2;
5 Plagman 517
            }
518
        }
1204 terminx 519
        else vm.g_sp->ang = goalang;
5 Plagman 520
    }
521
 
331 terminx 522
    if (ticselapsed < 1)
5 Plagman 523
    {
331 terminx 524
        if (a&furthestdir)
5 Plagman 525
        {
1909 terminx 526
            vm.g_sp->ang = A_GetFurthestAngle(vm.g_i, 2);
1204 terminx 527
            vm.g_sp->owner = g_player[vm.g_p].ps->i;
5 Plagman 528
        }
529
 
331 terminx 530
        if (a&fleeenemy)
1909 terminx 531
            vm.g_sp->ang = A_GetFurthestAngle(vm.g_i, 2);
5 Plagman 532
    }
533
}
534
 
3459 helixhorne 535
static void VM_AddAngle(int32_t shr, int32_t goalang)
2745 helixhorne 536
{
537
    int32_t angdif = G_GetAngleDelta(vm.g_sp->ang,goalang)>>shr;
538
 
539
    if ((angdif > -8 && angdif < 0) || (angdif < 8 && angdif > 0))
540
        angdif *= 2;
541
 
542
    vm.g_sp->ang += angdif;
543
}
544
 
3459 helixhorne 545
static void VM_FacePlayer(int32_t shr)
2745 helixhorne 546
{
547
    int32_t goalang;
548
    const DukePlayer_t *const ps = g_player[vm.g_p].ps;
549
 
550
    if (g_player[vm.g_p].ps->newowner >= 0)
551
        goalang = getangle(ps->opos.x-vm.g_sp->x, ps->opos.y-vm.g_sp->y);
552
    else
553
        goalang = getangle(ps->pos.x-vm.g_sp->x, ps->pos.y-vm.g_sp->y);
554
 
3459 helixhorne 555
    VM_AddAngle(shr, goalang);
2745 helixhorne 556
}
557
 
3666 helixhorne 558
////////// TROR get*zofslope //////////
559
// These rather belong into the engine.
560
 
561
static int32_t yax_getceilzofslope(int16_t sectnum, int32_t dax, int32_t day)
562
{
563
#ifdef YAX_ENABLE
564
    if ((sector[sectnum].ceilingstat&512)==0)
565
    {
566
        int32_t nsect = yax_getneighborsect(dax, day, sectnum, YAX_CEILING);
567
        if (nsect >= 0)
568
            return getceilzofslope(nsect, dax, day);
569
    }
570
#endif
571
    return getceilzofslope(sectnum, dax, day);
572
}
573
 
574
static int32_t yax_getflorzofslope(int16_t sectnum, int32_t dax, int32_t day)
575
{
576
#ifdef YAX_ENABLE
577
    if ((sector[sectnum].floorstat&512)==0)
578
    {
579
        int32_t nsect = yax_getneighborsect(dax, day, sectnum, YAX_FLOOR);
580
        if (nsect >= 0)
581
            return getflorzofslope(nsect, dax, day);
582
    }
583
#endif
584
    return getflorzofslope(sectnum, dax, day);
585
}
586
 
587
////////////////////
588
 
1625 terminx 589
GAMEEXEC_STATIC void VM_Move(void)
5 Plagman 590
{
3459 helixhorne 591
#if !defined LUNATIC
2185 helixhorne 592
    const intptr_t *moveptr;
2724 helixhorne 593
#endif
3459 helixhorne 594
    int32_t a = vm.g_sp->hitag, angdif;
595
    const int32_t deadflag = (A_CheckEnemySprite(vm.g_sp) && vm.g_sp->extra <= 0);
5 Plagman 596
 
331 terminx 597
    if (a == -1) a = 0;
5 Plagman 598
 
1204 terminx 599
    vm.g_t[0]++;
5 Plagman 600
 
1204 terminx 601
    if (vm.g_t[1] == 0 || a == 0)
1171 terminx 602
    {
3314 helixhorne 603
        if (deadflag || (actor[vm.g_i].bpos.x != vm.g_sp->x) || (actor[vm.g_i].bpos.y != vm.g_sp->y))
1171 terminx 604
        {
3314 helixhorne 605
            actor[vm.g_i].bpos.x = vm.g_sp->x;
606
            actor[vm.g_i].bpos.y = vm.g_sp->y;
2745 helixhorne 607
            setsprite(vm.g_i, (vec3_t *)vm.g_sp);
1171 terminx 608
        }
609
        return;
610
    }
611
 
1909 terminx 612
    if (deadflag) goto dead;
613
 
614
    if (a&face_player)
3459 helixhorne 615
        VM_FacePlayer(2);
5 Plagman 616
 
1909 terminx 617
    if (a&spin)
1204 terminx 618
        vm.g_sp->ang += sintable[((vm.g_t[0]<<3)&2047)]>>6;
5 Plagman 619
 
1909 terminx 620
    if (a&face_player_slow)
3459 helixhorne 621
        VM_FacePlayer(4);
5 Plagman 622
 
2745 helixhorne 623
    if ((a&jumptoplayer) == jumptoplayer)
5 Plagman 624
    {
1204 terminx 625
        if (vm.g_t[0] < 16)
626
            vm.g_sp->zvel -= (sintable[(512+(vm.g_t[0]<<4))&2047]>>5);
5 Plagman 627
    }
628
 
1909 terminx 629
    if (a&face_player_smart)
5 Plagman 630
    {
2875 helixhorne 631
        DukePlayer_t *const ps = g_player[vm.g_p].ps;
632
        int32_t newx = ps->pos.x + (ps->vel.x/768);
633
        int32_t newy = ps->pos.y + (ps->vel.y/768);
522 terminx 634
 
3459 helixhorne 635
        int32_t goalang = getangle(newx-vm.g_sp->x,newy-vm.g_sp->y);
636
        VM_AddAngle(2, goalang);
5 Plagman 637
    }
638
 
1909 terminx 639
dead:
3459 helixhorne 640
#if !defined LUNATIC
2750 helixhorne 641
    if ((unsigned)vm.g_t[1] >= (unsigned)g_scriptSize-1)
1684 terminx 642
    {
1685 terminx 643
        vm.g_t[1] = 0;
3238 hendricks2 644
        OSD_Printf_nowarn(OSD_ERROR "clearing bad moveptr for actor %d (%d)\n", vm.g_i, TrackerCast(vm.g_sp->picnum));
1686 terminx 645
        return;
1685 terminx 646
    }
5 Plagman 647
 
2185 helixhorne 648
    moveptr = script + vm.g_t[1];  // RESEARCH: what's with move 0 and >>> 1 <<<?
649
 
1820 terminx 650
    if (a&geth) vm.g_sp->xvel += ((*moveptr)-vm.g_sp->xvel)>>1;
651
    if (a&getv) vm.g_sp->zvel += ((*(moveptr+1)<<4)-vm.g_sp->zvel)>>1;
2724 helixhorne 652
#else
2864 helixhorne 653
    if (a&geth) vm.g_sp->xvel += (actor[vm.g_i].mv.hvel - vm.g_sp->xvel)>>1;
654
    if (a&getv) vm.g_sp->zvel += (actor[vm.g_i].mv.vvel - vm.g_sp->zvel)>>1;
2724 helixhorne 655
#endif
1820 terminx 656
 
1197 terminx 657
    if (a&dodgebullet && !deadflag)
1204 terminx 658
        A_Dodge(vm.g_sp);
5 Plagman 659
 
1204 terminx 660
    if (vm.g_sp->picnum != APLAYER)
1625 terminx 661
        VM_AlterAng(a);
5 Plagman 662
 
1204 terminx 663
    if (vm.g_sp->xvel > -6 && vm.g_sp->xvel < 6) vm.g_sp->xvel = 0;
5 Plagman 664
 
1204 terminx 665
    a = A_CheckEnemySprite(vm.g_sp);
5 Plagman 666
 
1204 terminx 667
    if (vm.g_sp->xvel || vm.g_sp->zvel)
5 Plagman 668
    {
2745 helixhorne 669
        int32_t daxvel;
670
 
1204 terminx 671
        if (a && vm.g_sp->picnum != ROTATEGUN)
5 Plagman 672
        {
1204 terminx 673
            if ((vm.g_sp->picnum == DRONE || vm.g_sp->picnum == COMMANDER) && vm.g_sp->extra > 0)
5 Plagman 674
            {
1204 terminx 675
                if (vm.g_sp->picnum == COMMANDER)
5 Plagman 676
                {
2745 helixhorne 677
                    int32_t l;
3663 helixhorne 678
                    // NOTE: COMMANDER updates both actor[].floorz and
679
                    // .ceilingz regardless of its zvel.
3666 helixhorne 680
                    actor[vm.g_i].floorz = l = yax_getflorzofslope(vm.g_sp->sectnum,vm.g_sp->x,vm.g_sp->y);
2745 helixhorne 681
                    if (vm.g_sp->z > l-(8<<8))
5 Plagman 682
                    {
2745 helixhorne 683
                        vm.g_sp->z = l-(8<<8);
1204 terminx 684
                        vm.g_sp->zvel = 0;
5 Plagman 685
                    }
686
 
3666 helixhorne 687
                    actor[vm.g_i].ceilingz = l = yax_getceilzofslope(vm.g_sp->sectnum,vm.g_sp->x,vm.g_sp->y);
3663 helixhorne 688
                    if (vm.g_sp->z < l+(80<<8))
5 Plagman 689
                    {
1204 terminx 690
                        vm.g_sp->z = l+(80<<8);
691
                        vm.g_sp->zvel = 0;
5 Plagman 692
                    }
693
                }
694
                else
695
                {
2745 helixhorne 696
                    int32_t l;
3663 helixhorne 697
                    // The DRONE updates either .floorz or .ceilingz, not both.
1204 terminx 698
                    if (vm.g_sp->zvel > 0)
5 Plagman 699
                    {
3666 helixhorne 700
                        actor[vm.g_i].floorz = l = yax_getflorzofslope(vm.g_sp->sectnum,vm.g_sp->x,vm.g_sp->y);
2745 helixhorne 701
                        if (vm.g_sp->z > l-(30<<8))
1204 terminx 702
                            vm.g_sp->z = l-(30<<8);
5 Plagman 703
                    }
704
                    else
705
                    {
3666 helixhorne 706
                        actor[vm.g_i].ceilingz = l = yax_getceilzofslope(vm.g_sp->sectnum,vm.g_sp->x,vm.g_sp->y);
3663 helixhorne 707
                        if (vm.g_sp->z < l+(50<<8))
5 Plagman 708
                        {
1204 terminx 709
                            vm.g_sp->z = l+(50<<8);
710
                            vm.g_sp->zvel = 0;
5 Plagman 711
                        }
712
                    }
713
                }
714
            }
1204 terminx 715
            else if (vm.g_sp->picnum != ORGANTIC)
5 Plagman 716
            {
3663 helixhorne 717
                // All other actors besides ORGANTIC don't update .floorz or
718
                // .ceilingz here.
1625 terminx 719
                if (vm.g_sp->zvel > 0 && actor[vm.g_i].floorz < vm.g_sp->z)
720
                    vm.g_sp->z = actor[vm.g_i].floorz;
1204 terminx 721
                if (vm.g_sp->zvel < 0)
5 Plagman 722
                {
3666 helixhorne 723
                    const int32_t l = yax_getceilzofslope(vm.g_sp->sectnum,vm.g_sp->x,vm.g_sp->y);
2745 helixhorne 724
 
3663 helixhorne 725
                    if (vm.g_sp->z < l+(66<<8))
5 Plagman 726
                    {
1204 terminx 727
                        vm.g_sp->z = l+(66<<8);
728
                        vm.g_sp->zvel >>= 1;
5 Plagman 729
                    }
730
                }
731
            }
732
        }
1204 terminx 733
        else if (vm.g_sp->picnum == APLAYER)
3663 helixhorne 734
            if (vm.g_sp->z < actor[vm.g_i].ceilingz+(32<<8))
1625 terminx 735
                vm.g_sp->z = actor[vm.g_i].ceilingz+(32<<8);
5 Plagman 736
 
1204 terminx 737
        daxvel = vm.g_sp->xvel;
738
        angdif = vm.g_sp->ang;
5 Plagman 739
 
1204 terminx 740
        if (a && vm.g_sp->picnum != ROTATEGUN)
5 Plagman 741
        {
2875 helixhorne 742
            DukePlayer_t *const ps = g_player[vm.g_p].ps;
743
 
1204 terminx 744
            if (vm.g_x < 960 && vm.g_sp->xrepeat > 16)
5 Plagman 745
            {
1204 terminx 746
                daxvel = -(1024-vm.g_x);
2745 helixhorne 747
                angdif = getangle(ps->pos.x-vm.g_sp->x, ps->pos.y-vm.g_sp->y);
5 Plagman 748
 
1204 terminx 749
                if (vm.g_x < 512)
5 Plagman 750
                {
2745 helixhorne 751
                    ps->vel.x = 0;
752
                    ps->vel.y = 0;
5 Plagman 753
                }
754
                else
755
                {
2745 helixhorne 756
                    ps->vel.x = mulscale16(ps->vel.x, ps->runspeed-0x2000);
757
                    ps->vel.y = mulscale16(ps->vel.y, ps->runspeed-0x2000);
5 Plagman 758
                }
759
            }
1204 terminx 760
            else if (vm.g_sp->picnum != DRONE && vm.g_sp->picnum != SHARK && vm.g_sp->picnum != COMMANDER)
5 Plagman 761
            {
3102 terminx 762
                if (ps->actorsqu == vm.g_i) return;
763
 
764
                if (!A_CheckSpriteFlags(vm.g_i, SPRITE_SMOOTHMOVE))
5 Plagman 765
                {
3102 terminx 766
                    if (vm.g_t[0]&1) return;
767
                    daxvel <<= 1;
5 Plagman 768
                }
769
            }
770
        }
771
 
1207 terminx 772
        {
1677 terminx 773
            vec3_t tmpvect = { (daxvel*(sintable[(angdif+512)&2047]))>>14,
774
                               (daxvel*(sintable[angdif&2047]))>>14, vm.g_sp->zvel
775
                             };
1207 terminx 776
 
2184 helixhorne 777
            actor[vm.g_i].movflag = A_MoveSprite(
778
                vm.g_i,&tmpvect, (A_CheckSpriteFlags(vm.g_i, SPRITE_NOCLIP) ? 0 : CLIPMASK0));
1207 terminx 779
        }
5 Plagman 780
    }
781
 
2745 helixhorne 782
    if (!a)
783
        return;
5 Plagman 784
 
1673 terminx 785
    if (sector[vm.g_sp->sectnum].ceilingstat&1)
786
        vm.g_sp->shade += (sector[vm.g_sp->sectnum].ceilingshade-vm.g_sp->shade)>>1;
787
    else vm.g_sp->shade += (sector[vm.g_sp->sectnum].floorshade-vm.g_sp->shade)>>1;
5 Plagman 788
}
789
 
3520 helixhorne 790
static void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap)
2873 helixhorne 791
{
2975 hendricks2 792
    if ((ps->weaponswitch & 1) && (ps->weaponswitch & 4))
793
    {
794
        int32_t snum = sprite[ps->i].yvel;
795
        int32_t i, w, new_wchoice = -1, curr_wchoice = -1;
796
 
797
        for (i=0; i<10 && (new_wchoice < 0 || curr_wchoice < 0); i++)
798
        {
799
            w = g_player[snum].wchoice[i];
800
 
801
            if (w == 0) w = 9;
802
            else w--;
803
 
804
            if (w == ps->curr_weapon)
805
                curr_wchoice = i;
806
            if (w == weap)
807
                new_wchoice = i;
808
        }
809
 
810
        if (new_wchoice < curr_wchoice)
811
            P_AddWeapon(ps, weap);
812
        else
813
            P_AddWeaponNoSwitch(ps, weap);
814
    }
815
    else if (ps->weaponswitch & 1)
816
        P_AddWeapon(ps, weap);
817
    else
2873 helixhorne 818
        P_AddWeaponNoSwitch(ps, weap);
819
}
820
 
3520 helixhorne 821
#if defined LUNATIC
822
void P_AddWeaponMaybeSwitchI(int32_t snum, int32_t weap)
823
{
824
    P_AddWeaponMaybeSwitch(g_player[snum].ps, weap);
825
}
826
#else
3249 helixhorne 827
static void P_AddWeaponAmmoCommon(DukePlayer_t *ps, int32_t weap, int32_t amount)
2873 helixhorne 828
{
829
    P_AddAmmo(weap, ps, amount);
830
 
831
    if (ps->curr_weapon == KNEE_WEAPON && (ps->gotweapon & (1 << weap)))
3249 helixhorne 832
        P_AddWeaponMaybeSwitch(ps, weap);
2873 helixhorne 833
}
834
 
835
static int32_t VM_AddWeapon(int32_t weap, int32_t amount, DukePlayer_t *ps)
836
{
837
    if ((unsigned)weap >= MAX_WEAPONS)
838
    {
3000 helixhorne 839
        CON_ERRPRINTF("Invalid weapon ID %d\n", weap);
2873 helixhorne 840
        return 1;
841
    }
842
 
843
    if ((ps->gotweapon & (1 << weap)) == 0)
844
    {
3249 helixhorne 845
        P_AddWeaponMaybeSwitch(ps, weap);
2873 helixhorne 846
    }
847
    else if (ps->ammo_amount[weap] >= ps->max_ammo_amount[weap])
848
    {
849
        vm.g_flags |= VM_NOEXECUTE;
850
        return 2;
851
    }
852
 
3249 helixhorne 853
    P_AddWeaponAmmoCommon(ps, weap, amount);
2873 helixhorne 854
 
855
    return 0;
856
}
3354 helixhorne 857
#endif
2873 helixhorne 858
 
3460 helixhorne 859
static void VM_Fall(int32_t g_i, spritetype *g_sp)
3252 helixhorne 860
{
3684 helixhorne 861
    int32_t grav = g_spriteGravity;
862
 
3460 helixhorne 863
    g_sp->xoffset = g_sp->yoffset = 0;
3252 helixhorne 864
 
3684 helixhorne 865
    if (G_CheckForSpaceCeiling(g_sp->sectnum) || sector[g_sp->sectnum].lotag == ST_2_UNDERWATER)
866
        grav = g_spriteGravity/6;
867
    else if (G_CheckForSpaceFloor(g_sp->sectnum))
868
        grav = 0;
869
 
870
    if (!actor[g_i].cgg-- || (sector[g_sp->sectnum].floorstat&2))
3252 helixhorne 871
    {
3684 helixhorne 872
        A_GetZLimits(g_i);
873
        actor[g_i].cgg = 3;
874
    }
3252 helixhorne 875
 
3684 helixhorne 876
    if (g_sp->z < actor[g_i].floorz-ZOFFSET)
877
    {
878
        // Free fall.
879
        g_sp->zvel = min(g_sp->zvel+grav, ACTOR_MAXFALLINGZVEL);
880
        g_sp->z += g_sp->zvel;
3252 helixhorne 881
#ifdef YAX_ENABLE
3684 helixhorne 882
        if (yax_getbunch(g_sp->sectnum, YAX_FLOOR) >= 0 &&
883
                (sector[g_sp->sectnum].floorstat&512)==0)
884
            setspritez(g_i, (vec3_t *)g_sp);
885
        else
3252 helixhorne 886
#endif
3684 helixhorne 887
            if (g_sp->z > actor[g_i].floorz - ZOFFSET)
888
                g_sp->z = actor[g_i].floorz - ZOFFSET;
889
        return;
890
    }
3679 helixhorne 891
 
3684 helixhorne 892
    // SET_SPRITE_Z
893
    g_sp->z = actor[g_i].floorz - ZOFFSET;
3252 helixhorne 894
 
3684 helixhorne 895
    if (A_CheckEnemySprite(g_sp) || (g_sp->picnum == APLAYER && g_sp->owner >= 0))
896
    {
897
        if (g_sp->zvel > 3084 && g_sp->extra <= 1)
3252 helixhorne 898
        {
3684 helixhorne 899
            // I'm guessing this DRONE check is from a beta version of the game
900
            // where they crashed into the ground when killed
901
            if (!(g_sp->picnum == APLAYER && g_sp->extra > 0) && g_sp->pal != 1 && g_sp->picnum != DRONE)
3252 helixhorne 902
            {
3684 helixhorne 903
                A_DoGuts(g_i,JIBS6,15);
904
                A_PlaySound(SQUISHED,g_i);
905
                A_Spawn(g_i,BLOODPOOL);
3252 helixhorne 906
            }
3679 helixhorne 907
 
3684 helixhorne 908
            actor[g_i].picnum = SHOTSPARK1;
909
            actor[g_i].extra = 1;
910
            g_sp->zvel = 0;
911
        }
912
        else if (g_sp->zvel > 2048 && sector[g_sp->sectnum].lotag != ST_1_ABOVE_WATER)
913
        {
914
            int16_t newsect = g_sp->sectnum;
3679 helixhorne 915
 
3684 helixhorne 916
            pushmove((vec3_t *)g_sp, &newsect, 128, 4<<8, 4<<8, CLIPMASK0);
917
            if ((unsigned)newsect < MAXSECTORS)
918
                changespritesect(g_i, newsect);
919
 
920
            A_PlaySound(THUD, g_i);
3252 helixhorne 921
        }
922
    }
923
 
3684 helixhorne 924
#if 0
925
    if (g_sp->z > actor[g_i].floorz - ZOFFSET)
3252 helixhorne 926
    {
3684 helixhorne 927
        // Unreachable because of SET_SPRITE_Z.
3460 helixhorne 928
        A_GetZLimits(g_i);
929
        if (actor[g_i].floorz != sector[g_sp->sectnum].floorz)
930
            g_sp->z = (actor[g_i].floorz - ZOFFSET);
3252 helixhorne 931
        return;
932
    }
3684 helixhorne 933
#endif
934
 
935
    if (sector[g_sp->sectnum].lotag == ST_1_ABOVE_WATER)
3252 helixhorne 936
    {
3460 helixhorne 937
        switch (DYNAMICTILEMAP(g_sp->picnum))
3252 helixhorne 938
        {
3679 helixhorne 939
        case OCTABRAIN__STATIC:
940
        case COMMANDER__STATIC:
941
        case DRONE__STATIC:
942
            break;
943
 
3252 helixhorne 944
        default:
945
        {
3459 helixhorne 946
#if !defined LUNATIC
3252 helixhorne 947
            int32_t moveScriptOfs = vm.g_t[1];
948
#endif
3679 helixhorne 949
            // fix for flying/jumping monsters getting stuck in water
3460 helixhorne 950
            if ((g_sp->hitag & jumptoplayer) ||
951
                (G_HaveActor(g_sp->picnum) &&
3459 helixhorne 952
#if !defined LUNATIC
3252 helixhorne 953
                 (unsigned)moveScriptOfs < (unsigned)g_scriptSize-1 && script[moveScriptOfs + 1]
954
#else
3460 helixhorne 955
                 actor[g_i].mv.vvel != 0
3252 helixhorne 956
#endif
957
                    ))
958
            {
959
//                OSD_Printf("%d\n", script[moveScriptOfs + 1]);
960
                break;
961
            }
962
 
3679 helixhorne 963
//            OSD_Printf("hitag: %d\n",g_sp->hitag);
964
            g_sp->z += ACTOR_ONWATER_ADDZ;
3252 helixhorne 965
            break;
966
        }
3679 helixhorne 967
        }
968
 
3252 helixhorne 969
        return;
970
    }
3459 helixhorne 971
 
3460 helixhorne 972
    g_sp->zvel = 0;
3252 helixhorne 973
}
974
 
3460 helixhorne 975
static int32_t VM_ResetPlayer(int32_t g_p, int32_t g_flags)
3252 helixhorne 976
{
977
    //AddLog("resetplayer");
3460 helixhorne 978
    if (!g_netServer && ud.multimode < 2)
3252 helixhorne 979
    {
980
        if (g_lastSaveSlot >= 0 && ud.recstat != 2)
981
        {
3460 helixhorne 982
            g_player[g_p].ps->gm |= MODE_MENU;
3252 helixhorne 983
            KB_ClearKeyDown(sc_Space);
984
            M_ChangeMenu(15000);
985
        }
3460 helixhorne 986
        else g_player[g_p].ps->gm = MODE_RESTART;
987
 
988
        g_flags |= VM_NOEXECUTE;
3252 helixhorne 989
    }
990
    else
991
    {
3460 helixhorne 992
        if (g_p == myconnectindex)
3252 helixhorne 993
        {
3405 helixhorne 994
            CAMERADIST = 0;
995
            CAMERACLOCK = totalclock;
3252 helixhorne 996
        }
997
 
998
        if (g_fakeMultiMode)
3460 helixhorne 999
            P_ResetPlayer(g_p);
3260 helixhorne 1000
#ifndef NETCODE_DISABLE
3252 helixhorne 1001
        if (g_netServer)
1002
        {
1003
            int32_t jj = 0;
1004
 
3460 helixhorne 1005
            P_ResetPlayer(g_p);
3252 helixhorne 1006
 
1007
            packbuf[jj++] = PACKET_PLAYER_SPAWN;
3460 helixhorne 1008
            packbuf[jj++] = g_p;
3252 helixhorne 1009
 
3460 helixhorne 1010
            Bmemcpy(&packbuf[jj], &g_player[g_p].ps->pos.x, sizeof(vec3_t) * 2);
3252 helixhorne 1011
            jj += sizeof(vec3_t) * 2;
1012
 
1013
            packbuf[jj++] = 0;
1014
 
1015
            enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(
1016
                                    packbuf, jj, ENET_PACKET_FLAG_RELIABLE));
1017
        }
3260 helixhorne 1018
#endif
3252 helixhorne 1019
    }
3460 helixhorne 1020
 
1021
    P_UpdateScreenPal(g_player[g_p].ps);
3252 helixhorne 1022
    //AddLog("EOF: resetplayer");
3460 helixhorne 1023
 
1024
    return g_flags;
3252 helixhorne 1025
}
1026
 
3486 helixhorne 1027
void G_GetTimeDate(int32_t *vals)
1028
{
1029
    time_t rawtime;
1030
    struct tm *ti;
1031
 
1032
    time(&rawtime);
1033
    ti=localtime(&rawtime);
1034
    // initprintf("Time&date: %s\n",asctime (ti));
1035
 
1036
    vals[0] = ti->tm_sec;
1037
    vals[1] = ti->tm_min;
1038
    vals[2] = ti->tm_hour;
1039
    vals[3] = ti->tm_mday;
1040
    vals[4] = ti->tm_mon;
1041
    vals[5] = ti->tm_year+1900;
1042
    vals[6] = ti->tm_wday;
1043
    vals[7] = ti->tm_yday;
1044
}
1045
 
3490 helixhorne 1046
int32_t G_StartTrack(int32_t level)
1047
{
1048
    if ((unsigned)level < MAXLEVELS)
1049
    {
1050
        int32_t musicIndex = MAXLEVELS*ud.volume_number + level;
1051
 
3542 helixhorne 1052
        if (MapInfo[musicIndex].musicfn != NULL)
3490 helixhorne 1053
        {
3542 helixhorne 1054
            // Only set g_musicIndex on success.
3490 helixhorne 1055
            g_musicIndex = musicIndex;
3542 helixhorne 1056
            S_PlayMusic(MapInfo[musicIndex].musicfn, g_musicIndex);
3490 helixhorne 1057
 
1058
            return 0;
1059
        }
1060
    }
1061
 
1062
    return 1;
1063
}
1064
 
3410 helixhorne 1065
#if !defined LUNATIC
1909 terminx 1066
GAMEEXEC_STATIC void VM_Execute(int32_t loop)
5 Plagman 1067
{
1458 terminx 1068
    register int32_t tw = *insptr;
5 Plagman 1069
 
1458 terminx 1070
    // jump directly into the loop, saving us from the checks during the first iteration
1071
    goto skip_check;
1072
 
1909 terminx 1073
    while (loop)
1436 terminx 1074
    {
1625 terminx 1075
        if (vm.g_flags & (VM_RETURN|VM_KILL|VM_NOEXECUTE))
1909 terminx 1076
            return;
1458 terminx 1077
 
1436 terminx 1078
        tw = *insptr;
5 Plagman 1079
 
1458 terminx 1080
skip_check:
1436 terminx 1081
        //      Bsprintf(g_szBuf,"Parsing: %d",*insptr);
1082
        //      AddLog(g_szBuf);
871 hnt_ts 1083
 
1436 terminx 1084
        g_errorLineNum = tw>>12;
1085
        g_tw = tw &= 0xFFF;
1086
 
1087
        switch (tw)
430 terminx 1088
        {
1436 terminx 1089
        case CON_REDEFINEQUOTE:
1090
            insptr++;
484 terminx 1091
            {
1436 terminx 1092
                int32_t q = *insptr++, i = *insptr++;
1625 terminx 1093
                if ((ScriptQuotes[q] == NULL || ScriptQuoteRedefinitions[i] == NULL))
1436 terminx 1094
                {
3000 helixhorne 1095
                    CON_ERRPRINTF("%d %d null quote\n", q,i);
1436 terminx 1096
                    break;
1097
                }
1098
                Bstrcpy(ScriptQuotes[q],ScriptQuoteRedefinitions[i]);
1458 terminx 1099
                continue;
484 terminx 1100
            }
49 terminx 1101
 
1436 terminx 1102
        case CON_GETTHISPROJECTILE:
1103
        case CON_SETTHISPROJECTILE:
1104
            insptr++;
5 Plagman 1105
            {
1436 terminx 1106
                // syntax [gs]etplayer[<var>].x <VAR>
1107
                // <varid> <xxxid> <varid>
1108
                int32_t lVar1=*insptr++, lLabelID=*insptr++, lVar2=*insptr++;
5 Plagman 1109
 
1625 terminx 1110
                VM_AccessActiveProjectile(tw==CON_SETTHISPROJECTILE,lVar1,lLabelID,lVar2);
1458 terminx 1111
                continue;
337 terminx 1112
            }
1436 terminx 1113
 
1114
        case CON_IFRND:
1909 terminx 1115
            VM_CONDITIONAL(rnd(*(++insptr)));
1458 terminx 1116
            continue;
1436 terminx 1117
 
1118
        case CON_IFCANSHOOTTARGET:
1440 terminx 1119
        {
1120
            int32_t j;
1909 terminx 1121
 
1440 terminx 1122
            if (vm.g_x > 1024)
337 terminx 1123
            {
1909 terminx 1124
                int16_t temphit;
1436 terminx 1125
 
1909 terminx 1126
                if ((j = A_CheckHitSprite(vm.g_i,&temphit)) == (1<<30))
1440 terminx 1127
                {
1909 terminx 1128
                    VM_CONDITIONAL(1);
1129
                    continue;
1440 terminx 1130
                }
1436 terminx 1131
 
1440 terminx 1132
                {
1909 terminx 1133
                    int32_t sclip = 768, angdif = 16;
1134
 
1135
                    if (A_CheckEnemySprite(vm.g_sp) && vm.g_sp->xrepeat > 56)
1436 terminx 1136
                    {
1909 terminx 1137
                        sclip = 3084;
1138
                        angdif = 48;
1139
                    }
1140
 
1141
                    if (j > sclip)
1142
                    {
1143
                        if (temphit >= 0 && sprite[temphit].picnum == vm.g_sp->picnum)
1144
                        {
1145
                            VM_CONDITIONAL(0);
1146
                            continue;
1147
                        }
1148
 
1440 terminx 1149
                        vm.g_sp->ang += angdif;
1150
                        j = A_CheckHitSprite(vm.g_i,&temphit);
1151
                        vm.g_sp->ang -= angdif;
1909 terminx 1152
 
1440 terminx 1153
                        if (j > sclip)
5 Plagman 1154
                        {
1440 terminx 1155
                            if (temphit >= 0 && sprite[temphit].picnum == vm.g_sp->picnum)
5 Plagman 1156
                            {
1909 terminx 1157
                                VM_CONDITIONAL(0);
1158
                                continue;
1159
                            }
1160
 
1161
                            vm.g_sp->ang -= angdif;
1162
                            j = A_CheckHitSprite(vm.g_i,&temphit);
1163
                            vm.g_sp->ang += angdif;
1164
 
1165
                            if (j > 768)
1166
                            {
1167
                                if (temphit >= 0 && sprite[temphit].picnum == vm.g_sp->picnum)
1436 terminx 1168
                                {
1909 terminx 1169
                                    VM_CONDITIONAL(0);
1170
                                    continue;
1436 terminx 1171
                                }
1909 terminx 1172
 
1173
                                VM_CONDITIONAL(1);
1174
                                continue;
5 Plagman 1175
                            }
1176
                        }
1177
                    }
1178
                }
1179
            }
1909 terminx 1180
            VM_CONDITIONAL(1);
1440 terminx 1181
        }
1458 terminx 1182
        continue;
1440 terminx 1183
 
1436 terminx 1184
        case CON_IFCANSEETARGET:
1440 terminx 1185
        {
2875 helixhorne 1186
            DukePlayer_t *const ps = g_player[vm.g_p].ps;
1187
            int32_t j = cansee(vm.g_sp->x, vm.g_sp->y, vm.g_sp->z-((krand()&41)<<8),
1188
                               vm.g_sp->sectnum, ps->pos.x, ps->pos.y,
1189
                               ps->pos.z/*-((krand()&41)<<8)*/, sprite[ps->i].sectnum);
1909 terminx 1190
            VM_CONDITIONAL(j);
1625 terminx 1191
            if (j) actor[vm.g_i].timetosleep = SLEEPTIME;
1440 terminx 1192
        }
1458 terminx 1193
        continue;
51 terminx 1194
 
1436 terminx 1195
        case CON_IFACTORNOTSTAYPUT:
1909 terminx 1196
            VM_CONDITIONAL(actor[vm.g_i].actorstayput == -1);
1458 terminx 1197
            continue;
5 Plagman 1198
 
1436 terminx 1199
        case CON_IFCANSEE:
1440 terminx 1200
        {
2875 helixhorne 1201
            DukePlayer_t *const ps = g_player[vm.g_p].ps;
1202
            spritetype *s = &sprite[ps->i];
1440 terminx 1203
            int32_t j;
1204
 
1205
            // select sprite for monster to target
1206
            // if holoduke is on, let them target holoduke first.
1207
            //
2875 helixhorne 1208
            if (ps->holoduke_on >= 0)
1436 terminx 1209
            {
2875 helixhorne 1210
                s = &sprite[ps->holoduke_on];
1440 terminx 1211
                j = cansee(vm.g_sp->x,vm.g_sp->y,vm.g_sp->z-(krand()&((32<<8)-1)),vm.g_sp->sectnum,
1212
                           s->x,s->y,s->z,s->sectnum);
51 terminx 1213
 
1440 terminx 1214
                if (j == 0)
1436 terminx 1215
                {
1440 terminx 1216
                    // they can't see player's holoduke
1217
                    // check for player...
2875 helixhorne 1218
                    s = &sprite[ps->i];
1436 terminx 1219
                }
1440 terminx 1220
            }
5 Plagman 1221
 
1440 terminx 1222
            // can they see player, (or player's holoduke)
1223
            j = cansee(vm.g_sp->x,vm.g_sp->y,vm.g_sp->z-(krand()&((47<<8))),vm.g_sp->sectnum,
1224
                       s->x,s->y,s->z-(24<<8),s->sectnum);
5 Plagman 1225
 
1440 terminx 1226
            if (j == 0)
1227
            {
1625 terminx 1228
                // search around for target player
5 Plagman 1229
 
1625 terminx 1230
                // also modifies 'target' x&y if found..
337 terminx 1231
 
1625 terminx 1232
                j = 1;
1233
                if (A_FurthestVisiblePoint(vm.g_i,s,&actor[vm.g_i].lastvx,&actor[vm.g_i].lastvy) == -1)
1234
                    j = 0;
1440 terminx 1235
            }
1236
            else
1237
            {
1238
                // else, they did see it.
1239
                // save where we were looking...
1625 terminx 1240
                actor[vm.g_i].lastvx = s->x;
1241
                actor[vm.g_i].lastvy = s->y;
1440 terminx 1242
            }
5 Plagman 1243
 
1487 terminx 1244
            if (j && (vm.g_sp->statnum == STAT_ACTOR || vm.g_sp->statnum == STAT_STANDABLE))
1625 terminx 1245
                actor[vm.g_i].timetosleep = SLEEPTIME;
1436 terminx 1246
 
1909 terminx 1247
            VM_CONDITIONAL(j);
1458 terminx 1248
            continue;
1440 terminx 1249
        }
335 terminx 1250
 
1436 terminx 1251
        case CON_IFHITWEAPON:
1909 terminx 1252
            VM_CONDITIONAL(A_IncurDamage(vm.g_i) >= 0);
1458 terminx 1253
            continue;
335 terminx 1254
 
1436 terminx 1255
        case CON_IFSQUISHED:
1909 terminx 1256
            VM_CONDITIONAL(VM_CheckSquished());
1458 terminx 1257
            continue;
335 terminx 1258
 
1436 terminx 1259
        case CON_IFDEAD:
1260
            //        j = vm.g_sp->extra;
1261
            //        if (vm.g_sp->picnum == APLAYER)
1262
            //            j--;
1909 terminx 1263
            VM_CONDITIONAL(vm.g_sp->extra <= 0);
1458 terminx 1264
            continue;
335 terminx 1265
 
1436 terminx 1266
        case CON_AI:
1267
            insptr++;
1268
            //Following changed to use pointersizes
1269
            vm.g_t[5] = *insptr++; // Ai
2451 helixhorne 1270
 
2185 helixhorne 1271
            vm.g_t[4] = *(script + vm.g_t[5]);  // Action
3456 helixhorne 1272
 
2869 helixhorne 1273
            // NOTE: "if (g_t[5])" added in r1155. It used to be a pointer though.
2724 helixhorne 1274
            if (vm.g_t[5])
1275
            {
1276
                vm.g_t[1] = *(script + vm.g_t[5] + 1);  // move
1277
            }
2185 helixhorne 1278
            vm.g_sp->hitag = *(script + vm.g_t[5] + 2);  // move flags
2451 helixhorne 1279
 
1540 terminx 1280
            vm.g_t[0] = vm.g_t[2] = vm.g_t[3] = 0; // count, actioncount... vm.g_t[3] = ??
2709 helixhorne 1281
            if (!A_CheckEnemySprite(vm.g_sp) || vm.g_sp->extra > 0) // hack
1282
                if (vm.g_sp->hitag&random_angle)
1283
                    vm.g_sp->ang = krand()&2047;
1458 terminx 1284
            continue;
5 Plagman 1285
 
1436 terminx 1286
        case CON_ACTION:
1287
            insptr++;
1288
            vm.g_t[2] = vm.g_t[3] = 0;
1289
            vm.g_t[4] = *insptr++;
1458 terminx 1290
            continue;
5 Plagman 1291
 
3803 terminx 1292
        case CON_IFPLAYERSL:
1293
            VM_CONDITIONAL(numplayers < *(++insptr));
1294
            continue;
1295
 
1436 terminx 1296
        case CON_IFPDISTL:
1909 terminx 1297
            VM_CONDITIONAL(vm.g_x < *(++insptr));
1625 terminx 1298
            if (vm.g_x > MAXSLEEPDIST && actor[vm.g_i].timetosleep == 0)
1299
                actor[vm.g_i].timetosleep = SLEEPTIME;
1458 terminx 1300
            continue;
5 Plagman 1301
 
1436 terminx 1302
        case CON_IFPDISTG:
1909 terminx 1303
            VM_CONDITIONAL(vm.g_x > *(++insptr));
1625 terminx 1304
            if (vm.g_x > MAXSLEEPDIST && actor[vm.g_i].timetosleep == 0)
1305
                actor[vm.g_i].timetosleep = SLEEPTIME;
1458 terminx 1306
            continue;
51 terminx 1307
 
1436 terminx 1308
        case CON_ELSE:
1309
            insptr = (intptr_t *) *(insptr+1);
1458 terminx 1310
            continue;
51 terminx 1311
 
1436 terminx 1312
        case CON_ADDSTRENGTH:
1313
            insptr++;
1314
            vm.g_sp->extra += *insptr++;
1458 terminx 1315
            continue;
51 terminx 1316
 
1436 terminx 1317
        case CON_STRENGTH:
1318
            insptr++;
1319
            vm.g_sp->extra = *insptr++;
1458 terminx 1320
            continue;
51 terminx 1321
 
1436 terminx 1322
        case CON_IFGOTWEAPONCE:
1323
            insptr++;
5 Plagman 1324
 
1587 terminx 1325
            if ((GametypeFlags[ud.coop]&GAMETYPE_WEAPSTAY) && (g_netServer || ud.multimode > 1))
5 Plagman 1326
            {
2875 helixhorne 1327
                DukePlayer_t *const ps = g_player[vm.g_p].ps;
1328
 
1436 terminx 1329
                if (*insptr == 0)
1330
                {
1331
                    int32_t j = 0;
2875 helixhorne 1332
                    for (; j < ps->weapreccnt; j++)
1333
                        if (ps->weaprecs[j] == vm.g_sp->picnum)
1436 terminx 1334
                            break;
5 Plagman 1335
 
2875 helixhorne 1336
                    VM_CONDITIONAL(j < ps->weapreccnt && vm.g_sp->owner == vm.g_i);
1625 terminx 1337
                    continue;
1436 terminx 1338
                }
2875 helixhorne 1339
                else if (ps->weapreccnt < MAX_WEAPONS)
1436 terminx 1340
                {
2875 helixhorne 1341
                    ps->weaprecs[ps->weapreccnt++] = vm.g_sp->picnum;
1909 terminx 1342
                    VM_CONDITIONAL(vm.g_sp->owner == vm.g_i);
1625 terminx 1343
                    continue;
1436 terminx 1344
                }
5 Plagman 1345
            }
1909 terminx 1346
            VM_CONDITIONAL(0);
1458 terminx 1347
            continue;
1436 terminx 1348
 
1349
        case CON_GETLASTPAL:
1350
            insptr++;
1351
            if (vm.g_sp->picnum == APLAYER)
1352
                vm.g_sp->pal = g_player[vm.g_sp->yvel].ps->palookup;
1353
            else
337 terminx 1354
            {
1436 terminx 1355
                if (vm.g_sp->pal == 1 && vm.g_sp->extra == 0) // hack for frozen
1356
                    vm.g_sp->extra++;
1625 terminx 1357
                vm.g_sp->pal = actor[vm.g_i].tempang;
337 terminx 1358
            }
1625 terminx 1359
            actor[vm.g_i].tempang = 0;
1458 terminx 1360
            continue;
51 terminx 1361
 
1436 terminx 1362
        case CON_TOSSWEAPON:
1363
            insptr++;
1364
            P_DropWeapon(g_player[vm.g_sp->yvel].ps);
1458 terminx 1365
            continue;
51 terminx 1366
 
1436 terminx 1367
        case CON_NULLOP:
1368
            insptr++;
1458 terminx 1369
            continue;
51 terminx 1370
 
1436 terminx 1371
        case CON_MIKESND:
1837 terminx 1372
            insptr++;
1373
            if (((unsigned)vm.g_sp->yvel >= MAXSOUNDS))
1436 terminx 1374
            {
3238 hendricks2 1375
                CON_ERRPRINTF("Invalid sound %d\n", TrackerCast(vm.g_sp->yvel));
1436 terminx 1376
                insptr++;
1458 terminx 1377
                continue;
1436 terminx 1378
            }
1461 terminx 1379
            if (!S_CheckSoundPlaying(vm.g_i,vm.g_sp->yvel))
1436 terminx 1380
                A_PlaySound(vm.g_sp->yvel,vm.g_i);
1458 terminx 1381
            continue;
51 terminx 1382
 
1436 terminx 1383
        case CON_PKICK:
951 hnt_ts 1384
            insptr++;
1436 terminx 1385
 
1587 terminx 1386
            if ((g_netServer || ud.multimode > 1) && vm.g_sp->picnum == APLAYER)
1436 terminx 1387
            {
1388
                if (g_player[otherp].ps->quick_kick == 0)
1389
                    g_player[otherp].ps->quick_kick = 14;
1390
            }
1391
            else if (vm.g_sp->picnum != APLAYER && g_player[vm.g_p].ps->quick_kick == 0)
1392
                g_player[vm.g_p].ps->quick_kick = 14;
1458 terminx 1393
            continue;
51 terminx 1394
 
1436 terminx 1395
        case CON_SIZETO:
1396
            insptr++;
5 Plagman 1397
 
1436 terminx 1398
            {
1625 terminx 1399
                int32_t j = (*insptr++ - vm.g_sp->xrepeat)<<1;
1436 terminx 1400
                vm.g_sp->xrepeat += ksgn(j);
51 terminx 1401
 
1677 terminx 1402
                if ((vm.g_sp->picnum == APLAYER && vm.g_sp->yrepeat < 36) || *insptr < vm.g_sp->yrepeat ||
1403
                        ((vm.g_sp->yrepeat*(tilesizy[vm.g_sp->picnum]+8))<<2) < (actor[vm.g_i].floorz - actor[vm.g_i].ceilingz))
1436 terminx 1404
                {
1405
                    j = ((*insptr)-vm.g_sp->yrepeat)<<1;
1406
                    if (klabs(j)) vm.g_sp->yrepeat += ksgn(j);
1407
                }
1408
            }
1409
            insptr++;
5 Plagman 1410
 
1458 terminx 1411
            continue;
5 Plagman 1412
 
1436 terminx 1413
        case CON_SIZEAT:
1414
            insptr++;
1415
            vm.g_sp->xrepeat = (uint8_t) *insptr++;
1416
            vm.g_sp->yrepeat = (uint8_t) *insptr++;
1458 terminx 1417
            continue;
1436 terminx 1418
 
1419
        case CON_SHOOT:
1420
            insptr++;
1421
            A_Shoot(vm.g_i,*insptr++);
1458 terminx 1422
            continue;
1436 terminx 1423
 
1424
        case CON_SOUNDONCE:
1820 terminx 1425
            if (((unsigned)*(++insptr) >= MAXSOUNDS))
1215 terminx 1426
            {
3000 helixhorne 1427
                CON_ERRPRINTF("Invalid sound %d\n", (int32_t)*insptr++);
1458 terminx 1428
                continue;
1215 terminx 1429
            }
1461 terminx 1430
            if (!S_CheckSoundPlaying(vm.g_i,*insptr++))
1436 terminx 1431
                A_PlaySound(*(insptr-1),vm.g_i);
1458 terminx 1432
            continue;
62 terminx 1433
 
1461 terminx 1434
        case CON_IFACTORSOUND:
1435
            insptr++;
1436
            {
1437
                int32_t i = Gv_GetVarX(*insptr++), j = Gv_GetVarX(*insptr++);
1438
 
1820 terminx 1439
                if (((unsigned)j >= MAXSOUNDS))
1461 terminx 1440
                {
3000 helixhorne 1441
                    CON_ERRPRINTF("Invalid sound %d\n", j);
1461 terminx 1442
                    insptr++;
1443
                    continue;
1444
                }
1445
                insptr--;
1909 terminx 1446
                VM_CONDITIONAL(A_CheckSoundPlaying(i,j));
1461 terminx 1447
            }
1448
            continue;
1449
 
1436 terminx 1450
        case CON_IFSOUND:
1820 terminx 1451
            if (((unsigned)*(++insptr) >= MAXSOUNDS))
1436 terminx 1452
            {
3000 helixhorne 1453
                CON_ERRPRINTF("Invalid sound %d\n", (int32_t)*insptr);
1436 terminx 1454
                insptr++;
1458 terminx 1455
                continue;
1436 terminx 1456
            }
1909 terminx 1457
            VM_CONDITIONAL(S_CheckSoundPlaying(vm.g_i,*insptr));
2442 helixhorne 1458
            //    VM_DoConditional(SoundOwner[*insptr][0].ow == vm.g_i);
1458 terminx 1459
            continue;
51 terminx 1460
 
1436 terminx 1461
        case CON_STOPSOUND:
1820 terminx 1462
            if (((unsigned)*(++insptr) >= MAXSOUNDS))
1436 terminx 1463
            {
3000 helixhorne 1464
                CON_ERRPRINTF("Invalid sound %d\n", (int32_t)*insptr);
1458 terminx 1465
                insptr++;
1466
                continue;
1436 terminx 1467
            }
1461 terminx 1468
            if (S_CheckSoundPlaying(vm.g_i,*insptr))
1465 terminx 1469
                S_StopSound((int16_t)*insptr);
1436 terminx 1470
            insptr++;
1458 terminx 1471
            continue;
51 terminx 1472
 
1461 terminx 1473
        case CON_STOPACTORSOUND:
1474
            insptr++;
1475
            {
1476
                int32_t i = Gv_GetVarX(*insptr++), j = Gv_GetVarX(*insptr++);
1477
 
1625 terminx 1478
                if ((j<0 || j>=MAXSOUNDS))
1461 terminx 1479
                {
3000 helixhorne 1480
                    CON_ERRPRINTF("Invalid sound %d\n", j);
1461 terminx 1481
                    continue;
1482
                }
1483
 
1484
                if (A_CheckSoundPlaying(i,j))
1485
                    S_StopEnvSound(j,i);
1486
 
1487
                continue;
1488
            }
1489
 
2104 helixhorne 1490
        case CON_SETACTORSOUNDPITCH:
1491
            insptr++;
1492
            {
1493
                int32_t i = Gv_GetVarX(*insptr++), j = Gv_GetVarX(*insptr++), pitchoffset = Gv_GetVarX(*insptr++);
1494
 
1495
                if ((j<0 || j>=MAXSOUNDS))
1496
                {
3000 helixhorne 1497
                    CON_ERRPRINTF("Invalid sound %d\n", j);
2104 helixhorne 1498
                    continue;
1499
                }
1500
 
1501
                S_ChangeSoundPitch(j,i,pitchoffset);
1502
 
1503
                continue;
1504
            }
1505
 
1436 terminx 1506
        case CON_GLOBALSOUND:
1820 terminx 1507
            if (((unsigned)*(++insptr) >= MAXSOUNDS))
1436 terminx 1508
            {
3000 helixhorne 1509
                CON_ERRPRINTF("Invalid sound %d\n", (int32_t)*insptr);
1458 terminx 1510
                insptr++;
1511
                continue;
1436 terminx 1512
            }
2890 helixhorne 1513
            if (vm.g_p == screenpeek || (GametypeFlags[ud.coop]&GAMETYPE_COOPSOUND)
2957 helixhorne 1514
                || (g_fakeMultiMode==2)
2890 helixhorne 1515
                )
1461 terminx 1516
                A_PlaySound(*insptr,g_player[screenpeek].ps->i);
1436 terminx 1517
            insptr++;
1458 terminx 1518
            continue;
51 terminx 1519
 
1436 terminx 1520
        case CON_SOUND:
1820 terminx 1521
            if ((unsigned)*(++insptr) >= MAXSOUNDS)
1436 terminx 1522
            {
3000 helixhorne 1523
                CON_ERRPRINTF("Invalid sound %d\n", (int32_t)*insptr);
1458 terminx 1524
                insptr++;
1525
                continue;
1436 terminx 1526
            }
1461 terminx 1527
            A_PlaySound(*insptr++,vm.g_i);
1458 terminx 1528
            continue;
51 terminx 1529
 
1436 terminx 1530
        case CON_TIP:
1215 terminx 1531
            insptr++;
1436 terminx 1532
            g_player[vm.g_p].ps->tipincs = GAMETICSPERSEC;
1458 terminx 1533
            continue;
51 terminx 1534
 
1436 terminx 1535
        case CON_FALL:
1536
            insptr++;
3460 helixhorne 1537
            VM_Fall(vm.g_i, vm.g_sp);
1458 terminx 1538
            continue;
1021 terminx 1539
 
1436 terminx 1540
        case CON_RETURN:
1625 terminx 1541
            vm.g_flags |= VM_RETURN;
1436 terminx 1542
        case CON_ENDA:
1543
        case CON_BREAK:
1544
        case CON_ENDS:
1909 terminx 1545
            return;
1436 terminx 1546
        case CON_RIGHTBRACE:
1547
            insptr++;
1909 terminx 1548
            return;
2873 helixhorne 1549
 
1436 terminx 1550
        case CON_ADDAMMO:
2873 helixhorne 1551
            insptr++;
532 terminx 1552
            {
2873 helixhorne 1553
                int32_t weap=*insptr++, amount=*insptr++;
1554
                DukePlayer_t *ps = g_player[vm.g_p].ps;
1555
 
1556
                if ((unsigned)weap >= MAX_WEAPONS)
1557
                {
3000 helixhorne 1558
                    CON_ERRPRINTF("Invalid weapon ID %d\n", weap);
2873 helixhorne 1559
                    break;
1560
                }
1561
 
1562
                if (ps->ammo_amount[weap] >= ps->max_ammo_amount[weap])
1563
                {
1564
                    vm.g_flags |= VM_NOEXECUTE;
1565
                    break;
1566
                }
1567
 
3249 helixhorne 1568
                P_AddWeaponAmmoCommon(ps, weap, amount);
2873 helixhorne 1569
 
1570
                continue;
1436 terminx 1571
            }
337 terminx 1572
 
1436 terminx 1573
        case CON_MONEY:
1574
            insptr++;
1575
            A_SpawnMultiple(vm.g_i, MONEY, *insptr++);
1458 terminx 1576
            continue;
51 terminx 1577
 
1436 terminx 1578
        case CON_MAIL:
1579
            insptr++;
1580
            A_SpawnMultiple(vm.g_i, MAIL, *insptr++);
1458 terminx 1581
            continue;
51 terminx 1582
 
1436 terminx 1583
        case CON_SLEEPTIME:
1584
            insptr++;
1625 terminx 1585
            actor[vm.g_i].timetosleep = (int16_t)*insptr++;
1458 terminx 1586
            continue;
51 terminx 1587
 
1436 terminx 1588
        case CON_PAPER:
1589
            insptr++;
1590
            A_SpawnMultiple(vm.g_i, PAPER, *insptr++);
1458 terminx 1591
            continue;
51 terminx 1592
 
1436 terminx 1593
        case CON_ADDKILLS:
1594
            insptr++;
1595
            g_player[vm.g_p].ps->actors_killed += *insptr++;
1625 terminx 1596
            actor[vm.g_i].actorstayput = -1;
1458 terminx 1597
            continue;
51 terminx 1598
 
1436 terminx 1599
        case CON_LOTSOFGLASS:
1600
            insptr++;
1601
            A_SpawnGlass(vm.g_i,*insptr++);
1458 terminx 1602
            continue;
51 terminx 1603
 
1436 terminx 1604
        case CON_KILLIT:
1605
            insptr++;
1625 terminx 1606
            vm.g_flags |= VM_KILL;
1458 terminx 1607
            continue;
51 terminx 1608
 
1436 terminx 1609
        case CON_ADDWEAPON:
2873 helixhorne 1610
            insptr++;
1436 terminx 1611
            {
2873 helixhorne 1612
                int32_t weap=*insptr++, amount=*insptr++;
1613
                VM_AddWeapon(weap, amount, g_player[vm.g_p].ps);
1614
 
1458 terminx 1615
                continue;
1436 terminx 1616
            }
337 terminx 1617
 
1436 terminx 1618
        case CON_DEBUG:
1619
            insptr++;
2419 hendricks2 1620
            initprintf("%" PRIdPTR "\n",*insptr++);
1458 terminx 1621
            continue;
51 terminx 1622
 
1436 terminx 1623
        case CON_ENDOFGAME:
3803 terminx 1624
        case CON_ENDOFLEVEL:
1436 terminx 1625
            insptr++;
1626
            g_player[vm.g_p].ps->timebeforeexit = *insptr++;
1627
            g_player[vm.g_p].ps->customexitsound = -1;
1628
            ud.eog = 1;
1458 terminx 1629
            continue;
51 terminx 1630
 
1436 terminx 1631
        case CON_ADDPHEALTH:
1632
            insptr++;
51 terminx 1633
 
335 terminx 1634
            {
1436 terminx 1635
                int32_t j;
2875 helixhorne 1636
                DukePlayer_t *const ps = g_player[vm.g_p].ps;
1215 terminx 1637
 
2875 helixhorne 1638
                if (ps->newowner >= 0)
1639
                    G_ClearCameraView(ps);
1436 terminx 1640
 
2875 helixhorne 1641
                j = sprite[ps->i].extra;
5 Plagman 1642
 
1436 terminx 1643
                if (vm.g_sp->picnum != ATOMICHEALTH)
1215 terminx 1644
                {
2875 helixhorne 1645
                    if (j > ps->max_player_health && *insptr > 0)
1436 terminx 1646
                    {
1647
                        insptr++;
1458 terminx 1648
                        continue;
1436 terminx 1649
                    }
1650
                    else
1651
                    {
1652
                        if (j > 0)
1653
                            j += *insptr;
2875 helixhorne 1654
                        if (j > ps->max_player_health && *insptr > 0)
1655
                            j = ps->max_player_health;
1436 terminx 1656
                    }
1215 terminx 1657
                }
1658
                else
1659
                {
1660
                    if (j > 0)
1661
                        j += *insptr;
2875 helixhorne 1662
                    if (j > (ps->max_player_health<<1))
1663
                        j = (ps->max_player_health<<1);
1215 terminx 1664
                }
5 Plagman 1665
 
1436 terminx 1666
                if (j < 0) j = 0;
5 Plagman 1667
 
1436 terminx 1668
                if (ud.god == 0)
1215 terminx 1669
                {
1436 terminx 1670
                    if (*insptr > 0)
1671
                    {
2875 helixhorne 1672
                        if ((j - *insptr) < (ps->max_player_health>>2) &&
1673
                                j >= (ps->max_player_health>>2))
1674
                            A_PlaySound(DUKE_GOTHEALTHATLOW,ps->i);
5 Plagman 1675
 
2875 helixhorne 1676
                        ps->last_extra = j;
1436 terminx 1677
                    }
1678
 
2875 helixhorne 1679
                    sprite[ps->i].extra = j;
1215 terminx 1680
                }
5 Plagman 1681
            }
1682
 
1436 terminx 1683
            insptr++;
1458 terminx 1684
            continue;
51 terminx 1685
 
1436 terminx 1686
        case CON_STATE:
1440 terminx 1687
        {
1688
            intptr_t *tempscrptr=insptr+2;
5 Plagman 1689
 
1440 terminx 1690
            insptr = (intptr_t *) *(insptr+1);
1909 terminx 1691
            VM_Execute(1);
1440 terminx 1692
            insptr = tempscrptr;
1693
        }
1458 terminx 1694
        continue;
337 terminx 1695
 
1436 terminx 1696
        case CON_LEFTBRACE:
1697
            insptr++;
1909 terminx 1698
            VM_Execute(1);
1458 terminx 1699
            continue;
5 Plagman 1700
 
1436 terminx 1701
        case CON_MOVE:
1702
            insptr++;
1703
            vm.g_t[0]=0;
1704
            vm.g_t[1] = *insptr++;
1705
            vm.g_sp->hitag = *insptr++;
1706
            if (A_CheckEnemySprite(vm.g_sp) && vm.g_sp->extra <= 0) // hack
1458 terminx 1707
                continue;
1436 terminx 1708
            if (vm.g_sp->hitag&random_angle)
1709
                vm.g_sp->ang = krand()&2047;
1458 terminx 1710
            continue;
5 Plagman 1711
 
1436 terminx 1712
        case CON_ADDWEAPONVAR:
1713
            insptr++;
484 terminx 1714
            {
2873 helixhorne 1715
                int32_t weap=Gv_GetVarX(*insptr++), amount=Gv_GetVarX(*insptr++);
1716
                VM_AddWeapon(weap, amount, g_player[vm.g_p].ps);
1458 terminx 1717
                continue;
484 terminx 1718
            }
335 terminx 1719
 
1436 terminx 1720
        case CON_ACTIVATEBYSECTOR:
1721
        case CON_OPERATESECTORS:
1722
        case CON_OPERATEACTIVATORS:
1723
        case CON_SETASPECT:
1724
        case CON_SSP:
1725
            insptr++;
1726
            {
1727
                int32_t var1 = Gv_GetVarX(*insptr++), var2;
1728
                if (tw == CON_OPERATEACTIVATORS && *insptr == g_iThisActorID)
1729
                {
1730
                    var2 = vm.g_p;
1731
                    insptr++;
1732
                }
1733
                else var2 = Gv_GetVarX(*insptr++);
335 terminx 1734
 
1436 terminx 1735
                switch (tw)
1736
                {
1737
                case CON_ACTIVATEBYSECTOR:
3000 helixhorne 1738
                    if ((unsigned)var1 >= (unsigned)numsectors) {CON_ERRPRINTF("Invalid sector %d\n", var1); break;}
1802 terminx 1739
                    G_ActivateBySector(var1, var2);
1436 terminx 1740
                    break;
1741
                case CON_OPERATESECTORS:
3000 helixhorne 1742
                    if ((unsigned)var1 >= (unsigned)numsectors) {CON_ERRPRINTF("Invalid sector %d\n", var1); break;}
1436 terminx 1743
                    G_OperateSectors(var1, var2);
1744
                    break;
1745
                case CON_OPERATEACTIVATORS:
3000 helixhorne 1746
                    if ((unsigned)var2>=(unsigned)playerswhenstarted) {CON_ERRPRINTF("Invalid player %d\n", var2); break;}
1436 terminx 1747
                    G_OperateActivators(var1, var2);
1748
                    break;
1749
                case CON_SETASPECT:
1750
                    setaspect(var1, var2);
1751
                    break;
1752
                case CON_SSP:
3000 helixhorne 1753
                    if ((unsigned)var1 >= MAXSPRITES) { CON_ERRPRINTF("Invalid sprite %d\n", var1); break;}
1436 terminx 1754
                    A_SetSprite(var1, var2);
1755
                    break;
1756
                }
1458 terminx 1757
                continue;
967 terminx 1758
            }
892 hnt_ts 1759
 
1436 terminx 1760
        case CON_CANSEESPR:
1761
            insptr++;
1762
            {
1763
                int32_t lVar1 = Gv_GetVarX(*insptr++), lVar2 = Gv_GetVarX(*insptr++), res;
106 terminx 1764
 
1820 terminx 1765
                if ((unsigned)lVar1 >= MAXSPRITES || (unsigned)lVar2 >= MAXSPRITES)
1436 terminx 1766
                {
3000 helixhorne 1767
                    CON_ERRPRINTF("Invalid sprite %d\n", (unsigned)lVar1 >= MAXSPRITES ? lVar1 : lVar2);
1436 terminx 1768
                    res=0;
1769
                }
1770
                else res=cansee(sprite[lVar1].x,sprite[lVar1].y,sprite[lVar1].z,sprite[lVar1].sectnum,
1440 terminx 1771
                                    sprite[lVar2].x,sprite[lVar2].y,sprite[lVar2].z,sprite[lVar2].sectnum);
106 terminx 1772
 
1436 terminx 1773
                Gv_SetVarX(*insptr++, res);
1458 terminx 1774
                continue;
1436 terminx 1775
            }
1776
 
1777
        case CON_OPERATERESPAWNS:
1909 terminx 1778
            insptr++;
1779
            G_OperateRespawns(Gv_GetVarX(*insptr++));
1780
            continue;
1781
 
1436 terminx 1782
        case CON_OPERATEMASTERSWITCHES:
1909 terminx 1783
            insptr++;
1784
            G_OperateMasterSwitches(Gv_GetVarX(*insptr++));
1785
            continue;
1786
 
1436 terminx 1787
        case CON_CHECKACTIVATORMOTION:
1788
            insptr++;
1909 terminx 1789
            aGameVars[g_iReturnVarID].val.lValue = G_CheckActivatorMotion(Gv_GetVarX(*insptr++));
1790
            continue;
1436 terminx 1791
 
1792
        case CON_INSERTSPRITEQ:
1793
            insptr++;
1794
            A_AddToDeleteQueue(vm.g_i);
1458 terminx 1795
            continue;
5 Plagman 1796
 
1436 terminx 1797
        case CON_QSTRLEN:
1798
            insptr++;
484 terminx 1799
            {
1436 terminx 1800
                int32_t i=*insptr++;
1801
                int32_t j=Gv_GetVarX(*insptr++);
1625 terminx 1802
                if ((ScriptQuotes[j] == NULL))
1436 terminx 1803
                {
3000 helixhorne 1804
                    CON_ERRPRINTF("null quote %d\n", j);
1436 terminx 1805
                    Gv_SetVarX(i,-1);
1458 terminx 1806
                    continue;
1436 terminx 1807
                }
1808
                Gv_SetVarX(i,Bstrlen(ScriptQuotes[j]));
1458 terminx 1809
                continue;
484 terminx 1810
            }
337 terminx 1811
 
1436 terminx 1812
        case CON_HEADSPRITESTAT:
1813
            insptr++;
1181 terminx 1814
            {
1436 terminx 1815
                int32_t i=*insptr++;
1816
                int32_t j=Gv_GetVarX(*insptr++);
1820 terminx 1817
                if ((unsigned)j > MAXSTATUS)
1436 terminx 1818
                {
3000 helixhorne 1819
                    CON_ERRPRINTF("invalid status list %d\n", j);
1458 terminx 1820
                    continue;
1436 terminx 1821
                }
1822
                Gv_SetVarX(i,headspritestat[j]);
1458 terminx 1823
                continue;
1181 terminx 1824
            }
1825
 
1436 terminx 1826
        case CON_PREVSPRITESTAT:
1827
            insptr++;
1181 terminx 1828
            {
1436 terminx 1829
                int32_t i=*insptr++;
1830
                int32_t j=Gv_GetVarX(*insptr++);
1820 terminx 1831
                if ((unsigned)j >= MAXSPRITES)
1436 terminx 1832
                {
3000 helixhorne 1833
                    CON_ERRPRINTF("invalid sprite ID %d\n", j);
1458 terminx 1834
                    continue;
1436 terminx 1835
                }
1836
                Gv_SetVarX(i,prevspritestat[j]);
1458 terminx 1837
                continue;
1181 terminx 1838
            }
1839
 
1436 terminx 1840
        case CON_NEXTSPRITESTAT:
1841
            insptr++;
1181 terminx 1842
            {
1436 terminx 1843
                int32_t i=*insptr++;
1844
                int32_t j=Gv_GetVarX(*insptr++);
1820 terminx 1845
                if ((unsigned)j >= MAXSPRITES)
1436 terminx 1846
                {
3000 helixhorne 1847
                    CON_ERRPRINTF("invalid sprite ID %d\n", j);
1458 terminx 1848
                    continue;
1436 terminx 1849
                }
1850
                Gv_SetVarX(i,nextspritestat[j]);
1458 terminx 1851
                continue;
1181 terminx 1852
            }
1853
 
1436 terminx 1854
        case CON_HEADSPRITESECT:
1855
            insptr++;
1181 terminx 1856
            {
1436 terminx 1857
                int32_t i=*insptr++;
1858
                int32_t j=Gv_GetVarX(*insptr++);
1820 terminx 1859
                if ((unsigned)j >= (unsigned)numsectors)
1436 terminx 1860
                {
3000 helixhorne 1861
                    CON_ERRPRINTF("invalid sector %d\n", j);
1458 terminx 1862
                    continue;
1436 terminx 1863
                }
1864
                Gv_SetVarX(i,headspritesect[j]);
1458 terminx 1865
                continue;
1181 terminx 1866
            }
1867
 
1436 terminx 1868
        case CON_PREVSPRITESECT:
1869
            insptr++;
1181 terminx 1870
            {
1436 terminx 1871
                int32_t i=*insptr++;
1872
                int32_t j=Gv_GetVarX(*insptr++);
1820 terminx 1873
                if ((unsigned)j >= MAXSPRITES)
1436 terminx 1874
                {
3000 helixhorne 1875
                    CON_ERRPRINTF("invalid sprite ID %d\n", j);
1458 terminx 1876
                    continue;
1436 terminx 1877
                }
1878
                Gv_SetVarX(i,prevspritesect[j]);
1458 terminx 1879
                continue;
1181 terminx 1880
            }
1881
 
1436 terminx 1882
        case CON_NEXTSPRITESECT:
1883
            insptr++;
1181 terminx 1884
            {
1436 terminx 1885
                int32_t i=*insptr++;
1886
                int32_t j=Gv_GetVarX(*insptr++);
1820 terminx 1887
                if ((unsigned)j >= MAXSPRITES)
1436 terminx 1888
                {
3000 helixhorne 1889
                    CON_ERRPRINTF("invalid sprite ID %d\n", j);
1458 terminx 1890
                    continue;
1436 terminx 1891
                }
1892
                Gv_SetVarX(i,nextspritesect[j]);
1458 terminx 1893
                continue;
1181 terminx 1894
            }
1895
 
1436 terminx 1896
        case CON_GETKEYNAME:
1897
            insptr++;
587 terminx 1898
            {
1436 terminx 1899
                int32_t i = Gv_GetVarX(*insptr++),
1909 terminx 1900
                        f = Gv_GetVarX(*insptr++);
1901
                int32_t j = Gv_GetVarX(*insptr++);
1902
 
1903
                if ((unsigned)i >= MAXQUOTES)
3200 terminx 1904
                {
3000 helixhorne 1905
                    CON_ERRPRINTF("invalid quote ID %d\n", i);
3200 terminx 1906
                    continue;
1907
                }
1625 terminx 1908
                else if ((ScriptQuotes[i] == NULL))
3200 terminx 1909
                {
3000 helixhorne 1910
                    CON_ERRPRINTF("null quote %d\n", i);
3200 terminx 1911
                    continue;
1912
                }
1909 terminx 1913
                else if ((unsigned)f >= NUMGAMEFUNCTIONS)
3200 terminx 1914
                {
3000 helixhorne 1915
                    CON_ERRPRINTF("invalid function %d\n", f);
3200 terminx 1916
                    continue;
1917
                }
622 terminx 1918
                else
967 terminx 1919
                {
1909 terminx 1920
                    if (j < 2)
1436 terminx 1921
                        Bstrcpy(tempbuf,KB_ScanCodeToString(ud.config.KeyboardKeys[f][j]));
1922
                    else
1923
                    {
1924
                        Bstrcpy(tempbuf,KB_ScanCodeToString(ud.config.KeyboardKeys[f][0]));
1909 terminx 1925
 
1436 terminx 1926
                        if (!*tempbuf)
1927
                            Bstrcpy(tempbuf,KB_ScanCodeToString(ud.config.KeyboardKeys[f][1]));
1928
                    }
587 terminx 1929
                }
622 terminx 1930
 
1436 terminx 1931
                if (*tempbuf)
1932
                    Bstrcpy(ScriptQuotes[i],tempbuf);
1909 terminx 1933
 
1458 terminx 1934
                continue;
962 terminx 1935
            }
1909 terminx 1936
 
1436 terminx 1937
        case CON_QSUBSTR:
1938
            insptr++;
484 terminx 1939
            {
1440 terminx 1940
                int32_t q1 = Gv_GetVarX(*insptr++);
1941
                int32_t q2 = Gv_GetVarX(*insptr++);
1942
                int32_t st = Gv_GetVarX(*insptr++);
1943
                int32_t ln = Gv_GetVarX(*insptr++);
165 terminx 1944
 
1857 terminx 1945
                if ((unsigned)q1>=MAXQUOTES)
1440 terminx 1946
                {
3000 helixhorne 1947
                    CON_ERRPRINTF("invalid quote ID %d\n", q1);
1458 terminx 1948
                    continue;
1440 terminx 1949
                }
1625 terminx 1950
                if ((ScriptQuotes[q1] == NULL))
1440 terminx 1951
                {
3000 helixhorne 1952
                    CON_ERRPRINTF("null quote %d\n", q1);
1458 terminx 1953
                    continue;
1440 terminx 1954
                }
1857 terminx 1955
                if ((unsigned)q2>=MAXQUOTES)
1440 terminx 1956
                {
3000 helixhorne 1957
                    CON_ERRPRINTF("invalid quote ID %d\n", q2);
1458 terminx 1958
                    continue;
1440 terminx 1959
                }
1625 terminx 1960
                if ((ScriptQuotes[q2] == NULL))
1440 terminx 1961
                {
3000 helixhorne 1962
                    CON_ERRPRINTF("null quote %d\n", q2);
1458 terminx 1963
                    continue;
1440 terminx 1964
                }
1436 terminx 1965
 
484 terminx 1966
                {
1440 terminx 1967
                    char *s1 = ScriptQuotes[q1];
1968
                    char *s2 = ScriptQuotes[q2];
1969
 
1970
                    while (*s2 && st--) s2++;
1971
                    while ((*s1 = *s2) && ln--)
1972
                    {
1973
                        s1++;
1974
                        s2++;
1975
                    }
1436 terminx 1976
                    *s1=0;
484 terminx 1977
                }
1458 terminx 1978
                continue;
1436 terminx 1979
            }
1980
 
1981
        case CON_GETPNAME:
1457 terminx 1982
        case CON_QSTRNCAT:
1436 terminx 1983
        case CON_QSTRCAT:
1984
        case CON_QSTRCPY:
1985
        case CON_QGETSYSSTR:
1986
        case CON_CHANGESPRITESECT:
1987
            insptr++;
1988
            {
1989
                int32_t i = Gv_GetVarX(*insptr++), j;
1990
                if (tw == CON_GETPNAME && *insptr == g_iThisActorID)
960 terminx 1991
                {
1436 terminx 1992
                    j = vm.g_p;
1993
                    insptr++;
960 terminx 1994
                }
1436 terminx 1995
                else j = Gv_GetVarX(*insptr++);
1996
 
1997
                switch (tw)
960 terminx 1998
                {
1436 terminx 1999
                case CON_GETPNAME:
1625 terminx 2000
                    if ((ScriptQuotes[i] == NULL))
1436 terminx 2001
                    {
3000 helixhorne 2002
                        CON_ERRPRINTF("null quote %d\n", i);
1436 terminx 2003
                        break;
2004
                    }
2005
                    if (g_player[j].user_name[0])
2006
                        Bstrcpy(ScriptQuotes[i],g_player[j].user_name);
2007
                    else Bsprintf(ScriptQuotes[i],"%d",j);
960 terminx 2008
                    break;
1436 terminx 2009
                case CON_QGETSYSSTR:
1625 terminx 2010
                    if ((ScriptQuotes[i] == NULL))
1436 terminx 2011
                    {
3000 helixhorne 2012
                        CON_ERRPRINTF("null quote %d %d\n", i,j);
1436 terminx 2013
                        break;
2014
                    }
2015
                    switch (j)
2016
                    {
2017
                    case STR_MAPNAME:
2018
                        Bstrcpy(ScriptQuotes[i],MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name);
2019
                        break;
2020
                    case STR_MAPFILENAME:
2021
                        Bstrcpy(ScriptQuotes[i],MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].filename);
2022
                        break;
2023
                    case STR_PLAYERNAME:
2024
                        Bstrcpy(ScriptQuotes[i],g_player[vm.g_p].user_name);
2025
                        break;
2026
                    case STR_VERSION:
1821 terminx 2027
                        Bsprintf(tempbuf,HEAD2 " %s",s_buildRev);
1436 terminx 2028
                        Bstrcpy(ScriptQuotes[i],tempbuf);
2029
                        break;
2030
                    case STR_GAMETYPE:
2031
                        Bstrcpy(ScriptQuotes[i],GametypeNames[ud.coop]);
2032
                        break;
2033
                    case STR_VOLUMENAME:
2034
                        Bstrcpy(ScriptQuotes[i],EpisodeNames[ud.volume_number]);
2035
                        break;
2036
                    default:
3000 helixhorne 2037
                        CON_ERRPRINTF("unknown str ID %d %d\n", i,j);
1436 terminx 2038
                    }
960 terminx 2039
                    break;
1436 terminx 2040
                case CON_QSTRCAT:
1625 terminx 2041
                    if ((ScriptQuotes[i] == NULL || ScriptQuotes[j] == NULL)) goto nullquote;
1436 terminx 2042
                    Bstrncat(ScriptQuotes[i],ScriptQuotes[j],(MAXQUOTELEN-1)-Bstrlen(ScriptQuotes[i]));
960 terminx 2043
                    break;
1457 terminx 2044
                case CON_QSTRNCAT:
1625 terminx 2045
                    if ((ScriptQuotes[i] == NULL || ScriptQuotes[j] == NULL)) goto nullquote;
1457 terminx 2046
                    Bstrncat(ScriptQuotes[i],ScriptQuotes[j],Gv_GetVarX(*insptr++));
2047
                    break;
1436 terminx 2048
                case CON_QSTRCPY:
1625 terminx 2049
                    if ((ScriptQuotes[i] == NULL || ScriptQuotes[j] == NULL)) goto nullquote;
3510 helixhorne 2050
                    if (i != j)
2051
                        Bstrcpy(ScriptQuotes[i],ScriptQuotes[j]);
960 terminx 2052
                    break;
1436 terminx 2053
                case CON_CHANGESPRITESECT:
1820 terminx 2054
                    if ((unsigned)i >= MAXSPRITES)
1587 terminx 2055
                    {
3000 helixhorne 2056
                        CON_ERRPRINTF("Invalid sprite %d\n", i);
1587 terminx 2057
                        break;
2058
                    }
1820 terminx 2059
                    if ((unsigned)j >= (unsigned)numsectors)
1587 terminx 2060
                    {
3000 helixhorne 2061
                        CON_ERRPRINTF("Invalid sector %d\n", j);
1587 terminx 2062
                        break;
2063
                    }
1436 terminx 2064
                    changespritesect(i,j);
960 terminx 2065
                    break;
1457 terminx 2066
                default:
2067
nullquote:
3000 helixhorne 2068
                    CON_ERRPRINTF("null quote %d\n", ScriptQuotes[i] ? j : i);
1457 terminx 2069
                    break;
960 terminx 2070
                }
1458 terminx 2071
                continue;
1436 terminx 2072
            }
2073
 
2074
        case CON_CHANGESPRITESTAT:
2075
            insptr++;
2076
            {
2077
                int32_t i = Gv_GetVarX(*insptr++);
2078
                int32_t j = Gv_GetVarX(*insptr++);
2079
 
1820 terminx 2080
                if ((unsigned)i >= MAXSPRITES)
960 terminx 2081
                {
3000 helixhorne 2082
                    CON_ERRPRINTF("Invalid sprite: %d\n", i);
1458 terminx 2083
                    continue;
960 terminx 2084
                }
1820 terminx 2085
                if ((unsigned)j >= MAXSTATUS)
960 terminx 2086
                {
3000 helixhorne 2087
                    CON_ERRPRINTF("Invalid statnum: %d\n", j);
1458 terminx 2088
                    continue;
960 terminx 2089
                }
1458 terminx 2090
                if (sprite[i].statnum == j) continue;
1188 terminx 2091
 
1436 terminx 2092
                /* initialize actor data when changing to an actor statnum because there's usually
2093
                garbage left over from being handled as a hard coded object */
1188 terminx 2094
 
1436 terminx 2095
                if (sprite[i].statnum > STAT_ZOMBIEACTOR && (j == STAT_ACTOR || j == STAT_ZOMBIEACTOR))
2096
                {
1625 terminx 2097
                    actor[i].lastvx = 0;
2098
                    actor[i].lastvy = 0;
2099
                    actor[i].timetosleep = 0;
2100
                    actor[i].cgg = 0;
2101
                    actor[i].movflag = 0;
2102
                    actor[i].tempang = 0;
2103
                    actor[i].dispicnum = 0;
1436 terminx 2104
                    T1=T2=T3=T4=T5=T6=T7=T8=T9=0;
1625 terminx 2105
                    actor[i].flags = 0;
1436 terminx 2106
                    sprite[i].hitag = 0;
3345 helixhorne 2107
// TODO: Lunatic
3102 terminx 2108
                    if (g_tile[sprite[i].picnum].execPtr)
1436 terminx 2109
                    {
2185 helixhorne 2110
                        // offsets
3102 terminx 2111
                        T5 = *(g_tile[sprite[i].picnum].execPtr+1);  // action
2112
                        T2 = *(g_tile[sprite[i].picnum].execPtr+2);  // move
2113
                        sprite[i].hitag = *(g_tile[sprite[i].picnum].execPtr+3);  // ai bits
1436 terminx 2114
                    }
2115
                }
2116
                changespritestat(i,j);
1458 terminx 2117
                continue;
1200 terminx 2118
            }
1046 terminx 2119
 
1436 terminx 2120
        case CON_STARTLEVEL:
2121
            insptr++; // skip command
1200 terminx 2122
            {
1436 terminx 2123
                // from 'level' cheat in game.c (about line 6250)
2124
                int32_t volnume=Gv_GetVarX(*insptr++), levnume=Gv_GetVarX(*insptr++);
1200 terminx 2125
 
1625 terminx 2126
                if ((volnume > MAXVOLUMES-1 || volnume < 0))
1085 terminx 2127
                {
3000 helixhorne 2128
                    CON_ERRPRINTF("invalid volume (%d)\n", volnume);
1458 terminx 2129
                    continue;
1044 terminx 2130
                }
337 terminx 2131
 
1625 terminx 2132
                if ((levnume > MAXLEVELS-1 || levnume < 0))
1436 terminx 2133
                {
3000 helixhorne 2134
                    CON_ERRPRINTF("invalid level (%d)\n", levnume);
1458 terminx 2135
                    continue;
1436 terminx 2136
                }
5 Plagman 2137
 
1436 terminx 2138
                ud.m_volume_number = ud.volume_number = volnume;
2139
                ud.m_level_number = ud.level_number = levnume;
3095 terminx 2140
                //if (numplayers > 1 && g_netServer)
2141
                //    Net_NewGame(volnume,levnume);
2142
                //else
1436 terminx 2143
                {
2144
                    g_player[myconnectindex].ps->gm |= MODE_EOL;
2145
                    ud.display_bonus_screen = 0;
2146
                } // MODE_RESTART;
484 terminx 2147
 
1458 terminx 2148
                continue;
484 terminx 2149
            }
2150
 
1436 terminx 2151
        case CON_MYOSX:
2152
        case CON_MYOSPALX:
2153
        case CON_MYOS:
2154
        case CON_MYOSPAL:
2155
            insptr++;
484 terminx 2156
            {
1436 terminx 2157
                int32_t x=Gv_GetVarX(*insptr++), y=Gv_GetVarX(*insptr++), tilenum=Gv_GetVarX(*insptr++);
2158
                int32_t shade=Gv_GetVarX(*insptr++), orientation=Gv_GetVarX(*insptr++);
484 terminx 2159
 
1436 terminx 2160
                switch (tw)
2161
                {
2162
                case CON_MYOS:
2163
                    G_DrawTile(x,y,tilenum,shade,orientation);
2164
                    break;
2165
                case CON_MYOSPAL:
1440 terminx 2166
                {
2167
                    int32_t pal=Gv_GetVarX(*insptr++);
2168
                    G_DrawTilePal(x,y,tilenum,shade,orientation,pal);
2169
                    break;
2170
                }
1436 terminx 2171
                case CON_MYOSX:
2172
                    G_DrawTileSmall(x,y,tilenum,shade,orientation);
2173
                    break;
2174
                case CON_MYOSPALX:
1440 terminx 2175
                {
2176
                    int32_t pal=Gv_GetVarX(*insptr++);
2177
                    G_DrawTilePalSmall(x,y,tilenum,shade,orientation,pal);
2178
                    break;
1436 terminx 2179
                }
1440 terminx 2180
                }
1458 terminx 2181
                continue;
428 terminx 2182
            }
5 Plagman 2183
 
1436 terminx 2184
        case CON_SWITCH:
2185
            insptr++; // p-code
5 Plagman 2186
            {
1436 terminx 2187
                // command format:
2188
                // variable ID to check
2189
                // script offset to 'end'
2190
                // count of case statements
2191
                // script offset to default case (null if none)
2192
                // For each case: value, ptr to code
2193