7e6ce878 by Barry

Added skills and Partial support for feats.. Breaking change.. I really

need to start doing pull requests and branches..
1 parent 1ebbbf31
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
30 } 30 }
31 }] 31 }]
32 }, 32 },
33 "skills" : { },
33 "prompt": "hp %hp mp %mp> ", 34 "prompt": "hp %hp mp %mp> ",
34 "aliases": {}, 35 "aliases": {},
35 "level": 1, 36 "level": 1,
......
1 import sys
2
3 if 'WiPy' in sys.platform:
4 from ucrypto import getrandbits
5 import network
6 wlan = network.WLAN(mode=network.WLAN.STA)
7 wlan.connect('Volley', auth=(network.WLAN.WPA2, '6198472223'))
8
1 import weemud 9 import weemud
...\ No newline at end of file ...\ No newline at end of file
......
1 {"name": "test", "password": "6c76899eb15393064b4f4db94805e5862232920b", "room": "town/tavern", "abilities": {"str": 10, "dex": 23, "con": 10, "int": 12, "wis": 10, "cha": 8}, "equipment": {"finger": [null, null], "hand": [null, null], "arm": [null, null], "leg": [null, null], "foot": [null, null], "head": null, "neck": null, "back": null, "body": null, "waist": null}, "inventory": {"bag": [{"expires": 0, "inventory": {"shirt": [{"expires": 0}]}}]}, "prompt": "hp %hp mp %mp> ", "aliases": {}, "hp": 100, "mp": 10, "maxhp": 100, "maxmp": 10, "maxsta": 10, "sta": 10, "aa": "1d2", "mpr": 0.25, "star": 0.4, "weapon": null, "sp": {}, "at": {"kick": {"cost": 5, "dmg": "2d4", "desc": "You unleash a powerful kick"}}, "createstep": 7, "color_enabled": true, "over_13": true, "race": "Android", "theme": "Ace Pilot", "class": "Envoy", "abilitypoints": 0, "baseattack": 0, "fort": 0, "ref": 2, "will": 2}
...\ No newline at end of file ...\ No newline at end of file
1 {"name": "test", "password": "6c76899eb15393064b4f4db94805e5862232920b", "room": "town/tavern", "abilities": {"str": 10, "dex": 11, "con": 10, "int": 10, "wis": 10, "cha": 10}, "equipment": {"finger": [null, null], "hand": [null, null], "arm": [null, null], "leg": [null, null], "foot": [null, null], "head": null, "neck": null, "back": null, "body": null, "waist": null}, "inventory": {"bag": [{"expires": 0, "inventory": {"shirt": [{"expires": 0}]}}]}, "skills": {}, "prompt": "hp %hp mp %mp> ", "aliases": {}, "level": 1, "hp": 10, "mp": 10, "maxhp": 10, "maxmp": 10, "maxsta": 10, "sta": 10, "aa": "1d2", "mpr": 0.25, "star": 0.4, "weapon": null, "sp": 7, "at": {"kick": {"cost": 5, "dmg": "2d4", "desc": "You unleash a powerful kick"}}, "createstep": 7, "color_enabled": true, "over_13": true, "race": "Human", "theme": "Ace Pilot", "class": "Envoy", "abilitypoints": 12, "baseattack": 0, "fort": 0, "ref": 2, "will": 2, "maxsp": 7, "maxrp": 3, "rp": 3, "skillpoints": 9}
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -3,6 +3,8 @@ import sys ...@@ -3,6 +3,8 @@ import sys
3 3
4 if 'esp' in sys.platform: 4 if 'esp' in sys.platform:
5 from urandom import getrandbits 5 from urandom import getrandbits
6 elif 'WiPy' in sys.platform:
7 from ucrypto import getrandbits
6 else: 8 else:
7 from random import getrandbits 9 from random import getrandbits
8 10
...@@ -15,7 +17,7 @@ codes = {'resetall': 0, 'bold': 1, 'underline': 4, ...@@ -15,7 +17,7 @@ codes = {'resetall': 0, 'bold': 1, 'underline': 4,
15 17
16 18
17 def password_hash(name, password): 19 def password_hash(name, password):
18 if 'esp' in sys.platform: 20 if sys.platform in ['esp', 'WiPy']:
19 import uhashlib 21 import uhashlib
20 return ''.join(['%.2x' % i for i in uhashlib.sha1(password + 'weemud' + name).digest()]) 22 return ''.join(['%.2x' % i for i in uhashlib.sha1(password + 'weemud' + name).digest()])
21 else: 23 else:
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 """ 3 """
4 MudServer author: Mark Frimston - mfrimston@gmail.com 4 MudServer author: Mark Frimston - mfrimston@gmail.com
5 5
6 Micropython port and expansion author: Barry Ruffner - barryruffner@gmail.com 6 Micropython port and extensions for more protocol author: Barry Ruffner - barryruffner@gmail.com
7 """ 7 """
8 8
9 from time import sleep 9 from time import sleep
...@@ -68,6 +68,134 @@ races = { ...@@ -68,6 +68,134 @@ races = {
68 } 68 }
69 } 69 }
70 70
71 feats = {
72 """
73 Adaptive Fighting*
74 Three or more combat feats Once per day as a move action, gain the benefit of a combat feat you don’t have
75 Amplified Glitch*
76 Computers 3 ranks, Intimidate 3 ranks Disrupt devices, causing targets to become shaken for 1 round or more Antagonize Diplomacy 5 ranks, Intimidate 5 ranks Anger a foe, causing it to become off-target and take a −2 penalty to skill checks for 1 round or more
77 Barricade*
78 Engineering 1 rank Create your own fragile cover
79 Basic Melee Weapon Proficiency*
80 — No penalty to attacks with basic melee weapons
81 Advanced Melee Weapon Proficiency*
82 Basic Melee Weapon Proficiency No penalty to attacks with advanced melee weapons
83 Special Weapon Proficiency*
84 Basic Melee Weapon Proficiency or Small Arm Proficiency No penalty to attacks with one special weapon
85 Blind-Fight*
86 — Reroll miss chances from concealment
87 Bodyguard*
88 — Add a +2 bonus to an adjacent ally’s AC as a reaction
89 In Harm’s Way*
90 Bodyguard Take the damage of a successful attack against an adjacent ally
91 Cleave*
92 Str 13, base attack bonus +1 Make an additional melee attack if the first one hits
93 Great Cleave*
94 Str 13, Cleave, base attack bonus +4 Make an additional melee attack after each melee attack that hits Climbing Master Athletics 5 ranks Gain a climb speed equal to your base speed
95 Combat Casting*
96 Ability to cast 2nd-level spells +2 bonus to AC and saves against attacks of opportunity when casting spells Connection Inkling Wis 15, character level 5th, no mystic levels Gain the ability to cast minor mystic spells
97 Coordinated Shot*
98 Base attack bonus +1 Allies gain a +1 bonus to ranged attacks against foes you threaten
99 Deadly Aim*
100 Base attack bonus +1 Take a −2 penalty to weapon attacks to deal extra damage
101 Deflect Projectiles*
102 Base attack bonus +8 Spend 1 Resolve Point to attempt to avoid a ranged attack
103 Reflect Projectiles*
104 Deflect Projectiles, base attack bonus +16 Spend 1 Resolve Point to attempt to redirect a ranged attack Diehard — You can spend Resolve Points to stabilize and to stay in the fight in the same round Dive for Cover*
105 Base Reflex save bonus +2 Fall prone in an adjacent square to roll a Reflex save twice Diversion — Use Bluff to create a distraction so that your allies can hide
106 Drag Down*
107 — When you are tripped, you can attempt to trip an adjacent foe Enhanced Resistance Base attack bonus +4 Gain damage reduction or energy resistance Extra Resolve Character level 5th Gain 2 additional Resolve Points
108 Far Shot*
109 Base attack bonus +1 Reduce penalty due to range increments Fast Talk Bluff 5 ranks Baffle a potential foe, causing it to be surprised when combat begins
110 Fleet*
111 — Increase your base speed
112 Fusillade*
113 Base attack bonus +1, 4 or more arms Make an automatic-mode attack with multiple small arms Great Fortitude — +2 bonus to Fortitude saves Improved Great Fortitude Great Fortitude, character level 5th Spend 1 Resolve Point to reroll a Fortitude save
114 Grenade Proficiency*
115 — No penalty to attacks made with grenades Harm Undead Healing channel connection power, mystic level 1st Expend a spell slot for healing channel to also damage undead
116 Improved Combat Maneuver*
117 Base attack bonus +1 +4 bonus to perform one combat maneuver
118 Pull the Pin*
119 Improved Combat Maneuver (disarm) Perform a disarm to activate a foe’s grenade
120 Improved Critical*
121 Base attack bonus +8 The DC to resist the critical effects of your critical hits increases by 2
122 Improved Feint*
123 — Use Bluff to feint as a move action
124 Greater Feint*
125 Improved Feint, base attack bonus +6 Foes you feint against are flat-footed for 1 round
126 Improved Initiative*
127 — +4 bonus to initiative checks
128 Improved Unarmed Strike*
129 — Deal more damage and threaten squares with unarmed strikes Iron Will — +2 bonus to Will saves Improved Iron Will Iron Will, character level 5th Spend 1 Resolve Point to reroll a Will save Jet Dash — Move faster when running, double height and distance when jumping
130 Kip Up*
131 Acrobatics 1 rank Stand from prone as a swift action
132 Light Armor Proficiency*
133 — No penalty to attack rolls while wearing light armor
134 Heavy Armor Proficiency*
135 Str 13, Light Armor Proficiency No penalty to attack rolls while wearing heavy armor
136 Powered Armor Proficiency*
137 Str 13, Light Armor Proficiency, Heavy Armor Proficiency, base attack bonus +5 No penalty to attack rolls while wearing powered armor Lightning Reflexes — +2 bonus to Reflex saves Improved Lightning Reflexes Lightning Reflexes, character level 5th Spend 1 Resolve Point to reroll a
138 Reflex save Lunge*
139 Base attack bonus +6 Increase reach of melee attacks by 5 feet until the end of your turn Master Crafter Computers, Engineering, Life Science, Mysticism, Physical Science, or Profession 5 ranks Craft items in half the normal time Medical Expert Life Science 1 rank, Medicine 1 rank, Physical Science 1 rank Treat deadly wounds more quickly, and provide long-term care without a medical lab Minor Psychic Power Cha 11 Cast a 0-level spell as a spell-like ability 3/day Psychic Power Cha 13, Minor Psychic Power, character level 4th Cast a 1st-level spell as a spell-like ability 1/day Major Psychic Power Cha 15, Minor Psychic Power, Psychic Power, character level 7th Cast a 2nd-level spell as a spell-like ability 1/day
140 Mobility*
141 Dex 13 +4 bonus to AC against attacks of opportunity from movement Agile Casting Key ability score 15, Dex 15, Mobility, caster level 4th Cast a spell at any point during movement Shot on the
142 Run*
143 Dex 15, Mobility, base attack bonus +4 Make a ranged attack at any point during movement
144 Parting Shot*
145 Dex 15, Mobility, Shot on the Run, base attack bonus +6 Make a single ranged attack when withdrawing Sidestep* Dex 15, Mobility or trick attack Take guarded step as a reaction when a foe misses you with melee attack
146 Improved Sidestep* Dex 17, Mobility or trick attack class feature, Sidestep Reduce penalties from Sidestep Spring Attack*
147 Dex 15, Mobility, base attack bonus +4 Move before and after a melee attack
148 Multi-Weapon Fighting*
149 — Reduce the penalty for full attacks when using multiple small arms or operative melee weapons
150 Mystic Strike*
151 Ability to cast spells Melee and ranged attacks count as magic
152 Nimble Moves*
153 Dex 15 Ignore 20 feet of difficult terrain when you move
154 Opening Volley*
155 — +2 bonus to a melee attack against a target you damaged with a ranged attack
156 Penetrating Attack*
157 Base attack bonus +12 Reduce enemy's DR and energy resistance against your weapons by 5 Penetrating Spell Ability to cast 4th-level spells Reduce enemy's DR and energy resistance against your spells by 5
158 Quick Draw*
159 Base attack bonus +1 Draw a weapon as a swift action Skill Focus — +3 insight bonus to one skill Skill Synergy — Gain two new class skills or a +2 insight bonus to those skills Sky Jockey Piloting 5 ranks Make jetpacks, vehicles, and starships go faster
160 Slippery Shooter*
161 Dex 15, base attack bonus +6 +3 bonus to AC against attacks of opportunity when making ranged attacks
162 Small Arm Proficiency*
163 — No penalty to attacks with small arms
164 Longarm Proficiency*
165 Small Arm Proficiency No penalty to attacks with longarms
166 Heavy Weapon Proficiency*
167 Str 13, Longarm Proficiency, Small Arm Proficiency No penalty to attacks with heavy weapons
168 Special Weapon Proficiency*
169 Basic Melee Weapon Proficiency or Small Arm Proficiency No penalty to attacks with one special weapon
170 Sniper Weapon Proficiency*
171 — No penalty to attacks with sniper weapons Spell Focus Ability to cast spells, character level 3rd DCs of spells you cast increase Spell Penetration — +2 bonus to caster level checks to overcome SR Greater Spell Penetration Spell Penetration Additional +2 bonus to caster level checks to overcome SR Spellbane Unable to cast spells or use spell-like abilities +2 insight bonus to saving throws against spells and spell-like abilities
172 Spry Cover*
173 Base attack bonus +1 Covering fire grants a +4 bonus to an ally’s Acrobatics check to tumble
174 Stand Still*
175 — Make an attack of opportunity to stop a foe’s movement
176 Improved Stand Still*
177 Stand Still +4 bonus to melee attacks with Stand Still
178 Step Up*
179 Base attack bonus +1 Take a guarded step as a reaction to an adjacent foe moving Step Up
180 and Strike*
181 Dex 13, Step Up, base attack bonus +6 Make an attack of opportunity as part of Step Up
182 Suppressive Fire*
183 Base attack bonus +1, proficiency with heavy weapons Provide covering fire or harrying fire in an area
184 Strike Back*
185 Base attack bonus +1 Ready an action to make a melee attack against a foe with reach Swimming Master Athletics 5 ranks Gain a swim speed equal to your base speed Technomantic Dabbler Int 15, character level 5th, no levels in technomancer Gain the ability to cast minor technomancer spells Toughness — +1 Stamina Point per character level and other bonuses
186 Unfriendly Fire*
187 Bluff 5 ranks Trick an attacker into shooting at another enemy adjacent to you Veiled Threat Cha 15, Intimidate 1 rank Intimidated foe doesn’t become hostile
188 Weapon Focus*
189 Proficiency with selected weapon type +1 bonus to attack rolls with selected weapon type
190 Versatile Focus*
191 Weapon Focus +1 bonus to attack rolls with all weapon types you are proficient with
192 Weapon Specialization*
193 Character level 3rd, proficiency with selected weapon type Deal extra damage with selected weapon type
194 Versatile Specialization*
195 Weapon Specialization, character level 3rd Deal extra damage with all weapon types you are proficient with
196 """
197 }
198
71 themes = { 199 themes = {
72 "Ace Pilot": { 200 "Ace Pilot": {
73 "mods": {"dex": 1} 201 "mods": {"dex": 1}
...@@ -272,8 +400,8 @@ def isalnum(c): ...@@ -272,8 +400,8 @@ def isalnum(c):
272 def show_list(id, title, singular_title, subject_list, instructions='Please choose a {} from the list by number: '): 400 def show_list(id, title, singular_title, subject_list, instructions='Please choose a {} from the list by number: '):
273 mud.send_message(id, " %green+------------={}=------------+".format(title), nowrap=True) 401 mud.send_message(id, " %green+------------={}=------------+".format(title), nowrap=True)
274 for idx, subject in enumerate(subject_list): 402 for idx, subject in enumerate(subject_list):
275 mud.send_message(id, " %%green|%%reset%%bold%%white%s%%reset%%green|" % ('{}. {:<28}'.format(idx, subject),), nowrap=True) 403 mud.send_message(id, " %%green|%%reset%%bold%%white%s%%reset%%green|" % ('{:<2}. {:<28}'.format(idx, subject),), nowrap=True)
276 mud.send_message(id, " %green+-------------------------------+", nowrap=True) 404 mud.send_message(id, " %green+--------------------------------+", nowrap=True)
277 405
278 mud.send_message(id, ' (Type %boldhelp [{}]%reset for details)\r\n'.format(singular_title)) 406 mud.send_message(id, ' (Type %boldhelp [{}]%reset for details)\r\n'.format(singular_title))
279 mud.send_message(id, instructions.format(singular_title)) 407 mud.send_message(id, instructions.format(singular_title))
...@@ -286,8 +414,20 @@ def get_base_abilities(id): ...@@ -286,8 +414,20 @@ def get_base_abilities(id):
286 base[name] += value 414 base[name] += value
287 return base 415 return base
288 416
417 def show_skills(id):
418 mud.send_message(id, "%greenEnter the number of the skill you wish to modify, 1 point will be added to that skill rank. You may not exceed the available skill points.")
419 mud.send_message(id, '%greenYou can reset to the base values by typing %boldreset')
420 mud.send_message(id, " %green+--------=Skill Ranks=-------+", nowrap=True)
421 for idx, skill in enumerate(classes[players[id]["class"]]["skills"]):
422 skill_rank = players[id]["skills"].get(skill, 0)
423 mud.send_message(id, " %%green|%%reset%%bold%%white%s%%reset%%green|" % ('{:<2}. {:<19} {:^4}'.format(idx, skill, skill_rank),), nowrap=True)
424 mud.send_message(id, " %green+- Points: %bold{:<2}%reset%green ---------------+".format(players[id]["skillpoints"]), nowrap=True)
425
426 mud.send_message(id, ' (Type %boldhelp [skill]%reset for details)\r\n')
427 mud.send_message(id, '%greenWhen finished type %bolddone')
428
289 def show_abilities(id): 429 def show_abilities(id):
290 mud.send_message(id, "%greenEnter the number of the ability you wish to modify 1 point will be added to that ability. You may not exceed the available ability points.") 430 mud.send_message(id, "%greenEnter the number of the ability you wish to modify, 1 point will be added to that ability. You may not exceed the available ability points.")
291 mud.send_message(id, '%greenYou can reset to the base values by typing %boldreset') 431 mud.send_message(id, '%greenYou can reset to the base values by typing %boldreset')
292 mud.send_message(id, " %green+-----=Abilities=-----+", nowrap=True) 432 mud.send_message(id, " %green+-----=Abilities=-----+", nowrap=True)
293 for idx, ability in enumerate(players[id]["abilities"]): 433 for idx, ability in enumerate(players[id]["abilities"]):
...@@ -396,8 +536,12 @@ def handle_character_create(id, command, params): ...@@ -396,8 +536,12 @@ def handle_character_create(id, command, params):
396 if players[id]["maxrp"] < 1: 536 if players[id]["maxrp"] < 1:
397 players[id]["maxrp"] = 1 537 players[id]["maxrp"] = 1
398 players[id]["rp"] = players[id]["maxrp"] 538 players[id]["rp"] = players[id]["maxrp"]
539 players[id]["skillpoints"] = get_ability_mod(id, 'int') + pclass["skillperlevel"]
540
399 players[id]["createstep"] = 7 541 players[id]["createstep"] = 7
542 show_skills(id)
400 elif not command.isdigit() or int(command) + 1 > len(players[id]["abilities"]) or int(command) < 0: 543 elif not command.isdigit() or int(command) + 1 > len(players[id]["abilities"]) or int(command) < 0:
544 mud.send_message(id, '%cyanInvalid number')
401 show_abilities(id) 545 show_abilities(id)
402 else: 546 else:
403 ability_name = list(players[id]["abilities"])[int(command)] 547 ability_name = list(players[id]["abilities"])[int(command)]
...@@ -407,6 +551,46 @@ def handle_character_create(id, command, params): ...@@ -407,6 +551,46 @@ def handle_character_create(id, command, params):
407 players[id]["abilities"][ability_name] += 1 551 players[id]["abilities"][ability_name] += 1
408 players[id]["abilitypoints"] -= 1 552 players[id]["abilitypoints"] -= 1
409 show_abilities(id) 553 show_abilities(id)
554 elif players[id]['createstep'] == 7:
555 if command.lower().startswith("help"):
556 cmd_handler.parse(id, command, params.lower().strip(), mud, players)
557 elif command.lower().startswith("reset"):
558 pclass = classes[players[id]["class"]]
559 players[id]["skills"] = { }
560 players[id]["skillpoints"] = get_ability_mod(id, 'int') + pclass["skillperlevel"]
561 show_skills(id)
562 elif command.lower().startswith("done"):
563 if players[id]["skillpoints"] > 0:
564 mud.send_message(id, '%cyanPlease spend all available skill points.')
565 show_skills(id)
566 else:
567 players[id]["createstep"] = 8
568 show_list(id, "Feats", "feat", feats)
569 elif not command.isdigit() or int(command) + 1 > len(themes) or int(command) < 0:
570 show_skills(id)
571 else:
572 skill_name = classes[players[id]["class"]]["skills"][int(command)]
573 if players[id]["skillpoints"] > 0:
574 if players[id]["skills"].get(skill_name):
575 players[id]["skills"][skill_name] += 1
576 else:
577 players[id]["skills"][skill_name] = 1
578 players[id]["skillpoints"] -= 1
579 show_skills(id)
580 elif players[id]['createstep'] == 8:
581 if command.lower().startswith("help"):
582 cmd_handler.parse(id, command, params.lower().strip(), mud, players)
583 elif not command.isdigit() or int(command) + 1 > len(themes) or int(command) < 0:
584 show_list(id, "Feats", "feat", feats)
585 else:
586 # skill_name = classes[players[id]["class"]]["skills"][int(command)]
587 # if players[id]["skillpoints"] > 0:
588 # if players[id]["skills"].get(skill_name):
589 # players[id]["skills"][skill_name] += 1
590 # else:
591 # players[id]["skills"][skill_name] = 1
592 # players[id]["skillpoints"] -= 1
593 show_list(id, "Feats", "feat", feats)
410 save_object_to_file(players[id], "players/{}.json".format(players[id]["name"])) 594 save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
411 595
412 # main game loop. We loop forever (i.e. until the program is terminated) 596 # main game loop. We loop forever (i.e. until the program is terminated)
......