def get_skills(class_dict, unit, classes, level, gameStateObj, feat=True, seed=0): class_skills = [] for index, klass in enumerate(classes): for level_needed, class_skill in class_dict[klass]['skills']: # If level is gte level needed for skill or gte max_level if level >= level_needed or index < len(classes) - 1: class_skills.append(class_skill) # === Handle Feats (Naive choice) if feat: for status in class_skills: if status == 'Feat': counter = 0 while StatusObject.feat_list[(seed + counter) % len( StatusObject.feat_list)] in class_skills: counter += 1 class_skills.append( StatusObject.feat_list[(seed + counter) % len(StatusObject.feat_list)]) class_skills = [status for status in class_skills if status != 'Feat'] logger.debug('Class Skills %s', class_skills) # === Actually add statuses status_effects = [ StatusObject.statusparser(status) for status in class_skills ] for status in status_effects: if status: StatusObject.HandleStatusAddition(status, unit, gameStateObj) # handle having a status that gives stats['HP'] unit.set_hp(int(unit.stats['HP']))
def apply(self, unit, gameStateObj): if (self.target == 'Ally' and self.parent_unit.checkIfAlly(unit) and self.parent_unit is not unit) or \ (self.target == 'Enemy' and self.parent_unit.checkIfEnemy(unit)): success = StatusObject.HandleStatusAddition(self.child_status, unit, gameStateObj) if success: self.children.add(unit.id) logger.debug('Applying Aura %s to %s at %s', self.child_status.name, unit.name, unit.position)
def add_global_status(self, s_id, gameStateObj=None): if any(status.id == s_id for status in self.status_effects): return # No stacking at all of global statuses status_obj = StatusObject.statusparser(s_id) self.status_effects.add(status_obj) if gameStateObj: for unit in gameStateObj.allunits: if unit.position: StatusObject.HandleStatusAddition(status_obj, unit, gameStateObj)
def create_unit(unitLine, allunits, groups, reinforceUnits, metaDataObj, gameStateObj): assert len(unitLine) in [ 9, 10 ], "unitLine %s must have length 9 or 10 (if optional status)" % (unitLine) legend = { 'team': unitLine[0], 'unit_type': unitLine[1], 'event_id': unitLine[2], 'class': unitLine[3], 'level': unitLine[4], 'items': unitLine[5], 'position': unitLine[6], 'ai': unitLine[7], 'group': unitLine[8] } class_dict = metaDataObj['class_dict'] u_i = {} GC.U_ID += 1 u_i['u_id'] = GC.U_ID u_i['team'] = legend['team'] u_i['event_id'] = legend['event_id'] if legend['class'].endswith('F'): legend['class'] = legend['class'][:-1] # strip off the F u_i['gender'] = 5 # Default female gender is 5 else: u_i['gender'] = 0 # Default male gender is 0 classes = legend['class'].split(',') u_i['klass'] = classes[-1] # Give default previous class default_previous_classes(u_i['klass'], classes, class_dict) u_i['level'] = int(legend['level']) u_i['position'] = tuple( [int(num) for num in legend['position'].split(',')]) u_i['name'], u_i['faction'], u_i['desc'] = groups[legend['group']] stats, u_i['growths'], u_i['growth_points'], u_i['items'], u_i[ 'wexp'] = get_unit_info(class_dict, u_i['klass'], u_i['level'], legend['items'], gameStateObj) u_i['stats'] = build_stat_dict(stats) logger.debug("%s's stats: %s", u_i['name'], u_i['stats']) u_i['tags'] = class_dict[u_i['klass']]['tags'] u_i['ai'] = legend['ai'] u_i['movement_group'] = class_dict[u_i['klass']]['movement_group'] cur_unit = UnitObject.UnitObject(u_i) # Reposition units if u_i['event_id'] != "0": # Unit does not start on board cur_unit.position = None reinforceUnits[u_i['event_id']] = (cur_unit.id, u_i['position']) else: # Unit does start on board cur_unit.position = u_i['position'] # Status Effects and Skills get_skills(class_dict, cur_unit, classes, u_i['level'], gameStateObj, feat=False) # Extra Skills if len(unitLine) == 10: statuses = [ StatusObject.statusparser(status) for status in unitLine[9].split(',') ] for status in statuses: StatusObject.HandleStatusAddition(status, cur_unit, gameStateObj) allunits.append(cur_unit) return cur_unit
def add_unit(unitLine, allunits, reinforceUnits, metaDataObj, gameStateObj): assert len(unitLine) == 6, "unitLine %s must have length 6" % (unitLine) legend = { 'team': unitLine[0], 'unit_type': unitLine[1], 'event_id': unitLine[2], 'unit_id': unitLine[3], 'position': unitLine[4], 'ai': unitLine[5] } class_dict = metaDataObj['class_dict'] for unit in GC.UNITDATA.getroot().findall('unit'): if unit.find('id').text == legend['unit_id']: u_i = {} u_i['u_id'] = unit.find('id').text u_i['event_id'] = legend['event_id'] u_i['position'] = tuple([ int(num) for num in legend['position'].split(',') ]) if ',' in legend['position'] else None u_i['name'] = unit.get('name') u_i['team'] = legend['team'] classes = unit.find('class').text.split(',') u_i['klass'] = classes[-1] # Give default previous class default_previous_classes(u_i['klass'], classes, class_dict) u_i['gender'] = int(unit.find('gender').text) u_i['level'] = int(unit.find('level').text) u_i['faction'] = unit.find('faction').text stats = intify_comma_list(unit.find('bases').text) for n in xrange(len(stats), cf.CONSTANTS['num_stats']): stats.append(class_dict[u_i['klass']]['bases'][n]) if u_i['team'] == 'player': # Modify stats bases = gameStateObj.modify_stats['player_bases'] growths = gameStateObj.modify_stats['player_growths'] else: bases = gameStateObj.modify_stats['enemy_bases'] growths = gameStateObj.modify_stats['enemy_growths'] stats = [sum(x) for x in zip(stats, bases)] assert len(stats) == cf.CONSTANTS[ 'num_stats'], "bases %s must be exactly %s integers long" % ( stats, cf.CONSTANTS['num_stats']) u_i['stats'] = build_stat_dict(stats) logger.debug("%s's stats: %s", u_i['name'], u_i['stats']) u_i['growths'] = intify_comma_list(unit.find('growths').text) u_i['growths'].extend( [0] * (cf.CONSTANTS['num_stats'] - len(u_i['growths']))) u_i['growths'] = [sum(x) for x in zip(u_i['growths'], growths)] assert len(u_i['growths']) == cf.CONSTANTS[ 'num_stats'], "growths %s must be exactly %s integers long" % ( stats, cf.CONSTANTS['num_stats']) u_i['growth_points'] = [50] * cf.CONSTANTS['num_stats'] u_i['items'] = ItemMethods.itemparser(unit.find('inventory').text) # Parse wexp u_i['wexp'] = unit.find('wexp').text.split(',') for index, wexp in enumerate(u_i['wexp'][:]): if wexp in CustomObjects.WEAPON_EXP.wexp_dict: u_i['wexp'][index] = CustomObjects.WEAPON_EXP.wexp_dict[ wexp] u_i['wexp'] = [int(num) for num in u_i['wexp']] assert len(u_i['wexp']) == len( CustomObjects.WEAPON_TRIANGLE.types ), "%s's wexp must have as many slots as there are weapon types." % ( u_i['name']) u_i['desc'] = unit.find('desc').text # Tags class_tags = class_dict[u_i['klass']]['tags'] personal_tags = set(unit.find('tags').text.split( ',')) if unit.find('tags') is not None and unit.find( 'tags').text is not None else set() u_i['tags'] = class_tags | personal_tags u_i['ai'] = legend['ai'] u_i['movement_group'] = class_dict[u_i['klass']]['movement_group'] cur_unit = UnitObject.UnitObject(u_i) if u_i['event_id'] != "0": # unit does not start on board cur_unit.position = None reinforceUnits[u_i['event_id']] = (u_i['u_id'], u_i['position']) else: # Unit does start on board cur_unit.position = u_i['position'] # Status Effects and Skills get_skills(class_dict, cur_unit, classes, u_i['level'], gameStateObj, feat=False) # Personal Skills personal_skills = unit.find('skills').text.split( ',') if unit.find('skills') is not None and unit.find( 'skills').text is not None else [] c_s = [ StatusObject.statusparser(status) for status in personal_skills ] for status in c_s: if status: StatusObject.HandleStatusAddition(status, cur_unit, gameStateObj) # handle having a status that gives stats['HP'] cur_unit.set_hp(int(cur_unit.stats['HP'])) allunits.append(cur_unit) break return allunits, reinforceUnits
def update(self, gameStateObj, metaDataObj): # print(self.state.getState()) # Don't do this if there is no exp change if not self.force_level and self.expNew == 0: return True unit_klass = metaDataObj['class_dict'][self.unit.klass] max_level = Utility.find_max_level(unit_klass['tier'], cf.CONSTANTS['max_level']) if self.unit.level >= max_level and unit_klass['turns_into'] is None: return True # We're done here currentTime = Engine.get_time() # Initiating State if self.state.getState() == 'init': self.exp_bar = Exp_Bar(self.expSet, not self.in_combat) # Create exp_bar self.state_time = currentTime self.state.changeState('exp_wait') # Wait before starting to increment exp elif self.state.getState() == 'exp_wait': self.exp_bar.update(self.expSet) if currentTime - self.state_time > 400: self.state.changeState('exp0') self.state_time = currentTime GC.SOUNDDICT['Experience Gain'].play(-1) # Increment exp until done or 100 exp is reached elif self.state.getState() == 'exp0': progress = (currentTime - self.state_time) / float( self.total_time_for_exp) self.expSet = self.expOld + progress * self.expNew self.expSet = int(min(self.expNew + self.expOld, self.expSet)) self.exp_bar.update(self.expSet) # transitions if self.expNew + self.expOld <= self.expSet: GC.SOUNDDICT['Experience Gain'].stop() if self.expSet >= 100: if self.unit.level >= max_level: # If I would promote because I am level 20 GC.SOUNDDICT['Experience Gain'].stop() if cf.CONSTANTS['auto_promote'] and metaDataObj[ 'class_dict'][self.unit.klass][ 'turns_into']: # If has at least one class to turn into self.expSet = 100 GC.SOUNDDICT['Level Up'].play() else: self.expSet = 99 self.state.clear() self.state.changeState('prepare_promote') self.state.changeState('exp_leave') self.exp_bar.fade_out() self.state_time = currentTime else: self.expSet = 0 self.unit.level += 1 self.levelup_list = self.unit.level_up( gameStateObj, metaDataObj['class_dict'][self.unit.klass]) self.state.changeState('exp100') # Do not reset state time # Extra time to account for end pause elif currentTime - self.state_time >= self.total_time_for_exp + 500: self.state.clear() self.state.changeState('exp_leave') self.state_time = currentTime self.exp_bar.fade_out() elif self.state.getState() == 'exp_leave': done = self.exp_bar.update(self.expSet) if done: self.unit.exp += self.expNew self.state.back() self.state_time = currentTime if len(self.state.state) <= 0: return True # Continue incrementing past 100 elif self.state.getState() == 'exp100': progress = (currentTime - self.state_time) / float( self.total_time_for_exp) self.expSet = self.expOld + self.expNew * progress - 100 self.expSet = int(min(self.expNew + self.expOld - 100, self.expSet)) self.exp_bar.update(self.expSet) if self.expNew + self.expOld - 100 <= self.expSet: GC.SOUNDDICT['Experience Gain'].stop() # Extra time to account for pause at end if currentTime - self.state_time >= self.total_time_for_exp + 500: self.state.clear() self.state.changeState('levelUp') self.state.changeState('exp_leave') self.exp_bar.fade_out() self.state_time = currentTime # Display the level up animation initial elif self.state.getState() == 'levelUp': if not self.level_up_sound_played: GC.SOUNDDICT['Level Up'].play() self.level_up_sound_played = True # Update it if self.levelUpAnimation.update(gameStateObj): if self.in_combat: self.in_combat.darken_ui() self.state.changeState('levelScreen') self.state_time = currentTime # Display the level up stat screen elif self.state.getState() == 'levelScreen': time_to_wait = self.LEVELUPWAIT + (self.get_num_sparks() + 1) * self.SPARKTIME + 500 # Am i Done displaying? if currentTime - self.state_time >= time_to_wait: if self.in_combat: self.in_combat.lighten_ui() # Handle EXP when the user levels up, if this is not a forced level if not self.force_level: self.unit.exp += self.expNew if self.unit.exp >= 100: self.unit.exp = self.expNew - (100 - self.expOld) # Remove animations self.animations = [] # check for weapon gain if self.new_wexp: self.unit.increase_wexp(self.new_wexp, gameStateObj) # check for skill gain if not a forced level if not self.force_level: for level_needed, class_skill in metaDataObj['class_dict'][ self.unit.klass]['skills']: if self.unit.level == level_needed: if class_skill == 'Feat': gameStateObj.cursor.currentSelectedUnit = self.unit gameStateObj.stateMachine.changeState( 'feat_choice') else: skill = StatusObject.statusparser(class_skill) # If we don't already have this skill if skill.stack or skill.id not in ( s.id for s in self.unit.status_effects): StatusObject.HandleStatusAddition( skill, self.unit, gameStateObj) gameStateObj.banners.append( Banner.gainedSkillBanner( self.unit, skill)) gameStateObj.stateMachine.changeState( 'itemgain') return True # Wait 100 milliseconds before transferring us to the promotion state elif self.state.getState() == 'prepare_promote': self.exp_bar.update(self.expSet) if currentTime - self.state_time > 100: if cf.CONSTANTS['auto_promote'] and metaDataObj['class_dict'][ self.unit.klass][ 'turns_into']: # If has at least one class to turn into self.expSet = 0 class_options = metaDataObj['class_dict'][ self.unit.klass]['turns_into'] if len(class_options) > 1: gameStateObj.cursor.currentSelectedUnit = self.unit gameStateObj.stateMachine.changeState( 'promotion_choice') gameStateObj.stateMachine.changeState('transition_out') self.state.changeState('wait') self.state_time = currentTime elif len(class_options) == 1: gameStateObj.cursor.currentSelectedUnit = self.unit self.unit.new_klass = class_options[0] gameStateObj.stateMachine.changeState('promotion') gameStateObj.stateMachine.changeState('transition_out') # self.state.changeState('promote') self.state.changeState('wait') self.state_time = currentTime else: self.unit.exp = 99 return True # Done else: # Unit is at the highest point it can be. No more. self.unit.exp = 99 return True # Done elif self.state.getState() == 'item_promote': if metaDataObj['class_dict'][self.unit.klass][ 'turns_into']: # If has at least one class to turn into class_options = metaDataObj['class_dict'][ self.unit.klass]['turns_into'] if len(class_options) > 1: gameStateObj.cursor.currentSelectedUnit = self.unit gameStateObj.stateMachine.changeState('promotion_choice') gameStateObj.stateMachine.changeState('transition_out') self.state.changeState('wait') self.state_time = currentTime elif len(class_options) == 1: gameStateObj.cursor.currentSelectedUnit = self.unit self.unit.new_klass = class_options[0] gameStateObj.stateMachine.changeState('promotion') gameStateObj.stateMachine.changeState('transition_out') # self.state.changeState('promote') self.state.changeState('wait') self.state_time = currentTime else: self.unit.exp = 99 return True # Done else: # Unit is at the highest point it can be. No more. self.unit.exp = 99 return True # Done elif self.state.getState() == 'wait': if currentTime - self.state_time > 1000: # Wait a while return True elif self.state.getState() == 'promote': # Class should already have been changed by now in the levelpromote state # Here's where I change all the important information new_class = metaDataObj['class_dict'][self.unit.klass] old_anim = self.unit.battle_anim self.unit.removeSprites() self.unit.loadSprites() # Reseed the combat animation if self.in_combat and old_anim: item = self.unit.getMainWeapon() magic = Weapons.TRIANGLE.isMagic(item) if item else False anim = GC.ANIMDICT.partake(self.unit.klass, self.unit.gender, item, magic) if anim: # Build animation script = anim['script'] if self.unit.name in anim['images']: frame_dir = anim['images'][self.unit.name] else: frame_dir = anim['images'][ 'Generic' + Utility.get_color(self.unit.team)] import BattleAnimation self.unit.battle_anim = BattleAnimation.BattleAnimation( self.unit, frame_dir, script) self.unit.battle_anim.awake( owner=old_anim.owner, parent=old_anim.parent, partner=old_anim.partner, right=old_anim.right, at_range=old_anim.at_range, init_speed=old_anim.entrance, init_position=old_anim.init_position) else: self.unit.battle_anim = old_anim # Reset Level self.unit.level = 1 # Actually change class # Reset movement group self.unit.movement_group = new_class['movement_group'] # Add weapon exp gains from that class. # This right here! self.new_wexp = new_class['wexp_gain'] # Add any extra tags if new_class[ 'tags']: # Add any necessary tags. Does not currently take away tags, although it may have to later self.unit.tags |= new_class['tags'] # Give promotion # self.levelup_list = self.unit.level_up(new_class, apply_level=False) # Level up once, then promote. # self.levelup_list = [x + y for x, y in zip(self.levelup_list, new_class['promotion'])] # Add lists together self.levelup_list = new_class[ 'promotion'] # No two level ups, too much gain in one level... current_stats = list(self.unit.stats.values()) assert len(self.levelup_list) == len( new_class['max']) == len(current_stats), "%s %s %s" % ( self.levelup_list, new_class['max'], current_stats) for index, stat in enumerate(self.levelup_list): self.levelup_list[index] = min( stat, new_class['max'][index] - current_stats[index].base_stat) self.unit.apply_levelup(self.levelup_list) if self.in_combat: self.in_combat.darken_ui() self.state.changeState('levelScreen') self.state_time = currentTime # Reset time so that it doesn't skip right over LevelScreen return False
def add_global_status(self, s_id, gameStateObj=None): self.status_effects.add(s_id) if gameStateObj: for unit in gameStateObj.allunits: if unit.position: StatusObject.HandleStatusAddition(s_id, unit, gameStateObj)