2024-01-17 23:09:18 +03:00
|
|
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
2023-06-05 01:32:24 +05:30
|
|
|
# Released under the MIT License. See LICENSE for details.
|
|
|
|
|
#
|
|
|
|
|
"""
|
|
|
|
|
DroneWar - Attack enemies with drone, Fly with drone and fire rocket launcher.
|
|
|
|
|
Author: Mr.Smoothy
|
|
|
|
|
Discord: https://discord.gg/ucyaesh
|
|
|
|
|
Youtube: https://www.youtube.com/c/HeySmoothy
|
|
|
|
|
Website: https://bombsquad-community.web.app
|
|
|
|
|
Github: https://github.com/bombsquad-community
|
|
|
|
|
"""
|
2024-01-17 23:09:18 +03:00
|
|
|
# ba_meta require api 8
|
2023-06-05 01:32:24 +05:30
|
|
|
# (see https://ballistica.net/wiki/meta-tag-system)
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
import babase
|
|
|
|
|
import bascenev1 as bs
|
|
|
|
|
from babase._mgen.enums import InputType
|
|
|
|
|
from bascenev1lib.actor.bomb import Blast
|
2023-06-05 01:32:24 +05:30
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
from bascenev1lib.gameutils import SharedObjects
|
|
|
|
|
from bascenev1lib.actor.playerspaz import PlayerSpaz, PlayerT
|
|
|
|
|
from bascenev1lib.game.deathmatch import DeathMatchGame, Player
|
|
|
|
|
from bascenev1lib.actor import spaz
|
2023-06-05 01:32:24 +05:30
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
|
|
|
|
|
|
|
|
|
STORAGE_ATTR_NAME = f'_shared_{__name__}_factory'
|
|
|
|
|
|
|
|
|
|
# SMoothy's Drone (fixed version of floater) with rocket launcher
|
|
|
|
|
# use drone as long as you want , unlike floater which dies after being idle.
|
2023-06-04 20:03:05 +00:00
|
|
|
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
class Drone(bs.Actor):
|
2023-06-05 01:32:24 +05:30
|
|
|
def __init__(self, spaz):
|
|
|
|
|
super().__init__()
|
|
|
|
|
shared = SharedObjects.get()
|
2024-01-17 23:09:18 +03:00
|
|
|
self._drone_material = bs.Material()
|
2023-06-05 01:32:24 +05:30
|
|
|
self.loop_ascend = None
|
|
|
|
|
self.loop_descend = None
|
|
|
|
|
self.loop_lr = None
|
|
|
|
|
self.loop_ud = None
|
|
|
|
|
self.rocket_launcher = None
|
|
|
|
|
self.x_direction = 0
|
|
|
|
|
self.z_direction = 0
|
|
|
|
|
self.spaz = spaz
|
|
|
|
|
self._drone_material.add_actions(
|
|
|
|
|
conditions=('they_have_material',
|
|
|
|
|
shared.player_material),
|
|
|
|
|
actions=(('modify_node_collision', 'collide', True),
|
|
|
|
|
('modify_part_collision', 'physical', True)))
|
|
|
|
|
self._drone_material.add_actions(
|
|
|
|
|
conditions=(('they_have_material',
|
|
|
|
|
shared.object_material), 'or',
|
|
|
|
|
('they_have_material',
|
|
|
|
|
shared.footing_material), 'or',
|
|
|
|
|
('they_have_material',
|
|
|
|
|
self._drone_material)),
|
|
|
|
|
actions=('modify_part_collision', 'physical', False))
|
2024-01-17 23:09:18 +03:00
|
|
|
self.node = bs.newnode(
|
2023-06-05 01:32:24 +05:30
|
|
|
'prop',
|
|
|
|
|
delegate=self,
|
2023-06-04 20:03:05 +00:00
|
|
|
owner=None,
|
2023-06-05 01:32:24 +05:30
|
|
|
attrs={
|
|
|
|
|
'position': spaz.node.position,
|
2024-01-17 23:09:18 +03:00
|
|
|
'mesh': bs.getmesh('landMine'),
|
|
|
|
|
'light_mesh': bs.getmesh('landMine'),
|
2023-06-04 20:03:05 +00:00
|
|
|
'body': 'landMine',
|
|
|
|
|
'body_scale': 1,
|
2024-01-17 23:09:18 +03:00
|
|
|
'mesh_scale': 1,
|
2023-06-04 20:03:05 +00:00
|
|
|
'shadow_size': 0.25,
|
|
|
|
|
'density': 999999,
|
|
|
|
|
'gravity_scale': 0.0,
|
2024-01-17 23:09:18 +03:00
|
|
|
'color_texture': bs.gettexture('achievementCrossHair'),
|
2023-06-04 20:03:05 +00:00
|
|
|
'reflection': 'soft',
|
2023-06-05 01:32:24 +05:30
|
|
|
'reflection_scale': [0.25],
|
2023-06-04 20:03:05 +00:00
|
|
|
'materials': [shared.footing_material, self._drone_material]
|
|
|
|
|
})
|
2024-01-17 23:09:18 +03:00
|
|
|
self.grab_node = bs.newnode(
|
2023-06-05 01:32:24 +05:30
|
|
|
'prop',
|
|
|
|
|
owner=self.node,
|
|
|
|
|
attrs={
|
|
|
|
|
'position': (0, 0, 0),
|
2023-06-04 20:03:05 +00:00
|
|
|
'body': 'sphere',
|
2024-01-17 23:09:18 +03:00
|
|
|
'mesh': None,
|
2023-06-04 20:03:05 +00:00
|
|
|
'color_texture': None,
|
|
|
|
|
'body_scale': 0.2,
|
|
|
|
|
'reflection': 'powerup',
|
|
|
|
|
'density': 999999,
|
2023-06-05 01:32:24 +05:30
|
|
|
'reflection_scale': [1.0],
|
2024-01-17 23:09:18 +03:00
|
|
|
'mesh_scale': 0.2,
|
2023-06-04 20:03:05 +00:00
|
|
|
'gravity_scale': 0,
|
|
|
|
|
'shadow_size': 0.1,
|
|
|
|
|
'is_area_of_interest': True,
|
|
|
|
|
'materials': [shared.object_material, self._drone_material]
|
2023-06-05 01:32:24 +05:30
|
|
|
})
|
|
|
|
|
self.node.connectattr('position', self.grab_node, 'position')
|
2024-01-17 23:09:18 +03:00
|
|
|
self._rcombine = bs.newnode('combine',
|
2023-06-04 20:03:05 +00:00
|
|
|
owner=self.node,
|
|
|
|
|
attrs={
|
|
|
|
|
'input0': self.spaz.node.position[0],
|
|
|
|
|
'input1': self.spaz.node.position[1]+3,
|
|
|
|
|
'input2': self.spaz.node.position[2],
|
|
|
|
|
'size': 3
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
self._rcombine.connectattr('output', self.node, 'position')
|
|
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def set_rocket_launcher(self, launcher: RocketLauncher):
|
|
|
|
|
self.rocket_launcher = launcher
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def fire(self):
|
2023-06-04 20:03:05 +00:00
|
|
|
if hasattr(self.grab_node, "position"):
|
|
|
|
|
self.rocket_launcher.shot(self.spaz, self.x_direction, self.z_direction, (
|
|
|
|
|
self.grab_node.position[0], self.grab_node.position[1] - 1, self.grab_node.position[2]))
|
|
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def ascend(self):
|
|
|
|
|
def loop():
|
|
|
|
|
if self.node.exists():
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.animate(self._rcombine, 'input1', {
|
2023-06-04 20:03:05 +00:00
|
|
|
0: self.node.position[1],
|
|
|
|
|
1: self.node.position[1] + 2
|
|
|
|
|
})
|
2023-06-05 01:32:24 +05:30
|
|
|
loop()
|
2024-01-17 23:09:18 +03:00
|
|
|
self.loop_ascend = bs.Timer(1, loop, repeat=True)
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def pause_movement(self):
|
|
|
|
|
self.loop_ascend = None
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def decend(self):
|
|
|
|
|
def loop():
|
|
|
|
|
if self.node.exists():
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.animate(self._rcombine, 'input1', {
|
2023-06-04 20:03:05 +00:00
|
|
|
0: self.node.position[1],
|
|
|
|
|
1: self.node.position[1] - 2
|
|
|
|
|
})
|
2023-06-05 01:32:24 +05:30
|
|
|
loop()
|
2024-01-17 23:09:18 +03:00
|
|
|
self.loop_ascend = bs.Timer(1, loop, repeat=True)
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def pause_lr(self):
|
|
|
|
|
self.loop_lr = None
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def pause_ud(self):
|
|
|
|
|
self.loop_ud = None
|
2023-06-04 20:03:05 +00:00
|
|
|
|
|
|
|
|
def left_(self, value=-1):
|
2023-06-05 01:32:24 +05:30
|
|
|
def loop():
|
|
|
|
|
if self.node.exists():
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.animate(self._rcombine, 'input0', {
|
2023-06-04 20:03:05 +00:00
|
|
|
0: self.node.position[0],
|
|
|
|
|
1: self.node.position[0] + 2 * value
|
|
|
|
|
})
|
2023-06-05 01:32:24 +05:30
|
|
|
if value == 0.0:
|
|
|
|
|
self.loop_lr = None
|
|
|
|
|
else:
|
|
|
|
|
self.x_direction = value
|
|
|
|
|
self.z_direction = 0
|
|
|
|
|
loop()
|
2024-01-17 23:09:18 +03:00
|
|
|
self.loop_lr = bs.Timer(1, loop, repeat=True)
|
2023-06-04 20:03:05 +00:00
|
|
|
|
|
|
|
|
def right_(self, value=1):
|
2023-06-05 01:32:24 +05:30
|
|
|
def loop():
|
|
|
|
|
if self.node.exists():
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.animate(self._rcombine, 'input0', {
|
2023-06-04 20:03:05 +00:00
|
|
|
0: self.node.position[0],
|
|
|
|
|
1: self.node.position[0] + 2 * value
|
|
|
|
|
})
|
2023-06-05 01:32:24 +05:30
|
|
|
if value == 0.0:
|
|
|
|
|
self.loop_lr = None
|
|
|
|
|
else:
|
|
|
|
|
self.x_direction = value
|
|
|
|
|
self.z_direction = 0
|
|
|
|
|
loop()
|
2024-01-17 23:09:18 +03:00
|
|
|
self.loop_lr = bs.Timer(1, loop, repeat=True)
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def up_(self, value=1):
|
|
|
|
|
def loop():
|
|
|
|
|
if self.node.exists():
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.animate(self._rcombine, 'input2', {
|
2023-06-04 20:03:05 +00:00
|
|
|
0: self.node.position[2],
|
|
|
|
|
1: self.node.position[2] - 2 * value
|
|
|
|
|
})
|
2023-06-05 01:32:24 +05:30
|
|
|
if value == 0.0:
|
|
|
|
|
self.loop_ud = None
|
|
|
|
|
else:
|
|
|
|
|
self.x_direction = 0
|
|
|
|
|
self.z_direction = - value
|
|
|
|
|
loop()
|
2024-01-17 23:09:18 +03:00
|
|
|
self.loop_ud = bs.Timer(1, loop, repeat=True)
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def down_(self, value=-1):
|
|
|
|
|
def loop():
|
|
|
|
|
if self.node.exists():
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.animate(self._rcombine, 'input2', {
|
2023-06-04 20:03:05 +00:00
|
|
|
0: self.node.position[2],
|
|
|
|
|
1: self.node.position[2] - 2 * value
|
|
|
|
|
})
|
2023-06-05 01:32:24 +05:30
|
|
|
if value == 0.0:
|
|
|
|
|
self.loop_ud = None
|
|
|
|
|
else:
|
|
|
|
|
self.x_direction = 0
|
|
|
|
|
self.z_direction = - value
|
|
|
|
|
loop()
|
2024-01-17 23:09:18 +03:00
|
|
|
self.loop_ud = bs.Timer(1, loop, repeat=True)
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def handlemessage(self, msg):
|
2024-01-17 23:09:18 +03:00
|
|
|
if isinstance(msg, bs.DieMessage):
|
2023-06-05 01:32:24 +05:30
|
|
|
self.node.delete()
|
|
|
|
|
self.grab_node.delete()
|
|
|
|
|
self.loop_ascend = None
|
|
|
|
|
self.loop_ud = None
|
|
|
|
|
self.loop_lr = None
|
2024-01-17 23:09:18 +03:00
|
|
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
|
|
|
|
self.handlemessage(bs.DieMessage())
|
2023-06-05 01:32:24 +05:30
|
|
|
else:
|
|
|
|
|
super().handlemessage(msg)
|
|
|
|
|
|
|
|
|
|
# =============================================Copied from Quake Game - Dliwk =====================================================================
|
2023-06-04 20:03:05 +00:00
|
|
|
|
|
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
class RocketFactory:
|
|
|
|
|
"""Quake Rocket factory"""
|
|
|
|
|
|
|
|
|
|
def __init__(self) -> None:
|
2024-01-17 23:09:18 +03:00
|
|
|
self.ball_material = bs.Material()
|
2023-06-05 01:32:24 +05:30
|
|
|
|
|
|
|
|
self.ball_material.add_actions(
|
|
|
|
|
conditions=((('we_are_younger_than', 5), 'or',
|
|
|
|
|
('they_are_younger_than', 5)), 'and',
|
|
|
|
|
('they_have_material',
|
|
|
|
|
SharedObjects.get().object_material)),
|
|
|
|
|
actions=('modify_node_collision', 'collide', False))
|
|
|
|
|
|
|
|
|
|
self.ball_material.add_actions(
|
|
|
|
|
conditions=('they_have_material',
|
|
|
|
|
SharedObjects.get().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',
|
|
|
|
|
SharedObjects.get().footing_material), 'or',
|
|
|
|
|
('they_have_material',
|
|
|
|
|
SharedObjects.get().object_material)),
|
|
|
|
|
actions=('message', 'our_node', 'at_connect', ImpactMessage()))
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def get(cls):
|
|
|
|
|
"""Get factory if exists else create new"""
|
2024-01-17 23:09:18 +03:00
|
|
|
activity = bs.getactivity()
|
2023-06-05 01:32:24 +05:30
|
|
|
if hasattr(activity, STORAGE_ATTR_NAME):
|
|
|
|
|
return getattr(activity, STORAGE_ATTR_NAME)
|
|
|
|
|
factory = cls()
|
|
|
|
|
setattr(activity, STORAGE_ATTR_NAME, factory)
|
|
|
|
|
return factory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RocketLauncher:
|
|
|
|
|
"""Very dangerous weapon"""
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
2024-01-17 23:09:18 +03:00
|
|
|
self.last_shot = bs.time()
|
2023-06-05 01:32:24 +05:30
|
|
|
|
|
|
|
|
def give(self, spaz: spaz.Spaz) -> None:
|
|
|
|
|
"""Give spaz a rocket launcher"""
|
|
|
|
|
spaz.punch_callback = self.shot
|
2024-01-17 23:09:18 +03:00
|
|
|
self.last_shot = bs.time()
|
2023-06-05 01:32:24 +05:30
|
|
|
|
|
|
|
|
# FIXME
|
|
|
|
|
# noinspection PyUnresolvedReferences
|
|
|
|
|
def shot(self, spaz, x, z, position) -> None:
|
|
|
|
|
"""Release a rocket"""
|
2024-01-17 23:09:18 +03:00
|
|
|
time = bs.time()
|
2023-06-05 01:32:24 +05:30
|
|
|
if time - self.last_shot > 0.6:
|
|
|
|
|
self.last_shot = time
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
direction = [x, 0, z]
|
|
|
|
|
direction[1] = 0.0
|
|
|
|
|
|
2024-01-18 13:41:11 +00:00
|
|
|
mag = 10.0 / \
|
|
|
|
|
1 if babase.Vec3(*direction).length() == 0 else babase.Vec3(*direction).length()
|
2023-06-05 01:32:24 +05:30
|
|
|
vel = [v * mag for v in direction]
|
|
|
|
|
Rocket(position=position,
|
|
|
|
|
velocity=vel,
|
2024-01-17 23:09:18 +03:00
|
|
|
owner=spaz.getplayer(bs.Player),
|
|
|
|
|
source_player=spaz.getplayer(bs.Player),
|
2023-06-05 01:32:24 +05:30
|
|
|
color=spaz.node.color).autoretain()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ImpactMessage:
|
|
|
|
|
"""Rocket touched something"""
|
|
|
|
|
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
class Rocket(bs.Actor):
|
2023-06-05 01:32:24 +05:30
|
|
|
"""Epic rocket from rocket launcher"""
|
|
|
|
|
|
|
|
|
|
def __init__(self,
|
|
|
|
|
position=(0, 5, 0),
|
|
|
|
|
velocity=(1, 0, 0),
|
|
|
|
|
source_player=None,
|
|
|
|
|
owner=None,
|
|
|
|
|
color=(1.0, 0.2, 0.2)) -> None:
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.source_player = source_player
|
|
|
|
|
self.owner = owner
|
|
|
|
|
self._color = color
|
|
|
|
|
factory = RocketFactory.get()
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
self.node = bs.newnode('prop',
|
2023-06-05 01:32:24 +05:30
|
|
|
delegate=self,
|
|
|
|
|
attrs={
|
|
|
|
|
'position': position,
|
|
|
|
|
'velocity': velocity,
|
2024-01-17 23:09:18 +03:00
|
|
|
'mesh': bs.getmesh('impactBomb'),
|
2023-06-05 01:32:24 +05:30
|
|
|
'body': 'sphere',
|
2024-01-17 23:09:18 +03:00
|
|
|
'color_texture': bs.gettexture(
|
2023-06-05 01:32:24 +05:30
|
|
|
'bunnyColor'),
|
2024-01-17 23:09:18 +03:00
|
|
|
'mesh_scale': 0.2,
|
2023-06-05 01:32:24 +05:30
|
|
|
'is_area_of_interest': True,
|
|
|
|
|
'body_scale': 0.8,
|
|
|
|
|
'materials': [
|
|
|
|
|
SharedObjects.get().object_material,
|
|
|
|
|
factory.ball_material]
|
|
|
|
|
}) # yapf: disable
|
|
|
|
|
self.node.extra_acceleration = (self.node.velocity[0] * 200, 0,
|
|
|
|
|
self.node.velocity[2] * 200)
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
self._life_timer = bs.Timer(
|
|
|
|
|
5, bs.WeakCall(self.handlemessage, bs.DieMessage()))
|
2023-06-05 01:32:24 +05:30
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
self._emit_timer = bs.Timer(0.001, bs.WeakCall(self.emit), repeat=True)
|
2023-06-05 01:32:24 +05:30
|
|
|
self.base_pos_y = self.node.position[1]
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.camerashake(5.0)
|
2023-06-05 01:32:24 +05:30
|
|
|
|
|
|
|
|
def emit(self) -> None:
|
|
|
|
|
"""Emit a trace after rocket"""
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.emitfx(position=self.node.position,
|
2023-06-05 01:32:24 +05:30
|
|
|
scale=0.4,
|
|
|
|
|
spread=0.01,
|
|
|
|
|
chunk_type='spark')
|
|
|
|
|
if not self.node:
|
|
|
|
|
return
|
|
|
|
|
self.node.position = (self.node.position[0], self.base_pos_y,
|
|
|
|
|
self.node.position[2]) # ignore y
|
2024-01-17 23:09:18 +03:00
|
|
|
bs.newnode('explosion',
|
2023-06-05 01:32:24 +05:30
|
|
|
owner=self.node,
|
|
|
|
|
attrs={
|
|
|
|
|
'position': self.node.position,
|
|
|
|
|
'radius': 0.2,
|
|
|
|
|
'color': self._color
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
def handlemessage(self, msg: Any) -> Any:
|
|
|
|
|
"""Message handling for rocket"""
|
|
|
|
|
super().handlemessage(msg)
|
|
|
|
|
if isinstance(msg, ImpactMessage):
|
2024-01-17 23:09:18 +03:00
|
|
|
self.node.handlemessage(bs.DieMessage())
|
2023-06-05 01:32:24 +05:30
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
elif isinstance(msg, bs.DieMessage):
|
2023-06-05 01:32:24 +05:30
|
|
|
if self.node:
|
|
|
|
|
Blast(position=self.node.position,
|
|
|
|
|
blast_radius=2,
|
|
|
|
|
source_player=self.source_player)
|
|
|
|
|
|
|
|
|
|
self.node.delete()
|
|
|
|
|
self._emit_timer = None
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
|
|
|
|
self.handlemessage(bs.DieMessage())
|
2023-06-05 01:32:24 +05:30
|
|
|
|
|
|
|
|
|
2024-01-17 23:09:18 +03:00
|
|
|
# ba_meta export bascenev1.GameActivity
|
2023-06-05 01:32:24 +05:30
|
|
|
class ChooseQueen(DeathMatchGame):
|
|
|
|
|
name = 'Drone War'
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2024-01-17 23:09:18 +03:00
|
|
|
def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool:
|
|
|
|
|
return issubclass(sessiontype, bs.DualTeamSession)
|
2023-06-05 01:32:24 +05:30
|
|
|
|
|
|
|
|
@classmethod
|
2024-01-17 23:09:18 +03:00
|
|
|
def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]:
|
2023-06-05 01:32:24 +05:30
|
|
|
return ['Football Stadium']
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def spawn_player_spaz(
|
|
|
|
|
self,
|
2024-01-17 23:09:18 +03:00
|
|
|
player: PlayerT,
|
2023-06-05 01:32:24 +05:30
|
|
|
position: Sequence[float] | None = None,
|
|
|
|
|
angle: float | None = None,
|
|
|
|
|
) -> PlayerSpaz:
|
2023-06-04 20:03:05 +00:00
|
|
|
spaz = super().spawn_player_spaz(player, position, angle)
|
2023-06-05 01:32:24 +05:30
|
|
|
self.spawn_drone(spaz)
|
|
|
|
|
return spaz
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
def on_begin(self):
|
|
|
|
|
super().on_begin()
|
|
|
|
|
shared = SharedObjects.get()
|
2024-01-17 23:09:18 +03:00
|
|
|
self.ground_material = bs.Material()
|
2023-06-05 01:32:24 +05:30
|
|
|
self.ground_material.add_actions(
|
2023-06-04 20:03:05 +00:00
|
|
|
conditions=('they_have_material', shared.player_material),
|
2023-06-05 01:32:24 +05:30
|
|
|
actions=(
|
|
|
|
|
('modify_part_collision', 'collide', True),
|
2024-01-17 23:09:18 +03:00
|
|
|
('call', 'at_connect', babase.Call(self._handle_player_collide)),
|
2023-06-05 01:32:24 +05:30
|
|
|
),
|
2023-06-04 20:03:05 +00:00
|
|
|
)
|
|
|
|
|
pos = (0, 0.1, -5)
|
2024-01-17 23:09:18 +03:00
|
|
|
self.main_region = bs.newnode('region', attrs={'position': pos, 'scale': (
|
2023-06-04 20:03:05 +00:00
|
|
|
30, 0.001, 23), 'type': 'box', 'materials': [shared.footing_material, self.ground_material]})
|
2023-06-05 01:32:24 +05:30
|
|
|
|
|
|
|
|
def _handle_player_collide(self):
|
|
|
|
|
try:
|
2024-01-17 23:09:18 +03:00
|
|
|
player = bs.getcollision().opposingnode.getdelegate(
|
2023-06-05 01:32:24 +05:30
|
|
|
PlayerSpaz, True)
|
2024-01-17 23:09:18 +03:00
|
|
|
except bs.NotFoundError:
|
2023-06-05 01:32:24 +05:30
|
|
|
return
|
|
|
|
|
if player.is_alive():
|
|
|
|
|
player.shatter(True)
|
|
|
|
|
|
|
|
|
|
def spawn_drone(self, spaz):
|
2024-01-17 23:09:18 +03:00
|
|
|
with bs.get_foreground_host_activity().context:
|
2023-06-04 20:03:05 +00:00
|
|
|
|
2023-06-05 01:32:24 +05:30
|
|
|
drone = Drone(spaz)
|
|
|
|
|
r_launcher = RocketLauncher()
|
|
|
|
|
drone.set_rocket_launcher(r_launcher)
|
|
|
|
|
player = spaz.getplayer(Player, True)
|
|
|
|
|
spaz.node.hold_node = drone.grab_node
|
|
|
|
|
player.actor.disconnect_controls_from_player()
|
|
|
|
|
player.resetinput()
|
|
|
|
|
player.assigninput(InputType.PICK_UP_PRESS, drone.ascend)
|
|
|
|
|
player.assigninput(InputType.PICK_UP_RELEASE, drone.pause_movement)
|
|
|
|
|
player.assigninput(InputType.JUMP_PRESS, drone.decend)
|
2024-08-22 12:07:31 +03:00
|
|
|
player.assigninput(InputType.JUMP_RELEASE, self.pause_movement)
|
2023-06-05 01:32:24 +05:30
|
|
|
player.assigninput(InputType.PUNCH_PRESS, drone.fire)
|
|
|
|
|
player.assigninput(InputType.LEFT_PRESS, drone.left_)
|
|
|
|
|
player.assigninput(InputType.RIGHT_PRESS, drone.right_)
|
|
|
|
|
player.assigninput(InputType.LEFT_RELEASE, drone.pause_lr)
|
|
|
|
|
player.assigninput(InputType.RIGHT_RELEASE, drone.pause_lr)
|
|
|
|
|
player.assigninput(InputType.UP_PRESS, drone.up_)
|
|
|
|
|
player.assigninput(InputType.DOWN_PRESS, drone.down_)
|
|
|
|
|
player.assigninput(InputType.UP_RELEASE, drone.pause_ud)
|
2023-06-04 20:03:05 +00:00
|
|
|
player.assigninput(InputType.DOWN_RELEASE, drone.pause_ud)
|