diff --git a/docs/rh-log.txt b/docs/rh-log.txt index c7b33ead8a..333a722c90 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,8 @@ May 28, 2007 (Changes by Graf Zahl) +- Split thingdef.cpp into several files so that the state and property code + no longer gets in the way of the main parser. +- Changed A_MissileAttack, A_MeleeAttack and A_ComboAttack so that they use + metadata. Now all the hack code associated with these functions can be removed. - Fixed: deadthings.txt contained a superfluous ';' which created parsing errors with my changed code. - Cleaned up DECORATE parser a little - moved the old style parsing code into its diff --git a/src/codepointers.h b/src/codepointers.h index 79cf805f9b..36271b7d51 100644 --- a/src/codepointers.h +++ b/src/codepointers.h @@ -11,6 +11,7 @@ WEAPON(Light) ACTOR(ChangeFlag) ACTOR(MeleeAttack) ACTOR(MissileAttack) +ACTOR(ComboAttack) ACTOR(BulletAttack) ACTOR(ScreamAndUnblock) ACTOR(ActiveAndUnblock) diff --git a/src/decallib.cpp b/src/decallib.cpp index d23e8e3d60..25cb29db51 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -49,7 +49,6 @@ FDecalLib DecalLibrary; static fixed_t ReadScale (); static TArray DecalTranslations; -extern TArray DecalNames; // A decal group holds multiple decals and returns one randomly // when GetDecal() is called. @@ -355,19 +354,12 @@ void FDecalLib::ReadAllDecals () { AActor *def = (AActor*)GetDefaultByType (PClass::m_RuntimeActors[i]); - intptr_t v = (intptr_t)def->DecalGenerator; - if (v > 0 && v <= (intptr_t)DecalNames.Size()) + FName v = ENamedName(intptr_t(def->DecalGenerator)); + if (v.IsValidName()) { - def->DecalGenerator = ScanTreeForName (DecalNames[v-1], Root); + def->DecalGenerator = ScanTreeForName (v, Root); } } - // Free the array which is no longer needed! - for (i = 0; i < DecalNames.Size(); i++) - { - delete[] DecalNames[i]; - } - DecalNames.Clear(); - DecalNames.ShrinkToFit(); } void FDecalLib::ReadDecals () diff --git a/src/sc_man.h b/src/sc_man.h index 54246081e3..b94889b955 100644 --- a/src/sc_man.h +++ b/src/sc_man.h @@ -77,7 +77,6 @@ enum TK_For, TK_If, TK_Return, - TK_States, TK_Switch, TK_Until, TK_While, diff --git a/src/sc_man_scanner.h b/src/sc_man_scanner.h index 960d7aa925..a0664eda5b 100644 --- a/src/sc_man_scanner.h +++ b/src/sc_man_scanner.h @@ -145,67 +145,67 @@ yy2: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if(yych <= '.') { - if(yych == '*') goto yy605; + if(yych == '*') goto yy603; } else { - if(yych <= '/') goto yy603; - if(yych == '=') goto yy601; + if(yych <= '/') goto yy601; + if(yych == '=') goto yy599; } yy3: -#line 206 "src/sc_man_scanner.re" +#line 205 "src/sc_man_scanner.re" { RET('/'); } #line 157 "src/sc_man_scanner.h" yy4: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Y') { if(yych <= 'Q') { - if(yych == 'O') goto yy583; + if(yych == 'O') goto yy581; goto yy177; } else { - if(yych <= 'R') goto yy584; + if(yych <= 'R') goto yy582; if(yych <= 'X') goto yy177; - goto yy585; + goto yy583; } } else { if(yych <= 'q') { - if(yych == 'o') goto yy583; + if(yych == 'o') goto yy581; goto yy177; } else { - if(yych <= 'r') goto yy584; - if(yych == 'y') goto yy585; + if(yych <= 'r') goto yy582; + if(yych == 'y') goto yy583; goto yy177; } } yy5: -#line 152 "src/sc_man_scanner.re" +#line 151 "src/sc_man_scanner.re" { RET(TK_Identifier); } #line 182 "src/sc_man_scanner.h" yy6: yych = *++YYCURSOR; switch(yych){ case 'A': - case 'a': goto yy541; + case 'a': goto yy539; case 'H': - case 'h': goto yy542; + case 'h': goto yy540; case 'L': - case 'l': goto yy543; + case 'l': goto yy541; case 'O': - case 'o': goto yy544; + case 'o': goto yy542; case 'R': - case 'r': goto yy545; + case 'r': goto yy543; default: goto yy177; } yy7: yych = *++YYCURSOR; if(yych <= 'O') { - if(yych == 'E') goto yy514; + if(yych == 'E') goto yy512; if(yych <= 'N') goto yy177; - goto yy515; + goto yy513; } else { if(yych <= 'e') { if(yych <= 'd') goto yy177; - goto yy514; + goto yy512; } else { - if(yych == 'o') goto yy515; + if(yych == 'o') goto yy513; goto yy177; } } @@ -213,25 +213,25 @@ yy8: yych = *++YYCURSOR; if(yych <= 'X') { if(yych <= 'N') { - if(yych == 'L') goto yy479; + if(yych == 'L') goto yy477; if(yych <= 'M') goto yy177; - goto yy480; + goto yy478; } else { - if(yych == 'V') goto yy481; + if(yych == 'V') goto yy479; if(yych <= 'W') goto yy177; - goto yy482; + goto yy480; } } else { if(yych <= 'n') { - if(yych == 'l') goto yy479; + if(yych == 'l') goto yy477; if(yych <= 'm') goto yy177; - goto yy480; + goto yy478; } else { if(yych <= 'v') { if(yych <= 'u') goto yy177; - goto yy481; + goto yy479; } else { - if(yych == 'x') goto yy482; + if(yych == 'x') goto yy480; goto yy177; } } @@ -240,25 +240,25 @@ yy9: yych = *++YYCURSOR; if(yych <= 'O') { if(yych <= 'I') { - if(yych == 'A') goto yy456; + if(yych == 'A') goto yy454; if(yych <= 'H') goto yy177; - goto yy457; + goto yy455; } else { - if(yych == 'L') goto yy458; + if(yych == 'L') goto yy456; if(yych <= 'N') goto yy177; - goto yy459; + goto yy457; } } else { if(yych <= 'i') { - if(yych == 'a') goto yy456; + if(yych == 'a') goto yy454; if(yych <= 'h') goto yy177; - goto yy457; + goto yy455; } else { if(yych <= 'l') { if(yych <= 'k') goto yy177; - goto yy458; + goto yy456; } else { - if(yych == 'o') goto yy459; + if(yych == 'o') goto yy457; goto yy177; } } @@ -266,15 +266,15 @@ yy9: yy10: yych = *++YYCURSOR; if(yych <= 'O') { - if(yych == 'L') goto yy446; + if(yych == 'L') goto yy444; if(yych <= 'N') goto yy177; - goto yy447; + goto yy445; } else { if(yych <= 'l') { if(yych <= 'k') goto yy177; - goto yy446; + goto yy444; } else { - if(yych == 'o') goto yy447; + if(yych == 'o') goto yy445; goto yy177; } } @@ -283,29 +283,29 @@ yy11: if(yych <= 'T') { if(yych <= 'G') { if(yych <= 'E') goto yy177; - if(yych <= 'F') goto yy417; - goto yy419; + if(yych <= 'F') goto yy415; + goto yy417; } else { - if(yych == 'N') goto yy420; + if(yych == 'N') goto yy418; if(yych <= 'S') goto yy177; - goto yy421; + goto yy419; } } else { if(yych <= 'm') { if(yych <= 'e') goto yy177; - if(yych <= 'f') goto yy417; - if(yych <= 'g') goto yy419; + if(yych <= 'f') goto yy415; + if(yych <= 'g') goto yy417; goto yy177; } else { - if(yych <= 'n') goto yy420; - if(yych == 't') goto yy421; + if(yych <= 'n') goto yy418; + if(yych == 't') goto yy419; goto yy177; } } yy12: yych = *++YYCURSOR; - if(yych == 'E') goto yy409; - if(yych == 'e') goto yy409; + if(yych == 'E') goto yy407; + if(yych == 'e') goto yy407; goto yy177; yy13: yych = *++YYCURSOR; @@ -480,7 +480,7 @@ yy24: if(yych == 'I') goto yy178; if(yych == 'i') goto yy178; yy25: -#line 217 "src/sc_man_scanner.re" +#line 216 "src/sc_man_scanner.re" { SC_ScriptError ("Unexpected character: %c (ASCII %d)\n", *tok, *tok); goto std1; @@ -496,7 +496,7 @@ yy27: if(yych == 'x') goto yy173; goto yy172; yy28: -#line 155 "src/sc_man_scanner.re" +#line 154 "src/sc_man_scanner.re" { RET(TK_IntConst); } #line 502 "src/sc_man_scanner.h" yy29: @@ -510,7 +510,7 @@ yy30: if(yych <= '/') goto yy31; if(yych <= '9') goto yy143; yy31: -#line 199 "src/sc_man_scanner.re" +#line 198 "src/sc_man_scanner.re" { RET('.'); } #line 516 "src/sc_man_scanner.h" yy32: @@ -529,7 +529,7 @@ yy34: if(yych <= '=') goto yy117; if(yych <= '>') goto yy119; yy35: -#line 209 "src/sc_man_scanner.re" +#line 208 "src/sc_man_scanner.re" { RET('>'); } #line 535 "src/sc_man_scanner.h" yy36: @@ -538,120 +538,120 @@ yy36: if(yych <= '<') goto yy113; if(yych <= '=') goto yy111; yy37: -#line 208 "src/sc_man_scanner.re" +#line 207 "src/sc_man_scanner.re" { RET('<'); } #line 544 "src/sc_man_scanner.h" yy38: ++YYCURSOR; if((yych = *YYCURSOR) == '+') goto yy107; if(yych == '=') goto yy109; -#line 204 "src/sc_man_scanner.re" +#line 203 "src/sc_man_scanner.re" { RET('+'); } #line 551 "src/sc_man_scanner.h" yy40: ++YYCURSOR; if((yych = *YYCURSOR) == '-') goto yy103; if(yych == '=') goto yy105; -#line 203 "src/sc_man_scanner.re" +#line 202 "src/sc_man_scanner.re" { RET('-'); } #line 558 "src/sc_man_scanner.h" yy42: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy101; -#line 205 "src/sc_man_scanner.re" +#line 204 "src/sc_man_scanner.re" { RET('*'); } #line 564 "src/sc_man_scanner.h" yy44: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy99; -#line 207 "src/sc_man_scanner.re" +#line 206 "src/sc_man_scanner.re" { RET('%'); } #line 570 "src/sc_man_scanner.h" yy46: ++YYCURSOR; if((yych = *YYCURSOR) == '&') goto yy95; if(yych == '=') goto yy97; -#line 200 "src/sc_man_scanner.re" +#line 199 "src/sc_man_scanner.re" { RET('&'); } #line 577 "src/sc_man_scanner.h" yy48: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy93; -#line 210 "src/sc_man_scanner.re" +#line 209 "src/sc_man_scanner.re" { RET('^'); } #line 583 "src/sc_man_scanner.h" yy50: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy91; if(yych == '|') goto yy89; -#line 211 "src/sc_man_scanner.re" +#line 210 "src/sc_man_scanner.re" { RET('|'); } #line 590 "src/sc_man_scanner.h" yy52: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy87; -#line 194 "src/sc_man_scanner.re" +#line 193 "src/sc_man_scanner.re" { RET('='); } #line 596 "src/sc_man_scanner.h" yy54: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy85; -#line 201 "src/sc_man_scanner.re" +#line 200 "src/sc_man_scanner.re" { RET('!'); } #line 602 "src/sc_man_scanner.h" yy56: ++YYCURSOR; -#line 189 "src/sc_man_scanner.re" +#line 188 "src/sc_man_scanner.re" { RET(';'); } #line 607 "src/sc_man_scanner.h" yy58: ++YYCURSOR; -#line 190 "src/sc_man_scanner.re" +#line 189 "src/sc_man_scanner.re" { RET('{'); } #line 612 "src/sc_man_scanner.h" yy60: ++YYCURSOR; -#line 191 "src/sc_man_scanner.re" +#line 190 "src/sc_man_scanner.re" { RET('}'); } #line 617 "src/sc_man_scanner.h" yy62: ++YYCURSOR; -#line 192 "src/sc_man_scanner.re" +#line 191 "src/sc_man_scanner.re" { RET(','); } #line 622 "src/sc_man_scanner.h" yy64: ++YYCURSOR; -#line 193 "src/sc_man_scanner.re" +#line 192 "src/sc_man_scanner.re" { RET(':'); } #line 627 "src/sc_man_scanner.h" yy66: ++YYCURSOR; -#line 195 "src/sc_man_scanner.re" +#line 194 "src/sc_man_scanner.re" { RET('('); } #line 632 "src/sc_man_scanner.h" yy68: ++YYCURSOR; -#line 196 "src/sc_man_scanner.re" +#line 195 "src/sc_man_scanner.re" { RET(')'); } #line 637 "src/sc_man_scanner.h" yy70: ++YYCURSOR; -#line 197 "src/sc_man_scanner.re" +#line 196 "src/sc_man_scanner.re" { RET('['); } #line 642 "src/sc_man_scanner.h" yy72: ++YYCURSOR; -#line 198 "src/sc_man_scanner.re" +#line 197 "src/sc_man_scanner.re" { RET(']'); } #line 647 "src/sc_man_scanner.h" yy74: ++YYCURSOR; -#line 202 "src/sc_man_scanner.re" +#line 201 "src/sc_man_scanner.re" { RET('~'); } #line 652 "src/sc_man_scanner.h" yy76: ++YYCURSOR; -#line 212 "src/sc_man_scanner.re" +#line 211 "src/sc_man_scanner.re" { RET('?'); } #line 657 "src/sc_man_scanner.h" yy78: @@ -659,12 +659,12 @@ yy78: yych = *YYCURSOR; goto yy84; yy79: -#line 214 "src/sc_man_scanner.re" +#line 213 "src/sc_man_scanner.re" { goto std1; } #line 665 "src/sc_man_scanner.h" yy80: ++YYCURSOR; -#line 215 "src/sc_man_scanner.re" +#line 214 "src/sc_man_scanner.re" { goto newline; } #line 670 "src/sc_man_scanner.h" yy82: @@ -685,88 +685,88 @@ yy84: } yy85: ++YYCURSOR; -#line 188 "src/sc_man_scanner.re" +#line 187 "src/sc_man_scanner.re" { RET(TK_Neq); } #line 691 "src/sc_man_scanner.h" yy87: ++YYCURSOR; -#line 187 "src/sc_man_scanner.re" +#line 186 "src/sc_man_scanner.re" { RET(TK_Eq); } #line 696 "src/sc_man_scanner.h" yy89: ++YYCURSOR; -#line 184 "src/sc_man_scanner.re" +#line 183 "src/sc_man_scanner.re" { RET(TK_OrOr); } #line 701 "src/sc_man_scanner.h" yy91: ++YYCURSOR; -#line 177 "src/sc_man_scanner.re" +#line 176 "src/sc_man_scanner.re" { RET(TK_OrEq); } #line 706 "src/sc_man_scanner.h" yy93: ++YYCURSOR; -#line 176 "src/sc_man_scanner.re" +#line 175 "src/sc_man_scanner.re" { RET(TK_XorEq); } #line 711 "src/sc_man_scanner.h" yy95: ++YYCURSOR; -#line 183 "src/sc_man_scanner.re" +#line 182 "src/sc_man_scanner.re" { RET(TK_AndAnd); } #line 716 "src/sc_man_scanner.h" yy97: ++YYCURSOR; -#line 175 "src/sc_man_scanner.re" +#line 174 "src/sc_man_scanner.re" { RET(TK_AndEq); } #line 721 "src/sc_man_scanner.h" yy99: ++YYCURSOR; -#line 174 "src/sc_man_scanner.re" +#line 173 "src/sc_man_scanner.re" { RET(TK_ModEq); } #line 726 "src/sc_man_scanner.h" yy101: ++YYCURSOR; -#line 172 "src/sc_man_scanner.re" +#line 171 "src/sc_man_scanner.re" { RET(TK_MulEq); } #line 731 "src/sc_man_scanner.h" yy103: ++YYCURSOR; -#line 182 "src/sc_man_scanner.re" +#line 181 "src/sc_man_scanner.re" { RET(TK_Decr); } #line 736 "src/sc_man_scanner.h" yy105: ++YYCURSOR; -#line 171 "src/sc_man_scanner.re" +#line 170 "src/sc_man_scanner.re" { RET(TK_SubEq); } #line 741 "src/sc_man_scanner.h" yy107: ++YYCURSOR; -#line 181 "src/sc_man_scanner.re" +#line 180 "src/sc_man_scanner.re" { RET(TK_Incr); } #line 746 "src/sc_man_scanner.h" yy109: ++YYCURSOR; -#line 170 "src/sc_man_scanner.re" +#line 169 "src/sc_man_scanner.re" { RET(TK_AddEq); } #line 751 "src/sc_man_scanner.h" yy111: ++YYCURSOR; -#line 185 "src/sc_man_scanner.re" +#line 184 "src/sc_man_scanner.re" { RET(TK_Leq); } #line 756 "src/sc_man_scanner.h" yy113: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy115; -#line 180 "src/sc_man_scanner.re" +#line 179 "src/sc_man_scanner.re" { RET(TK_LShift); } #line 762 "src/sc_man_scanner.h" yy115: ++YYCURSOR; -#line 169 "src/sc_man_scanner.re" +#line 168 "src/sc_man_scanner.re" { RET(TK_LShiftEq); } #line 767 "src/sc_man_scanner.h" yy117: ++YYCURSOR; -#line 186 "src/sc_man_scanner.re" +#line 185 "src/sc_man_scanner.re" { RET(TK_Geq); } #line 772 "src/sc_man_scanner.h" yy119: @@ -775,23 +775,23 @@ yy119: if(yych <= '=') goto yy123; if(yych <= '>') goto yy121; yy120: -#line 179 "src/sc_man_scanner.re" +#line 178 "src/sc_man_scanner.re" { RET(TK_RShift); } #line 781 "src/sc_man_scanner.h" yy121: ++YYCURSOR; if((yych = *YYCURSOR) == '=') goto yy125; -#line 178 "src/sc_man_scanner.re" +#line 177 "src/sc_man_scanner.re" { RET(TK_URShift); } #line 787 "src/sc_man_scanner.h" yy123: ++YYCURSOR; -#line 168 "src/sc_man_scanner.re" +#line 167 "src/sc_man_scanner.re" { RET(TK_RShiftEq); } #line 792 "src/sc_man_scanner.h" yy125: ++YYCURSOR; -#line 167 "src/sc_man_scanner.re" +#line 166 "src/sc_man_scanner.re" { RET(TK_URShiftEq); } #line 797 "src/sc_man_scanner.h" yy127: @@ -823,7 +823,7 @@ yy129: } yy130: ++YYCURSOR; -#line 164 "src/sc_man_scanner.re" +#line 163 "src/sc_man_scanner.re" { RET(TK_NameConst); } #line 829 "src/sc_man_scanner.h" yy132: @@ -885,7 +885,7 @@ yy134: } yy135: ++YYCURSOR; -#line 161 "src/sc_man_scanner.re" +#line 160 "src/sc_man_scanner.re" { RET(TK_StringConst); } #line 891 "src/sc_man_scanner.h" yy137: @@ -971,7 +971,7 @@ yy143: } } yy145: -#line 158 "src/sc_man_scanner.re" +#line 157 "src/sc_man_scanner.re" { RET(TK_FloatConst); } #line 977 "src/sc_man_scanner.h" yy146: @@ -1016,7 +1016,7 @@ yy149: } yy151: ++YYCURSOR; -#line 166 "src/sc_man_scanner.re" +#line 165 "src/sc_man_scanner.re" { RET(TK_Ellipsis); } #line 1022 "src/sc_man_scanner.h" yy153: @@ -1307,7 +1307,7 @@ yy183: if(yych != 'e') goto yy129; yy184: ++YYCURSOR; -#line 147 "src/sc_man_scanner.re" +#line 146 "src/sc_man_scanner.re" { RET(TK_Include); } #line 1313 "src/sc_man_scanner.h" yy186: @@ -1361,7 +1361,7 @@ yy192: } } yy193: -#line 121 "src/sc_man_scanner.re" +#line 120 "src/sc_man_scanner.re" { RET(TK_Public); } #line 1367 "src/sc_man_scanner.h" yy194: @@ -1410,7 +1410,7 @@ yy199: } } yy200: -#line 123 "src/sc_man_scanner.re" +#line 122 "src/sc_man_scanner.re" { RET(TK_Private); } #line 1416 "src/sc_man_scanner.h" yy201: @@ -1453,7 +1453,7 @@ yy207: } } yy208: -#line 122 "src/sc_man_scanner.re" +#line 121 "src/sc_man_scanner.re" { RET(TK_Protected); } #line 1459 "src/sc_man_scanner.h" yy209: @@ -1491,7 +1491,7 @@ yy214: } } yy215: -#line 150 "src/sc_man_scanner.re" +#line 149 "src/sc_man_scanner.re" { RET(TK_Projectile); } #line 1497 "src/sc_man_scanner.h" yy216: @@ -1521,7 +1521,7 @@ yy219: } } yy220: -#line 148 "src/sc_man_scanner.re" +#line 147 "src/sc_man_scanner.re" { RET(TK_Pickup); } #line 1527 "src/sc_man_scanner.h" yy221: @@ -1548,7 +1548,7 @@ yy223: } } yy224: -#line 113 "src/sc_man_scanner.re" +#line 112 "src/sc_man_scanner.re" { RET(TK_Out); } #line 1554 "src/sc_man_scanner.h" yy225: @@ -1586,7 +1586,7 @@ yy230: } } yy231: -#line 133 "src/sc_man_scanner.re" +#line 132 "src/sc_man_scanner.re" { RET(TK_Optional); } #line 1592 "src/sc_man_scanner.h" yy232: @@ -1650,7 +1650,7 @@ yy241: } } yy242: -#line 117 "src/sc_man_scanner.re" +#line 116 "src/sc_man_scanner.re" { RET(TK_Transient); } #line 1656 "src/sc_man_scanner.h" yy243: @@ -1668,7 +1668,7 @@ yy243: } } yy244: -#line 104 "src/sc_man_scanner.re" +#line 103 "src/sc_man_scanner.re" { RET(TK_True); } #line 1674 "src/sc_man_scanner.h" yy245: @@ -1698,7 +1698,7 @@ yy248: } } yy249: -#line 119 "src/sc_man_scanner.re" +#line 118 "src/sc_man_scanner.re" { RET(TK_Throws); } #line 1704 "src/sc_man_scanner.h" yy250: @@ -1734,7 +1734,7 @@ yy254: } } yy255: -#line 109 "src/sc_man_scanner.re" +#line 108 "src/sc_man_scanner.re" { RET(TK_Auto); } #line 1740 "src/sc_man_scanner.h" yy256: @@ -1764,7 +1764,7 @@ yy259: } } yy260: -#line 144 "src/sc_man_scanner.re" +#line 143 "src/sc_man_scanner.re" { RET(TK_Action); } #line 1770 "src/sc_man_scanner.h" yy261: @@ -1802,7 +1802,7 @@ yy266: } } yy267: -#line 102 "src/sc_man_scanner.re" +#line 101 "src/sc_man_scanner.re" { RET(TK_Abstract); } #line 1808 "src/sc_man_scanner.h" yy268: @@ -1848,7 +1848,7 @@ yy272: } } yy273: -#line 106 "src/sc_man_scanner.re" +#line 105 "src/sc_man_scanner.re" { RET(TK_None); } #line 1854 "src/sc_man_scanner.h" yy274: @@ -1866,7 +1866,7 @@ yy274: } } yy275: -#line 107 "src/sc_man_scanner.re" +#line 106 "src/sc_man_scanner.re" { RET(TK_New); } #line 1872 "src/sc_man_scanner.h" yy276: @@ -1901,7 +1901,7 @@ yy280: } } yy281: -#line 112 "src/sc_man_scanner.re" +#line 111 "src/sc_man_scanner.re" { RET(TK_Native); } #line 1907 "src/sc_man_scanner.h" yy282: @@ -1919,7 +1919,7 @@ yy282: } } yy283: -#line 95 "src/sc_man_scanner.re" +#line 94 "src/sc_man_scanner.re" { RET(TK_Name); } #line 1925 "src/sc_man_scanner.h" yy284: @@ -1945,7 +1945,7 @@ yy286: } } yy287: -#line 93 "src/sc_man_scanner.re" +#line 92 "src/sc_man_scanner.re" { RET(TK_Mode); } #line 1951 "src/sc_man_scanner.h" yy288: @@ -2009,7 +2009,7 @@ yy297: } } yy298: -#line 127 "src/sc_man_scanner.re" +#line 126 "src/sc_man_scanner.re" { RET(TK_Localized); } #line 2015 "src/sc_man_scanner.h" yy299: @@ -2027,7 +2027,7 @@ yy299: } } yy300: -#line 88 "src/sc_man_scanner.re" +#line 87 "src/sc_man_scanner.re" { RET(TK_Long); } #line 2033 "src/sc_man_scanner.h" yy301: @@ -2057,7 +2057,7 @@ yy304: } } yy305: -#line 128 "src/sc_man_scanner.re" +#line 127 "src/sc_man_scanner.re" { RET(TK_Latent); } #line 2063 "src/sc_man_scanner.h" yy306: @@ -2087,7 +2087,7 @@ yy309: } } yy310: -#line 75 "src/sc_man_scanner.re" +#line 74 "src/sc_man_scanner.re" { RET(TK_While); } #line 2093 "src/sc_man_scanner.h" yy311: @@ -2131,7 +2131,7 @@ yy315: } } yy316: -#line 90 "src/sc_man_scanner.re" +#line 89 "src/sc_man_scanner.re" { RET(TK_Void); } #line 2137 "src/sc_man_scanner.h" yy317: @@ -2165,7 +2165,7 @@ yy321: } } yy322: -#line 74 "src/sc_man_scanner.re" +#line 73 "src/sc_man_scanner.re" { RET(TK_Volatile); } #line 2171 "src/sc_man_scanner.h" yy323: @@ -2199,7 +2199,7 @@ yy327: } } yy328: -#line 135 "src/sc_man_scanner.re" +#line 134 "src/sc_man_scanner.re" { RET(TK_Virtual); } #line 2205 "src/sc_man_scanner.h" yy329: @@ -2248,7 +2248,7 @@ yy336: } } yy337: -#line 85 "src/sc_man_scanner.re" +#line 84 "src/sc_man_scanner.re" { RET(TK_UShort); } #line 2254 "src/sc_man_scanner.h" yy338: @@ -2274,7 +2274,7 @@ yy340: } } yy341: -#line 73 "src/sc_man_scanner.re" +#line 72 "src/sc_man_scanner.re" { RET(TK_Until); } #line 2280 "src/sc_man_scanner.h" yy342: @@ -2300,7 +2300,7 @@ yy344: } } yy345: -#line 89 "src/sc_man_scanner.re" +#line 88 "src/sc_man_scanner.re" { RET(TK_ULong); } #line 2306 "src/sc_man_scanner.h" yy346: @@ -2322,52 +2322,52 @@ yy347: } } yy348: -#line 87 "src/sc_man_scanner.re" +#line 86 "src/sc_man_scanner.re" { RET(TK_UInt); } #line 2328 "src/sc_man_scanner.h" yy349: yych = *++YYCURSOR; - if(yych == 'Y') goto yy405; - if(yych == 'y') goto yy405; + if(yych == 'Y') goto yy403; + if(yych == 'y') goto yy403; goto yy177; yy350: yych = *++YYCURSOR; - if(yych == 'L') goto yy402; - if(yych == 'l') goto yy402; + if(yych == 'L') goto yy400; + if(yych == 'l') goto yy400; goto yy177; yy351: yych = *++YYCURSOR; - if(yych == 'O') goto yy398; - if(yych == 'o') goto yy398; + if(yych == 'O') goto yy396; + if(yych == 'o') goto yy396; goto yy177; yy352: yych = *++YYCURSOR; - if(yych == 'N') goto yy391; - if(yych == 'n') goto yy391; + if(yych == 'N') goto yy389; + if(yych == 'n') goto yy389; goto yy177; yy353: yych = *++YYCURSOR; - if(yych == 'U') goto yy387; - if(yych == 'u') goto yy387; + if(yych == 'U') goto yy385; + if(yych == 'u') goto yy385; goto yy177; yy354: yych = *++YYCURSOR; if(yych <= 'R') { if(yych <= 'N') { - if(yych == 'A') goto yy366; + if(yych == 'A') goto yy367; goto yy177; } else { if(yych <= 'O') goto yy368; if(yych <= 'Q') goto yy177; - goto yy367; + goto yy366; } } else { if(yych <= 'n') { - if(yych == 'a') goto yy366; + if(yych == 'a') goto yy367; goto yy177; } else { if(yych <= 'o') goto yy368; - if(yych == 'r') goto yy367; + if(yych == 'r') goto yy366; goto yy177; } } @@ -2407,7 +2407,7 @@ yy360: } } yy361: -#line 72 "src/sc_man_scanner.re" +#line 71 "src/sc_man_scanner.re" { RET(TK_Switch); } #line 2413 "src/sc_man_scanner.h" yy362: @@ -2433,29 +2433,29 @@ yy364: } } yy365: -#line 136 "src/sc_man_scanner.re" +#line 135 "src/sc_man_scanner.re" { RET(TK_Super); } #line 2439 "src/sc_man_scanner.h" yy366: - yych = *++YYCURSOR; - if(yych == 'T') goto yy379; - if(yych == 't') goto yy379; - goto yy177; -yy367: yych = *++YYCURSOR; if(yych <= 'U') { - if(yych == 'I') goto yy371; + if(yych == 'I') goto yy377; if(yych <= 'T') goto yy177; - goto yy372; + goto yy378; } else { if(yych <= 'i') { if(yych <= 'h') goto yy177; - goto yy371; + goto yy377; } else { - if(yych == 'u') goto yy372; + if(yych == 'u') goto yy378; goto yy177; } } +yy367: + yych = *++YYCURSOR; + if(yych == 'T') goto yy371; + if(yych == 't') goto yy371; + goto yy177; yy368: yych = *++YYCURSOR; if(yych == 'P') goto yy369; @@ -2475,102 +2475,98 @@ yy369: } } yy370: -#line 139 "src/sc_man_scanner.re" +#line 138 "src/sc_man_scanner.re" { RET(TK_Stop); } #line 2481 "src/sc_man_scanner.h" yy371: - yych = *++YYCURSOR; - if(yych == 'N') goto yy376; - if(yych == 'n') goto yy376; - goto yy177; -yy372: - yych = *++YYCURSOR; - if(yych == 'C') goto yy373; - if(yych != 'c') goto yy177; -yy373: - yych = *++YYCURSOR; - if(yych == 'T') goto yy374; - if(yych != 't') goto yy177; -yy374: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy375; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy375; - if(yych <= 'z') goto yy176; - } - } -yy375: -#line 91 "src/sc_man_scanner.re" - { RET(TK_Struct); } -#line 2512 "src/sc_man_scanner.h" -yy376: - yych = *++YYCURSOR; - if(yych == 'G') goto yy377; - if(yych != 'g') goto yy177; -yy377: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy378; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy378; - if(yych <= 'z') goto yy176; - } - } -yy378: -#line 96 "src/sc_man_scanner.re" - { RET(TK_String); } -#line 2534 "src/sc_man_scanner.h" -yy379: yych = *++YYCURSOR; if(yych <= 'I') { - if(yych == 'E') goto yy380; + if(yych == 'E') goto yy372; if(yych <= 'H') goto yy177; - goto yy382; + goto yy374; } else { if(yych <= 'e') { if(yych <= 'd') goto yy177; } else { - if(yych == 'i') goto yy382; + if(yych == 'i') goto yy374; goto yy177; } } +yy372: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy373; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy373; + if(yych <= 'z') goto yy176; + } + } +yy373: +#line 97 "src/sc_man_scanner.re" + { RET(TK_State); } +#line 2513 "src/sc_man_scanner.h" +yy374: + yych = *++YYCURSOR; + if(yych == 'C') goto yy375; + if(yych != 'c') goto yy177; +yy375: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy376; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy376; + if(yych <= 'z') goto yy176; + } + } +yy376: +#line 115 "src/sc_man_scanner.re" + { RET(TK_Static); } +#line 2535 "src/sc_man_scanner.h" +yy377: + yych = *++YYCURSOR; + if(yych == 'N') goto yy382; + if(yych == 'n') goto yy382; + goto yy177; +yy378: + yych = *++YYCURSOR; + if(yych == 'C') goto yy379; + if(yych != 'c') goto yy177; +yy379: + yych = *++YYCURSOR; + if(yych == 'T') goto yy380; + if(yych != 't') goto yy177; yy380: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '@') { - if(yych <= '/') goto yy381; - if(yych <= '9') goto yy176; - } else { - if(yych == 'S') goto yy385; - goto yy176; - } + if(yych <= '/') goto yy381; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; } else { - if(yych <= '`') { - if(yych == '_') goto yy176; + if(yych <= '_') { + if(yych >= '_') goto yy176; } else { - if(yych == 's') goto yy385; + if(yych <= '`') goto yy381; if(yych <= 'z') goto yy176; } } yy381: -#line 98 "src/sc_man_scanner.re" - { RET(TK_State); } -#line 2570 "src/sc_man_scanner.h" +#line 90 "src/sc_man_scanner.re" + { RET(TK_Struct); } +#line 2566 "src/sc_man_scanner.h" yy382: yych = *++YYCURSOR; - if(yych == 'C') goto yy383; - if(yych != 'c') goto yy177; + if(yych == 'G') goto yy383; + if(yych != 'g') goto yy177; yy383: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { @@ -2586,208 +2582,208 @@ yy383: } } yy384: -#line 116 "src/sc_man_scanner.re" - { RET(TK_Static); } -#line 2592 "src/sc_man_scanner.h" +#line 95 "src/sc_man_scanner.re" + { RET(TK_String); } +#line 2588 "src/sc_man_scanner.h" yy385: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy386; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy386; - if(yych <= 'z') goto yy176; - } - } -yy386: -#line 71 "src/sc_man_scanner.re" - { RET(TK_States); } -#line 2610 "src/sc_man_scanner.h" -yy387: yych = *++YYCURSOR; - if(yych == 'N') goto yy388; + if(yych == 'N') goto yy386; if(yych != 'n') goto yy177; -yy388: +yy386: yych = *++YYCURSOR; - if(yych == 'D') goto yy389; + if(yych == 'D') goto yy387; if(yych != 'd') goto yy177; -yy389: +yy387: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy390; + if(yych <= '/') goto yy388; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy390; + if(yych <= '`') goto yy388; if(yych <= 'z') goto yy176; } } -yy390: -#line 97 "src/sc_man_scanner.re" +yy388: +#line 96 "src/sc_man_scanner.re" { RET(TK_Sound); } -#line 2636 "src/sc_man_scanner.h" +#line 2614 "src/sc_man_scanner.h" +yy389: + yych = *++YYCURSOR; + if(yych == 'G') goto yy390; + if(yych != 'g') goto yy177; +yy390: + yych = *++YYCURSOR; + if(yych == 'U') goto yy391; + if(yych != 'u') goto yy177; yy391: yych = *++YYCURSOR; - if(yych == 'G') goto yy392; - if(yych != 'g') goto yy177; + if(yych == 'L') goto yy392; + if(yych != 'l') goto yy177; yy392: yych = *++YYCURSOR; - if(yych == 'U') goto yy393; - if(yych != 'u') goto yy177; + if(yych == 'A') goto yy393; + if(yych != 'a') goto yy177; yy393: yych = *++YYCURSOR; - if(yych == 'L') goto yy394; - if(yych != 'l') goto yy177; + if(yych == 'R') goto yy394; + if(yych != 'r') goto yy177; yy394: - yych = *++YYCURSOR; - if(yych == 'A') goto yy395; - if(yych != 'a') goto yy177; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy395; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy395; + if(yych <= 'z') goto yy176; + } + } yy395: - yych = *++YYCURSOR; - if(yych == 'R') goto yy396; - if(yych != 'r') goto yy177; -yy396: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy397; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy397; - if(yych <= 'z') goto yy176; - } - } -yy397: -#line 129 "src/sc_man_scanner.re" +#line 128 "src/sc_man_scanner.re" { RET(TK_Singular); } -#line 2674 "src/sc_man_scanner.h" -yy398: +#line 2652 "src/sc_man_scanner.h" +yy396: yych = *++YYCURSOR; - if(yych == 'R') goto yy399; + if(yych == 'R') goto yy397; if(yych != 'r') goto yy177; +yy397: + yych = *++YYCURSOR; + if(yych == 'T') goto yy398; + if(yych != 't') goto yy177; +yy398: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy399; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy399; + if(yych <= 'z') goto yy176; + } + } yy399: - yych = *++YYCURSOR; - if(yych == 'T') goto yy400; - if(yych != 't') goto yy177; -yy400: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy401; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy401; - if(yych <= 'z') goto yy176; - } - } -yy401: -#line 84 "src/sc_man_scanner.re" - { RET(TK_Short); } -#line 2700 "src/sc_man_scanner.h" -yy402: - yych = *++YYCURSOR; - if(yych == 'F') goto yy403; - if(yych != 'f') goto yy177; -yy403: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy404; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy404; - if(yych <= 'z') goto yy176; - } - } -yy404: -#line 138 "src/sc_man_scanner.re" - { RET(TK_Self); } -#line 2722 "src/sc_man_scanner.h" -yy405: - yych = *++YYCURSOR; - if(yych == 'T') goto yy406; - if(yych != 't') goto yy177; -yy406: - yych = *++YYCURSOR; - if(yych == 'E') goto yy407; - if(yych != 'e') goto yy177; -yy407: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy408; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy408; - if(yych <= 'z') goto yy176; - } - } -yy408: #line 83 "src/sc_man_scanner.re" + { RET(TK_Short); } +#line 2678 "src/sc_man_scanner.h" +yy400: + yych = *++YYCURSOR; + if(yych == 'F') goto yy401; + if(yych != 'f') goto yy177; +yy401: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy402; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy402; + if(yych <= 'z') goto yy176; + } + } +yy402: +#line 137 "src/sc_man_scanner.re" + { RET(TK_Self); } +#line 2700 "src/sc_man_scanner.h" +yy403: + yych = *++YYCURSOR; + if(yych == 'T') goto yy404; + if(yych != 't') goto yy177; +yy404: + yych = *++YYCURSOR; + if(yych == 'E') goto yy405; + if(yych != 'e') goto yy177; +yy405: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy406; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy406; + if(yych <= 'z') goto yy176; + } + } +yy406: +#line 82 "src/sc_man_scanner.re" { RET(TK_SByte); } -#line 2748 "src/sc_man_scanner.h" -yy409: +#line 2726 "src/sc_man_scanner.h" +yy407: yych = *++YYCURSOR; if(yych <= 'T') { - if(yych == 'F') goto yy411; + if(yych == 'F') goto yy409; if(yych <= 'S') goto yy177; } else { if(yych <= 'f') { if(yych <= 'e') goto yy177; - goto yy411; + goto yy409; } else { if(yych != 't') goto yy177; } } yych = *++YYCURSOR; - if(yych == 'U') goto yy413; - if(yych == 'u') goto yy413; + if(yych == 'U') goto yy411; + if(yych == 'u') goto yy411; goto yy177; -yy411: +yy409: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy412; + if(yych <= '/') goto yy410; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy412; + if(yych <= '`') goto yy410; if(yych <= 'z') goto yy176; } } -yy412: -#line 114 "src/sc_man_scanner.re" +yy410: +#line 113 "src/sc_man_scanner.re" { RET(TK_Ref); } -#line 2783 "src/sc_man_scanner.h" -yy413: +#line 2761 "src/sc_man_scanner.h" +yy411: yych = *++YYCURSOR; - if(yych == 'R') goto yy414; + if(yych == 'R') goto yy412; if(yych != 'r') goto yy177; -yy414: +yy412: yych = *++YYCURSOR; - if(yych == 'N') goto yy415; + if(yych == 'N') goto yy413; if(yych != 'n') goto yy177; +yy413: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy414; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy414; + if(yych <= 'z') goto yy176; + } + } +yy414: +#line 70 "src/sc_man_scanner.re" + { RET(TK_Return); } +#line 2787 "src/sc_man_scanner.h" yy415: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { @@ -2803,68 +2799,68 @@ yy415: } } yy416: -#line 70 "src/sc_man_scanner.re" - { RET(TK_Return); } -#line 2809 "src/sc_man_scanner.h" +#line 69 "src/sc_man_scanner.re" + { RET(TK_If); } +#line 2805 "src/sc_man_scanner.h" yy417: + yych = *++YYCURSOR; + if(yych == 'N') goto yy438; + if(yych == 'n') goto yy438; + goto yy177; +yy418: + yych = *++YYCURSOR; + if(yych <= 'T') { + if(yych <= 'R') goto yy177; + if(yych <= 'S') goto yy429; + goto yy427; + } else { + if(yych <= 'r') goto yy177; + if(yych <= 's') goto yy429; + if(yych <= 't') goto yy427; + goto yy177; + } +yy419: + yych = *++YYCURSOR; + if(yych == 'E') goto yy420; + if(yych != 'e') goto yy177; +yy420: + yych = *++YYCURSOR; + if(yych == 'R') goto yy421; + if(yych != 'r') goto yy177; +yy421: + yych = *++YYCURSOR; + if(yych == 'A') goto yy422; + if(yych != 'a') goto yy177; +yy422: + yych = *++YYCURSOR; + if(yych == 'T') goto yy423; + if(yych != 't') goto yy177; +yy423: + yych = *++YYCURSOR; + if(yych == 'O') goto yy424; + if(yych != 'o') goto yy177; +yy424: + yych = *++YYCURSOR; + if(yych == 'R') goto yy425; + if(yych != 'r') goto yy177; +yy425: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy418; + if(yych <= '/') goto yy426; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy418; + if(yych <= '`') goto yy426; if(yych <= 'z') goto yy176; } } -yy418: -#line 69 "src/sc_man_scanner.re" - { RET(TK_If); } -#line 2827 "src/sc_man_scanner.h" -yy419: - yych = *++YYCURSOR; - if(yych == 'N') goto yy440; - if(yych == 'n') goto yy440; - goto yy177; -yy420: - yych = *++YYCURSOR; - if(yych <= 'T') { - if(yych <= 'R') goto yy177; - if(yych <= 'S') goto yy431; - goto yy429; - } else { - if(yych <= 'r') goto yy177; - if(yych <= 's') goto yy431; - if(yych <= 't') goto yy429; - goto yy177; - } -yy421: - yych = *++YYCURSOR; - if(yych == 'E') goto yy422; - if(yych != 'e') goto yy177; -yy422: - yych = *++YYCURSOR; - if(yych == 'R') goto yy423; - if(yych != 'r') goto yy177; -yy423: - yych = *++YYCURSOR; - if(yych == 'A') goto yy424; - if(yych != 'a') goto yy177; -yy424: - yych = *++YYCURSOR; - if(yych == 'T') goto yy425; - if(yych != 't') goto yy177; -yy425: - yych = *++YYCURSOR; - if(yych == 'O') goto yy426; - if(yych != 'o') goto yy177; yy426: - yych = *++YYCURSOR; - if(yych == 'R') goto yy427; - if(yych != 'r') goto yy177; +#line 131 "src/sc_man_scanner.re" + { RET(TK_Iterator); } +#line 2864 "src/sc_man_scanner.h" yy427: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { @@ -2880,412 +2876,412 @@ yy427: } } yy428: -#line 132 "src/sc_man_scanner.re" - { RET(TK_Iterator); } -#line 2886 "src/sc_man_scanner.h" -yy429: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy430; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy430; - if(yych <= 'z') goto yy176; - } - } -yy430: -#line 86 "src/sc_man_scanner.re" +#line 85 "src/sc_man_scanner.re" { RET(TK_Int); } -#line 2904 "src/sc_man_scanner.h" +#line 2882 "src/sc_man_scanner.h" +yy429: + yych = *++YYCURSOR; + if(yych == 'T') goto yy430; + if(yych != 't') goto yy177; +yy430: + yych = *++YYCURSOR; + if(yych == 'A') goto yy431; + if(yych != 'a') goto yy177; yy431: yych = *++YYCURSOR; - if(yych == 'T') goto yy432; - if(yych != 't') goto yy177; + if(yych == 'N') goto yy432; + if(yych != 'n') goto yy177; yy432: yych = *++YYCURSOR; - if(yych == 'A') goto yy433; - if(yych != 'a') goto yy177; + if(yych == 'C') goto yy433; + if(yych != 'c') goto yy177; yy433: yych = *++YYCURSOR; - if(yych == 'N') goto yy434; - if(yych != 'n') goto yy177; + if(yych == 'E') goto yy434; + if(yych != 'e') goto yy177; yy434: yych = *++YYCURSOR; - if(yych == 'C') goto yy435; - if(yych != 'c') goto yy177; + if(yych == 'O') goto yy435; + if(yych != 'o') goto yy177; yy435: yych = *++YYCURSOR; - if(yych == 'E') goto yy436; - if(yych != 'e') goto yy177; -yy436: - yych = *++YYCURSOR; - if(yych == 'O') goto yy437; - if(yych != 'o') goto yy177; -yy437: - yych = *++YYCURSOR; - if(yych == 'F') goto yy438; + if(yych == 'F') goto yy436; if(yych != 'f') goto yy177; -yy438: +yy436: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy439; + if(yych <= '/') goto yy437; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy439; + if(yych <= '`') goto yy437; if(yych <= 'z') goto yy176; } } -yy439: -#line 108 "src/sc_man_scanner.re" +yy437: +#line 107 "src/sc_man_scanner.re" { RET(TK_InstanceOf); } -#line 2950 "src/sc_man_scanner.h" +#line 2928 "src/sc_man_scanner.h" +yy438: + yych = *++YYCURSOR; + if(yych == 'O') goto yy439; + if(yych != 'o') goto yy177; +yy439: + yych = *++YYCURSOR; + if(yych == 'R') goto yy440; + if(yych != 'r') goto yy177; yy440: yych = *++YYCURSOR; - if(yych == 'O') goto yy441; - if(yych != 'o') goto yy177; + if(yych == 'E') goto yy441; + if(yych != 'e') goto yy177; yy441: yych = *++YYCURSOR; - if(yych == 'R') goto yy442; - if(yych != 'r') goto yy177; -yy442: - yych = *++YYCURSOR; - if(yych == 'E') goto yy443; - if(yych != 'e') goto yy177; -yy443: - yych = *++YYCURSOR; - if(yych == 'S') goto yy444; + if(yych == 'S') goto yy442; if(yych != 's') goto yy177; -yy444: +yy442: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy445; + if(yych <= '/') goto yy443; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy445; + if(yych <= '`') goto yy443; if(yych <= 'z') goto yy176; } } -yy445: -#line 126 "src/sc_man_scanner.re" +yy443: +#line 125 "src/sc_man_scanner.re" { RET(TK_Ignores); } -#line 2984 "src/sc_man_scanner.h" -yy446: - yych = *++YYCURSOR; - if(yych == 'O') goto yy451; - if(yych == 'o') goto yy451; - goto yy177; -yy447: - yych = *++YYCURSOR; - if(yych == 'T') goto yy448; - if(yych != 't') goto yy177; -yy448: +#line 2962 "src/sc_man_scanner.h" +yy444: yych = *++YYCURSOR; if(yych == 'O') goto yy449; + if(yych == 'o') goto yy449; + goto yy177; +yy445: + yych = *++YYCURSOR; + if(yych == 'T') goto yy446; + if(yych != 't') goto yy177; +yy446: + yych = *++YYCURSOR; + if(yych == 'O') goto yy447; if(yych != 'o') goto yy177; -yy449: +yy447: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy450; + if(yych <= '/') goto yy448; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy450; + if(yych <= '`') goto yy448; if(yych <= 'z') goto yy176; } } -yy450: +yy448: #line 68 "src/sc_man_scanner.re" { RET(TK_Goto); } -#line 3015 "src/sc_man_scanner.h" +#line 2993 "src/sc_man_scanner.h" +yy449: + yych = *++YYCURSOR; + if(yych == 'B') goto yy450; + if(yych != 'b') goto yy177; +yy450: + yych = *++YYCURSOR; + if(yych == 'A') goto yy451; + if(yych != 'a') goto yy177; yy451: yych = *++YYCURSOR; - if(yych == 'B') goto yy452; - if(yych != 'b') goto yy177; -yy452: - yych = *++YYCURSOR; - if(yych == 'A') goto yy453; - if(yych != 'a') goto yy177; -yy453: - yych = *++YYCURSOR; - if(yych == 'L') goto yy454; + if(yych == 'L') goto yy452; if(yych != 'l') goto yy177; -yy454: +yy452: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy455; + if(yych <= '/') goto yy453; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy455; + if(yych <= '`') goto yy453; if(yych <= 'z') goto yy176; } } -yy455: -#line 137 "src/sc_man_scanner.re" +yy453: +#line 136 "src/sc_man_scanner.re" { RET(TK_Global); } -#line 3045 "src/sc_man_scanner.h" +#line 3023 "src/sc_man_scanner.h" +yy454: + yych = *++YYCURSOR; + if(yych == 'L') goto yy473; + if(yych == 'l') goto yy473; + goto yy177; +yy455: + yych = *++YYCURSOR; + if(yych == 'N') goto yy469; + if(yych == 'n') goto yy469; + goto yy177; yy456: yych = *++YYCURSOR; - if(yych == 'L') goto yy475; - if(yych == 'l') goto yy475; + if(yych == 'O') goto yy465; + if(yych == 'o') goto yy465; goto yy177; yy457: yych = *++YYCURSOR; - if(yych == 'N') goto yy471; - if(yych == 'n') goto yy471; - goto yy177; -yy458: - yych = *++YYCURSOR; - if(yych == 'O') goto yy467; - if(yych == 'o') goto yy467; - goto yy177; -yy459: - yych = *++YYCURSOR; - if(yych == 'R') goto yy460; + if(yych == 'R') goto yy458; if(yych != 'r') goto yy177; -yy460: +yy458: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { if(yych <= '@') { - if(yych <= '/') goto yy461; + if(yych <= '/') goto yy459; if(yych <= '9') goto yy176; } else { - if(yych == 'E') goto yy462; + if(yych == 'E') goto yy460; goto yy176; } } else { if(yych <= '`') { if(yych == '_') goto yy176; } else { - if(yych == 'e') goto yy462; + if(yych == 'e') goto yy460; if(yych <= 'z') goto yy176; } } -yy461: +yy459: #line 67 "src/sc_man_scanner.re" { RET(TK_For); } -#line 3086 "src/sc_man_scanner.h" +#line 3064 "src/sc_man_scanner.h" +yy460: + yych = *++YYCURSOR; + if(yych == 'A') goto yy461; + if(yych != 'a') goto yy177; +yy461: + yych = *++YYCURSOR; + if(yych == 'C') goto yy462; + if(yych != 'c') goto yy177; yy462: yych = *++YYCURSOR; - if(yych == 'A') goto yy463; - if(yych != 'a') goto yy177; -yy463: - yych = *++YYCURSOR; - if(yych == 'C') goto yy464; - if(yych != 'c') goto yy177; -yy464: - yych = *++YYCURSOR; - if(yych == 'H') goto yy465; + if(yych == 'H') goto yy463; if(yych != 'h') goto yy177; -yy465: +yy463: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy466; + if(yych <= '/') goto yy464; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy466; + if(yych <= '`') goto yy464; if(yych <= 'z') goto yy176; } } -yy466: -#line 103 "src/sc_man_scanner.re" +yy464: +#line 102 "src/sc_man_scanner.re" { RET(TK_ForEach); } -#line 3116 "src/sc_man_scanner.h" -yy467: +#line 3094 "src/sc_man_scanner.h" +yy465: yych = *++YYCURSOR; - if(yych == 'A') goto yy468; + if(yych == 'A') goto yy466; if(yych != 'a') goto yy177; -yy468: +yy466: yych = *++YYCURSOR; - if(yych == 'T') goto yy469; + if(yych == 'T') goto yy467; if(yych != 't') goto yy177; -yy469: +yy467: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy470; + if(yych <= '/') goto yy468; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy470; + if(yych <= '`') goto yy468; if(yych <= 'z') goto yy176; } } -yy470: -#line 79 "src/sc_man_scanner.re" +yy468: +#line 78 "src/sc_man_scanner.re" { RET(TK_Float); } -#line 3142 "src/sc_man_scanner.h" -yy471: +#line 3120 "src/sc_man_scanner.h" +yy469: yych = *++YYCURSOR; - if(yych == 'A') goto yy472; + if(yych == 'A') goto yy470; if(yych != 'a') goto yy177; -yy472: +yy470: yych = *++YYCURSOR; - if(yych == 'L') goto yy473; + if(yych == 'L') goto yy471; if(yych != 'l') goto yy177; -yy473: +yy471: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy474; + if(yych <= '/') goto yy472; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy474; + if(yych <= '`') goto yy472; if(yych <= 'z') goto yy176; } } -yy474: -#line 118 "src/sc_man_scanner.re" +yy472: +#line 117 "src/sc_man_scanner.re" { RET(TK_Final); } -#line 3168 "src/sc_man_scanner.h" -yy475: +#line 3146 "src/sc_man_scanner.h" +yy473: yych = *++YYCURSOR; - if(yych == 'S') goto yy476; + if(yych == 'S') goto yy474; if(yych != 's') goto yy177; -yy476: +yy474: yych = *++YYCURSOR; - if(yych == 'E') goto yy477; + if(yych == 'E') goto yy475; if(yych != 'e') goto yy177; -yy477: +yy475: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy478; + if(yych <= '/') goto yy476; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy478; + if(yych <= '`') goto yy476; if(yych <= 'z') goto yy176; } } -yy478: -#line 105 "src/sc_man_scanner.re" +yy476: +#line 104 "src/sc_man_scanner.re" { RET(TK_False); } -#line 3194 "src/sc_man_scanner.h" +#line 3172 "src/sc_man_scanner.h" +yy477: + yych = *++YYCURSOR; + if(yych == 'S') goto yy509; + if(yych == 's') goto yy509; + goto yy177; +yy478: + yych = *++YYCURSOR; + if(yych == 'U') goto yy506; + if(yych == 'u') goto yy506; + goto yy177; yy479: - yych = *++YYCURSOR; - if(yych == 'S') goto yy511; - if(yych == 's') goto yy511; - goto yy177; -yy480: - yych = *++YYCURSOR; - if(yych == 'U') goto yy508; - if(yych == 'u') goto yy508; - goto yy177; -yy481: yych = *++YYCURSOR; if(yych <= 'E') { - if(yych == 'A') goto yy498; + if(yych == 'A') goto yy496; if(yych <= 'D') goto yy177; - goto yy497; + goto yy495; } else { if(yych <= 'a') { if(yych <= '`') goto yy177; - goto yy498; + goto yy496; } else { - if(yych == 'e') goto yy497; + if(yych == 'e') goto yy495; goto yy177; } } -yy482: +yy480: yych = *++YYCURSOR; if(yych <= 'T') { if(yych <= 'O') { if(yych != 'E') goto yy177; } else { - if(yych <= 'P') goto yy485; + if(yych <= 'P') goto yy483; if(yych <= 'S') goto yy177; - goto yy484; + goto yy482; } } else { if(yych <= 'o') { if(yych != 'e') goto yy177; } else { - if(yych <= 'p') goto yy485; - if(yych == 't') goto yy484; + if(yych <= 'p') goto yy483; + if(yych == 't') goto yy482; goto yy177; } } yych = *++YYCURSOR; - if(yych == 'C') goto yy495; - if(yych == 'c') goto yy495; + if(yych == 'C') goto yy493; + if(yych == 'c') goto yy493; goto yy177; +yy482: + yych = *++YYCURSOR; + if(yych == 'E') goto yy488; + if(yych == 'e') goto yy488; + goto yy177; +yy483: + yych = *++YYCURSOR; + if(yych == 'O') goto yy484; + if(yych != 'o') goto yy177; yy484: yych = *++YYCURSOR; - if(yych == 'E') goto yy490; - if(yych == 'e') goto yy490; - goto yy177; + if(yych == 'R') goto yy485; + if(yych != 'r') goto yy177; yy485: yych = *++YYCURSOR; - if(yych == 'O') goto yy486; - if(yych != 'o') goto yy177; -yy486: - yych = *++YYCURSOR; - if(yych == 'R') goto yy487; - if(yych != 'r') goto yy177; -yy487: - yych = *++YYCURSOR; - if(yych == 'T') goto yy488; + if(yych == 'T') goto yy486; if(yych != 't') goto yy177; -yy488: +yy486: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy489; + if(yych <= '/') goto yy487; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy489; + if(yych <= '`') goto yy487; if(yych <= 'z') goto yy176; } } -yy489: -#line 134 "src/sc_man_scanner.re" +yy487: +#line 133 "src/sc_man_scanner.re" { RET(TK_Export); } -#line 3277 "src/sc_man_scanner.h" +#line 3255 "src/sc_man_scanner.h" +yy488: + yych = *++YYCURSOR; + if(yych == 'N') goto yy489; + if(yych != 'n') goto yy177; +yy489: + yych = *++YYCURSOR; + if(yych == 'D') goto yy490; + if(yych != 'd') goto yy177; yy490: yych = *++YYCURSOR; - if(yych == 'N') goto yy491; - if(yych != 'n') goto yy177; -yy491: - yych = *++YYCURSOR; - if(yych == 'D') goto yy492; - if(yych != 'd') goto yy177; -yy492: - yych = *++YYCURSOR; - if(yych == 'S') goto yy493; + if(yych == 'S') goto yy491; if(yych != 's') goto yy177; +yy491: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy492; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy492; + if(yych <= 'z') goto yy176; + } + } +yy492: +#line 119 "src/sc_man_scanner.re" + { RET(TK_Extends); } +#line 3285 "src/sc_man_scanner.h" yy493: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { @@ -3301,165 +3297,147 @@ yy493: } } yy494: -#line 120 "src/sc_man_scanner.re" - { RET(TK_Extends); } -#line 3307 "src/sc_man_scanner.h" -yy495: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy496; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy496; - if(yych <= 'z') goto yy176; - } - } -yy496: -#line 110 "src/sc_man_scanner.re" +#line 109 "src/sc_man_scanner.re" { RET(TK_Exec); } -#line 3325 "src/sc_man_scanner.h" -yy497: +#line 3303 "src/sc_man_scanner.h" +yy495: yych = *++YYCURSOR; - if(yych == 'N') goto yy505; - if(yych == 'n') goto yy505; + if(yych == 'N') goto yy503; + if(yych == 'n') goto yy503; goto yy177; -yy498: +yy496: yych = *++YYCURSOR; - if(yych == 'L') goto yy499; + if(yych == 'L') goto yy497; if(yych != 'l') goto yy177; -yy499: +yy497: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { if(yych <= '@') { - if(yych <= '/') goto yy500; + if(yych <= '/') goto yy498; if(yych <= '9') goto yy176; } else { - if(yych == 'N') goto yy501; + if(yych == 'N') goto yy499; goto yy176; } } else { if(yych <= '`') { if(yych == '_') goto yy176; } else { - if(yych == 'n') goto yy501; + if(yych == 'n') goto yy499; if(yych <= 'z') goto yy176; } } -yy500: -#line 142 "src/sc_man_scanner.re" +yy498: +#line 141 "src/sc_man_scanner.re" { RET(TK_Eval); } -#line 3356 "src/sc_man_scanner.h" -yy501: +#line 3334 "src/sc_man_scanner.h" +yy499: yych = *++YYCURSOR; - if(yych == 'O') goto yy502; + if(yych == 'O') goto yy500; if(yych != 'o') goto yy177; +yy500: + yych = *++YYCURSOR; + if(yych == 'T') goto yy501; + if(yych != 't') goto yy177; +yy501: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy502; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy502; + if(yych <= 'z') goto yy176; + } + } yy502: - yych = *++YYCURSOR; - if(yych == 'T') goto yy503; - if(yych != 't') goto yy177; -yy503: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy504; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy504; - if(yych <= 'z') goto yy176; - } - } -yy504: -#line 143 "src/sc_man_scanner.re" +#line 142 "src/sc_man_scanner.re" { RET(TK_EvalNot); } -#line 3382 "src/sc_man_scanner.h" -yy505: +#line 3360 "src/sc_man_scanner.h" +yy503: yych = *++YYCURSOR; - if(yych == 'T') goto yy506; + if(yych == 'T') goto yy504; if(yych != 't') goto yy177; -yy506: +yy504: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy507; + if(yych <= '/') goto yy505; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy507; + if(yych <= '`') goto yy505; if(yych <= 'z') goto yy176; } } -yy507: -#line 115 "src/sc_man_scanner.re" +yy505: +#line 114 "src/sc_man_scanner.re" { RET(TK_Event); } -#line 3404 "src/sc_man_scanner.h" -yy508: +#line 3382 "src/sc_man_scanner.h" +yy506: yych = *++YYCURSOR; - if(yych == 'M') goto yy509; + if(yych == 'M') goto yy507; if(yych != 'm') goto yy177; -yy509: +yy507: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy510; + if(yych <= '/') goto yy508; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy510; + if(yych <= '`') goto yy508; if(yych <= 'z') goto yy176; } } -yy510: -#line 94 "src/sc_man_scanner.re" +yy508: +#line 93 "src/sc_man_scanner.re" { RET(TK_Enum); } -#line 3426 "src/sc_man_scanner.h" -yy511: +#line 3404 "src/sc_man_scanner.h" +yy509: yych = *++YYCURSOR; - if(yych == 'E') goto yy512; + if(yych == 'E') goto yy510; if(yych != 'e') goto yy177; -yy512: +yy510: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy513; + if(yych <= '/') goto yy511; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy513; + if(yych <= '`') goto yy511; if(yych <= 'z') goto yy176; } } -yy513: +yy511: #line 66 "src/sc_man_scanner.re" { RET(TK_Else); } -#line 3448 "src/sc_man_scanner.h" -yy514: +#line 3426 "src/sc_man_scanner.h" +yy512: yych = *++YYCURSOR; - if(yych == 'F') goto yy524; - if(yych == 'f') goto yy524; + if(yych == 'F') goto yy522; + if(yych == 'f') goto yy522; goto yy177; -yy515: +yy513: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { if(yych <= '@') { - if(yych <= '/') goto yy516; + if(yych <= '/') goto yy514; if(yych <= '9') goto yy176; } else { if(yych <= 'S') goto yy176; - if(yych <= 'T') goto yy518; - if(yych <= 'U') goto yy517; + if(yych <= 'T') goto yy516; + if(yych <= 'U') goto yy515; goto yy176; } } else { @@ -3467,326 +3445,344 @@ yy515: if(yych == '_') goto yy176; if(yych >= 'a') goto yy176; } else { - if(yych <= 't') goto yy518; - if(yych <= 'u') goto yy517; + if(yych <= 't') goto yy516; + if(yych <= 'u') goto yy515; if(yych <= 'z') goto yy176; } } -yy516: +yy514: #line 65 "src/sc_man_scanner.re" { RET(TK_Do); } -#line 3479 "src/sc_man_scanner.h" -yy517: +#line 3457 "src/sc_man_scanner.h" +yy515: yych = *++YYCURSOR; - if(yych == 'B') goto yy520; - if(yych == 'b') goto yy520; + if(yych == 'B') goto yy518; + if(yych == 'b') goto yy518; goto yy177; -yy518: +yy516: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy519; + if(yych <= '/') goto yy517; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy519; + if(yych <= '`') goto yy517; if(yych <= 'z') goto yy176; } } -yy519: -#line 124 "src/sc_man_scanner.re" +yy517: +#line 123 "src/sc_man_scanner.re" { RET(TK_Dot); } -#line 3502 "src/sc_man_scanner.h" -yy520: +#line 3480 "src/sc_man_scanner.h" +yy518: yych = *++YYCURSOR; - if(yych == 'L') goto yy521; + if(yych == 'L') goto yy519; if(yych != 'l') goto yy177; -yy521: +yy519: yych = *++YYCURSOR; - if(yych == 'E') goto yy522; + if(yych == 'E') goto yy520; if(yych != 'e') goto yy177; -yy522: +yy520: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy523; + if(yych <= '/') goto yy521; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy523; + if(yych <= '`') goto yy521; if(yych <= 'z') goto yy176; } } -yy523: -#line 80 "src/sc_man_scanner.re" +yy521: +#line 79 "src/sc_man_scanner.re" { RET(TK_Double); } -#line 3528 "src/sc_man_scanner.h" +#line 3506 "src/sc_man_scanner.h" +yy522: + yych = *++YYCURSOR; + if(yych == 'A') goto yy523; + if(yych != 'a') goto yy177; +yy523: + yych = *++YYCURSOR; + if(yych == 'U') goto yy524; + if(yych != 'u') goto yy177; yy524: yych = *++YYCURSOR; - if(yych == 'A') goto yy525; - if(yych != 'a') goto yy177; + if(yych == 'L') goto yy525; + if(yych != 'l') goto yy177; yy525: yych = *++YYCURSOR; - if(yych == 'U') goto yy526; - if(yych != 'u') goto yy177; -yy526: - yych = *++YYCURSOR; - if(yych == 'L') goto yy527; - if(yych != 'l') goto yy177; -yy527: - yych = *++YYCURSOR; - if(yych == 'T') goto yy528; + if(yych == 'T') goto yy526; if(yych != 't') goto yy177; -yy528: +yy526: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { if(yych <= '@') { - if(yych <= '/') goto yy529; + if(yych <= '/') goto yy527; if(yych <= '9') goto yy176; } else { - if(yych == 'P') goto yy530; + if(yych == 'P') goto yy528; goto yy176; } } else { if(yych <= '`') { if(yych == '_') goto yy176; } else { - if(yych == 'p') goto yy530; + if(yych == 'p') goto yy528; if(yych <= 'z') goto yy176; } } -yy529: +yy527: #line 64 "src/sc_man_scanner.re" { RET(TK_Default); } -#line 3566 "src/sc_man_scanner.h" +#line 3544 "src/sc_man_scanner.h" +yy528: + yych = *++YYCURSOR; + if(yych == 'R') goto yy529; + if(yych != 'r') goto yy177; +yy529: + yych = *++YYCURSOR; + if(yych == 'O') goto yy530; + if(yych != 'o') goto yy177; yy530: yych = *++YYCURSOR; - if(yych == 'R') goto yy531; - if(yych != 'r') goto yy177; + if(yych == 'P') goto yy531; + if(yych != 'p') goto yy177; yy531: yych = *++YYCURSOR; - if(yych == 'O') goto yy532; - if(yych != 'o') goto yy177; + if(yych == 'E') goto yy532; + if(yych != 'e') goto yy177; yy532: yych = *++YYCURSOR; - if(yych == 'P') goto yy533; - if(yych != 'p') goto yy177; + if(yych == 'R') goto yy533; + if(yych != 'r') goto yy177; yy533: yych = *++YYCURSOR; - if(yych == 'E') goto yy534; - if(yych != 'e') goto yy177; + if(yych == 'T') goto yy534; + if(yych != 't') goto yy177; yy534: yych = *++YYCURSOR; - if(yych == 'R') goto yy535; - if(yych != 'r') goto yy177; + if(yych == 'I') goto yy535; + if(yych != 'i') goto yy177; yy535: yych = *++YYCURSOR; - if(yych == 'T') goto yy536; - if(yych != 't') goto yy177; + if(yych == 'E') goto yy536; + if(yych != 'e') goto yy177; yy536: yych = *++YYCURSOR; - if(yych == 'I') goto yy537; - if(yych != 'i') goto yy177; -yy537: - yych = *++YYCURSOR; - if(yych == 'E') goto yy538; - if(yych != 'e') goto yy177; -yy538: - yych = *++YYCURSOR; - if(yych == 'S') goto yy539; + if(yych == 'S') goto yy537; if(yych != 's') goto yy177; -yy539: +yy537: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy540; + if(yych <= '/') goto yy538; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy540; + if(yych <= '`') goto yy538; if(yych <= 'z') goto yy176; } } -yy540: -#line 111 "src/sc_man_scanner.re" +yy538: +#line 110 "src/sc_man_scanner.re" { RET(TK_DefaultProperties); } -#line 3620 "src/sc_man_scanner.h" +#line 3598 "src/sc_man_scanner.h" +yy539: + yych = *++YYCURSOR; + if(yych == 'S') goto yy578; + if(yych == 's') goto yy578; + goto yy177; +yy540: + yych = *++YYCURSOR; + if(yych == 'A') goto yy575; + if(yych == 'a') goto yy575; + goto yy177; yy541: yych = *++YYCURSOR; - if(yych == 'S') goto yy580; - if(yych == 's') goto yy580; + if(yych == 'A') goto yy571; + if(yych == 'a') goto yy571; goto yy177; yy542: - yych = *++YYCURSOR; - if(yych == 'A') goto yy577; - if(yych == 'a') goto yy577; - goto yy177; -yy543: - yych = *++YYCURSOR; - if(yych == 'A') goto yy573; - if(yych == 'a') goto yy573; - goto yy177; -yy544: yych = *++YYCURSOR; if(yych <= 'N') { if(yych <= 'K') { - if(yych == 'E') goto yy552; + if(yych == 'E') goto yy550; goto yy177; } else { - if(yych <= 'L') goto yy551; + if(yych <= 'L') goto yy549; if(yych <= 'M') goto yy177; - goto yy550; + goto yy548; } } else { if(yych <= 'k') { - if(yych == 'e') goto yy552; + if(yych == 'e') goto yy550; goto yy177; } else { - if(yych <= 'l') goto yy551; - if(yych == 'n') goto yy550; + if(yych <= 'l') goto yy549; + if(yych == 'n') goto yy548; goto yy177; } } +yy543: + yych = *++YYCURSOR; + if(yych == 'O') goto yy544; + if(yych != 'o') goto yy177; +yy544: + yych = *++YYCURSOR; + if(yych == 'S') goto yy545; + if(yych != 's') goto yy177; yy545: yych = *++YYCURSOR; - if(yych == 'O') goto yy546; - if(yych != 'o') goto yy177; + if(yych == 'S') goto yy546; + if(yych != 's') goto yy177; yy546: - yych = *++YYCURSOR; - if(yych == 'S') goto yy547; - if(yych != 's') goto yy177; -yy547: - yych = *++YYCURSOR; - if(yych == 'S') goto yy548; - if(yych != 's') goto yy177; -yy548: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy549; + if(yych <= '/') goto yy547; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy549; + if(yych <= '`') goto yy547; if(yych <= 'z') goto yy176; } } -yy549: -#line 125 "src/sc_man_scanner.re" +yy547: +#line 124 "src/sc_man_scanner.re" { RET(TK_Cross); } -#line 3686 "src/sc_man_scanner.h" -yy550: +#line 3664 "src/sc_man_scanner.h" +yy548: yych = *++YYCURSOR; if(yych <= 'T') { if(yych <= 'F') { if(yych <= 'E') goto yy177; - goto yy560; + goto yy558; } else { if(yych <= 'R') goto yy177; - if(yych <= 'S') goto yy561; - goto yy562; + if(yych <= 'S') goto yy559; + goto yy560; } } else { if(yych <= 'r') { - if(yych == 'f') goto yy560; + if(yych == 'f') goto yy558; goto yy177; } else { - if(yych <= 's') goto yy561; - if(yych <= 't') goto yy562; + if(yych <= 's') goto yy559; + if(yych <= 't') goto yy560; goto yy177; } } +yy549: + yych = *++YYCURSOR; + if(yych == 'O') goto yy555; + if(yych == 'o') goto yy555; + goto yy177; +yy550: + yych = *++YYCURSOR; + if(yych == 'R') goto yy551; + if(yych != 'r') goto yy177; yy551: yych = *++YYCURSOR; - if(yych == 'O') goto yy557; - if(yych == 'o') goto yy557; - goto yy177; + if(yych == 'C') goto yy552; + if(yych != 'c') goto yy177; yy552: yych = *++YYCURSOR; - if(yych == 'R') goto yy553; - if(yych != 'r') goto yy177; -yy553: - yych = *++YYCURSOR; - if(yych == 'C') goto yy554; - if(yych != 'c') goto yy177; -yy554: - yych = *++YYCURSOR; - if(yych == 'E') goto yy555; + if(yych == 'E') goto yy553; if(yych != 'e') goto yy177; -yy555: +yy553: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy556; + if(yych <= '/') goto yy554; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy556; + if(yych <= '`') goto yy554; if(yych <= 'z') goto yy176; } } -yy556: -#line 131 "src/sc_man_scanner.re" +yy554: +#line 130 "src/sc_man_scanner.re" { RET(TK_Coerce); } -#line 3742 "src/sc_man_scanner.h" -yy557: +#line 3720 "src/sc_man_scanner.h" +yy555: yych = *++YYCURSOR; - if(yych == 'R') goto yy558; + if(yych == 'R') goto yy556; if(yych != 'r') goto yy177; -yy558: +yy556: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy559; + if(yych <= '/') goto yy557; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy559; + if(yych <= '`') goto yy557; if(yych <= 'z') goto yy176; } } -yy559: -#line 99 "src/sc_man_scanner.re" +yy557: +#line 98 "src/sc_man_scanner.re" { RET(TK_Color); } -#line 3764 "src/sc_man_scanner.h" +#line 3742 "src/sc_man_scanner.h" +yy558: + yych = *++YYCURSOR; + if(yych == 'I') goto yy568; + if(yych == 'i') goto yy568; + goto yy177; +yy559: + yych = *++YYCURSOR; + if(yych == 'T') goto yy566; + if(yych == 't') goto yy566; + goto yy177; yy560: yych = *++YYCURSOR; - if(yych == 'I') goto yy570; - if(yych == 'i') goto yy570; - goto yy177; + if(yych == 'I') goto yy561; + if(yych != 'i') goto yy177; yy561: yych = *++YYCURSOR; - if(yych == 'T') goto yy568; - if(yych == 't') goto yy568; - goto yy177; + if(yych == 'N') goto yy562; + if(yych != 'n') goto yy177; yy562: yych = *++YYCURSOR; - if(yych == 'I') goto yy563; - if(yych != 'i') goto yy177; + if(yych == 'U') goto yy563; + if(yych != 'u') goto yy177; yy563: yych = *++YYCURSOR; - if(yych == 'N') goto yy564; - if(yych != 'n') goto yy177; -yy564: - yych = *++YYCURSOR; - if(yych == 'U') goto yy565; - if(yych != 'u') goto yy177; -yy565: - yych = *++YYCURSOR; - if(yych == 'E') goto yy566; + if(yych == 'E') goto yy564; if(yych != 'e') goto yy177; +yy564: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy565; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy565; + if(yych <= 'z') goto yy176; + } + } +yy565: +#line 63 "src/sc_man_scanner.re" + { RET(TK_Continue); } +#line 3786 "src/sc_man_scanner.h" yy566: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { @@ -3802,266 +3798,248 @@ yy566: } } yy567: -#line 63 "src/sc_man_scanner.re" - { RET(TK_Continue); } -#line 3808 "src/sc_man_scanner.h" -yy568: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy569; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy569; - if(yych <= 'z') goto yy176; - } - } -yy569: #line 62 "src/sc_man_scanner.re" { RET(TK_Const); } -#line 3826 "src/sc_man_scanner.h" -yy570: +#line 3804 "src/sc_man_scanner.h" +yy568: yych = *++YYCURSOR; - if(yych == 'G') goto yy571; + if(yych == 'G') goto yy569; if(yych != 'g') goto yy177; -yy571: +yy569: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy572; + if(yych <= '/') goto yy570; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy572; + if(yych <= '`') goto yy570; if(yych <= 'z') goto yy176; } } -yy572: -#line 130 "src/sc_man_scanner.re" +yy570: +#line 129 "src/sc_man_scanner.re" { RET(TK_Config); } -#line 3848 "src/sc_man_scanner.h" +#line 3826 "src/sc_man_scanner.h" +yy571: + yych = *++YYCURSOR; + if(yych == 'S') goto yy572; + if(yych != 's') goto yy177; +yy572: + yych = *++YYCURSOR; + if(yych == 'S') goto yy573; + if(yych != 's') goto yy177; yy573: - yych = *++YYCURSOR; - if(yych == 'S') goto yy574; - if(yych != 's') goto yy177; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy574; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy574; + if(yych <= 'z') goto yy176; + } + } yy574: - yych = *++YYCURSOR; - if(yych == 'S') goto yy575; - if(yych != 's') goto yy177; -yy575: - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy576; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy576; - if(yych <= 'z') goto yy176; - } - } -yy576: -#line 92 "src/sc_man_scanner.re" +#line 91 "src/sc_man_scanner.re" { RET(TK_Class); } -#line 3874 "src/sc_man_scanner.h" -yy577: +#line 3852 "src/sc_man_scanner.h" +yy575: yych = *++YYCURSOR; - if(yych == 'R') goto yy578; + if(yych == 'R') goto yy576; if(yych != 'r') goto yy177; -yy578: +yy576: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy579; + if(yych <= '/') goto yy577; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy579; + if(yych <= '`') goto yy577; if(yych <= 'z') goto yy176; } } -yy579: -#line 81 "src/sc_man_scanner.re" +yy577: +#line 80 "src/sc_man_scanner.re" { RET(TK_Char); } -#line 3896 "src/sc_man_scanner.h" -yy580: +#line 3874 "src/sc_man_scanner.h" +yy578: yych = *++YYCURSOR; - if(yych == 'E') goto yy581; + if(yych == 'E') goto yy579; if(yych != 'e') goto yy177; -yy581: +yy579: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy582; + if(yych <= '/') goto yy580; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy582; + if(yych <= '`') goto yy580; if(yych <= 'z') goto yy176; } } -yy582: +yy580: #line 61 "src/sc_man_scanner.re" { RET(TK_Case); } -#line 3918 "src/sc_man_scanner.h" -yy583: +#line 3896 "src/sc_man_scanner.h" +yy581: yych = *++YYCURSOR; - if(yych == 'O') goto yy598; - if(yych == 'o') goto yy598; + if(yych == 'O') goto yy596; + if(yych == 'o') goto yy596; goto yy177; -yy584: - yych = *++YYCURSOR; - if(yych == 'E') goto yy589; - if(yych == 'e') goto yy589; - goto yy177; -yy585: - yych = *++YYCURSOR; - if(yych == 'T') goto yy586; - if(yych != 't') goto yy177; -yy586: +yy582: yych = *++YYCURSOR; if(yych == 'E') goto yy587; + if(yych == 'e') goto yy587; + goto yy177; +yy583: + yych = *++YYCURSOR; + if(yych == 'T') goto yy584; + if(yych != 't') goto yy177; +yy584: + yych = *++YYCURSOR; + if(yych == 'E') goto yy585; if(yych != 'e') goto yy177; -yy587: +yy585: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy588; + if(yych <= '/') goto yy586; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy588; + if(yych <= '`') goto yy586; if(yych <= 'z') goto yy176; } } -yy588: -#line 82 "src/sc_man_scanner.re" +yy586: +#line 81 "src/sc_man_scanner.re" { RET(TK_Byte); } -#line 3954 "src/sc_man_scanner.h" -yy589: +#line 3932 "src/sc_man_scanner.h" +yy587: yych = *++YYCURSOR; - if(yych == 'A') goto yy590; + if(yych == 'A') goto yy588; if(yych != 'a') goto yy177; -yy590: +yy588: yych = *++YYCURSOR; - if(yych == 'K') goto yy591; + if(yych == 'K') goto yy589; if(yych != 'k') goto yy177; -yy591: +yy589: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { if(yych <= '9') { if(yych >= '0') goto yy176; } else { - if(yych <= '@') goto yy592; - if(yych <= 'A') goto yy593; + if(yych <= '@') goto yy590; + if(yych <= 'A') goto yy591; goto yy176; } } else { if(yych <= '`') { if(yych == '_') goto yy176; } else { - if(yych <= 'a') goto yy593; + if(yych <= 'a') goto yy591; if(yych <= 'z') goto yy176; } } -yy592: +yy590: #line 60 "src/sc_man_scanner.re" { RET(TK_Break); } -#line 3984 "src/sc_man_scanner.h" +#line 3962 "src/sc_man_scanner.h" +yy591: + yych = *++YYCURSOR; + if(yych == 'B') goto yy592; + if(yych != 'b') goto yy177; +yy592: + yych = *++YYCURSOR; + if(yych == 'L') goto yy593; + if(yych != 'l') goto yy177; yy593: yych = *++YYCURSOR; - if(yych == 'B') goto yy594; - if(yych != 'b') goto yy177; -yy594: - yych = *++YYCURSOR; - if(yych == 'L') goto yy595; - if(yych != 'l') goto yy177; -yy595: - yych = *++YYCURSOR; - if(yych == 'E') goto yy596; + if(yych == 'E') goto yy594; if(yych != 'e') goto yy177; -yy596: +yy594: ++YYCURSOR; if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy597; + if(yych <= '/') goto yy595; if(yych <= '9') goto yy176; if(yych >= 'A') goto yy176; } else { if(yych <= '_') { if(yych >= '_') goto yy176; } else { - if(yych <= '`') goto yy597; + if(yych <= '`') goto yy595; if(yych <= 'z') goto yy176; } } -yy597: -#line 149 "src/sc_man_scanner.re" +yy595: +#line 148 "src/sc_man_scanner.re" { RET(TK_Breakable); } -#line 4014 "src/sc_man_scanner.h" -yy598: +#line 3992 "src/sc_man_scanner.h" +yy596: yych = *++YYCURSOR; - if(yych == 'L') goto yy599; + if(yych == 'L') goto yy597; if(yych != 'l') goto yy177; +yy597: + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy598; + if(yych <= '9') goto yy176; + if(yych >= 'A') goto yy176; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy176; + } else { + if(yych <= '`') goto yy598; + if(yych <= 'z') goto yy176; + } + } +yy598: +#line 77 "src/sc_man_scanner.re" + { RET(TK_Bool); } +#line 4014 "src/sc_man_scanner.h" yy599: ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy600; - if(yych <= '9') goto yy176; - if(yych >= 'A') goto yy176; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy176; - } else { - if(yych <= '`') goto yy600; - if(yych <= 'z') goto yy176; - } - } -yy600: -#line 78 "src/sc_man_scanner.re" - { RET(TK_Bool); } -#line 4036 "src/sc_man_scanner.h" -yy601: - ++YYCURSOR; -#line 173 "src/sc_man_scanner.re" +#line 172 "src/sc_man_scanner.re" { RET(TK_DivEq); } -#line 4041 "src/sc_man_scanner.h" -yy603: +#line 4019 "src/sc_man_scanner.h" +yy601: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if(yych == 0x0A) goto yy607; - goto yy603; -yy605: + if(yych == 0x0A) goto yy605; + goto yy601; +yy603: ++YYCURSOR; #line 56 "src/sc_man_scanner.re" { goto comment; } -#line 4052 "src/sc_man_scanner.h" -yy607: +#line 4030 "src/sc_man_scanner.h" +yy605: ++YYCURSOR; #line 57 "src/sc_man_scanner.re" { goto newline; } -#line 4057 "src/sc_man_scanner.h" +#line 4035 "src/sc_man_scanner.h" } -#line 221 "src/sc_man_scanner.re" +#line 220 "src/sc_man_scanner.re" } if (!CMode) // The classic Hexen scanner. { -#line 4065 "src/sc_man_scanner.h" +#line 4043 "src/sc_man_scanner.h" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -4069,188 +4047,188 @@ yy607: yych = *YYCURSOR; if(yych <= '/') { if(yych <= ' ') { - if(yych == 0x0A) goto yy617; - goto yy615; + if(yych == 0x0A) goto yy615; + goto yy613; } else { - if(yych == '"') goto yy619; - if(yych <= '.') goto yy623; - goto yy612; + if(yych == '"') goto yy617; + if(yych <= '.') goto yy621; + goto yy610; } } else { if(yych <= '<') { - if(yych == ';') goto yy614; - goto yy623; + if(yych == ';') goto yy612; + goto yy621; } else { - if(yych <= '=') goto yy621; - if(yych <= 'z') goto yy623; - if(yych <= '}') goto yy621; - goto yy623; + if(yych <= '=') goto yy619; + if(yych <= 'z') goto yy621; + if(yych <= '}') goto yy619; + goto yy621; } } -yy611: -#line 236 "src/sc_man_scanner.re" +yy609: +#line 235 "src/sc_man_scanner.re" { goto normal_token; } -#line 4094 "src/sc_man_scanner.h" -yy612: +#line 4072 "src/sc_man_scanner.h" +yy610: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if(yych <= '/') { if(yych <= '"') { - if(yych == '!') goto yy628; + if(yych == '!') goto yy626; } else { - if(yych == '*') goto yy636; - if(yych <= '.') goto yy628; - goto yy632; + if(yych == '*') goto yy634; + if(yych <= '.') goto yy626; + goto yy630; } } else { if(yych <= '<') { - if(yych != ';') goto yy628; + if(yych != ';') goto yy626; } else { - if(yych <= '=') goto yy613; - if(yych <= 'z') goto yy628; - if(yych >= '~') goto yy628; + if(yych <= '=') goto yy611; + if(yych <= 'z') goto yy626; + if(yych >= '~') goto yy626; } } -yy613: -#line 238 "src/sc_man_scanner.re" +yy611: +#line 237 "src/sc_man_scanner.re" { goto normal_token; } -#line 4118 "src/sc_man_scanner.h" -yy614: +#line 4096 "src/sc_man_scanner.h" +yy612: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - goto yy633; -yy615: + goto yy631; +yy613: ++YYCURSOR; yych = *YYCURSOR; - goto yy631; -yy616: -#line 229 "src/sc_man_scanner.re" + goto yy629; +yy614: +#line 228 "src/sc_man_scanner.re" { goto std1; } -#line 4130 "src/sc_man_scanner.h" +#line 4108 "src/sc_man_scanner.h" +yy615: + ++YYCURSOR; +#line 229 "src/sc_man_scanner.re" + { goto newline; } +#line 4113 "src/sc_man_scanner.h" yy617: ++YYCURSOR; #line 230 "src/sc_man_scanner.re" - { goto newline; } -#line 4135 "src/sc_man_scanner.h" + { goto string; } +#line 4118 "src/sc_man_scanner.h" yy619: ++YYCURSOR; -#line 231 "src/sc_man_scanner.re" - { goto string; } -#line 4140 "src/sc_man_scanner.h" -yy621: - ++YYCURSOR; -#line 233 "src/sc_man_scanner.re" +#line 232 "src/sc_man_scanner.re" { goto normal_token; } -#line 4145 "src/sc_man_scanner.h" -yy623: +#line 4123 "src/sc_man_scanner.h" +yy621: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - goto yy627; -yy624: + goto yy625; +yy622: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; if(yych <= '/') { if(yych <= '"') { - if(yych == '!') goto yy628; + if(yych == '!') goto yy626; } else { - if(yych == '*') goto yy625; - if(yych <= '.') goto yy628; + if(yych == '*') goto yy623; + if(yych <= '.') goto yy626; } } else { if(yych <= '<') { - if(yych != ';') goto yy628; + if(yych != ';') goto yy626; } else { - if(yych <= '=') goto yy625; - if(yych <= 'z') goto yy628; - if(yych >= '~') goto yy628; + if(yych <= '=') goto yy623; + if(yych <= 'z') goto yy626; + if(yych >= '~') goto yy626; } } -yy625: +yy623: YYCURSOR = YYMARKER; if(yyaccept <= 0) { - goto yy613; - } else { goto yy611; + } else { + goto yy609; + } +yy624: + yyaccept = 1; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy625: + if(yych <= ':') { + if(yych <= '"') { + if(yych == '!') goto yy624; + goto yy609; + } else { + if(yych == '/') goto yy622; + goto yy624; + } + } else { + if(yych <= '=') { + if(yych == '<') goto yy624; + goto yy609; + } else { + if(yych <= 'z') goto yy624; + if(yych <= '}') goto yy609; + goto yy624; + } } yy626: yyaccept = 1; YYMARKER = ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy627: if(yych <= ':') { if(yych <= '"') { if(yych == '!') goto yy626; - goto yy611; + goto yy609; } else { - if(yych == '/') goto yy624; + if(yych == '/') goto yy622; goto yy626; } } else { if(yych <= '=') { if(yych == '<') goto yy626; - goto yy611; + goto yy609; } else { if(yych <= 'z') goto yy626; - if(yych <= '}') goto yy611; + if(yych <= '}') goto yy609; goto yy626; } } yy628: - yyaccept = 1; - YYMARKER = ++YYCURSOR; + ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if(yych <= ':') { - if(yych <= '"') { - if(yych == '!') goto yy628; - goto yy611; - } else { - if(yych == '/') goto yy624; - goto yy628; - } - } else { - if(yych <= '=') { - if(yych == '<') goto yy628; - goto yy611; - } else { - if(yych <= 'z') goto yy628; - if(yych <= '}') goto yy611; - goto yy628; - } - } +yy629: + if(yych == 0x0A) goto yy614; + if(yych <= ' ') goto yy628; + goto yy614; yy630: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy631: - if(yych == 0x0A) goto yy616; - if(yych <= ' ') goto yy630; - goto yy616; -yy632: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; -yy633: - if(yych != 0x0A) goto yy632; - ++YYCURSOR; -#line 227 "src/sc_man_scanner.re" - { goto newline; } -#line 4241 "src/sc_man_scanner.h" -yy636: + if(yych != 0x0A) goto yy630; ++YYCURSOR; #line 226 "src/sc_man_scanner.re" + { goto newline; } +#line 4219 "src/sc_man_scanner.h" +yy634: + ++YYCURSOR; +#line 225 "src/sc_man_scanner.re" { goto comment; } -#line 4246 "src/sc_man_scanner.h" +#line 4224 "src/sc_man_scanner.h" } -#line 239 "src/sc_man_scanner.re" +#line 238 "src/sc_man_scanner.re" } else // A modified Hexen scanner for DECORATE. { -#line 4254 "src/sc_man_scanner.h" +#line 4232 "src/sc_man_scanner.h" { YYCTYPE yych; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); @@ -4258,247 +4236,247 @@ yy636: if(yych <= ':') { if(yych <= '&') { if(yych <= ' ') { - if(yych == 0x0A) goto yy644; - goto yy642; + if(yych == 0x0A) goto yy642; + goto yy640; } else { - if(yych == '"') goto yy646; - if(yych <= '%') goto yy659; - goto yy654; + if(yych == '"') goto yy644; + if(yych <= '%') goto yy657; + goto yy652; } } else { if(yych <= '-') { - if(yych <= '\'') goto yy660; - if(yych <= ',') goto yy659; - goto yy648; + if(yych <= '\'') goto yy658; + if(yych <= ',') goto yy657; + goto yy646; } else { - if(yych <= '.') goto yy652; - if(yych <= '/') goto yy640; - if(yych <= '9') goto yy650; - goto yy653; + if(yych <= '.') goto yy650; + if(yych <= '/') goto yy638; + if(yych <= '9') goto yy648; + goto yy651; } } } else { if(yych <= '^') { if(yych <= '=') { - if(yych <= ';') goto yy659; - if(yych <= '<') goto yy657; - goto yy655; + if(yych <= ';') goto yy657; + if(yych <= '<') goto yy655; + goto yy653; } else { - if(yych <= '>') goto yy658; - if(yych <= '@') goto yy659; - if(yych <= 'Z') goto yy660; - goto yy659; + if(yych <= '>') goto yy656; + if(yych <= '@') goto yy657; + if(yych <= 'Z') goto yy658; + goto yy657; } } else { if(yych <= 'z') { - if(yych == '`') goto yy659; - goto yy660; + if(yych == '`') goto yy657; + goto yy658; } else { - if(yych == '|') goto yy656; - if(yych <= '~') goto yy659; - goto yy660; + if(yych == '|') goto yy654; + if(yych <= '~') goto yy657; + goto yy658; } } } -yy640: +yy638: yych = *(YYMARKER = ++YYCURSOR); - if(yych == '*') goto yy686; - if(yych == '/') goto yy684; -yy641: -#line 259 "src/sc_man_scanner.re" + if(yych == '*') goto yy684; + if(yych == '/') goto yy682; +yy639: +#line 258 "src/sc_man_scanner.re" { goto normal_token; } -#line 4311 "src/sc_man_scanner.h" -yy642: +#line 4289 "src/sc_man_scanner.h" +yy640: ++YYCURSOR; yych = *YYCURSOR; - goto yy683; -yy643: -#line 247 "src/sc_man_scanner.re" + goto yy681; +yy641: +#line 246 "src/sc_man_scanner.re" { goto std1; } -#line 4319 "src/sc_man_scanner.h" +#line 4297 "src/sc_man_scanner.h" +yy642: + ++YYCURSOR; +#line 247 "src/sc_man_scanner.re" + { goto newline; } +#line 4302 "src/sc_man_scanner.h" yy644: ++YYCURSOR; #line 248 "src/sc_man_scanner.re" - { goto newline; } -#line 4324 "src/sc_man_scanner.h" + { goto string; } +#line 4307 "src/sc_man_scanner.h" yy646: ++YYCURSOR; -#line 249 "src/sc_man_scanner.re" - { goto string; } -#line 4329 "src/sc_man_scanner.h" +#line 250 "src/sc_man_scanner.re" + { goto negative_check; } +#line 4312 "src/sc_man_scanner.h" yy648: ++YYCURSOR; -#line 251 "src/sc_man_scanner.re" - { goto negative_check; } -#line 4334 "src/sc_man_scanner.h" -yy650: - ++YYCURSOR; - if((yych = *YYCURSOR) == '.') goto yy680; - if(yych <= '/') goto yy662; - if(yych <= '9') goto yy678; - goto yy662; -yy651: -#line 260 "src/sc_man_scanner.re" + if((yych = *YYCURSOR) == '.') goto yy678; + if(yych <= '/') goto yy660; + if(yych <= '9') goto yy676; + goto yy660; +yy649: +#line 259 "src/sc_man_scanner.re" { goto normal_token; } -#line 4344 "src/sc_man_scanner.h" +#line 4322 "src/sc_man_scanner.h" +yy650: + yych = *++YYCURSOR; + if(yych <= '/') goto yy639; + if(yych <= '9') goto yy673; + goto yy639; +yy651: + yych = *++YYCURSOR; + if(yych == ':') goto yy671; + goto yy639; yy652: yych = *++YYCURSOR; - if(yych <= '/') goto yy641; - if(yych <= '9') goto yy675; - goto yy641; + if(yych == '&') goto yy669; + goto yy639; yy653: yych = *++YYCURSOR; - if(yych == ':') goto yy673; - goto yy641; + if(yych == '=') goto yy667; + goto yy639; yy654: yych = *++YYCURSOR; - if(yych == '&') goto yy671; - goto yy641; + if(yych == '|') goto yy665; + goto yy639; yy655: yych = *++YYCURSOR; - if(yych == '=') goto yy669; - goto yy641; + if(yych == '<') goto yy663; + goto yy639; yy656: yych = *++YYCURSOR; - if(yych == '|') goto yy667; - goto yy641; + if(yych == '>') goto yy661; + goto yy639; yy657: yych = *++YYCURSOR; - if(yych == '<') goto yy665; - goto yy641; + goto yy639; yy658: yych = *++YYCURSOR; - if(yych == '>') goto yy663; - goto yy641; + goto yy660; yy659: - yych = *++YYCURSOR; - goto yy641; -yy660: - yych = *++YYCURSOR; - goto yy662; -yy661: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy662: +yy660: if(yych <= 'Z') { if(yych <= '/') { - if(yych == '\'') goto yy661; - goto yy651; + if(yych == '\'') goto yy659; + goto yy649; } else { - if(yych <= '9') goto yy661; - if(yych <= '@') goto yy651; - goto yy661; + if(yych <= '9') goto yy659; + if(yych <= '@') goto yy649; + goto yy659; } } else { if(yych <= '`') { - if(yych == '_') goto yy661; - goto yy651; + if(yych == '_') goto yy659; + goto yy649; } else { - if(yych <= 'z') goto yy661; - if(yych <= '~') goto yy651; - goto yy661; + if(yych <= 'z') goto yy659; + if(yych <= '~') goto yy649; + goto yy659; } } -yy663: - ++YYCURSOR; -#line 258 "src/sc_man_scanner.re" - { goto normal_token; } -#line 4408 "src/sc_man_scanner.h" -yy665: +yy661: ++YYCURSOR; #line 257 "src/sc_man_scanner.re" { goto normal_token; } -#line 4413 "src/sc_man_scanner.h" -yy667: +#line 4386 "src/sc_man_scanner.h" +yy663: ++YYCURSOR; #line 256 "src/sc_man_scanner.re" { goto normal_token; } -#line 4418 "src/sc_man_scanner.h" -yy669: +#line 4391 "src/sc_man_scanner.h" +yy665: ++YYCURSOR; #line 255 "src/sc_man_scanner.re" { goto normal_token; } -#line 4423 "src/sc_man_scanner.h" -yy671: +#line 4396 "src/sc_man_scanner.h" +yy667: ++YYCURSOR; #line 254 "src/sc_man_scanner.re" { goto normal_token; } -#line 4428 "src/sc_man_scanner.h" -yy673: +#line 4401 "src/sc_man_scanner.h" +yy669: ++YYCURSOR; #line 253 "src/sc_man_scanner.re" { goto normal_token; } -#line 4433 "src/sc_man_scanner.h" -yy675: +#line 4406 "src/sc_man_scanner.h" +yy671: + ++YYCURSOR; +#line 252 "src/sc_man_scanner.re" + { goto normal_token; } +#line 4411 "src/sc_man_scanner.h" +yy673: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if(yych <= '/') goto yy677; - if(yych <= '9') goto yy675; -yy677: -#line 252 "src/sc_man_scanner.re" + if(yych <= '/') goto yy675; + if(yych <= '9') goto yy673; +yy675: +#line 251 "src/sc_man_scanner.re" { goto normal_token; } -#line 4443 "src/sc_man_scanner.h" -yy678: +#line 4421 "src/sc_man_scanner.h" +yy676: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; if(yych <= '@') { if(yych <= '-') { - if(yych == '\'') goto yy661; - goto yy651; + if(yych == '\'') goto yy659; + goto yy649; } else { - if(yych <= '.') goto yy680; - if(yych <= '/') goto yy651; - if(yych <= '9') goto yy678; - goto yy651; + if(yych <= '.') goto yy678; + if(yych <= '/') goto yy649; + if(yych <= '9') goto yy676; + goto yy649; } } else { if(yych <= '_') { - if(yych <= 'Z') goto yy661; - if(yych <= '^') goto yy651; - goto yy661; + if(yych <= 'Z') goto yy659; + if(yych <= '^') goto yy649; + goto yy659; } else { - if(yych <= '`') goto yy651; - if(yych <= 'z') goto yy661; - if(yych <= '~') goto yy651; - goto yy661; + if(yych <= '`') goto yy649; + if(yych <= 'z') goto yy659; + if(yych <= '~') goto yy649; + goto yy659; } } +yy678: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '/') goto yy675; + if(yych <= '9') goto yy678; + goto yy675; yy680: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if(yych <= '/') goto yy677; - if(yych <= '9') goto yy680; - goto yy677; +yy681: + if(yych == 0x0A) goto yy641; + if(yych <= ' ') goto yy680; + goto yy641; yy682: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy683: - if(yych == 0x0A) goto yy643; - if(yych <= ' ') goto yy682; - goto yy643; + if(yych == 0x0A) goto yy686; + goto yy682; yy684: ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - if(yych == 0x0A) goto yy688; - goto yy684; +#line 243 "src/sc_man_scanner.re" + { goto comment; } +#line 4473 "src/sc_man_scanner.h" yy686: ++YYCURSOR; #line 244 "src/sc_man_scanner.re" - { goto comment; } -#line 4495 "src/sc_man_scanner.h" -yy688: - ++YYCURSOR; -#line 245 "src/sc_man_scanner.re" { goto newline; } -#line 4500 "src/sc_man_scanner.h" +#line 4478 "src/sc_man_scanner.h" } -#line 263 "src/sc_man_scanner.re" +#line 262 "src/sc_man_scanner.re" } @@ -4526,22 +4504,22 @@ negative_check: comment: -#line 4530 "src/sc_man_scanner.h" +#line 4508 "src/sc_man_scanner.h" { YYCTYPE yych; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if(yych == 0x0A) goto yy694; - if(yych != '*') goto yy696; + if(yych == 0x0A) goto yy692; + if(yych != '*') goto yy694; ++YYCURSOR; - if((yych = *YYCURSOR) == '/') goto yy697; -yy693: -#line 312 "src/sc_man_scanner.re" + if((yych = *YYCURSOR) == '/') goto yy695; +yy691: +#line 311 "src/sc_man_scanner.re" { goto comment; } -#line 4542 "src/sc_man_scanner.h" -yy694: +#line 4520 "src/sc_man_scanner.h" +yy692: ++YYCURSOR; -#line 301 "src/sc_man_scanner.re" +#line 300 "src/sc_man_scanner.re" { if (YYCURSOR >= YYLIMIT) { @@ -4553,13 +4531,13 @@ yy694: sc_Crossed = true; goto comment; } -#line 4557 "src/sc_man_scanner.h" -yy696: +#line 4535 "src/sc_man_scanner.h" +yy694: yych = *++YYCURSOR; - goto yy693; -yy697: + goto yy691; +yy695: ++YYCURSOR; -#line 291 "src/sc_man_scanner.re" +#line 290 "src/sc_man_scanner.re" { if (YYCURSOR >= YYLIMIT) { @@ -4569,9 +4547,9 @@ yy697: } goto std1; } -#line 4573 "src/sc_man_scanner.h" +#line 4551 "src/sc_man_scanner.h" } -#line 313 "src/sc_man_scanner.re" +#line 312 "src/sc_man_scanner.re" newline: diff --git a/src/sc_man_scanner.re b/src/sc_man_scanner.re index 900be99c1e..cec6162f61 100644 --- a/src/sc_man_scanner.re +++ b/src/sc_man_scanner.re @@ -68,7 +68,6 @@ std2: 'goto' { RET(TK_Goto); } 'if' { RET(TK_If); } 'return' { RET(TK_Return); } - 'states' { RET(TK_States); } 'switch' { RET(TK_Switch); } 'until' { RET(TK_Until); } 'volatile' { RET(TK_Volatile); } diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index e53f5ae76c..e69b2859de 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -73,1027 +73,212 @@ const PClass *QuestItemClasses[31]; -// allow decal specifications in DECORATE. Decals are loaded after DECORATE so the names must be stored here. -TArray DecalNames; -// all state parameters -TArray StateParameters; -TArray JumpParameters; //========================================================================== // -// List of all flags +// ActorConstDef +// +// Parses a constant definition. // //========================================================================== -// [RH] Keep GCC quiet by not using offsetof on Actor types. -#define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1 } -#define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1 } -#define DEFINE_DEPRECATED_FLAG(name, type, index) { index, #name, -1 } - -struct flagdef +void ParseConstant (PSymbolTable * symt, PClass *cls) { - int flagbit; - const char *name; - int structoffset; -}; + // Read the type and make sure it's int. + // (Maybe there will be other types later.) + SC_MustGetToken(TK_Int); + SC_MustGetToken(TK_Identifier); + FName symname = sc_String; + SC_MustGetToken('='); + int expr = ParseExpression (false, cls); + SC_MustGetToken(';'); - -static flagdef ActorFlags[]= -{ - DEFINE_FLAG(MF, SOLID, AActor, flags), - DEFINE_FLAG(MF, SHOOTABLE, AActor, flags), - DEFINE_FLAG(MF, NOSECTOR, AActor, flags), - DEFINE_FLAG(MF, NOBLOCKMAP, AActor, flags), - DEFINE_FLAG(MF, AMBUSH, AActor, flags), - DEFINE_FLAG(MF, JUSTHIT, AActor, flags), - DEFINE_FLAG(MF, JUSTATTACKED, AActor, flags), - DEFINE_FLAG(MF, SPAWNCEILING, AActor, flags), - DEFINE_FLAG(MF, NOGRAVITY, AActor, flags), - DEFINE_FLAG(MF, DROPOFF, AActor, flags), - DEFINE_FLAG(MF, NOCLIP, AActor, flags), - DEFINE_FLAG(MF, FLOAT, AActor, flags), - DEFINE_FLAG(MF, TELEPORT, AActor, flags), - DEFINE_FLAG(MF, MISSILE, AActor, flags), - DEFINE_FLAG(MF, DROPPED, AActor, flags), - DEFINE_FLAG(MF, SHADOW, AActor, flags), - DEFINE_FLAG(MF, NOBLOOD, AActor, flags), - DEFINE_FLAG(MF, CORPSE, AActor, flags), - DEFINE_FLAG(MF, INFLOAT, AActor, flags), - DEFINE_FLAG(MF, COUNTKILL, AActor, flags), - DEFINE_FLAG(MF, COUNTITEM, AActor, flags), - DEFINE_FLAG(MF, SKULLFLY, AActor, flags), - DEFINE_FLAG(MF, NOTDMATCH, AActor, flags), - DEFINE_FLAG(MF, SPAWNSOUNDSOURCE, AActor, flags), - DEFINE_FLAG(MF, FRIENDLY, AActor, flags), - DEFINE_FLAG(MF, NOLIFTDROP, AActor, flags), - DEFINE_FLAG(MF, STEALTH, AActor, flags), - DEFINE_FLAG(MF, ICECORPSE, AActor, flags), - DEFINE_FLAG(MF2, DONTREFLECT, AActor, flags2), - DEFINE_FLAG(MF2, WINDTHRUST, AActor, flags2), - DEFINE_FLAG(MF2, HERETICBOUNCE , AActor, flags2), - DEFINE_FLAG(MF2, BLASTED, AActor, flags2), - DEFINE_FLAG(MF2, FLOORCLIP, AActor, flags2), - DEFINE_FLAG(MF2, SPAWNFLOAT, AActor, flags2), - DEFINE_FLAG(MF2, NOTELEPORT, AActor, flags2), - DEFINE_FLAG2(MF2_RIP, RIPPER, AActor, flags2), - DEFINE_FLAG(MF2, PUSHABLE, AActor, flags2), - DEFINE_FLAG2(MF2_SLIDE, SLIDESONWALLS, AActor, flags2), - DEFINE_FLAG2(MF2_PASSMOBJ, CANPASS, AActor, flags2), - DEFINE_FLAG(MF2, CANNOTPUSH, AActor, flags2), - DEFINE_FLAG(MF2, THRUGHOST, AActor, flags2), - DEFINE_FLAG(MF2, BOSS, AActor, flags2), - DEFINE_FLAG2(MF2_NODMGTHRUST, NODAMAGETHRUST, AActor, flags2), - DEFINE_FLAG(MF2, DONTTRANSLATE, AActor, flags2), - DEFINE_FLAG(MF2, TELESTOMP, AActor, flags2), - DEFINE_FLAG(MF2, FLOATBOB, AActor, flags2), - DEFINE_FLAG(MF2, HEXENBOUNCE, AActor, flags2), - DEFINE_FLAG(MF2, DOOMBOUNCE, AActor, flags2), - DEFINE_FLAG2(MF2_IMPACT, ACTIVATEIMPACT, AActor, flags2), - DEFINE_FLAG2(MF2_PUSHWALL, CANPUSHWALLS, AActor, flags2), - DEFINE_FLAG2(MF2_MCROSS, ACTIVATEMCROSS, AActor, flags2), - DEFINE_FLAG2(MF2_PCROSS, ACTIVATEPCROSS, AActor, flags2), - DEFINE_FLAG(MF2, CANTLEAVEFLOORPIC, AActor, flags2), - DEFINE_FLAG(MF2, NONSHOOTABLE, AActor, flags2), - DEFINE_FLAG(MF2, INVULNERABLE, AActor, flags2), - DEFINE_FLAG(MF2, DORMANT, AActor, flags2), - DEFINE_FLAG(MF2, SEEKERMISSILE, AActor, flags2), - DEFINE_FLAG(MF2, REFLECTIVE, AActor, flags2), - DEFINE_FLAG(MF3, FLOORHUGGER, AActor, flags3), - DEFINE_FLAG(MF3, CEILINGHUGGER, AActor, flags3), - DEFINE_FLAG(MF3, NORADIUSDMG, AActor, flags3), - DEFINE_FLAG(MF3, GHOST, AActor, flags3), - DEFINE_FLAG(MF3, ALWAYSPUFF, AActor, flags3), - DEFINE_FLAG(MF3, DONTSPLASH, AActor, flags3), - DEFINE_FLAG(MF3, DONTOVERLAP, AActor, flags3), - DEFINE_FLAG(MF3, DONTMORPH, AActor, flags3), - DEFINE_FLAG(MF3, DONTSQUASH, AActor, flags3), - DEFINE_FLAG(MF3, FULLVOLACTIVE, AActor, flags3), - DEFINE_FLAG(MF3, ISMONSTER, AActor, flags3), - DEFINE_FLAG(MF3, SKYEXPLODE, AActor, flags3), - DEFINE_FLAG(MF3, STAYMORPHED, AActor, flags3), - DEFINE_FLAG(MF3, DONTBLAST, AActor, flags3), - DEFINE_FLAG(MF3, CANBLAST, AActor, flags3), - DEFINE_FLAG(MF3, NOTARGET, AActor, flags3), - DEFINE_FLAG(MF3, DONTGIB, AActor, flags3), - DEFINE_FLAG(MF3, NOBLOCKMONST, AActor, flags3), - DEFINE_FLAG(MF3, FULLVOLDEATH, AActor, flags3), - DEFINE_FLAG(MF3, CANBOUNCEWATER, AActor, flags3), - DEFINE_FLAG(MF3, NOWALLBOUNCESND, AActor, flags3), - DEFINE_FLAG(MF3, FOILINVUL, AActor, flags3), - DEFINE_FLAG(MF3, NOTELEOTHER, AActor, flags3), - DEFINE_FLAG(MF3, BLOODLESSIMPACT, AActor, flags3), - DEFINE_FLAG(MF3, NOEXPLODEFLOOR, AActor, flags3), - DEFINE_FLAG(MF3, PUFFONACTORS, AActor, flags3), - DEFINE_FLAG(MF4, QUICKTORETALIATE, AActor, flags4), - DEFINE_FLAG(MF4, NOICEDEATH, AActor, flags4), - DEFINE_FLAG(MF4, RANDOMIZE, AActor, flags4), - DEFINE_FLAG(MF4, FIXMAPTHINGPOS , AActor, flags4), - DEFINE_FLAG(MF4, ACTLIKEBRIDGE, AActor, flags4), - DEFINE_FLAG(MF4, STRIFEDAMAGE, AActor, flags4), - DEFINE_FLAG(MF4, CANUSEWALLS, AActor, flags4), - DEFINE_FLAG(MF4, MISSILEMORE, AActor, flags4), - DEFINE_FLAG(MF4, MISSILEEVENMORE, AActor, flags4), - DEFINE_FLAG(MF4, FORCERADIUSDMG, AActor, flags4), - DEFINE_FLAG(MF4, DONTFALL, AActor, flags4), - DEFINE_FLAG(MF4, SEESDAGGERS, AActor, flags4), - DEFINE_FLAG(MF4, INCOMBAT, AActor, flags4), - DEFINE_FLAG(MF4, LOOKALLAROUND, AActor, flags4), - DEFINE_FLAG(MF4, STANDSTILL, AActor, flags4), - DEFINE_FLAG(MF4, SPECTRAL, AActor, flags4), - DEFINE_FLAG(MF4, FIRERESIST, AActor, flags4), - DEFINE_FLAG(MF4, NOSPLASHALERT, AActor, flags4), - DEFINE_FLAG(MF4, SYNCHRONIZED, AActor, flags4), - DEFINE_FLAG(MF4, NOTARGETSWITCH, AActor, flags4), - DEFINE_FLAG(MF4, DONTHURTSPECIES, AActor, flags4), - DEFINE_FLAG(MF4, SHIELDREFLECT, AActor, flags4), - DEFINE_FLAG(MF4, DEFLECT, AActor, flags4), - DEFINE_FLAG(MF4, ALLOWPARTICLES, AActor, flags4), - DEFINE_FLAG(MF4, EXTREMEDEATH, AActor, flags4), - DEFINE_FLAG(MF4, NOEXTREMEDEATH, AActor, flags4), - DEFINE_FLAG(MF4, FRIGHTENED, AActor, flags4), - DEFINE_FLAG(MF4, NOBOUNCESOUND, AActor, flags4), - DEFINE_FLAG(MF4, NOSKIN, AActor, flags4), - DEFINE_FLAG(MF4, BOSSDEATH, AActor, flags4), - - DEFINE_FLAG(MF5, FASTER, AActor, flags5), - DEFINE_FLAG(MF5, FASTMELEE, AActor, flags5), - DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5), - DEFINE_FLAG(MF5, BOUNCEONACTORS, AActor, flags5), - DEFINE_FLAG(MF5, EXPLODEONWATER, AActor, flags5), - DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5), - DEFINE_FLAG(MF5, BLOODSPLATTER, AActor, flags5), - DEFINE_FLAG(MF5, OLDRADIUSDMG, AActor, flags5), - DEFINE_FLAG(MF5, DEHEXPLOSION, AActor, flags5), - DEFINE_FLAG(MF5, PIERCEARMOR, AActor, flags5), - DEFINE_FLAG(MF5, NOBLOODDECALS, AActor, flags5), - DEFINE_FLAG(MF5, USESPECIAL, AActor, flags5), - DEFINE_FLAG(MF5, NOPAIN, AActor, flags5), - - // Effect flags - DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), - DEFINE_FLAG2(FX_ROCKET, ROCKETTRAIL, AActor, effects), - DEFINE_FLAG2(FX_GRENADE, GRENADETRAIL, AActor, effects), - DEFINE_FLAG(RF, INVISIBLE, AActor, renderflags), - - // Deprecated flags. Handling must be performed in HandleDeprecatedFlags - DEFINE_DEPRECATED_FLAG(FIREDAMAGE, AActor, 0), - DEFINE_DEPRECATED_FLAG(ICEDAMAGE, AActor, 1), - DEFINE_DEPRECATED_FLAG(LOWGRAVITY, AActor, 2), - DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE, AActor, 3), - DEFINE_DEPRECATED_FLAG(LONGMELEERANGE, AActor, 4), -}; - -static flagdef InventoryFlags[] = -{ - // Inventory flags - DEFINE_FLAG(IF, QUIET, AInventory, ItemFlags), - DEFINE_FLAG(IF, AUTOACTIVATE, AInventory, ItemFlags), - DEFINE_FLAG(IF, UNDROPPABLE, AInventory, ItemFlags), - DEFINE_FLAG(IF, INVBAR, AInventory, ItemFlags), - DEFINE_FLAG(IF, HUBPOWER, AInventory, ItemFlags), - DEFINE_FLAG(IF, INTERHUBSTRIP, AInventory, ItemFlags), - DEFINE_FLAG(IF, PICKUPFLASH, AInventory, ItemFlags), - DEFINE_FLAG(IF, ALWAYSPICKUP, AInventory, ItemFlags), - DEFINE_FLAG(IF, FANCYPICKUPSOUND, AInventory, ItemFlags), - DEFINE_FLAG(IF, BIGPOWERUP, AInventory, ItemFlags), - DEFINE_FLAG(IF, KEEPDEPLETED, AInventory, ItemFlags), -}; - -static flagdef WeaponFlags[] = -{ - // Weapon flags - DEFINE_FLAG(WIF, NOAUTOFIRE, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, READYSNDHALF, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, DONTBOB, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, AXEBLOOD, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, NOALERT, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, AMMO_OPTIONAL, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, ALT_AMMO_OPTIONAL, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, PRIMARY_USES_BOTH, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, WIMPY_WEAPON, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, POWERED_UP, AWeapon, WeaponFlags), - //DEFINE_FLAG(WIF, EXTREME_DEATH, AWeapon, WeaponFlags), // this should be removed now! - DEFINE_FLAG(WIF, STAFF2_KICKBACK, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF_BOT, EXPLOSIVE, AWeapon, WeaponFlags), - DEFINE_FLAG2(WIF_BOT_MELEE, MELEEWEAPON, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF_BOT, BFG, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, CHEATNOTWEAPON, AWeapon, WeaponFlags), - DEFINE_FLAG(WIF, NO_AUTO_SWITCH, AWeapon, WeaponFlags), - //WIF_BOT_REACTION_SKILL_THING = 1<<31, // I don't understand this -}; - -static const struct { const PClass *Type; flagdef *Defs; int NumDefs; } FlagLists[] = -{ - { RUNTIME_CLASS(AActor), ActorFlags, sizeof(ActorFlags)/sizeof(flagdef) }, - { RUNTIME_CLASS(AInventory), InventoryFlags, sizeof(InventoryFlags)/sizeof(flagdef) }, - { RUNTIME_CLASS(AWeapon), WeaponFlags, sizeof(WeaponFlags)/sizeof(flagdef) } -}; -#define NUM_FLAG_LISTS 3 - -//========================================================================== -// -// Find a flag by name using a binary search -// -//========================================================================== -static int STACK_ARGS flagcmp (const void * a, const void * b) -{ - return stricmp( ((flagdef*)a)->name, ((flagdef*)b)->name); + int val = EvalExpressionI (expr, NULL, cls); + PSymbolConst *sym = new PSymbolConst; + sym->SymbolName = symname; + sym->SymbolType = SYM_Const; + sym->Value = val; + if (symt->AddSymbol (sym) == NULL) + { + delete sym; + SC_ScriptError ("'%s' is already defined in class '%s'.", + symname.GetChars(), cls->TypeName.GetChars()); + } } -static flagdef *FindFlag (flagdef *flags, int numflags, const char *flag) -{ - int min = 0, max = numflags - 1; +//========================================================================== +// +// ActorEnumDef +// +// Parses an enum definition. +// +//========================================================================== - while (min <= max) +void ParseEnum (PSymbolTable * symt, PClass *cls) +{ + int currvalue = 0; + + SC_MustGetToken('{'); + while (!SC_CheckToken('}')) { - int mid = (min + max) / 2; - int lexval = stricmp (flag, flags[mid].name); - if (lexval == 0) + SC_MustGetToken(TK_Identifier); + FName symname = sc_String; + if (SC_CheckToken('=')) { - return &flags[mid]; + int expr = ParseExpression(false, cls); + currvalue = EvalExpressionI (expr, NULL, cls); } - else if (lexval > 0) + PSymbolConst *sym = new PSymbolConst; + sym->SymbolName = symname; + sym->SymbolType = SYM_Const; + sym->Value = currvalue; + if (symt->AddSymbol (sym) == NULL) { - min = mid + 1; - } - else - { - max = mid - 1; + delete sym; + SC_ScriptError ("'%s' is already defined in class '%s'.", + symname.GetChars(), cls->TypeName.GetChars()); } + // This allows a comma after the last value but doesn't enforce it. + if (SC_CheckToken('}')) break; + SC_MustGetToken(','); + currvalue++; } - return NULL; + SC_MustGetToken(';'); } -static flagdef *FindFlag (const PClass *type, const char *part1, const char *part2) -{ - static bool flagsorted = false; - flagdef *def; - int i; +//========================================================================== +// +// ActorActionDef +// +// Parses an action function definition. A lot of this is essentially +// documentation in the declaration for when I have a proper language +// ready. +// +//========================================================================== - if (!flagsorted) +static void ParseActionDef (PClass *cls) +{ +#define OPTIONAL 1 +#define EVAL 2 +#define EVALNOT 4 + + AFuncDesc *afd; + FName funcname; + FString args; + + SC_MustGetToken(TK_Native); + SC_MustGetToken(TK_Identifier); + funcname = sc_String; + afd = FindFunction(sc_String); + if (afd == NULL) { - for (i = 0; i < NUM_FLAG_LISTS; ++i) - { - qsort (FlagLists[i].Defs, FlagLists[i].NumDefs, sizeof(flagdef), flagcmp); - } - flagsorted = true; + SC_ScriptError ("The function '%s' has not been exported from the executable.", sc_String); } - if (part2 == NULL) - { // Search all lists - for (i = 0; i < NUM_FLAG_LISTS; ++i) + SC_MustGetToken('('); + if (!SC_CheckToken(')')) + { + while (sc_TokenType != ')') { - if (type->IsDescendantOf (FlagLists[i].Type)) + int flags = 0; + char type = '@'; + + // Retrieve flags before type name + for (;;) { - def = FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part1); - if (def != NULL) + if (SC_CheckToken(TK_Optional)) { - return def; + flags |= OPTIONAL; } - } - } - } - else - { // Search just the named list - for (i = 0; i < NUM_FLAG_LISTS; ++i) - { - if (stricmp (FlagLists[i].Type->TypeName.GetChars(), part1) == 0) - { - if (type->IsDescendantOf (FlagLists[i].Type)) + else if (SC_CheckToken(TK_Eval)) + { + flags |= EVAL; + } + else if (SC_CheckToken(TK_EvalNot)) + { + flags |= EVALNOT; + } + else if (SC_CheckToken(TK_Coerce) || SC_CheckToken(TK_Native)) { - return FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part2); } else { - return NULL; + break; } } + // Read the variable type + SC_MustGetAnyToken(); + switch (sc_TokenType) + { + case TK_Bool: type = 'i'; break; + case TK_Int: type = 'i'; break; + case TK_Float: type = 'f'; break; + case TK_Sound: type = 's'; break; + case TK_String: type = 't'; break; + case TK_Name: type = 't'; break; + case TK_State: type = 'l'; break; + case TK_Color: type = 'c'; break; + case TK_Class: + SC_MustGetToken('<'); + SC_MustGetToken(TK_Identifier); // Skip class name, since the parser doesn't care + SC_MustGetToken('>'); + type = 'm'; + break; + case TK_Ellipsis: + type = '+'; + SC_MustGetToken(')'); + SC_UnGet(); + break; + default: + SC_ScriptError ("Unknown variable type %s", SC_TokenName(sc_TokenType, sc_String).GetChars()); + break; + } + // Read the optional variable name + if (!SC_CheckToken(',') && !SC_CheckToken(')')) + { + SC_MustGetToken(TK_Identifier); + } + else + { + SC_UnGet(); + } + // If eval or evalnot were a flag, hey the decorate parser doesn't actually care about the type. + if (flags & EVALNOT) + { + type = 'y'; + } + else if (flags & EVAL) + { + type = 'x'; + } + if (!(flags & OPTIONAL) && type != '+') + { + type -= 'a' - 'A'; + } + #undef OPTIONAL + #undef EVAL + #undef EVALNOT + args += type; + SC_MustGetAnyToken(); + if (sc_TokenType != ',' && sc_TokenType != ')') + { + SC_ScriptError ("Expected ',' or ')' but got %s instead", SC_TokenName(sc_TokenType, sc_String).GetChars()); + } } } - return NULL; -} - - -//=========================================================================== -// -// HandleDeprecatedFlags -// -// Handles the deprecated flags and sets the respective properties -// to appropriate values. This is solely intended for backwards -// compatibility so mixing this with code that is aware of the real -// properties is not recommended -// -//=========================================================================== -static void HandleDeprecatedFlags(AActor *defaults, bool set, int index) -{ - switch (index) + SC_MustGetToken(';'); + PSymbolActionFunction *sym = new PSymbolActionFunction; + sym->SymbolName = funcname; + sym->SymbolType = SYM_ActionFunction; + sym->Arguments = args; + sym->Function = afd->Function; + if (cls->Symbols.AddSymbol (sym) == NULL) { - case 0: // FIREDAMAGE - defaults->DamageType = set? NAME_Fire : NAME_None; - break; - case 1: // ICEDAMAGE - defaults->DamageType = set? NAME_Ice : NAME_None; - break; - case 2: // LOWGRAVITY - defaults->gravity = set? FRACUNIT/8 : FRACUNIT; - break; - case 3: // SHORTMISSILERANGE - defaults->maxtargetrange = set? 896*FRACUNIT : 0; - break; - case 4: // LONGMELEERANGE - defaults->meleethreshold = set? 196*FRACUNIT : 0; - break; - default: - break; // silence GCC + delete sym; + SC_ScriptError ("'%s' is already defined in class '%s'.", + funcname.GetChars(), cls->TypeName.GetChars()); } } -//=========================================================================== -// -// A_ChangeFlag -// -// This cannot be placed in thingdef_codeptr because it needs the flag table -// -//=========================================================================== -void A_ChangeFlag(AActor * self) -{ - int index=CheckIndex(2); - const char * flagname = FName((ENamedName)StateParameters[index]).GetChars(); - int expression = EvalExpressionI (StateParameters[index+1], self); - - const char *dot = strchr (flagname, '.'); - flagdef *fd; - - if (dot != NULL) - { - FString part1(flagname, dot-flagname); - fd = FindFlag (self->GetClass(), part1, dot+1); - } - else - { - fd = FindFlag (self->GetClass(), flagname, NULL); - } - - if (fd != NULL) - { - if (fd->structoffset == -1) - { - HandleDeprecatedFlags(self, !!expression, fd->flagbit); - } - else - { - int * flagp = (int*) (((char*)self) + fd->structoffset); - - if (expression) *flagp |= fd->flagbit; - else *flagp &= ~fd->flagbit; - } - } - else - { - Printf("Unknown flag '%s' in '%s'\n", flagname, self->GetClass()->TypeName.GetChars()); - } -} - - -//========================================================================== -// -// Action functions -// -//========================================================================== - - -#include "thingdef_specials.h" - -struct AFuncDesc -{ - const char *Name; - actionf_p Function; -}; - - -#define FROM_THINGDEF -// Prototype the code pointers -#define WEAPON(x) void A_##x(AActor*); -#define ACTOR(x) void A_##x(AActor*); -#include "codepointers.h" -#include "d_dehackedactions.h" -void A_ComboAttack(AActor*); -void A_ExplodeParms(AActor*); - -AFuncDesc AFTable[] = -{ -#define WEAPON(x) { "A_" #x, A_##x }, -#define ACTOR(x) { "A_" #x, A_##x }, -#include "codepointers.h" -#include "d_dehackedactions.h" - { "A_Fall", A_NoBlocking }, - { "A_BasicAttack", A_ComboAttack }, - { "A_Explode", A_ExplodeParms } -}; - - -//========================================================================== -// -// Find a function by name using a binary search -// -//========================================================================== -static int STACK_ARGS funccmp(const void * a, const void * b) -{ - return stricmp( ((AFuncDesc*)a)->Name, ((AFuncDesc*)b)->Name); -} - -static AFuncDesc * FindFunction(const char * string) -{ - static bool funcsorted=false; - - if (!funcsorted) - { - qsort(AFTable, countof(AFTable), sizeof(AFTable[0]), funccmp); - funcsorted=true; - } - - int min = 0, max = countof(AFTable)-1; - - while (min <= max) - { - int mid = (min + max) / 2; - int lexval = stricmp (string, AFTable[mid].Name); - if (lexval == 0) - { - return &AFTable[mid]; - } - else if (lexval > 0) - { - min = mid + 1; - } - else - { - max = mid - 1; - } - } - return NULL; -} - - -static const char *BasicAttackNames[4] = -{ - "A_MeleeAttack", - "A_MissileAttack", - "A_ComboAttack", - NULL -}; -static const actionf_p BasicAttacks[3] = -{ - A_MeleeAttack, - A_MissileAttack, - A_ComboAttack -}; - - - -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -// -// Translation parsing -// -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -static int NumUsedTranslations; -static int NumUsedBloodTranslations; -BYTE decorate_translations[256*256*2]; -PalEntry BloodTranslations[256]; - -void InitDecorateTranslations() -{ - // The translation tables haven't been allocated yet so we may as easily use a static buffer instead! - NumUsedBloodTranslations = NumUsedTranslations = 0; - for(int i=0;i<256*256*2;i++) decorate_translations[i]=i&255; -} - -static bool Check(char *& range, char c, bool error=true) -{ - while (isspace(*range)) range++; - if (*range==c) - { - range++; - return true; - } - if (error) - { - //SC_ScriptError("Invalid syntax in translation specification: '%c' expected", c); - } - return false; -} - - -static void AddToTranslation(unsigned char * translation, char * range) -{ - int start,end; - - start=strtol(range, &range, 10); - if (!Check(range, ':')) return; - end=strtol(range, &range, 10); - if (!Check(range, '=')) return; - if (!Check(range, '[', false)) - { - int pal1,pal2; - fixed_t palcol, palstep; - - pal1=strtol(range, &range, 10); - if (!Check(range, ':')) return; - pal2=strtol(range, &range, 10); - - if (start > end) - { - swap (start, end); - swap (pal1, pal2); - } - else if (start == end) - { - translation[start] = pal1; - return; - } - palcol = pal1 << FRACBITS; - palstep = ((pal2 << FRACBITS) - palcol) / (end - start); - for (int i = start; i <= end; palcol += palstep, ++i) - { - translation[i] = palcol >> FRACBITS; - } - } - else - { - // translation using RGB values - int r1; - int g1; - int b1; - int r2; - int g2; - int b2; - int r,g,b; - int rs,gs,bs; - - r1=strtol(range, &range, 10); - if (!Check(range, ',')) return; - g1=strtol(range, &range, 10); - if (!Check(range, ',')) return; - b1=strtol(range, &range, 10); - if (!Check(range, ']')) return; - if (!Check(range, ':')) return; - if (!Check(range, '[')) return; - r2=strtol(range, &range, 10); - if (!Check(range, ',')) return; - g2=strtol(range, &range, 10); - if (!Check(range, ',')) return; - b2=strtol(range, &range, 10); - if (!Check(range, ']')) return; - - if (start > end) - { - swap (start, end); - r = r2; - g = g2; - b = b2; - rs = r1 - r2; - gs = g1 - g2; - bs = b1 - b2; - } - else - { - r = r1; - g = g1; - b = b1; - rs = r2 - r1; - gs = g2 - g1; - bs = b2 - b1; - } - if (start == end) - { - translation[start] = ColorMatcher.Pick - (r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); - return; - } - rs /= (end - start); - gs /= (end - start); - bs /= (end - start); - for (int i = start; i <= end; ++i) - { - translation[i] = ColorMatcher.Pick - (r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); - r += rs; - g += gs; - b += bs; - } - - } -} - -static int StoreTranslation(const unsigned char * translation) -{ - for (int i = 0; i < NumUsedTranslations; i++) - { - if (!memcmp(translation, decorate_translations + i*256, 256)) - { - // A duplicate of this translation already exists - return TRANSLATION(TRANSLATION_Decorate, i); - } - } - if (NumUsedTranslations>=MAX_DECORATE_TRANSLATIONS) - { - SC_ScriptError("Too many translations in DECORATE"); - } - memcpy(decorate_translations + NumUsedTranslations*256, translation, 256); - NumUsedTranslations++; - return TRANSLATION(TRANSLATION_Decorate, NumUsedTranslations-1); -} - -static int CreateBloodTranslation(PalEntry color) -{ - int i; - - for (i = 0; i < NumUsedBloodTranslations; i++) - { - if (color.r == BloodTranslations[i].r && - color.g == BloodTranslations[i].g && - color.b == BloodTranslations[i].b) - { - // A duplicate of this translation already exists - return i; - } - } - if (NumUsedBloodTranslations>=MAX_DECORATE_TRANSLATIONS) - { - SC_ScriptError("Too many blood colors in DECORATE"); - } - for (i = 0; i < 256; i++) - { - int bright = MAX(MAX(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b); - int entry = ColorMatcher.Pick(color.r*bright/255, color.g*bright/255, color.b*bright/255); - - *(decorate_translations + MAX_DECORATE_TRANSLATIONS*256 + NumUsedBloodTranslations*256 + i)=entry; - } - BloodTranslations[NumUsedBloodTranslations]=color; - return NumUsedBloodTranslations++; -} - -//---------------------------------------------------------------------------- -// -// DropItem handling -// -//---------------------------------------------------------------------------- - -static void FreeDropItemChain(FDropItem *chain) -{ - while (chain != NULL) - { - FDropItem *next = chain->Next; - delete chain; - chain = next; - } -} - -class FDropItemPtrArray : public TArray -{ -public: - ~FDropItemPtrArray() - { - for (unsigned int i = 0; i < Size(); ++i) - { - FreeDropItemChain ((*this)[i]); - } - } -}; - -static FDropItemPtrArray DropItemList; - -FDropItem *GetDropItems(const PClass *cls) -{ - unsigned int index = cls->Meta.GetMetaInt (ACMETA_DropItems) - 1; - - if (index >= 0 && index < DropItemList.Size()) - { - return DropItemList[index]; - } - return NULL; -} - -//========================================================================== -// -// Extra info maintained while defining an actor. The original -// implementation stored these in a CustomActor class. They have all been -// moved into action function parameters so that no special CustomActor -// class is necessary. -// -//========================================================================== - -struct FBasicAttack -{ - int MeleeDamage; - int MeleeSound; - FName MissileName; - fixed_t MissileHeight; -}; - -struct Baggage -{ - FActorInfo *Info; - bool DropItemSet; - bool StateSet; - int CurrentState; - - FDropItem *DropItemList; - FBasicAttack BAttack; -}; - - -//========================================================================== -// -// -//========================================================================== - -static TArray StateArray; - - - -typedef void (*ActorPropFunction) (AActor *defaults, Baggage &bag); - -struct ActorProps { const char *name; ActorPropFunction Handler; const PClass * type; }; - -typedef ActorProps (*ActorPropHandler) (register const char *str, register unsigned int len); - -static const ActorProps *is_actorprop (const char *str); - -//========================================================================== -// -// Find a state address -// -//========================================================================== - -struct FStateDefine -{ - FName Label; - TArray Children; - FState *State; -}; - -static TArray StateLabels; - -void ClearStateLabels() -{ - StateLabels.Clear(); -} - -//========================================================================== -// -// Search one list of state definitions for the given name -// -//========================================================================== - -static FStateDefine * FindStateLabelInList(TArray & list, FName name, bool create) -{ - for(unsigned i = 0; i namelist(3); - FStateDefine * statedef=NULL; - - MakeStateNameList(name, &namelist); - - TArray * statelist = &StateLabels; - for(unsigned i=0;iChildren; - } - return statedef; -} - -void AddState (const char * statename, FState * state) -{ - FStateDefine * std = FindStateAddress(statename); - std->State = state; -} - -//========================================================================== -// -// Finds the state associated with the given name -// -//========================================================================== - -FState * FindState(AActor * actor, const PClass * type, const char * name) -{ - static TArray namelist(3); - FStateDefine * statedef=NULL; - - MakeStateNameList(name, &namelist); - - TArray * statelist = &StateLabels; - for(unsigned i=0;iChildren; - } - return statedef? statedef->State : NULL; -} - -//========================================================================== -// -// Finds the state associated with the given name -// -//========================================================================== - -FState * FindStateInClass(AActor * actor, const PClass * type, const char * name) -{ - static TArray namelist(3); - - MakeStateNameList(name, &namelist); - FActorInfo * info = type->ActorInfo; - if (info) return info->FindState(namelist.Size(), &namelist[0], true); - return NULL; -} - -//========================================================================== -// -// Checks if a state list is empty -// A list is empty if it doesn't contain any states and no children -// that contain any states -// -//========================================================================== - -static bool IsStateListEmpty(TArray & statelist) -{ - for(unsigned i=0;iLabel - (int)B->Label); -} - -static FStateLabels * CreateStateLabelList(TArray & statelist) -{ - // First delete all empty labels from the list - for (int i=statelist.Size()-1;i>=0;i--) - { - if (statelist[i].Label == NAME_None || (statelist[i].State == NULL && statelist[i].Children.Size() == 0)) - { - statelist.Delete(i); - } - } - - int count=statelist.Size(); - - if (count == 0) return NULL; - - FStateLabels * list = (FStateLabels*)M_Malloc(sizeof(FStateLabels)+(count-1)*sizeof(FStateLabel)); - list->NumLabels = count; - - for (int i=0;iLabels[i].Label = statelist[i].Label; - list->Labels[i].State = statelist[i].State; - list->Labels[i].Children = CreateStateLabelList(statelist[i].Children); - } - qsort(list->Labels, count, sizeof(FStateLabel), labelcmp); - return list; -} - -//=========================================================================== -// -// InstallStates -// -// Creates the actor's state list from the current definition -// -//=========================================================================== - -void InstallStates(FActorInfo *info, AActor *defaults) -{ - // First ensure we have a valid spawn state. - FState * state = FindState(defaults, info->Class, "Spawn"); - - // Stateless actors that are direct subclasses of AActor - // have their spawnstate default to something that won't - // immediately destroy them. - if (state == &AActor::States[2] && info->Class->ParentClass == RUNTIME_CLASS(AActor)) - { - AddState("Spawn", &AActor::States[0]); - } - else if (state == NULL) - { - // A NULL spawn state will crash the engine so set it to something that will make - // the actor disappear as quickly as possible. - AddState("Spawn", &AActor::States[2]); - } - - if (info->StateList != NULL) - { - info->StateList->Destroy(); - free(info->StateList); - } - info->StateList = CreateStateLabelList(StateLabels); - - // Cache these states as member veriables. - defaults->SpawnState = info->FindState(NAME_Spawn); - defaults->SeeState = info->FindState(NAME_See); - // Melee and Missile states are manipulated by the scripted marines so they - // have to be stored locally - defaults->MeleeState = info->FindState(NAME_Melee); - defaults->MissileState = info->FindState(NAME_Missile); -} - - -//=========================================================================== -// -// MakeStateDefines -// -// Creates a list of state definitions from an existing actor -// Used by Dehacked to modify an actor's state list -// -//=========================================================================== - -static void MakeStateList(const FStateLabels *list, TArray &dest) -{ - dest.Clear(); - if (list != NULL) for(int i=0;iNumLabels;i++) - { - FStateDefine def; - - def.Label = list->Labels[i].Label; - def.State = list->Labels[i].State; - dest.Push(def); - if (list->Labels[i].Children != NULL) - { - MakeStateList(list->Labels[i].Children, dest[dest.Size()-1].Children); - } - } -} - -void MakeStateDefines(const FStateLabels *list) -{ - MakeStateList(list, StateLabels); -} - -//========================================================================== -// -// Sets the default values with which an actor definition starts -// -//========================================================================== - -static void ResetBaggage (Baggage *bag) -{ - bag->DropItemList = NULL; - bag->BAttack.MeleeDamage = 0; - bag->BAttack.MissileHeight = 32*FRACUNIT; - bag->BAttack.MeleeSound = 0; - bag->BAttack.MissileName = NAME_None; - bag->DropItemSet = false; - bag->CurrentState = 0; - bag->StateSet = false; -} - -static void ResetActor (AActor *actor, Baggage *bag) -{ - memcpy (actor, GetDefault(), sizeof(AActor)); - if (bag->DropItemList != NULL) - { - FreeDropItemChain (bag->DropItemList); - } - ResetBaggage (bag); -} - - - //========================================================================== // // Starts a new actor definition @@ -1229,964 +414,57 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag) return info; } -//========================================================================== -// -// PrepareStateParameters -// creates an empty parameter list for a parameterized function call -// -//========================================================================== -int PrepareStateParameters(FState * state, int numparams) -{ - int paramindex=StateParameters.Size(); - int i, v; - - v=0; - for(i=0;iParameterIndex = paramindex+1; - return paramindex; -} - -//========================================================================== -// -// Returns the index of the given line special -// -//========================================================================== -int FindLineSpecial(const char * string) -{ - const ACSspecials *spec; - - spec = is_special(string, (unsigned int)strlen(string)); - if (spec) return spec->Special; - return 0; -} - -//========================================================================== -// -// FindLineSpecialEx -// -// Like FindLineSpecial, but also returns the min and max argument count. -// -//========================================================================== - -int FindLineSpecialEx (const char *string, int *min_args, int *max_args) -{ - const ACSspecials *spec; - - spec = is_special(string, (unsigned int)strlen(string)); - if (spec != NULL) - { - *min_args = spec->MinArgs; - *max_args = MAX(spec->MinArgs, spec->MaxArgs); - return spec->Special; - } - *min_args = *max_args = 0; - return 0; -} - -//========================================================================== -// -// DoSpecialFunctions -// handles special functions that can't be dealt with by the generic routine -// -//========================================================================== -bool DoSpecialFunctions(FState & state, bool multistate, int * statecount, Baggage &bag) -{ - int i; - const ACSspecials *spec; - - if ((spec = is_special (sc_String, sc_StringLen)) != NULL) - { - - int paramindex=PrepareStateParameters(&state, 6); - - StateParameters[paramindex]=spec->Special; - - // Make this consistent with all other parameter parsing - if (SC_CheckToken('(')) - { - for (i = 0; i < 5;) - { - StateParameters[paramindex+i+1]=ParseExpression (false, bag.Info->Class); - i++; - if (!SC_CheckToken (',')) break; - } - SC_MustGetToken (')'); - } - else i=0; - - if (i < spec->MinArgs) - { - SC_ScriptError ("Too few arguments to %s", spec->name); - } - if (i > MAX (spec->MinArgs, spec->MaxArgs)) - { - SC_ScriptError ("Too many arguments to %s", spec->name); - } - state.Action = A_CallSpecial; - return true; - } - - // Check for A_MeleeAttack, A_MissileAttack, or A_ComboAttack - int batk = SC_MatchString (BasicAttackNames); - if (batk >= 0) - { - int paramindex=PrepareStateParameters(&state, 4); - - StateParameters[paramindex] = bag.BAttack.MeleeDamage; - StateParameters[paramindex+1] = bag.BAttack.MeleeSound; - StateParameters[paramindex+2] = bag.BAttack.MissileName; - StateParameters[paramindex+3] = bag.BAttack.MissileHeight; - state.Action = BasicAttacks[batk]; - return true; - } - return false; -} - -//========================================================================== -// -// RetargetState(Pointer)s -// -// These functions are used when a goto follows one or more labels. -// Because multiple labels are permitted to occur consecutively with no -// intervening states, it is not enough to remember the last label defined -// and adjust it. So these functions search for all labels that point to -// the current position in the state array and give them a copy of the -// target string instead. -// -//========================================================================== - -static void RetargetStatePointers (intptr_t count, const char *target, TArray & statelist) -{ - for(unsigned i = 0;i 0) - { - RetargetStatePointers(count, target, statelist[i].Children); - } - } -} - -static void RetargetStates (intptr_t count, const char *target) -{ - RetargetStatePointers(count, target, StateLabels); -} - -//========================================================================== -// -// Reads a state label that may contain '.'s. -// processes a state block -// -//========================================================================== -static FString ParseStateString() -{ - FString statestring; - - SC_MustGetString(); - statestring = sc_String; - if (SC_CheckString("::")) - { - SC_MustGetString (); - statestring << "::" << sc_String; - } - while (SC_CheckString (".")) - { - SC_MustGetString (); - statestring << "." << sc_String; - } - return statestring; -} - -//========================================================================== -// -// ProcessStates -// processes a state block -// -//========================================================================== -static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag) -{ - FString statestring; - intptr_t count = 0; - FState state; - FState * laststate = NULL; - intptr_t lastlabel = -1; - int minrequiredstate = -1; - - SC_MustGetStringName ("{"); - SC_SetEscape(false); // disable escape sequences in the state parser - while (!SC_CheckString ("}") && !sc_End) - { - memset(&state,0,sizeof(state)); - statestring = ParseStateString(); - if (!statestring.CompareNoCase("GOTO")) - { -do_goto: - statestring = ParseStateString(); - if (SC_CheckString ("+")) - { - SC_MustGetNumber (); - statestring += '+'; - statestring += sc_String; - } - // copy the text - this must be resolved later! - if (laststate != NULL) - { // Following a state definition: Modify it. - laststate->NextState = (FState*)copystring(statestring); - } - else if (lastlabel >= 0) - { // Following a label: Retarget it. - RetargetStates (count+1, statestring); - } - else - { - SC_ScriptError("GOTO before first state"); - } - } - else if (!statestring.CompareNoCase("STOP")) - { -do_stop: - if (laststate!=NULL) - { - laststate->NextState=(FState*)-1; - } - else if (lastlabel >=0) - { - RetargetStates (count+1, NULL); - } - else - { - SC_ScriptError("STOP before first state"); - continue; - } - } - else if (!statestring.CompareNoCase("WAIT") || !statestring.CompareNoCase("FAIL")) - { - if (!laststate) - { - SC_ScriptError("%s before first state", sc_String); - continue; - } - laststate->NextState=(FState*)-2; - } - else if (!statestring.CompareNoCase("LOOP")) - { - if (!laststate) - { - SC_ScriptError("LOOP before first state"); - continue; - } - laststate->NextState=(FState*)(lastlabel+1); - } - else - { - const char * statestrp; - - SC_MustGetString(); - if (SC_Compare (":")) - { - laststate = NULL; - do - { - lastlabel = count; - AddState(statestring, (FState *) (count+1)); - statestring = ParseStateString(); - if (!statestring.CompareNoCase("GOTO")) - { - goto do_goto; - } - else if (!statestring.CompareNoCase("STOP")) - { - goto do_stop; - } - SC_MustGetString (); - } while (SC_Compare (":")); -// continue; - } - - SC_UnGet (); - - if (statestring.Len() != 4) - { - SC_ScriptError ("Sprite names must be exactly 4 characters\n"); - } - - memcpy(state.sprite.name, statestring, 4); - state.Misc1=state.Misc2=0; - state.ParameterIndex=0; - SC_MustGetString(); - statestring = (sc_String+1); - statestrp = statestring; - state.Frame=(*sc_String&223)-'A'; - if ((*sc_String&223)<'A' || (*sc_String&223)>']') - { - SC_ScriptError ("Frames must be A-Z, [, \\, or ]"); - state.Frame=0; - } - - SC_MustGetNumber(); - sc_Number++; - state.Tics=sc_Number&255; - state.Misc1=(sc_Number>>8)&255; - if (state.Misc1) state.Frame|=SF_BIGTIC; - - while (SC_GetString() && !sc_Crossed) - { - if (SC_Compare("BRIGHT")) - { - state.Frame|=SF_FULLBRIGHT; - continue; - } - if (SC_Compare("OFFSET")) - { - if (state.Frame&SF_BIGTIC) - { - SC_ScriptError("You cannot use OFFSET with a state duration larger than 254!"); - } - // specify a weapon offset - SC_MustGetStringName("("); - SC_MustGetNumber(); - state.Misc1=sc_Number; - SC_MustGetStringName (","); - SC_MustGetNumber(); - state.Misc2=sc_Number; - SC_MustGetStringName(")"); - continue; - } - - // Make the action name lowercase to satisfy the gperf hashers - strlwr (sc_String); - - int minreq=count; - if (DoSpecialFunctions(state, !statestring.IsEmpty(), &minreq, bag)) - { - if (minreq>minrequiredstate) minrequiredstate=minreq; - goto endofstate; - } - - PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true); - if (sym != NULL && sym->SymbolType == SYM_ActionFunction) - { - PSymbolActionFunction *afd = static_cast(sym); - state.Action = afd->Function; - if (!afd->Arguments.IsEmpty()) - { - const char *params = afd->Arguments.GetChars(); - int numparams = (int)afd->Arguments.Len(); - - int v; - - if (!islower(*params)) - { - SC_MustGetStringName("("); - } - else - { - if (!SC_CheckString("(")) goto endofstate; - } - - int paramindex = PrepareStateParameters(&state, numparams); - int paramstart = paramindex; - bool varargs = params[numparams - 1] == '+'; - - if (varargs) - { - StateParameters[paramindex++] = 0; - } - - while (*params) - { - switch(*params) - { - case 'I': - case 'i': // Integer - SC_MustGetNumber(); - v=sc_Number; - break; - - case 'F': - case 'f': // Fixed point - SC_MustGetFloat(); - v=fixed_t(sc_Float*FRACUNIT); - break; - - - case 'S': - case 's': // Sound name - SC_MustGetString(); - v=S_FindSound(sc_String); - break; - - case 'M': - case 'm': // Actor name - case 'T': - case 't': // String - SC_SetEscape(true); - SC_MustGetString(); - SC_SetEscape(false); - v = (int)(sc_String[0] ? FName(sc_String) : NAME_None); - break; - - case 'L': - case 'l': // Jump label - - if (SC_CheckNumber()) - { - if (strlen(statestring)>0) - { - SC_ScriptError("You cannot use A_Jump commands with a jump index on multistate definitions\n"); - } - - v=sc_Number; - if (v<1) - { - SC_ScriptError("Negative jump offsets are not allowed"); - } - - { - int minreq=count+v; - if (minreq>minrequiredstate) minrequiredstate=minreq; - } - } - else - { - if (JumpParameters.Size()==0) JumpParameters.Push(NAME_None); - - v = -(int)JumpParameters.Size(); - FString statestring = ParseStateString(); - const PClass *stype=NULL; - int scope = statestring.IndexOf("::"); - if (scope >= 0) - { - FName scopename = FName(statestring, scope, false); - if (scopename == NAME_Super) - { - // Super refers to the direct superclass - scopename = actor->Class->ParentClass->TypeName; - } - JumpParameters.Push(scopename); - statestring = statestring.Right(statestring.Len()-scope-2); - - stype = PClass::FindClass (scopename); - if (stype == NULL) - { - SC_ScriptError ("%s is an unknown class.", scopename.GetChars()); - } - if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor))) - { - SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars()); - } - if (!stype->IsAncestorOf (actor->Class)) - { - SC_ScriptError ("%s is not derived from %s so cannot access its states.", - actor->Class->TypeName.GetChars(), stype->TypeName.GetChars()); - } - } - else - { - // No class name is stored. This allows 'virtual' jumps to - // labels in subclasses. - // It also means that the validity of the given state cannot - // be checked here. - JumpParameters.Push(NAME_None); - } - TArray names; - MakeStateNameList(statestring, &names); - - if (stype != NULL) - { - if (!stype->ActorInfo->FindState(names.Size(), &names[0])) - { - SC_ScriptError("Jump to unknown state '%s' in class '%s'", - statestring.GetChars(), stype->TypeName.GetChars()); - } - } - JumpParameters.Push((ENamedName)names.Size()); - for(unsigned i=0;iClass); - break; - - case 'Y': - case 'y': - v = ParseExpression (true, bag.Info->Class); - break; - - default: - assert(false); - v = -1; - break; - } - StateParameters[paramindex++] = v; - params++; - if (varargs) - { - StateParameters[paramstart]++; - } - if (*params) - { - if (*params == '+') - { - if (SC_CheckString(")")) - { - goto endofstate; - } - params--; - v = 0; - StateParameters.Push(v); - } - else if ((islower(*params) || *params=='!') && SC_CheckString(")")) - { - goto endofstate; - } - SC_MustGetStringName (","); - } - } - SC_MustGetStringName(")"); - } - else - { - SC_MustGetString(); - if (SC_Compare("(")) - { - SC_ScriptError("You cannot pass parameters to '%s'\n",sc_String); - } - SC_UnGet(); - } - goto endofstate; - } - SC_ScriptError("Invalid state parameter %s\n", sc_String); - } - SC_UnGet(); -endofstate: - StateArray.Push(state); - while (*statestrp) - { - int frame=((*statestrp++)&223)-'A'; - - if (frame<0 || frame>28) - { - SC_ScriptError ("Frames must be A-Z, [, \\, or ]"); - frame=0; - } - - state.Frame=(state.Frame&(SF_FULLBRIGHT|SF_BIGTIC))|frame; - StateArray.Push(state); - count++; - } - laststate=&StateArray[count]; - count++; - } - } - if (count<=minrequiredstate) - { - SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars()); - } - SC_SetEscape(true); // re-enable escape sequences - return count; -} - -//========================================================================== -// -// ResolveGotoLabel -// -//========================================================================== - -static FState *ResolveGotoLabel (AActor *actor, const PClass *mytype, char *name) -{ - const PClass *type=mytype; - FState *state; - char *namestart = name; - char *label, *offset, *pt; - int v; - - // Check for classname - if ((pt = strstr (name, "::")) != NULL) - { - const char *classname = name; - *pt = '\0'; - name = pt + 2; - - // The classname may either be "Super" to identify this class's immediate - // superclass, or it may be the name of any class that this one derives from. - if (stricmp (classname, "Super") == 0) - { - type = type->ParentClass; - actor = GetDefaultByType (type); - } - else - { - // first check whether a state of the desired name exists - const PClass *stype = PClass::FindClass (classname); - if (stype == NULL) - { - SC_ScriptError ("%s is an unknown class.", classname); - } - if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor))) - { - SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars()); - } - if (!stype->IsAncestorOf (type)) - { - SC_ScriptError ("%s is not derived from %s so cannot access its states.", - type->TypeName.GetChars(), stype->TypeName.GetChars()); - } - if (type != stype) - { - type = stype; - actor = GetDefaultByType (type); - } - } - } - label = name; - // Check for offset - offset = NULL; - if ((pt = strchr (name, '+')) != NULL) - { - *pt = '\0'; - offset = pt + 1; - } - v = offset ? strtol (offset, NULL, 0) : 0; - - // Get the state's address. - if (type==mytype) state = FindState (actor, type, label); - else state = FindStateInClass (actor, type, label); - - if (state != NULL) - { - state += v; - } - else if (v != 0) - { - SC_ScriptError ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars()); - } - delete[] namestart; // free the allocated string buffer - return state; -} - -//========================================================================== -// -// FixStatePointers -// -// Fixes an actor's default state pointers. -// -//========================================================================== - -static void FixStatePointers (FActorInfo *actor, TArray & list) -{ - for(unsigned i=0;i= 1 && v < 0x10000) - { - list[i].State = actor->OwnedStates + v - 1; - } - if (list[i].Children.Size() > 0) FixStatePointers(actor, list[i].Children); - } -} - -//========================================================================== -// -// FixStatePointersAgain -// -// Resolves an actor's state pointers that were specified as jumps. -// -//========================================================================== - -static void FixStatePointersAgain (FActorInfo *actor, AActor *defaults, TArray & list) -{ - for(unsigned i=0;iClass, (char *)list[i].State); - } - if (list[i].Children.Size() > 0) FixStatePointersAgain(actor, defaults, list[i].Children); - } -} - - -//========================================================================== -// -// FinishStates -// copies a state block and fixes all state links -// -//========================================================================== - -static int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag) -{ - static int c=0; - int count = StateArray.Size(); - - if (count > 0) - { - FState *realstates = new FState[count]; - int i; - int currange; - - memcpy(realstates, &StateArray[0], count*sizeof(FState)); - actor->OwnedStates = realstates; - actor->NumOwnedStates = count; - - // adjust the state pointers - // In the case new states are added these must be adjusted, too! - FixStatePointers (actor, StateLabels); - - for(i = currange = 0; i < count; i++) - { - // resolve labels and jumps - switch((ptrdiff_t)realstates[i].NextState) - { - case 0: // next - realstates[i].NextState = (i < count-1 ? &realstates[i+1] : &realstates[0]); - break; - - case -1: // stop - realstates[i].NextState = NULL; - break; - - case -2: // wait - realstates[i].NextState = &realstates[i]; - break; - - default: // loop - if ((size_t)realstates[i].NextState < 0x10000) - { - realstates[i].NextState = &realstates[(size_t)realstates[i].NextState-1]; - } - else // goto - { - realstates[i].NextState = ResolveGotoLabel (defaults, bag.Info->Class, (char *)realstates[i].NextState); - } - } - } - } - StateArray.Clear (); - - // Fix state pointers that are gotos - FixStatePointersAgain (actor, defaults, StateLabels); - - return count; -} - -//========================================================================== -// -// For getting a state address from the parent -// No attempts have been made to add new functionality here -// This is strictly for keeping compatibility with old WADs! -// -//========================================================================== -static FState *CheckState(PClass *type) -{ - int v=0; - - if (SC_GetString() && !sc_Crossed) - { - if (SC_Compare("0")) return NULL; - else if (SC_Compare("PARENT")) - { - FState * state = NULL; - SC_MustGetString(); - - FActorInfo * info = type->ParentClass->ActorInfo; - - if (info != NULL) - { - state = info->FindState(FName(sc_String)); - } - - if (SC_GetString ()) - { - if (SC_Compare ("+")) - { - SC_MustGetNumber (); - v = sc_Number; - } - else - { - SC_UnGet (); - } - } - - if (state == NULL && v==0) return NULL; - - if (v!=0 && state==NULL) - { - SC_ScriptError("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars()); - return NULL; - } - state+=v; - return state; - } - else SC_ScriptError("Invalid state assignment"); - } - return NULL; -} - - -//========================================================================== -// -// Checks for a numeric parameter which may or may not be preceded by a comma -// -//========================================================================== -static bool CheckNumParm() -{ - if (SC_CheckString(",")) - { - SC_MustGetNumber(); - return true; - } - else - { - return !!SC_CheckNumber(); - } -} - -static bool CheckFloatParm() -{ - if (SC_CheckString(",")) - { - SC_MustGetFloat(); - return true; - } - else - { - return !!SC_CheckFloat(); - } -} - -//========================================================================== -// -// Handle actor properties -// -//========================================================================== -void ParseActorProperties (Baggage &bag) -{ - const PClass *info; - const ActorProps *prop; - - SC_MustGetStringName ("{"); - while (!SC_CheckString ("}")) - { - if (sc_End) - { - SC_ScriptError("Unexpected end of file encountered"); - } - - SC_GetString (); - strlwr (sc_String); - - // Walk the ancestors of this type and see if any of them know - // about the property. - info = bag.Info->Class; - - FString propname = sc_String; - - if (sc_String[0]!='-' && sc_String[0]!='+') - { - if (SC_CheckString (".")) - { - SC_MustGetString (); - propname += '.'; - strlwr (sc_String); - propname += sc_String; - } - else - { - SC_UnGet (); - } - } - prop = is_actorprop (propname.GetChars()); - - if (prop != NULL) - { - if (!info->IsDescendantOf(prop->type)) - { - SC_ScriptError("\"%s\" requires an actor of type \"%s\"\n", propname.GetChars(), prop->type->TypeName.GetChars()); - } - else - { - prop->Handler ((AActor *)bag.Info->Class->Defaults, bag); - } - } - else - { - SC_ScriptError("\"%s\" is an unknown actor property\n", propname.GetChars()); - } - } -} - //========================================================================== // // Reads an actor definition // //========================================================================== -void ProcessActor() +void ParseActor() { FActorInfo * info=NULL; - AActor * defaults; Baggage bag; try { FActorInfo * parent; - info=CreateNewActor(&parent, &bag); - defaults=(AActor*)info->Class->Defaults; - bag.StateSet = false; - bag.DropItemSet = false; - bag.CurrentState = 0; + SC_MustGetToken('{'); + while (SC_MustGetAnyToken(), sc_TokenType != '}') + { + switch (sc_TokenType) + { + case TK_Action: + ParseActionDef (info->Class); + break; - ParseActorProperties (bag); - FinishStates (info, defaults, bag); - InstallStates (info, defaults); - ProcessStates (info->OwnedStates, info->NumOwnedStates); - if (bag.DropItemSet) - { - if (bag.DropItemList == NULL) - { - if (info->Class->Meta.GetMetaInt (ACMETA_DropItems) != 0) - { - info->Class->Meta.SetMetaInt (ACMETA_DropItems, 0); - } - } - else - { - info->Class->Meta.SetMetaInt (ACMETA_DropItems, - DropItemList.Push (bag.DropItemList) + 1); + case TK_Const: + ParseConstant (&info->Class->Symbols, info->Class); + break; + + case TK_Enum: + ParseEnum (&info->Class->Symbols, info->Class); + break; + + case TK_Identifier: + // other identifier related checks here + case TK_Projectile: // special case: both keyword and property name + ParseActorProperty(bag); + break; + + case '+': + case '-': + ParseActorFlag(bag, sc_TokenType); + break; + + default: + SC_ScriptError("Unexpected '%s' in definition of '%s'", sc_String, bag.Info->Class->TypeName.GetChars()); + break; } + } - if (info->Class->IsDescendantOf (RUNTIME_CLASS(AInventory))) - { - defaults->flags |= MF_SPECIAL; - } + + FinishActor(info, bag); } catch(CRecoverableError & e) @@ -2207,2136 +485,6 @@ void ProcessActor() SC_SetCMode (false); } -//========================================================================== -// -// StatePropertyIsDeprecated -// -//========================================================================== - -static void StatePropertyIsDeprecated (const char *actorname, const char *prop) -{ - /* - static bool warned = false; - - Printf (TEXTCOLOR_YELLOW "In actor %s, the %s property is deprecated.\n", actorname, prop); - if (!warned) - { - warned = true; - Printf (TEXTCOLOR_YELLOW "Instead of \"%s \", add this to the actor's States block:\n" - TEXTCOLOR_YELLOW " %s:\n" - TEXTCOLOR_YELLOW " Goto \n", prop, prop); - } - */ -} - -//========================================================================== -// -// Property parsers -// -//========================================================================== - -//========================================================================== -// -// ActorConstDef -// -// Parses a constant definition. -// -//========================================================================== - -static void ActorConstDef (AActor *defaults, Baggage &bag) -{ - // Read the type and make sure it's int. - // (Maybe there will be other types later.) - SC_MustGetToken(TK_Int); - SC_MustGetToken(TK_Identifier); - FName symname = sc_String; - SC_MustGetToken('='); - int expr = ParseExpression (false, bag.Info->Class); - SC_MustGetToken(';'); - - int val = EvalExpressionI (expr, NULL, bag.Info->Class); - PSymbolConst *sym = new PSymbolConst; - sym->SymbolName = symname; - sym->SymbolType = SYM_Const; - sym->Value = val; - if (bag.Info->Class->Symbols.AddSymbol (sym) == NULL) - { - delete sym; - SC_ScriptError ("'%s' is already defined in class '%s'.", - symname.GetChars(), bag.Info->Class->TypeName.GetChars()); - } -} - -//========================================================================== -// -// ActorEnumDef -// -// Parses an enum definition. -// -//========================================================================== - -static void ActorEnumDef (AActor *defaults, Baggage &bag) -{ - int currvalue = 0; - - SC_MustGetToken('{'); - while (!SC_CheckToken('}')) - { - SC_MustGetToken(TK_Identifier); - FName symname = sc_String; - if (SC_CheckToken('=')) - { - int expr = ParseExpression(false, bag.Info->Class); - currvalue = EvalExpressionI (expr, NULL, bag.Info->Class); - } - PSymbolConst *sym = new PSymbolConst; - sym->SymbolName = symname; - sym->SymbolType = SYM_Const; - sym->Value = currvalue; - if (bag.Info->Class->Symbols.AddSymbol (sym) == NULL) - { - delete sym; - SC_ScriptError ("'%s' is already defined in class '%s'.", - symname.GetChars(), bag.Info->Class->TypeName.GetChars()); - } - // This allows a comma after the last value but doesn't enforce it. - if (SC_CheckToken('}')) break; - SC_MustGetToken(','); - currvalue++; - } - SC_MustGetToken(';'); -} - -//========================================================================== -// -// ParseGlobalConst -// -// Parses a constant outside an actor definition -// These will be inserted into AActor's symbol table -// -//========================================================================== - -void ParseGlobalConst() -{ - Baggage bag; - - bag.Info = RUNTIME_CLASS(AActor)->ActorInfo; - ActorConstDef(GetDefault(), bag); -} - -void ParseGlobalEnum() -{ - Baggage bag; - - bag.Info = RUNTIME_CLASS(AActor)->ActorInfo; - ActorEnumDef(GetDefault(), bag); -} - -//========================================================================== -// -// ActorActionDef -// -// Parses an action function definition. A lot of this is essentially -// documentation in the declaration for when I have a proper language -// ready. -// -//========================================================================== - -static void ActorActionDef (AActor *defaults, Baggage &bag) -{ -#define OPTIONAL 1 -#define EVAL 2 -#define EVALNOT 4 - - AFuncDesc *afd; - FName funcname; - FString args; - - SC_MustGetToken(TK_Native); - SC_MustGetToken(TK_Identifier); - funcname = sc_String; - afd = FindFunction(sc_String); - if (afd == NULL) - { - SC_ScriptError ("The function '%s' has not been exported from the executable.", sc_String); - } - SC_MustGetToken('('); - if (!SC_CheckToken(')')) - { - while (sc_TokenType != ')') - { - int flags = 0; - char type = '@'; - - // Retrieve flags before type name - for (;;) - { - if (SC_CheckToken(TK_Optional)) - { - flags |= OPTIONAL; - } - else if (SC_CheckToken(TK_Eval)) - { - flags |= EVAL; - } - else if (SC_CheckToken(TK_EvalNot)) - { - flags |= EVALNOT; - } - else if (SC_CheckToken(TK_Coerce) || SC_CheckToken(TK_Native)) - { - } - else - { - break; - } - } - // Read the variable type - SC_MustGetAnyToken(); - switch (sc_TokenType) - { - case TK_Bool: type = 'i'; break; - case TK_Int: type = 'i'; break; - case TK_Float: type = 'f'; break; - case TK_Sound: type = 's'; break; - case TK_String: type = 't'; break; - case TK_Name: type = 't'; break; - case TK_State: type = 'l'; break; - case TK_Color: type = 'c'; break; - case TK_Class: - SC_MustGetToken('<'); - SC_MustGetToken(TK_Identifier); // Skip class name, since the parser doesn't care - SC_MustGetToken('>'); - type = 'm'; - break; - case TK_Ellipsis: - type = '+'; - SC_MustGetToken(')'); - SC_UnGet(); - break; - default: - SC_ScriptError ("Unknown variable type %s", SC_TokenName(sc_TokenType, sc_String).GetChars()); - break; - } - // Read the optional variable name - if (!SC_CheckToken(',') && !SC_CheckToken(')')) - { - SC_MustGetToken(TK_Identifier); - } - else - { - SC_UnGet(); - } - // If eval or evalnot were a flag, hey the decorate parser doesn't actually care about the type. - if (flags & EVALNOT) - { - type = 'y'; - } - else if (flags & EVAL) - { - type = 'x'; - } - if (!(flags & OPTIONAL) && type != '+') - { - type -= 'a' - 'A'; - } - #undef OPTIONAL - #undef EVAL - #undef EVALNOT - args += type; - SC_MustGetAnyToken(); - if (sc_TokenType != ',' && sc_TokenType != ')') - { - SC_ScriptError ("Expected ',' or ')' but got %s instead", SC_TokenName(sc_TokenType, sc_String).GetChars()); - } - } - } - SC_MustGetToken(';'); - PSymbolActionFunction *sym = new PSymbolActionFunction; - sym->SymbolName = funcname; - sym->SymbolType = SYM_ActionFunction; - sym->Arguments = args; - sym->Function = afd->Function; - if (bag.Info->Class->Symbols.AddSymbol (sym) == NULL) - { - delete sym; - SC_ScriptError ("'%s' is already defined in class '%s'.", - funcname.GetChars(), bag.Info->Class->TypeName.GetChars()); - } -} - -//========================================================================== -// -//========================================================================== -static void ActorSkipSuper (AActor *defaults, Baggage &bag) -{ - ResetActor(defaults, &bag); -} - -//========================================================================== -// -//========================================================================== -static void ActorGame (AActor *defaults, Baggage &bag) -{ - SC_MustGetString (); - if (SC_Compare ("Doom")) - { - bag.Info->GameFilter |= GAME_Doom; - } - else if (SC_Compare ("Heretic")) - { - bag.Info->GameFilter |= GAME_Heretic; - } - else if (SC_Compare ("Hexen")) - { - bag.Info->GameFilter |= GAME_Hexen; - } - else if (SC_Compare ("Raven")) - { - bag.Info->GameFilter |= GAME_Raven; - } - else if (SC_Compare ("Strife")) - { - bag.Info->GameFilter |= GAME_Strife; - } - else if (SC_Compare ("Any")) - { - bag.Info->GameFilter = GAME_Any; - } - else - { - SC_ScriptError ("Unknown game type %s", sc_String); - } -} - -//========================================================================== -// -//========================================================================== -static void ActorSpawnID (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - if (sc_Number<0 || sc_Number>255) - { - SC_ScriptError ("SpawnID must be in the range [0,255]"); - } - else bag.Info->SpawnID=(BYTE)sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorConversationID (AActor *defaults, Baggage &bag) -{ - int convid; - - SC_MustGetNumber(); - convid = sc_Number; - - // Handling for Strife teaser IDs - only of meaning for the standard items - // as PWADs cannot be loaded with the teasers. - if (SC_CheckString(",")) - { - SC_MustGetNumber(); - if ((gameinfo.flags & (GI_SHAREWARE|GI_TEASER2)) == (GI_SHAREWARE)) - convid=sc_Number; - - SC_MustGetStringName(","); - SC_MustGetNumber(); - if ((gameinfo.flags & (GI_SHAREWARE|GI_TEASER2)) == (GI_SHAREWARE|GI_TEASER2)) - convid=sc_Number; - - if (convid==-1) return; - } - if (convid<0 || convid>1000) - { - SC_ScriptError ("ConversationID must be in the range [0,1000]"); - } - else StrifeTypes[convid] = bag.Info->Class; -} - -//========================================================================== -// -//========================================================================== -static void ActorTag (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - bag.Info->Class->Meta.SetMetaString(AMETA_StrifeName, sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorHealth (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->health=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorGibHealth (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt (AMETA_GibHealth, sc_Number); -} - -//========================================================================== -// -//========================================================================== -static void ActorWoundHealth (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt (AMETA_WoundHealth, sc_Number); -} - -//========================================================================== -// -//========================================================================== -static void ActorReactionTime (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->reactiontime=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorPainChance (AActor *defaults, Baggage &bag) -{ - if (!SC_CheckNumber()) - { - FName painType; - if (SC_Compare("Normal")) painType = NAME_None; - else painType=sc_String; - SC_MustGetToken(','); - SC_MustGetNumber(); - - if (bag.Info->PainChances == NULL) bag.Info->PainChances=new PainChanceList; - (*bag.Info->PainChances)[painType] = (BYTE)sc_Number; - return; - } - defaults->PainChance=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorDamage (AActor *defaults, Baggage &bag) -{ - // Damage can either be a single number, in which case it is subject - // to the original damage calculation rules. Or, it can be an expression - // and will be calculated as-is, ignoring the original rules. For - // compatibility reasons, expressions must be enclosed within - // parentheses. - - if (SC_CheckString ("(")) - { - defaults->Damage = 0x40000000 | ParseExpression (false, bag.Info->Class); - SC_MustGetStringName(")"); - } - else - { - SC_MustGetNumber (); - defaults->Damage = sc_Number; - } -} - -//========================================================================== -// -//========================================================================== -static void ActorSpeed (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->Speed=fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorFloatSpeed (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->FloatSpeed=fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorRadius (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->radius=fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorHeight (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->height=fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorMass (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->Mass=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorXScale (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->scaleX = FLOAT2FIXED(sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void ActorYScale (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->scaleY = FLOAT2FIXED(sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void ActorScale (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->scaleX= defaults->scaleY = FLOAT2FIXED(sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void ActorArgs (AActor *defaults, Baggage &bag) -{ - for (int i=0;i<5;i++) - { - SC_MustGetNumber(); - defaults->args[i] = sc_Number; - if (i < 4 && !SC_CheckToken(',')) break; - } - defaults->flags2|=MF2_ARGSDEFINED; -} - -//========================================================================== -// -//========================================================================== -static void ActorSeeSound (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->SeeSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorAttackSound (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->AttackSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorPainSound (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->PainSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorDeathSound (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->DeathSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorActiveSound (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->ActiveSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorHowlSound (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - bag.Info->Class->Meta.SetMetaInt (AMETA_HowlSound, S_FindSound(sc_String)); -} - -//========================================================================== -// -//========================================================================== -static void ActorDropItem (AActor *defaults, Baggage &bag) -{ - // create a linked list of dropitems - if (!bag.DropItemSet) - { - bag.DropItemSet = true; - bag.DropItemList = NULL; - } - - FDropItem * di=new FDropItem; - - SC_MustGetString(); - di->Name=sc_String; - di->probability=255; - di->amount=-1; - - if (CheckNumParm()) - { - di->probability=sc_Number; - if (CheckNumParm()) - { - di->amount=sc_Number; - } - } - di->Next = bag.DropItemList; - bag.DropItemList = di; -} - -//========================================================================== -// -//========================================================================== -static void ActorSpawnState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Spawn"); - AddState("Spawn", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorSeeState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "See"); - AddState("See", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorMeleeState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Melee"); - AddState("Melee", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorMissileState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Missile"); - AddState("Missile", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorPainState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Pain"); - AddState("Pain", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorDeathState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Death"); - AddState("Death", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorXDeathState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "XDeath"); - AddState("XDeath", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorBurnState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Burn"); - AddState("Burn", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorIceState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Ice"); - AddState("Ice", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorRaiseState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Raise"); - AddState("Raise", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorCrashState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Crash"); - AddState("Crash", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorCrushState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Crush"); - AddState("Crush", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorWoundState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Wound"); - AddState("Wound", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorDisintegrateState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Disintegrate"); - AddState("Disintegrate", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorHealState (AActor *defaults, Baggage &bag) -{ - StatePropertyIsDeprecated (bag.Info->Class->TypeName.GetChars(), "Heal"); - AddState("Heal", CheckState ( bag.Info->Class)); -} - -//========================================================================== -// -//========================================================================== -static void ActorStates (AActor *defaults, Baggage &bag) -{ - if (!bag.StateSet) ProcessStates(bag.Info, defaults, bag); - else SC_ScriptError("Multiple state declarations not allowed"); - bag.StateSet=true; -} - -//========================================================================== -// -//========================================================================== -static void ActorRenderStyle (AActor *defaults, Baggage &bag) -{ - static const char * renderstyles[]={ - "NONE","NORMAL","FUZZY","SOULTRANS","OPTFUZZY","STENCIL","TRANSLUCENT", "ADD",NULL}; - - static const int renderstyle_values[]={ - STYLE_None, STYLE_Normal, STYLE_Fuzzy, STYLE_SoulTrans, STYLE_OptFuzzy, - STYLE_Stencil, STYLE_Translucent, STYLE_Add}; - - SC_MustGetString(); - defaults->RenderStyle=renderstyle_values[SC_MustMatchString(renderstyles)]; -} - -//========================================================================== -// -//========================================================================== -static void ActorAlpha (AActor *defaults, Baggage &bag) -{ - if (SC_CheckString("DEFAULT")) - { - defaults->alpha = gameinfo.gametype==GAME_Heretic? HR_SHADOW : HX_SHADOW; - } - else - { - SC_MustGetFloat(); - defaults->alpha=fixed_t(sc_Float*FRACUNIT); - } -} - -//========================================================================== -// -//========================================================================== -static void ActorObituary (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - bag.Info->Class->Meta.SetMetaString (AMETA_Obituary, sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorHitObituary (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - bag.Info->Class->Meta.SetMetaString (AMETA_HitObituary, sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorDontHurtShooter (AActor *defaults, Baggage &bag) -{ - bag.Info->Class->Meta.SetMetaInt (ACMETA_DontHurtShooter, true); -} - -//========================================================================== -// -//========================================================================== -static void ActorExplosionRadius (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt (ACMETA_ExplosionRadius, sc_Number); -} - -//========================================================================== -// -//========================================================================== -static void ActorExplosionDamage (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt (ACMETA_ExplosionDamage, sc_Number); -} - -//========================================================================== -// -//========================================================================== -static void ActorDeathHeight (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - fixed_t h = fixed_t(sc_Float * FRACUNIT); - // AActor::Die() uses a height of 0 to mean "cut the height to 1/4", - // so if a height of 0 is desired, store it as -1. - bag.Info->Class->Meta.SetMetaFixed (AMETA_DeathHeight, h <= 0 ? -1 : h); -} - -//========================================================================== -// -//========================================================================== -static void ActorBurnHeight (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - fixed_t h = fixed_t(sc_Float * FRACUNIT); - // The note above for AMETA_DeathHeight also applies here. - bag.Info->Class->Meta.SetMetaFixed (AMETA_BurnHeight, h <= 0 ? -1 : h); -} - -//========================================================================== -// -//========================================================================== -static void ActorMaxTargetRange (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->maxtargetrange = fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorMeleeThreshold (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->meleethreshold = fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorMeleeDamage (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.BAttack.MeleeDamage = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorMeleeRange (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->meleerange = fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorMeleeSound (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - bag.BAttack.MeleeSound = S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void ActorMissileType (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - bag.BAttack.MissileName = sc_String; -} - -//========================================================================== -// -//========================================================================== -static void ActorMissileHeight (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - bag.BAttack.MissileHeight = fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorTranslation (AActor *defaults, Baggage &bag) -{ - if (SC_CheckNumber()) - { - int max = (gameinfo.gametype==GAME_Strife || (bag.Info->GameFilter&GAME_Strife)) ? 6:2; - if (sc_Number < 0 || sc_Number > max) - { - SC_ScriptError ("Translation must be in the range [0,%d]", max); - } - defaults->Translation = TRANSLATION(TRANSLATION_Standard, sc_Number); - } - else - { - unsigned char translation[256]; - for(int i=0;i<256;i++) translation[i]=i; - do - { - SC_GetString(); - AddToTranslation(translation,sc_String); - } - while (SC_CheckString(",")); - defaults->Translation = StoreTranslation (translation); - } -} - -//========================================================================== -// -//========================================================================== -static void ActorBloodColor (AActor *defaults, Baggage &bag) -{ - int r,g,b; - - if (SC_CheckNumber()) - { - SC_MustGetNumber(); - r=clamp(sc_Number, 0, 255); - SC_CheckString(","); - SC_MustGetNumber(); - g=clamp(sc_Number, 0, 255); - SC_CheckString(","); - SC_MustGetNumber(); - b=clamp(sc_Number, 0, 255); - } - else - { - SC_MustGetString(); - int c = V_GetColor(NULL, sc_String); - r=RPART(c); - g=GPART(c); - b=BPART(c); - } - PalEntry pe = MAKERGB(r,g,b); - pe.a = CreateBloodTranslation(pe); - bag.Info->Class->Meta.SetMetaInt (AMETA_BloodColor, pe); -} - - -//========================================================================== -// -//========================================================================== -static void ActorBloodType (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - FName blood = sc_String; - // normal blood - bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType, blood); - - if (SC_CheckString(",")) - { - SC_MustGetString(); - blood = sc_String; - } - // blood splatter - bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType2, blood); - - if (SC_CheckString(",")) - { - SC_MustGetString(); - blood = sc_String; - } - // axe blood - bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType3, blood); -} - -//========================================================================== -// -//========================================================================== -static void ActorBounceFactor (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat (); - defaults->bouncefactor = clamp(fixed_t(sc_Float * FRACUNIT), 0, FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorBounceCount (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber (); - defaults->bouncecount = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorMinMissileChance (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber (); - defaults->MinMissileChance=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ActorDamageType (AActor *defaults, Baggage &bag) -{ - SC_MustGetString (); - if (SC_Compare("Normal")) defaults->DamageType = NAME_None; - else defaults->DamageType=sc_String; -} - -//========================================================================== -// -//========================================================================== -static void ActorDamageFactor (AActor *defaults, Baggage &bag) -{ - SC_MustGetString (); - if (bag.Info->DamageFactors == NULL) bag.Info->DamageFactors=new DmgFactors; - - FName dmgType; - if (SC_Compare("Normal")) dmgType = NAME_None; - else dmgType=sc_String; - - SC_MustGetToken(','); - SC_MustGetFloat(); - (*bag.Info->DamageFactors)[dmgType]=(fixed_t)(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorDecal (AActor *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->DecalGenerator = (FDecalBase *) ((size_t)DecalNames.Push(copystring(sc_String))+1); -} - -//========================================================================== -// -//========================================================================== -static void ActorMaxStepHeight (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber (); - defaults->MaxStepHeight=sc_Number * FRACUNIT; -} - -//========================================================================== -// -//========================================================================== -static void ActorMaxDropoffHeight (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber (); - defaults->MaxDropOffHeight=sc_Number * FRACUNIT; -} - -//========================================================================== -// -//========================================================================== -static void ActorPoisonDamage (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt (AMETA_PoisonDamage, sc_Number); -} - -//========================================================================== -// -//========================================================================== -static void ActorFastSpeed (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - bag.Info->Class->Meta.SetMetaFixed (AMETA_FastSpeed, fixed_t(sc_Float*FRACUNIT)); -} - -//========================================================================== -// -//========================================================================== -static void ActorRadiusDamageFactor (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - bag.Info->Class->Meta.SetMetaFixed (AMETA_RDFactor, fixed_t(sc_Float*FRACUNIT)); -} - -//========================================================================== -// -//========================================================================== -static void ActorCameraheight (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - bag.Info->Class->Meta.SetMetaFixed (AMETA_CameraHeight, fixed_t(sc_Float*FRACUNIT)); -} - -//========================================================================== -// -//========================================================================== -static void ActorVSpeed (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->momz = fixed_t(sc_Float*FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void ActorGravity (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat (); - - if (sc_Float < 0.f || sc_Float > 1.f) - SC_ScriptError ("Gravity must be in the range [0,1]"); - - defaults->gravity = FLOAT2FIXED (sc_Float); - - if (sc_Float == 0.f) - defaults->flags |= MF_NOGRAVITY; -} - -//========================================================================== -// -//========================================================================== -static void ActorClearFlags (AActor *defaults, Baggage &bag) -{ - defaults->flags=defaults->flags3=defaults->flags4=defaults->flags5=0; - defaults->flags2&=MF2_ARGSDEFINED; // this flag must not be cleared -} - -//========================================================================== -// -//========================================================================== -static void ActorMonster (AActor *defaults, Baggage &bag) -{ - // sets the standard flag for a monster - defaults->flags|=MF_SHOOTABLE|MF_COUNTKILL|MF_SOLID; - defaults->flags2|=MF2_PUSHWALL|MF2_MCROSS|MF2_PASSMOBJ; - defaults->flags3|=MF3_ISMONSTER; - defaults->flags4|=MF4_CANUSEWALLS; -} - -//========================================================================== -// -//========================================================================== -static void ActorProjectile (AActor *defaults, Baggage &bag) -{ - // sets the standard flags for a projectile - defaults->flags|=MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE; - defaults->flags2|=MF2_IMPACT|MF2_PCROSS|MF2_NOTELEPORT; - if (gameinfo.gametype&GAME_Raven) defaults->flags5|=MF5_BLOODSPLATTER; -} - -//========================================================================== -// -//========================================================================== -static void ActorFlagSetOrReset (AActor *defaults, Baggage &bag) -{ - char mod = sc_String[0]; - flagdef *fd; - - SC_MustGetString (); - - FString part1 = sc_String; - const char *part2 = NULL; - if (SC_CheckString (".")) - { - SC_MustGetString (); - part2 = sc_String; - } - if ( (fd = FindFlag (bag.Info->Class, part1.GetChars(), part2)) ) - { - if (fd->structoffset == -1) // this is a deprecated flag that has been changed into a real property - { - HandleDeprecatedFlags(defaults, mod=='+', fd->flagbit); - } - else - { - DWORD * flagvar = (DWORD*) ((char*)defaults + fd->structoffset); - if (mod == '+') - { - *flagvar |= fd->flagbit; - } - else - { - *flagvar &= ~fd->flagbit; - } - } - } - else - { - if (part2 == NULL) - { - SC_ScriptError("\"%s\" is an unknown flag\n", part1.GetChars()); - } - else - { - SC_ScriptError("\"%s.%s\" is an unknown flag\n", part1.GetChars(), part2); - } - } -} - -//========================================================================== -// -// Special inventory properties -// -//========================================================================== - -//========================================================================== -// -//========================================================================== -static void AmmoBackpackAmount (AAmmo *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->BackpackAmount=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void AmmoBackpackMaxAmount (AAmmo *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->BackpackMaxAmount=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void AmmoDropAmount (AAmmo *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt (AIMETA_DropAmount, sc_Number); -} - -//========================================================================== -// -//========================================================================== -static void ArmorMaxSaveAmount (ABasicArmorBonus *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->MaxSaveAmount = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ArmorMaxBonus (ABasicArmorBonus *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->BonusCount = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ArmorMaxBonusMax (ABasicArmorBonus *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->BonusMax = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void ArmorSaveAmount (AActor *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - // Special case here because this property has to work for 2 unrelated classes - if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) - { - ((ABasicArmorPickup*)defaults)->SaveAmount=sc_Number; - } - else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) - { - ((ABasicArmorBonus*)defaults)->SaveAmount=sc_Number; - } - else - { - SC_ScriptError("\"%s\" requires an actor of type \"Armor\"\n", sc_String); - } -} - -//========================================================================== -// -//========================================================================== -static void ArmorSavePercent (AActor *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - if (sc_Float<0.0f) sc_Float=0.0f; - if (sc_Float>100.0f) sc_Float=100.0f; - // Special case here because this property has to work for 2 unrelated classes - if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) - { - ((ABasicArmorPickup*)defaults)->SavePercent=fixed_t(sc_Float*FRACUNIT/100.0f); - } - else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) - { - ((ABasicArmorBonus*)defaults)->SavePercent=fixed_t(sc_Float*FRACUNIT/100.0f); - } - else - { - SC_ScriptError("\"%s\" requires an actor of type \"Armor\"\n", sc_String); - } -} - -//========================================================================== -// -//========================================================================== -static void InventoryAmount (AInventory *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->Amount=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void InventoryIcon (AInventory *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->Icon = TexMan.AddPatch (sc_String); - if (defaults->Icon <= 0) - { - defaults->Icon = TexMan.AddPatch (sc_String, ns_sprites); - if (defaults->Icon<=0) - { - // Don't print warnings if the item is for another game or if this is a shareware IWAD. - // Strife's teaser doesn't contain all the icon graphics of the full game. - if ((bag.Info->GameFilter == GAME_Any || bag.Info->GameFilter & gameinfo.gametype) && - !(gameinfo.flags&GI_SHAREWARE)) - { - Printf("Icon '%s' for '%s' not found\n", sc_String, bag.Info->Class->TypeName.GetChars()); - } - } - } -} - -//========================================================================== -// -//========================================================================== -static void InventoryMaxAmount (AInventory *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->MaxAmount=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void InventoryDefMaxAmount (AInventory *defaults, Baggage &bag) -{ - defaults->MaxAmount = gameinfo.gametype == GAME_Heretic ? 16 : 25; -} - - -//========================================================================== -// -//========================================================================== -static void InventoryPickupmsg (AInventory *defaults, Baggage &bag) -{ - // allow game specific pickup messages - const char * games[] = {"Doom", "Heretic", "Hexen", "Raven", "Strife", NULL}; - int gamemode[]={GAME_Doom, GAME_Heretic, GAME_Hexen, GAME_Raven, GAME_Strife}; - - SC_MustGetString(); - int game = SC_MatchString(games); - - if (game!=-1 && SC_CheckString(",")) - { - SC_MustGetString(); - if (!(gameinfo.gametype&gamemode[game])) return; - } - bag.Info->Class->Meta.SetMetaString(AIMETA_PickupMessage, sc_String); -} - -//========================================================================== -// -//========================================================================== -static void InventoryPickupsound (AInventory *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->PickupSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void InventoryRespawntics (AInventory *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->RespawnTics=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void InventoryUsesound (AInventory *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->UseSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void InventoryGiveQuest (AInventory *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt(AIMETA_GiveQuest, sc_Number); -} - -//========================================================================== -// -//========================================================================== -static void HealthLowMessage (AHealth *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - bag.Info->Class->Meta.SetMetaInt(AIMETA_LowHealth, sc_Number); - SC_MustGetStringName(","); - SC_MustGetString(); - bag.Info->Class->Meta.SetMetaString(AIMETA_LowHealthMessage, sc_String); -} - -//========================================================================== -// -//========================================================================== -static void PuzzleitemNumber (APuzzleItem *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->PuzzleItemNumber=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void PuzzleitemFailMsg (APuzzleItem *defaults, Baggage &bag) -{ - SC_MustGetString(); - bag.Info->Class->Meta.SetMetaString(AIMETA_PuzzFailMessage, sc_String); -} - -//========================================================================== -// -//========================================================================== -static void WeaponAmmoGive1 (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->AmmoGive1=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void WeaponAmmoGive2 (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->AmmoGive2=sc_Number; -} - -//========================================================================== -// -// Passing these parameters is really tricky to allow proper inheritance -// and forward declarations. Here only a name is -// stored which must be resolved after everything has been declared -// -//========================================================================== - -static void WeaponAmmoType1 (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->AmmoType1 = fuglyname(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void WeaponAmmoType2 (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->AmmoType2 = fuglyname(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void WeaponAmmoUse1 (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->AmmoUse1=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void WeaponAmmoUse2 (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->AmmoUse2=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void WeaponKickback (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->Kickback=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void WeaponReadySound (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->ReadySound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void WeaponSelectionOrder (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->SelectionOrder=sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void WeaponSisterWeapon (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->SisterWeaponType=fuglyname(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void WeaponUpSound (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->UpSound=S_FindSound(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void WeaponYAdjust (AWeapon *defaults, Baggage &bag) -{ - SC_MustGetFloat(); - defaults->YAdjust=fixed_t(sc_Float * FRACUNIT); -} - -//========================================================================== -// -//========================================================================== -static void WPieceValue (AWeaponPiece *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->PieceValue = 1 << (sc_Number-1); -} - -//========================================================================== -// -//========================================================================== -static void WPieceWeapon (AWeaponPiece *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->WeaponClass = fuglyname(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void PowerupColor (APowerupGiver *defaults, Baggage &bag) -{ - int r; - int g; - int b; - int alpha; - - if (SC_CheckNumber()) - { - r=clamp(sc_Number, 0, 255); - SC_CheckString(","); - SC_MustGetNumber(); - g=clamp(sc_Number, 0, 255); - SC_CheckString(","); - SC_MustGetNumber(); - b=clamp(sc_Number, 0, 255); - } - else - { - SC_MustGetString(); - - if (SC_Compare("INVERSEMAP")) - { - defaults->BlendColor = INVERSECOLOR; - return; - } - else if (SC_Compare("GOLDMAP")) - { - defaults->BlendColor = GOLDCOLOR; - return; - } - // [BC] Yay, more hacks. - else if ( SC_Compare( "REDMAP" )) - { - defaults->BlendColor = REDCOLOR; - return; - } - else if ( SC_Compare( "GREENMAP" )) - { - defaults->BlendColor = GREENCOLOR; - return; - } - - int c = V_GetColor(NULL, sc_String); - r=RPART(c); - g=GPART(c); - b=BPART(c); - } - SC_CheckString(","); - SC_MustGetFloat(); - alpha=int(sc_Float*255); - alpha=clamp(alpha, 0, 255); - if (alpha!=0) defaults->BlendColor = MAKEARGB(alpha, r, g, b); - else defaults->BlendColor = 0; -} - -//========================================================================== -// -//========================================================================== -static void PowerupDuration (APowerupGiver *defaults, Baggage &bag) -{ - SC_MustGetNumber(); - defaults->EffectTics = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void PowerupMode (APowerupGiver *defaults, Baggage &bag) -{ - SC_MustGetString(); - defaults->mode = (FName)sc_String; -} - -//========================================================================== -// -//========================================================================== -static void PowerupType (APowerupGiver *defaults, Baggage &bag) -{ - FString typestr; - - SC_MustGetString(); - typestr.Format ("Power%s", sc_String); - const PClass * powertype=PClass::FindClass(typestr); - if (!powertype) - { - SC_ScriptError("Unknown powerup type '%s' in '%s'\n", sc_String, bag.Info->Class->TypeName.GetChars()); - } - else if (!powertype->IsDescendantOf(RUNTIME_CLASS(APowerup))) - { - SC_ScriptError("Invalid powerup type '%s' in '%s'\n", sc_String, bag.Info->Class->TypeName.GetChars()); - } - else - { - defaults->PowerupType=powertype; - } -} - -//========================================================================== -// -// [GRB] Special player properties -// -//========================================================================== - -//========================================================================== -// -//========================================================================== -static void PlayerDisplayName (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetString (); - bag.Info->Class->Meta.SetMetaString (APMETA_DisplayName, sc_String); -} - -//========================================================================== -// -//========================================================================== -static void PlayerSoundClass (APlayerPawn *defaults, Baggage &bag) -{ - FString tmp; - - SC_MustGetString (); - tmp = sc_String; - tmp.ReplaceChars (' ', '_'); - bag.Info->Class->Meta.SetMetaString (APMETA_SoundClass, tmp); -} - -//========================================================================== -// -//========================================================================== -static void PlayerColorRange (APlayerPawn *defaults, Baggage &bag) -{ - int start, end; - - SC_MustGetNumber (); - start = sc_Number; - SC_CheckString(","); - SC_MustGetNumber (); - end = sc_Number; - - if (start > end) - swap (start, end); - - bag.Info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8)); -} - -//========================================================================== -// -//========================================================================== -static void PlayerAttackZOffset (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetFloat (); - defaults->AttackZOffset = FLOAT2FIXED (sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void PlayerJumpZ (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetFloat (); - defaults->JumpZ = FLOAT2FIXED (sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void PlayerSpawnClass (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetString (); - if (SC_Compare ("Any")) - defaults->SpawnMask = 0; - else if (SC_Compare ("Fighter")) - defaults->SpawnMask |= MTF_FIGHTER; - else if (SC_Compare ("Cleric")) - defaults->SpawnMask |= MTF_CLERIC; - else if (SC_Compare ("Mage")) - defaults->SpawnMask |= MTF_MAGE; - else if (IsNum(sc_String)) - { - int val = strtol(sc_String, NULL, 0); - defaults->SpawnMask = (val*MTF_FIGHTER) & (MTF_FIGHTER|MTF_CLERIC|MTF_MAGE); - } -} - -//========================================================================== -// -//========================================================================== -static void PlayerViewHeight (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetFloat (); - defaults->ViewHeight = FLOAT2FIXED (sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void PlayerForwardMove (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetFloat (); - defaults->ForwardMove1 = defaults->ForwardMove2 = FLOAT2FIXED (sc_Float); - if (CheckFloatParm ()) - defaults->ForwardMove2 = FLOAT2FIXED (sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void PlayerSideMove (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetFloat (); - defaults->SideMove1 = defaults->SideMove2 = FLOAT2FIXED (sc_Float); - if (CheckFloatParm ()) - defaults->SideMove2 = FLOAT2FIXED (sc_Float); -} - -//========================================================================== -// -//========================================================================== -static void PlayerMaxHealth (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetNumber (); - defaults->MaxHealth = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void PlayerRunHealth (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetNumber (); - defaults->RunHealth = sc_Number; -} - -//========================================================================== -// -//========================================================================== -static void PlayerMorphWeapon (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetString (); - defaults->MorphWeapon = FName(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void PlayerScoreIcon (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetString (); - defaults->ScoreIcon = TexMan.AddPatch (sc_String); - if (defaults->ScoreIcon <= 0) - { - defaults->ScoreIcon = TexMan.AddPatch (sc_String, ns_sprites); - if (defaults->ScoreIcon <= 0) - { - Printf("Icon '%s' for '%s' not found\n", sc_String, bag.Info->Class->TypeName.GetChars ()); - } - } -} - -//========================================================================== -// -//========================================================================== -static void PlayerCrouchSprite (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetString (); - for (unsigned int i = 0; i < sc_StringLen; i++) sc_String[i] = toupper (sc_String[i]); - defaults->crouchsprite = GetSpriteIndex (sc_String); -} - -//========================================================================== -// -// [GRB] Store start items in drop item list -// -//========================================================================== -static void PlayerStartItem (APlayerPawn *defaults, Baggage &bag) -{ - // create a linked list of dropitems - if (!bag.DropItemSet) - { - bag.DropItemSet = true; - bag.DropItemList = NULL; - } - - FDropItem * di=new FDropItem; - - SC_MustGetString(); - di->Name = sc_String; - di->probability = 255; - di->amount = 1; - if (CheckNumParm()) - { - di->amount = sc_Number; - } - di->Next = bag.DropItemList; - bag.DropItemList = di; -} - -//========================================================================== -// -//========================================================================== -static void PlayerInvulMode (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetString (); - bag.Info->Class->Meta.SetMetaInt (APMETA_InvulMode, (FName)sc_String); -} - -//========================================================================== -// -//========================================================================== -static void PlayerHealRadius (APlayerPawn *defaults, Baggage &bag) -{ - SC_MustGetString (); - bag.Info->Class->Meta.SetMetaInt (APMETA_HealingRadius, (FName)sc_String); -} - -//========================================================================== -// -//========================================================================== -static void PlayerHexenArmor (APlayerPawn *defaults, Baggage &bag) -{ - for (int i=0;i<5;i++) - { - SC_MustGetFloat (); - bag.Info->Class->Meta.SetMetaFixed (APMETA_Hexenarmor0+i, FLOAT2FIXED (sc_Float)); - if (i!=4) SC_MustGetStringName(","); - } -} - -//========================================================================== -// -//========================================================================== -static void EggFXMonsterClass (AMorphProjectile *defaults, Baggage &bag) -{ - SC_MustGetString (); - defaults->MonsterClass = FName(sc_String); -} - -//========================================================================== -// -//========================================================================== -static void EggFXPlayerClass (AMorphProjectile *defaults, Baggage &bag) -{ - SC_MustGetString (); - defaults->PlayerClass = FName(sc_String); -} - -//========================================================================== -// -//========================================================================== -static const ActorProps *APropSearch (const char *str, const ActorProps *props, int numprops) -{ - int min = 0, max = numprops - 1; - - while (min <= max) - { - int mid = (min + max) / 2; - int lexval = strcmp (str, props[mid].name); - if (lexval == 0) - { - return &props[mid]; - } - else if (lexval > 0) - { - min = mid + 1; - } - else - { - max = mid - 1; - } - } - return NULL; -} - -//========================================================================== -// -// all actor properties -// -//========================================================================== -#define apf ActorPropFunction -static const ActorProps props[] = -{ - { "+", ActorFlagSetOrReset, RUNTIME_CLASS(AActor) }, - { "-", ActorFlagSetOrReset, RUNTIME_CLASS(AActor) }, - { "action", ActorActionDef, RUNTIME_CLASS(AActor) }, - { "activesound", ActorActiveSound, RUNTIME_CLASS(AActor) }, - { "alpha", ActorAlpha, RUNTIME_CLASS(AActor) }, - { "ammo.backpackamount", (apf)AmmoBackpackAmount, RUNTIME_CLASS(AAmmo) }, - { "ammo.backpackmaxamount", (apf)AmmoBackpackMaxAmount, RUNTIME_CLASS(AAmmo) }, - { "ammo.dropamount", (apf)AmmoDropAmount, RUNTIME_CLASS(AAmmo) }, - { "args", ActorArgs, RUNTIME_CLASS(AActor) }, - { "armor.maxbonus", (apf)ArmorMaxBonus, RUNTIME_CLASS(ABasicArmorBonus) }, - { "armor.maxbonusmax", (apf)ArmorMaxBonusMax, RUNTIME_CLASS(ABasicArmorBonus) }, - { "armor.maxsaveamount", (apf)ArmorMaxSaveAmount, RUNTIME_CLASS(ABasicArmorBonus) }, - { "armor.saveamount", (apf)ArmorSaveAmount, RUNTIME_CLASS(AActor) }, - { "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) }, - { "attacksound", ActorAttackSound, RUNTIME_CLASS(AActor) }, - { "bloodcolor", ActorBloodColor, RUNTIME_CLASS(AActor) }, - { "bloodtype", ActorBloodType, RUNTIME_CLASS(AActor) }, - { "bouncecount", ActorBounceCount, RUNTIME_CLASS(AActor) }, - { "bouncefactor", ActorBounceFactor, RUNTIME_CLASS(AActor) }, - { "burn", ActorBurnState, RUNTIME_CLASS(AActor) }, - { "burnheight", ActorBurnHeight, RUNTIME_CLASS(AActor) }, - { "cameraheight", ActorCameraheight, RUNTIME_CLASS(AActor) }, - { "clearflags", ActorClearFlags, RUNTIME_CLASS(AActor) }, - { "const", ActorConstDef, RUNTIME_CLASS(AActor) }, - { "conversationid", ActorConversationID, RUNTIME_CLASS(AActor) }, - { "crash", ActorCrashState, RUNTIME_CLASS(AActor) }, - { "crush", ActorCrushState, RUNTIME_CLASS(AActor) }, - { "damage", ActorDamage, RUNTIME_CLASS(AActor) }, - { "damagefactor", ActorDamageFactor, RUNTIME_CLASS(AActor) }, - { "damagetype", ActorDamageType, RUNTIME_CLASS(AActor) }, - { "death", ActorDeathState, RUNTIME_CLASS(AActor) }, - { "deathheight", ActorDeathHeight, RUNTIME_CLASS(AActor) }, - { "deathsound", ActorDeathSound, RUNTIME_CLASS(AActor) }, - { "decal", ActorDecal, RUNTIME_CLASS(AActor) }, - { "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) }, - { "donthurtshooter", ActorDontHurtShooter, RUNTIME_CLASS(AActor) }, - { "dropitem", ActorDropItem, RUNTIME_CLASS(AActor) }, - { "enum", ActorEnumDef, RUNTIME_CLASS(AActor) }, - { "explosiondamage", ActorExplosionDamage, RUNTIME_CLASS(AActor) }, - { "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) }, - { "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) }, - { "floatspeed", ActorFloatSpeed, RUNTIME_CLASS(AActor) }, - { "game", ActorGame, RUNTIME_CLASS(AActor) }, - { "gibhealth", ActorGibHealth, RUNTIME_CLASS(AActor) }, - { "gravity", ActorGravity, RUNTIME_CLASS(AActor) }, - { "heal", ActorHealState, RUNTIME_CLASS(AActor) }, - { "health", ActorHealth, RUNTIME_CLASS(AActor) }, - { "health.lowmessage", (apf)HealthLowMessage, RUNTIME_CLASS(AHealth) }, - { "height", ActorHeight, RUNTIME_CLASS(AActor) }, - { "hitobituary", ActorHitObituary, RUNTIME_CLASS(AActor) }, - { "howlsound", ActorHowlSound, RUNTIME_CLASS(AActor) }, - { "ice", ActorIceState, RUNTIME_CLASS(AActor) }, - { "inventory.amount", (apf)InventoryAmount, RUNTIME_CLASS(AInventory) }, - { "inventory.defmaxamount", (apf)InventoryDefMaxAmount, RUNTIME_CLASS(AInventory) }, - { "inventory.givequest", (apf)InventoryGiveQuest, RUNTIME_CLASS(AInventory) }, - { "inventory.icon", (apf)InventoryIcon, RUNTIME_CLASS(AInventory) }, - { "inventory.maxamount", (apf)InventoryMaxAmount, RUNTIME_CLASS(AInventory) }, - { "inventory.pickupmessage", (apf)InventoryPickupmsg, RUNTIME_CLASS(AInventory) }, - { "inventory.pickupsound", (apf)InventoryPickupsound, RUNTIME_CLASS(AInventory) }, - { "inventory.respawntics", (apf)InventoryRespawntics, RUNTIME_CLASS(AInventory) }, - { "inventory.usesound", (apf)InventoryUsesound, RUNTIME_CLASS(AInventory) }, - { "mass", ActorMass, RUNTIME_CLASS(AActor) }, - { "maxdropoffheight", ActorMaxDropoffHeight, RUNTIME_CLASS(AActor) }, - { "maxstepheight", ActorMaxStepHeight, RUNTIME_CLASS(AActor) }, - { "maxtargetrange", ActorMaxTargetRange, RUNTIME_CLASS(AActor) }, - { "melee", ActorMeleeState, RUNTIME_CLASS(AActor) }, - { "meleedamage", ActorMeleeDamage, RUNTIME_CLASS(AActor) }, - { "meleerange", ActorMeleeRange, RUNTIME_CLASS(AActor) }, - { "meleesound", ActorMeleeSound, RUNTIME_CLASS(AActor) }, - { "meleethreshold", ActorMeleeThreshold, RUNTIME_CLASS(AActor) }, - { "minmissilechance", ActorMinMissileChance, RUNTIME_CLASS(AActor) }, - { "missile", ActorMissileState, RUNTIME_CLASS(AActor) }, - { "missileheight", ActorMissileHeight, RUNTIME_CLASS(AActor) }, - { "missiletype", ActorMissileType, RUNTIME_CLASS(AActor) }, - { "monster", ActorMonster, RUNTIME_CLASS(AActor) }, - { "morphprojectile.monsterclass",(apf)EggFXMonsterClass, RUNTIME_CLASS(AMorphProjectile) }, - { "morphprojectile.playerclass",(apf)EggFXPlayerClass, RUNTIME_CLASS(AMorphProjectile) }, - { "obituary", ActorObituary, RUNTIME_CLASS(AActor) }, - { "pain", ActorPainState, RUNTIME_CLASS(AActor) }, - { "painchance", ActorPainChance, RUNTIME_CLASS(AActor) }, - { "painsound", ActorPainSound, RUNTIME_CLASS(AActor) }, - { "player.attackzoffset", (apf)PlayerAttackZOffset, RUNTIME_CLASS(APlayerPawn) }, - { "player.colorrange", (apf)PlayerColorRange, RUNTIME_CLASS(APlayerPawn) }, - { "player.crouchsprite", (apf)PlayerCrouchSprite, RUNTIME_CLASS(APlayerPawn) }, - { "player.displayname", (apf)PlayerDisplayName, RUNTIME_CLASS(APlayerPawn) }, - { "player.forwardmove", (apf)PlayerForwardMove, RUNTIME_CLASS(APlayerPawn) }, - { "player.healradiustype", (apf)PlayerHealRadius, RUNTIME_CLASS(APlayerPawn) }, - { "player.hexenarmor", (apf)PlayerHexenArmor, RUNTIME_CLASS(APlayerPawn) }, - { "player.invulnerabilitymode", (apf)PlayerInvulMode, RUNTIME_CLASS(APlayerPawn) }, - { "player.jumpz", (apf)PlayerJumpZ, RUNTIME_CLASS(APlayerPawn) }, - { "player.maxhealth", (apf)PlayerMaxHealth, RUNTIME_CLASS(APlayerPawn) }, - { "player.morphweapon", (apf)PlayerMorphWeapon, RUNTIME_CLASS(APlayerPawn) }, - { "player.runhealth", (apf)PlayerRunHealth, RUNTIME_CLASS(APlayerPawn) }, - { "player.scoreicon", (apf)PlayerScoreIcon, RUNTIME_CLASS(APlayerPawn) }, - { "player.sidemove", (apf)PlayerSideMove, RUNTIME_CLASS(APlayerPawn) }, - { "player.soundclass", (apf)PlayerSoundClass, RUNTIME_CLASS(APlayerPawn) }, - { "player.spawnclass", (apf)PlayerSpawnClass, RUNTIME_CLASS(APlayerPawn) }, - { "player.startitem", (apf)PlayerStartItem, RUNTIME_CLASS(APlayerPawn) }, - { "player.viewheight", (apf)PlayerViewHeight, RUNTIME_CLASS(APlayerPawn) }, - { "poisondamage", ActorPoisonDamage, RUNTIME_CLASS(AActor) }, - { "powerup.color", (apf)PowerupColor, RUNTIME_CLASS(APowerupGiver) }, - { "powerup.duration", (apf)PowerupDuration, RUNTIME_CLASS(APowerupGiver) }, - { "powerup.mode", (apf)PowerupMode, RUNTIME_CLASS(APowerupGiver) }, - { "powerup.type", (apf)PowerupType, RUNTIME_CLASS(APowerupGiver) }, - { "projectile", ActorProjectile, RUNTIME_CLASS(AActor) }, - { "puzzleitem.failmessage", (apf)PuzzleitemFailMsg, RUNTIME_CLASS(APuzzleItem) }, - { "puzzleitem.number", (apf)PuzzleitemNumber, RUNTIME_CLASS(APuzzleItem) }, - { "radius", ActorRadius, RUNTIME_CLASS(AActor) }, - { "radiusdamagefactor", ActorRadiusDamageFactor, RUNTIME_CLASS(AActor) }, - { "raise", ActorRaiseState, RUNTIME_CLASS(AActor) }, - { "reactiontime", ActorReactionTime, RUNTIME_CLASS(AActor) }, - { "renderstyle", ActorRenderStyle, RUNTIME_CLASS(AActor) }, - { "scale", ActorScale, RUNTIME_CLASS(AActor) }, - { "see", ActorSeeState, RUNTIME_CLASS(AActor) }, - { "seesound", ActorSeeSound, RUNTIME_CLASS(AActor) }, - { "skip_super", ActorSkipSuper, RUNTIME_CLASS(AActor) }, - { "spawn", ActorSpawnState, RUNTIME_CLASS(AActor) }, - { "spawnid", ActorSpawnID, RUNTIME_CLASS(AActor) }, - { "speed", ActorSpeed, RUNTIME_CLASS(AActor) }, - { "states", ActorStates, RUNTIME_CLASS(AActor) }, - { "tag", ActorTag, RUNTIME_CLASS(AActor) }, - { "translation", ActorTranslation, RUNTIME_CLASS(AActor) }, - { "vspeed", ActorVSpeed, RUNTIME_CLASS(AActor) }, - { "weapon.ammogive", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammogive1", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammogive2", (apf)WeaponAmmoGive2, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammotype", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammotype1", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammotype2", (apf)WeaponAmmoType2, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammouse", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammouse1", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammouse2", (apf)WeaponAmmoUse2, RUNTIME_CLASS(AWeapon) }, - { "weapon.kickback", (apf)WeaponKickback, RUNTIME_CLASS(AWeapon) }, - { "weapon.readysound", (apf)WeaponReadySound, RUNTIME_CLASS(AWeapon) }, - { "weapon.selectionorder", (apf)WeaponSelectionOrder, RUNTIME_CLASS(AWeapon) }, - { "weapon.sisterweapon", (apf)WeaponSisterWeapon, RUNTIME_CLASS(AWeapon) }, - { "weapon.upsound", (apf)WeaponUpSound, RUNTIME_CLASS(AWeapon) }, - { "weapon.yadjust", (apf)WeaponYAdjust, RUNTIME_CLASS(AWeapon) }, - { "weaponpiece.number", (apf)WPieceValue, RUNTIME_CLASS(AWeaponPiece) }, - { "weaponpiece.weapon", (apf)WPieceWeapon, RUNTIME_CLASS(AWeaponPiece) }, - { "wound", ActorWoundState, RUNTIME_CLASS(AActor) }, - { "woundhealth", ActorWoundHealth, RUNTIME_CLASS(AActor) }, - { "xdeath", ActorXDeathState, RUNTIME_CLASS(AActor) }, - { "xscale", ActorXScale, RUNTIME_CLASS(AActor) }, - { "yscale", ActorYScale, RUNTIME_CLASS(AActor) }, - // AWeapon:MinAmmo1 and 2 are never used so there is no point in adding them here! -}; -static const ActorProps *is_actorprop (const char *str) -{ - return APropSearch (str, props, sizeof(props)/sizeof(ActorProps)); -} - //========================================================================== // // Do some postprocessing after everything has been defined @@ -4490,7 +638,7 @@ void FinishThingdef() void ParseClass() { Baggage bag; - const PClass *cls; + PClass *cls; FName classname; FName supername; @@ -4502,7 +650,7 @@ void ParseClass() SC_MustGetToken(TK_Native); // use actor definitions for your own stuff SC_MustGetToken('{'); - cls = PClass::FindClass (classname); + cls = const_cast(PClass::FindClass (classname)); if (cls == NULL) { SC_ScriptError ("'%s' is not a native class", classname.GetChars()); @@ -4518,15 +666,15 @@ void ParseClass() { if (sc_TokenType == TK_Action) { - ActorActionDef (0, bag); + ParseActionDef(cls); } else if (sc_TokenType == TK_Const) { - ActorConstDef (0, bag); + ParseConstant(&cls->Symbols, cls); } else if (sc_TokenType == TK_Enum) { - ActorEnumDef (0, bag); + ParseEnum(&cls->Symbols, cls); } else { diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index dac3ce3dc4..e34d58aca3 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -1,9 +1,13 @@ #ifndef __THINGDEF_H #define __THINGDEF_H +//========================================================================== +// // This class is for storing a name inside a const PClass* field without // generating compiler warnings. It does not manipulate data in any other // way. +// +//========================================================================== class fuglyname : public FName { public: @@ -21,23 +25,12 @@ public: } }; -// All state parameters are stored in this array now. -extern TArray StateParameters; -extern TArray JumpParameters; - -int ParseExpression (bool _not, PClass *cls); - -int EvalExpressionI (int id, AActor *self, const PClass *cls=NULL); -float EvalExpressionF (int id, AActor *self, const PClass *cls=NULL); -bool EvalExpressionN (int id, AActor *self, const PClass *cls=NULL); - -void ClearStateLabels(); -void AddState (const char * statename, FState * state); -FState * FindState(AActor * actor, const PClass * type, const char * name); -void InstallStates(FActorInfo *info, AActor *defaults); -void MakeStateDefines(const FStateLabels *list); -FState *P_GetState(AActor *self, FState *CallingState, int offset); +//========================================================================== +// +// Dropitem list +// +//========================================================================== struct FDropItem { @@ -49,6 +42,86 @@ struct FDropItem FDropItem *GetDropItems(const PClass * cls); +//========================================================================== +// +// Extra info maintained while defining an actor. +// +//========================================================================== + +struct Baggage +{ + FActorInfo *Info; + bool DropItemSet; + bool StateSet; + int CurrentState; + + FDropItem *DropItemList; +}; + +inline void ResetBaggage (Baggage *bag) +{ + bag->DropItemList = NULL; + bag->DropItemSet = false; + bag->CurrentState = 0; + bag->StateSet = false; +} + + +//========================================================================== +// +// Action function lookup +// +//========================================================================== + +struct AFuncDesc +{ + const char *Name; + actionf_p Function; +}; + +AFuncDesc * FindFunction(const char * string); + + +//========================================================================== +// +// State parser +// +//========================================================================== + +extern TArray StateParameters; +extern TArray JumpParameters; + +void ClearStateLabels(); +void AddState (const char * statename, FState * state); +FState * FindState(AActor * actor, const PClass * type, const char * name); +void InstallStates(FActorInfo *info, AActor *defaults); +void MakeStateDefines(const FStateLabels *list); +FState *P_GetState(AActor *self, FState *CallingState, int offset); +int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag); +int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag); +FState *CheckState(PClass *type); + + +//========================================================================== +// +// Property parser +// +//========================================================================== + +void ParseActorProperty(Baggage &bag); +void ParseActorFlag (Baggage &bag, int mod); +void FinishActor(FActorInfo *info, Baggage &bag); + +void ParseConstant (PSymbolTable * symt, PClass *cls); +void ParseEnum (PSymbolTable * symt, PClass *cls); + + +int ParseExpression (bool _not, PClass *cls); + +int EvalExpressionI (int id, AActor *self, const PClass *cls=NULL); +float EvalExpressionF (int id, AActor *self, const PClass *cls=NULL); +bool EvalExpressionN (int id, AActor *self, const PClass *cls=NULL); + // A truly awful hack to get to the state that called an action function // without knowing whether it has been called from a weapon or actor. @@ -64,6 +137,10 @@ enum ACMETA_ExplosionDamage, ACMETA_ExplosionRadius, ACMETA_DontHurtShooter, + ACMETA_MeleeSound, + ACMETA_MeleeDamage, + ACMETA_MissileName, + ACMETA_MissileHeight, }; diff --git a/src/thingdef/thingdef_main.cpp b/src/thingdef/thingdef_main.cpp index 4f92a3bb00..52c393b4a2 100644 --- a/src/thingdef/thingdef_main.cpp +++ b/src/thingdef/thingdef_main.cpp @@ -47,7 +47,7 @@ // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- -void ProcessActor(); +void ParseActor(); void ParseClass(); void ParseGlobalConst(); void ParseGlobalEnum(); @@ -96,27 +96,27 @@ static void ParseDecorate () break; case TK_Class: - ParseClass(); + ParseClass (); break; case TK_Const: - ParseGlobalConst(); + ParseConstant (&RUNTIME_CLASS(AActor)->Symbols, RUNTIME_CLASS(AActor)); break; case TK_Enum: - ParseGlobalEnum(); + ParseEnum (&RUNTIME_CLASS(AActor)->Symbols, RUNTIME_CLASS(AActor)); break; case TK_Pickup: - ParseOldDecoration(DEF_Pickup); + ParseOldDecoration (DEF_Pickup); break; case TK_Breakable: - ParseOldDecoration(DEF_BreakableDecoration); + ParseOldDecoration (DEF_BreakableDecoration); break; case TK_Projectile: - ParseOldDecoration(DEF_Projectile); + ParseOldDecoration (DEF_Projectile); break; case ';': @@ -132,7 +132,7 @@ static void ParseDecorate () // so let's do a special case for this. if (SC_Compare("ACTOR")) { - ProcessActor (); + ParseActor (); break; } diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp new file mode 100644 index 0000000000..bc050c932f --- /dev/null +++ b/src/thingdef/thingdef_properties.cpp @@ -0,0 +1,2663 @@ +/* +** thingdef-properties.cpp +** +** Actor definitions - properties and flags parser +** +**--------------------------------------------------------------------------- +** Copyright 2002-2007 Christoph Oelckers +** Copyright 2004-2007 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be +** covered by the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or (at +** your option) any later version. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "gi.h" +#include "actor.h" +#include "info.h" +#include "sc_man.h" +#include "tarray.h" +#include "w_wad.h" +#include "templates.h" +#include "r_defs.h" +#include "r_draw.h" +#include "a_pickups.h" +#include "s_sound.h" +#include "cmdlib.h" +#include "p_lnspec.h" +#include "p_enemy.h" +#include "a_action.h" +#include "decallib.h" +#include "m_random.h" +#include "autosegs.h" +#include "i_system.h" +#include "p_local.h" +#include "p_effect.h" +#include "v_palette.h" +#include "doomerrors.h" +#include "a_doomglobal.h" +#include "a_hexenglobal.h" +#include "a_weaponpiece.h" +#include "p_conversation.h" +#include "v_text.h" +#include "thingdef.h" +#include "a_sharedglobal.h" + +//========================================================================== +// +// List of all flags +// +//========================================================================== + +// [RH] Keep GCC quiet by not using offsetof on Actor types. +#define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1 } +#define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1 } +#define DEFINE_DEPRECATED_FLAG(name, type, index) { index, #name, -1 } + +struct flagdef +{ + int flagbit; + const char *name; + int structoffset; +}; + + +static flagdef ActorFlags[]= +{ + DEFINE_FLAG(MF, SOLID, AActor, flags), + DEFINE_FLAG(MF, SHOOTABLE, AActor, flags), + DEFINE_FLAG(MF, NOSECTOR, AActor, flags), + DEFINE_FLAG(MF, NOBLOCKMAP, AActor, flags), + DEFINE_FLAG(MF, AMBUSH, AActor, flags), + DEFINE_FLAG(MF, JUSTHIT, AActor, flags), + DEFINE_FLAG(MF, JUSTATTACKED, AActor, flags), + DEFINE_FLAG(MF, SPAWNCEILING, AActor, flags), + DEFINE_FLAG(MF, NOGRAVITY, AActor, flags), + DEFINE_FLAG(MF, DROPOFF, AActor, flags), + DEFINE_FLAG(MF, NOCLIP, AActor, flags), + DEFINE_FLAG(MF, FLOAT, AActor, flags), + DEFINE_FLAG(MF, TELEPORT, AActor, flags), + DEFINE_FLAG(MF, MISSILE, AActor, flags), + DEFINE_FLAG(MF, DROPPED, AActor, flags), + DEFINE_FLAG(MF, SHADOW, AActor, flags), + DEFINE_FLAG(MF, NOBLOOD, AActor, flags), + DEFINE_FLAG(MF, CORPSE, AActor, flags), + DEFINE_FLAG(MF, INFLOAT, AActor, flags), + DEFINE_FLAG(MF, COUNTKILL, AActor, flags), + DEFINE_FLAG(MF, COUNTITEM, AActor, flags), + DEFINE_FLAG(MF, SKULLFLY, AActor, flags), + DEFINE_FLAG(MF, NOTDMATCH, AActor, flags), + DEFINE_FLAG(MF, SPAWNSOUNDSOURCE, AActor, flags), + DEFINE_FLAG(MF, FRIENDLY, AActor, flags), + DEFINE_FLAG(MF, NOLIFTDROP, AActor, flags), + DEFINE_FLAG(MF, STEALTH, AActor, flags), + DEFINE_FLAG(MF, ICECORPSE, AActor, flags), + DEFINE_FLAG(MF2, DONTREFLECT, AActor, flags2), + DEFINE_FLAG(MF2, WINDTHRUST, AActor, flags2), + DEFINE_FLAG(MF2, HERETICBOUNCE , AActor, flags2), + DEFINE_FLAG(MF2, BLASTED, AActor, flags2), + DEFINE_FLAG(MF2, FLOORCLIP, AActor, flags2), + DEFINE_FLAG(MF2, SPAWNFLOAT, AActor, flags2), + DEFINE_FLAG(MF2, NOTELEPORT, AActor, flags2), + DEFINE_FLAG2(MF2_RIP, RIPPER, AActor, flags2), + DEFINE_FLAG(MF2, PUSHABLE, AActor, flags2), + DEFINE_FLAG2(MF2_SLIDE, SLIDESONWALLS, AActor, flags2), + DEFINE_FLAG2(MF2_PASSMOBJ, CANPASS, AActor, flags2), + DEFINE_FLAG(MF2, CANNOTPUSH, AActor, flags2), + DEFINE_FLAG(MF2, THRUGHOST, AActor, flags2), + DEFINE_FLAG(MF2, BOSS, AActor, flags2), + DEFINE_FLAG2(MF2_NODMGTHRUST, NODAMAGETHRUST, AActor, flags2), + DEFINE_FLAG(MF2, DONTTRANSLATE, AActor, flags2), + DEFINE_FLAG(MF2, TELESTOMP, AActor, flags2), + DEFINE_FLAG(MF2, FLOATBOB, AActor, flags2), + DEFINE_FLAG(MF2, HEXENBOUNCE, AActor, flags2), + DEFINE_FLAG(MF2, DOOMBOUNCE, AActor, flags2), + DEFINE_FLAG2(MF2_IMPACT, ACTIVATEIMPACT, AActor, flags2), + DEFINE_FLAG2(MF2_PUSHWALL, CANPUSHWALLS, AActor, flags2), + DEFINE_FLAG2(MF2_MCROSS, ACTIVATEMCROSS, AActor, flags2), + DEFINE_FLAG2(MF2_PCROSS, ACTIVATEPCROSS, AActor, flags2), + DEFINE_FLAG(MF2, CANTLEAVEFLOORPIC, AActor, flags2), + DEFINE_FLAG(MF2, NONSHOOTABLE, AActor, flags2), + DEFINE_FLAG(MF2, INVULNERABLE, AActor, flags2), + DEFINE_FLAG(MF2, DORMANT, AActor, flags2), + DEFINE_FLAG(MF2, SEEKERMISSILE, AActor, flags2), + DEFINE_FLAG(MF2, REFLECTIVE, AActor, flags2), + DEFINE_FLAG(MF3, FLOORHUGGER, AActor, flags3), + DEFINE_FLAG(MF3, CEILINGHUGGER, AActor, flags3), + DEFINE_FLAG(MF3, NORADIUSDMG, AActor, flags3), + DEFINE_FLAG(MF3, GHOST, AActor, flags3), + DEFINE_FLAG(MF3, ALWAYSPUFF, AActor, flags3), + DEFINE_FLAG(MF3, DONTSPLASH, AActor, flags3), + DEFINE_FLAG(MF3, DONTOVERLAP, AActor, flags3), + DEFINE_FLAG(MF3, DONTMORPH, AActor, flags3), + DEFINE_FLAG(MF3, DONTSQUASH, AActor, flags3), + DEFINE_FLAG(MF3, FULLVOLACTIVE, AActor, flags3), + DEFINE_FLAG(MF3, ISMONSTER, AActor, flags3), + DEFINE_FLAG(MF3, SKYEXPLODE, AActor, flags3), + DEFINE_FLAG(MF3, STAYMORPHED, AActor, flags3), + DEFINE_FLAG(MF3, DONTBLAST, AActor, flags3), + DEFINE_FLAG(MF3, CANBLAST, AActor, flags3), + DEFINE_FLAG(MF3, NOTARGET, AActor, flags3), + DEFINE_FLAG(MF3, DONTGIB, AActor, flags3), + DEFINE_FLAG(MF3, NOBLOCKMONST, AActor, flags3), + DEFINE_FLAG(MF3, FULLVOLDEATH, AActor, flags3), + DEFINE_FLAG(MF3, CANBOUNCEWATER, AActor, flags3), + DEFINE_FLAG(MF3, NOWALLBOUNCESND, AActor, flags3), + DEFINE_FLAG(MF3, FOILINVUL, AActor, flags3), + DEFINE_FLAG(MF3, NOTELEOTHER, AActor, flags3), + DEFINE_FLAG(MF3, BLOODLESSIMPACT, AActor, flags3), + DEFINE_FLAG(MF3, NOEXPLODEFLOOR, AActor, flags3), + DEFINE_FLAG(MF3, PUFFONACTORS, AActor, flags3), + DEFINE_FLAG(MF4, QUICKTORETALIATE, AActor, flags4), + DEFINE_FLAG(MF4, NOICEDEATH, AActor, flags4), + DEFINE_FLAG(MF4, RANDOMIZE, AActor, flags4), + DEFINE_FLAG(MF4, FIXMAPTHINGPOS , AActor, flags4), + DEFINE_FLAG(MF4, ACTLIKEBRIDGE, AActor, flags4), + DEFINE_FLAG(MF4, STRIFEDAMAGE, AActor, flags4), + DEFINE_FLAG(MF4, CANUSEWALLS, AActor, flags4), + DEFINE_FLAG(MF4, MISSILEMORE, AActor, flags4), + DEFINE_FLAG(MF4, MISSILEEVENMORE, AActor, flags4), + DEFINE_FLAG(MF4, FORCERADIUSDMG, AActor, flags4), + DEFINE_FLAG(MF4, DONTFALL, AActor, flags4), + DEFINE_FLAG(MF4, SEESDAGGERS, AActor, flags4), + DEFINE_FLAG(MF4, INCOMBAT, AActor, flags4), + DEFINE_FLAG(MF4, LOOKALLAROUND, AActor, flags4), + DEFINE_FLAG(MF4, STANDSTILL, AActor, flags4), + DEFINE_FLAG(MF4, SPECTRAL, AActor, flags4), + DEFINE_FLAG(MF4, FIRERESIST, AActor, flags4), + DEFINE_FLAG(MF4, NOSPLASHALERT, AActor, flags4), + DEFINE_FLAG(MF4, SYNCHRONIZED, AActor, flags4), + DEFINE_FLAG(MF4, NOTARGETSWITCH, AActor, flags4), + DEFINE_FLAG(MF4, DONTHURTSPECIES, AActor, flags4), + DEFINE_FLAG(MF4, SHIELDREFLECT, AActor, flags4), + DEFINE_FLAG(MF4, DEFLECT, AActor, flags4), + DEFINE_FLAG(MF4, ALLOWPARTICLES, AActor, flags4), + DEFINE_FLAG(MF4, EXTREMEDEATH, AActor, flags4), + DEFINE_FLAG(MF4, NOEXTREMEDEATH, AActor, flags4), + DEFINE_FLAG(MF4, FRIGHTENED, AActor, flags4), + DEFINE_FLAG(MF4, NOBOUNCESOUND, AActor, flags4), + DEFINE_FLAG(MF4, NOSKIN, AActor, flags4), + DEFINE_FLAG(MF4, BOSSDEATH, AActor, flags4), + + DEFINE_FLAG(MF5, FASTER, AActor, flags5), + DEFINE_FLAG(MF5, FASTMELEE, AActor, flags5), + DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5), + DEFINE_FLAG(MF5, BOUNCEONACTORS, AActor, flags5), + DEFINE_FLAG(MF5, EXPLODEONWATER, AActor, flags5), + DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5), + DEFINE_FLAG(MF5, BLOODSPLATTER, AActor, flags5), + DEFINE_FLAG(MF5, OLDRADIUSDMG, AActor, flags5), + DEFINE_FLAG(MF5, DEHEXPLOSION, AActor, flags5), + DEFINE_FLAG(MF5, PIERCEARMOR, AActor, flags5), + DEFINE_FLAG(MF5, NOBLOODDECALS, AActor, flags5), + DEFINE_FLAG(MF5, USESPECIAL, AActor, flags5), + DEFINE_FLAG(MF5, NOPAIN, AActor, flags5), + + // Effect flags + DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), + DEFINE_FLAG2(FX_ROCKET, ROCKETTRAIL, AActor, effects), + DEFINE_FLAG2(FX_GRENADE, GRENADETRAIL, AActor, effects), + DEFINE_FLAG(RF, INVISIBLE, AActor, renderflags), + + // Deprecated flags. Handling must be performed in HandleDeprecatedFlags + DEFINE_DEPRECATED_FLAG(FIREDAMAGE, AActor, 0), + DEFINE_DEPRECATED_FLAG(ICEDAMAGE, AActor, 1), + DEFINE_DEPRECATED_FLAG(LOWGRAVITY, AActor, 2), + DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE, AActor, 3), + DEFINE_DEPRECATED_FLAG(LONGMELEERANGE, AActor, 4), +}; + +static flagdef InventoryFlags[] = +{ + // Inventory flags + DEFINE_FLAG(IF, QUIET, AInventory, ItemFlags), + DEFINE_FLAG(IF, AUTOACTIVATE, AInventory, ItemFlags), + DEFINE_FLAG(IF, UNDROPPABLE, AInventory, ItemFlags), + DEFINE_FLAG(IF, INVBAR, AInventory, ItemFlags), + DEFINE_FLAG(IF, HUBPOWER, AInventory, ItemFlags), + DEFINE_FLAG(IF, INTERHUBSTRIP, AInventory, ItemFlags), + DEFINE_FLAG(IF, PICKUPFLASH, AInventory, ItemFlags), + DEFINE_FLAG(IF, ALWAYSPICKUP, AInventory, ItemFlags), + DEFINE_FLAG(IF, FANCYPICKUPSOUND, AInventory, ItemFlags), + DEFINE_FLAG(IF, BIGPOWERUP, AInventory, ItemFlags), + DEFINE_FLAG(IF, KEEPDEPLETED, AInventory, ItemFlags), +}; + +static flagdef WeaponFlags[] = +{ + // Weapon flags + DEFINE_FLAG(WIF, NOAUTOFIRE, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, READYSNDHALF, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, DONTBOB, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, AXEBLOOD, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, NOALERT, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, AMMO_OPTIONAL, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, ALT_AMMO_OPTIONAL, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, PRIMARY_USES_BOTH, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, WIMPY_WEAPON, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, POWERED_UP, AWeapon, WeaponFlags), + //DEFINE_FLAG(WIF, EXTREME_DEATH, AWeapon, WeaponFlags), // this should be removed now! + DEFINE_FLAG(WIF, STAFF2_KICKBACK, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF_BOT, EXPLOSIVE, AWeapon, WeaponFlags), + DEFINE_FLAG2(WIF_BOT_MELEE, MELEEWEAPON, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF_BOT, BFG, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, CHEATNOTWEAPON, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, NO_AUTO_SWITCH, AWeapon, WeaponFlags), + //WIF_BOT_REACTION_SKILL_THING = 1<<31, // I don't understand this +}; + +static const struct { const PClass *Type; flagdef *Defs; int NumDefs; } FlagLists[] = +{ + { RUNTIME_CLASS(AActor), ActorFlags, sizeof(ActorFlags)/sizeof(flagdef) }, + { RUNTIME_CLASS(AInventory), InventoryFlags, sizeof(InventoryFlags)/sizeof(flagdef) }, + { RUNTIME_CLASS(AWeapon), WeaponFlags, sizeof(WeaponFlags)/sizeof(flagdef) } +}; +#define NUM_FLAG_LISTS 3 + +//========================================================================== +// +// Find a flag by name using a binary search +// +//========================================================================== +static int STACK_ARGS flagcmp (const void * a, const void * b) +{ + return stricmp( ((flagdef*)a)->name, ((flagdef*)b)->name); +} + +static flagdef *FindFlag (flagdef *flags, int numflags, const char *flag) +{ + int min = 0, max = numflags - 1; + + while (min <= max) + { + int mid = (min + max) / 2; + int lexval = stricmp (flag, flags[mid].name); + if (lexval == 0) + { + return &flags[mid]; + } + else if (lexval > 0) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } + return NULL; +} + +static flagdef *FindFlag (const PClass *type, const char *part1, const char *part2) +{ + static bool flagsorted = false; + flagdef *def; + int i; + + if (!flagsorted) + { + for (i = 0; i < NUM_FLAG_LISTS; ++i) + { + qsort (FlagLists[i].Defs, FlagLists[i].NumDefs, sizeof(flagdef), flagcmp); + } + flagsorted = true; + } + if (part2 == NULL) + { // Search all lists + for (i = 0; i < NUM_FLAG_LISTS; ++i) + { + if (type->IsDescendantOf (FlagLists[i].Type)) + { + def = FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part1); + if (def != NULL) + { + return def; + } + } + } + } + else + { // Search just the named list + for (i = 0; i < NUM_FLAG_LISTS; ++i) + { + if (stricmp (FlagLists[i].Type->TypeName.GetChars(), part1) == 0) + { + if (type->IsDescendantOf (FlagLists[i].Type)) + { + return FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part2); + } + else + { + return NULL; + } + } + } + } + return NULL; +} + + +//=========================================================================== +// +// HandleDeprecatedFlags +// +// Handles the deprecated flags and sets the respective properties +// to appropriate values. This is solely intended for backwards +// compatibility so mixing this with code that is aware of the real +// properties is not recommended +// +//=========================================================================== +static void HandleDeprecatedFlags(AActor *defaults, bool set, int index) +{ + switch (index) + { + case 0: // FIREDAMAGE + defaults->DamageType = set? NAME_Fire : NAME_None; + break; + case 1: // ICEDAMAGE + defaults->DamageType = set? NAME_Ice : NAME_None; + break; + case 2: // LOWGRAVITY + defaults->gravity = set? FRACUNIT/8 : FRACUNIT; + break; + case 3: // SHORTMISSILERANGE + defaults->maxtargetrange = set? 896*FRACUNIT : 0; + break; + case 4: // LONGMELEERANGE + defaults->meleethreshold = set? 196*FRACUNIT : 0; + break; + default: + break; // silence GCC + } +} + +//=========================================================================== +// +// A_ChangeFlag +// +// This cannot be placed in thingdef_codeptr because it needs the flag table +// +//=========================================================================== +void A_ChangeFlag(AActor * self) +{ + int index=CheckIndex(2); + const char * flagname = FName((ENamedName)StateParameters[index]).GetChars(); + int expression = EvalExpressionI (StateParameters[index+1], self); + + const char *dot = strchr (flagname, '.'); + flagdef *fd; + + if (dot != NULL) + { + FString part1(flagname, dot-flagname); + fd = FindFlag (self->GetClass(), part1, dot+1); + } + else + { + fd = FindFlag (self->GetClass(), flagname, NULL); + } + + if (fd != NULL) + { + if (fd->structoffset == -1) + { + HandleDeprecatedFlags(self, !!expression, fd->flagbit); + } + else + { + int * flagp = (int*) (((char*)self) + fd->structoffset); + + if (expression) *flagp |= fd->flagbit; + else *flagp &= ~fd->flagbit; + } + } + else + { + Printf("Unknown flag '%s' in '%s'\n", flagname, self->GetClass()->TypeName.GetChars()); + } +} + +//========================================================================== +// +//========================================================================== +void ParseActorFlag (Baggage &bag, int mod) +{ + flagdef *fd; + + SC_MustGetString (); + + FString part1 = sc_String; + const char *part2 = NULL; + if (SC_CheckString (".")) + { + SC_MustGetString (); + part2 = sc_String; + } + if ( (fd = FindFlag (bag.Info->Class, part1.GetChars(), part2)) ) + { + AActor *defaults = (AActor*)bag.Info->Class->Defaults; + if (fd->structoffset == -1) // this is a deprecated flag that has been changed into a real property + { + HandleDeprecatedFlags(defaults, mod=='+', fd->flagbit); + } + else + { + DWORD * flagvar = (DWORD*) ((char*)defaults + fd->structoffset); + if (mod == '+') + { + *flagvar |= fd->flagbit; + } + else + { + *flagvar &= ~fd->flagbit; + } + } + } + else + { + if (part2 == NULL) + { + SC_ScriptError("\"%s\" is an unknown flag\n", part1.GetChars()); + } + else + { + SC_ScriptError("\"%s.%s\" is an unknown flag\n", part1.GetChars(), part2); + } + } +} + + + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// +// Translation parsing +// +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +static int NumUsedTranslations; +static int NumUsedBloodTranslations; +BYTE decorate_translations[256*256*2]; +PalEntry BloodTranslations[256]; + +void InitDecorateTranslations() +{ + // The translation tables haven't been allocated yet so we may as easily use a static buffer instead! + NumUsedBloodTranslations = NumUsedTranslations = 0; + for(int i=0;i<256*256*2;i++) decorate_translations[i]=i&255; +} + +static bool Check(char *& range, char c, bool error=true) +{ + while (isspace(*range)) range++; + if (*range==c) + { + range++; + return true; + } + if (error) + { + //SC_ScriptError("Invalid syntax in translation specification: '%c' expected", c); + } + return false; +} + + +static void AddToTranslation(unsigned char * translation, char * range) +{ + int start,end; + + start=strtol(range, &range, 10); + if (!Check(range, ':')) return; + end=strtol(range, &range, 10); + if (!Check(range, '=')) return; + if (!Check(range, '[', false)) + { + int pal1,pal2; + fixed_t palcol, palstep; + + pal1=strtol(range, &range, 10); + if (!Check(range, ':')) return; + pal2=strtol(range, &range, 10); + + if (start > end) + { + swap (start, end); + swap (pal1, pal2); + } + else if (start == end) + { + translation[start] = pal1; + return; + } + palcol = pal1 << FRACBITS; + palstep = ((pal2 << FRACBITS) - palcol) / (end - start); + for (int i = start; i <= end; palcol += palstep, ++i) + { + translation[i] = palcol >> FRACBITS; + } + } + else + { + // translation using RGB values + int r1; + int g1; + int b1; + int r2; + int g2; + int b2; + int r,g,b; + int rs,gs,bs; + + r1=strtol(range, &range, 10); + if (!Check(range, ',')) return; + g1=strtol(range, &range, 10); + if (!Check(range, ',')) return; + b1=strtol(range, &range, 10); + if (!Check(range, ']')) return; + if (!Check(range, ':')) return; + if (!Check(range, '[')) return; + r2=strtol(range, &range, 10); + if (!Check(range, ',')) return; + g2=strtol(range, &range, 10); + if (!Check(range, ',')) return; + b2=strtol(range, &range, 10); + if (!Check(range, ']')) return; + + if (start > end) + { + swap (start, end); + r = r2; + g = g2; + b = b2; + rs = r1 - r2; + gs = g1 - g2; + bs = b1 - b2; + } + else + { + r = r1; + g = g1; + b = b1; + rs = r2 - r1; + gs = g2 - g1; + bs = b2 - b1; + } + if (start == end) + { + translation[start] = ColorMatcher.Pick + (r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); + return; + } + rs /= (end - start); + gs /= (end - start); + bs /= (end - start); + for (int i = start; i <= end; ++i) + { + translation[i] = ColorMatcher.Pick + (r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); + r += rs; + g += gs; + b += bs; + } + + } +} + +static int StoreTranslation(const unsigned char * translation) +{ + for (int i = 0; i < NumUsedTranslations; i++) + { + if (!memcmp(translation, decorate_translations + i*256, 256)) + { + // A duplicate of this translation already exists + return TRANSLATION(TRANSLATION_Decorate, i); + } + } + if (NumUsedTranslations>=MAX_DECORATE_TRANSLATIONS) + { + SC_ScriptError("Too many translations in DECORATE"); + } + memcpy(decorate_translations + NumUsedTranslations*256, translation, 256); + NumUsedTranslations++; + return TRANSLATION(TRANSLATION_Decorate, NumUsedTranslations-1); +} + +static int CreateBloodTranslation(PalEntry color) +{ + int i; + + for (i = 0; i < NumUsedBloodTranslations; i++) + { + if (color.r == BloodTranslations[i].r && + color.g == BloodTranslations[i].g && + color.b == BloodTranslations[i].b) + { + // A duplicate of this translation already exists + return i; + } + } + if (NumUsedBloodTranslations>=MAX_DECORATE_TRANSLATIONS) + { + SC_ScriptError("Too many blood colors in DECORATE"); + } + for (i = 0; i < 256; i++) + { + int bright = MAX(MAX(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b); + int entry = ColorMatcher.Pick(color.r*bright/255, color.g*bright/255, color.b*bright/255); + + *(decorate_translations + MAX_DECORATE_TRANSLATIONS*256 + NumUsedBloodTranslations*256 + i)=entry; + } + BloodTranslations[NumUsedBloodTranslations]=color; + return NumUsedBloodTranslations++; +} + +//---------------------------------------------------------------------------- +// +// DropItem handling +// +//---------------------------------------------------------------------------- + +static void FreeDropItemChain(FDropItem *chain) +{ + while (chain != NULL) + { + FDropItem *next = chain->Next; + delete chain; + chain = next; + } +} + +class FDropItemPtrArray : public TArray +{ +public: + ~FDropItemPtrArray() + { + for (unsigned int i = 0; i < Size(); ++i) + { + FreeDropItemChain ((*this)[i]); + } + } +}; + +static FDropItemPtrArray DropItemList; + +FDropItem *GetDropItems(const PClass *cls) +{ + unsigned int index = cls->Meta.GetMetaInt (ACMETA_DropItems) - 1; + + if (index >= 0 && index < DropItemList.Size()) + { + return DropItemList[index]; + } + return NULL; +} + +//========================================================================== +// +// +//========================================================================== + +typedef void (*ActorPropFunction) (AActor *defaults, Baggage &bag); + +struct ActorProps +{ + const char *name; + ActorPropFunction Handler; + const PClass * type; +}; + +typedef ActorProps (*ActorPropHandler) (register const char *str, register unsigned int len); + +static const ActorProps *is_actorprop (const char *str); + + +//========================================================================== +// +// Checks for a numeric parameter which may or may not be preceded by a comma +// +//========================================================================== +static bool CheckNumParm() +{ + if (SC_CheckString(",")) + { + SC_MustGetNumber(); + return true; + } + else + { + return !!SC_CheckNumber(); + } +} + +static bool CheckFloatParm() +{ + if (SC_CheckString(",")) + { + SC_MustGetFloat(); + return true; + } + else + { + return !!SC_CheckFloat(); + } +} + +//========================================================================== +// +// Property parsers +// +//========================================================================== + +//========================================================================== +// +//========================================================================== +static void ActorSkipSuper (AActor *defaults, Baggage &bag) +{ + memcpy (defaults, GetDefault(), sizeof(AActor)); + if (bag.DropItemList != NULL) + { + FreeDropItemChain (bag.DropItemList); + } + ResetBaggage (&bag); +} + +//========================================================================== +// +//========================================================================== +static void ActorGame (AActor *defaults, Baggage &bag) +{ + SC_MustGetString (); + if (SC_Compare ("Doom")) + { + bag.Info->GameFilter |= GAME_Doom; + } + else if (SC_Compare ("Heretic")) + { + bag.Info->GameFilter |= GAME_Heretic; + } + else if (SC_Compare ("Hexen")) + { + bag.Info->GameFilter |= GAME_Hexen; + } + else if (SC_Compare ("Raven")) + { + bag.Info->GameFilter |= GAME_Raven; + } + else if (SC_Compare ("Strife")) + { + bag.Info->GameFilter |= GAME_Strife; + } + else if (SC_Compare ("Any")) + { + bag.Info->GameFilter = GAME_Any; + } + else + { + SC_ScriptError ("Unknown game type %s", sc_String); + } +} + +//========================================================================== +// +//========================================================================== +static void ActorSpawnID (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + if (sc_Number<0 || sc_Number>255) + { + SC_ScriptError ("SpawnID must be in the range [0,255]"); + } + else bag.Info->SpawnID=(BYTE)sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ActorConversationID (AActor *defaults, Baggage &bag) +{ + int convid; + + SC_MustGetNumber(); + convid = sc_Number; + + // Handling for Strife teaser IDs - only of meaning for the standard items + // as PWADs cannot be loaded with the teasers. + if (SC_CheckString(",")) + { + SC_MustGetNumber(); + if ((gameinfo.flags & (GI_SHAREWARE|GI_TEASER2)) == (GI_SHAREWARE)) + convid=sc_Number; + + SC_MustGetStringName(","); + SC_MustGetNumber(); + if ((gameinfo.flags & (GI_SHAREWARE|GI_TEASER2)) == (GI_SHAREWARE|GI_TEASER2)) + convid=sc_Number; + + if (convid==-1) return; + } + if (convid<0 || convid>1000) + { + SC_ScriptError ("ConversationID must be in the range [0,1000]"); + } + else StrifeTypes[convid] = bag.Info->Class; +} + +//========================================================================== +// +//========================================================================== +static void ActorTag (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaString(AMETA_StrifeName, sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorHealth (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->health=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ActorGibHealth (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt (AMETA_GibHealth, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void ActorWoundHealth (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt (AMETA_WoundHealth, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void ActorReactionTime (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->reactiontime=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ActorPainChance (AActor *defaults, Baggage &bag) +{ + if (!SC_CheckNumber()) + { + FName painType; + if (SC_Compare("Normal")) painType = NAME_None; + else painType=sc_String; + SC_MustGetToken(','); + SC_MustGetNumber(); + + if (bag.Info->PainChances == NULL) bag.Info->PainChances=new PainChanceList; + (*bag.Info->PainChances)[painType] = (BYTE)sc_Number; + return; + } + defaults->PainChance=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ActorDamage (AActor *defaults, Baggage &bag) +{ + // Damage can either be a single number, in which case it is subject + // to the original damage calculation rules. Or, it can be an expression + // and will be calculated as-is, ignoring the original rules. For + // compatibility reasons, expressions must be enclosed within + // parentheses. + + if (SC_CheckString ("(")) + { + defaults->Damage = 0x40000000 | ParseExpression (false, bag.Info->Class); + SC_MustGetStringName(")"); + } + else + { + SC_MustGetNumber (); + defaults->Damage = sc_Number; + } +} + +//========================================================================== +// +//========================================================================== +static void ActorSpeed (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->Speed=fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorFloatSpeed (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->FloatSpeed=fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorRadius (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->radius=fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorHeight (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->height=fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorMass (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->Mass=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ActorXScale (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->scaleX = FLOAT2FIXED(sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void ActorYScale (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->scaleY = FLOAT2FIXED(sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void ActorScale (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->scaleX= defaults->scaleY = FLOAT2FIXED(sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void ActorArgs (AActor *defaults, Baggage &bag) +{ + for (int i=0;i<5;i++) + { + SC_MustGetNumber(); + defaults->args[i] = sc_Number; + if (i < 4 && !SC_CheckToken(',')) break; + } + defaults->flags2|=MF2_ARGSDEFINED; +} + +//========================================================================== +// +//========================================================================== +static void ActorSeeSound (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->SeeSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorAttackSound (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->AttackSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorPainSound (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->PainSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorDeathSound (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->DeathSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorActiveSound (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->ActiveSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorHowlSound (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaInt (AMETA_HowlSound, S_FindSound(sc_String)); +} + +//========================================================================== +// +//========================================================================== +static void ActorDropItem (AActor *defaults, Baggage &bag) +{ + // create a linked list of dropitems + if (!bag.DropItemSet) + { + bag.DropItemSet = true; + bag.DropItemList = NULL; + } + + FDropItem * di=new FDropItem; + + SC_MustGetString(); + di->Name=sc_String; + di->probability=255; + di->amount=-1; + + if (CheckNumParm()) + { + di->probability=sc_Number; + if (CheckNumParm()) + { + di->amount=sc_Number; + } + } + di->Next = bag.DropItemList; + bag.DropItemList = di; +} + +//========================================================================== +// +//========================================================================== +static void ActorSpawnState (AActor *defaults, Baggage &bag) +{ + AddState("Spawn", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorSeeState (AActor *defaults, Baggage &bag) +{ + AddState("See", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorMeleeState (AActor *defaults, Baggage &bag) +{ + AddState("Melee", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorMissileState (AActor *defaults, Baggage &bag) +{ + AddState("Missile", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorPainState (AActor *defaults, Baggage &bag) +{ + AddState("Pain", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorDeathState (AActor *defaults, Baggage &bag) +{ + AddState("Death", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorXDeathState (AActor *defaults, Baggage &bag) +{ + AddState("XDeath", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorBurnState (AActor *defaults, Baggage &bag) +{ + AddState("Burn", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorIceState (AActor *defaults, Baggage &bag) +{ + AddState("Ice", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorRaiseState (AActor *defaults, Baggage &bag) +{ + AddState("Raise", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorCrashState (AActor *defaults, Baggage &bag) +{ + AddState("Crash", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorCrushState (AActor *defaults, Baggage &bag) +{ + AddState("Crush", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorWoundState (AActor *defaults, Baggage &bag) +{ + AddState("Wound", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorDisintegrateState (AActor *defaults, Baggage &bag) +{ + AddState("Disintegrate", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorHealState (AActor *defaults, Baggage &bag) +{ + AddState("Heal", CheckState ( bag.Info->Class)); +} + +//========================================================================== +// +//========================================================================== +static void ActorStates (AActor *defaults, Baggage &bag) +{ + if (!bag.StateSet) ParseStates(bag.Info, defaults, bag); + else SC_ScriptError("Multiple state declarations not allowed"); + bag.StateSet=true; +} + +//========================================================================== +// +//========================================================================== +static void ActorRenderStyle (AActor *defaults, Baggage &bag) +{ + static const char * renderstyles[]={ + "NONE","NORMAL","FUZZY","SOULTRANS","OPTFUZZY","STENCIL","TRANSLUCENT", "ADD",NULL}; + + static const int renderstyle_values[]={ + STYLE_None, STYLE_Normal, STYLE_Fuzzy, STYLE_SoulTrans, STYLE_OptFuzzy, + STYLE_Stencil, STYLE_Translucent, STYLE_Add}; + + SC_MustGetString(); + defaults->RenderStyle=renderstyle_values[SC_MustMatchString(renderstyles)]; +} + +//========================================================================== +// +//========================================================================== +static void ActorAlpha (AActor *defaults, Baggage &bag) +{ + if (SC_CheckString("DEFAULT")) + { + defaults->alpha = gameinfo.gametype==GAME_Heretic? HR_SHADOW : HX_SHADOW; + } + else + { + SC_MustGetFloat(); + defaults->alpha=fixed_t(sc_Float*FRACUNIT); + } +} + +//========================================================================== +// +//========================================================================== +static void ActorObituary (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaString (AMETA_Obituary, sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorHitObituary (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaString (AMETA_HitObituary, sc_String); +} + +//========================================================================== +// +//========================================================================== +static void ActorDontHurtShooter (AActor *defaults, Baggage &bag) +{ + bag.Info->Class->Meta.SetMetaInt (ACMETA_DontHurtShooter, true); +} + +//========================================================================== +// +//========================================================================== +static void ActorExplosionRadius (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt (ACMETA_ExplosionRadius, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void ActorExplosionDamage (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt (ACMETA_ExplosionDamage, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void ActorDeathHeight (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + fixed_t h = fixed_t(sc_Float * FRACUNIT); + // AActor::Die() uses a height of 0 to mean "cut the height to 1/4", + // so if a height of 0 is desired, store it as -1. + bag.Info->Class->Meta.SetMetaFixed (AMETA_DeathHeight, h <= 0 ? -1 : h); +} + +//========================================================================== +// +//========================================================================== +static void ActorBurnHeight (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + fixed_t h = fixed_t(sc_Float * FRACUNIT); + // The note above for AMETA_DeathHeight also applies here. + bag.Info->Class->Meta.SetMetaFixed (AMETA_BurnHeight, h <= 0 ? -1 : h); +} + +//========================================================================== +// +//========================================================================== +static void ActorMaxTargetRange (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->maxtargetrange = fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorMeleeThreshold (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->meleethreshold = fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorMeleeDamage (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt (ACMETA_MeleeDamage, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void ActorMeleeRange (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->meleerange = fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorMeleeSound (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaInt (ACMETA_MeleeSound, S_FindSound(sc_String)); +} + +//========================================================================== +// +//========================================================================== +static void ActorMissileType (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaInt (ACMETA_MissileName, FName(sc_String)); +} + +//========================================================================== +// +//========================================================================== +static void ActorMissileHeight (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + bag.Info->Class->Meta.SetMetaFixed (ACMETA_MissileHeight, fixed_t(sc_Float*FRACUNIT)); +} + +//========================================================================== +// +//========================================================================== +static void ActorTranslation (AActor *defaults, Baggage &bag) +{ + if (SC_CheckNumber()) + { + int max = (gameinfo.gametype==GAME_Strife || (bag.Info->GameFilter&GAME_Strife)) ? 6:2; + if (sc_Number < 0 || sc_Number > max) + { + SC_ScriptError ("Translation must be in the range [0,%d]", max); + } + defaults->Translation = TRANSLATION(TRANSLATION_Standard, sc_Number); + } + else + { + unsigned char translation[256]; + for(int i=0;i<256;i++) translation[i]=i; + do + { + SC_GetString(); + AddToTranslation(translation,sc_String); + } + while (SC_CheckString(",")); + defaults->Translation = StoreTranslation (translation); + } +} + +//========================================================================== +// +//========================================================================== +static void ActorBloodColor (AActor *defaults, Baggage &bag) +{ + int r,g,b; + + if (SC_CheckNumber()) + { + SC_MustGetNumber(); + r=clamp(sc_Number, 0, 255); + SC_CheckString(","); + SC_MustGetNumber(); + g=clamp(sc_Number, 0, 255); + SC_CheckString(","); + SC_MustGetNumber(); + b=clamp(sc_Number, 0, 255); + } + else + { + SC_MustGetString(); + int c = V_GetColor(NULL, sc_String); + r=RPART(c); + g=GPART(c); + b=BPART(c); + } + PalEntry pe = MAKERGB(r,g,b); + pe.a = CreateBloodTranslation(pe); + bag.Info->Class->Meta.SetMetaInt (AMETA_BloodColor, pe); +} + + +//========================================================================== +// +//========================================================================== +static void ActorBloodType (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + FName blood = sc_String; + // normal blood + bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType, blood); + + if (SC_CheckString(",")) + { + SC_MustGetString(); + blood = sc_String; + } + // blood splatter + bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType2, blood); + + if (SC_CheckString(",")) + { + SC_MustGetString(); + blood = sc_String; + } + // axe blood + bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType3, blood); +} + +//========================================================================== +// +//========================================================================== +static void ActorBounceFactor (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + defaults->bouncefactor = clamp(fixed_t(sc_Float * FRACUNIT), 0, FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorBounceCount (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber (); + defaults->bouncecount = sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ActorMinMissileChance (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber (); + defaults->MinMissileChance=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ActorDamageType (AActor *defaults, Baggage &bag) +{ + SC_MustGetString (); + if (SC_Compare("Normal")) defaults->DamageType = NAME_None; + else defaults->DamageType=sc_String; +} + +//========================================================================== +// +//========================================================================== +static void ActorDamageFactor (AActor *defaults, Baggage &bag) +{ + SC_MustGetString (); + if (bag.Info->DamageFactors == NULL) bag.Info->DamageFactors=new DmgFactors; + + FName dmgType; + if (SC_Compare("Normal")) dmgType = NAME_None; + else dmgType=sc_String; + + SC_MustGetToken(','); + SC_MustGetFloat(); + (*bag.Info->DamageFactors)[dmgType]=(fixed_t)(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorDecal (AActor *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->DecalGenerator = (FDecalBase *)intptr_t(int(FName(sc_String))); +} + +//========================================================================== +// +//========================================================================== +static void ActorMaxStepHeight (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber (); + defaults->MaxStepHeight=sc_Number * FRACUNIT; +} + +//========================================================================== +// +//========================================================================== +static void ActorMaxDropoffHeight (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber (); + defaults->MaxDropOffHeight=sc_Number * FRACUNIT; +} + +//========================================================================== +// +//========================================================================== +static void ActorPoisonDamage (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt (AMETA_PoisonDamage, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void ActorFastSpeed (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + bag.Info->Class->Meta.SetMetaFixed (AMETA_FastSpeed, fixed_t(sc_Float*FRACUNIT)); +} + +//========================================================================== +// +//========================================================================== +static void ActorRadiusDamageFactor (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + bag.Info->Class->Meta.SetMetaFixed (AMETA_RDFactor, fixed_t(sc_Float*FRACUNIT)); +} + +//========================================================================== +// +//========================================================================== +static void ActorCameraheight (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + bag.Info->Class->Meta.SetMetaFixed (AMETA_CameraHeight, fixed_t(sc_Float*FRACUNIT)); +} + +//========================================================================== +// +//========================================================================== +static void ActorVSpeed (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->momz = fixed_t(sc_Float*FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void ActorGravity (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + + if (sc_Float < 0.f || sc_Float > 1.f) + SC_ScriptError ("Gravity must be in the range [0,1]"); + + defaults->gravity = FLOAT2FIXED (sc_Float); + + if (sc_Float == 0.f) + defaults->flags |= MF_NOGRAVITY; +} + +//========================================================================== +// +//========================================================================== +static void ActorClearFlags (AActor *defaults, Baggage &bag) +{ + defaults->flags=defaults->flags3=defaults->flags4=defaults->flags5=0; + defaults->flags2&=MF2_ARGSDEFINED; // this flag must not be cleared +} + +//========================================================================== +// +//========================================================================== +static void ActorMonster (AActor *defaults, Baggage &bag) +{ + // sets the standard flag for a monster + defaults->flags|=MF_SHOOTABLE|MF_COUNTKILL|MF_SOLID; + defaults->flags2|=MF2_PUSHWALL|MF2_MCROSS|MF2_PASSMOBJ; + defaults->flags3|=MF3_ISMONSTER; + defaults->flags4|=MF4_CANUSEWALLS; +} + +//========================================================================== +// +//========================================================================== +static void ActorProjectile (AActor *defaults, Baggage &bag) +{ + // sets the standard flags for a projectile + defaults->flags|=MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE; + defaults->flags2|=MF2_IMPACT|MF2_PCROSS|MF2_NOTELEPORT; + if (gameinfo.gametype&GAME_Raven) defaults->flags5|=MF5_BLOODSPLATTER; +} + +//========================================================================== +// +// Special inventory properties +// +//========================================================================== + +//========================================================================== +// +//========================================================================== +static void AmmoBackpackAmount (AAmmo *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->BackpackAmount=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void AmmoBackpackMaxAmount (AAmmo *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->BackpackMaxAmount=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void AmmoDropAmount (AAmmo *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt (AIMETA_DropAmount, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void ArmorMaxSaveAmount (ABasicArmorBonus *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->MaxSaveAmount = sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ArmorMaxBonus (ABasicArmorBonus *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->BonusCount = sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ArmorMaxBonusMax (ABasicArmorBonus *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->BonusMax = sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void ArmorSaveAmount (AActor *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + // Special case here because this property has to work for 2 unrelated classes + if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) + { + ((ABasicArmorPickup*)defaults)->SaveAmount=sc_Number; + } + else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) + { + ((ABasicArmorBonus*)defaults)->SaveAmount=sc_Number; + } + else + { + SC_ScriptError("\"%s\" requires an actor of type \"Armor\"\n", sc_String); + } +} + +//========================================================================== +// +//========================================================================== +static void ArmorSavePercent (AActor *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + if (sc_Float<0.0f) sc_Float=0.0f; + if (sc_Float>100.0f) sc_Float=100.0f; + // Special case here because this property has to work for 2 unrelated classes + if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) + { + ((ABasicArmorPickup*)defaults)->SavePercent=fixed_t(sc_Float*FRACUNIT/100.0f); + } + else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) + { + ((ABasicArmorBonus*)defaults)->SavePercent=fixed_t(sc_Float*FRACUNIT/100.0f); + } + else + { + SC_ScriptError("\"%s\" requires an actor of type \"Armor\"\n", sc_String); + } +} + +//========================================================================== +// +//========================================================================== +static void InventoryAmount (AInventory *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->Amount=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void InventoryIcon (AInventory *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->Icon = TexMan.AddPatch (sc_String); + if (defaults->Icon <= 0) + { + defaults->Icon = TexMan.AddPatch (sc_String, ns_sprites); + if (defaults->Icon<=0) + { + // Don't print warnings if the item is for another game or if this is a shareware IWAD. + // Strife's teaser doesn't contain all the icon graphics of the full game. + if ((bag.Info->GameFilter == GAME_Any || bag.Info->GameFilter & gameinfo.gametype) && + !(gameinfo.flags&GI_SHAREWARE)) + { + Printf("Icon '%s' for '%s' not found\n", sc_String, bag.Info->Class->TypeName.GetChars()); + } + } + } +} + +//========================================================================== +// +//========================================================================== +static void InventoryMaxAmount (AInventory *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->MaxAmount=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void InventoryDefMaxAmount (AInventory *defaults, Baggage &bag) +{ + defaults->MaxAmount = gameinfo.gametype == GAME_Heretic ? 16 : 25; +} + + +//========================================================================== +// +//========================================================================== +static void InventoryPickupmsg (AInventory *defaults, Baggage &bag) +{ + // allow game specific pickup messages + const char * games[] = {"Doom", "Heretic", "Hexen", "Raven", "Strife", NULL}; + int gamemode[]={GAME_Doom, GAME_Heretic, GAME_Hexen, GAME_Raven, GAME_Strife}; + + SC_MustGetString(); + int game = SC_MatchString(games); + + if (game!=-1 && SC_CheckString(",")) + { + SC_MustGetString(); + if (!(gameinfo.gametype&gamemode[game])) return; + } + bag.Info->Class->Meta.SetMetaString(AIMETA_PickupMessage, sc_String); +} + +//========================================================================== +// +//========================================================================== +static void InventoryPickupsound (AInventory *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->PickupSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void InventoryRespawntics (AInventory *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->RespawnTics=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void InventoryUsesound (AInventory *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->UseSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void InventoryGiveQuest (AInventory *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt(AIMETA_GiveQuest, sc_Number); +} + +//========================================================================== +// +//========================================================================== +static void HealthLowMessage (AHealth *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + bag.Info->Class->Meta.SetMetaInt(AIMETA_LowHealth, sc_Number); + SC_MustGetStringName(","); + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaString(AIMETA_LowHealthMessage, sc_String); +} + +//========================================================================== +// +//========================================================================== +static void PuzzleitemNumber (APuzzleItem *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->PuzzleItemNumber=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void PuzzleitemFailMsg (APuzzleItem *defaults, Baggage &bag) +{ + SC_MustGetString(); + bag.Info->Class->Meta.SetMetaString(AIMETA_PuzzFailMessage, sc_String); +} + +//========================================================================== +// +//========================================================================== +static void WeaponAmmoGive1 (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->AmmoGive1=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void WeaponAmmoGive2 (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->AmmoGive2=sc_Number; +} + +//========================================================================== +// +// Passing these parameters is really tricky to allow proper inheritance +// and forward declarations. Here only a name is +// stored which must be resolved after everything has been declared +// +//========================================================================== + +static void WeaponAmmoType1 (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->AmmoType1 = fuglyname(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void WeaponAmmoType2 (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->AmmoType2 = fuglyname(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void WeaponAmmoUse1 (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->AmmoUse1=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void WeaponAmmoUse2 (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->AmmoUse2=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void WeaponKickback (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->Kickback=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void WeaponReadySound (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->ReadySound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void WeaponSelectionOrder (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->SelectionOrder=sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void WeaponSisterWeapon (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->SisterWeaponType=fuglyname(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void WeaponUpSound (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->UpSound=S_FindSound(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void WeaponYAdjust (AWeapon *defaults, Baggage &bag) +{ + SC_MustGetFloat(); + defaults->YAdjust=fixed_t(sc_Float * FRACUNIT); +} + +//========================================================================== +// +//========================================================================== +static void WPieceValue (AWeaponPiece *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->PieceValue = 1 << (sc_Number-1); +} + +//========================================================================== +// +//========================================================================== +static void WPieceWeapon (AWeaponPiece *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->WeaponClass = fuglyname(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void PowerupColor (APowerupGiver *defaults, Baggage &bag) +{ + int r; + int g; + int b; + int alpha; + + if (SC_CheckNumber()) + { + r=clamp(sc_Number, 0, 255); + SC_CheckString(","); + SC_MustGetNumber(); + g=clamp(sc_Number, 0, 255); + SC_CheckString(","); + SC_MustGetNumber(); + b=clamp(sc_Number, 0, 255); + } + else + { + SC_MustGetString(); + + if (SC_Compare("INVERSEMAP")) + { + defaults->BlendColor = INVERSECOLOR; + return; + } + else if (SC_Compare("GOLDMAP")) + { + defaults->BlendColor = GOLDCOLOR; + return; + } + // [BC] Yay, more hacks. + else if ( SC_Compare( "REDMAP" )) + { + defaults->BlendColor = REDCOLOR; + return; + } + else if ( SC_Compare( "GREENMAP" )) + { + defaults->BlendColor = GREENCOLOR; + return; + } + + int c = V_GetColor(NULL, sc_String); + r=RPART(c); + g=GPART(c); + b=BPART(c); + } + SC_CheckString(","); + SC_MustGetFloat(); + alpha=int(sc_Float*255); + alpha=clamp(alpha, 0, 255); + if (alpha!=0) defaults->BlendColor = MAKEARGB(alpha, r, g, b); + else defaults->BlendColor = 0; +} + +//========================================================================== +// +//========================================================================== +static void PowerupDuration (APowerupGiver *defaults, Baggage &bag) +{ + SC_MustGetNumber(); + defaults->EffectTics = sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void PowerupMode (APowerupGiver *defaults, Baggage &bag) +{ + SC_MustGetString(); + defaults->mode = (FName)sc_String; +} + +//========================================================================== +// +//========================================================================== +static void PowerupType (APowerupGiver *defaults, Baggage &bag) +{ + FString typestr; + + SC_MustGetString(); + typestr.Format ("Power%s", sc_String); + const PClass * powertype=PClass::FindClass(typestr); + if (!powertype) + { + SC_ScriptError("Unknown powerup type '%s' in '%s'\n", sc_String, bag.Info->Class->TypeName.GetChars()); + } + else if (!powertype->IsDescendantOf(RUNTIME_CLASS(APowerup))) + { + SC_ScriptError("Invalid powerup type '%s' in '%s'\n", sc_String, bag.Info->Class->TypeName.GetChars()); + } + else + { + defaults->PowerupType=powertype; + } +} + +//========================================================================== +// +// [GRB] Special player properties +// +//========================================================================== + +//========================================================================== +// +//========================================================================== +static void PlayerDisplayName (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetString (); + bag.Info->Class->Meta.SetMetaString (APMETA_DisplayName, sc_String); +} + +//========================================================================== +// +//========================================================================== +static void PlayerSoundClass (APlayerPawn *defaults, Baggage &bag) +{ + FString tmp; + + SC_MustGetString (); + tmp = sc_String; + tmp.ReplaceChars (' ', '_'); + bag.Info->Class->Meta.SetMetaString (APMETA_SoundClass, tmp); +} + +//========================================================================== +// +//========================================================================== +static void PlayerColorRange (APlayerPawn *defaults, Baggage &bag) +{ + int start, end; + + SC_MustGetNumber (); + start = sc_Number; + SC_CheckString(","); + SC_MustGetNumber (); + end = sc_Number; + + if (start > end) + swap (start, end); + + bag.Info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8)); +} + +//========================================================================== +// +//========================================================================== +static void PlayerAttackZOffset (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + defaults->AttackZOffset = FLOAT2FIXED (sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void PlayerJumpZ (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + defaults->JumpZ = FLOAT2FIXED (sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void PlayerSpawnClass (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetString (); + if (SC_Compare ("Any")) + defaults->SpawnMask = 0; + else if (SC_Compare ("Fighter")) + defaults->SpawnMask |= MTF_FIGHTER; + else if (SC_Compare ("Cleric")) + defaults->SpawnMask |= MTF_CLERIC; + else if (SC_Compare ("Mage")) + defaults->SpawnMask |= MTF_MAGE; + else if (IsNum(sc_String)) + { + int val = strtol(sc_String, NULL, 0); + defaults->SpawnMask = (val*MTF_FIGHTER) & (MTF_FIGHTER|MTF_CLERIC|MTF_MAGE); + } +} + +//========================================================================== +// +//========================================================================== +static void PlayerViewHeight (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + defaults->ViewHeight = FLOAT2FIXED (sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void PlayerForwardMove (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + defaults->ForwardMove1 = defaults->ForwardMove2 = FLOAT2FIXED (sc_Float); + if (CheckFloatParm ()) + defaults->ForwardMove2 = FLOAT2FIXED (sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void PlayerSideMove (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetFloat (); + defaults->SideMove1 = defaults->SideMove2 = FLOAT2FIXED (sc_Float); + if (CheckFloatParm ()) + defaults->SideMove2 = FLOAT2FIXED (sc_Float); +} + +//========================================================================== +// +//========================================================================== +static void PlayerMaxHealth (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetNumber (); + defaults->MaxHealth = sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void PlayerRunHealth (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetNumber (); + defaults->RunHealth = sc_Number; +} + +//========================================================================== +// +//========================================================================== +static void PlayerMorphWeapon (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetString (); + defaults->MorphWeapon = FName(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void PlayerScoreIcon (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetString (); + defaults->ScoreIcon = TexMan.AddPatch (sc_String); + if (defaults->ScoreIcon <= 0) + { + defaults->ScoreIcon = TexMan.AddPatch (sc_String, ns_sprites); + if (defaults->ScoreIcon <= 0) + { + Printf("Icon '%s' for '%s' not found\n", sc_String, bag.Info->Class->TypeName.GetChars ()); + } + } +} + +//========================================================================== +// +//========================================================================== +static void PlayerCrouchSprite (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetString (); + for (unsigned int i = 0; i < sc_StringLen; i++) sc_String[i] = toupper (sc_String[i]); + defaults->crouchsprite = GetSpriteIndex (sc_String); +} + +//========================================================================== +// +// [GRB] Store start items in drop item list +// +//========================================================================== +static void PlayerStartItem (APlayerPawn *defaults, Baggage &bag) +{ + // create a linked list of dropitems + if (!bag.DropItemSet) + { + bag.DropItemSet = true; + bag.DropItemList = NULL; + } + + FDropItem * di=new FDropItem; + + SC_MustGetString(); + di->Name = sc_String; + di->probability = 255; + di->amount = 1; + if (CheckNumParm()) + { + di->amount = sc_Number; + } + di->Next = bag.DropItemList; + bag.DropItemList = di; +} + +//========================================================================== +// +//========================================================================== +static void PlayerInvulMode (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetString (); + bag.Info->Class->Meta.SetMetaInt (APMETA_InvulMode, (FName)sc_String); +} + +//========================================================================== +// +//========================================================================== +static void PlayerHealRadius (APlayerPawn *defaults, Baggage &bag) +{ + SC_MustGetString (); + bag.Info->Class->Meta.SetMetaInt (APMETA_HealingRadius, (FName)sc_String); +} + +//========================================================================== +// +//========================================================================== +static void PlayerHexenArmor (APlayerPawn *defaults, Baggage &bag) +{ + for (int i=0;i<5;i++) + { + SC_MustGetFloat (); + bag.Info->Class->Meta.SetMetaFixed (APMETA_Hexenarmor0+i, FLOAT2FIXED (sc_Float)); + if (i!=4) SC_MustGetStringName(","); + } +} + +//========================================================================== +// +//========================================================================== +static void EggFXMonsterClass (AMorphProjectile *defaults, Baggage &bag) +{ + SC_MustGetString (); + defaults->MonsterClass = FName(sc_String); +} + +//========================================================================== +// +//========================================================================== +static void EggFXPlayerClass (AMorphProjectile *defaults, Baggage &bag) +{ + SC_MustGetString (); + defaults->PlayerClass = FName(sc_String); +} + +//========================================================================== +// +//========================================================================== +static const ActorProps *APropSearch (const char *str, const ActorProps *props, int numprops) +{ + int min = 0, max = numprops - 1; + + while (min <= max) + { + int mid = (min + max) / 2; + int lexval = strcmp (str, props[mid].name); + if (lexval == 0) + { + return &props[mid]; + } + else if (lexval > 0) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } + return NULL; +} + +//========================================================================== +// +// all actor properties +// +//========================================================================== +#define apf ActorPropFunction +static const ActorProps props[] = +{ + { "activesound", ActorActiveSound, RUNTIME_CLASS(AActor) }, + { "alpha", ActorAlpha, RUNTIME_CLASS(AActor) }, + { "ammo.backpackamount", (apf)AmmoBackpackAmount, RUNTIME_CLASS(AAmmo) }, + { "ammo.backpackmaxamount", (apf)AmmoBackpackMaxAmount, RUNTIME_CLASS(AAmmo) }, + { "ammo.dropamount", (apf)AmmoDropAmount, RUNTIME_CLASS(AAmmo) }, + { "args", ActorArgs, RUNTIME_CLASS(AActor) }, + { "armor.maxbonus", (apf)ArmorMaxBonus, RUNTIME_CLASS(ABasicArmorBonus) }, + { "armor.maxbonusmax", (apf)ArmorMaxBonusMax, RUNTIME_CLASS(ABasicArmorBonus) }, + { "armor.maxsaveamount", (apf)ArmorMaxSaveAmount, RUNTIME_CLASS(ABasicArmorBonus) }, + { "armor.saveamount", (apf)ArmorSaveAmount, RUNTIME_CLASS(AActor) }, + { "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) }, + { "attacksound", ActorAttackSound, RUNTIME_CLASS(AActor) }, + { "bloodcolor", ActorBloodColor, RUNTIME_CLASS(AActor) }, + { "bloodtype", ActorBloodType, RUNTIME_CLASS(AActor) }, + { "bouncecount", ActorBounceCount, RUNTIME_CLASS(AActor) }, + { "bouncefactor", ActorBounceFactor, RUNTIME_CLASS(AActor) }, + { "burn", ActorBurnState, RUNTIME_CLASS(AActor) }, + { "burnheight", ActorBurnHeight, RUNTIME_CLASS(AActor) }, + { "cameraheight", ActorCameraheight, RUNTIME_CLASS(AActor) }, + { "clearflags", ActorClearFlags, RUNTIME_CLASS(AActor) }, + { "conversationid", ActorConversationID, RUNTIME_CLASS(AActor) }, + { "crash", ActorCrashState, RUNTIME_CLASS(AActor) }, + { "crush", ActorCrushState, RUNTIME_CLASS(AActor) }, + { "damage", ActorDamage, RUNTIME_CLASS(AActor) }, + { "damagefactor", ActorDamageFactor, RUNTIME_CLASS(AActor) }, + { "damagetype", ActorDamageType, RUNTIME_CLASS(AActor) }, + { "death", ActorDeathState, RUNTIME_CLASS(AActor) }, + { "deathheight", ActorDeathHeight, RUNTIME_CLASS(AActor) }, + { "deathsound", ActorDeathSound, RUNTIME_CLASS(AActor) }, + { "decal", ActorDecal, RUNTIME_CLASS(AActor) }, + { "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) }, + { "donthurtshooter", ActorDontHurtShooter, RUNTIME_CLASS(AActor) }, + { "dropitem", ActorDropItem, RUNTIME_CLASS(AActor) }, + { "explosiondamage", ActorExplosionDamage, RUNTIME_CLASS(AActor) }, + { "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) }, + { "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) }, + { "floatspeed", ActorFloatSpeed, RUNTIME_CLASS(AActor) }, + { "game", ActorGame, RUNTIME_CLASS(AActor) }, + { "gibhealth", ActorGibHealth, RUNTIME_CLASS(AActor) }, + { "gravity", ActorGravity, RUNTIME_CLASS(AActor) }, + { "heal", ActorHealState, RUNTIME_CLASS(AActor) }, + { "health", ActorHealth, RUNTIME_CLASS(AActor) }, + { "health.lowmessage", (apf)HealthLowMessage, RUNTIME_CLASS(AHealth) }, + { "height", ActorHeight, RUNTIME_CLASS(AActor) }, + { "hitobituary", ActorHitObituary, RUNTIME_CLASS(AActor) }, + { "howlsound", ActorHowlSound, RUNTIME_CLASS(AActor) }, + { "ice", ActorIceState, RUNTIME_CLASS(AActor) }, + { "inventory.amount", (apf)InventoryAmount, RUNTIME_CLASS(AInventory) }, + { "inventory.defmaxamount", (apf)InventoryDefMaxAmount, RUNTIME_CLASS(AInventory) }, + { "inventory.givequest", (apf)InventoryGiveQuest, RUNTIME_CLASS(AInventory) }, + { "inventory.icon", (apf)InventoryIcon, RUNTIME_CLASS(AInventory) }, + { "inventory.maxamount", (apf)InventoryMaxAmount, RUNTIME_CLASS(AInventory) }, + { "inventory.pickupmessage", (apf)InventoryPickupmsg, RUNTIME_CLASS(AInventory) }, + { "inventory.pickupsound", (apf)InventoryPickupsound, RUNTIME_CLASS(AInventory) }, + { "inventory.respawntics", (apf)InventoryRespawntics, RUNTIME_CLASS(AInventory) }, + { "inventory.usesound", (apf)InventoryUsesound, RUNTIME_CLASS(AInventory) }, + { "mass", ActorMass, RUNTIME_CLASS(AActor) }, + { "maxdropoffheight", ActorMaxDropoffHeight, RUNTIME_CLASS(AActor) }, + { "maxstepheight", ActorMaxStepHeight, RUNTIME_CLASS(AActor) }, + { "maxtargetrange", ActorMaxTargetRange, RUNTIME_CLASS(AActor) }, + { "melee", ActorMeleeState, RUNTIME_CLASS(AActor) }, + { "meleedamage", ActorMeleeDamage, RUNTIME_CLASS(AActor) }, + { "meleerange", ActorMeleeRange, RUNTIME_CLASS(AActor) }, + { "meleesound", ActorMeleeSound, RUNTIME_CLASS(AActor) }, + { "meleethreshold", ActorMeleeThreshold, RUNTIME_CLASS(AActor) }, + { "minmissilechance", ActorMinMissileChance, RUNTIME_CLASS(AActor) }, + { "missile", ActorMissileState, RUNTIME_CLASS(AActor) }, + { "missileheight", ActorMissileHeight, RUNTIME_CLASS(AActor) }, + { "missiletype", ActorMissileType, RUNTIME_CLASS(AActor) }, + { "monster", ActorMonster, RUNTIME_CLASS(AActor) }, + { "morphprojectile.monsterclass",(apf)EggFXMonsterClass, RUNTIME_CLASS(AMorphProjectile) }, + { "morphprojectile.playerclass",(apf)EggFXPlayerClass, RUNTIME_CLASS(AMorphProjectile) }, + { "obituary", ActorObituary, RUNTIME_CLASS(AActor) }, + { "pain", ActorPainState, RUNTIME_CLASS(AActor) }, + { "painchance", ActorPainChance, RUNTIME_CLASS(AActor) }, + { "painsound", ActorPainSound, RUNTIME_CLASS(AActor) }, + { "player.attackzoffset", (apf)PlayerAttackZOffset, RUNTIME_CLASS(APlayerPawn) }, + { "player.colorrange", (apf)PlayerColorRange, RUNTIME_CLASS(APlayerPawn) }, + { "player.crouchsprite", (apf)PlayerCrouchSprite, RUNTIME_CLASS(APlayerPawn) }, + { "player.displayname", (apf)PlayerDisplayName, RUNTIME_CLASS(APlayerPawn) }, + { "player.forwardmove", (apf)PlayerForwardMove, RUNTIME_CLASS(APlayerPawn) }, + { "player.healradiustype", (apf)PlayerHealRadius, RUNTIME_CLASS(APlayerPawn) }, + { "player.hexenarmor", (apf)PlayerHexenArmor, RUNTIME_CLASS(APlayerPawn) }, + { "player.invulnerabilitymode", (apf)PlayerInvulMode, RUNTIME_CLASS(APlayerPawn) }, + { "player.jumpz", (apf)PlayerJumpZ, RUNTIME_CLASS(APlayerPawn) }, + { "player.maxhealth", (apf)PlayerMaxHealth, RUNTIME_CLASS(APlayerPawn) }, + { "player.morphweapon", (apf)PlayerMorphWeapon, RUNTIME_CLASS(APlayerPawn) }, + { "player.runhealth", (apf)PlayerRunHealth, RUNTIME_CLASS(APlayerPawn) }, + { "player.scoreicon", (apf)PlayerScoreIcon, RUNTIME_CLASS(APlayerPawn) }, + { "player.sidemove", (apf)PlayerSideMove, RUNTIME_CLASS(APlayerPawn) }, + { "player.soundclass", (apf)PlayerSoundClass, RUNTIME_CLASS(APlayerPawn) }, + { "player.spawnclass", (apf)PlayerSpawnClass, RUNTIME_CLASS(APlayerPawn) }, + { "player.startitem", (apf)PlayerStartItem, RUNTIME_CLASS(APlayerPawn) }, + { "player.viewheight", (apf)PlayerViewHeight, RUNTIME_CLASS(APlayerPawn) }, + { "poisondamage", ActorPoisonDamage, RUNTIME_CLASS(AActor) }, + { "powerup.color", (apf)PowerupColor, RUNTIME_CLASS(APowerupGiver) }, + { "powerup.duration", (apf)PowerupDuration, RUNTIME_CLASS(APowerupGiver) }, + { "powerup.mode", (apf)PowerupMode, RUNTIME_CLASS(APowerupGiver) }, + { "powerup.type", (apf)PowerupType, RUNTIME_CLASS(APowerupGiver) }, + { "projectile", ActorProjectile, RUNTIME_CLASS(AActor) }, + { "puzzleitem.failmessage", (apf)PuzzleitemFailMsg, RUNTIME_CLASS(APuzzleItem) }, + { "puzzleitem.number", (apf)PuzzleitemNumber, RUNTIME_CLASS(APuzzleItem) }, + { "radius", ActorRadius, RUNTIME_CLASS(AActor) }, + { "radiusdamagefactor", ActorRadiusDamageFactor, RUNTIME_CLASS(AActor) }, + { "raise", ActorRaiseState, RUNTIME_CLASS(AActor) }, + { "reactiontime", ActorReactionTime, RUNTIME_CLASS(AActor) }, + { "renderstyle", ActorRenderStyle, RUNTIME_CLASS(AActor) }, + { "scale", ActorScale, RUNTIME_CLASS(AActor) }, + { "see", ActorSeeState, RUNTIME_CLASS(AActor) }, + { "seesound", ActorSeeSound, RUNTIME_CLASS(AActor) }, + { "skip_super", ActorSkipSuper, RUNTIME_CLASS(AActor) }, + { "spawn", ActorSpawnState, RUNTIME_CLASS(AActor) }, + { "spawnid", ActorSpawnID, RUNTIME_CLASS(AActor) }, + { "speed", ActorSpeed, RUNTIME_CLASS(AActor) }, + { "states", ActorStates, RUNTIME_CLASS(AActor) }, + { "tag", ActorTag, RUNTIME_CLASS(AActor) }, + { "translation", ActorTranslation, RUNTIME_CLASS(AActor) }, + { "vspeed", ActorVSpeed, RUNTIME_CLASS(AActor) }, + { "weapon.ammogive", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammogive1", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammogive2", (apf)WeaponAmmoGive2, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammotype", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammotype1", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammotype2", (apf)WeaponAmmoType2, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammouse", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammouse1", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammouse2", (apf)WeaponAmmoUse2, RUNTIME_CLASS(AWeapon) }, + { "weapon.kickback", (apf)WeaponKickback, RUNTIME_CLASS(AWeapon) }, + { "weapon.readysound", (apf)WeaponReadySound, RUNTIME_CLASS(AWeapon) }, + { "weapon.selectionorder", (apf)WeaponSelectionOrder, RUNTIME_CLASS(AWeapon) }, + { "weapon.sisterweapon", (apf)WeaponSisterWeapon, RUNTIME_CLASS(AWeapon) }, + { "weapon.upsound", (apf)WeaponUpSound, RUNTIME_CLASS(AWeapon) }, + { "weapon.yadjust", (apf)WeaponYAdjust, RUNTIME_CLASS(AWeapon) }, + { "weaponpiece.number", (apf)WPieceValue, RUNTIME_CLASS(AWeaponPiece) }, + { "weaponpiece.weapon", (apf)WPieceWeapon, RUNTIME_CLASS(AWeaponPiece) }, + { "wound", ActorWoundState, RUNTIME_CLASS(AActor) }, + { "woundhealth", ActorWoundHealth, RUNTIME_CLASS(AActor) }, + { "xdeath", ActorXDeathState, RUNTIME_CLASS(AActor) }, + { "xscale", ActorXScale, RUNTIME_CLASS(AActor) }, + { "yscale", ActorYScale, RUNTIME_CLASS(AActor) }, + // AWeapon:MinAmmo1 and 2 are never used so there is no point in adding them here! +}; +static const ActorProps *is_actorprop (const char *str) +{ + return APropSearch (str, props, sizeof(props)/sizeof(ActorProps)); +} + + +//========================================================================== +// +// Parses an actor property +// +//========================================================================== + +void ParseActorProperty(Baggage &bag) +{ + strlwr (sc_String); + + FString propname = sc_String; + + if (SC_CheckString (".")) + { + SC_MustGetString (); + propname += '.'; + strlwr (sc_String); + propname += sc_String; + } + else + { + SC_UnGet (); + } + + const ActorProps *prop = is_actorprop (propname.GetChars()); + + if (prop != NULL) + { + if (!bag.Info->Class->IsDescendantOf(prop->type)) + { + SC_ScriptError("\"%s\" requires an actor of type \"%s\"\n", propname.GetChars(), prop->type->TypeName.GetChars()); + } + else + { + prop->Handler ((AActor *)bag.Info->Class->Defaults, bag); + } + } + else + { + SC_ScriptError("\"%s\" is an unknown actor property\n", propname.GetChars()); + } +} + + +//========================================================================== +// +// Finalizes an actor definition +// +//========================================================================== + +void FinishActor(FActorInfo *info, Baggage &bag) +{ + AActor *defaults = (AActor*)info->Class->Defaults; + + FinishStates (info, defaults, bag); + InstallStates (info, defaults); + ProcessStates (info->OwnedStates, info->NumOwnedStates); + if (bag.DropItemSet) + { + if (bag.DropItemList == NULL) + { + if (info->Class->Meta.GetMetaInt (ACMETA_DropItems) != 0) + { + info->Class->Meta.SetMetaInt (ACMETA_DropItems, 0); + } + } + else + { + info->Class->Meta.SetMetaInt (ACMETA_DropItems, + DropItemList.Push (bag.DropItemList) + 1); + } + } + if (info->Class->IsDescendantOf (RUNTIME_CLASS(AInventory))) + { + defaults->flags |= MF_SPECIAL; + } +} \ No newline at end of file diff --git a/src/thingdef/thingdef_states.cpp b/src/thingdef/thingdef_states.cpp new file mode 100644 index 0000000000..ac65b726cf --- /dev/null +++ b/src/thingdef/thingdef_states.cpp @@ -0,0 +1,1183 @@ +/* +** thingdef_states.cpp +** +** Actor definitions - the state parser +** +**--------------------------------------------------------------------------- +** Copyright 2002-2007 Christoph Oelckers +** Copyright 2004-2007 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be +** covered by the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or (at +** your option) any later version. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "actor.h" +#include "info.h" +#include "sc_man.h" +#include "tarray.h" +#include "templates.h" +#include "cmdlib.h" +#include "p_lnspec.h" +#include "a_action.h" +#include "p_local.h" +#include "p_effect.h" +#include "v_palette.h" +#include "doomerrors.h" +#include "thingdef.h" +#include "a_sharedglobal.h" +#include "s_sound.h" + +TArray StateParameters; +TArray JumpParameters; + +//========================================================================== +// +// Action functions +// +//========================================================================== + + + +#include "thingdef_specials.h" + + +#define FROM_THINGDEF +// Prototype the code pointers +#define WEAPON(x) void A_##x(AActor*); +#define ACTOR(x) void A_##x(AActor*); +#include "codepointers.h" +#include "d_dehackedactions.h" + +AFuncDesc AFTable[] = +{ +#define WEAPON(x) { "A_" #x, A_##x }, +#define ACTOR(x) { "A_" #x, A_##x }, +#include "codepointers.h" +#include "d_dehackedactions.h" + { "A_Fall", A_NoBlocking }, + { "A_BasicAttack", A_ComboAttack }, + { "A_Explode", A_ExplodeParms } +}; + + +static TArray StateArray; + +//========================================================================== +// +// Find a function by name using a binary search +// +//========================================================================== +static int STACK_ARGS funccmp(const void * a, const void * b) +{ + return stricmp( ((AFuncDesc*)a)->Name, ((AFuncDesc*)b)->Name); +} + +AFuncDesc * FindFunction(const char * string) +{ + static bool funcsorted=false; + + if (!funcsorted) + { + qsort(AFTable, countof(AFTable), sizeof(AFTable[0]), funccmp); + funcsorted=true; + } + + int min = 0, max = countof(AFTable)-1; + + while (min <= max) + { + int mid = (min + max) / 2; + int lexval = stricmp (string, AFTable[mid].Name); + if (lexval == 0) + { + return &AFTable[mid]; + } + else if (lexval > 0) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } + return NULL; +} + + +//========================================================================== +// +// Find a state address +// +//========================================================================== + +struct FStateDefine +{ + FName Label; + TArray Children; + FState *State; +}; + +static TArray StateLabels; + +void ClearStateLabels() +{ + StateLabels.Clear(); +} + +//========================================================================== +// +// Search one list of state definitions for the given name +// +//========================================================================== + +static FStateDefine * FindStateLabelInList(TArray & list, FName name, bool create) +{ + for(unsigned i = 0; i namelist(3); + FStateDefine * statedef=NULL; + + MakeStateNameList(name, &namelist); + + TArray * statelist = &StateLabels; + for(unsigned i=0;iChildren; + } + return statedef; +} + +void AddState (const char * statename, FState * state) +{ + FStateDefine * std = FindStateAddress(statename); + std->State = state; +} + +//========================================================================== +// +// Finds the state associated with the given name +// +//========================================================================== + +FState * FindState(AActor * actor, const PClass * type, const char * name) +{ + static TArray namelist(3); + FStateDefine * statedef=NULL; + + MakeStateNameList(name, &namelist); + + TArray * statelist = &StateLabels; + for(unsigned i=0;iChildren; + } + return statedef? statedef->State : NULL; +} + +//========================================================================== +// +// Finds the state associated with the given name +// +//========================================================================== + +FState * FindStateInClass(AActor * actor, const PClass * type, const char * name) +{ + static TArray namelist(3); + + MakeStateNameList(name, &namelist); + FActorInfo * info = type->ActorInfo; + if (info) return info->FindState(namelist.Size(), &namelist[0], true); + return NULL; +} + +//========================================================================== +// +// Checks if a state list is empty +// A list is empty if it doesn't contain any states and no children +// that contain any states +// +//========================================================================== + +static bool IsStateListEmpty(TArray & statelist) +{ + for(unsigned i=0;iLabel - (int)B->Label); +} + +static FStateLabels * CreateStateLabelList(TArray & statelist) +{ + // First delete all empty labels from the list + for (int i=statelist.Size()-1;i>=0;i--) + { + if (statelist[i].Label == NAME_None || (statelist[i].State == NULL && statelist[i].Children.Size() == 0)) + { + statelist.Delete(i); + } + } + + int count=statelist.Size(); + + if (count == 0) return NULL; + + FStateLabels * list = (FStateLabels*)M_Malloc(sizeof(FStateLabels)+(count-1)*sizeof(FStateLabel)); + list->NumLabels = count; + + for (int i=0;iLabels[i].Label = statelist[i].Label; + list->Labels[i].State = statelist[i].State; + list->Labels[i].Children = CreateStateLabelList(statelist[i].Children); + } + qsort(list->Labels, count, sizeof(FStateLabel), labelcmp); + return list; +} + +//=========================================================================== +// +// InstallStates +// +// Creates the actor's state list from the current definition +// +//=========================================================================== + +void InstallStates(FActorInfo *info, AActor *defaults) +{ + // First ensure we have a valid spawn state. + FState * state = FindState(defaults, info->Class, "Spawn"); + + // Stateless actors that are direct subclasses of AActor + // have their spawnstate default to something that won't + // immediately destroy them. + if (state == &AActor::States[2] && info->Class->ParentClass == RUNTIME_CLASS(AActor)) + { + AddState("Spawn", &AActor::States[0]); + } + else if (state == NULL) + { + // A NULL spawn state will crash the engine so set it to something that will make + // the actor disappear as quickly as possible. + AddState("Spawn", &AActor::States[2]); + } + + if (info->StateList != NULL) + { + info->StateList->Destroy(); + free(info->StateList); + } + info->StateList = CreateStateLabelList(StateLabels); + + // Cache these states as member veriables. + defaults->SpawnState = info->FindState(NAME_Spawn); + defaults->SeeState = info->FindState(NAME_See); + // Melee and Missile states are manipulated by the scripted marines so they + // have to be stored locally + defaults->MeleeState = info->FindState(NAME_Melee); + defaults->MissileState = info->FindState(NAME_Missile); +} + + +//=========================================================================== +// +// MakeStateDefines +// +// Creates a list of state definitions from an existing actor +// Used by Dehacked to modify an actor's state list +// +//=========================================================================== + +static void MakeStateList(const FStateLabels *list, TArray &dest) +{ + dest.Clear(); + if (list != NULL) for(int i=0;iNumLabels;i++) + { + FStateDefine def; + + def.Label = list->Labels[i].Label; + def.State = list->Labels[i].State; + dest.Push(def); + if (list->Labels[i].Children != NULL) + { + MakeStateList(list->Labels[i].Children, dest[dest.Size()-1].Children); + } + } +} + +void MakeStateDefines(const FStateLabels *list) +{ + MakeStateList(list, StateLabels); +} + +//========================================================================== +// +// PrepareStateParameters +// creates an empty parameter list for a parameterized function call +// +//========================================================================== +int PrepareStateParameters(FState * state, int numparams) +{ + int paramindex=StateParameters.Size(); + int i, v; + + v=0; + for(i=0;iParameterIndex = paramindex+1; + return paramindex; +} + +//========================================================================== +// +// Returns the index of the given line special +// +//========================================================================== +int FindLineSpecial(const char * string) +{ + const ACSspecials *spec; + + spec = is_special(string, (unsigned int)strlen(string)); + if (spec) return spec->Special; + return 0; +} + +//========================================================================== +// +// FindLineSpecialEx +// +// Like FindLineSpecial, but also returns the min and max argument count. +// +//========================================================================== + +int FindLineSpecialEx (const char *string, int *min_args, int *max_args) +{ + const ACSspecials *spec; + + spec = is_special(string, (unsigned int)strlen(string)); + if (spec != NULL) + { + *min_args = spec->MinArgs; + *max_args = MAX(spec->MinArgs, spec->MaxArgs); + return spec->Special; + } + *min_args = *max_args = 0; + return 0; +} + +//========================================================================== +// +// DoActionSpecials +// handles action specials as code pointers +// +//========================================================================== +bool DoActionSpecials(FState & state, bool multistate, int * statecount, Baggage &bag) +{ + int i; + const ACSspecials *spec; + + if ((spec = is_special (sc_String, sc_StringLen)) != NULL) + { + + int paramindex=PrepareStateParameters(&state, 6); + + StateParameters[paramindex]=spec->Special; + + // Make this consistent with all other parameter parsing + if (SC_CheckToken('(')) + { + for (i = 0; i < 5;) + { + StateParameters[paramindex+i+1]=ParseExpression (false, bag.Info->Class); + i++; + if (!SC_CheckToken (',')) break; + } + SC_MustGetToken (')'); + } + else i=0; + + if (i < spec->MinArgs) + { + SC_ScriptError ("Too few arguments to %s", spec->name); + } + if (i > MAX (spec->MinArgs, spec->MaxArgs)) + { + SC_ScriptError ("Too many arguments to %s", spec->name); + } + state.Action = A_CallSpecial; + return true; + } + return false; +} + +//========================================================================== +// +// RetargetState(Pointer)s +// +// These functions are used when a goto follows one or more labels. +// Because multiple labels are permitted to occur consecutively with no +// intervening states, it is not enough to remember the last label defined +// and adjust it. So these functions search for all labels that point to +// the current position in the state array and give them a copy of the +// target string instead. +// +//========================================================================== + +static void RetargetStatePointers (intptr_t count, const char *target, TArray & statelist) +{ + for(unsigned i = 0;i 0) + { + RetargetStatePointers(count, target, statelist[i].Children); + } + } +} + +static void RetargetStates (intptr_t count, const char *target) +{ + RetargetStatePointers(count, target, StateLabels); +} + +//========================================================================== +// +// Reads a state label that may contain '.'s. +// processes a state block +// +//========================================================================== +static FString ParseStateString() +{ + FString statestring; + + SC_MustGetString(); + statestring = sc_String; + if (SC_CheckString("::")) + { + SC_MustGetString (); + statestring << "::" << sc_String; + } + while (SC_CheckString (".")) + { + SC_MustGetString (); + statestring << "." << sc_String; + } + return statestring; +} + +//========================================================================== +// +// ParseStates +// parses a state block +// +//========================================================================== +int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag) +{ + FString statestring; + intptr_t count = 0; + FState state; + FState * laststate = NULL; + intptr_t lastlabel = -1; + int minrequiredstate = -1; + + SC_MustGetStringName ("{"); + SC_SetEscape(false); // disable escape sequences in the state parser + while (!SC_CheckString ("}") && !sc_End) + { + memset(&state,0,sizeof(state)); + statestring = ParseStateString(); + if (!statestring.CompareNoCase("GOTO")) + { +do_goto: + statestring = ParseStateString(); + if (SC_CheckString ("+")) + { + SC_MustGetNumber (); + statestring += '+'; + statestring += sc_String; + } + // copy the text - this must be resolved later! + if (laststate != NULL) + { // Following a state definition: Modify it. + laststate->NextState = (FState*)copystring(statestring); + } + else if (lastlabel >= 0) + { // Following a label: Retarget it. + RetargetStates (count+1, statestring); + } + else + { + SC_ScriptError("GOTO before first state"); + } + } + else if (!statestring.CompareNoCase("STOP")) + { +do_stop: + if (laststate!=NULL) + { + laststate->NextState=(FState*)-1; + } + else if (lastlabel >=0) + { + RetargetStates (count+1, NULL); + } + else + { + SC_ScriptError("STOP before first state"); + continue; + } + } + else if (!statestring.CompareNoCase("WAIT") || !statestring.CompareNoCase("FAIL")) + { + if (!laststate) + { + SC_ScriptError("%s before first state", sc_String); + continue; + } + laststate->NextState=(FState*)-2; + } + else if (!statestring.CompareNoCase("LOOP")) + { + if (!laststate) + { + SC_ScriptError("LOOP before first state"); + continue; + } + laststate->NextState=(FState*)(lastlabel+1); + } + else + { + const char * statestrp; + + SC_MustGetString(); + if (SC_Compare (":")) + { + laststate = NULL; + do + { + lastlabel = count; + AddState(statestring, (FState *) (count+1)); + statestring = ParseStateString(); + if (!statestring.CompareNoCase("GOTO")) + { + goto do_goto; + } + else if (!statestring.CompareNoCase("STOP")) + { + goto do_stop; + } + SC_MustGetString (); + } while (SC_Compare (":")); +// continue; + } + + SC_UnGet (); + + if (statestring.Len() != 4) + { + SC_ScriptError ("Sprite names must be exactly 4 characters\n"); + } + + memcpy(state.sprite.name, statestring, 4); + state.Misc1=state.Misc2=0; + state.ParameterIndex=0; + SC_MustGetString(); + statestring = (sc_String+1); + statestrp = statestring; + state.Frame=(*sc_String&223)-'A'; + if ((*sc_String&223)<'A' || (*sc_String&223)>']') + { + SC_ScriptError ("Frames must be A-Z, [, \\, or ]"); + state.Frame=0; + } + + SC_MustGetNumber(); + sc_Number++; + state.Tics=sc_Number&255; + state.Misc1=(sc_Number>>8)&255; + if (state.Misc1) state.Frame|=SF_BIGTIC; + + while (SC_GetString() && !sc_Crossed) + { + if (SC_Compare("BRIGHT")) + { + state.Frame|=SF_FULLBRIGHT; + continue; + } + if (SC_Compare("OFFSET")) + { + if (state.Frame&SF_BIGTIC) + { + SC_ScriptError("You cannot use OFFSET with a state duration larger than 254!"); + } + // specify a weapon offset + SC_MustGetStringName("("); + SC_MustGetNumber(); + state.Misc1=sc_Number; + SC_MustGetStringName (","); + SC_MustGetNumber(); + state.Misc2=sc_Number; + SC_MustGetStringName(")"); + continue; + } + + // Make the action name lowercase to satisfy the gperf hashers + strlwr (sc_String); + + int minreq=count; + if (DoActionSpecials(state, !statestring.IsEmpty(), &minreq, bag)) + { + if (minreq>minrequiredstate) minrequiredstate=minreq; + goto endofstate; + } + + PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true); + if (sym != NULL && sym->SymbolType == SYM_ActionFunction) + { + PSymbolActionFunction *afd = static_cast(sym); + state.Action = afd->Function; + if (!afd->Arguments.IsEmpty()) + { + const char *params = afd->Arguments.GetChars(); + int numparams = (int)afd->Arguments.Len(); + + int v; + + if (!islower(*params)) + { + SC_MustGetStringName("("); + } + else + { + if (!SC_CheckString("(")) goto endofstate; + } + + int paramindex = PrepareStateParameters(&state, numparams); + int paramstart = paramindex; + bool varargs = params[numparams - 1] == '+'; + + if (varargs) + { + StateParameters[paramindex++] = 0; + } + + while (*params) + { + switch(*params) + { + case 'I': + case 'i': // Integer + SC_MustGetNumber(); + v=sc_Number; + break; + + case 'F': + case 'f': // Fixed point + SC_MustGetFloat(); + v=fixed_t(sc_Float*FRACUNIT); + break; + + + case 'S': + case 's': // Sound name + SC_MustGetString(); + v=S_FindSound(sc_String); + break; + + case 'M': + case 'm': // Actor name + case 'T': + case 't': // String + SC_SetEscape(true); + SC_MustGetString(); + SC_SetEscape(false); + v = (int)(sc_String[0] ? FName(sc_String) : NAME_None); + break; + + case 'L': + case 'l': // Jump label + + if (SC_CheckNumber()) + { + if (strlen(statestring)>0) + { + SC_ScriptError("You cannot use A_Jump commands with a jump index on multistate definitions\n"); + } + + v=sc_Number; + if (v<1) + { + SC_ScriptError("Negative jump offsets are not allowed"); + } + + { + int minreq=count+v; + if (minreq>minrequiredstate) minrequiredstate=minreq; + } + } + else + { + if (JumpParameters.Size()==0) JumpParameters.Push(NAME_None); + + v = -(int)JumpParameters.Size(); + FString statestring = ParseStateString(); + const PClass *stype=NULL; + int scope = statestring.IndexOf("::"); + if (scope >= 0) + { + FName scopename = FName(statestring, scope, false); + if (scopename == NAME_Super) + { + // Super refers to the direct superclass + scopename = actor->Class->ParentClass->TypeName; + } + JumpParameters.Push(scopename); + statestring = statestring.Right(statestring.Len()-scope-2); + + stype = PClass::FindClass (scopename); + if (stype == NULL) + { + SC_ScriptError ("%s is an unknown class.", scopename.GetChars()); + } + if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor))) + { + SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars()); + } + if (!stype->IsAncestorOf (actor->Class)) + { + SC_ScriptError ("%s is not derived from %s so cannot access its states.", + actor->Class->TypeName.GetChars(), stype->TypeName.GetChars()); + } + } + else + { + // No class name is stored. This allows 'virtual' jumps to + // labels in subclasses. + // It also means that the validity of the given state cannot + // be checked here. + JumpParameters.Push(NAME_None); + } + TArray names; + MakeStateNameList(statestring, &names); + + if (stype != NULL) + { + if (!stype->ActorInfo->FindState(names.Size(), &names[0])) + { + SC_ScriptError("Jump to unknown state '%s' in class '%s'", + statestring.GetChars(), stype->TypeName.GetChars()); + } + } + JumpParameters.Push((ENamedName)names.Size()); + for(unsigned i=0;iClass); + break; + + case 'Y': + case 'y': + v = ParseExpression (true, bag.Info->Class); + break; + + default: + assert(false); + v = -1; + break; + } + StateParameters[paramindex++] = v; + params++; + if (varargs) + { + StateParameters[paramstart]++; + } + if (*params) + { + if (*params == '+') + { + if (SC_CheckString(")")) + { + goto endofstate; + } + params--; + v = 0; + StateParameters.Push(v); + } + else if ((islower(*params) || *params=='!') && SC_CheckString(")")) + { + goto endofstate; + } + SC_MustGetStringName (","); + } + } + SC_MustGetStringName(")"); + } + else + { + SC_MustGetString(); + if (SC_Compare("(")) + { + SC_ScriptError("You cannot pass parameters to '%s'\n",sc_String); + } + SC_UnGet(); + } + goto endofstate; + } + SC_ScriptError("Invalid state parameter %s\n", sc_String); + } + SC_UnGet(); +endofstate: + StateArray.Push(state); + while (*statestrp) + { + int frame=((*statestrp++)&223)-'A'; + + if (frame<0 || frame>28) + { + SC_ScriptError ("Frames must be A-Z, [, \\, or ]"); + frame=0; + } + + state.Frame=(state.Frame&(SF_FULLBRIGHT|SF_BIGTIC))|frame; + StateArray.Push(state); + count++; + } + laststate=&StateArray[count]; + count++; + } + } + if (count<=minrequiredstate) + { + SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars()); + } + SC_SetEscape(true); // re-enable escape sequences + return count; +} + +//========================================================================== +// +// ResolveGotoLabel +// +//========================================================================== + +static FState *ResolveGotoLabel (AActor *actor, const PClass *mytype, char *name) +{ + const PClass *type=mytype; + FState *state; + char *namestart = name; + char *label, *offset, *pt; + int v; + + // Check for classname + if ((pt = strstr (name, "::")) != NULL) + { + const char *classname = name; + *pt = '\0'; + name = pt + 2; + + // The classname may either be "Super" to identify this class's immediate + // superclass, or it may be the name of any class that this one derives from. + if (stricmp (classname, "Super") == 0) + { + type = type->ParentClass; + actor = GetDefaultByType (type); + } + else + { + // first check whether a state of the desired name exists + const PClass *stype = PClass::FindClass (classname); + if (stype == NULL) + { + SC_ScriptError ("%s is an unknown class.", classname); + } + if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor))) + { + SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars()); + } + if (!stype->IsAncestorOf (type)) + { + SC_ScriptError ("%s is not derived from %s so cannot access its states.", + type->TypeName.GetChars(), stype->TypeName.GetChars()); + } + if (type != stype) + { + type = stype; + actor = GetDefaultByType (type); + } + } + } + label = name; + // Check for offset + offset = NULL; + if ((pt = strchr (name, '+')) != NULL) + { + *pt = '\0'; + offset = pt + 1; + } + v = offset ? strtol (offset, NULL, 0) : 0; + + // Get the state's address. + if (type==mytype) state = FindState (actor, type, label); + else state = FindStateInClass (actor, type, label); + + if (state != NULL) + { + state += v; + } + else if (v != 0) + { + SC_ScriptError ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars()); + } + delete[] namestart; // free the allocated string buffer + return state; +} + +//========================================================================== +// +// FixStatePointers +// +// Fixes an actor's default state pointers. +// +//========================================================================== + +static void FixStatePointers (FActorInfo *actor, TArray & list) +{ + for(unsigned i=0;i= 1 && v < 0x10000) + { + list[i].State = actor->OwnedStates + v - 1; + } + if (list[i].Children.Size() > 0) FixStatePointers(actor, list[i].Children); + } +} + +//========================================================================== +// +// FixStatePointersAgain +// +// Resolves an actor's state pointers that were specified as jumps. +// +//========================================================================== + +static void FixStatePointersAgain (FActorInfo *actor, AActor *defaults, TArray & list) +{ + for(unsigned i=0;iClass, (char *)list[i].State); + } + if (list[i].Children.Size() > 0) FixStatePointersAgain(actor, defaults, list[i].Children); + } +} + + +//========================================================================== +// +// FinishStates +// copies a state block and fixes all state links +// +//========================================================================== + +int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag) +{ + static int c=0; + int count = StateArray.Size(); + + if (count > 0) + { + FState *realstates = new FState[count]; + int i; + int currange; + + memcpy(realstates, &StateArray[0], count*sizeof(FState)); + actor->OwnedStates = realstates; + actor->NumOwnedStates = count; + + // adjust the state pointers + // In the case new states are added these must be adjusted, too! + FixStatePointers (actor, StateLabels); + + for(i = currange = 0; i < count; i++) + { + // resolve labels and jumps + switch((ptrdiff_t)realstates[i].NextState) + { + case 0: // next + realstates[i].NextState = (i < count-1 ? &realstates[i+1] : &realstates[0]); + break; + + case -1: // stop + realstates[i].NextState = NULL; + break; + + case -2: // wait + realstates[i].NextState = &realstates[i]; + break; + + default: // loop + if ((size_t)realstates[i].NextState < 0x10000) + { + realstates[i].NextState = &realstates[(size_t)realstates[i].NextState-1]; + } + else // goto + { + realstates[i].NextState = ResolveGotoLabel (defaults, bag.Info->Class, (char *)realstates[i].NextState); + } + } + } + } + StateArray.Clear (); + + // Fix state pointers that are gotos + FixStatePointersAgain (actor, defaults, StateLabels); + + return count; +} + +//========================================================================== +// +// For getting a state address from the parent +// No attempts have been made to add new functionality here +// This is strictly for keeping compatibility with old WADs! +// +//========================================================================== +FState *CheckState(PClass *type) +{ + int v=0; + + if (SC_GetString() && !sc_Crossed) + { + if (SC_Compare("0")) return NULL; + else if (SC_Compare("PARENT")) + { + FState * state = NULL; + SC_MustGetString(); + + FActorInfo * info = type->ParentClass->ActorInfo; + + if (info != NULL) + { + state = info->FindState(FName(sc_String)); + } + + if (SC_GetString ()) + { + if (SC_Compare ("+")) + { + SC_MustGetNumber (); + v = sc_Number; + } + else + { + SC_UnGet (); + } + } + + if (state == NULL && v==0) return NULL; + + if (v!=0 && state==NULL) + { + SC_ScriptError("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars()); + return NULL; + } + state+=v; + return state; + } + else SC_ScriptError("Invalid state assignment"); + } + return NULL; +} + diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp index e159588cdf..e375d0f20d 100644 --- a/src/thingdef_codeptr.cpp +++ b/src/thingdef_codeptr.cpp @@ -202,14 +202,27 @@ void A_UnsetFloat(AActor * self) static void DoAttack (AActor *self, bool domelee, bool domissile) { int index=CheckIndex(4); + int MeleeDamage; + int MeleeSound; + FName MissileName; + fixed_t MissileHeight; - if (index<0) return; if (self->target == NULL) return; - int MeleeDamage=StateParameters[index]; - int MeleeSound=StateParameters[index+1]; - FName MissileName=(ENamedName)StateParameters[index+2]; - fixed_t MissileHeight=StateParameters[index+3]; + if (index > 0) + { + MeleeDamage=StateParameters[index]; + MeleeSound=StateParameters[index+1]; + MissileName=(ENamedName)StateParameters[index+2]; + MissileHeight=StateParameters[index+3]; + } + else + { + MeleeDamage = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeDamage, 0); + MeleeSound = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeSound, 0); + MissileName=(ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None); + MissileHeight= self->GetClass()->Meta.GetMetaFixed (ACMETA_MissileHeight, 32*FRACUNIT); + } A_FaceTarget (self); if (domelee && MeleeDamage>0 && self->CheckMeleeRange ()) diff --git a/wadsrc/decorate/nativeclasses.txt b/wadsrc/decorate/nativeclasses.txt index 882f152609..30b3c50b40 100644 --- a/wadsrc/decorate/nativeclasses.txt +++ b/wadsrc/decorate/nativeclasses.txt @@ -115,6 +115,9 @@ class Actor extends Thinker action native A_FireAssaultGun(); action native A_CheckTerrain(); + action native A_MissileAttack(); + action native A_MeleeAttack(); + action native A_ComboAttack(); action native A_BulletAttack(); action native A_PlaySound(sound whattoplay); action native A_PlayWeaponSound(sound whattoplay); diff --git a/zdoom.vcproj b/zdoom.vcproj index c264df5235..8c771c2ce1 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -4306,10 +4306,18 @@ RelativePath=".\src\thingdef\thingdef_main.cpp" > + + + +