/
effects.py
234 lines (214 loc) · 10.7 KB
/
effects.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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
import libtcodpy as libtcod
import time
import game
import util
# checks if there are active effects and if someone is in them
def check_active_effects():
for y in range(game.current_map.map_height):
for x in range(game.current_map.map_width):
if 'duration' in game.current_map.tile[x][y]:
if game.current_map.tile[x][y]['duration'] < game.turns:
explored = game.current_map.tile_is_explored(x, y)
game.current_map.set_tile_values(game.current_map.tile[x][y]['name'], x, y)
if game.current_map.tile_is_invisible(x, y):
game.current_map.tile[x][y].pop('invisible', None)
if explored:
game.current_map.tile[x][y].update({'explored': True})
for obj in game.current_map.objects:
if obj.name == 'player':
if 'type' in game.current_map.tile[game.char.x][game.char.y]:
if game.current_map.tile[game.char.x][game.char.y]['type'] == 'poison_gas':
game.message.new('You step into poisonous gas!', game.turns)
if 'poison' not in game.player.flags:
dice = util.roll_dice(1, 50)
if dice > game.player.endurance + (game.player.karma / 2):
game.message.new('You are poisoned!', game.turns, libtcod.Color(0, 112, 0))
game.player.flags.append('poison')
if game.current_map.tile[game.char.x][game.char.y]['type'] == 'sleep_gas':
if 'sleep' not in game.player.flags:
game.message.new('You step into sleeping gas!', game.turns)
dice = util.roll_dice(1, 50)
if dice > game.player.wisdom + (game.player.karma / 2):
game.message.new('You fall asleep!', game.turns, libtcod.Color(0, 143, 189))
game.player.flags.append('sleep')
elif obj.entity:
if 'type' in game.current_map.tile[obj.x][obj.y]:
if game.current_map.tile[obj.x][obj.y]['type'] == 'poison_gas':
if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y):
game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' step into poisonous gas!', game.turns)
if 'poison' not in obj.entity.flags:
dice = util.roll_dice(1, 3)
if dice == 3:
obj.entity.flags.append('poison')
if game.current_map.tile[obj.x][obj.y]['type'] == 'sleep_gas':
if 'sleep' not in obj.entity.flags:
if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y):
game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' step into sleeping gas!', game.turns)
dice = util.roll_dice(1, 3)
if dice == 3:
if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y):
game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' falls asleep!', game.turns)
obj.entity.flags.append('sleep')
# fireball effect
def fireball(x, y, radius):
path = util.set_full_explore_map(game.current_map)
libtcod.dijkstra_compute(path, x, y)
for step in range(0, radius + 1):
player_fov = False
for i in range(-radius, radius + 1):
for j in range(-radius, radius + 1):
if libtcod.map_is_in_fov(game.fov_map, x + i, y + j) and libtcod.dijkstra_get_distance(path, x + i, y + j) <= step and libtcod.dijkstra_get_distance(path, x + i, y + j) >= 0:
(front, back, lerp) = util.render_tiles_animations(x + i, y + j, libtcod.Color(160, 0, 0), libtcod.Color(64, 0, 0), libtcod.Color(0, 0, 0), round(libtcod.random_get_float(game.rnd, 0, 1), 1))
libtcod.console_put_char_ex(0, game.MAP_X + x - game.curx + i, game.MAP_Y + y - game.cury + j, '*', front, back)
player_fov = True
if player_fov:
libtcod.console_flush()
time.sleep(0.05)
player_fov = False
for obj in game.current_map.objects:
damage = util.roll_dice(1, 10)
if obj.name == 'player':
if libtcod.dijkstra_get_distance(path, game.char.x, game.char.y) <= radius:
game.message.new('You are hit by a fireball for ' + str(damage) + ' pts of damage!', game.turns, libtcod.Color(160, 0, 0))
game.player.take_damage(damage, 'a fireball')
elif obj.entity:
if libtcod.dijkstra_get_distance(path, obj.x, obj.y) <= radius:
obj.entity.take_damage(obj.x, obj.y, damage, 'a fireball', True)
# missile attack animation
def missile_attack(sx, sy, dx, dy, trap=False):
cx, cy = sx, sy
if sx == dx:
char = '|'
if sy == dy:
char = chr(196)
if (sx < dx and sy > dy) or (sx > dx and sy < dy):
char = '/'
if (sx < dx and sy < dy) or (sx > dx and sy > dy):
char = '\\'
path = util.set_full_explore_map(game.current_map, False)
libtcod.path_compute(path, sx, sy, dx, dy)
while not libtcod.path_is_empty(path):
cx, cy = libtcod.path_walk(path, False)
libtcod.console_blit(game.con, 0, 0, game.MAP_WIDTH, game.MAP_HEIGHT, 0, game.MAP_X, game.MAP_Y)
libtcod.console_put_char_ex(0, game.MAP_X + cx - game.curx, game.MAP_Y + cy - game.cury, char, libtcod.light_gray, libtcod.black)
libtcod.console_flush()
time.sleep(0.05)
if trap:
for obj in game.current_map.objects:
if obj.x == dx and obj.y == dy and not obj.item:
damage = util.roll_dice(1, 6)
if obj.name == 'player':
game.message.new('You are hit by an arrow for ' + str(damage) + ' pts of damage!', game.turns, libtcod.Color(160, 0, 0))
game.player.take_damage(damage, 'an arrow trap')
else:
obj.entity.take_damage(obj.x, obj.y, damage, 'an arrow', True)
# poison gas effect
def poison_gas(x, y, radius, duration):
path = util.set_full_explore_map(game.current_map)
libtcod.dijkstra_compute(path, x, y)
for i in range(-radius, radius + 1):
for j in range(-radius, radius + 1):
if libtcod.dijkstra_get_distance(path, x + i, y + j) <= radius and libtcod.dijkstra_get_distance(path, x + i, y + j) >= 0:
game.current_map.tile[x + i][y + j].update({'icon': game.current_map.tile[x + i][y + j]['icon'], 'back_light_color': libtcod.Color(0, 224, 0), 'back_dark_color': libtcod.Color(0, 112, 0), 'lerp': round(libtcod.random_get_float(game.rnd, 0, 1), 1), 'duration': game.turns + duration, 'type': 'poison_gas'})
for obj in game.current_map.objects:
if obj.item is None:
if obj.x == x + i and obj.y == y + j:
if obj.name == 'player':
game.message.new('You are caught in a poisonous cloud!', game.turns)
if 'poison' not in game.player.flags:
dice = util.roll_dice(1, 50)
if dice > game.player.endurance + (game.player.karma / 2):
game.message.new('You are poisoned!', game.turns, libtcod.Color(0, 112, 0))
game.player.flags.append('poison')
else:
if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y):
game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' is caught in a poisonous cloud!', game.turns)
if 'poison' not in obj.entity.flags:
dice = util.roll_dice(1, 3)
if dice == 3:
obj.entity.flags.append('poison')
# poison needle effect
def poison_needle(x, y):
for obj in game.current_map.objects:
if obj.x == x and obj.y == y and not obj.item:
damage = util.roll_dice(1, 4)
if obj.name == 'player':
game.message.new('You are hit by a poison needle!', game.turns)
if 'poison' not in game.player.flags:
dice = util.roll_dice(1, 50)
if dice > game.player.endurance + (game.player.karma / 2):
game.message.new('You are poisoned!', game.turns, libtcod.Color(0, 112, 0))
game.player.flags.append('poison')
game.player.take_damage(damage, 'a poison needle')
else:
if 'poison' not in obj.entity.flags:
dice = util.roll_dice(1, 3)
if dice == 3:
obj.entity.flags.append('poison')
obj.entity.take_damage(obj.x, obj.y, damage, 'a poison needle')
# sleeping gas effect
def sleeping_gas(x, y, radius, duration):
path = util.set_full_explore_map(game.current_map)
libtcod.dijkstra_compute(path, x, y)
for i in range(-radius, radius + 1):
for j in range(-radius, radius + 1):
if libtcod.dijkstra_get_distance(path, x + i, y + j) <= radius and libtcod.dijkstra_get_distance(path, x + i, y + j) >= 0:
game.current_map.tile[x + i][y + j].update({'icon': game.current_map.tile[x + i][y + j]['icon'], 'back_light_color': libtcod.Color(115, 220, 225), 'back_dark_color': libtcod.Color(0, 143, 189), 'lerp': round(libtcod.random_get_float(game.rnd, 0, 1), 1), 'duration': game.turns + duration, 'type': 'sleep_gas'})
for obj in game.current_map.objects:
if obj.item is None:
if obj.x == x + i and obj.y == y + j:
if obj.name == 'player':
game.message.new('You are caught in a sleeping cloud!', game.turns)
if 'sleep' not in game.player.flags:
dice = util.roll_dice(1, 50)
if dice > game.player.wisdom + (game.player.karma / 2):
game.message.new('You fall asleep!', game.turns, libtcod.Color(0, 143, 189))
game.player.flags.append('sleep')
else:
if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y):
game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' is caught in a sleeping cloud!', game.turns)
if 'sleep' not in obj.entity.flags:
dice = util.roll_dice(1, 3)
if dice == 3:
if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y):
game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' falls asleep!', game.turns)
obj.entity.flags.append('sleep')
# victim becomes stuck
def stuck(x, y, victim='You'):
for obj in game.current_map.objects:
if obj.x == x and obj.y == y and not obj.item:
dice = util.roll_dice(1, 10)
if victim == 'You':
if 'stuck' not in game.player.flags:
game.player.flags.append('stuck')
game.message.new('You are stuck in a bear trap!', game.turns)
game.player.take_damage(dice, 'a bear trap')
else:
obj.entity.flags.append('stuck')
obj.entity.take_damage(obj.x, obj.y, dice, 'a bear trap')
if libtcod.map_is_in_fov(game.fov_map, x, y):
game.message.new(victim + ' is stuck in a bear trap!', game.turns)
elif not obj.entity.is_dead():
game.message.new('You hear a scream.', game.turns)
# teleports to a random location on the same map
def teleportation(x, y, victim='You'):
victims = []
for obj in game.current_map.objects:
if obj.x == x and obj.y == y:
victims.append(obj)
if (obj.entity and obj.entity.is_above_ground()) or (obj.name == 'player' and game.player.is_above_ground()):
victims.pop()
dx = libtcod.random_get_int(game.rnd, 0, game.current_map.map_width - 1)
dy = libtcod.random_get_int(game.rnd, 0, game.current_map.map_height - 1)
while game.current_map.tile_is_blocked(dx, dy):
dx = libtcod.random_get_int(game.rnd, 0, game.current_map.map_width - 1)
dy = libtcod.random_get_int(game.rnd, 0, game.current_map.map_height - 1)
for i in range(len(victims)):
victims[i].x = dx
victims[i].y = dy
if victim == 'You':
game.message.new('You just got teleported to a random location!', game.turns)
else:
if libtcod.map_is_in_fov(game.fov_map, x, y):
game.message.new(victim + ' just disappeared!', game.turns)
game.fov_recompute = True