Odamex
Setting the Standard in Multiplayer Doom
common/p_acs.h
Go to the documentation of this file.
00001 // p_acs.h: ACS Script Stuff
00002 
00003 #ifndef __P_ACS_H__
00004 #define __P_ACS_H__
00005 
00006 #include "dobject.h"
00007 
00008 #define STACK_SIZE      200
00009 #define LOCAL_SIZE      10
00010 
00011 class DLevelScript : public DObject
00012 {
00013         DECLARE_SERIAL (DLevelScript, DObject)
00014 public:
00015 
00016         // P-codes for ACS scripts
00017         enum
00018         {
00019                 PCD_NOP =                                       0,
00020                 PCD_TERMINATE =                         1,
00021                 PCD_SUSPEND =                           2,
00022                 PCD_PUSHNUMBER =                        3,
00023                 PCD_LSPEC1 =                            4,
00024                 PCD_LSPEC2 =                            5,
00025                 PCD_LSPEC3 =                            6,
00026                 PCD_LSPEC4 =                            7,
00027                 PCD_LSPEC5 =                            8,
00028                 PCD_LSPEC1DIRECT =                      9,
00029                 PCD_LSPEC2DIRECT =                      10,
00030                 PCD_LSPEC3DIRECT =                      11,
00031                 PCD_LSPEC4DIRECT =                      12,
00032                 PCD_LSPEC5DIRECT =                      13,
00033                 PCD_ADD =                                       14,
00034                 PCD_SUBTRACT =                          15,
00035                 PCD_MULTIPLY =                          16,
00036                 PCD_DIVIDE =                            17,
00037                 PCD_MODULUS =                           18,
00038                 PCD_EQ =                                        19,
00039                 PCD_NE =                                        20,
00040                 PCD_LT =                                        21,
00041                 PCD_GT =                                        22,
00042                 PCD_LE =                                        23,
00043                 PCD_GE =                                        24,
00044                 PCD_ASSIGNSCRIPTVAR =           25,
00045                 PCD_ASSIGNMAPVAR =                      26,
00046                 PCD_ASSIGNWORLDVAR =            27,
00047                 PCD_PUSHSCRIPTVAR =                     28,
00048                 PCD_PUSHMAPVAR =                        29,
00049                 PCD_PUSHWORLDVAR =                      30,
00050                 PCD_ADDSCRIPTVAR =                      31,
00051                 PCD_ADDMAPVAR =                         32,
00052                 PCD_ADDWORLDVAR =                       33,
00053                 PCD_SUBSCRIPTVAR =                      34,
00054                 PCD_SUBMAPVAR =                         35,
00055                 PCD_SUBWORLDVAR =                       36,
00056                 PCD_MULSCRIPTVAR =                      37,
00057                 PCD_MULMAPVAR =                         38,
00058                 PCD_MULWORLDVAR =                       39,
00059                 PCD_DIVSCRIPTVAR =                      40,
00060                 PCD_DIVMAPVAR =                         41,
00061                 PCD_DIVWORLDVAR =                       42,
00062                 PCD_MODSCRIPTVAR =                      43,
00063                 PCD_MODMAPVAR =                         44,
00064                 PCD_MODWORLDVAR =                       45,
00065                 PCD_INCSCRIPTVAR =                      46,
00066                 PCD_INCMAPVAR =                         47,
00067                 PCD_INCWORLDVAR =                       48,
00068                 PCD_DECSCRIPTVAR =                      49,
00069                 PCD_DECMAPVAR =                         50,
00070                 PCD_DECWORLDVAR =                       51,
00071                 PCD_GOTO =                                      52,
00072                 PCD_IFGOTO =                            53,
00073                 PCD_DROP =                                      54,
00074                 PCD_DELAY =                                     55,
00075                 PCD_DELAYDIRECT =                       56,
00076                 PCD_RANDOM =                            57,
00077                 PCD_RANDOMDIRECT =                      58,
00078                 PCD_THINGCOUNT =                        59,
00079                 PCD_THINGCOUNTDIRECT =          60,
00080                 PCD_TAGWAIT =                           61,
00081                 PCD_TAGWAITDIRECT =                     62,
00082                 PCD_POLYWAIT =                          63,
00083                 PCD_POLYWAITDIRECT =            64,
00084                 PCD_CHANGEFLOOR =                       65,
00085                 PCD_CHANGEFLOORDIRECT =         66,
00086                 PCD_CHANGECEILING =                     67,
00087                 PCD_CHANGECEILINGDIRECT =       68,
00088                 PCD_RESTART =                           69,
00089                 PCD_ANDLOGICAL =                        70,
00090                 PCD_ORLOGICAL =                         71,
00091                 PCD_ANDBITWISE =                        72,
00092                 PCD_ORBITWISE =                         73,
00093                 PCD_EORBITWISE =                        74,
00094                 PCD_NEGATELOGICAL =                     75,
00095                 PCD_LSHIFT =                            76,
00096                 PCD_RSHIFT =                            77,
00097                 PCD_UNARYMINUS =                        78,
00098                 PCD_IFNOTGOTO =                         79,
00099                 PCD_LINESIDE =                          80,
00100                 PCD_SCRIPTWAIT =                        81,
00101                 PCD_SCRIPTWAITDIRECT =          82,
00102                 PCD_CLEARLINESPECIAL =          83,
00103                 PCD_CASEGOTO =                          84,
00104                 PCD_BEGINPRINT =                        85,
00105                 PCD_ENDPRINT =                          86,
00106                 PCD_PRINTSTRING =                       87,
00107                 PCD_PRINTNUMBER =                       88,
00108                 PCD_PRINTCHARACTER =            89,
00109                 PCD_PLAYERCOUNT =                       90,
00110                 PCD_GAMETYPE =                          91,
00111                 PCD_GAMESKILL =                         92,
00112                 PCD_TIMER =                                     93,
00113                 PCD_SECTORSOUND =                       94,
00114                 PCD_AMBIENTSOUND =                      95,
00115                 PCD_SOUNDSEQUENCE =                     96,
00116                 PCD_SETLINETEXTURE =            97,
00117                 PCD_SETLINEBLOCKING =           98,
00118                 PCD_SETLINESPECIAL =            99,
00119                 PCD_THINGSOUND =                        100,
00120                 PCD_ENDPRINTBOLD =                      101,
00121                 PCD_ACTIVATORSOUND =            102,
00122                 PCD_LOCALAMBIENTSOUND =         103,
00123                 PCD_SETLINEMONSTERBLOCKING =104,
00124                 PCD_FIXEDMUL                      = 136,
00125                 PCD_FIXEDDIV                      = 137,
00126                 PCD_SETGRAVITY                    = 138,
00127                 PCD_SETGRAVITYDIRECT      = 139,
00128                 PCD_SETAIRCONTROL                 = 140,
00129                 PCD_SETAIRCONTROLDIRECT   = 141         
00130         };
00131 
00132         // Some constants used by ACS scripts
00133         enum {
00134                 LINE_FRONT =                    0,
00135                 LINE_BACK =                             1
00136         };
00137         enum {
00138                 SIDE_FRONT =                    0,
00139                 SIDE_BACK =                             1
00140         };
00141         enum {
00142                 TEXTURE_TOP =                   0,
00143                 TEXTURE_MIDDLE =                1,
00144                 TEXTURE_BOTTOM =                2
00145         };
00146         enum {
00147                 GAME_SINGLE_PLAYER =    0,
00148                 GAME_NET_COOPERATIVE =  1,
00149                 GAME_NET_DEATHMATCH =   2
00150         };
00151         enum {
00152                 CLASS_FIGHTER =                 0,
00153                 CLASS_CLERIC =                  1,
00154                 CLASS_MAGE =                    2
00155         };
00156         enum {
00157                 SKILL_VERY_EASY =               0,
00158                 SKILL_EASY =                    1,
00159                 SKILL_NORMAL =                  2,
00160                 SKILL_HARD =                    3,
00161                 SKILL_VERY_HARD =               4
00162         };
00163         enum {
00164                 BLOCK_NOTHING =                 0,
00165                 BLOCK_CREATURES =               1,
00166                 BLOCK_EVERYTHING =              2
00167         };
00168 
00169         enum EScriptState
00170         {
00171                 SCRIPT_Running,
00172                 SCRIPT_Suspended,
00173                 SCRIPT_Delayed,
00174                 SCRIPT_TagWait,
00175                 SCRIPT_PolyWait,
00176                 SCRIPT_ScriptWaitPre,
00177                 SCRIPT_ScriptWait,
00178                 SCRIPT_PleaseRemove
00179         };
00180 
00181         DLevelScript (AActor *who, line_t *where, int num, int *code,
00182                 int lineSide, int arg0, int arg1, int arg2, int always, bool delay);
00183 
00184         void RunScript ();
00185 
00186         inline void SetState (EScriptState newstate) { state = newstate; }
00187         inline EScriptState GetState () { return state; }
00188 
00189         void *operator new (size_t size);
00190         void operator delete (void *block);
00191 
00192 protected:
00193         DLevelScript    *next, *prev;
00194         int                             script;
00195         int                             stack[STACK_SIZE];
00196         int                             sp;
00197         int                             locals[LOCAL_SIZE];
00198         int                             *pc;
00199         EScriptState    state;
00200         int                             statedata;
00201         AActor                  *activator;
00202         line_t                  *activationline;
00203         int                             lineSide;
00204         int                             stringstart;
00205 
00206         inline void PushToStack (int val);
00207 
00208         void Link ();
00209         void Unlink ();
00210         void PutLast ();
00211         void PutFirst ();
00212         static int Random (int min, int max);
00213         static int ThingCount (int type, int tid);
00214         static void ChangeFlat (int tag, int name, bool floorOrCeiling);
00215         static int CountPlayers ();
00216         static void SetLineTexture (int lineid, int side, int position, int name);
00217 
00218 private:
00219         DLevelScript ();
00220 
00221         friend class DACSThinker;
00222 };
00223 
00224 inline FArchive &operator<< (FArchive &arc, DLevelScript::EScriptState state)
00225 {
00226         return arc << (BYTE)state;
00227 }
00228 inline FArchive &operator>> (FArchive &arc, DLevelScript::EScriptState &state)
00229 {
00230         BYTE in; arc >> in; state = (DLevelScript::EScriptState)in; return arc;
00231 }
00232 
00233 inline void DLevelScript::PushToStack (int val)
00234 {
00235         if (sp == STACK_SIZE)
00236         {
00237                 Printf (PRINT_HIGH, "Stack overflow in script %d\n", script);
00238                 state = SCRIPT_PleaseRemove;
00239         }
00240         stack[sp++] = val;
00241 }
00242 
00243 class DACSThinker : public DThinker
00244 {
00245         DECLARE_SERIAL (DACSThinker, DThinker)
00246 public:
00247         DACSThinker ();
00248         ~DACSThinker ();
00249 
00250         void RunThink ();
00251 
00252         DLevelScript *RunningScripts[1000];     // Array of all synchronous scripts
00253         static DACSThinker *ActiveThinker;
00254 
00255 private:
00256         DLevelScript *LastScript;
00257         DLevelScript *Scripts;                          // List of all running scripts
00258 
00259         friend class DLevelScript;
00260 };
00261 
00262 // The structure used to control scripts between maps
00263 struct acsdefered_s
00264 {
00265         struct acsdefered_s *next;
00266 
00267         enum EType
00268         {
00269                 defexecute,
00270                 defexealways,
00271                 defsuspend,
00272                 defterminate
00273         } type;
00274         int script;
00275         int arg0, arg1, arg2;
00276 };
00277 typedef struct acsdefered_s acsdefered_t;
00278 
00279 FArchive &operator<< (FArchive &arc, acsdefered_s *defer);
00280 FArchive &operator>> (FArchive &arc, acsdefered_s* &defer);
00281 
00282 #endif //__P_ACS_H__
00283 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends