From 109e967987df22879d74fe8fe56fff870299f95b Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Thu, 29 Mar 2012 18:06:09 -0400 Subject: [PATCH] battleman.py: Implemented --resume, made global variables less global --- battleman.py | 145 +++++++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 63 deletions(-) diff --git a/battleman.py b/battleman.py index 2d00da3..cbafaf7 100755 --- a/battleman.py +++ b/battleman.py @@ -15,8 +15,9 @@ from dice import Dice import cPickle as pickle -import sys +import argparse import os.path +import sys class CombatGroup(): @@ -406,7 +407,7 @@ class Battle(): def add_group(self, group): # If battle is already going, need to know # where in the init order the new mooks go - if battle.is_started(): + if self.is_started(): if group.is_solo_group() and group.members[0].pc: group.set_init(input_int('Initiative for {}'.format(group.name))) else: @@ -549,40 +550,54 @@ class Battle(): return None - -battle = Battle() - -### This is the pickling jar -battle_pickle = None -bp_io_failed = False -BP_FILE = os.path.expanduser('~/.config/4etools/battleman/battle.pickle') -### - - def main(): + battle = Battle() + + ### This is the pickling jar + battle_pickle = None + bp_io_failed = False + BP_FILE = os.path.expanduser('~/.config/4etools/battleman/battle.pickle') + ### + # Make sure config directory exists if not os.path.exists(os.path.dirname(BP_FILE)): os.makedirs(os.path.dirname(BP_FILE)) - # hard-coding test cases for now. - # Eventually, use a state-saving text file that's easy to edit - battle.add_group(CombatGroup("Adele", [Combatant("Adele", hp=26, pc=True, surges=8, sw=1)], 2)) - battle.add_group(CombatGroup("Aristaire", [Combatant("Aristaire", hp=20, pc=True, surges=6, sw=1)], 0)) + # Get command-line args + settings = parse_args() - battle.add_group(CombatGroup("Foobolds", [Combatant("Foobold", hp=50), Combatant("Foobold", hp=50), Combatant("Foobold", hp=50), Combatant("Foobold", hp=50), Combatant("Foobold", hp=50)], 20)) - battle.add_group(CombatGroup("Barglins", [Combatant("Barglin", hp=1), Combatant("Barglin", hp=1)], 3)) - battle.add_group(CombatGroup("Orcs of Baz", [Combatant("Orc", hp=32), Combatant("Orc", hp=32)], 1)) - print "Welcome to 4e Battle Manager.\n" + + # Resume battle if needed + if settings.resume: + try: + with open(BP_FILE, 'r') as f: + battle = pickle.load(f) + battle_pickle = pickle.dumps(battle) + except: + print "Error: Couldn't resume. Quitting to preserve our pickle." + sys.exit(1) + + print 'Resuming battle. We are in round: {}\n'.format(battle.round) + + else: + # hard-coding test cases for now. + # Eventually, use a state-saving text file that's easy to edit, or at least copy... + battle.add_group(CombatGroup("Adele", [Combatant("Adele", hp=26, pc=True, surges=8, sw=1)], 2)) + battle.add_group(CombatGroup("Aristaire", [Combatant("Aristaire", hp=20, pc=True, surges=6, sw=1)], 0)) + + battle.add_group(CombatGroup("Foobolds", [Combatant("Foobold", hp=50), Combatant("Foobold", hp=50), Combatant("Foobold", hp=50), Combatant("Foobold", hp=50), Combatant("Foobold", hp=50)], 20)) + battle.add_group(CombatGroup("Barglins", [Combatant("Barglin", hp=1), Combatant("Barglin", hp=1)], 3)) + battle.add_group(CombatGroup("Orcs of Baz", [Combatant("Orc", hp=32), Combatant("Orc", hp=32)], 1)) print battle while True: - do_prompt() + do_prompt(battle, battle_pickle, bp_io_failed, BP_FILE) -def do_prompt(): +def do_prompt(battle, battle_pickle, bp_io_failed, BP_FILE): print '' (comm, rdata) = input_str('', default='n', show_default=False, prompt_str='>').partition(' ')[::2] data = rdata.split(' ') @@ -593,39 +608,39 @@ def do_prompt(): if comm == '?': do_help() # fixme - add ability to get command-specific help elif comm == 'a': - do_add_combatants(data) + do_add_combatants(battle, data) elif comm == 'p': - do_print_combatant_info(data) + do_print_combatant_info(battle, data) elif comm == 'l': print battle.format_combatants() elif comm == 'b': battle.begin() elif comm == 'd': - do_damage(data) + do_damage(battle, data) elif comm == 'h': - do_heal(data) + do_heal(battle, data) elif comm == 't': - do_add_temp_hp(data) + do_add_temp_hp(battle, data) elif comm == 'T': - do_remove_temp_hp(data) + do_remove_temp_hp(battle, data) elif comm == 's': - do_surge(data) + do_surge(battle, data) elif comm == 'so': - do_surge(data, heal=False) + do_surge(battle, data, heal=False) elif comm == 'sw': - do_second_wind(data) + do_second_wind(battle, data) elif comm == 'c': - do_add_condition(data) + do_add_condition(battle, data) elif comm == 'C': - do_remove_condition(data) + do_remove_condition(battle, data) elif comm == 'n': battle.next_combatant() elif comm == 'r': - do_use_recharge_power(data) + do_use_recharge_power(battle, data) elif comm == 'w': - do_wait(data) + do_wait(battle, data) elif comm == 'W': - do_unwait(data) + do_unwait(battle, data) elif comm == 'x': do_stub() elif comm == 'q': @@ -633,8 +648,6 @@ def do_prompt(): # Re-pickle and write if changed after every query. It's cheap # and we only have to run at user-speed anyway - global battle_pickle - old_bp = battle_pickle battle_pickle = pickle.dumps(battle) @@ -672,7 +685,7 @@ q - quit""") # Core data parsing functions -def do_add_combatants(data): +def do_add_combatants(battle, data): if len(data) >= 1: ngroups = int(data[0]) else: @@ -683,7 +696,7 @@ def do_add_combatants(data): battle.add_group(CombatGroup.from_input()) -def do_print_combatant_info(data): +def do_print_combatant_info(battle, data): if len(data) >= 1: c = battle.get_combatant(int(data[0])) if not c: @@ -694,8 +707,8 @@ def do_print_combatant_info(data): print battle.format_current_group() -def do_damage(data): - c = do_combatant_select(data) +def do_damage(battle, data): + c = do_combatant_select(battle, data) if not c: return @@ -707,8 +720,8 @@ def do_damage(data): c.damage(amount) -def do_heal(data): - c = do_combatant_select(data) +def do_heal(battle, data): + c = do_combatant_select(battle, data) if not c: return @@ -720,8 +733,8 @@ def do_heal(data): c.heal(amount) -def do_add_temp_hp(data): - c = do_combatant_select(data) +def do_add_temp_hp(battle, data): + c = do_combatant_select(battle, data) if not c: return @@ -733,29 +746,29 @@ def do_add_temp_hp(data): c.add_temp_hp(amount) -def do_remove_temp_hp(data): +def do_remove_temp_hp(battle, data): do_stub() -def do_surge(data, heal=True): - c = do_combatant_select(data) +def do_surge(battle, data, heal=True): + c = do_combatant_select(battle, data) if not c: return c.use_surge(heal) -def do_second_wind(data): - c = do_combatant_select(data) +def do_second_wind(battle, data): + c = do_combatant_select(battle, data) if not c: return c.use_second_wind() -def do_add_condition(data): +def do_add_condition(battle, data): duration = None end_type = 'e' - c = do_combatant_select(data) + c = do_combatant_select(battle, data) if not c: return @@ -769,8 +782,8 @@ def do_add_condition(data): c.add_condition(name, ctype, duration, end_type) -def do_remove_condition(data): - c = do_combatant_select(data) +def do_remove_condition(battle, data): + c = do_combatant_select(battle, data) if not c: return @@ -786,8 +799,8 @@ def do_remove_condition(data): c.remove_condition(index) -def do_use_recharge_power(data): - c = do_combatant_select(data) +def do_use_recharge_power(battle, data): + c = do_combatant_select(battle, data) if not c: return @@ -803,11 +816,11 @@ def do_use_recharge_power(data): c.use_recharge_power(index) -def do_wait(data): +def do_wait(battle, data): do_stub() -def do_unwait(data): +def do_unwait(battle, data): do_stub() @@ -816,9 +829,15 @@ def do_stub(): +def parse_args(): + parser = argparse.ArgumentParser(description='Command-line interface to manage battle data for D&D 4e', formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('--resume', '-r', action='store_true', help='Resume the battle from the last run of the program') + return parser.parse_args() + + # Data parsing helper functions -def do_combatant_select(data): +def do_combatant_select(battle, data): c = None if len(data) >= 1: @@ -833,15 +852,15 @@ def do_combatant_select(data): return c -def do_data_input_str(data, index, prompt, default=None, show_default=False, prompt_str=':'): +def do_data_input_str(battle, data, index, prompt, default=None, show_default=False, prompt_str=':'): if len(data) >= index + 1: return data[index] else: return input_str(prompt, default, show_default, prompt_str) -def do_data_input_int(data, index, prompt, default=None, show_default=True, prompt_str=':'): - return int(do_data_select_str(data, index, prompt, default, show_default, prompt_str)) +def do_data_input_int(battle, data, index, prompt, default=None, show_default=True, prompt_str=':'): + return int(do_data_select_str(battle, data, index, prompt, default, show_default, prompt_str)) # Input primitives