make end screens only show stamps from current session

This commit is contained in:
nhaar 2024-09-16 14:34:23 -03:00
parent 27da6fef06
commit ed38f66923
4 changed files with 82 additions and 18 deletions

View File

@ -1465,6 +1465,7 @@ CREATE TABLE penguin_stamp (
penguin_id INT NOT NULL,
stamp_id INT NOT NULL,
recent BOOLEAN NOT NULL DEFAULT TRUE,
in_game_session BOOLEAN NOT NULL DEFAULT TRUE,
PRIMARY KEY (penguin_id, stamp_id),
CONSTRAINT stamp_ibfk_1 FOREIGN KEY (penguin_id) REFERENCES penguin (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT stamp_ibfk_2 FOREIGN KEY (stamp_id) REFERENCES stamp (id) ON DELETE CASCADE ON UPDATE CASCADE
@ -1476,6 +1477,7 @@ COMMENT ON COLUMN penguin_stamp.penguin_id IS 'Stamp penguin ID';
COMMENT ON COLUMN penguin_stamp.stamp_id IS 'Stamp ID';
COMMENT ON COLUMN penguin_stamp.recent IS 'Is recently earned?';
COMMENT ON COLUMN penguin_stamp.recent IS 'Is recently earned?';
COMMENT ON COLUMN penguin_stamp.in_game_session IS 'Still in the minigame session it was earned';
DROP TABLE IF EXISTS penguin_membership;
CREATE TABLE penguin_membership (

View File

@ -54,6 +54,7 @@ class PenguinStamp(db.Model):
stamp_id = db.Column(db.ForeignKey('stamp.id', ondelete='CASCADE', onupdate='CASCADE'), primary_key=True,
nullable=False)
recent = db.Column(db.Boolean, nullable=False, server_default=db.text("true"))
in_game_session = db.Column(db.Boolean, nullable=False, server_default=db.text("true"))
class StampCollection(AbstractDataCollection):

View File

@ -80,28 +80,15 @@ async def handle_get_game_over(p, score: int):
if p.room.game and not p.waddle and not p.table:
coins_earned = determine_coins_earned(p, score)
if await determine_coins_overdose(p, coins_earned):
return await cheat_ban(p, p.id, comment='Coins overdose')
stamp_info = "", 0, 0, 0
collected_stamps_string, total_collected_stamps, total_game_stamps, total_stamps = '', 0, 0, 0
if 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]
total_stamps = len([stamp for stamp in p.stamps.values() if p.server.stamps[stamp.stamp_id].group_id])
total_collected_stamps = len(collected_stamps)
total_game_stamps = len(game_stamps)
collected_stamps_string = '|'.join(str(stamp.id) for stamp in collected_stamps)
if total_collected_stamps == total_game_stamps:
stamp_info = await p.get_game_end_stamps_info(True)
# has all stamps in game
if stamp_info[1] == stamp_info[2]:
coins_earned *= 2
await p.update(coins=min(p.coins + coins_earned, p.server.config.max_coins)).apply()
await p.send_xt('zo', p.coins,
collected_stamps_string,
total_collected_stamps,
total_game_stamps,
total_stamps)
await p.send_xt("zo", p.coins, *stamp_info)
@handlers.handler(XTPacket('ggd', ext='z'), client=ClientType.Vanilla)
@ -146,3 +133,10 @@ async def handle_game_complete(p, medals: int):
medals = min(6, medals)
await p.update(career_medals=p.career_medals + medals,
agent_medals=p.agent_medals + medals).apply()
@handlers.disconnected
@handlers.player_attribute(joined_world=True)
async def clear_stamp_sessions(p):
"""When disconnected, clear stamps in case any were obtained and not properly handled"""
await p.clear_stamps_session()

View File

@ -380,7 +380,74 @@ class Penguin(Spheniscidae, penguin.Penguin):
self.logger.info(f'{self.username} updated their background to \'{item.name}\' ' if item else
f'{self.username} removed their background item')
async def get_game_end_stamps_info(
self, clear_session: bool
) -> tuple[str, int, int, int]:
"""
Get the info of the stamps at the end of a game that the client requires
If clear_session is True, the stamps will be marked off and will no longer
show up as new stamps at the end of minigames
"""
(
collected_game_stamps_string,
total_collected_game_stamps,
total_game_stamps,
total_stamps,
) = ("", 0, 0, 0)
game_stamps = [
stamp
for stamp in self.server.stamps.values()
if stamp.group_id == self.room.stamp_group
]
game_stamps_ids = [stamp.id for stamp in game_stamps]
recently_collected_game_stamps = [
stamp
for stamp in self.stamps.values()
if (stamp.in_game_session and stamp.stamp_id in game_stamps_ids)
]
collected_game_stamps = [
stamp for stamp in game_stamps if (stamp.id in self.stamps and stamp)
]
collected_game_stamps_string = "|".join(
str(stamp.stamp_id) for stamp in recently_collected_game_stamps
)
total_collected_game_stamps = len(collected_game_stamps)
total_game_stamps = len(game_stamps)
total_stamps = len(
[
stamp
for stamp in self.stamps.values()
if self.server.stamps[stamp.stamp_id].group_id
]
)
if clear_session:
await self.clear_stamps_session()
return (
collected_game_stamps_string,
total_collected_game_stamps,
total_game_stamps,
total_stamps,
)
async def clear_stamps_session(self):
"""
Exits a game session and unmarks all stamps since we are no longer in their session
"""
stamps = [stamp for stamp in self.stamps.values() if stamp.in_game_session]
for stamp in stamps:
await stamp.update(in_game_session=False).apply()
def __repr__(self):
if self.id is not None:
return f'<Penguin ID=\'{self.id}\' Username=\'{self.username}\'>'