int CLuaUnitScript::CreateScript(lua_State* L) { CUnit* unit = ParseUnit(L, __FUNCTION__, 1); if (unit == NULL) { LUA_TRACE("no such unit"); return 0; } // check table of callIns // (we might not get a chance to clean up later on, if something is wrong) if (!lua_istable(L, 2)) { luaL_error(L, "%s(): error parsing callIn table", __FUNCTION__); } for (lua_pushnil(L); lua_next(L, 2) != 0; lua_pop(L, 1)) { if (!lua_israwstring(L, -2) || !lua_isfunction(L, -1)) { luaL_error(L, "%s(): error parsing callIn table", __FUNCTION__); } } // replace the unit's script (ctor parses callIn table) CLuaUnitScript* newScript = new CLuaUnitScript(L, unit); if (unit->script != &CNullUnitScript::value) { delete unit->script; } unit->script = newScript; // flush some caches (which store availability of certain script functions) for (std::vector<CWeapon*>::iterator wi = unit->weapons.begin(); wi != unit->weapons.end(); ++wi) { CWeapon* w = *wi; w->SetWeaponNum(w->weaponNum); } LUA_TRACE("script replaced with CLuaUnitScript"); return 0; }
CWeapon* CUnitLoader::LoadWeapon(const WeaponDef *weapondef, CUnit* owner, const UnitDef::UnitDefWeapon* udw) { CWeapon* weapon; if (!weapondef) { logOutput.Print("Error: No weapon def?"); } if (udw->name == "NOWEAPON") { weapon = new CNoWeapon(owner); } else if (weapondef->type == "Cannon") { weapon = new CCannon(owner); ((CCannon*)weapon)->selfExplode = weapondef->selfExplode; } else if (weapondef->type == "Rifle") { weapon = new CRifle(owner); } else if (weapondef->type == "Melee") { weapon = new CMeleeWeapon(owner); } else if (weapondef->type == "AircraftBomb") { weapon = new CBombDropper(owner, false); } else if (weapondef->type == "Shield") { weapon = new CPlasmaRepulser(owner); } else if (weapondef->type == "Flame") { weapon = new CFlameThrower(owner); } else if (weapondef->type == "MissileLauncher") { weapon = new CMissileLauncher(owner); } else if (weapondef->type == "TorpedoLauncher") { if (owner->unitDef->canfly && !weapondef->submissile) { weapon = new CBombDropper(owner, true); if (weapondef->tracks) ((CBombDropper*) weapon)->tracking = weapondef->turnrate; ((CBombDropper*) weapon)->bombMoveRange = weapondef->range; } else { weapon = new CTorpedoLauncher(owner); if (weapondef->tracks) ((CTorpedoLauncher*) weapon)->tracking = weapondef->turnrate; } } else if (weapondef->type == "LaserCannon") { weapon = new CLaserCannon(owner); ((CLaserCannon*) weapon)->color = weapondef->visuals.color; } else if (weapondef->type == "BeamLaser") { weapon = new CBeamLaser(owner); ((CBeamLaser*) weapon)->color = weapondef->visuals.color; } else if (weapondef->type == "LightningCannon") { weapon = new CLightningCannon(owner); ((CLightningCannon*) weapon)->color = weapondef->visuals.color; } else if (weapondef->type == "EmgCannon") { weapon = new CEmgCannon(owner); } else if (weapondef->type == "DGun") { weapon = new CDGunWeapon(owner); } else if (weapondef->type == "StarburstLauncher"){ weapon = new CStarburstLauncher(owner); if (weapondef->tracks) ((CStarburstLauncher*) weapon)->tracking = weapondef->turnrate; else ((CStarburstLauncher*) weapon)->tracking = 0; ((CStarburstLauncher*) weapon)->uptime = weapondef->uptime * GAME_SPEED; } else { LogObject() << "Unknown weapon type " << weapondef->type.c_str() << "\n"; return 0; } weapon->weaponDef = weapondef; weapon->reloadTime = (int) (weapondef->reload * GAME_SPEED); if (weapon->reloadTime == 0) weapon->reloadTime = 1; weapon->range = weapondef->range; // weapon->baseRange = weapondef->range; weapon->heightMod = weapondef->heightmod; weapon->projectileSpeed = weapondef->projectilespeed; // weapon->baseProjectileSpeed = weapondef->projectilespeed / GAME_SPEED; weapon->areaOfEffect = weapondef->areaOfEffect; weapon->accuracy = weapondef->accuracy; weapon->sprayAngle = weapondef->sprayAngle; weapon->stockpileTime = (int) (weapondef->stockpileTime * GAME_SPEED); weapon->salvoSize = weapondef->salvosize; weapon->salvoDelay = (int) (weapondef->salvodelay * GAME_SPEED); weapon->projectilesPerShot = weapondef->projectilespershot; weapon->metalFireCost = weapondef->metalcost; weapon->energyFireCost = weapondef->energycost; weapon->fireSoundId = weapondef->firesound.getID(0); weapon->fireSoundVolume = weapondef->firesound.getVolume(0); weapon->onlyForward = weapondef->onlyForward; if (owner->unitDef->type == "Fighter" && !owner->unitDef->hoverAttack) { // fighter aircraft have too big tolerance in TA weapon->maxAngleDif = cos(weapondef->maxAngle * 0.4f / 180 * PI); } else { weapon->maxAngleDif = cos(weapondef->maxAngle / 180 * PI); } weapon->SetWeaponNum(owner->weapons.size()); weapon->badTargetCategory = udw->badTargetCat; weapon->onlyTargetCategory = weapondef->onlyTargetCategory & udw->onlyTargetCat; if (udw->slavedTo) { const int index = (udw->slavedTo - 1); if ((index < 0) || (static_cast<size_t>(index) >= owner->weapons.size())) { throw content_error("Bad weapon slave in " + owner->unitDef->name); } weapon->slavedTo = owner->weapons[index]; } weapon->mainDir = udw->mainDir; weapon->maxMainDirAngleDif = udw->maxAngleDif; weapon->fuelUsage = udw->fuelUsage; weapon->avoidFriendly = weapondef->avoidFriendly; weapon->avoidFeature = weapondef->avoidFeature; weapon->avoidNeutral = weapondef->avoidNeutral; weapon->targetBorder = weapondef->targetBorder; weapon->cylinderTargetting = weapondef->cylinderTargetting; weapon->minIntensity = weapondef->minIntensity; weapon->heightBoostFactor = weapondef->heightBoostFactor; weapon->collisionFlags = weapondef->collisionFlags; weapon->Init(); return weapon; }