neelthee-mansion 3.22.9__py3-none-any.whl → 3.23.1__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.
@@ -4,6 +4,7 @@ from .items import *
4
4
  from .Quests import *
5
5
  from .all_game_utils import *
6
6
  import tkinter as tk
7
+ from tkinter import scrolledtext
7
8
 
8
9
 
9
10
  GameState = {
@@ -16,10 +17,11 @@ GameState = {
16
17
  Neel-thee's Mansion of Amnesia
17
18
  """
18
19
 
19
- global player, evil_mage, commands, NOTE_NUM, credits, color_coding, quest_manager, revealer, CHARACTERSLIST, BACKGROUNDS
20
+ global player, evil_mage, commands, NOTE_NUM, credits, color_coding, quest_manager, revealer, CHARACTERSLIST, BACKGROUNDS, info_text_area
20
21
 
21
22
  player_info_root = None
22
23
  player_info_label = None
24
+ info_text_area = None
23
25
 
24
26
  BACKGROUNDS = {
25
27
  "Adventurer": ["survival", "climbing"],
@@ -121,7 +123,7 @@ def parse_command(command_str: str, commands: dict):
121
123
  def showInstructions():
122
124
  global player
123
125
  # Display the game instructions
124
- type_text(
126
+ add_text_to_textbox(
125
127
  """
126
128
  ===========================
127
129
  Commands:
@@ -138,18 +140,17 @@ help - Show these instructions
138
140
  hint - Get a random hint for your current location
139
141
  map - Display the map of places you have been to
140
142
  """,
141
- colorTrue=color_coding,
142
143
  )
143
144
 
144
145
 
145
146
  def showHint():
146
147
  global player
147
148
  if "Hints" in ROOMS[player.CURRENTROOM]:
148
- type_text("You think:", colorTrue=color_coding)
149
+ add_text_to_textbox("You think:")
149
150
  hint = choice(ROOMS[player.CURRENTROOM]["Hints"])
150
- type_text(hint, colorTrue=color_coding)
151
+ add_text_to_textbox(hint)
151
152
  else:
152
- type_text("You can't think of anything", colorTrue=color_coding)
153
+ add_text_to_textbox("You can't think of anything")
153
154
 
154
155
 
155
156
  def check_direction(var: str, directions: list):
@@ -162,27 +163,25 @@ def check_direction(var: str, directions: list):
162
163
 
163
164
  def End(text: str, win: bool = True):
164
165
  global player
165
- type_text(text, colorTrue=color_coding)
166
+ add_text_to_textbox(text)
166
167
  if win:
167
- type_text("Do you want to leave the game? Y/N", colorTrue=color_coding)
168
+ add_text_to_textbox("Do you want to leave the game? Y/N")
168
169
  while True:
169
- leave = input(">").lower()
170
+ leave = loop_til_valid_input("", ).lower()
170
171
  if leave == "n":
171
- type_text("You decide to continue exploring.", colorTrue=color_coding)
172
+ add_text_to_textbox("You decide to continue exploring.")
172
173
  break
173
174
  elif leave == "y":
174
- type_text(
175
+ add_text_to_textbox(
175
176
  "You escaped the house... %*BOLD*%GAME OVER, YOU WIN!",
176
- colorTrue=color_coding,
177
177
  )
178
178
  commands["quit"]()
179
179
  else:
180
- type_text(
180
+ add_text_to_textbox(
181
181
  "Sorry, that wasn't 'y' or 'n'. Please enter 'y' or 'n'.",
182
- colorTrue=color_coding,
183
182
  )
184
183
  else:
185
- type_text("%*BOLD*%GAME OVER, YOU LOSE!", colorTrue=color_coding)
184
+ add_text_to_textbox("%*BOLD*%GAME OVER, YOU LOSE!")
186
185
  commands["quit"]()
187
186
 
188
187
 
@@ -206,32 +205,28 @@ def Use_grappling_hook():
206
205
 
207
206
  def swing_into_forest():
208
207
  global player
209
- type_text(
210
- "You throw your grappling-hook, it catches a branch of a nearby tree and hooks back onto itself. \nYou can swing into the forest!",
211
- colorTrue=color_coding,
208
+ add_text_to_textbox(
209
+ "You throw your grappling-hook, it catches a branch of a nearby tree and hooks back onto itself. \nYou can swing into the forest!"
212
210
  )
213
211
  if ask_for_consent("Do you want to swing into the forest"):
214
- type_text("You swing into the forest", colorTrue=color_coding)
212
+ add_text_to_textbox("You swing into the forest")
215
213
  Move("Forest Clearing")
216
214
  else:
217
- type_text(
218
- "You flick the rope and it unhooks. You continue exploring the house.",
219
- colorTrue=color_coding,
215
+ add_text_to_textbox(
216
+ "You flick the rope and it unhooks. You continue exploring the house."
220
217
  )
221
218
 
222
219
  def climb_into_house():
223
220
  global player
224
- type_text(
225
- "You throw your grappling-hook, it catches the railing of the nearby house and hooks back onto itself. \nYou can climb into the house!",
226
- colorTrue=color_coding,
221
+ add_text_to_textbox(
222
+ "You throw your grappling-hook, it catches the railing of the nearby house and hooks back onto itself. \nYou can climb into the house!"
227
223
  )
228
224
  if ask_for_consent("Do you want to climb into the house"):
229
- type_text("You climb into the house", colorTrue=color_coding)
225
+ add_text_to_textbox("You climb into the house")
230
226
  Move("Balcony")
231
227
  else:
232
- type_text(
233
- "You flick the rope and it unhooks. You continue exploring the forest",
234
- colorTrue=color_coding,
228
+ add_text_to_textbox(
229
+ "You flick the rope and it unhooks. You continue exploring the forest"
235
230
  )
236
231
 
237
232
  if player.CURRENTROOM == "Balcony" and "grappling-hook" in player.inventory:
@@ -247,17 +242,16 @@ def Use_quill():
247
242
 
248
243
  if all(item in player.inventory for item in ["ink-pot", "parchment", "quill"]):
249
244
  parchment_index = player.inventory.index("parchment")
250
- type_text("What do you want to write", colorTrue=color_coding)
245
+ add_text_to_textbox("What do you want to write")
251
246
  write = str(input(">")).strip()
252
247
 
253
248
  if write:
254
249
  add_note(write, parchment_index)
255
250
  else:
256
- type_text("You can't write nothing", colorTrue=color_coding)
251
+ add_text_to_textbox("You can't write nothing")
257
252
  else:
258
- type_text(
259
- "You need an ink pot, parchment, and a quill to write.",
260
- colorTrue=color_coding,
253
+ add_text_to_textbox(
254
+ "You need an ink pot, parchment, and a quill to write."
261
255
  )
262
256
 
263
257
 
@@ -267,10 +261,10 @@ def Use_note(note_number):
267
261
  note_key = f"note {note_number}"
268
262
  if note_key in player.inventory:
269
263
  note_index = int(note_number) - 1
270
- type_text(f"You read:", colorTrue=color_coding)
271
- type_text(player.NOTES[note_index], colorTrue=color_coding)
264
+ add_text_to_textbox(f"You read:")
265
+ add_text_to_textbox(player.NOTES[note_index])
272
266
  else:
273
- type_text("You do not have that note", colorTrue=color_coding)
267
+ add_text_to_textbox("You do not have that note")
274
268
 
275
269
 
276
270
  def Use(*Args):
@@ -283,8 +277,8 @@ def Use(*Args):
283
277
  item_obj = player.inventory[player.inventory.index(Item)]
284
278
  if isinstance(item_obj, item):
285
279
  if item_obj.sell(player):
286
- type_text(
287
- f"You sell the %*BLUE*%{Item}%*RESET*%", colorTrue=color_coding
280
+ add_text_to_textbox(
281
+ f"You sell the %*BLUE*%{Item}%*RESET*%"
288
282
  )
289
283
  player.inventory.remove(item_obj.name)
290
284
  elif Item == "quill":
@@ -305,13 +299,13 @@ def PickKey(locked_obj):
305
299
 
306
300
  if keys:
307
301
  while True:
308
- type_text(
302
+ add_text_to_textbox(
309
303
  f"Please pick which key you want to use in the lock. This is what you know about the lock: {locked_obj}. These are your keys:"
310
304
  )
311
305
 
312
306
  # Enumerate keys and display them
313
307
  for idx, key in enumerate(keys, 1): # Starts numbering at 1
314
- type_text(f"{idx}. {key.name} - {key.CurentRevealStr}")
308
+ add_text_to_textbox(f"{idx}. {key.name} - {key.CurentRevealStr}")
315
309
 
316
310
  # Use loop_til_valid_input to get a valid integer within the correct range
317
311
  choice = loop_til_valid_input(
@@ -338,8 +332,8 @@ def Move(move):
338
332
  ROOMS[newRoom]["descovered"] = True
339
333
  return ROOMS[player.CURRENTROOM]["directions"][move]
340
334
  else:
341
- type_text(
342
- "You don't have enough money to charter a ship.", colorTrue=color_coding
335
+ add_text_to_textbox(
336
+ "You don't have enough money to charter a ship."
343
337
  )
344
338
  return player.CURRENTROOM
345
339
 
@@ -349,7 +343,7 @@ def Move(move):
349
343
  if key.GetKeyCode() == "629.IdnXwnt":
350
344
  End("You unlock the gate to the garden with the key!")
351
345
  return newRoom
352
- type_text("The gate is locked.", colorTrue=color_coding)
346
+ add_text_to_textbox("The gate is locked.")
353
347
  return newRoom
354
348
 
355
349
  def move_to_room():
@@ -389,15 +383,17 @@ def Move(move):
389
383
  if isinstance(randomEvent, RandomEvent):
390
384
  randomEvent.check_and_trigger(player)
391
385
  return
392
- type_text(f"There is no exit {move}", colorTrue=color_coding)
386
+ add_text_to_textbox(f"There is no exit {move}")
393
387
 
394
388
 
395
389
  def start():
396
- global player
390
+ global player, info_text_area
391
+ # Wait until info_text_area is initialized
392
+ while info_text_area is None:
393
+ time.sleep(0.1)
397
394
  # shows the main menu
398
- type_text(
395
+ add_text_to_textbox(
399
396
  f"\nHello %*MAGENTA*%{player.name}%*RESET*% and welcome to my Role Playing Game. \nI hope you have fun!",
400
- colorTrue=color_coding,
401
397
  )
402
398
  showInstructions()
403
399
 
@@ -429,10 +425,9 @@ def update_player_info():
429
425
  player_info_root.after(0, lambda: player_info_label.config(text=info_text))
430
426
 
431
427
  def start_tkinter_thread():
432
- thread = threading.Thread(target=show_player_info)
433
- thread.daemon = True
434
- thread.start()
435
-
428
+ player_info_thread = threading.Thread(target=show_player_info)
429
+ player_info_thread.daemon = True
430
+ player_info_thread.start()
436
431
 
437
432
  def showStatus():
438
433
  global player
@@ -456,14 +451,14 @@ def showStatus():
456
451
 
457
452
  text += f"\n---------------------------"
458
453
 
459
- type_text(text, colorTrue=color_coding)
454
+ add_text_to_textbox(text)
460
455
 
461
456
  # Optionally display additional room description
462
457
  if "description" in ROOMS[player.CURRENTROOM] and ask_for_consent(
463
458
  "Do you want to observe the area"
464
459
  ):
465
- type_text("The area:", colorTrue=color_coding)
466
- type_text(ROOMS[player.CURRENTROOM]["description"], colorTrue=color_coding)
460
+ add_text_to_textbox("The area:")
461
+ add_text_to_textbox(ROOMS[player.CURRENTROOM]["description"])
467
462
 
468
463
 
469
464
  def display_directions(text):
@@ -516,27 +511,27 @@ def Examine(*Args):
516
511
  if item_index is not None: # Check explicitly if item_index is valid
517
512
  _ = player.inventory[item_index]
518
513
  if isinstance(_, item):
519
- type_text("You look at your item and you figure out this about it:")
514
+ add_text_to_textbox("You look at your item and you figure out this about it:")
520
515
  if not revealer.reveal_key_code(_):
521
516
  if _.type == "weapon":
522
- type_text(f"This item is a weapon that adds {_.value} damage.")
517
+ add_text_to_textbox(f"This item is a weapon that adds {_.value} damage.")
523
518
  elif _.type == "readable":
524
519
  if "reading" in player.Skills:
525
- type_text(f"You read {_.name} and it contains:")
520
+ add_text_to_textbox(f"You read {_.name} and it contains:")
526
521
  if isinstance(_, Book):
527
- type_text(_.GetContense())
522
+ add_text_to_textbox(_.GetContense())
528
523
  else:
529
- type_text(_.value)
524
+ add_text_to_textbox(_.value)
530
525
  elif isinstance(_, Recorder):
531
- type_text("This device records sound. The current message is:")
532
- type_text(_.message)
526
+ add_text_to_textbox("This device records sound. The current message is:")
527
+ add_text_to_textbox(_.message)
533
528
  else:
534
- type_text(_.value)
529
+ add_text_to_textbox(_.value)
535
530
  elif Name in ROOMS[player.CURRENTROOM]["directions"]: # Check exits in the room
536
531
  door = ROOMS[player.CURRENTROOM]["directions"][Name]
537
532
  if isinstance(door, Door):
538
533
  if isinstance(door.lock, Lock):
539
- type_text(
534
+ add_text_to_textbox(
540
535
  (
541
536
  "The door is locked,"
542
537
  if door.lock.is_locked
@@ -546,14 +541,14 @@ def Examine(*Args):
546
541
  )
547
542
  revealer.reveal_key_code(door)
548
543
  else:
549
- type_text(f"The exit {Name} has no lock.")
544
+ add_text_to_textbox(f"The exit {Name} has no lock.")
550
545
  else:
551
- type_text(f"There is nothing special about the exit {Name}.")
546
+ add_text_to_textbox(f"There is nothing special about the exit {Name}.")
552
547
  elif "containers" in ROOMS[player.CURRENTROOM] and Name in ROOMS[player.CURRENTROOM]["containers"]:
553
548
  containerins = ROOMS[player.CURRENTROOM]["containers"][Name]
554
549
  if isinstance(containerins, container):
555
550
  if isinstance(containerins.lock, Lock):
556
- type_text(
551
+ add_text_to_textbox(
557
552
  (
558
553
  "The container is locked,"
559
554
  if containerins.lock.is_locked
@@ -563,9 +558,9 @@ def Examine(*Args):
563
558
  )
564
559
  revealer.reveal_key_code(containerins)
565
560
  else:
566
- type_text(f"The container {Name} has no lock.")
561
+ add_text_to_textbox(f"The container {Name} has no lock.")
567
562
  else:
568
- type_text(f"There is no container named {Name} in this room.")
563
+ add_text_to_textbox(f"There is no container named {Name} in this room.")
569
564
  elif "creatures stats" in ROOMS[player.CURRENTROOM]:
570
565
  for Creature in ROOMS[player.CURRENTROOM]["creatures stats"]:
571
566
  if isinstance(Creature, creature):
@@ -574,7 +569,7 @@ def Examine(*Args):
574
569
  Creature.talk()
575
570
  return
576
571
  else:
577
- type_text(f"There is nothing special about the {Name}.")
572
+ add_text_to_textbox(f"There is nothing special about the {Name}.")
578
573
 
579
574
 
580
575
  def battle(player: PC, good_guys: list, bad_guys: list, last_room):
@@ -639,7 +634,7 @@ def player_turn(player: PC, monster: creature):
639
634
  perform_attack(player, monster)
640
635
  elif player_action == "defend":
641
636
  player.defending = True
642
- type_text("You brace yourself for the next attack.", colorTrue=color_coding)
637
+ add_text_to_textbox("You brace yourself for the next attack.")
643
638
  elif player_action == "special":
644
639
  use_special_ability(player, monster)
645
640
 
@@ -652,7 +647,7 @@ def monster_turn(player: PC, monster: creature):
652
647
  player (PC): The player or ally.
653
648
  monster (creature): The monster attacking.
654
649
  """
655
- type_text(f"The %*CYAN*%{monster.name}%*RESET*% attacks!", colorTrue=color_coding)
650
+ add_text_to_textbox(f"The %*CYAN*%{monster.name}%*RESET*% attacks!")
656
651
  damage = calculate_damage(monster, player)
657
652
  player.take_damage(damage)
658
653
 
@@ -677,7 +672,7 @@ def handle_victory(player: PC, monsters: list):
677
672
  player (PC): The player character.
678
673
  monsters (list): The list of defeated monsters.
679
674
  """
680
- type_text("You have defeated all the enemies!", colorTrue=color_coding)
675
+ add_text_to_textbox("You have defeated all the enemies!")
681
676
  for monster in monsters:
682
677
  if monster.hp <= 0:
683
678
  player.inventory_add(monster.dropped_items)
@@ -699,11 +694,11 @@ def calculate_damage(attacker, defender) -> int:
699
694
 
700
695
  if random() < attacker.crit_chance:
701
696
  damage *= 2
702
- type_text("Critical hit!", colorTrue=color_coding)
697
+ add_text_to_textbox("Critical hit!")
703
698
 
704
699
  if hasattr(defender, "defending") and defender.defending:
705
700
  damage //= 2
706
- type_text("The attack is defended, reducing damage.", colorTrue=color_coding)
701
+ add_text_to_textbox("The attack is defended, reducing damage.")
707
702
  defender.defending = False
708
703
 
709
704
  return damage
@@ -736,13 +731,12 @@ def use_special_ability(player: PC, monster: creature):
736
731
  """
737
732
  if player.special_ability.ready:
738
733
  player.special_ability.activate(monster)
739
- type_text(
740
- f"You use your special ability: {player.special_ability.name}.",
741
- colorTrue=color_coding,
734
+ add_text_to_textbox(
735
+ f"You use your special ability: {player.special_ability.name}."
742
736
  )
743
737
  player.special_ability.ready = False
744
738
  else:
745
- type_text("Your special ability is not ready yet.", colorTrue=color_coding)
739
+ add_text_to_textbox("Your special ability is not ready yet.")
746
740
 
747
741
 
748
742
  def select_target(chooser, targets: list):
@@ -758,11 +752,11 @@ def select_target(chooser, targets: list):
758
752
  """
759
753
  if chooser == player:
760
754
  valid_targets = []
761
- type_text("Who do you want to attack? The options:")
755
+ add_text_to_textbox("Who do you want to attack? The options:")
762
756
  # Enumerate through the targets to get both the index and the enemy.
763
757
  for index, enemy in enumerate(targets):
764
758
  if enemy.hp > 0:
765
- type_text(f"{index + 1}: {enemy.name} ({enemy.hp} HP)")
759
+ add_text_to_textbox(f"{index + 1}: {enemy.name} ({enemy.hp} HP)")
766
760
  valid_targets.append(index)
767
761
 
768
762
  # Prompt the player to select a target
@@ -772,9 +766,9 @@ def select_target(chooser, targets: list):
772
766
  if choice in valid_targets:
773
767
  return targets[choice]
774
768
  else:
775
- type_text("Invalid choice. Please select a valid target.")
769
+ add_text_to_textbox("Invalid choice. Please select a valid target.")
776
770
  except ValueError:
777
- type_text("Invalid input. Please enter a number.")
771
+ add_text_to_textbox("Invalid input. Please enter a number.")
778
772
  else:
779
773
  # AI or other logic for non-player chooser
780
774
  for target in targets:
@@ -807,24 +801,24 @@ def command():
807
801
  else:
808
802
  commands[action]()
809
803
  else:
810
- type_text(
804
+ add_text_to_textbox(
811
805
  f"Unknown command '{action}'. Type 'help' for a list of commands.",
812
- colorTrue=color_coding,
806
+
813
807
  )
814
808
  if action in commands:
815
809
  ShouldBreak = True
816
810
  if ShouldBreak:
817
811
  return
818
812
  #except KeyError as e:
819
- # type_text(f"KeyError: {e} - This might be due to an undefined command or incorrect arguments.", colorTrue=color_coding)
813
+ # add_text_to_textbox(f"KeyError: {e} - This might be due to an undefined command or incorrect arguments.")
820
814
  #except ValueError as e:
821
- # type_text(f"ValueError: {e} - This might be due to incorrect arguments provided.", colorTrue=color_coding)
815
+ # add_text_to_textbox(f"ValueError: {e} - This might be due to incorrect arguments provided.")
822
816
  #except Exception as e:
823
- # type_text(f"Unexpected Error: {e}", colorTrue=color_coding)
817
+ # add_text_to_textbox(f"Unexpected Error: {e}")
824
818
 
825
819
 
826
820
  def handle_sleep_command(player: PC):
827
- type_text("You decide to rest for a while.", colorTrue=color_coding)
821
+ add_text_to_textbox("You decide to rest for a while.")
828
822
 
829
823
  # Simulate some time passing
830
824
  sleep(2) # Example: sleep for 2 seconds
@@ -833,7 +827,7 @@ def handle_sleep_command(player: PC):
833
827
  player.heal(3) # Example: heal 3 health points during sleep
834
828
 
835
829
  # Optional: Print a message or effect that happens during sleep
836
- type_text("You feel refreshed after a good rest.", colorTrue=color_coding)
830
+ add_text_to_textbox("You feel refreshed after a good rest.")
837
831
 
838
832
 
839
833
  def get_player_input(split=True):
@@ -858,29 +852,27 @@ def handle_get_command(player: PC, *Args):
858
852
  if item_name == ItemName:
859
853
  player.inventory_add([ROOMS[player.CURRENTROOM]["items"][ItemName]])
860
854
  del ROOMS[player.CURRENTROOM]["items"][ItemName]
861
- type_text(f"%*BLUE*%{item_name}%*RESET*% got!", colorTrue=color_coding)
855
+ add_text_to_textbox(f"%*BLUE*%{item_name}%*RESET*% got!")
862
856
  return
863
- type_text(f"Can't get {item_name}!", colorTrue=color_coding)
857
+ add_text_to_textbox(f"Can't get {item_name}!")
864
858
 
865
859
 
866
860
  def handle_look_command():
867
861
  global player
868
862
  should_return = False
869
863
  if "items" in ROOMS[player.CURRENTROOM]:
870
- type_text(
871
- f'The items in the room: %*BLUE*%{", ".join(ROOMS[player.CURRENTROOM]["items"].keys())}%*RESET*%.',
872
- colorTrue=color_coding,
864
+ add_text_to_textbox(
865
+ f'The items in the room: %*BLUE*%{", ".join(ROOMS[player.CURRENTROOM]["items"].keys())}%*RESET*%.'
873
866
  )
874
867
  should_return = True
875
868
  if "containers" in ROOMS[player.CURRENTROOM]:
876
- type_text(
877
- f"The containers here are: %*RED*%{', '.join(ROOMS[player.CURRENTROOM]['containers'].keys())}%*RESET*%",
878
- colorTrue=color_coding,
869
+ add_text_to_textbox(
870
+ f"The containers here are: %*RED*%{', '.join(ROOMS[player.CURRENTROOM]['containers'].keys())}%*RESET*%"
879
871
  )
880
872
  should_return = True
881
873
  if should_return:
882
874
  return
883
- type_text("There is nothing of interest.", colorTrue=color_coding)
875
+ add_text_to_textbox("There is nothing of interest.")
884
876
 
885
877
 
886
878
  def handle_use_command(*Args):
@@ -896,7 +888,7 @@ def handle_search_command(player, *Args):
896
888
  ):
897
889
  search_container(player, Container)
898
890
  else:
899
- type_text(f"You cannot search the {Container}", colorTrue=color_coding)
891
+ add_text_to_textbox(f"You cannot search the {Container}")
900
892
 
901
893
 
902
894
  def search_container(player: PC, Container):
@@ -906,10 +898,9 @@ def search_container(player: PC, Container):
906
898
  if isinstance(Container.lock, Lock):
907
899
  key = PickKey(Container.lock)
908
900
  Container.Unlock(key, player)
909
- type_text(
901
+ add_text_to_textbox(
910
902
  f"You search the{' secret' if Container.secret else ''} %*RED*%{ContainerName}%*RESET*% and find a ",
911
- newline=False,
912
- colorTrue=color_coding,
903
+ newline=False
913
904
  )
914
905
  for searchitem in Container.contents:
915
906
  if searchitem:
@@ -920,23 +911,38 @@ def search_container(player: PC, Container):
920
911
  < last_index(Container.contents)
921
912
  else "\n"
922
913
  )
923
- type_text(
914
+ add_text_to_textbox(
924
915
  f"%*BLUE*%{searchitem.name}%*RESET*%{end_str}",
925
916
  newline=False,
926
- colorTrue=color_coding,
917
+
927
918
  )
928
919
  Container.take_contents(player)
929
920
 
930
921
 
922
+ def put_in_container(player: PC, PutItem=None, container=None):
923
+ player.inventory.remove(PutItem.name)
924
+ if not ROOMS[player.CURRENTROOM]["containers"][container].contents:
925
+ ROOMS[player.CURRENTROOM]["containers"][container].contents = []
926
+ if not isinstance(
927
+ ROOMS[player.CURRENTROOM]["containers"][container].contents, list
928
+ ):
929
+ ROOMS[player.CURRENTROOM]["containers"][container].contents = [
930
+ ROOMS[player.CURRENTROOM]["containers"][container].contents
931
+ ]
932
+ ROOMS[player.CURRENTROOM]["containers"][container].contents += [PutItem]
933
+ add_text_to_textbox(
934
+ f"You put you're %*BLUE*%{PutItem.name}%*RESET*% into the %*RED*%{container}%*RESET*%",
935
+ )
936
+
937
+
931
938
  def handle_put_command(player: PC, *Args):
932
939
  arguments = " ".join(Args)
933
940
  Arguments = arguments.split(" in ")
934
941
 
935
942
  # Ensure we have exactly two parts
936
943
  if len(Arguments) < 2:
937
- type_text(
938
- "You need to specify an item and where to put it (e.g., 'put book in drawer').",
939
- colorTrue=color_coding,
944
+ add_text_to_textbox(
945
+ "You need to specify an item and where to put it (e.g., 'put book drawer')."
940
946
  )
941
947
  return
942
948
 
@@ -947,8 +953,8 @@ def handle_put_command(player: PC, *Args):
947
953
 
948
954
  # Check if item is in inventory
949
955
  if item_name not in [item.name for item in player.inventory]:
950
- type_text(
951
- f"You don't have {item_name} in your inventory.", colorTrue=color_coding
956
+ add_text_to_textbox(
957
+ f"You don't have {item_name} in your inventory."
952
958
  )
953
959
  return
954
960
 
@@ -959,29 +965,11 @@ def handle_put_command(player: PC, *Args):
959
965
  if "containers" in ROOMS[player.CURRENTROOM]:
960
966
  put_in_container(player, PutItem, container_name)
961
967
  else:
962
- type_text(
963
- f"You cannot put the {PutItem.name} in the {container_name}",
964
- colorTrue=color_coding,
968
+ add_text_to_textbox(
969
+ f"You cannot put the {PutItem.name} in the {container_name}"
965
970
  )
966
971
 
967
972
 
968
- def put_in_container(player: PC, PutItem=None, container=None):
969
- player.inventory.remove(PutItem.name)
970
- if not ROOMS[player.CURRENTROOM]["containers"][container].contents:
971
- ROOMS[player.CURRENTROOM]["containers"][container].contents = []
972
- if not isinstance(
973
- ROOMS[player.CURRENTROOM]["containers"][container].contents, list
974
- ):
975
- ROOMS[player.CURRENTROOM]["containers"][container].contents = [
976
- ROOMS[player.CURRENTROOM]["containers"][container].contents
977
- ]
978
- ROOMS[player.CURRENTROOM]["containers"][container].contents += [PutItem]
979
- type_text(
980
- f"You put you're %*BLUE*%{PutItem.name}%*RESET*% into the %*RED*%{container}%*RESET*%",
981
- colorTrue=color_coding,
982
- )
983
-
984
-
985
973
  def handle_get_quest_command(questnum):
986
974
  global player
987
975
  if "quests" in ROOMS[player.CURRENTROOM]:
@@ -993,7 +981,7 @@ def handle_get_quest_command(questnum):
993
981
 
994
982
  def PrintMap():
995
983
  global player
996
- type_text(ShowMap())
984
+ add_text_to_textbox(ShowMap())
997
985
 
998
986
 
999
987
  # Define handling functions for different types of enemies
@@ -1003,9 +991,8 @@ def handle_hungry_bear(player: PC, enemy: creature):
1003
991
  if ask_for_consent("Do you want to throw your potion at the bear"):
1004
992
  enemy_reacting = False
1005
993
  del player.inventory[player.inventory.index("potion")]
1006
- type_text(
1007
- f"You throw the potion at the bear and it explodes into a puff of magic smoke that stuns the bear!",
1008
- colorTrue=color_coding,
994
+ add_text_to_textbox(
995
+ f"You throw the potion at the bear and it explodes into a puff of magic smoke that stuns the bear!"
1009
996
  )
1010
997
  if enemy_reacting:
1011
998
  return [enemy, enemy_reacting]
@@ -1016,9 +1003,8 @@ def handle_grumpy_pig(player: PC, enemy: creature):
1016
1003
  if "saddle" in player.inventory and "pig-rod" in player.inventory:
1017
1004
  if ask_for_consent("Do you want to use your saddle and pig-rod on the pig"):
1018
1005
  enemy_reacting = False
1019
- type_text(
1020
- f"You throw a saddle onto the pig and leap on steering it about with a pig fishing rod!",
1021
- colorTrue=color_coding,
1006
+ add_text_to_textbox(
1007
+ f"You throw a saddle onto the pig and leap on steering it about with a pig fishing rod!"
1022
1008
  )
1023
1009
  del ROOMS[player.CURRENTROOM]["creatures stats"]
1024
1010
  del player.inventory[player.inventory.index("saddle")]
@@ -1028,9 +1014,8 @@ def handle_grumpy_pig(player: PC, enemy: creature):
1028
1014
  if "torch" in player.inventory:
1029
1015
  if ask_for_consent("Do you want to use your torch to scare the pig away"):
1030
1016
  enemy_reacting = False
1031
- type_text(
1032
- f"You wave your torch at the pig and it runs away through a tiny open window.",
1033
- colorTrue=color_coding,
1017
+ add_text_to_textbox(
1018
+ f"You wave your torch at the pig and it runs away through a tiny open window."
1034
1019
  )
1035
1020
  del ROOMS[player.CURRENTROOM]["creatures stats"][
1036
1021
  ROOMS[player.CURRENTROOM]["creatures stats"].index(enemy)
@@ -1039,9 +1024,8 @@ def handle_grumpy_pig(player: PC, enemy: creature):
1039
1024
  if "rations" in player.inventory:
1040
1025
  if ask_for_consent("Do you want to throw your ration at the pig"):
1041
1026
  enemy_reacting = False
1042
- type_text(
1043
- f"You quickly throw rations at the pig. It still doesn't look happy though.",
1044
- colorTrue=color_coding,
1027
+ add_text_to_textbox(
1028
+ f"You quickly throw rations at the pig. It still doesn't look happy though."
1045
1029
  )
1046
1030
  del player.inventory[player.inventory.index("rations")]
1047
1031
  player.xp += 15
@@ -1055,9 +1039,8 @@ def handle_greedy_goblin(player: PC, enemy: creature):
1055
1039
  if player.money >= 15:
1056
1040
  if ask_for_consent("Do you want to pay the goblin to not attack you"):
1057
1041
  enemy_reacting = False
1058
- type_text(
1059
- f"You pay the {enemy.name} to not attack you for now, but he says you should run.",
1060
- colorTrue=color_coding,
1042
+ add_text_to_textbox(
1043
+ f"You pay the {enemy.name} to not attack you for now, but he says you should run."
1061
1044
  )
1062
1045
  player.money -= 15
1063
1046
  enemy.dropped_items[1].value += 15
@@ -1117,9 +1100,8 @@ def handle_wolf(player: PC, wolf: Guard):
1117
1100
  if "rations" in player.inventory:
1118
1101
  if ask_for_consent("Do you want to give your ration to the wolf"):
1119
1102
  enemy_reacting = False
1120
- type_text(
1121
- "You quickly give your rations to the wolf. It looks happy, walks up to you, and nuzzles you.",
1122
- colorTrue=color_coding,
1103
+ add_text_to_textbox(
1104
+ "You quickly give your rations to the wolf. It looks happy, walks up to you, and nuzzles you."
1123
1105
  )
1124
1106
  player.inventory.remove("rations")
1125
1107
  wolf.patrol_type = "follow"
@@ -1144,9 +1126,22 @@ def handle_guard_action(guard):
1144
1126
  return [False, [guard, True]] # Function was not found
1145
1127
 
1146
1128
 
1129
+ def create_info_textbox():
1130
+ global info_text_area
1131
+ root = tk.Tk()
1132
+ root.title("Text Box with Scrollbar")
1133
+
1134
+ info_text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=120, height=40)
1135
+ info_text_area.pack(padx=10, pady=10)
1136
+
1137
+ # Set the text box to read-only
1138
+ info_text_area.config(state=tk.DISABLED)
1139
+
1140
+ root.mainloop()
1141
+
1142
+
1147
1143
  def initializer():
1148
1144
  global color_coding, player, CHARACTERSLIST
1149
- df = pd.DataFrame(CHARACTERSLIST)
1150
1145
 
1151
1146
  # A tkinter window that asks these questions, instead of the console.Include a button that says "Exit Game". When the button is clicked, the game exits. Include a button that says "premade character". When the button is clicked, a new window opens that lets you choose one of the premade characters from teh CHARACTERSLIST var. Include a button that says "custom character". When the button is clicked, a new window opens that asks them for a name, age, hight, and waight(LBs).
1152
1147
  def create_main_menu():
@@ -1279,6 +1274,9 @@ def initializer():
1279
1274
 
1280
1275
  create_main_menu()
1281
1276
 
1277
+ info_text_thread = threading.Thread(target=create_info_textbox, daemon=True, name="Info Text Box Thread")
1278
+ info_text_thread.start()
1279
+
1282
1280
 
1283
1281
  def main():
1284
1282
  global player, color_coding
@@ -1352,11 +1350,11 @@ def main():
1352
1350
  if isinstance(enemy, creature):
1353
1351
  if not isinstance(enemy, NPC):
1354
1352
  if enemy.hp > 0:
1355
- enemy.type_text_flavor_text()
1353
+ enemy.add_text_to_textbox_flavor_text()
1356
1354
  if ask_for_consent(
1357
1355
  f"Do you want to examine the {enemy.name}"
1358
1356
  ):
1359
- enemy.type_text_description()
1357
+ enemy.add_text_to_textbox_description()
1360
1358
 
1361
1359
  is_reacting = False
1362
1360
 
neelthee_mansion/items.py CHANGED
@@ -24,7 +24,7 @@ class Lock:
24
24
  self.key_code = key_code if key_code else get_random_string(10)
25
25
  self.is_locked = True
26
26
 
27
- def unlock(self, key, player):
27
+ def unlock(self, key, player, text_area=None):
28
28
  if not self.is_locked:
29
29
  do_lock = loop_til_valid_input(
30
30
  "The lock is not locked, do you want to lock it again? Y/N",
@@ -32,21 +32,21 @@ class Lock:
32
32
  Y_N,
33
33
  ).value
34
34
  if do_lock:
35
- type_text("You relock the lock")
35
+ add_text_to_textbox(text_area, "You relock the lock")
36
36
  return False
37
37
 
38
38
  elif key.GetKeyCode() == self.key_code:
39
- type_text("The lock clicks open!")
39
+ add_text_to_textbox(text_area, "The lock clicks open!")
40
40
  self.is_locked = False
41
41
  if key.KeyDels:
42
42
  player.inventory.remove(key)
43
- type_text(
43
+ add_text_to_textbox(
44
44
  f"The {key.name} was used and has been removed from your inventory."
45
45
  )
46
46
  return True
47
47
 
48
48
  else:
49
- type_text("The lock holds fast!")
49
+ add_text_to_textbox(text_area, "The lock holds fast!")
50
50
  return False
51
51
 
52
52
  def __str__(self) -> str:
@@ -68,11 +68,11 @@ class KeyRevealer:
68
68
  def __init__(self, max_reveals=2):
69
69
  self.max_reveals = max_reveals
70
70
 
71
- def reveal_key_code(self, obj: Key, mask_char="="):
71
+ def reveal_key_code(self, obj: Key, mask_char="=", text_area=None):
72
72
  if hasattr(obj, "reveal_count"):
73
73
  if obj.reveal_count >= self.max_reveals:
74
- type_text(f"You can only reveal a Key Code {self.max_reveals} times.")
75
- type_text(
74
+ add_text_to_textbox(text_area, f"You can only reveal a Key Code {self.max_reveals} times.")
75
+ add_text_to_textbox(text_area,
76
76
  f"Here is what you already know about this lock: {obj.CurentRevealStr}"
77
77
  )
78
78
  return
@@ -103,7 +103,7 @@ class KeyRevealer:
103
103
 
104
104
  obj.reveal_count += 1
105
105
  obj.CurentRevealStr = "".join(result)
106
- type_text("".join(result))
106
+ add_text_to_textbox(text_area, "".join(result))
107
107
  return True
108
108
 
109
109
 
@@ -174,9 +174,9 @@ class container:
174
174
  "=" * len(self.lock.key_code) if isinstance(self.lock, Lock) else ""
175
175
  )
176
176
 
177
- def take_contents(self, geter=None):
177
+ def take_contents(self, geter=None, text_area=None):
178
178
  if isinstance(self.lock, Lock) and self.lock.is_locked:
179
- type_text("The container is locked and won't budge.")
179
+ add_text_to_textbox(text_area, "The container is locked and won't budge.")
180
180
  return None
181
181
 
182
182
  try:
@@ -203,9 +203,9 @@ class Recorder(item):
203
203
  def __str__(self):
204
204
  return self.record if self.record else "This recorder has no record on it."
205
205
 
206
- def Record(self):
207
- type_text("What record do you want to put on the recorder? \n>", newline=False)
208
- message = input()
206
+ def Record(self, text_area=None):
207
+ add_text_to_textbox(text_area, "What record do you want to put on the recorder? \n>", newline=False)
208
+ message = loop_til_valid_input()
209
209
  self.message = message
210
210
 
211
211
  def use(self):
neelthee_mansion/utils.py CHANGED
@@ -14,6 +14,8 @@ try:
14
14
 
15
15
  # Importing the whole module
16
16
  import pickle as pk
17
+ import tkinter as tk
18
+ from tkinter import scrolledtext
17
19
  import inspect
18
20
  import threading
19
21
  import json
@@ -45,6 +47,17 @@ These utilities aim to simplify development processes, promote code reuse, and i
45
47
  """
46
48
 
47
49
 
50
+ # a function that adds text to a text box and scrolls to the bottom and updates it
51
+ def add_text_to_textbox(text_area: scrolledtext.ScrolledText, text, newline=True):
52
+ # Enable the text box to insert text
53
+ text_area.config(state=tk.NORMAL)
54
+ text_area.insert(tk.END, text + f'{"\n"if newline else ""}')
55
+ text_area.see(tk.END)
56
+ text_area.update_idletasks()
57
+ # Set the text box back to read-only
58
+ text_area.config(state=tk.DISABLED)
59
+
60
+
48
61
  def perform_action_on_matches(input_list, target, action):
49
62
  """
50
63
  Perform an action on all items in the list that are the same as the target.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: neelthee-mansion
3
- Version: 3.22.9
3
+ Version: 3.23.1
4
4
  Summary: A text-based adventure game set in Neel-thee’s mansion.
5
5
  Home-page: https://github.com/Flameblade375/neelthee_mansion
6
6
  Author: Alexander.E.F
@@ -1,16 +1,16 @@
1
1
  neelthee_mansion/Books.py,sha256=Zs6GOi12vrikne-E37LdrLNRb6CyUogOCDApDGFj6Ls,26168
2
- neelthee_mansion/Mansion_of_Amnesia.py,sha256=RNC3D0JhYDMO-rng3zEr5OPnkbgJOIdD29-LNBSY-zM,53106
2
+ neelthee_mansion/Mansion_of_Amnesia.py,sha256=aL2brsPuJMyqq8c5XqPyamwH3QXLQiSYHV6OUHPr0JQ,52820
3
3
  neelthee_mansion/Quests.py,sha256=pUlru2RugP57MACQORZaF_X9lsbefTdPYTSO474phgo,2791
4
4
  neelthee_mansion/Rooms.py,sha256=CgenMX9ssTCWbDFopX6GHhNDnRYF5MpaDufWvt5fPwU,86025
5
5
  neelthee_mansion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  neelthee_mansion/__main__.py,sha256=OIAWZ04le70DyjtR4hlmK9csHej7EHxeUrMoNnM-Vjc,95
7
7
  neelthee_mansion/all_game_utils.py,sha256=AasunTkFmgAqt9ZIoYmymi4R7leBe4ubW-C1ts0Qclo,351
8
8
  neelthee_mansion/creatures.py,sha256=vUR8PmdiftCFBCGJbHkCT4AMUPvqwouDGQ4ye2fiPCw,20910
9
- neelthee_mansion/items.py,sha256=--DtMCZrurDAe3S-gB5DXAul_kmG9BGB0QmBY2-Fphc,6383
10
- neelthee_mansion/utils.py,sha256=GaCkein6dppeufYfBMk59gHAE2b4p9TJW2MsRjyyFvQ,13702
11
- neelthee_mansion-3.22.9.dist-info/LICENSE.md,sha256=CV8XGZaCyyAMdbkYFQUjb8AjBq9vkoyqdZCq1_hetms,1105
12
- neelthee_mansion-3.22.9.dist-info/METADATA,sha256=m5P0ZgqoW42173ZuHjIHsFh0fEAUPk78tiTY9LgecPs,1756
13
- neelthee_mansion-3.22.9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
14
- neelthee_mansion-3.22.9.dist-info/entry_points.txt,sha256=j5ScTTyIidFhmT3F6hcX9pnlom4cJdDmfe26BmM6Igo,56
15
- neelthee_mansion-3.22.9.dist-info/top_level.txt,sha256=woQImQewylhly5Rb24HwPEGMxPY6do_PaUwGd5BNLOM,17
16
- neelthee_mansion-3.22.9.dist-info/RECORD,,
9
+ neelthee_mansion/items.py,sha256=tSWWRzTIJja6I_BOz4hNz58MxVLRw9SKsdnavHWQPZs,6639
10
+ neelthee_mansion/utils.py,sha256=XZmFTGfhxdv8fCaq-4GWI7Vl8oAE0szv_eli2yjc2lE,14229
11
+ neelthee_mansion-3.23.1.dist-info/LICENSE.md,sha256=CV8XGZaCyyAMdbkYFQUjb8AjBq9vkoyqdZCq1_hetms,1105
12
+ neelthee_mansion-3.23.1.dist-info/METADATA,sha256=rMgqiMvleMIybDdWdcFG1WPlbTb4HvskihERsMx_D2I,1756
13
+ neelthee_mansion-3.23.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
14
+ neelthee_mansion-3.23.1.dist-info/entry_points.txt,sha256=j5ScTTyIidFhmT3F6hcX9pnlom4cJdDmfe26BmM6Igo,56
15
+ neelthee_mansion-3.23.1.dist-info/top_level.txt,sha256=woQImQewylhly5Rb24HwPEGMxPY6do_PaUwGd5BNLOM,17
16
+ neelthee_mansion-3.23.1.dist-info/RECORD,,