Most of the magic system is now in place.
Showing
4 changed files
with
412 additions
and
119 deletions
... | @@ -67,6 +67,7 @@ def db_buy_ticket(member_id, amount): | ... | @@ -67,6 +67,7 @@ def db_buy_ticket(member_id, amount): |
67 | return True, int(credits[1]) + int(amount) | 67 | return True, int(credits[1]) + int(amount) |
68 | except Exception as e: | 68 | except Exception as e: |
69 | log(e) | 69 | log(e) |
70 | |||
70 | def db_update_credit(member_id, amount): | 71 | def db_update_credit(member_id, amount): |
71 | conn = sqlite3.connect('db.sqlite3') | 72 | conn = sqlite3.connect('db.sqlite3') |
72 | c = conn.cursor() | 73 | c = conn.cursor() |
... | @@ -168,7 +169,6 @@ def db_get_fortune(): | ... | @@ -168,7 +169,6 @@ def db_get_fortune(): |
168 | try: | 169 | try: |
169 | conn = sqlite3.connect('db.sqlite3') | 170 | conn = sqlite3.connect('db.sqlite3') |
170 | c = conn.cursor() | 171 | c = conn.cursor() |
171 | # TODO: Move this shit to data | ||
172 | return c.execute("SELECT fortune FROM fortunes ORDER BY RANDOM() LIMIT 1;").fetchone()[0] | 172 | return c.execute("SELECT fortune FROM fortunes ORDER BY RANDOM() LIMIT 1;").fetchone()[0] |
173 | finally: | 173 | finally: |
174 | conn.close() | 174 | conn.close() |
... | @@ -192,7 +192,6 @@ def db_get_fortune(): | ... | @@ -192,7 +192,6 @@ def db_get_fortune(): |
192 | try: | 192 | try: |
193 | conn = sqlite3.connect('db.sqlite3') | 193 | conn = sqlite3.connect('db.sqlite3') |
194 | c = conn.cursor() | 194 | c = conn.cursor() |
195 | # TODO: Move this shit to data | ||
196 | return c.execute("SELECT fortune FROM fortunes ORDER BY RANDOM() LIMIT 1;").fetchone()[0] | 195 | return c.execute("SELECT fortune FROM fortunes ORDER BY RANDOM() LIMIT 1;").fetchone()[0] |
197 | finally: | 196 | finally: |
198 | conn.close() | 197 | conn.close() | ... | ... |
No preview for this file type
... | @@ -27,7 +27,7 @@ import wolframalpha | ... | @@ -27,7 +27,7 @@ import wolframalpha |
27 | import sqlite3 | 27 | import sqlite3 |
28 | from blackjack import Blackjack | 28 | from blackjack import Blackjack |
29 | import data | 29 | import data |
30 | from pankration import Pankration, HuntResponse, Jobs, Action, MissAction, AttackAction, DefeatAction, TemperamentPosture, TemperamentAttitude | 30 | from pankration import Pankration, HuntResponse, Jobs, Action, MagicResistAction, MissAction, AttackAction, DefeatAction, TemperamentPosture, TemperamentAttitude |
31 | 31 | ||
32 | VERSION = 2.3 | 32 | VERSION = 2.3 |
33 | 33 | ||
... | @@ -1203,7 +1203,7 @@ def do_hunt_monster(client, message_parts, message): | ... | @@ -1203,7 +1203,7 @@ def do_hunt_monster(client, message_parts, message): |
1203 | if not result: | 1203 | if not result: |
1204 | send_message(client, message.author, error_message) | 1204 | send_message(client, message.author, error_message) |
1205 | return | 1205 | return |
1206 | send_message(client, message.channel, 'Soul Plate purchased for {} credits\n Hunting in {}'.format(cost, zone)) | 1206 | send_message(client, message.channel, '{} Soul Plate purchased for {} credits\n Hunting in {}'.format(message.author.name, cost, zone)) |
1207 | time.sleep(3) | 1207 | time.sleep(3) |
1208 | hunt_response = p.hunt_monster(' '.join(message_parts)) | 1208 | hunt_response = p.hunt_monster(' '.join(message_parts)) |
1209 | str_out = hunt_response.message + "\n\n" | 1209 | str_out = hunt_response.message + "\n\n" |
... | @@ -1212,7 +1212,7 @@ def do_hunt_monster(client, message_parts, message): | ... | @@ -1212,7 +1212,7 @@ def do_hunt_monster(client, message_parts, message): |
1212 | member = data.db_get_member(message.author.id) | 1212 | member = data.db_get_member(message.author.id) |
1213 | data.db_add_soul_plate(member['member_id'], soul_plate) | 1213 | data.db_add_soul_plate(member['member_id'], soul_plate) |
1214 | str_out += str(soul_plate.get_soul_plate_description()) | 1214 | str_out += str(soul_plate.get_soul_plate_description()) |
1215 | send_message(client, message.channel, str_out) | 1215 | send_message(client, message.channel, "{} {}".format(message.author.name, str_out)) |
1216 | 1216 | ||
1217 | 1217 | ||
1218 | def do_list_zones(client, message_parts, message): | 1218 | def do_list_zones(client, message_parts, message): |
... | @@ -1271,12 +1271,20 @@ def check_arena(): | ... | @@ -1271,12 +1271,20 @@ def check_arena(): |
1271 | time.sleep(4) | 1271 | time.sleep(4) |
1272 | out_str = "" | 1272 | out_str = "" |
1273 | for action in actions: | 1273 | for action in actions: |
1274 | # TODO: Decide if I should merge magicresistaction with miss action | ||
1275 | if isinstance(action, MagicResistAction): | ||
1276 | out_str += "{} {} {} while casting {}.\n".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name(), action.spell) | ||
1274 | if isinstance(action, MissAction): | 1277 | if isinstance(action, MissAction): |
1275 | out_str += "{} {} {}.\n".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name()) | 1278 | if action.spell: |
1279 | out_str += "{} {} {} while casting {}.\n".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name(), action.spell) | ||
1280 | else: | ||
1281 | out_str += "{} {} {}.\n".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name()) | ||
1276 | if isinstance(action, AttackAction): | 1282 | if isinstance(action, AttackAction): |
1277 | out_str += "{} {} {} for {}.\n".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name(), int(action.damage)) | 1283 | if action.spell: |
1284 | out_str += "{} {} {} against {} for {}.\n".format(action.attacker.get_monster_name(), action.message, action.spell, action.target.get_monster_name(), int(action.damage)) | ||
1285 | else: | ||
1286 | out_str += "{} {} {} for {}.\n".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name(), int(action.damage)) | ||
1278 | if isinstance(action, DefeatAction): | 1287 | if isinstance(action, DefeatAction): |
1279 | |||
1280 | out_str += "\n\n**{}** {}. {} gains {} xp.\n\n".format(action.target.get_monster_name(), action.message, action.attacker.get_monster_name(), action.xp) | 1288 | out_str += "\n\n**{}** {}. {} gains {} xp.\n\n".format(action.target.get_monster_name(), action.message, action.attacker.get_monster_name(), action.xp) |
1281 | fighting = False | 1289 | fighting = False |
1282 | if action.attacker == monster: | 1290 | if action.attacker == monster: |
... | @@ -1294,7 +1302,8 @@ def check_arena(): | ... | @@ -1294,7 +1302,8 @@ def check_arena(): |
1294 | monster2.wins += 1 | 1302 | monster2.wins += 1 |
1295 | monster.losses += 1 | 1303 | monster.losses += 1 |
1296 | break | 1304 | break |
1297 | out_str += "\n{} {}% - {} {}%\n".format(monster.get_monster_name(), monster.get_hp_percent(), monster2.get_monster_name(), monster2.get_hp_percent()) | 1305 | if fighting: |
1306 | out_str += "\n{} {}% - {} {}%\n".format(monster.get_monster_name(), monster.get_hp_percent(), monster2.get_monster_name(), monster2.get_hp_percent()) | ||
1298 | log(out_str) | 1307 | log(out_str) |
1299 | send_message(client, arena_channel, byteify(out_str)) | 1308 | send_message(client, arena_channel, byteify(out_str)) |
1300 | # Heal the monsters before they are returned to the player inventory | 1309 | # Heal the monsters before they are returned to the player inventory | ... | ... |
... | @@ -87,29 +87,30 @@ class Jobs: | ... | @@ -87,29 +87,30 @@ class Jobs: |
87 | members = [attr for attr in dir(Jobs()) if not callable(attr) and not attr.startswith("__") and not attr.startswith("get_job_name")] | 87 | members = [attr for attr in dir(Jobs()) if not callable(attr) and not attr.startswith("__") and not attr.startswith("get_job_name")] |
88 | return members[job-1] | 88 | return members[job-1] |
89 | 89 | ||
90 | evasion_by_job = { | 90 | # MP Per level is actually the amount added to the multiplier per level for the mp base for that monster. |
91 | Jobs.BLM: {'base_eva': 4, 'eva_per_level': 2.48}, | 91 | adjustments_by_job = { |
92 | Jobs.BLU: {'base_eva': 5, 'eva_per_level': 2.78}, | 92 | Jobs.BLM: {'base_eva': 4, 'eva_per_level': 2.48, 'mp_per_level': 0.3}, |
93 | Jobs.BRD: {'base_eva': 4, 'eva_per_level': 2.66}, | 93 | Jobs.BLU: {'base_eva': 5, 'eva_per_level': 2.78, 'mp_per_level': 0.15}, |
94 | Jobs.BST: {'base_eva': 5, 'eva_per_level': 2.78}, | 94 | Jobs.BRD: {'base_eva': 4, 'eva_per_level': 2.66, 'mp_per_level': 0}, |
95 | Jobs.COR: {'base_eva': 4, 'eva_per_level': 2.66}, | 95 | Jobs.BST: {'base_eva': 5, 'eva_per_level': 2.78, 'mp_per_level': 0}, |
96 | Jobs.DNC: {'base_eva': 5, 'eva_per_level': 2.88}, | 96 | Jobs.COR: {'base_eva': 4, 'eva_per_level': 2.66, 'mp_per_level': 0}, |
97 | Jobs.DRG: {'base_eva': 5, 'eva_per_level': 2.88}, | 97 | Jobs.DNC: {'base_eva': 5, 'eva_per_level': 2.88, 'mp_per_level': 0}, |
98 | Jobs.DRK: {'base_eva': 5, 'eva_per_level': 2.78}, | 98 | Jobs.DRG: {'base_eva': 5, 'eva_per_level': 2.88, 'mp_per_level': 0}, |
99 | Jobs.GEO: {'base_eva': 4, 'eva_per_level': 2.66}, | 99 | Jobs.DRK: {'base_eva': 5, 'eva_per_level': 2.78, 'mp_per_level': 0.1}, |
100 | Jobs.MNK: {'base_eva': 5, 'eva_per_level': 2.88}, | 100 | Jobs.GEO: {'base_eva': 4, 'eva_per_level': 2.66, 'mp_per_level': 0}, |
101 | Jobs.NIN: {'base_eva': 6, 'eva_per_level': 3}, | 101 | Jobs.MNK: {'base_eva': 5, 'eva_per_level': 2.88, 'mp_per_level': 0}, |
102 | Jobs.PLD: {'base_eva': 5, 'eva_per_level': 2.78}, | 102 | Jobs.NIN: {'base_eva': 6, 'eva_per_level': 3, 'mp_per_level': 0}, |
103 | Jobs.PUP: {'base_eva': 5, 'eva_per_level': 2.88}, | 103 | Jobs.PLD: {'base_eva': 5, 'eva_per_level': 2.78, 'mp_per_level': 0.1}, |
104 | Jobs.RDM: {'base_eva': 4, 'eva_per_level': 2.66}, | 104 | Jobs.PUP: {'base_eva': 5, 'eva_per_level': 2.88, 'mp_per_level': 0}, |
105 | Jobs.RNG: {'base_eva': 4, 'eva_per_level': 2.48}, | 105 | Jobs.RDM: {'base_eva': 4, 'eva_per_level': 2.66, 'mp_per_level': 0.15}, |
106 | Jobs.RUN: {'base_eva': 5, 'eva_per_level': 2.88}, | 106 | Jobs.RNG: {'base_eva': 4, 'eva_per_level': 2.48, 'mp_per_level': 0}, |
107 | Jobs.SAM: {'base_eva': 5, 'eva_per_level': 2.88}, | 107 | Jobs.RUN: {'base_eva': 5, 'eva_per_level': 2.88, 'mp_per_level': 0.1}, |
108 | Jobs.SCH: {'base_eva': 4, 'eva_per_level': 2.48}, | 108 | Jobs.SAM: {'base_eva': 5, 'eva_per_level': 2.88, 'mp_per_level': 0}, |
109 | Jobs.SMN: {'base_eva': 4, 'eva_per_level': 2.48}, | 109 | Jobs.SCH: {'base_eva': 4, 'eva_per_level': 2.48, 'mp_per_level': 0.15}, |
110 | Jobs.THF: {'base_eva': 6, 'eva_per_level': 3}, | 110 | Jobs.SMN: {'base_eva': 4, 'eva_per_level': 2.48, 'mp_per_level': 0.4}, |
111 | Jobs.WAR: {'base_eva': 5, 'eva_per_level': 2.78}, | 111 | Jobs.THF: {'base_eva': 6, 'eva_per_level': 3, 'mp_per_level': 0}, |
112 | Jobs.WHM: {'base_eva': 4, 'eva_per_level': 2.48}, | 112 | Jobs.WAR: {'base_eva': 5, 'eva_per_level': 2.78, 'mp_per_level': 0}, |
113 | Jobs.WHM: {'base_eva': 4, 'eva_per_level': 2.48, 'mp_per_level': 0.2}, | ||
113 | } | 114 | } |
114 | 115 | ||
115 | TemperamentPosture = { | 116 | TemperamentPosture = { |
... | @@ -143,6 +144,78 @@ FeralSkills = { | ... | @@ -143,6 +144,78 @@ FeralSkills = { |
143 | 'Magic Barrier': {'type': 'Magical', 'sub_type': 'Dark', 'mp_cost': 29, 'shadows': 'absorb', 'range': None, 'aoe': True}, | 144 | 'Magic Barrier': {'type': 'Magical', 'sub_type': 'Dark', 'mp_cost': 29, 'shadows': 'absorb', 'range': None, 'aoe': True}, |
144 | 'Sinker Drill': {'type': 'Physical', 'sub_type': 'Piercing', 'shadows': 'absorb', 'range': None, 'aoe': False}, | 145 | 'Sinker Drill': {'type': 'Physical', 'sub_type': 'Piercing', 'shadows': 'absorb', 'range': None, 'aoe': False}, |
145 | } | 146 | } |
147 | |||
148 | class Spells: | ||
149 | SpellTypes = { | ||
150 | 't1': {'multiplier': 1.0, 'earth': 10, 'water': 16, 'wind': 25, 'fire': 35, 'ice': 46, 'thunder': 60, 'dark': 0, 'light': 14}, | ||
151 | 't2': {'multiplier': 1.0, 'earth': 78, 'water': 95, 'wind': 113, 'fire': 133, 'ice': 155, 'thunder': 178, 'dark': 0, 'light': 85}, | ||
152 | 't3': {'multiplier': 1.5, 'earth': 210, 'water': 236, 'wind': 265, 'fire': 295, 'ice': 320, 'thunder': 345, 'dark': 0, 'light': 198}, | ||
153 | 't4': {'multiplier': 2.0, 'earth': 381, 'water': 410, 'wind': 440, 'fire': 472, 'ice': 506, 'thunder': 541, 'dark': 0, 'light': 0}, | ||
154 | 't5': {'multiplier': 2.299, 'earth': 626, 'water': 680, 'wind': 738, 'fire': 785, 'ice': 828, 'thunder': 874, 'dark': 963, 'light': 0}, | ||
155 | 't1-ga': {'multiplier': 1.0, 'earth': 56, 'water': 74, 'wind': 93, 'fire': 120, 'ice': 145, 'thunder': 172, 'dark': 0, 'light': 50}, | ||
156 | 't2-ga-a': {'multiplier': 1.0, 'earth': 201, 'water': 232, 'wind': 266, 'fire': 312, 'ice': 350, 'thunder': 392, 'dark': 0, 'light': 180}, | ||
157 | 't2-ga-b': {'multiplier': 1.5, 'earth': 201, 'water': 232, 'wind': 266, 'fire': 312, 'ice': 350, 'thunder': 392, 'dark': 0, 'light': 180}, | ||
158 | 't3-ga': {'multiplier': 1.5, 'earth': 434, 'water': 480, 'wind': 527, 'fire': 589, 'ice': 642, 'thunder': 697, 'dark': 0, 'light': 0}, | ||
159 | 'ja': {'multiplier': 1.0, 'earth': 719, 'water': 782, 'wind': 844, 'fire': 902, 'ice': 953, 'thunder': 1004, 'dark': 0, 'light': 0}, | ||
160 | 't1-ra': {'multiplier': 1.0, 'earth': 128, 'water': 153, 'wind': 179, 'fire': 216, 'ice': 247, 'thunder': 282, 'dark': 0, 'light': 0}, | ||
161 | 't2-ra-a': {'multiplier': 1.0, 'earth': 317, 'water': 356, 'wind': 396, 'fire': 450, 'ice': 496, 'thunder': 544, 'dark': 0, 'light': 0}, | ||
162 | 't2-ra-b': {'multiplier': 1.5, 'earth': 317, 'water': 356, 'wind': 396, 'fire': 450, 'ice': 496, 'thunder': 544, 'dark': 0, 'light': 0}, | ||
163 | 't1-am': {'multiplier': 2.0, 'earth': 577, 'water': 630, 'wind': 552, 'fire': 657, 'ice': 526, 'thunder': 603, 'dark': 939, 'light': 125}, | ||
164 | 't2-am': {'multiplier': 2.0, 'earth': 710, 'water': 710, 'wind': 710, 'fire': 710, 'ice': 710, 'thunder': 710, 'dark': 0, 'light': 0}, | ||
165 | 'helix': {'multiplier': 1.0, 'earth': 25, 'water': 25, 'wind': 25, 'fire': 25, 'ice': 25, 'thunder': 25, 'dark': 25, 'light': 25}, | ||
166 | 'ichi': {'multiplier': 1.0, 'earth': 10, 'water': 10, 'wind': 10, 'fire': 10, 'ice': 10, 'thunder': 10, 'dark': 0, 'light': 0}, | ||
167 | 'ni': {'multiplier': 1.0, 'earth': 78, 'water': 78, 'wind': 78, 'fire': 78, 'ice': 78, 'thunder': 78, 'dark': 0, 'light': 0}, | ||
168 | 'san': {'multiplier': 1.5, 'earth': 78, 'water': 78, 'wind': 78, 'fire': 78, 'ice': 78, 'thunder': 78, 'dark': 0, 'light': 0}, | ||
169 | } | ||
170 | |||
171 | # TODO: Finish jobs listing for each spell. | ||
172 | SpellList = { | ||
173 | 'Stone': {'mp_cost': 4, 'casting_time': 0.5, 'recast_time': 2, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'earth', 'jobs': {Jobs.BLM: 1, Jobs.RDM: 4, Jobs.SCH: 4, Jobs.GEO: 4, Jobs.DRK: 5, Jobs.PUP: 5} }, | ||
174 | 'Water': {'mp_cost': 5, 'casting_time': 0.5, 'recast_time': 2, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'water', 'jobs': {Jobs.BLM: 5, Jobs.SCH: 8, Jobs.RDM: 9, Jobs.GEO: 9, Jobs.PUP: 10, Jobs.DRK: 11} }, | ||
175 | 'Aero': {'mp_cost': 6, 'casting_time': 0.5, 'recast_time': 2, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'wind', 'jobs': {Jobs.BLM: 9, Jobs.SCH: 12, Jobs.RDM: 14, Jobs.PUP: 15, Jobs.DRK: 17} }, | ||
176 | 'Fire': {'mp_cost': 7, 'casting_time': 0.5, 'recast_time': 2, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'fire', 'jobs': {Jobs.BLM: 13, Jobs.SCH: 16, Jobs.RDM: 19, Jobs.GEO: 19, Jobs.PUP: 20, Jobs.DRK: 23} }, | ||
177 | 'Blizzard': {'mp_cost': 8, 'casting_time': 0.5, 'recast_time': 2, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'ice', 'jobs': {Jobs.BLM: 17, Jobs.SCH: 20, Jobs.RDM: 24, Jobs.PUP: 24, Jobs.DRK: 29} }, | ||
178 | 'Thunder': {'mp_cost': 9, 'casting_time': 0.5, 'recast_time': 2, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'lightning', 'jobs': {Jobs.BLM: 21, Jobs.SCH: 24, Jobs.RDM: 29, Jobs.PUP: 29, Jobs.DRK: 35} }, | ||
179 | 'Banish': {'mp_cost': 15, 'casting_time': 3, 'recast_time': 14, 'magic_acc_stat': 'mnd', 'spell_type': 't1', 'damage_type': 'light', 'jobs': {Jobs.WHM: 5, Jobs.PLD: 7} }, | ||
180 | 'Stone II': {'mp_cost': 16, 'casting_time': 1.5, 'recast_time': 6, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'earth', 'jobs': {Jobs.BLM: 26, Jobs.SCH: 30, Jobs.RDM: 35, Jobs.DRK: 42, Jobs.PUP: 35} }, | ||
181 | 'Water II': {'mp_cost': 19, 'casting_time': 1.5, 'recast_time': 6, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'water', 'jobs': {Jobs.BLM: 30, Jobs.SCH: 34, Jobs.RDM: 40, Jobs.PUP: 40, Jobs.DRK: 48} }, | ||
182 | 'Aero II': {'mp_cost': 22, 'casting_time': 1.5, 'recast_time': 6, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'wind', 'jobs': {Jobs.BLM: 34, Jobs.SCH: 38, Jobs.RDM: 45, Jobs.PUP: 45, Jobs.DRK: 54} }, | ||
183 | 'Fire II': {'mp_cost': 26, 'casting_time': 1.5, 'recast_time': 6, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'fire', 'jobs': {Jobs.BLM: 38, Jobs.SCH: 42, Jobs.RDM: 50, Jobs.PUP: 50, Jobs.DRK: 60} }, | ||
184 | 'Blizzard II': {'mp_cost': 31, 'casting_time': 1.5, 'recast_time': 6, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'ice', 'jobs': {Jobs.BLM: 42, Jobs.SCH: 46, Jobs.RDM: 55, Jobs.PUP: 55, Jobs.DRK: 66} }, | ||
185 | 'Thunder II': {'mp_cost': 37, 'casting_time': 1.5, 'recast_time': 6, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'lightning', 'jobs': {Jobs.BLM: 46, Jobs.SCH: 51, Jobs.RDM: 60, Jobs.PUP: 60, Jobs.DRK: 72} }, | ||
186 | 'Banish II': {'mp_cost': 57, 'casting_time': 2.5, 'recast_time': 21, 'magic_acc_stat': 'mnd', 'spell_type': 't1', 'damage_type': 'light', 'jobs': {Jobs.WHM: 30, Jobs.PLD: 34} }, | ||
187 | 'Stone III': {'mp_cost': 40, 'casting_time': 3, 'recast_time': 15, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'earth', 'jobs': {Jobs.BLM: 51, Jobs.SCH: 54, Jobs.RDM: 65, Jobs.DRK: 76, Jobs.PUP: 65} }, | ||
188 | 'Water III': {'mp_cost': 46, 'casting_time': 3, 'recast_time': 15, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'water', 'jobs': {Jobs.BLM: 55, Jobs.SCH: 57, Jobs.RDM: 67, Jobs.PUP: 67, Jobs.DRK: 80} }, | ||
189 | 'Aero III': {'mp_cost': 54, 'casting_time': 3, 'recast_time': 15, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'wind', 'jobs': {Jobs.BLM: 59, Jobs.SCH: 60, Jobs.RDM: 69, Jobs.PUP: 69, Jobs.DRK: 84} }, | ||
190 | 'Fire III': {'mp_cost': 63, 'casting_time': 3, 'recast_time': 15, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'fire', 'jobs': {Jobs.BLM: 62, Jobs.SCH: 63, Jobs.RDM: 71, Jobs.PUP: 70, Jobs.DRK: 88} }, | ||
191 | 'Blizzard III': {'mp_cost': 75, 'casting_time': 3, 'recast_time': 15, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'ice', 'jobs': {Jobs.BLM: 64, Jobs.SCH: 66, Jobs.RDM: 73, Jobs.PUP: 71, Jobs.DRK: 92} }, | ||
192 | 'Thunder III': {'mp_cost': 91, 'casting_time': 3, 'recast_time': 15, 'magic_acc_stat': 'int', 'spell_type': 't1', 'damage_type': 'lightning', 'jobs': {Jobs.BLM: 66, Jobs.SCH: 69, Jobs.RDM: 75, Jobs.PUP: 72, Jobs.DRK: 96} }, | ||
193 | 'Banish III': {'mp_cost': 96, 'casting_time': 3, 'recast_time': 45, 'magic_acc_stat': 'mnd', 'spell_type': 't1', 'damage_type': 'light', 'jobs': {Jobs.WHM: 65} }, | ||
194 | } | ||
195 | |||
196 | def get_spell_list(self, level, job = None, sub_job = None): | ||
197 | available_spells = [] | ||
198 | for spell_name, spell in self.SpellList.iteritems(): | ||
199 | if job and job in spell['jobs'] and spell['jobs'][job] <= level: | ||
200 | if spell_name not in available_spells: | ||
201 | available_spells.append(spell_name) | ||
202 | if sub_job and sub_job in spell['jobs'] and spell['jobs'][sub_job] <= level / 2: | ||
203 | if spell_name not in available_spells: | ||
204 | available_spells.append(spell_name) | ||
205 | return sorted(available_spells) | ||
206 | |||
207 | def get_spell_data(self, spell): | ||
208 | spell = self.SpellList[spell] | ||
209 | type_data = self.SpellTypes[spell['spell_type']] | ||
210 | spell_data = { | ||
211 | 'type': type_data, | ||
212 | 'magic_acc_stat': spell['magic_acc_stat'], | ||
213 | 'base_damage': type_data[spell['damage_type']], | ||
214 | 'multiplier': type_data['multiplier'], | ||
215 | 'mp_cost': spell['mp_cost'] | ||
216 | } | ||
217 | return spell_data | ||
218 | |||
146 | Families = { | 219 | Families = { |
147 | 'acrolith': { | 220 | 'acrolith': { |
148 | 'base_fp': 50, | 221 | 'base_fp': 50, |
... | @@ -151,6 +224,7 @@ Families = { | ... | @@ -151,6 +224,7 @@ Families = { |
151 | 'available_main_job': [Jobs.WAR, Jobs.DRG, Jobs.DRK, Jobs.PLD], | 224 | 'available_main_job': [Jobs.WAR, Jobs.DRG, Jobs.DRK, Jobs.PLD], |
152 | 'available_support_job': [Jobs.WAR, Jobs.DRG, Jobs.DRK, Jobs.PLD], | 225 | 'available_support_job': [Jobs.WAR, Jobs.DRG, Jobs.DRK, Jobs.PLD], |
153 | 'innate_feral_skills': ['Sinker Drill', 'Dire Straight', 'Dismemberment', 'Earthshatter'], | 226 | 'innate_feral_skills': ['Sinker Drill', 'Dire Straight', 'Dismemberment', 'Earthshatter'], |
227 | 'target_magic_damage_adjustment': 1.00, | ||
154 | 'type': 'Arcana', | 228 | 'type': 'Arcana', |
155 | 'strong_vs': ['Dark'], | 229 | 'strong_vs': ['Dark'], |
156 | 'charmable': False, | 230 | 'charmable': False, |
... | @@ -168,6 +242,8 @@ Families = { | ... | @@ -168,6 +242,8 @@ Families = { |
168 | 'mnd_per_level': 0.76, | 242 | 'mnd_per_level': 0.76, |
169 | 'base_int': 8, | 243 | 'base_int': 8, |
170 | 'int_per_level': 0.76, | 244 | 'int_per_level': 0.76, |
245 | 'base_chr': 7, | ||
246 | 'chr_per_level': 0.76, | ||
171 | 'temperament_attitude': { | 247 | 'temperament_attitude': { |
172 | 'initial_value': 4, | 248 | 'initial_value': 4, |
173 | 'actions': { | 249 | 'actions': { |
... | @@ -196,6 +272,7 @@ Families = { | ... | @@ -196,6 +272,7 @@ Families = { |
196 | 'innate_feral_skills': ['Binding Wave', 'Magic Barrier', 'Hypnosis', 'Eyes On Me', 'Airy Shield'], | 272 | 'innate_feral_skills': ['Binding Wave', 'Magic Barrier', 'Hypnosis', 'Eyes On Me', 'Airy Shield'], |
197 | 'type': 'Demon', | 273 | 'type': 'Demon', |
198 | 'traits': ['magic defence bonus +25%'], | 274 | 'traits': ['magic defence bonus +25%'], |
275 | 'target_magic_damage_adjustment': 0.75, | ||
199 | 'charmable': False, | 276 | 'charmable': False, |
200 | 'aspir': True, | 277 | 'aspir': True, |
201 | 'drain': True, | 278 | 'drain': True, |
... | @@ -211,6 +288,8 @@ Families = { | ... | @@ -211,6 +288,8 @@ Families = { |
211 | 'mnd_per_level': 0.9066, | 288 | 'mnd_per_level': 0.9066, |
212 | 'base_int': 9, | 289 | 'base_int': 9, |
213 | 'int_per_level': 0.9066, | 290 | 'int_per_level': 0.9066, |
291 | 'base_chr': 8, | ||
292 | 'chr_per_level': 0.84, | ||
214 | 'temperament_attitude': { | 293 | 'temperament_attitude': { |
215 | 'initial_value': 4, | 294 | 'initial_value': 4, |
216 | 'actions': { | 295 | 'actions': { |
... | @@ -237,12 +316,14 @@ Monsters = { | ... | @@ -237,12 +316,14 @@ Monsters = { |
237 | 'family': 'acrolith', | 316 | 'family': 'acrolith', |
238 | 'zone': ['abyssea - uleguerand'], | 317 | 'zone': ['abyssea - uleguerand'], |
239 | 'hp': 20, | 318 | 'hp': 20, |
319 | 'mp': 20, | ||
240 | 'weapon_base_damage': 18 | 320 | 'weapon_base_damage': 18 |
241 | }, | 321 | }, |
242 | 'Floating Eye': { | 322 | 'Floating Eye': { |
243 | 'family': 'ahriman', | 323 | 'family': 'ahriman', |
244 | 'zone': ['ranguemont pass'], | 324 | 'zone': ['ranguemont pass'], |
245 | 'hp': 15, | 325 | 'hp': 15, |
326 | 'mp': 24, | ||
246 | 'weapon_base_damage': 15, | 327 | 'weapon_base_damage': 15, |
247 | 'image_url': 'http://vignette1.wikia.nocookie.net/ffxi/images/9/94/Floating_Eye.JPG/revision/latest?cb=20070704142439' | 328 | 'image_url': 'http://vignette1.wikia.nocookie.net/ffxi/images/9/94/Floating_Eye.JPG/revision/latest?cb=20070704142439' |
248 | }, | 329 | }, |
... | @@ -250,6 +331,7 @@ Monsters = { | ... | @@ -250,6 +331,7 @@ Monsters = { |
250 | 'family': 'ahriman', | 331 | 'family': 'ahriman', |
251 | 'zone': ['ranguemont pass', 'beaucedine glacier'], | 332 | 'zone': ['ranguemont pass', 'beaucedine glacier'], |
252 | 'hp': 15, | 333 | 'hp': 15, |
334 | 'mp': 24, | ||
253 | 'weapon_base_damage': 15, | 335 | 'weapon_base_damage': 15, |
254 | 'image_url': 'http://vignette3.wikia.nocookie.net/ffxi/images/4/40/Bat_Eye.jpg/revision/latest?cb=20060909124134', | 336 | 'image_url': 'http://vignette3.wikia.nocookie.net/ffxi/images/4/40/Bat_Eye.jpg/revision/latest?cb=20060909124134', |
255 | }, | 337 | }, |
... | @@ -257,66 +339,77 @@ Monsters = { | ... | @@ -257,66 +339,77 @@ Monsters = { |
257 | 'family': 'ahriman', | 339 | 'family': 'ahriman', |
258 | 'zone': ['castle zvahl baileys', 'castle zvahl keep', 'xarcabard'], | 340 | 'zone': ['castle zvahl baileys', 'castle zvahl keep', 'xarcabard'], |
259 | 'hp': 15, | 341 | 'hp': 15, |
342 | 'mp': 24, | ||
260 | 'weapon_base_damage': 15, | 343 | 'weapon_base_damage': 15, |
261 | }, | 344 | }, |
262 | 'Morbid Eye': { | 345 | 'Morbid Eye': { |
263 | 'family': 'ahriman', | 346 | 'family': 'ahriman', |
264 | 'zone': ['castle zvahl baileys', 'castle zvahl keep'], | 347 | 'zone': ['castle zvahl baileys', 'castle zvahl keep'], |
265 | 'hp': 15, | 348 | 'hp': 15, |
349 | 'mp': 24, | ||
266 | 'weapon_base_damage': 15 | 350 | 'weapon_base_damage': 15 |
267 | }, | 351 | }, |
268 | 'Deadly Iris': { | 352 | 'Deadly Iris': { |
269 | 'family': 'ahriman', | 353 | 'family': 'ahriman', |
270 | 'zone': ['castle zvahl keep'], | 354 | 'zone': ['castle zvahl keep'], |
271 | 'hp': 15, | 355 | 'hp': 15, |
356 | 'mp': 24, | ||
272 | 'weapon_base_damage': 15 | 357 | 'weapon_base_damage': 15 |
273 | }, | 358 | }, |
274 | 'Ahriman': { | 359 | 'Ahriman': { |
275 | 'family': 'ahriman', | 360 | 'family': 'ahriman', |
276 | 'zone': ['castle zvahl baileys'], | 361 | 'zone': ['castle zvahl baileys'], |
277 | 'hp': 15, | 362 | 'hp': 15, |
363 | 'mp': 24, | ||
278 | 'weapon_base_damage': 15 | 364 | 'weapon_base_damage': 15 |
279 | }, | 365 | }, |
280 | 'Fachan': { | 366 | 'Fachan': { |
281 | 'family': 'ahriman', | 367 | 'family': 'ahriman', |
282 | 'zone': ['uleguerand range'], | 368 | 'zone': ['uleguerand range'], |
283 | 'hp': 15, | 369 | 'hp': 15, |
370 | 'mp': 24, | ||
284 | 'weapon_base_damage': 15 | 371 | 'weapon_base_damage': 15 |
285 | }, | 372 | }, |
286 | 'Gawper': { | 373 | 'Gawper': { |
287 | 'family': 'ahriman', | 374 | 'family': 'ahriman', |
288 | 'zone': ['beaucedine glacier (s)'], | 375 | 'zone': ['beaucedine glacier (s)'], |
289 | 'hp': 15, | 376 | 'hp': 15, |
377 | 'mp': 24, | ||
290 | 'weapon_base_damage': 15 | 378 | 'weapon_base_damage': 15 |
291 | }, | 379 | }, |
292 | 'Menacing Eye': { | 380 | 'Menacing Eye': { |
293 | 'family': 'ahriman', | 381 | 'family': 'ahriman', |
294 | 'zone': ['xarcabard (s)'], | 382 | 'zone': ['xarcabard (s)'], |
295 | 'hp': 15, | 383 | 'hp': 15, |
384 | 'mp': 24, | ||
296 | 'weapon_base_damage': 15 | 385 | 'weapon_base_damage': 15 |
297 | }, | 386 | }, |
298 | 'Ogler': { | 387 | 'Ogler': { |
299 | 'family': 'ahriman', | 388 | 'family': 'ahriman', |
300 | 'zone': ['castle zvahl keep (s)', 'castle zvahl baileys (s)'], | 389 | 'zone': ['castle zvahl keep (s)', 'castle zvahl baileys (s)'], |
301 | 'hp': 15, | 390 | 'hp': 15, |
391 | 'mp': 24, | ||
302 | 'weapon_base_damage': 15 | 392 | 'weapon_base_damage': 15 |
303 | }, | 393 | }, |
304 | 'Smolenkos': { | 394 | 'Smolenkos': { |
305 | 'family': 'ahriman', | 395 | 'family': 'ahriman', |
306 | 'zone': ['uleguerand range'], | 396 | 'zone': ['uleguerand range'], |
307 | 'hp': 15, | 397 | 'hp': 15, |
398 | 'mp': 24, | ||
308 | 'weapon_base_damage': 15 | 399 | 'weapon_base_damage': 15 |
309 | }, | 400 | }, |
310 | 'Doom Lens': { | 401 | 'Doom Lens': { |
311 | 'family': 'ahriman', | 402 | 'family': 'ahriman', |
312 | 'zone': ['castle zvahl keep (s)', 'castle zvahl baileys (s)'], | 403 | 'zone': ['castle zvahl keep (s)', 'castle zvahl baileys (s)'], |
313 | 'hp': 15, | 404 | 'hp': 15, |
405 | 'mp': 24, | ||
314 | 'weapon_base_damage': 15 | 406 | 'weapon_base_damage': 15 |
315 | }, | 407 | }, |
316 | 'Scowlenkos': { | 408 | 'Scowlenkos': { |
317 | 'family': 'ahriman', | 409 | 'family': 'ahriman', |
318 | 'zone': ['uleguerand range'], | 410 | 'zone': ['uleguerand range'], |
319 | 'hp': 15, | 411 | 'hp': 15, |
412 | 'mp': 24, | ||
320 | 'weapon_base_damage': 15 | 413 | 'weapon_base_damage': 15 |
321 | } | 414 | } |
322 | 415 | ||
... | @@ -372,6 +465,7 @@ class Pankration: | ... | @@ -372,6 +465,7 @@ class Pankration: |
372 | monster_name = random.choice(self.get_monsters(zone)) | 465 | monster_name = random.choice(self.get_monsters(zone)) |
373 | monster_data = Monsters[monster_name] | 466 | monster_data = Monsters[monster_name] |
374 | hp = monster_data['hp'] | 467 | hp = monster_data['hp'] |
468 | mp = monster_data['mp'] | ||
375 | weapon_base_damage = monster_data['weapon_base_damage'] | 469 | weapon_base_damage = monster_data['weapon_base_damage'] |
376 | log("Monster: {} Data: {}".format(monster_name, monster_data)) | 470 | log("Monster: {} Data: {}".format(monster_name, monster_data)) |
377 | family_name = monster_data['family'] | 471 | family_name = monster_data['family'] |
... | @@ -391,7 +485,8 @@ class Pankration: | ... | @@ -391,7 +485,8 @@ class Pankration: |
391 | feral_skills.append(skills[2]) | 485 | feral_skills.append(skills[2]) |
392 | dicipline_level = 1 | 486 | dicipline_level = 1 |
393 | 487 | ||
394 | monster = Monster(monster_name, family_name, family, hp, level, weapon_base_damage, main_job, support_job, feral_skills, | 488 | monster = Monster(monster_name, family_name, family, hp, mp, level, |
489 | weapon_base_damage, main_job, support_job, feral_skills, | ||
395 | [], dicipline_level) | 490 | [], dicipline_level) |
396 | url = '' | 491 | url = '' |
397 | if 'image_url' in monster_data: | 492 | if 'image_url' in monster_data: |
... | @@ -405,15 +500,26 @@ class Pankration: | ... | @@ -405,15 +500,26 @@ class Pankration: |
405 | def get_action(): | 500 | def get_action(): |
406 | return "" | 501 | return "" |
407 | 502 | ||
503 | class AttackResponse: | ||
504 | def __init__(self, is_a_hit, damage, is_a_crit, spell, resisted): | ||
505 | self.spell = spell | ||
506 | self.is_a_crit = is_a_crit | ||
507 | self.is_a_hit = is_a_hit | ||
508 | self.resisted = resisted | ||
509 | self.damage = damage | ||
510 | |||
511 | def __str__(self): | ||
512 | return "Spell: {} Resisted: {} Is a Hit: {} Is a Crit: {} Damage: {}".format(self.spell, self.resisted, self.is_a_hit, self.is_a_crit, self.damage) | ||
408 | 513 | ||
409 | class Monster: | 514 | class Monster: |
410 | def __init__(self, monster_type, family_name, family, base_hp, level, weapon_base_damage, main_job, support_job, innate_feral_skills, | 515 | def __init__(self, monster_type, family_name, family, base_hp, base_mp, level, weapon_base_damage, main_job, |
411 | equipped_feral_skills, dicipline_level): | 516 | support_job, innate_feral_skills, equipped_feral_skills, dicipline_level): |
412 | self.custom_name = None | 517 | self.custom_name = None |
413 | self.monster_type = monster_type | 518 | self.monster_type = monster_type |
414 | self.family_name = family_name | 519 | self.family_name = family_name |
415 | self.family = family | 520 | self.family = family |
416 | self.base_hp = base_hp | 521 | self.base_hp = base_hp |
522 | self.base_mp = base_mp | ||
417 | self.level = level | 523 | self.level = level |
418 | self.main_job = main_job | 524 | self.main_job = main_job |
419 | self.support_job = support_job | 525 | self.support_job = support_job |
... | @@ -423,7 +529,8 @@ class Monster: | ... | @@ -423,7 +529,8 @@ class Monster: |
423 | self.temperament_posture = family['temperament_posture']['initial_value'] | 529 | self.temperament_posture = family['temperament_posture']['initial_value'] |
424 | self.temperament_attitude = family['temperament_attitude']['initial_value'] | 530 | self.temperament_attitude = family['temperament_attitude']['initial_value'] |
425 | self.pre_fight_command = {"temperament_posture": None, "temperament_attitude": None} | 531 | self.pre_fight_command = {"temperament_posture": None, "temperament_attitude": None} |
426 | self.exp = exp_to_level[level] + 1 | 532 | self.target_magic_damage_adjustment = family['target_magic_damage_adjustment'] |
533 | self.exp = 200 * (level - 1) | ||
427 | # TODO: Setup something more interesting for each monster. | 534 | # TODO: Setup something more interesting for each monster. |
428 | self.weapon_base_damage = weapon_base_damage | 535 | self.weapon_base_damage = weapon_base_damage |
429 | self.ammo_damage = 0 | 536 | self.ammo_damage = 0 |
... | @@ -439,8 +546,11 @@ class Monster: | ... | @@ -439,8 +546,11 @@ class Monster: |
439 | self.mnd_per_level = family['mnd_per_level'] | 546 | self.mnd_per_level = family['mnd_per_level'] |
440 | self.base_int = family['base_int'] | 547 | self.base_int = family['base_int'] |
441 | self.int_per_level = family['int_per_level'] | 548 | self.int_per_level = family['int_per_level'] |
549 | self.base_chr = family['base_chr'] | ||
550 | self.chr_per_level = family['chr_per_level'] | ||
442 | self.tp = 0 | 551 | self.tp = 0 |
443 | self.hp = self.get_hp() | 552 | self.hp = self.get_hp() |
553 | self.mp = self.get_mp() | ||
444 | self.wins = 0 | 554 | self.wins = 0 |
445 | self.losses = 0 | 555 | self.losses = 0 |
446 | 556 | ||
... | @@ -478,20 +588,31 @@ class Monster: | ... | @@ -478,20 +588,31 @@ class Monster: |
478 | #this is a bit dumb but it's close enough. | 588 | #this is a bit dumb but it's close enough. |
479 | return int((self.level * 20) + self.base_hp) | 589 | return int((self.level * 20) + self.base_hp) |
480 | 590 | ||
591 | def get_mp(self): | ||
592 | #this is a bit dumb but it's close enough. | ||
593 | |||
594 | main_add_amount = self.base_mp * adjustments_by_job[self.main_job]['mp_per_level'] | ||
595 | sub_add_amount = self.base_mp * adjustments_by_job[self.support_job]['mp_per_level'] | ||
596 | |||
597 | main_mp = int((self.level * (self.base_mp + main_add_amount)) + self.base_mp) | ||
598 | sub_mp = int((self.level/2) * sub_add_amount) | ||
599 | return main_mp + sub_mp | ||
600 | |||
601 | |||
481 | def get_fp(self): | 602 | def get_fp(self): |
482 | return int(self.level / self.family['fp_per_level'] + self.family['base_fp']) | 603 | return int(self.level / self.family['fp_per_level'] + self.family['base_fp']) |
483 | 604 | ||
484 | def add_xp(self, exp_to_add): | 605 | def add_xp(self, exp_to_add): |
485 | self.exp += exp_to_add | 606 | self.exp += exp_to_add |
486 | for i in range(self.level, 51): | 607 | for i in range(self.level, 51): |
487 | if self.exp > 200 * i: | 608 | if self.exp >= 200 * i: |
488 | if i > self.level: | 609 | if i > self.level: |
489 | # We leveled up! | 610 | # We leveled up! |
490 | self.level = i | 611 | self.level = i |
491 | return (True, "Start level: {} New Level: {}".format(self.level, i)) | 612 | return (True, "Congratulations your monster leveled up!\n\nStart level: {} New Level: {}".format(self.level, i)) |
492 | else: | 613 | else: |
493 | break | 614 | break |
494 | return (False,) | 615 | return (False,None) |
495 | 616 | ||
496 | def get_current_posture(self): | 617 | def get_current_posture(self): |
497 | return TemperamentPosture[self.temperament_posture] | 618 | return TemperamentPosture[self.temperament_posture] |
... | @@ -524,7 +645,7 @@ class Monster: | ... | @@ -524,7 +645,7 @@ class Monster: |
524 | return int(math.floor(3*self.get_dexterity()/4) + self.get_combat_skill()) | 645 | return int(math.floor(3*self.get_dexterity()/4) + self.get_combat_skill()) |
525 | 646 | ||
526 | def get_evasion(self): | 647 | def get_evasion(self): |
527 | job_eva = evasion_by_job[self.main_job] | 648 | job_eva = adjustments_by_job[self.main_job] |
528 | base_eva = int(round(max(job_eva['base_eva'], self.level * job_eva['eva_per_level']))) | 649 | base_eva = int(round(max(job_eva['base_eva'], self.level * job_eva['eva_per_level']))) |
529 | 650 | ||
530 | return base_eva + int(self.get_agility() / 2) | 651 | return base_eva + int(self.get_agility() / 2) |
... | @@ -544,12 +665,17 @@ class Monster: | ... | @@ -544,12 +665,17 @@ class Monster: |
544 | def get_intelligence(self): | 665 | def get_intelligence(self): |
545 | return int(round(max(self.base_int, self.level * self.int_per_level))) | 666 | return int(round(max(self.base_int, self.level * self.int_per_level))) |
546 | 667 | ||
668 | def get_charisma(self): | ||
669 | return int(round(max(self.base_chr, self.level * self.chr_per_level))) | ||
670 | |||
547 | def get_base_defense(self): | 671 | def get_base_defense(self): |
548 | return (math.floor(self.get_vitality()/2) + 8 + self.level) | 672 | return (math.floor(self.get_vitality()/2) + 8 + self.level) |
549 | 673 | ||
550 | def get_hp_percent(self): | 674 | def get_hp_percent(self): |
551 | print(self.hp) | 675 | return max(1, int(round((self.hp/self.get_hp())*100))) |
552 | return max(0, int(round((self.hp/self.get_hp())*100))) | 676 | |
677 | def get_magic_evasion(self): | ||
678 | return max(1, int(1+round(self.level/4))) | ||
553 | 679 | ||
554 | def get_hit_rate(self, enemy_eva, level_difference): | 680 | def get_hit_rate(self, enemy_eva, level_difference): |
555 | rate = 75 + math.floor(((self.get_accuracy() - enemy_eva)/2)) - (2*level_difference) | 681 | rate = 75 + math.floor(((self.get_accuracy() - enemy_eva)/2)) - (2*level_difference) |
... | @@ -559,54 +685,34 @@ class Monster: | ... | @@ -559,54 +685,34 @@ class Monster: |
559 | rate = 95 | 685 | rate = 95 |
560 | return rate | 686 | return rate |
561 | 687 | ||
562 | def get_physical_ws_damage(self, base_damage, modifiers): | 688 | def get_magic_hit_rate(self, spell, enemy): |
563 | level_range_alpha = 1.01 - (math.floor(float(self.level) / 5.0) / 100.0) | 689 | # Calculate the magic accuracy |
564 | wsc = 0 | 690 | spell_data = Spells().get_spell_data(spell) |
565 | for modifier in modifiers: | 691 | # Get the stat for the spell and base magic accuracy for that spells MA |
566 | if modifier['stat'] == 'str': | 692 | magic_acc_stat = spell_data['magic_acc_stat'] |
567 | wsc += (modifer['percent'] / 100) * self.get_strength() | 693 | if magic_acc_stat == 'int': |
568 | elif modifiers['stat'] == 'vit': | 694 | dSTAT = self.get_intelligence() - enemy.get_intelligence() |
569 | wsc += (modifer['percent'] / 100) * self.get_vitality() | 695 | elif magic_acc_stat == 'mnd': |
570 | elif modifiers['stat'] == 'dex': | 696 | dSTAT = self.get_mind() - enemy.get_mind() |
571 | wsc += (modifer['percent'] / 100) * self.get_dexterity() | 697 | elif magic_acc_stat == 'chr': |
572 | elif modifiers['stat'] == 'agi': | 698 | dSTAT = self.get_charisma() - enemy.get_charisma() |
573 | wsc += (modifer['percent'] / 100) * self.get_agility() | 699 | elif magic_acc_stat == 'agi': |
574 | elif modifiers['stat'] == 'eva': | 700 | dSTAT = self.get_agility() - enemy.get_agility() |
575 | wsc += (modifer['percent'] / 100) * self.get_evasion() | 701 | |
576 | elif modifiers['stat'] == 'int': | 702 | magic_hit_rate = 50 - 0.5 * (enemy.get_magic_evasion() - dSTAT) |
577 | wsc += (modifer['percent'] / 100) * self.get_intelligence() | 703 | |
578 | elif modifiers['stat'] == 'mnd': | 704 | if magic_hit_rate < 5: |
579 | wsc += (modifer['percent'] / 100) * self.get_mind() | 705 | magic_hit_rate = 5 |
580 | wsc = (wsc * level_range_alpha) | 706 | elif magic_hit_rate > 95: |
581 | 707 | magic_hit_rate = 95 | |
582 | bd = float(self.weapon_base_damage) | 708 | return magic_hit_rate |
583 | if attack_type == 'ranged': | 709 | |
584 | bd += self.ammo_damage | 710 | def get_pdif(self, base_damage, defense, attack_type, level_difference): |
585 | |||
586 | fstr = ((self.get_strength() - enemy_vit)+4) / 4 | ||
587 | |||
588 | final_damage = bd + fstr + wsc | ||
589 | 711 | ||
590 | return final_damage | ||
591 | |||
592 | #TODO: Add fTP calculation and PDIF | ||
593 | #final_damage = (bd ) | ||
594 | #return final_damage | ||
595 | |||
596 | |||
597 | # Calculate the base damage against the provided defense | ||
598 | # attack_type can be 'ranged' or 'melee' | ||
599 | def get_physical_base_damage(self, defense, attack_type, level_difference, enemy_vit): | ||
600 | #print("Defense: {} Type: {} Level diff: {}".format(defense, attack_type, level_difference)) | ||
601 | # Calculate the attack/defense ratio | ||
602 | bd = float(self.weapon_base_damage) | ||
603 | if attack_type == 'ranged': | ||
604 | bd += self.ammo_damage | ||
605 | |||
606 | if defense == 0: | 712 | if defense == 0: |
607 | ratio = 99 | 713 | ratio = 99 |
608 | else: | 714 | else: |
609 | ratio = bd / float(defense) | 715 | ratio = base_damage / float(defense) |
610 | if attack_type == 'ranged': | 716 | if attack_type == 'ranged': |
611 | cap = 3.0 | 717 | cap = 3.0 |
612 | else: | 718 | else: |
... | @@ -646,17 +752,151 @@ class Monster: | ... | @@ -646,17 +752,151 @@ class Monster: |
646 | 752 | ||
647 | # Some fuckery since python doesn't let you do a rand between decimals | 753 | # Some fuckery since python doesn't let you do a rand between decimals |
648 | pDif_rand = float(random.randint(int(pDif_min*100000), int(pDif_max*100000))) / 100000.0 | 754 | pDif_rand = float(random.randint(int(pDif_min*100000), int(pDif_max*100000))) / 100000.0 |
649 | 755 | return pDif_rand * cRatio | |
756 | |||
757 | def get_physical_ws_damage(self, defense, attack_type, fTP, modifiers, level_difference, enemy_vit): | ||
758 | level_range_alpha = 1.01 - (math.floor(float(self.level) / 5.0) / 100.0) | ||
759 | wsc = 0 | ||
760 | for modifier in modifiers: | ||
761 | if modifier['stat'] == 'str': | ||
762 | wsc += (modifer['percent'] / 100) * self.get_strength() | ||
763 | elif modifiers['stat'] == 'vit': | ||
764 | wsc += (modifer['percent'] / 100) * self.get_vitality() | ||
765 | elif modifiers['stat'] == 'dex': | ||
766 | wsc += (modifer['percent'] / 100) * self.get_dexterity() | ||
767 | elif modifiers['stat'] == 'agi': | ||
768 | wsc += (modifer['percent'] / 100) * self.get_agility() | ||
769 | elif modifiers['stat'] == 'eva': | ||
770 | wsc += (modifer['percent'] / 100) * self.get_evasion() | ||
771 | elif modifiers['stat'] == 'int': | ||
772 | wsc += (modifer['percent'] / 100) * self.get_intelligence() | ||
773 | elif modifiers['stat'] == 'mnd': | ||
774 | wsc += (modifer['percent'] / 100) * self.get_mind() | ||
775 | wsc = (wsc * level_range_alpha) | ||
776 | |||
777 | bd = float(self.weapon_base_damage) | ||
778 | if attack_type == 'ranged': | ||
779 | bd += self.ammo_damage | ||
780 | |||
781 | fstr = ((self.get_strength() - enemy_vit)+4) / 4 | ||
782 | |||
783 | # These are specific to each WS | ||
784 | fTP_1000 = fTP[0] | ||
785 | fTP_2000 = fTP[1] | ||
786 | fTP_3000 = fTP[2] | ||
787 | |||
788 | if self.tp < 1000: | ||
789 | return | ||
790 | if 1000 <= self.tp <= 2000: | ||
791 | prev_anchor = fTP_1000 | ||
792 | next_anchor = fTP_2000 | ||
793 | dTP = float(self.tp - 1000) / 1000.0 | ||
794 | elif 2000 <= self.tp <= 3000: | ||
795 | prev_anchor = fTP_2000 | ||
796 | next_anchor = fTP_3000 | ||
797 | dTP = float(self.tp - 2000) / 1000.0 | ||
798 | |||
799 | fTP = prev_anchor + (dTP * (next_anchor - prev_anchor)) | ||
800 | pDif = self.get_pdif(bd, defense, attack_type, level_difference) | ||
801 | |||
802 | final_damage = int((bd + fstr + wsc) * fTP * pDif) | ||
803 | |||
804 | return final_damage | ||
805 | |||
806 | def get_magic_base_damage(self, spell, enemy): | ||
807 | |||
808 | if spell in ['Banish', 'Holy']: | ||
809 | dINT = self.get_mind() - enemy.get_mind() | ||
810 | else: | ||
811 | dINT = self.get_intelligence() - enemy.get_intelligence() | ||
812 | |||
813 | spell_data = Spells().get_spell_data(spell) | ||
814 | |||
815 | base_damage = 0 | ||
816 | if dINT < 0: | ||
817 | # multiplier ignored since dINT is too low. | ||
818 | base_damage = spell_data['base_damage'] + dINT | ||
819 | elif 0 <= dINT <= 150: | ||
820 | base_damage = spell_data['base_damage'] + (dINT * spell_data['multiplier']) | ||
821 | if base_damage < 0: | ||
822 | base_damage = 0 | ||
823 | # We can skip multi-target damage reduction. There is no such thing since we only have a single enemy. | ||
824 | |||
825 | # Calculate the hit rate so we can determine if the resistance applied to the base damage. | ||
826 | resist_level = 0 | ||
827 | for i in range(0, 3): | ||
828 | if not self.is_a_magic_hit(spell, enemy): | ||
829 | resist_level += 1 | ||
830 | base_damage = base_damage / 2 | ||
831 | if resist_level == 3: | ||
832 | base_damage = 0 | ||
833 | |||
834 | # TODO: Add weather later maybe | ||
835 | |||
836 | # Not adding in magic burst since it is primarily a player thing | ||
837 | base_damage *= enemy.target_magic_damage_adjustment | ||
838 | |||
839 | return base_damage | ||
840 | |||
841 | # Calculate the base damage against the provided defense | ||
842 | # attack_type can be 'ranged' or 'melee' | ||
843 | # TODO: Replace enemyvit with the actual enemy variable | ||
844 | def get_physical_base_damage(self, defense, attack_type, level_difference, enemy_vit): | ||
845 | #print("Defense: {} Type: {} Level diff: {}".format(defense, attack_type, level_difference)) | ||
846 | # Calculate the attack/defense ratio | ||
847 | bd = float(self.weapon_base_damage) | ||
848 | if attack_type == 'ranged': | ||
849 | bd += self.ammo_damage | ||
850 | pDif = self.get_pdif(bd, defense, attack_type, level_difference) | ||
851 | |||
650 | fstr = ((self.get_strength() - enemy_vit)+4) / 4 | 852 | fstr = ((self.get_strength() - enemy_vit)+4) / 4 |
651 | log("Str: {} Vit: {} fstr: {}".format(self.get_strength(), enemy_vit, fstr)) | 853 | log("Str: {} Vit: {} fstr: {}".format(self.get_strength(), enemy_vit, fstr)) |
652 | bd = bd + fstr | 854 | bd = bd + fstr |
653 | final_damage = int((bd * (pDif_rand * cRatio))) | 855 | final_damage = int(bd * pDif) |
654 | return final_damage | 856 | return final_damage |
655 | 857 | ||
656 | def attack(self, monster): | 858 | def attack(self, monster): |
657 | phy_damage = self.get_physical_base_damage(monster.get_base_defense(), 'melee', monster.level - self.level, monster.get_vitality()) | 859 | is_a_crit = False |
658 | self.tp += 64 | 860 | is_a_hit = False |
659 | return (phy_damage, 'hits') | 861 | spell = None |
862 | resisted = False | ||
863 | damage = 0 | ||
864 | |||
865 | |||
866 | ###### | ||
867 | # TODO: Build some type of AI / testing to find the most powerful attack and use that (magic, melee, or ranged) | ||
868 | ###### | ||
869 | |||
870 | spell = 'Fire' | ||
871 | if self.is_a_magic_hit(spell, monster): | ||
872 | damage = self.get_magic_base_damage(spell, monster) | ||
873 | if damage == 0: | ||
874 | resisted = True | ||
875 | log("MAGIC DAMAGE: {}".format(damage)) | ||
876 | is_a_hit = True | ||
877 | spell_data = Spells().get_spell_data(spell) | ||
878 | self.mp -= spell_data['mp_cost'] | ||
879 | if self.mp < 0: | ||
880 | self.mp = 0 | ||
881 | return AttackResponse(is_a_hit, damage, is_a_crit, spell, resisted) | ||
882 | |||
883 | if self.is_a_hit(monster): | ||
884 | # TODO: Make this follow the behavior in temprament and select the right behavior. | ||
885 | if self.tp >= 1000: | ||
886 | damage = self.get_physical_ws_damage(monster.get_base_defense(), 'melee', [1.0, 1.5, 4.0], [], monster.level - self.level, monster.get_vitality()) | ||
887 | log("WS DAMAGE: {}".format(damage)) | ||
888 | self.tp = 0 | ||
889 | else: | ||
890 | damage = self.get_physical_base_damage(monster.get_base_defense(), 'melee', monster.level - self.level, monster.get_vitality()) | ||
891 | print("STD DAMAGE: {}".format(damage)) | ||
892 | self.tp += 64 | ||
893 | is_a_hit = True | ||
894 | # Returns the amount of damage and if it is a crit | ||
895 | return AttackResponse(is_a_hit, damage, is_a_crit, spell, resisted) | ||
896 | |||
897 | def is_a_magic_hit(self, spell, monster): | ||
898 | hit_rate = self.get_magic_hit_rate(spell, monster) | ||
899 | return random.randint(1, 100) < hit_rate | ||
660 | 900 | ||
661 | def is_a_hit(self, monster): | 901 | def is_a_hit(self, monster): |
662 | hit_rate = self.get_hit_rate(monster.get_evasion(), monster.level - self.level) | 902 | hit_rate = self.get_hit_rate(monster.get_evasion(), monster.level - self.level) |
... | @@ -695,23 +935,56 @@ class Action: | ... | @@ -695,23 +935,56 @@ class Action: |
695 | self.monster = monster | 935 | self.monster = monster |
696 | 936 | ||
697 | class AttackAction(Action): | 937 | class AttackAction(Action): |
698 | def __init__(self, attacker, target, damage, message): | 938 | STANDARD_MESSAGES = ['hit', 'smashed', 'walloped', 'struck', 'beat', |
939 | 'knocked', 'punched', 'belted', 'decked', 'banged', | ||
940 | 'battered', 'clipped', 'slapped', 'bashed', 'socked', | ||
941 | 'smacked', 'thumped', 'cuffed', 'flogged', 'whacked', | ||
942 | 'clobbered', 'swatted'] | ||
943 | MAGIC_MESSAGES = ['cast'] | ||
944 | CRIT_MESSAGES = ['CRITICALLY hit'] | ||
945 | |||
946 | def __init__(self, attacker, target, damage, is_a_crit=False, spell=None): | ||
699 | self.attacker = attacker | 947 | self.attacker = attacker |
700 | self.target = target | 948 | self.target = target |
701 | self.damage = damage | 949 | self.damage = damage |
702 | self.message = message | 950 | self.spell = spell |
951 | if spell: | ||
952 | self.message = random.choice(AttackAction.MAGIC_MESSAGES) | ||
953 | elif is_a_crit: | ||
954 | self.message = random.choice(AttackAction.CRIT_MESSAGES) | ||
955 | else: | ||
956 | self.message = random.choice(AttackAction.STANDARD_MESSAGES) | ||
957 | |||
958 | #TODO: Modify and add resist as part of attacks | ||
959 | class MagicResistAction(Action): | ||
960 | MESSAGES = ['resisted'] | ||
961 | |||
962 | def __init__(self, attacker, target, spell): | ||
963 | self.attacker = attacker | ||
964 | self.target = target | ||
965 | self.spell = spell | ||
966 | self.message = random.choice(MagicResistAction.MESSAGES) | ||
703 | 967 | ||
704 | class MissAction(Action): | 968 | class MissAction(Action): |
705 | def __init__(self, attacker, target, message): | 969 | MAGIC_MESSAGES = ['fizzled the spell against'] |
970 | MESSAGES = ['missed', 'was unable to hit', 'attack went wide of', 'fumbled the hit on'] | ||
971 | |||
972 | def __init__(self, attacker, target, spell): | ||
706 | self.attacker = attacker | 973 | self.attacker = attacker |
707 | self.target = target | 974 | self.target = target |
708 | self.message = message | 975 | self.spell = spell |
976 | if spell: | ||
977 | self.message = random.choice(MissAction.MESSAGES) | ||
978 | else: | ||
979 | self.message = random.choice(MissAction.MAGIC_MESSAGES) | ||
709 | 980 | ||
710 | class DefeatAction(Action): | 981 | class DefeatAction(Action): |
711 | def __init__(self, attacker, target, message, xp): | 982 | MESSAGES = ['was defeated', 'was smited', 'was conquered', 'was routed', 'was thwarted', |
983 | 'was vanquished', 'was bested'] | ||
984 | def __init__(self, attacker, target, xp): | ||
712 | self.attacker = attacker | 985 | self.attacker = attacker |
713 | self.target = target | 986 | self.target = target |
714 | self.message = message | 987 | self.message = random.choice(DefeatAction.MESSAGES) |
715 | self.xp = xp | 988 | self.xp = xp |
716 | 989 | ||
717 | 990 | ||
... | @@ -725,7 +998,8 @@ class Arena: | ... | @@ -725,7 +998,8 @@ class Arena: |
725 | def heal_monsters(self): | 998 | def heal_monsters(self): |
726 | self.monster1.hp = self.monster1.get_hp() | 999 | self.monster1.hp = self.monster1.get_hp() |
727 | self.monster2.hp = self.monster2.get_hp() | 1000 | self.monster2.hp = self.monster2.get_hp() |
728 | 1001 | self.monster1.mp = self.monster1.get_mp() | |
1002 | self.monster2.mp = self.monster2.get_mp() | ||
729 | 1003 | ||
730 | def start(self): | 1004 | def start(self): |
731 | self.heal_monsters() | 1005 | self.heal_monsters() |
... | @@ -740,11 +1014,16 @@ class Arena: | ... | @@ -740,11 +1014,16 @@ class Arena: |
740 | else: | 1014 | else: |
741 | primary = self.monster2 | 1015 | primary = self.monster2 |
742 | secondary = self.monster1 | 1016 | secondary = self.monster1 |
743 | 1017 | # TODO: Add a way to decide if the monster will use magic or melee or range | |
744 | if primary.is_a_hit(secondary): | 1018 | |
745 | result1 = primary.attack(secondary) | 1019 | #if primary.is_a_magic_hit(spell, secondary) |
746 | secondary.apply_damage(result1[0]) | 1020 | result1 = primary.attack(secondary) |
747 | actions.append(AttackAction(primary, secondary, result1[0], result1[1])) | 1021 | if result1.resisted: |
1022 | actions.append(MagicResistAction(primary, secondary, result1.spell)) | ||
1023 | elif result1.is_a_hit: | ||
1024 | secondary.apply_damage(result1.damage) | ||
1025 | actions.append(AttackAction(primary, secondary, result1.damage, result1.is_a_crit, | ||
1026 | result1.spell)) | ||
748 | if secondary.hp <= 0: | 1027 | if secondary.hp <= 0: |
749 | level_difference = secondary.level - primary.level | 1028 | level_difference = secondary.level - primary.level |
750 | if level_difference in exp_table: | 1029 | if level_difference in exp_table: |
... | @@ -753,15 +1032,18 @@ class Arena: | ... | @@ -753,15 +1032,18 @@ class Arena: |
753 | xp = exp_table[15] | 1032 | xp = exp_table[15] |
754 | else: | 1033 | else: |
755 | xp = 0 | 1034 | xp = 0 |
756 | actions.append(DefeatAction(primary, secondary, 'was defeated', xp)) | 1035 | actions.append(DefeatAction(primary, secondary, xp)) |
757 | return actions | 1036 | return actions |
758 | else: | 1037 | else: |
759 | actions.append(MissAction(primary, secondary, 'missed')) | 1038 | actions.append(MissAction(primary, secondary, result1.spell)) |
760 | 1039 | ||
761 | if secondary.is_a_hit(primary): | 1040 | result2 = secondary.attack(primary) |
762 | result2 = secondary.attack(primary) | 1041 | if result2.resisted: |
763 | primary.apply_damage(result2[0]) | 1042 | actions.append(MagicResistAction(secondary, primary, result2.spell)) |
764 | actions.append(AttackAction(secondary, primary, result2[0], result2[1])) | 1043 | elif result2.is_a_hit: |
1044 | primary.apply_damage(result2.damage) | ||
1045 | actions.append(AttackAction(secondary, primary, result2.damage, result2.is_a_crit, | ||
1046 | result2.spell)) | ||
765 | if primary.hp <= 0: | 1047 | if primary.hp <= 0: |
766 | level_difference = primary.level - secondary.level | 1048 | level_difference = primary.level - secondary.level |
767 | if level_difference in exp_table: | 1049 | if level_difference in exp_table: |
... | @@ -770,16 +1052,17 @@ class Arena: | ... | @@ -770,16 +1052,17 @@ class Arena: |
770 | xp = exp_table[15] | 1052 | xp = exp_table[15] |
771 | else: | 1053 | else: |
772 | xp = 0 | 1054 | xp = 0 |
773 | actions.append(DefeatAction(secondary, primary, 'was defeated', xp)) | 1055 | actions.append(DefeatAction(secondary, primary, xp)) |
774 | return actions | 1056 | return actions |
775 | else: | 1057 | else: |
776 | actions.append(MissAction(secondary, primary, 'missed')) | 1058 | actions.append(MissAction(secondary, primary, result2.spell)) |
777 | return actions | 1059 | return actions |
778 | 1060 | ||
779 | 1061 | ||
780 | if __name__ == "__main__": | 1062 | if __name__ == "__main__": |
781 | #print Families | 1063 | #print Families |
782 | 1064 | ||
1065 | print("Spell List: \n{}\n".format(Spells().get_spell_list(20, job=Jobs.BLM, sub_job=Jobs.WHM))) | ||
783 | hunt_response = None | 1066 | hunt_response = None |
784 | p = Pankration() | 1067 | p = Pankration() |
785 | print("Zones: \n\n{}".format('\n'.join(p.list_zones()))) | 1068 | print("Zones: \n\n{}".format('\n'.join(p.list_zones()))) |
... | @@ -798,7 +1081,7 @@ if __name__ == "__main__": | ... | @@ -798,7 +1081,7 @@ if __name__ == "__main__": |
798 | # print(monster.set_strategy(4, 3)) | 1081 | # print(monster.set_strategy(4, 3)) |
799 | # print(monster.set_strategy(1, 1)) | 1082 | # print(monster.set_strategy(1, 1)) |
800 | # print(monster.set_strategy(1, 2)) | 1083 | # print(monster.set_strategy(1, 2)) |
801 | #monster.add_xp(22900) | 1084 | monster.add_xp(22900) |
802 | # phy_damage = monster.get_physical_base_damage(100, 'melee', -15) | 1085 | # phy_damage = monster.get_physical_base_damage(100, 'melee', -15) |
803 | # print("Phys Attack: {}".format(phy_damage)) | 1086 | # print("Phys Attack: {}".format(phy_damage)) |
804 | # print(monster.get_base_defense()) | 1087 | # print(monster.get_base_defense()) |
... | @@ -818,8 +1101,8 @@ if __name__ == "__main__": | ... | @@ -818,8 +1101,8 @@ if __name__ == "__main__": |
818 | monster2.set_monster_name('wreckbutt 2') | 1101 | monster2.set_monster_name('wreckbutt 2') |
819 | print("1 The Soul Plate Shows: \n\n{}".format(monster)) | 1102 | print("1 The Soul Plate Shows: \n\n{}".format(monster)) |
820 | print("2 The Soul Plate Shows: \n\n{}".format(monster2)) | 1103 | print("2 The Soul Plate Shows: \n\n{}".format(monster2)) |
821 | 1104 | print("MP m1: {}\nMP m2: {}".format(monster.get_mp(), monster2.get_mp())) | |
822 | #monster2.add_xp(16900) | 1105 | monster2.add_xp(16900) |
823 | phy_damage = monster2.attack(monster) | 1106 | phy_damage = monster2.attack(monster) |
824 | print("Phys Attack: {}".format(phy_damage)) | 1107 | print("Phys Attack: {}".format(phy_damage)) |
825 | 1108 | ||
... | @@ -836,17 +1119,19 @@ if __name__ == "__main__": | ... | @@ -836,17 +1119,19 @@ if __name__ == "__main__": |
836 | actions = battle_arena.step() | 1119 | actions = battle_arena.step() |
837 | time.sleep(2) | 1120 | time.sleep(2) |
838 | for action in actions: | 1121 | for action in actions: |
1122 | if isinstance(action, MagicResistAction): | ||
1123 | print("{} {} {} while casting {}.".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name(), action.spell)) | ||
839 | if isinstance(action, MissAction): | 1124 | if isinstance(action, MissAction): |
840 | print("{} {} {}.".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name())) | 1125 | print("{} {} {} while casting {}.".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name(), action.spell)) |
841 | if isinstance(action, AttackAction): | 1126 | if isinstance(action, AttackAction): |
842 | print("{} {} {} for {}.".format(action.attacker.get_monster_name(), action.message, action.target.get_monster_name(), action.damage)) | 1127 | print("{} {} {} against {} for {}.".format(action.attacker.get_monster_name(), action.message, action.spell, action.target.get_monster_name(), action.damage)) |
843 | if isinstance(action, DefeatAction): | 1128 | if isinstance(action, DefeatAction): |
844 | print("{} {}. {} gains {} xp.".format(action.target.get_monster_name(), action.message, action.attacker.get_monster_name(), action.xp)) | 1129 | print("{} {} {} gains {} xp.".format(action.target.get_monster_name(), action.message, action.attacker.get_monster_name(), action.xp)) |
845 | action.attacker.hp = 500 | 1130 | action.attacker.hp = 500 |
846 | print("{} {}".format(action.target.hp, action.attacker.hp)) | 1131 | print("{} {}".format(action.target.hp, action.attacker.hp)) |
847 | fighting = False | 1132 | fighting = False |
848 | break | 1133 | break |
849 | print("\n\nhp: {} {}\n\n".format(monster.hp, monster2.hp)) | 1134 | print("\n\nhp: {} {}\nmp: {} {}\n\n".format(monster.hp, monster2.hp, monster.mp, monster2.mp)) |
850 | print("\n{} {}% - {} {}%\n".format(monster.get_monster_name(), monster.get_hp_percent(), monster2.get_monster_name(), monster2.get_hp_percent())) | 1135 | print("\n{} {}% - {} {}%\n".format(monster.get_monster_name(), monster.get_hp_percent(), monster2.get_monster_name(), monster2.get_hp_percent())) |
851 | 1136 | ||
852 | 1137 | ... | ... |
-
Please register or sign in to post a comment