diff --git a/Kanjin-PygameGUI b/Kanjin-PygameGUI new file mode 100644 index 0000000..13f3c2d --- /dev/null +++ b/Kanjin-PygameGUI @@ -0,0 +1,485 @@ +import pygame +import pygame_gui +from enum import Enum, auto +from random import randint +from functions import * + + +class Player: + """Character Creation""" + + # Default Character + def __init__(self, name, gender, age, race, job): + # Personality + self.name = name + self.gender = gender + self.age = age + self.race = race + self.job = job + # Health + self.currentHP = 100 + self.maxHP = 100 + # Levels + self.level = 1 + self.exp = 0 + self.maxEXP = 100 + # Magic + self.spells_known = [] + self.spells_ready = [] + # Equipment + self.weapon = rock + self.armor = tornRags + # Defence + self.ac = 0 + self.elemental_resistance = {DamageType.FIRE: False, DamageType.WATER: False, DamageType.LIGHTNING: False} + self.physical_resistance = {DamageType.SLASHING: False, DamageType.CRUSHING: False, DamageType.PIERCING: False} + # Ability Scores + self.stats = {"Strength": 0, + "Dexterity": 0, + "Constitution": 0, + "Intelligence": 0, + "Wisdom": 0, + "Charisma": 0} + # Ability Modifiers + self.mods = {"Strength": 0, + "Dexterity": 0, + "Constitution": 0, + "Intelligence": 0, + "Wisdom": 0, + "Charisma": 0} + # Held items + self.inventory = {rock: {"Count": 1, + "object": Weapon, + "equipped": True + }, + tornRags: {"Count": 1, + "object": Armor, + "equipped": True + }, + GP1: {"Count": 10, + "object": Money, + "equipped": False + }, + } + + # @property + # def dexMod(self): + # return self.mods["Dexterity"] + + def getModifier(self): + self.mods["Strength"] = -5 + self.stats["Strength"] // 2 + self.mods["Dexterity"] = -5 + self.stats["Dexterity"] // 2 + self.mods["Constitution"] = -5 + self.stats["Constitution"] // 2 + self.mods["Intelligence"] = -5 + self.stats["Intelligence"] // 2 + self.mods["Wisdom"] = -5 + self.stats["Wisdom"] // 2 + self.mods["Charisma"] = -5 + self.stats["Charisma"] // 2 + + def set_stats(self): + if self.race == "elf": + self.stats["Dexterity"] += 2 + self.stats["Intelligence"] += 2 + elif self.race == "human": + self.stats["Strength"] += 2 + self.stats["Constitution"] += 2 + elif self.race == "dwarf": + self.stats["Constitution"] += 2 + self.stats["Strength"] += 2 + elif self.job == "warrior": + self.stats["Strength"] += 2 + self.stats["Constitution"] += 1 + elif self.job == "ranger": + self.stats["Dexterity"] += 2 + self.stats["Charisma"] += 1 + elif self.job == "mage": + self.stats["Intelligence"] += 2 + self.stats["Charisma"] += 1 + + def introduce(self): + typingPrint("Adjusting for your race and class bonuses." + "\n", time) + time.sleep(1) + typingPrint(f'Welcome {self.name}, to Kanjin: An RPG Text Adventure.\n', time) + + def current_stats(self): + """Prints a display of the user's current statistics.""" + print("Your current stats are:") + print(f'Hit Points: {self.currentHP}/{self.maxHP}') + print(f'Strength: {self.stats["Strength"]}') + print(f'Dexterity: {self.stats["Dexterity"]}') + print(f'Constitution: {self.stats["Constitution"]}') + print(f'Intelligence: {self.stats["Intelligence"]}') + print(f'Charisma: {self.stats["Charisma"]}') + + def current_equip(self): + """Prints a list of items currently equipped.""" + typingPrint(f"You have equipped:
{self.armor.name}
" + f" {self.armor.description}" + f"
{self.weapon.name}
" + f" {self.weapon.description}
>", time) + + def new_char(self): + """Outputs final stats, armour, and inventory""" + typingPrint("We will now generate random stats for your character.
", time) + self.introduce() + print(' ') + time.sleep(2) + self.rollStats() + self.set_stats() + print(' ') + self.getModifier() + self.current_stats() + print(' ') + time.sleep(2) + self.current_equip() + print(' ') + current_inventory() + print(' ') + + def rollStats(self): + """Rolls stats 4d6kh3""" + # Roll stats + typingPrint("Rolling for Strength...\n", time) + self.dice_rolls("Strength") + typingPrint(f'Strength: {self.stats["Strength"]}\n', time) + time.sleep(1) + typingPrint("Rolling for Dexterity...\n", time) + self.dice_rolls("Dexterity") + typingPrint(f'Dexterity: {self.stats["Dexterity"]}\n', time) + time.sleep(1) + typingPrint("Rolling for Constitution...\n", time) + self.dice_rolls("Constitution") + typingPrint(f'Constitution: {self.stats["Constitution"]}\n', time) + time.sleep(1) + typingPrint("Rolling for Intelligence...\n", time) + self.dice_rolls("Intelligence") + typingPrint(f'Intelligence: {self.stats["Intelligence"]}\n', time) + time.sleep(1) + typingPrint("Rolling for Wisdom...\n", time) + self.dice_rolls("Wisdom") + typingPrint(f'Wisdom: {self.stats["Wisdom"]}\n', time) + time.sleep(1) + typingPrint("Rolling for Charisma...\n", time) + self.dice_rolls("Charisma") + typingPrint(f'Charisma: {self.stats["Charisma"]}\n', time) + time.sleep(1) + + def health_check(self): + """Print out current/max HP""" + print(f'You have {self.currentHP}/{self.maxHP} HP.') + + def take_damage(self, DMGtype, size): + """Define the damage type and dice size""" + damage = randint(1, size) + if DMGtype in self.elemental_resistance or DMGtype in self.physical_resistance: + damage //= 2 + self.currentHP -= damage + return damage + + def dice_rolls(self, attribute): + """Rolling 4d6 to get stats for PC""" + rolls = [] + # roll 4d6 + for roll in range(4): + r = randint(1, 6) + rolls.append(r) + # Drop the lowest number + del rolls[rolls.index(min(rolls))] + self.stats[attribute] += sum(rolls) + return attribute + + +# Inventory list +def current_inventory(): + """Prints a list of items in your backpack that aren't equipped to your person.""" + typingPrint(f'In your rucksack you have:\n', time) + for item_key, item_value in user.inventory.items(): + for key, value in item_value.items(): + if key == "equipped" and value == False: + typingPrint(f'{item_key.name}\n' + f' {item_key.description}\n', time) + + +def helpMenu(): + helpmenu = "This is the help menu" + return helpmenu + + +# Equipment list +# def equipment(): + +# elif event.type == pygame_gui.UI_TEXT_ENTRY_FINISHED: +# a = userTextEntry.get_text() +# if a == "armor": +# return (f"
You currently have equipped:
{user.armor}
" +# f"Would you like to equip something new? Y/N") +# +# elif a == "weapons": +# return (f"
You currently have equipped:
{user.weapon}
" +# f"Would you like to equip something new? Y/N") + + +def equipped(): + """Print currently equipped, print a list of held armor pieces, + if input matches a held item, replace equipped condition""" + + text = f"You currently have equipped: {user.armor}\n Would you like to equip something new? Y/N" + if event.type == pygame_gui.UI_BUTTON_PRESSED: + if event.ui_element == helpButton: + for item_key, item_value in user.inventory.items(): + # item_info = dict + for key, value in item_value.items(): + # Leather armor[items], "object"[key], Armor[value] + if key == "object" and value == Armor: + armor_list = "\n", item_key + return armor_list + else: + else_comment = "I'm sorry, I didn't understand that.\nWould you like to equip something new? Y/N" + return else_comment + return text + + +class DamageType(Enum): + SLASHING = auto() + CRUSHING = auto() + PIERCING = auto() + FIRE = auto() + WATER = auto() + LIGHTNING = auto() + + +class DamageMod(Enum): + STRENGTH = auto() + DEXTERITY = auto() + CONSTITUTION = auto() + INTELLIGENCE = auto() + WISDOM = auto() + CHARISMA = auto() + + +class Item: + """The base class for all items""" + + def __init__(self, name, description, value, magical): + self.name = name + self.description = description + self.value = value + self.magical = magical + + def __repr__(self): + return f"{self.name}
=====
{self.description}
Value: {self.value}
" + + +class Money(Item): + """The currency item used in the world of Kanjin""" + + def __init__(self, name, amt, magical): + self.name = name + self.amt = amt + self.magical = magical + super().__init__(name=self.name, + description=f"A small round coin made of {self.name.lower()} " + f"with the imperial city logo stamped on the face.", + value=self.amt, + magical=self.magical) + + +class Weapon(Item): + """The base class for all weapons""" + + def __init__(self, name, description, value, damage1H, damage2H, dmgType, dmgMod, vers, thrown, magical): + self.damage1H = damage1H + self.damage2H = damage2H + self.dmgType = dmgType + self.dmgMod = dmgMod + self.vers = vers + self.thrown = thrown + super().__init__(name, description, value, magical) + + def __repr__(self): + return f"{self.name}
=====
{self.description}
Value: {self.value}" \ + f"
Damage: One Handed - {self.damage1H}" \ + f"
Damage: Two Handed - {self.damage2H}
" \ + f"Damage Type: {self.dmgType}
Magical: {self.magical}.
" + + +class Armor(Item): + """The base class for all armor""" + + def __init__(self, name, description, value, grade, ac, disadvantage, dmgRes, magical): + self.grade = grade + self.ac = ac + self.stealthDis = disadvantage + self.dmgRes = dmgRes + super().__init__(name, description, value, magical) + + def __repr__(self): + if self.stealthDis: + return f"{self.name}
=====
{self.description}
Value: {self.value}
" \ + f"AC: {self.ac}
Magical: {self.magical}" + elif not self.stealthDis: + return f"{self.name}
=====
{self.description}
Value: {self.value}
" \ + f"AC: {self.ac}
Disadvantage on Stealth checks: {self.stealthDis}
Magical: {self.magical}" + + +# Different types of coins +GP1 = Money("Gold", 1, False) +SP1 = Money("Silver", 1, False) +CP1 = Money("Copper", 1, False) + +rock = Weapon( + name="Rock", + description="A fist-sized rock, suitable for bludgeoning.", + value="No value", + damage1H=randint(1, 6), + damage2H=0, + dmgType=DamageType.CRUSHING, + dmgMod=DamageMod.STRENGTH, + vers=False, + thrown=True, + magical=False +) +tornRags = Armor( + name="Torn Rags", + description="A ripped and worn-out outfit.", + value=0, + grade="Light", + ac=0, + disadvantage=True, + dmgRes="None", + magical=False +) + +user = Player("Jamie", "Male", 29, "Elf", "Mage") +pygame.init() + +# Create a screen +screen = pygame.display.set_mode((1240, 720)) +screen.fill("black") + +# Set title and Icon +pygame.display.set_caption('Kanjin: An RPG Text Adventure') +icon = pygame.image.load("icon.png").convert_alpha() +pygame.display.set_icon(icon) + +# ((size), "theme.json") +manager = pygame_gui.UIManager((1200, 720)) +manager.set_visual_debug_mode(False) + +# Set surface elements +# relative_rect = pygame.Rect((top left position)(UIButton size)) +userInputButton = pygame_gui.elements.UIButton(relative_rect=pygame.Rect((708, 642), (115, 33)), + text='Send', + manager=manager, + object_id="#userInputButton") + +inventoryButton = pygame_gui.elements.UIButton(relative_rect=pygame.Rect((1085, 20), (107, 100)), + text='Inventory', + manager=manager, + object_id="#inventoryButton") + +equipmentButton = pygame_gui.elements.UIButton(relative_rect=pygame.Rect((1085, 150), (107, 100)), + text='Equipment', + manager=manager, + object_id="#equipmentButton") + +helpButton = pygame_gui.elements.UIButton(relative_rect=pygame.Rect((1085, 280), (107, 100)), + text='Help', + manager=manager, + object_id="#helpButton") + +sceneImage_surface = pygame.Surface((1003, 242)) +sceneImage_surface.fill((34, 40, 45)) +sceneImage_image = pygame_gui.elements.UIImage(relative_rect=pygame.Rect((20, 20), (1003, 242)), + image_surface=icon, + manager=manager, + object_id="#sceneImage") + +userTextEntry_surface = pygame.Surface((645, 33)) +userTextEntry = pygame_gui.elements.UITextEntryLine(pygame.Rect((20, 642), (645, 33)), + manager=manager, + object_id="#player_input") +sceneText_surface = pygame.Surface((1003, 325)) +sceneText = pygame_gui.elements.UITextBox("Test", + pygame.Rect((20, 282), (803, 325)), + manager=manager, + object_id="#scene_text") +# Typewriter Text +sceneText.set_active_effect(pygame_gui.TEXT_EFFECT_TYPING_APPEAR, + params={'time_per_letter': 0.001, + 'time_per_letter_deviation': 0.0003} + + ) + +# Set FPS +clock = pygame.time.Clock() + +# Engine loop +equipmentButtonPressed = False +while True: + selection = "Not selected" + time_delta = clock.tick(60) / 1000.0 + for event in pygame.event.get(): + + if event.type == pygame.QUIT: + quit() + + if event.type == pygame_gui.UI_BUTTON_PRESSED: + if event.ui_element == userInputButton: + sceneText.append_html_text("
" + userTextEntry.get_text()) + userTextEntry.set_text("") + + if event.type == pygame_gui.UI_TEXT_ENTRY_FINISHED: + if not equipmentButtonPressed: + if userTextEntry.get_text().lower() == "clear": + sceneText = pygame_gui.elements.UITextBox("", + pygame.Rect((20, 282), (803, 325)), + manager=manager, + object_id="#scene_text") + userTextEntry.set_text("") + else: + selection = "text" + print("selection " + selection) + print(f"equip button pressed: {equipmentButtonPressed}") + sceneText.append_html_text("
" + userTextEntry.get_text()) + userTextEntry.set_text("") + + if event.type == pygame_gui.UI_TEXT_ENTRY_FINISHED: + if equipmentButtonPressed: + if userTextEntry.get_text().lower() == "armor": + selection = "armor" + sceneText.append_html_text("

" + f"You currently have equipped:
" + f"{user.armor}
" + f"Would you like to equip something new? Y/N") + userTextEntry.set_text("") + # equipmentButtonPressed = False + + elif userTextEntry.get_text().lower() == "weapons": + sceneText.append_html_text(f"
You currently have equipped:
{user.weapon}
" + f"Would you like to equip something new? Y/N") + userTextEntry.set_text("") + equipmentButtonPressed = False + + else: + sceneText.append_html_text(f"
Sorry, I didn't understand that. Try again.") + userTextEntry.set_text("") + + if event.type == pygame_gui.UI_BUTTON_PRESSED: + if event.ui_element == equipmentButton: + print("pressed button") + print(f"equip button pressed: {equipmentButtonPressed}") + equipmentButtonPressed = True + sceneText.append_html_text("
" + f"You currently have equipped: {user.armor}
" + f"Type 'armor' or 'weapons' to change equipment. ") + print("code executed") + print(f"equip button pressed: {equipmentButtonPressed}") + + manager.process_events(event) + + manager.update(time_delta) + + # Blit + screen.blit(sceneText_surface, (20, 282)) + screen.blit(userTextEntry_surface, (20, 642)) + screen.blit(sceneImage_surface, (20, 20)) + + manager.draw_ui(screen) + pygame.display.update()