/* virtual */ void CAnimation_SetPlayerVar::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); const char *var = this->varStr.c_str(); const char *arg = this->argStr.c_str(); const int playerId = ParseAnimInt(unit, this->playerStr.c_str()); int rop = ParseAnimInt(unit, this->valueStr.c_str()); int data = GetPlayerData(playerId, var, arg); switch (this->mod) { case modAdd: data += rop; break; case modSub: data -= rop; break; case modMul: data *= rop; break; case modDiv: if (!rop) { fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n"); Exit(1); } data /= rop; break; case modMod: if (!rop) { fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n"); Exit(1); } data %= rop; break; case modAnd: data &= rop; break; case modOr: data |= rop; break; case modXor: data ^= rop; break; case modNot: data = !data; break; default: data = rop; } rop = data; SetPlayerData(playerId, var, arg, rop); }
static int ParseAnimPlayer(const CUnit &unit, char *parseint) { if (!strcmp(parseint, "this")) { return unit.Player->Index; } return ParseAnimInt(unit, parseint); }
/* virtual */ void CAnimation_RandomGoto::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); if (SyncRand() % 100 < ParseAnimInt(unit, this->randomStr.c_str())) { unit.Anim.Anim = this->gotoLabel; } }
/* virtual */ void CAnimation_Frame::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); if (unit.Type->Building && unit.Type->NumDirections == 1 && FancyBuildings && unit.Type->NoRandomPlacing == false && unit.Frame < 0) { } else { unit.Frame = ParseAnimInt(&unit); } UnitUpdateHeading(unit); }
/* virtual */ void CAnimation_SetPlayerVar::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); const char *var = this->varStr.c_str(); const char *arg = this->argStr.c_str(); const int playerId = ParseAnimInt(&unit, this->playerStr.c_str()); int rop = ParseAnimInt(&unit, this->valueStr.c_str()); int data = GetPlayerData(playerId, var, arg); switch (this->mod) { case MOD_ADD: data += rop; break; case MOD_SUB: data -= rop; break; case MOD_MUL: data *= rop; break; case MOD_DIV: if (!rop) { fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n"); Exit(1); } data /= rop; break; case MOD_MOD: if (!rop) { fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n"); Exit(1); } data %= rop; break; default: data = rop; } rop = data; SetPlayerData(playerId, var, arg, rop); }
/* virtual */ void CAnimation_SpawnUnit::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); const int offX = ParseAnimInt(unit, this->offXStr.c_str()); const int offY = ParseAnimInt(unit, this->offYStr.c_str()); const int range = ParseAnimInt(unit, this->rangeStr.c_str()); const int playerId = ParseAnimInt(unit, this->playerStr.c_str()); const SpawnUnit_Flags flags = (SpawnUnit_Flags)(ParseAnimFlags(unit, this->flagsStr.c_str())); CPlayer &player = Players[playerId]; const Vec2i pos(unit.tilePos.x + offX, unit.tilePos.y + offY); CUnitType *type = UnitTypeByIdent(this->unitTypeStr.c_str()); Assert(type); Vec2i resPos; DebugPrint("Creating a %s\n" _C_ type->Name.c_str()); FindNearestDrop(*type, pos, resPos, LookingW); if (SquareDistance(pos, resPos) <= square(range)) { CUnit *target = MakeUnit(*type, &player); if (target != NULL) { target->tilePos = resPos; target->Place(resPos); if (flags & SU_Summoned) { target->Summoned = 1; } if ((flags & SU_JoinToAIForce) && unit.Player->AiEnabled) { int force = unit.Player->Ai->Force.GetForce(unit); if (force != -1) { unit.Player->Ai->Force[force].Insert(*target); target->GroupId = unit.GroupId; CommandDefend(*target, unit, FlushCommands); } } //DropOutOnSide(*target, LookingW, NULL); } else { DebugPrint("Unable to allocate Unit"); } } }
/* virtual */ void CAnimation_LuaCallback::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); Assert(cb); cb->pushPreamble(); for (std::vector<std::string>::const_iterator it = cbArgs.begin(); it != cbArgs.end(); ++it) { const std::string str = *it; const int arg = ParseAnimInt(unit, str.c_str()); cb->pushInteger(arg); } cb->run(); }
/* virtual */ void CAnimation_Rotate::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); if (!strcmp(this->rotateStr.c_str(), "target") && unit.CurrentOrder()->HasGoal()) { COrder &order = *unit.CurrentOrder(); const CUnit &target = *order.GetGoal(); if (target.Destroyed) { order.ClearGoal(); return; } const Vec2i pos = target.tilePos + target.Type->GetHalfTileSize() - unit.tilePos; UnitHeadingFromDeltaXY(unit, pos); } else { UnitRotate(unit, ParseAnimInt(unit, this->rotateStr.c_str())); } }
/* 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 }
/* virtual */ void CAnimation_SpawnMissile::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); const int startx = ParseAnimInt(&unit, this->startXStr.c_str()); const int starty = ParseAnimInt(&unit, this->startYStr.c_str()); const int destx = ParseAnimInt(&unit, this->destXStr.c_str()); const int desty = ParseAnimInt(&unit, this->destYStr.c_str()); const int flags = ParseAnimFlags(unit, this->flagsStr.c_str()); const int offsetnum = ParseAnimInt(&unit, this->offsetNumStr.c_str()); const CUnit *goal = flags & ANIM_SM_RELTARGET ? unit.CurrentOrder()->GetGoal() : &unit; const int dir = ((goal->Direction + NextDirection / 2) & 0xFF) / NextDirection; const PixelPos moff = goal->Type->MissileOffsets[dir][!offsetnum ? 0 : offsetnum - 1]; PixelPos start; PixelPos dest; MissileType *mtype = MissileTypeByIdent(this->missileTypeStr); if (mtype == NULL) { return; } if (!goal || goal->Destroyed) { return; } if ((flags & ANIM_SM_PIXEL)) { start.x = goal->tilePos.x * PixelTileSize.x + goal->IX + moff.x + startx; start.y = goal->tilePos.y * PixelTileSize.y + goal->IY + moff.y + starty; } else { start.x = (goal->tilePos.x + startx) * PixelTileSize.x + PixelTileSize.x / 2 + moff.x; start.y = (goal->tilePos.y + starty) * PixelTileSize.y + PixelTileSize.y / 2 + moff.y; } if ((flags & ANIM_SM_TOTARGET)) { CUnit *target = goal->CurrentOrder()->GetGoal(); if (!target || target->Destroyed) { Assert(!mtype->AlwaysFire || mtype->Range); if (!target && mtype->AlwaysFire == false) { return; } } if (!target) { if (goal->CurrentAction() == UnitActionAttack || goal->CurrentAction() == UnitActionAttackGround) { COrder_Attack &order = *static_cast<COrder_Attack *>(goal->CurrentOrder()); dest = Map.TilePosToMapPixelPos_Center(order.GetGoalPos()); } else if (goal->CurrentAction() == UnitActionSpellCast) { COrder_SpellCast &order = *static_cast<COrder_SpellCast *>(goal->CurrentOrder()); dest = Map.TilePosToMapPixelPos_Center(order.GetGoalPos()); } if (flags & ANIM_SM_PIXEL) { dest.x += destx; dest.y += desty; } else { dest.x += destx * PixelTileSize.x; dest.y += desty * PixelTileSize.y; } } else if (flags & ANIM_SM_PIXEL) { dest.x = target->GetMapPixelPosCenter().x + destx; dest.y = target->GetMapPixelPosCenter().y + desty; } else { dest.x = (target->tilePos.x + destx) * PixelTileSize.x; dest.y = (target->tilePos.y + desty) * PixelTileSize.y; dest += target->Type->GetPixelSize() / 2; } } else { if ((flags & ANIM_SM_PIXEL)) { dest.x = goal->GetMapPixelPosCenter().x + destx; dest.y = goal->GetMapPixelPosCenter().y + desty; } else { dest.x = (goal->tilePos.x + destx) * PixelTileSize.x; dest.y = (goal->tilePos.y + desty) * PixelTileSize.y; dest += goal->Type->GetPixelSize() / 2; } } Vec2i destTilePos = Map.MapPixelPosToTilePos(dest); const int dist = goal->MapDistanceTo(destTilePos); if ((flags & ANIM_SM_RANGED) && !(flags & ANIM_SM_PIXEL) && dist > goal->Stats->Variables[ATTACKRANGE_INDEX].Max && dist < goal->Type->MinAttackRange) { } else { Missile *missile = MakeMissile(*mtype, start, dest); if (flags & ANIM_SM_SETDIRECTION) { PixelPos posd; posd.x = Heading2X[goal->Direction / NextDirection]; posd.y = Heading2Y[goal->Direction / NextDirection]; missile->MissileNewHeadingFromXY(posd); } if (flags & ANIM_SM_DAMAGE) { missile->SourceUnit = &unit; } if (flags & ANIM_SM_TOTARGET) { missile->TargetUnit = goal->CurrentOrder()->GetGoal(); } } }
/* virtual */ void CAnimation_Frame::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); unit.Frame = ParseAnimInt(&unit); UnitUpdateHeading(unit); }