-
Notifications
You must be signed in to change notification settings - Fork 1
/
dnd_combat_gui.py
184 lines (160 loc) · 6.95 KB
/
dnd_combat_gui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import dnd_objects
import dnd_data
import dnd_mechanics
class Combat:
"""
Order of use:
1. make an instance of Combat()
2. instance.load_scenario(path to scenario)
3. instance.load_charpool()
4. instance.start_routine()
5. instance.run()
"""
def __init__(self, conditions=0):
"""
:param conditions:
0 - normal
1 - heroes surprise enemies
2 - enemies surprise heroes
"""
self.conditions = conditions
self.surprise_list = []
self.heroes = []
self.enemies = []
self.charpool = []
self.initiative_scores = {}
self.turn_list = []
def start_routine(self):
self.assign()
self.check_for_surprise()
self.sort()
def check_for_surprise(self):
if self.conditions == 1:
for enemy in self.enemies:
for hero in self.heroes:
modifier = 2 if hero.hidden == 1 else 0
counter = 0
if enemy.passive_perception < hero.abilities["dex"] + modifier:
counter += 1
if counter == len(self.heroes):
self.surprise_list.append(enemy)
elif self.conditions == 2:
for hero in self.heroes:
for enemy in self.enemies:
counter = 0
modifier = 2 if enemy.hidden == 1 else 0
if hero.passive_perception < enemy.abilities["dex"] + modifier:
counter += 1
if counter == len(self.enemies):
self.surprise_list.append(hero)
else:
pass
def assign(self):
for char in self.charpool:
if char.char_class == "fighter" \
or char.char_class == "wizard" \
or char.char_class == "cleric" \
or char.char_class == "rogue":
self.heroes.append(char)
else:
self.enemies.append(char)
def sort(self):
for char in self.charpool:
score = dnd_mechanics.roll(20, 1) + char.initiative()
self.initiative_scores[str(char.name)] = score
while len(self.initiative_scores) > 0:
max_value = max(self.initiative_scores.values())
character = [name for name, score in self.initiative_scores.items() if score == max_value][0]
self.turn_list.append([c for c in self.charpool if c.name == character][0])
del self.initiative_scores[character]
for i in self.turn_list:
if i in self.surprise_list:
self.turn_list.append(self.turn_list.pop(i))
def turn(self, char):
print("{}, now it's your turn! What are you gonna do?".format(char.name))
request = str(input("-> "))
return request
def load_scenario(self, scenario): # TODO: Importing combat scenarios after button click
"""
Current idea is to import one file: dnd_current_scenario, but before doing it - rewrite it from a different
scenario file. So you specify the path -> file gets opened -> file gets copied -> file gets written as new current
scenario file -> then import current scenario file -> use charpool that exists there.
:param scenario: path to an existing scenario
:return: nothing, just assigns a charpool with created characters.
"""
open("dnd_current_scenario.py", "w").close()
f = open('{}'.format(scenario))
f1 = open('dnd_current_scenario.py', 'a')
for x in f.readlines():
f1.write(x)
f.close()
f1.close()
def load_charpool(self):
import dnd_current_scenario
self.charpool = dnd_current_scenario.charpool
def reset_counters(self, creature):
for k, v in creature.main_action_counters.items():
creature.main_action_counters[k] = 0
for k, v in creature.bonus_action_counters.items():
creature.bonus_action_counters[k] = 0
def run(self):
stat = True
h_counter = 0
e_counter = 0
while stat: # TODO: knock out and kill counters
if h_counter == len(self.heroes) or e_counter == len(self.enemies):
stat = False
for char in self.turn_list:
print(char.name)
if "rechargable" in char.placeholder.keys():
if char.placeholder["rechargable"] > 0:
char.placeholder["rechargable"] -= 1
else:
pass
main_action_counters = char.main_action_counters
bonus_action_counters = char.bonus_action_counters
main_counter = 0
bonus_counter = 0
finished = False
if stat is False:
break
while not finished:
if char in self.surprise_list:
self.surprise_list.remove(char)
if char.turns_to_skip["quantity"] > 0:
print("{} has to skip turn.\nReason: {}".format(char.name, char.turns_to_skip["reason"]))
char.turns_to_skip["quantity"] -= 1
finished = True
else:
# THOSE LINES ARE TO BE REMOVED ONCE GUI IS IMPLEMENTED
request = str(input())
if request == "main":
main_action_counters["attack"] += 1
elif request == "bonus":
bonus_action_counters["other"] += 1
elif request == "split":
char.usePerk("split")
else: # DANGEROUS BUT NECESSARY FOR TESTING, DELETE OR HASH ONCE DONE
eval(request)
# ======================================================
if 1 in main_action_counters.values():
main_counter = 1
if 1 in bonus_action_counters.values():
bonus_counter = 1
if main_counter == 1 and bonus_counter == 1:
self.reset_counters(char)
finished = True
print("One tour finished")
game_on = Combat()
game_on.load_scenario(r"C:\Users\User\PycharmProjects\Thadeus\dbs\combat_scenarios\test_scenario_ochre_jelly.txt")
# FOR TESTING OF COURSE MODIFY THE PATH TO SCENARIO
game_on.load_charpool()
game_on.start_routine()
# game_on.run()
# if __name__ == "__main__":
# game_on = Combat()
# game_on.load_scenario(r"C:\Users\User\PycharmProjects\Thadeus\dbs\combat_scenarios\test_scenario_ochre_jelly.txt")
# # FOR TESTING OF COURSE MODIFY THE PATH TO SCENARIO
# game_on.load_charpool()
# game_on.start_routine()
# game_on.run()