void Ship::RemoveRig( InventoryItemRef item, uint32 inventoryID ) { m_ModuleManager->UninstallRig(item->itemID()); //move the item to the void or w/e m_pOperator->MoveItem(item->itemID(), inventoryID, flagAutoFit); //delete the item item->Delete(); }
void Inventory::AddItem(InventoryItemRef item) { std::map<uint32, InventoryItemRef>::iterator res = mContents.find( item->itemID() ); if( res == mContents.end() ) { mContents.insert( std::make_pair( item->itemID(), item ) ); sLog.Debug("Inventory", "Updated location %u to contain item %u with flag %d.", inventoryID(), item->itemID(), (int)item->flag() ); } //else already here sLog.Debug("Inventory", "unable to updated location %u to contain item %u with flag %d, because it already happend.", inventoryID(), item->itemID(), (int)item->flag() ); }
void Ship::RemoveItem(InventoryItemRef item, uint32 inventoryID, EVEItemFlags flag) { //coming from ship, we need to deactivate it and remove mass if it isn't a charge if( item->categoryID() != EVEDB::invCategories::Charge ) { m_pOperator->GetShip()->Deactivate( item->itemID(), "online" ); // m_pOperator->GetShip()->Set_mass( m_pOperator->GetShip()->mass() - item->massAddition() ); //m_pOperator->GetShip()->SetAttribute(AttrMass, m_pOperator->GetShip()->GetAttribute(AttrMass) - item->GetAttribute(AttrMassAddition) ); m_pOperator->GetShip()->UnloadModule( item->itemID() ); } //Move New item to its new location m_pOperator->MoveItem(item->itemID(), inventoryID, flag); }
void Inventory::RemoveItem(InventoryItemRef item) { std::map<uint32, InventoryItemRef>::iterator res = mContents.find( item->itemID() ); if( res != mContents.end() ) { mContents.erase( res ); sLog.Debug("Inventory", "Updated location %u to no longer contain item %u.", inventoryID(), item->itemID() ); } else { sLog.Debug("Inventory", "unable to remove %u from %u.", item->itemID(), inventoryID() ); } }
void Ship::RemoveRig( InventoryItemRef item, uint32 inventoryID ) { m_ModuleManager->UnfitModule(item->itemID()); //delete the item item->Delete(); }
void Ship::RemoveItem(InventoryItemRef item, uint32 inventoryID, EVEItemFlags flag) { // If item IS a module and it's being removed from a slot: if( (item->categoryID() == EVEDB::invCategories::Module) && ((item->flag() >= flagLowSlot0) && (item->flag() <= flagHiSlot7)) ) { m_pOperator->GetShip()->Deactivate( item->itemID(), "online" ); // m_pOperator->GetShip()->Set_mass( m_pOperator->GetShip()->mass() - item->massAddition() ); //m_pOperator->GetShip()->SetAttribute(AttrMass, m_pOperator->GetShip()->GetAttribute(AttrMass) - item->GetAttribute(AttrMassAddition) ); m_pOperator->GetShip()->UnloadModule( item->itemID() ); } // If item IS a rig and it's being removed from a slot: if( (item->categoryID() == EVEDB::invCategories::Module) && ((item->flag() >= flagRigSlot0) && (item->flag() <= flagRigSlot7)) ) { // Don't know what to do when removing a Rig... yet ;) } // If item IS a rig and it's being removed from a slot: if( (item->categoryID() == EVEDB::invCategories::Subsystem) && ((item->flag() >= flagSubSystem0) && (item->flag() <= flagSubSystem7)) ) { // Don't know what to do when removing a Subsystem... yet ;) } // if item being removed IS a charge, it needs to be removed via Module Manager so modules know charge is removed, // BUT, only if it is loaded into a module in one of the 3 slot banks, so we also check its flag value: if( (item->categoryID() == EVEDB::invCategories::Charge) && ((item->flag() >= flagLowSlot0) && (item->flag() <= flagHiSlot7)) ) { m_ModuleManager->UnloadCharge(item->flag()); } if( item->flag() == flag ) // Item's already been moved, let's return return; // Move New item to its new location: if( !( ((item->flag() >= flagLowSlot0) && (item->flag() <= flagHiSlot7)) || ((item->flag() >= flagRigSlot0) && (item->flag() <= flagRigSlot7)) || ((item->flag() >= flagSubSystem0) && (item->flag() <= flagSubSystem7)) ) ) { _DecreaseCargoHoldsUsedVolume(item->flag(), (item->getAttribute(AttrVolume).get_float() * item->quantity())); m_pOperator->MoveItem(item->itemID(), inventoryID, flag); } else { m_pOperator->MoveItem(item->itemID(), inventoryID, flag); } }
InventoryItemRef ItemFactory::SpawnItem(ItemData &data) { InventoryItemRef i = InventoryItem::Spawn(*this, data); if( !i ) return InventoryItemRef(); // spawn successful; store the ref m_items.insert( std::make_pair( i->itemID(), i ) ); return i; }
bool ModuleManager::FitModule(InventoryItemRef item, EVEItemFlags flag) { if(item->categoryID() == EVEDB::invCategories::Module) { // Attempt to fit the module if( _fitModule(item, flag) ) { // Now that module is successfully fitted, attempt to put it Online: Online(item->itemID()); return true; } } else SysLog::Debug("ModuleManager","%s tried to fit item %u, which is not a module", m_Ship->GetOperator()->GetName(), item->itemID()); return false; }
bool Ship::AlterCargoQty(InventoryItemRef item, int qtyChange) { // Make sure we actually contain this item! if (!Contains(item->itemID())) { // We don't contain it, sorry! return false; } // Calculate total volume needed. double volumeNeed = item->getAttribute(AttrVolume).get_float() * qtyChange; // Get remaining volume. double remain = GetRemainingCapacity(item->flag()); if (remain >= volumeNeed) { // We have enough space remaining, add the items. item->AlterQuantity(qtyChange); // Adjust the remaining volume. _IncreaseCargoHoldsUsedVolume(item->flag(), volumeNeed); return true; } return false; }
uint32 Ship::AddItem(EVEItemFlags flag, InventoryItemRef item) { ValidateAddItem( flag, item ); //it's a new module, make sure it's state starts at offline so that it is added correctly if( item->categoryID() == EVEDB::invCategories::Module ) item->PutOffline(); switch( item->categoryID() ) { case EVEDB::invCategories::Charge: { m_ModuleManager->LoadCharge(item, flag); InventoryItemRef loadedChargeOnModule = m_ModuleManager->GetLoadedChargeOnModule(flag); if( loadedChargeOnModule ) { return loadedChargeOnModule->itemID(); } else return 0; } break; case EVEDB::invCategories::Module: if( m_ModuleManager->FitModule(item, flag) ) item->Move(itemID(), flag); break; // The default case handles ANY other items added to ship and assumes they go into one of the valid cargo holds on this ship: default: //Log::Error( "Ship::AddItem(flag,item)", "ERROR! Function called with item '%s' (id: %u) of category neither Charge nor Module!", item->itemName().c_str(), item->itemID() ); _IncreaseCargoHoldsUsedVolume(item->flag(), (item->getAttribute(AttrVolume).get_float() * item->quantity())); item->Move(itemID(), flag); break; } return 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; }
ModuleManager::ModuleManager(Ship *const ship) { // Create ModuleContainer object and initialize with sizes for all slot banks for this ship: m_Modules = new ModuleContainer((uint32)ship->GetAttribute(AttrLowSlots).get_int(), (uint32)ship->GetAttribute(AttrMedSlots).get_int(), (uint32)ship->GetAttribute(AttrHiSlots).get_int(), (uint32)ship->GetAttribute(AttrRigSlots).get_int(), (uint32)ship->GetAttribute(AttrSubSystemSlot).get_int(), (uint32)ship->GetAttribute(AttrTurretSlotsLeft).get_int(), (uint32)ship->GetAttribute(AttrLauncherSlotsLeft).get_int(), this); // Store reference to the Ship object to which the ModuleManager belongs: m_Ship = ship; // Initialize the log file for this Module Manager instance std::string logsubdirectory = "ModuleManagers"; //std::string logfilename = "On_Ship_" + m_Ship->itemName(); // This method using ship's name string may NOT be path friendly as players naming ships may use path-unfriendly characters - need function to convert to path-friendly ship name string std::string logfilename = "On_Ship_" + m_Ship->itemName() + "_(" + std::string(itoa(m_Ship->itemID())) + ")"; m_pLog = new Task_Log( EVEServerConfig::files.logDir, logsubdirectory, logfilename ); m_pLog->InitializeLogging( EVEServerConfig::files.logDir, logsubdirectory, logfilename ); // Load modules, rigs and subsystems from Ship's inventory into ModuleContainer: m_pLog->Log("ModuleManager", "Loading modules..."); uint32 flagIndex; for(flagIndex=flagLowSlot0; flagIndex<=flagLowSlot7; flagIndex++) { InventoryItemRef moduleRef; InventoryItemRef chargeRef; std::vector<InventoryItemRef>::iterator cur, end; std::vector<InventoryItemRef> items; m_Ship->FindByFlag( (EVEItemFlags)flagIndex, items ); // Operator assumed to be Client * cur = items.begin(); end = items.end(); if( items.size() > 0 ) { while( (cur != end) ) { if( cur->get()->categoryID() == EVEDB::invCategories::Charge ) chargeRef = (*cur); if( cur->get()->categoryID() == EVEDB::invCategories::Module ) moduleRef = (*cur); cur++; } if( moduleRef ) { if( _fitModule( moduleRef, (EVEItemFlags)flagIndex ) ) { //_fitModule( moduleRef, (EVEItemFlags)flagIndex ); if( moduleRef->GetAttribute(AttrIsOnline).get_int() == 1 ) Online(moduleRef->itemID()); else Offline(moduleRef->itemID()); if( chargeRef ) ((ActiveModule *)GetModule((EVEItemFlags)flagIndex))->load(chargeRef); } else { SysLog::Error( "ModuleManager::ModuleManager()", "ERROR: Cannot fit Low Slot module '%s' (id %u)", moduleRef->itemName().c_str(), moduleRef->itemID() ); throw PyException( MakeCustomError( "ERROR! Cannot fit Low Slot module '%s'", moduleRef->itemName().c_str() ) ); } } } } for(flagIndex=flagMedSlot0; flagIndex<=flagMedSlot7; flagIndex++) { InventoryItemRef moduleRef; InventoryItemRef chargeRef; std::vector<InventoryItemRef>::iterator cur, end; std::vector<InventoryItemRef> items; m_Ship->FindByFlag( (EVEItemFlags)flagIndex, items ); // Operator assumed to be Client * cur = items.begin(); end = items.end(); if( items.size() > 0 ) { while( (cur != end) ) { if( cur->get()->categoryID() == EVEDB::invCategories::Charge ) chargeRef = (*cur); if( cur->get()->categoryID() == EVEDB::invCategories::Module ) moduleRef = (*cur); cur++; } if( moduleRef ) { if( _fitModule( moduleRef, (EVEItemFlags)flagIndex ) ) { //_fitModule( moduleRef, (EVEItemFlags)flagIndex ); if( moduleRef->GetAttribute(AttrIsOnline).get_int() == 1 ) Online(moduleRef->itemID()); else Offline(moduleRef->itemID()); if( chargeRef ) ((ActiveModule *)GetModule((EVEItemFlags)flagIndex))->load(chargeRef); } else { SysLog::Error( "ModuleManager::ModuleManager()", "ERROR: Cannot fit Med Slot module '%s' (id %u)", moduleRef->itemName().c_str(), moduleRef->itemID() ); throw PyException( MakeCustomError( "ERROR! Cannot fit Med Slot module '%s'", moduleRef->itemName().c_str() ) ); } } } } for(flagIndex=flagHiSlot0; flagIndex<=flagHiSlot7; flagIndex++) { InventoryItemRef moduleRef; InventoryItemRef chargeRef; std::vector<InventoryItemRef>::iterator cur, end; std::vector<InventoryItemRef> items; m_Ship->FindByFlag( (EVEItemFlags)flagIndex, items ); // Operator assumed to be Client * cur = items.begin(); end = items.end(); if( items.size() > 0 ) { while( (cur != end) ) { if( cur->get()->categoryID() == EVEDB::invCategories::Charge ) chargeRef = (*cur); if( cur->get()->categoryID() == EVEDB::invCategories::Module ) moduleRef = (*cur); cur++; } if( moduleRef ) { if( _fitModule( moduleRef, (EVEItemFlags)flagIndex ) ) { if( moduleRef->GetAttribute(AttrIsOnline).get_int() == 1 ) Online(moduleRef->itemID()); else Offline(moduleRef->itemID()); if( chargeRef ) ((ActiveModule *)GetModule((EVEItemFlags)flagIndex))->load(chargeRef); } else { SysLog::Error( "ModuleManager::ModuleManager()", "ERROR: Cannot fit High Slot module '%s' (id %u)", moduleRef->itemName().c_str(), moduleRef->itemID() ); throw PyException( MakeCustomError( "ERROR! Cannot fit High Slot module '%s'", moduleRef->itemName().c_str() ) ); } } } } for(flagIndex=flagRigSlot0; flagIndex<=flagRigSlot7; flagIndex++) { InventoryItemRef itemRef; std::vector<InventoryItemRef>::iterator cur, end; std::vector<InventoryItemRef> items; m_Ship->FindByFlag( (EVEItemFlags)flagIndex, items ); // Operator assumed to be Client * cur = items.begin(); end = items.end(); if( items.size() > 0 ) { while( (cur->get()->categoryID() != EVEDB::invCategories::Module) && (cur != end) ) { cur++; } if( cur->get()->categoryID() == EVEDB::invCategories::Module ) itemRef = (*cur); if( itemRef ) { _fitModule( itemRef, (EVEItemFlags)flagIndex ); // We don't think Rigs need the Online attribute set, but keep this code here in case we do: //if( itemRef->GetAttribute(AttrIsOnline).get_int() == 1 ) // Online(itemRef->itemID()); //else // Offline(itemRef->itemID()); } } } for(flagIndex=flagSubSystem0; flagIndex<=flagSubSystem7; flagIndex++) { InventoryItemRef itemRef; std::vector<InventoryItemRef>::iterator cur, end; std::vector<InventoryItemRef> items; m_Ship->FindByFlag( (EVEItemFlags)flagIndex, items ); // Operator assumed to be Client * cur = items.begin(); end = items.end(); if( items.size() > 0 ) { while( (cur->get()->categoryID() != EVEDB::invCategories::Module) && (cur != end) ) { cur++; } if( cur->get()->categoryID() == EVEDB::invCategories::Module ) itemRef = (*cur); if( itemRef ) { _fitModule( itemRef, (EVEItemFlags)flagIndex ); // We don't think Subsystems need the Online attribute set, but keep this code here in case we do: //if( itemRef->GetAttribute(AttrIsOnline).get_int() == 1 ) // Online(itemRef->itemID()); //else // Offline(itemRef->itemID()); } } } m_pLog->Log("ModuleManager", "Module loading complete!"); }
bool ModuleManager::_fitModule(InventoryItemRef item, EVEItemFlags flag) { bool verifyFailed = false; GenericModule * mod; // First, check to see if this module item is already fitted, and if so, let's instruct ModuleContainer to move the module GenericModule * existingMod = m_Modules->GetModule(item->itemID()); if( existingMod != NULL ) { if( m_Modules->isSlotOccupied(flag) ) { throw PyException( MakeUserError( "SlotAlreadyOccupied" ) ); verifyFailed = true; } m_Modules->RemoveModule( existingMod->flag() ); // Remove this module from existing slot existingMod->getItem()->SetFlag( flag ); // Change item's flag to the NEW slot flag m_Modules->AddModule( flag, existingMod ); // Add this module back to the container at the NEW slot location } else { mod = ModuleFactory(item, ShipRef(m_Ship)); // Set module's pointer to its owner ModuleManager's log object: mod->setLog(m_pLog); // Check for max turret modules allowed: if( mod->isTurretFitted() && (m_Modules->GetFittedTurretCount() == m_Ship->GetMaxTurrentHardpoints().get_int()) ) { //std::map<std::string, PyRep *> args; //args["typename"] = new PyString(item->itemName().c_str()); //args["portion"] = new PyInt(item->type().portionSize()); throw PyException( MakeUserError( "NotEnoughTurretSlots" ) ); verifyFailed = true; } // Check for max launcher modules allowed: if( mod->isLauncherFitted() && (m_Modules->GetFittedLauncherCount() == m_Ship->GetMaxLauncherHardpoints().get_int()) ) { //std::map<std::string, PyRep *> args; //args["typename"] = new PyString(item->itemName().c_str()); //args["portion"] = new PyInt(item->type().portionSize()); throw PyException( MakeUserError( "NotEnoughLauncherSlots" ) ); verifyFailed = true; } // Check for max modules of group allowed: else if( mod->isMaxGroupFitLimited() && (m_Modules->GetFittedModuleCountByGroup(item->groupID()) == mod->getItem()->GetAttribute(AttrMaxGroupFitted).get_int()) ) { //std::map<std::string, PyRep *> args; //args["typename"] = new PyString(item->itemName().c_str()); //args["portion"] = new PyInt(item->type().portionSize()); throw PyException( MakeUserError( "CantFitTooManyByGroup" ) ); verifyFailed = true; } else { // Fit Module now that all checks have passed: m_Modules->AddModule(flag, mod); } } if( verifyFailed ) { if( mod != NULL ) delete mod; return false; } else return true; }
bool ModuleManager::SwapSubSystem(InventoryItemRef item, EVEItemFlags flag) { if(item->groupID() >= 954 && item->groupID() <= 958) { _fitModule(item,flag); return true; } else SysLog::Debug("ModuleManager","%s tried to fit item %u, which is not a subsystem", m_Ship->GetOperator()->GetName(), item->itemID()); return false; }
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_fit(Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if( args.argCount() < 2 ) { throw PyException( MakeCustomError("Correct Usage: /fit [typeID] ") ); } uint32 typeID = 0; if( args.argCount() == 3) { if( !args.isNumber( 2 ) ) throw PyException( MakeCustomError( "Argument 1 must be type ID." ) ); typeID = atoi( args.arg( 2 ).c_str() ); } else if( args.argCount() == 2 ) { if( !args.isNumber( 1 ) ) throw PyException( MakeCustomError( "Argument 1 must be type ID." ) ); typeID = atoi( args.arg( 1 ).c_str() ); } uint32 qty = 1; _log( COMMAND__MESSAGE, "Create %s %u times", typeID, qty ); EVEItemFlags flag; uint32 powerSlot; uint32 useableSlot; std::string affectName = "online"; if( typeID == 0 ) { throw PyException( MakeCustomError( "Unable to create item of type %u.", typeID ) ); return new PyString( "Creation FAILED." ); } else { //Get Range of slots for item InventoryDB::GetModulePowerSlotByTypeID( typeID, powerSlot ); //Get open slots available on ship InventoryDB::GetOpenPowerSlots(powerSlot, who->GetShip(), useableSlot); ItemData idata( typeID, who->GetCharacterID(), 0, //temp location flag = (EVEItemFlags)useableSlot, qty ); InventoryItemRef i = services->item_factory.SpawnItem( idata ); if( !i ) throw PyException( MakeCustomError( "Unable to create item of type %u.", typeID ) ); who->MoveItem( i->itemID(), who->GetShipID(), flag ); return new PyString( "Creation successful." ); } }
PyResult Command_spawn( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { uint32 typeID = 0; uint32 actualTypeID = 0; std::string actualTypeName = ""; uint32 actualGroupID = 0; uint32 actualCategoryID = 0; double actualRadius = 0.0; InventoryItemRef item; ShipRef ship; double radius; bool offsetLocationSet = false; if( args.argCount() < 2 ) { throw PyException( MakeCustomError("Correct Usage: /spawn [typeID(int)/typeName(string)] with optional X Y Z coordinate as in /spawn [typeID(int/typeName(string)] [x(float)] [y(float)] [z(float)]") ); } if( !(args.isNumber( 1 )) ) throw PyException( MakeCustomError( "Argument 1 should be an item type ID" ) ); typeID = atoi( args.arg( 1 ).c_str() ); if( !who->IsInSpace() ) throw PyException( MakeCustomError( "You must be in space to spawn things." ) ); // Search for item type using typeID: if( !(db->ItemSearch(typeID, actualTypeID, actualTypeName, actualGroupID, actualCategoryID, actualRadius) ) ) { return new PyString( "Unknown typeID or typeName returned no matches." ); } // Check to see if the X Y Z optional coordinates were supplied with the command: GPoint offsetLocation; if( args.argCount() > 2 ) { if( !(args.isNumber(2)) ) throw PyException( MakeCustomError( "Argument 2 should be the X distance from your ship in meters you want the item spawned" ) ); if( !(args.isNumber(3)) ) throw PyException( MakeCustomError( "Argument 3 should be the Y distance from your ship in meters you want the item spawned" ) ); if( !(args.isNumber(4)) ) throw PyException( MakeCustomError( "Argument 4 should be the Z distance from your ship in meters you want the item spawned" ) ); offsetLocation.x = atoi( args.arg( 2 ).c_str() ); offsetLocation.y = atoi( args.arg( 3 ).c_str() ); offsetLocation.z = atoi( args.arg( 4 ).c_str() ); offsetLocationSet = true; } GPoint loc( who->GetPosition() ); if( offsetLocationSet ) { // An X, Y, Z coordinate offset was specified along with the command, so use this to calculate // the final cooridnate of the newly spawned item: loc.x += offsetLocation.x; loc.y += offsetLocation.y; loc.z += offsetLocation.z; } else { // Calculate a random coordinate on the sphere centered on the player's position with // a radius equal to the radius of the ship/celestial being spawned times 10 for really good measure of separation: radius = (actualRadius * 5.0) * (double)(MakeRandomInt( 1, 3)); // Scale the distance from player that the object will spawn to between 10x and 15x the object's radius loc.MakeRandomPointOnSphere( radius ); } // Spawn the item: ItemData idata( actualTypeID, 1, // owner is EVE System who->GetLocationID(), flagAutoFit, actualTypeName.c_str(), loc ); item = services->item_factory.SpawnItem( idata ); if( !item ) throw PyException( MakeCustomError( "Unable to spawn item of type %u.", typeID ) ); DBSystemDynamicEntity entity; entity.allianceID = 0; entity.categoryID = actualCategoryID; entity.corporationID = 0; entity.flag = 0; entity.groupID = actualGroupID; entity.itemID = item->itemID(); entity.itemName = actualTypeName; entity.locationID = who->GetLocationID(); entity.ownerID = 1; entity.typeID = actualTypeID; entity.x = loc.x; entity.y = loc.y; entity.z = loc.z; // Actually do the spawn using SystemManager's BuildEntity: if( !(who->System()->BuildDynamicEntity( who, entity )) ) return new PyString( "Spawn Failed: typeID or typeName not supported." ); // TEST FOR FUN: If this is a drone, make its destiny manager orbit the ship that spawned it like a little lost puppy... if( item->categoryID() == EVEDB::invCategories::Drone ) { ((DroneEntity *)(who->System()->get( entity.itemID )))->Destiny()->SetSpeedFraction( 1.0, true ); ((DroneEntity *)(who->System()->get( entity.itemID )))->Destiny()->Orbit( who, 1000.0, true ); } sLog.Log( "Command", "%s: Spawned %u.", who->GetName(), typeID ); return new PyString( "Spawn successful." ); }
PyResult Command_spawnn( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { uint32 typeID = 0; uint32 actualTypeID = 0; std::string actualTypeName = ""; uint32 actualGroupID = 0; uint32 actualCategoryID = 0; double actualRadius = 0.0; InventoryItemRef item; ShipRef ship; // "/spawnn" arguments: // #1 = quantity ? // #2 = some double value ? // #3 = typeID if( (args.argCount() < 4) || (args.argCount() > 4) ) { throw PyException( MakeCustomError("LOL, we don't know the correct usage of /spawnn, sorry you're S.O.L., BUT it should have 4 arguments.") ); } // Since we don't know what args 1 and 2 are, we don't care about them right now... if( !(args.isNumber( 3 )) ) throw PyException( MakeCustomError( "Argument 3 should be an item type ID" ) ); typeID = atoi( args.arg( 3 ).c_str() ); if( !who->IsInSpace() ) throw PyException( MakeCustomError( "You must be in space to spawn things." ) ); // Search for item type using typeID: if( !(db->ItemSearch(typeID, actualTypeID, actualTypeName, actualGroupID, actualCategoryID, actualRadius) ) ) { return new PyString( "Unknown typeID or typeName returned no matches." ); } GPoint loc( who->GetPosition() ); // Calculate a random coordinate on the sphere centered on the player's position with // a radius equal to the radius of the ship/celestial being spawned times 10 for really good measure of separation: double radius = (actualRadius * 5.0) * (double)(MakeRandomInt( 1, 3)); // Scale the distance from player that the object will spawn to between 10x and 15x the object's radius loc.MakeRandomPointOnSphere( radius ); // Spawn the item: ItemData idata( actualTypeID, 1, // owner is EVE System who->GetLocationID(), flagAutoFit, actualTypeName.c_str(), loc ); item = services->item_factory.SpawnItem( idata ); if( !item ) throw PyException( MakeCustomError( "Unable to spawn item of type %u.", typeID ) ); DBSystemDynamicEntity entity; entity.allianceID = 0; entity.categoryID = actualCategoryID; entity.corporationID = 0; entity.flag = 0; entity.groupID = actualGroupID; entity.itemID = item->itemID(); entity.itemName = actualTypeName; entity.locationID = who->GetLocationID(); entity.ownerID = 1; entity.typeID = actualTypeID; entity.x = loc.x; entity.y = loc.y; entity.z = loc.z; // Actually do the spawn using SystemManager's BuildEntity: if( !(who->System()->BuildDynamicEntity( who, entity )) ) return new PyString( "Spawn Failed: typeID or typeName not supported." ); sLog.Log( "Command", "%s: Spawned %u.", who->GetName(), typeID ); return new PyString( "Spawn successful." ); }
void SpawnEntry::_DoSpawn(SystemManager &mgr, PyServiceMgr &svc) { _log(SPAWN__POP, "Spawning spawn entry %u with group %u", m_id, m_group.id); //pick our spawn point... GPoint spawn_point; switch(m_boundsType) { //safe to assume `bounds` are correct. case boundsPoint: { spawn_point = bounds[0]; } break; case boundsLine: { GVector vec(bounds[0], bounds[1]); double len = vec.length(); spawn_point = GPoint(bounds[0] + Ga::GaFloat(MakeRandomFloat(0, len))*Ga::GaVec3(vec)); } break; default: _log(SPAWN__ERROR, "Invalid bounds type %u on spawn entry %u when spawning...", m_boundsType, GetID()); return; } _log(SPAWN__POP, " selected point (%.1f, %.1f, %.1f)", spawn_point.x, spawn_point.y, spawn_point.z); std::vector<NPC *> spawned; //now see what is gunna spawn... std::vector<SpawnGroup::Entry>::const_iterator cur, end; cur = m_group.entries.begin(); end = m_group.entries.end(); for(; cur != end; cur++) { _log(SPAWN__POP, " Evaluating spawn entry for NPC type %u in group %u", cur->npcTypeID, cur->spawnGroupID); int r; for(r = 0; r < cur->quantity; r++) { if(cur->probability < 1.0f) { if(MakeRandomFloat(0, 1.0f) > cur->probability) { _log(SPAWN__POP, " [%d] not spawning, p=%.4f failed.", r, cur->probability); continue; } _log(SPAWN__POP, " [%d] passed proability check of p=%.4f", r, cur->probability); } //NOTE: this is currently creating an entry in the DB... //which is terrible... we need to make an "in-memory only" // item concept. ItemData idata( cur->npcTypeID, cur->ownerID, //owner mgr.GetID(), flagAutoFit ); InventoryItemRef i = svc.item_factory.SpawnItem(idata); if( !i ) { _log(SPAWN__ERROR, "Failed to spawn item with type %u for group %u.", cur->npcTypeID, cur->spawnGroupID); continue; } _log(SPAWN__POP, " [%d] spawning NPC id %u", r, i->itemID()); //create them all at the same point to start with... //we will move them before they get added to the system NPC *npc = new NPC(&mgr, svc, i, cur->corporationID, 0, spawn_point, this); //TODO: add allianceID spawned.push_back(npc); } } if(spawned.empty()) { int timer = MakeRandomInt(m_timerMin, m_timerMax); _log(SPAWN__POP, "No NPCs produced by spawn entry %u. Resetting spawn timer to %d s.", m_id, timer); m_timer.Start(timer*1000); return; } //TODO: apply formation.. //hacking it for now... std::vector<NPC *>::iterator curn, endn; curn = spawned.begin(); endn = spawned.end(); for(; curn != endn; curn++) { _log(SPAWN__POP, "Moving NPC %u to (%.1f, %.1f, %.1f) due to formation.", (*curn)->GetID(), spawn_point.x, spawn_point.y, spawn_point.z); (*curn)->ForcedSetPosition(spawn_point); spawn_point.y += 1000.0f; } //now the NPCs are all set up, lets drop them into the system. curn = spawned.begin(); endn = spawned.end(); for(; curn != endn; curn++) { //load up any NPC attributes... if(!(*curn)->Load(svc.serviceDB())) { _log(SPAWN__POP, "Failed to load NPC data for NPC %u with type %u, depoping.", (*curn)->GetID(), (*curn)->Item()->typeID()); delete *curn; continue; } //record this NPC as something we spawned. m_spawnedIDs.insert((*curn)->GetID()); mgr.AddNPC(*curn); } //timer is disabled while the spawn is up. m_timer.Disable(); }
bool ModuleManager::InstallRig(InventoryItemRef item, EVEItemFlags flag) { if(item->groupID() >= 773 && item->groupID() <= 786 && item->groupID() != 783) { _fitModule(item,flag); return true; } else SysLog::Debug("ModuleManager","%s tried to fit item %u, which is not a rig", m_Ship->GetOperator()->GetName(), item->itemID()); return false; }