Damage::Damage( SystemEntity *_source, InventoryItemRef _weapon, EVEEffectID _effect): source(_source), charge(), effect(_effect) { if(_weapon->HasAttribute(AttrKineticDamage)) kinetic = _weapon->GetAttribute(AttrKineticDamage).get_float(); else kinetic = 0.0; if(_weapon->HasAttribute(AttrThermalDamage)) thermal = _weapon->GetAttribute(AttrThermalDamage).get_float(); else thermal = 0.0; if(_weapon->HasAttribute(AttrEmDamage)) em = _weapon->GetAttribute(AttrEmDamage).get_float(); else em = 0.0; if(_weapon->HasAttribute(AttrExplosiveDamage)) explosive = _weapon->GetAttribute(AttrExplosiveDamage).get_float(); else explosive = 0.0; weapon = _weapon; }
bool Ship::ValidateItemSpecifics(InventoryItemRef equip) { //declaring explicitly as int...not sure if this is needed or not int groupID = m_pOperator->GetShip()->groupID(); int typeID = m_pOperator->GetShip()->typeID(); EvilNumber canFitShipGroup1 = equip->GetAttribute(AttrCanFitShipGroup1); EvilNumber canFitShipGroup2 = equip->GetAttribute(AttrCanFitShipGroup2); EvilNumber canFitShipGroup3 = equip->GetAttribute(AttrCanFitShipGroup3); EvilNumber canFitShipGroup4 = equip->GetAttribute(AttrCanFitShipGroup4); EvilNumber canFitShipType1 = equip->GetAttribute(AttrCanFitShipType1); EvilNumber canFitShipType2 = equip->GetAttribute(AttrCanFitShipType2); EvilNumber canFitShipType3 = equip->GetAttribute(AttrCanFitShipType3); EvilNumber canFitShipType4 = equip->GetAttribute(AttrCanFitShipType4); if( canFitShipGroup1 != 0 || canFitShipGroup2 != 0 || canFitShipGroup3 != 0 || canFitShipGroup4 != 0 ) if( canFitShipGroup1 != groupID && canFitShipGroup2 != groupID && canFitShipGroup3 != groupID && canFitShipGroup4 != groupID ) return false; /* if( canFitShipGroup1 != 0 ) if( canFitShipGroup1 != groupID ) return false; if( canFitShipGroup2 != 0 ) if( canFitShipGroup2 != groupID ) return false; if( canFitShipGroup3 != 0 ) if( canFitShipGroup3 != groupID ) return false; if( canFitShipGroup4 != 0 ) if( canFitShipGroup4 != groupID ) return false; */ if( canFitShipType1 != 0 || canFitShipType2 != 0 || canFitShipType3 != 0 || canFitShipType4 != 0 ) if( canFitShipType1 != typeID && canFitShipType2 != typeID && canFitShipType3 != typeID && canFitShipType4 != typeID ) return false; /* if( canFitShipType1 != 0 ) if( canFitShipType1 != typeID ) return false; if( canFitShipType2 != 0 ) if( canFitShipType2 != typeID ) return false; if( canFitShipType3 != 0 ) if( canFitShipType3 != typeID ) return false; if( canFitShipType4 != 0 ) if( canFitShipType4 != typeID ) return false; */ return true; }
/* * InventoryEx */ void InventoryEx::ValidateAddItem(EVEItemFlags flag, InventoryItemRef item) const { //double volume = item->quantity() * item->volume(); EvilNumber volume = item->GetAttribute(AttrQuantity) * item->GetAttribute(AttrVolume); double capacity = GetRemainingCapacity( flag ); if( volume > capacity ) { std::map<std::string, PyRep *> args; args["available"] = new PyFloat( capacity ); args["volume"] = volume.GetPyObject(); throw PyException( MakeUserError( "NotEnoughCargoSpace", args ) ); } }
NPC::NPC( SystemManager *system, PyServiceMgr &services, InventoryItemRef self, uint32 corporationID, uint32 allianceID, const GPoint &position, SpawnEntry *spawner) : DynamicSystemEntity(new DestinyManager(this, system), self), m_system(system), m_services(services), m_spawner(spawner), // m_itemID(self->itemID()), // m_typeID(self->typeID()), // m_ownerID(self->ownerID()), m_corporationID(corporationID), m_allianceID(allianceID), m_orbitingID(0) { //NOTE: this is bad if we inherit NPC! m_AI = new NPCAIMgr(this); m_destiny->SetPosition(position, false); /* Gets the value from the NPC and put on our own vars */ //m_shieldCharge = self->shieldCharge(); m_shieldCharge = self->GetAttribute(AttrShieldCharge).get_float(); m_armorDamage = 0.0; m_hullDamage = 0.0; }
void Contract::GetItemRow( InventoryItemRef item, PyPackedRow* into ) const { into->SetField( "contractID", new PyInt( contractID() ) ); into->SetField( "itemID", new PyInt( item->itemID() ) ); into->SetField( "quantity", new PyInt( item->quantity() ) ); into->SetField( "itemTypeID", new PyInt( item->typeID() ) ); into->SetField( "inCrate", new PyBool( true ) ); if( item->categoryID() == EVEDB::invCategories::Blueprint ) { BlueprintRef bp = m_itemFactory.GetBlueprint( item->itemID() ); into->SetField( "parentID", new PyInt( bp->parentBlueprintTypeID() ) ); into->SetField( "productivityLevel", new PyInt( bp->productivityLevel() ) ); into->SetField( "materialLevel", new PyInt( bp->materialLevel() ) ); into->SetField( "copy", new PyInt( bp->copy() ) ); into->SetField( "licensedProductionRunsRemaining", new PyInt( bp->licensedProductionRunsRemaining() ) ); } else { into->SetField( "parentID", new PyInt( 0 ) ); into->SetField( "productivityLevel", new PyInt( 0 ) ); into->SetField( "materialLevel", new PyInt( 0 ) ); into->SetField( "copy", new PyInt( 0 ) ); into->SetField( "licensedProductionRunsRemaining", new PyInt( 0 ) ); } if( item->HasAttribute( AttrDamage ) ) into->SetField( "damage", new PyInt( item->GetAttribute( AttrDamage ).get_int() ) ); else into->SetField( "damage", new PyInt( 0 ) ); into->SetField( "flagID", new PyInt( item->flag() ) ); }
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 ); }
Damage::Damage( SystemEntity *_source, InventoryItemRef _weapon, EVEEffectID _effect ) /*: kinetic(_weapon->kineticDamage()), thermal(_weapon->thermalDamage()), em(_weapon->emDamage()), explosive(_weapon->explosiveDamage()),*/ : kinetic(_weapon->GetAttribute(AttrKineticDamage).get_float()), thermal(_weapon->GetAttribute(AttrThermalDamage).get_float()), em(_weapon->GetAttribute(AttrEmDamage).get_float()), explosive(_weapon->GetAttribute(AttrExplosiveDamage).get_float()), source(_source), weapon(_weapon), charge(), effect(_effect) {}
void Structure::ValidateAddItem(EVEItemFlags flag, InventoryItemRef item, Client *c) { CharacterRef character = c->GetChar(); if( flag == flagCargoHold ) { //get all items in cargohold EvilNumber capacityUsed(0); std::vector<InventoryItemRef> items; c->GetShip()->FindByFlag(flag, items); for(uint32 i = 0; i < items.size(); i++){ capacityUsed += items[i]->GetAttribute(AttrVolume); } if( capacityUsed + item->GetAttribute(AttrVolume) > c->GetShip()->GetAttribute(AttrCapacity) ) throw PyException( MakeCustomError( "Not enough cargo space!") ); } else if( flag == flagSecondaryStorage ) { //get all items in SecondaryStorage EvilNumber capacityUsed(0); std::vector<InventoryItemRef> items; c->GetShip()->FindByFlag(flag, items); for(uint32 i = 0; i < items.size(); i++){ capacityUsed += items[i]->GetAttribute(AttrVolume); } if( capacityUsed + item->GetAttribute(AttrVolume) > c->GetShip()->GetAttribute(AttrCapacitySecondary) ) throw PyException( MakeCustomError( "Not enough Secondary Storage space!") ); } else if( flag == flagSpecializedAmmoHold ) { //get all items in ammo hold EvilNumber capacityUsed(0); std::vector<InventoryItemRef> items; c->GetShip()->FindByFlag(flag, items); for(uint32 i = 0; i < items.size(); i++){ capacityUsed += items[i]->GetAttribute(AttrVolume); } if( capacityUsed + item->GetAttribute(AttrVolume) > c->GetShip()->GetAttribute(AttrAmmoCapacity) ) throw PyException( MakeCustomError( "Not enough Ammo Storage space!") ); } }
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; }
void CargoContainer::ValidateAddItem(EVEItemFlags flag, InventoryItemRef item, Client *c) { CharacterRef character = c->GetChar(); if( flag == flagCargoHold ) { //get all items in cargohold EvilNumber capacityUsed(0); std::vector<InventoryItemRef> items; c->GetShip()->FindByFlag(flag, items); for(uint32 i = 0; i < items.size(); i++){ capacityUsed += items[i]->GetAttribute(AttrVolume); } if( capacityUsed + item->GetAttribute(AttrVolume) > c->GetShip()->GetAttribute(AttrCapacity) ) throw PyException( MakeCustomError( "Not enough cargo space!") ); } }
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); } }
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(); }
void NPCAIMgr::CheckAttacks(SystemEntity *target) { if(m_mainAttackTimer.Check(false)) { _log(NPC__AI_TRACE, "[%u] Attack timer expired. Attacking %u.", m_npc->GetID(), target->GetID()); InventoryItemRef self = m_npc->Item(); //reset the attack timer. //NOTE: there is probably a more intelligent way to make this descision. //if(self->entityAttackDelayMax() <= 0) { //use speed field... m_mainAttackTimer.Start(self->GetAttribute(AttrSpeed).get_int()); //} else { //I think this field is actually meant as a reaction time to the player showing up in range. // m_mainAttackTimer.Start(MakeRandomInt( // self->entityAttackDelayMin(), // self->entityAttackDelayMax() )); //} //Do main attack... //check our attack range... if(m_npc->DistanceTo2(target) > m_entityAttackRange2.get_float()) { _log(NPC__AI_TRACE, "[%u] Target (%u) is too far away (%.2f > %.2f)", m_npc->GetID(), target->GetID(), m_npc->DistanceTo2(target), m_entityAttackRange2); _EnterFollowing(target); return; } //TODO: check to-hit... //TODO: Need to consult dgmTypeEffects to determine what kind // of effects to throw for this attack. _SendWeaponEffect("effects.Laser", target); Damage d( m_npc, (InventoryItemRef)self, effectTargetAttack); //should get this from somewhere. m_npc->ApplyDamageModifiers(d, m_npc); target->ApplyDamage(d); } }
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 ); }
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 != NULL ) { 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: //sLog.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; }
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); } }
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!" ) ); } } } }
NPC::NPC( SystemManager *system, PyServiceMgr &services, InventoryItemRef self, uint32 corporationID, uint32 allianceID, const GPoint &position, SpawnEntry *spawner) : DynamicSystemEntity(new DestinyManager(this, system), self), m_system(system), m_services(services), m_spawner(spawner), // m_itemID(self->itemID()), // m_typeID(self->typeID()), // m_ownerID(self->ownerID()), m_corporationID(corporationID), m_allianceID(allianceID), m_orbitingID(0) { //NOTE: this is bad if we inherit NPC! m_AI = new NPCAIMgr(this); // SET ALL ATTRIBUTES MISSING FROM DATABASE BEFORE USING THEM FOR ANYTHING: // Create default dynamic attributes in the AttributeMap: self->SetAttribute(AttrIsOnline, 1); // Is Online self->SetAttribute(AttrShieldCharge, self->GetAttribute(AttrShieldCapacity)); // Shield Charge self->SetAttribute(AttrArmorDamage, 0.0); // Armor Damage self->SetAttribute(AttrMass, self->type().attributes.mass()); // Mass self->SetAttribute(AttrRadius, self->type().attributes.radius()); // Radius self->SetAttribute(AttrVolume, self->type().attributes.volume()); // Volume self->SetAttribute(AttrCapacity, self->type().attributes.capacity()); // Capacity self->SetAttribute(AttrInertia, 1); // Inertia self->SetAttribute(AttrCharge, self->GetAttribute(AttrCapacitorCapacity)); // Set Capacitor Charge to the Capacitor Capacity self->SetAttribute(AttrShieldCharge, self->GetAttribute(AttrShieldCapacity)); // Shield Charge // Agility - WARNING! NO NPC Ships have Agility, so we're setting it to 1 for ALL NPC ships if( !(self->HasAttribute(AttrAgility)) ) self->SetAttribute(AttrAgility, 1 ); // Hull Damage if( !(self->HasAttribute(AttrDamage)) ) self->SetAttribute(AttrDamage, 0 ); // AttrHullEmDamageResonance if( !(self->HasAttribute(AttrHullEmDamageResonance)) ) self->SetAttribute(AttrHullEmDamageResonance, 0.0); // AttrHullExplosiveDamageResonance if( !(self->HasAttribute(AttrHullExplosiveDamageResonance)) ) self->SetAttribute(AttrHullExplosiveDamageResonance, 0.0); // AttrHullKineticDamageResonance if( !(self->HasAttribute(AttrHullKineticDamageResonance)) ) self->SetAttribute(AttrHullKineticDamageResonance, 0.0); // AttrHullThermalDamageResonance if( !(self->HasAttribute(AttrHullThermalDamageResonance)) ) self->SetAttribute(AttrHullThermalDamageResonance, 0.0); // AttrOrbitRange if( !(self->HasAttribute(AttrOrbitRange)) ) self->SetAttribute(AttrOrbitRange, 5000); // Set internal and Destiny values FROM these Attributes, now that they are all setup: m_destiny->SetPosition(position, false); m_destiny->SetShipCapabilities(self); m_destiny->SetSpeedFraction(1.0); m_destiny->Halt(); /* Gets the value from the NPC and put on our own vars */ //m_shieldCharge = self->shieldCharge(); m_shieldCharge = self->GetAttribute(AttrShieldCharge).get_float(); m_armorDamage = 0.0; m_hullDamage = 0.0; }
bool Ship::ValidateAddItem(EVEItemFlags flag, InventoryItemRef item) { CharacterRef character = m_pOperator->GetChar(); // Operator assumed to be Client * if( flag == flagDroneBay ) { if( item->categoryID() != EVEDB::invCategories::Drone ) //Can only put drones in drone bay throw PyException( MakeUserError( "ItemCannotBeInDroneBay" ) ); } else if( flag == flagShipHangar ) { if( m_pOperator->GetShip()->GetAttribute(AttrHasShipMaintenanceBay ) != 0) // Operator assumed to be Client * // We have no ship maintenance bay throw PyException( MakeCustomError( "%s has no ship maintenance bay.", item->itemName().c_str() ) ); if( item->categoryID() != EVEDB::invCategories::Ship ) // Only ships may be put here throw PyException( MakeCustomError( "Only ships may be placed into ship maintenance bay." ) ); } else if( flag == flagHangar ) { if( m_pOperator->GetShip()->GetAttribute(AttrHasCorporateHangars ) != 0) // Operator assumed to be Client * // We have no corporate hangars throw PyException( MakeCustomError( "%s has no corporate hangars.", item->itemName().c_str() ) ); } else if( (flag >= flagLowSlot0) && (flag <= flagHiSlot7) ) { if( m_pOperator->IsClient() ) if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); if(!ValidateItemSpecifics(item)) throw PyException( MakeCustomError( "Your ship cannot equip this module" ) ); if(item->categoryID() == EVEDB::invCategories::Charge) { if( m_ModuleManager->GetModule(flag) != NULL ) { InventoryItemRef module; module = m_ModuleManager->GetModule(flag)->getItem(); if(module->GetAttribute(AttrChargeSize) != item->GetAttribute(AttrChargeSize) ) throw PyException( MakeCustomError( "The charge is not the correct size for this module." ) ); if(module->GetAttribute(AttrChargeGroup1) != item->groupID()) throw PyException( MakeCustomError( "Incorrect charge type for this module.") ); // NOTE: Module Manager will check for actual room to load charges and make stack splits, or reject loading altogether } else throw PyException( MakeCustomError( "Module at flag '%u' does not exist!", flag ) ); } else { if( m_ModuleManager->IsSlotOccupied(flag) ) throw PyException( MakeUserError( "SlotAlreadyOccupied" ) ); } } else if( (flag >= flagRigSlot0) && (flag <= flagRigSlot7) ) { if( m_pOperator->IsClient() ) if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); if(m_pOperator->GetShip()->GetAttribute(AttrRigSize) != item->GetAttribute(AttrRigSize)) // Operator assumed to be Client * throw PyException( MakeCustomError( "Your ship cannot fit this size module" ) ); if( m_pOperator->GetShip()->GetAttribute(AttrUpgradeLoad) + item->GetAttribute(AttrUpgradeCost) > m_pOperator->GetShip()->GetAttribute(AttrUpgradeCapacity) ) // Operator assumed to be Client * throw PyException( MakeCustomError( "Your ship cannot handle the extra calibration" ) ); } else if( (flag >= flagSubSystem0) && (flag <= flagSubSystem7) ) { if( m_pOperator->IsClient() ) if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); } else { // Handle any other flag, legal or not by virtue of GetRemainingVolumeByFlag() and GetCapacity() that handle supported capacity types: // (unsupported or illegal flags report capacity of 0.0, so are automatically rejected) double capacityRemaining(0.0); capacityRemaining = GetRemainingVolumeByFlag(flag); if( (capacityRemaining < (item->GetAttribute(AttrVolume).get_float() * (double)item->quantity())) ) // Operator assumed to be Client * throw PyException( MakeCustomError( "Not enough cargo space!<br><br>flag = %u", (uint32)flag) ); } return true; }
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; }
void Ship::ValidateAddItem(EVEItemFlags flag, InventoryItemRef item) { CharacterRef character = m_pOperator->GetChar(); // Operator assumed to be Client * if( flag == flagDroneBay ) { if( item->categoryID() != EVEDB::invCategories::Drone ) //Can only put drones in drone bay throw PyException( MakeUserError( "ItemCannotBeInDroneBay" ) ); } else if( flag == flagShipHangar ) { if( m_pOperator->GetShip()->GetAttribute(AttrHasShipMaintenanceBay ) != 0) // Operator assumed to be Client * // We have no ship maintenance bay throw PyException( MakeCustomError( "%s has no ship maintenance bay.", item->itemName().c_str() ) ); if( item->categoryID() != EVEDB::invCategories::Ship ) // Only ships may be put here throw PyException( MakeCustomError( "Only ships may be placed into ship maintenance bay." ) ); } else if( flag == flagHangar ) { if( m_pOperator->GetShip()->GetAttribute(AttrHasCorporateHangars ) != 0) // Operator assumed to be Client * // We have no corporate hangars throw PyException( MakeCustomError( "%s has no corporate hangars.", item->itemName().c_str() ) ); } else if( flag == flagCargoHold ) { //get all items in cargohold EvilNumber capacityUsed(0); std::vector<InventoryItemRef> items; m_pOperator->GetShip()->FindByFlag(flag, items); // Operator assumed to be Client * for(uint32 i = 0; i < items.size(); i++){ capacityUsed += items[i]->GetAttribute(AttrVolume); } if( capacityUsed + item->GetAttribute(AttrVolume) > m_pOperator->GetShip()->GetAttribute(AttrCapacity) ) // Operator assumed to be Client * throw PyException( MakeCustomError( "Not enough cargo space!") ); } else if( flag > flagLowSlot0 && flag < flagHiSlot7 ) { if( m_pOperator->IsClient() ) if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); if(!ValidateItemSpecifics(item)) throw PyException( MakeCustomError( "Your ship cannot equip this module" ) ); if(item->categoryID() == EVEDB::invCategories::Charge) { InventoryItemRef module; m_pOperator->GetShip()->FindSingleByFlag(flag, module); // Operator assumed to be Client * if(module->GetAttribute(AttrChargeSize) != item->GetAttribute(AttrChargeSize) ) throw PyException( MakeCustomError( "The charge is not the correct size for this module." ) ); if(module->GetAttribute(AttrChargeGroup1) != item->groupID()) throw PyException( MakeCustomError( "Incorrect charge type for this module.") ); } } else if( flag > flagRigSlot0 && flag < flagRigSlot7 ) { if( m_pOperator->IsClient() ) if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); if(m_pOperator->GetShip()->GetAttribute(AttrRigSize) != item->GetAttribute(AttrRigSize)) // Operator assumed to be Client * throw PyException( MakeCustomError( "Your ship cannot fit this size module" ) ); if( m_pOperator->GetShip()->GetAttribute(AttrUpgradeLoad) + item->GetAttribute(AttrUpgradeCost) > m_pOperator->GetShip()->GetAttribute(AttrUpgradeCapacity) ) // Operator assumed to be Client * throw PyException( MakeCustomError( "Your ship cannot handle the extra calibration" ) ); } else if( flag > flagSubSystem0 && flag < flagSubSystem7 ) { if( m_pOperator->IsClient() ) if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); } }
bool Skill::FitModuleSkillCheck(InventoryItemRef item, CharacterRef character) { //TODO: move to skills SkillRef requiredSkill; //Primary Skill if(item->GetAttribute(AttrRequiredSkill1) != 0) { requiredSkill = character->GetSkill( static_cast<uint32>(item->GetAttribute(AttrRequiredSkill1).get_int()) ); if( !requiredSkill ) return false; if( item->GetAttribute(AttrRequiredSkill1Level) > requiredSkill->GetAttribute(AttrSkillLevel) ) return false; } //Secondary Skill if(item->GetAttribute(AttrRequiredSkill2) != 0) { requiredSkill = character->GetSkill( static_cast<uint32>(item->GetAttribute(AttrRequiredSkill2).get_int()) ); if( !requiredSkill ) return false; if( item->GetAttribute(AttrRequiredSkill2Level) > requiredSkill->GetAttribute(AttrSkillLevel) ) return false; } //Tertiary Skill if(item->GetAttribute(AttrRequiredSkill3) != 0) { requiredSkill = character->GetSkill( static_cast<uint32>(item->GetAttribute(AttrRequiredSkill3).get_int()) ); if( !requiredSkill ) return false; if( item->GetAttribute(AttrRequiredSkill3Level) > requiredSkill->GetAttribute(AttrSkillLevel) ) return false; } //Quarternary Skill if(item->GetAttribute(AttrRequiredSkill4) != 0) { requiredSkill = character->GetSkill( static_cast<uint32>(item->GetAttribute(AttrRequiredSkill4).get_int()) ); if( !requiredSkill ) return false; if( item->GetAttribute(AttrRequiredSkill4Level) > requiredSkill->GetAttribute(AttrSkillLevel) ) return false; } //Quinary Skill if(item->GetAttribute(AttrRequiredSkill5) != 0) { requiredSkill = character->GetSkill(static_cast<uint32>(item->GetAttribute(AttrRequiredSkill5).get_int())); if( !requiredSkill ) return false; if( item->GetAttribute(AttrRequiredSkill5Level) > requiredSkill->GetAttribute(AttrSkillLevel) ) return false; } //Senary Skill if(item->GetAttribute(AttrRequiredSkill6) != 0) { requiredSkill = character->GetSkill(static_cast<uint32>(item->GetAttribute(AttrRequiredSkill6).get_int())); if( !requiredSkill ) return false; if( item->GetAttribute(AttrRequiredSkill6Level) > requiredSkill->GetAttribute(AttrSkillLevel) ) return false; } return true; }
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; }