Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated RAH to version 2. Thank you @ccplarrikin #688

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ There are two different distributives for OS X: `-mac` and `-mac-deprecated`.

There is also a [Homebrew](http://brew.sh) option for installing pyfa on OS X. Please note this is maintained by a third-party and is not tested by pyfa developers. Simply fire up in terminal:
```
$ brew cask install pyfa
$ brew install Caskroom/cask/pyfa
```

### Linux Distro-specific Packages
Expand Down
6 changes: 3 additions & 3 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
saveInRoot = False

# Version data
version = "1.22.2"
version = "1.23.2"
tag = "Stable"
expansionName = "YC 118.6"
expansionVersion = "1.0"
expansionName = "YC 118.7"
expansionVersion = "1.4"
evemonMinVersion = "4081"

pyfaPath = None
Expand Down
5 changes: 4 additions & 1 deletion eos/db/gamedata/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@ def searchItems(nameLike, where=None, join=None, eager=None):
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
for token in nameLike.split(' '):
token_safe = u"%{0}%".format(sqlizeString(token))
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), where))
if where is not None:
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), where))
else:
items = items.filter(Item.name.like(token_safe, escape="\\"))
items = items.limit(100).all()
return items

Expand Down
21 changes: 21 additions & 0 deletions eos/db/migrations/upgrade15.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Migration 15

- Delete projected modules on citadels
"""

import sqlalchemy

def upgrade(saveddata_engine):

sql = """
DELETE FROM modules WHERE ID IN
(
SELECT m.ID FROM modules AS m
JOIN fits AS f ON m.fitID = f.ID
WHERE f.shipID IN ("35832", "35833", "35834", "40340")
AND m.projected = 1
)
"""

saveddata_engine.execute(sql)
2 changes: 1 addition & 1 deletion eos/db/saveddata/override.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from eos.types import Override

overrides_table = Table("overrides", saveddata_meta,
Column("itemID", Integer, primary_key=True, index = True),
Column("itemID", Integer, primary_key=True, index = True),
Column("attrID", Integer, primary_key=True, index = True),
Column("value", Float, nullable = False))

Expand Down
214 changes: 202 additions & 12 deletions eos/effects/adaptivearmorhardener.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,207 @@
#
# Used by:
# Module: Reactive Armor Hardener
import logging
import operator

logger = logging.getLogger(__name__)

runTime = "late"
type = "active"
def handler(fit, module, context):
for type in ("kinetic", "thermal", "explosive", "em"):
attr = "armor%sDamageResonance" % type.capitalize()

#Adjust RAH to match the current damage pattern
damagePattern = fit.damagePattern
if damagePattern:
attrDamagePattern = "%sAmount" % type
damagePatternModifier = getattr(damagePattern,attrDamagePattern)/float(sum((damagePattern.emAmount,damagePattern.thermalAmount,damagePattern.kineticAmount,damagePattern.explosiveAmount)))
modifiedResistModifier = (1-(((1-module.getModifiedItemAttr(attr))*4)*(damagePatternModifier)))
module.forceItemAttr(attr, modifiedResistModifier)

fit.ship.multiplyItemAttr(attr, module.getModifiedItemAttr(attr), stackingPenalties=True, penaltyGroup="preMul")
damagePattern = fit.damagePattern

# Skip if there is no damage pattern. Example: projected ships or fleet boosters
if damagePattern:

# Populate a tuple with the damage profile modified by current armor resists.
# Build this up front as there are a number of values we only need to touch once
damagePattern_tuple = []

'''
# Bit of documentation for how the tuple is layed out
damagePattern_tuple.append(['RESIST TYPE',
SHIP ARMOR RESIST AMOUNT,
DAMAGE PATTERN AMOUNT,
MODIFIED DAMAGE PATTERN AMOUNT (SHIP ARMOR RESIST AMOUNT * DAMAGE PATTERN AMOUND),
ADAPTIVE RESIST AMOUNT,
ADAPTIVE RESIST AMOUNT (ORIGINAL))
'''

damagePattern_tuple.append(['Em',
fit.ship.getModifiedItemAttr('armorEmDamageResonance'),
damagePattern.emAmount,
damagePattern.emAmount*fit.ship.getModifiedItemAttr('armorEmDamageResonance'),
module.getModifiedItemAttr('armorEmDamageResonance'),
module.getModifiedItemAttr('armorEmDamageResonance')])

damagePattern_tuple.append(['Thermal',
fit.ship.getModifiedItemAttr('armorThermalDamageResonance'),
damagePattern.thermalAmount,
damagePattern.thermalAmount * fit.ship.getModifiedItemAttr('armorThermalDamageResonance'),
module.getModifiedItemAttr('armorThermalDamageResonance'),
module.getModifiedItemAttr('armorThermalDamageResonance')])

damagePattern_tuple.append(['Kinetic',
fit.ship.getModifiedItemAttr('armorKineticDamageResonance'),
damagePattern.kineticAmount,
damagePattern.kineticAmount*fit.ship.getModifiedItemAttr('armorKineticDamageResonance'),
module.getModifiedItemAttr('armorKineticDamageResonance'),
module.getModifiedItemAttr('armorKineticDamageResonance')])

damagePattern_tuple.append(['Explosive',
fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'),
damagePattern.explosiveAmount,
damagePattern.explosiveAmount*fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'),
module.getModifiedItemAttr('armorExplosiveDamageResonance'),
module.getModifiedItemAttr('armorExplosiveDamageResonance')])

runLoop = 1
countPasses = 1
countPassesDos = 1
resistanceShiftAmount = module.getModifiedItemAttr('resistanceShiftAmount')/100
while runLoop == 1:

for i in range(4):
# Update tuple with current values
attr = "armor%sDamageResonance" % damagePattern_tuple[i][0].capitalize()
damagePattern_tuple[i][3] = damagePattern_tuple[i][2] * damagePattern_tuple[i][1]
damagePattern_tuple[i][4] = module.getModifiedItemAttr(attr)
#logger.debug("Update values (Type|Resist|ModifiedDamage|AdaptiveResists): %s | %f | %f | %f", damagePattern_tuple[i][0], fit.ship.getModifiedItemAttr(attr), damagePattern_tuple[i][3], damagePattern_tuple[i][4])

# Sort the tuple by which resist took the most damage
damagePattern_tuple = sorted(damagePattern_tuple, key=operator.itemgetter(3,0))

if damagePattern.emAmount == damagePattern.thermalAmount == damagePattern.kineticAmount == damagePattern.explosiveAmount:
# If damage pattern is even across the board, we "reset" back to original resist values.
logger.debug("Setting adaptivearmorhardener resists to uniform profile.")
# Do nothing, because the RAH gets recalculated, so just don't change it
runLoop = 0
elif damagePattern_tuple[0][2] == damagePattern_tuple[1][2] == damagePattern_tuple[2][2] == 0:
# If damage pattern is a single source, we set all resists to one damage profile.
logger.debug("Setting adaptivearmorhardener resists to single damage profile.")

#Do this dynamically just in case CCP mucks with the values.
vampDmg=0
for i in [0,1,2]:
attr = "armor%sDamageResonance" % damagePattern_tuple[i][0].capitalize()
vampDmg = vampDmg+1-damagePattern_tuple[i][4]
module.increaseItemAttr(attr, (1-damagePattern_tuple[i][4]))
damagePattern_tuple[i][4] = 1

attr = "armor%sDamageResonance" % damagePattern_tuple[3][0].capitalize()
damagePattern_tuple[3][4]=damagePattern_tuple[3][4]-vampDmg
module.increaseItemAttr(attr, 0-vampDmg)
runLoop = 0
else:
#logger.debug("Multiple damage type profile.")
if damagePattern_tuple[1][4] == 1 == damagePattern_tuple[0][4]:
logger.debug("We've run out of resists to steal. Breaking out of RAH cycle.")
break
elif (countPasses >= 100) or (countPassesDos >= 5):
logger.debug("Looped a total of %f times, and %f times after resistance shift amount was reduced. Most likely the RAH is cycling between two different profiles and is in an infinite loop. Breaking out of RAH cycle.", countPasses, countPassesDos)
# If we hit this break point and have over 100 passes, something has gone horribly wrong.
# Most likely we'll hit this after we've reduced the resist shifting down to .01 and looped 5 times.
break
elif (damagePattern_tuple[0][4] == 1) or (countPasses >= 15):
# Most likely the RAH is cycling between two different profiles and is in an infinite loop.
# Reduce the amount of resists we shift each loop, to try and stabilize on a more average profile.
if resistanceShiftAmount > .01:
resistanceShiftAmount = resistanceShiftAmount - .01
logger.debug("Reducing resistance shift amount to %f", resistanceShiftAmount)
else:
# Start a new counter
countPassesDos = countPassesDos+1

countPasses = countPasses+1
#logger.debug("Looped %f times.", countPasses)
else:
countPasses = countPasses+1
#logger.debug("Looped %f times.",countPasses)

# Loop through the resists that did least damage and figure out how much there is to steal
vampDmg=[0]*2
for i in [0,1]:
attr = "armor%sDamageResonance" % damagePattern_tuple[i][0].capitalize()
if damagePattern_tuple[i][4] < 1-resistanceShiftAmount:
# If there is more than 3% to steal, let's steal 3% and reduce the resit by that amount.
vampDmg[i] = resistanceShiftAmount
else:
# If there is equal to or less than 3% left to steal, grab what we can and set the resist to 0%.
vampDmg[i] = 1-damagePattern_tuple[i][4]

# Adjust the module resists down
if vampDmg[i] > 0:
module.increaseItemAttr(attr, vampDmg[i])
# Set our "ship" resists
damagePattern_tuple[i][1] = fit.ship.getModifiedItemAttr(attr) * module.getModifiedItemAttr(attr)

#Add up the two amounts we stole, and divide it equally between the two
vampDmgTotal = vampDmg[0] + vampDmg[1]

# Loop through the resists that took the most damage, and add what we vamped from the weakest resists.
for i in [2,3]:
attr = "armor%sDamageResonance" % damagePattern_tuple[i][0].capitalize()
# And by add we mean subtract, because in CCPland up is down and down is up
if vampDmgTotal > 0:
module.increaseItemAttr(attr, 0-(vampDmgTotal/2))
# Set our "ship" resists
damagePattern_tuple[i][1] = fit.ship.getModifiedItemAttr(attr)*module.getModifiedItemAttr(attr)

adaptiveResists_tuple = [0.0] * 12
for damagePatternType in damagePattern_tuple:
attr = "armor%sDamageResonance" % damagePatternType[0].capitalize()

if damagePatternType[0] == 'Em':
adaptiveResists_tuple[0] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[4] = damagePatternType[1]
adaptiveResists_tuple[8] = damagePatternType[3]
elif damagePatternType[0] == 'Thermal':
adaptiveResists_tuple[1] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[5] = damagePatternType[1]
adaptiveResists_tuple[9] = damagePatternType[3]
elif damagePatternType[0] == 'Kinetic':
adaptiveResists_tuple[2] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[6] = damagePatternType[1]
adaptiveResists_tuple[10] = damagePatternType[3]
elif damagePatternType[0] == 'Explosive':
adaptiveResists_tuple[3] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[7] = damagePatternType[1]
adaptiveResists_tuple[11] = damagePatternType[3]

logger.debug(
"Adaptive Resists, Ship Resists, Modified Damage (EM|The|Kin|Exp) : %f | %f | %f | %f || %f | %f | %f | %f || %f | %f | %f | %f",
adaptiveResists_tuple[0], adaptiveResists_tuple[1], adaptiveResists_tuple[2], adaptiveResists_tuple[3],
adaptiveResists_tuple[4], adaptiveResists_tuple[5], adaptiveResists_tuple[6], adaptiveResists_tuple[7],
adaptiveResists_tuple[8], adaptiveResists_tuple[9], adaptiveResists_tuple[10],
adaptiveResists_tuple[11])

adaptiveResists_tuple = [0.0] * 12
# Apply module resists to the ship (for reals this time and not just pretend)
for damagePatternType in damagePattern_tuple:
attr = "armor%sDamageResonance" % damagePatternType[0].capitalize()

fit.ship.multiplyItemAttr(attr, module.getModifiedItemAttr(attr), stackingPenalties=True, penaltyGroup="preMul")

if damagePatternType[0] == 'Em':
adaptiveResists_tuple[0] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[4] = fit.ship.getModifiedItemAttr(attr)
adaptiveResists_tuple[8] = damagePatternType[3]
elif damagePatternType[0] == 'Thermal':
adaptiveResists_tuple[1] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[5] = fit.ship.getModifiedItemAttr(attr)
adaptiveResists_tuple[9] = damagePatternType[3]
elif damagePatternType[0] == 'Kinetic':
adaptiveResists_tuple[2] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[6] = fit.ship.getModifiedItemAttr(attr)
adaptiveResists_tuple[10] = damagePatternType[3]
elif damagePatternType[0] == 'Explosive':
adaptiveResists_tuple[3] = module.getModifiedItemAttr(attr)
adaptiveResists_tuple[7] = fit.ship.getModifiedItemAttr(attr)
adaptiveResists_tuple[11] = damagePatternType[3]

logger.debug(
"Adaptive Resists, Ship Resists, Modified Damage (EM|The|Kin|Exp) : %f | %f | %f | %f || %f | %f | %f | %f || %f | %f | %f | %f",
adaptiveResists_tuple[0], adaptiveResists_tuple[1], adaptiveResists_tuple[2], adaptiveResists_tuple[3],
adaptiveResists_tuple[4], adaptiveResists_tuple[5], adaptiveResists_tuple[6], adaptiveResists_tuple[7],
adaptiveResists_tuple[8], adaptiveResists_tuple[9], adaptiveResists_tuple[10], adaptiveResists_tuple[11])
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# Used by:
# Modules named like: Targeting Systems Stabilizer (8 of 8)
type = "offline"
type = "passive"
def handler(fit, module, context):
fit.modules.filteredItemBoost(lambda module: module.item.requiresSkill("Cloaking"),
"cloakingTargetingDelay", module.getModifiedItemAttr("cloakingTargetingDelayBonus"))
5 changes: 5 additions & 0 deletions eos/effects/ecmburstjammer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Used by:
# Modules from group: Burst Jammer (11 of 11)
type = "active"
def handler(fit, module, context):
pass
3 changes: 3 additions & 0 deletions eos/effects/lightningweapon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type = 'active'
def handler(fit, module, context):
pass
4 changes: 2 additions & 2 deletions eos/effects/missileaoecloudsizebonusonline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Used by:
# Modules from group: Missile Guidance Enhancer (3 of 3)
type = "passive"
def handler(fit, container, context):
def handler(fit, module, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"aoeCloudSize", container.getModifiedItemAttr("aoeCloudSizeBonus"),
"aoeCloudSize", module.getModifiedItemAttr("aoeCloudSizeBonus"),
stackingPenalties=True)
4 changes: 2 additions & 2 deletions eos/effects/missileaoevelocitybonusonline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Used by:
# Modules from group: Missile Guidance Enhancer (3 of 3)
type = "passive"
def handler(fit, container, context):
def handler(fit, module, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"aoeVelocity", container.getModifiedItemAttr("aoeVelocityBonus"),
"aoeVelocity", module.getModifiedItemAttr("aoeVelocityBonus"),
stackingPenalties=True)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
type = "passive"
def handler(fit, container, context):
level = container.level if "skill" in context else 1
penalized = False if "skill" in context or "implant" in context else True
penalized = False if "skill" in context or "implant" in context or "booster" in context else True
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"explosionDelay", container.getModifiedItemAttr("maxFlightTimeBonus") * level,
stackingPenalties=penalized)
4 changes: 2 additions & 2 deletions eos/effects/missileexplosiondelaybonusonline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Used by:
# Modules from group: Missile Guidance Enhancer (3 of 3)
type = "passive"
def handler(fit, container, context):
def handler(fit, module, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"explosionDelay", container.getModifiedItemAttr("explosionDelayBonus"),
"explosionDelay", module.getModifiedItemAttr("explosionDelayBonus"),
stackingPenalties=True)
4 changes: 2 additions & 2 deletions eos/effects/missilevelocitybonusonline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Used by:
# Modules from group: Missile Guidance Enhancer (3 of 3)
type = "passive"
def handler(fit, container, context):
def handler(fit, module, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"maxVelocity", container.getModifiedItemAttr("missileVelocityBonus"),
"maxVelocity", module.getModifiedItemAttr("missileVelocityBonus"),
stackingPenalties=True)
Loading