Hot Potato - api 9 update (#338)

* Hot Potato - api 9 update

* [ci] auto-format

* [ci] apply-version-metadata

* [ci] auto-format

* Re-run version workflow

* [ci] apply-version-metadata

* Update hot_potato.py

* Version metadata again

* [ci] apply-version-metadata

* f*** ci

* [ci] apply-version-metadata

* Version metadata should be automated

* [ci] apply-version-metadata

---------

Co-authored-by: TheMikirog <7281309+TheMikirog@users.noreply.github.com>
Co-authored-by: brostos <67740566+brostosjoined@users.noreply.github.com>
This commit is contained in:
TheMikirog 2025-02-21 09:45:59 +01:00 committed by GitHub
parent 4ab37f302b
commit 5313c0fa9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 11 deletions

View file

@ -418,6 +418,12 @@
} }
], ],
"versions": { "versions": {
"1.0.2": {
"api_version": 9,
"commit_sha": "b2b786b",
"released_on": "21-02-2025",
"md5sum": "2273f55338718a4d4c3db55ec9b01516"
},
"1.0.1": { "1.0.1": {
"api_version": 8, "api_version": 8,
"commit_sha": "2b5c9ee", "commit_sha": "2b5c9ee",

View file

@ -1,7 +1,7 @@
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport) # Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
""" """
Hot Potato by TheMikirog#1984 Hot Potato by themikirog
A random player(s) gets Marked. A random player(s) gets Marked.
They will die if they don't pass the mark to other players. They will die if they don't pass the mark to other players.
@ -14,16 +14,17 @@
""" """
# ba_meta require api 8
# ba_meta require api 9
# (see https://ballistica.net/wiki/meta-tag-system)
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, override
# Define only what we need and nothing more # Define only what we need and nothing more
from baenv import TARGET_BALLISTICA_BUILD as build_number
import babase import babase
import bauiv1 as bui
import bascenev1 as bs import bascenev1 as bs
from bascenev1lib.actor.spaz import SpazFactory from bascenev1lib.actor.spaz import SpazFactory
from bascenev1lib.actor.spaz import PickupMessage from bascenev1lib.actor.spaz import PickupMessage
@ -330,8 +331,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
# If the attacker is healthy and we're stunned, do a flash and play a sound, then ignore the rest of the code. # If the attacker is healthy and we're stunned, do a flash and play a sound, then ignore the rest of the code.
if self.source_player.state == PlayerState.STUNNED and msg._source_player != PlayerState.MARKED: if self.source_player.state == PlayerState.STUNNED and msg._source_player != PlayerState.MARKED:
self.node.handlemessage('flash') self.node.handlemessage('flash')
SpazFactory.get().block_sound.play(1.0, position=self.node.position) SpazFactory.get().block_sound.play(1, position=self.node.position)
return True
# Here's all the damage and force calculations unchanged from the source. # Here's all the damage and force calculations unchanged from the source.
mag = msg.magnitude * self.impact_scale mag = msg.magnitude * self.impact_scale
@ -449,6 +449,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
# It's the same sound and flashing behavior as hitting a stunned player as a healthy player. # It's the same sound and flashing behavior as hitting a stunned player as a healthy player.
if (opposingnode.source_player.state == PlayerState.STUNNED and self.source_player.state != PlayerState.MARKED): if (opposingnode.source_player.state == PlayerState.STUNNED and self.source_player.state != PlayerState.MARKED):
opposingnode.handlemessage('flash') opposingnode.handlemessage('flash')
SpazFactory.get().block_sound.play(1.0, position=opposingnode.position) SpazFactory.get().block_sound.play(1.0, position=opposingnode.position)
return True return True
# If they're marked and we're healthy or stunned, pass that mark along to us. # If they're marked and we're healthy or stunned, pass that mark along to us.
@ -580,6 +581,7 @@ class Player(bs.Player['Team']):
# ba_meta export bascenev1.GameActivity # ba_meta export bascenev1.GameActivity
class HotPotato(bs.TeamGameActivity[Player, bs.Team]): class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
# Let's define the basics like the name of the game, description and some tips that should appear at the start of a match. # Let's define the basics like the name of the game, description and some tips that should appear at the start of a match.
@ -624,17 +626,20 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
] ]
# Hot Potato is strictly a Free-For-All gamemode, so only picking the gamemode in FFA playlists. # Hot Potato is strictly a Free-For-All gamemode, so only picking the gamemode in FFA playlists.
@override
@classmethod @classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool: def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.FreeForAllSession) return issubclass(sessiontype, bs.FreeForAllSession)
# Most maps should work in Hot Potato. Generally maps marked as 'melee' are the most versatile map types of them all. # Most maps should work in Hot Potato. Generally maps marked as 'melee' are the most versatile map types of them all.
# As the name implies, fisticuffs are common forms of engagement. # As the name implies, fisticuffs are common forms of engagement.
@override
@classmethod @classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]: def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
return bs.app.classic.getmaps('melee') return bs.app.classic.getmaps('melee')
# Here we define everything the gamemode needs, like sounds and settings. # Here we define everything the gamemode needs, like sounds and settings.
def __init__(self, settings: dict): def __init__(self, settings: dict):
super().__init__(settings) super().__init__(settings)
self.settings = settings self.settings = settings
@ -732,12 +737,12 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
if len(self.get_marked_players()) == 0: if len(self.get_marked_players()) == 0:
raise Exception("no marked players!") raise Exception("no marked players!")
self.elimination_timer_display -= 1 # Decrease our timer by one second.
if self.elimination_timer_display > 1: if self.elimination_timer_display > 1:
self.elimination_timer_display -= 1 # Decrease our timer by one second. self.elimination_timer_display -= 1 # Decrease our timer by one second.
sound_volume = 1.0 / marked_player_amount sound_volume = 1.0 / marked_player_amount
for target in marked_players: for target in marked_players:
self._tick_sound.play(sound_volume, target.actor.node.position) self._tick_sound.play(sound_volume, target.actor.node.position)
target.actor.marked_timer_text.text = str(self.elimination_timer_display) target.actor.marked_timer_text.text = str(self.elimination_timer_display)
@ -747,6 +752,7 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
# depending on time remaining. Arrays start at index 0, so we need to decrease # depending on time remaining. Arrays start at index 0, so we need to decrease
# our variable by 1 to get the element index. # our variable by 1 to get the element index.
self._danger_tick_sounds[self.elimination_timer_display - 1].play(1.5) self._danger_tick_sounds[self.elimination_timer_display - 1].play(1.5)
else: else:
# Elimination timer is up! Let's eliminate all marked players. # Elimination timer is up! Let's eliminate all marked players.
self.elimination_timer_display -= 1 # Decrease our timer by one second. self.elimination_timer_display -= 1 # Decrease our timer by one second.
@ -841,6 +847,7 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
self.mark(new_victim) self.mark(new_victim)
# This function is called when the gamemode first loads. # This function is called when the gamemode first loads.
@override
def on_begin(self) -> None: def on_begin(self) -> None:
super().on_begin() # Do standard gamemode on_begin behavior super().on_begin() # Do standard gamemode on_begin behavior
@ -876,7 +883,7 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
def _show_tip(self) -> None: def _show_tip(self) -> None:
from bascenev1._gameutils import animate, GameTip from bascenev1._gameutils import animate, GameTip
from babase._mgen.enums import SpecialChar from bauiv1 import SpecialChar
from babase._language import Lstr from babase._language import Lstr
# If there's any tips left on the list, display one. # If there's any tips left on the list, display one.
@ -899,7 +906,7 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
base_position = (75, 50) base_position = (75, 50)
tip_scale = 0.8 tip_scale = 0.8
tip_title_scale = 1.2 tip_title_scale = 1.2
vrmode = babase.app.vr_mode if build_number < 21282 else babase.app.env.vr vrmode = babase.app.env.vr # ba.app.vr_mode
t_offs = -350.0 t_offs = -350.0
height_offs = 100.0 height_offs = 100.0
@ -966,6 +973,7 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
# This function is called when a player leaves the game. # This function is called when a player leaves the game.
# This is only called when the player already joined with a character. # This is only called when the player already joined with a character.
@override
def player_left(self, player: Player) -> None: def player_left(self, player: Player) -> None:
# If the leaving player is marked, remove the mark # If the leaving player is marked, remove the mark
if player.state == PlayerState.MARKED: if player.state == PlayerState.MARKED:
@ -987,7 +995,8 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
player.set_state(PlayerState.ELIMINATED) player.set_state(PlayerState.ELIMINATED)
# This function is called every time a player spawns # This function is called every time a player spawns
def spawn_player(self, player: Player) -> bs.Actor: @override
def spawn_player(self, player: Player) -> ba.Actor:
position = self.map.get_ffa_start_position(self.players) position = self.map.get_ffa_start_position(self.players)
position = (position[0], position = (position[0],
position[1] - 0.3, # Move the spawn a bit lower position[1] - 0.3, # Move the spawn a bit lower
@ -1022,6 +1031,7 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
bs.timer(0.5, light.delete) bs.timer(0.5, light.delete)
# Game reacts to various events # Game reacts to various events
@override
def handlemessage(self, msg: Any) -> Any: def handlemessage(self, msg: Any) -> Any:
# This is called if the player dies. # This is called if the player dies.
if isinstance(msg, bs.PlayerDiedMessage): if isinstance(msg, bs.PlayerDiedMessage):
@ -1044,6 +1054,7 @@ class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
self.mark(player) self.mark(player)
# This is called when we want to end the game and announce a victor # This is called when we want to end the game and announce a victor
@override
def end_game(self) -> None: def end_game(self) -> None:
# Proceed only if the game hasn't ended yet. # Proceed only if the game hasn't ended yet.
if self.has_ended(): if self.has_ended():