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 ); } } }
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 ); }
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 ); }
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; }
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() ) ); }
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; }
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; }
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; }
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 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; }
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; }
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"); }
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; }