void Contract::Delete() { // Return the items to the hangar std::map<uint32, ContractGetItemsRef>::iterator cur, end; cur = items().begin(); end = items().end(); for(; cur != end; cur++) { InventoryItemRef item = m_itemFactory.GetItem( cur->second->m_itemID ); item->Move( startStationID(), flagHangar, true ); item->ChangeOwner( issuerID(), true ); } // take ourself out of the DB m_factory.db().DeleteContract( contractID() ); // Delete ourselves from factory cache m_factory.DeleteContract( contractID() ); }
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!" ) ); } } } }
PyResult ContractMgrService::Handle_CreateContract( PyCallArgs& call ) { Call_CreateContract info; PyList* requestItemTypeList = new PyList; PyList* itemList = new PyList; uint32 flag = 0; bool forCorp = false; double volume = 0; uint32 maxCharContracts = 0; if( call.byname.find( "forCorp" ) != call.byname.end() ) { forCorp = call.byname.find( "forCorp" )->second->AsBool()->value(); } // Let's see the players limit of contracts CharacterRef ch = call.client->GetChar(); if( forCorp ) { if( ch->HasSkill( 25233 ) ) { SkillRef skill = ch->GetSkill( 25233 ); uint32 skillLevel = skill->GetAttribute( 280 ).get_int(); maxCharContracts = ( 10 * skillLevel ) + 10; } else { maxCharContracts = 10; } } else { if( ch->HasSkill( 25235 ) ) { SkillRef skill = ch->GetSkill( 25235 ); uint32 skillLevel = skill->GetAttribute( 280 ).get_int(); maxCharContracts = ( 4 * skillLevel ) + 1; } else { maxCharContracts = 1; } uint32 numOutstandingContractsNonCorp = 0; uint32 numOutstandingContractsForCorp = 0; std::map<uint32, ContractRef>::const_iterator cur, end; std::map<uint32, ContractRef> contracts = m_contractManager->GetContractList(); cur = contracts.begin(); end = contracts.end(); for(; cur != end; cur++ ) { ContractRef contract = cur->second; if( contract->issuerID() == call.client->GetCharacterID() ) { if( contract->forCorp() ) numOutstandingContractsForCorp += 1; else numOutstandingContractsNonCorp += 1; } } if( ( forCorp ) && ( numOutstandingContractsForCorp >= maxCharContracts ) ) { call.client->SendInfoModalMsg( "Your Corporation Contracting skill level only allows you to create %d public contracts for your corp/alliance", maxCharContracts ); return new PyBool( false ); } if( ( !forCorp ) && ( numOutstandingContractsNonCorp >= maxCharContracts ) ) { call.client->SendInfoModalMsg( "Your Contracting skill level only allows you to create %d public contracts", maxCharContracts ); return new PyBool( false ); } } if( !info.Decode( &call.tuple ) ) { codelog(SERVICE__ERROR, "%s: Bad arguments to CreateContract in contractMgr", call.client->GetCharacterName() ); return NULL; } if( call.byname.find( "requestItemTypeList" ) != call.byname.end() ) { requestItemTypeList = call.byname.find( "requestItemTypeList" )->second->AsList(); } if( call.byname.find( "flag" ) != call.byname.end() ) { flag = call.byname.find( "flag" )->second->AsInt()->value(); } if( call.byname.find( "itemList" ) != call.byname.end() ) { itemList = call.byname.find( "itemList" )->second->AsList(); } if( info.endStationID == 0 )info.endStationID = info.startStationID; ContractData* cData = new ContractData( call.client->GetCharacterID(), call.client->GetCorporationID(), info.type, info.avail, info.assigneeID, info.expiretime, info.expiretime, info.startStationID, info.endStationID, call.client->GetSystemID(), call.client->GetSystemID(), call.client->GetRegionID(), call.client->GetRegionID(), info.price, info.reward, info.collateral, info.title, info.description, forCorp, conStatusOutstanding, false, 0, Win32TimeNow(), Win32TimeNow() + ( info.duration * Win32Time_Day ), Win32TimeNow(), Win32TimeNow(), 0, false, 0, 0, 0 ); std::map<uint32, ContractRequestItemRef> requestItems; std::map<uint32, ContractGetItemsRef> items; uint32 itemID = 0; uint32 typeID = 0; for( size_t i = 0; i < itemList->size(); i ++ ) { if( itemList->IsList() ) { if( itemList->GetItem( i )->AsList()->GetItem( 0 )->IsInt() ) itemID = itemList->GetItem( i )->AsList()->GetItem( 0 )->AsInt()->value(); else{ sLog.Error( "ContractMgrService", "Wrong list args" ); break; } } InventoryItemRef item = m_manager->item_factory.GetItem( itemID ); if( item == NULL ) { sLog.Error( "ContractMgrService", "GetItem returned NULL" ); break; } item->Move( call.client->GetStationID(), flagBriefcase, true ); item->ChangeOwner( 1, true ); items.insert( std::make_pair( itemID, ContractGetItemsRef( new ContractGetItems( itemID, itemList->GetItem( i )->AsList()->GetItem( 1 )->AsInt()->value() ) ) ) ); } if( cData->m_type == conTypeItemExchange ) { for( size_t i = 0; i < requestItemTypeList->size(); i ++ ) { if( itemList->IsList() ) { if( requestItemTypeList->GetItem( i )->AsList()->GetItem( 0 )->IsInt() ) typeID = requestItemTypeList->GetItem( i )->AsList()->GetItem( 0 )->AsInt()->value(); else{ sLog.Error( "ContractMgrService", "Wrong list args" ); break; } } requestItems.insert( std::make_pair( itemID, ContractRequestItemRef( new ContractRequestItem(itemID, requestItemTypeList->GetItem( i )->AsList()->GetItem( 1 )->AsInt()->value() ) ) ) ); } } uint32 contractID = 0; sLog.Debug( "ContractMgrService", "Creating contract..." ); ContractRef _contract = ContractRef( new Contract( contractID, *cData, requestItems, items, m_manager->item_factory, *m_contractManager ) ); contractID = m_contractManager->CreateContract( _contract ); sLog.Debug( "ContractMgrService", "Contract created" ); return new PyInt( contractID ); }