示例#1
0
InventoryItemRef InventoryItem::Spawn(ItemFactory &factory, ItemData &data)
{
    // obtain type of new item
    const ItemType *t = factory.GetType( data.typeID );
    if( t == NULL )
        return InventoryItemRef();

    // See what to do next:
    switch( t->categoryID() ) {
        //! TODO not handled.
        case EVEDB::invCategories::_System:
        case EVEDB::invCategories::Station:
        case EVEDB::invCategories::Material:
        case EVEDB::invCategories::Accessories:
        case EVEDB::invCategories::Charge:
        case EVEDB::invCategories::Trading:
        case EVEDB::invCategories::Bonus:
        case EVEDB::invCategories::Commodity:
        case EVEDB::invCategories::Implant:
        case EVEDB::invCategories::Reaction:
             break;

		///////////////////////////////////////
        // Entity:
        ///////////////////////////////////////
        case EVEDB::invCategories::Entity: {
			// Spawn generic item for Entities at this time:
			uint32 itemID = InventoryItem::_SpawnEntity( factory, data );
			if( itemID == 0 )
				return InventoryItemRef();
			InventoryItemRef itemRef = InventoryItem::LoadEntity( factory, itemID, data );
			return itemRef;
		}

		///////////////////////////////////////
        // Blueprint:
        ///////////////////////////////////////
        case EVEDB::invCategories::Blueprint: {
            BlueprintData bdata; // use default blueprint attributes

            BlueprintRef blueRef = Blueprint::Spawn( factory, data, bdata );
            blueRef.get()->SaveAttributes();

            return blueRef;
        }

        ///////////////////////////////////////
        // Celestial:
        // (used for Cargo Containers, Rings, and Biomasses, Wrecks, Large Collidable Objects, Clouds,
        //  Cosmic Signatures, Mobile Sentry Guns, Global Warp Disruptors, Agents in Space, Cosmic Anomaly, Beacons, Wormholes,
        //  and other celestial static objects such as NPC stations, stars, moons, planets, and stargates)
        ///////////////////////////////////////
        case EVEDB::invCategories::Celestial: {
            if ( (t->groupID() == EVEDB::invGroups::Secure_Cargo_Container)
                || (t->groupID() == EVEDB::invGroups::Cargo_Container)
                || (t->groupID() == EVEDB::invGroups::Freight_Container)
                || (t->groupID() == EVEDB::invGroups::Audit_Log_Secure_Container)
                || (t->groupID() == EVEDB::invGroups::Spawn_Container)
                || (t->groupID() == EVEDB::invGroups::Wreck) )
            {
                // Spawn new Cargo Container
                uint32 itemID = CargoContainer::_Spawn( factory, data );
                if( itemID == 0 )
                    return CargoContainerRef();

                CargoContainerRef cargoRef = CargoContainer::Load( factory, itemID );

                // THESE SHOULD BE MOVED INTO A CargoContainer::Spawn() function that does not exist yet
                // Create default dynamic attributes in the AttributeMap:
                cargoRef.get()->SetAttribute(AttrIsOnline,      1);                                                 // Is Online
                cargoRef.get()->SetAttribute(AttrDamage,        0.0);                                               // Structure Damage
                //cargoRef.get()->SetAttribute(AttrShieldCharge,  cargoRef.get()->GetAttribute(AttrShieldCapacity));  // Shield Charge
                //cargoRef.get()->SetAttribute(AttrArmorDamage,   0.0);                                               // Armor Damage
                cargoRef.get()->SetAttribute(AttrMass,          cargoRef.get()->type().attributes.mass());          // Mass
                cargoRef.get()->SetAttribute(AttrRadius,        cargoRef.get()->type().attributes.radius());        // Radius
                cargoRef.get()->SetAttribute(AttrVolume,        cargoRef.get()->type().attributes.volume());        // Volume
                cargoRef.get()->SetAttribute(AttrCapacity,      cargoRef.get()->type().attributes.capacity());      // Capacity
                cargoRef.get()->SaveAttributes();

                return cargoRef;
                //uint32 itemID = InventoryItem::_Spawn( factory, data );
                //if( itemID == 0 )
                //    return InventoryItemRef();
                //return InventoryItem::Load( factory, itemID );
            }
            else
            {
                // Spawn new Celestial Object
                uint32 itemID = CelestialObject::_Spawn( factory, data );
                if( itemID == 0 )
                    return CelestialObjectRef();
                CelestialObjectRef celestialRef = CelestialObject::Load( factory, itemID );
                celestialRef.get()->SaveAttributes();

                return celestialRef;
            }
        }

        ///////////////////////////////////////
        // Ship:
        ///////////////////////////////////////
        case EVEDB::invCategories::Ship: {
            ShipRef shipRef = Ship::Spawn( factory, data );
            shipRef.get()->SaveAttributes();

            return shipRef;
        }

        ///////////////////////////////////////
        // Skill:
        ///////////////////////////////////////
        case EVEDB::invCategories::Skill: {
            return Skill::Spawn( factory, data );
        }

        ///////////////////////////////////////
        // Owner:
        ///////////////////////////////////////
        case EVEDB::invCategories::Owner:
        {
            return Owner::Spawn( factory, data );
        }

        ///////////////////////////////////////
        // Module:
        ///////////////////////////////////////
        case EVEDB::invCategories::Module:
        {
            // Spawn generic item:
            uint32 itemID = InventoryItem::_Spawn( factory, data );
            if( itemID == 0 )
                return InventoryItemRef();

            InventoryItemRef itemRef = InventoryItem::Load( factory, itemID );

            // THESE SHOULD BE MOVED INTO A Module::Spawn() function that does not exist yet
            // Create default dynamic attributes in the AttributeMap:
            itemRef.get()->SetAttribute(AttrIsOnline,   1);                                             // Is Online
            itemRef.get()->SetAttribute(AttrDamage,     0.0);                                             // Structure Damage
            //itemRef.get()->SetAttribute(AttrShieldCharge, itemRef.get()->GetAttribute(AttrShieldCapacity));       // Shield Charge
            //itemRef.get()->SetAttribute(AttrArmorDamage, 0.0);                                        // Armor Damage
            itemRef.get()->SetAttribute(AttrMass,       itemRef.get()->type().attributes.mass());           // Mass
            itemRef.get()->SetAttribute(AttrRadius,     itemRef.get()->type().attributes.radius());       // Radius
            itemRef.get()->SetAttribute(AttrVolume,     itemRef.get()->type().attributes.volume());       // Volume
            itemRef.get()->SetAttribute(AttrCapacity,   itemRef.get()->type().attributes.capacity());   // Capacity
            itemRef.get()->SaveAttributes();

            return itemRef;
        }

        ///////////////////////////////////////
        // Drone:
        ///////////////////////////////////////
        case EVEDB::invCategories::Drone:
        {
            // Spawn generic item:
            uint32 itemID = InventoryItem::_Spawn( factory, data );
            if( itemID == 0 )
                return InventoryItemRef();

            InventoryItemRef itemRef = InventoryItem::Load( factory, itemID );

            // THESE SHOULD BE MOVED INTO A Drone::Spawn() function that does not exist yet
            // Create default dynamic attributes in the AttributeMap:
            itemRef.get()->SetAttribute(AttrIsOnline,       1);                                             // Is Online
            itemRef.get()->SetAttribute(AttrDamage,         0.0);                                             // Structure Damage
            itemRef.get()->SetAttribute(AttrShieldCharge,   itemRef.get()->GetAttribute(AttrShieldCapacity));       // Shield Charge
            itemRef.get()->SetAttribute(AttrArmorDamage,    0.0);                                        // Armor Damage
            itemRef.get()->SetAttribute(AttrMass,           itemRef.get()->type().attributes.mass());           // Mass
            itemRef.get()->SetAttribute(AttrRadius,         itemRef.get()->type().attributes.radius());       // Radius
            itemRef.get()->SetAttribute(AttrVolume,         itemRef.get()->type().attributes.volume());       // Volume
            itemRef.get()->SetAttribute(AttrCapacity,       itemRef.get()->type().attributes.capacity());   // Capacity
            itemRef.get()->SaveAttributes();

            return itemRef;
        }

        ///////////////////////////////////////
        // Deployable:
        ///////////////////////////////////////
        case EVEDB::invCategories::Deployable:
        {
            // Spawn generic item:
            uint32 itemID = InventoryItem::_Spawn( factory, data );
            if( itemID == 0 )
                return InventoryItemRef();

            InventoryItemRef itemRef = InventoryItem::Load( factory, itemID );

            // THESE SHOULD BE MOVED INTO A Deployable::Spawn() function that does not exist yet
            // Create default dynamic attributes in the AttributeMap:
            itemRef.get()->SetAttribute(AttrIsOnline,       1);                                             // Is Online
            itemRef.get()->SetAttribute(AttrDamage,         0.0);                                             // Structure Damage
            //itemRef.get()->SetAttribute(AttrShieldCharge,   itemRef.get()->GetAttribute(AttrShieldCapacity));       // Shield Charge
            //itemRef.get()->SetAttribute(AttrArmorDamage,    0.0);                                        // Armor Damage
            itemRef.get()->SetAttribute(AttrMass,           itemRef.get()->type().attributes.mass());           // Mass
            itemRef.get()->SetAttribute(AttrRadius,         itemRef.get()->type().attributes.radius());       // Radius
            itemRef.get()->SetAttribute(AttrVolume,         itemRef.get()->type().attributes.volume());       // Volume
            itemRef.get()->SetAttribute(AttrCapacity,       itemRef.get()->type().attributes.capacity());   // Capacity
            itemRef.get()->SaveAttributes();

            return itemRef;
        }

        ///////////////////////////////////////
        // Asteroid:
        ///////////////////////////////////////
        case EVEDB::invCategories::Asteroid:
        {
            // Spawn generic item:
            uint32 itemID = InventoryItem::_Spawn( factory, data );
            if( itemID == 0 )
                return InventoryItemRef();

            InventoryItemRef itemRef = InventoryItem::Load( factory, itemID );

            // THESE SHOULD BE MOVED INTO AN Asteroid::Spawn() function that does not exist yet
            // Create default dynamic attributes in the AttributeMap:
            itemRef.get()->SetAttribute(AttrRadius, 500.0);       // Radius
            itemRef.get()->SetAttribute(AttrMass,   1000000.0);    // Mass
            itemRef.get()->SetAttribute(AttrVolume, 8000.0);       // Volume
            itemRef.get()->SetAttribute(AttrQuantity, 1000.0);      // Quantity
            itemRef.get()->SaveAttributes();

            return itemRef;
        }

        ///////////////////////////////////////
        // Structure:
        ///////////////////////////////////////
        case EVEDB::invCategories::Structure:
        {
            // Spawn generic item:
            uint32 itemID = InventoryItem::_Spawn( factory, data );
            if( itemID == 0 )
                return InventoryItemRef();

            InventoryItemRef itemRef = InventoryItem::Load( factory, itemID );

            // THESE SHOULD BE MOVED INTO A Structure::Spawn() function that does not exist yet
            // Create default dynamic attributes in the AttributeMap:
            itemRef.get()->SetAttribute(AttrIsOnline,       1);                                             // Is Online
            itemRef.get()->SetAttribute(AttrDamage,         0.0);                                             // Structure Damage
            itemRef.get()->SetAttribute(AttrShieldCharge,   itemRef.get()->GetAttribute(AttrShieldCapacity));       // Shield Charge
            itemRef.get()->SetAttribute(AttrArmorDamage,    0.0);                                        // Armor Damage
            itemRef.get()->SetAttribute(AttrMass,           itemRef.get()->type().attributes.mass());           // Mass
            itemRef.get()->SetAttribute(AttrRadius,         itemRef.get()->type().attributes.radius());       // Radius
            itemRef.get()->SetAttribute(AttrVolume,         itemRef.get()->type().attributes.volume());       // Volume
            itemRef.get()->SetAttribute(AttrCapacity,       itemRef.get()->type().attributes.capacity());   // Capacity
            itemRef.get()->SaveAttributes();

            return itemRef;
        }
    }

    switch( t->groupID() ) {
        ///////////////////////////////////////
        // Station:
        ///////////////////////////////////////
        case EVEDB::invGroups::Station: {
            //_log( ITEM__ERROR, "Refusing to create station '%s'.", data.name.c_str() );
            //return InventoryItemRef();
            //return Station::Spawn( factory, data );
            uint32 itemID = Station::_Spawn( factory, data );
            if( itemID == 0 )
                return StationRef();

            StationRef stationRef = Station::Load( factory, itemID );

            // THESE SHOULD BE MOVED INTO A Station::Spawn() function that does not exist yet
            // Create default dynamic attributes in the AttributeMap:
            stationRef.get()->SetAttribute(AttrIsOnline,    1);                                              // Is Online
            stationRef.get()->SetAttribute(AttrDamage,      0.0);                                              // Structure Damage
            stationRef.get()->SetAttribute(AttrShieldCharge,stationRef.get()->GetAttribute(AttrShieldCapacity));     // Shield Charge
            stationRef.get()->SetAttribute(AttrArmorDamage, 0.0);                                         // Armor Damage
            stationRef.get()->SetAttribute(AttrMass,        stationRef.get()->type().attributes.mass());         // Mass
            stationRef.get()->SetAttribute(AttrRadius,      stationRef.get()->type().attributes.radius());     // Radius
            stationRef.get()->SetAttribute(AttrVolume,      stationRef.get()->type().attributes.volume());     // Volume
            stationRef.get()->SetAttribute(AttrCapacity,    stationRef.get()->type().attributes.capacity()); // Capacity
            stationRef.get()->SaveAttributes();

            return stationRef;
        }
    }

    // Spawn generic item:
    uint32 itemID = InventoryItem::_Spawn( factory, data );
    if( itemID == 0 )
        return InventoryItemRef();
    InventoryItemRef itemRef = InventoryItem::Load( factory, itemID );
    itemRef.get()->SaveAttributes();
    return itemRef;
}
示例#2
0
bool MiningLaser::endCycle(bool continuing)
{
    // Check to see if our target is still in this bubble or has left or been destroyed:
    if( m_ship->GetOperator()->GetSystemEntity()->Bubble()->GetEntity(m_targetID) == nullptr )
    {
        // Target has left our bubble or been destroyed, deactivate this module:
        return false;
    }
    if (m_ship->GetOperator()->GetSystemEntity()->targets.getTarget(m_targetID, true) == nullptr)
    {
        // Target no longer targeted.
        return false;
    }
    // Check range
    double maxRange = m_item->GetAttribute(AttrMaxRange).get_float();
    double targetRange = m_targetEntity->DistanceTo2(m_ship->GetOperator()->GetSystemEntity());
    targetRange = std::sqrt(targetRange);
    targetRange -= m_targetEntity->GetRadius();
    if (targetRange > maxRange)
    {
        // We must have drifted out of range.
        // TO-DO: send proper out or range response.
        SysLog::Error("MiningLaser::Activate()", "ERROR: mining laser target moved out of range!");
        return false;
    }
    // Retrieve ore from target Asteroid and put into flagCargoHold
    InventoryItemRef asteroidRef = m_targetEntity->Item();
	uint32 remainingOreUnits = asteroidRef->GetAttribute(AttrQuantity).get_int();
	double oreUnitVolume = asteroidRef->GetAttribute(AttrVolume).get_float();

    // Calculate how many units of ore to pull from the asteroid on this cycle:
    // Get base mining amount.
    double oreUnitsToPull = m_item->GetAttribute(AttrMiningAmount).get_float() / oreUnitVolume;
    // Do we have a crystal?
	if( m_chargeRef )
    {
        // Yes, apply yield multiplier.
        if (m_chargeRef->HasAttribute(AttrSpecialisationAsteroidYieldMultiplier))
        {
            // TO-DO: check for correct type of crystal.
            oreUnitsToPull *= m_chargeRef->GetAttribute(AttrSpecialisationAsteroidYieldMultiplier).get_float();
        }
        // TO-DO: do crystal damage.
    }
    // Get percent cycle complete.
    double cycleTime = getTotalCycleTimeMS();
    double percent = 1.0; // Assume full cycle if timer disabled.
    if(cycleTime != -1)
    {
        double usedTime = getElapsedCycleTimeMS();
        percent = usedTime / cycleTime;
        // Limit to range 0.0 - 1.0.
        percent = std::min(1.0, std::max(0.0, percent));
        if(percent == 0.0)
        {
            percent = 1.0;
        }
    }
    // Round down to next lowest integer value.
    oreUnitsToPull = floor(oreUnitsToPull * percent);

    // Limit to units remaining in asteroid.
    oreUnitsToPull = std::min(oreUnitsToPull, (double) remainingOreUnits);

    // Find what cargo hold to use.
    EVEItemFlags cargoFlag = flagCargoHold;
    // Check for specialized cargo hold.
    if (m_ship->HasAttribute(AttrSpecialOreHoldCapacity))
    {
        // We have a specialized ore hold all or goes here.
        cargoFlag = flagSpecializedOreHold;
    }
    // Get cargo hold and remaining capacity.
    double remainingCargoVolume = m_ship->GetRemainingVolumeByFlag(cargoFlag);
    // Do we have enough room for the whole stack?
    if (remainingCargoVolume < (floor((oreUnitsToPull * oreUnitVolume) * 100.0)/100.0))
    {
        // No, Do we have room for at least one unit?
        if (remainingCargoVolume < oreUnitVolume)
        {
            // No, Send cargo full message.
            PyDict *dict = new PyDict();
            PyTuple *tuple = new PyTuple(2);
            tuple->SetItem(0, new PyInt(MOD_ACTIVATED)); //???? what is this really?
            tuple->SetItem(1, new PyInt(m_item->typeID()));
            dict->SetItem(new PyString("modulename"), tuple);
            PyTuple *error = new PyTuple(2);
            error->SetItem(0, new PyString("MiningDronesDeactivatedCargoHoldNowFull"));
            error->SetItem(1, dict);
            m_error = error;
            return false;
        }
        // Yes, reduce the stack size.
        oreUnitsToPull = floor(remainingCargoVolume / oreUnitVolume);
    }
    // Are we actually pulling anything?
    if (oreUnitsToPull <= 0.0)
    {
        // No, hmmm... thats bad!
        // TO-DO: send client miner deactivated because hold full message.
        SysLog::Warning("MiningLaser::DoCycle()", "Somehow MiningLaser could not extract ore from current target asteroid '%s' (id %u)", m_targetEntity->Item()->itemName().c_str(), m_targetEntity->GetID());
        checkAsteroidDepleted(remainingOreUnits);
        return false;
    }

    // Check for an existing ore item in the cargo.
    InventoryItemRef existing = m_ship->GetByTypeFlag(asteroidRef->typeID(), cargoFlag);
    if (existing.get() != nullptr)
    {
        // We have an existing ore sample, add to it.
        m_ship->AlterCargoQty(existing, oreUnitsToPull);
    }
    else
    {
        // No existing ore sample, create one.
        ItemData idata(
                       asteroidRef->typeID(),
                       m_ship->ownerID(),
                       0, //temp location
                       cargoFlag,
                       oreUnitsToPull
                       );

        InventoryItemRef ore = ItemFactory::SpawnItem(idata);
        if (ore)
        {
            m_ship->AddItem(cargoFlag, ore);
        }
        else
        {
            SysLog::Error("MiningLaser::DoCycle()", "ERROR: Could not create ore stack for '%s' ship (id %u)!", m_ship->itemName().c_str(), m_ship->itemID());
            return false;
        }
    }
    // Finally, reduce the amount of ore in the asteroid by how much we took out:
    remainingOreUnits -= oreUnitsToPull;
    asteroidRef->SetAttribute(AttrQuantity, remainingOreUnits);

    // Check to see is ship is full or asteroid depleted.
    remainingCargoVolume = m_ship->GetRemainingVolumeByFlag(cargoFlag);
    if ((remainingCargoVolume < oreUnitVolume) || remainingOreUnits == 0)
    {
        // Asteroid is empty OR cargo hold is entirely full, either way, DEACTIVATE module immediately!
        checkAsteroidDepleted(remainingOreUnits);
        return false;
    }
    return true;
}