def __init__(self, resref, container): are = resref+'.are' self.container = container if container.has_file(are): self.are = container[are] self.are = Gff(self.are) else: raise ValueError("Container does not contain %s" % are) git = resref+'.git' if container.has_file(git): self.git = container[git] self.git = Gff(self.git) else: raise ValueError("Container does not contain %s.git" % resref) gic = resref+'.gic' if container.has_file(gic): self.gic = container[gic] self.gic = Gff(self.gic) else: raise ValueError("Container does not contain %s.gic" % resref) self._vars = None self._scripts = None self._locstr = {}
def __init__(self, resref, container): self._scripts = None if resref[-4:] != '.bic': resref = resref+'.bic' if container.has_file(resref): self.gff = container[resref] self.gff = Gff(self.gff) else: raise ValueError("Container does not contain: %s" % resref)
def __init__(self, resource): self.is_file = False if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0])
def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_instance = instance if not instance: if isinstance(resource, str): from resource import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource
def __init__(self, resource): self.is_file = False self.reply_cache = None self.entry_cache = None if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] co = resource[0] self.gff = Gff(co) self._resref = co.resref
def __init__(self, resource): self.is_file = False self.reply_cache = None self.entry_cache = None if isinstance(resource, str): from resource import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] co = resource[0] self.gff = Gff(co) self._resref = co.resref
class Faction(object): def __init__(self, resource): self.is_file = False if isinstance(resource, str): from resource import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) def stage(self): """Stages changes to GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def factions(self): res = [] for f in self.gff['FactionList']: res.append( (f['FactionParentID'], f['FactionName'], f['FactionGlobal'])) return res @property def reputations(self): res = [] for f in self.gff['RepList']: res.append((f['FactionID1'], f['FactionID2'], f['FactionRep'])) return res
class Sound(object): def __init__(self, resource, instance=False): self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def random_range(self): return self.gff['RandomRangeX'], self.gff['RandomRangeY'] @property def sounds(self): return [s['Sound'] for s in self.gff['Sounds']]
class Palette(object): """ This is a very rough absraction over ITPs. """ def __init__(self, resource): self.is_file = False self.container = None if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) @property def nodes(self): """ Gets all nodes in the palette. :returns: a list of :class:`PaletteNode` objects. """ return [PaletteNode(p, self) for p in self.gff['MAIN']] def stage(self): if self.gff.is_loaded() and self.container: self.container.add_to_saves(self.gff)
class Waypoint(object): def __init__(self, resource, instance=False): self._vars = None self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): """Stage changes to GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars
class PlayerCharacter(object): def __init__(self, resref, container): self._scripts = None if resref[-4:] != '.bic': resref += '.bic' self.container = container if container.has_file(resref): self.gff = container[resref] self.gff = Gff(self.gff) else: raise ValueError("Container does not contain: %s" % resref) def stage(self): """ Stage changes to the placeable's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def equips(self): """ Creature's equipment list. :returns: List of tuples containing equipment ID and ItemInstance. """ result = [] i = 0 for p in self.gff['Equip_ItemList']: gff_inst = GffInstance(self.gff, 'Equip_ItemList', i) st_inst = ItemInstance(gff_inst, self) equip_slot = p['_STRUCT_TYPE_'] result.append((equip_slot, st_inst)) i += 1 return result @property def level_stats(self): """ Player's level stat list. """ result = [] for p in self.gff['LvlStatList']: ls = LevelStats() ls.class_type = p['LvlStatClass'].value ls.hitdice = p['LvlStatHitDie'].value ls.epic_level = p['EpicLevel'].value ls.skillpoints = p['SkillPoints'].value for sk in p['SkillList']: ls.skills.append(sk['Rank'].value) for ft in p['FeatList']: ls.feats.append(ft['Feat'].value) result.append(ls) return result
class PlayerCharacter(object): def __init__(self, resref, container): self._scripts = None if resref[-4:] != ".bic": resref += ".bic" self.container = container if container.has_file(resref): self.gff = container[resref] self.gff = Gff(self.gff) else: raise ValueError("Container does not contain: %s" % resref) def stage(self): """ Stage changes to the placeable's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def equips(self): """ Creature's equipment list. :returns: List of tuples containing equipment ID and ItemInstance. """ result = [] i = 0 for p in self.gff["Equip_ItemList"]: gff_inst = GffInstance(self.gff, "Equip_ItemList", i) st_inst = ItemInstance(gff_inst, self) equip_slot = p["_STRUCT_TYPE_"] result.append((equip_slot, st_inst)) i += 1 return result @property def level_stats(self): """ Player's level stat list. """ result = [] for p in self.gff["LvlStatList"]: ls = LevelStats() ls.class_type = p["LvlStatClass"].value ls.hitdice = p["LvlStatHitDie"].value ls.epic_level = p["EpicLevel"].value ls.skillpoints = p["SkillPoints"].value for sk in p["SkillList"]: ls.skills.append(sk["Rank"].value) for ft in p["FeatList"]: ls.feats.append(ft["Feat"].value) result.append(ls) return result
class Trigger(object): def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from resource import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): """Stages changes to GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def scripts(self): """Scripts. Responds to script events: #. Event.TRAP_DISARMED #. Event.TRAP_TRIGGERED #. Event.CLICK #. Event.HEARTBEAT #. Event.ENTER #. Event.EXIT #. Event.USER_DEFINED """ if self._scripts: return self._scripts lbls = {} lbls[Event.TRAP_DISARMED] = 'OnDisarm' lbls[Event.TRAP_TRIGGERED] = 'OnTrapTriggered' lbls[Event.CLICK] = 'OnClick' lbls[Event.HEARTBEAT] = 'ScriptHeartbeat' lbls[Event.ENTER] = 'ScriptOnEnter' lbls[Event.EXIT] = 'ScriptOnExit' lbls[Event.USER_DEFINED] = 'ScriptUserDefine' self._scripts = NWObjectScripts(self, lbls) return self._scripts
def __init__(self, resref, container): self._scripts = None if resref[-4:] != ".bic": resref = resref + ".bic" if container.has_file(resref): self.gff = container[resref] self.gff = Gff(self.gff) else: raise ValueError("Container does not contain: %s" % resref)
def __init__(self, resref, container): are = resref + '.are' self.container = container if container.has_file(are): self.are = container[are] self.are = Gff(self.are) else: raise ValueError("Container does not contain %s" % are) git = resref + '.git' if container.has_file(git): self.git = container[git] self.git = Gff(self.git) else: raise ValueError("Container does not contain %s.git" % resref) gic = resref + '.gic' if container.has_file(gic): self.gic = container[gic] self.gic = Gff(self.gic) else: raise ValueError("Container does not contain %s.gic" % resref) self._vars = None self._scripts = None self._locstr = {}
class Item(object): def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.container = None self.is_instance = instance if not instance: if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): if self.gff.is_loaded() and self.container: self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def model(self): # It will probably be best to encapsulate this... pass @property def properties(self): """Item properties :returns: List of :class:`ItemProperty` objects. """ result = [] i = 0 for p in self.gff['PropertiesList']: gff_inst = GffInstance(self.gff, 'PropertiesList', i) st_inst = ItemProperty(gff_inst, self) result.append(st_inst) i += 1 return result
def __init__(self, module): if not isinstance(module, str): raise ValueError( "Module must be instantiated with a file path to a MOD file or a directory" ) if os.path.isdir(module): self.container = RES.DirectoryContainer(module) elif os.path.isfile(module): # If it's a file, assume that it is a module ERF. self.container = Erf.from_file(module) else: msg = "File/Directory %s does not exist!" % module raise ValueError(msg) if not self.container.has_file('module.ifo'): raise ValueError("The %s Container has no module.ifo!" % module) self.gff = Gff(self.container['module.ifo']) self._scripts = None self._vars = None self._locstr = {}
def __init__(self, module): if not isinstance(module, str): raise ValueError("Module must be instantiated with a file path to a MOD file or a directory") if os.path.isdir(module): self.container = RES.DirectoryContainer(module) elif os.path.isfile(module): # If it's a file, assume that it is a module ERF. self.container = Erf.from_file(module) else: msg = "File/Directory %s does not exist!" % module raise ValueError(msg) if not self.container.has_file("module.ifo"): raise ValueError("The %s Container has no module.ifo!" % module) self.gff = Gff(self.container["module.ifo"]) self._scripts = None self._vars = None self._locstr = {}
class Faction(object): def __init__(self, resource): self.is_file = False if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) def stage(self): """Stages changes to GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def factions(self): res = [] for f in self.gff['FactionList']: res.append((f['FactionParentID'], f['FactionName'], f['FactionGlobal'])) return res @property def reputations(self): res = [] for f in self.gff['RepList']: res.append((f['FactionID1'], f['FactionID2'], f['FactionRep'])) return res
class Module(object): """Module abstracts over MOD ERF files and directories containing the contents of MOD files. """ def __init__(self, module): if not isinstance(module, str): raise ValueError("Module must be instantiated with a file path to a MOD file or a directory") if os.path.isdir(module): self.container = RES.DirectoryContainer(module) elif os.path.isfile(module): # If it's a file, assume that it is a module ERF. self.container = Erf.from_file(module) else: msg = "File/Directory %s does not exist!" % module raise ValueError(msg) if not self.container.has_file("module.ifo"): raise ValueError("The %s Container has no module.ifo!" % module) self.gff = Gff(self.container["module.ifo"]) self._scripts = None self._vars = None self._locstr = {} def glob(self, glob_pattern): """Returns a list of (ContentObject, Container) tuples for file names matching the glob pattern. i.e. Unix shell-style wildcards: \*.utc Note: all file names are converted to lowercase. """ return self.container.glob(glob_pattern) def stage(self): """Stages changes to the modules IFO GFF structure.""" if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def areas(self): """Areas. :returns: List of Area objects. """ res = [] for a in self.gff["Mod_Area_list"]: res.append(Area(a["Area_Name"].val, self.container)) return res @property def entry_area(self): """Entry area resref""" return Area(self.gff["Mod_Entry_Area"], self.container) @property def entry_location(self): """Entry location. :returns: Tuple of the X, Y, Z coordinates. """ return (self.gff["Mod_Entry_X"], self.gff["Mod_Entry_Y"], self.gff["Mod_Entry_Z"]) @property def haks(self): """List of HAK files.""" return [hak["Mod_Hak"].value for hak in self.gff["Mod_HakList"]] @property def script(self): """Scripts. Responds to script events: #. Event.CUTSCENE_ABORT #. Event.ENTER #. Event.EXIT #. Event.HEARTBEAT #. Event.ITEM_ACQUIRED #. Event.ITEM_ACTIVATED #. Event.ITEM_EQUIPPED #. Event.ITEM_UNACQUIRED #. Event.ITEM_UNEQUIPPED #. Event.LEVELUP #. Event.LOAD #. Event.DEATH #. Event.DYING #. Event.RESPAWN #. Event.REST #. Event.USER_DEFINED """ if self._scripts: return self._scripts lbls = {} lbls[Event.CUTSCENE_ABORT] = "Mod_OnCutsnAbort" lbls[Event.ENTER] = "Mod_OnClientEntr" lbls[Event.EXIT] = "Mod_OnClientLeav" lbls[Event.HEARTBEAT] = "Mod_OnHeartbeat" lbls[Event.ITEM_ACQUIRED] = "Mod_OnAcquirItem" lbls[Event.ITEM_ACTIVATED] = "Mod_OnActvtItem" lbls[Event.ITEM_EQUIPPED] = "Mod_OnPlrEqItm" lbls[Event.ITEM_UNACQUIRED] = "Mod_OnUnAqreItem" lbls[Event.ITEM_UNEQUIPPED] = "Mod_OnPlrUnEqItm" lbls[Event.LEVELUP] = "Mod_OnPlrLvlUp" lbls[Event.LOAD] = "Mod_OnModLoad" lbls[Event.DEATH] = "Mod_OnPlrDeath" lbls[Event.DYING] = "Mod_OnPlrDying" lbls[Event.RESPAWN] = "Mod_OnSpawnBtnDn" lbls[Event.REST] = "Mod_OnPlrRest" lbls[Event.USER_DEFINED] = "Mod_OnUsrDefined" self._scripts = NWObjectScripts(self, lbls) return self._scripts
class Placeable(object): def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): """ Stage changes to the placeable's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def scripts(self): """Scripts. Responds to script events: #. Event.CLOSE #. Event.DAMAGED #. Event.DEATH #. Event.TRAP_DISARMED #. Event.HEARTBEAT #. Event.LOCK #. Event.ATTACKED #. Event.OPEN #. Event.SPELL_CAST_AT #. Event.TRAP_TRIGGERED #. Event.UNLOCK #. Event.USER_DEFINED #. Event.CLICK #. Event.DISTURBED #. Event.USED """ if self._scripts: return self._scripts lbls = { Event.CLOSE: 'OnClosed', Event.DAMAGED: 'OnDamaged', Event.DEATH: 'OnDeath', Event.TRAP_DISARMED: 'OnDisarm', Event.HEARTBEAT: 'OnHeartbeat', Event.LOCK: 'OnLock', Event.ATTACKED: 'OnMeleeAttacked', Event.OPEN: 'OnOpen', Event.SPELL_CAST_AT: 'OnSpellCastAt', Event.TRAP_TRIGGERED: 'OnTrapTriggered', Event.UNLOCK: 'OnUnlock', Event.USER_DEFINED: 'OnUserDefined', Event.CLICK: 'OnClick', Event.DISTURBED: 'OnInvDisturbed', Event.USED: 'OnUsed' } self._scripts = NWObjectScripts(self, lbls) return self._scripts @property def items(self): """Invenory items. :returns: List of RepositoryItem objects or [] if the object does not have an inventory. """ if self.has_inventory and self.gff.has_field('ItemList'): result = [] i = 0 for p in self.gff['ItemList']: gff_inst = GffInstance(self.gff, 'ItemList', i) st_inst = RepositoryItem(gff_inst, self) result.append(st_inst) i += 1 return result else: return []
class Door(object): def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_instance = instance if not instance: if isinstance(resource, str): from resource import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): """Stages changes to door's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def script(self): """Scripts: Door responds to the following script events: #. Event.CLOSE #. Event.DAMAGED #. Event.DEATH #. Event.TRAP_DISARMED #. Event.HEARTBEAT #. Event.LOCK #. Event.ATTACKED #. Event.OPEN #. Event.SPELL_CAST_AT #. Event.TRAP_TRIGGERED #. Event.UNLOCK #. Event.USER_DEFINED #. Event.CLICK #. Event.FAIL_TO_OPEN """ if self._scripts: return self._scripts lbls = {} lbls[Event.CLOSE] = 'OnClosed' lbls[Event.DAMAGED] = 'OnDamaged' lbls[Event.DEATH] = 'OnDeath' lbls[Event.TRAP_DISARMED] = 'OnDisarm' lbls[Event.HEARTBEAT] = 'OnHeartbeat' lbls[Event.LOCK] = 'OnLock' lbls[Event.ATTACKED] = 'OnMeleeAttacked' lbls[Event.OPEN] = 'OnOpen' lbls[Event.SPELL_CAST_AT] = 'OnSpellCastAt' lbls[Event.TRAP_TRIGGERED] = 'OnTrapTriggered' lbls[Event.UNLOCK] = 'OnUnlock' lbls[Event.USER_DEFINED] = 'OnUserDefined' lbls[Event.CLICK] = 'OnClick' lbls[Event.FAIL_TO_OPEN] = 'OnFailToOpen' self._scripts = NWObjectScripts(self, lbls) return self._scripts
class Area(object): def __init__(self, resref, container): are = resref + '.are' self.container = container if container.has_file(are): self.are = container[are] self.are = Gff(self.are) else: raise ValueError("Container does not contain %s" % are) git = resref + '.git' if container.has_file(git): self.git = container[git] self.git = Gff(self.git) else: raise ValueError("Container does not contain %s.git" % resref) gic = resref + '.gic' if container.has_file(gic): self.gic = container[gic] self.gic = Gff(self.gic) else: raise ValueError("Container does not contain %s.gic" % resref) self._vars = None self._scripts = None self._locstr = {} def stage(self): if self.are.is_loaded() and self.container: self.container.add_to_saves(self.are) if self.git.is_loaded() and self.container: self.container.add_to_saves(self.git) if self.gic.is_loaded() and self.container: self.container.add_to_saves(self.gic) def get_instances(self, list_name, instance_class): result = [] i = 0 for p in self.git[list_name]: gff_inst = GffInstance(self.git, list_name, i) st_inst = instance_class(gff_inst, self) result.append(st_inst) i += 1 return result @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.git) return self._vars @property def doors(self): """Door instances. :returns: List of DoorInstance objects. """ return self.get_instances('Door List', DoorInstance) @property def creatures(self): """Creature instances. :returns: List of :class:`pynwn.CreatureInstance` objects. """ return self.get_instances('Creature List', CreatureInstance) @property def encounters(self): """Encounters :returns: List of :class:`pynwn.EncounterInstance` objects. """ return self.get_instances('Encounter List', EncounterInstance) @property def items(self): """Item instance list. :returns: List of :class:`pynwn.ItemInstance` objects. """ return self.get_instances('List', ItemInstance) @property def placeables(self): """Placeables :returns: List of :class:`pynwn.PlaceableInstance` objects. """ return self.get_instances('Placeable List', PlaceableInstance) @property def scripts(self): """Scripts. Responds to script events: #. Event.ENTER #. Event.EXIT #. Event.HEARTBEAT #. Event.USER_DEFINED """ if self._scripts: return self._scripts lbls = { Event.ENTER: 'OnEnter', Event.EXIT: 'OnExit', Event.HEARTBEAT: 'OnHeartbeat', Event.USER_DEFINED: 'OnUserDefined' } self._scripts = NWObjectScripts(self, lbls, self.are) return self._scripts @property def sounds(self): """Sounds :returns: List of :class:`pynwn.SoundInstance` objects. """ return self.get_instances('SoundList', SoundInstance) @property def tiles(self): """Tiles :returns: List of :class:`pynwn.TileInstance` objects. """ result = [] i = 0 for p in self.are['Tile_List']: gff_inst = GffInstance(self.are, 'Tile_List', i) st_inst = TileInstance(gff_inst, self) result.append(st_inst) i += 1 return result @property def stores(self): """Stores :returns: List of :class:`pynwn.StoreInstance` objects. """ return self.get_instances('StoreList', StoreInstance) @property def triggers(self): """Triggers :returns: List of :class:`pynwn.TriggerInstance` objects. """ return self.get_instances('TriggerList', TriggerInstance) @property def waypoints(self): """Waypoints :returns: List of :class:`pynwn.WaypointInstance` objects. """ return self.get_instances('WaypointList', WaypointInstance)
class Module(object): """Module abstracts over MOD ERF files and directories containing the contents of MOD files. """ def __init__(self, module): if not isinstance(module, str): raise ValueError( "Module must be instantiated with a file path to a MOD file or a directory" ) self.container = None if os.path.isdir(module): self.container = DirectoryContainer(module) elif os.path.isfile(module): # If it's a file, assume that it is a module ERF. self.container = Erf.from_file(module) else: msg = "File/Directory %s does not exist!" % module raise ValueError(msg) if not self.container.has_file('module.ifo'): raise ValueError("The %s has no module.ifo!" % module) self.gff = Gff(self.container['module.ifo']) self._scripts = None self._vars = None self._locstr = {} def glob(self, glob_pattern): """Returns a list of (ContentObject, Container) tuples for file names matching the glob pattern. i.e. Unix shell-style wildcards: \*.utc Note: all file names are converted to lowercase. """ return self.container.glob(glob_pattern) def stage(self): if self.gff.is_loaded() and self.container: self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def areas(self): """Areas. :returns: List of :class:`pynwn.Area` objects. """ res = [] for a in self.gff['Mod_Area_list']: res.append(Area(a['Area_Name'].val, self.container)) return res @property def entry_area(self): """Entry area. :returns: :class:`pynwn.Area` instance. """ return Area(self.gff['Mod_Entry_Area'], self.container) @property def entry_location(self): """Entry location. :returns: Tuple of the X, Y, Z coordinates. """ return self.gff['Mod_Entry_X'], self.gff['Mod_Entry_Y'], self.gff[ 'Mod_Entry_Z'] @property def haks(self): """List of HAK files without 'hak' extension.""" return [hak['Mod_Hak'].value for hak in self.gff['Mod_HakList']] @property def scripts(self): """Scripts. Responds to script events: #. Event.CUTSCENE_ABORT #. Event.ENTER #. Event.EXIT #. Event.HEARTBEAT #. Event.ITEM_ACQUIRED #. Event.ITEM_ACTIVATED #. Event.ITEM_EQUIPPED #. Event.ITEM_UNACQUIRED #. Event.ITEM_UNEQUIPPED #. Event.LEVELUP #. Event.LOAD #. Event.DEATH #. Event.DYING #. Event.RESPAWN #. Event.REST #. Event.USER_DEFINED """ if self._scripts: return self._scripts lbls = { Event.CUTSCENE_ABORT: 'Mod_OnCutsnAbort', Event.ENTER: 'Mod_OnClientEntr', Event.EXIT: 'Mod_OnClientLeav', Event.HEARTBEAT: 'Mod_OnHeartbeat', Event.ITEM_ACQUIRED: 'Mod_OnAcquirItem', Event.ITEM_ACTIVATED: 'Mod_OnActvtItem', Event.ITEM_EQUIPPED: 'Mod_OnPlrEqItm', Event.ITEM_UNACQUIRED: 'Mod_OnUnAqreItem', Event.ITEM_UNEQUIPPED: 'Mod_OnPlrUnEqItm', Event.LEVELUP: 'Mod_OnPlrLvlUp', Event.LOAD: 'Mod_OnModLoad', Event.DEATH: 'Mod_OnPlrDeath', Event.DYING: 'Mod_OnPlrDying', Event.RESPAWN: 'Mod_OnSpawnBtnDn', Event.REST: 'Mod_OnPlrRest', Event.USER_DEFINED: 'Mod_OnUsrDefined' } self._scripts = NWObjectScripts(self, lbls) return self._scripts
class Area(object): def __init__(self, resref, container): are = resref+'.are' self.container = container if container.has_file(are): self.are = container[are] self.are = Gff(self.are) else: raise ValueError("Container does not contain %s" % are) git = resref+'.git' if container.has_file(git): self.git = container[git] self.git = Gff(self.git) else: raise ValueError("Container does not contain %s.git" % resref) gic = resref+'.gic' if container.has_file(gic): self.gic = container[gic] self.gic = Gff(self.gic) else: raise ValueError("Container does not contain %s.gic" % resref) self._vars = None self._scripts = None self._locstr = {} def stage(self): """Stages changes to the Area's GFF structures. """ if self.are.is_loaded(): self.container.add_to_saves(self.are) if self.git.is_loaded(): self.container.add_to_saves(self.git) if self.gic.is_loaded(): self.container.add_to_saves(self.gic) def get_instances(self, list_name, instance_class): result = [] i = 0 for p in self.git[list_name]: gff_inst = GffInstance(self.git, list_name, i) st_inst = instance_class(gff_inst, self) result.append(st_inst) i += 1 return result @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.git) return self._vars @property def doors(self): """Door instances. :returns: List of DoorInstance objects. """ return self.get_instances('Door List', DoorInstance) @property def creatures(self): """Creature instances. :returns: List of CreatureInstance objects. """ return self.get_instances('Creature List', CreatureInstance) @property def encounters(self): """Encounters :returns: List of EncounterInstance objects. """ return self.get_instances('Encounter List', EncounterInstance) @property def items(self): """Item instance list. :returns: List of ItemInstance objects. """ return self.get_instances('List', ItemInstance) @property def placeables(self): """Placeables :returns: List of PlaceableInstance objects. """ return self.get_instances('Placeable List', PlaceableInstance) @property def script(self): """Scripts. Responds to script events: #. Event.ENTER #. Event.EXIT #. Event.HEARTBEAT #. Event.USER_DEFINED """ if self._scripts: return self._scripts lbls = {} lbls[Event.ENTER] = 'OnEnter' lbls[Event.EXIT] = 'OnExit' lbls[Event.HEARTBEAT] = 'OnHeartbeat' lbls[Event.USER_DEFINED] = 'OnUserDefined' self._scripts = NWObjectScripts(self, lbls, self.are) return self._scripts @property def sounds(self): """Sounds :returns: List of SoundInstance objects. """ return self.get_instances('SoundList', SoundInstance) @property def tiles(self): """Tiles :returns: List of TileInstance objects. """ result = [] i = 0 for p in self.are['Tile_List']: gff_inst = GffInstance(self.are, 'Tile_List', i) st_inst = TileInstance(gff_inst, self) result.append(st_inst) i += 1 return result @property def stores(self): """Stores :returns: List of StoreInstance objects. """ return self.get_instances('StoreList', StoreInstance) @property def triggers(self): """Triggers :returns: List of TriggerInstance objects. """ return self.get_instances('TriggerList', TriggerInstance) @property def waypoints(self): """Waypoints :returns: List of WaypointInstance objects. """ return self.get_instances('WaypointList', WaypointInstance)
class Dialog(object): """Abstracts .dlg GFF files. """ def __init__(self, resource): self.is_file = False self.reply_cache = None self.entry_cache = None if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] co = resource[0] self.gff = Gff(co) self._resref = co.resref def stage(self): """Stages changes to the dialog's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def resref(self): """Resref Dialogs don't store their resref internally. """ return self._resref @property def entries(self): """Entries :returns: List of DialogNodes """ if self.entry_cache is None: result = [] i = 0 for p in self.gff["EntryList"]: gff_inst = GffInstance(self.gff, "EntryList", i) st_inst = DialogNode(gff_inst, "RepliesList", self) result.append(st_inst) i += 1 self.entry_cache = result return self.entry_cache @property def replies(self): """Replies :returns: List of DialogNodes """ if self.reply_cache is None: result = [] i = 0 for p in self.gff["ReplyList"]: gff_inst = GffInstance(self.gff, "ReplyList", i) st_inst = DialogNode(gff_inst, "EntriesList", self) result.append(st_inst) i += 1 self.reply_cache = result return self.reply_cache @property def starts(self): """Starts These are limited pointers in the entry list to the topmost level of dialog in a concersation. :returns: List of DialogPointers """ result = [] i = 0 for p in self.gff["StartingList"]: gff_inst = GffInstance(self.gff, "StartingList", i) st_inst = DialogPointer(gff_inst, "EntriesList", self, True) result.append(st_inst) i += 1 return result
class Creature(object): """The Creature class abstracts over UTCs only. It doesn't handle all the additional fields one finds in BICs, see :class:`pynwn.PlayerCharacter` for that. :param resource: Filename or content object. :type resource: ``str``, (:class:`pynwn.ContentObject`, :class:`pynwn.Container`), or :class:`pynwn.GffInstance` :param instance: Deterimines if the current creature is an instanced object or not. """ def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): """Stages changes creature's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def scripts(self): """Creature's scripts. Responds to script events: * Event.HEARTBEAT * Event.PERCEPTION * Event.SPELL_CAST_AT * Event.ATTACKED * Event.DAMAGED * Event.DISTURBED * Event.END_COMBAT_ROUND * Event.CONVERSATION * Event.SPAWN * Event.REST * Event.DEATH * Event.USER_DEFINED * Event.BLOCKED """ if self._scripts: return self._scripts lbls = { Event.HEARTBEAT: 'ScriptHeartbeat', Event.PERCEPTION: 'ScriptOnNotice', Event.SPELL_CAST_AT: 'ScriptSpellAt', Event.ATTACKED: 'ScriptAttacked', Event.DAMAGED: 'ScriptDamaged', Event.DISTURBED: 'ScriptDisturbed', Event.END_COMBAT_ROUND: 'ScriptEndRound', Event.CONVERSATION: 'ScriptDialogue', Event.SPAWN: 'ScriptSpawn', Event.REST: 'ScriptRested', Event.DEATH: 'ScriptDeath', Event.USER_DEFINED: 'ScriptUserDefine', Event.BLOCKED: 'ScriptOnBlocked' } self._scripts = NWObjectScripts(self, lbls) return self._scripts @property def skills(self): """Creature's skills :returns: List of skill ranks in order of skill ID. """ return [sk['Rank'].val for sk in self.gff['SkillList']] def get_skill(self, skill): return self.gff['SkillList'][skill]['Rank'] def set_skill(self, skill, value): self.gff['SkillList'][skill]['Rank'].val = value self.stage() @property def feats(self): """Creature's feats. :returns: List of feat IDs. """ return [sk['Feat'].val for sk in self.gff['FeatList']] @property def special_abilities(self): res = [] for s in self.gff['SpecAbilityList']: res.append((s['Spell'].val, s['SpellFlags'].val, s['SpellCasterLevel'].val)) return res @property def classes(self): """Creature's classes. :returns: List of tuples containing class ID and level. """ return [(cl['Class'].val, cl['ClassLevel'].val) for cl in self.gff['ClassList']] @property def items(self): """Creature's inventory items. :returns: List of RepositoryItems. """ result = [] i = 0 try: for p in self.gff['ItemList']: gff_inst = GffInstance(self.gff, 'ItemList', i) st_inst = RepositoryItem(gff_inst, self) result.append(st_inst) i += 1 except KeyError: pass return result @property def equips(self): """ Creature's equipment list. :returns: List of tuples containing equipment ID and resref. """ return [(e['_STRUCT_TYPE_'], e['EquippedRes'].val) for e in self.gff['Equip_ItemList']]
class Store(object): def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def scripts(self): """Scripts. Responds to script events: #. Event.OPEN #. Event.CLOSE """ if self._scripts: return self._scripts lbls = { Event.OPEN: 'OnOpenStore', Event.CLOSE: 'OnStoreClosed' } self._scripts = NWObjectScripts(self, lbls) return self._scripts @property def will_not_buy(self): """Will not buy list. :returns: List of baseitem IDs that store will not buy. """ return [i['BaseItem'] for i in self.gff['WillNotBuy']] @property def will_only_buy(self): """Will only buy list. :returns: List of baseitem IDs that store will only buy. """ return [i['BaseItem'] for i in self.gff['WillOnlyBuy']] @property def items(self): """Items in inventory. :returns: a two dimensional array with the format: [<store page>][<RepositoryItem objects>] """ res = [] for page in self.gff['StoreList']: items = [] i = 0 try: for p in self.gff['ItemList']: gff_inst = GffInstance(self.gff, 'ItemList', i) st_inst = RepositoryItem(gff_inst, self) items.append(st_inst) i += 1 except Exception as e: print(e) pass res.append(items) return res
class Dialog(object): """Abstracts .dlg GFF files. """ def __init__(self, resource): self.is_file = False self.reply_cache = None self.entry_cache = None if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] co = resource[0] self.gff = Gff(co) self._resref = co.resref def stage(self): """Stages changes to the dialog's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def resref(self): """Resref Dialogs don't store their resref internally. """ return self._resref @property def entries(self): """Entries :returns: List of DialogNodes """ if self.entry_cache is None: result = [] i = 0 for p in self.gff['EntryList']: gff_inst = GffInstance(self.gff, 'EntryList', i) st_inst = DialogNode(gff_inst, 'RepliesList', self) result.append(st_inst) i += 1 self.entry_cache = result return self.entry_cache @property def replies(self): """Replies :returns: List of DialogNodes """ if self.reply_cache is None: result = [] i = 0 for p in self.gff['ReplyList']: gff_inst = GffInstance(self.gff, 'ReplyList', i) st_inst = DialogNode(gff_inst, 'EntriesList', self) result.append(st_inst) i += 1 self.reply_cache = result return self.reply_cache @property def starts(self): """Starts These are limited pointers in the entry list to the topmost level of dialog in a concersation. :returns: List of DialogPointers """ result = [] i = 0 for p in self.gff['StartingList']: gff_inst = GffInstance(self.gff, 'StartingList', i) st_inst = DialogPointer(gff_inst, 'EntriesList', self, True) result.append(st_inst) i += 1 return result
class Creature(object): """This abstracts over UTCs only... It doesn't handle all the additional fields one finds in BICs, see object PlayerCharacter for that. """ def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from resource import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): """Stages changes creature's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def scripts(self): """Creature's scripts. Responds to script events: * Event.HEARTBEAT * Event.PERCEPTION * Event.SPELL_CAST_AT * Event.ATTACKED * Event.DAMAGED * Event.DISTURBED * Event.END_COMBAT_ROUND * Event.CONVERSATION * Event.SPAWN * Event.REST * Event.DEATH * Event.USER_DEFINED * Event.BLOCKED """ if self._scripts: return self._scripts lbls = {} lbls[Event.HEARTBEAT] = 'ScriptHeartbeat' lbls[Event.PERCEPTION] = 'ScriptOnNotice' lbls[Event.SPELL_CAST_AT] = 'ScriptSpellAt' lbls[Event.ATTACKED] = 'ScriptAttacked' lbls[Event.DAMAGED] = 'ScriptDamaged' lbls[Event.DISTURBED] = 'ScriptDisturbed' lbls[Event.END_COMBAT_ROUND] = 'ScriptEndRound' lbls[Event.CONVERSATION] = 'ScriptDialogue' lbls[Event.SPAWN] = 'ScriptSpawn' lbls[Event.REST] = 'ScriptRested' lbls[Event.DEATH] = 'ScriptDeath' lbls[Event.USER_DEFINED] = 'ScriptUserDefine' lbls[Event.BLOCKED] = 'ScriptOnBlocked' self._scripts = NWObjectScripts(self, lbls) return self._scripts @property def skills(self): """Creature's skills :returns: List of skill ranks in order of skill ID. """ return [sk['Rank'].val for sk in self.gff['SkillList']] def get_skill(self, skill): return self.gff['SkillList'][skill]['Rank'] def set_skill(self, skill, value): self.gff['SkillList'][skill]['Rank'].val = value self.stage() @property def feats(self): """Creature's feats. :returns: List of feat IDs. """ return [sk['Feat'].val for sk in self.gff['FeatList']] @property def special_abilities(self): res = [] for s in self.gff['SpecAbilityList']: res.append( (s['Spell'].val, s['SpellFlags'].val, s['SpellCasterLevel'].val) ) return res @property def classes(self): """Creature's classes. :returns: List of tuples containing class ID and level. """ return [(cl['Class'].val, cl['ClassLevel'].val) for cl in self.gff['ClassList']] @property def items(self): """Creature's inventory items. :returns: List of RepositoryItems. """ result = [] i = 0 try: for p in self.gff['ItemList']: gff_inst = GffInstance(self.gff, 'ItemList', i) st_inst = RepositoryItem(gff_inst, self) result.append(st_inst) i += 1 except KeyError: pass return result @property def equips(self): """ Creature's equipment list. :returns: List of tuples containing equipment ID and resref. """ return [(e['_STRUCT_TYPE_'], e['EquippedRes'].val) for e in self.gff['Equip_ItemList']]
class Door(object): def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_instance = instance if not instance: if isinstance(resource, str): from resource import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): """Stages changes to door's GFF structure. """ if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def script(self): """Scripts: Door responds to the following script events: #. Event.CLOSE #. Event.DAMAGED #. Event.DEATH #. Event.TRAP_DISARMED #. Event.HEARTBEAT #. Event.LOCK #. Event.ATTACKED #. Event.OPEN #. Event.SPELL_CAST_AT #. Event.TRAP_TRIGGERED #. Event.UNLOCK #. Event.USER_DEFINED #. Event.CLICK #. Event.FAIL_TO_OPEN """ if self._scripts: return self._scripts lbls = {} lbls[Event.CLOSE] = "OnClosed" lbls[Event.DAMAGED] = "OnDamaged" lbls[Event.DEATH] = "OnDeath" lbls[Event.TRAP_DISARMED] = "OnDisarm" lbls[Event.HEARTBEAT] = "OnHeartbeat" lbls[Event.LOCK] = "OnLock" lbls[Event.ATTACKED] = "OnMeleeAttacked" lbls[Event.OPEN] = "OnOpen" lbls[Event.SPELL_CAST_AT] = "OnSpellCastAt" lbls[Event.TRAP_TRIGGERED] = "OnTrapTriggered" lbls[Event.UNLOCK] = "OnUnlock" lbls[Event.USER_DEFINED] = "OnUserDefined" lbls[Event.CLICK] = "OnClick" lbls[Event.FAIL_TO_OPEN] = "OnFailToOpen" self._scripts = NWObjectScripts(self, lbls) return self._scripts
class Store(object): def __init__(self, resource, instance=False): self._scripts = None self._vars = None self.is_file = False self.is_instance = instance if not instance: if isinstance(resource, str): from pynwn import ContentObject co = ContentObject.from_file(resource) self.gff = Gff(co) self.is_file = True else: self.container = resource[1] self.gff = Gff(resource[0]) else: self.gff = resource def stage(self): if self.gff.is_loaded(): self.container.add_to_saves(self.gff) @property def vars(self): """ Variable table """ if self._vars: return self._vars self._vars = NWObjectVarable(self, self.gff) return self._vars @property def scripts(self): """Scripts. Responds to script events: #. Event.OPEN #. Event.CLOSE """ if self._scripts: return self._scripts lbls = {Event.OPEN: 'OnOpenStore', Event.CLOSE: 'OnStoreClosed'} self._scripts = NWObjectScripts(self, lbls) return self._scripts @property def will_not_buy(self): """Will not buy list. :returns: List of baseitem IDs that store will not buy. """ return [i['BaseItem'] for i in self.gff['WillNotBuy']] @property def will_only_buy(self): """Will only buy list. :returns: List of baseitem IDs that store will only buy. """ return [i['BaseItem'] for i in self.gff['WillOnlyBuy']] @property def items(self): """Items in inventory. :returns: a two dimensional array with the format: [<store page>][<RepositoryItem objects>] """ res = [] for page in self.gff['StoreList']: items = [] i = 0 try: for p in self.gff['ItemList']: gff_inst = GffInstance(self.gff, 'ItemList', i) st_inst = RepositoryItem(gff_inst, self) items.append(st_inst) i += 1 except Exception as e: print(e) pass res.append(items) return res