Added a proper DeathType enum to replace string values

This commit is contained in:
Eric Froemling 2020-04-06 15:18:19 -07:00
parent 9a6c094824
commit 8b0b332f1a
9 changed files with 65 additions and 43 deletions

View File

@ -74,11 +74,11 @@ from ba._general import WeakCall, Call
from ba._level import Level from ba._level import Level
from ba._lobby import Lobby, Chooser from ba._lobby import Lobby, Chooser
from ba._math import normalized_color, is_point_in_box, vec3validate from ba._math import normalized_color, is_point_in_box, vec3validate
from ba._messages import (OutOfBoundsMessage, DieMessage, StandMessage, from ba._messages import (OutOfBoundsMessage, DeathType, DieMessage,
PickUpMessage, DropMessage, PickedUpMessage, StandMessage, PickUpMessage, DropMessage,
DroppedMessage, ShouldShatterMessage, PickedUpMessage, DroppedMessage,
ImpactDamageMessage, FreezeMessage, ThawMessage, ShouldShatterMessage, ImpactDamageMessage,
HitMessage) FreezeMessage, ThawMessage, HitMessage)
from ba._music import setmusic, MusicPlayer, MusicType, MusicPlayMode from ba._music import setmusic, MusicPlayer, MusicType, MusicPlayMode
from ba._powerup import PowerupMessage, PowerupAcceptMessage from ba._powerup import PowerupMessage, PowerupAcceptMessage
from ba._teambasesession import TeamBaseSession from ba._teambasesession import TeamBaseSession

View File

@ -658,7 +658,7 @@ class GameActivity(Activity):
def on_player_leave(self, player: ba.Player) -> None: def on_player_leave(self, player: ba.Player) -> None:
from ba._general import Call from ba._general import Call
from ba._messages import DieMessage from ba._messages import DieMessage, DeathType
super().on_player_leave(player) super().on_player_leave(player)
@ -668,7 +668,8 @@ class GameActivity(Activity):
# will incorrectly try to respawn them, etc. # will incorrectly try to respawn them, etc.
actor = player.actor actor = player.actor
if actor is not None: if actor is not None:
_ba.pushcall(Call(actor.handlemessage, DieMessage(how='leftGame'))) _ba.pushcall(
Call(actor.handlemessage, DieMessage(how=DeathType.LEFT_GAME)))
player.set_actor(None) player.set_actor(None)
def handlemessage(self, msg: Any) -> Any: def handlemessage(self, msg: Any) -> Any:

View File

@ -24,6 +24,7 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from enum import Enum
import _ba import _ba
@ -40,6 +41,18 @@ class OutOfBoundsMessage:
""" """
class DeathType(Enum):
"""A reason for a death.
Category: Enums
"""
GENERIC = 'generic'
IMPACT = 'impact'
FALL = 'fall'
REACHED_GOAL = 'reached_goal'
LEFT_GAME = 'left_game'
@dataclass @dataclass
class DieMessage: class DieMessage:
"""A message telling an object to die. """A message telling an object to die.
@ -57,12 +70,11 @@ class DieMessage:
its time with lingering corpses, sound effects, etc. its time with lingering corpses, sound effects, etc.
how how
The particular reason for death; 'fall', 'impact', 'leftGame', etc. The particular reason for death.
This can be examined for scoring or other purposes.
""" """
immediate: bool = False immediate: bool = False
how: str = 'generic' how: DeathType = DeathType.GENERIC
@dataclass @dataclass

View File

@ -350,7 +350,7 @@ class Flag(ba.Actor):
elif isinstance(msg, ba.OutOfBoundsMessage): elif isinstance(msg, ba.OutOfBoundsMessage):
# We just kill ourselves when out-of-bounds.. would we ever not # We just kill ourselves when out-of-bounds.. would we ever not
# want this?.. # want this?..
self.handlemessage(ba.DieMessage(how='fall')) self.handlemessage(ba.DieMessage(how=ba.DeathType.FALL))
elif isinstance(msg, ba.PickedUpMessage): elif isinstance(msg, ba.PickedUpMessage):
self._held_count += 1 self._held_count += 1
if self._held_count == 1 and self._counter is not None: if self._held_count == 1 and self._counter is not None:

View File

@ -53,7 +53,7 @@ class PlayerSpazDeathMessage:
""" """
def __init__(self, spaz: PlayerSpaz, was_killed: bool, def __init__(self, spaz: PlayerSpaz, was_killed: bool,
killerplayer: Optional[ba.Player], how: str): killerplayer: Optional[ba.Player], how: ba.DeathType):
"""Instantiate a message with the given values.""" """Instantiate a message with the given values."""
self.spaz = spaz self.spaz = spaz
self.killed = was_killed self.killed = was_killed
@ -252,7 +252,8 @@ class PlayerSpaz(basespaz.Spaz):
if not self._dead: if not self._dead:
# Immediate-mode or left-game deaths don't count as 'kills'. # Immediate-mode or left-game deaths don't count as 'kills'.
killed = (not msg.immediate and msg.how != 'leftGame') killed = (not msg.immediate
and msg.how is not ba.DeathType.LEFT_GAME)
activity = self._activity() activity = self._activity()

View File

@ -588,11 +588,12 @@ class Spaz(ba.Actor):
def on_punched(self, damage: int) -> None: def on_punched(self, damage: int) -> None:
"""Called when this spaz gets punched.""" """Called when this spaz gets punched."""
def get_death_points(self, how: str) -> Tuple[int, int]: def get_death_points(self, how: ba.DeathType) -> Tuple[int, int]:
"""Get the points awarded for killing this spaz.""" """Get the points awarded for killing this spaz."""
del how # unused arg del how # Unused.
num_hits = float(max(1, self._num_times_hit)) num_hits = float(max(1, self._num_times_hit))
# base points is simply 10 for 1-hit-kills and 5 otherwise
# Base points is simply 10 for 1-hit-kills and 5 otherwise.
importance = 2 if num_hits < 2 else 1 importance = 2 if num_hits < 2 else 1
return (10 if num_hits < 2 else 5) * self.points_mult, importance return (10 if num_hits < 2 else 5) * self.points_mult, importance
@ -604,7 +605,8 @@ class Spaz(ba.Actor):
if not self._cursed: if not self._cursed:
factory = get_factory() factory = get_factory()
self._cursed = True self._cursed = True
# add the curse material..
# Add the curse material.
for attr in ['materials', 'roller_materials']: for attr in ['materials', 'roller_materials']:
materials = getattr(self.node, attr) materials = getattr(self.node, attr)
if factory.curse_material not in materials: if factory.curse_material not in materials:
@ -616,7 +618,7 @@ class Spaz(ba.Actor):
if self.curse_time is None: if self.curse_time is None:
self.node.curse_death_time = -1 self.node.curse_death_time = -1
else: else:
# note: curse-death-time takes milliseconds # Note: curse-death-time takes milliseconds.
tval = ba.time() tval = ba.time()
assert isinstance(tval, int) assert isinstance(tval, int)
self.node.curse_death_time = int(1000.0 * self.node.curse_death_time = int(1000.0 *
@ -629,7 +631,7 @@ class Spaz(ba.Actor):
""" """
assert self.node assert self.node
self.node.boxing_gloves = True self.node.boxing_gloves = True
if self._demo_mode: # preserve old behavior if self._demo_mode: # Preserve old behavior.
self._punch_power_scale = 1.7 self._punch_power_scale = 1.7
self._punch_cooldown = 300 self._punch_cooldown = 300
else: else:
@ -664,7 +666,7 @@ class Spaz(ba.Actor):
self.shield_decay_timer = ba.Timer(0.5, self.shield_decay_timer = ba.Timer(0.5,
ba.WeakCall(self.shield_decay), ba.WeakCall(self.shield_decay),
repeat=True) repeat=True)
# so user can see the decay # So user can see the decay.
self.shield.always_show_health_bar = True self.shield.always_show_health_bar = True
def shield_decay(self) -> None: def shield_decay(self) -> None:
@ -698,17 +700,18 @@ class Spaz(ba.Actor):
if self.node: if self.node:
self.node.handlemessage("hurt_sound") self.node.handlemessage("hurt_sound")
self.node.handlemessage("picked_up") self.node.handlemessage("picked_up")
# this counts as a hit
# This counts as a hit.
self._num_times_hit += 1 self._num_times_hit += 1
elif isinstance(msg, ba.ShouldShatterMessage): elif isinstance(msg, ba.ShouldShatterMessage):
# eww; seems we have to do this in a timer or it wont work right # Eww; seems we have to do this in a timer or it wont work right.
# (since we're getting called from within update() perhaps?..) # (since we're getting called from within update() perhaps?..)
# NOTE: should test to see if that's still the case # NOTE: should test to see if that's still the case.
ba.timer(0.001, ba.WeakCall(self.shatter)) ba.timer(0.001, ba.WeakCall(self.shatter))
elif isinstance(msg, ba.ImpactDamageMessage): elif isinstance(msg, ba.ImpactDamageMessage):
# eww; seems we have to do this in a timer or it wont work right # Eww; seems we have to do this in a timer or it wont work right.
# (since we're getting called from within update() perhaps?..) # (since we're getting called from within update() perhaps?..)
ba.timer(0.001, ba.WeakCall(self._hit_self, msg.intensity)) ba.timer(0.001, ba.WeakCall(self._hit_self, msg.intensity))
@ -799,7 +802,8 @@ class Spaz(ba.Actor):
timeformat=ba.TimeFormat.MILLISECONDS)) timeformat=ba.TimeFormat.MILLISECONDS))
elif msg.poweruptype == 'shield': elif msg.poweruptype == 'shield':
factory = get_factory() factory = get_factory()
# let's allow powerup-equipped shields to lose hp over time
# Let's allow powerup-equipped shields to lose hp over time.
self.equip_shields(decay=factory.shield_decay_rate > 0) self.equip_shields(decay=factory.shield_decay_rate > 0)
elif msg.poweruptype == 'curse': elif msg.poweruptype == 'curse':
self.curse() self.curse()
@ -825,7 +829,8 @@ class Spaz(ba.Actor):
elif msg.poweruptype == 'health': elif msg.poweruptype == 'health':
if self._cursed: if self._cursed:
self._cursed = False self._cursed = False
# remove cursed material
# Remove cursed material.
factory = get_factory() factory = get_factory()
for attr in ['materials', 'roller_materials']: for attr in ['materials', 'roller_materials']:
materials = getattr(self.node, attr) materials = getattr(self.node, attr)
@ -861,7 +866,7 @@ class Spaz(ba.Actor):
self.node.frozen = True self.node.frozen = True
ba.timer(5.0, ba.WeakCall(self.handlemessage, ba.timer(5.0, ba.WeakCall(self.handlemessage,
ba.ThawMessage())) ba.ThawMessage()))
# instantly shatter if we're already dead # Instantly shatter if we're already dead.
# (otherwise its hard to tell we're dead) # (otherwise its hard to tell we're dead)
if self.hitpoints <= 0: if self.hitpoints <= 0:
self.shatter() self.shatter()
@ -880,7 +885,7 @@ class Spaz(ba.Actor):
position=self.node.position) position=self.node.position)
return True return True
# if we were recently hit, don't count this as another # If we were recently hit, don't count this as another.
# (so punch flurries and bomb pileups essentially count as 1 hit) # (so punch flurries and bomb pileups essentially count as 1 hit)
local_time = ba.time(timeformat=ba.TimeFormat.MILLISECONDS) local_time = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
assert isinstance(local_time, int) assert isinstance(local_time, int)
@ -893,13 +898,13 @@ class Spaz(ba.Actor):
velocity_mag = msg.velocity_magnitude * self.impact_scale velocity_mag = msg.velocity_magnitude * self.impact_scale
damage_scale = 0.22 damage_scale = 0.22
# if they've got a shield, deliver it to that instead.. # If they've got a shield, deliver it to that instead.
if self.shield: if self.shield:
if msg.flat_damage: if msg.flat_damage:
damage = msg.flat_damage * self.impact_scale damage = msg.flat_damage * self.impact_scale
else: else:
# hit our spaz with an impulse but tell it to only return # Hit our spaz with an impulse but tell it to only return
# theoretical damage; not apply the impulse.. # theoretical damage; not apply the impulse.
assert msg.force_direction is not None assert msg.force_direction is not None
self.node.handlemessage( self.node.handlemessage(
"impulse", msg.pos[0], msg.pos[1], msg.pos[2], "impulse", msg.pos[0], msg.pos[1], msg.pos[2],
@ -1086,7 +1091,8 @@ class Spaz(ba.Actor):
if self.frozen and (damage > 200 or self.hitpoints <= 0): if self.frozen and (damage > 200 or self.hitpoints <= 0):
self.shatter() self.shatter()
elif self.hitpoints <= 0: elif self.hitpoints <= 0:
self.node.handlemessage(ba.DieMessage(how='impact')) self.node.handlemessage(
ba.DieMessage(how=ba.DeathType.IMPACT))
# if we're dead, take a look at the smoothed damage val # if we're dead, take a look at the smoothed damage val
# (which gives us a smoothed average of recent damage) and shatter # (which gives us a smoothed average of recent damage) and shatter
@ -1114,8 +1120,8 @@ class Spaz(ba.Actor):
ba.timer(2.0, self.node.delete) ba.timer(2.0, self.node.delete)
elif isinstance(msg, ba.OutOfBoundsMessage): elif isinstance(msg, ba.OutOfBoundsMessage):
# by default we just die here # By default we just die here.
self.handlemessage(ba.DieMessage(how='fall')) self.handlemessage(ba.DieMessage(how=ba.DeathType.FALL))
elif isinstance(msg, ba.StandMessage): elif isinstance(msg, ba.StandMessage):
self._last_stand_pos = (msg.position[0], msg.position[1], self._last_stand_pos = (msg.position[0], msg.position[1],
msg.position[2]) msg.position[2])

View File

@ -80,7 +80,7 @@ class SpazBotDeathMessage:
""" """
def __init__(self, badguy: SpazBot, killerplayer: Optional[ba.Player], def __init__(self, badguy: SpazBot, killerplayer: Optional[ba.Player],
how: str): how: ba.DeathType):
"""Instantiate with given values.""" """Instantiate with given values."""
self.badguy = badguy self.badguy = badguy
self.killerplayer = killerplayer self.killerplayer = killerplayer

View File

@ -415,7 +415,8 @@ class RunaroundGame(ba.CoopGameActivity):
}) })
ba.animate(light, 'intensity', {0.0: 0, 0.1: 1, 0.5: 0}, loop=False) ba.animate(light, 'intensity', {0.0: 0, 0.1: 1, 0.5: 0}, loop=False)
ba.timer(1.0, light.delete) ba.timer(1.0, light.delete)
spaz.handlemessage(ba.DieMessage(immediate=True, how='goal')) spaz.handlemessage(
ba.DieMessage(immediate=True, how=ba.DeathType.REACHED_GOAL))
if self._lives > 0: if self._lives > 0:
self._lives -= 1 self._lives -= 1
@ -1141,7 +1142,7 @@ class RunaroundGame(ba.CoopGameActivity):
player, respawn_time) player, respawn_time)
elif isinstance(msg, spazbot.SpazBotDeathMessage): elif isinstance(msg, spazbot.SpazBotDeathMessage):
if msg.how == 'goal': if msg.how is ba.DeathType.REACHED_GOAL:
return return
pts, importance = msg.badguy.get_death_points(msg.how) pts, importance = msg.badguy.get_death_points(msg.how)
if msg.killerplayer is not None: if msg.killerplayer is not None:

View File

@ -301,12 +301,13 @@ class CoopBrowserWindow(ba.Window):
self._fg_state = ba.app.fg_state self._fg_state = ba.app.fg_state
self._last_tournament_query_time = cur_time self._last_tournament_query_time = cur_time
self._doing_tournament_query = True self._doing_tournament_query = True
_ba.tournament_query(args={ _ba.tournament_query(
'source': 'coop window refresh', args={
'numScores': 1 'source': 'coop window refresh',
}, 'numScores': 1
callback=ba.WeakCall( },
self._on_tournament_query_response)) callback=ba.WeakCall(self._on_tournament_query_response),
)
# Decrement time on our tournament buttons. # Decrement time on our tournament buttons.
ads_enabled = _ba.have_incentivized_ad() ads_enabled = _ba.have_incentivized_ad()