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._lobby import Lobby, Chooser
from ba._math import normalized_color, is_point_in_box, vec3validate
from ba._messages import (OutOfBoundsMessage, DieMessage, StandMessage,
PickUpMessage, DropMessage, PickedUpMessage,
DroppedMessage, ShouldShatterMessage,
ImpactDamageMessage, FreezeMessage, ThawMessage,
HitMessage)
from ba._messages import (OutOfBoundsMessage, DeathType, DieMessage,
StandMessage, PickUpMessage, DropMessage,
PickedUpMessage, DroppedMessage,
ShouldShatterMessage, ImpactDamageMessage,
FreezeMessage, ThawMessage, HitMessage)
from ba._music import setmusic, MusicPlayer, MusicType, MusicPlayMode
from ba._powerup import PowerupMessage, PowerupAcceptMessage
from ba._teambasesession import TeamBaseSession

View File

@ -658,7 +658,7 @@ class GameActivity(Activity):
def on_player_leave(self, player: ba.Player) -> None:
from ba._general import Call
from ba._messages import DieMessage
from ba._messages import DieMessage, DeathType
super().on_player_leave(player)
@ -668,7 +668,8 @@ class GameActivity(Activity):
# will incorrectly try to respawn them, etc.
actor = player.actor
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)
def handlemessage(self, msg: Any) -> Any:

View File

@ -24,6 +24,7 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
from enum import Enum
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
class DieMessage:
"""A message telling an object to die.
@ -57,12 +70,11 @@ class DieMessage:
its time with lingering corpses, sound effects, etc.
how
The particular reason for death; 'fall', 'impact', 'leftGame', etc.
This can be examined for scoring or other purposes.
The particular reason for death.
"""
immediate: bool = False
how: str = 'generic'
how: DeathType = DeathType.GENERIC
@dataclass

View File

@ -350,7 +350,7 @@ class Flag(ba.Actor):
elif isinstance(msg, ba.OutOfBoundsMessage):
# We just kill ourselves when out-of-bounds.. would we ever not
# want this?..
self.handlemessage(ba.DieMessage(how='fall'))
self.handlemessage(ba.DieMessage(how=ba.DeathType.FALL))
elif isinstance(msg, ba.PickedUpMessage):
self._held_count += 1
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,
killerplayer: Optional[ba.Player], how: str):
killerplayer: Optional[ba.Player], how: ba.DeathType):
"""Instantiate a message with the given values."""
self.spaz = spaz
self.killed = was_killed
@ -252,7 +252,8 @@ class PlayerSpaz(basespaz.Spaz):
if not self._dead:
# 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()

View File

@ -588,11 +588,12 @@ class Spaz(ba.Actor):
def on_punched(self, damage: int) -> None:
"""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."""
del how # unused arg
del how # Unused.
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
return (10 if num_hits < 2 else 5) * self.points_mult, importance
@ -604,7 +605,8 @@ class Spaz(ba.Actor):
if not self._cursed:
factory = get_factory()
self._cursed = True
# add the curse material..
# Add the curse material.
for attr in ['materials', 'roller_materials']:
materials = getattr(self.node, attr)
if factory.curse_material not in materials:
@ -616,7 +618,7 @@ class Spaz(ba.Actor):
if self.curse_time is None:
self.node.curse_death_time = -1
else:
# note: curse-death-time takes milliseconds
# Note: curse-death-time takes milliseconds.
tval = ba.time()
assert isinstance(tval, int)
self.node.curse_death_time = int(1000.0 *
@ -629,7 +631,7 @@ class Spaz(ba.Actor):
"""
assert self.node
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_cooldown = 300
else:
@ -664,7 +666,7 @@ class Spaz(ba.Actor):
self.shield_decay_timer = ba.Timer(0.5,
ba.WeakCall(self.shield_decay),
repeat=True)
# so user can see the decay
# So user can see the decay.
self.shield.always_show_health_bar = True
def shield_decay(self) -> None:
@ -698,17 +700,18 @@ class Spaz(ba.Actor):
if self.node:
self.node.handlemessage("hurt_sound")
self.node.handlemessage("picked_up")
# this counts as a hit
# This counts as a hit.
self._num_times_hit += 1
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?..)
# 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))
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?..)
ba.timer(0.001, ba.WeakCall(self._hit_self, msg.intensity))
@ -799,7 +802,8 @@ class Spaz(ba.Actor):
timeformat=ba.TimeFormat.MILLISECONDS))
elif msg.poweruptype == 'shield':
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)
elif msg.poweruptype == 'curse':
self.curse()
@ -825,7 +829,8 @@ class Spaz(ba.Actor):
elif msg.poweruptype == 'health':
if self._cursed:
self._cursed = False
# remove cursed material
# Remove cursed material.
factory = get_factory()
for attr in ['materials', 'roller_materials']:
materials = getattr(self.node, attr)
@ -861,7 +866,7 @@ class Spaz(ba.Actor):
self.node.frozen = True
ba.timer(5.0, ba.WeakCall(self.handlemessage,
ba.ThawMessage()))
# instantly shatter if we're already dead
# Instantly shatter if we're already dead.
# (otherwise its hard to tell we're dead)
if self.hitpoints <= 0:
self.shatter()
@ -880,7 +885,7 @@ class Spaz(ba.Actor):
position=self.node.position)
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)
local_time = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
assert isinstance(local_time, int)
@ -893,13 +898,13 @@ class Spaz(ba.Actor):
velocity_mag = msg.velocity_magnitude * self.impact_scale
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 msg.flat_damage:
damage = msg.flat_damage * self.impact_scale
else:
# hit our spaz with an impulse but tell it to only return
# theoretical damage; not apply the impulse..
# Hit our spaz with an impulse but tell it to only return
# theoretical damage; not apply the impulse.
assert msg.force_direction is not None
self.node.handlemessage(
"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):
self.shatter()
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
# (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)
elif isinstance(msg, ba.OutOfBoundsMessage):
# by default we just die here
self.handlemessage(ba.DieMessage(how='fall'))
# By default we just die here.
self.handlemessage(ba.DieMessage(how=ba.DeathType.FALL))
elif isinstance(msg, ba.StandMessage):
self._last_stand_pos = (msg.position[0], msg.position[1],
msg.position[2])

View File

@ -80,7 +80,7 @@ class SpazBotDeathMessage:
"""
def __init__(self, badguy: SpazBot, killerplayer: Optional[ba.Player],
how: str):
how: ba.DeathType):
"""Instantiate with given values."""
self.badguy = badguy
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.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:
self._lives -= 1
@ -1141,7 +1142,7 @@ class RunaroundGame(ba.CoopGameActivity):
player, respawn_time)
elif isinstance(msg, spazbot.SpazBotDeathMessage):
if msg.how == 'goal':
if msg.how is ba.DeathType.REACHED_GOAL:
return
pts, importance = msg.badguy.get_death_points(msg.how)
if msg.killerplayer is not None:

View File

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