|
Odamex
Setting the Standard in Multiplayer Doom
|
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