#!/usr/bin/python # # battleman.py - RPG Battle Manager # # A table-top RPG battle flow manager # Tuned pretty specifically to D&D 4e for now... need a templatized system # to do anything fancier... may develop that at some point. import dice class Combatant(): @classmethod def from_input(cls): name = raw_input("Name: ") hp = int(raw_input("hp: ")) surges = raw_input("surges [0]: ") if surges: surges = int(surges) else: surges = 0 recharges = [] recharge = '-1' while True: recharge = raw_input("recharge: ").split(',') if recharge == ['']: break else: recharges.append(recharge) return Combatant(name, hp, pc=0, surges=surges, recharges=recharges) def __init__(self, name, hp, init_mod, pc=False, surges=0, ap=0, sw=0, recharges=[]): self.name = name self.hp = hp self.pc = pc self.surges = surges self.ap = ap self.sw = sw self.recharges = [] self.init_mod = init_mod self.init = 0 self.conditions = [] def roll_init(self): d = Dice.from_desc('1d20+' + self.init_mod) self.set_init(d.roll()['total']) def set_init(self, init): self.init = init def add_condition(self, name, cond_type, duration): condition = {} condition['name'] = name condition['type'] = cond_type condition['duration'] = duration self.conditions.append(condition) def turn_begin(self): print("{} has initiative.".format(self)) def __str__(self): return "{} ({hp} hp)".format(self.name, hp=self.hp) # data about the battle - includes combatant list, etc battle = {} def main(): battle['combatants'] = [] battle['current'] = None battle['round'] = -1 # hard-coding test cases for now. # Eventually, use a state-saving text file that's easy to edit battle['combatants'].append(Combatant("Adele", hp=26, init_mod=2, pc=True, surges=8, sw=1)) battle['combatants'].append(Combatant("Aristaire", hp=20, init_mod=0, pc=True, surges=6, sw=1)) ngroups = int(raw_input("Num enemy groups: ")) for i in range(1, ngroups+1): print("Adding enemy group {}".format(i)) battle['combatants'].append(Combatant.from_input()) # debug for c in battle['combatants']: print(c) while True: do_prompt() def do_prompt(): comm = raw_input('> ') # help if 'comm' == '?': do_help() # add more combatants elif 'comm' == 'a': pass # list combatants with indices elif 'comm' == 'l': do_list_combatants() # begin the battle elif 'comm' == 'b': do_begin_battle() # deal damage to a combatant elif 'comm' == 'd': pass # heal damage from a combatant elif 'comm' == 'h': pass # use a healing surge elif 'comm' == 's': pass # apply a condition elif 'comm' == 'c': pass # remove a condition early elif 'comm' == 'r': pass # end the current combatant's turn elif 'comm' == 'n': pass # remove the combatant from the initiative order (delay/prepare) elif 'comm' == 'w': pass def do_help(): print(""" Possible commands: ? - print this help menu (yay, you already figured that one out) a - add more combatants (works during battle) l - list current combatants b - begin the battle d - deal damage to someone h - heal someone s - let someone use a healing surge c - apply a condition r - remove a condition (this can also happen automatically) n - next (end the current combatant's turn) w - wait (remove the combatant from the initiative order and into a separate pool) """) def do_list_combatants(): index = 0 for c in battle['combatants']: print('{}: {}'.format(index, c.name)) index += 1 def do_begin_battle(): if current != None: print("Error: battle is already running") return for c in battle['combatants']: if c.pc: raw_input('Initiative for {}: '.format(c.name)) else: c.roll_init() battle['combatants'].sort(reverse=True) current = 0 if __name__ == '__main__': main()