mirror of
https://github.com/bombsquad-community/plugin-manager.git
synced 2025-11-07 17:36:00 +00:00
commit
3d787180ce
2 changed files with 670 additions and 27 deletions
|
|
@ -597,42 +597,61 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ufo_fight": {
|
||||
"description": "Fight the UFO boss!",
|
||||
"quake_original": {
|
||||
"description": "Good ol' Quake minigame",
|
||||
"external_url": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cross Joy",
|
||||
"email": "cross.joy.official@gmail.com",
|
||||
"discord": "Cross Joy#0721"
|
||||
"name": "Unknown",
|
||||
"email": "",
|
||||
"discord": ""
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"1.0.0": {
|
||||
"api_version": 7,
|
||||
"commit_sha": "7219487",
|
||||
"released_on": "15-05-2023",
|
||||
"md5sum": "81617b130716996368b7d8f20f3a5154"
|
||||
"api_version": 8,
|
||||
"commit_sha": "185480d",
|
||||
"released_on": "24-07-2023",
|
||||
"md5sum": "f68395cc90dc8cddb166a23b2da81b7b"
|
||||
}
|
||||
}
|
||||
},
|
||||
"yeeting_party": {
|
||||
"description": "Yeet your enemies out of the map!",
|
||||
"external_url": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freaku",
|
||||
"email": "",
|
||||
"discord": "[Just] Freak#4999"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"1.0.0": {
|
||||
"api_version": 7,
|
||||
"commit_sha": "7219487",
|
||||
"released_on": "15-05-2023",
|
||||
"md5sum": "197a377652ab0c3bfbe1ca07833924b4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ufo_fight": {
|
||||
"description": "Fight the UFO boss!",
|
||||
"external_url": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cross Joy",
|
||||
"email": "cross.joy.official@gmail.com",
|
||||
"discord": "Cross Joy#0721"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"1.0.0": {
|
||||
"api_version": 7,
|
||||
"commit_sha": "7219487",
|
||||
"released_on": "15-05-2023",
|
||||
"md5sum": "81617b130716996368b7d8f20f3a5154"
|
||||
}
|
||||
}
|
||||
},
|
||||
"yeeting_party": {
|
||||
"description": "Yeet your enemies out of the map!",
|
||||
"external_url": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freaku",
|
||||
"email": "",
|
||||
"discord": "[Just] Freak#4999"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"1.0.0": {
|
||||
"api_version": 7,
|
||||
"commit_sha": "7219487",
|
||||
"released_on": "15-05-2023",
|
||||
"md5sum": "197a377652ab0c3bfbe1ca07833924b4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
624
plugins/minigames/quake_original.py
Normal file
624
plugins/minigames/quake_original.py
Normal file
|
|
@ -0,0 +1,624 @@
|
|||
# Created By Idk
|
||||
# Ported to 1.7 by Yan
|
||||
|
||||
# ba_meta require api 8
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bascenev1lib.actor.powerupbox import PowerupBox as Powerup
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
|
||||
import bascenev1lib.actor.bomb
|
||||
import bascenev1lib.actor.spaz
|
||||
import weakref
|
||||
import random
|
||||
import math
|
||||
import babase
|
||||
import bauiv1 as bui
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
|
||||
|
||||
class TouchedToSpaz(object):
|
||||
pass
|
||||
|
||||
|
||||
class TouchedToAnything(object):
|
||||
pass
|
||||
|
||||
|
||||
class TouchedToFootingMaterial(object):
|
||||
pass
|
||||
|
||||
|
||||
class QuakeBallFactory(object):
|
||||
"""Components used by QuakeBall stuff
|
||||
|
||||
category: Game Classes
|
||||
|
||||
"""
|
||||
_STORENAME = babase.storagename()
|
||||
|
||||
@classmethod
|
||||
def get(cls) -> QuakeBallFactory:
|
||||
"""Get/create a shared bascenev1lib.actor.bomb.BombFactory object."""
|
||||
activity = bs.getactivity()
|
||||
factory = activity.customdata.get(cls._STORENAME)
|
||||
if factory is None:
|
||||
factory = QuakeBallFactory()
|
||||
activity.customdata[cls._STORENAME] = factory
|
||||
assert isinstance(factory, QuakeBallFactory)
|
||||
return factory
|
||||
|
||||
def __init__(self):
|
||||
shared = SharedObjects.get()
|
||||
|
||||
self.ball_material = bs.Material()
|
||||
|
||||
self.ball_material.add_actions(
|
||||
conditions=((('we_are_younger_than', 5), 'or', ('they_are_younger_than', 50)),
|
||||
'and', ('they_have_material', shared.object_material)),
|
||||
actions=(('modify_node_collision', 'collide', False)))
|
||||
|
||||
self.ball_material.add_actions(
|
||||
conditions=('they_have_material', shared.pickup_material),
|
||||
actions=(('modify_part_collision', 'use_node_collide', False)))
|
||||
|
||||
self.ball_material.add_actions(
|
||||
actions=('modify_part_collision', 'friction', 0))
|
||||
|
||||
self.ball_material.add_actions(
|
||||
conditions=('they_have_material', shared.player_material),
|
||||
actions=(('modify_part_collision', 'physical', False),
|
||||
('message', 'our_node', 'at_connect', TouchedToSpaz())))
|
||||
|
||||
self.ball_material.add_actions(
|
||||
conditions=(('they_dont_have_material', shared.player_material), 'and',
|
||||
('they_have_material', shared.object_material)),
|
||||
actions=('message', 'our_node', 'at_connect', TouchedToAnything()))
|
||||
|
||||
self.ball_material.add_actions(
|
||||
conditions=(('they_dont_have_material', shared.player_material), 'and',
|
||||
('they_have_material', shared.footing_material)),
|
||||
actions=('message', 'our_node', 'at_connect', TouchedToFootingMaterial()))
|
||||
|
||||
def give(self, spaz):
|
||||
spaz.punch_callback = self.shot
|
||||
self.last_shot = int(bs.time() * 1000)
|
||||
|
||||
def shot(self, spaz):
|
||||
time = int(bs.time() * 1000)
|
||||
if time - self.last_shot > 0.6:
|
||||
self.last_shot = time
|
||||
p1 = spaz.node.position_center
|
||||
p2 = spaz.node.position_forward
|
||||
direction = [p1[0]-p2[0], p2[1]-p1[1], p1[2]-p2[2]]
|
||||
direction[1] = 0.0
|
||||
|
||||
mag = 10.0/babase.Vec3(*direction).length()
|
||||
vel = [v * mag for v in direction]
|
||||
QuakeBall(
|
||||
position=spaz.node.position,
|
||||
velocity=(vel[0]*2, vel[1]*2, vel[2]*2),
|
||||
owner=spaz._player,
|
||||
source_player=spaz._player,
|
||||
color=spaz.node.color).autoretain()
|
||||
|
||||
|
||||
class QuakeBall(bs.Actor):
|
||||
|
||||
def __init__(self,
|
||||
position=(0, 5, 0),
|
||||
velocity=(0, 2, 0),
|
||||
source_player=None,
|
||||
owner=None,
|
||||
color=(random.random(), random.random(), random.random()),
|
||||
light_radius=0
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
shared = SharedObjects.get()
|
||||
b_shared = QuakeBallFactory.get()
|
||||
|
||||
self.source_player = source_player
|
||||
self.owner = owner
|
||||
|
||||
self.node = bs.newnode('prop', delegate=self, attrs={
|
||||
'position': position,
|
||||
'velocity': velocity,
|
||||
'mesh': bs.getmesh('impactBomb'),
|
||||
'body': 'sphere',
|
||||
'color_texture': bs.gettexture('bunnyColor'),
|
||||
'mesh_scale': 0.2,
|
||||
'is_area_of_interest': True,
|
||||
'body_scale': 0.8,
|
||||
'materials': [shared.object_material,
|
||||
b_shared.ball_material]})
|
||||
|
||||
self.light_node = bs.newnode('light', attrs={
|
||||
'position': position,
|
||||
'color': color,
|
||||
'radius': 0.1+light_radius,
|
||||
'volume_intensity_scale': 15.0})
|
||||
|
||||
self.node.connectattr('position', self.light_node, 'position')
|
||||
self.emit_time = bs.Timer(0.015, bs.WeakCall(self.emit), repeat=True)
|
||||
self.life_time = bs.Timer(5.0, bs.WeakCall(self.handlemessage, bs.DieMessage()))
|
||||
|
||||
def emit(self):
|
||||
bs.emitfx(
|
||||
position=self.node.position,
|
||||
velocity=self.node.velocity,
|
||||
count=10,
|
||||
scale=0.4,
|
||||
spread=0.01,
|
||||
chunk_type='spark')
|
||||
|
||||
def handlemessage(self, m):
|
||||
if isinstance(m, TouchedToAnything):
|
||||
node = bs.getcollision().opposingnode
|
||||
if node is not None and node.exists():
|
||||
v = self.node.velocity
|
||||
t = self.node.position
|
||||
hitdir = self.node.velocity
|
||||
m = self.node
|
||||
node.handlemessage(
|
||||
bs.HitMessage(
|
||||
pos=t,
|
||||
velocity=v,
|
||||
magnitude=babase.Vec3(*v).length()*40,
|
||||
velocity_magnitude=babase.Vec3(*v).length()*40,
|
||||
radius=0,
|
||||
srcnode=self.node,
|
||||
source_player=self.source_player,
|
||||
force_direction=hitdir))
|
||||
|
||||
self.node.handlemessage(bs.DieMessage())
|
||||
|
||||
elif isinstance(m, bs.DieMessage):
|
||||
if self.node.exists():
|
||||
velocity = self.node.velocity
|
||||
explosion = bs.newnode('explosion', attrs={
|
||||
'position': self.node.position,
|
||||
'velocity': (velocity[0], max(-1.0, velocity[1]), velocity[2]),
|
||||
'radius': 1,
|
||||
'big': False})
|
||||
|
||||
bs.getsound(random.choice(['impactHard', 'impactHard2', 'impactHard3'])).play(),
|
||||
position = self.node.position
|
||||
|
||||
self.emit_time = None
|
||||
self.light_node.delete()
|
||||
self.node.delete()
|
||||
|
||||
elif isinstance(m, bs.OutOfBoundsMessage):
|
||||
self.handlemessage(bs.DieMessage())
|
||||
|
||||
elif isinstance(m, bs.HitMessage):
|
||||
self.node.handlemessage('impulse', m.pos[0], m.pos[1], m.pos[2],
|
||||
m.velocity[0], m.velocity[1], m.velocity[2],
|
||||
1.0*m.magnitude, 1.0*m.velocity_magnitude, m.radius, 0,
|
||||
m.force_direction[0], m.force_direction[1], m.force_direction[2])
|
||||
|
||||
elif isinstance(m, TouchedToSpaz):
|
||||
node = bs.getcollision() .opposingnode
|
||||
if node is not None and node.exists() and node != self.owner \
|
||||
and node.getdelegate(object)._player.team != self.owner.team:
|
||||
node.handlemessage(bs.FreezeMessage())
|
||||
v = self.node.velocity
|
||||
t = self.node.position
|
||||
hitdir = self.node.velocity
|
||||
|
||||
node.handlemessage(
|
||||
bs.HitMessage(
|
||||
pos=t,
|
||||
velocity=(10, 10, 10),
|
||||
magnitude=50,
|
||||
velocity_magnitude=50,
|
||||
radius=0,
|
||||
srcnode=self.node,
|
||||
source_player=self.source_player,
|
||||
force_direction=hitdir))
|
||||
|
||||
self.node.handlemessage(bs.DieMessage())
|
||||
|
||||
elif isinstance(m, TouchedToFootingMaterial):
|
||||
bs.getsound('blip').play(),
|
||||
position = self.node.position
|
||||
else:
|
||||
super().handlemessage(m)
|
||||
|
||||
|
||||
class Player(bs.Player['Team']):
|
||||
...
|
||||
|
||||
|
||||
class Team(bs.Team[Player]):
|
||||
"""Our team type for this game."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.score = 0
|
||||
|
||||
# ba_meta export bascenev1.GameActivity
|
||||
|
||||
|
||||
class QuakeGame(bs.TeamGameActivity[Player, Team]):
|
||||
"""A game type based on acquiring kills."""
|
||||
|
||||
name = 'Quake'
|
||||
description = 'Kill a set number of enemies to win.'
|
||||
|
||||
# Print messages when players die since it matters here.
|
||||
announce_player_deaths = True
|
||||
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
|
||||
sessiontype, bs.FreeForAllSession
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
return ['Doom Shroom', 'Monkey Face', 'Football Stadium']
|
||||
|
||||
@classmethod
|
||||
def get_available_settings(
|
||||
cls, sessiontype: type[bs.Session]
|
||||
) -> list[babase.Setting]:
|
||||
settings = [
|
||||
bs.IntSetting(
|
||||
'Kills to Win Per Player',
|
||||
min_value=1,
|
||||
default=5,
|
||||
increment=1,
|
||||
),
|
||||
bs.IntChoiceSetting(
|
||||
'Time Limit',
|
||||
choices=[
|
||||
('None', 0),
|
||||
('1 Minute', 60),
|
||||
('2 Minutes', 120),
|
||||
('5 Minutes', 300),
|
||||
('10 Minutes', 600),
|
||||
('20 Minutes', 1200),
|
||||
],
|
||||
default=0,
|
||||
),
|
||||
bs.FloatChoiceSetting(
|
||||
'Respawn Times',
|
||||
choices=[
|
||||
('Shorter', 0.25),
|
||||
('Short', 0.5),
|
||||
('Normal', 1.0),
|
||||
('Long', 2.0),
|
||||
('Longer', 4.0),
|
||||
],
|
||||
default=1.0,
|
||||
),
|
||||
bs.IntChoiceSetting(
|
||||
'Graphics',
|
||||
choices=[
|
||||
('Normal', 1),
|
||||
('High', 2)
|
||||
],
|
||||
default=1),
|
||||
bs.BoolSetting('Fast Movespeed', default=True),
|
||||
bs.BoolSetting('Enable Jump', default=False),
|
||||
bs.BoolSetting('Enable Pickup', default=False),
|
||||
bs.BoolSetting('Enable Bomb', default=False),
|
||||
bs.BoolSetting('Obstacles', default=False),
|
||||
bs.IntChoiceSetting(
|
||||
'Obstacles Shape',
|
||||
choices=[
|
||||
('Cube', 1),
|
||||
('Sphere', 2),
|
||||
('Puck', 3),
|
||||
('Egg', 4),
|
||||
('Random', 5),
|
||||
],
|
||||
default=1),
|
||||
bs.BoolSetting('Obstacles Bounces Shots', default=False),
|
||||
bs.IntSetting(
|
||||
'Obstacle Count',
|
||||
min_value=1,
|
||||
default=16,
|
||||
increment=1,
|
||||
),
|
||||
bs.BoolSetting('Random Obstacle Color', default=True),
|
||||
bs.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
return settings
|
||||
|
||||
def __init__(self, settings: dict):
|
||||
super().__init__(settings)
|
||||
self._scoreboard = Scoreboard()
|
||||
self._score_to_win: int | None = None
|
||||
self._dingsound = bs.getsound('dingSmall')
|
||||
self._epic_mode = bool(settings['Epic Mode'])
|
||||
self._kills_to_win_per_player = int(settings['Kills to Win Per Player'])
|
||||
self._time_limit = float(settings['Time Limit'])
|
||||
self._allow_negative_scores = bool(
|
||||
settings.get('Allow Negative Scores', False)
|
||||
)
|
||||
|
||||
# Base class overrides.
|
||||
self.slow_motion = self._epic_mode
|
||||
self.default_music = (
|
||||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.TO_THE_DEATH
|
||||
)
|
||||
self.settings = settings
|
||||
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
return 'Crush ${ARG1} of your enemies.', self._score_to_win
|
||||
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
return 'kill ${ARG1} enemies', self._score_to_win
|
||||
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
if self.has_begun():
|
||||
self._update_scoreboard()
|
||||
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.dingsound = bs.getsound('dingSmall')
|
||||
self.setup_standard_time_limit(self._time_limit)
|
||||
|
||||
self.drop_shield()
|
||||
self.drop_shield_timer = bs.Timer(8.001, bs.WeakCall(self.drop_shield), repeat=True)
|
||||
|
||||
shared = SharedObjects.get()
|
||||
if self.settings['Obstacles']:
|
||||
count = self.settings['Obstacle Count']
|
||||
map = bs.getactivity()._map.getname()
|
||||
for i in range(count):
|
||||
if map == 'Football Stadium':
|
||||
radius = (random.uniform(-10, 1),
|
||||
6,
|
||||
random.uniform(-4.5, 4.5)) \
|
||||
if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-4.5, 4.5))
|
||||
else:
|
||||
radius = (random.uniform(-10, 1),
|
||||
6,
|
||||
random.uniform(-8, 8)) \
|
||||
if i > count/2 else (random.uniform(10, 1), 6, random.uniform(-8, 8))
|
||||
|
||||
Obstacle(
|
||||
position=radius,
|
||||
graphics=self.settings['Graphics'],
|
||||
random_color=self.settings['Random Obstacle Color'],
|
||||
rebound=self.settings['Obstacles Bounces Shots'],
|
||||
shape=int(self.settings['Obstacles Shape'])).autoretain()
|
||||
|
||||
if self.settings['Graphics'] == 2:
|
||||
bs.getactivity().globalsnode.tint = (bs.getactivity(
|
||||
).globalsnode.tint[0]-0.6, bs.getactivity().globalsnode.tint[1]-0.6, bs.getactivity().globalsnode.tint[2]-0.6)
|
||||
light = bs.newnode('light', attrs={
|
||||
'position': (9, 10, 0) if map == 'Football Stadium' else (6, 7, -2)
|
||||
if not map == 'Rampage' else (6, 11, -2) if not map == 'The Pad' else (6, 8.5, -2),
|
||||
'color': (0.4, 0.4, 0.45),
|
||||
'radius': 1,
|
||||
'intensity': 6,
|
||||
'volume_intensity_scale': 10.0})
|
||||
|
||||
light2 = bs.newnode('light', attrs={
|
||||
'position': (-9, 10, 0) if map == 'Football Stadium' else (-6, 7, -2)
|
||||
if not map == 'Rampage' else (-6, 11, -2) if not map == 'The Pad' else (-6, 8.5, -2),
|
||||
'color': (0.4, 0.4, 0.45),
|
||||
'radius': 1,
|
||||
'intensity': 6,
|
||||
'volume_intensity_scale': 10.0})
|
||||
|
||||
if len(self.teams) > 0:
|
||||
self._score_to_win = self.settings['Kills to Win Per Player'] * \
|
||||
max(1, max(len(t.players) for t in self.teams))
|
||||
else:
|
||||
self._score_to_win = self.settings['Kills to Win Per Player']
|
||||
self._update_scoreboard()
|
||||
|
||||
def drop_shield(self):
|
||||
p = Powerup(
|
||||
poweruptype='shield',
|
||||
position=(random.uniform(-10, 10), 6, random.uniform(-5, 5))).autoretain()
|
||||
|
||||
bs.getsound('dingSmall').play()
|
||||
|
||||
p_light = bs.newnode('light', attrs={
|
||||
'position': (0, 0, 0),
|
||||
'color': (0.3, 0.0, 0.4),
|
||||
'radius': 0.3,
|
||||
'intensity': 2,
|
||||
'volume_intensity_scale': 10.0})
|
||||
|
||||
p.node.connectattr('position', p_light, 'position')
|
||||
|
||||
bs.animate(p_light, 'intensity', {0: 2, 8000: 0})
|
||||
|
||||
def check_exists():
|
||||
if p is None or p.node.exists() == False:
|
||||
delete_light()
|
||||
del_checker()
|
||||
|
||||
self._checker = bs.Timer(0.1, babase.Call(check_exists), repeat=True)
|
||||
|
||||
def del_checker():
|
||||
if self._checker is not None:
|
||||
self._checker = None
|
||||
|
||||
def delete_light():
|
||||
if p_light.exists():
|
||||
p_light.delete()
|
||||
|
||||
bs.timer(6.9, babase.Call(del_checker))
|
||||
bs.timer(7.0, babase.Call(delete_light))
|
||||
|
||||
def spawn_player(self, player: bs.Player):
|
||||
spaz = self.spawn_player_spaz(player)
|
||||
QuakeBallFactory().give(spaz)
|
||||
spaz.connect_controls_to_player(
|
||||
enable_jump=self.settings['Enable Jump'],
|
||||
enable_punch=True,
|
||||
enable_pickup=self.settings['Enable Pickup'],
|
||||
enable_bomb=self.settings['Enable Bomb'],
|
||||
enable_run=True,
|
||||
enable_fly=False)
|
||||
|
||||
if self.settings['Fast Movespeed']:
|
||||
spaz.node.hockey = True
|
||||
spaz.spaz_light = bs.newnode('light', attrs={
|
||||
'position': (0, 0, 0),
|
||||
'color': spaz.node.color,
|
||||
'radius': 0.12,
|
||||
'intensity': 1,
|
||||
'volume_intensity_scale': 10.0})
|
||||
|
||||
spaz.node.connectattr('position', spaz.spaz_light, 'position')
|
||||
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
|
||||
# Augment standard behavior.
|
||||
super().handlemessage(msg)
|
||||
|
||||
player = msg.getplayer(Player)
|
||||
self.respawn_player(player)
|
||||
|
||||
killer = msg.getkillerplayer(Player)
|
||||
if hasattr(player.actor, 'spaz_light'):
|
||||
player.actor.spaz_light.delete()
|
||||
if killer is None:
|
||||
return None
|
||||
|
||||
# Handle team-kills.
|
||||
if killer.team is player.team:
|
||||
|
||||
# In free-for-all, killing yourself loses you a point.
|
||||
if isinstance(self.session, bs.FreeForAllSession):
|
||||
new_score = player.team.score - 1
|
||||
if not self._allow_negative_scores:
|
||||
new_score = max(0, new_score)
|
||||
player.team.score = new_score
|
||||
|
||||
# In teams-mode it gives a point to the other team.
|
||||
else:
|
||||
self._dingsound.play()
|
||||
for team in self.teams:
|
||||
if team is not killer.team:
|
||||
team.score += 1
|
||||
|
||||
# Killing someone on another team nets a kill.
|
||||
else:
|
||||
killer.team.score += 1
|
||||
self._dingsound.play()
|
||||
|
||||
# In FFA show scores since its hard to find on the scoreboard.
|
||||
if isinstance(killer.actor, PlayerSpaz) and killer.actor:
|
||||
killer.actor.set_score_text(
|
||||
str(killer.team.score) + '/' + str(self._score_to_win),
|
||||
color=killer.team.color,
|
||||
flash=True,
|
||||
)
|
||||
|
||||
self._update_scoreboard()
|
||||
|
||||
# If someone has won, set a timer to end shortly.
|
||||
# (allows the dust to clear and draws to occur if deaths are
|
||||
# close enough)
|
||||
assert self._score_to_win is not None
|
||||
if any(team.score >= self._score_to_win for team in self.teams):
|
||||
bs.timer(0.5, self.end_game)
|
||||
|
||||
else:
|
||||
return super().handlemessage(msg)
|
||||
return None
|
||||
|
||||
def _update_scoreboard(self) -> None:
|
||||
for team in self.teams:
|
||||
self._scoreboard.set_team_value(
|
||||
team, team.score, self._score_to_win
|
||||
)
|
||||
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
results.set_team_score(team, team.score)
|
||||
self.end(results=results)
|
||||
|
||||
|
||||
class Obstacle(bs.Actor):
|
||||
|
||||
def __init__(self,
|
||||
position: tuple(float, float, float),
|
||||
graphics: bool,
|
||||
random_color: bool,
|
||||
rebound: bool,
|
||||
shape: int) -> None:
|
||||
super().__init__()
|
||||
|
||||
shared = SharedObjects.get()
|
||||
if shape == 1:
|
||||
mesh = 'tnt'
|
||||
body = 'crate'
|
||||
elif shape == 2:
|
||||
mesh = 'bomb'
|
||||
body = 'sphere'
|
||||
elif shape == 3:
|
||||
mesh = 'puck'
|
||||
body = 'puck'
|
||||
elif shape == 4:
|
||||
mesh = 'egg'
|
||||
body = 'capsule'
|
||||
elif shape == 5:
|
||||
pair = random.choice([
|
||||
{'mesh': 'tnt', 'body': 'crate'},
|
||||
{'mesh': 'bomb', 'body': 'sphere'},
|
||||
{'mesh': 'puckModel', 'body': 'puck'},
|
||||
{'mesh': 'egg', 'body': 'capsule'}
|
||||
])
|
||||
mesh = pair['mesh']
|
||||
body = pair['body']
|
||||
|
||||
self.node = bs.newnode('prop', delegate=self, attrs={
|
||||
'position': position,
|
||||
'mesh': bs.getmesh(mesh),
|
||||
'body': body,
|
||||
'body_scale': 1.3,
|
||||
'mesh_scale': 1.3,
|
||||
'reflection': 'powerup',
|
||||
'reflection_scale': [0.7],
|
||||
'color_texture': bs.gettexture('bunnyColor'),
|
||||
'materials': [shared.footing_material if rebound else shared.object_material,
|
||||
shared.footing_material]})
|
||||
|
||||
if graphics == 2:
|
||||
self.light_node = bs.newnode('light', attrs={
|
||||
'position': (0, 0, 0),
|
||||
'color': ((0.8, 0.2, 0.2) if i < count/2 else (0.2, 0.2, 0.8))
|
||||
if not random_color else ((random.uniform(0, 1.1), random.uniform(0, 1.1), random.uniform(0, 1.1))),
|
||||
'radius': 0.2,
|
||||
'intensity': 1,
|
||||
'volume_intensity_scale': 10.0})
|
||||
|
||||
self.node.connectattr('position', self.light_node, 'position')
|
||||
|
||||
def handlemessage(self, m):
|
||||
if isinstance(m, bs.DieMessage):
|
||||
if self.node.exists():
|
||||
if hasattr(self, 'light_node'):
|
||||
self.light_node.delete()
|
||||
self.node.delete()
|
||||
|
||||
elif isinstance(m, bs.OutOfBoundsMessage):
|
||||
if self.node.exists():
|
||||
self.handlemessage(bs.DieMessage())
|
||||
|
||||
elif isinstance(m, bs.HitMessage):
|
||||
self.node.handlemessage('impulse', m.pos[0], m.pos[1], m.pos[2],
|
||||
m.velocity[0], m.velocity[1], m.velocity[2],
|
||||
m.magnitude, m.velocity_magnitude, m.radius, 0,
|
||||
m.velocity[0], m.velocity[1], m.velocity[2])
|
||||
Loading…
Add table
Add a link
Reference in a new issue