Merge pull request #214 from blitzmann/singularity

This commit is contained in:
Anton Vorobyov
2014-12-08 03:05:04 +03:00
41 changed files with 353 additions and 19 deletions

View File

@@ -21,7 +21,7 @@ evemonMinVersion = "4081"
# Database version (int ONLY)
# Increment every time we need to flag for user database upgrade/modification
dbversion = 2
dbversion = 3
pyfaPath = None
savePath = None

View File

@@ -40,6 +40,15 @@ gamedata_meta = MetaData()
gamedata_meta.bind = gamedata_engine
gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on_commit=False)()
# This should be moved elsewhere, maybe as an actual query. Current, without try-except, it breaks when making a new
# game db because we haven't reached gamedata_meta.create_all()
try:
config.gamedata_version = gamedata_session.execute(
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
).fetchone()[0]
except:
config.gamedata_version = None
saveddata_connectionstring = config.saveddata_connectionstring
if saveddata_connectionstring is not None:
if callable(saveddata_connectionstring):
@@ -75,3 +84,4 @@ if config.saveddata_connectionstring == "sqlite:///:memory:":
def rollback():
with sd_lock:
saveddata_session.rollback()

View File

@@ -0,0 +1,13 @@
"""
Migration 3
- Adds mode column for fits (t3 dessy)
"""
import sqlalchemy
def upgrade(saveddata_engine):
try:
saveddata_engine.execute("SELECT mode FROM fits LIMIT 1")
except sqlalchemy.exc.DatabaseError:
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN modeID INTEGER")

View File

@@ -40,7 +40,9 @@ fits_table = Table("fits", saveddata_meta,
Column("characterID", ForeignKey("characters.ID"), nullable = True),
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
Column("booster", Boolean, nullable = False, index = True, default = 0),
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True))
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
Column("modeID", Integer, nullable=True),
)
projectedFits_table = Table("projectedFits", saveddata_meta,
Column("sourceID", ForeignKey("fits.ID"), primary_key = True),

View File

@@ -0,0 +1,4 @@
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("ORE Freighter").level
fit.ship.boostItemAttr("shipMaintenanceBayCapacity", ship.getModifiedItemAttr("freighterBonusO1")*level)

View File

@@ -0,0 +1,5 @@
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("ORE Freighter").level
fit.ship.boostItemAttr("agility", ship.getModifiedItemAttr("freighterBonusO2")*level,
stackingPenalties = True)

View File

@@ -0,0 +1,4 @@
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("agility", 1/module.getModifiedItemAttr("modeAgilityPostDiv"),
stackingPenalties = True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,11 @@
type = "passive"
def handler(fit, module, context):
for resType in ("Em", "Explosive", "Kinetic"):
fit.ship.multiplyItemAttr("armor{0}DamageResonance".format(resType),
1/module.getModifiedItemAttr("mode{0}ResistancePostDiv".format(resType)),
stackingPenalties = True, penaltyGroup="postDiv")
# Thermal != Thermic
fit.ship.multiplyItemAttr("armorThermalDamageResonance",
1/module.getModifiedItemAttr("modeThermicResistancePostDiv"),
stackingPenalties = True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,5 @@
type = "passive"
def handler(fit, module, context):
level = fit.character.getSkill("Minmatar Destroyer").level
fit.ship.multiplyItemAttr("signatureRadius", 1/module.getModifiedItemAttr("modeSignatureRadiusPostDiv"),
stackingPenalties = True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,4 @@
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("maxVelocity", 1/module.getModifiedItemAttr("modeVelocityPostDiv"),
stackingPenalties = True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,4 @@
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Astrometrics"),
"cpu", ship.getModifiedItemAttr("roleBonusTacticalDestroyer1"))

View File

@@ -0,0 +1,5 @@
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Tactical Destroyer").level
fit.modules.filteredItemBoost(lambda mod: True, "heatDamage",
ship.getModifiedItemAttr("shipBonusTacticalDestroyerAmarr3") * level)

View File

@@ -0,0 +1,4 @@
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("maxTargetRange", 1/module.getModifiedItemAttr("modeMaxTargetRangePostDiv"),
stackingPenalties = True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,4 @@
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("scanResolution", 1/module.getModifiedItemAttr("modeScanResPostDiv"),
stackingPenalties = True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,4 @@
type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("scanRadarStrength", 1/module.getModifiedItemAttr("modeRadarStrengthPostDiv"),
stackingPenalties = True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,5 @@
type = "passive"
def handler(fit, module, context):
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Small Energy Turret"),
"maxRange", 1/module.getModifiedItemAttr("modeMaxRangePostDiv"),
stackingPenalties=True, penaltyGroup="postDiv")

View File

@@ -0,0 +1,5 @@
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Tactical Destroyer").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Energy Turret"),
"capacitorNeed", ship.getModifiedItemAttr("shipBonusTacticalDestroyerAmarr2") * level)

View File

@@ -0,0 +1,5 @@
type = "passive"
def handler(fit, ship, context):
level = fit.character.getSkill("Amarr Tactical Destroyer").level
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Energy Turret"),
"damageMultiplier", ship.getModifiedItemAttr("shipBonusTacticalDestroyerAmarr1") * level)

View File

@@ -27,6 +27,7 @@ from copy import deepcopy
from math import sqrt, log, asinh
from eos.types import Drone, Cargo, Ship, Character, State, Slot, Module, Implant, Booster, Skill
from eos.saveddata.module import State
from eos.saveddata.mode import Mode
import time
try:
@@ -66,6 +67,7 @@ class Fit(object):
self.gangBoosts = None
self.timestamp = time.time()
self.ecmProjectedStr = 1
self.modeID = None
self.build()
@reconstructor
@@ -98,6 +100,10 @@ class Fit(object):
self.extraAttributes = ModifiedAttributeDict(self)
self.extraAttributes.original = self.EXTRA_ATTRIBUTES
self.ship = Ship(db.getItem(self.shipID)) if self.shipID is not None else None
if self.ship is not None:
self.mode = self.ship.checkModeItem(db.getItem(self.modeID) if self.modeID else None)
else:
self.mode = None
@property
def targetResists(self):
@@ -120,6 +126,15 @@ class Fit(object):
self.__ehp = None
self.__effectiveTank = None
@property
def mode(self):
return self._mode
@mode.setter
def mode(self, mode):
self._mode = mode
self.modeID = mode.item.ID if mode is not None else None
@property
def character(self):
return self.__character if self.__character is not None else Character.getAll0()
@@ -355,9 +370,9 @@ class Fit(object):
# Avoid adding projected drones and modules when fit is projected onto self
# TODO: remove this workaround when proper self-projection using virtual duplicate fits is implemented
if forceProjected is True:
c = chain((self.character, self.ship), self.drones, self.boosters, self.appliedImplants, self.modules)
c = chain((self.character, self.ship, self.mode), self.drones, self.boosters, self.appliedImplants, self.modules)
else:
c = chain((self.character, self.ship), self.drones, self.boosters, self.appliedImplants, self.modules,
c = chain((self.character, self.ship, self.mode), self.drones, self.boosters, self.appliedImplants, self.modules,
self.projectedDrones, self.projectedModules)
if self.gangBoosts is not None:
@@ -480,6 +495,10 @@ class Fit(object):
Slot.RIG: "rigSlots",
Slot.SUBSYSTEM: "maxSubSystems"}
if type == Slot.MODE:
# Mode slot doesn't really exist, return default 0
return 0
slotsUsed = self.getSlotsUsed(type, countDummies)
totalSlots = self.ship.getModifiedItemAttr(slots[type]) or 0
return int(totalSlots - slotsUsed)

65
eos/saveddata/mode.py Normal file
View File

@@ -0,0 +1,65 @@
#===============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of eos.
#
# eos is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# eos is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with eos. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
from eos.effectHandlerHelpers import HandledItem
class Mode(ItemAttrShortcut, HandledItem):
def __init__(self, item):
self.__item = item
self.__itemModifiedAttributes = ModifiedAttributeDict()
if not isinstance(item, int):
self.__buildOriginal()
def __fetchItemInfo(self):
import eos.db
self.__item = eos.db.getItem(self.__item)
self.__buildOriginal()
def __buildOriginal(self):
self.__itemModifiedAttributes.original = self.item.attributes
@property
def item(self):
if isinstance(self.__item, int):
self.__fetchItemInfo()
return self.__item
@property
def itemModifiedAttributes(self):
if isinstance(self.__item, int):
self.__fetchItemInfo()
return self.__itemModifiedAttributes
# @todo: rework to fit only on t3 dessy
def fits(self, fit):
raise NotImplementedError()
def clear(self):
self.itemModifiedAttributes.clear()
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
if self.item:
for effect in self.item.effects.itervalues():
if effect.runTime == runTime:
effect.handler(fit, self, context = ("module",))

View File

@@ -36,6 +36,7 @@ class Slot(Enum):
HIGH = 3
RIG = 4
SUBSYSTEM = 5
MODE = 6 # not a real slot, need for pyfa display rack separation
class Hardpoint(Enum):
NONE = 0

View File

@@ -19,6 +19,7 @@
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
from eos.effectHandlerHelpers import HandledItem
from eos.saveddata.mode import Mode
class Ship(ItemAttrShortcut, HandledItem):
def __init__(self, item):
@@ -65,6 +66,52 @@ class Ship(ItemAttrShortcut, HandledItem):
if effect.runTime == runTime and effect.isType("passive"):
effect.handler(fit, self, ("ship",))
def checkModeItem(self, item):
"""
Checks if provided item is a valid mode.
If ship has modes, and current item is not valid, return forced mode
else if mode is valid, return Mode
else if ship does not have modes, return None
@todo: rename this
"""
items = self.getModeItems()
if items != None:
if item == None or item not in items:
# We have a tact dessy, but mode is None or not valid. Force new mode
return Mode(items[0])
elif item in items:
# We have a valid mode
return Mode(item)
return None
def getModes(self):
items = self.getModeItems()
return [Mode(item) for item in items] if items else None
def getModeItems(self):
"""
Returns a list of valid mode items for ship. Note that this returns the
valid Item objects, not the Mode objects. Returns None if not a
t3 dessy
"""
# @todo: is there a better way to determine this that isn't hardcoded groupIDs?
if self.item.groupID != 1305:
return None
modeGroupID = 1306
import eos.db
items = []
g = eos.db.getGroup(modeGroupID, eager=("items.icon", "items.attributes"))
for item in g.items:
if item.raceID == self.item.raceID:
items.append(item)
return items
def __deepcopy__(self, memo):
copy = Ship(self.item)
return copy

View File

@@ -32,6 +32,7 @@ from eos.saveddata.booster import SideEffect
from eos.saveddata.booster import Booster
from eos.saveddata.ship import Ship
from eos.saveddata.fit import Fit
from eos.saveddata.mode import Mode
from eos.saveddata.fleet import Fleet, Wing, Squad
from eos.saveddata.miscData import MiscData
import eos.db

View File

@@ -15,6 +15,7 @@ __all__ = [
"cargo",
"shipJump",
#"changeAffectingSkills",
"tacticalMode",
"targetResists",
"priceClear"
]

View File

@@ -0,0 +1,55 @@
import wx
from gui.contextMenu import ContextMenu
import gui.mainFrame
import service
import gui.globalEvents as GE
class TacticalMode(ContextMenu):
def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
def display(self, srcContext, selection):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
self.modes = fit.ship.getModes()
self.currMode = fit.mode
return srcContext == "fittingShip" and self.modes is not None
def getText(self, itmContext, selection):
return "Tactical Mode"
def addMode(self, rootMenu, mode):
label = mode.item.name.rsplit()[-2]
id = wx.NewId()
self.modeIds[id] = mode
menuItem = wx.MenuItem(rootMenu, id, label, kind=wx.ITEM_RADIO)
rootMenu.Bind(wx.EVT_MENU, self.handleMode, menuItem)
return menuItem
def getSubMenu(self, context, selection, rootMenu, i, pitem):
self.context = context
self.modeIds = {}
sub = wx.Menu()
for mode in self.modes:
menuItem = self.addMode(rootMenu, mode)
sub.AppendItem(menuItem)
menuItem.Check(self.currMode.item == mode.item)
return sub
def handleMode(self, event):
item = self.modeIds[event.Id]
if item is False or item not in self.modes:
event.Skip()
return
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setMode(fitID, self.modeIds[event.Id])
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
TacticalMode.register()

View File

@@ -42,7 +42,10 @@ class BaseName(ViewColumn):
return "%s (%s)" % (stuff.name, stuff.ship.item.name)
elif isinstance(stuff, Rack):
if service.Fit.getInstance().serviceFittingOptions["rackLabels"]:
return u'{} Slots ─'.format(Slot.getName(stuff.slot).capitalize())
if stuff.slot == Slot.MODE:
return u'─ Tactical Mode ─'
else:
return u'{} Slots ─'.format(Slot.getName(stuff.slot).capitalize())
else:
return ""
elif isinstance(stuff, Module):

View File

@@ -23,6 +23,7 @@ import service
from gui.utils.numberFormatter import formatAmount
from gui.viewColumn import ViewColumn
from gui import bitmapLoader
from eos.types import Mode
class CapacitorUse(ViewColumn):
name = "Capacitor Usage"
@@ -38,6 +39,9 @@ class CapacitorUse(ViewColumn):
def getText(self, mod):
if isinstance(mod, Mode):
return ""
capUse = mod.capUse
if capUse:
return "%s%s" % ("+" if capUse < 0 else "", (formatAmount(-capUse, 3, 0, 3)))

View File

@@ -23,6 +23,7 @@ from gui import bitmapLoader
import service
from gui.utils.numberFormatter import formatAmount
import wx
from eos.types import Mode
class MaxRange(ViewColumn):
name = "Max Range"
@@ -51,6 +52,9 @@ class MaxRange(ViewColumn):
self.mask |= wx.LIST_MASK_TEXT
def getText(self, stuff):
if isinstance(stuff, Mode):
return ""
maxRange = stuff.maxRange if hasattr(stuff, "maxRange") else stuff.getModifiedItemAttr("maxRange")
falloff = stuff.falloff
if falloff:

View File

@@ -19,7 +19,6 @@
import gui.mainFrame
from gui import builtinViewColumns
from gui.viewColumn import ViewColumn
from gui import bitmapLoader
from gui.utils.numberFormatter import formatAmount
@@ -69,7 +68,9 @@ class Miscellanea(ViewColumn):
itemGroup = item.group.name
itemCategory = item.category.name
if itemGroup in ("Energy Weapon", "Hybrid Weapon", "Projectile Weapon", "Combat Drone", "Fighter Drone"):
if itemGroup == "Ship Modifiers":
return "", None
elif itemGroup in ("Energy Weapon", "Hybrid Weapon", "Projectile Weapon", "Combat Drone", "Fighter Drone"):
trackingSpeed = stuff.getModifiedItemAttr("trackingSpeed")
if not trackingSpeed:
return "", None

View File

@@ -403,6 +403,10 @@ class FittingView(d.Display):
self.mods = fit.modules[:]
self.mods.sort(key=lambda mod: (slotOrder.index(mod.slot), mod.position))
# Blanks is a list of indexes that mark non-module positions (such
# as Racks and tactical Modes. This allows us to skip over common
# module operations such as swapping, removing, copying, etc. that
# would otherwise cause complications
self.blanks = [] # preliminary markers where blanks will be inserted
if sFit.serviceFittingOptions["rackSlots"]:
@@ -419,6 +423,15 @@ class FittingView(d.Display):
for i, (x, slot) in enumerate(self.blanks):
self.blanks[i] = x+i # modify blanks with actual index
self.mods.insert(x+i, Rack.buildRack(slot))
if fit.mode:
# Modes are special snowflakes and need a little manual loving
# We basically append the Mode rack and Mode to the modules
# while also marking their positions in the Blanks list
self.blanks.append(len(self.mods))
self.mods.append(Rack.buildRack(Slot.MODE))
self.blanks.append(len(self.mods))
self.mods.append(fit.mode)
else:
self.mods = None
@@ -457,7 +470,7 @@ class FittingView(d.Display):
sel = self.GetFirstSelected()
contexts = []
while sel != -1:
while sel != -1 and sel not in self.blanks:
mod = self.mods[self.GetItemData(sel)]
if not mod.isEmpty:
srcContext = "fittingModule"
@@ -544,14 +557,17 @@ class FittingView(d.Display):
font = (self.GetClassDefaultAttributes()).font
for i, mod in enumerate(self.mods):
if slotMap[mod.slot]:
if hasattr(mod,"slot") and slotMap[mod.slot]:
self.SetItemBackgroundColour(i, wx.Colour(204, 51, 51))
elif sFit.serviceFittingOptions["colorFitBySlot"] and not isinstance(mod, Rack):
self.SetItemBackgroundColour(i, self.slotColour(mod.slot))
else:
self.SetItemBackgroundColour(i, self.GetBackgroundColour())
if i in self.blanks and sFit.serviceFittingOptions["rackSlots"] and sFit.serviceFittingOptions["rackLabels"]:
# Set rack face to bold
if isinstance(mod, Rack) and \
sFit.serviceFittingOptions["rackSlots"] and \
sFit.serviceFittingOptions["rackLabels"]:
font.SetWeight(wx.FONTWEIGHT_BOLD)
self.SetItemFont(i, font)
else:

View File

@@ -22,9 +22,9 @@ import re
import gui.mainFrame
import bitmapLoader
import sys
import wx.lib.mixins.listctrl as listmix
import wx.lib.mixins.listctrl as listmix
import wx.html
from eos.types import Ship, Module, Skill, Booster, Implant, Drone
from eos.types import Ship, Module, Skill, Booster, Implant, Drone, Mode
from gui.utils.numberFormatter import formatAmount
import service
import config
@@ -535,7 +535,7 @@ class ItemEffects (wx.Panel):
class ItemAffectedBy (wx.Panel):
ORDER = [Ship, Module, Drone, Implant, Booster, Skill]
ORDER = [Ship, Mode, Module, Drone, Implant, Booster, Skill]
def __init__(self, parent, stuff, item):
wx.Panel.__init__ (self, parent)
self.stuff = stuff

View File

@@ -290,6 +290,7 @@ class MainFrame(wx.Frame):
event.Skip()
def ShowAboutBox(self, evt):
import eos.config
info = wx.AboutDialogInfo()
info.Name = "pyfa"
info.Version = gui.aboutData.versionString
@@ -299,7 +300,8 @@ class MainFrame(wx.Frame):
"\n\t".join(gui.aboutData.credits) +
"\n\nLicenses:\n\t" +
"\n\t".join(gui.aboutData.licenses) +
"\n\nPython: \t" + sys.version +
"\n\nEVE Data: \t" + eos.config.gamedata_version +
"\nPython: \t" + sys.version +
"\nwxPython: \t" + wx.__version__ +
"\nSQLAlchemy: \t" + sqlalchemy.__version__,
700, wx.ClientDC(self))

View File

@@ -42,7 +42,10 @@ def main(old, new, groups=True, effects=True, attributes=True, renames=True):
new_cursor = new_db.cursor()
# Force some of the items to make them published
FORCEPUB_TYPES = ("Ibis", "Impairor", "Velator", "Reaper")
FORCEPUB_TYPES = ("Ibis", "Impairor", "Velator", "Reaper",
"Amarr Tactical Destroyer Propulsion Mode",
"Amarr Tactical Destroyer Sharpshooter Mode",
"Amarr Tactical Destroyer Defense Mode")
OVERRIDES_TYPEPUB = 'UPDATE invtypes SET published = 1 WHERE typeName = ?'
for typename in FORCEPUB_TYPES:
old_cursor.execute(OVERRIDES_TYPEPUB, (typename,))
@@ -211,7 +214,7 @@ def main(old, new, groups=True, effects=True, attributes=True, renames=True):
# Initialize container for the data for each item with empty stuff besides groupID
dictionary[itemid] = [groupID, set(), {}]
# Add items filtered by group
query = 'SELECT it.typeID, it.groupID FROM invtypes AS it INNER JOIN invgroups AS ig ON it.groupID = ig.groupID WHERE it.published = 1 AND ig.groupName IN ("Effect Beacon")'
query = 'SELECT it.typeID, it.groupID FROM invtypes AS it INNER JOIN invgroups AS ig ON it.groupID = ig.groupID WHERE it.published = 1 AND ig.groupName IN ("Effect Beacon", "Ship Modifiers")'
cursor.execute(query)
for row in cursor:
itemid = row[0]

View File

@@ -143,15 +143,17 @@ def main(db, json_path):
tableData = convertTraits(tableData)
data[jsonName] = tableData
# 1306 - group Ship Modifiers, for items like tactical t3 ship modes
# Do some preprocessing to make our job easier
invTypes = set()
for row in data["invtypes"]:
if row["published"]:
if (row["published"] or row['groupID'] == 1306):
invTypes.add(row["typeID"])
# ignore checker
def isIgnored(file, row):
if file == "invtypes" and not row["published"]:
if file == "invtypes" and not (row["published"] or row['groupID'] == 1306):
return True
elif file == "dgmtypeeffects" and not row["typeID"] in invTypes:
return True

View File

@@ -48,6 +48,8 @@ CONVERSIONS = {
"Merlin Wiyrkomi Edition": "Merlin",
"Miasmos Amastris Edition": "Miasmos Quafe Ultra Edition",
"Miasmos Quafe Ultramarine Edition": "Miasmos Quafe Ultra Edition",
"Moros Interbus Edition": "Moros",
"Naglfar Justice Edition": "Naglfar",
"Nefantar Thrasher": "Thrasher",
"Omen Kador Edition": "Omen",
"Omen Tash-Murkon Edition": "Omen",
@@ -55,6 +57,7 @@ CONVERSIONS = {
"Paladin Blood Raider Edition": "Paladin",
"Paladin Kador Edition": "Paladin",
"Paladin Tash-Murkon Edition": "Paladin",
"Phoenix Wiyrkomi Edition": "Phoenix",
"Police Pursuit Comet": "Federation Navy Comet",
"Prophecy Blood Raiders Edition": "Prophecy",
"Punisher Kador Edition": "Punisher",
@@ -64,6 +67,7 @@ CONVERSIONS = {
"Raven Kaalakiota Edition": "Raven",
"Raven Nugoeihuvi Edition": "Raven",
"Rattlesnake Victory Edition": "Rattlesnake",
"Revelation Sarum Edition": "Revelation",
"Rifter Krusual Edition": "Rifter",
"Rifter Nefantar Edition": "Rifter",
"Rokh Nugoeihuvi Edition": "Rokh",

View File

@@ -147,6 +147,7 @@ class Fit(object):
def newFit(self, shipID, name=None):
fit = eos.types.Fit()
fit.ship = eos.types.Ship(eos.db.getItem(shipID))
fit.mode = fit.ship.checkModeItem(None)
fit.name = name if name is not None else "New %s" % fit.ship.item.name
fit.damagePattern = self.pattern
fit.targetResists = self.targetResists
@@ -719,6 +720,16 @@ class Fit(object):
self.recalc(fit)
def setMode(self, fitID, mode):
if fitID is None:
return
fit = eos.db.getFit(fitID)
fit.mode = mode
eos.db.commit()
self.recalc(fit)
def setAsPattern(self, fitID, ammo):
if fitID is None:
return

View File

@@ -214,7 +214,8 @@ class Market():
"Goru's Shuttle": False,
"Guristas Shuttle": False,
"Mobile Decoy Unit": False, # Seems to be left over test mod for deployables
"Tournament Micro Jump Unit": False } # Normally seen only on tournament arenas
"Tournament Micro Jump Unit": False} # Normally seen only on tournament arenas
# do not publish ships that we convert
for name in conversions.packs['skinnedShips']:

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

0
utils/__init__.py Normal file
View File