neelthee-mansion 0.3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -0,0 +1,4 @@
1
+ from . import Mansion_of_Amnesia
2
+
3
+ if __name__ == "__main__":
4
+ Mansion_of_Amnesia.main()
@@ -0,0 +1,13 @@
1
+ from .utils import *
2
+ from re import *
3
+
4
+ def ask_for_consent(text: str) -> bool:
5
+ while True:
6
+ type_text(f"{text}? Y/N")
7
+ anser = str(input(">")).lower()
8
+ if anser == 'y':
9
+ return True
10
+ elif anser == 'n':
11
+ return False
12
+ else:
13
+ type_text("That wasn't Y or N")
@@ -0,0 +1,391 @@
1
+ from .items import *
2
+ from .utils import *
3
+
4
+ global ValidActions
5
+
6
+ ValidActions = [
7
+ "attack",
8
+ "defend",
9
+ "special",
10
+ ]
11
+
12
+ class Height:
13
+ def __init__(self, height_str="0ft 0"):
14
+ feet, inches = map(float, height_str.split('ft '))
15
+ if inches >= 12:
16
+ raise ValueError("Inches must be less than 12.")
17
+ try:
18
+ feet = int(feet)
19
+ except ValueError:
20
+ pass
21
+ try:
22
+ inches = int(inches)
23
+ except ValueError:
24
+ pass
25
+ self.feet = feet
26
+ self.inches = inches
27
+
28
+ def __str__(self):
29
+ return f"{self.feet}ft {self.inches}"
30
+
31
+
32
+ class base_character:
33
+ """
34
+ Represents a base character in the game, including both players and creatures.
35
+ """
36
+
37
+ def take_damage(self, damage_taken: int = 5):
38
+ """
39
+ Reduces the character's hit points by the specified amount of damage.
40
+
41
+ Args:
42
+ damage_taken (int): The amount of damage to be subtracted from the character's hit points. Default is 5.
43
+
44
+ Returns:
45
+ None
46
+ """
47
+ string_beginning = "%*MAGENTA*%"
48
+ if type(self) == creature:
49
+ string_beginning = "The %*CYAN*%"
50
+ self.hp = self.hp - damage_taken
51
+ if self.hp < 0:
52
+ self.hp = 0
53
+ type_text(f"{string_beginning}{self.name}%*RESET*% takes {damage_taken} damage and has {self.hp} HP left!")
54
+
55
+
56
+ class creature_type:
57
+ """
58
+ Represents the type of a creature in the game.
59
+ """
60
+
61
+ def __init__(self, type: str, subtype: str = None) -> None:
62
+ """
63
+ Initializes a creature type with the specified type and optional subtype.
64
+
65
+ Args:
66
+ type (str): The primary type of the creature.
67
+ subtype (str, optional): The subtype of the creature. Defaults to None.
68
+ """
69
+ self.type = type
70
+ self.subtype = subtype
71
+
72
+ def check_type(self):
73
+ """
74
+ Returns the type and subtype of the creature.
75
+
76
+ Returns:
77
+ tuple: A tuple containing the type and subtype of the creature, or just the type if no subtype is specified.
78
+ """
79
+ if self.subtype:
80
+ return self.type, self.subtype
81
+ return self.type
82
+
83
+ def __str__(self) -> str:
84
+ """
85
+ Returns a string representation of the creature type.
86
+
87
+ Returns:
88
+ str: A string representation of the creature type.
89
+ """
90
+ if self.subtype:
91
+ return f"{self.type}, {self.subtype}"
92
+ return f"{self.type}"
93
+
94
+ class creature(base_character):
95
+ """
96
+ A class representing a creature in the game.
97
+
98
+ Attributes:
99
+ name (str): The name of the creature.
100
+ hp (int): The hit points of the creature.
101
+ atpw (int): The attack power of the creature.
102
+ dropped_items (list[str]): A list of items dropped by the creature when defeated.
103
+ description (str): The description of the creature.
104
+ flavor_text (str): The flavor text associated with encountering the creature.
105
+ type (creature_type): The type of the creature.
106
+ crit_chance (float): The chance of the creature landing a critical hit.
107
+ """
108
+
109
+ def __init__(self, name: str, hp: int, atpw: int, dropped_items: list[str] = [], description: str = None, flavor_text: str = None, type: creature_type = creature_type('beast'), crit_chance: float = 0.05, frendly_text: str = ""):
110
+ """
111
+ Initializes a new creature instance.
112
+
113
+ Args:
114
+ name (str): The name of the creature.
115
+ hp (int): The hit points of the creature.
116
+ atpw (int): The attack power of the creature.
117
+ dropped_items (list[str], optional): A list of items dropped by the creature when defeated. Defaults to [].
118
+ description (str, optional): The description of the creature. Defaults to None.
119
+ flavor_text (str, optional): The flavor text associated with encountering the creature. Defaults to None.
120
+ type (creature_type, optional): The type of the creature. Defaults to creature_type('beast').
121
+ crit_chance (float, optional): The chance of the creature landing a critical hit. Defaults to 0.05.
122
+ """
123
+ self.name = name
124
+ self.hp = hp
125
+ self.atpw = atpw
126
+ self.difficulty = self.hp / 10 + self.atpw
127
+ self.dropped_items = dropped_items
128
+ self.xp = rounding(self.difficulty * 2 + len(self.dropped_items))
129
+ self.description = description if description else f'A %*CYAN*%{self.name}%*RESET'
130
+ self.flavor_text = flavor_text if flavor_text else f'You see a %*CYAN*%{self.name}%*RESET*%!'
131
+ self.type = type
132
+ self.crit_chance = crit_chance
133
+ self.frendly = False
134
+ self.frendly_text = frendly_text
135
+
136
+ def type_text_flavor_text(self):
137
+ """
138
+ Prints the flavor text associated with encountering the creature.
139
+ """
140
+ type_text(self.flavor_text)
141
+
142
+ def type_text_description(self):
143
+ """
144
+ Prints the description of the creature.
145
+ """
146
+ type_text(self.description)
147
+
148
+ class Guard(creature):
149
+ """
150
+ A class representing a guard that patrols in the game.
151
+
152
+ Attributes:
153
+ current_room (str): The current room where the guard is located.
154
+ patrol_route (list[str]): The list of rooms the guard patrols through.
155
+ """
156
+
157
+ def __init__(self, name: str, hp: int, atpw: int, dropped_items: list[str] = [], description: str = None, flavor_text: str = None, type: creature_type = creature_type('humanoid'), crit_chance: float = 0.05, current_room: str = None, patrol_route: list[str] = None, patrol_type: str = 'normal', frendly_text: str = ""):
158
+ """
159
+ Initializes a new guard instance.
160
+
161
+ Args:
162
+ name (str): The name of the guard.
163
+ hp (int): The hit points of the guard.
164
+ atpw (int): The attack power of the guard.
165
+ dropped_items (list[str], optional): A list of items dropped by the guard when defeated. Defaults to [].
166
+ description (str, optional): The description of the guard. Defaults to None.
167
+ flavor_text (str, optional): The flavor text associated with encountering the guard. Defaults to None.
168
+ type (creature_type, optional): The type of the guard. Defaults to creature_type('humanoid').
169
+ crit_chance (float, optional): The chance of the guard landing a critical hit. Defaults to 0.05.
170
+ current_room (str, optional): The current room where the guard is located. Defaults to None.
171
+ patrol_route (list[str], optional): The list of rooms the guard patrols through. Defaults to None.
172
+ patrol_type (str): The type of patrol the guard is doing. Defaults to normal.
173
+ """
174
+ super().__init__(name, hp, atpw, dropped_items, description, flavor_text, type, crit_chance, frendly_text)
175
+ self.current_room = current_room
176
+ self.patrol_route = patrol_route or []
177
+ self.patrol_type = patrol_type
178
+
179
+ def move(self, ROOMS, player):
180
+ """
181
+ Moves the guard depending on his patrol type.
182
+ """
183
+
184
+ if self.patrol_type == 'normal':
185
+ if self.patrol_route:
186
+ current_index = self.patrol_route.index(self.current_room)
187
+ next_index = (current_index + 1) % len(self.patrol_route)
188
+ self.current_room = self.patrol_route[next_index]
189
+ elif self.patrol_type == 'random':
190
+ rooms = []
191
+ for direction, room in ROOMS[self.current_room]['directions'].items():
192
+ rooms.append(room)
193
+ self.current_room = choice(rooms)
194
+ elif self.patrol_type == 'follow':
195
+ for direction, room in ROOMS[self.current_room]['directions'].items():
196
+ if room == player.CURRENTROOM:
197
+ self.current_room = room
198
+ return
199
+
200
+ def check_detection(self, player_room):
201
+ """
202
+ Checks if the guard has detected the player.
203
+
204
+ Args:
205
+ player_room (str): The current room where the player is located.
206
+
207
+ Returns:
208
+ bool: True if the player is detected, False otherwise.
209
+ """
210
+ if self.current_room == player_room and not self.frendly:
211
+ type_text(f"You have been caught by {self.name} in the {self.current_room}!")
212
+ return True
213
+ elif self.current_room == player_room and self.frendly:
214
+ if random() <= 0.015:
215
+ type_text(self.frendly_text)
216
+ return False
217
+
218
+ class base_ability:
219
+ def __init__(self, name, cooldown_time) -> None:
220
+ self.ready = True
221
+ self.name = name
222
+ self.cooldown_time = cooldown_time
223
+ self.current_cooldown = 0
224
+
225
+ def activate(self, target: creature, damage: int = 5):
226
+ self.ready = False
227
+ self.current_cooldown = 0
228
+ print(f"Ability {self.name} will be ready after {self.cooldown_time} commands.")
229
+
230
+ def Tick(self):
231
+ self.current_cooldown += 1
232
+ self.check_cooldown
233
+
234
+ def check_cooldown(self):
235
+ if self.current_cooldown >= self.cooldown_time:
236
+ type_text(f"\nAbility {self.name} is ready to use again. ")
237
+ self.ready = True
238
+
239
+ class supercrit_ability(base_ability):
240
+ def __init__(self) -> None:
241
+ super().__init__("Super Crit", 5)
242
+
243
+ def activate(self, target: base_character, damage: int = 5):
244
+ target.take_damage(damage*5)
245
+ super().activate(target, damage)
246
+
247
+ class PC(base_character):
248
+
249
+ def __init__(
250
+ self,
251
+ Name: str,
252
+ Age: int,
253
+ Class: str,
254
+ Level: int,
255
+ Background: str,
256
+ Height: Height,
257
+ Weight: int,
258
+ Notes: list = [],
259
+ special_ability: base_ability = supercrit_ability(),
260
+ NOTES: list = [],
261
+ xp: int = None,
262
+ inventory: inv = None,
263
+ money: int = 0,
264
+ weapons_atpws: list = [],
265
+ backstory: str = "",
266
+ CURRENTROOM: str = "",
267
+ LASTROOM: str = None,
268
+ ):
269
+ if not xp:
270
+ if Level == 1:
271
+ xp = 0
272
+ else:
273
+ xp = Level*25
274
+ if not LASTROOM:
275
+ LASTROOM = CURRENTROOM
276
+ self.name = Name
277
+ self.Age = Age
278
+ self.Class = Class
279
+ self.Level = Level
280
+ self.Background = Background
281
+ self.Height = Height
282
+ self.Weight = Weight
283
+ self.BackstoryNotes = Notes
284
+ self.NOTES = NOTES
285
+ self.maxhp = self.Level * 10
286
+ self.hp = self.maxhp
287
+ self.atpw = rounding(self.Level * 1.5 + 3, 1)
288
+ self.xp = xp
289
+ self.inventory = inventory if inventory is not None else inv() # Initialize an inv if inventory is None
290
+ self.money = money
291
+ self.weapons_atpws = weapons_atpws
292
+ self.crit_chance = 0.075
293
+ self.defending = False
294
+ self.special_ability = special_ability
295
+ self.backstory = backstory
296
+ self.CURRENTROOM = CURRENTROOM
297
+ self.LASTROOM = LASTROOM
298
+
299
+ def get_change_weapon(self, weapon_atpw: int = 0, weapon_index: int = -1):
300
+ if weapon_atpw > 0:
301
+ self.weapons_atpws.append(weapon_atpw)
302
+ if weapon_index <= 0 or weapon_index > (len(self.weapons_atpws) - 1):
303
+ self.atpw = self.Level * 2 + 3 + max(self.weapons_atpws)
304
+ else:
305
+ self.atpw = self.Level * 2 + 3 + self.weapons_atpws[weapon_index]
306
+
307
+ def check_xp(self):
308
+ self.level = rounding(self.xp/25, 1)
309
+
310
+ def add_xp(self, xp_added: int = 5):
311
+ self.xp += xp_added
312
+ self.check_xp()
313
+
314
+ def inventory_add(self, added: list[item]):
315
+ try:
316
+ for item_to_add in added:
317
+ if isinstance(item_to_add, item):
318
+ # Add the item to the player's inventory
319
+ self.inventory.append(item_to_add)
320
+
321
+ # Check if the added item is a weapon and update player's weapon if needed
322
+ if item_to_add.type == 'weapon':
323
+ self.get_change_weapon(item_to_add.value)
324
+ else:
325
+ # Print an error message if the item is not an instance of Item class
326
+ type_text(f"Error: {item_to_add} is not an instance of Item class")
327
+ except Exception as e:
328
+ # Print the full traceback if an exception occurs
329
+ type_text(("Error:", e))
330
+
331
+ def heal(self, value):
332
+ self.hp = clamp(value, 0, self.maxhp)
333
+
334
+ class NPC(PC):
335
+ def __init__(
336
+ self,
337
+ Name: str,
338
+ Age: int,
339
+ Class: str,
340
+ Level: int,
341
+ Background: str,
342
+ Height: Height,
343
+ Weight: int,
344
+ Notes: list = [],
345
+ special_ability: base_ability = supercrit_ability(),
346
+ NOTES: list = [],
347
+ xp: int = None,
348
+ inventory: inv = None,
349
+ money: int = 0,
350
+ weapons_atpws: list = [],
351
+ npc_role: str = "generic", # New attribute for NPC role (e.g., merchant, enemy, etc.)
352
+ aggressive: bool = False # New attribute to determine if NPC is aggressive
353
+ ):
354
+ super().__init__(
355
+ Name=Name,
356
+ Age=Age,
357
+ Class=Class,
358
+ Level=Level,
359
+ Background=Background,
360
+ Height=Height,
361
+ Weight=Weight,
362
+ Notes=Notes,
363
+ special_ability=special_ability,
364
+ NOTES=NOTES,
365
+ xp=xp,
366
+ inventory=inventory,
367
+ money=money,
368
+ weapons_atpws=weapons_atpws
369
+ )
370
+ self.npc_role = npc_role
371
+ self.aggressive = aggressive
372
+
373
+ def interact(self):
374
+ if self.aggressive:
375
+ return f"{self.name} looks hostile and prepares for a fight!"
376
+ else:
377
+ return f"{self.name} has nothing to say to you."
378
+
379
+ def npc_info(self):
380
+ return f"Name: {self.name}, Age: {self.Age}, Class: {self.Class}, Level: {self.Level}, Role: {self.npc_role}, Aggressive: {self.aggressive}"
381
+
382
+ class PC_action:
383
+ def __init__(self, value) -> None:
384
+ if not value in ValidActions:
385
+ raise ValueError
386
+ self.value = value
387
+
388
+ def __eq__(self, value: object) -> bool:
389
+ if isinstance(value, PC_action):
390
+ return self.value == value.value
391
+ return self.value == value
@@ -0,0 +1,74 @@
1
+ from .utils import *
2
+
3
+ class item:
4
+
5
+ def __init__(self, name: str = '', type: str = 'miscellaneous', value: int = 0):
6
+ self.name = name
7
+ self.type = type
8
+ self.value = value
9
+
10
+ def sell(self, seller) -> bool:
11
+ if self.type.lower() == 'valuable':
12
+ seller.money += self.value
13
+ return True
14
+ else:
15
+ return False
16
+
17
+ def IsUsable(self) -> bool:
18
+ return self.usable
19
+
20
+ class ShopItem:
21
+ def __init__(self, item: item, price: int):
22
+ self.item = item
23
+ self.price = price
24
+
25
+ def display(self):
26
+ return f"{self.item.name} - {self.price} gold: {self.item.effect}"
27
+
28
+ def can_buy(self, player) -> bool:
29
+ return player.money >= self.price
30
+
31
+ def buy(self, player) -> bool:
32
+ if self.can_buy(player):
33
+ player.money -= self.price
34
+ player.inventory.append(self.item)
35
+ return True
36
+ else:
37
+ return False
38
+
39
+ class inv(list):
40
+ def __contains__(self, item_name) -> bool:
41
+ for item_ in self:
42
+ if item_.name == item_name:
43
+ return True
44
+ return False
45
+
46
+ def index(self, value, start=0, end=None):
47
+ if end is None:
48
+ end = len(self)
49
+
50
+ # Custom implementation of index method
51
+ for i in range(start, end):
52
+ if isinstance(self[i], item):
53
+ if self[i].name == value:
54
+ return i
55
+ return None
56
+
57
+ def remove(self, value):
58
+ if isinstance(value, item):
59
+ if value in self:
60
+ del self[self.index(value.name)]
61
+ return
62
+ del self[self.index(value)]
63
+
64
+ class container:
65
+ def __init__(self, contents: list[item], secret: bool = False) -> None:
66
+ self.contents = contents
67
+ self.secret = secret
68
+
69
+ def take_contents(self, geter = None):
70
+ try:
71
+ for Item in self.contents:
72
+ geter.inventory_add(Item)
73
+ finally:
74
+ self.contents = None