00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037
00038 #include "stratagus.h"
00039 #include "spells.h"
00040 #include "sound.h"
00041 #include "script.h"
00042 #include "missile.h"
00043 #include "unittype.h"
00044 #include "upgrade.h"
00045
00046
00047
00048
00049
00050
00060 static void CclSpellMissileLocation(lua_State *l, SpellActionMissileLocation *location)
00061 {
00062 const char *value;
00063 int args;
00064 int j;
00065
00066 Assert(location != NULL);
00067
00068 if (!lua_istable(l, -1)) {
00069 LuaError(l, "incorrect argument");
00070 }
00071 args = lua_objlen(l, -1);
00072 j = 0;
00073
00074 for (j = 0; j < args; ++j) {
00075 lua_rawgeti(l, -1, j + 1);
00076 value = LuaToString(l, -1);
00077 lua_pop(l, 1);
00078 ++j;
00079 if (!strcmp(value, "base")) {
00080 lua_rawgeti(l, -1, j + 1);
00081 value = LuaToString(l, -1);
00082 lua_pop(l, 1);
00083 if (!strcmp(value, "caster")) {
00084 location->Base = LocBaseCaster;
00085 } else if (!strcmp(value, "target")) {
00086 location->Base = LocBaseTarget;
00087 } else {
00088 LuaError(l, "Unsupported missile location base flag: %s" _C_ value);
00089 }
00090 } else if (!strcmp(value, "add-x")) {
00091 lua_rawgeti(l, -1, j + 1);
00092 location->AddX = LuaToNumber(l, -1);
00093 lua_pop(l, 1);
00094 } else if (!strcmp(value, "add-y")) {
00095 lua_rawgeti(l, -1, j + 1);
00096 location->AddY = LuaToNumber(l, -1);
00097 lua_pop(l, 1);
00098 } else if (!strcmp(value, "add-rand-x")) {
00099 lua_rawgeti(l, -1, j + 1);
00100 location->AddRandX = LuaToNumber(l, -1);
00101 lua_pop(l, 1);
00102 } else if (!strcmp(value, "add-rand-y")) {
00103 lua_rawgeti(l, -1, j + 1);
00104 location->AddRandY = LuaToNumber(l, -1);
00105 lua_pop(l, 1);
00106 } else {
00107 LuaError(l, "Unsupported missile location description flag: %s" _C_ value);
00108 }
00109 }
00110 }
00111
00117 static SpellActionType *CclSpellAction(lua_State *l)
00118 {
00119 const char *value;
00120 int args;
00121 int j;
00122
00123 if (!lua_istable(l, -1)) {
00124 LuaError(l, "incorrect argument");
00125 }
00126 args = lua_objlen(l, -1);
00127 j = 0;
00128
00129 lua_rawgeti(l, -1, j + 1);
00130 value = LuaToString(l, -1);
00131 lua_pop(l, 1);
00132 ++j;
00133
00134 if (!strcmp(value, "spawn-missile")) {
00135 SpawnMissile *spellaction = new SpawnMissile;
00136 for (; j < args; ++j) {
00137 lua_rawgeti(l, -1, j + 1);
00138 value = LuaToString(l, -1);
00139 lua_pop(l, 1);
00140 ++j;
00141 if (!strcmp(value, "damage")) {
00142 lua_rawgeti(l, -1, j + 1);
00143 spellaction->Damage = LuaToNumber(l, -1);
00144 lua_pop(l, 1);
00145 } else if (!strcmp(value, "delay")) {
00146 lua_rawgeti(l, -1, j + 1);
00147 spellaction->Delay = LuaToNumber(l, -1);
00148 lua_pop(l, 1);
00149 } else if (!strcmp(value, "ttl")) {
00150 lua_rawgeti(l, -1, j + 1);
00151 spellaction->TTL = LuaToNumber(l, -1);
00152 lua_pop(l, 1);
00153 } else if (!strcmp(value, "start-point")) {
00154 lua_rawgeti(l, -1, j + 1);
00155 CclSpellMissileLocation(l, &spellaction->StartPoint);
00156 lua_pop(l, 1);
00157 } else if (!strcmp(value, "end-point")) {
00158 lua_rawgeti(l, -1, j + 1);
00159 CclSpellMissileLocation(l, &spellaction->EndPoint);
00160 lua_pop(l, 1);
00161 } else if (!strcmp(value, "missile")) {
00162 lua_rawgeti(l, -1, j + 1);
00163 value = LuaToString(l, -1);
00164 spellaction->Missile = MissileTypeByIdent(value);
00165 if (spellaction->Missile == NULL) {
00166 DebugPrint("in spawn-missile : missile %s does not exist\n" _C_ value);
00167 }
00168 lua_pop(l, 1);
00169 } else {
00170 LuaError(l, "Unsupported spawn-missile tag: %s" _C_ value);
00171 }
00172 }
00173
00174 if (spellaction->Missile == NULL) {
00175 LuaError(l, "Use a missile for spawn-missile (with missile)");
00176 }
00177 return spellaction;
00178 } else if (!strcmp(value, "area-adjust-vitals")) {
00179 AreaAdjustVitals *spellaction = new AreaAdjustVitals;
00180 for (; j < args; ++j) {
00181 lua_rawgeti(l, -1, j + 1);
00182 value = LuaToString(l, -1);
00183 lua_pop(l, 1);
00184 ++j;
00185 if (!strcmp(value, "hit-points")) {
00186 lua_rawgeti(l, -1, j + 1);
00187 spellaction->HP = LuaToNumber(l, -1);
00188 lua_pop(l, 1);
00189 } else if (!strcmp(value, "mana-points")) {
00190 lua_rawgeti(l, -1, j + 1);
00191 spellaction->Mana = LuaToNumber(l, -1);
00192 lua_pop(l, 1);
00193 } else {
00194 LuaError(l, "Unsupported area-adjust-vitals tag: %s" _C_ value);
00195 }
00196 }
00197 return spellaction;
00198 } else if (!strcmp(value, "area-bombardment")) {
00199 AreaBombardment *spellaction = new AreaBombardment;
00200 for (; j < args; ++j) {
00201 lua_rawgeti(l, -1, j + 1);
00202 value = LuaToString(l, -1);
00203 lua_pop(l, 1);
00204 ++j;
00205 if (!strcmp(value, "fields")) {
00206 lua_rawgeti(l, -1, j + 1);
00207 spellaction->Fields = LuaToNumber(l, -1);
00208 lua_pop(l, 1);
00209 } else if (!strcmp(value, "shards")) {
00210 lua_rawgeti(l, -1, j + 1);
00211 spellaction->Shards = LuaToNumber(l, -1);
00212 lua_pop(l, 1);
00213 } else if (!strcmp(value, "damage")) {
00214 lua_rawgeti(l, -1, j + 1);
00215 spellaction->Damage = LuaToNumber(l, -1);
00216 lua_pop(l, 1);
00217 } else if (!strcmp(value, "start-offset-x")) {
00218 lua_rawgeti(l, -1, j + 1);
00219 spellaction->StartOffsetX = LuaToNumber(l, -1);
00220 lua_pop(l, 1);
00221 } else if (!strcmp(value, "start-offset-y")) {
00222 lua_rawgeti(l, -1, j + 1);
00223 spellaction->StartOffsetY = LuaToNumber(l, -1);
00224 lua_pop(l, 1);
00225 } else if (!strcmp(value, "missile")) {
00226 lua_rawgeti(l, -1, j + 1);
00227 value = LuaToString(l, -1);
00228 spellaction->Missile = MissileTypeByIdent(value);
00229 if (spellaction->Missile == NULL) {
00230 DebugPrint("in area-bombardement : missile %s does not exist\n" _C_ value);
00231 }
00232 lua_pop(l, 1);
00233 } else {
00234 LuaError(l, "Unsupported area-bombardment tag: %s" _C_ value);
00235 }
00236 }
00237
00238 if (spellaction->Missile == NULL) {
00239 LuaError(l, "Use a missile for area-bombardment (with missile)");
00240 }
00241 return spellaction;
00242 } else if (!strcmp(value, "demolish")) {
00243 Demolish *spellaction = new Demolish;
00244 for (; j < args; ++j) {
00245 lua_rawgeti(l, -1, j + 1);
00246 value = LuaToString(l, -1);
00247 lua_pop(l, 1);
00248 ++j;
00249 if (!strcmp(value, "range")) {
00250 lua_rawgeti(l, -1, j + 1);
00251 spellaction->Range = LuaToNumber(l, -1);
00252 lua_pop(l, 1);
00253 } else if (!strcmp(value, "damage")) {
00254 lua_rawgeti(l, -1, j + 1);
00255 spellaction->Damage = LuaToNumber(l, -1);
00256 lua_pop(l, 1);
00257 } else {
00258 LuaError(l, "Unsupported demolish tag: %s" _C_ value);
00259 }
00260 }
00261 return spellaction;
00262 } else if (!strcmp(value, "adjust-variable")) {
00263 AdjustVariable *spellaction = new AdjustVariable;
00264 lua_rawgeti(l, -1, j + 1);
00265 if (!lua_istable(l, -1)) {
00266 LuaError(l, "Table expected for adjust-variable.");
00267 }
00268 spellaction->Var = new SpellActionTypeAdjustVariable[UnitTypeVar.NumberVariable];
00269 for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) {
00270 int i;
00271
00272 i = GetVariableIndex(LuaToString(l, -2));
00273 if (i == -1) {
00274 LuaError(l, "in adjust-variable : Bad variable index : '%s'" _C_ LuaToString(l, -2));
00275 }
00276 if (lua_isnumber(l, -1)) {
00277 spellaction->Var[i].Enable = (LuaToNumber(l, -1) != 0);
00278 spellaction->Var[i].ModifEnable = 1;
00279 spellaction->Var[i].Value = LuaToNumber(l, -1);
00280 spellaction->Var[i].ModifValue = 1;
00281 spellaction->Var[i].Max = LuaToNumber(l, -1);
00282 spellaction->Var[i].ModifMax = 1;
00283 } else if (lua_istable(l, -1)) {
00284 for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) {
00285 const char *key;
00286
00287 key = LuaToString(l, -2);
00288 if (!strcmp(key, "Enable")) {
00289 spellaction->Var[i].Enable = LuaToBoolean(l, -1);
00290 spellaction->Var[i].ModifEnable = 1;
00291 } else if (!strcmp(key, "Value")) {
00292 spellaction->Var[i].Value = LuaToNumber(l, -1);
00293 spellaction->Var[i].ModifValue = 1;
00294 } else if (!strcmp(key, "Max")) {
00295 spellaction->Var[i].Max = LuaToNumber(l, -1);
00296 spellaction->Var[i].ModifMax = 1;
00297 } else if (!strcmp(key, "Increase")) {
00298 spellaction->Var[i].Increase = LuaToNumber(l, -1);
00299 spellaction->Var[i].ModifIncrease = 1;
00300 } else if (!strcmp(key, "InvertEnable")) {
00301 spellaction->Var[i].InvertEnable = LuaToBoolean(l, -1);
00302 } else if (!strcmp(key, "AddValue")) {
00303 spellaction->Var[i].AddValue = LuaToNumber(l, -1);
00304 } else if (!strcmp(key, "AddMax")) {
00305 spellaction->Var[i].AddMax = LuaToNumber(l, -1);
00306 } else if (!strcmp(key, "AddIncrease")) {
00307 spellaction->Var[i].AddIncrease = LuaToNumber(l, -1);
00308 } else if (!strcmp(key, "IncreaseTime")) {
00309 spellaction->Var[i].IncreaseTime = LuaToNumber(l, -1);
00310 } else if (!strcmp(key, "TargetIsCaster")) {
00311 value = LuaToString(l, -1);
00312 if (!strcmp(value, "caster")) {
00313 spellaction->Var[i].TargetIsCaster = 1;
00314 } else if (!strcmp(value, "target")) {
00315 spellaction->Var[i].TargetIsCaster = 0;
00316 } else {
00317 LuaError(l, "key '%s' not valid for TargetIsCaster in adjustvariable" _C_ value);
00318 }
00319 } else {
00320 LuaError(l, "key '%s' not valid for adjustvariable" _C_ key);
00321 }
00322 }
00323 } else {
00324 LuaError(l, "in adjust-variable : Bad variable value");
00325 }
00326 }
00327 lua_pop(l, 1);
00328 return spellaction;
00329 } else if (!strcmp(value, "summon")) {
00330 Summon *spellaction = new Summon;
00331 for (; j < args; ++j) {
00332 lua_rawgeti(l, -1, j + 1);
00333 value = LuaToString(l, -1);
00334 lua_pop(l, 1);
00335 ++j;
00336 if (!strcmp(value, "unit-type")) {
00337 lua_rawgeti(l, -1, j + 1);
00338 value = LuaToString(l, -1);
00339 lua_pop(l, 1);
00340 spellaction->UnitType = UnitTypeByIdent(value);
00341 if (!spellaction->UnitType) {
00342 spellaction->UnitType = 0;
00343 DebugPrint("unit type \"%s\" not found for summon spell.\n" _C_ value);
00344 }
00345 } else if (!strcmp(value, "time-to-live")) {
00346 lua_rawgeti(l, -1, j + 1);
00347 spellaction->TTL = LuaToNumber(l, -1);
00348 lua_pop(l, 1);
00349 } else if (!strcmp(value, "require-corpse")) {
00350 spellaction->RequireCorpse = 1;
00351 --j;
00352 } else {
00353 LuaError(l, "Unsupported summon tag: %s" _C_ value);
00354 }
00355 }
00356
00357 if (spellaction->UnitType == NULL) {
00358 LuaError(l, "Use a unittype for summon (with unit-type)");
00359 }
00360 return spellaction;
00361 } else if (!strcmp(value, "spawn-portal")) {
00362 SpawnPortal *spellaction = new SpawnPortal;
00363 for (; j < args; ++j) {
00364 lua_rawgeti(l, -1, j + 1);
00365 value = LuaToString(l, -1);
00366 lua_pop(l, 1);
00367 ++j;
00368 if (!strcmp(value, "portal-type")) {
00369 lua_rawgeti(l, -1, j + 1);
00370 value = LuaToString(l, -1);
00371 lua_pop(l, 1);
00372 spellaction->PortalType = UnitTypeByIdent(value);
00373 if (!spellaction->PortalType) {
00374 spellaction->PortalType = 0;
00375 DebugPrint("unit type \"%s\" not found for spawn-portal.\n" _C_ value);
00376 }
00377 } else {
00378 LuaError(l, "Unsupported spawn-portal tag: %s" _C_ value);
00379 }
00380 }
00381
00382 if (spellaction->PortalType == NULL) {
00383 LuaError(l, "Use a unittype for spawn-portal (with portal-type)");
00384 }
00385 return spellaction;
00386 } else if (!strcmp(value, "capture")) {
00387 Capture *spellaction = new Capture;
00388 for (; j < args; ++j) {
00389 lua_rawgeti(l, -1, j + 1);
00390 value = LuaToString(l, -1);
00391 lua_pop(l, 1);
00392 ++j;
00393 if (!strcmp(value, "sacrifice")) {
00394 spellaction->SacrificeEnable = 1;
00395 } else if (!strcmp(value, "damage")) {
00396 lua_rawgeti(l, -1, j + 1);
00397 spellaction->Damage = LuaToNumber(l, -1);
00398 lua_pop(l, 1);
00399 } else if (!strcmp(value, "percent")) {
00400 lua_rawgeti(l, -1, j + 1);
00401 spellaction->DamagePercent = LuaToNumber(l, -1);
00402 lua_pop(l, 1);
00403 } else {
00404 LuaError(l, "Unsupported Capture tag: %s" _C_ value);
00405 }
00406 }
00407 return spellaction;
00408 } else if (!strcmp(value, "polymorph")) {
00409 Polymorph *spellaction = new Polymorph;
00410 for (; j < args; ++j) {
00411 lua_rawgeti(l, -1, j + 1);
00412 value = LuaToString(l, -1);
00413 lua_pop(l, 1);
00414 ++j;
00415 if (!strcmp(value, "new-form")) {
00416 lua_rawgeti(l, -1, j + 1);
00417 value = LuaToString(l, -1);
00418 lua_pop(l, 1);
00419 spellaction->NewForm = UnitTypeByIdent(value);
00420 if (!spellaction->NewForm) {
00421 spellaction->NewForm= 0;
00422 DebugPrint("unit type \"%s\" not found for polymorph spell.\n" _C_ value);
00423 }
00424
00425 } else if (!strcmp(value, "player-neutral")) {
00426 spellaction->PlayerNeutral = 1;
00427 --j;
00428 } else {
00429 LuaError(l, "Unsupported polymorph tag: %s" _C_ value);
00430 }
00431 }
00432
00433 if (spellaction->NewForm == NULL) {
00434 LuaError(l, "Use a unittype for polymorph (with new-form)");
00435 }
00436 return spellaction;
00437 } else if (!strcmp(value, "adjust-vitals")) {
00438 AdjustVitals *spellaction = new AdjustVitals;
00439 for (; j < args; ++j) {
00440 lua_rawgeti(l, -1, j + 1);
00441 value = LuaToString(l, -1);
00442 lua_pop(l, 1);
00443 ++j;
00444 if (!strcmp(value, "hit-points")) {
00445 lua_rawgeti(l, -1, j + 1);
00446 spellaction->HP = LuaToNumber(l, -1);
00447 lua_pop(l, 1);
00448 } else if (!strcmp(value, "mana-points")) {
00449 lua_rawgeti(l, -1, j + 1);
00450 spellaction->Mana = LuaToNumber(l, -1);
00451 lua_pop(l, 1);
00452 } else if (!strcmp(value, "max-multi-cast")) {
00453 lua_rawgeti(l, -1, j + 1);
00454 spellaction->MaxMultiCast = LuaToNumber(l, -1);
00455 lua_pop(l, 1);
00456 } else {
00457 LuaError(l, "Unsupported adjust-vitals tag: %s" _C_ value);
00458 }
00459 }
00460 return spellaction;
00461 } else {
00462 LuaError(l, "Unsupported action type: %s" _C_ value);
00463 }
00464 return NULL;
00465 }
00466
00477 char Ccl2Condition(lua_State *l, const char *value)
00478 {
00479 if (!strcmp(value, "true")) {
00480 return CONDITION_TRUE;
00481 } else if (!strcmp(value, "false")) {
00482 return CONDITION_FALSE;
00483 } else if (!strcmp(value, "only")) {
00484 return CONDITION_ONLY;
00485 } else {
00486 LuaError(l, "Bad condition result: %s" _C_ value);
00487 return -1;
00488 }
00489 }
00490
00499 static void CclSpellCondition(lua_State *l, ConditionInfo *condition)
00500 {
00501 const char *value;
00502 int i;
00503 int args;
00504 int j;
00505
00506
00507
00508
00509
00510
00511 condition->Variable = new ConditionInfoVariable[UnitTypeVar.NumberVariable];
00512
00513 for (i = 0; i < UnitTypeVar.NumberVariable; i++) {
00514 condition->Variable[i].MinValue = -1;
00515 condition->Variable[i].MaxValue = -1;
00516 condition->Variable[i].MinMax = -1;
00517 condition->Variable[i].MinValuePercent = -8;
00518 condition->Variable[i].MaxValuePercent = 1024;
00519 }
00520
00521 if (!lua_istable(l, -1)) {
00522 LuaError(l, "incorrect argument");
00523 }
00524 args = lua_objlen(l, -1);
00525 for (j = 0; j < args; ++j) {
00526 lua_rawgeti(l, -1, j + 1);
00527 value = LuaToString(l, -1);
00528 lua_pop(l, 1);
00529 ++j;
00530 if (!strcmp(value, "alliance")) {
00531 lua_rawgeti(l, -1, j + 1);
00532 condition->Alliance = Ccl2Condition(l, LuaToString(l, -1));
00533 lua_pop(l, 1);
00534 } else if (!strcmp(value, "opponent")) {
00535 lua_rawgeti(l, -1, j + 1);
00536 condition->Opponent = Ccl2Condition(l, LuaToString(l, -1));
00537 lua_pop(l, 1);
00538 } else if (!strcmp(value, "self")) {
00539 lua_rawgeti(l, -1, j + 1);
00540 condition->TargetSelf = Ccl2Condition(l, LuaToString(l, -1));
00541 lua_pop(l, 1);
00542 } else if (!strcmp(value, "Building")) {
00543 lua_rawgeti(l, -1, j + 1);
00544 condition->Building = Ccl2Condition(l, LuaToString(l, -1));
00545 lua_pop(l, 1);
00546 } else if (!strcmp(value, "Organic")) {
00547 lua_rawgeti(l, -1, j + 1);
00548 condition->Organic = Ccl2Condition(l, LuaToString(l, -1));
00549 lua_pop(l, 1);
00550 } else {
00551 i = GetVariableIndex(value);
00552 if (i != -1) {
00553 lua_rawgeti(l, -1, j + 1);
00554 if (!lua_istable(l, -1)) {
00555 LuaError(l, "Table expected in variable in condition");
00556 }
00557 for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) {
00558 const char *key;
00559
00560 key = LuaToString(l, -2);
00561 if (!strcmp(key, "Enable")) {
00562 condition->Variable[i].Enable = Ccl2Condition(l, LuaToString(l, -1));
00563 } else if (!strcmp(key, "MinValue")) {
00564 condition->Variable[i].MinValue = LuaToNumber(l, -1);
00565 } else if (!strcmp(key, "MaxValue")) {
00566 condition->Variable[i].MaxValue = LuaToNumber(l, -1);
00567 } else if (!strcmp(key, "MinMax")) {
00568 condition->Variable[i].MinMax = LuaToNumber(l, -1);
00569 } else if (!strcmp(key, "MinValuePercent")) {
00570 condition->Variable[i].MinValuePercent = LuaToNumber(l, -1);
00571 } else if (!strcmp(key, "MaxValuePercent")) {
00572 condition->Variable[i].MaxValuePercent = LuaToNumber(l, -1);
00573 } else if (!strcmp(key, "ConditionApplyOnCaster")) {
00574 condition->Variable[i].ConditionApplyOnCaster = LuaToBoolean(l, -1);
00575 } else {
00576 LuaError(l, "%s invalid for Variable in condition" _C_ key);
00577 }
00578 }
00579 lua_pop(l, 1);
00580 continue;
00581 }
00582 LuaError(l, "Unsuported condition tag: %s" _C_ value);
00583 }
00584 }
00585 }
00586
00595 static void CclSpellAutocast(lua_State *l, AutoCastInfo *autocast)
00596 {
00597 const char *value;
00598 int args;
00599 int j;
00600
00601 if (!lua_istable(l, -1)) {
00602 LuaError(l, "incorrect argument");
00603 }
00604 args = lua_objlen(l, -1);
00605 for (j = 0; j < args; ++j) {
00606 lua_rawgeti(l, -1, j + 1);
00607 value = LuaToString(l, -1);
00608 lua_pop(l, 1);
00609 ++j;
00610 if (!strcmp(value, "range")) {
00611 lua_rawgeti(l, -1, j + 1);
00612 autocast->Range = LuaToNumber(l, -1);
00613 lua_pop(l, 1);
00614 } else if (!strcmp(value, "combat")) {
00615 lua_rawgeti(l, -1, j + 1);
00616 autocast->Combat = Ccl2Condition(l, LuaToString(l, -1));
00617 lua_pop(l, 1);
00618 } else if (!strcmp(value, "condition")) {
00619 if (!autocast->Condition) {
00620 autocast->Condition = new ConditionInfo;
00621 }
00622 lua_rawgeti(l, -1, j + 1);
00623 CclSpellCondition(l, autocast->Condition);
00624 lua_pop(l, 1);
00625 } else {
00626 LuaError(l, "Unsupported autocast tag: %s" _C_ value);
00627 }
00628 }
00629 }
00630
00636 static int CclDefineSpell(lua_State *l)
00637 {
00638 std::string identname;
00639 SpellType *spell;
00640 const char *value;
00641 int args;
00642 int i;
00643
00644 args = lua_gettop(l);
00645 identname = LuaToString(l, 1);
00646 spell = SpellTypeByIdent(identname);
00647 if (spell != NULL) {
00648 DebugPrint("Redefining spell-type `%s'\n" _C_ identname.c_str());
00649 } else {
00650 spell = new SpellType(SpellTypeTable.size(), identname);
00651 for (size_t i = 0; i < UnitTypes.size(); ++i) {
00652 if (UnitTypes[i]->CanCastSpell) {
00653 char *newc = new char[(SpellTypeTable.size() + 1) * sizeof(char)];
00654 memcpy(newc, UnitTypes[i]->CanCastSpell, SpellTypeTable.size() * sizeof(char));
00655 delete[] UnitTypes[i]->CanCastSpell;
00656 UnitTypes[i]->CanCastSpell = newc;
00657 UnitTypes[i]->CanCastSpell[SpellTypeTable.size()] = 0;
00658 }
00659 if (UnitTypes[i]->AutoCastActive) {
00660 char *newc = new char[(SpellTypeTable.size() + 1) * sizeof(char)];
00661 memcpy(newc, UnitTypes[i]->AutoCastActive, SpellTypeTable.size() * sizeof(char));
00662 delete[] UnitTypes[i]->AutoCastActive;
00663 UnitTypes[i]->AutoCastActive = newc;
00664 UnitTypes[i]->AutoCastActive[SpellTypeTable.size()] = 0;
00665 }
00666 }
00667 SpellTypeTable.push_back(spell);
00668 }
00669 for (i = 1; i < args; ++i) {
00670 value = LuaToString(l, i + 1);
00671 ++i;
00672 if (!strcmp(value, "showname")) {
00673 spell->Name = LuaToString(l, i + 1);
00674 } else if (!strcmp(value, "manacost")) {
00675 spell->ManaCost = LuaToNumber(l, i + 1);
00676 } else if (!strcmp(value, "range")) {
00677 if (!lua_isstring(l, i + 1) && !lua_isnumber(l, i + 1)) {
00678 LuaError(l, "incorrect argument");
00679 }
00680 if (lua_isstring(l, i + 1) && !strcmp(lua_tostring(l, i + 1), "infinite")) {
00681 spell->Range = INFINITE_RANGE;
00682 } else if (lua_isnumber(l, i + 1)) {
00683 spell->Range = static_cast<int>(lua_tonumber(l, i + 1));
00684 } else {
00685 LuaError(l, "Invalid range");
00686 }
00687 } else if (!strcmp(value, "repeat-cast")) {
00688 spell->RepeatCast = 1;
00689 --i;
00690 } else if (!strcmp(value, "target")) {
00691 value = LuaToString(l, i + 1);
00692 if (!strcmp(value, "self")) {
00693 spell->Target = TargetSelf;
00694 } else if (!strcmp(value, "unit")) {
00695 spell->Target = TargetUnit;
00696 } else if (!strcmp(value, "position")) {
00697 spell->Target = TargetPosition;
00698 } else {
00699 LuaError(l, "Unsupported spell target type tag: %s" _C_ value);
00700 }
00701 } else if (!strcmp(value, "action")) {
00702 int subargs;
00703 int k;
00704
00705 if (!lua_istable(l, i + 1)) {
00706 LuaError(l, "incorrect argument");
00707 }
00708 subargs = lua_objlen(l, i + 1);
00709 for (k = 0; k < subargs; ++k) {
00710 lua_rawgeti(l, i + 1, k + 1);
00711 spell->Action.push_back(CclSpellAction(l));
00712 lua_pop(l, 1);
00713 }
00714 } else if (!strcmp(value, "condition")) {
00715 if (!spell->Condition) {
00716 spell->Condition = new ConditionInfo;
00717 }
00718 lua_pushvalue(l, i + 1);
00719 CclSpellCondition(l, spell->Condition);
00720 lua_pop(l, 1);
00721 } else if (!strcmp(value, "autocast")) {
00722 if (!spell->AutoCast) {
00723 spell->AutoCast = new AutoCastInfo();
00724 }
00725 lua_pushvalue(l, i + 1);
00726 CclSpellAutocast(l, spell->AutoCast);
00727 lua_pop(l, 1);
00728 } else if (!strcmp(value, "ai-cast")) {
00729 if (!spell->AICast) {
00730 spell->AICast = new AutoCastInfo();
00731 }
00732 lua_pushvalue(l, i + 1);
00733 CclSpellAutocast(l, spell->AICast);
00734 lua_pop(l, 1);
00735 } else if (!strcmp(value, "sound-when-cast")) {
00736
00737 spell->SoundWhenCast.Name = LuaToString(l, i + 1);
00738 spell->SoundWhenCast.Sound = SoundForName(spell->SoundWhenCast.Name);
00739
00740 if (!spell->SoundWhenCast.Sound) {
00741 spell->SoundWhenCast.Name.clear();
00742 }
00743 } else {
00744 LuaError(l, "Unsupported tag: %s" _C_ value);
00745 }
00746 }
00747 return 0;
00748 }
00749
00753 void SpellCclRegister(void)
00754 {
00755 lua_register(Lua, "DefineSpell", CclDefineSpell);
00756 }
00757