Added full combat, spawner, emotes, actions, casting spells, perform,
spells, help for spells and other commands
Showing
32 changed files
with
451 additions
and
37 deletions
... | @@ -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 | ... | ... |
commands/actions.txt
0 → 100644
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 |
commands/cast.txt
0 → 100644
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 |
commands/emote.txt
0 → 100644
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 |
commands/kill.txt
0 → 100644
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 | ... | ... |
commands/perform.txt
0 → 100644
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 |
commands/spells.txt
0 → 100644
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 | ... | ... |
help/actions.txt
0 → 100644
help/cast.txt
0 → 100644
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 |
help/drop.txt
0 → 100644
help/emote.txt
0 → 100644
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 |
help/fireball.txt
0 → 100644
help/get.txt
0 → 100644
... | @@ -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 | ... | ... |
help/inventory.txt
0 → 100644
help/kick.txt
0 → 100644
help/perform.txt
0 → 100644
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 |
help/spells.txt
0 → 100644
help/zap.txt
0 → 100644
... | @@ -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 | {"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 | ... | ... |
-
Please register or sign in to post a comment