Exemplo n.º 1
0
int valid_ammo_mode(MECH * mech, int loc, int part, int let)
{
	int w, i;

	if(!IsAmmo(GetPartType(mech, loc, part)) || !let)
		return -1;
	let = toupper(let);
	w = Ammo2I(GetPartType(mech, loc, part));

	if(MechWeapons[w].special & NOSPA)
		return -1;

	for(i = 0; ammo_types[i].name; i++) {
		if(ammo_types[i].name != let)
			continue;
		if(ammo_types[i].rtype >= 0 &&
		   MechWeapons[w].type != ammo_types[i].rtype)
			continue;
		if(ammo_types[i].rspec &&
		   !(MechWeapons[w].special & ammo_types[i].rspec))
			continue;
		if(ammo_types[i].ntype >= 0 &&
		   MechWeapons[w].type == ammo_types[i].ntype)
			continue;
		if(ammo_types[i].nspec &&
		   (MechWeapons[w].special & ammo_types[i].nspec))
			continue;
		return ammo_types[i].aflag;
	}
	return -1;
}
Exemplo n.º 2
0
void Ship::Resupply() {
    Meter* fuel_meter = UniverseObject::GetMeter(METER_FUEL);
    const Meter* max_fuel_meter = UniverseObject::GetMeter(METER_MAX_FUEL);
    if (!fuel_meter || !max_fuel_meter) {
        Logger().errorStream() << "Ship::Resupply couldn't get fuel meters!";
        return;
    }

    fuel_meter->SetCurrent(max_fuel_meter->Current());

    for (ConsumablesMap::iterator it = m_fighters.begin();
         it != m_fighters.end(); ++it)
    {
        const PartType* part_type = GetPartType(it->first);
        if (part_type)
            it->second.second = it->second.first *
                boost::get<FighterStats>(part_type->Stats()).m_capacity;
    }

    for (ConsumablesMap::iterator it = m_missiles.begin();
         it != m_missiles.end(); ++it)
    {
        const PartType* part_type = GetPartType(it->first);
        if (part_type)
            it->second.second = it->second.first *
                boost::get<LRStats>(part_type->Stats()).m_capacity;
    }
}
Exemplo n.º 3
0
std::vector<float> Ship::AllWeaponsDamage() const {
    std::vector<float> retval;

    const ShipDesign* design = GetShipDesign(m_design_id);
    if (!design)
        return retval;
    const std::vector<std::string>& parts = design->Parts();

    // for each weapon part, get its damage meter value
    for (std::vector<std::string>::const_iterator part_it = parts.begin();
         part_it != parts.end(); ++part_it)
    {
        const std::string& part_name = *part_it;
        const PartType* part = GetPartType(part_name);
        if (!part)
            continue;
        ShipPartClass part_class = part->Class();

        // get the attack power for each weapon part
        float part_attack = 0.0;

        if (part_class == PC_SHORT_RANGE || part_class == PC_POINT_DEFENSE || part_class == PC_MISSILES)
            part_attack = this->CurrentPartMeterValue(METER_DAMAGE, part_name);
        else if (part_class == PC_FIGHTERS)
            part_attack = this->CurrentPartMeterValue(METER_ANTI_SHIP_DAMAGE, part_name);

        if (part_attack > 0.0)
            retval.push_back(part_attack);
    }
    return retval;
}
Exemplo n.º 4
0
void CheckWeaponFailed(MECH * mech, int weapnum, int weaptype, int section,
					   int critical, int *modifier, int *type)
{
	short roll;
	int l = GetPartBrand(mech, section, critical);
	int t = GetPartType(mech, section, critical);
	int i = GetBrandIndex(t), in;

	*type = FAIL_NONE;
	if(i < 0)
		return;
	if(mudconf.btech_parts) {
		if(!l)
			l = 5;
		if(MechWeapons[Weapon2I(t)].special & PCOMBAT)
			return;
	} else
		return;
	if(Number(1, 10) < 9)
		return;
	if(Number(1, 100) <= brands[(i + l - 1) * 5 / 6].success)
		return;
	roll = Number(1, 6);
	if(roll == 6)
		roll = Number(1, 6);
	in = i + roll - 1;
	if(failures[in].flag & REQ_HEAT)
		if(!MechWeapons[weaptype].heat)
			return;
	if(failures[in].message && strcmp(failures[in].message, "none"))
		mech_notify(mech, MECHALL, failures[in].message);
	failures[in].func(mech, weapnum, weaptype, section, critical, roll,
					  modifier, type);
}
Exemplo n.º 5
0
float Ship::TroopCapacity() const {
    float retval = 0.0f;
    // find which troop parts are present in design (one copy of name for each instance of a part, allowing duplicate names to appear)
    const ShipDesign* design = Design();
    if (!design)
        return retval;

    const std::vector<std::string>& parts = design->Parts();
    for (std::vector<std::string>::const_iterator part_it = parts.begin();
         part_it != parts.end(); ++part_it)
    {
        const std::string& part_name = *part_it;
        if (part_name.empty())
            continue;
        const PartType* part_type = GetPartType(part_name);
        if (!part_type)
            continue;
        ShipPartClass part_class = part_type->Class();
        if (part_class != PC_TROOPS)
            continue;
        // add capacity for all instances of colony parts to accumulator
        retval += this->CurrentPartMeterValue(METER_CAPACITY, part_name);
    }

    return retval;
}
Exemplo n.º 6
0
void Ship::AddFighters(const std::string& part_name, std::size_t n) {
    const PartType* part_type = GetPartType(part_name);
    if (!part_type) return;
    assert(m_fighters[part_name].second + n <=
           m_fighters[part_name].first *
           boost::get<FighterStats>(part_type->Stats()).m_capacity);
    m_fighters[part_name].second += n;
}
Exemplo n.º 7
0
int Find_DS_Bay_Number(MECH * ds, int dir)
{
	int bayn = 0;
	int i, j;

	for(i = 0; i <= dir; i++) {
		for(j = 0; j < NUM_CRITICALS; j++)
			if(GetPartType(ds, dir2loc[i % 6],
						   j) == I2Special(DS_MECHDOOR) ||
			   GetPartType(ds, dir2loc[i % 6], j) == I2Special(DS_AERODOOR))
				break;
		if(j != NUM_CRITICALS) {
			if(i == dir)
				return bayn;
			bayn++;
		}
	}
	return -1;
}
Exemplo n.º 8
0
double ShipDesign::ProductionCost(int empire_id, int location_id) const {
    if (CHEAP_AND_FAST_SHIP_PRODUCTION) {
        return 1.0;
    } else {
        double cost_accumulator = 0.0;
        if (const HullType* hull = GetHullType(m_hull))
            cost_accumulator += hull->ProductionCost(empire_id, location_id);
        for (std::vector<std::string>::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it)
            if (const PartType* part = GetPartType(*it))
                cost_accumulator += part->ProductionCost(empire_id, location_id);
        return std::max(0.0, cost_accumulator);
    }
}
Exemplo n.º 9
0
int ShipDesign::ProductionTime(int empire_id, int location_id) const {
    if (CHEAP_AND_FAST_SHIP_PRODUCTION) {
        return 1;
    } else {
        int time_accumulator = 1;
        if (const HullType* hull = GetHullType(m_hull))
            time_accumulator = std::max(time_accumulator, hull->ProductionTime(empire_id, location_id));
        for (std::vector<std::string>::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it)
            if (const PartType* part = GetPartType(*it))
                time_accumulator = std::max(time_accumulator, part->ProductionTime(empire_id, location_id));
        return std::max(1, time_accumulator);
    }
}
Exemplo n.º 10
0
bool ShipDesign::CanColonize() const {
    //if (m_colony_capacity > 0.0)
    //    return true;
    for (std::vector<std::string>::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it) {
        const std::string& part_name = *it;
        if (part_name.empty())
            continue;
        if (const PartType* part = GetPartType(part_name))
            if (part->Class() == PC_COLONY)
                return true;
    }
    return false;
}
Exemplo n.º 11
0
static int DS_Bay_Is_Open(MECH * mech, MECH * ds, dbref bayref)
{
	int i, j;

	for(i = 0; i < NUM_BAYS; i++)
		if(AeroBay(ds, i) > 0)
			if(AeroBay(ds, i) == bayref) {
				j = Find_DS_Bay_Dir(ds, i);
				for(i = 0; i < NUM_CRITICALS; i++) {
					if(((is_aero(mech) &&
						 GetPartType(ds, dir2loc[j],
									 i) == I2Special(DS_AERODOOR)) ||
						(!is_aero(mech)
						 && GetPartType(ds, dir2loc[j],
										i) == I2Special(DS_MECHDOOR))) &&
					   !PartIsDestroyed(ds, dir2loc[j], i))
						return 1;
				}
				return 0;
			}
	return 0;
}
Exemplo n.º 12
0
float Ship::FighterCount() const {
    float retval = 0.0f;
    for (PartMeterMap::const_iterator it = m_part_meters.begin(); it != m_part_meters.end(); ++it) {
        //std::map<std::pair<MeterType, std::string>, Meter>
        if (it->first.first != METER_CAPACITY)
            continue;
        const PartType* part_type = GetPartType(it->first.second);
        if (!part_type || part_type->Class() != PC_FIGHTER_HANGAR)
            continue;
        retval += it->second.Current();
    }

    return retval;
}
Exemplo n.º 13
0
std::vector<std::string> ShipDesign::Weapons() const {
    std::vector<std::string> retval;
    retval.reserve(m_parts.size());
    for (unsigned int i = 0; i < m_parts.size(); ++i) {
        const std::string& part_name = m_parts[i];
        const PartType* part = GetPartType(part_name);
        if (!part)
            continue;
        ShipPartClass part_class = part->Class();
        if (part_class == PC_SHORT_RANGE    || part_class == PC_MISSILES ||
            part_class == PC_FIGHTERS       || part_class == PC_POINT_DEFENSE)
        { retval.push_back(part_name); }
    }
    return retval;
}
Exemplo n.º 14
0
bool ShipDesign::ProductionCostTimeLocationInvariant() const {
    if (CHEAP_AND_FAST_SHIP_PRODUCTION)
        return true;
    // as seen in ShipDesign::ProductionCost, the location is passed as the
    // local candidate in the ScriptingContext

    // check hull and all parts
    if (const HullType* hull = GetHullType(m_hull))
        if (!hull->ProductionCostTimeLocationInvariant())
            return false;
    for (std::vector<std::string>::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it)
        if (const PartType* part = GetPartType(*it))
            if (!part->ProductionCostTimeLocationInvariant())
                return false;

    // if hull and all parts are invariant, so is whole design
    return true;
}
Exemplo n.º 15
0
void        CdispenserIGC::Update(Time   now)
{
    assert (m_ship);

    if (m_mountedFraction < 1.0f)
    {
        float   dt = now - m_ship->GetLastUpdate();
        assert (dt >= 0.0f);

        m_mountedFraction += dt * m_pMission->GetFloatConstant(c_fcidMountRate);
        if (m_mountedFraction < 1.0f)
            return;

        IIgcSite*   pigc = GetMission()->GetIgcSite();
        pigc->PlayNotificationSound(mountedSound, m_ship);
        pigc->PostNotificationText(m_ship, false, "%s ready.", GetPartType()->GetName());
        m_mountedFraction = 1.0f;
    }

    if ((m_timeLoaded < now) && (m_amount > 0))
    {
        static const int    c_maskFire[ET_MAX] =
            { chaffFireIGC,
              0, 0,
              mineFireIGC,
              0, 0, 0, 0 };

        assert (c_maskFire[ET_ChaffLauncher] == chaffFireIGC);
        assert (c_maskFire[ET_Dispenser] == mineFireIGC);

        EquipmentType   et = m_expendableType->GetEquipmentType();
        
        if ((m_ship->GetStateM() & c_maskFire[et]) &&
            ((et == ET_ChaffLauncher) || (m_ship->GetRipcordModel() == NULL)))
        {
            m_timeLoaded = now + m_expendableType->GetLoadTime();

            m_pMission->GetIgcSite()->FireExpendable(m_ship,
                                                     this,
                                                     now);
        }
    }
}
Exemplo n.º 16
0
void CombatShip::LaunchFighters()
{
    // Note that this just launches the fighters that can be launched on this
    // turn.  There is currently no code that accounts for turns(!), so we're
    // only launching part of the fighters here and not providing for the
    // launches of the rest.

    for (FighterMap::iterator it = m_unlaunched_fighters.begin();
         it != m_unlaunched_fighters.end();
         ++it) {
        const PartType* part = GetPartType(it->first);
        assert(part && part->Class() == PC_FIGHTERS);

        std::vector<CombatFighterPtr>& fighters_vec = it->second.second;
        std::size_t num_fighters = fighters_vec.size();
        double launch_rate = GetShip()->GetPartMeter(METER_LAUNCH_RATE, part->Name())->Current();
        std::size_t launch_size =
            std::min<std::size_t>(num_fighters, launch_rate * it->second.first);

        std::size_t formation_size =
            std::min(CombatFighter::FORMATION_SIZE, launch_size);
        std::size_t num_formations = launch_size / formation_size;
        std::size_t final_formation_size = launch_size % formation_size;
        if (final_formation_size)
            ++num_formations;
        else
            final_formation_size = formation_size;
        for (std::size_t j = 0; j < num_formations; ++j) {
            std::size_t size =
                j == num_formations - 1 ? final_formation_size : formation_size;
            std::set<CombatFighterFormationPtr>::iterator formation_it =
                m_launched_formations.insert(
                    m_pathing_engine->CreateFighterFormation(
                        shared_from_this(),
                        fighters_vec.end() - size,
                        fighters_vec.end())).first;
            fighters_vec.resize(fighters_vec.size() - size);
            m_pathing_engine->AddFighterFormation(*formation_it);
        }
        GetShip()->RemoveFighters(it->first, launch_size);
    }
}
Exemplo n.º 17
0
int tech_parsegun(MECH * mech, char *buffer, int *loc, int *pos, int *brand)
{
	char *args[3];
	int l, argc, t, c = 0, pi, pb;

	argc = mech_parseattributes(buffer, args, 3);
	if(argc < 1 || argc > (2 + (brand != NULL)))
		return -1;
	if(argc == (2 + (brand != NULL)) || (brand && argc == 2 && atoi(args[1]))) {
		if((*loc =
			ArmorSectionFromString(MechType(mech), MechMove(mech),
								   args[0])) < 0)
			return -1;
		l = atoi(args[1]);
		if(l <= 0 || l > CritsInLoc(mech, *loc))
			return -4;
		*pos = l - 1;
	} else {
		/* Check if it's a number */
		if(args[0][0] < '0' || args[0][0] > '9')
			return -1;
		l = atoi(args[0]);
		if(l < 0)
			return -1;
		if((t = FindWeaponNumberOnMech(mech, l, loc, pos)) == -1)
			return -1;
	}
	t = GetPartType(mech, *loc, *pos);
	if(brand != NULL && argc > 1 && !atoi(args[argc - 1])) {
		if(!find_matching_long_part(args[argc - 1], &c, &pi, &pb))
			return -2;
		if(pi != t)
			return -3;
		*brand = pb;
	} else if(brand != NULL)
		*brand = GetPartBrand(mech, *loc, *pos);
	return 0;
}
Exemplo n.º 18
0
bool Ship::HasTag(const std::string& name) const {
    const ShipDesign* design = GetShipDesign(m_design_id);
    if (design) {
        // check hull for tag
        const HullType* hull = ::GetHullType(design->Hull());
        if (hull && hull->Tags().count(name))
            return true;

        // check parts for tag
        const std::vector<std::string>& parts = design->Parts();
        for (std::vector<std::string>::const_iterator part_it = parts.begin(); part_it != parts.end(); ++part_it) {
            const PartType* part = GetPartType(*part_it);
            if (part && part->Tags().count(name))
                return true;
        }
    }
    // check species for tag
    const Species* species = GetSpecies(SpeciesName());
    if (species && species->Tags().count(name))
        return true;

    return false;
}
Exemplo n.º 19
0
static int check_for_scrappage(MECH * mech, int loc)
{
    int a, b;
    int ret = 1;

    if (SectIsDestroyed(mech, loc))
	return 1;

    if (SomeoneScrappingLoc(mech, loc)) {
	DAMAGE2(DETACH, loc);
	return 1;
    }
    for (a = 0; a < NUM_CRITICALS; a++) {
	if (!(b = GetPartType(mech, loc, a)))
	    continue;
	if (PartIsBroken(mech, loc, a))
	    continue;
	if (IsCrap(b))
	    continue;
	if (IsAmmo(b) && GetPartData(mech, loc, a)) {
	    DAMAGE3(UNLOAD, loc, a);
	    if (ret && !SomeoneRepairing(mech, loc, a))
		ret = 0;
	    continue;
	}
	DAMAGE3(IsWeapon(b) ? SCRAPG : SCRAPP, loc, a);
	if (ret && !SomeoneScrappingPart(mech, loc, a))
	    ret = 0;
	if (IsWeapon(b))
	    a += GetWeaponCrits(mech, Weapon2I(b)) - 1;
    }

    if (ret && !Invalid_Scrap_Path(mech, loc))
	DAMAGE2(DETACH, loc);

    return 0;
}
Exemplo n.º 20
0
std::set<std::string> Ship::Tags() const {
    std::set<std::string> retval;

    const ShipDesign* design = GetShipDesign(m_design_id);
    if (!design)
        return retval;

    const HullType* hull = ::GetHullType(design->Hull());
    if (!hull)
        return retval;
    retval.insert(hull->Tags().begin(), hull->Tags().end());

    const std::vector<std::string>& parts = design->Parts();
    if (parts.empty())
        return retval;

    for (std::vector<std::string>::const_iterator part_it = parts.begin(); part_it != parts.end(); ++part_it) {
        if (const PartType* part = GetPartType(*part_it)) {
            retval.insert(part->Tags().begin(), part->Tags().end());
        }
    }

    return retval;
}
Exemplo n.º 21
0
void ShipDesign::BuildStatCaches() {
    const HullType* hull = GetHullType(m_hull);
    if (!hull) {
        Logger().errorStream() << "ShipDesign::BuildStatCaches couldn't get hull with name " << m_hull;
        return;
    }

    m_producible =      hull->Producible();
    m_detection =       hull->Detection();
    m_colony_capacity = hull->ColonyCapacity();
    m_troop_capacity =  hull->TroopCapacity();
    m_stealth =         hull->Stealth();
    m_fuel =            hull->Fuel();
    m_shields =         hull->Shields();
    m_structure =       hull->Structure();
    m_battle_speed =    hull->BattleSpeed();
    m_starlane_speed =  hull->StarlaneSpeed();

    for (std::vector<std::string>::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it) {
        if (it->empty())
            continue;

        const PartType* part = GetPartType(*it);
        if (!part) {
            Logger().errorStream() << "ShipDesign::BuildStatCaches couldn't get part with name " << *it;
            continue;
        }

        if (!part->Producible())
            m_producible = false;

        switch (part->Class()) {
        case PC_SHORT_RANGE: {
            const DirectFireStats& stats = boost::get<DirectFireStats>(part->Stats());
            m_SR_weapons.insert(std::make_pair(stats.m_range, part));
            m_is_armed = true;
            m_min_SR_range = std::min(m_min_SR_range, stats.m_range);
            m_max_SR_range = std::max(m_max_SR_range, stats.m_range);
            m_min_weapon_range = std::min(m_min_weapon_range, stats.m_range);
            m_max_weapon_range = std::max(m_max_weapon_range, stats.m_range);
            m_min_non_PD_weapon_range = std::min(m_min_non_PD_weapon_range, stats.m_range);
            m_max_non_PD_weapon_range = std::max(m_max_non_PD_weapon_range, stats.m_range);
            break;
        }
        case PC_MISSILES: {
            const LRStats& stats = boost::get<LRStats>(part->Stats());
            m_LR_weapons.insert(std::make_pair(stats.m_range, part));
            m_is_armed = true;
            m_min_LR_range = std::min(m_min_LR_range, stats.m_range);
            m_max_LR_range = std::max(m_max_LR_range, stats.m_range);
            m_min_weapon_range = std::min(m_min_weapon_range, stats.m_range);
            m_max_weapon_range = std::max(m_max_weapon_range, stats.m_range);
            m_min_non_PD_weapon_range = std::min(m_min_non_PD_weapon_range, stats.m_range);
            m_max_non_PD_weapon_range = std::max(m_max_non_PD_weapon_range, stats.m_range);
            break;
        }
        case PC_FIGHTERS:
            m_F_weapons.push_back(part);
            m_is_armed = true;
            break;
        case PC_POINT_DEFENSE: {
            const DirectFireStats& stats = boost::get<DirectFireStats>(part->Stats());
            m_PD_weapons.insert(std::make_pair(stats.m_range, part));
            m_is_armed = true;
            m_min_PD_range = std::min(m_min_PD_range, stats.m_range);
            m_max_PD_range = std::max(m_max_PD_range, stats.m_range);
            m_min_weapon_range = std::min(m_min_weapon_range, stats.m_range);
            m_max_weapon_range = std::max(m_max_weapon_range, stats.m_range);
            break;
        }
        case PC_COLONY:
            m_colony_capacity += boost::get<float>(part->Stats());
            break;
        case PC_TROOPS:
            m_troop_capacity += boost::get<float>(part->Stats());
            break;
        case PC_STEALTH:
            m_stealth += boost::get<float>(part->Stats());
            break;
        case PC_BATTLE_SPEED:
            m_battle_speed += boost::get<float>(part->Stats());
            break;
        case PC_STARLANE_SPEED:
            m_starlane_speed += boost::get<float>(part->Stats());
            break;
        case PC_SHIELD:
            m_shields += boost::get<float>(part->Stats());
            break;
        case PC_FUEL:
            m_fuel += boost::get<float>(part->Stats());
            break;
        case PC_ARMOUR:
            m_structure += boost::get<float>(part->Stats());
            break;
        case PC_DETECTION:
            m_detection += boost::get<float>(part->Stats());
            break;
        default:
            break;
        }
    }

    if (m_SR_weapons.empty())
        m_min_SR_range = 0.0;
    if (m_LR_weapons.empty())
        m_min_LR_range = 0.0;
    if (m_PD_weapons.empty())
        m_min_PD_range = 0.0;
    if (!m_min_SR_range && !m_min_LR_range && !m_min_PD_range)
        m_min_weapon_range = 0.0;
    if (!m_min_LR_range && !m_min_PD_range)
        m_min_non_PD_weapon_range = 0.0;
}
Exemplo n.º 22
0
bool ShipDesign::ProductionLocation(int empire_id, int location_id) const {
    const UniverseObject* location = GetUniverseObject(location_id);
    if (!location)
        return false;

    // currently ships can only be built at planets, and by species that are
    // not planetbound
    const Planet* planet = universe_object_cast<const Planet*>(location);
    if (!planet)
        return false;
    const std::string& species_name = planet->SpeciesName();
    if (species_name.empty())
        return false;
    const Species* species = GetSpecies(species_name);
    if (!species)
        return false;
    if (!species->CanProduceShips())
        return false;
    // also, species that can't colonize can't produce colony ships
    if (this->CanColonize() && !species->CanColonize())
        return false;

    Empire* empire = Empires().Lookup(empire_id);
    if (!empire) {
        Logger().debugStream() << "ShipDesign::ProductionLocation: Unable to get pointer to empire " << empire_id;
        return false;
    }

    // get a source object, which is owned by the empire with the passed-in
    // empire id.  this is used in conditions to reference which empire is
    // doing the producing.  Ideally this will be the capital, but any object
    // owned by the empire will work.
    const UniverseObject* source = SourceForEmpire(empire_id);
    // if this empire doesn't own ANYTHING, then how is it producing anyway?
    if (!source)
        return false;

    // apply hull location conditions to potential location
    const HullType* hull = GetHull();
    if (!hull) {
        Logger().errorStream() << "ShipDesign::ProductionLocation  ShipDesign couldn't get its own hull with name " << m_hull;
        return false;
    }
    if (!hull->Location()->Eval(ScriptingContext(source), location))
        return false;

    // apply external and internal parts' location conditions to potential location
    for (std::vector<std::string>::const_iterator part_it = m_parts.begin(); part_it != m_parts.end(); ++part_it) {
        std::string part_name = *part_it;
        if (part_name.empty())
            continue;       // empty slots don't limit build location

        const PartType* part = GetPartType(part_name);
        if (!part) {
            Logger().errorStream() << "ShipDesign::ProductionLocation  ShipDesign couldn't get part with name " << part_name;
            return false;
        }
        if (!part->Location()->Eval(ScriptingContext(source), location))
            return false;
    }
    // location matched all hull and part conditions, so is a valid build location
    return true;
}
Exemplo n.º 23
0
Ship::Ship(int empire_id, int design_id, const std::string& species_name,
           int produced_by_empire_id/* = ALL_EMPIRES*/) :
    m_design_id(design_id),
    m_fleet_id(INVALID_OBJECT_ID),
    m_ordered_scrapped(false),
    m_ordered_colonize_planet_id(INVALID_OBJECT_ID),
    m_ordered_invade_planet_id(INVALID_OBJECT_ID),
    m_ordered_bombard_planet_id(INVALID_OBJECT_ID),
    m_last_turn_active_in_combat(INVALID_GAME_TURN),
    m_species_name(species_name),
    m_produced_by_empire_id(produced_by_empire_id)
{
    if (!GetShipDesign(design_id))
        throw std::invalid_argument("Attempted to construct a Ship with an invalid design id");

    if (!m_species_name.empty() && !GetSpecies(m_species_name))
        Logger().debugStream() << "Ship created with invalid species name: " << m_species_name;

    SetOwner(empire_id);

    UniverseObject::Init();

    AddMeter(METER_FUEL);
    AddMeter(METER_MAX_FUEL);
    AddMeter(METER_SHIELD);
    AddMeter(METER_MAX_SHIELD);
    AddMeter(METER_DETECTION);
    AddMeter(METER_STRUCTURE);
    AddMeter(METER_MAX_STRUCTURE);
    AddMeter(METER_BATTLE_SPEED);
    AddMeter(METER_STARLANE_SPEED);

    const std::vector<std::string>& part_names = Design()->Parts();
    for (std::size_t i = 0; i < part_names.size(); ++i) {
        if (part_names[i] != "") {
            const PartType* part = GetPartType(part_names[i]);
            if (!part) {
                Logger().errorStream() << "Ship::Ship couldn't get part with name " << part_names[i];
                continue;
            }

            switch (part->Class()) {
            case PC_SHORT_RANGE:
            case PC_POINT_DEFENSE: {
                m_part_meters[std::make_pair(METER_DAMAGE,              part->Name())];
                m_part_meters[std::make_pair(METER_ROF,                 part->Name())];
                m_part_meters[std::make_pair(METER_RANGE,               part->Name())];
                break;
            }
            case PC_MISSILES: {
                std::pair<std::size_t, std::size_t>& part_missiles =
                    m_missiles[part_names[i]];
                ++part_missiles.first;
                part_missiles.second += boost::get<LRStats>(part->Stats()).m_capacity;
                m_part_meters[std::make_pair(METER_DAMAGE,              part->Name())];
                m_part_meters[std::make_pair(METER_ROF,                 part->Name())];
                m_part_meters[std::make_pair(METER_RANGE,               part->Name())];
                m_part_meters[std::make_pair(METER_SPEED,               part->Name())];
                m_part_meters[std::make_pair(METER_STEALTH,             part->Name())];
                m_part_meters[std::make_pair(METER_STRUCTURE,           part->Name())];
                m_part_meters[std::make_pair(METER_CAPACITY,            part->Name())];
                break;
            }
            case PC_FIGHTERS: {
                std::pair<std::size_t, std::size_t>& part_fighters =
                    m_fighters[part_names[i]];
                ++part_fighters.first;
                part_fighters.second += boost::get<FighterStats>(part->Stats()).m_capacity;
                m_part_meters[std::make_pair(METER_ANTI_SHIP_DAMAGE,    part->Name())];
                m_part_meters[std::make_pair(METER_ANTI_FIGHTER_DAMAGE, part->Name())];
                m_part_meters[std::make_pair(METER_LAUNCH_RATE,         part->Name())];
                m_part_meters[std::make_pair(METER_FIGHTER_WEAPON_RANGE,part->Name())];
                m_part_meters[std::make_pair(METER_SPEED,               part->Name())];
                m_part_meters[std::make_pair(METER_STEALTH,             part->Name())];
                m_part_meters[std::make_pair(METER_STRUCTURE,           part->Name())];
                m_part_meters[std::make_pair(METER_DETECTION,           part->Name())];
                m_part_meters[std::make_pair(METER_CAPACITY,            part->Name())];
                break;
            }
            default:
                break;
            }
        }
    }
}
Exemplo n.º 24
0
void ShipDesign::BuildStatCaches() {
    const HullType* hull = GetHullType(m_hull);
    if (!hull) {
        ErrorLogger() << "ShipDesign::BuildStatCaches couldn't get hull with name " << m_hull;
        return;
    }

    m_producible =      hull->Producible();
    m_detection =       hull->Detection();
    m_colony_capacity = hull->ColonyCapacity();
    m_troop_capacity =  hull->TroopCapacity();
    m_stealth =         hull->Stealth();
    m_fuel =            hull->Fuel();
    m_shields =         hull->Shields();
    m_structure =       hull->Structure();
    m_speed =           hull->Speed();

    for (std::vector<std::string>::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it) {
        if (it->empty())
            continue;

        const PartType* part = GetPartType(*it);
        if (!part) {
            ErrorLogger() << "ShipDesign::BuildStatCaches couldn't get part with name " << *it;
            continue;
        }

        if (!part->Producible())
            m_producible = false;

        switch (part->Class()) {
        case PC_SHORT_RANGE:
        case PC_MISSILES:
        case PC_FIGHTERS:
        case PC_POINT_DEFENSE: {
            m_is_armed = true;
            break;
        }
        case PC_COLONY:
            m_colony_capacity += part->Capacity();
            break;
        case PC_TROOPS:
            m_troop_capacity += part->Capacity();
            break;
        case PC_STEALTH:
            m_stealth += part->Capacity();
            break;
        case PC_SPEED:
            m_speed += part->Capacity();
            break;
        case PC_SHIELD:
            m_shields += part->Capacity();
            break;
        case PC_FUEL:
            m_fuel += part->Capacity();
            break;
        case PC_ARMOUR:
            m_structure += part->Capacity();
            break;
        case PC_DETECTION:
            m_detection += part->Capacity();
            break;
        case PC_BOMBARD:
            m_can_bombard = true;
            break;
        case PC_RESEARCH:
            m_research_generation += part->Capacity();
            break;
        case PC_INDUSTRY:
            m_industry_generation += part->Capacity();
            break;
        case PC_TRADE:
            m_trade_generation += part->Capacity();
            break;
        case PC_PRODICTION_LOCATION:
            m_is_production_location = true;
            break;
        default:
            break;
        }
    }
}
Exemplo n.º 25
0
static int check_for_damage(MECH * mech, int loc)
{
    int a, b, c, d;

    if (SectIsDestroyed(mech, loc)) {
	if (MechType(mech) != CLASS_BSUIT)
	    DAMAGE2(REATTACH, loc);
	else
	    DAMAGE2(REPLACESUIT, loc);
	return 0;
    }

    /*
       * Added by Kipsta
       * 8/4/99
     */

    if (SectIsFlooded(mech, loc)) {
	DAMAGE2(RESEAL, loc);
	return 0;
    }
    if ((a = GetSectInt(mech, loc)) != (b = GetSectOInt(mech, loc)))
	DAMAGE3(FIXINTERNAL, loc, (b - a));
    else {
	if ((a = GetSectArmor(mech, loc)) != (b =
		GetSectOArmor(mech, loc)))
	    DAMAGE3(FIXARMOR, loc, (b - a));
	if ((a = GetSectRArmor(mech, loc)) != (b =
		GetSectORArmor(mech, loc)))
	    DAMAGE3(FIXARMOR_R, loc, (b - a));
    }
    for (a = 0; a < NUM_CRITICALS; a++) {
	if (!(b = GetPartType(mech, loc, a)))
	    continue;
	if (IsAmmo(b) && !PartIsDestroyed(mech, loc, a) &&
	    (c = GetPartData(mech, loc, a)) != (d =
		FullAmmo(mech, loc, a)))
	    DAMAGE3(RELOAD, loc, a);
	if (!PartIsNonfunctional(mech, loc, a) &&
	    !PartTempNuke(mech, loc, a) && !PartIsDamaged(mech, loc, a))
	    continue;
	if (IsCrap(b))
	    continue;
	/* Destroyed / tempnuke'd part. Either case, it works for us :) */

	if (PartIsDamaged(mech, loc, a)) {
	    if (GetPartDamageFlags(mech, loc, a) & WEAP_DAM_EN_FOCUS)
		DAMAGE3(ENHCRIT_FOCUS, loc, a);
	    else if (GetPartDamageFlags(mech, loc,
		    a) & WEAP_DAM_EN_CRYSTAL)
		DAMAGE3(ENHCRIT_CRYSTAL, loc, a);
	    else if (GetPartDamageFlags(mech, loc,
		    a) & WEAP_DAM_BALL_BARREL)
		DAMAGE3(ENHCRIT_BARREL, loc, a);
	    else if (GetPartDamageFlags(mech, loc, a) & WEAP_DAM_BALL_AMMO)
		DAMAGE3(ENHCRIT_AMMOB, loc, a);
	    else if (GetPartDamageFlags(mech, loc,
		    a) & WEAP_DAM_MSL_RANGING)
		DAMAGE3(ENHCRIT_RANGING, loc, a);
	    else if (GetPartDamageFlags(mech, loc, a) & WEAP_DAM_MSL_AMMO)
		DAMAGE3(ENHCRIT_AMMOM, loc, a);
	    else
		DAMAGE3(ENHCRIT_MISC, loc, a);

	} else if (IsWeapon(b) && GetWeaponCrits(mech, Weapon2I(b)) > 4 &&
	    !PartIsDestroyed(mech, loc, a + 1))
	    DAMAGE3(REPAIRP_T, loc, a);
	else
	    DAMAGE3(IsWeapon(b) ? REPAIRG : REPAIRP, loc, a);

	if (IsWeapon(b))
	    a += GetWeaponCrits(mech, Weapon2I(b)) - 1;
    }
    return 1;
}
Exemplo n.º 26
0
void CombatShip::Init(const OpenSteer::Vec3& position_, const OpenSteer::Vec3& direction)
{
    m_proximity_token =
        m_pathing_engine->GetProximityDB().Insert(this, SHIP_FLAG, EmpireFlag(m_empire_id));

    SimpleVehicle::reset();
    SimpleVehicle::setMaxForce(3.0);
    SimpleVehicle::setMaxSpeed(GetShip()->Design()->BattleSpeed());

    // TODO: setMass()

    SimpleVehicle::regenerateOrthonormalBasis(direction, OpenSteer::Vec3(0, 0, 1));

    SimpleVehicle::setPosition(position_);
    SimpleVehicle::setSpeed(0);

    m_proximity_token->UpdatePosition(position());

    m_mission_queue.push_front(ShipMission(ShipMission::NONE));

    const Ship::ConsumablesMap& fighters = GetShip()->Fighters();
    for (Ship::ConsumablesMap::const_iterator it = fighters.begin(); it != fighters.end(); ++it) {
        const PartType* part = GetPartType(it->first);
        assert(part && part->Class() == PC_FIGHTERS);
        std::size_t num_fighters = it->second.second;

        m_unlaunched_fighters[it->first].first = it->second.first;
        std::vector<CombatFighterPtr>& fighter_vec =
            m_unlaunched_fighters[it->first].second;
        fighter_vec.resize(num_fighters);
        for (std::size_t i = 0; i < num_fighters; ++i) {
            fighter_vec[i].reset(
                new CombatFighter(shared_from_this(), *part, m_empire_id, *m_pathing_engine));
            fighter_vec[i]->SetWeakPtr(fighter_vec[i]);
        }
    }

    m_missiles = GetShip()->Missiles();

    float PD_minus_non_PD = 0.0f;
    const std::vector<std::string>& part_names = GetShip()->Design()->Parts();
    for (std::size_t i = 0; i < part_names.size(); ++i) {
        if (part_names[i].empty())
            continue;

        const PartType* part = GetPartType(part_names[i]);
        assert(part);
        if (part->Class() == PC_POINT_DEFENSE) {
            const std::string& part_name = part->Name();
            float damage = GetShip()->GetPartMeter(METER_DAMAGE, part_name)->Current();
            m_raw_PD_strength +=
                damage *
                GetShip()->GetPartMeter(METER_ROF, part_name)->Current() *
                GetShip()->GetPartMeter(METER_RANGE, part_name)->Current();
            PD_minus_non_PD += damage;
        } else if (part->Class() == PC_SHORT_RANGE) {
            const std::string& part_name = part->Name();
            float damage = GetShip()->GetPartMeter(METER_DAMAGE, part_name)->Current();
            m_raw_SR_strength +=
                damage *
                GetShip()->GetPartMeter(METER_ROF, part_name)->Current() *
                GetShip()->GetPartMeter(METER_RANGE, part_name)->Current();
            PD_minus_non_PD -= damage;
        } else if (part->Class() == PC_MISSILES) {
            const std::string& part_name = part->Name();
            float damage = GetShip()->GetPartMeter(METER_DAMAGE, part_name)->Current();
            m_raw_LR_strength +=
                damage *
                GetShip()->GetPartMeter(METER_ROF, part_name)->Current() *
                GetShip()->GetPartMeter(METER_RANGE, part_name)->Current();
            PD_minus_non_PD -= damage;
        }
    }
    m_is_PD_ship = 0.0f < PD_minus_non_PD;
}
Exemplo n.º 27
0
void    CafterburnerIGC::IncrementalUpdate(Time lastUpdate, Time now, bool bUseFuel)
{
    assert (m_ship);
    assert (now >= lastUpdate);

    {
#ifdef WIN
        float   dt = now - lastUpdate;
#else
        float dt = Seconds(now - lastUpdate).count();
#endif

        if (m_mountedFraction < 1.0f)
        {
            if (bUseFuel)
                m_mountedFraction += dt * m_pMission->GetFloatConstant(c_fcidMountRate);

            if (m_mountedFraction >= 1.0f)
            {
                IIgcSite*   pigc = GetMission()->GetIgcSite();
                pigc->PlayNotificationSound(mountedSound, m_ship);
                pigc->PostNotificationText(m_ship, false, "%s ready.", GetPartType()->GetName());
                m_mountedFraction = 1.0f;
            }
            else
                return;
        }

        {
            float   fuel = m_ship->GetFuel();
            bool    bActivated = (m_ship->GetStateM() & afterburnerButtonIGC) && (fuel != 0.0f || m_typeData->fuelConsumption == 0.0f); //Spunky - #271 
            if (bActivated)
                Activate();

            if (m_fActive)
            {
                if (bActivated)
                {
                    m_power += dt * m_typeData->onRate;
                    if (m_power > 1.0f)
                        m_power = 1.0f;
                }
                else
                {
                    m_power -= dt * m_typeData->offRate;
                    if (m_power <= 0.0f)
                        Deactivate();
                }

                if ((m_power != 0.0f) && bUseFuel)
                {
                    float   fuelUsed = m_power * m_typeData->fuelConsumption * m_typeData->maxThrust * dt;

                    if (fuelUsed < fuel)
                        m_ship->SetFuel(fuel - fuelUsed);
                    else if (fuel != 0.0f)
                    {
                        //Out of gas
                        m_ship->SetFuel(0.0f);
                        Deactivate();
                    }
                }
            }
        }
    }
}
Exemplo n.º 28
0
Ship::Ship(int empire_id, int design_id, const std::string& species_name,
           int produced_by_empire_id/* = ALL_EMPIRES*/) :
    UniverseObject(),
    m_design_id(design_id),
    m_fleet_id(INVALID_OBJECT_ID),
    m_ordered_scrapped(false),
    m_ordered_colonize_planet_id(INVALID_OBJECT_ID),
    m_ordered_invade_planet_id(INVALID_OBJECT_ID),
    m_ordered_bombard_planet_id(INVALID_OBJECT_ID),
    m_last_turn_active_in_combat(INVALID_GAME_TURN),
    m_species_name(species_name),
    m_produced_by_empire_id(produced_by_empire_id),
    m_arrived_on_turn(CurrentTurn())
{
    if (!GetShipDesign(design_id))
        throw std::invalid_argument("Attempted to construct a Ship with an invalid design id");

    if (!m_species_name.empty() && !GetSpecies(m_species_name))
        DebugLogger() << "Ship created with invalid species name: " << m_species_name;

    SetOwner(empire_id);

    UniverseObject::Init();

    AddMeter(METER_FUEL);
    AddMeter(METER_MAX_FUEL);
    AddMeter(METER_SHIELD);
    AddMeter(METER_MAX_SHIELD);
    AddMeter(METER_DETECTION);
    AddMeter(METER_STRUCTURE);
    AddMeter(METER_MAX_STRUCTURE);
    AddMeter(METER_SPEED);
    AddMeter(METER_TARGET_INDUSTRY);
    AddMeter(METER_INDUSTRY);
    AddMeter(METER_TARGET_RESEARCH);
    AddMeter(METER_RESEARCH);
    AddMeter(METER_TARGET_TRADE);
    AddMeter(METER_TRADE);

    const std::vector<std::string>& part_names = Design()->Parts();
    for (std::size_t i = 0; i < part_names.size(); ++i) {
        if (part_names[i] != "") {
            const PartType* part = GetPartType(part_names[i]);
            if (!part) {
                ErrorLogger() << "Ship::Ship couldn't get part with name " << part_names[i];
                continue;
            }

            switch (part->Class()) {
            case PC_COLONY:
            case PC_TROOPS: {
                m_part_meters[std::make_pair(METER_CAPACITY, part->Name())];
                break;
            }
            case PC_DIRECT_WEAPON:      // capacity is damage, secondary stat is shots per attack
            case PC_FIGHTER_HANGAR: {   // capacity is how many fighters contained, secondary stat is damage per fighter attack
                m_part_meters[std::make_pair(METER_SECONDARY_STAT,      part->Name())];
                m_part_meters[std::make_pair(METER_MAX_SECONDARY_STAT,  part->Name())];
                // intentionally no break here
            }
            case PC_FIGHTER_BAY: {      // capacity is how many fighters launched per combat round
                m_part_meters[std::make_pair(METER_CAPACITY,            part->Name())];
                m_part_meters[std::make_pair(METER_MAX_CAPACITY,        part->Name())];
                break;
            }
            default:
                break;
            }
        }
    }
}
Exemplo n.º 29
0
int FindAmmoType(MECH * mech, int loc, int part)
{
	int t = GetPartType(mech, loc, part);
	int m = GetPartAmmoMode(mech, loc, part);
	int base = -1;

	if(!IsAmmo(t))
		return t;
	t = Ammo2I(t);

	if(strstr(MechWeapons[t].name, "StreakSRM"))
		base = SSRM_AMMO;
	else if(strstr(MechWeapons[t].name, "StreakLRM"))
		base = SLRM_AMMO;
	else if(strstr(MechWeapons[t].name, "ELRM"))
		base = ELRM_AMMO;
	else if(strstr(MechWeapons[t].name, "LR_DFM"))
		base = LR_DFM_AMMO;
	else if(strstr(MechWeapons[t].name, "SR_DFM"))
		base = SR_DFM_AMMO;
	else if(strstr(MechWeapons[t].name, "LRM"))
		base = LRM_AMMO;
	else if(strstr(MechWeapons[t].name, "SRM"))
		base = SRM_AMMO;
	else if(strstr(MechWeapons[t].name, "MRM"))
		base = MRM_AMMO;

	if(!(m & AMMO_MODES)) {
		if(base < 0)
			return I2Ammo(t);
		else
			return Cargo(base);
	}

	if(m & LBX_MODE) {
		if(strstr(MechWeapons[t].name, "LB20"))
			base = LBX20_AMMO;
		else if(strstr(MechWeapons[t].name, "LB10"))
			base = LBX10_AMMO;
		else if(strstr(MechWeapons[t].name, "LB5"))
			base = LBX5_AMMO;
		else if(strstr(MechWeapons[t].name, "LB2"))
			base = LBX2_AMMO;
		if(base < 0)
			return I2Ammo(t);
		return Cargo(base);
	}

	if(m & AC_MODES) {
		if(m & AC_AP_MODE) {
			if(strstr(MechWeapons[t].name, "AC/2"))
				base = AC2_AP_AMMO;
			if(strstr(MechWeapons[t].name, "AC/5"))
				base = AC5_AP_AMMO;
			if(strstr(MechWeapons[t].name, "AC/10"))
				base = AC10_AP_AMMO;
			if(strstr(MechWeapons[t].name, "AC/20"))
				base = AC20_AP_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/2"))
				base = LAC2_AP_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/5"))
				base = LAC5_AP_AMMO;
		}

		if(m & AC_FLECHETTE_MODE) {
			if(strstr(MechWeapons[t].name, "AC/2"))
				base = AC2_FLECHETTE_AMMO;
			if(strstr(MechWeapons[t].name, "AC/5"))
				base = AC5_FLECHETTE_AMMO;
			if(strstr(MechWeapons[t].name, "AC/10"))
				base = AC10_FLECHETTE_AMMO;
			if(strstr(MechWeapons[t].name, "AC/20"))
				base = AC20_FLECHETTE_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/2"))
				base = LAC2_FLECHETTE_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/5"))
				base = LAC5_FLECHETTE_AMMO;
		}

		if(m & AC_INCENDIARY_MODE) {
			if(strstr(MechWeapons[t].name, "AC/2"))
				base = AC2_INCENDIARY_AMMO;
			if(strstr(MechWeapons[t].name, "AC/5"))
				base = AC5_INCENDIARY_AMMO;
			if(strstr(MechWeapons[t].name, "AC/10"))
				base = AC10_INCENDIARY_AMMO;
			if(strstr(MechWeapons[t].name, "AC/20"))
				base = AC20_INCENDIARY_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/2"))
				base = LAC2_INCENDIARY_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/5"))
				base = LAC5_INCENDIARY_AMMO;
		}

		if(m & AC_PRECISION_MODE) {
			if(strstr(MechWeapons[t].name, "AC/2"))
				base = AC2_PRECISION_AMMO;
			if(strstr(MechWeapons[t].name, "AC/5"))
				base = AC5_PRECISION_AMMO;
			if(strstr(MechWeapons[t].name, "AC/10"))
				base = AC10_PRECISION_AMMO;
			if(strstr(MechWeapons[t].name, "AC/20"))
				base = AC20_PRECISION_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/2"))
				base = LAC2_PRECISION_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/5"))
				base = LAC5_PRECISION_AMMO;
		}

		if(m & AC_CASELESS_MODE) {
			if(strstr(MechWeapons[t].name, "AC/2"))
				base = AC2_CASELESS_AMMO;
			if(strstr(MechWeapons[t].name, "AC/5"))
				base = AC5_CASELESS_AMMO;
			if(strstr(MechWeapons[t].name, "AC/10"))
				base = AC10_CASELESS_AMMO;
			if(strstr(MechWeapons[t].name, "AC/20"))
				base = AC20_CASELESS_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/2"))
				base = LAC2_CASELESS_AMMO;
			if(strstr(MechWeapons[t].name, "LightAC/5"))
				base = LAC5_CASELESS_AMMO;
		}
		if(base < 0)
			return I2Ammo(t);
		return Cargo(base);
	}

	if(m & INARC_EXPLO_MODE)
		return Cargo(INARC_EXPLO_AMMO);
	else if(m & INARC_HAYWIRE_MODE)
		return Cargo(INARC_HAYWIRE_AMMO);
	else if(m & INARC_ECM_MODE)
		return Cargo(INARC_ECM_AMMO);
	else if(m & INARC_NEMESIS_MODE)
		return Cargo(INARC_NEMESIS_AMMO);

	if(base < 0)
		return I2Ammo(t);
	if(m & NARC_MODE)
		return Cargo(base) + NARC_LRM_AMMO - LRM_AMMO;
	if(m & ARTEMIS_MODE)
		return Cargo(base) + ARTEMIS_LRM_AMMO - LRM_AMMO;
	if(m & SWARM_MODE)
		return Cargo(base) + SWARM_LRM_AMMO - LRM_AMMO;
	if(m & SWARM1_MODE)
		return Cargo(base) + SWARM1_LRM_AMMO - LRM_AMMO;
	if(m & INFERNO_MODE)
		return Cargo(base) + INFERNO_SRM_AMMO - SRM_AMMO;
	if(m & STINGER_MODE)
		return Cargo(base) + AMMO_LRM_STINGER - LRM_AMMO;
	if(m & SGUIDED_MODE)
	        return Cargo(base) + AMMO_LRM_SGUIDED - LRM_AMMO;
	return Cargo(base);
}