/** ** Get a player's units in rectangle box specified with 2 coordinates ** ** @param l Lua state. ** ** @return Array of units. */ static int CclGetUnitsAroundUnit(lua_State *l) { const int nargs = lua_gettop(l); if (nargs != 2 && nargs != 3) { LuaError(l, "incorrect argument\n"); } const int slot = LuaToNumber(l, 1); const CUnit &unit = UnitManager.GetSlotUnit(slot); const int range = LuaToNumber(l, 2); bool allUnits = false; if (nargs == 3) { allUnits = LuaToBoolean(l, 3); } lua_newtable(l); std::vector<CUnit *> table; if (allUnits) { SelectAroundUnit(unit, range, table, HasNotSamePlayerAs(Players[PlayerNumNeutral])); } else { SelectAroundUnit(unit, range, table, HasSamePlayerAs(*unit.Player)); } size_t n = 0; for (size_t i = 0; i < table.size(); ++i) { if (table[i]->IsAliveOnMap()) { lua_pushnumber(l, UnitNumber(*table[i])); lua_rawseti(l, -2, ++n); } } return 1; }
/** ** Change unit owner ** ** @param l Lua state. */ static int CclChangeUnitsOwner(lua_State *l) { LuaCheckArgs(l, 4); Vec2i pos1; Vec2i pos2; CclGetPos(l, &pos1.x, &pos1.y, 1); CclGetPos(l, &pos2.x, &pos2.y, 2); const int oldp = LuaToNumber(l, 3); const int newp = LuaToNumber(l, 4); std::vector<CUnit *> table; Select(pos1, pos2, table, HasSamePlayerAs(Players[oldp])); for (size_t i = 0; i != table.size(); ++i) { table[i]->ChangeOwner(Players[newp]); } return 0; }
/** ** Cast capture. ** ** @param caster Unit that casts the spell ** @param spell Spell-type pointer ** @param target Target unit that spell is addressed to ** @param goalPos coord of target spot when/if target does not exist ** ** @return =!0 if spell should be repeated, 0 if not */ /* virtual */ int Spell_Capture::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &/*goalPos*/) { if (!target || caster.Player == target->Player) { return 0; } if (this->DamagePercent) { if ((100 * target->Variable[HP_INDEX].Value) / target->Variable[HP_INDEX].Max > this->DamagePercent && target->Variable[HP_INDEX].Value > this->Damage) { HitUnit(&caster, *target, this->Damage); if (this->SacrificeEnable) { // No corpse. caster.Remove(NULL); caster.Release(); } return 1; } } caster.Player->Score += target->Variable[POINTS_INDEX].Value; if (caster.IsEnemy(*target)) { if (target->Type->Building) { caster.Player->TotalRazings++; } else { caster.Player->TotalKills++; } //Wyrmgus start caster.Player->UnitTypeKills[target->Type->Slot]++; /* if (UseHPForXp) { caster.Variable[XP_INDEX].Max += target->Variable[HP_INDEX].Value; } else { caster.Variable[XP_INDEX].Max += target->Variable[POINTS_INDEX].Value; } caster.Variable[XP_INDEX].Value = caster.Variable[XP_INDEX].Max; */ //distribute experience between nearby units belonging to the same player if (!target->Type->BoolFlag[BUILDING_INDEX].value) { std::vector<CUnit *> table; SelectAroundUnit(caster, 6, table, MakeAndPredicate(HasSamePlayerAs(*caster.Player), IsNotBuildingType())); if (UseHPForXp) { caster.Variable[XP_INDEX].Max += target->Variable[HP_INDEX].Value / (table.size() + 1); } else { caster.Variable[XP_INDEX].Max += target->Variable[POINTS_INDEX].Value / (table.size() + 1); } caster.Variable[XP_INDEX].Value = caster.Variable[XP_INDEX].Max; caster.XPChanged(); for (size_t i = 0; i != table.size(); ++i) { if (UseHPForXp) { table[i]->Variable[XP_INDEX].Max += target->Variable[HP_INDEX].Value / (table.size() + 1); } else { table[i]->Variable[XP_INDEX].Max += target->Variable[POINTS_INDEX].Value / (table.size() + 1); } table[i]->Variable[XP_INDEX].Value = table[i]->Variable[XP_INDEX].Max; table[i]->XPChanged(); } } //Wyrmgus end caster.Variable[KILL_INDEX].Value++; caster.Variable[KILL_INDEX].Max++; caster.Variable[KILL_INDEX].Enable = 1; } target->ChangeOwner(*caster.Player); UnitClearOrders(*target); if (this->JoinToAIForce && caster.Player->AiEnabled) { int force = caster.Player->Ai->Force.GetForce(caster); if (force != -1) { caster.Player->Ai->Force[force].Insert(*target); target->GroupId = caster.GroupId; CommandDefend(*target, caster, FlushCommands); } } if (this->SacrificeEnable) { // No corpse. caster.Remove(NULL); caster.Release(); } else { caster.Variable[MANA_INDEX].Value -= spell.ManaCost; } return 0; }