Skip to content

Commit

Permalink
feat(crew): Acquiring ability
Browse files Browse the repository at this point in the history
  • Loading branch information
Nickelza committed Nov 2, 2023
1 parent 672d496 commit 4add168
Show file tree
Hide file tree
Showing 23 changed files with 484 additions and 116 deletions.
8 changes: 8 additions & 0 deletions resources/Environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,14 @@ def get_belly(self):
CREW_POWERUP_BASE_PRICE = Environment('CREW_POWERUP_BASE_PRICE', default_value='1000000000')
# How long a crew ability should last in days. Default: 7
CREW_ABILITY_DURATION_DAYS = Environment('CREW_ABILITY_DURATION_DAYS', default_value='7')
# Default value percentage for crew ability. Default: 50%
CREW_ABILITY_DEFAULT_VALUE_PERCENTAGE = Environment('CREW_ABILITY_DEFAULT_VALUE_PERCENTAGE', default_value='50')
# Minimum value percentage for crew random ability. Default: 1%
CREW_ABILITY_RANDOM_MIN_VALUE_PERCENTAGE = Environment('CREW_ABILITY_RANDOM_MIN_VALUE_PERCENTAGE',
default_value='1')
# Maximum value percentage for crew random ability. Default: 99%
CREW_ABILITY_RANDOM_MAX_VALUE_PERCENTAGE = Environment('CREW_ABILITY_RANDOM_MAX_VALUE_PERCENTAGE',
default_value='99')

# Minimum amount for Bounty Gift. Default: 10.000.000
BOUNTY_GIFT_MIN_AMOUNT = Environment('BOUNTY_GIFT_MIN_AMOUNT', default_value='10000000')
Expand Down
23 changes: 20 additions & 3 deletions resources/phrases.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
SHOW_USER_STATUS_INCOME_TAX = 'Income tax'
SHOW_USER_STATUS_ADD_REPLY = '_Requested by {}_'
SHOW_USER_STATUS_DEVIL_FRUIT = '\n\n*Devil Fruit*\n_{}_{}'
SHOW_USER_STATUS_CREW_ABILITIES = '\n\n*Crew Abilities*{}'
NOT_ALLOWED_TO_VIEW_REPLIED_STATUS = 'You can only view the status of those who rank below you.' \
'\n\n{} rank: {}' \
'\n{} rank: {}'
Expand Down Expand Up @@ -118,6 +119,7 @@
TEXT_TOPIC = 'Topic'
TEXT_GROUP = 'Group'
TEXT_NOT_SET = 'Not set'
TEXT_RANDOM = 'Random'

EXCEPTION_CHAT_ID_NOT_PROVIDED = 'chat_id is None and update.effective_chat.id is None'
EXCEPTION_NO_EDIT_MESSAGE = 'new_message is False but update.callback_query is None'
Expand Down Expand Up @@ -188,6 +190,7 @@
PVT_KEY_CREW_MEMBER_REMOVE = 'Expel'
PVT_KEY_CREW_ABILITY = 'Abilities'
PVT_KEY_CREW_ABILITY_ACTIVATE = 'Activate'
PVT_KEY_CREW_ABILITY_RANDOM = Emoji.DICE + ' Random'
PVT_KEY_SETTINGS_NOTIFICATIONS = 'Notifications'
PVT_TXT_SETTINGS_NOTIFICATIONS = 'Which category of notifications would you like to change?'
PVT_TXT_SETTINGS_NOTIFICATIONS_TYPE = 'Which notification would you like to change?'
Expand Down Expand Up @@ -669,12 +672,26 @@
'\n\nNext ability cost: ฿*{}*' \
'\nCrew chest: ฿{}'
CREW_ABILITY_NO_ABILITIES = '\n_No abilities are currently activated in this Crew_'
CREW_ABILITY_ITEM_TEXT = '\n{}: {}%' \
'\nRemaining time: {}'
CREW_ABILITY_ITEM_TEXT = '\n{}{} \\({}%\\)'
CREW_ABILITY_ITEM_TEXT_DURATION = '\nRemaining time: {}'
CREW_ABILITY_INSUFFICIENT_CREW_CHEST = 'Insufficient Crew Chest' \
'\n\nCrew chest: ฿{}' \
'\nAbility cost: ฿{}'
CREW_ABILITY_MAX_ABILITIES_REACHED = 'Max number of active abilities reached'
CREW_ABILITY_ACTIVATE_CHOOSE = "Choose an ability you want to use, or go with Random' for a surprise. " \
"\n\nIf you pick a specific ability, it will always be set at " \
f"{Env.CREW_ABILITY_DEFAULT_VALUE_PERCENTAGE.get_int()}%." \
f"\n\nIf you choose Random instead you'll get a completely random ability and its " \
f"value can be anywhere between " \
f"{Env.CREW_ABILITY_RANDOM_MIN_VALUE_PERCENTAGE.get_int()}% " \
f"and {Env.CREW_ABILITY_RANDOM_MAX_VALUE_PERCENTAGE.get_int()}%."
CREW_ABILITY_ACTIVATE_CHOOSE_RECAP = '\n\n*Ability*: {}' \
'\n*Value*: {}' \
'\n*Duration*: {} days' \
'\n*Cost*: ฿{}'
CREW_ABILITY_ACTIVATE_CHOOSE_CONFIRMATION_REQUEST = 'Are you sure you want to activate the following ability?' \
+ CREW_ABILITY_ACTIVATE_CHOOSE_RECAP
CREW_ABILITY_ACTIVATE_SUCCESS = 'Ability activated successfully' + CREW_ABILITY_ACTIVATE_CHOOSE_RECAP

# Bounty Gift
BOUNTY_GIFT_NO_AMOUNT = 'You need to specify the amount of belly you want to gift' \
Expand Down Expand Up @@ -1074,7 +1091,7 @@

# Devil Fruit
DEVIL_FRUIT_ABILITY_TEXT = '\n\n*Abilities*'
DEVIL_FRUIT_ABILITY_TEXT_LINE = '\n{}{}: \\({}{}%\\)'
DEVIL_FRUIT_ABILITY_TEXT_LINE = '\n{}{} \\({}{}%\\)'
DEVIL_FRUIT_ABILITY_UNKNOWN = '\nUnknown'
# Devil Fruit - Private Chat
DEVIL_FRUIT_ITEM_TEXT = '{}'
Expand Down
190 changes: 103 additions & 87 deletions src/chat/group/screens/screen_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import src.model.enums.Command as Command
import src.model.enums.LeaderboardRank as LeaderboardRank
import src.service.bounty_service as bounty_service
from src.model.Crew import Crew
from src.model.DevilFruit import DevilFruit
from src.model.GroupChat import GroupChat
from src.model.User import User
Expand All @@ -19,6 +20,7 @@
from src.model.error.GroupChatError import GroupChatError, GroupChatException
from src.model.pojo.Keyboard import Keyboard
from src.service.bounty_poster_service import get_bounty_poster
from src.service.crew_service import get_crew_abilities_text
from src.service.date_service import get_remaining_duration
from src.service.devil_fruit_service import get_devil_fruit_abilities_text
from src.service.income_tax_service import user_has_complete_tax_deduction
Expand Down Expand Up @@ -58,8 +60,10 @@ async def manage(update: Update, context: ContextTypes.DEFAULT_TYPE, command: Co
return

target_user: User = User.get_or_none(User.tg_user_id == update.effective_message.reply_to_message.from_user.id)
own_status = False
else:
target_user: User = user
own_status = True

# If the user is not in the database, error
if target_user is None:
Expand Down Expand Up @@ -128,93 +132,105 @@ async def manage(update: Update, context: ContextTypes.DEFAULT_TYPE, command: Co
target_user_rank,
escape_valid_markdown_chars(location_name))

# Add Crew if in one
if target_user.is_crew_member():
crew = target_user.crew
message_text += phrases.SHOW_USER_STATUS_CREW.format(escape_valid_markdown_chars(crew.name))

# Remaining sentence if arrested
if target_user.is_arrested():
if not user.impel_down_is_permanent:
remaining_time = get_remaining_duration(target_user.impel_down_release_date)
else:
remaining_time = phrases.SHOW_USER_STATUS_PERMANENT_IMPEL_DOWN
message_text += phrases.SHOW_USER_STATUS_REMAINING_SENTENCE.format(remaining_time)

# Add fight immunity if active
if target_user.fight_immunity_end_date is not None and \
target_user.fight_immunity_end_date > datetime.datetime.now():
# Get remaining time
remaining_time = get_remaining_duration(target_user.fight_immunity_end_date)
message_text += phrases.SHOW_USER_STATUS_FIGHT_IMMUNITY.format(remaining_time)

# Add fight cooldown if active
if target_user.fight_cooldown_end_date is not None and \
target_user.fight_cooldown_end_date > datetime.datetime.now():
# Get remaining time
remaining_time = get_remaining_duration(target_user.fight_cooldown_end_date)
message_text += phrases.SHOW_USER_STATUS_FIGHT_COOLDOWN.format(remaining_time)

# BOUNTY BONUSES
has_bounty_bonus = False
bounty_bonus_text = phrases.SHOW_USER_STATUS_BOUNTY_DAILY_BONUSES_TITLE

# Crew Bounty Bonus
if target_user.has_crew_bonus():
bounty_bonus_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_POSITIVE if Env.CREW_BOUNTY_BONUS.get_int() > 0 else Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_BOUNTY_BONUS_CREW,
Env.CREW_BOUNTY_BONUS.get_int())
has_bounty_bonus = True

# Crew MVP Bounty Bonus
if target_user.has_crew_mvp_bonus():
bounty_bonus_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_POSITIVE if Env.CREW_MVP_BOUNTY_BONUS.get_int() > 0 else Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_BOUNTY_BONUS_CREW_MVP,
Env.CREW_MVP_BOUNTY_BONUS.get_int())
has_bounty_bonus = True

# New World Bounty Bonus
if target_user.has_new_world_bonus():
bounty_bonus_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_POSITIVE if Env.NEW_WORLD_BOUNTY_BONUS.get_int() > 0 else Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_BOUNTY_BONUS_NEW_WORLD,
Env.NEW_WORLD_BOUNTY_BONUS.get_int())
has_bounty_bonus = True

if has_bounty_bonus:
message_text += bounty_bonus_text

# BOUNTY DEDUCTIONS
has_bounty_deduction = False
bounty_deduction_text = phrases.SHOW_USER_STATUS_BOUNTY_DEDUCTIONS_TITLE

# Expired loan
if target_user.has_expired_bounty_loans():
bounty_deduction_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_EXPIRED_LOAN,
(-1 * Env.BOUNTY_LOAN_GARNISH_PERCENTAGE.get_float()))
has_bounty_deduction = True

# Income tax
if target_user.has_income_tax() and not user_has_complete_tax_deduction(target_user):
bounty_deduction_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_INCOME_TAX,
(-1 * target_user.get_income_tax_percentage()))
has_bounty_deduction = True

if has_bounty_deduction:
message_text += bounty_deduction_text

# Devil Fruit
eaten_devil_fruit = DevilFruit.get_by_owner_if_eaten(target_user)
if eaten_devil_fruit is not None:
message_text += phrases.SHOW_USER_STATUS_DEVIL_FRUIT.format(
eaten_devil_fruit.get_full_name(),
get_devil_fruit_abilities_text(eaten_devil_fruit, add_header=False))
# Extra info visible only if checking own status
if own_status:
# Add Crew if in one
if target_user.is_crew_member():
crew = target_user.crew
message_text += phrases.SHOW_USER_STATUS_CREW.format(escape_valid_markdown_chars(crew.name))

# Remaining sentence if arrested
if target_user.is_arrested():
if not user.impel_down_is_permanent:
remaining_time = get_remaining_duration(target_user.impel_down_release_date)
else:
remaining_time = phrases.SHOW_USER_STATUS_PERMANENT_IMPEL_DOWN
message_text += phrases.SHOW_USER_STATUS_REMAINING_SENTENCE.format(remaining_time)

# Add fight immunity if active
if target_user.fight_immunity_end_date is not None and \
target_user.fight_immunity_end_date > datetime.datetime.now():
# Get remaining time
remaining_time = get_remaining_duration(target_user.fight_immunity_end_date)
message_text += phrases.SHOW_USER_STATUS_FIGHT_IMMUNITY.format(remaining_time)

# Add fight cooldown if active
if target_user.fight_cooldown_end_date is not None and \
target_user.fight_cooldown_end_date > datetime.datetime.now():
# Get remaining time
remaining_time = get_remaining_duration(target_user.fight_cooldown_end_date)
message_text += phrases.SHOW_USER_STATUS_FIGHT_COOLDOWN.format(remaining_time)

# BOUNTY BONUSES
has_bounty_bonus = False
bounty_bonus_text = phrases.SHOW_USER_STATUS_BOUNTY_DAILY_BONUSES_TITLE

# Crew Bounty Bonus
if target_user.has_crew_bonus():
bounty_bonus_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_POSITIVE if Env.CREW_BOUNTY_BONUS.get_int() > 0 else Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_BOUNTY_BONUS_CREW,
Env.CREW_BOUNTY_BONUS.get_int())
has_bounty_bonus = True

# Crew MVP Bounty Bonus
if target_user.has_crew_mvp_bonus():
bounty_bonus_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_POSITIVE if Env.CREW_MVP_BOUNTY_BONUS.get_int() > 0 else Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_BOUNTY_BONUS_CREW_MVP,
Env.CREW_MVP_BOUNTY_BONUS.get_int())
has_bounty_bonus = True

# New World Bounty Bonus
if target_user.has_new_world_bonus():
bounty_bonus_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_POSITIVE if Env.NEW_WORLD_BOUNTY_BONUS.get_int() > 0 else Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_BOUNTY_BONUS_NEW_WORLD,
Env.NEW_WORLD_BOUNTY_BONUS.get_int())
has_bounty_bonus = True

if has_bounty_bonus:
message_text += bounty_bonus_text

# BOUNTY DEDUCTIONS
has_bounty_deduction = False
bounty_deduction_text = phrases.SHOW_USER_STATUS_BOUNTY_DEDUCTIONS_TITLE

# Expired loan
if target_user.has_expired_bounty_loans():
bounty_deduction_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_EXPIRED_LOAN,
(-1 * Env.BOUNTY_LOAN_GARNISH_PERCENTAGE.get_float()))
has_bounty_deduction = True

# Income tax
if target_user.has_income_tax() and not user_has_complete_tax_deduction(target_user):
bounty_deduction_text += phrases.SHOW_USER_STATUS_BOUNTY_BONUSES_TEXT.format(
Emoji.LOG_NEGATIVE,
phrases.SHOW_USER_STATUS_INCOME_TAX,
(-1 * target_user.get_income_tax_percentage()))
has_bounty_deduction = True

if has_bounty_deduction:
message_text += bounty_deduction_text

# Abilities visible only if checking own status
if own_status:
# Devil Fruit
eaten_devil_fruit = DevilFruit.get_by_owner_if_eaten(target_user)
if eaten_devil_fruit is not None:
message_text += phrases.SHOW_USER_STATUS_DEVIL_FRUIT.format(
eaten_devil_fruit.get_full_name(),
get_devil_fruit_abilities_text(eaten_devil_fruit, add_header=False))

# Crew abilities
if target_user.is_crew_member():
crew: Crew = target_user.crew
crew_active_abilities = crew.get_active_abilities()
if len(crew_active_abilities) > 0:
message_text += phrases.SHOW_USER_STATUS_CREW_ABILITIES.format(
get_crew_abilities_text(active_abilities=crew_active_abilities, add_emoji=True))

# If used in reply to a message, reply to original message
reply_to_message_id = None
Expand Down
5 changes: 5 additions & 0 deletions src/chat/private/private_chat_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from src.chat.private.screens.screen_crew import manage as manage_screen_crew
from src.chat.private.screens.screen_crew_ability import manage as manage_screen_crew_ability
from src.chat.private.screens.screen_crew_ability_activate import manage as manage_screen_crew_ability_activate
from src.chat.private.screens.screen_crew_ability_activate_confirm import manage as \
manage_screen_crew_ability_activate_confirm
from src.chat.private.screens.screen_crew_create import manage as manage_screen_crew_create_or_edit
from src.chat.private.screens.screen_crew_disband import manage as manage_screen_crew_disband
from src.chat.private.screens.screen_crew_leave import manage as manage_screen_crew_leave
Expand Down Expand Up @@ -156,6 +158,9 @@ async def dispatch_screens(update: Update, context: ContextTypes.DEFAULT_TYPE, c
case Screen.PVT_CREW_ABILITY_ACTIVATE: # Crew Ability Activate
await manage_screen_crew_ability_activate(update, context, inbound_keyboard, user)

case Screen.PVT_CREW_ABILITY_ACTIVATE_CONFIRM: # Crew Ability Activate Confirm
await manage_screen_crew_ability_activate_confirm(update, context, inbound_keyboard, user)

case Screen.PVT_CREW_CREATE_OR_EDIT: # Crew Create or Edit
await manage_screen_crew_create_or_edit(update, context, inbound_keyboard, user)

Expand Down
2 changes: 1 addition & 1 deletion src/chat/private/screens/screen_crew_ability.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async def manage(update: Update, context: ContextTypes.DEFAULT_TYPE, inbound_key
inline_keyboard.append([Keyboard(phrases.PVT_KEY_CREW_ABILITY_ACTIVATE,
screen=Screen.PVT_CREW_ABILITY_ACTIVATE)])

abilities_text = get_crew_abilities_text(active_abilities=active_abilities)
abilities_text = get_crew_abilities_text(active_abilities=active_abilities, add_duration=True)

ot_text = phrases.CREW_ABILITIES.format(abilities_text, crew.get_powerup_price_formatted(),
crew.get_crew_chest_formatted())
Expand Down
31 changes: 26 additions & 5 deletions src/chat/private/screens/screen_crew_ability_activate.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
from enum import StrEnum

from telegram import Update
from telegram.ext import ContextTypes

import resources.phrases as phrases
from src.model.Crew import Crew
from src.model.CrewAbility import CrewAbility
from src.model.User import User
from src.model.enums.Screen import Screen
from src.model.error.CustomException import CrewValidationException
from src.model.pojo.Keyboard import Keyboard
from src.service.crew_service import get_crew
from src.service.message_service import full_message_send


class CrewAbilityActivateReservedKeys(StrEnum):
"""
The reserved keys for the Crew ability activate screen
"""
ABILITY_TYPE = 'a'


async def manage(update: Update, context: ContextTypes.DEFAULT_TYPE, inbound_keyboard: Keyboard, user: User) -> None:
"""
Manage the Crew ability activate screen
Manage the Crew ability activate choose screen
:param update: The update object
:param context: The context object
:param user: The user object
Expand All @@ -29,10 +40,20 @@ async def manage(update: Update, context: ContextTypes.DEFAULT_TYPE, inbound_key
if not await validate(update, context, inbound_keyboard, crew):
return

await full_message_send(
context, "Awkward, this is not implemented yet, never thought a Crew would get here this fast."
"\nForward this message to an Admin in @onepiecegroup to get a special price",
update=update, inbound_keyboard=inbound_keyboard)
allowed_ability_types = CrewAbility.get_allowed_ability_types()
inline_keyboard: list[list[Keyboard]] = []

screen = Screen.PVT_CREW_ABILITY_ACTIVATE_CONFIRM
for ability_type in allowed_ability_types:
info = {CrewAbilityActivateReservedKeys.ABILITY_TYPE: ability_type}
inline_keyboard.append([Keyboard(ability_type.get_description(), info=info, screen=screen)])

# Add random ability
info = {CrewAbilityActivateReservedKeys.ABILITY_TYPE: None}
inline_keyboard.append([Keyboard(phrases.PVT_KEY_CREW_ABILITY_RANDOM, info=info, screen=screen)])

await full_message_send(context, phrases.CREW_ABILITY_ACTIVATE_CHOOSE, update=update, keyboard=inline_keyboard,
inbound_keyboard=inbound_keyboard)


async def validate(update: Update, context: ContextTypes.DEFAULT_TYPE, inbound_keyboard: Keyboard, crew: Crew) -> bool:
Expand Down
Loading

0 comments on commit 4add168

Please sign in to comment.