예제 #1
0
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;
}
예제 #2
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;
}