rendered paste body#!/usr/bin/env pythonfrom misc import Worldfrom ent import Entfrom effect import Effect, EffectContainerfrom items import StatboostEquipmentfrom stats import * from races import Humanfrom random import randomfrom threading import Timerfrom time import timeworld = World()class AI: def __init__(self, puppet): self.puppet = puppet def think(self): puppet = self.puppet #print "%s <%s/%s> " %(puppet.name, puppet.hp.value, puppet.max_hp.value) target = False suggested_ability = False suggested_suitability = 0 for x in world.ents: if x is not puppet: target = x suitability_scores = { } for ability in puppet.abilities: if ability.targeted: suitability_score = ability.AI_Usefulness_Metric(target) else: suitability_score = ability.AI_Usefulness_Metric() if suitability_score > suggested_suitability: suggested_ability = ability suggested_suitability = suitability_score if suggested_ability: if suggested_ability.targeted: suggested_ability.use(target) else: suggested_ability.use() else: puppet.melee(target) break def emoteStats(self): print "-----------------------------" puppet = self.puppet seen_stats = [] for pseudoID in puppet.stats: self.descStat(puppet.stats[pseudoID]) print "-----------------------------" def descStat(self, stat, level=0, seen_stats = []): spacer = "---" * level print spacer, stat.__class__, stat.value for nstat in stat._updated_by: self.descStat(nstat, level + 1, seen_stats)class TwoHandedSword(StatboostEquipment): bonuses = [Str + 5, Str.Multiplier(.001)]sword = TwoHandedSword()class brightAura(Effect): name = "brutal power" flavor = "str increased by 10%" def onApply(self, ent): self.bonus = Str.Multiplier(5) ent.stats.apply(self.bonus) def onRemove(self, ent): self.bonus.cancel()class Ability: targeted = Falseclass Shove(Ability): targeted = True def AI_Usefulness_Metric(self, target): if target.doing: return 100 return 0 def __init__(self, ent): self.ent = ent def use(self, target): if self.ent.extendGCD(5): self.ent.emote(" shoves %s to the ground." % (target.name)) target.doing = Falseclass Wrath(Ability): class Effect(Effect): name = "Wrath" flavor = "str increased by 300%" def __init__(self, parentAbility): self.parentAbility = parentAbility Effect.__init__(self) self.parentAbility.effect = self def onApply(self, ent): self.bonus = Str * 300 self.completionFunction = Timer(2,ent.effects.remove,(self,)) self.completionFunction.start() ent.stats.apply(self.bonus) ent.emote("displays his incredible wrath.") def onRemove(self, ent): self.completionFunction.cancel() self.bonus.cancel() ent.emote("'s wrath begins to subside.") self.parentAbility.effect = False def __init__(self, ent): self.ent = ent self.effect = False def AI_Usefulness_Metric(self): if self.ent.hp.value < 2: if not self.effect: return 100 return 0 def use(self): if not self.effect: self.effect = self.Effect(self) self.ent.effects.add(self.effect) else: self.ent.emote("fails to kick his wrath up a notch.")class Fireball(Ability): targeted = True def __init__(self, ent): self.ent = ent self.castTimer = False def AI_Usefulness_Metric(self, target): return 100 def interrupt(self): if self.castTimer: self.castTimer.cancel() self.ent.emote("'s fireball is interrupted!") self.doing = False def cast(self, target): self.ent.emote("hurls a fireball at %s!" % (target.name,)) doing = False target.hp -= 3 def use(self, target): # start over with duration if self.ent.extendGCD(2): self.ent.emote("begins to cast a spell.") self.castTimer = Timer(2,self.cast,(target,)) self.castTimer.start() #self.ent.doing = selfclass SeepingHeal(Ability): class Effect(Effect): name = "Seeping Heal" flavor = "slowly regenerates hit-points" duration = 5 def __init__(self, parentAbility): self.parentAbility = parentAbility Effect.__init__(self) self.parentAbility.effect = self self.__start_time = time() def remaining(self): return (self.__start_time + self.duration) - time() def onApply(self, ent): self.bonus = Str * 300 self.completionFunction = Timer(self.duration,ent.effects.remove,(self,)) self.completionFunction.start() ent.stats.apply(self.bonus) ent.emote("'s body is covered with a glowing liquid.") def onRemove(self, ent): self.completionFunction.cancel() self.bonus.cancel() ent.emote("'s glowing liquid has completely absorbed into his skin.") self.parentAbility.effect = False def __init__(self, ent): self.ent = ent self.effect = False def AI_Usefulness_Metric(self): if self.ent.hp.value < 10: if not self.effect: return 80 else: if self.effect.remaining() <= 1: return 20 return 0 def interrupt(self): if self.effect: self.ent.effects.remove(self.effect) self.ent.emote("loses control of the glowing liquid and it flees from his skin!") def use(self): # start over with duration if self.effect: self.ent.effects.remove(self.effect) self.ent.emote("summons more of the flowing liquid onto his body.") self.effect = self.Effect(self) self.ent.effects.add(self.effect) self.ent.doing = selfclass Combatant(Ent): def __set_doing(self, doing): if self.__doing: self.__doing.interrupt() self.__doing = doing def __get_doing(self): return self.__doing doing = property(__get_doing, __set_doing) def __init__(self): Ent.__init__(self) self.__initStats() self.channeling = False self.ai = AI(self) self.__doing = False def alertHP(self, stat): print "%s <%s/%s> " %(self.name, self.hp.value, self.max_hp.value) def __initStats(self): self.mytest = ChainUpdatingNumber() self.stats = StatCollection() self.level = Level() self.str = Str() self.dex = Dex() self.con = Con() self.int = Int() self.wis = Wis() self.cha = Cha() self.armor = Armor() self.base_attack_power = CalculatedStat(lambda: (self.level.value * 2) + self.str.value, [self.level,self.str]) self.attack_power = AttackPower(self.base_attack_power) self.base_max_hp = CalculatedStat(lambda: self.level.value * 10, [self.level]) self.max_hp = MaxHP(self.base_max_hp) self.level.set(1) self.hp = PrimitiveStat() self.hp.set(self.max_hp.value) self.hp.subscribe(self.alertHP) self.cha.addToStatCollection(self.stats) self.hp.addToStatCollection(self.stats) self.abilities = [Wrath(self), SeepingHeal(self), Shove(self), Fireball(self)] self.gcd = False def readyGCD(self): self.gcd = False def extendGCD(self, seconds): if self.gcd: return False else: self.gcd = True t = Timer(seconds, self.readyGCD) t.start() return True def melee(self, victim): if self.extendGCD(.03): dex_delta = self.dex.value - victim.dex.value dex_mod = (dex_delta ** .33) / 100 # base 25% chance to miss if (random() + dex_mod) < .25: self.emote("lands a blow.") victim.hp.set(victim.hp.value - 1) else: self.emote("missed!") def emote(self, txt): print self.name, txt warrior = Combatant()mage = Combatant()mage.str.base.set(13)mage.cha.base.set(17)mage.setRace(Human)mage.level.set(4)i = brightAura()mage.effects.add(i)mage.effects.remove(i)mage.bodyparts.gloves.equip(sword)mage.bodyparts.gloves.unequip()class Team(list): def stillAlive(self): for ent in self: if ent.hp.value > 0: return True return Falseclass Teamset(list): def anyoneDead(self): for team in self: if not team.stillAlive(): return True else: return Falsea = Team([mage])b = Team([warrior])teams = Teamset()teams.append(a)teams.append(b)mage.name = "mage"mage.team = awarrior.name = "warrior"warrior.team = bworld.ents = [mage,warrior]print mage.hp.value, mage.level.value, mage.max_hp.valuefor ent in world.ents: ent.ai.emoteStats()i = 0while not teams.anyoneDead(): for team in teams: for ent in team: ent.ai.think() i+= 1for ent in world.ents: ent.ai.emoteStats()