示例#1
0
void Inventory::StackAll(EVEItemFlags locFlag, uint32 forOwner)
{
    std::map<uint32, InventoryItemRef> types;

    std::map<uint32, InventoryItemRef>::iterator cur, end;
    cur = mContents.begin();
    end = mContents.end();
    for(; cur != end; )
    {
        // Iterator becomes invalid when the item
        // is moved out; we have to increment before
        // calling Merge().
        InventoryItemRef i = cur->second;
        cur++;

        if( !i->singleton() && ( forOwner == 0 || forOwner == i->ownerID() ) )
        {
            std::map<uint32, InventoryItemRef>::iterator res = types.find( i->typeID() );
            if( res == types.end() )
                types.insert( std::make_pair( i->typeID(), i ) );
            else
                res->second->Merge( i );
        }
    }
}
示例#2
0
void Character::PlugImplant( uint32 itemID )
{
	// Get itemID, change its location to characterID
	// and change the flag to flagImplant
	// So now its on character's brain
	InventoryItemRef item = m_factory.GetItem( itemID );

	// First of all check if we already have this
	Implants::iterator cur, end;

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

	for(; cur != end; cur++ )
	{
		InventoryItemRef implant = m_factory.GetItem( cur->itemID );

		if( implant == NULL ) return;

		// Ok, we already have this booster, return
		if( item->typeID() == implant->typeID() ) return;
	}

	item->MoveInto( *this, flagImplant );

	EvilNumber num = 1;
	item->SetAttribute( AttrIsOnline, num, true );
	item->SaveAttributes();

	cImplants i;
	i.itemID = itemID;

	m_implants.push_back( i );
}
示例#3
0
void Character::PlugBooster( uint32 itemID )
{
	// Get itemID, change its location to characterID
	// and change the flag to flagBooster
	// So now its on character's brain
	InventoryItemRef item = m_factory.GetItem( itemID );

	// First of all check if we already have this
	Boosters::iterator cur, end;

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

	for(; cur != end; cur++ )
	{
		InventoryItemRef booster = m_factory.GetItem( cur->itemID );

		if( booster == NULL ) return;
		// Ok, we already have this booster, return
		if( item->typeID() == booster->typeID() )return;
	}

	item->MoveInto( *this, flagBooster );

	EvilNumber num = 1;
	item->SetAttribute( AttrIsOnline, num, true );
	item->SaveAttributes();

	cBoosters i;
	i.itemID = itemID;
	i.plugDate = Win32TimeNow();
	i.expiretime = item->GetAttribute( AttrBoosterDuration ).get_int();

	m_boosters.push_back( i );
}
示例#4
0
bool InventoryItem::Merge(InventoryItemRef to_merge, int32 qty, bool notify) {
    if(typeID() != to_merge->typeID()) {
        _log(ITEM__ERROR, "%s (%u): Asked to merge with %s (%u).", itemName().c_str(), itemID(), to_merge->itemName().c_str(), to_merge->itemID());
        return false;
    }
    if(locationID() != to_merge->locationID() || flag() != to_merge->flag()) {
        _log(ITEM__ERROR, "%s (%u) in location %u, flag %u: Asked to merge with item %u in location %u, flag %u.", itemName().c_str(), itemID(), locationID(), flag(), to_merge->itemID(), to_merge->locationID(), to_merge->flag());
        return false;
    }
    if(qty == 0)
        qty = to_merge->quantity();
    if(qty <= 0) {
        _log(ITEM__ERROR, "%s (%u): Asked to merge with %d units of item %u.", itemName().c_str(), itemID(), qty, to_merge->itemID());
        return false;
    }
    if(!AlterQuantity(qty, notify)) {
        _log(ITEM__ERROR, "%s (%u): Failed to add quantity %d.", itemName().c_str(), itemID(), qty);
        return false;
    }

    if(qty == to_merge->quantity()) {
        to_merge->Delete();
    } else if(!to_merge->AlterQuantity(-qty, notify)) {
        _log(ITEM__ERROR, "%s (%u): Failed to remove quantity %d.", to_merge->itemName().c_str(), to_merge->itemID(), qty);
        return false;
    }

    return true;
}
示例#5
0
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() ) );
}
示例#6
0
bool MiningLaser::canActivate(SystemEntity *targetEntity)
{
    if(targetEntity == nullptr)
    {
        return false;
    }
    InventoryItemRef miner = getItem();
    bool isIceMiner = (miner->typeID() == 16278 || miner->typeID() == 22229 || miner->typeID() == 28752);
    if (isIceMiner)
    {
        // Only allow ice harvesters to mine ice.
        if (targetEntity->Item()->groupID() != EVEDB::invGroups::Ice)
        {
            SysLog::Error("MiningLaser::Activate()", "ERROR: invalid target!");
            throw PyException(MakeCustomError("ERROR!  invalid target!"));
        }
    }
    else if (miner->groupID() == EVEDB::invGroups::Gas_Cloud_Harvester)
    {
        // Gas cloud harvesters only allowed to harvest gas.
        if (targetEntity->Item()->groupID() != EVEDB::invGroups::Harvestable_Cloud)
        {
            SysLog::Error("MiningLaser::Activate()", "ERROR: invalid target!");
            throw PyException(MakeCustomError("ERROR!  invalid target!"));
        }
    }
        // Only thing left are astroid miners.
    else if (targetEntity->Item()->categoryID() != EVEDB::invCategories::Asteroid)
    {
        // We are not targeting an asteroid.
        SysLog::Error("MiningLaser::Activate()", "ERROR: invalid target!");
        throw PyException(MakeCustomError("ERROR!  invalid target!"));
    }
    // We have a valid target, are we in range?
    double maxRange = miner->GetAttribute(AttrMaxRange).get_float();
    double targetRange = targetEntity->DistanceTo2(m_ship->GetOperator()->GetSystemEntity());
    targetRange = std::sqrt(targetRange);
    targetRange -= targetEntity->GetRadius();
    if (targetRange > maxRange)
    {
        // We are not targeting a valid target.
        // TO-DO: send proper out or range response.
        SysLog::Error("MiningLaser::Activate()", "ERROR: Cannot activate mining laser target out of range! (%f/%f)", targetRange, maxRange);
        throw PyException(MakeCustomError("ERROR!  Cannot activate mining laser target out of range! (%f/%f)", targetRange, maxRange));
    }
    return true;
}
示例#7
0
bool Character::HasImplant( uint32 implantTypeID )
{
	uint32 i = 0;
	for( i = 0; i < m_implants.size(); i++ )
	{
		InventoryItemRef item = m_factory.GetItem( m_implants.at( i ).itemID );
		if( item->typeID() == implantTypeID ) return true;
	}
	
	return false;
}
示例#8
0
bool Character::HasBooster( uint32 boosterTypeID )
{
	uint32 i = 0;
	for( i = 0; i < m_boosters.size(); i++ )
	{
		InventoryItemRef item = m_factory.GetItem( m_boosters.at( i ).itemID );
		if( item->typeID() == boosterTypeID ) return true;
	}

	return false;
}
示例#9
0
void ModuleManager::LoadCharge(InventoryItemRef chargeRef, EVEItemFlags flag)
{
    ActiveModule * mod = (ActiveModule *)(m_Modules->GetModule(flag));			// Should not be dangrous to assume ALL modules where charges are loaded are ACTIVE modules
    if( mod != NULL )
    {
		// Scenarios to handle:
		// + no charge loaded: check capacity >= volume of charge to add, if true, LOAD
		//     - ELSE: if charge to load is qty > 1, calculate smallest integer qty that will EQUAL capacity, SPLIT remainder off, then LOAD!
		// + some charge loaded: check capacity >= volume of charge to add, if true, MERGE new charge to existing
		//     - ELSE: if charge to load is qty > 1, calculate smallest integer qty that added to existing charge qty will EQUAL capacity, SPLIT remainder off, then LOAD!

		// Key facts to get:
		// * existing charge ref -> qty and volume/unit
		// * module ref -> capacity of module
		// * charge to add ref -> qty and volume/unit

		EvilNumber modCapacity = mod->getItem()->GetAttribute(AttrCapacity);
		EvilNumber chargeToLoadVolume = chargeRef->GetAttribute(AttrVolume);
		EvilNumber chargeToLoadQty = EvilNumber(chargeRef->quantity());

		/////////////////////////////////////////
		// chargeRef->Split();
		// chargeRef->Merge();
		// mod->Load(chargeRef);
		// chargeRef->Move(m_Ship->itemID(), flag);		// used to be (m_pOperator->GetLocationID(), flag)
		/////////////////////////////////////////

		//m_Ship->GetOperator()->Client()->MoveItem(chargeRef->itemID(), m_Ship->itemID(), flag);

		if( mod->isLoaded() )
		{
			// Module is loaded, let's check available capacity:
			InventoryItemRef loadedChargeRef = mod->getLoadedChargeRef();
			EvilNumber loadedChargeVolume = loadedChargeRef->GetAttribute(AttrVolume);
			EvilNumber loadedChargeQty = EvilNumber(loadedChargeRef->quantity());
			modCapacity -= (loadedChargeVolume * loadedChargeQty);		// Calculate remaining capacity
			if( chargeRef->typeID() != loadedChargeRef->typeID() )
			{
				// Different charge type is being swapped into this module, so unload what's loaded
				if( IsStation(m_Ship->GetOperator()->GetLocationID()) )
					loadedChargeRef->Move(m_Ship->locationID(), flagHangar);
				else
				{
					m_Ship->ValidateAddItem(flagCargoHold,loadedChargeRef);
					loadedChargeRef->Move(m_Ship->itemID(), flagCargoHold);
				}
				mod->unload();

				// Loading of charge will be performed below
			}
			else
			{
				if( modCapacity > chargeToLoadVolume )
				{
					// Great!  We can load at least one, let's top off the loaded charges:
					uint32 quantityWeCanLoad = floor((modCapacity / chargeToLoadVolume).get_float());
					if( quantityWeCanLoad > 0 )
					{
						if( quantityWeCanLoad < chargeToLoadQty.get_int() )
						{
							// Split chargeRef to qty 'quantityWeCanLoad'
							// Merge new smaller qty 'quantityWeCanLoad' with loadedChargeRef
							// Load this merged charge Ref into module
							InventoryItemRef loadableChargeQtyRef = chargeRef->Split( quantityWeCanLoad );
							loadableChargeQtyRef->ChangeOwner( chargeRef->ownerID() );
							loadedChargeRef->Merge( loadableChargeQtyRef );
							mod->load( loadedChargeRef );
							loadedChargeRef->Move(m_Ship->itemID(), flag);		// used to be (m_pOperator->GetLocationID(), flag)
						}
						else
						{
							// Merge chargeRef with loadedChargeRef
							// Load this merged charge Ref into module
							loadedChargeRef->Merge( chargeRef );
							mod->load( loadedChargeRef );
							loadedChargeRef->Move(m_Ship->itemID(), flag);		// used to be (m_pOperator->GetLocationID(), flag)
						}
					}
					else
						throw PyException( MakeCustomError( "Cannot load even one unit of this charge!" ) );
				}
				else
				{
					throw PyException( MakeCustomError( "Charge is full!" ) );
				}
			}
		}

		// Refresh ammo capacity of module in case it was modified in previous code block ahead of a load action:
		modCapacity = mod->getItem()->GetAttribute(AttrCapacity);

		// Load charge supplied if this module was either never loaded, or just unloaded from a different type right above:
		if( !(mod->isLoaded()) )
		{
			// Module is not loaded at all, let's check total volume of charge to load against available capacity:
			if( modCapacity >= (chargeToLoadVolume * chargeToLoadQty) )
			{
				// We can insert entire stack of chargeRef into module
				// Load chargeRef as-is into module
				mod->load( chargeRef );
				chargeRef->Move(m_Ship->itemID(), flag);		// used to be (m_pOperator->GetLocationID(), flag)
			}
			else
			{
				// We need to split off only as many charge units as can fit into this module
				// Split chargeRef
				uint32 quantityWeCanLoad = floor((modCapacity / chargeToLoadVolume).get_float());
				if( quantityWeCanLoad > 0 )
				{
					// Split chargeRef to qty 'quantityWeCanLoad'
					// Merge new smaller qty 'quantityWeCanLoad' with loadedChargeRef
					// Load this merged charge Ref into module
					InventoryItemRef loadableChargeQtyRef = chargeRef->Split( quantityWeCanLoad );
					loadableChargeQtyRef->ChangeOwner( chargeRef->ownerID() );
					mod->load( loadableChargeQtyRef );
					loadableChargeQtyRef->Move(m_Ship->itemID(), flag);		// used to be (m_pOperator->GetLocationID(), flag)
				}
				else
		            throw PyException( MakeCustomError( "Cannot load even one unit of this charge!" ) );
			}
		}
    }
}
示例#10
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;
}
示例#11
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;
    }
}
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;
}
示例#13
0
PyResult Command_giveskill( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args )
{

	uint32 typeID;
	uint8 level;
	CharacterRef character;
	EVEItemFlags flag;
	uint32 gty = 1;
	//uint8 oldSkillLevel = 0;
    EvilNumber oldSkillLevel(0);
	uint32 ownerID = 0;

	if( args.argCount() == 4 )
	{  
		if( args.isNumber( 1 ) )
		{
			ownerID = atoi( args.arg( 1 ).c_str() );
			character = services->entity_list.FindCharacter( ownerID )->GetChar();
		}
		else if( args.arg( 1 ) == "me" )
		{
			ownerID = who->GetCharacterID();
			character = who->GetChar();
		}
		else if( !args.isNumber( 1 ) )
		{
			const char *name = args.arg( 1 ).c_str();
			Client *target = services->entity_list.FindCharacter( name );
			if(target == NULL)
				throw PyException( MakeCustomError( "Cannot find Character by the name of %s", name ) );
			ownerID = target->GetCharacterID();
		}
		else
			throw PyException( MakeCustomError( "Argument 1 must be Character ID or Character Name ") );


		if( !args.isNumber( 2 ) )
			throw PyException( MakeCustomError( "Argument 2 must be type ID." ) );
		typeID = atoi( args.arg( 2 ).c_str() );
	
		if( !args.isNumber( 3 ) )
			throw PyException( MakeCustomError( "Argument 3 must be level" ) );
		level = atoi( args.arg( 3 ).c_str() );
	
		//levels don't go higher than 5
		if( level > 5 )
			level = 5;
	} else
		throw PyException( MakeCustomError("Correct Usage: /giveskill [Character Name or ID] [skillID] [desired level]") );

    SkillRef skill;

	if(character->HasSkill( typeID ) )
	{
        // Character already has this skill, so let's get the current level and check to see
        // if we need to update its level to what's required:
		SkillRef oldSkill = character->GetSkill( typeID );
        oldSkillLevel = oldSkill->GetAttribute( AttrSkillLevel );

        // Now check the current level to the required level and update it 
        if( oldSkillLevel < level )
        {
            character->InjectSkillIntoBrain( oldSkill, level);
            return new PyString ( "Gifting skills complete" );
        }
    }
    else
    {
        // Character DOES NOT have this skill, so spawn a new one and then add this
        // to the character with required level and skill points:
	    ItemData idata(
		    typeID,
		    ownerID,
		    0, //temp location
		    flag = (EVEItemFlags)flagSkill,
		    gty
	    );

	    InventoryItemRef item = services->item_factory.SpawnItem( idata );
	    skill = SkillRef::StaticCast( item );

	    if( !item )
		    throw PyException( MakeCustomError( "Unable to create item of type %s.", item->typeID() ) );

        character->InjectSkillIntoBrain( skill, level);
		return new PyString ( "Gifting skills complete" );
    }

	return new PyString ("Skill Gifting Failure");
}
示例#14
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;
}