Skip to content

Commit

Permalink
Updates/adding armor
Browse files Browse the repository at this point in the history
  • Loading branch information
fungamer2-2 committed Dec 23, 2023
1 parent 1ab0e4c commit 07007d7
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 92 deletions.
20 changes: 20 additions & 0 deletions activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from abc import ABC, abstractmethod

class Activity:

def __init__(self, name, duration):
self.name = name
self.duration = duration

@abstractmethod
def on_finished(self, player):
pass

class EquipArmorActivity(Activity):

def __init__(self, armor, duration):
super().__init__(f"putting on your {armor.name}", duration)
self.armor = armor

def on_finished(self, player):
player.equip_armor(self.armor)
31 changes: 31 additions & 0 deletions armor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[
{
"id": "leather",
"name": "leather armor",
"symbol": "l",
"protection": 1
},
{
"id": "hide",
"name": "hide armor",
"symbol": "h",
"protection": 2,
"encumbrance": 1
},
{
"id": "scale_mail",
"name": "scale mail",
"symbol": "M",
"protection": 4,
"encumbrance": 7,
"stealth_pen": 2
},
{
"id": "half_plate",
"name": "half-plate armor",
"symbol": "H",
"protection": 5,
"encumbrance": 6,
"stealth_pen": 2
}
]
1 change: 1 addition & 0 deletions const.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
COLOR_BLUE = 12
COLOR_CYAN = 14
COLOR_BLUE1 = 21
COLOR_DODGER_BLUE2 = 27
COLOR_DEEP_PINK2 = 167

MSG_TYPES = {
Expand Down
131 changes: 92 additions & 39 deletions game_inst.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@

import curses, textwrap, math

def _check_type(typ, types, type_name):
if typ not in types:
valid_types = sorted(types.keys())
error = ValueError(f"invalid {type_name} type {typ!r}")
error.add_note(f"Valid {type_name} types are: {', '.join(valid_types)}")
raise error

class Game:

def __init__(self):
Expand All @@ -26,6 +33,7 @@ def __init__(self):
self.mon_types = {}
self.eff_types = {}
self.weap_types = {}
self.armor_types = {}
self.level = 1
self.subtick_timer = 0
self.tick = 0
Expand All @@ -45,34 +53,28 @@ def clear_mon_select(self):
self.select_mon = None

def check_mon_type(self, typ):
if typ not in self.mon_types:
valid_types = sorted(self.mon_types.keys())
error = ValueError(f"invalid monster type {typ!r}")
error.add_note(f"Valid monster types are: {', '.join(valid_types)}")
raise error
_check_type(typ, self.mon_types, "monster")

def check_effect_type(self, name):
if name not in self.eff_types:
valid_types = sorted(self.eff_types.keys())
error = ValueError(f"invalid effect name {name!r}")
error.add_note(f"Valid effect names are: {', '.join(valid_types)}")
raise error
_check_type(name, self.eff_types, "effect")

def check_weapon_type(self, typ):
if typ not in self.weap_types:
valid_types = sorted(self.weap_types.keys())
error = ValueError(f"invalid weapon type {typ!r}")
error.add_note(f"Valid weapon types are: {', '.join(valid_types)}")
raise error
_check_type(typ, self.weap_types, "weapon")

def check_armor_type(self, typ):
_check_type(typ, self.armor_types, "armor")

def load_monsters(self):
self.mon_types = load_monster_types()

def load_effects(self):
self.eff_types = load_effect_types()

def load_weapons(self):
self.weap_types = load_weapon_types()
self.weap_types = load_weapon_types()

def load_armors(self):
self.armor_types = load_armor_types()

def get_mon_type(self, typ):
self.check_mon_type(typ)
Expand All @@ -82,14 +84,19 @@ def get_weapon_type(self, typ):
self.check_weapon_type(typ)
return self.weap_types[typ]

def get_all_monster_types(self):
for typ in self.mon_types.values():
yield typ
def get_armor_type(self, typ):
self.check_armor_type(typ)
return self.armor_types[typ]

def get_effect_type(self, name):
self.check_effect_type(name)
return self.eff_types[name]

def get_all_monster_types(self):
for typ in self.mon_types.values():
yield typ


def add_message(self, text, typ="neutral"):
self.msg_log.add_message(text, typ)

Expand All @@ -102,14 +109,17 @@ def init_colors(self):
curses.init_pair(i + 1, i + 1, -1)

def init_game(self):
self.screen = curses.initscr()
screen = curses.initscr()
self.screen = screen
self.init_colors()

curses.noecho()
curses.curs_set(False)
Entity.g = self
self.load_json_data()
screen.addstr("Loading roguelike game, please wait...")
screen.refresh()

self.load_json_data()
self.init_player()
self.generate_level()
self.draw_board()
Expand All @@ -118,6 +128,7 @@ def load_json_data(self):
self.load_monsters()
self.load_effects()
self.load_weapons()
self.load_armors()

def next_level(self):
player = self.get_player()
Expand Down Expand Up @@ -160,6 +171,11 @@ def choose_mon_spawn_pos(self):
def create_weapon(self, id):
typ = self.get_weapon_type(id)
return Weapon.from_type(typ)

def create_armor(self, id):
typ = self.get_armor_type(id)
return Armor.from_type(typ)


def place_items(self):
board = self.get_board()
Expand Down Expand Up @@ -188,19 +204,36 @@ def place_items(self):
]

for _ in range(rng(1, 4)):
if x_in_y(3, 8):
if one_in(2):
pos = board.random_passable()
name = random_weighted(weapons)
board.place_item_at(pos, self.create_weapon(name))

armors = [
["leather", 100],
["hide", 50],
["scale_mail", 30]
]

for _ in range(rng(2, 4)):
if one_in(2):
pos = board.random_passable()
name = random_weighted(armors)
board.place_item_at(pos, self.create_armor(name))


def place_monsters(self):
eligible_types = {}
highest = 0
levels = []

levels = WeightedList()
for typ in self.get_all_monster_types():
if self.level >= typ.level:
w = 3
if typ.level > 1:
w = min(w, self.level - typ.level + 1)
if typ.level not in eligible_types:
levels.append(typ.level)
levels.add(typ.level, w)
eligible_types[typ.level] = []
eligible_types[typ.level].append(typ)

Expand All @@ -211,13 +244,13 @@ def place_monsters(self):

packs = 0
while num_monsters > 0:
typ = random.choice(eligible_types[random.choice(levels)])
typ = random.choice(eligible_types[levels.pick()])
min_level = typ.level
pack_spawn_chance = self.level - min_level + 1
if "PACK_TRAVEL" in typ.flags and x_in_y(pack_spawn_chance, pack_spawn_chance + 3) and one_in(6 + packs * 3):
pack_spawn_chance = self.level - min_level
if "PACK_TRAVEL" in typ.flags and x_in_y(pack_spawn_chance, pack_spawn_chance + 4) and one_in(6 + packs * 3):
pack_num = rng(2, 4)
if self.spawn_pack(typ.id, pack_num):
num_monsters -= rng(1, pack_num)
num_monsters -= pack_num
packs += 1
else:
num_monsters -= 1
Expand Down Expand Up @@ -420,9 +453,10 @@ def place_stairs(self):

def getch(self, wait=True):
screen = self.screen
if wait != self.delay:
self.delay = wait
screen.nodelay(not wait)

screen.nodelay(not wait)
if wait:
curses.flushinp()
code = screen.getch()
return code

Expand Down Expand Up @@ -463,7 +497,7 @@ def draw_walls(self, offset_y):
elif seen and tile.items:
item = tile.items[-1]
symbol = item.symbol
color = curses.color_pair(item.display_color())
color = item.display_color()
elif tile.stair:
symbol = STAIR_SYMBOL
else:
Expand Down Expand Up @@ -517,16 +551,21 @@ def draw_stats(self):

ev_str = f"+{ev}" if ev >= 0 else str(ev)

stealth_str = f"+{stealth}" if stealth >= 0 else str(ev)
stealth_str = f"+{stealth}" if stealth >= 0 else str(stealth)

wield_str = player.weapon.name
dmg_str = str(player.weapon.damage)

armor_str = player.armor.name if player.armor else ""
prot_str = f"Protection: {player.get_armor()}"
strings2 = [
f"Stealth: {stealth_str}",
f"Evasion: {ev_str}",
"",
" ",
f"Wield: {wield_str}",
f"Damage: {dmg_str}"
f"Damage: {dmg_str}",
armor_str,
prot_str
]

for i, string in enumerate(strings2):
Expand Down Expand Up @@ -624,7 +663,7 @@ def input_text(self, msg=""):
result = screen.getstr()
curses.curs_set(False)
curses.noecho()
return result.decode()
return result.decode().rstrip()

def input_int(self, msg=""):
while True:
Expand All @@ -634,7 +673,15 @@ def input_int(self, msg=""):
except ValueError:
self.add_message("Integers only, please.", "input")

def process_input(self):
def confirm(self, question):
while True:
txt = self.input_text(question + " (Y/N)")
if txt in ["Y", "N"]:
return txt == "Y"
else:
self.add_message("Please enter an uppercase Y or N.", "input")

def process_input(self):
self.maybe_refresh()

player = self.get_player()
Expand All @@ -651,7 +698,13 @@ def process_input(self):
if player.has_status("Paralyzed"):
player.use_energy(100)
return True

player.handle_activities()
if player.activity:
player.use_energy(100)
return True

self.draw_board()
code = self.getch()
char = chr(code)
if code == -1:
Expand All @@ -669,10 +722,10 @@ def process_input(self):
elif char == ">":
return player.descend()
elif char == "r":
if player.HP < player.MAX_HP:
if player.can_rest():
self.add_message("You begin resting.")
player.is_resting = True
return True
return True
elif char == "v":
return self.view_monsters()
elif char == "p":
Expand Down
Loading

0 comments on commit 07007d7

Please sign in to comment.