Update Card-Jitsu belt progression system to be accurate to the original Club Penguin (#95)

* change ninja progress system

* make it so ranking up does not reset your progress

* make losing against sensei give you experience

* remove rank speed from card-jitsu

* move get_percentage_to_next_belt

* add autocorrection to card-jitsu exp if it is not proper to the rank

* fix typo

* change the correction for card-jitsu exp
This commit is contained in:
nhaar 2024-08-29 22:28:15 -03:00 committed by GitHub
parent 57e541f3af
commit 015b645414
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 15 deletions

View File

@ -47,8 +47,6 @@ class CardJitsuLogic(IWaddle):
StampAwards = {0: 230, 4: 232, 8: 234, 9: 236} StampAwards = {0: 230, 4: 232, 8: 234, 9: 236}
StampGroupId = 38 StampGroupId = 38
RankSpeed = 1
def __init__(self, waddle): def __init__(self, waddle):
super().__init__(waddle) super().__init__(waddle)
@ -188,7 +186,7 @@ class CardJitsuLogic(IWaddle):
class CardJitsuMatLogic(CardJitsuLogic): class CardJitsuMatLogic(CardJitsuLogic):
RankSpeed = 0.5 pass
class SenseiLogic(CardJitsuLogic): class SenseiLogic(CardJitsuLogic):
@ -238,24 +236,36 @@ async def ninja_rank_up(p, ranks=1):
await p.add_inbox(p.server.postcards[CardJitsuLogic.PostcardAwards[rank]]) await p.add_inbox(p.server.postcards[CardJitsuLogic.PostcardAwards[rank]])
if rank in CardJitsuLogic.StampAwards: if rank in CardJitsuLogic.StampAwards:
await p.add_stamp(p.server.stamps[CardJitsuLogic.StampAwards[rank]]) await p.add_stamp(p.server.stamps[CardJitsuLogic.StampAwards[rank]])
await p.update(ninja_rank=p.ninja_rank + ranks, ninja_progress=0).apply() await p.update(ninja_rank=p.ninja_rank + ranks).apply()
return True return True
def get_exp_difference_to_next_rank(cur_rank: int) -> int:
return (cur_rank + 1) * 5
def get_threshold_for_rank(rank: int) -> int:
# using arithmetic progression sum because the exp structure allows
return (rank + 1) * rank // 2 * 5
async def ninja_progress(p, won=False): async def ninja_progress(p, won=False):
if p.ninja_rank == 0: # black belts don't need exp, otherwise it could overflow
await p.update(ninja_progress=100).apply() if p.ninja_rank >= 9:
elif p.ninja_rank < 9: return
speed = type(p.waddle).RankSpeed gained_exp = 5 if won else 1
if not won:
speed *= 0.5 previous_progress = p.ninja_progress
points = math.floor((100 / p.ninja_rank) * speed) cur_rank_threshold = get_threshold_for_rank(p.ninja_rank)
await p.update(ninja_progress=p.ninja_progress+points).apply() next_rank_threshold = get_threshold_for_rank(p.ninja_rank + 1)
if p.ninja_progress >= 100: # this is for correcting old versions, where the exp might not be in the proper threshold.
if previous_progress < cur_rank_threshold or previous_progress > next_rank_threshold:
# in this case, ninja_progress is the percentage to next belt
previous_progress = int(cur_rank_threshold + previous_progress * get_exp_difference_to_next_rank(p.ninja_rank) / 100)
new_progress = previous_progress + gained_exp
await p.update(ninja_progress=new_progress).apply()
if new_progress >= next_rank_threshold:
await ninja_rank_up(p) await ninja_rank_up(p)
await p.send_xt('cza', p.ninja_rank) await p.send_xt('cza', p.ninja_rank)
async def ninja_stamps_earned(p): async def ninja_stamps_earned(p):
game_stamps = [stamp for stamp in p.server.stamps.values() if stamp.group_id == p.room.stamp_group] game_stamps = [stamp for stamp in p.server.stamps.values() if stamp.group_id == p.room.stamp_group]
collected_stamps = [stamp for stamp in game_stamps if stamp.id in p.stamps] collected_stamps = [stamp for stamp in game_stamps if stamp.id in p.stamps]
@ -526,6 +536,8 @@ async def handle_send_sensei_pick(p, action: str, card_id: int):
can_rank_up = await ninja_rank_up(p) can_rank_up = await ninja_rank_up(p)
if can_rank_up: if can_rank_up:
await p.send_xt('cza', p.ninja_rank) await p.send_xt('cza', p.ninja_rank)
else:
await ninja_progress(p, False)
else: else:
for seat_id, ninja in enumerate(p.waddle.ninjas): for seat_id, ninja in enumerate(p.waddle.ninjas):
if not p.waddle.has_cards_to_play(seat_id): if not p.waddle.has_cards_to_play(seat_id):

View File

@ -1,7 +1,11 @@
from houdini import handlers from houdini import handlers
from houdini.handlers import XTPacket from houdini.handlers import XTPacket
from houdini.data.penguin import Penguin from houdini.data.penguin import Penguin
from houdini.handlers.games.ninja.card import get_threshold_for_rank, get_exp_difference_to_next_rank
# rank doesn't need to be known, but requiring it since it is always known and is simpler/faster to compute
def get_percentage_to_next_belt(xp: int, rank: int) -> int:
return int(((xp - get_threshold_for_rank(rank)) / get_exp_difference_to_next_rank(rank)) * 100)
@handlers.handler(XTPacket('ni', 'gnr')) @handlers.handler(XTPacket('ni', 'gnr'))
@handlers.cooldown(2) @handlers.cooldown(2)
@ -13,7 +17,7 @@ async def handle_get_ninja_ranks(p, penguin_id: int):
@handlers.handler(XTPacket('ni', 'gnl')) @handlers.handler(XTPacket('ni', 'gnl'))
async def handle_get_ninja_level(p): async def handle_get_ninja_level(p):
await p.send_xt('gnl', p.ninja_rank, p.ninja_progress, 10) await p.send_xt('gnl', p.ninja_rank, get_percentage_to_next_belt(p.ninja_progress, p.ninja_rank), 10)
@handlers.handler(XTPacket('ni', 'gfl')) @handlers.handler(XTPacket('ni', 'gfl'))