Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added equipping and managing items in backpack #186

Merged
merged 15 commits into from
Apr 27, 2023
61 changes: 38 additions & 23 deletions dnd-bot/dnd_bot/assets/campaigns/campaign.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@
},
"items": {
"armors": {
"helmets": {},
"helmets": {
"Plate Helmet": {
"hp": 5
pcichowski marked this conversation as resolved.
Show resolved Hide resolved
}
},
"chestplates": {},
"leg armors": {},
"boots: ": {}
Expand All @@ -79,7 +83,8 @@
"damage": [10, 13],
"range": 2,
"action-points": 8,
"base-price": 3
"base-price": 3,
"two-handed": true
}
},
"staffs": {
Expand Down Expand Up @@ -113,28 +118,37 @@
},
"off-hands": {
"shields": {
"Wooden shield": {
"dexterity": -2,
"strength": 2
}
}
},
"accessories": {
"Ring of vitality" :{
"hp": 4,
"charisma": 2,
"base-price": 9
},
"Necklace of prudence": {
"intelligence": 5,
"base-price": 10
},
"Holy Bible": {
"hp": 10,
"strength": 3,
"base-price": 35
},
"Hunting necklace": {
"dexterity": 6,
"perception": 1
"type1": {
pcichowski marked this conversation as resolved.
Show resolved Hide resolved
"Ring of vitality" :{
"hp": 4,
"charisma": 2,
"base-price": 9
},
"Necklace of prudence": {
"intelligence": 5,
"base-price": 10
},
"Holy Bible": {
"hp": 10,
"strength": 3,
"base-price": 35
},
"Hunting necklace": {
"dexterity": 6,
"perception": 1
},
"Glasses": {
"perception": 1
}
}
}
}
},
"entities": {
"enemies": {
Expand All @@ -152,7 +166,8 @@
"equipment": {},
"drop_money": [1, 3],
"drops": {
"Ring of vitality": 0.2
"Plate Helmet": 0.95,
"Wooden shield": 0.9
},
"ai": 0
},
Expand All @@ -170,8 +185,8 @@
"equipment": {},
"drop_money": [1, 3],
"drops": {
"Hunting necklace": 0.2,
"Necklace of prudence": 0.15
"Hunting necklace": 0.9,
"Necklace of prudence": 0.85
},
"ai": 0
},
Expand Down
69 changes: 68 additions & 1 deletion dnd-bot/dnd_bot/dc/ui/views/view_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from dnd_bot.dc.utils.handler_views import HandlerViews
from dnd_bot.logic.game.handler_attack import HandlerAttack
from dnd_bot.logic.game.handler_loot_corpse import HandlerLootCorpse
from dnd_bot.logic.game.handler_manage_items import HandlerManageItems
from dnd_bot.logic.game.handler_movement import HandlerMovement
from dnd_bot.logic.game.handler_skills import HandlerSkills
from dnd_bot.logic.prototype.game import Game
Expand Down Expand Up @@ -289,7 +290,6 @@ async def attack_button(self, interaction: nextcord.Interaction):

async def cancel(self, interaction: nextcord.Interaction):
player = self.game.get_player_by_id_user(interaction.user.id)
player.attack_mode = False
await super().cancel(interaction, [get_player_view(self.game, player)])

@staticmethod
Expand Down Expand Up @@ -348,8 +348,75 @@ async def character_view_skills(self, button: nextcord.ui.Button, interaction: n
await super().character_view_skills(interaction)


class ViewManageItems(ViewGame):
""" view for managing player's equipment"""
def __init__(self, token, user_discord_id):
super().__init__(token, user_discord_id)

self.player = Multiverse.get_game(token).get_player_by_id_user(user_discord_id)

if len(self.player.backpack) > 0:
item_select_options = []

for count, item in enumerate(self.player.backpack):
item_select_options.append(nextcord.SelectOption(
label=f"{item.name}",
value=str(count) # TODO should be item.id, but for now database is not functioning properly
))
self.select_list = nextcord.ui.Select(
placeholder="Choose an item to manage",
options=item_select_options,
row=0
)

self.add_item(self.select_list)

equip_button = Button(label='Equip item', style=nextcord.ButtonStyle.blurple, custom_id='manage-items-equip'
'-button')
equip_button.callback = self.equip
self.add_item(equip_button)

remove_button = Button(label='Remove item', style=nextcord.ButtonStyle.blurple,
custom_id='manage-items-remove-button')
remove_button.callback = self.remove
self.add_item(remove_button)

cancel_button = Button(label='Cancel', style=nextcord.ButtonStyle.red, row=1, custom_id='attack-cancel-button')
cancel_button.callback = self.cancel
self.add_item(cancel_button)

async def equip(self, interaction: nextcord.Interaction):
await HandlerManageItems.equip_item(self.player, int(self.select_list.values[0]))
embed = MessageTemplates.equipment_message_template(self.player)
await Messager.edit_last_user_message(user_id=interaction.user.id, embeds=[embed],
view=ViewManageItems(self.token, interaction.user.id))

async def remove(self, interaction: nextcord.Interaction):
await HandlerManageItems.remove_item(self.player, int(self.select_list.values[0]))
embed = MessageTemplates.equipment_message_template(self.player)
await Messager.edit_last_user_message(user_id=interaction.user.id, embeds=[embed],
view=ViewManageItems(self.token, interaction.user.id))

async def cancel(self, interaction: nextcord.Interaction):
turn_view_embed = MessageTemplates.equipment_message_template(self.player)

self.game.players_views[self.user_discord_id] = (ViewMain, [])
await Messager.edit_last_user_message(user_id=interaction.user.id, embeds=[turn_view_embed],
view=ViewEquipment(self.token, interaction.user.id))


pcichowski marked this conversation as resolved.
Show resolved Hide resolved
class ViewEquipment(ViewGame):

@nextcord.ui.button(label='Manage items', style=nextcord.ButtonStyle.blurple, custom_id='equipment-manage-items')
async def manage_items(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
"""button for managing items"""
game = Multiverse.get_game(self.token)
player = game.get_player_by_id_user(interaction.user.id)
embed = MessageTemplates.equipment_message_template(player)
await Messager.edit_last_user_message(user_id=interaction.user.id, embeds=[embed],
view=ViewManageItems(self.token, interaction.user.id))
game.players_views[str(interaction.user.id)] = (ViewManageItems, [])

@nextcord.ui.button(label='Cancel', style=nextcord.ButtonStyle.red, custom_id='equipment-cancel')
async def cancel(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
"""button for moving back to main menu"""
Expand Down
1 change: 0 additions & 1 deletion dnd-bot/dnd_bot/logic/game/handler_kill_enemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def handle_kill_enemy(game: Game, enemy: Creature):
chance = enemy.drops[item_name]
if random.randint(0, 1000) <= chance * 1000:
dropped_items.append(Item(name=item_name))
print(f"Dropped {item_name} ({chance*100}% chance)")

# creating corpse entity
# if you want the corpse to have other sprite pass its path below
Expand Down
55 changes: 55 additions & 0 deletions dnd-bot/dnd_bot/logic/game/handler_manage_items.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from dnd_bot.dc.ui.messager import Messager
from dnd_bot.logic.prototype.items.equipable import Equipable
from dnd_bot.logic.prototype.items.item import Item


class HandlerManageItems:
"""handler for managing items in equipment"""
@staticmethod
async def equip_item(player, index_of_item_in_backpack):
"""handles equipping an item"""
item = player.backpack[index_of_item_in_backpack]

def equip(to_be_equipped: Item):
""" equips an item andchecks if an item of this category is
already equipped and puts it in backpack"""
del player.backpack[index_of_item_in_backpack]

if to_be_equipped.equipable == Equipable.WEAPON:
if player.equipment.right_hand:
player.backpack.append(player.equipment.right_hand)
player.equipment.right_hand = to_be_equipped
elif to_be_equipped.equipable == Equipable.HELMET:
if player.equipment.helmet:
player.backpack.append(player.equipment.helmet)
player.equipment.helmet = to_be_equipped
elif to_be_equipped.equipable == Equipable.CHEST:
if player.equipment.chest:
player.backpack.append(player.equipment.chest)
player.equipment.chest = to_be_equipped
elif to_be_equipped.equipable == Equipable.LEG_ARMOR:
if player.equipment.leg_armor:
player.backpack.append(player.equipment.leg_armor)
player.equipment.leg_armor = to_be_equipped
elif to_be_equipped.equipable == Equipable.BOOTS:
if player.equipment.boots:
player.backpack.append(player.equipment.boots)
player.equipment.boots = to_be_equipped
elif to_be_equipped.equipable == Equipable.ACCESSORY:
if player.equipment.accessory:
player.backpack.append(player.equipment.accessory)
player.equipment.accessory = to_be_equipped
elif to_be_equipped.equipable == Equipable.OFF_HAND:
if player.equipment.left_hand:
player.backpack.append(player.equipment.left_hand)
player.equipment.left_hand = to_be_equipped

if item.equipable == Equipable.NO:
await Messager.send_dm_error_message(player.discord_identity, "You can't equip this item")
return
equip(item)

@staticmethod
async def remove_item(player, index_of_item_in_backpack):
"""handles removing an item"""
del player.backpack[index_of_item_in_backpack]
2 changes: 1 addition & 1 deletion dnd-bot/dnd_bot/logic/prototype/database_object.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
class DatabaseObject:
def __init__(self, id=0):
self.id = id
self.id = id
12 changes: 12 additions & 0 deletions dnd-bot/dnd_bot/logic/prototype/items/equipable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from enum import Enum


class Equipable(Enum):
NO = 0
pcichowski marked this conversation as resolved.
Show resolved Hide resolved
WEAPON = 1
HELMET = 4
CHEST = 5
LEG_ARMOR = 6
BOOTS = 7
OFF_HAND = 8
ACCESSORY = 9
pcichowski marked this conversation as resolved.
Show resolved Hide resolved
19 changes: 18 additions & 1 deletion dnd-bot/dnd_bot/logic/prototype/items/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from dnd_bot.database.database_item import DatabaseItem
from dnd_bot.logic.prototype.database_object import DatabaseObject
from dnd_bot.logic.prototype.items.equipable import Equipable


class Item(DatabaseObject):
Expand All @@ -26,6 +27,7 @@ def __init__(self, id_item: int = 0, name: str = "", effect: str = ""):
self.charisma = 0
self.perception = 0
self.action_points = 0
self.equipable: Equipable = Equipable.NO

self.load_attributes_from_json()

Expand All @@ -38,10 +40,25 @@ def load_attributes_from_json(self):

for item_type in items.keys():
if self.name in items[item_type]: # items without a subtype
pass
print(f"{self.name} is without a subtype")
pcichowski marked this conversation as resolved.
Show resolved Hide resolved
pcichowski marked this conversation as resolved.
Show resolved Hide resolved
item_subtype_dict = items[item_type]
for item_subtype in item_subtype_dict:
if self.name in item_subtype_dict[item_subtype]: # items with a subtype
if item_type == "weapons":
self.equipable = Equipable.WEAPON
elif item_type == "armors":
if item_subtype == "helmets":
self.equipable = Equipable.HELMET
elif item_subtype == "chestplates":
self.equipable = Equipable.CHEST
elif item_subtype == "leg armors":
self.equipable = Equipable.LEG_ARMOR
elif item_subtype == "boots":
self.equipable = Equipable.BOOTS
elif item_type == "off-hands":
self.equipable = Equipable.OFF_HAND
elif item_type == "accessories":
self.equipable = Equipable.ACCESSORY

item = item_subtype_dict[item_subtype][self.name]
if item:
Expand Down