bool EnergyTurret::canActivate(SystemEntity * targetEntity) { if( !m_chargeRef ) { SysLog::Error( "EnergyTurret::Activate()", "ERROR: Cannot find charge that is supposed to be loaded into this module!" ); throw PyException( MakeCustomError( "ERROR! Cannot find charge that is supposed to be loaded into this module!" ) ); } return true; }
PyResult CommandDispatcher::Execute( Client *from, const char* msg ) { //might want to check for # or / at the beginning of this crap. Seperator sep( &msg[1] ); if( 0 == sep.argCount() ) { //empty command, return list of commands std::string reason = "Commands: "; std::map<std::string, CommandRecord *>::const_iterator cur, end; cur = m_commands.begin(); end = m_commands.end(); reason += "["; for(; cur != end; cur++) reason += "'" + cur->second->command + "',"; reason += "]"; UserError *err = new UserError( "" ); err->AddKeyword( "reason", new PyString( reason ) ); throw PyException( err ); } std::map<std::string, CommandRecord*>::const_iterator res = m_commands.find( sep.arg( 0 ) ); if( m_commands.end() == res ) { sLog.Error( "CommandDispatcher", "Unable to find command '%s' for %s", sep.arg( 0 ).c_str(), from->GetName() ); throw PyException( MakeCustomError( "Unknown command '%s'", sep.arg( 0 ).c_str() ) ); } CommandRecord* rec = res->second; if( ( from->GetAccountRole() & rec->required_role ) != rec->required_role ) { sLog.Error( "CommandDispatcher", "Access denied to %s for command '%s', had role 0x%x, need role 0x%x", from->GetName(), rec->command.c_str(), from->GetAccountRole(), rec->required_role ); throw PyException( MakeCustomError( "Access denied to command '%s'", sep.arg( 0 ).c_str() ) ); } return ( *rec->function )( from, &m_db, &m_services, sep ); }
PyResult Command_search( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if( args.argCount() < 2 ) { throw PyException( MakeCustomError("Correct Usage: /search [text]") ); } const std::string& query = args.arg( 1 ); //an empty query is a bad idea. if( 0 == query.length() ) throw PyException( MakeCustomError( "Usage: /search [text]" ) ); std::map<uint32, std::string> matches; if( !db->ItemSearch( query.c_str(), matches ) ) throw PyException( MakeCustomError( "Failed to query DB." ) ); std::string result( itoa( matches.size() ) ); result += " matches found.<br>"; std::map<uint32, std::string>::iterator cur, end; cur = matches.begin(); end = matches.end(); for(; cur != end; cur++) { result += itoa( cur->first ); result += ": "; result += cur->second; result += "<br>"; } if( 10 < matches.size() ) { //send the results in an evemail. std::string subject( "Search results for " ); subject += query; who->SelfEveMail( subject.c_str(), result.c_str() ); return new PyString( "Results sent via evemail." ); } else return new PyString( result ); }
PyResult Command_getattr( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if( args.argCount() < 3 ) { throw PyException( MakeCustomError("Correct Usage: /getattr [itemID] [attributeID]") ); } if( !args.isNumber( 1 ) ) throw PyException( MakeCustomError( "1st argument must be itemID (got %s).", args.arg( 1 ).c_str() ) ); const uint32 itemID = atoi( args.arg( 1 ).c_str() ); if( !args.isNumber( 2 ) ) throw PyException( MakeCustomError( "2nd argument must be attributeID (got %s).", args.arg( 2 ).c_str() ) ); const ItemAttributeMgr::Attr attribute = (ItemAttributeMgr::Attr)atoi( args.arg( 2 ).c_str() ); InventoryItemRef item = services->item_factory.GetItem( itemID ); if( !item ) throw PyException( MakeCustomError( "Failed to load item %u.", itemID ) ); //return item->attributes.PyGet( attribute ); return item->GetAttribute(attribute).GetPyObject(); }
PyResult Command_unspawn( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { uint32 entityID = 0; uint32 itemID = 0; if( (args.argCount() < 3) || (args.argCount() > 3) ) throw PyException( MakeCustomError("Correct Usage: /unspawn (entityID) (itemID), and for now (entityID) is unused, so just type 0, and use the itemID from the entity table for (itemID)") ); if( !(args.isNumber( 1 )) ) throw PyException( MakeCustomError( "Argument 1 should be an item entity ID" ) ); if( !(args.isNumber( 2 )) ) throw PyException( MakeCustomError( "Argument 2 should be an item item ID" ) ); entityID = atoi( args.arg( 1 ).c_str() ); itemID = atoi( args.arg( 2 ).c_str() ); if( !who->IsInSpace() ) throw PyException( MakeCustomError( "You must be in space to unspawn things." ) ); // Search for the itemRef for itemID: InventoryItemRef itemRef = who->services().item_factory.GetItem( itemID ); SystemEntity * entityRef = who->System()->get( itemID ); // Actually do the unspawn using SystemManager's RemoveEntity: if( entityRef == NULL ) { return new PyString( "Un-Spawn Failed: itemID not found." ); } else { who->System()->RemoveEntity( entityRef ); itemRef->Delete(); } sLog.Log( "Command", "%s: Un-Spawned %u.", who->GetName(), itemID ); return new PyString( "Un-Spawn successful." ); }
PyResult Command_repairmodules( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if(args.argCount()==1) { who->GetShip()->RepairModules(); } if(args.argCount()==2) { if( !args.isNumber( 1 ) ) { throw PyException( MakeCustomError( "Argument 1 should be a character ID" ) ); } uint32 charID = atoi( args.arg( 1 ).c_str() ); Client *target = services->entity_list.FindCharacter( charID ); if(target == NULL) throw PyException( MakeCustomError( "Cannot find Character by the entity %d", charID ) ); target->GetShip()->RepairModules(); } return(new PyString("Modules repaired successful!")); }
PyResult Command_kick( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { Client *target; if( args.argCount() == 2 ) { if( args.isNumber( 1 ) ) { int id = atoi( args.arg( 1 ).c_str() ); target = services->entity_list.FindCharacter( id ); } else { const char *name = args.arg( 1 ).c_str(); target = services->entity_list.FindCharacter( name ); } } //support for characters with first and last names else if( args.argCount() == 3 ) { if( args.isHexNumber( 1 ) ) throw PyException( MakeCustomError("Unknown arguments") ); std::string name = args.arg( 1 ) + " " + args.arg( 2 ); target = services->entity_list.FindCharacter( name.c_str() ) ; } else throw PyException( MakeCustomError("Correct Usage: /kick [Character Name]") ); if(target == NULL) throw PyException( MakeCustomError( "Cannot find Character" ) ); else target->DisconnectClient(); return NULL; }
PyResult Command_kenny( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if( args.argCount() == 2 ) { if( args.arg(1) == "ON" || args.arg(1) == "On" || args.arg(1) == "oN" || args.arg(1) == "on" || args.arg(1) == "1" ) { // Enable Kenny Translator who->EnableKennyTranslator(); } else if( args.arg(1) == "OFF" || args.arg(1) == "off" || args.arg(1) == "Off" || args.arg(1) == "0" ) { // Disable Kenny Translator who->DisableKennyTranslator(); } else throw PyException( MakeCustomError("Correct Usage: /kenny ON/OFF On/Off on/off 1/0") ); } else throw PyException( MakeCustomError("Correct Usage: /kenny ON/OFF On/Off on/off 1/0") ); return NULL; }
void EnergyTurret::Activate(SystemEntity * targetEntity) { if( this->m_chargeRef != NULL ) { m_targetEntity = targetEntity; m_targetID = targetEntity->Item()->itemID(); // Activate active processing component timer: m_ActiveModuleProc->ActivateCycle(); } else { sLog.Error( "EnergyTurret::Activate()", "ERROR: Cannot find charge that is supposed to be loaded into this module!" ); throw PyException( MakeCustomError( "ERROR! Cannot find charge that is supposed to be loaded into this module!" ) ); } }
PyResult Command_goto( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args) { if( 3 != args.argCount() || !args.isNumber( 1 ) || !args.isNumber( 2 ) || !args.isNumber( 3 ) ) { throw PyException( MakeCustomError( "Correct Usage: /goto [x coord] [y coor] [z coord]" ) ); } GPoint p( atof( args.arg( 1 ).c_str() ), atof( args.arg( 2 ).c_str() ), atof( args.arg( 3 ).c_str() ) ); sLog.Log( "Command", "%s: Goto (%.13f, %.13f, %.13f)", who->GetName(), p.x, p.y, p.z ); who->MoveToPosition( p ); return new PyString( "Goto successful." ); }
void SpawnAsteroid( SystemManager* system, uint32 typeID, double radius, const GVector& position ) { //TODO: make item in IsUniverseAsteroid() range... ItemData idata( typeID, 1 /* who->GetCorporationID() */, //owner system->GetID(), flagAutoFit, "", //name position ); InventoryItemRef i = system->itemFactory().SpawnItem( idata ); if( !i ) throw PyException( MakeCustomError( "Unable to spawn item of type %u.", typeID ) ); //i->Set_radius( radius ); // Calculate 1/10000th of the volume of a sphere with radius 'radius': // (this should yield around 90,000 units of Veldspar in an asteroid with 1000.0m radius) double volume = (1.0/10000.0) * (4.0/3.0) * M_PI * pow(radius,3); i->SetAttribute(AttrQuantity, EvilNumber(floor(100*(volume/(i->GetAttribute(AttrVolume).get_float()))))); i->SetAttribute(AttrRadius, EvilNumber(radius)); //i->SetAttribute(AttrVolume, EvilNumber(volume)); //i->SetAttribute(AttrIsOnline,EvilNumber(1)); // Is Online //i->SetAttribute(AttrDamage,EvilNumber(0.0)); // Structure Damage //i->SetAttribute(AttrShieldCharge,i->GetAttribute(AttrShieldCapacity)); // Shield Charge //i->SetAttribute(AttrArmorDamage,EvilNumber(0.0)); // Armor Damage //i->SetAttribute(AttrMass,EvilNumber(i->type().attributes.mass())); // Mass //i->SetAttribute(AttrRadius,EvilNumber(i->type().attributes.radius())); // Radius //i->SetAttribute(AttrVolume,EvilNumber(i->type().attributes.volume())); // Volume // TODO: Rework this code now that AsteroidEntity* new_roid = NULL; new_roid = new AsteroidEntity( i, system, *(system->GetServiceMgr()), position ); if( new_roid != NULL ) sLog.Debug( "SpawnAsteroid()", "Spawned new asteroid of radius= %fm and volume= %f m3", radius, volume ); //TODO: check for a local asteroid belt object? //TODO: actually add this to the asteroid belt too... system->AddEntity( new_roid ); }
PyResult Command_pop( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if( 4 != args.argCount() ) throw PyException( MakeCustomError( "Correct Usage: /pop [message type] [key] [text]" ) ); //CustomNotify: notify //ServerMessage: msg //CustomError: error const std::string& msgType = args.arg( 1 ); const std::string& key = args.arg( 2 ); const std::string& text = args.arg( 3 ); Notify_OnRemoteMessage n; n.msgType = msgType; n.args[ key ] = new PyString( text ); PyTuple* t = n.Encode(); who->SendNotification( "OnRemoteMessage", "charid", &t ); PySafeDecRef( t ); return new PyString( "Message sent." ); }
void SpawnAsteroid( SystemManager* system, uint32 typeID, double radius, const GVector& position ) { ItemData idata( typeID, 1, system->GetID(), flagAutoFit, "", //name position ); InventoryItemRef i = ItemFactory::SpawnItem(idata); if (!i) { throw PyException(MakeCustomError("Unable to spawn item of type %u.", typeID)); } // Calculate 1/10000th of the volume of a sphere with radius 'radius': // (this should yield around 90,000 units of Veldspar in an asteroid with 1000.0m radius) double volume = (1.0/100000.0) * (4.0/3.0) * M_PI * pow(radius,3); //uint32 qty = floor((volume/(i->GetAttribute(AttrVolume).get_float()))); uint32 qty = (radius * 10) / std::sqrt(i->GetAttribute(AttrVolume).get_float()); if (i->groupID() == EVEDB::invGroups::Veldspar) { qty *= 2; } i->SetAttribute(AttrQuantity, qty); i->SetAttribute(AttrRadius, radius); // Create astroid srvEntity. AsteroidEntity* new_roid = new AsteroidEntity(i, system, position); if (new_roid != nullptr) { SysLog::Debug("SpawnAsteroid()", "Spawned new asteroid of radius= %fm and volume= %f m3", radius, volume); // Add srvEntity to system. system->AddEntity(new_roid); } }
// command to modify blueprint's attributes, we have to give it blueprint's itemID ... // isn't much comfortable, but I don't know about better solution ... PyResult Command_setbpattr( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if( args.argCount() < 6 ) { throw PyException( MakeCustomError("Correct Usage: /setbpattr [blueprintID] [0 (not copy) or 1 (copy)] [material level] [productivity level] [remaining runs]") ); } if( !args.isNumber( 1 ) ) throw PyException( MakeCustomError( "Argument 1 must be blueprint ID. (got %s)", args.arg( 1 ).c_str() ) ); const uint32 blueprintID = atoi( args.arg( 1 ).c_str() ); if( "0" != args.arg( 2 ) && "1" != args.arg( 2 ) ) throw PyException( MakeCustomError( "Argument 2 must be 0 (not copy) or 1 (copy). (got %s)", args.arg( 2 ).c_str() ) ); const bool copy = ( atoi( args.arg( 2 ).c_str() ) ? true : false ); if( !args.isNumber( 3 ) ) throw PyException( MakeCustomError( "Argument 3 must be material level. (got %s)", args.arg( 3 ).c_str() ) ); const uint32 materialLevel = atoi( args.arg( 3 ).c_str() ); if( !args.isNumber( 4 ) ) throw PyException( MakeCustomError( "Argument 4 must be productivity level. (got %s)", args.arg( 4 ).c_str() ) ); const uint32 productivityLevel = atoi( args.arg( 4 ).c_str() ); if( !args.isNumber( 5 ) ) throw PyException( MakeCustomError( "Argument 5 must be remaining licensed production runs. (got %s)", args.arg( 5 ).c_str() ) ); const uint32 licensedProductionRunsRemaining = atoi( args.arg( 5 ).c_str() ); BlueprintRef bp = services->item_factory.GetBlueprint( blueprintID ); if( !bp ) throw PyException( MakeCustomError( "Failed to load blueprint %u.", blueprintID ) ); bp->SetCopy( copy ); bp->SetMaterialLevel( materialLevel ); bp->SetProductivityLevel( productivityLevel ); bp->SetLicensedProductionRunsRemaining( licensedProductionRunsRemaining ); return new PyString( "Properties modified." ); }
PyResult Command_growbelt( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { throw PyException( MakeCustomError( "Not implemented yet." ) ); }
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!"); }
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 Command_spawnbelt( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args ) { if( !who->IsInSpace() ) throw PyException( MakeCustomError( "You must be in space to spawn things." ) ); bool makeIceBelt = false; bool makeRareIce = false; uint32 customCount = 0; if( args.argCount() >= 2 ) { if( !args.isNumber( 1 ) ) { if( args.arg( 1 ) == "ice" ) makeIceBelt = true; } else { if( atoi(args.arg( 1 ).c_str()) > 15 ) customCount = atoi(args.arg( 1 ).c_str()); else PyException( MakeCustomError( "Argument 1 should be at least 15!" ) ); } } if( args.argCount() >= 3 ) { if( args.isNumber( 2 ) ) { if( atoi(args.arg( 2 ).c_str()) > 15 ) customCount = atoi(args.arg(2).c_str()); else PyException( MakeCustomError( "Argument 2 should be at least 15!" ) ); } else if( args.arg( 2 ) == "ice" ) makeIceBelt = true; if( args.arg( 2 ) == "rareice" ) { makeIceBelt = true; makeRareIce = true; } } const double beltradius = 100000.0; const double beltdistance = 25000.0; double roidradius; const double beltangle = M_PI * 2.0 / 3.0; uint32 pcs = 0; if( customCount > 15 ) pcs = customCount + static_cast<uint32>(MakeRandomInt( -10, 10 )); else pcs = 30 + static_cast<uint32>(MakeRandomInt( -10, 10 )); const GPoint position( who->GetPosition() ); const double R = sqrt( position.x * position.x + position.z * position.z ); const GPoint r = position * ( R + beltdistance - beltradius ) / R; double phi = atan( position.x / position.z ); if( position.z < 0 ) phi += M_PI; SystemManager* sys = who->System(); std::map<double, uint32> roidDist; if( makeIceBelt ) { std::string securityStatus = sys->GetSystemSecurity(); if( !makeRareIce ) { roidDist.insert(std::pair<double,uint32>(0.60,16264)); // Blue Ice roidDist.insert(std::pair<double,uint32>(0.45,17975)); // Thick Blue Ice roidDist.insert(std::pair<double,uint32>(0.30,28627)); // Azure Ice roidDist.insert(std::pair<double,uint32>(0.20,16262)); // Clear Icicle roidDist.insert(std::pair<double,uint32>(0.10,16267)); // Dark Glitter } if( makeRareIce ) { roidDist.insert(std::pair<double,uint32>(0.90,16263)); // Glacial Mass roidDist.insert(std::pair<double,uint32>(0.80,16265)); // White Glaze roidDist.insert(std::pair<double,uint32>(0.70,16266)); // Glare Crust roidDist.insert(std::pair<double,uint32>(0.60,16268)); // Gelidus roidDist.insert(std::pair<double,uint32>(0.50,16269)); // Krystallos roidDist.insert(std::pair<double,uint32>(0.40,17976)); // Pristine White Glaze roidDist.insert(std::pair<double,uint32>(0.30,17977)); // Smooth Glacial Mass roidDist.insert(std::pair<double,uint32>(0.20,17978)); // Enriched Clear Icicle roidDist.insert(std::pair<double,uint32>(0.10,28628)); // Crystalline Icicle } } else { if( !db->GetRoidDist( sys->GetSystemSecurity(), roidDist ) ) { sLog.Error( "Command", "Couldn't get roid list for system security %s", sys->GetSystemSecurity() ); throw PyException( MakeCustomError( "Couldn't get roid list for system security %s", sys->GetSystemSecurity() ) ); } } double distanceToMe; double alpha; GPoint mposition; if( makeIceBelt ) pcs *= 2; for( uint32 i = 0; i < pcs; ++i ) { alpha = beltangle * MakeRandomFloat( -0.5, 0.5 ); if( makeIceBelt ) roidradius = MakeRandomFloat( 1000.0, 10000.0 ); else roidradius = MakeRandomFloat( 100.0, 1000.0 ); mposition.x = beltradius * sin( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 ); mposition.z = beltradius * cos( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 ); mposition.y = position.y - r.y + roidradius * MakeRandomFloat( 0, 15 ); distanceToMe = (r + mposition - position).length(); SpawnAsteroid( who->System(), GetAsteroidType( MakeRandomFloat(), roidDist ), roidradius, r + mposition ); } return new PyString( "Spawn successsfull." ); }
/* * SQL to remove all asteroids from space in ALL systems. * Important, run in this order or the attributes will not be deleted! * DELETE FROM srvEntity_default_attributes WHERE attributeID > 0 and itemID in (SELECT itemID from srvEntity where ownerID=1 AND typeID in (SELECT typeID from invTypes where groupID in (select groupID FROM invGroups where categoryID=25) or groupID=711)); DELETE FROM srvEntity_attributes WHERE attributeID > 0 and itemID in (SELECT itemID from srvEntity where ownerID=1 AND typeID in (SELECT typeID from invTypes where groupID in (select groupID FROM invGroups where categoryID=25) or groupID=711)); DELETE FROM srvEntity WHERE itemID>=140000000 AND ownerID=1 AND typeID in (SELECT typeID from invTypes where groupID in (select groupID FROM invGroups where categoryID=25) or groupID=711); * */ PyResult Command_spawnbelt( Client* who, const Seperator& args ) { if (!who->IsInSpace()) { throw PyException(MakeCustomError("You must be in space to spawn things.")); } bool makeIceBelt = false; bool makeRareIce = false; uint32 customCount = 0; if( args.argCount() >= 2 ) { if( !args.isNumber( 1 ) ) { if( args.arg( 1 ) == "ice" ) makeIceBelt = true; } else { if( atoi(args.arg( 1 ).c_str()) > 15 ) customCount = atoi(args.arg( 1 ).c_str()); else PyException( MakeCustomError( "Argument 1 should be at least 15!" ) ); } } if( args.argCount() >= 3 ) { if( args.isNumber( 2 ) ) { if( atoi(args.arg( 2 ).c_str()) > 15 ) customCount = atoi(args.arg(2).c_str()); else PyException( MakeCustomError( "Argument 2 should be at least 15!" ) ); } else if( args.arg( 2 ) == "ice" ) makeIceBelt = true; if( args.arg( 2 ) == "rareice" ) { makeIceBelt = true; makeRareIce = true; } } double beltradius = 25000.0; // 25 KM if(makeIceBelt) { beltradius = 100000.0; // 100 KM } uint32 pcs = 0; if (customCount > 15) { pcs = customCount + static_cast<uint32> (MakeRandomInt(-10, 10)); } else { pcs = 200 + static_cast<uint32> (MakeRandomInt(-10, 10)); } SystemManager* sys = who->System(); std::map<double, uint32> roidDist; if (makeIceBelt) { pcs /= 8; std::string securityStatus = sys->GetSystemSecurity(); if (!makeRareIce) { roidDist.insert(std::pair<double, uint32>(0.60, 16264)); // Blue Ice roidDist.insert(std::pair<double, uint32>(0.45, 17975)); // Thick Blue Ice roidDist.insert(std::pair<double, uint32>(0.30, 28627)); // Azure Ice roidDist.insert(std::pair<double, uint32>(0.20, 16262)); // Clear Icicle roidDist.insert(std::pair<double, uint32>(0.10, 16267)); // Dark Glitter } if (makeRareIce) { roidDist.insert(std::pair<double, uint32>(0.90, 16263)); // Glacial Mass roidDist.insert(std::pair<double, uint32>(0.80, 16265)); // White Glaze roidDist.insert(std::pair<double, uint32>(0.70, 16266)); // Glare Crust roidDist.insert(std::pair<double, uint32>(0.60, 16268)); // Gelidus roidDist.insert(std::pair<double, uint32>(0.50, 16269)); // Krystallos roidDist.insert(std::pair<double, uint32>(0.40, 17976)); // Pristine White Glaze roidDist.insert(std::pair<double, uint32>(0.30, 17977)); // Smooth Glacial Mass roidDist.insert(std::pair<double, uint32>(0.20, 17978)); // Enriched Clear Icicle roidDist.insert(std::pair<double, uint32>(0.10, 28628)); // Crystalline Icicle } } else { if (!CommandDB::GetRoidDist(sys->GetSystemSecurity(), roidDist)) { SysLog::Error("Command", "Couldn't get roid list for system security %s", sys->GetSystemSecurity()); throw PyException(MakeCustomError("Couldn't get roid list for system security %s", sys->GetSystemSecurity())); } } const GPoint position(who->GetPosition()); double phi = atan(position.x / position.z); if (position.z == 0) { phi = M_PI / 2; } if (position.z < 0) { phi += M_PI; } GPoint beltOffset; if (makeIceBelt) { beltOffset.x = (beltradius * 0.75) * sin(phi); beltOffset.z = (beltradius * 0.75) * cos(phi); } double alpha; GPoint mposition; double beltThickness = 3000; double height; double roidradius; const double beltangle = M_PI * 2.0 / 3.0; int triesLeft = pcs * 25; int pcsLeft = pcs; std::vector<std::pair<GPoint, double>> spawned; while (triesLeft-- && pcsLeft) { uint32 typeID = GetAsteroidType(MakeRandomFloat(), roidDist); // Generate asteroid parameters. if( makeIceBelt) { height = MakeRandomFloat(-0.2, 1.8); alpha = beltangle * ((M_PI / 8) * height); roidradius = MakeRandomFloat(4000.0, 10000.0); height *= 8; } else { alpha = beltangle * MakeRandomFloat(-M_PI / 4, M_PI / 4); roidradius = MakeRandomFloat( 100.0, 1000.0 ); height = MakeRandomFloat(-1, 1); const ItemType *type = ItemFactory::GetType(typeID); if (type->groupID() == EVEDB::invGroups::Veldspar) { roidradius *= 2; } } // Calculate new position. mposition.y = beltThickness * height; mposition.x = beltradius * sin(phi + alpha) + beltThickness * MakeRandomFloat(-1, 1); mposition.z = beltradius * cos(phi + alpha) + beltThickness * MakeRandomFloat(-1, 1); // Check for collision. bool collision = false; for (auto pair : spawned) { GPoint point = pair.first; double dist = (mposition - point).length(); double radii = (roidradius + pair.second); if ((dist - radii) < 0) { collision = true; continue; } } if (collision) { // There was a collision, try again. continue; } // Were good, add the asteroid. pcsLeft--; SpawnAsteroid(who->System(), typeID, roidradius, mposition + position - beltOffset); // Save the location for collision checks. spawned.push_back(std::pair<GPoint, double>(mposition, roidradius)); } return new PyString( "Spawn successsfull." ); }
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"); }
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." ); }
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_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_growbelt( Client* who, const Seperator& args ) { throw PyException( MakeCustomError( "Not implemented yet." ) ); }