/* virtual */ void CAnimation_Die::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); if (unit.Anim.Unbreakable) { fprintf(stderr, "Can't call \"die\" action in unbreakable section\n"); Exit(1); } if (this->DeathType.empty() == false) { unit.DamagedType = ExtraDeathIndex(this->DeathType.c_str()); } throw AnimationDie_Exception(); }
/** ** Define a unit-type animation set. ** ** @param l Lua state. */ static int CclDefineAnimations(lua_State *l) { LuaCheckArgs(l, 2); if (!lua_istable(l, 2)) { LuaError(l, "incorrect argument"); } const char *name = LuaToString(l, 1); CAnimations *anims = AnimationsByIdent(name); if (!anims) { anims = new CAnimations; AnimationMap[name] = anims; } lua_pushnil(l); while (lua_next(l, 2)) { const char *value = LuaToString(l, -2); if (!strcmp(value, "Start")) { anims->Start = ParseAnimation(l, -1); } else if (!strncmp(value, "Still", 5)) { anims->Still = ParseAnimation(l, -1); } else if (!strncmp(value, "Death", 5)) { if (strlen(value) > 5) { const int death = ExtraDeathIndex(value + 6); if (death == ANIMATIONS_DEATHTYPES) { anims->Death[ANIMATIONS_DEATHTYPES] = ParseAnimation(l, -1); } else { anims->Death[death] = ParseAnimation(l, -1); } } else { anims->Death[ANIMATIONS_DEATHTYPES] = ParseAnimation(l, -1); } } else if (!strcmp(value, "Attack")) { anims->Attack = ParseAnimation(l, -1); } else if (!strcmp(value, "SpellCast")) { anims->SpellCast = ParseAnimation(l, -1); } else if (!strcmp(value, "Move")) { anims->Move = ParseAnimation(l, -1); } else if (!strcmp(value, "Repair")) { anims->Repair = ParseAnimation(l, -1); } else if (!strcmp(value, "Train")) { anims->Train = ParseAnimation(l, -1); } else if (!strcmp(value, "Research")) { anims->Research = ParseAnimation(l, -1); } else if (!strcmp(value, "Upgrade")) { anims->Upgrade = ParseAnimation(l, -1); } else if (!strcmp(value, "Build")) { anims->Build = ParseAnimation(l, -1); } else if (!strncmp(value, "Harvest_", 8)) { const int res = GetResourceIdByName(l, value + 8); anims->Harvest[res] = ParseAnimation(l, -1); } else { LuaError(l, "Unsupported animation: %s" _C_ value); } lua_pop(l, 1); } // Must add to array in a fixed order for save games AddAnimationToArray(anims->Start); AddAnimationToArray(anims->Still); for (int i = 0; i != ANIMATIONS_DEATHTYPES + 1; ++i) { AddAnimationToArray(anims->Death[i]); } AddAnimationToArray(anims->Attack); AddAnimationToArray(anims->SpellCast); AddAnimationToArray(anims->Move); AddAnimationToArray(anims->Repair); AddAnimationToArray(anims->Train); for (int i = 0; i != MaxCosts; ++i) { AddAnimationToArray(anims->Harvest[i]); } return 0; }
/* virtual */ void CAnimation_SetVar::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); char arg1[128]; CUnit *goal = &unit; strcpy(arg1, this->varStr.c_str()); if (this->unitSlotStr.empty() == false) { switch (this->unitSlotStr[0]) { case 'l': // last created unit goal = UnitManager.lastCreatedUnit(); break; case 't': // target unit goal = unit.CurrentOrder()->GetGoal(); break; case 's': // unit self (no use) goal = &unit; break; } } if (!goal) { return; } char *next = strchr(arg1, '.'); if (next == NULL) { // Special case for non-CVariable variables if (!strcmp(arg1, "DamageType")) { int death = ExtraDeathIndex(this->valueStr.c_str()); if (death == ANIMATIONS_DEATHTYPES) { fprintf(stderr, "Incorrect death type : %s \n" _C_ this->valueStr.c_str()); Exit(1); return; } goal->Type->DamageType = this->valueStr; return; } fprintf(stderr, "Need also specify the variable '%s' tag \n" _C_ arg1); Exit(1); return; } else { *next = '\0'; } const int index = UnitTypeVar.VariableNameLookup[arg1];// User variables if (index == -1) { fprintf(stderr, "Bad variable name '%s'\n" _C_ arg1); Exit(1); return; } const int rop = ParseAnimInt(unit, this->valueStr.c_str()); int value = 0; if (!strcmp(next + 1, "Value")) { value = goal->Variable[index].Value; } else if (!strcmp(next + 1, "Max")) { value = goal->Variable[index].Max; } else if (!strcmp(next + 1, "Increase")) { value = goal->Variable[index].Increase; } else if (!strcmp(next + 1, "Enable")) { value = goal->Variable[index].Enable; } else if (!strcmp(next + 1, "Percent")) { value = goal->Variable[index].Value * 100 / goal->Variable[index].Max; } switch (this->mod) { case modAdd: value += rop; break; case modSub: value -= rop; break; case modMul: value *= rop; break; case modDiv: if (!rop) { fprintf(stderr, "Division by zero in AnimationSetVar\n"); Exit(1); return; } value /= rop; break; case modMod: if (!rop) { fprintf(stderr, "Division by zero in AnimationSetVar\n"); Exit(1); return; } value %= rop; break; case modAnd: value &= rop; break; case modOr: value |= rop; break; case modXor: value ^= rop; break; case modNot: value = !value; break; default: value = rop; } if (!strcmp(next + 1, "Value")) { goal->Variable[index].Value = value; } else if (!strcmp(next + 1, "Max")) { goal->Variable[index].Max = value; } else if (!strcmp(next + 1, "Increase")) { goal->Variable[index].Increase = value; } else if (!strcmp(next + 1, "Enable")) { goal->Variable[index].Enable = value; } else if (!strcmp(next + 1, "Percent")) { goal->Variable[index].Value = goal->Variable[index].Max * value / 100; } clamp(&goal->Variable[index].Value, 0, goal->Variable[index].Max); //Wyrmgus start if (index == ATTACKRANGE_INDEX && goal->Container) { goal->Container->UpdateContainerAttackRange(); } else if (index == LEVEL_INDEX || index == POINTS_INDEX) { goal->UpdateXPRequired(); } else if (index == XP_INDEX) { goal->XPChanged(); } else if (index == STUN_INDEX && goal->Variable[index].Value > 0) { //if unit has become stunned, stop it CommandStopUnit(*goal); } //Wyrmgus end }