1
2 //**************************************************************************
3 //**
4 //** p_acs.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile: p_acs.c,v $
7 //** $Revision: 1.31 $
8 //** $Date: 95/10/09 16:25:17 $
9 //** $Author: cjr $
10 //**
11 //**************************************************************************
12
13 // HEADER FILES ------------------------------------------------------------
14
15 #include "h2def.h"
16 #include "p_local.h"
17
18 // MACROS ------------------------------------------------------------------
19
20 #define SCRIPT_CONTINUE 0
21 #define SCRIPT_STOP 1
22 #define SCRIPT_TERMINATE 2
23 #define OPEN_SCRIPTS_BASE 1000
24 #define PRINT_BUFFER_SIZE 256
25 #define GAME_SINGLE_PLAYER 0
26 #define GAME_NET_COOPERATIVE 1
27 #define GAME_NET_DEATHMATCH 2
28 #define TEXTURE_TOP 0
29 #define TEXTURE_MIDDLE 1
30 #define TEXTURE_BOTTOM 2
31 #define S_DROP ACScript->stackPtr--
32 #define S_POP ACScript->stack[--ACScript->stackPtr]
33 #define S_PUSH(x) ACScript->stack[ACScript->stackPtr++] = x
34
35 // TYPES -------------------------------------------------------------------
36
37 typedef struct
38 {
39 int marker;
40 int infoOffset;
41 int code;
42 } acsHeader_t;
43
44 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
45
46 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
47
48 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
49
50 static void StartOpenACS(int number, int infoIndex, int *address);
51 static void ScriptFinished(int number);
52 static boolean TagBusy(int tag);
53 static boolean AddToACSStore(int map, int number, byte *args);
54 static int GetACSIndex(int number);
55 static void Push(int value);
56 static int Pop(void);
57 static int Top(void);
58 static void Drop(void);
59
60 static int CmdNOP(void);
61 static int CmdTerminate(void);
62 static int CmdSuspend(void);
63 static int CmdPushNumber(void);
64 static int CmdLSpec1(void);
65 static int CmdLSpec2(void);
66 static int CmdLSpec3(void);
67 static int CmdLSpec4(void);
68 static int CmdLSpec5(void);
69 static int CmdLSpec1Direct(void);
70 static int CmdLSpec2Direct(void);
71 static int CmdLSpec3Direct(void);
72 static int CmdLSpec4Direct(void);
73 static int CmdLSpec5Direct(void);
74 static int CmdAdd(void);
75 static int CmdSubtract(void);
76 static int CmdMultiply(void);
77 static int CmdDivide(void);
78 static int CmdModulus(void);
79 static int CmdEQ(void);
80 static int CmdNE(void);
81 static int CmdLT(void);
82 static int CmdGT(void);
83 static int CmdLE(void);
84 static int CmdGE(void);
85 static int CmdAssignScriptVar(void);
86 static int CmdAssignMapVar(void);
87 static int CmdAssignWorldVar(void);
88 static int CmdPushScriptVar(void);
89 static int CmdPushMapVar(void);
90 static int CmdPushWorldVar(void);
91 static int CmdAddScriptVar(void);
92 static int CmdAddMapVar(void);
93 static int CmdAddWorldVar(void);
94 static int CmdSubScriptVar(void);
95 static int CmdSubMapVar(void);
96 static int CmdSubWorldVar(void);
97 static int CmdMulScriptVar(void);
98 static int CmdMulMapVar(void);
99 static int CmdMulWorldVar(void);
100 static int CmdDivScriptVar(void);
101 static int CmdDivMapVar(void);
102 static int CmdDivWorldVar(void);
103 static int CmdModScriptVar(void);
104 static int CmdModMapVar(void);
105 static int CmdModWorldVar(void);
106 static int CmdIncScriptVar(void);
107 static int CmdIncMapVar(void);
108 static int CmdIncWorldVar(void);
109 static int CmdDecScriptVar(void);
110 static int CmdDecMapVar(void);
111 static int CmdDecWorldVar(void);
112 static int CmdGoto(void);
113 static int CmdIfGoto(void);
114 static int CmdDrop(void);
115 static int CmdDelay(void);
116 static int CmdDelayDirect(void);
117 static int CmdRandom(void);
118 static int CmdRandomDirect(void);
119 static int CmdThingCount(void);
120 static int CmdThingCountDirect(void);
121 static int CmdTagWait(void);
122 static int CmdTagWaitDirect(void);
123 static int CmdPolyWait(void);
124 static int CmdPolyWaitDirect(void);
125 static int CmdChangeFloor(void);
126 static int CmdChangeFloorDirect(void);
127 static int CmdChangeCeiling(void);
128 static int CmdChangeCeilingDirect(void);
129 static int CmdRestart(void);
130 static int CmdAndLogical(void);
131 static int CmdOrLogical(void);
132 static int CmdAndBitwise(void);
133 static int CmdOrBitwise(void);
134 static int CmdEorBitwise(void);
135 static int CmdNegateLogical(void);
136 static int CmdLShift(void);
137 static int CmdRShift(void);
138 static int CmdUnaryMinus(void);
139 static int CmdIfNotGoto(void);
140 static int CmdLineSide(void);
141 static int CmdScriptWait(void);
142 static int CmdScriptWaitDirect(void);
143 static int CmdClearLineSpecial(void);
144 static int CmdCaseGoto(void);
145 static int CmdBeginPrint(void);
146 static int CmdEndPrint(void);
147 static int CmdPrintString(void);
148 static int CmdPrintNumber(void);
149 static int CmdPrintCharacter(void);
150 static int CmdPlayerCount(void);
151 static int CmdGameType(void);
152 static int CmdGameSkill(void);
153 static int CmdTimer(void);
154 static int CmdSectorSound(void);
155 static int CmdAmbientSound(void);
156 static int CmdSoundSequence(void);
157 static int CmdSetLineTexture(void);
158 static int CmdSetLineBlocking(void);
159 static int CmdSetLineSpecial(void);
160 static int CmdThingSound(void);
161 static int CmdEndPrintBold(void);
162
163 static void ThingCount(int type, int tid);
164
165 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
166
167 // PUBLIC DATA DEFINITIONS -------------------------------------------------
168
169 int ACScriptCount;
170 byte *ActionCodeBase;
171 acsInfo_t *ACSInfo;
172 int MapVars[MAX_ACS_MAP_VARS];
173 int WorldVars[MAX_ACS_WORLD_VARS];
174 acsstore_t ACSStore[MAX_ACS_STORE+1]; // +1 for termination marker
175
176 // PRIVATE DATA DEFINITIONS ------------------------------------------------
177
178 static acs_t *ACScript;
179 static int *PCodePtr;
180 static byte SpecArgs[8];
181 static int ACStringCount;
182 static char **ACStrings;
183 static char PrintBuffer[PRINT_BUFFER_SIZE];
184 static acs_t *NewScript;
185
186 static int (*PCodeCmds[])(void) =
187 {
188 CmdNOP,
189 CmdTerminate,
190 CmdSuspend,
191 CmdPushNumber,
192 CmdLSpec1,
193 CmdLSpec2,
194 CmdLSpec3,
195 CmdLSpec4,
196 CmdLSpec5,
197 CmdLSpec1Direct,
198 CmdLSpec2Direct,
199 CmdLSpec3Direct,
200 CmdLSpec4Direct,
201 CmdLSpec5Direct,
202 CmdAdd,
203 CmdSubtract,
204 CmdMultiply,
205 CmdDivide,
206 CmdModulus,
207 CmdEQ,
208 CmdNE,
209 CmdLT,
210 CmdGT,
211 CmdLE,
212 CmdGE,
213 CmdAssignScriptVar,
214 CmdAssignMapVar,
215 CmdAssignWorldVar,
216 CmdPushScriptVar,
217 CmdPushMapVar,
218 CmdPushWorldVar,
219 CmdAddScriptVar,
220 CmdAddMapVar,
221 CmdAddWorldVar,
222 CmdSubScriptVar,
223 CmdSubMapVar,
224 CmdSubWorldVar,
225 CmdMulScriptVar,
226 CmdMulMapVar,
227 CmdMulWorldVar,
228 CmdDivScriptVar,
229 CmdDivMapVar,
230 CmdDivWorldVar,
231 CmdModScriptVar,
232 CmdModMapVar,
233 CmdModWorldVar,
234 CmdIncScriptVar,
235 CmdIncMapVar,
236 CmdIncWorldVar,
237 CmdDecScriptVar,
238 CmdDecMapVar,
239 CmdDecWorldVar,
240 CmdGoto,
241 CmdIfGoto,
242 CmdDrop,
243 CmdDelay,
244 CmdDelayDirect,
245 CmdRandom,
246 CmdRandomDirect,
247 CmdThingCount,
248 CmdThingCountDirect,
249 CmdTagWait,
250 CmdTagWaitDirect,
251 CmdPolyWait,
252 CmdPolyWaitDirect,
253 CmdChangeFloor,
254 CmdChangeFloorDirect,
255 CmdChangeCeiling,
256 CmdChangeCeilingDirect,
257 CmdRestart,
258 CmdAndLogical,
259 CmdOrLogical,
260 CmdAndBitwise,
261 CmdOrBitwise,
262 CmdEorBitwise,
263 CmdNegateLogical,
264 CmdLShift,
265 CmdRShift,
266 CmdUnaryMinus,
267 CmdIfNotGoto,
268 CmdLineSide,
269 CmdScriptWait,
270 CmdScriptWaitDirect,
271 CmdClearLineSpecial,
272 CmdCaseGoto,
273 CmdBeginPrint,
274 CmdEndPrint,
275 CmdPrintString,
276 CmdPrintNumber,
277 CmdPrintCharacter,
278 CmdPlayerCount,
279 CmdGameType,
280 CmdGameSkill,
281 CmdTimer,
282 CmdSectorSound,
283 CmdAmbientSound,
284 CmdSoundSequence,
285 CmdSetLineTexture,
286 CmdSetLineBlocking,
287 CmdSetLineSpecial,
288 CmdThingSound,
289 CmdEndPrintBold
290 };
291
292 // CODE --------------------------------------------------------------------
293
294 //==========================================================================
295 //
296 // P_LoadACScripts
297 //
298 //==========================================================================
299
P_LoadACScripts(int lump)300 void P_LoadACScripts(int lump)
301 {
302 int i;
303 int *buffer;
304 acsHeader_t *header;
305 acsInfo_t *info;
306
307 header = W_CacheLumpNum(lump, PU_LEVEL);
308 ActionCodeBase = (byte *)header;
309 buffer = (int *)((byte *)header+header->infoOffset);
310 ACScriptCount = *buffer++;
311 if(ACScriptCount == 0)
312 { // Empty behavior lump
313 return;
314 }
315 ACSInfo = Z_Malloc(ACScriptCount*sizeof(acsInfo_t), PU_LEVEL, 0);
316 memset(ACSInfo, 0, ACScriptCount*sizeof(acsInfo_t));
317 for(i = 0, info = ACSInfo; i < ACScriptCount; i++, info++)
318 {
319 info->number = *buffer++;
320 info->address = (int *)((byte *)ActionCodeBase+*buffer++);
321 info->argCount = *buffer++;
322 if(info->number >= OPEN_SCRIPTS_BASE)
323 { // Auto-activate
324 info->number -= OPEN_SCRIPTS_BASE;
325 StartOpenACS(info->number, i, info->address);
326 info->state = ASTE_RUNNING;
327 }
328 else
329 {
330 info->state = ASTE_INACTIVE;
331 }
332 }
333 ACStringCount = *buffer++;
334 ACStrings = (char **)buffer;
335 for(i = 0; i < ACStringCount; i++)
336 {
337 ACStrings[i] += (int)ActionCodeBase;
338 }
339 memset(MapVars, 0, sizeof(MapVars));
340 }
341
342 //==========================================================================
343 //
344 // StartOpenACS
345 //
346 //==========================================================================
347
StartOpenACS(int number,int infoIndex,int * address)348 static void StartOpenACS(int number, int infoIndex, int *address)
349 {
350 acs_t *script;
351
352 script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0);
353 memset(script, 0, sizeof(acs_t));
354 script->number = number;
355
356 // World objects are allotted 1 second for initialization
357 script->delayCount = 35;
358
359 script->infoIndex = infoIndex;
360 script->ip = address;
361 script->thinker.function = T_InterpretACS;
362 P_AddThinker(&script->thinker);
363 }
364
365 //==========================================================================
366 //
367 // P_CheckACSStore
368 //
369 // Scans the ACS store and executes all scripts belonging to the current
370 // map.
371 //
372 //==========================================================================
373
P_CheckACSStore(void)374 void P_CheckACSStore(void)
375 {
376 acsstore_t *store;
377
378 for(store = ACSStore; store->map != 0; store++)
379 {
380 if(store->map == gamemap)
381 {
382 P_StartACS(store->script, 0, store->args, NULL, NULL, 0);
383 if(NewScript)
384 {
385 NewScript->delayCount = 35;
386 }
387 store->map = -1;
388 }
389 }
390 }
391
392 //==========================================================================
393 //
394 // P_StartACS
395 //
396 //==========================================================================
397
398 static char ErrorMsg[128];
399
P_StartACS(int number,int map,byte * args,mobj_t * activator,line_t * line,int side)400 boolean P_StartACS(int number, int map, byte *args, mobj_t *activator,
401 line_t *line, int side)
402 {
403 int i;
404 acs_t *script;
405 int infoIndex;
406 aste_t *statePtr;
407
408 NewScript = NULL;
409 if(map && map != gamemap)
410 { // Add to the script store
411 return AddToACSStore(map, number, args);
412 }
413 infoIndex = GetACSIndex(number);
414 if(infoIndex == -1)
415 { // Script not found
416 //I_Error("P_StartACS: Unknown script number %d", number);
417 sprintf(ErrorMsg, "P_STARTACS ERROR: UNKNOWN SCRIPT %d", number);
418 P_SetMessage(&players[consoleplayer], ErrorMsg, true);
419 }
420 statePtr = &ACSInfo[infoIndex].state;
421 if(*statePtr == ASTE_SUSPENDED)
422 { // Resume a suspended script
423 *statePtr = ASTE_RUNNING;
424 return true;
425 }
426 if(*statePtr != ASTE_INACTIVE)
427 { // Script is already executing
428 return false;
429 }
430 script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0);
431 memset(script, 0, sizeof(acs_t));
432 script->number = number;
433 script->infoIndex = infoIndex;
434 script->activator = activator;
435 script->line = line;
436 script->side = side;
437 script->ip = ACSInfo[infoIndex].address;
438 script->thinker.function = T_InterpretACS;
439 for(i = 0; i < ACSInfo[infoIndex].argCount; i++)
440 {
441 script->vars[i] = args[i];
442 }
443 *statePtr = ASTE_RUNNING;
444 P_AddThinker(&script->thinker);
445 NewScript = script;
446 return true;
447 }
448
449 //==========================================================================
450 //
451 // AddToACSStore
452 //
453 //==========================================================================
454
AddToACSStore(int map,int number,byte * args)455 static boolean AddToACSStore(int map, int number, byte *args)
456 {
457 int i;
458 int index;
459
460 index = -1;
461 for(i = 0; ACSStore[i].map != 0; i++)
462 {
463 if(ACSStore[i].script == number
464 && ACSStore[i].map == map)
465 { // Don't allow duplicates
466 return false;
467 }
468 if(index == -1 && ACSStore[i].map == -1)
469 { // Remember first empty slot
470 index = i;
471 }
472 }
473 if(index == -1)
474 { // Append required
475 if(i == MAX_ACS_STORE)
476 {
477 I_Error("AddToACSStore: MAX_ACS_STORE (%d) exceeded.",
478 MAX_ACS_STORE);
479 }
480 index = i;
481 ACSStore[index+1].map = 0;
482 }
483 ACSStore[index].map = map;
484 ACSStore[index].script = number;
485 *((int *)ACSStore[index].args) = *((int *)args);
486 return true;
487 }
488
489 //==========================================================================
490 //
491 // P_StartLockedACS
492 //
493 //==========================================================================
494
495
P_StartLockedACS(line_t * line,byte * args,mobj_t * mo,int side)496 boolean P_StartLockedACS(line_t *line, byte *args, mobj_t *mo, int side)
497 {
498 int i;
499 int lock;
500 byte newArgs[5];
501 char LockedBuffer[80];
502
503 extern char *TextKeyMessages[11];
504
505 lock = args[4];
506 if(!mo->player)
507 {
508 return false;
509 }
510 if(lock)
511 {
512 if(!(mo->player->keys&(1<<(lock-1))))
513 {
514 sprintf(LockedBuffer, "YOU NEED THE %s\n",
515 TextKeyMessages[lock-1]);
516 P_SetMessage(mo->player, LockedBuffer, true);
517 S_StartSound(mo, SFX_DOOR_LOCKED);
518 return false;
519 }
520 }
521 for(i = 0; i < 4; i++)
522 {
523 newArgs[i] = args[i];
524 }
525 newArgs[4] = 0;
526 return P_StartACS(newArgs[0], newArgs[1], &newArgs[2], mo,
527 line, side);
528 }
529
530 //==========================================================================
531 //
532 // P_TerminateACS
533 //
534 //==========================================================================
535
P_TerminateACS(int number,int map)536 boolean P_TerminateACS(int number, int map)
537 {
538 int infoIndex;
539
540 infoIndex = GetACSIndex(number);
541 if(infoIndex == -1)
542 { // Script not found
543 return false;
544 }
545 if(ACSInfo[infoIndex].state == ASTE_INACTIVE
546 || ACSInfo[infoIndex].state == ASTE_TERMINATING)
547 { // States that disallow termination
548 return false;
549 }
550 ACSInfo[infoIndex].state = ASTE_TERMINATING;
551 return true;
552 }
553
554 //==========================================================================
555 //
556 // P_SuspendACS
557 //
558 //==========================================================================
559
P_SuspendACS(int number,int map)560 boolean P_SuspendACS(int number, int map)
561 {
562 int infoIndex;
563
564 infoIndex = GetACSIndex(number);
565 if(infoIndex == -1)
566 { // Script not found
567 return false;
568 }
569 if(ACSInfo[infoIndex].state == ASTE_INACTIVE
570 || ACSInfo[infoIndex].state == ASTE_SUSPENDED
571 || ACSInfo[infoIndex].state == ASTE_TERMINATING)
572 { // States that disallow suspension
573 return false;
574 }
575 ACSInfo[infoIndex].state = ASTE_SUSPENDED;
576 return true;
577 }
578
579 //==========================================================================
580 //
581 // P_Init
582 //
583 //==========================================================================
584
P_ACSInitNewGame(void)585 void P_ACSInitNewGame(void)
586 {
587 memset(WorldVars, 0, sizeof(WorldVars));
588 memset(ACSStore, 0, sizeof(ACSStore));
589 }
590
591 //==========================================================================
592 //
593 // T_InterpretACS
594 //
595 //==========================================================================
596
T_InterpretACS(acs_t * script)597 void T_InterpretACS(acs_t *script)
598 {
599 int cmd;
600 int action;
601
602 if(ACSInfo[script->infoIndex].state == ASTE_TERMINATING)
603 {
604 ACSInfo[script->infoIndex].state = ASTE_INACTIVE;
605 ScriptFinished(ACScript->number);
606 P_RemoveThinker(&ACScript->thinker);
607 return;
608 }
609 if(ACSInfo[script->infoIndex].state != ASTE_RUNNING)
610 {
611 return;
612 }
613 if(script->delayCount)
614 {
615 script->delayCount--;
616 return;
617 }
618 ACScript = script;
619 PCodePtr = ACScript->ip;
620 do
621 {
622 cmd = *PCodePtr++;
623 action = PCodeCmds[cmd]();
624 } while(action == SCRIPT_CONTINUE);
625 ACScript->ip = PCodePtr;
626 if(action == SCRIPT_TERMINATE)
627 {
628 ACSInfo[script->infoIndex].state = ASTE_INACTIVE;
629 ScriptFinished(ACScript->number);
630 P_RemoveThinker(&ACScript->thinker);
631 }
632 }
633
634 //==========================================================================
635 //
636 // P_TagFinished
637 //
638 //==========================================================================
639
P_TagFinished(int tag)640 void P_TagFinished(int tag)
641 {
642 int i;
643
644 if(TagBusy(tag) == true)
645 {
646 return;
647 }
648 for(i = 0; i < ACScriptCount; i++)
649 {
650 if(ACSInfo[i].state == ASTE_WAITINGFORTAG
651 && ACSInfo[i].waitValue == tag)
652 {
653 ACSInfo[i].state = ASTE_RUNNING;
654 }
655 }
656 }
657
658 //==========================================================================
659 //
660 // P_PolyobjFinished
661 //
662 //==========================================================================
663
P_PolyobjFinished(int po)664 void P_PolyobjFinished(int po)
665 {
666 int i;
667
668 if(PO_Busy(po) == true)
669 {
670 return;
671 }
672 for(i = 0; i < ACScriptCount; i++)
673 {
674 if(ACSInfo[i].state == ASTE_WAITINGFORPOLY
675 && ACSInfo[i].waitValue == po)
676 {
677 ACSInfo[i].state = ASTE_RUNNING;
678 }
679 }
680 }
681
682 //==========================================================================
683 //
684 // ScriptFinished
685 //
686 //==========================================================================
687
ScriptFinished(int number)688 static void ScriptFinished(int number)
689 {
690 int i;
691
692 for(i = 0; i < ACScriptCount; i++)
693 {
694 if(ACSInfo[i].state == ASTE_WAITINGFORSCRIPT
695 && ACSInfo[i].waitValue == number)
696 {
697 ACSInfo[i].state = ASTE_RUNNING;
698 }
699 }
700 }
701
702 //==========================================================================
703 //
704 // TagBusy
705 //
706 //==========================================================================
707
TagBusy(int tag)708 static boolean TagBusy(int tag)
709 {
710 int sectorIndex;
711
712 sectorIndex = -1;
713 while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
714 {
715 if(sectors[sectorIndex].specialdata)
716 {
717 return true;
718 }
719 }
720 return false;
721 }
722
723 //==========================================================================
724 //
725 // GetACSIndex
726 //
727 // Returns the index of a script number. Returns -1 if the script number
728 // is not found.
729 //
730 //==========================================================================
731
GetACSIndex(int number)732 static int GetACSIndex(int number)
733 {
734 int i;
735
736 for(i = 0; i < ACScriptCount; i++)
737 {
738 if(ACSInfo[i].number == number)
739 {
740 return i;
741 }
742 }
743 return -1;
744 }
745
746 //==========================================================================
747 //
748 // Push
749 //
750 //==========================================================================
751
Push(int value)752 static void Push(int value)
753 {
754 ACScript->stack[ACScript->stackPtr++] = value;
755 }
756
757 //==========================================================================
758 //
759 // Pop
760 //
761 //==========================================================================
762
Pop(void)763 static int Pop(void)
764 {
765 return ACScript->stack[--ACScript->stackPtr];
766 }
767
768 //==========================================================================
769 //
770 // Top
771 //
772 //==========================================================================
773
Top(void)774 static int Top(void)
775 {
776 return ACScript->stack[ACScript->stackPtr-1];
777 }
778
779 //==========================================================================
780 //
781 // Drop
782 //
783 //==========================================================================
784
Drop(void)785 static void Drop(void)
786 {
787 ACScript->stackPtr--;
788 }
789
790 //==========================================================================
791 //
792 // P-Code Commands
793 //
794 //==========================================================================
795
CmdNOP(void)796 static int CmdNOP(void)
797 {
798 return SCRIPT_CONTINUE;
799 }
800
CmdTerminate(void)801 static int CmdTerminate(void)
802 {
803 return SCRIPT_TERMINATE;
804 }
805
CmdSuspend(void)806 static int CmdSuspend(void)
807 {
808 ACSInfo[ACScript->infoIndex].state = ASTE_SUSPENDED;
809 return SCRIPT_STOP;
810 }
811
CmdPushNumber(void)812 static int CmdPushNumber(void)
813 {
814 Push(*PCodePtr++);
815 return SCRIPT_CONTINUE;
816 }
817
CmdLSpec1(void)818 static int CmdLSpec1(void)
819 {
820 int special;
821
822 special = *PCodePtr++;
823 SpecArgs[0] = Pop();
824 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
825 ACScript->side, ACScript->activator);
826 return SCRIPT_CONTINUE;
827 }
828
CmdLSpec2(void)829 static int CmdLSpec2(void)
830 {
831 int special;
832
833 special = *PCodePtr++;
834 SpecArgs[1] = Pop();
835 SpecArgs[0] = Pop();
836 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
837 ACScript->side, ACScript->activator);
838 return SCRIPT_CONTINUE;
839 }
840
CmdLSpec3(void)841 static int CmdLSpec3(void)
842 {
843 int special;
844
845 special = *PCodePtr++;
846 SpecArgs[2] = Pop();
847 SpecArgs[1] = Pop();
848 SpecArgs[0] = Pop();
849 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
850 ACScript->side, ACScript->activator);
851 return SCRIPT_CONTINUE;
852 }
853
CmdLSpec4(void)854 static int CmdLSpec4(void)
855 {
856 int special;
857
858 special = *PCodePtr++;
859 SpecArgs[3] = Pop();
860 SpecArgs[2] = Pop();
861 SpecArgs[1] = Pop();
862 SpecArgs[0] = Pop();
863 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
864 ACScript->side, ACScript->activator);
865 return SCRIPT_CONTINUE;
866 }
867
CmdLSpec5(void)868 static int CmdLSpec5(void)
869 {
870 int special;
871
872 special = *PCodePtr++;
873 SpecArgs[4] = Pop();
874 SpecArgs[3] = Pop();
875 SpecArgs[2] = Pop();
876 SpecArgs[1] = Pop();
877 SpecArgs[0] = Pop();
878 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
879 ACScript->side, ACScript->activator);
880 return SCRIPT_CONTINUE;
881 }
882
CmdLSpec1Direct(void)883 static int CmdLSpec1Direct(void)
884 {
885 int special;
886
887 special = *PCodePtr++;
888 SpecArgs[0] = *PCodePtr++;
889 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
890 ACScript->side, ACScript->activator);
891 return SCRIPT_CONTINUE;
892 }
893
CmdLSpec2Direct(void)894 static int CmdLSpec2Direct(void)
895 {
896 int special;
897
898 special = *PCodePtr++;
899 SpecArgs[0] = *PCodePtr++;
900 SpecArgs[1] = *PCodePtr++;
901 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
902 ACScript->side, ACScript->activator);
903 return SCRIPT_CONTINUE;
904 }
905
CmdLSpec3Direct(void)906 static int CmdLSpec3Direct(void)
907 {
908 int special;
909
910 special = *PCodePtr++;
911 SpecArgs[0] = *PCodePtr++;
912 SpecArgs[1] = *PCodePtr++;
913 SpecArgs[2] = *PCodePtr++;
914 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
915 ACScript->side, ACScript->activator);
916 return SCRIPT_CONTINUE;
917 }
918
CmdLSpec4Direct(void)919 static int CmdLSpec4Direct(void)
920 {
921 int special;
922
923 special = *PCodePtr++;
924 SpecArgs[0] = *PCodePtr++;
925 SpecArgs[1] = *PCodePtr++;
926 SpecArgs[2] = *PCodePtr++;
927 SpecArgs[3] = *PCodePtr++;
928 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
929 ACScript->side, ACScript->activator);
930 return SCRIPT_CONTINUE;
931 }
932
CmdLSpec5Direct(void)933 static int CmdLSpec5Direct(void)
934 {
935 int special;
936
937 special = *PCodePtr++;
938 SpecArgs[0] = *PCodePtr++;
939 SpecArgs[1] = *PCodePtr++;
940 SpecArgs[2] = *PCodePtr++;
941 SpecArgs[3] = *PCodePtr++;
942 SpecArgs[4] = *PCodePtr++;
943 P_ExecuteLineSpecial(special, SpecArgs, ACScript->line,
944 ACScript->side, ACScript->activator);
945 return SCRIPT_CONTINUE;
946 }
947
CmdAdd(void)948 static int CmdAdd(void)
949 {
950 Push(Pop()+Pop());
951 return SCRIPT_CONTINUE;
952 }
953
CmdSubtract(void)954 static int CmdSubtract(void)
955 {
956 int operand2;
957
958 operand2 = Pop();
959 Push(Pop()-operand2);
960 return SCRIPT_CONTINUE;
961 }
962
CmdMultiply(void)963 static int CmdMultiply(void)
964 {
965 Push(Pop()*Pop());
966 return SCRIPT_CONTINUE;
967 }
968
CmdDivide(void)969 static int CmdDivide(void)
970 {
971 int operand2;
972
973 operand2 = Pop();
974 Push(Pop()/operand2);
975 return SCRIPT_CONTINUE;
976 }
977
CmdModulus(void)978 static int CmdModulus(void)
979 {
980 int operand2;
981
982 operand2 = Pop();
983 Push(Pop()%operand2);
984 return SCRIPT_CONTINUE;
985 }
986
CmdEQ(void)987 static int CmdEQ(void)
988 {
989 Push(Pop() == Pop());
990 return SCRIPT_CONTINUE;
991 }
992
CmdNE(void)993 static int CmdNE(void)
994 {
995 Push(Pop() != Pop());
996 return SCRIPT_CONTINUE;
997 }
998
CmdLT(void)999 static int CmdLT(void)
1000 {
1001 int operand2;
1002
1003 operand2 = Pop();
1004 Push(Pop() < operand2);
1005 return SCRIPT_CONTINUE;
1006 }
1007
CmdGT(void)1008 static int CmdGT(void)
1009 {
1010 int operand2;
1011
1012 operand2 = Pop();
1013 Push(Pop() > operand2);
1014 return SCRIPT_CONTINUE;
1015 }
1016
CmdLE(void)1017 static int CmdLE(void)
1018 {
1019 int operand2;
1020
1021 operand2 = Pop();
1022 Push(Pop() <= operand2);
1023 return SCRIPT_CONTINUE;
1024 }
1025
CmdGE(void)1026 static int CmdGE(void)
1027 {
1028 int operand2;
1029
1030 operand2 = Pop();
1031 Push(Pop() >= operand2);
1032 return SCRIPT_CONTINUE;
1033 }
1034
CmdAssignScriptVar(void)1035 static int CmdAssignScriptVar(void)
1036 {
1037 ACScript->vars[*PCodePtr++] = Pop();
1038 return SCRIPT_CONTINUE;
1039 }
1040
CmdAssignMapVar(void)1041 static int CmdAssignMapVar(void)
1042 {
1043 MapVars[*PCodePtr++] = Pop();
1044 return SCRIPT_CONTINUE;
1045 }
1046
CmdAssignWorldVar(void)1047 static int CmdAssignWorldVar(void)
1048 {
1049 WorldVars[*PCodePtr++] = Pop();
1050 return SCRIPT_CONTINUE;
1051 }
1052
CmdPushScriptVar(void)1053 static int CmdPushScriptVar(void)
1054 {
1055 Push(ACScript->vars[*PCodePtr++]);
1056 return SCRIPT_CONTINUE;
1057 }
1058
CmdPushMapVar(void)1059 static int CmdPushMapVar(void)
1060 {
1061 Push(MapVars[*PCodePtr++]);
1062 return SCRIPT_CONTINUE;
1063 }
1064
CmdPushWorldVar(void)1065 static int CmdPushWorldVar(void)
1066 {
1067 Push(WorldVars[*PCodePtr++]);
1068 return SCRIPT_CONTINUE;
1069 }
1070
CmdAddScriptVar(void)1071 static int CmdAddScriptVar(void)
1072 {
1073 ACScript->vars[*PCodePtr++] += Pop();
1074 return SCRIPT_CONTINUE;
1075 }
1076
CmdAddMapVar(void)1077 static int CmdAddMapVar(void)
1078 {
1079 MapVars[*PCodePtr++] += Pop();
1080 return SCRIPT_CONTINUE;
1081 }
1082
CmdAddWorldVar(void)1083 static int CmdAddWorldVar(void)
1084 {
1085 WorldVars[*PCodePtr++] += Pop();
1086 return SCRIPT_CONTINUE;
1087 }
1088
CmdSubScriptVar(void)1089 static int CmdSubScriptVar(void)
1090 {
1091 ACScript->vars[*PCodePtr++] -= Pop();
1092 return SCRIPT_CONTINUE;
1093 }
1094
CmdSubMapVar(void)1095 static int CmdSubMapVar(void)
1096 {
1097 MapVars[*PCodePtr++] -= Pop();
1098 return SCRIPT_CONTINUE;
1099 }
1100
CmdSubWorldVar(void)1101 static int CmdSubWorldVar(void)
1102 {
1103 WorldVars[*PCodePtr++] -= Pop();
1104 return SCRIPT_CONTINUE;
1105 }
1106
CmdMulScriptVar(void)1107 static int CmdMulScriptVar(void)
1108 {
1109 ACScript->vars[*PCodePtr++] *= Pop();
1110 return SCRIPT_CONTINUE;
1111 }
1112
CmdMulMapVar(void)1113 static int CmdMulMapVar(void)
1114 {
1115 MapVars[*PCodePtr++] *= Pop();
1116 return SCRIPT_CONTINUE;
1117 }
1118
CmdMulWorldVar(void)1119 static int CmdMulWorldVar(void)
1120 {
1121 WorldVars[*PCodePtr++] *= Pop();
1122 return SCRIPT_CONTINUE;
1123 }
1124
CmdDivScriptVar(void)1125 static int CmdDivScriptVar(void)
1126 {
1127 ACScript->vars[*PCodePtr++] /= Pop();
1128 return SCRIPT_CONTINUE;
1129 }
1130
CmdDivMapVar(void)1131 static int CmdDivMapVar(void)
1132 {
1133 MapVars[*PCodePtr++] /= Pop();
1134 return SCRIPT_CONTINUE;
1135 }
1136
CmdDivWorldVar(void)1137 static int CmdDivWorldVar(void)
1138 {
1139 WorldVars[*PCodePtr++] /= Pop();
1140 return SCRIPT_CONTINUE;
1141 }
1142
CmdModScriptVar(void)1143 static int CmdModScriptVar(void)
1144 {
1145 ACScript->vars[*PCodePtr++] %= Pop();
1146 return SCRIPT_CONTINUE;
1147 }
1148
CmdModMapVar(void)1149 static int CmdModMapVar(void)
1150 {
1151 MapVars[*PCodePtr++] %= Pop();
1152 return SCRIPT_CONTINUE;
1153 }
1154
CmdModWorldVar(void)1155 static int CmdModWorldVar(void)
1156 {
1157 WorldVars[*PCodePtr++] %= Pop();
1158 return SCRIPT_CONTINUE;
1159 }
1160
CmdIncScriptVar(void)1161 static int CmdIncScriptVar(void)
1162 {
1163 ACScript->vars[*PCodePtr++]++;
1164 return SCRIPT_CONTINUE;
1165 }
1166
CmdIncMapVar(void)1167 static int CmdIncMapVar(void)
1168 {
1169 MapVars[*PCodePtr++]++;
1170 return SCRIPT_CONTINUE;
1171 }
1172
CmdIncWorldVar(void)1173 static int CmdIncWorldVar(void)
1174 {
1175 WorldVars[*PCodePtr++]++;
1176 return SCRIPT_CONTINUE;
1177 }
1178
CmdDecScriptVar(void)1179 static int CmdDecScriptVar(void)
1180 {
1181 ACScript->vars[*PCodePtr++]--;
1182 return SCRIPT_CONTINUE;
1183 }
1184
CmdDecMapVar(void)1185 static int CmdDecMapVar(void)
1186 {
1187 MapVars[*PCodePtr++]--;
1188 return SCRIPT_CONTINUE;
1189 }
1190
CmdDecWorldVar(void)1191 static int CmdDecWorldVar(void)
1192 {
1193 WorldVars[*PCodePtr++]--;
1194 return SCRIPT_CONTINUE;
1195 }
1196
CmdGoto(void)1197 static int CmdGoto(void)
1198 {
1199 PCodePtr = (int *)(ActionCodeBase+*PCodePtr);
1200 return SCRIPT_CONTINUE;
1201 }
1202
CmdIfGoto(void)1203 static int CmdIfGoto(void)
1204 {
1205 if(Pop())
1206 {
1207 PCodePtr = (int *)(ActionCodeBase+*PCodePtr);
1208 }
1209 else
1210 {
1211 PCodePtr++;
1212 }
1213 return SCRIPT_CONTINUE;
1214 }
1215
CmdDrop(void)1216 static int CmdDrop(void)
1217 {
1218 Drop();
1219 return SCRIPT_CONTINUE;
1220 }
1221
CmdDelay(void)1222 static int CmdDelay(void)
1223 {
1224 ACScript->delayCount = Pop();
1225 return SCRIPT_STOP;
1226 }
1227
CmdDelayDirect(void)1228 static int CmdDelayDirect(void)
1229 {
1230 ACScript->delayCount = *PCodePtr++;
1231 return SCRIPT_STOP;
1232 }
1233
CmdRandom(void)1234 static int CmdRandom(void)
1235 {
1236 int low;
1237 int high;
1238
1239 high = Pop();
1240 low = Pop();
1241 Push(low+(P_Random()%(high-low+1)));
1242 return SCRIPT_CONTINUE;
1243 }
1244
CmdRandomDirect(void)1245 static int CmdRandomDirect(void)
1246 {
1247 int low;
1248 int high;
1249
1250 low = *PCodePtr++;
1251 high = *PCodePtr++;
1252 Push(low+(P_Random()%(high-low+1)));
1253 return SCRIPT_CONTINUE;
1254 }
1255
CmdThingCount(void)1256 static int CmdThingCount(void)
1257 {
1258 int tid;
1259
1260 tid = Pop();
1261 ThingCount(Pop(), tid);
1262 return SCRIPT_CONTINUE;
1263 }
1264
CmdThingCountDirect(void)1265 static int CmdThingCountDirect(void)
1266 {
1267 int type;
1268
1269 type = *PCodePtr++;
1270 ThingCount(type, *PCodePtr++);
1271 return SCRIPT_CONTINUE;
1272 }
1273
ThingCount(int type,int tid)1274 static void ThingCount(int type, int tid)
1275 {
1276 int count;
1277 int searcher;
1278 mobj_t *mobj;
1279 mobjtype_t moType;
1280 thinker_t *think;
1281
1282 if(!(type+tid))
1283 { // Nothing to count
1284 return;
1285 }
1286 moType = TranslateThingType[type];
1287 count = 0;
1288 searcher = -1;
1289 if(tid)
1290 { // Count TID things
1291 while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
1292 {
1293 if(type == 0)
1294 { // Just count TIDs
1295 count++;
1296 }
1297 else if(moType == mobj->type)
1298 {
1299 if(mobj->flags&MF_COUNTKILL && mobj->health <= 0)
1300 { // Don't count dead monsters
1301 continue;
1302 }
1303 count++;
1304 }
1305 }
1306 }
1307 else
1308 { // Count only types
1309 for(think = thinkercap.next; think != &thinkercap;
1310 think = think->next)
1311 {
1312 if(think->function != P_MobjThinker)
1313 { // Not a mobj thinker
1314 continue;
1315 }
1316 mobj = (mobj_t *)think;
1317 if(mobj->type != moType)
1318 { // Doesn't match
1319 continue;
1320 }
1321 if(mobj->flags&MF_COUNTKILL && mobj->health <= 0)
1322 { // Don't count dead monsters
1323 continue;
1324 }
1325 count++;
1326 }
1327 }
1328 Push(count);
1329 }
1330
CmdTagWait(void)1331 static int CmdTagWait(void)
1332 {
1333 ACSInfo[ACScript->infoIndex].waitValue = Pop();
1334 ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORTAG;
1335 return SCRIPT_STOP;
1336 }
1337
CmdTagWaitDirect(void)1338 static int CmdTagWaitDirect(void)
1339 {
1340 ACSInfo[ACScript->infoIndex].waitValue = *PCodePtr++;
1341 ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORTAG;
1342 return SCRIPT_STOP;
1343 }
1344
CmdPolyWait(void)1345 static int CmdPolyWait(void)
1346 {
1347 ACSInfo[ACScript->infoIndex].waitValue = Pop();
1348 ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORPOLY;
1349 return SCRIPT_STOP;
1350 }
1351
CmdPolyWaitDirect(void)1352 static int CmdPolyWaitDirect(void)
1353 {
1354 ACSInfo[ACScript->infoIndex].waitValue = *PCodePtr++;
1355 ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORPOLY;
1356 return SCRIPT_STOP;
1357 }
1358
CmdChangeFloor(void)1359 static int CmdChangeFloor(void)
1360 {
1361 int tag;
1362 int flat;
1363 int sectorIndex;
1364
1365 flat = R_FlatNumForName(ACStrings[Pop()]);
1366 tag = Pop();
1367 sectorIndex = -1;
1368 while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
1369 {
1370 sectors[sectorIndex].floorpic = flat;
1371 }
1372 return SCRIPT_CONTINUE;
1373 }
1374
CmdChangeFloorDirect(void)1375 static int CmdChangeFloorDirect(void)
1376 {
1377 int tag;
1378 int flat;
1379 int sectorIndex;
1380
1381 tag = *PCodePtr++;
1382 flat = R_FlatNumForName(ACStrings[*PCodePtr++]);
1383 sectorIndex = -1;
1384 while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
1385 {
1386 sectors[sectorIndex].floorpic = flat;
1387 }
1388 return SCRIPT_CONTINUE;
1389 }
1390
CmdChangeCeiling(void)1391 static int CmdChangeCeiling(void)
1392 {
1393 int tag;
1394 int flat;
1395 int sectorIndex;
1396
1397 flat = R_FlatNumForName(ACStrings[Pop()]);
1398 tag = Pop();
1399 sectorIndex = -1;
1400 while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
1401 {
1402 sectors[sectorIndex].ceilingpic = flat;
1403 }
1404 return SCRIPT_CONTINUE;
1405 }
1406
CmdChangeCeilingDirect(void)1407 static int CmdChangeCeilingDirect(void)
1408 {
1409 int tag;
1410 int flat;
1411 int sectorIndex;
1412
1413 tag = *PCodePtr++;
1414 flat = R_FlatNumForName(ACStrings[*PCodePtr++]);
1415 sectorIndex = -1;
1416 while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
1417 {
1418 sectors[sectorIndex].ceilingpic = flat;
1419 }
1420 return SCRIPT_CONTINUE;
1421 }
1422
CmdRestart(void)1423 static int CmdRestart(void)
1424 {
1425 PCodePtr = ACSInfo[ACScript->infoIndex].address;
1426 return SCRIPT_CONTINUE;
1427 }
1428
CmdAndLogical(void)1429 static int CmdAndLogical(void)
1430 {
1431 Push(Pop() && Pop());
1432 return SCRIPT_CONTINUE;
1433 }
1434
CmdOrLogical(void)1435 static int CmdOrLogical(void)
1436 {
1437 Push(Pop() || Pop());
1438 return SCRIPT_CONTINUE;
1439 }
1440
CmdAndBitwise(void)1441 static int CmdAndBitwise(void)
1442 {
1443 Push(Pop()&Pop());
1444 return SCRIPT_CONTINUE;
1445 }
1446
CmdOrBitwise(void)1447 static int CmdOrBitwise(void)
1448 {
1449 Push(Pop()|Pop());
1450 return SCRIPT_CONTINUE;
1451 }
1452
CmdEorBitwise(void)1453 static int CmdEorBitwise(void)
1454 {
1455 Push(Pop()^Pop());
1456 return SCRIPT_CONTINUE;
1457 }
1458
CmdNegateLogical(void)1459 static int CmdNegateLogical(void)
1460 {
1461 Push(!Pop());
1462 return SCRIPT_CONTINUE;
1463 }
1464
CmdLShift(void)1465 static int CmdLShift(void)
1466 {
1467 int operand2;
1468
1469 operand2 = Pop();
1470 Push(Pop()<<operand2);
1471 return SCRIPT_CONTINUE;
1472 }
1473
CmdRShift(void)1474 static int CmdRShift(void)
1475 {
1476 int operand2;
1477
1478 operand2 = Pop();
1479 Push(Pop()>>operand2);
1480 return SCRIPT_CONTINUE;
1481 }
1482
CmdUnaryMinus(void)1483 static int CmdUnaryMinus(void)
1484 {
1485 Push(-Pop());
1486 return SCRIPT_CONTINUE;
1487 }
1488
CmdIfNotGoto(void)1489 static int CmdIfNotGoto(void)
1490 {
1491 if(Pop())
1492 {
1493 PCodePtr++;
1494 }
1495 else
1496 {
1497 PCodePtr = (int *)(ActionCodeBase+*PCodePtr);
1498 }
1499 return SCRIPT_CONTINUE;
1500 }
1501
CmdLineSide(void)1502 static int CmdLineSide(void)
1503 {
1504 Push(ACScript->side);
1505 return SCRIPT_CONTINUE;
1506 }
1507
CmdScriptWait(void)1508 static int CmdScriptWait(void)
1509 {
1510 ACSInfo[ACScript->infoIndex].waitValue = Pop();
1511 ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORSCRIPT;
1512 return SCRIPT_STOP;
1513 }
1514
CmdScriptWaitDirect(void)1515 static int CmdScriptWaitDirect(void)
1516 {
1517 ACSInfo[ACScript->infoIndex].waitValue = *PCodePtr++;
1518 ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORSCRIPT;
1519 return SCRIPT_STOP;
1520 }
1521
CmdClearLineSpecial(void)1522 static int CmdClearLineSpecial(void)
1523 {
1524 if(ACScript->line)
1525 {
1526 ACScript->line->special = 0;
1527 }
1528 return SCRIPT_CONTINUE;
1529 }
1530
CmdCaseGoto(void)1531 static int CmdCaseGoto(void)
1532 {
1533 if(Top() == *PCodePtr++)
1534 {
1535 PCodePtr = (int *)(ActionCodeBase+*PCodePtr);
1536 Drop();
1537 }
1538 else
1539 {
1540 PCodePtr++;
1541 }
1542 return SCRIPT_CONTINUE;
1543 }
1544
CmdBeginPrint(void)1545 static int CmdBeginPrint(void)
1546 {
1547 *PrintBuffer = 0;
1548 return SCRIPT_CONTINUE;
1549 }
1550
CmdEndPrint(void)1551 static int CmdEndPrint(void)
1552 {
1553 player_t *player;
1554
1555 if(ACScript->activator && ACScript->activator->player)
1556 {
1557 player = ACScript->activator->player;
1558 }
1559 else
1560 {
1561 player = &players[consoleplayer];
1562 }
1563 P_SetMessage(player, PrintBuffer, true);
1564 return SCRIPT_CONTINUE;
1565 }
1566
CmdEndPrintBold(void)1567 static int CmdEndPrintBold(void)
1568 {
1569 int i;
1570
1571 for(i = 0; i < MAXPLAYERS; i++)
1572 {
1573 if(playeringame[i])
1574 {
1575 P_SetYellowMessage(&players[i], PrintBuffer, true);
1576 }
1577 }
1578 return SCRIPT_CONTINUE;
1579 }
1580
CmdPrintString(void)1581 static int CmdPrintString(void)
1582 {
1583 strcat(PrintBuffer, ACStrings[Pop()]);
1584 return SCRIPT_CONTINUE;
1585 }
1586
CmdPrintNumber(void)1587 static int CmdPrintNumber(void)
1588 {
1589 char tempStr[16];
1590
1591 sprintf(tempStr, "%d", Pop());
1592 strcat(PrintBuffer, tempStr);
1593 return SCRIPT_CONTINUE;
1594 }
1595
CmdPrintCharacter(void)1596 static int CmdPrintCharacter(void)
1597 {
1598 char *bufferEnd;
1599
1600 bufferEnd = PrintBuffer+strlen(PrintBuffer);
1601 *bufferEnd++ = Pop();
1602 *bufferEnd = 0;
1603 return SCRIPT_CONTINUE;
1604 }
1605
CmdPlayerCount(void)1606 static int CmdPlayerCount(void)
1607 {
1608 int i;
1609 int count;
1610
1611 count = 0;
1612 for(i = 0; i < MAXPLAYERS; i++)
1613 {
1614 count += playeringame[i];
1615 }
1616 Push(count);
1617 return SCRIPT_CONTINUE;
1618 }
1619
CmdGameType(void)1620 static int CmdGameType(void)
1621 {
1622 int gametype;
1623
1624 if(netgame == false)
1625 {
1626 gametype = GAME_SINGLE_PLAYER;
1627 }
1628 else if(deathmatch)
1629 {
1630 gametype = GAME_NET_DEATHMATCH;
1631 }
1632 else
1633 {
1634 gametype = GAME_NET_COOPERATIVE;
1635 }
1636 Push(gametype);
1637 return SCRIPT_CONTINUE;
1638 }
1639
CmdGameSkill(void)1640 static int CmdGameSkill(void)
1641 {
1642 Push(gameskill);
1643 return SCRIPT_CONTINUE;
1644 }
1645
CmdTimer(void)1646 static int CmdTimer(void)
1647 {
1648 Push(leveltime);
1649 return SCRIPT_CONTINUE;
1650 }
1651
CmdSectorSound(void)1652 static int CmdSectorSound(void)
1653 {
1654 int volume;
1655 mobj_t *mobj;
1656
1657 mobj = NULL;
1658 if(ACScript->line)
1659 {
1660 mobj = (mobj_t *)&ACScript->line->frontsector->soundorg;
1661 }
1662 volume = Pop();
1663 S_StartSoundAtVolume(mobj, S_GetSoundID(ACStrings[Pop()]), volume);
1664 return SCRIPT_CONTINUE;
1665 }
1666
CmdThingSound(void)1667 static int CmdThingSound(void)
1668 {
1669 int tid;
1670 int sound;
1671 int volume;
1672 mobj_t *mobj;
1673 int searcher;
1674
1675 volume = Pop();
1676 sound = S_GetSoundID(ACStrings[Pop()]);
1677 tid = Pop();
1678 searcher = -1;
1679 while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
1680 {
1681 S_StartSoundAtVolume(mobj, sound, volume);
1682 }
1683 return SCRIPT_CONTINUE;
1684 }
1685
CmdAmbientSound(void)1686 static int CmdAmbientSound(void)
1687 {
1688 int volume;
1689
1690 volume = Pop();
1691 S_StartSoundAtVolume(NULL, S_GetSoundID(ACStrings[Pop()]), volume);
1692 return SCRIPT_CONTINUE;
1693 }
1694
CmdSoundSequence(void)1695 static int CmdSoundSequence(void)
1696 {
1697 mobj_t *mobj;
1698
1699 mobj = NULL;
1700 if(ACScript->line)
1701 {
1702 mobj = (mobj_t *)&ACScript->line->frontsector->soundorg;
1703 }
1704 SN_StartSequenceName(mobj, ACStrings[Pop()]);
1705 return SCRIPT_CONTINUE;
1706 }
1707
CmdSetLineTexture(void)1708 static int CmdSetLineTexture(void)
1709 {
1710 line_t *line;
1711 int lineTag;
1712 int side;
1713 int position;
1714 int texture;
1715 int searcher;
1716
1717 texture = R_TextureNumForName(ACStrings[Pop()]);
1718 position = Pop();
1719 side = Pop();
1720 lineTag = Pop();
1721 searcher = -1;
1722 while((line = P_FindLine(lineTag, &searcher)) != NULL)
1723 {
1724 if(position == TEXTURE_MIDDLE)
1725 {
1726 sides[line->sidenum[side]].midtexture = texture;
1727 }
1728 else if(position == TEXTURE_BOTTOM)
1729 {
1730 sides[line->sidenum[side]].bottomtexture = texture;
1731 }
1732 else
1733 { // TEXTURE_TOP
1734 sides[line->sidenum[side]].toptexture = texture;
1735 }
1736 }
1737 return SCRIPT_CONTINUE;
1738 }
1739
CmdSetLineBlocking(void)1740 static int CmdSetLineBlocking(void)
1741 {
1742 line_t *line;
1743 int lineTag;
1744 boolean blocking;
1745 int searcher;
1746
1747 blocking = Pop() ? ML_BLOCKING : 0;
1748 lineTag = Pop();
1749 searcher = -1;
1750 while((line = P_FindLine(lineTag, &searcher)) != NULL)
1751 {
1752 line->flags = (line->flags&~ML_BLOCKING)|blocking;
1753 }
1754 return SCRIPT_CONTINUE;
1755 }
1756
CmdSetLineSpecial(void)1757 static int CmdSetLineSpecial(void)
1758 {
1759 line_t *line;
1760 int lineTag;
1761 int special, arg1, arg2, arg3, arg4, arg5;
1762 int searcher;
1763
1764 arg5 = Pop();
1765 arg4 = Pop();
1766 arg3 = Pop();
1767 arg2 = Pop();
1768 arg1 = Pop();
1769 special = Pop();
1770 lineTag = Pop();
1771 searcher = -1;
1772 while((line = P_FindLine(lineTag, &searcher)) != NULL)
1773 {
1774 line->special = special;
1775 line->arg1 = arg1;
1776 line->arg2 = arg2;
1777 line->arg3 = arg3;
1778 line->arg4 = arg4;
1779 line->arg5 = arg5;
1780 }
1781 return SCRIPT_CONTINUE;
1782 }
1783