示例#1
0
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;
}
示例#2
0
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;

}
示例#3
0
/*
 * 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 ) );
    }
}
示例#4
0
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;
}
示例#5
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() ) );
}
示例#6
0
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 );
}
示例#7
0
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)
{}
示例#8
0
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!") );
    }
}
示例#9
0
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;
}
示例#10
0
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!") );
    }
}
示例#11
0
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);
	}
}
示例#12
0
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();
}
示例#13
0
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);
	}
}
示例#14
0
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 );
}
示例#15
0
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;
}
示例#16
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);
    }
}
示例#17
0
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!");

}
示例#18
0
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!" ) );
			}
		}
    }
}
示例#19
0
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;
}
示例#20
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;
}
示例#21
0
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;
}
示例#22
0
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() ) );
	}
	
}
示例#23
0
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;
}