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