Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Barry
/
esp8266-Mud
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
4112e223
authored
2018-05-07 01:39:10 -0700
by
Barry
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
memory use improvements.
1 parent
bb158dfa
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
87 additions
and
78 deletions
commandhandler.py
commands/drop.txt
commands/get.txt
commands/go.txt
commands/help.txt
commands/inventory.txt
commands/look.txt
commands/prompt.txt
commands/quit.txt
commands/save.txt
commands/say.txt
commands/whisper.txt
commands/who.txt
main.py
mobs.txt
players/test.json
release.py
rooms/tavern_monsters.json
utils.py
commandhandler.py
View file @
4112e22
...
...
@@ -41,12 +41,15 @@ class CommandHandler(object):
command
=
cmd
ldict
=
locals
()
with
open
(
'commands/{}.txt'
.
format
(
cmd
),
'r'
,
encoding
=
'utf-8'
)
as
f
:
exec
(
f
.
read
(),
globals
(),
ldict
)
command_text
=
f
.
read
()
exec
(
command_text
,
globals
(),
ldict
)
del
command_text
if
ldict
[
'next_command'
]
!=
None
:
locals
()[
'tokens'
]
=
[]
tokens
=
[]
with
open
(
'commands/{}.txt'
.
format
(
ldict
[
'next_command'
]),
'r'
,
encoding
=
'utf-8'
)
as
f
:
exec
(
f
.
read
())
del
ldict
return
True
# except Exception as e:
# print('Something happened...')
...
...
commands/drop.txt
View file @
4112e22
...
...
@@ -24,3 +24,4 @@ def drop(id, tokens, players, mud):
mud.send_message(id, 'You do not have {} in your inventory.'.format(tokens[0]))
drop(id, tokens, players, mud)
del drop
\ No newline at end of file
...
...
commands/get.txt
View file @
4112e22
...
...
@@ -9,6 +9,9 @@ def get(id, tokens, players, mud):
players[id]['inventory'][tokens[0]] += 1
else:
players[id]['inventory'][tokens[0]] = 1
room_data['inventory'][tokens[0]] -= 1
if room_data['inventory'][tokens[0]] <= 0:
del room_data['inventory'][tokens[0]]
for pid, pl in players.items():
# if they're in the same room as the player
if players[pid]["room"] == players[id]["room"]:
...
...
@@ -16,6 +19,7 @@ def get(id, tokens, players, mud):
mud.send_message(pid, "{} picked up a {}.".format(
players[id]["name"], tokens[0]))
utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
utils.save_object_to_file(room_data, 'rooms/' + room_name + '.json')
else:
mud.send_message(id, 'There is no {} here to get.'.format(tokens[0]))
...
...
commands/go.txt
View file @
4112e22
...
...
@@ -57,3 +57,4 @@ def go(id, params, players, mud, tokens, command):
if command is None and cmd is not None:
command = cmd
next_command = go(id, params, players, mud, tokens, command)
del go
\ No newline at end of file
...
...
commands/help.txt
View file @
4112e22
...
...
@@ -12,3 +12,4 @@ def help(id, tokens, mud):
mud.send_message(id, 'No help topics available for \"{}\". A list\r\n of all commands is available at: help index'.format(tokens[0]))
help(id, tokens, mud)
del help
\ No newline at end of file
...
...
commands/inventory.txt
View file @
4112e22
...
...
@@ -5,3 +5,4 @@ def inventory(id, players, mud):
mud.send_message(id, '\r\n-----------------------------------------')
inventory(id, players, mud)
del inventory
\ No newline at end of file
...
...
commands/look.txt
View file @
4112e22
...
...
@@ -47,3 +47,4 @@ def look(id, mud, players, tokens):
mud.send_message(id, "Mobs here: {}".format( ", ".join(room_monsters.keys())))
look(id, mud, players, tokens)
del look
\ No newline at end of file
...
...
commands/prompt.txt
View file @
4112e22
...
...
@@ -6,3 +6,4 @@ def prompt(id, tokens, params, players, mud):
utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
prompt(id, tokens, params, players, mud)
del prompt
\ No newline at end of file
...
...
commands/quit.txt
View file @
4112e22
...
...
@@ -5,3 +5,4 @@ def quit(id, players, mud):
mud.disconnect_player(id)
quit(id, players, mud)
del quit
\ No newline at end of file
...
...
commands/save.txt
View file @
4112e22
...
...
@@ -5,3 +5,4 @@ def save(id, players, mud):
mud.send_message(id, "Save complete")
save(id, players, mud)
del save
\ No newline at end of file
...
...
commands/say.txt
View file @
4112e22
...
...
@@ -7,3 +7,4 @@ def say(id, params, players, mud):
mud.send_message(pid, "{} says: {}".format(
players[id]["name"], params))
say(id, params, players, mud)
del say
\ No newline at end of file
...
...
commands/whisper.txt
View file @
4112e22
...
...
@@ -8,3 +8,4 @@ def whisper(id, tokens, players, mud):
players[id]["name"], ' '.join(tokens[1:])))
whisper(id, tokens, players, mud)
del whisper
\ No newline at end of file
...
...
commands/who.txt
View file @
4112e22
...
...
@@ -6,3 +6,4 @@ def who(id, players, mud):
mud.send_message(id, "---------------------------------------------".format(len(players)))
mud.send_message(id, "")
who(id, players, mud)
del who
\ No newline at end of file
...
...
main.py
View file @
4112e22
#!/usr/bin/env python
"""A simple Multi-User Dungeon (MUD) game. Players can talk to each
other, examine their surroundings and move between rooms.
Some ideas for things to try adding:
* More rooms to explore
* An 'emote' command e.g. 'emote laughs out loud' -> 'Mark laughs
out loud'
* A 'whisper' command for talking to individual players
* A 'shout' command for yelling to players in all rooms
* Items to look at in rooms e.g. 'look fireplace' -> 'You see a
roaring, glowing fire'
* Items to pick up e.g. 'take rock' -> 'You pick up the rock'
* Monsters to fight
* Loot to collect
* Saving players accounts between sessions
* A password login
* A shop from which to buy items
author: Mark Frimston - mfrimston@gmail.com
"""
MudServer author: Mark Frimston - mfrimston@gmail.com
import
time
import
sys
if
'esp'
in
sys
.
platform
:
import
gc
import
machine
Micropython port and expansion author: Barry Ruffner - barryruffner@gmail.com
"""
from
time
import
sleep
from
sys
import
platform
if
'esp'
in
platform
:
from
gc
import
collect
,
mem_free
from
machine
import
Pin
# import the MUD server class
from
mudserver
import
MudServer
import
utils
from
utils
import
load_object_from_file
,
save_object_to_file
print
(
'STARTING MUD
\r\n\r\n\r\n
'
)
if
'esp'
in
sys
.
platform
:
flash_button
=
machine
.
Pin
(
0
,
machine
.
Pin
.
IN
,
machine
.
Pin
.
PULL_UP
)
if
'esp'
in
platform
:
flash_button
=
Pin
(
0
,
Pin
.
IN
,
Pin
.
PULL_UP
)
# stores the players in the game
players
=
{}
...
...
@@ -59,14 +44,13 @@ tick = 0.0
spawn
=
0.0
# main game loop. We loop forever (i.e. until the program is terminated)
while
True
:
if
'esp'
in
sys
.
platform
:
gc
.
collect
()
if
'esp'
in
platform
:
collect
()
if
flash_button
.
value
()
==
0
:
break
# pause for 1/5 of a second on each loop, so that we don't constantly
# use 100% CPU time
time
.
sleep
(
0.001
)
if
'esp'
in
sys
.
platform
:
sleep
(
0.001
)
if
'esp'
in
platform
:
tick
+=
0.001
else
:
tick
+=
0.0005
...
...
@@ -80,6 +64,7 @@ while True:
print
(
'spawner error:'
)
print
(
e
)
if
tick
>=
1
:
print
(
mem_free
())
spawn
+=
tick
tick
=
0
# try:
...
...
@@ -101,7 +86,7 @@ while True:
# The dictionary key is the player's id number. We set their room to
# None initially until they have entered a name
# Try adding more player stats - level, gold, inventory, etc
players
[
id
]
=
utils
.
load_object_from_file
(
"defaultplayer.json"
)
players
[
id
]
=
load_object_from_file
(
"defaultplayer.json"
)
with
open
(
'welcome.txt'
,
'r'
,
encoding
=
'utf-8'
)
as
f
:
for
line
in
f
:
mud
.
send_message
(
id
,
line
,
"
\r
"
)
...
...
@@ -121,12 +106,11 @@ while True:
# send each player a message to tell them about the diconnected
# player
if
players
[
pid
][
"name"
]
!=
None
:
mud
.
send_message
(
pid
,
"{} quit the game"
.
format
(
players
[
pid
][
"name"
]))
mud
.
send_message
(
pid
,
"{} quit the game"
.
format
(
players
[
pid
][
"name"
]))
# remove the player's entry in the player dictionary
if
players
[
id
][
"name"
]
!=
None
:
utils
.
save_object_to_file
(
players
[
id
],
"players/{}.json"
.
format
(
players
[
id
][
"name"
]))
save_object_to_file
(
players
[
id
],
"players/{}.json"
.
format
(
players
[
id
][
"name"
]))
del
(
players
[
id
])
# go through any new commands sent from players
...
...
@@ -151,7 +135,7 @@ while True:
already_logged_in
=
True
if
already_logged_in
:
continue
loaded_player
=
utils
.
load_object_from_file
(
"players/{}.json"
.
format
(
command
))
loaded_player
=
load_object_from_file
(
"players/{}.json"
.
format
(
command
))
if
loaded_player
is
None
:
players
[
id
][
"name"
]
=
command
players
[
id
][
"room"
]
=
"Tavern"
...
...
@@ -171,7 +155,7 @@ while True:
# send the new player the description of their current room
mud
.
send_message
(
id
,
utils
.
load_object_from_file
(
'rooms/'
+
players
[
id
][
"room"
]
+
'.json'
)[
'description'
])
mud
.
send_message
(
id
,
load_object_from_file
(
'rooms/'
+
players
[
id
][
"room"
]
+
'.json'
)[
'description'
])
else
:
from
commandhandler
import
CommandHandler
...
...
@@ -182,7 +166,7 @@ while True:
show_prompt
(
id
)
# Start WIFI Setup
if
'esp'
in
sys
.
platform
:
if
'esp'
in
platform
:
if
flash_button
.
value
()
==
0
:
print
(
'Starting WIFIWeb'
)
import
wifiweb
...
...
mobs.txt
View file @
4112e22
def run_mobs(players, mud):
def get_att(d):
att = 0
if 'd' in d:
dice = d.split('d')
for d in range(int(dice[0])):
att += utils.randrange(int(dice[1])) + 1
else:
att = int(d)
return att
def calc_att(pid, attacks, bank):
v_att = []
att = 0
for attack in attacks:
if attack['cost'] < bank:
v_att.append(attack)
# Select a random attack
if len(v_att) > 0:
attack = v_att[utils.randrange(len(v_att))]
att = get_att(attack['dmg'])
mud.send_message(pid, "%s for %d" % (attack['desc'], att,))
bank -= attack['cost']
return att, bank
from utils import load_object_from_file, save_object_to_file, calc_att, get_att
for pid, player in players.items():
if not player['name']:
continue
room_monsters =
utils.
load_object_from_file('rooms/{}_monsters.json'.format(player['room']))
room_monsters = load_object_from_file('rooms/{}_monsters.json'.format(player['room']))
if not room_monsters:
continue
for mon_name, monster in room_monsters.items():
monster_template =
utils.
load_object_from_file('mobs/{}.json'.format(mon_name))
monster_template = load_object_from_file('mobs/{}.json'.format(mon_name))
if not monster_template:
continue
for active_monster_idx, active_monster in enumerate(monster['active']):
...
...
@@ -44,40 +23,43 @@ def run_mobs(players, mud):
sta += monster_template['star']
active_monster['sta'] = sta
if active_monster['action'] == "attack" and active_monster['target'] == player['name']:
if player["weapon"]:
weapon = utils.load_object_from_file('inventory/{}.json'.format(player['weapon']))
if weapon:
if player.get("weapon"):
weapon = load_object_from_file('inventory/{}.json'.format(player['weapon']))
att = get_att(weapon['damage'])
mud.send_message(pid, "Your %s strikes the %s for %d" % (weapon['title'], mon_name, att,))
else:
att = get_att(player['aa'])
else:
att = get_att(player['aa'])
mud.send_message(pid, "You hit the %s for %d" % (mon_name, att,))
hp -= att
if hp == 0:
DEAD = 1
if active_monster.get("weapon"):
weapon = load_object_from_file('inventory/{}.json'.format(active_monster['weapon']))
att = get_att(weapon['damage'])
mud.send_message(pid, "The %s strikes you with a %s for %d" % (mon_name, weapon['title'], att,))
else:
att = get_att(monster_template['aa'])
players[pid]['hp'] -= att
mud.send_message(pid, "You were hit by a %s for %d" % (mon_name, att,))
players[pid]['hp'] -= att
# wait until at least 50% of stamina or mp are regenerated or hp is less than 25%
if (hp/active_monster['maxhp'] < 0.25) or (mp > 0 and mp/active_monster['maxmp'] > 0.5) or (sta > 0 and sta/active_monster['maxsta'] > 0.5):
magic_cast = False
if mp > 0:
att, mp = calc_att(pid, monster_template['sp'], mp)
att, mp = calc_att(
mud,
pid, monster_template['sp'], mp)
active_monster['mp'] = mp
players[pid]['hp'] -= att
if att > 0:
magic_cast = True
if not magic_cast:
if sta > 0:
att, sta = calc_att(pid, monster_template['at'], sta)
att, sta = calc_att(
mud,
pid, monster_template['at'], sta)
active_monster['sta'] = sta
players[pid]['hp'] -= att
room_monsters[mon_name]['active'][active_monster_idx] = active_monster
utils.
save_object_to_file(room_monsters, 'rooms/{}_monsters.json'.format(player['room']))
save_object_to_file(room_monsters, 'rooms/{}_monsters.json'.format(player['room']))
run_mobs(players, mud)
del run_mobs
\ No newline at end of file
...
...
players/test.json
View file @
4112e22
{
"name"
:
"test"
,
"room"
:
"Tavern"
,
"inventory"
:
{
"candle"
:
1
},
"prompt"
:
"%hp> "
,
"aliases"
:
{},
"hp"
:
596
,
"mp"
:
100
,
"sta"
:
10
,
"aa"
:
"1d2"
,
"mpr"
:
0.25
,
"star"
:
0.4
,
"maxhp"
:
953
,
"maxmp"
:
100
,
"maxsta"
:
10
,
"weapon"
:
"sword"
}
\ No newline at end of file
{
"name"
:
"test"
,
"room"
:
"Outside"
,
"inventory"
:
{
"candle"
:
1
},
"prompt"
:
"%hp> "
,
"aliases"
:
{},
"hp"
:
593
,
"mp"
:
100
,
"sta"
:
10
,
"aa"
:
"1d2"
,
"mpr"
:
0.25
,
"star"
:
0.4
,
"maxhp"
:
953
,
"maxmp"
:
100
,
"maxsta"
:
10
,
"weapon"
:
"sword"
}
\ No newline at end of file
...
...
release.py
View file @
4112e22
...
...
@@ -36,6 +36,7 @@ def run_command(sio, command, expected='>>>'):
with
serial
.
Serial
(
PORT
,
BAUDRATE
,
timeout
=
1
)
as
ser
:
sio
=
io
.
TextIOWrapper
(
io
.
BufferedRWPair
(
ser
,
ser
))
run_command
(
sio
,
'
\x03
'
)
run_command
(
sio
,
'import os'
)
root
=
eval
(
run_command
(
sio
,
'os.listdir()'
,
expected
=
']'
))
...
...
@@ -52,13 +53,14 @@ with serial.Serial(PORT, BAUDRATE, timeout=1) as ser:
print
(
'Folders already created.'
)
for
folder
in
folders
:
for
folder
in
folders
:
for
f
in
os
.
listdir
(
folder
):
files
.
append
(
'{}/{}'
.
format
(
folder
,
f
))
with
open
(
'releasepw.conf'
,
'r'
,
encoding
=
'utf-8'
)
as
f
:
with
open
(
'releasepw.conf'
,
'r'
,
encoding
=
'utf-8'
)
as
f
:
password
=
f
.
read
()
for
file
in
files
:
for
file
in
files
:
os
.
system
(
"python webrepl
\
webrepl_cli.py -p {} {} {}:/{}"
.
format
(
password
,
file
,
IPADDRESS
,
file
))
run_command
(
sio
,
'import machine;machine.reset'
)
...
...
rooms/tavern_monsters.json
View file @
4112e22
{
"cricket"
:
{
"max"
:
1
,
"active"
:
[{
"hp"
:
100
,
"mp"
:
0.25
,
"sta"
:
2.7500000000000715
,
"maxhp"
:
100
,
"maxmp"
:
10
,
"maxsta"
:
10
,
"action"
:
"attack"
,
"target"
:
"test"
}]}}
\ No newline at end of file
{
"cricket"
:
{
"max"
:
1
,
"active"
:
[{
"hp"
:
100
,
"mp"
:
2.0
,
"sta"
:
4.550000000000075
,
"maxhp"
:
100
,
"maxmp"
:
10
,
"maxsta"
:
10
,
"action"
:
"attack"
,
"target"
:
"test"
}]}}
\ No newline at end of file
...
...
utils.py
View file @
4112e22
...
...
@@ -38,3 +38,26 @@ def randrange(start, stop=None):
return
r
+
start
else
:
return
random
.
randrange
(
start
)
def
get_att
(
d
):
att
=
0
if
'd'
in
d
:
dice
=
d
.
split
(
'd'
)
for
d
in
range
(
int
(
dice
[
0
])):
att
+=
randrange
(
int
(
dice
[
1
]))
+
1
else
:
att
=
int
(
d
)
return
att
def
calc_att
(
mud
,
pid
,
attacks
,
bank
):
v_att
=
[]
att
=
0
for
attack
in
attacks
:
if
attack
[
'cost'
]
<
bank
:
v_att
.
append
(
attack
)
# Select a random attack
if
len
(
v_att
)
>
0
:
attack
=
v_att
[
randrange
(
len
(
v_att
))]
att
=
get_att
(
attack
[
'dmg'
])
mud
.
send_message
(
pid
,
"
%
s for
%
d"
%
(
attack
[
'desc'
],
att
,))
bank
-=
attack
[
'cost'
]
return
att
,
bank
\ No newline at end of file
...
...
Please
register
or
sign in
to post a comment