void ModuleManager::_processExternalEffect(SubEffect * s) { //50-50 it's targeting a specific module ( i'm assuming here ) GenericModule * mod = m_Modules->GetModule(s->TargetItemID()); if( mod != NULL ) { //calculate new attribute mod->setAttribute(s->AttributeID(), CalculateNewAttributeValue(mod->getAttribute(s->AttributeID()), s->AppliedValue(), s->CalculationType())); } else if( s->TargetItemID() == m_Ship->itemID() ) //guess it's not, but that means it should be targeting our ship itself { //calculate new attribute m_Ship->SetAttribute(s->AttributeID(), CalculateNewAttributeValue(m_Ship->GetAttribute(s->AttributeID()), s->AppliedValue(), s->CalculationType())); } else //i have no idea what their targeting X_X SysLog::Error("ModuleManager", "Process external effect inconsistency. This shouldn't happen"); }
/* 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); }
// 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()); }
//calculate the new value including the stacking penalty EvilNumber ModifyShipAttributesComponent::_calculateNewAttributeValue( EvilNumber sourceAttr, EvilNumber targetAttr, EVECalculationType type, int stackNumber ) { EvilNumber effectiveness = exp(-pow((double)(stackNumber - 1),2)/7.1289); //should be correct, but should be checked return CalculateNewAttributeValue(targetAttr, sourceAttr * effectiveness, type); }