-
Notifications
You must be signed in to change notification settings - Fork 0
/
Mech.py
206 lines (201 loc) · 8 KB
/
Mech.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import random
from Gadget import Gadget
import Gadgets
from tile_content import tile_content
from location import location
# from Station import Station
from Cover import Cover
class Mech(tile_content):
BASE_MOVEMENT = 1
# print("suck it")
def d6(self):
return random.randint(1,6)
def d8(self):
return random.randint(1,8)
def twoD6(self):
return self.d6() + self.d6()
def __init__(self, world, gadgets, location, team):
self.team = team
self.gadgets = gadgets
self.gadgets.update_count()
self.location = location
self.world = world
self.world.table[location.row][location.col] = self
# self.movement_range = calculateMovement()
self.scores = {"atk":0,"def":0,"mov":0,"spt":0}
self.active = True
self.prepped = False
self.atk_range = 8
self.nearby_cover = []
def is_prepped(self):
return self.prepped
def is_active(self):
return self.active
def take_damage(self, damage):
if not self.gadgets.has_active():
self.active = False
return
if damage > 0:
if self.gadgets.has_active():
dmg = random.randint(0,len(self.gadgets.members)-1)
while not self.gadgets.members[dmg].active:
dmg = random.randint(0,len(self.gadgets.members)-1)
self.gadgets.members[dmg].active = False
self.gadgets.update_count()
self.take_damage(damage - 1)
else:
self.active = False
def get_scores(self):
self.prep()
s = ""
for score in self.scores:
s += score + ": " + str(self.scores[score]) + " "
return s
def reset_scores(self):
self.scores = {"atk":0,"def":0,"mov":0,"spt":0}
def prep_atk(self):
if self.gadgets.count["atk"] == 2:
self.scores["atk"] = self.d8() + self.twoD6()
else:
self.scores["atk"] = self.twoD6() * self.gadgets.count["atk"]
def prep_def(self):
self.scores["def"] = 0
for i in range(self.gadgets.count["def"]):
self.scores["def"] += self.d6()
def prep_mov(self):
self.scores["mov"] = 0
for i in range(self.gadgets.count["mov"]):
self.scores["mov"] += self.d6()
def prep_spt(self):
for i in range(self.gadgets.count["spt"]):
self.scores["spt"] += self.d6()
def prep(self):
if not self.is_prepped():
self.reset_scores
self.prep_atk()
self.prep_def()
self.prep_mov()
self.prep_spt()
self.prepped = True
def valid_move_tiles(self):
if self.gadgets.count["mov"] == 2:
return self.world.list_tiles_in_range(self.location, self.scores["mov"])
else:
return self.world.list_walkable_tiles_in_range(self.location, self.scores["mov"])
def move(self,target):
self.set_location(target)
self.world.curses_display_table()
def can_move_to(self, target):
return self.world.is_walkable(target) and target in self.valid_atk_tiles()
def set_location(self, target):
self.world.table[self.location.row][self.location.col] = tile_content(self.world)
self.location = target
self.world.table[target.row][target.col] = self
self.update_nearby_cover()
def valid_atk_tiles(self):
return self.world.list_tiles_in_range(self.location, self.atk_range)
def can_attack(self, target):
# return target in self.valid_atk_tiles()
return True
def attack(self, target):
# self.world.window.addstr(6,50, self.short_specs() + " is attacking " + target.short_specs())
if isinstance(target, location):
target = self.world.at(target)
if isinstance(target, Mech):
if not target.is_prepped():
target.prep()
self.world.scr.addstr(7,50, " " *50)
self.world.scr.addstr(7,50, self.short_specs() + " is attacking " + target.short_specs())
hits = max(self.scores["atk"] + target.scores["spt"] - target.scores["def"],0)
self.world.scr.addstr(8,50, " " * 50)
self.world.scr.addstr(8,50, "scored " + str(hits) + " hits")
dmg_to_take = 0
for hit in range(hits-1):
hit_score = self.d6()
if target.is_in_cover():
if hit_score == 6:
target.take_damage(1)
dmg_to_take += 1
else:
if hit_score == 5 or hit_score == 4:
self.world.at(target.get_nearby_cover()[random.randint(0,len(target.get_nearby_cover()))-1 ]).height -= 1
else: #target_mech is not in cover
if hit_score == 6 or hit_score == 5:
target.take_damage(1)
dmg_to_take += 1
# target.take_damage(dmg_to_take)
self.world.scr.addstr(9,50, " "*50)
self.world.scr.addstr(9,50, "dealt " + str(dmg_to_take) + " dmg")
self.world.curses_display_table()
# if hit_score >= roll_above_to_damage:
def spot(self, target):
print("spotting mech at " + str(target))
def __str__(self):
def match(x1, x2):
c1 = {}
c2 = {}
for x in x1:
if x in c1:
c1[x] += 1
else:
c1[x] = 1
for x in x2:
if x in c2:
c2[x] += 1
else:
c2[x] = 1
return c1 == c2
pawn = ["atk", "spt", "def", "mov"] #RYBG
knight = ["atk", "mov",'mov',"def"] #RGGB
bishop = ["atk", "atk","mov","mov"] #RRGG
rook = ["atk","def","def","mov"] #RBBG
queen = ["atk","mov","spt","mov"] #RBYB
king = ["spt","spt","def","def"] #YYBB
keys = [pawn, knight, bishop, rook, queen, king]
black_chars = ["\u265F","\u265E","\u265D","\u265C","\u265B","\u265A"]
white_chars = ["\u2659","\u2658","\u2657","\u2656","\u2655","\u2654"]
for i in range(len(keys)):
if match(self.gadgets.as_string_arr(),keys[i]):
if self.active:
return black_chars[i]
else:
return white_chars[i]
else:
return "#"
def short_specs(self):
return self.team.name + " " + str(self.location)
def __repr__(self):
specs = ""
dice = {"atk":"R", "def":"B", "mov":"G", "spt":"Y"}
for gadget in self.gadgets.members:
specs += dice[gadget.kind] if gadget.is_active() else dice[gadget.kind].lower()
return specs + " @ " + str(self.location)
def get_specs(self):
specs = self.team.name + " "
dice = {"atk":"R", "def":"B", "mov":"G", "spt":"Y"}
for gadget in self.gadgets.members:
specs += dice[gadget.kind] if gadget.is_active() else dice[gadget.kind].lower()
specs += " @ "+ str(self.location)
specs += " NOT " if not self.is_in_cover() else " "
specs += "in cover"
return specs
def update_nearby_cover(self):
self.nearby_cover = []
for tile in self.location.neighbors():
if isinstance(self.world.at(tile), Cover):
self.nearby_cover.append(tile)
def get_nearby_cover(self):
return self.nearby_cover
def is_in_cover(self):
self.update_nearby_cover()
return len(self.nearby_cover) > 0
def nearby_enemies(self):
enemies = []
nearby_tiles = self.world.list_tiles_in_range(self.location, self.atk_range)
for tile in nearby_tiles:
if isinstance(self.world.at(tile), Mech):
m = self.world.at(tile)
if m.team != self.team:
enemies.append(self.world.at(tile))
return enemies
# soldier = Mech(Gadgets.soldier_kit, location(0,0), "barrett's privateers")