d809b92a by Barry

Added full combat, spawner, emotes, actions, casting spells, perform,

spells, help for spells and other commands
1 parent 2f3e968d
...@@ -11,6 +11,9 @@ global_aliases = { ...@@ -11,6 +11,9 @@ global_aliases = {
11 '\'': 'say', 11 '\'': 'say',
12 'i': 'inventory', 12 'i': 'inventory',
13 'inv': 'inventory', 13 'inv': 'inventory',
14 'attack': 'kill',
15 ',': 'emote',
16 'social': 'emote'
14 } 17 }
15 18
16 class CommandHandler(object): 19 class CommandHandler(object):
...@@ -36,6 +39,12 @@ class CommandHandler(object): ...@@ -36,6 +39,12 @@ class CommandHandler(object):
36 if cmd in utils.load_object_from_file('rooms/' + players[id]["room"] + '.json').get('exits'): 39 if cmd in utils.load_object_from_file('rooms/' + players[id]["room"] + '.json').get('exits'):
37 params = cmd + " " + params.lower().strip() 40 params = cmd + " " + params.lower().strip()
38 cmd = "go" 41 cmd = "go"
42 if cmd in players[id]["sp"]:
43 params = cmd + " " + params.lower().strip()
44 cmd = "cast"
45 if cmd in players[id]["at"]:
46 params = cmd + " " + params.lower().strip()
47 cmd = "perform"
39 if cmd == '': 48 if cmd == '':
40 return True 49 return True
41 command = cmd 50 command = cmd
......
1 def actions(id, players, mud):
2 mud.send_message(id, '\r\n-Action----------=Actions=-----------Cost-\r\n')
3 for name, action in players[id]['at'].items():
4 mud.send_message(id, '{} {}'.format("%-37s" % name, action['cost']))
5 mud.send_message(id, '\r\n------------------------------------------\r\n')
6 mud.send_message(id, 'For more detail on a specific action use "help <action>"')
7
8
9 actions(id, players, mud)
10 del actions
...\ No newline at end of file ...\ No newline at end of file
1 import utils
2
3 # for now spells can only be cast on the thing you are fighting since I don't have a good lexer to pull
4 # out targets. This also means that spells are offensive only since you cant cast on 'me'
5 # TODO: Add proper parsing so you can do: cast fireball on turkey or even better, cast fireball on the first turkey
6 def cast(id, params, players, mud, command):
7 if params == '':
8 params = command.strip()
9 else:
10 params = params.strip()
11 if len(params) == 0:
12 mud.send_message(id, 'What spell do you want to cast?')
13 return True
14 spell = players[id]['sp'].get(params)
15 if not spell:
16 mud.send_message(id, 'You do not appear to know how to cast %s.' % (params,))
17 return True
18 mp = players[id]['mp']
19 if mp > 0 and mp > spell['cost']:
20 room_monsters = utils.load_object_from_file('rooms/{}_monsters.json'.format(players[id]['room']))
21 if not room_monsters:
22 mud.send_message(id, 'There is nothing here to cast that spell on.')
23 for mon_name, monster in room_monsters.items():
24 monster_template = utils.load_object_from_file('mobs/{}.json'.format(mon_name))
25 if not monster_template:
26 continue
27 fighting = False
28 for active_monster_idx, active_monster in enumerate(monster['active']):
29 if active_monster['action'] == "attack" and active_monster['target'] == players[id]['name']:
30 fighting = True
31 att, mp = utils.calc_att(mud, id, [], mp, spell)
32
33 players[id]['mp'] = mp
34 active_monster['hp'] -= att
35 # don't let them off without saving cheating sons of bees
36 utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
37 room_monsters[mon_name]['active'][active_monster_idx] = active_monster
38 if not fighting:
39 mud.send_message(id, 'You are not currently in combat')
40 return True
41
42 utils.save_object_to_file(room_monsters, 'rooms/{}_monsters.json'.format(players[id]['room']))
43 else:
44 mud.send_message(id, 'You do not have enough mana to cast that spell.')
45
46 if command is None and cmd is not None:
47 command = cmd
48 cast(id, params.strip(), players, mud, command)
49 del cast
...\ No newline at end of file ...\ No newline at end of file
1 def emote(id, params, players, mud):
2 # go through every player in the game
3 for pid, pl in players.items():
4 # if they're in the same room as the player
5 if players[pid]["room"] == players[id]["room"]:
6 # send them a message telling them what the player said
7 mud.send_message(pid, "{} {}".format(players[id]["name"], params))
8
9 emote(id, params, players, mud)
10 del emote
...\ No newline at end of file ...\ No newline at end of file
1
2 def kill(id, params, players, mud):
3 if len(params) == 0:
4 mud.send_message(id, 'What did you want to attack?')
5 return True
6 room_monsters = utils.load_object_from_file('rooms/{}_monsters.json'.format(players[id]['room']))
7 for mon_name, monster in room_monsters.items():
8 if mon_name in params.lower():
9 if len(monster['active']) > 0:
10 if monster['active'][0]['target'] == players[id]['name']:
11 mud.send_message(id, 'You are already engaged in combat with that target.')
12 return True
13 else:
14 room_monsters[mon_name]['active'][0]['target'] = players[id]['name']
15 mud.send_message(id, 'You attack the {}.'.format(mon_name), color=['red', 'bold'])
16 utils.save_object_to_file(room_monsters, 'rooms/{}_monsters.json'.format(players[id]['room']))
17 return True
18 if params[0] in 'aeiou':
19 mud.send_message(id, 'You do not see an {} here.'.format(params))
20 else:
21 mud.send_message(id, 'You do not see a {} here.'.format(params))
22
23 kill(id, params, players, mud)
24 del kill
...\ No newline at end of file ...\ No newline at end of file
1 def look(id, mud, players, tokens): 1 def look(id, mud, players, tokens):
2 room_name = players[id]["room"] 2 room_name = players[id]["room"]
3 room_data = utils.load_object_from_file('rooms/' + room_name + '.json') 3 room_data = utils.load_object_from_file('rooms/' + room_name + '.json')
4 room_monsters = utils.load_object_from_file('rooms/' + room_name + '_monsters.json')
4 mud.send_message(id, "") 5 mud.send_message(id, "")
5 if len(tokens) > 0 and tokens[0] == 'at': 6 if len(tokens) > 0 and tokens[0] == 'at':
6 del tokens[0] 7 del tokens[0]
...@@ -21,7 +22,14 @@ def look(id, mud, players, tokens): ...@@ -21,7 +22,14 @@ def look(id, mud, players, tokens):
21 item = utils.load_object_from_file('inventory/' + subject + '.json') 22 item = utils.load_object_from_file('inventory/' + subject + '.json')
22 mud.send_message(id, 'You check your inventory and see {}'.format(item.get('description'))) 23 mud.send_message(id, 'You check your inventory and see {}'.format(item.get('description')))
23 return True 24 return True
25 if subject in room_monsters:
26 if len(room_monsters[subject]['active']) > 0:
27 monster_template = utils.load_object_from_file('mobs/{}.json'.format(subject))
28 if monster_template:
29 mud.send_message(id, 'You see {}'.format(monster_template.get('desc').lower()))
30 return True
24 mud.send_message(id, "That doesn't seem to be here.") 31 mud.send_message(id, "That doesn't seem to be here.")
32 return
25 33
26 playershere = [] 34 playershere = []
27 # go through every player in the game 35 # go through every player in the game
...@@ -29,22 +37,28 @@ def look(id, mud, players, tokens): ...@@ -29,22 +37,28 @@ def look(id, mud, players, tokens):
29 # if they're in the same room as the player 37 # if they're in the same room as the player
30 if players[pid]["room"] == players[id]["room"]: 38 if players[pid]["room"] == players[id]["room"]:
31 # ... and they have a name to be shown 39 # ... and they have a name to be shown
32 if players[pid]["name"] is not None: 40 if players[pid]["name"] is not None and players[id]["name"] != players[pid]["name"]:
33 # add their name to the list 41 # add their name to the list
34 playershere.append(players[pid]["name"]) 42 playershere.append(players[pid]["name"])
35 43
36 # send player a message containing the list of players in the room 44 # send player a message containing the list of players in the room
37 mud.send_message(id, "Players here: {}".format(", ".join(playershere))) 45 if len(playershere) > 0:
46 mud.send_message(id, "Players here: {}".format(", ".join(playershere)))
38 47
39 # send player a message containing the list of exits from this room 48 # send player a message containing the list of exits from this room
40 mud.send_message(id, "Exits are: {}".format(", ".join(room_data.get('exits')))) 49 mud.send_message(id, "Exits are: {}".format(", ".join(room_data.get('exits'))))
41 50
42 # send player a message containing the list of exits from this room 51 # send player a message containing the list of exits from this room
43 mud.send_message(id, "Items here: {}".format(", ".join(room_data.get('inventory').keys()))) 52 if len(room_data.get('inventory').keys()) > 0:
53 mud.send_message(id, "Items here: {}".format(", ".join(room_data.get('inventory').keys())))
44 54
45 # send player a message containing the list of players in the room 55 # send player a message containing the list of players in the room
46 room_monsters = utils.load_object_from_file('rooms/' + room_name + '_monsters.json') 56 for mon_name, monster in room_monsters.items():
47 mud.send_message(id, "Mobs here: {}".format( ", ".join(room_monsters.keys()))) 57 count = len(monster['active'])
58 if count > 1:
59 mud.send_message(id, "{} {} are here.".format(count, mon_name))
60 elif count > 0:
61 mud.send_message(id, "a {} is here.".format(mon_name))
48 62
49 look(id, mud, players, tokens) 63 look(id, mud, players, tokens)
50 del look 64 del look
...\ No newline at end of file ...\ No newline at end of file
......
1 import utils
2
3 # for now actions can only be cast on the thing you are fighting since I don't have a good lexer to pull
4 # out targets. This also means that actions are offensive only since you cant cast on 'me'
5 # TODO: Add proper parsing so you can do: cast fireball on turkey or even better, cast fireball on the first turkey
6 def perform(id, params, players, mud, command):
7 if params == '':
8 params = command.strip()
9 else:
10 params = params.strip()
11 if len(params) == 0:
12 mud.send_message(id, 'What action do you want to perform?')
13 return True
14 action = players[id]['at'].get(params)
15 if not action:
16 mud.send_message(id, 'You do not appear to know the action %s.' % (params,))
17 return True
18 sta = players[id]['sta']
19 if sta > 0 and sta > action['cost']:
20 room_monsters = utils.load_object_from_file('rooms/{}_monsters.json'.format(players[id]['room']))
21 if not room_monsters:
22 mud.send_message(id, 'There is nothing here to perform that action on.')
23 for mon_name, monster in room_monsters.items():
24 monster_template = utils.load_object_from_file('mobs/{}.json'.format(mon_name))
25 if not monster_template:
26 continue
27 fighting = False
28 for active_monster_idx, active_monster in enumerate(monster['active']):
29 if active_monster['action'] == "attack" and active_monster['target'] == players[id]['name']:
30 fighting = True
31 att, sta = utils.calc_att(mud, id, [], sta, action)
32
33 players[id]['sta'] = sta
34 active_monster['hp'] -= att
35 # don't let them off without saving cheating sons of bees
36 utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
37 room_monsters[mon_name]['active'][active_monster_idx] = active_monster
38 if not fighting:
39 mud.send_message(id, 'You are not currently in combat')
40 return True
41
42 utils.save_object_to_file(room_monsters, 'rooms/{}_monsters.json'.format(players[id]['room']))
43 else:
44 mud.send_message(id, 'You do not have enough stamina to perform that action.')
45
46 if command is None and cmd is not None:
47 command = cmd
48 perform(id, params.strip(), players, mud, command)
49 del perform
...\ No newline at end of file ...\ No newline at end of file
1 def spells(id, players, mud):
2 mud.send_message(id, '\r\n-Spell-----------=Spells=-----------Cost-\r\n')
3 for name, spell in players[id]['sp'].items():
4 mud.send_message(id, '{} {}'.format("%-37s" % name, spell['cost']))
5 mud.send_message(id, '\r\n-----------------------------------------\r\n')
6 mud.send_message(id, 'For more detail on a specific spell use "help <spell>"')
7
8
9 spells(id, players, mud)
10 del spells
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
5 "prompt": "hp %hp mp %mp> ", 5 "prompt": "hp %hp mp %mp> ",
6 "aliases": {}, 6 "aliases": {},
7 "hp": 100, 7 "hp": 100,
8 "mp": 100, 8 "mp": 10,
9 "maxhp": 100, 9 "maxhp": 100,
10 "maxmp": 100, 10 "maxmp": 10,
11 "maxsta": 10, 11 "maxsta": 10,
12 "sta": 10, 12 "sta": 10,
13 "aa": "1d2", 13 "aa": "1d2",
...@@ -15,5 +15,7 @@ ...@@ -15,5 +15,7 @@
15 "star": 0.4, 15 "star": 0.4,
16 "weapon": null, 16 "weapon": null,
17 "sp": {}, 17 "sp": {},
18 "at": {} 18 "at": {
19 "kick": {"cost":5, "dmg": "2d4", "desc": "You unleash a powerful kick"}
20 }
19 } 21 }
...\ No newline at end of file ...\ No newline at end of file
......
1 Command:
2 actions
3
4 Usage:
5 actions
6
7 Description:
8 List all actions and the perform cost in stamina points (sta).
9
10 See Also:
11 perform
12 cast
13 spells
14 examine
...\ No newline at end of file ...\ No newline at end of file
...@@ -13,3 +13,8 @@ Default Aliases: ...@@ -13,3 +13,8 @@ Default Aliases:
13 d: down 13 d: down
14 l: look 14 l: look
15 ': say 15 ': say
16 ,: emote
17 i: inventory
18 inv: inventory
19 attack: kill
20 social: emote
......
1 Command:
2 cast
3
4 Usage:
5 cast <spell>
6
7 Short Form:
8 <spell>
9
10 Description:
11 The cast command invokes a magic spell that you have learned and is in your list of spells. Magic requires the use of your mana points (mp) which is slowly regenerated. Spells may only be cast if you have the required mana even if you know the spell.
12
13 You may also call spells by their name directly,
14 e.g. > fireball
15
16 See Also:
17 spells
18 perform
19 examine
...\ No newline at end of file ...\ No newline at end of file
1 Command:
2 drop
3
4 Usage:
5 drop <item>
6
7 Description:
8 Drops an item in your inventory in the current room.
9
10 See Also:
11 inventory
12 get
13 look
1 Command:
2 emote
3
4 Usage:
5 emote <description>
6 , <description>
7 social <description>
8
9 Description:
10 The command causes you to display an action. You can use this to perform a role played action within a room.
11
12 Example:
13 emote smiles broadly
14
15 This will appear as:
16
17 Joe smiles broadly
1 Spell:
2 fireball
3
4 Usage:
5 cast fireball
6
7 Short Form:
8 fireball
9
10 Description:
11 A fireball explodes out from your fingertips on demand and blisters through the air at your target bursting into a ball of flame on contact.
12
13 See Also:
14 spells
15 cast
1 Command:
2 get
3
4 Usage:
5 get <item>
6
7 Description:
8 Picks up an item in the current room and adds it to your inventory.
9
10 See Also:
11 inventory
12 drop
13 look
...@@ -4,6 +4,9 @@ Command: ...@@ -4,6 +4,9 @@ Command:
4 Usage: 4 Usage:
5 go <exit> 5 go <exit>
6 6
7 Short Form:
8 <exit>
9
7 Description: 10 Description:
8 The go command moves through the exit specified. Common exits are 11 The go command moves through the exit specified. Common exits are
9 north, south, east, west, up, and down. Normally the exits will 12 north, south, east, west, up, and down. Normally the exits will
......
...@@ -2,11 +2,19 @@ Additional information can be learned about a command by passing a command: help ...@@ -2,11 +2,19 @@ Additional information can be learned about a command by passing a command: help
2 2
3 Help Topics: 3 Help Topics:
4 4
5 actions
5 aliases 6 aliases
7 cast
8 drop
9 get
6 go 10 go
11 inventory
7 look 12 look
13 perform
14 prompt
8 quit 15 quit
9 save 16 save
10 whisper
11 say 17 say
18 spells
19 whisper
12 who 20 who
......
1 Command:
2 inventory
3
4 Aliases:
5 i
6 inv
7
8 Usage:
9 inventory
10
11 Description:
12 List all inventory and the quantity of each item.
13
14 See Also:
15 get
16 drop
1 Action:
2 kick
3
4 Usage:
5 perform kick
6
7 Short Form:
8 kick
9
10 Description:
11 Your foot snaps out at the current target causing blunt damage.
12
13 See Also:
14 actions
15 perform
1 Command:
2 perform
3
4 Usage:
5 perform <action>
6
7 Short Form:
8 <action>
9
10 Description:
11 The perform an action that you have learned and is in your list of actions. Special actions require the use of your stamina points (sta) which is slowly regenerated. Special actions may only be performed if you have the required stamina even if you know the action.
12
13 You may also perform actions by their name directly,
14 e.g. > kick
15
16 See Also:
17 actions
18 spells
19 cast
20 examine
...\ No newline at end of file ...\ No newline at end of file
1 Command:
2 spells
3
4 Usage:
5 spells
6
7 Description:
8 List all spells and the casting cost in mana points (mp).
9
10 See Also:
11 cast
12 perform
13 actions
14 examine
...\ No newline at end of file ...\ No newline at end of file
1 Spell:
2 zap
3
4 Usage:
5 cast zap
6
7 Short Form:
8 zap
9
10 Description:
11 A spark leaps out and strikes the target causing burning and electric damage.
12
13 See Also:
14 spells
15 cast
...@@ -15,6 +15,7 @@ if 'esp' in platform: ...@@ -15,6 +15,7 @@ if 'esp' in platform:
15 from mudserver import MudServer 15 from mudserver import MudServer
16 16
17 from utils import load_object_from_file, save_object_to_file 17 from utils import load_object_from_file, save_object_to_file
18 from math import floor
18 19
19 print('STARTING MUD\r\n\r\n\r\n') 20 print('STARTING MUD\r\n\r\n\r\n')
20 21
...@@ -37,7 +38,7 @@ def show_prompt(pid): ...@@ -37,7 +38,7 @@ def show_prompt(pid):
37 if 'sta' not in players[pid]: 38 if 'sta' not in players[pid]:
38 players[pid]["sta"] = 10 39 players[pid]["sta"] = 10
39 40
40 prompt = players[pid]["prompt"].replace('%hp', str(players[pid]["hp"])).replace('%mp', str(players[pid]["mp"])) 41 prompt = players[pid]["prompt"].replace('%st', str(floor(players[pid]['sta']))).replace('%hp', str(floor(players[pid]["hp"]))).replace('%mp', str(floor(players[pid]["mp"])))
41 mud.send_message(pid, "\r\n" + prompt, '') 42 mud.send_message(pid, "\r\n" + prompt, '')
42 43
43 tick = 0.0 44 tick = 0.0
...@@ -54,7 +55,7 @@ while True: ...@@ -54,7 +55,7 @@ while True:
54 tick += 0.001 55 tick += 0.001
55 else: 56 else:
56 tick += 0.0005 57 tick += 0.0005
57 if spawn >= 30: 58 if spawn >= 10:
58 spawn = 0 59 spawn = 0
59 try: 60 try:
60 ldict = {} 61 ldict = {}
......
...@@ -5,6 +5,10 @@ def run_mobs(players, mud): ...@@ -5,6 +5,10 @@ def run_mobs(players, mud):
5 for pid, player in players.items(): 5 for pid, player in players.items():
6 if not player['name']: 6 if not player['name']:
7 continue 7 continue
8 if player['mp'] < player['maxmp']:
9 players[pid]['mp'] += player['mpr']
10 if player['sta'] < player['maxsta']:
11 players[pid]['sta'] += player['star']
8 room_monsters = load_object_from_file('rooms/{}_monsters.json'.format(player['room'])) 12 room_monsters = load_object_from_file('rooms/{}_monsters.json'.format(player['room']))
9 if not room_monsters: 13 if not room_monsters:
10 continue 14 continue
...@@ -26,20 +30,23 @@ def run_mobs(players, mud): ...@@ -26,20 +30,23 @@ def run_mobs(players, mud):
26 if player.get("weapon"): 30 if player.get("weapon"):
27 weapon = load_object_from_file('inventory/{}.json'.format(player['weapon'])) 31 weapon = load_object_from_file('inventory/{}.json'.format(player['weapon']))
28 att = get_att(weapon['damage']) 32 att = get_att(weapon['damage'])
29 mud.send_message(pid, "Your %s strikes the %s for %d" % (weapon['title'], mon_name, att,)) 33 mud.send_message(pid, "Your %s strikes the %s for %d" % (weapon['title'], mon_name, att,), color='yellow')
30 else: 34 else:
31 att = get_att(player['aa']) 35 att = get_att(player['aa'])
32 mud.send_message(pid, "You hit the %s for %d" % (mon_name, att,)) 36 mud.send_message(pid, "You hit the %s for %d" % (mon_name, att,), color='yellow')
33 hp -= att 37 hp -= att
34 if hp == 0: 38 if hp <= 0:
35 DEAD = 1 39 del room_monsters[mon_name]['active'][active_monster_idx]
40 mud.send_message(pid, "The %s dies." % (mon_name,), color=['bold', 'blue'])
41 # TODO: Create a corpse
42 break
36 if active_monster.get("weapon"): 43 if active_monster.get("weapon"):
37 weapon = load_object_from_file('inventory/{}.json'.format(active_monster['weapon'])) 44 weapon = load_object_from_file('inventory/{}.json'.format(active_monster['weapon']))
38 att = get_att(weapon['damage']) 45 att = get_att(weapon['damage'])
39 mud.send_message(pid, "The %s strikes you with a %s for %d" % (mon_name, weapon['title'], att,)) 46 mud.send_message(pid, "The %s strikes you with a %s for %d" % (mon_name, weapon['title'], att,), color='magenta')
40 else: 47 else:
41 att = get_att(monster_template['aa']) 48 att = get_att(monster_template['aa'])
42 mud.send_message(pid, "You were hit by a %s for %d" % (mon_name, att,)) 49 mud.send_message(pid, "You were hit by a %s for %d" % (mon_name, att,), color='magenta')
43 players[pid]['hp'] -= att 50 players[pid]['hp'] -= att
44 # wait until at least 50% of stamina or mp are regenerated or hp is less than 25% 51 # wait until at least 50% of stamina or mp are regenerated or hp is less than 25%
45 52
......
...@@ -12,7 +12,7 @@ import socket ...@@ -12,7 +12,7 @@ import socket
12 import select 12 import select
13 import time 13 import time
14 import sys 14 import sys
15 15 from utils import get_color
16 16
17 class MudServer(object): 17 class MudServer(object):
18 """A basic server for text-based Multi-User Dungeon (MUD) games. 18 """A basic server for text-based Multi-User Dungeon (MUD) games.
...@@ -181,7 +181,7 @@ class MudServer(object): ...@@ -181,7 +181,7 @@ class MudServer(object):
181 # return the info list 181 # return the info list
182 return retval 182 return retval
183 183
184 def send_message(self, to, message, line_ending='\r\n'): 184 def send_message(self, to, message, line_ending='\r\n', color=None):
185 """Sends the text in the 'message' parameter to the player with 185 """Sends the text in the 'message' parameter to the player with
186 the id number given in the 'to' parameter. The text will be 186 the id number given in the 'to' parameter. The text will be
187 printed out in the player's terminal. 187 printed out in the player's terminal.
...@@ -190,7 +190,14 @@ class MudServer(object): ...@@ -190,7 +190,14 @@ class MudServer(object):
190 # message on its own line 190 # message on its own line
191 chunks, chunk_size = len(message), 80 #len(x)/4 191 chunks, chunk_size = len(message), 80 #len(x)/4
192 lines = [ message[i:i+chunk_size] for i in range(0, chunks, chunk_size) ] 192 lines = [ message[i:i+chunk_size] for i in range(0, chunks, chunk_size) ]
193 self._attempt_send(to, '\r\n'.join(lines) + line_ending) 193 if color:
194 if isinstance(color, list):
195 colors = ''.join([get_color(c) for c in color])
196 self._attempt_send(to, colors + '\r\n'.join(lines) + line_ending + get_color('reset'))
197 else:
198 self._attempt_send(to, get_color(color) + '\r\n'.join(lines) + line_ending + get_color('reset'))
199 else:
200 self._attempt_send(to, '\r\n'.join(lines) + line_ending)
194 201
195 def shutdown(self): 202 def shutdown(self):
196 """Closes down the server, disconnecting all clients and 203 """Closes down the server, disconnecting all clients and
......
1 {"name": "test", "room": "Tavern", "inventory": {"candle": 1}, "prompt": "hp %hp mp %mp> ", "aliases": {}, "hp": 461, "mp": 50, "sta": 10, "aa": "1d2", "mpr": 0.25, "star": 0.4, "maxhp": 953, "maxmp": 100, "maxsta": 10, "weapon": "sword", "sp": {"fireball": {"cost": 5, "dmg": "2d4", "desc": "A fireball blasts from your fingertips striking the target"}}, "at": {}}
...\ No newline at end of file ...\ No newline at end of file
1 {"name": "test", "room": "Room001", "inventory": {"candle": 1}, "prompt": "h %hp m %mp s %st> ", "aliases": {}, "hp": 100, "mp": 10.0, "sta": 10.200000000000031, "aa": "1d2", "mpr": 0.25, "star": 0.4, "maxhp": 953, "maxmp": 10, "maxsta": 10, "weapon": "sword", "sp": {"fireball": {"cost": 5, "dmg": "2d4", "desc": "A fireball blasts from your fingertips striking the target"}}, "at": {"kick": {"cost": 5, "dmg": "2d4", "desc": "You unleash a powerful kick"}}}
...\ No newline at end of file ...\ No newline at end of file
......
1 { 1 {"title": "Behind the bar", "description": "The back of the bar gives a full view of the tavern. The bar top is a large wooden plank thrown across some barrels.", "exits": {"tavern": "Tavern"}, "look_items": {"bar": "The bar is a long wooden plank thrown over roughly hewn barrels.", "barrel,barrels": "The old barrels bands are thick with oxidation and stained with the purple of spilled wine.", "wooden,oak,plank": "An old solid oak plank that has a large number of chips and drink marks."}, "inventory": {}}
2 "title": "Behind the bar",
3 "description": "The back of the bar gives a full view of the tavern. The bar top is a large wooden plank thrown across some barrels.",
4 "exits": {"tavern": "Tavern"},
5 "look_items": {
6 "bar": "The bar is a long wooden plank thrown over roughly hewn barrels.",
7 "barrel,barrels": "The old barrels bands are thick with oxidation and stained with the purple of spilled wine.",
8 "wooden,oak,plank": "An old solid oak plank that has a large number of chips and drink marks."
9 },
10 "inventory": {}
11 }
...\ No newline at end of file ...\ No newline at end of file
......
1 {}
...\ No newline at end of file ...\ No newline at end of file
1 {"cricket": {"max": 1, "active": [{"mp": 10, "maxhp": 3, "hp": 3, "sta": 10, "maxmp": 10, "target": "", "action": "attack", "maxsta": 10}]}}
...\ No newline at end of file ...\ No newline at end of file
......
1 {"cricket": {"max": 1, "active": [{"hp": 48, "mp": 5.0, "sta": 0.35000000000008313, "maxhp": 100, "maxmp": 10, "maxsta": 10, "action": "attack", "target": "test"}]}}
...\ No newline at end of file ...\ No newline at end of file
1 {"cricket": {"max": 2, "active": [{"mp": 10, "maxhp": 3, "hp": 3, "sta": 10, "maxmp": 10, "target": "", "action": "attack", "maxsta": 10}, {"mp": 10, "maxhp": 3, "hp": 3, "sta": 10, "maxmp": 10, "target": "", "action": "attack", "maxsta": 10}]}}
...\ No newline at end of file ...\ No newline at end of file
......
1 def spawn_mobs(players): 1 def spawn_mobs(players):
2 for pid, player in players.items(): 2 from os import listdir
3 print('checking spawn in room: ' + player['room']) 3 from utils import get_att
4 rooms = listdir('rooms')
5 for room in rooms:
6 if '_monsters.json' not in room:
7 continue
8 room_monsters = load_object_from_file('rooms/{}'.format(room))
9 for mon_name, monster in room_monsters.items():
10 monster_template = load_object_from_file('mobs/{}.json'.format(mon_name))
11 if not monster_template:
12 continue
13 while len(room_monsters[mon_name]['active']) < monster['max']:
14 print('Spawning {} in {}'.format(mon_name, room))
15 mp = get_att(monster_template['spawn']["mp"])
16 hp = get_att(monster_template['spawn']["hp"])
17 sta = get_att(monster_template['spawn']["sta"])
18 new_active = {
19 "mp": mp,
20 "maxhp": hp,
21 "hp": hp,
22 "sta": sta,
23 "maxmp": mp,
24 "target": "",
25 "action": "attack",
26 "maxsta": sta}
27 room_monsters[mon_name]['active'].append(new_active)
28 for pid, pl in players.items():
29 if players[pid]['room'].lower() == room.split('_')[0]:
30 mud.send_message(pid, "a {} arrived".format(mon_name))
31 save_object_to_file(room_monsters, 'rooms/{}'.format(room))
4 32
5 spawn_mobs(players) 33 spawn_mobs(players)
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -5,6 +5,19 @@ if 'esp' in sys.platform: ...@@ -5,6 +5,19 @@ if 'esp' in sys.platform:
5 else: 5 else:
6 import random 6 import random
7 7
8
9 def get_color(name):
10 CODES = {'resetall': 0, 'bold': 1, 'underline': 4,
11 'blink': 5, 'reverse': 7, 'boldoff': 22,
12 'blinkoff': 25, 'underlineoff': 24, 'reverseoff': 27,
13 'reset': 0, 'black': 30, 'red': 31, 'green': 32,
14 'yellow': 33, 'blue': 34, 'magenta': 35, 'cyan': 36,
15 'white':37}
16 if name not in CODES:
17 return ''
18 return '\x1b[{}m'.format(CODES.get(name, 0))
19
20
8 def save_object_to_file(obj, filename): 21 def save_object_to_file(obj, filename):
9 with open(filename, 'w', encoding='utf-8') as f: 22 with open(filename, 'w', encoding='utf-8') as f:
10 f.write(json.dumps(obj)) 23 f.write(json.dumps(obj))
...@@ -61,6 +74,10 @@ def calc_att(mud, pid, attacks, bank, attack=None): ...@@ -61,6 +74,10 @@ def calc_att(mud, pid, attacks, bank, attack=None):
61 if len(v_att) > 0: 74 if len(v_att) > 0:
62 attack = v_att[randrange(len(v_att))] 75 attack = v_att[randrange(len(v_att))]
63 att = get_att(attack['dmg']) 76 att = get_att(attack['dmg'])
64 mud.send_message(pid, "%s for %d" % (attack['desc'], att,)) 77 if attack:
78 mud.send_message(pid, "%s for %d" % (attack['desc'], att,), color=['bold', 'yellow'])
79 else:
80 mud.send_message(pid, "%s for %d" % (attack['desc'], att,), color=['bold', 'magenta'])
81
65 bank -= attack['cost'] 82 bank -= attack['cost']
66 return att, bank 83 return att, bank
...\ No newline at end of file ...\ No newline at end of file
......