EvilNumber EvilNumber::_Subtract( const EvilNumber & val1, const EvilNumber & val2 ) { EvilNumber result; // WARNING! There should be NO implicit or explicit use of the 'this' pointer here! if (val2.mType == val1.mType) { if (val1.mType == evil_number_float) { result.mValue.fVal = val1.mValue.fVal - val2.mValue.fVal; result.mType = evil_number_float; } else if (val1.mType == evil_number_int) { result.mValue.iVal = val1.mValue.iVal - val2.mValue.iVal; result.mType = evil_number_int; } } else { // we assume that the val argument is the opposite of the 'this' type if (val1.mType == evil_number_float) { result.mValue.fVal = val1.mValue.fVal - double(val2.mValue.iVal); result.mType = evil_number_float; } else if (val1.mType == evil_number_int) { double tVal = (double)val1.mValue.iVal; // normal integer number result.mValue.fVal = tVal - val2.mValue.fVal; result.mType = evil_number_float; } else { assert(false); // crash } // check if we are a integer result.CheckIntegrity(); } return result; }
EvilNumber EvilNumber::_Divide( const EvilNumber & val1, const EvilNumber & val2 ) { EvilNumber result; // WARNING! There should be NO implicit or explicit use of the 'this' pointer here! if (val2.mType == val1.mType) { if (val1.mType == evil_number_float) { result.mValue.fVal = val1.mValue.fVal / val2.mValue.fVal; result.mType = evil_number_float; } else if (val1.mType == evil_number_int) { // make sure we can do things like 2 / 4 = 0.5f result.mValue.fVal = double(val1.mValue.iVal) / double(val2.mValue.iVal); result.mType = evil_number_float; // check if its possibly an integer result.CheckIntegrity(); } } else { // we assume that the val1 argument type is the opposite of the val2 argument type if (val1.mType == evil_number_float) { result.mValue.fVal = val1.mValue.fVal / double(val2.mValue.iVal); result.mType = evil_number_float; } else if (val1.mType == evil_number_int) { double tVal = (double)val1.mValue.iVal; // normal integer number result.mValue.fVal = tVal / val2.mValue.fVal; result.mType = evil_number_float; } else { assert(false); // crash } // check if we are an integer result.CheckIntegrity(); } return result; }
void ActiveModuleProcessingComponent::ProcessActiveCycle() { //TO-DO: Check to see if capacitor is drained at activation or after the cycle //check for stop signal if(m_Stop) return; //else consume capacitor EvilNumber capCapacity = m_Ship->GetAttribute(AttrCharge); EvilNumber capNeed = m_Mod->GetAttribute(AttrCapacitorNeed); capCapacity -= capNeed; m_Ship->SetAttribute(AttrCharge, capCapacity.get_float()); //then check if we are targeting another ship or not and apply attribute changes //maybe we can have a check for modules that repeat the same attributes so we //send the changes just once at activation and at deactivation //--pseudocode-- //if(target != self) // m_ShipAttrComp->ModifyTargetShipAttribute(); //else // m_ShipAttrComp->ModifyShipAttribute(); }
EvilNumber EvilNumber::_Modulus( const EvilNumber & val1, const EvilNumber & val2 ) { EvilNumber result; // WARNING! There should be NO implicit or explicit use of the 'this' pointer here! if (val2.mType == val1.mType) { if (val1.mType == evil_number_float) { result.mValue.iVal = (int64)(val1.mValue.fVal) % (int64)(val2.mValue.fVal); result.mType = evil_number_int; } else if (val1.mType == evil_number_int) { result.mValue.iVal = val1.mValue.iVal % val2.mValue.iVal; result.mType = evil_number_int; } } else { // we assume that the val1 argument type is the opposite of the val2 argument type if (val1.mType == evil_number_float) { result.mValue.iVal = (int64)(val1.mValue.fVal) % val2.mValue.iVal; result.mType = evil_number_int; } else if (val1.mType == evil_number_int) { result.mValue.iVal = val1.mValue.iVal % (int64)(val2.mValue.fVal); result.mType = evil_number_int; } else { assert(false); // crash } // check if we are a integer result.CheckIntegrity(); } return result; }
EvilNumber Character::GetSPPerMin( SkillRef skill ) { EvilNumber primarySkillTrainingAttr = skill->GetAttribute(AttrPrimaryAttribute); EvilNumber secondarySkillTrainingAttr = skill->GetAttribute(AttrSecondaryAttribute); EvilNumber primarySPperMin = GetAttribute( (uint32)(primarySkillTrainingAttr.get_int()) ); EvilNumber secondarySPperMin = GetAttribute( (uint32)(secondarySkillTrainingAttr.get_int()) ); //EvilNumber skillLearningLevel(0); // ////3374 - Skill Learning //SkillRef skillLearning = GetSkill( 3374 ); //if( skillLearning ) // skillLearningLevel = skillLearning->GetAttribute(AttrSkillLevel); primarySPperMin = primarySPperMin + secondarySPperMin / 2.0f; //primarySPperMin = primarySPperMin * (EvilNumber(1.0f) + EvilNumber(0.02f) * skillLearningLevel); // 100% Training bonus for 30day and under character age has been removed in Incursion // http://www.eveonline.com/en/incursion/article/57/learning-skills-are-going-away // Check Total SP Trained for this character against the threshold for granting the 100% training bonus: //if( m_totalSPtrained.get_float() < ((double)MAX_SP_FOR_100PCT_TRAINING_BONUS) ) // primarySPperMin = primarySPperMin * EvilNumber(2.0f); return primarySPperMin; }
EvilNumber EffectiveStanding( EvilNumber YourStanding, EvilNumber ConnectionsSkillLevel, EvilNumber DiplomacySkillLevel ) { EvilNumber SkillLevel(0.0); if( YourStanding < 0.0 ) SkillLevel = DiplomacySkillLevel; else SkillLevel = ConnectionsSkillLevel; return (YourStanding.get_float() + ((10.0 - YourStanding.get_float()) * (0.04 * (SkillLevel.get_float())))); }
EvilNumber ME_EffectOnWaste( EvilNumber MaterialAmount, EvilNumber BaseWasteFactor, EvilNumber MaterialEfficiency ) { EvilNumber ME_Factor(0.0); if( MaterialEfficiency >= 0 ) ME_Factor = (1.0 / (MaterialEfficiency.get_float() + 1.0)); else ME_Factor = (1.0 - MaterialEfficiency.get_float()); return (floor(0.5 + (MaterialAmount.get_float() * (BaseWasteFactor.get_float() / 100.0) * ME_Factor.get_float()))); }
uint32 TargetManager::TimeToLock(ShipRef ship, SystemEntity *target) const { EvilNumber scanRes = ship->GetAttribute(AttrScanResolution); EvilNumber sigRad(500); if( target->Item().get() != NULL ) if( target->Item()->HasAttribute(AttrSignatureRadius) ) sigRad = target->Item()->GetAttribute(AttrSignatureRadius); EvilNumber time = ( EvilNumber(40000) / ( scanRes ) ) /( EvilNumber::pow( e_log( sigRad + e_sqrt( sigRad * sigRad + 1) ), 2) ); return static_cast<uint32>(time.get_float() * 1000); // Timer uses ms instead of seconds }
bool AttributeMap::Change( uint32 attributeID, EvilNumber& old_val, EvilNumber& new_val ) { Notify_OnModuleAttributeChange modChange; modChange.ownerID = mItem.ownerID(); modChange.itemKey = mItem.itemID(); modChange.attributeID = attributeID; modChange.time = Win32TimeNow(); modChange.newValue = new_val.GetPyObject(); modChange.oldValue = old_val.GetPyObject(); return SendAttributeChanges(modChange.Encode()); }
bool AttributeMap::Change( uint32 attributeID, EvilNumber& old_val, EvilNumber& new_val ) { mChanged = true; PyTuple* AttrChange = new PyTuple(7); AttrChange->SetItem(0, new PyString("OnModuleAttributeChange")); AttrChange->SetItem(1, new PyInt(mItem.ownerID())); AttrChange->SetItem(2, new PyInt(mItem.itemID())); AttrChange->SetItem(3, new PyInt(attributeID)); AttrChange->SetItem(4, new PyLong(Win32TimeNow())); AttrChange->SetItem(5, old_val.GetPyObject()); AttrChange->SetItem(6, new_val.GetPyObject()); return SendAttributeChanges(AttrChange); }
/* * 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 ) ); } }
/* rewrote attrib calculations and implemented true stacking penality, with checks for exceptions. -allan 13April16 */ void ModifyModuleAttributesComponent::_modifyModuleAttributes(GenericModule* targetMod, uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type) { uint8 stackSize = 1; EvilNumber modVal = m_Mod->GetAttribute(sourceAttrID), startVal = targetMod->GetAttribute(targetAttrID); /* check for attribs that are NOT penalized here, and bypass stacking method. */ /* note: DCU, rigs and subsystems do not use this method */ if ((targetAttrID != AttrWarpFactor) or (sourceAttrID != AttrCargoCapacityMultiplier)) { std::map<uint16, uint8>::iterator itr = m_attribMap.find(targetAttrID); if (itr != m_attribMap.end()) { /** @todo verify these module states */ if (m_Mod->GetModuleState() == MOD_ONLINE) stackSize = ++itr->second; else if ((m_Mod->GetModuleState() == MOD_OFFLINE) or (m_Mod->GetModuleState() == MOD_DEACTIVATING)) /** @todo implement the difference between MOD_OFFLINE and MOD_DEACTIVATING */ { if (itr->second == 1) m_attribMap.erase(itr); else stackSize = --itr->second; } } else m_attribMap.emplace(targetAttrID, 1); } double effectiveness = 1; if (m_Mod->GetModuleState() == MOD_ONLINE) { effectiveness = exp(-pow(((stackSize - 1)/2.67),2)); //stacking calculation fixed -allan 20Dec15 m_Mod->SetEffectiveness(targetAttrID, effectiveness); } else if ((m_Mod->GetModuleState() == MOD_OFFLINE) or (m_Mod->GetModuleState() == MOD_DEACTIVATING)) { effectiveness = m_Mod->GetEffectiveness(targetAttrID); } if (effectiveness <= 0) { /* this should never happen */ codelog(SHIP__MODULE_ERROR, "MMAC::_modifyModuleAttributes() - effectiveness <= 0"); targetMod->GetShipRef()->GetPilot()->SendErrorMsg("Internal Server Error. Ref: ServerError 25620"); } modVal *= effectiveness; EvilNumber newVal = CalculateNewAttributeValue(startVal, modVal, type); _log(SHIP__MODULE_TRACE, "MMAC::_modifyModuleAttributes() - origVal:%f, Mod:%f, newVal:%f, stackSize:%u, effective:%f, type:%i", \ startVal.get_float(), modVal.get_float(), newVal.get_float(), stackSize, effectiveness, (int)type); SetAttribute(targetMod, targetAttrID, newVal); }
void Character::_CalculateTotalSPTrained() { // Loop through all skills trained and calculate total SP this character has trained so far, // NOT including the skill currently being trained: double exponent = 0.0f; double totalSP = 0.0f; EvilNumber skillLevel; EvilNumber skillRank; std::vector<InventoryItemRef> skills; GetSkillsList( skills ); std::vector<InventoryItemRef>::iterator cur, end; cur = skills.begin(); end = skills.end(); for(; cur != end; cur++) { // Calculate exact SP from each skill and add to total SP skillLevel = cur->get()->GetAttribute( AttrSkillLevel ); skillRank = cur->get()->GetAttribute( AttrSkillTimeConstant ); totalSP += 250.0f * (double)(skillRank.get_int()) * pow(32.0, (double)(((double)(skillLevel.get_int()) - 1.0f) / 2.0f)); } m_totalSPtrained = totalSP; }
EvilNumber Character::GetSPPerMin( SkillRef skill ) { EvilNumber primarySkillTrainingAttr = skill->GetAttribute(AttrPrimaryAttribute); EvilNumber secondarySkillTrainingAttr = skill->GetAttribute(AttrSecondaryAttribute); EvilNumber primarySPperMin = GetAttribute( (uint32)(primarySkillTrainingAttr.get_int()) ); EvilNumber secondarySPperMin = GetAttribute( (uint32)(secondarySkillTrainingAttr.get_int()) ); EvilNumber skillLearningLevel(0); //3374 - Skill Learning SkillRef skillLearning = GetSkill( 3374 ); if( skillLearning ) skillLearningLevel = skillLearning->GetAttribute(AttrSkillLevel); primarySPperMin = primarySPperMin + secondarySPperMin / 2.0f; primarySPperMin = primarySPperMin * (EvilNumber(1.0f) + EvilNumber(0.02f) * skillLearningLevel); // Check Total SP Trained for this character against the threshold for granting the 100% training bonus: if( m_totalSPtrained.get_float() < ((double)MAX_SP_FOR_100PCT_TRAINING_BONUS) ) primarySPperMin = primarySPperMin * EvilNumber(2.0f); return primarySPperMin; }
EvilNumber ProductionTime( EvilNumber BaseProductionTime, EvilNumber ProductivityModifier, EvilNumber ProductionEfficiency, EvilNumber ProductionTimeModifier ) { EvilNumber PE_Factor(0.0); if( ProductionEfficiency >= 0.0 ) PE_Factor = (ProductionEfficiency.get_float() / (1.0 + ProductionEfficiency.get_float())); else PE_Factor = (ProductionEfficiency.get_float() - 1.0); return (BaseProductionTime.get_float() * (1.0 - (ProductivityModifier.get_float() / BaseProductionTime.get_float()) * (PE_Factor.get_float())) * ProductionTimeModifier.get_float()); }
EvilNumber TargetingLockTime( EvilNumber YourEffectiveScanResolution, EvilNumber TargetEffectiveSignatureRadius ) { return (40000.0 / (YourEffectiveScanResolution.get_float() * pow(asinh(TargetEffectiveSignatureRadius.get_float()),2))); }
EvilNumber StationTaxesForReprocessing( EvilNumber CharacterStandingWithStationOwner ) { return (5.0 - 0.75 * CharacterStandingWithStationOwner.get_float()); }
EvilNumber EffectiveRefiningYield( EvilNumber StationEquipmentYield, EvilNumber RefiningSkillLevel, EvilNumber RefiningEfficiencySkillLevel, EvilNumber OreSpecificProcessingSkillLevel ) { return (StationEquipmentYield.get_float() + 0.375 * (1 + (RefiningSkillLevel.get_float() * 0.02)) * (1 + (RefiningEfficiencySkillLevel.get_float() * 0.04)) * (1 + (OreSpecificProcessingSkillLevel.get_float() * 0.05))); }
EvilNumber BlueprintInventionChance( EvilNumber BaseChance, EvilNumber EncryptionSkillLevel, EvilNumber DataCore1SkillLevel, EvilNumber DataCore2SkillLevel, EvilNumber MetaLevel, EvilNumber DecryptorModifier ) { return (BaseChance.get_float() * (1+0.01*EncryptionSkillLevel.get_float()) * (1+(DataCore1SkillLevel.get_float()+DataCore2SkillLevel.get_float()) * (0.1 / (5 - MetaLevel.get_float())) * DecryptorModifier.get_float())); }
EvilNumber ResearchPointsPerDay( EvilNumber Multiplier, EvilNumber AgentEffectiveQuality, EvilNumber YourResearchSkillLevel, EvilNumber AgentResearchSkillLevel ) { return (Multiplier.get_float() * (1 + (AgentEffectiveQuality.get_float() / 100.0)) * pow(YourResearchSkillLevel.get_float() + AgentResearchSkillLevel.get_float(),2)); }
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!" ) ); } } } }
EvilNumber AgentEffectiveQuality( EvilNumber AgentQuality, EvilNumber NegotiationSkillLevel, EvilNumber AgentPersonalStanding ) { return (AgentQuality.get_float() + (5.0 * NegotiationSkillLevel.get_float()) + AgentPersonalStanding.get_float()); }
// set attributes that are not stackable here...calibration, PG, CPU, etc. void ModifyModuleAttributesComponent::ModifyNonStackingModuleAttributes(GenericModule* targetMod, uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type) { EvilNumber newVal = CalculateNewAttributeValue(targetMod->GetAttribute(targetAttrID), m_Mod->GetAttribute(sourceAttrID), type); if (!targetMod->getItem()->SetAttribute(targetAttrID, newVal)) sLog.Error("MMAC::ModifyNonStackingModuleAttributes()","Failed to set attribute %u to %f on module %u", targetAttrID, newVal.get_float(), targetMod->itemID()); }
void UT_EvilNumber() { // EVILNUMBER MATH TESTING: sLog.Log( "EvilNumber Testing", ">>>>> BEGIN" ); EvilNumber fval1(5.0); EvilNumber fval2(-12.123); EvilNumber ival1(10); EvilNumber ival2(123456); EvilNumber result; // UNARY: sLog.Log( "EvilNumber Test", "before ival1++ ival1 = %s", ival1.to_str().c_str(), result.to_str().c_str() ); result = ival1++; sLog.Log( "EvilNumber Test", "ival1++ = %s", ival1.to_str().c_str(), result.to_str().c_str() ); sLog.Log( "EvilNumber Test", "before ival2-- ival2 = %s", ival2.to_str().c_str(), result.to_str().c_str() ); result = ival2--; sLog.Log( "EvilNumber Test", "ival2-- = %s-- = %s", ival2.to_str().c_str(), result.to_str().c_str() ); sLog.Log( "EvilNumber Test", "before fval1++ fval1 = %s", fval1.to_str().c_str(), result.to_str().c_str() ); result = fval1++; sLog.Log( "EvilNumber Test", "fval1++ = %s++ = %s", fval1.to_str().c_str(), result.to_str().c_str() ); sLog.Log( "EvilNumber Test", "before fval2-- fval2 = %s", fval2.to_str().c_str(), result.to_str().c_str() ); result = fval2--; sLog.Log( "EvilNumber Test", "fval2-- = %s-- = %s", fval2.to_str().c_str(), result.to_str().c_str() ); // MIXED: result = fval1 + ival2; sLog.Log( "EvilNumber Test", "fval1 + ival2 = %s + %s = %s", fval1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); result = fval1 - ival2; sLog.Log( "EvilNumber Test", "fval1 - ival2 = %s - %s = %s", fval1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); result = fval1 * ival2; sLog.Log( "EvilNumber Test", "fval1 * ival2 = %s * %s = %s", fval1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); result = fval1 / ival2; sLog.Log( "EvilNumber Test", "fval1 / ival2 = %s / %s = %s", fval1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); // BOTH INT: result = ival1 + ival2; sLog.Log( "EvilNumber Test", "ival1 + ival2 = %s + %s = %s", ival1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); result = ival1 - ival2; sLog.Log( "EvilNumber Test", "ival1 - ival2 = %s - %s = %s", ival1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); result = ival1 * ival2; sLog.Log( "EvilNumber Test", "ival1 * ival2 = %s * %s = %s", ival1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); result = ival1 / ival2; sLog.Log( "EvilNumber Test", "ival1 / ival2 = %s / %s = %s", ival1.to_str().c_str(), ival2.to_str().c_str(), result.to_str().c_str() ); // BOTH FLOAT: result = fval1 + fval2; sLog.Log( "EvilNumber Test", "fval1 + fval2 = %s + %s = %s", fval1.to_str().c_str(), fval2.to_str().c_str(), result.to_str().c_str() ); result = fval1 - fval2; sLog.Log( "EvilNumber Test", "fval1 - fval2 = %s - %s = %s", fval1.to_str().c_str(), fval2.to_str().c_str(), result.to_str().c_str() ); fval2 = 2.0; result = fval1 * fval2; sLog.Log( "EvilNumber Test", "fval1 * fval2 = %s * %s = %s", fval1.to_str().c_str(), fval2.to_str().c_str(), result.to_str().c_str() ); result = fval1 / fval2; sLog.Log( "EvilNumber Test", "fval1 / fval2 = %s / %s = %s", fval1.to_str().c_str(), fval2.to_str().c_str(), result.to_str().c_str() ); result = EvilNumber(6.0) + EvilNumber(100); sLog.Log( "EvilNumber Test", "6.0 + 100= %s", result.to_str().c_str() ); result = EvilNumber(52) - EvilNumber(26.0); sLog.Log( "EvilNumber Test", "52 - 26.0= %s", result.to_str().c_str() ); result = EvilNumber(22) * EvilNumber(10); sLog.Log( "EvilNumber Test", "22 * 10= %s", result.to_str().c_str() ); result = EvilNumber(220.0) / EvilNumber(11); sLog.Log( "EvilNumber Test", "220.0 / 11= %s", result.to_str().c_str() ); result = EvilNumber::sin(EvilNumber(3.14159*1.5)); sLog.Log( "EvilNumber Test", "sin(3.14159*1.5)= %f, EvilNumber::sin(3.14159*1.5)= %s", sin(3.14159*1.5), result.to_str().c_str() ); result = EvilNumber::cos(EvilNumber(3.14159*1.5)); sLog.Log( "EvilNumber Test", "cos(-3.14159*1.5)= %f, EvilNumber::cos(-3.14159*1.5)= %s", cos(-3.14159*1.5), result.to_str().c_str() ); result = EvilNumber::tan(EvilNumber(3.14159*3)); sLog.Log( "EvilNumber Test", "tan(-3.14159*3)= %f, EvilNumber:tan(-3.14159*3)= %s", tan(-3.14159*3), result.to_str().c_str() ); result = EvilNumber::asin(EvilNumber(0.5)); sLog.Log( "EvilNumber Test", "asin(0.5)= %f, EvilNumber::asin(0.5)= %s", asin(0.5), result.to_str().c_str() ); result = EvilNumber::acos(EvilNumber(-0.5)); sLog.Log( "EvilNumber Test", "acos(-0.5)= %f, EvilNumber::acos(-0.5)= %s", acos(-0.5), result.to_str().c_str() ); result = EvilNumber::atan(EvilNumber(3.0)); sLog.Log( "EvilNumber Test", "atan(3.0)= %f, EvilNumber::atan(3.0)= %s", atan(3.0), result.to_str().c_str() ); result = EvilNumber::sqrt(EvilNumber(400.0)); sLog.Log( "EvilNumber Test", "sqrt(400.0)= %f, EvilNumber::sqrt(400.0)= %s", sqrt(400.0), result.to_str().c_str() ); result = EvilNumber::pow(EvilNumber(39.0), EvilNumber(2.0)); sLog.Log( "EvilNumber Test", "pow(39.0,2.0)= %f, EvilNumber::pow(39.0,2.0)= %s", pow(39.0,2.0), result.to_str().c_str() ); result = EvilNumber::log(EvilNumber(1.5)); sLog.Log( "EvilNumber Test", "log(1.5)= %f, EvilNumber::log(1.5)= %s", log(1.5), result.to_str().c_str() ); result = EvilNumber::log10(EvilNumber(1.5)); sLog.Log( "EvilNumber Test", "log10(1.5)= %f, EvilNumber::log10(1.5)= %s", log10(1.5), result.to_str().c_str() ); result = EvilNumber::exp(EvilNumber(1.5)); sLog.Log( "EvilNumber Test", "exp(1.5)= %f, EvilNumber::exp(1.5)= %s", exp(1.5), result.to_str().c_str() ); sLog.Log( "EvilNumber Testing", "<<<<< END" ); }
void Character::UpdateSkillQueue() { Client *c = m_factory.entity_list.FindCharacter( itemID() ); SkillRef currentTraining = GetSkillInTraining(); if( currentTraining ) { if( m_skillQueue.empty() || currentTraining->typeID() != m_skillQueue.front().typeID ) { // either queue is empty or skill with different typeID is in training ... // stop training: _log( ITEM__ERROR, "%s (%u): Stopping training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() ); /* uint64 timeEndTrain = currentTraining->expiryTime(); if(timeEndTrain != 0) { double nextLevelSP = currentTraining->GetSPForLevel( currentTraining->skillLevel() + 1 ); double SPPerMinute = GetSPPerMin( currentTraining ); double minRemaining = (double)(timeEndTrain - Win32TimeNow()) / (double)Win32Time_Minute; currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) ); } currentTraining->Clear_expiryTime(); */ EvilNumber timeEndTrain = currentTraining->GetAttribute(AttrExpiryTime); if (timeEndTrain != 0) { EvilNumber nextLevelSP = currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) + 1 ); EvilNumber SPPerMinute = GetSPPerMin( currentTraining ); EvilNumber minRemaining = (timeEndTrain - EvilNumber(Win32TimeNow())) / (double)Win32Time_Minute; //currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) ); currentTraining->SetAttribute(AttrSkillPoints, nextLevelSP - (minRemaining * SPPerMinute)); } currentTraining->SetAttribute(AttrExpiryTime, 0); currentTraining->MoveInto( *this, flagSkill, true ); if( c != NULL ) { OnSkillTrainingStopped osst; osst.itemID = currentTraining->itemID(); osst.endOfTraining = 0; PyTuple* tmp = osst.Encode(); c->QueueDestinyEvent( &tmp ); PySafeDecRef( tmp ); c->UpdateSkillTraining(); } // nothing currently in training currentTraining = SkillRef(); } } EvilNumber nextStartTime = EvilTimeNow(); while( !m_skillQueue.empty() ) { if( !currentTraining ) { // something should be trained, get desired skill uint32 skillTypeID = m_skillQueue.front().typeID; currentTraining = GetSkill( skillTypeID ); if( !currentTraining ) { _log( ITEM__ERROR, "%s (%u): Skill %u to train was not found.", itemName().c_str(), itemID(), skillTypeID ); break; } _log( ITEM__TRACE, "%s (%u): Starting training of skill %s (%u).", m_itemName.c_str(), m_itemID, currentTraining->itemName().c_str(), currentTraining->itemID() ); EvilNumber SPPerMinute = GetSPPerMin( currentTraining ); // double SPToNextLevel = currentTraining->GetSPForLevel( currentTraining->skillLevel() + 1 ) - currentTraining->skillPoints(); EvilNumber SPToNextLevel = currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) + 1) - currentTraining->GetAttribute(AttrSkillPoints); //uint64 timeTraining = nextStartTime + Win32Time_Minute * SPToNextLevel / SPPerMinute; EvilNumber timeTraining = nextStartTime + EvilTime_Minute * SPToNextLevel / SPPerMinute; currentTraining->MoveInto( *this, flagSkillInTraining ); //currentTraining->Set_expiryTime( timeTraining ); currentTraining->SetAttribute(AttrExpiryTime, timeTraining); if( c != NULL ) { OnSkillStartTraining osst; osst.itemID = currentTraining->itemID(); osst.endOfTraining = timeTraining.get_int(); PyTuple* tmp = osst.Encode(); c->QueueDestinyEvent( &tmp ); PySafeDecRef( tmp ); c->UpdateSkillTraining(); } } //if( currentTraining->expiryTime() <= Win32TimeNow() ) if( currentTraining->GetAttribute(AttrExpiryTime) <= EvilTimeNow() ) { // training has been finished: _log( ITEM__ERROR, "%s (%u): Finishing training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() ); //currentTraining->Set_skillLevel( currentTraining->skillLevel() + 1 ); //currentTraining->Set_skillPoints( currentTraining->GetSPForLevel( currentTraining->skillLevel() ) ); //nextStartTime = currentTraining->expiryTime(); //currentTraining->Clear_expiryTime(); currentTraining->SetAttribute(AttrSkillLevel, currentTraining->GetAttribute(AttrSkillLevel) + 1 ); currentTraining->SetAttribute(AttrSkillPoints, currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) ) ); nextStartTime = currentTraining->GetAttribute(AttrExpiryTime); currentTraining->SetAttribute(AttrExpiryTime, 0); currentTraining->MoveInto( *this, flagSkill, true ); if( c != NULL ) { OnSkillTrained ost; ost.itemID = currentTraining->itemID(); PyTuple* tmp = ost.Encode(); c->QueueDestinyEvent( &tmp ); PySafeDecRef( tmp ); c->UpdateSkillTraining(); } // erase first element in skill queue m_skillQueue.erase( m_skillQueue.begin() ); // nothing currently in training currentTraining = SkillRef(); } // else the skill is in training ... else break; } // Re-Calculate total SP trained and store in internal variable: _CalculateTotalSPTrained(); // Save character and skill data: SaveCharacter(); SaveSkillQueue(); }
EvilNumber RequiredAgentStanding( EvilNumber AgentLevel, EvilNumber AgentQuality ) { return (((AgentLevel.get_float() - 1) * 2) + (AgentQuality.get_float()/20.0)); }
EvilNumber MissionStandingIncrease( EvilNumber BaseMissionIncrease, EvilNumber YourSocialSkillLevel ) { return (BaseMissionIncrease * (1 + 0.05 * YourSocialSkillLevel.get_float())); }
EvilNumber SkillPointsAtLevel( EvilNumber SkillLevel, EvilNumber SkillRank ) { return (pow( 2, (2.5 * SkillLevel.get_float()) - 2.5 ) * 250.0 * SkillRank); }
void Character::UpdateSkillQueue() { Client *c = m_factory.entity_list.FindCharacter( itemID() ); SkillRef currentTraining = GetSkillInTraining(); if( currentTraining ) { if( m_skillQueue.empty() || currentTraining->typeID() != m_skillQueue.front().typeID ) { // either queue is empty or skill with different typeID is in training ... // stop training: _log( ITEM__ERROR, "%s (%u): Stopping training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() ); /* uint64 timeEndTrain = currentTraining->expiryTime(); if(timeEndTrain != 0) { double nextLevelSP = currentTraining->GetSPForLevel( currentTraining->skillLevel() + 1 ); double SPPerMinute = GetSPPerMin( currentTraining ); double minRemaining = (double)(timeEndTrain - Win32TimeNow()) / (double)Win32Time_Minute; currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) ); } currentTraining->Clear_expiryTime(); */ EvilNumber timeEndTrain = currentTraining->GetAttribute(AttrExpiryTime); if (timeEndTrain != 0) { EvilNumber nextLevelSP = currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) + 1 ); EvilNumber SPPerMinute = GetSPPerMin( currentTraining ); EvilNumber minRemaining = (timeEndTrain - EvilNumber(Win32TimeNow())) / (double)Win32Time_Minute; //currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) ); EvilNumber skillPointsTrained = nextLevelSP - (minRemaining * SPPerMinute); currentTraining->SetAttribute(AttrSkillPoints, skillPointsTrained); sLog.Debug( "", "Skill %s (%u) trained %u skill points before termination from training queue", currentTraining->itemName().c_str(), currentTraining->itemID(), skillPointsTrained.get_float() ); } currentTraining->SetAttribute(AttrExpiryTime, 0); currentTraining->MoveInto( *this, flagSkill, true ); if( c != NULL ) { OnSkillTrainingStopped osst; osst.itemID = currentTraining->itemID(); osst.endOfTraining = 0; PyTuple* tmp = osst.Encode(); c->QueueDestinyEvent( &tmp ); PySafeDecRef( tmp ); c->UpdateSkillTraining(); } // nothing currently in training currentTraining = SkillRef(); } } EvilNumber nextStartTime = EvilTimeNow(); while( !m_skillQueue.empty() ) { if( !currentTraining ) { // something should be trained, get desired skill uint32 skillTypeID = m_skillQueue.front().typeID; currentTraining = GetSkill( skillTypeID ); if( !currentTraining ) { _log( ITEM__ERROR, "%s (%u): Skill %u to train was not found.", itemName().c_str(), itemID(), skillTypeID ); break; } sLog.Debug( "Character::UpdateSkillQueue()", "%s (%u): Starting training of skill %s (%u)", m_itemName.c_str(), m_itemID, currentTraining->itemName().c_str(), currentTraining->itemID() ); EvilNumber SPPerMinute = GetSPPerMin( currentTraining ); EvilNumber NextLevel = currentTraining->GetAttribute(AttrSkillLevel) + 1; EvilNumber SPToNextLevel = currentTraining->GetSPForLevel( NextLevel ) - currentTraining->GetAttribute(AttrSkillPoints); sLog.Debug( " ", "Training skill at %f SP/min", SPPerMinute.get_float() ); sLog.Debug( " ", "%f SP to next Level of %d", SPToNextLevel.get_float(), NextLevel.get_int() ); SPPerMinute.to_float(); SPToNextLevel.to_float(); nextStartTime.to_float(); EvilNumber timeTraining = nextStartTime + EvilTime_Minute * SPToNextLevel / SPPerMinute; currentTraining->MoveInto( *this, flagSkillInTraining ); double dbl_timeTraining = timeTraining.get_float() + (double)(Win32Time_Second * 10); currentTraining->SetAttribute(AttrExpiryTime, dbl_timeTraining); // Set server-side // skill expiry + 10 sec sLog.Debug( " ", "Calculated time to complete training = %s", Win32TimeToString((uint64)dbl_timeTraining).c_str() ); if( c != NULL ) { OnSkillStartTraining osst; osst.itemID = currentTraining->itemID(); osst.endOfTraining = timeTraining.get_float(); PyTuple* tmp = osst.Encode(); c->QueueDestinyEvent( &tmp ); PySafeDecRef( tmp ); c->UpdateSkillTraining(); } } if( currentTraining->GetAttribute(AttrExpiryTime) <= EvilTimeNow() ) { // training has been finished: sLog.Debug( "Character::UpdateSkillQueue()", "%s (%u): Finishing training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() ); currentTraining->SetAttribute(AttrSkillLevel, currentTraining->GetAttribute(AttrSkillLevel) + 1 ); currentTraining->SetAttribute(AttrSkillPoints, currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) ), true); nextStartTime = currentTraining->GetAttribute(AttrExpiryTime); currentTraining->SetAttribute(AttrExpiryTime, 0); currentTraining->MoveInto( *this, flagSkill, true ); if( c != NULL ) { OnSkillTrained ost; ost.itemID = currentTraining->itemID(); PyTuple* tmp = ost.Encode(); c->QueueDestinyEvent( &tmp ); PySafeDecRef( tmp ); c->UpdateSkillTraining(); } // erase first element in skill queue m_skillQueue.erase( m_skillQueue.begin() ); // nothing currently in training currentTraining = SkillRef(); } // else the skill is in training ... else break; } // Re-Calculate total SP trained and store in internal variable: _CalculateTotalSPTrained(); // Save character and skill data: SaveCharacter(); SaveSkillQueue(); }
EvilNumber TradeBrokerFee( EvilNumber BrokerRelationsSkillLevel, EvilNumber FactionStanding, EvilNumber CorporationStanding ) { return (100.0 * ((0.01 - 0.0005 * BrokerRelationsSkillLevel.get_float()) / (pow( 2, (0.14 * FactionStanding.get_float() + 0.06 * CorporationStanding.get_float()) )))); }