コード例 #1
0
    def loadCombat(self):
        filename = tkfd.askopenfilename(title="Select file",
                                        defaultextension='.rmc',
                                        filetypes=(("Rolemaster Combat files",
                                                    "*.rmc"), ("all files",
                                                               "*.*")))
        load_file = open(filename, 'rb')
        self.combat = pickle.load(load_file)
        load_file.close()

        v.p(
            verbose_msg, "Combat loaded. Combatants: " + str([
                self.combat.combatants[guy].name
                for guy in self.combat.combatants
            ]))

        for combatant in self.combat.combatants:
            new_frame = combatantframe.CombatantFrame(
                self, self.combat, self.combat.combatants[combatant])
            if self.combat.num_of_combatants == 1:
                new_frame.grid(row=1, column=0, columnspan=7)
            else:
                new_frame.grid(column=0, columnspan=7)
            self.combatant_frames.append(new_frame)
            new_frame.update_targets()
        self.combat_log_msg.grid(rowspan=len(self.combatant_frames) + 1)

        for i in self.combat.log:
            self.combat_log_msg.insert(tk.END, i)

        self.update_combatants_list()
コード例 #2
0
    def initialize(self):
        v.p(verbose_msg,
            "Creating the combatant frame for " + self.combatant.name)
        r = 0
        self.hits_and_PP_label = ttk.Label(self, textvariable=self.hits_PP)
        self.hits_and_PP_label.grid(row=r, column=0, sticky="w")
        r += 1
        self.status_label = ttk.Label(self, textvariable=self.status)
        self.status_label.grid(row=r, column=0, sticky="w")
        r += 1
        self.AT_and_DB_label = ttk.Label(self, textvariable=self.AT_DB)
        self.AT_and_DB_label.grid(row=r, column=0, sticky="w")
        r += 1
        self.exh_label = ttk.Label(self, textvariable=self.exh)
        self.exh_label.grid(row=r, column=0, sticky="w")
        r += 1
        self.init_bonus_label = ttk.Label(self, textvariable=self.init_bonus)
        self.init_bonus_label.grid(row=r, column=0, sticky="w")
        r += 1
        self.edit_combatant_btn = ttk.Button(self,
                                             text="Edit",
                                             command=self.edit)
        self.edit_combatant_btn.grid(row=r, column=0)

        self.choose_actions_ntbk = chooseactionsnotebook.ChooseActionNtbk(
            self, self.combat, self.combatant)
        self.choose_actions_ntbk.grid(row=0,
                                      column=1,
                                      rowspan=r + 1,
                                      sticky=tk.N + tk.S + tk.E + tk.W)

        self.update_info()
コード例 #3
0
 def __init__(self, parent, combat, guy):
     tk.Frame.__init__(self, parent)
     v.p(verbose_msg, "Init Targeted Action Frame")
     self.parent = parent
     self.combat = combat
     self.combatant = guy
     self.targets_list = []
     self.target = tk.StringVar()
     self.choose_target_optmenu = ttk.OptionMenu(self, self.target,
                                                 *['None'])
コード例 #4
0
 def resolve_recurring_trigger(self, rtrigger):
     if rtrigger.name == "Bleeding":
         rtrigger.target.hits += -rtrigger.parameters['damage']
         self.add_to_log(rtrigger.target.name + " bled " +
                         str(rtrigger.parameters['damage']) + " hits.")
     else:
         v.p(
             verbose_msg,
             "Not actually doing anything with recurring trigger: " +
             rtrigger.name)
     rtrigger.target.update_status()
コード例 #5
0
 def update_attacks_list(self):
     self.attacks_list = []
     for item in self.combatant.attacks_list:
         self.attacks_list.append(str(item))
     v.p(verbose_msg, "      Updating attacks list for " + self.combatant.name + " to " + str(self.attacks_list))
     self.choose_attack_optmenu['menu'].delete(0, tk.END)
     if not self.attacks_list:
         self.attack.set("None")
         self.choose_attack_optmenu['menu'].add_command(label="None", command=tk._setit(self.attack, "None"))
     else:
         for item in self.attacks_list:
             self.choose_attack_optmenu['menu'].add_command(label=item, command=tk._setit(self.attack, item))
         self.attack.set(self.attacks_list[0])
コード例 #6
0
    def submit(self):
        if self.name.get() in self.combat.get_combatant_names() and \
                        self.combatant != self.combat.get_combatant(self.name.get()):
            self.duplicate_mb = tkmb.showwarning(
                "Duplicate Name",
                "A combatant with that name already exists. Please change the name."
            )
        else:
            if self.frame is None:
                self.combatant.update_info(self.name.get(),
                                           self.max_hits.get(),
                                           self.hits.get(),
                                           self.combatant.status,
                                           self.max_PP.get(), self.PP.get(),
                                           self.AT.get(), self.DB_melee.get(),
                                           self.DB_ranged.get(),
                                           self.max_exhpts.get(),
                                           self.exhpts.get(),
                                           self.initiative_bonus.get())
                self.combatant.update_status()
                self.combat.add_combatant(self.combatant)
                self.frame = combatantframe.CombatantFrame(
                    self.parent, self.combat, self.combatant)
                if self.combat.num_of_combatants == 1:
                    self.frame.grid(row=1, column=0, columnspan=2)
                else:
                    self.frame.grid(column=0, columnspan=2)
                self.parent.combatant_frames.append(self.frame)
                self.parent.combat_log_msg.grid(
                    rowspan=len(self.parent.combatant_frames) + 1)

            else:
                self.combat.update_combatant(self.combatant, self.name.get(),
                                             self.max_hits.get(),
                                             self.hits.get(),
                                             self.combatant.status,
                                             self.max_PP.get(), self.PP.get(),
                                             self.AT.get(),
                                             self.DB_melee.get(),
                                             self.DB_ranged.get(),
                                             self.max_exhpts.get(),
                                             self.exhpts.get(),
                                             self.initiative_bonus.get())
                self.combatant.update_status()
                v.p(verbose_msg, "Updating combatant: " + self.name.get())

            self.frame.update_info()
            self.parent.update_combatants_list()
            self.parent.update_target_lists()

            self.destroy()
コード例 #7
0
    def resolve_trigger(self, trig):
        v.p(verbose_msg,
            "Resolving trigger: " + trig.name + " for " + trig.target.name)
        print(self.trigger_list)
        if trig.name == "Stun No Parry":
            if trig.target.stun_ends_at > self.time:
                new_trig = trigger.Trigger("Stun", trig.target,
                                           trig.target.stun_ends_at)
                self.add_trigger(new_trig)

        else:
            v.p(verbose_msg,
                "Not actually doing anything with this trigger: " + trig.name)
        trig.target.update_status()
コード例 #8
0
    def act(self):
        triggers_to_resolve = self.trigger_list.get(self.time)
        recurring_triggers_to_resolve = self.recurring_trigger_list.get(
            self.time)
        actions_to_resolve = self.action_list.get(self.time)
        v.p(verbose_msg, "Actions to resolve: " + str(actions_to_resolve))

        while not actions_to_resolve and not triggers_to_resolve and not recurring_triggers_to_resolve:
            self.time += 0.5
            triggers_to_resolve = self.trigger_list.get(self.time)
            recurring_triggers_to_resolve = self.recurring_trigger_list.get(
                self.time)
            actions_to_resolve = self.action_list.get(self.time)

        v.p(verbose_msg, "Time is " + str(self.time))
        self.add_to_log("    Time is " + str(self.time))

        if recurring_triggers_to_resolve:
            v.p(
                verbose_msg, "---Resolving recurring triggers at " +
                str(self.time) + " seconds")
            for rtrigger in recurring_triggers_to_resolve:
                self.resolve_recurring_trigger(rtrigger)
                rtrigger.end_time += 10
                self.add_recurring_trigger(rtrigger)
            self.recurring_trigger_list[self.time] = []

        if actions_to_resolve:
            v.p(verbose_msg,
                "---Resolving actions at " + str(self.time) + " seconds")
            if len(actions_to_resolve) > 1:
                actions_to_resolve = self.roll_initiative(actions_to_resolve)
            for action in actions_to_resolve:
                self.resolve_action(action)
            self.action_list[self.time] = []

        if triggers_to_resolve:
            v.p(verbose_msg,
                "---Resolving triggers at " + str(self.time) + " seconds")
            for item in triggers_to_resolve:
                self.resolve_trigger(item)
            self.trigger_list[self.time] = []
コード例 #9
0
ファイル: attacktable.py プロジェクト: PyleOfBytes/RMCombat
 def __init__(self, filename):
     with open(filename) as attack_table_file:
         v.p(verbose_msg, "Reading attack table: " + filename)
         readCSV = csv.reader(attack_table_file, delimiter=',')
         self.name = next(readCSV)[1]
         self.critical_type = next(readCSV)[1]
         line = next(readCSV)
         self.hands = line[1]
         line = next(readCSV)
         self.min_length = float(line[1])
         self.max_length = float(line[2])
         line = next(readCSV)
         self.min_weight = float(line[1])
         self.max_weight = float(line[2])
         line = next(readCSV)
         self.fumble = int(line[2])
         line = next(readCSV)
         self.breakage_num = int(line[2])
         line = next(readCSV)
         self.min_strength = int(line[1])
         self.max_strength = int(line[2])
         if len(line) == 4:
             self.strength_type = line[3]
         else:
             self.strength_type = None
         line = next(readCSV)
         self.ranges = []
         ranges = int(line[1])
         if ranges > 0:
             for i in range(0, ranges):
                 line = next(readCSV)
                 self.ranges.append(
                     [int(line[1]),
                      int(line[2]),
                      int(line[3])])
         line = next(readCSV)
         self.results = []
         for i in readCSV:  #readCSV.line_num - 9 - ranges):
             self.results.append(i)
コード例 #10
0
    def loadCombatant(self):
        filename = tkfd.askopenfilename(
            title="Select file",
            defaultextension='.cbt',
            filetypes=(("Rolemaster Combatant files", "*.cbt"), ("all files",
                                                                 "*.*")))
        load_file = open(filename, 'rb')
        combatant = pickle.load(load_file)
        load_file.close()

        proceed = True
        if combatant.name in self.combat.get_combatant_names():
            proceed = tkmb.askokcancel(
                "Overwrite Combatant?", combatant.name +
                " already exists in this combat. Continuing will overwrite the current combatant."
            )
            if proceed:
                for frame in self.combatant_frames:
                    if frame.combatant.name == combatant.name:
                        self.combatant_frames.remove(frame)
                self.combat.combatants.pop(combatant.name)

        if proceed:
            self.combat.add_combatant(combatant)
            new_frame = combatantframe.CombatantFrame(
                self, self.combat, self.combat.combatants[combatant.name])
            if self.combat.num_of_combatants == 1:
                new_frame.grid(row=1, column=0, columnspan=4)
            else:
                new_frame.grid(column=0, columnspan=4)
            self.combatant_frames.append(new_frame)

        self.update_target_lists()

        v.p(verbose_msg, "Combatant loaded: " + combatant.name)
        self.combat_log_msg.grid(rowspan=len(self.combatant_frames) + 1)
コード例 #11
0
 def update_targets(self):
     v.p(verbose_msg,
         "      Updating Targets in " + self.combatant.name + "'s frame.")
     self.choose_actions_ntbk.attack_frame.update_targets_list()
     self.choose_actions_ntbk.cast_spell_frame.update_targets_list()
コード例 #12
0
    def begin_combat(self):
        for item in self.combatant_frames:
            action_num = item.choose_actions_ntbk.index(
                item.choose_actions_ntbk.select())
            action_desc = self.action_dict[action_num]
            parameters = {}

            # if action is an attack
            if action_num == 0:
                target = item.choose_actions_ntbk.attack_frame.target.get()
                parameters['target'] = self.combat.get_combatant(target)
                parameters['attack'] = item.combatant.get_attack(
                    item.choose_actions_ntbk.attack_frame.attack.get())
                parameters[
                    'parry_percentage'] = item.choose_actions_ntbk.attack_frame.parry_percentage.get(
                    )
                target_text = " " + target + " with a " + item.choose_actions_ntbk.attack_frame.attack.get(
                )
                log_message = item.combatant.name + " " + action_desc + target_text
                action = attackaction.AttackAction(self.combat, item.combatant,
                                                   self.combat.time,
                                                   action_num, parameters,
                                                   log_message)

            # if action is a spell cast
            elif action_num == 1:
                target = item.choose_actions_ntbk.cast_spell_frame.target.get()

                if target and target != "None":
                    parameters['target'] = self.combat.get_combatant(target)
                else:
                    parameters['target'] = None

                spell_to_cast = spell.Spell(
                    item.choose_actions_ntbk.cast_spell_frame.spell_list.get(),
                    item.choose_actions_ntbk.cast_spell_frame.spell_level.get(
                    ))
                parameters['spell'] = spell_to_cast
                target_text = " at " + target
                log_message = item.combatant.name + " " + action_desc + target_text

                action = castspellaction.CastSpellAction(
                    self.combat, item.combatant, self.combat.time, action_num,
                    parameters, log_message)

            elif action_num == 2:
                parameters[
                    'pace'] = item.choose_actions_ntbk.move_frame.pace.get()
                log_message = item.combatant.name + " " + action_desc

                action = moveaction.MoveAction(self.combat, item.combatant,
                                               self.combat.time, action_num,
                                               parameters, log_message)

            elif action_num == 3:
                parameters = []
                log_message = item.combatant.name + " " + action_desc

                action = performskillaction.PerformSkillAction(
                    self.combat, item.combatant, self.combat.time, action_num,
                    parameters, log_message)

            else:
                raise (NotImplementedError,
                       "This action type is not implemented yet.")

            self.combat.add_action(action)
            item.combatant.current_action = action
            v.p(
                verbose_msg, "Action put in list: " + action.log_message +
                " at time " + str(action.end_time))

        prior_log_length = len(self.combat.log)

        # Call the routine to carry out the actions
        self.combat.act()

        for item in self.combatant_frames:
            item.update_info()

        for i in range(prior_log_length, len(self.combat.log)):
            self.combat_log_msg.insert(tk.END, self.combat.log[i])
コード例 #13
0
    def resolve_attack(self, action):
        roll = dice.oehighroll()
        table = self.attack_tables[action.attack_table]
        if roll <= table.fumble:
            v.p(verbose_msg, "Attack roll is fumbled: " + str(roll))
            self.add_to_log(action.combatant.name + " fumbled the attack.")
        else:
            penalties = self.calc_penalties(action.combatant.hits,
                                            action.combatant.max_hits,
                                            action.combatant.exhpts,
                                            action.combatant.max_exhpts)
            if action.target.current_action.action_type == 0 and \
                            action.target.current_action.target == action.combatant:
                target_parry = action.target.current_action.parry_DB
            else:
                target_parry = 0

            if action.attack_ranged:
                # need to deal with parrying ranged attacks
                adjusted_roll = roll + action.attack_OB + penalties[
                    0] - action.target.DB_ranged
            else:
                adjusted_roll = roll + action.attack_OB + penalties[
                    0] - action.target.DB_melee - target_parry

            v.p(
                verbose_msg, "Roll: " + str(roll) + "OB: " +
                str(action.attack_OB) + " Pen: " + str(penalties[0]) +
                " DBs: " + str(action.target.DB_melee) + "/" +
                str(action.target.DB_ranged) + " Parried by: " +
                str(target_parry) + " Final: " + str(adjusted_roll))

            for item in table.results:
                if adjusted_roll < int(item[0]):
                    pass
                else:
                    result = item[22 - action.target.AT]
                    v.p(verbose_msg, "Attack result: " + result)
                    if result == "-":
                        self.add_to_log(action.combatant.name + " missed " +
                                        action.target.name)
                    else:
                        if result[len(result) - 1].isdigit():
                            damage = int(result)
                            self.add_to_log(action.combatant.name + " did " +
                                            str(damage) + " hits to " +
                                            action.target.name)
                        else:
                            i = 0
                            while result[i].isdigit():
                                i += 1
                            damage = int(result[0:i])
                            critical_level = result[i:]
                            self.add_to_log(action.combatant.name + " did " +
                                            str(damage) + " hits and a " +
                                            critical_level + " critical to " +
                                            action.target.name)

                            critical_table = self.critical_tables[
                                self.attack_tables[
                                    action.attack_table].critical_type]
                            critical_column = critical_table.columns[
                                critical_level]
                            i = 0
                            critical_roll = dice.Dice.d100()
                            while critical_column[i][2] < critical_roll:
                                i += 1
                            crit = critical_column[i]
                            log_message = "Crit: " + str(
                                critical_roll) + " " + crit[3] + "\n   "

                            #Next four lines are for testing purposes:
                            crit[8] = "1~0"
                            crit[7] = "2~0"
                            crit[6] = "1~0"

                            if crit[4] != 0:
                                damage += crit[4]
                                log_message = log_message + " Hits: " + str(
                                    crit[4])
                            if crit[5] != 0:
                                rtrigger = trigger.Trigger(
                                    "Bleeding", action.target, self.time + 10,
                                    {"damage": crit[5]})
                                self.add_recurring_trigger(rtrigger)
                                log_message = log_message + " Bleeding: " + str(
                                    crit[5])
                            if crit[8] != "0~0":
                                snp = crit[8].split("~")
                                num_of_rounds = int(snp[0])
                                penalty = int(snp[1])
                                stun_duration = 0
                                if action.target.stun_no_parry_ends_at > self.time:
                                    end_time = action.target.stun_no_parry_ends_at + 10 * num_of_rounds
                                    for i in self.trigger_list[
                                            action.target.
                                            stun_no_parry_ends_at]:
                                        if i.name == "Stun No Parry" and i.target == action.target:
                                            self.trigger_list[
                                                action.target.
                                                stun_no_parry_ends_at].remove(
                                                    i)
                                    if action.target.stun_ends_at > action.target.stun_no_parry_ends_at:
                                        stun_duration = action.target.stun_ends_at - action.target.stun_no_parry_ends_at
                                        for i in self.trigger_list[
                                                action.target.stun_ends_at]:
                                            if i.name == "Stun" and i.target == action.target:
                                                self.trigger_list[
                                                    action.target.
                                                    stun_ends_at].remove(i)
                                else:
                                    end_time = self.time + 10 * num_of_rounds
                                    if action.target.stun_ends_at > self.time:
                                        stun_duration = action.target.stun_ends_at - self.time
                                action.target.stun_no_parry_ends_at = end_time
                                action.target.stun_ends_at = end_time + stun_duration
                                trig = trigger.Trigger("Stun No Parry",
                                                       action.target, end_time)
                                self.add_trigger(trig)
                                log_message = log_message + " Stun No Parry: " + snp[
                                    0]
                            if crit[7] != "0~0":
                                snp = crit[7].split("~")
                                num_of_rounds = int(snp[0])
                                penalty = int(snp[1])
                                must_parry_duration = 0
                                if action.target.stun_ends_at > self.time:
                                    end_time = action.target.stun_ends_at + 10 * num_of_rounds
                                    for i in self.trigger_list[
                                            action.target.stun_ends_at]:
                                        if i.name == "Stun" and i.target == action.target:
                                            self.trigger_list[
                                                action.target.
                                                stun_ends_at].remove(i)
                                    if action.target.must_parry_ends_at > action.target.stun_ends_at:
                                        must_parry_duration = action.target.must_parry_ends_at - action.target.stun_ends_at
                                        for i in self.trigger_list[
                                                action.target.
                                                must_parry_ends_at]:
                                            if i.name == "Must Parry" and i.target == action.target:
                                                self.trigger_list[
                                                    action.target.
                                                    must_parry_ends_at].remove(
                                                        i)
                                else:
                                    end_time = self.time + 10 * num_of_rounds
                                    if action.target.must_parry_ends_at > self.time:
                                        must_parry_duration = action.target.must_parry_ends_at - self.time
                                action.target.stun_ends_at = end_time
                                action.target.must_parry_ends_at = end_time + must_parry_duration
                                trig = trigger.Trigger("Stun", action.target,
                                                       end_time)
                                self.add_trigger(trig)
                                log_message = log_message + " Stunned: " + snp[
                                    0]
                            if crit[6] != "0~0":
                                snp = crit[6].split("~")
                                num_of_rounds = int(snp[0])
                                penalty = int(snp[1])
                                initiative_loss_duration = 0
                                if action.target.must_parry_ends_at > self.time:
                                    end_time = action.target.must_parry_ends_at + 10 * num_of_rounds
                                    for i in self.trigger_list[
                                            action.target.must_parry_ends_at]:
                                        if i.name == "Must Parry" and i.target == action.target:
                                            self.trigger_list[
                                                action.target.
                                                must_parry_ends_at].remove(i)
                                    if action.target.initiative_loss_ends_at > action.target.must_parry_ends_at:
                                        initiative_loss_duration = action.target.initiative_loss_ends_at - action.target.must_parry_ends_at
                                        for i in self.trigger_list[
                                                action.target.
                                                initiative_loss_ends_at]:
                                            if i.name == "Initiative Loss" and i.target == action.target:
                                                self.trigger_list[
                                                    action.target.
                                                    initiative_loss_ends_at].remove(
                                                        i)
                                else:
                                    end_time = self.time + 10 * num_of_rounds
                                    if action.target.initiative_loss_ends_at > self.time:
                                        initiative_loss_duration = action.target.initiative_loss_ends_at - self.time
                                action.target.must_parry_ends_at = end_time
                                action.target.initiative_loss_ends_at = end_time + initiative_loss_duration
                                trig = trigger.Trigger("Must Parry",
                                                       action.target, end_time)
                                self.add_trigger(trig)
                                log_message = log_message + " Must Parry: " + snp[
                                    0]

                            self.add_to_log(log_message)
                        action.target.hits += -damage
                        action.target.update_status()
                    break
コード例 #14
0
 def add_combatant(self, guy):
     if guy.name not in self.combatants:
         self.combatants[guy.name] = guy
     else:
         raise NameError('Another combatant already has this name.')
     v.p(verbose_msg, "Added combatant: " + guy.name)