-
Notifications
You must be signed in to change notification settings - Fork 1
/
traps.py
309 lines (278 loc) · 11.5 KB
/
traps.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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
__filename__ = "traps.py"
__author__ = "Bob Mottram"
__credits__ = [""]
__license__ = "AGPL3+"
__version__ = "1.0.0"
__maintainer__ = "Bob Mottram"
__email__ = "[email protected]"
__status__ = "Production"
__module_group__ = "DnD Mechanics"
import time
from random import randint
from functions import random_desc
from functions import time_string_to_sec
def teleport_from_trap(mud, id: int, players: {}, rooms: {}):
"""Teleport out of a trap
"""
plyr = players[id]
room_id = plyr['room']
if not rooms[room_id]['trap'].get('trappedPlayers'):
return
if plyr['name'] in rooms[room_id]['trap']['trappedPlayers']:
rooms[room_id]['trap']['trappedPlayers'].remove(plyr['name'])
if len(rooms[room_id]['trap']['trappedPlayers']) == 0:
rooms[room_id]['trap']['trapDamaged'] = 0
def describe_trapped_player(mud, id: int, players: {}, rooms: {}):
"""Describes being in a trap
"""
room_id = players[id]['room']
if not rooms[room_id]['trap'].get('trapType'):
return
trap_type = rooms[room_id]['trap']['trapType']
if trap_type == 'net':
desc = (
"You struggle with the net but it's pinning you down",
"You seem to be trapped in a net",
"Being covered by a net makes it difficult to move"
)
mud.send_message(id, random_desc(desc) + '.\n\n')
elif trap_type == 'chain net':
desc = (
"You struggle with the net but its chain webbing is " +
"pinning you down",
"You seem to be trapped in a net made from linked chains",
"Being covered by a chain net makes it difficult to move"
)
mud.send_message(id, random_desc(desc) + '.\n\n')
elif trap_type == 'tar pit':
desc = (
"You have sunk into a pit of sticky tar, " +
"which prevents you from moving",
"Sticky tar surrounds you, preventing you from moving"
)
mud.send_message(id, random_desc(desc) + '.\n\n')
elif trap_type == 'pit':
desc = (
"You have fallen into a pit in the ground, which you " +
"don't seem to be able to get out from",
"You appear to be in a hole in the ground"
)
mud.send_message(id, random_desc(desc) + '.\n\n')
elif trap_type in ('ditch', 'marsh', 'bog'):
desc = (
"You have fallen into a " + trap_type + " full of thick mud, " +
"which is too slippery to get out from",
"You appear to be swimming very slowly in a " +
trap_type + " full of thick mud"
)
mud.send_message(id, random_desc(desc) + '.\n\n')
def player_is_trapped(id: int, players: {}, rooms: {}):
"""Returns true if the player is trapped
"""
plyr = players[id]
room_id = plyr['room']
if rooms[room_id].get('trap'):
if rooms[room_id]['trap'].get('trappedPlayers'):
if plyr['name'] in rooms[room_id]['trap']['trappedPlayers']:
return True
return False
def _describe_trap_deactivation(mud, room_id: str, trap, players: {}):
"""Describes when a trap gets reset
"""
for pid, plyr in players.items():
if plyr['name'] is None:
continue
if plyr['room'] != room_id:
continue
if plyr['name'] not in trap['trappedPlayers']:
continue
if trap['trapType'] == 'net' or \
trap['trapType'] == 'chain net':
desc = 'The ' + trap['trapType'] + ' lifts and you escape'
mud.send_message(pid, random_desc(desc) + '.\n\n')
elif trap['trapType'] == 'pit' or trap['trapType'] == 'tar pit':
desc = 'You clamber out from the ' + \
trap['trapType']
mud.send_message(pid, random_desc(desc) + '.\n\n')
elif (trap['trapType'] == 'ditch' or trap['trapType'] == 'marsh' or
trap['trapType'] == 'bog'):
desc = 'With squelching noises, you climb out of the muddy ' + \
trap['trapType']
mud.send_message(pid, random_desc(desc) + '.\n\n')
def _holding_cutting_weapon(id: int, players: {}, items_db: {}):
"""If the player is holding a cutting weapon return its item_id
"""
plyr = players[id]
item_id = plyr['clo_rhand']
if item_id > 0:
if items_db[item_id]['type'].startswith('slashing'):
return item_id
item_id = plyr['clo_lhand']
if item_id > 0:
if items_db[item_id]['type'].startswith('slashing'):
return item_id
return -1
def _escape_with_cutting_tool(mud, id: int, players: {}, rooms: {},
items_db: {}):
"""Escape from a trap using a cutting tool
"""
item_id = _holding_cutting_weapon(id, players, items_db)
if item_id == -1:
desc = (
"You attempt to escape with your bare hands, " +
"but remain trapped|You tug and wrestle but can't escape",
"Looks like you need to use a cutting tool, otherwise " +
"you'll be here for a while",
"Looks like you need something to cut with"
)
mud.send_message(
id, random_desc(desc) + '.\n\n')
return
room_id = players[id]['room']
max_trap_damage = rooms[room_id]['trap']['trapDamagedMax']
tool_damage_max = items_db[item_id]['mod_str']
slashing_damage = randint(1, tool_damage_max)
trap_damage = \
rooms[room_id]['trap']['trapDamaged'] + slashing_damage
if trap_damage < max_trap_damage:
rooms[room_id]['trap']['trapDamaged'] = trap_damage
damage_str = ', causing <f15><b2>* ' + str(slashing_damage) + \
' *<r> points of damage to it'
desc = 'You slash at the ' + rooms[room_id]['trap']['trapType'] + \
damage_str + '|You cut the ' + \
rooms[room_id]['trap']['trapType'] + damage_str
mud.send_message(id, random_desc(desc) + '.\n\n')
else:
rooms[room_id]['trap']['trapDamaged'] = 0
rooms[room_id]['trap']['trappedPlayers'].clear()
if len(rooms[room_id]['trap']['trapEscapeDescription']) > 0:
desc = rooms[room_id]['trap']['trapEscapeDescription']
mud.send_message(id, random_desc(desc) + '.\n\n')
else:
desc = 'You cut a large hole in the ' + \
rooms[room_id]['trap']['trapType'] + ' and escape'
mud.send_message(
id, random_desc(desc) + '.\n\n')
def escape_from_trap(mud, id: int, players: {}, rooms: {}, items_db: {}):
"""Attempt to escape from a trap
"""
room_id = players[id]['room']
if not rooms[room_id]['trap'].get('trapEscapeMethod'):
mud.send_message(
id, random_desc("Nothing happens") + '.\n\n')
return
escape_method = rooms[room_id]['trap']['trapEscapeMethod']
if 'slash' in escape_method:
_escape_with_cutting_tool(mud, id, players, rooms, items_db)
else:
mud.send_message(
id, random_desc("Nothing happens") + '.\n\n')
def _trap_activation_describe(mud, id: int, players: {},
room_id: str, rooms: {},
penalty_value: str, trap_tag: str):
trap_type = rooms[room_id]['trap']['trapType']
if trap_type in ('net', 'chain net'):
if rooms[room_id]['trap']['trap_activation'].startswith('pressure'):
desc = (
trap_tag +
"You hear a click as you step onto a pressure plate. A " +
trap_type + " falls from above and pins you down"
)
mud.send_message(id, random_desc(desc) + '.<r>\n\n')
else:
desc = (
trap_tag + "A " + trap_type +
" falls from above and pins you down"
)
mud.send_message(id, random_desc(desc) + '.<r>\n\n')
elif trap_type in ('pit', 'tar pit'):
desc = (
trap_tag + "You fall into a " + trap_type
)
mud.send_message(id, random_desc(desc) + '.<r>\n\n')
elif trap_type in ('ditch', 'marsh', 'bog'):
desc = (
trap_tag + "You fall into a muddy " + trap_type,
trap_tag + "You slip and fall into a muddy " + trap_type
)
mud.send_message(id, random_desc(desc) + '.<r>\n\n')
elif trap_type.startswith('dart'):
desc = (
trap_tag +
"Poisoned darts emerge from holes in the wall and " +
"sting you for <r><f15><b88>* " + str(penalty_value) +
" *<r>" + trap_tag + " hit points"
)
mud.send_message(id, random_desc(desc) + '.<r>\n\n')
def trap_activation(mud, id: int, players: {}, rooms: {},
exit_direction: str) -> bool:
"""Activates a trap
"""
room_id = players[id]['room']
if not rooms[room_id]['trap'].get('trap_activation'):
return False
# Is the trap already activated?
if rooms[room_id]['trap']['trap_activationTime'] != 0:
return False
trap_tag = '<f202>'
# recognised activation type
activation_type = rooms[room_id]['trap']['trap_activation']
if not (activation_type == 'tripwire' or
activation_type.startswith('move') or
activation_type.startswith('pressure')):
return False
# probability of the trap being activated
prob = 100
if rooms[room_id]['trap'].get('trap_activationProbability'):
prob = rooms[room_id]['trap']['trap_activationProbability']
rand_percent = randint(1, 100)
if rand_percent > prob:
return False
# which exit activates the trap?
if not rooms[room_id]['trap'].get('trapExit'):
return False
# are we going in that direction?
if rooms[room_id]['trap']['trapExit'] != exit_direction:
return False
# add player to the list of trapped ones
rooms[room_id]['trap']['trappedPlayers'] = [players[id]['name']]
# record the time when the trap was activated
if time_string_to_sec(rooms[room_id]['trap']['trapDuration']) > 0:
rooms[room_id]['trap']['trap_activationTime'] = \
int(time.time())
# reset the amount of damage to the trap
rooms[room_id]['trap']['trapDamaged'] = 0
# subtract a trap penalty from the player
penalty_type = rooms[room_id]['trap']['trapPenaltyType']
penalty_value = randint(1, rooms[room_id]['trap']['trapPenalty'])
players[id][penalty_type] -= penalty_value
# describe the trapped player
if len(rooms[room_id]['trap']['trap_activationDescription']) > 0:
desc = rooms[room_id]['trap']['trap_activationDescription']
mud.send_message(id, trap_tag +
random_desc(desc) + '.<r>\n\n')
else:
_trap_activation_describe(mud, id, players, room_id, rooms,
penalty_value, trap_tag)
return True
def run_traps(mud, rooms: {}, players: {}, npcs: {}):
"""Update the status of any traps
"""
for room_id, room in rooms.items():
if not room['trap'].get('trappedPlayers'):
continue
if len(room['trap']['trappedPlayers']) == 0:
continue
if not room.get('trapDuration'):
continue
if room['trap']['trap_activationTime'] == 0:
continue
now = int(time.time())
if now >= \
room['trap']['trap_activationTime'] + \
time_string_to_sec(room['trap']['trapDuration']):
_describe_trap_deactivation(mud, room_id,
room['trap'], players)
room['trap']['trappedPlayers'].clear()
room['trap']['trap_activationTime'] = 0
room['trap']['trapDamaged'] = 0