コード例 #1
0
BlueprintRef ItemFactory::SpawnBlueprint(ItemData &data, BlueprintData &bpData) {
    BlueprintRef bi = Blueprint::Spawn(*this, data, bpData);
    if( !bi )
        return BlueprintRef();

    m_items.insert( std::make_pair( bi->itemID(), bi ) );
    return bi;
}
コード例 #2
0
PyResult FactoryService::Handle_GetBlueprintAttributes(PyCallArgs &call) {
    Call_SingleIntegerArg arg;
    if(!arg.Decode(&call.tuple)) {
        _log(SERVICE__ERROR, "Failed to decode args.");
        return NULL;
    }

    BlueprintRef b = ItemFactory::GetBlueprint(arg.arg);
    if( !b )
        return NULL;

    return b->GetBlueprintAttributes();
}
コード例 #3
0
ファイル: Blueprint.cpp プロジェクト: bryogus/evemu_crucible
BlueprintRef Blueprint::SplitBlueprint(int32 qty_to_take, bool notify) {
    // split item
    BlueprintRef res = BlueprintRef::StaticCast( InventoryItem::Split( qty_to_take, notify ) );
    if( !res )
        return BlueprintRef();

    // copy our attributes
    res->SetCopy(m_copy);
    res->SetMaterialLevel(m_materialLevel);
    res->SetProductivityLevel(m_productivityLevel);
    res->SetLicensedProductionRunsRemaining(m_licensedProductionRunsRemaining);

    return res;
}
コード例 #4
0
ファイル: Contract.cpp プロジェクト: Almamu/evemu_apocrypha
void Contract::GetItemRow( InventoryItemRef item, PyPackedRow* into ) const
{
    into->SetField( "contractID",								new PyInt( contractID() ) );
    into->SetField( "itemID",									new PyInt( item->itemID() ) );
    into->SetField( "quantity",									new PyInt( item->quantity() ) );
    into->SetField( "itemTypeID",								new PyInt( item->typeID() ) );
    into->SetField( "inCrate",									new PyBool( true ) );

    if( item->categoryID() == EVEDB::invCategories::Blueprint )
    {
        BlueprintRef bp = m_itemFactory.GetBlueprint( item->itemID() );
        into->SetField( "parentID",								new PyInt( bp->parentBlueprintTypeID() ) );
        into->SetField( "productivityLevel",					new PyInt( bp->productivityLevel() ) );
        into->SetField( "materialLevel",						new PyInt( bp->materialLevel() ) );
        into->SetField( "copy",									new PyInt( bp->copy() ) );
        into->SetField( "licensedProductionRunsRemaining",		new PyInt( bp->licensedProductionRunsRemaining() ) );
    }
    else
    {
        into->SetField( "parentID",								new PyInt( 0 ) );
        into->SetField( "productivityLevel",					new PyInt( 0 ) );
        into->SetField( "materialLevel",						new PyInt( 0 ) );
        into->SetField( "copy",									new PyInt( 0 ) );
        into->SetField( "licensedProductionRunsRemaining",		new PyInt( 0 ) );
    }

    if( item->HasAttribute( AttrDamage ) )
        into->SetField( "damage",								new PyInt( item->GetAttribute( AttrDamage ).get_int() ) );
    else
        into->SetField( "damage",								new PyInt( 0 ) );

    into->SetField( "flagID",									new PyInt( item->flag() ) );
}
コード例 #5
0
ファイル: GMCommands.cpp プロジェクト: Almamu/evemu_incursion
// command to modify blueprint's attributes, we have to give it blueprint's itemID ...
// isn't much comfortable, but I don't know about better solution ...
PyResult Command_setbpattr( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args )
{
	
	if( args.argCount() < 6 ) {
		throw PyException( MakeCustomError("Correct Usage: /setbpattr [blueprintID] [0 (not copy) or 1 (copy)] [material level] [productivity level] [remaining runs]") );
	}
	
	if( !args.isNumber( 1 ) )
		throw PyException( MakeCustomError( "Argument 1 must be blueprint ID. (got %s)", args.arg( 1 ).c_str() ) );
    const uint32 blueprintID = atoi( args.arg( 1 ).c_str() );

	if( "0" != args.arg( 2 ) && "1" != args.arg( 2 ) )
		throw PyException( MakeCustomError( "Argument 2 must be 0 (not copy) or 1 (copy). (got %s)", args.arg( 2 ).c_str() ) );
    const bool copy = ( atoi( args.arg( 2 ).c_str() ) ? true : false );

	if( !args.isNumber( 3 ) )
		throw PyException( MakeCustomError( "Argument 3 must be material level. (got %s)", args.arg( 3 ).c_str() ) );
    const uint32 materialLevel = atoi( args.arg( 3 ).c_str() );

	if( !args.isNumber( 4 ) )
		throw PyException( MakeCustomError( "Argument 4 must be productivity level. (got %s)", args.arg( 4 ).c_str() ) );
    const uint32 productivityLevel = atoi( args.arg( 4 ).c_str() );

	if( !args.isNumber( 5 ) )
		throw PyException( MakeCustomError( "Argument 5 must be remaining licensed production runs. (got %s)", args.arg( 5 ).c_str() ) );
    const uint32 licensedProductionRunsRemaining = atoi( args.arg( 5 ).c_str() );

	BlueprintRef bp = services->item_factory.GetBlueprint( blueprintID );
	if( !bp )
		throw PyException( MakeCustomError( "Failed to load blueprint %u.", blueprintID ) );

	bp->SetCopy( copy );
	bp->SetMaterialLevel( materialLevel );
	bp->SetProductivityLevel( productivityLevel );
	bp->SetLicensedProductionRunsRemaining( licensedProductionRunsRemaining );

	return new PyString( "Properties modified." );
}
コード例 #6
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;
}
コード例 #7
0
bool RamProxyService::_Calculate(const Call_InstallJob &args, InventoryItemRef installedItem, Client *const c, Rsp_InstallJob &into) {
    if(!m_db.GetAssemblyLineProperties(args.installationAssemblyLineID, into.materialMultiplier, into.timeMultiplier, into.installCost, into.usageCost))
        return false;

    const ItemType *productType;
    // perform some activity-specific actions
    switch(args.activityID) {
        /*
         * Manufacturing
         */
        case ramActivityManufacturing: {
            BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

            productType = &bp->productType();

            into.productionTime = bp->type().productionTime();

            into.materialMultiplier *= bp->materialMultiplier();
            into.timeMultiplier *= bp->timeMultiplier();

            into.charMaterialMultiplier = c->GetChar()->GetAttribute(AttrManufactureCostMultiplier).get_float();
            into.charTimeMultiplier = c->GetChar()->GetAttribute(AttrManufactureTimeMultiplier).get_float();

            switch(productType->race()) {
                case raceCaldari:       into.charTimeMultiplier *= double(c->GetChar()->GetAttribute(AttrCaldariTechTimePercent).get_int()) / 100.0; break;
                case raceMinmatar:      into.charTimeMultiplier *= double(c->GetChar()->GetAttribute(AttrMinmatarTechTimePercent).get_int()) / 100.0; break;
                case raceAmarr:         into.charTimeMultiplier *= double(c->GetChar()->GetAttribute(AttrAmarrTechTimePercent).get_int()) / 100.0; break;
                case raceGallente:      into.charTimeMultiplier *= double(c->GetChar()->GetAttribute(AttrGallenteTechTimePercent).get_int()) / 100.0; break;
                case raceJove:          break;
                case racePirate:        break;
            }
            break;
        }
        /*
         * Time productivity research
         */
        case ramActivityResearchingTimeProductivity: {
            BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

            productType = &installedItem->type();

            into.productionTime = bp->type().researchProductivityTime();
            into.charMaterialMultiplier = double(c->GetChar()->GetAttribute(AttrResearchCostPercent).get_int()) / 100.0;
            into.charTimeMultiplier = c->GetChar()->GetAttribute(AttrManufacturingTimeResearchSpeed).get_float();
            break;
        }
        /*
         * Material productivity research
         */
        case ramActivityResearchingMaterialProductivity: {
            BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

            productType = &installedItem->type();

            into.productionTime = bp->type().researchMaterialTime();
            into.charMaterialMultiplier = double(c->GetChar()->GetAttribute(AttrResearchCostPercent).get_int()) / 100.0;
            into.charTimeMultiplier = c->GetChar()->GetAttribute(AttrMineralNeedResearchSpeed).get_float();
            break;
        }
        /*
         * Copying
         */
        case ramActivityCopying: {
            BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

            productType = &installedItem->type();

            // no ceil() here on purpose
            into.productionTime = (bp->type().researchCopyTime() / bp->type().maxProductionLimit()) * args.licensedProductionRuns;

            into.charMaterialMultiplier = double(c->GetChar()->GetAttribute(AttrResearchCostPercent).get_int()) / 100.0;
            into.charTimeMultiplier = c->GetChar()->GetAttribute(AttrCopySpeedPercent).get_float();
            break;
        }
        default: {
            productType = &installedItem->type();

            into.charMaterialMultiplier = 1.0;
            into.charTimeMultiplier = 1.0;
            break;
        }
    }

    if(!m_db.MultiplyMultipliers(args.installationAssemblyLineID, productType->groupID(), into.materialMultiplier, into.timeMultiplier))
        return false;

    // calculate the remaining things
    into.productionTime *= static_cast<int32>(into.timeMultiplier * into.charTimeMultiplier * args.runs);
    into.usageCost *= ceil(into.productionTime / 3600.0);
    into.cost = into.installCost + into.usageCost;

    // I "hope" this is right, simple tells client how soon will his job be started
    // Unfortunately, rounding done on client's side causes showing "Start time: 0 seconds" when he has to wait less than minute
    // I have no idea how to avoid this ...
    into.maxJobStartTime = m_db.GetNextFreeTime(args.installationAssemblyLineID);

    return true;
}
コード例 #8
0
void RamProxyService::_VerifyInstallJob_Call(const Call_InstallJob &args, InventoryItemRef installedItem, const PathElement &bomLocation, Client *const c) {
    // ACTIVITY CHECK
    // ***************

    const ItemType *productType;
    switch(args.activityID) {
        /*
         * Manufacturing
         */
        case ramActivityManufacturing: {
            if(installedItem->categoryID() != EVEDB::invCategories::Blueprint)
                throw(PyException(MakeUserError("RamActivityRequiresABlueprint")));

            BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

            if(!bp->infinite() && (bp->licensedProductionRunsRemaining() - args.runs) < 0)
                throw(PyException(MakeUserError("RamTooManyProductionRuns")));

            productType = &bp->productType();
            break;
        }
        /*
         * Time/Material Research
         */
        case ramActivityResearchingMaterialProductivity:
        case ramActivityResearchingTimeProductivity: {
            if(installedItem->categoryID() != EVEDB::invCategories::Blueprint)
                throw(PyException(MakeUserError("RamActivityRequiresABlueprint")));

            BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

            if(bp->copy())
                throw(PyException(MakeUserError("RamCannotResearchABlueprintCopy")));

            productType = &bp->type();
            break;
        }
        /*
         * Copying
         */
        case ramActivityCopying: {
            if(installedItem->categoryID() != EVEDB::invCategories::Blueprint)
                throw(PyException(MakeUserError("RamActivityRequiresABlueprint")));

            BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

            if(bp->copy())
                throw(PyException(MakeUserError("RamCannotCopyABlueprintCopy")));

            productType = &bp->type();
            break;
        }
        /*
         * The rest
         */
        case ramActivityResearchingTechnology:
        case ramActivityDuplicating:
        case ramActivityReverseEngineering:
        case ramActivityInvention: /* {
            if(installedItem->categoryID() != EVEDB::invCategories::Blueprint)
                throw(PyException(MakeUserError("RamActivityRequiresABlueprint")));

            Blueprint *bp = (Blueprint *)installedItem;

            if(!bp->copy())
                throw(PyException(MakeUserError("RamCannotInventABlueprintOriginal")));

            uint32 productTypeID = m_db.GetTech2Blueprint(installedItem->typeID());
            if(productTypeID == NULL)
                throw(PyException(MakeUserError("RamInventionNoOutput")));

            productType = m_manager->item_factory.type(productTypeID);
            break;
        } */
        default: {
            // not supported
            throw(PyException(MakeUserError("RamActivityInvalid")));
            //throw(PyException(MakeUserError("RamNoKnownOutputType")));
        }
    }

    if(!m_db.IsProducableBy(args.installationAssemblyLineID, productType->groupID()))
        throw(PyException(MakeUserError("RamBadEndProductForActivity")));

    // JOBS CHECK
    // ***********
    if(args.activityID == ramActivityManufacturing) {
        uint32 jobCount = m_db.CountManufacturingJobs(c->GetCharacterID());
        if(c->GetChar()->GetAttribute(AttrManufactureSlotLimit).get_int() <= jobCount) {
            std::map<std::string, PyRep *> exceptArgs;
            exceptArgs["current"] = new PyInt(jobCount);
            exceptArgs["max"] = c->GetChar()->GetAttribute(AttrManufactureSlotLimit).GetPyObject();
            throw(PyException(MakeUserError("MaxFactorySlotUsageReached", exceptArgs)));
        }
    } else {
        uint32 jobCount = m_db.CountResearchJobs(c->GetCharacterID());
        if(c->GetChar()->GetAttribute(AttrMaxLaborotorySlots).get_int() <= jobCount) {
            std::map<std::string, PyRep *> exceptArgs;
            exceptArgs["current"] = new PyInt(jobCount);
            exceptArgs["max"] = c->GetChar()->GetAttribute(AttrMaxLaborotorySlots).GetPyObject();
            throw(PyException(MakeUserError("MaxResearchFacilitySlotUsageReached", exceptArgs)));
        }
    }

    // INSTALLATION CHECK
    // *******************

    uint32 regionID = m_db.GetRegionOfContainer(args.installationContainerID);
    if(regionID == 0)
        throw(PyException(MakeUserError("RamIsNotAnInstallation")));

    if(c->GetRegionID() != regionID)
        throw(PyException(MakeUserError("RamRangeLimitationRegion")));

    // RamStructureNotInSpace
    // RamStructureNotIsSolarsystem
    // RamRangeLimitation
    // RamRangeLimitationJumps
    // RamRangeLimitationJumpsNoSkill

    // ASSEMBLY LINE CHECK
    // *********************

    uint32 ownerID;
    double minCharSec, maxCharSec;
    EVERamRestrictionMask restrictionMask;
    EVERamActivity activity;

    // get properties
    if(!m_db.GetAssemblyLineVerifyProperties(args.installationAssemblyLineID, ownerID, minCharSec, maxCharSec, restrictionMask, activity))
        throw(PyException(MakeUserError("RamInstallationHasNoDefaultContent")));

    // check validity of activity
    if(activity < ramActivityManufacturing || activity > ramActivityInvention)
        throw(PyException(MakeUserError("RamAssemblyLineHasNoActivity")));

    // check security rating if required
    if((restrictionMask & ramRestrictBySecurity) == ramRestrictBySecurity) {
        if(minCharSec > c->GetSecurityRating())
            throw(PyException(MakeUserError("RamAccessDeniedSecStatusTooLow")));

        if(maxCharSec < c->GetSecurityRating())
            throw(PyException(MakeUserError("RamAccessDeniedSecStatusTooHigh")));

        // RamAccessDeniedCorpSecStatusTooHigh
        // RamAccessDeniedCorpSecStatusTooLow
    }

    // check standing if required
    if((restrictionMask & ramRestrictByStanding) == ramRestrictByStanding) {
        // RamAccessDeniedCorpStandingTooLow
        // RamAccessDeniedStandingTooLow
    }

    if((restrictionMask & ramRestrictByAlliance) == ramRestrictByAlliance) {
//      if(...)
            throw(PyException(MakeUserError("RamAccessDeniedWrongAlliance")));
    } else if((restrictionMask & ramRestrictByCorp) == ramRestrictByCorp) {
        if(ownerID != c->GetCorporationID())
            throw(PyException(MakeUserError("RamAccessDeniedWrongCorp")));
    }

    if(args.isCorpJob) {
        if((c->GetCorpRole() & corpRoleFactoryManager) != corpRoleFactoryManager)
            throw(PyException(MakeUserError("RamCannotInstallForCorpByRoleFactoryManager")));

        if(args.activityID == ramActivityManufacturing) {
            if((c->GetCorpRole() & corpRoleCanRentFactorySlot) != corpRoleCanRentFactorySlot)
                throw(PyException(MakeUserError("RamCannotInstallForCorpByRole")));
        } else {
            if((c->GetCorpRole() & corpRoleCanRentResearchSlot) != corpRoleCanRentResearchSlot)
                throw(PyException(MakeUserError("RamCannotInstallForCorpByRole")));
        }
    }

    // INSTALLED ITEM CHECK
    // *********************

    // ownership
    if(args.isCorpJob) {
        if(installedItem->ownerID() != c->GetCorporationID())
            throw(PyException(MakeUserError("RamCannotInstallItemForAnotherCorp")));
    } else {
        if(installedItem->ownerID() != c->GetCharacterID())
            throw(PyException(MakeUserError("RamCannotInstallItemForAnother")));
    }

    // corp hangar permission
    if(    (installedItem->flag() == flagCorpSecurityAccessGroup2 && (c->GetCorpRole() & corpRoleHangarCanTake2) != corpRoleHangarCanTake2)
        || (installedItem->flag() == flagCorpSecurityAccessGroup3 && (c->GetCorpRole() & corpRoleHangarCanTake3) != corpRoleHangarCanTake3)
        || (installedItem->flag() == flagCorpSecurityAccessGroup4 && (c->GetCorpRole() & corpRoleHangarCanTake4) != corpRoleHangarCanTake4)
        || (installedItem->flag() == flagCorpSecurityAccessGroup5 && (c->GetCorpRole() & corpRoleHangarCanTake5) != corpRoleHangarCanTake5)
        || (installedItem->flag() == flagCorpSecurityAccessGroup6 && (c->GetCorpRole() & corpRoleHangarCanTake6) != corpRoleHangarCanTake6)
        || (installedItem->flag() == flagCorpSecurityAccessGroup7 && (c->GetCorpRole() & corpRoleHangarCanTake7) != corpRoleHangarCanTake7)
    )
            throw(PyException(MakeUserError("RamAccessDeniedToBOMHangar")));

    // large location check
    if(IsStation(args.installationContainerID)) {
        if(/*args.isCorpJob && */installedItem->flag() == flagCargoHold)
            throw(PyException(MakeUserError("RamCorpInstalledItemNotInCargo")));

        if(installedItem->locationID() != (uint32)args.installationContainerID) {
            if((uint32)args.installationContainerID == c->GetLocationID()) {
                std::map<std::string, PyRep *> exceptArgs;
                exceptArgs["location"] = new PyString(m_db.GetStationName(args.installationContainerID));

                if(args.isCorpJob)
                    throw(PyException(MakeUserError("RamCorpInstalledItemWrongLocation", exceptArgs)));
                else
                    throw(PyException(MakeUserError("RamInstalledItemWrongLocation", exceptArgs)));
            } else
                throw(PyException(MakeUserError("RamRemoteInstalledItemNotInStation")));
        } else {
            if(args.isCorpJob) {
                if(installedItem->flag() < flagCorpSecurityAccessGroup2 || installedItem->flag() > flagCorpSecurityAccessGroup7) {
                    if((uint32)args.installationContainerID == c->GetLocationID()) {
                        std::map<std::string, PyRep *> exceptArgs;
                        exceptArgs["location"] = new PyString(m_db.GetStationName(args.installationContainerID));

                        throw(PyException(MakeUserError("RamCorpInstalledItemWrongLocation", exceptArgs)));
                    } else
                        throw(PyException(MakeUserError("RamRemoteInstalledItemNotInOffice")));
                }
            } else {
                if(installedItem->flag() != flagHangar) {
                    if((uint32)args.installationInvLocationID == c->GetLocationID()) {
                        std::map<std::string, PyRep *> exceptArgs;
                        exceptArgs["location"] = new PyString(m_db.GetStationName(args.installationContainerID));

                        throw(PyException(MakeUserError("RamInstalledItemWrongLocation", exceptArgs)));
                    } else {
                        throw(PyException(MakeUserError("RamRemoteInstalledItemInStationNotHangar")));
                    }
                }
            }
        }
    } else if((uint32)args.installationContainerID == c->GetShipID()) {
        if(c->GetChar()->flag() != flagPilot)
            throw(PyException(MakeUserError("RamAccessDeniedNotPilot")));

        if(installedItem->locationID() != (uint32)args.installationContainerID)
            throw(PyException(MakeUserError("RamInstalledItemMustBeInShip")));
    } else {
        // here should be stuff around POS, but I dont certainly know how it should work, so ...
        // RamInstalledItemBadLocationStructure
        // RamInstalledItemInStructureNotInContainer
        // RamInstalledItemInStructureUnknownLocation
    }

    // BOM LOCATION CHECK
    // *******************

    // corp hangar permission
    if(    (bomLocation.flag == flagCorpSecurityAccessGroup2 && (c->GetCorpRole() & corpRoleHangarCanTake2) != corpRoleHangarCanTake2)
        || (bomLocation.flag == flagCorpSecurityAccessGroup3 && (c->GetCorpRole() & corpRoleHangarCanTake3) != corpRoleHangarCanTake3)
        || (bomLocation.flag == flagCorpSecurityAccessGroup4 && (c->GetCorpRole() & corpRoleHangarCanTake4) != corpRoleHangarCanTake4)
        || (bomLocation.flag == flagCorpSecurityAccessGroup5 && (c->GetCorpRole() & corpRoleHangarCanTake5) != corpRoleHangarCanTake5)
        || (bomLocation.flag == flagCorpSecurityAccessGroup6 && (c->GetCorpRole() & corpRoleHangarCanTake6) != corpRoleHangarCanTake6)
        || (bomLocation.flag == flagCorpSecurityAccessGroup7 && (c->GetCorpRole() & corpRoleHangarCanTake7) != corpRoleHangarCanTake7)
    )
            throw(PyException(MakeUserError("RamAccessDeniedToBOMHangar")));
}
コード例 #9
0
PyResult RamProxyService::Handle_CompleteJob(PyCallArgs &call) {
    Call_CompleteJob args;

    if(!args.Decode(&call.tuple)) {
        _log(CLIENT__ERROR, "Failed to decode args.");
        return NULL;
    }

    _VerifyCompleteJob(args, call.client);

    // hundreds of variables to allocate ... maybe we can make struct for GetJobProperties and InstallJob?
    uint32 installedItemID, ownerID, runs, licensedProductionRuns;
    EVEItemFlags outputFlag;
    EVERamActivity activity;
    if(!m_db.GetJobProperties(args.jobID, installedItemID, ownerID, outputFlag, runs, licensedProductionRuns, activity))
        return NULL;

    // return item
    InventoryItemRef installedItem = m_manager->item_factory.GetItem( installedItemID );
    if( !installedItem )
        return NULL;
    installedItem->Move( installedItem->locationID(), outputFlag );

    std::vector<RequiredItem> reqItems;
    if( !m_db.GetRequiredItems( installedItem->typeID(), activity, reqItems ) )
        return NULL;

    // return materials which weren't completely consumed
    std::vector<RequiredItem>::iterator cur, end;
    cur = reqItems.begin();
    end = reqItems.end();
    for(; cur != end; cur++) {
        if(!cur->isSkill && cur->damagePerJob != 1.0) {
            uint32 quantity = static_cast<uint32>(cur->quantity * runs * (1.0 - cur->damagePerJob));
            if(quantity == 0)
                continue;

            ItemData idata(
                cur->typeID,
                ownerID,
                0, //temp location
                outputFlag,
                quantity
            );

            InventoryItemRef item = m_manager->item_factory.SpawnItem( idata );
            if( !item )
                return NULL;

            item->Move(args.containerID, outputFlag);
        }
    }

    // if not cancelled, realize result of activity
    if(!args.cancel) {
        switch(activity) {
            /*
             * Manufacturing
             */
            case ramActivityManufacturing: {
                BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

                ItemData idata(
                    bp->productTypeID(),
                    ownerID,
                    0,  // temp location
                    outputFlag,
                    bp->productType().portionSize() * runs
                );

                InventoryItemRef item = m_manager->item_factory.SpawnItem( idata );
                if( !item )
                    return NULL;

                item->Move(args.containerID, outputFlag);
            } break;
            /*
             * Time productivity research
             */
            case ramActivityResearchingTimeProductivity: {
                BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

                bp->AlterProductivityLevel( runs );
            } break;
            /*
             * Material productivity research
             */
            case ramActivityResearchingMaterialProductivity: {
                BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

                bp->AlterMaterialLevel( runs) ;
            } break;
            /*
             * Copying
             */
            case ramActivityCopying: {
                BlueprintRef bp = BlueprintRef::StaticCast( installedItem );

                ItemData idata(
                    installedItem->typeID(),
                    ownerID,
                    0, //temp location
                    outputFlag,
                    runs
                );
                BlueprintData bdata(
                    true,
                    bp->materialLevel(),
                    bp->productivityLevel(),
                    licensedProductionRuns
                );

                BlueprintRef copy = m_manager->item_factory.SpawnBlueprint( idata, bdata );
                if( !copy )
                    return NULL;

                copy->Move(args.containerID, outputFlag);
            } break;
            /*
             * The rest is unsupported
             */
            case ramActivityResearchingTechnology:
            case ramActivityDuplicating:
            case ramActivityReverseEngineering:
            case ramActivityInvention:
            default: {
                _log(SERVICE__ERROR, "Activity %u is currently unsupported.", activity);
            } break;
        }
    }

    // regardless on success of this, we will return NULL, so there's no condition here
    m_db.CompleteJob(args.jobID, args.cancel ? ramCompletedStatusAbort : ramCompletedStatusDelivered);

    return NULL;
}
コード例 #10
0
PyResult RamProxyService::Handle_InstallJob(PyCallArgs &call) {
    Call_InstallJob args;
    if(!args.Decode(&call.tuple)) {
        _log(SERVICE__ERROR, "Failed to decode args.");
        return NULL;
    }

    // load installed item
    InventoryItemRef installedItem = m_manager->item_factory.GetItem( args.installedItemID );
    if( !installedItem )
        return NULL;

    // if output flag not set, put it where it was
    if(args.flagOutput == flagAutoFit)
        args.flagOutput = installedItem->flag();

    // decode path to BOM location
    PathElement pathBomLocation;
    if( !pathBomLocation.Decode( args.bomPath->GetItem(0) ) ) {
        _log(SERVICE__ERROR, "Failed to decode BOM location.");
        return NULL;
    }

    // verify call
    _VerifyInstallJob_Call( args, (InventoryItemRef)installedItem, pathBomLocation, call.client );

    // this calculates some useful multipliers ... Rsp_InstallJob is used as container ...
    Rsp_InstallJob rsp;
    if(!_Calculate(args, (InventoryItemRef)installedItem, call.client, rsp))
        return NULL;

    // I understand sent maxJobStartTime as a limit, so this checks whether it's in limit
    if(rsp.maxJobStartTime > call.byname["maxJobStartTime"]->AsInt()->value())
        throw(PyException(MakeUserError("RamCannotGuaranteeStartTime")));

    // query required items for activity
    std::vector<RequiredItem> reqItems;
    if(!m_db.GetRequiredItems(installedItem->typeID(), (EVERamActivity)args.activityID, reqItems))
        return NULL;

    // if 'quoteOnly' is 1 -> send quote, if 0 -> install job
    if(call.byname["quoteOnly"]->AsInt()->value())
    {
        _EncodeBillOfMaterials(reqItems, rsp.materialMultiplier, rsp.charMaterialMultiplier, args.runs, rsp.bom);
        _EncodeMissingMaterials(reqItems, pathBomLocation, call.client, rsp.materialMultiplier, rsp.charMaterialMultiplier, args.runs, rsp.missingMaterials);

        return rsp.Encode();
    }
    else
    {
        // verify install
        _VerifyInstallJob_Install(rsp, pathBomLocation, reqItems, args.runs, call.client);

        // now we are sure everything from the client side is right, we can start it ...

        // calculate proper start time
        uint64 beginProductionTime = Win32TimeNow();
        if(beginProductionTime < (uint32)rsp.maxJobStartTime)
            beginProductionTime = rsp.maxJobStartTime;

        // register our job
        if( !m_db.InstallJob(
            args.isCorpJob ? call.client->GetCorporationID() : call.client->GetCharacterID(),
            call.client->GetCharacterID(),
            args.installationAssemblyLineID,
            installedItem->itemID(),
            beginProductionTime,
            beginProductionTime + uint64(rsp.productionTime) * Win32Time_Second,
            args.description.c_str(),
            args.runs,
            (EVEItemFlags)args.flagOutput,
            pathBomLocation.locationID,
            args.licensedProductionRuns ) )
        {
            return NULL;
        }

        // do some activity-specific actions
        switch(args.activityID) {
            case ramActivityManufacturing: {
                // decrease licensed production runs
                BlueprintRef bp = BlueprintRef::StaticCast( installedItem );
                if(!bp->infinite())
                    bp->AlterLicensedProductionRunsRemaining(-1);
            }
        }

        // pay for assembly lines, move the item away
        call.client->AddBalance(-rsp.cost);
        installedItem->Move( installedItem->locationID(), flagFactoryBlueprint );

        // query all items contained in "Bill of Materials" location
        std::vector<InventoryItemRef> items;
        _GetBOMItems( pathBomLocation, items );

        std::vector<RequiredItem>::iterator cur, end;
        cur = reqItems.begin();
        end = reqItems.end();
        for(; cur != end; cur++) {
            if(cur->isSkill)
                continue;       // not interested

            // calculate needed quantity
            uint32 qtyNeeded = static_cast<uint32>(ceil(cur->quantity * rsp.materialMultiplier * args.runs));
            if(cur->damagePerJob == 1.0)
                qtyNeeded = static_cast<uint32>(ceil(qtyNeeded * rsp.charMaterialMultiplier));   // skill multiplier is applied only on fully consumed materials

            std::vector<InventoryItemRef>::iterator curi, endi;
            curi = items.begin();
            endi = items.end();
            // consume required materials
            for(; curi != endi; curi++) {
                if((*curi)->typeID() == cur->typeID && (*curi)->ownerID() == call.client->GetCharacterID()) {
                    if(qtyNeeded >= (*curi)->quantity()) {
                        qtyNeeded -= (*curi)->quantity();
                        (*curi)->Delete();
                    } else {
                        (*curi)->AlterQuantity(-(int32)qtyNeeded);
                        break;  // we are done, stop searching
                    }
                }
            }
        }

        return NULL;
    }
}
コード例 #11
0
PyResult ContractMgrService::Handle_GetContract( PyCallArgs& call )
{
	Call_SingleIntegerArg arg;
	PyDict* _contract = new PyDict;

	if( !arg.Decode( &call.tuple ) )
	{
		codelog(SERVICE__ERROR, "%s: Bad arguments to GetContract in contractMgr", call.client->GetCharacterName() );
		return NULL;
	}

	// Manual creation of PyPackedRow
	DBRowDescriptor *header = new DBRowDescriptor();
	header->AddColumn( "contractID",			DBTYPE_I4 );
	header->AddColumn( "issuerID",				DBTYPE_I4 );
	header->AddColumn( "issuerCorpID",			DBTYPE_I4 );
	header->AddColumn( "type",					DBTYPE_UI1 );
	header->AddColumn( "availability",			DBTYPE_I4 );
	header->AddColumn( "assigneeID",			DBTYPE_I4 );
	header->AddColumn( "numDays",				DBTYPE_I4 );
	header->AddColumn( "startStationID",		DBTYPE_I4 );
	header->AddColumn( "endStationID",			DBTYPE_I4 );
	header->AddColumn( "startSolarSystemID",	DBTYPE_I4 );
	header->AddColumn( "endSolarSystemID",		DBTYPE_I4 );
	header->AddColumn( "startRegionID",			DBTYPE_I4 );
	header->AddColumn( "endRegionID",			DBTYPE_I4 );
	header->AddColumn( "price",					DBTYPE_CY );
	header->AddColumn( "reward",				DBTYPE_CY );
	header->AddColumn( "collateral",			DBTYPE_CY );
	header->AddColumn( "title",					DBTYPE_WSTR );
	header->AddColumn( "description",			DBTYPE_WSTR );
	header->AddColumn( "forCorp",				DBTYPE_BOOL );
	header->AddColumn( "status",				DBTYPE_UI1 );
	header->AddColumn( "acceptorID",			DBTYPE_I4 );
	header->AddColumn( "dateIssued",			DBTYPE_FILETIME );
	header->AddColumn( "dateExpired",			DBTYPE_FILETIME );
	header->AddColumn( "dateAccepted",			DBTYPE_FILETIME );
	header->AddColumn( "dateCompleted",			DBTYPE_FILETIME );
	header->AddColumn( "volume",				DBTYPE_R8 );
	header->AddColumn( "issuerAllianceID",		DBTYPE_I4 );
	header->AddColumn( "issuerWalletKey",		DBTYPE_I4 );
	header->AddColumn( "acceptorWalletKey",		DBTYPE_I4 );
	header->AddColumn( "crateID",				DBTYPE_I4 );

	ContractRef contract = m_contractManager->GetContract( arg.arg );
	
	uint32 n = 0;

	PyPackedRow* into = new PyPackedRow( header );
	into->SetField( "contractID",			new PyInt(		contract->contractID() ) );
	into->SetField( "issuerID",				new PyInt(		contract->issuerID() ) );
	into->SetField( "issuerCorpID",			new PyInt(		contract->issuerCorpID() ) );
	into->SetField( "type",					new PyInt(		contract->type() ) );
	into->SetField( "availability",			new PyInt(		contract->avail() ) );
	into->SetField( "assigneeID",			new PyInt(		contract->assigneeID() ) );
	into->SetField( "numDays",				new PyInt(		0 ) );
	into->SetField( "startStationID",		new PyInt(		contract->startStationID() ) );
	into->SetField( "endStationID",			new PyInt(		contract->endStationID() ) );
	into->SetField( "startSolarSystemID",   new PyInt(		contract->startSolarSystemID() ) );
	into->SetField( "endSolarSystemID",		new PyInt(		contract->endSolarSystemID() ) );
	into->SetField( "startRegionID",		new PyInt(		contract->startRegionID() ) );
	into->SetField( "endRegionID",			new PyInt(		contract->endRegionID() ) );
	into->SetField( "price",				new PyFloat(	contract->price() ) );
	into->SetField( "reward",				new PyFloat(	contract->reward() ) );
	into->SetField( "collateral",			new PyFloat(	contract->collateral() ) );
	into->SetField( "title",				new PyString(	"title" ) );
	into->SetField( "description",			new PyString(	"description" ) );
	into->SetField( "forCorp",				new PyBool(		contract->forCorp() ) );
	into->SetField( "status",				new PyInt(		contract->status() ) );
	into->SetField( "acceptorID",			new PyInt(		contract->acceptorID() ) );
	into->SetField( "dateIssued",			new PyLong(		contract->dateIssued() ) );
	into->SetField( "dateExpired",			new PyLong(		contract->dateExpired() ) );
	into->SetField( "dateAccepted",			new PyLong(		contract->dateAccepted() ) );
	into->SetField( "dateCompleted",		new PyLong(		contract->dateCompleted() ) );
	into->SetField( "volume",				new PyFloat(	contract->volume() ) );
	into->SetField( "issuerAllianceID",		new PyInt(		contract->issuerAllianceID() ) );
	into->SetField( "issuerWalletKey",		new PyInt(		contract->issuerWalletKey() ) );
	into->SetField( "acceptorWalletKey",	new PyInt(		0 ) );
	into->SetField( "crateID",				new PyInt(		0 ) );

	PyList* itemList = new PyList;

	DBRowDescriptor *itemHeader = new DBRowDescriptor();
	itemHeader->AddColumn( "contractID",						DBTYPE_I4 );
	itemHeader->AddColumn( "itemID",							DBTYPE_I4 );
	itemHeader->AddColumn( "quantity",							DBTYPE_I4 );
	itemHeader->AddColumn( "itemTypeID",						DBTYPE_I4 );
	itemHeader->AddColumn( "inCrate",							DBTYPE_BOOL );
	itemHeader->AddColumn( "parentID",							DBTYPE_I4 );
	itemHeader->AddColumn( "productivityLevel",					DBTYPE_I4 );
	itemHeader->AddColumn( "materialLevel",						DBTYPE_I4 );
	itemHeader->AddColumn( "copy",								DBTYPE_I4 );
	itemHeader->AddColumn( "licensedProductionRunsRemaining",	DBTYPE_I4 );
	itemHeader->AddColumn( "damage",							DBTYPE_R8 );
	itemHeader->AddColumn( "flagID",							DBTYPE_I2 );

	std::map<uint32, ContractGetItemsRef>::const_iterator cur, end;
	std::map<uint32, ContractGetItemsRef> items = contract->items();

	cur = items.begin();
	end = items.end();

	for(; cur != end; cur++ )
	{
		PyPackedRow* data = new PyPackedRow( itemHeader );

		InventoryItemRef item = m_manager->item_factory.GetItem( cur->second->m_itemID );
		data->SetField( "contractID",							new PyInt(	contract->contractID() ) );
		data->SetField( "itemID",								new PyInt(	item->itemID() ) );
		data->SetField( "quantity",								new PyInt(	cur->second->m_quantity ) );
		data->SetField( "itemTypeID",							new PyInt(	item->typeID() ) );
		data->SetField( "inCrate",								new PyBool(	true ) );

		if( item->categoryID() == EVEDB::invCategories::Blueprint )
		{
			BlueprintRef bp = m_manager->item_factory.GetBlueprint( item->itemID() );
			data->SetField( "parentID",							new PyInt( bp->parentBlueprintTypeID() ) );
			data->SetField( "productivityLevel",				new PyInt( bp->productivityLevel() ) );
			data->SetField( "materialLevel",					new PyInt( bp->materialLevel() ) );
			data->SetField( "copy",								new PyInt( bp->copy() ) );
			data->SetField( "licensedProductionRunsRemaining",	new PyInt( bp->licensedProductionRunsRemaining() ) );

			if( bp->HasAttribute( 3 ) )
				data->SetField( "damage",						new PyFloat( bp->GetAttribute( 3 ).get_float() ) );
			else
				data->SetField( "damage",						new PyFloat( 0.0 ) );

			data->SetField( "flagID",							new PyInt( bp->flag() ) );
		}
		else
		{
			data->SetField( "parentID",							new PyInt( 0 ) );
			data->SetField( "productivityLevel",				new PyInt( 0 ) );
			data->SetField( "materialLevel",					new PyInt( 0 ) );
			data->SetField( "copy",								new PyInt( 0 ) );
			data->SetField( "licensedProductionRunsRemaining",	new PyInt( 0 ) );

			if( item->HasAttribute( 3 ) )
				data->SetField( "damage",						new PyFloat( item->GetAttribute( 3 ).get_float() ) );
			else
				data->SetField( "damage",						new PyFloat( 0.0 ) );

			data->SetField( "flagID",							new PyInt( item->flag() ) );
		}

		itemList->AddItem( data );
	}

	std::map<uint32, ContractRequestItemRef>::const_iterator c, e;
	std::map<uint32, ContractRequestItemRef> requestItems = contract->requestItems();

	c = requestItems.begin();
	e = requestItems.end();

	for(; c != e; c++ )
	{
		PyPackedRow* data = new PyPackedRow( itemHeader );
		data->SetField( "contractID",						new PyInt(	arg.arg ) );
		data->SetField(	"itemID",							new PyInt(	0 ) );
		data->SetField(	"quantity",							new PyInt(	c->second->m_quantity ) );
		data->SetField(	"itemTypeID",						new PyInt(	c->second->m_typeID ) );
		data->SetField( "inCrate",							new PyBool( false ) );
		data->SetField(	"parentID",							new PyInt(  0 ) );
		data->SetField( "productivityLevel",				new PyInt(  0 ) );
		data->SetField( "materialLevel",					new PyInt(  0 ) );
		data->SetField( "copy",								new PyInt(	0 ) );
		data->SetField( "licensedProductionRunsRemaining",	new PyInt(   0 ) );
		data->SetField( "damage",							new PyFloat( 0.0 ) );
		data->SetField( "flagID",							new PyInt(   0 ) );

		itemList->AddItem( data );
	}

	DBRowDescriptor *bidsHeader = new DBRowDescriptor();
	bidsHeader->AddColumn( "bidID",					DBTYPE_I4 );
	bidsHeader->AddColumn( "contractID",			DBTYPE_I4 );
	bidsHeader->AddColumn( "issuerID",				DBTYPE_I4 );
	bidsHeader->AddColumn( "quantity",				DBTYPE_I4 );
	bidsHeader->AddColumn( "issuerCorpID",			DBTYPE_I4 );
	bidsHeader->AddColumn( "issuerStationID",		DBTYPE_I4 );
	bidsHeader->AddColumn( "issuerSolarSystemID",	DBTYPE_I4 );
	bidsHeader->AddColumn( "issuerRegionID",		DBTYPE_I4 );
	CRowSet *bids_rowset = new CRowSet( &bidsHeader );

	_contract->SetItemString( "items",		itemList );
	_contract->SetItemString( "bids",		bids_rowset );
	_contract->SetItemString( "contract",	into);

	PyObject* res = new PyObject( new PyString( "util.KeyVal" ), _contract );

	return res;
}