mirror of
https://github.com/bombsquad-community/plugin-manager.git
synced 2026-08-15 13:03:08 +00:00
[ci] apply-plugin-metadata-and-formatting
This commit is contained in:
parent
ebbd198628
commit
e67d891716
5 changed files with 627 additions and 519 deletions
|
|
@ -2426,6 +2426,62 @@
|
||||||
"md5sum": "d8002dfc93be74d71f8e6e4aacfe6fd1"
|
"md5sum": "d8002dfc93be74d71f8e6e4aacfe6fd1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"better_camera_shake": {
|
||||||
|
"description": "This plugin makes the camera only shake when an explosion hits a player character, begone excessive camera shaking!",
|
||||||
|
"external_url": "",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "DinoWattz",
|
||||||
|
"email": "",
|
||||||
|
"discord": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"versions": {
|
||||||
|
"1.0.0": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chat_bubbles": {
|
||||||
|
"description": "Adds whatever the players say above their character, includes a few other features too!",
|
||||||
|
"external_url": "",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "DinoWattz",
|
||||||
|
"email": "",
|
||||||
|
"discord": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"versions": {
|
||||||
|
"1.0.0": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enhanced_effects": {
|
||||||
|
"description": "Explosions affect character colors, slow-mo tnt, fair colored shields, a trippy background screen and maybe more in the future!",
|
||||||
|
"external_url": "",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "DinoWattz",
|
||||||
|
"email": "",
|
||||||
|
"discord": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"versions": {
|
||||||
|
"1.0.0": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sleep_on_afk": {
|
||||||
|
"description": "Staying idle for 40 seconds will make your character fall asleep, they need rest too..",
|
||||||
|
"external_url": "",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "DinoWattz",
|
||||||
|
"email": "",
|
||||||
|
"discord": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"versions": {
|
||||||
|
"1.0.0": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,356 +26,363 @@ plugman = dict(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Camera shake only on player impact
|
# Camera shake only on player impact
|
||||||
|
|
||||||
|
|
||||||
def new__init__(
|
def new__init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
position: Sequence[float] = (0.0, 1.0, 0.0),
|
position: Sequence[float] = (0.0, 1.0, 0.0),
|
||||||
velocity: Sequence[float] = (0.0, 0.0, 0.0),
|
velocity: Sequence[float] = (0.0, 0.0, 0.0),
|
||||||
blast_radius: float = 2.0,
|
blast_radius: float = 2.0,
|
||||||
blast_type: str = 'normal',
|
blast_type: str = 'normal',
|
||||||
source_player: bs.Player | None = None,
|
source_player: bs.Player | None = None,
|
||||||
hit_type: str = 'explosion',
|
hit_type: str = 'explosion',
|
||||||
hit_subtype: str = 'normal',
|
hit_subtype: str = 'normal',
|
||||||
):
|
):
|
||||||
"""Instantiate with given values."""
|
"""Instantiate with given values."""
|
||||||
|
|
||||||
# bah; get off my lawn!
|
# bah; get off my lawn!
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
|
|
||||||
super(type(self), self).__init__()
|
super(type(self), self).__init__()
|
||||||
|
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
factory = BombFactory.get()
|
factory = BombFactory.get()
|
||||||
|
|
||||||
self.blast_type = blast_type
|
self.blast_type = blast_type
|
||||||
self._source_player = source_player
|
self._source_player = source_player
|
||||||
self.hit_type = hit_type
|
self.hit_type = hit_type
|
||||||
self.hit_subtype = hit_subtype
|
self.hit_subtype = hit_subtype
|
||||||
self.radius = blast_radius
|
self.radius = blast_radius
|
||||||
|
|
||||||
# Set our position a bit lower so we throw more things upward.
|
# Set our position a bit lower so we throw more things upward.
|
||||||
rmats = (factory.blast_material, shared.attack_material)
|
rmats = (factory.blast_material, shared.attack_material)
|
||||||
self.node = bs.newnode(
|
self.node = bs.newnode(
|
||||||
'region',
|
'region',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'position': (position[0], position[1] - 0.1, position[2]),
|
'position': (position[0], position[1] - 0.1, position[2]),
|
||||||
'scale': (self.radius, self.radius, self.radius),
|
'scale': (self.radius, self.radius, self.radius),
|
||||||
'type': 'sphere',
|
'type': 'sphere',
|
||||||
'materials': rmats,
|
'materials': rmats,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
bs.timer(0.05, self.node.delete)
|
bs.timer(0.05, self.node.delete)
|
||||||
|
|
||||||
# Throw in an explosion and flash.
|
# Throw in an explosion and flash.
|
||||||
evel = (velocity[0], max(-1.0, velocity[1]), velocity[2])
|
evel = (velocity[0], max(-1.0, velocity[1]), velocity[2])
|
||||||
explosion = bs.newnode(
|
explosion = bs.newnode(
|
||||||
'explosion',
|
'explosion',
|
||||||
attrs={
|
attrs={
|
||||||
'position': position,
|
'position': position,
|
||||||
'velocity': evel,
|
'velocity': evel,
|
||||||
'radius': self.radius,
|
'radius': self.radius,
|
||||||
'big': (self.blast_type == 'tnt'),
|
'big': (self.blast_type == 'tnt'),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if self.blast_type == 'ice':
|
if self.blast_type == 'ice':
|
||||||
explosion.color = (0, 0.05, 0.4)
|
explosion.color = (0, 0.05, 0.4)
|
||||||
|
|
||||||
bs.timer(1.0, explosion.delete)
|
bs.timer(1.0, explosion.delete)
|
||||||
|
|
||||||
if self.blast_type != 'ice':
|
if self.blast_type != 'ice':
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=int(1.0 + random.random() * 4),
|
|
||||||
emit_type='tendrils',
|
|
||||||
tendril_type='thin_smoke',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
bs.emitfx(
|
||||||
position=position,
|
position=position,
|
||||||
velocity=velocity,
|
velocity=velocity,
|
||||||
count=int(4.0 + random.random() * 4),
|
count=int(1.0 + random.random() * 4),
|
||||||
emit_type='tendrils',
|
emit_type='tendrils',
|
||||||
tendril_type='ice' if self.blast_type == 'ice' else 'smoke',
|
tendril_type='thin_smoke',
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
emit_type='distortion',
|
|
||||||
spread=1.0 if self.blast_type == 'tnt' else 2.0,
|
|
||||||
)
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(4.0 + random.random() * 4),
|
||||||
|
emit_type='tendrils',
|
||||||
|
tendril_type='ice' if self.blast_type == 'ice' else 'smoke',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
emit_type='distortion',
|
||||||
|
spread=1.0 if self.blast_type == 'tnt' else 2.0,
|
||||||
|
)
|
||||||
|
|
||||||
# And emit some shrapnel.
|
# And emit some shrapnel.
|
||||||
if self.blast_type == 'ice':
|
if self.blast_type == 'ice':
|
||||||
|
|
||||||
def emit() -> None:
|
def emit() -> None:
|
||||||
bs.emitfx(
|
bs.emitfx(
|
||||||
position=position,
|
position=position,
|
||||||
velocity=velocity,
|
velocity=velocity,
|
||||||
count=30,
|
count=30,
|
||||||
spread=2.0,
|
spread=2.0,
|
||||||
scale=0.4,
|
scale=0.4,
|
||||||
chunk_type='ice',
|
chunk_type='ice',
|
||||||
emit_type='stickers',
|
emit_type='stickers',
|
||||||
)
|
)
|
||||||
|
|
||||||
# It looks better if we delay a bit.
|
# It looks better if we delay a bit.
|
||||||
bs.timer(0.05, emit)
|
bs.timer(0.05, emit)
|
||||||
|
|
||||||
elif self.blast_type == 'sticky':
|
elif self.blast_type == 'sticky':
|
||||||
|
|
||||||
def emit() -> None:
|
def emit() -> None:
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(4.0 + random.random() * 8),
|
||||||
|
spread=0.7,
|
||||||
|
chunk_type='slime',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(4.0 + random.random() * 8),
|
||||||
|
scale=0.5,
|
||||||
|
spread=0.7,
|
||||||
|
chunk_type='slime',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=15,
|
||||||
|
scale=0.6,
|
||||||
|
chunk_type='slime',
|
||||||
|
emit_type='stickers',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=20,
|
||||||
|
scale=0.7,
|
||||||
|
chunk_type='spark',
|
||||||
|
emit_type='stickers',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(6.0 + random.random() * 12),
|
||||||
|
scale=0.8,
|
||||||
|
spread=1.5,
|
||||||
|
chunk_type='spark',
|
||||||
|
)
|
||||||
|
|
||||||
|
# It looks better if we delay a bit.
|
||||||
|
bs.timer(0.05, emit)
|
||||||
|
|
||||||
|
elif self.blast_type == 'impact':
|
||||||
|
|
||||||
|
def emit() -> None:
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(4.0 + random.random() * 8),
|
||||||
|
scale=0.8,
|
||||||
|
chunk_type='metal',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(4.0 + random.random() * 8),
|
||||||
|
scale=0.4,
|
||||||
|
chunk_type='metal',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=20,
|
||||||
|
scale=0.7,
|
||||||
|
chunk_type='spark',
|
||||||
|
emit_type='stickers',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(8.0 + random.random() * 15),
|
||||||
|
scale=0.8,
|
||||||
|
spread=1.5,
|
||||||
|
chunk_type='spark',
|
||||||
|
)
|
||||||
|
|
||||||
|
# It looks better if we delay a bit.
|
||||||
|
bs.timer(0.05, emit)
|
||||||
|
|
||||||
|
else: # Regular or land mine bomb shrapnel.
|
||||||
|
|
||||||
|
def emit() -> None:
|
||||||
|
if self.blast_type != 'tnt':
|
||||||
bs.emitfx(
|
bs.emitfx(
|
||||||
position=position,
|
position=position,
|
||||||
velocity=velocity,
|
velocity=velocity,
|
||||||
count=int(4.0 + random.random() * 8),
|
count=int(4.0 + random.random() * 8),
|
||||||
spread=0.7,
|
chunk_type='rock',
|
||||||
chunk_type='slime',
|
|
||||||
)
|
)
|
||||||
bs.emitfx(
|
bs.emitfx(
|
||||||
position=position,
|
position=position,
|
||||||
velocity=velocity,
|
velocity=velocity,
|
||||||
count=int(4.0 + random.random() * 8),
|
count=int(4.0 + random.random() * 8),
|
||||||
scale=0.5,
|
scale=0.5,
|
||||||
spread=0.7,
|
chunk_type='rock',
|
||||||
chunk_type='slime',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=15,
|
|
||||||
scale=0.6,
|
|
||||||
chunk_type='slime',
|
|
||||||
emit_type='stickers',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=20,
|
|
||||||
scale=0.7,
|
|
||||||
chunk_type='spark',
|
|
||||||
emit_type='stickers',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=int(6.0 + random.random() * 12),
|
|
||||||
scale=0.8,
|
|
||||||
spread=1.5,
|
|
||||||
chunk_type='spark',
|
|
||||||
)
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=30,
|
||||||
|
scale=1.0 if self.blast_type == 'tnt' else 0.7,
|
||||||
|
chunk_type='spark',
|
||||||
|
emit_type='stickers',
|
||||||
|
)
|
||||||
|
bs.emitfx(
|
||||||
|
position=position,
|
||||||
|
velocity=velocity,
|
||||||
|
count=int(18.0 + random.random() * 20),
|
||||||
|
scale=1.0 if self.blast_type == 'tnt' else 0.8,
|
||||||
|
spread=1.5,
|
||||||
|
chunk_type='spark',
|
||||||
|
)
|
||||||
|
|
||||||
# It looks better if we delay a bit.
|
# TNT throws splintery chunks.
|
||||||
bs.timer(0.05, emit)
|
if self.blast_type == 'tnt':
|
||||||
|
|
||||||
elif self.blast_type == 'impact':
|
def emit_splinters() -> None:
|
||||||
|
|
||||||
def emit() -> None:
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=int(4.0 + random.random() * 8),
|
|
||||||
scale=0.8,
|
|
||||||
chunk_type='metal',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=int(4.0 + random.random() * 8),
|
|
||||||
scale=0.4,
|
|
||||||
chunk_type='metal',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=20,
|
|
||||||
scale=0.7,
|
|
||||||
chunk_type='spark',
|
|
||||||
emit_type='stickers',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=int(8.0 + random.random() * 15),
|
|
||||||
scale=0.8,
|
|
||||||
spread=1.5,
|
|
||||||
chunk_type='spark',
|
|
||||||
)
|
|
||||||
|
|
||||||
# It looks better if we delay a bit.
|
|
||||||
bs.timer(0.05, emit)
|
|
||||||
|
|
||||||
else: # Regular or land mine bomb shrapnel.
|
|
||||||
|
|
||||||
def emit() -> None:
|
|
||||||
if self.blast_type != 'tnt':
|
|
||||||
bs.emitfx(
|
bs.emitfx(
|
||||||
position=position,
|
position=position,
|
||||||
velocity=velocity,
|
velocity=velocity,
|
||||||
count=int(4.0 + random.random() * 8),
|
count=int(20.0 + random.random() * 25),
|
||||||
chunk_type='rock',
|
scale=0.8,
|
||||||
|
spread=1.0,
|
||||||
|
chunk_type='splinter',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bs.timer(0.01, emit_splinters)
|
||||||
|
|
||||||
|
# Every now and then do a sparky one.
|
||||||
|
if self.blast_type == 'tnt' or random.random() < 0.1:
|
||||||
|
|
||||||
|
def emit_extra_sparks() -> None:
|
||||||
bs.emitfx(
|
bs.emitfx(
|
||||||
position=position,
|
position=position,
|
||||||
velocity=velocity,
|
velocity=velocity,
|
||||||
count=int(4.0 + random.random() * 8),
|
count=int(10.0 + random.random() * 20),
|
||||||
scale=0.5,
|
scale=0.8,
|
||||||
chunk_type='rock',
|
spread=1.5,
|
||||||
|
chunk_type='spark',
|
||||||
)
|
)
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=30,
|
|
||||||
scale=1.0 if self.blast_type == 'tnt' else 0.7,
|
|
||||||
chunk_type='spark',
|
|
||||||
emit_type='stickers',
|
|
||||||
)
|
|
||||||
bs.emitfx(
|
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=int(18.0 + random.random() * 20),
|
|
||||||
scale=1.0 if self.blast_type == 'tnt' else 0.8,
|
|
||||||
spread=1.5,
|
|
||||||
chunk_type='spark',
|
|
||||||
)
|
|
||||||
|
|
||||||
# TNT throws splintery chunks.
|
bs.timer(0.02, emit_extra_sparks)
|
||||||
if self.blast_type == 'tnt':
|
|
||||||
|
|
||||||
def emit_splinters() -> None:
|
# It looks better if we delay a bit.
|
||||||
bs.emitfx(
|
bs.timer(0.05, emit)
|
||||||
position=position,
|
|
||||||
velocity=velocity,
|
|
||||||
count=int(20.0 + random.random() * 25),
|
|
||||||
scale=0.8,
|
|
||||||
spread=1.0,
|
|
||||||
chunk_type='splinter',
|
|
||||||
)
|
|
||||||
|
|
||||||
bs.timer(0.01, emit_splinters)
|
lcolor = (0.6, 0.6, 1.0) if self.blast_type == 'ice' else (1, 0.3, 0.1)
|
||||||
|
light = bs.newnode(
|
||||||
|
'light',
|
||||||
|
attrs={
|
||||||
|
'position': position,
|
||||||
|
'volume_intensity_scale': 10.0,
|
||||||
|
'color': lcolor,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
# Every now and then do a sparky one.
|
scl = random.uniform(0.6, 0.9)
|
||||||
if self.blast_type == 'tnt' or random.random() < 0.1:
|
scorch_radius = light_radius = self.radius
|
||||||
|
if self.blast_type == 'tnt':
|
||||||
|
light_radius *= 1.4
|
||||||
|
scorch_radius *= 1.15
|
||||||
|
scl *= 3.0
|
||||||
|
|
||||||
def emit_extra_sparks() -> None:
|
iscale = 1.6
|
||||||
bs.emitfx(
|
bs.animate(
|
||||||
position=position,
|
light,
|
||||||
velocity=velocity,
|
'intensity',
|
||||||
count=int(10.0 + random.random() * 20),
|
{
|
||||||
scale=0.8,
|
0: 2.0 * iscale,
|
||||||
spread=1.5,
|
scl * 0.02: 0.1 * iscale,
|
||||||
chunk_type='spark',
|
scl * 0.025: 0.2 * iscale,
|
||||||
)
|
scl * 0.05: 17.0 * iscale,
|
||||||
|
scl * 0.06: 5.0 * iscale,
|
||||||
|
scl * 0.08: 4.0 * iscale,
|
||||||
|
scl * 0.2: 0.6 * iscale,
|
||||||
|
scl * 2.0: 0.00 * iscale,
|
||||||
|
scl * 3.0: 0.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
bs.animate(
|
||||||
|
light,
|
||||||
|
'radius',
|
||||||
|
{
|
||||||
|
0: light_radius * 0.2,
|
||||||
|
scl * 0.05: light_radius * 0.55,
|
||||||
|
scl * 0.1: light_radius * 0.3,
|
||||||
|
scl * 0.3: light_radius * 0.15,
|
||||||
|
scl * 1.0: light_radius * 0.05,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
bs.timer(scl * 3.0, light.delete)
|
||||||
|
|
||||||
bs.timer(0.02, emit_extra_sparks)
|
# Make a scorch that fades over time.
|
||||||
|
scorch = bs.newnode(
|
||||||
|
'scorch',
|
||||||
|
attrs={
|
||||||
|
'position': position,
|
||||||
|
'size': scorch_radius * 0.5,
|
||||||
|
'big': (self.blast_type == 'tnt'),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if self.blast_type == 'ice':
|
||||||
|
scorch.color = (1, 1, 1.5)
|
||||||
|
|
||||||
# It looks better if we delay a bit.
|
bs.animate(scorch, 'presence', {3.000: 1, 13.000: 0})
|
||||||
bs.timer(0.05, emit)
|
bs.timer(13.0, scorch.delete)
|
||||||
|
|
||||||
lcolor = (0.6, 0.6, 1.0) if self.blast_type == 'ice' else (1, 0.3, 0.1)
|
if self.blast_type == 'ice':
|
||||||
light = bs.newnode(
|
factory.hiss_sound.play(position=light.position)
|
||||||
'light',
|
|
||||||
attrs={
|
|
||||||
'position': position,
|
|
||||||
'volume_intensity_scale': 10.0,
|
|
||||||
'color': lcolor,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
scl = random.uniform(0.6, 0.9)
|
lpos = light.position
|
||||||
scorch_radius = light_radius = self.radius
|
factory.random_explode_sound().play(position=lpos)
|
||||||
if self.blast_type == 'tnt':
|
factory.debris_fall_sound.play(position=lpos)
|
||||||
light_radius *= 1.4
|
|
||||||
scorch_radius *= 1.15
|
|
||||||
scl *= 3.0
|
|
||||||
|
|
||||||
iscale = 1.6
|
# ↓ We don't need any of this, we're fully trained professionals.
|
||||||
bs.animate(
|
# bs.camerashake(intensity=5.0 if self.blast_type == 'tnt' else 1.0)
|
||||||
light,
|
|
||||||
'intensity',
|
|
||||||
{
|
|
||||||
0: 2.0 * iscale,
|
|
||||||
scl * 0.02: 0.1 * iscale,
|
|
||||||
scl * 0.025: 0.2 * iscale,
|
|
||||||
scl * 0.05: 17.0 * iscale,
|
|
||||||
scl * 0.06: 5.0 * iscale,
|
|
||||||
scl * 0.08: 4.0 * iscale,
|
|
||||||
scl * 0.2: 0.6 * iscale,
|
|
||||||
scl * 2.0: 0.00 * iscale,
|
|
||||||
scl * 3.0: 0.0,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
bs.animate(
|
|
||||||
light,
|
|
||||||
'radius',
|
|
||||||
{
|
|
||||||
0: light_radius * 0.2,
|
|
||||||
scl * 0.05: light_radius * 0.55,
|
|
||||||
scl * 0.1: light_radius * 0.3,
|
|
||||||
scl * 0.3: light_radius * 0.15,
|
|
||||||
scl * 1.0: light_radius * 0.05,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
bs.timer(scl * 3.0, light.delete)
|
|
||||||
|
|
||||||
# Make a scorch that fades over time.
|
# TNT is more epic.
|
||||||
scorch = bs.newnode(
|
if self.blast_type == 'tnt':
|
||||||
'scorch',
|
|
||||||
attrs={
|
|
||||||
'position': position,
|
|
||||||
'size': scorch_radius * 0.5,
|
|
||||||
'big': (self.blast_type == 'tnt'),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if self.blast_type == 'ice':
|
|
||||||
scorch.color = (1, 1, 1.5)
|
|
||||||
|
|
||||||
bs.animate(scorch, 'presence', {3.000: 1, 13.000: 0})
|
|
||||||
bs.timer(13.0, scorch.delete)
|
|
||||||
|
|
||||||
if self.blast_type == 'ice':
|
|
||||||
factory.hiss_sound.play(position=light.position)
|
|
||||||
|
|
||||||
lpos = light.position
|
|
||||||
factory.random_explode_sound().play(position=lpos)
|
factory.random_explode_sound().play(position=lpos)
|
||||||
factory.debris_fall_sound.play(position=lpos)
|
|
||||||
|
|
||||||
# ↓ We don't need any of this, we're fully trained professionals.
|
def _extra_boom() -> None:
|
||||||
#bs.camerashake(intensity=5.0 if self.blast_type == 'tnt' else 1.0)
|
|
||||||
|
|
||||||
# TNT is more epic.
|
|
||||||
if self.blast_type == 'tnt':
|
|
||||||
factory.random_explode_sound().play(position=lpos)
|
factory.random_explode_sound().play(position=lpos)
|
||||||
|
|
||||||
def _extra_boom() -> None:
|
bs.timer(0.25, _extra_boom)
|
||||||
factory.random_explode_sound().play(position=lpos)
|
|
||||||
|
|
||||||
bs.timer(0.25, _extra_boom)
|
def _extra_debris_sound() -> None:
|
||||||
|
factory.debris_fall_sound.play(position=lpos)
|
||||||
|
factory.wood_debris_fall_sound.play(position=lpos)
|
||||||
|
|
||||||
def _extra_debris_sound() -> None:
|
bs.timer(0.4, _extra_debris_sound)
|
||||||
factory.debris_fall_sound.play(position=lpos)
|
|
||||||
factory.wood_debris_fall_sound.play(position=lpos)
|
|
||||||
|
|
||||||
bs.timer(0.4, _extra_debris_sound)
|
|
||||||
|
|
||||||
bomb.Blast.__init__ = new__init__
|
bomb.Blast.__init__ = new__init__
|
||||||
|
|
||||||
org_handlemessage = bomb.Blast.handlemessage
|
org_handlemessage = bomb.Blast.handlemessage
|
||||||
|
|
||||||
|
|
||||||
def new_handlemessage(self, msg: Any, *args, **kwargs) -> Any:
|
def new_handlemessage(self, msg: Any, *args, **kwargs) -> Any:
|
||||||
org_handlemessage(self, msg, *args, **kwargs)
|
org_handlemessage(self, msg, *args, **kwargs)
|
||||||
|
|
||||||
if isinstance(msg, ExplodeHitMessage):
|
if isinstance(msg, ExplodeHitMessage):
|
||||||
node = bs.getcollision().opposingnode
|
node = bs.getcollision().opposingnode
|
||||||
delegate = node.getdelegate(PlayerSpaz)
|
delegate = node.getdelegate(PlayerSpaz)
|
||||||
has_used_camerashake = getattr(self, 'has_used_camerashake', False)
|
has_used_camerashake = getattr(self, 'has_used_camerashake', False)
|
||||||
if not has_used_camerashake and (delegate and not delegate.shield) and not node.invincible:
|
if not has_used_camerashake and (delegate and not delegate.shield) and not node.invincible:
|
||||||
self.has_used_camerashake = True
|
self.has_used_camerashake = True
|
||||||
bs.camerashake(intensity=5.0 if self.blast_type == 'tnt' else 1.0)
|
bs.camerashake(intensity=5.0 if self.blast_type == 'tnt' else 1.0)
|
||||||
|
|
||||||
|
|
||||||
bomb.Blast.handlemessage = new_handlemessage
|
bomb.Blast.handlemessage = new_handlemessage
|
||||||
|
|
||||||
# ba_meta export babase.Plugin
|
# ba_meta export babase.Plugin
|
||||||
|
|
||||||
|
|
||||||
class Plugin(babase.Plugin):
|
class Plugin(babase.Plugin):
|
||||||
pass
|
pass
|
||||||
|
|
@ -23,8 +23,9 @@ plugman = dict(
|
||||||
version="1.0.0",
|
version="1.0.0",
|
||||||
)
|
)
|
||||||
|
|
||||||
PRINT_CHAT_MESSAGES = True # Prints chat messages to the console as "[Character's Name] Player 1/Player 2: Hello World!"
|
# Prints chat messages to the console as "[Character's Name] Player 1/Player 2: Hello World!"
|
||||||
BUBBLE_DURATION: float = 4.7 # 4.7 matches the default onscreen message duration
|
PRINT_CHAT_MESSAGES = True
|
||||||
|
BUBBLE_DURATION: float = 4.7 # 4.7 matches the default onscreen message duration
|
||||||
SPEAK_VOLUME = 1.5
|
SPEAK_VOLUME = 1.5
|
||||||
SHOUT_VOLUME = 3.0
|
SHOUT_VOLUME = 3.0
|
||||||
|
|
||||||
|
|
@ -35,13 +36,13 @@ CELEBRATE_MESSAGE = [(bs.CelebrateMessage, {"duration": 1.0})]
|
||||||
EASTER_EGGS = [
|
EASTER_EGGS = [
|
||||||
{
|
{
|
||||||
"triggers": {
|
"triggers": {
|
||||||
"hi", "hello", "hey", "hiya", "yo", "sup", "heya", "howdy",
|
"hi", "hello", "hey", "hiya", "yo", "sup", "heya", "howdy",
|
||||||
"greetings", "salutations", "ahoy", "ahoyhoy", "bonjour",
|
"greetings", "salutations", "ahoy", "ahoyhoy", "bonjour",
|
||||||
"hola", "ciao", "ola", "oi", "eae", "salve",
|
"hola", "ciao", "ola", "oi", "eae", "salve",
|
||||||
"bye", "goodbye", "see ya", "see you", "cya",
|
"bye", "goodbye", "see ya", "see you", "cya",
|
||||||
"adios", "chau", "chao", "tchau",
|
"adios", "chau", "chao", "tchau",
|
||||||
"adeus", "ate mais", "falou", "flw"
|
"adeus", "ate mais", "falou", "flw"
|
||||||
},
|
},
|
||||||
"node_messages": [("celebrate_r", 1000)],
|
"node_messages": [("celebrate_r", 1000)],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -229,6 +230,8 @@ EASTER_EGGS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
# Chat bubble functionality
|
# Chat bubble functionality
|
||||||
|
|
||||||
|
|
||||||
def create_bubble(player: bs.SessionPlayer, text: str, name: str):
|
def create_bubble(player: bs.SessionPlayer, text: str, name: str):
|
||||||
msg = normalize_message(text)
|
msg = normalize_message(text)
|
||||||
is_caps = len(text) > 1 and text.isupper()
|
is_caps = len(text) > 1 and text.isupper()
|
||||||
|
|
@ -240,11 +243,14 @@ def create_bubble(player: bs.SessionPlayer, text: str, name: str):
|
||||||
def _fallback_logic():
|
def _fallback_logic():
|
||||||
nonlocal handled, activityplayer
|
nonlocal handled, activityplayer
|
||||||
color = (1, 1, 0.4)
|
color = (1, 1, 0.4)
|
||||||
image_icon = {'texture': bs.gettexture("cuteSpaz"), 'tint_texture': bs.gettexture("cuteSpaz"), 'tint_color': (1.0, 1.0, 1.0), 'tint2_color': (1.0, 1.0, 1.0)}
|
image_icon = {'texture': bs.gettexture("cuteSpaz"), 'tint_texture': bs.gettexture(
|
||||||
|
"cuteSpaz"), 'tint_color': (1.0, 1.0, 1.0), 'tint2_color': (1.0, 1.0, 1.0)}
|
||||||
|
|
||||||
if activityplayer:
|
if activityplayer:
|
||||||
normal_highlight = bs.normalized_color( bs.safecolor(player.highlight, target_intensity=1.15) )
|
normal_highlight = bs.normalized_color(
|
||||||
saturated_highlight = bs.normalized_color( bs.safecolor(player.highlight, target_intensity=0.75) )
|
bs.safecolor(player.highlight, target_intensity=1.15))
|
||||||
|
saturated_highlight = bs.normalized_color(
|
||||||
|
bs.safecolor(player.highlight, target_intensity=0.75))
|
||||||
color = saturated_highlight if is_caps else normal_highlight
|
color = saturated_highlight if is_caps else normal_highlight
|
||||||
image_icon = activityplayer.get_icon()
|
image_icon = activityplayer.get_icon()
|
||||||
|
|
||||||
|
|
@ -312,23 +318,25 @@ def create_bubble(player: bs.SessionPlayer, text: str, name: str):
|
||||||
})
|
})
|
||||||
char_node.connectattr('torso_position', mnode, 'input2')
|
char_node.connectattr('torso_position', mnode, 'input2')
|
||||||
|
|
||||||
normal_highlight = bs.normalized_color( bs.safecolor(player.highlight, target_intensity=1.15) )
|
normal_highlight = bs.normalized_color(
|
||||||
saturated_highlight = bs.normalized_color( bs.safecolor(player.highlight, target_intensity=0.75) )
|
bs.safecolor(player.highlight, target_intensity=1.15))
|
||||||
|
saturated_highlight = bs.normalized_color(
|
||||||
|
bs.safecolor(player.highlight, target_intensity=0.75))
|
||||||
bubble_color = saturated_highlight if is_caps else normal_highlight
|
bubble_color = saturated_highlight if is_caps else normal_highlight
|
||||||
|
|
||||||
textnode = bs.newnode('text',
|
textnode = bs.newnode('text',
|
||||||
owner=char_node,
|
owner=char_node,
|
||||||
attrs={
|
attrs={
|
||||||
'text': text,
|
'text': text,
|
||||||
'color': bubble_color,
|
'color': bubble_color,
|
||||||
'shadow': 0.5,
|
'shadow': 0.5,
|
||||||
'flatness': 0.5,
|
'flatness': 0.5,
|
||||||
'scale': scale,
|
'scale': scale,
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
'v_align': 'bottom',
|
'v_align': 'bottom',
|
||||||
'in_world': True,
|
'in_world': True,
|
||||||
'opacity': 1.0,
|
'opacity': 1.0,
|
||||||
})
|
})
|
||||||
|
|
||||||
mnode.connectattr('output', textnode, 'position')
|
mnode.connectattr('output', textnode, 'position')
|
||||||
|
|
||||||
|
|
@ -366,7 +374,8 @@ def create_bubble(player: bs.SessionPlayer, text: str, name: str):
|
||||||
sound = random.choice(pickup_sounds)
|
sound = random.choice(pickup_sounds)
|
||||||
|
|
||||||
if sound:
|
if sound:
|
||||||
_play_chat_sound(actor, sound, SHOUT_VOLUME if is_caps else SPEAK_VOLUME)
|
_play_chat_sound(
|
||||||
|
actor, sound, SHOUT_VOLUME if is_caps else SPEAK_VOLUME)
|
||||||
|
|
||||||
# Animation logic
|
# Animation logic
|
||||||
if egg.get('messages') and actor.is_alive() and hasattr(actor, 'handlemessage'):
|
if egg.get('messages') and actor.is_alive() and hasattr(actor, 'handlemessage'):
|
||||||
|
|
@ -423,6 +432,7 @@ def create_bubble(player: bs.SessionPlayer, text: str, name: str):
|
||||||
_fallback_logic()
|
_fallback_logic()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def update_bubble_offsets(bubbles):
|
def update_bubble_offsets(bubbles):
|
||||||
for i, (tnode, mnode) in enumerate(reversed(bubbles)):
|
for i, (tnode, mnode) in enumerate(reversed(bubbles)):
|
||||||
y_offset = 1.2 + 0.25 * i
|
y_offset = 1.2 + 0.25 * i
|
||||||
|
|
@ -430,6 +440,8 @@ def update_bubble_offsets(bubbles):
|
||||||
mnode.input1 = (0, y_offset, 0)
|
mnode.input1 = (0, y_offset, 0)
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
|
|
||||||
|
|
||||||
def normalize_message(text):
|
def normalize_message(text):
|
||||||
msg = text.strip().lower()
|
msg = text.strip().lower()
|
||||||
msg = msg.translate(str.maketrans('', '', string.punctuation))
|
msg = msg.translate(str.maketrans('', '', string.punctuation))
|
||||||
|
|
@ -441,6 +453,8 @@ def normalize_message(text):
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
# ba_meta export babase.Plugin
|
# ba_meta export babase.Plugin
|
||||||
|
|
||||||
|
|
||||||
class Plugin(babase.Plugin):
|
class Plugin(babase.Plugin):
|
||||||
def on_app_running(self) -> None:
|
def on_app_running(self) -> None:
|
||||||
# Hook into chat message filtering
|
# Hook into chat message filtering
|
||||||
|
|
@ -451,6 +465,7 @@ class Plugin(babase.Plugin):
|
||||||
import bascenev1._hooks as _hooks
|
import bascenev1._hooks as _hooks
|
||||||
|
|
||||||
_org_filter_chat_message = _hooks.filter_chat_message
|
_org_filter_chat_message = _hooks.filter_chat_message
|
||||||
|
|
||||||
def _chat_bubbles_hook(msg: str, client_id: int, *args, **kwargs) -> str | None:
|
def _chat_bubbles_hook(msg: str, client_id: int, *args, **kwargs) -> str | None:
|
||||||
org_msg = _org_filter_chat_message(msg, client_id, *args, **kwargs)
|
org_msg = _org_filter_chat_message(msg, client_id, *args, **kwargs)
|
||||||
|
|
||||||
|
|
@ -478,42 +493,43 @@ class Plugin(babase.Plugin):
|
||||||
player_list.append(player)
|
player_list.append(player)
|
||||||
continue
|
continue
|
||||||
if player_list:
|
if player_list:
|
||||||
# Get combined name for multiple players on same client
|
# Get combined name for multiple players on same client
|
||||||
name = ''
|
name = ''
|
||||||
created_bubble = False
|
created_bubble = False
|
||||||
|
|
||||||
for player in player_list:
|
for player in player_list:
|
||||||
if name == '':
|
if name == '':
|
||||||
name = player.getname()
|
name = player.getname()
|
||||||
else:
|
else:
|
||||||
name = name + '/' + player.getname()
|
name = name + '/' + player.getname()
|
||||||
|
|
||||||
# Create chat bubble
|
# Create chat bubble
|
||||||
for player in player_list:
|
for player in player_list:
|
||||||
activityplayer: bs.Player = player.activityplayer
|
activityplayer: bs.Player = player.activityplayer
|
||||||
# We have a session player but not an activity player
|
# We have a session player but not an activity player
|
||||||
if not activityplayer:
|
if not activityplayer:
|
||||||
if not dead_bubble:
|
if not dead_bubble:
|
||||||
create_bubble(player, org_msg, name)
|
|
||||||
created_bubble = dead_bubble = True
|
|
||||||
continue
|
|
||||||
# We have a dead activity player
|
|
||||||
if not activityplayer.is_alive() and not dead_bubble:
|
|
||||||
create_bubble(player, org_msg, name)
|
create_bubble(player, org_msg, name)
|
||||||
created_bubble = dead_bubble = True
|
created_bubble = dead_bubble = True
|
||||||
character = activityplayer.character if character is None else character
|
continue
|
||||||
# elif we have an alive activity player
|
# We have a dead activity player
|
||||||
elif activityplayer.is_alive():
|
if not activityplayer.is_alive() and not dead_bubble:
|
||||||
create_bubble(player, org_msg, name)
|
create_bubble(player, org_msg, name)
|
||||||
created_bubble = True
|
created_bubble = dead_bubble = True
|
||||||
character = activityplayer.character if character is None else character
|
character = activityplayer.character if character is None else character
|
||||||
|
# elif we have an alive activity player
|
||||||
|
elif activityplayer.is_alive():
|
||||||
|
create_bubble(player, org_msg, name)
|
||||||
|
created_bubble = True
|
||||||
|
character = activityplayer.character if character is None else character
|
||||||
|
|
||||||
if created_bubble:
|
if created_bubble:
|
||||||
matched = True
|
matched = True
|
||||||
if PRINT_CHAT_MESSAGES:
|
if PRINT_CHAT_MESSAGES:
|
||||||
print(f"[{character}] {name}: {org_msg}")
|
print(f"[{character}] {name}: {org_msg}")
|
||||||
else:
|
else:
|
||||||
bs.logging.warning("Failed to create a chat bubble, using non-session player method now.")
|
bs.logging.warning(
|
||||||
|
"Failed to create a chat bubble, using non-session player method now.")
|
||||||
# Non-session players (in lobby or just spectating, this only works for servers)
|
# Non-session players (in lobby or just spectating, this only works for servers)
|
||||||
if not matched and not dead_bubble:
|
if not matched and not dead_bubble:
|
||||||
for client in roster:
|
for client in roster:
|
||||||
|
|
@ -537,40 +553,41 @@ class Plugin(babase.Plugin):
|
||||||
|
|
||||||
class Focus(bs.Actor):
|
class Focus(bs.Actor):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
owner: bs.Node | None = None,
|
owner: bs.Node | None = None,
|
||||||
):
|
):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self._focusnode_material = bs.Material()
|
self._focusnode_material = bs.Material()
|
||||||
self._focusnode_material.add_actions(
|
self._focusnode_material.add_actions(
|
||||||
actions=('modify_node_collision', 'collide', False),
|
actions=('modify_node_collision', 'collide', False),
|
||||||
)
|
)
|
||||||
|
|
||||||
if getattr(owner, 'owner', None):
|
if getattr(owner, 'owner', None):
|
||||||
assert owner is not None
|
assert owner is not None
|
||||||
area_of_interest = False if getattr(owner.owner, 'is_area_of_interest', False) else True
|
area_of_interest = False if getattr(
|
||||||
|
owner.owner, 'is_area_of_interest', False) else True
|
||||||
else:
|
else:
|
||||||
area_of_interest = False if getattr(owner, 'is_area_of_interest', False) else True
|
area_of_interest = False if getattr(owner, 'is_area_of_interest', False) else True
|
||||||
|
|
||||||
# I'm tired of this area_of_interest nonsense, it never works right
|
# I'm tired of this area_of_interest nonsense, it never works right
|
||||||
#area_of_interest = False
|
# area_of_interest = False
|
||||||
# actually it might work now that we don't spawn bubbles for dead players.
|
# actually it might work now that we don't spawn bubbles for dead players.
|
||||||
|
|
||||||
self.node = bs.newnode(
|
self.node = bs.newnode(
|
||||||
'prop',
|
'prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
owner=owner,
|
owner=owner,
|
||||||
attrs={
|
attrs={
|
||||||
'body': 'sphere',
|
'body': 'sphere',
|
||||||
'body_scale': 0.0,
|
'body_scale': 0.0,
|
||||||
'shadow_size': 0.0,
|
'shadow_size': 0.0,
|
||||||
'gravity_scale': 0.0,
|
'gravity_scale': 0.0,
|
||||||
'is_area_of_interest': area_of_interest,
|
'is_area_of_interest': area_of_interest,
|
||||||
'materials': (self._focusnode_material,),
|
'materials': (self._focusnode_material,),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
|
|
|
||||||
|
|
@ -25,92 +25,95 @@ plugman = dict(
|
||||||
|
|
||||||
# Transparent Background (kinda hacky, works best on pc with high/higher quality 'visuals' setting)
|
# Transparent Background (kinda hacky, works best on pc with high/higher quality 'visuals' setting)
|
||||||
BACKGROUND_OPACITY = 0.5
|
BACKGROUND_OPACITY = 0.5
|
||||||
|
|
||||||
|
|
||||||
def __modified_background_init(
|
def __modified_background_init(
|
||||||
self,
|
self,
|
||||||
fade_time: float = 0.5,
|
fade_time: float = 0.5,
|
||||||
start_faded: bool = False,
|
start_faded: bool = False,
|
||||||
show_logo: bool = False,
|
show_logo: bool = False,
|
||||||
):
|
):
|
||||||
super(type(self), self).__init__()
|
super(type(self), self).__init__()
|
||||||
self._dying = False
|
self._dying = False
|
||||||
self.fade_time = fade_time
|
self.fade_time = fade_time
|
||||||
# We're special in that we create our node in the session
|
# We're special in that we create our node in the session
|
||||||
# scene instead of the activity scene.
|
# scene instead of the activity scene.
|
||||||
# This way we can overlap multiple activities for fades
|
# This way we can overlap multiple activities for fades
|
||||||
# and whatnot.
|
# and whatnot.
|
||||||
session = bs.getsession()
|
session = bs.getsession()
|
||||||
self._session = weakref.ref(session)
|
self._session = weakref.ref(session)
|
||||||
with session.context:
|
with session.context:
|
||||||
self.node = bs.newnode(
|
self.node = bs.newnode(
|
||||||
|
'image',
|
||||||
|
delegate=self,
|
||||||
|
attrs={
|
||||||
|
'fill_screen': True,
|
||||||
|
'texture': bs.gettexture('bg'),
|
||||||
|
'tilt_translate': -0.3,
|
||||||
|
'has_alpha_channel': False,
|
||||||
|
'color': (1, 1, 1),
|
||||||
|
'opacity': BACKGROUND_OPACITY,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if not start_faded:
|
||||||
|
bs.animate(
|
||||||
|
self.node,
|
||||||
|
'opacity',
|
||||||
|
{0.0: 0.0, self.fade_time: BACKGROUND_OPACITY},
|
||||||
|
loop=False,
|
||||||
|
)
|
||||||
|
if show_logo:
|
||||||
|
logo_texture = bs.gettexture('logo')
|
||||||
|
logo_mesh = bs.getmesh('logo')
|
||||||
|
logo_mesh_transparent = bs.getmesh('logoTransparent')
|
||||||
|
self.logo = bs.newnode(
|
||||||
'image',
|
'image',
|
||||||
delegate=self,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'fill_screen': True,
|
'texture': logo_texture,
|
||||||
'texture': bs.gettexture('bg'),
|
'mesh_opaque': logo_mesh,
|
||||||
'tilt_translate': -0.3,
|
'mesh_transparent': logo_mesh_transparent,
|
||||||
'has_alpha_channel': False,
|
'scale': (0.7, 0.7),
|
||||||
'color': (1, 1, 1),
|
'vr_depth': -250,
|
||||||
'opacity': BACKGROUND_OPACITY,
|
'color': (0.15, 0.15, 0.15),
|
||||||
|
'position': (0, 0),
|
||||||
|
'tilt_translate': -0.05,
|
||||||
|
'absolute_scale': False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if not start_faded:
|
self.node.connectattr('opacity', self.logo, 'opacity')
|
||||||
bs.animate(
|
# add jitter/pulse for a stop-motion-y look unless we're in VR
|
||||||
self.node,
|
# in which case stillness is better
|
||||||
'opacity',
|
if not bs.app.env.vr:
|
||||||
{0.0: 0.0, self.fade_time: BACKGROUND_OPACITY},
|
self.cmb = bs.newnode(
|
||||||
loop=False,
|
'combine', owner=self.node, attrs={'size': 2}
|
||||||
)
|
)
|
||||||
if show_logo:
|
for attr in ['input0', 'input1']:
|
||||||
logo_texture = bs.gettexture('logo')
|
bs.animate(
|
||||||
logo_mesh = bs.getmesh('logo')
|
self.cmb,
|
||||||
logo_mesh_transparent = bs.getmesh('logoTransparent')
|
attr,
|
||||||
self.logo = bs.newnode(
|
{0.0: 0.693, 0.05: 0.7, 0.5: 0.693},
|
||||||
'image',
|
loop=True,
|
||||||
owner=self.node,
|
)
|
||||||
attrs={
|
self.cmb.connectattr('output', self.logo, 'scale')
|
||||||
'texture': logo_texture,
|
cmb = bs.newnode(
|
||||||
'mesh_opaque': logo_mesh,
|
'combine', owner=self.node, attrs={'size': 2}
|
||||||
'mesh_transparent': logo_mesh_transparent,
|
|
||||||
'scale': (0.7, 0.7),
|
|
||||||
'vr_depth': -250,
|
|
||||||
'color': (0.15, 0.15, 0.15),
|
|
||||||
'position': (0, 0),
|
|
||||||
'tilt_translate': -0.05,
|
|
||||||
'absolute_scale': False,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
self.node.connectattr('opacity', self.logo, 'opacity')
|
cmb.connectattr('output', self.logo, 'position')
|
||||||
# add jitter/pulse for a stop-motion-y look unless we're in VR
|
# Gen some random keys for that stop-motion-y look.
|
||||||
# in which case stillness is better
|
keys = {}
|
||||||
if not bs.app.env.vr:
|
timeval = 0.0
|
||||||
self.cmb = bs.newnode(
|
for _i in range(10):
|
||||||
'combine', owner=self.node, attrs={'size': 2}
|
keys[timeval] = (random.random() - 0.5) * 0.0015
|
||||||
)
|
timeval += random.random() * 0.1
|
||||||
for attr in ['input0', 'input1']:
|
bs.animate(cmb, 'input0', keys, loop=True)
|
||||||
bs.animate(
|
keys = {}
|
||||||
self.cmb,
|
timeval = 0.0
|
||||||
attr,
|
for _i in range(10):
|
||||||
{0.0: 0.693, 0.05: 0.7, 0.5: 0.693},
|
keys[timeval] = (random.random() - 0.5) * 0.0015 + 0.05
|
||||||
loop=True,
|
timeval += random.random() * 0.1
|
||||||
)
|
bs.animate(cmb, 'input1', keys, loop=True)
|
||||||
self.cmb.connectattr('output', self.logo, 'scale')
|
|
||||||
cmb = bs.newnode(
|
|
||||||
'combine', owner=self.node, attrs={'size': 2}
|
|
||||||
)
|
|
||||||
cmb.connectattr('output', self.logo, 'position')
|
|
||||||
# Gen some random keys for that stop-motion-y look.
|
|
||||||
keys = {}
|
|
||||||
timeval = 0.0
|
|
||||||
for _i in range(10):
|
|
||||||
keys[timeval] = (random.random() - 0.5) * 0.0015
|
|
||||||
timeval += random.random() * 0.1
|
|
||||||
bs.animate(cmb, 'input0', keys, loop=True)
|
|
||||||
keys = {}
|
|
||||||
timeval = 0.0
|
|
||||||
for _i in range(10):
|
|
||||||
keys[timeval] = (random.random() - 0.5) * 0.0015 + 0.05
|
|
||||||
timeval += random.random() * 0.1
|
|
||||||
bs.animate(cmb, 'input1', keys, loop=True)
|
|
||||||
|
|
||||||
def _modified_background_die(self, immediate: bool = False) -> None:
|
def _modified_background_die(self, immediate: bool = False) -> None:
|
||||||
session = self._session()
|
session = self._session()
|
||||||
|
|
@ -138,10 +141,13 @@ def _modified_background_die(self, immediate: bool = False) -> None:
|
||||||
)
|
)
|
||||||
bs.timer(self.fade_time + 0.1, self.node.delete)
|
bs.timer(self.fade_time + 0.1, self.node.delete)
|
||||||
|
|
||||||
|
|
||||||
Background.__init__ = __modified_background_init
|
Background.__init__ = __modified_background_init
|
||||||
Background._die = _modified_background_die
|
Background._die = _modified_background_die
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
|
|
||||||
|
|
||||||
def blend_toward(
|
def blend_toward(
|
||||||
rgb: tuple[float, float, float],
|
rgb: tuple[float, float, float],
|
||||||
target: tuple[float, float, float],
|
target: tuple[float, float, float],
|
||||||
|
|
@ -177,6 +183,8 @@ def blend_toward(
|
||||||
return tuple(clamp01(linear_to_srgb(c)) for c in blended_lin)
|
return tuple(clamp01(linear_to_srgb(c)) for c in blended_lin)
|
||||||
|
|
||||||
# ba_meta export babase.Plugin
|
# ba_meta export babase.Plugin
|
||||||
|
|
||||||
|
|
||||||
class Plugin(babase.Plugin):
|
class Plugin(babase.Plugin):
|
||||||
def on_app_running(self) -> None:
|
def on_app_running(self) -> None:
|
||||||
from bascenev1lib.actor.bomb import Blast, ExplodeHitMessage
|
from bascenev1lib.actor.bomb import Blast, ExplodeHitMessage
|
||||||
|
|
@ -190,7 +198,8 @@ class Plugin(babase.Plugin):
|
||||||
def equip_shields(self, decay: bool = False) -> None:
|
def equip_shields(self, decay: bool = False) -> None:
|
||||||
org_equip_shields(self, decay)
|
org_equip_shields(self, decay)
|
||||||
if self.shield is not None:
|
if self.shield is not None:
|
||||||
safe_highlight = bs.safecolor(getattr(self, '_original_highlight', self.node.highlight), target_intensity=0.75)
|
safe_highlight = bs.safecolor(
|
||||||
|
getattr(self, '_original_highlight', self.node.highlight), target_intensity=0.75)
|
||||||
self.shield.color = bs.normalized_color(safe_highlight)
|
self.shield.color = bs.normalized_color(safe_highlight)
|
||||||
|
|
||||||
Spaz.equip_shields = equip_shields
|
Spaz.equip_shields = equip_shields
|
||||||
|
|
@ -208,7 +217,8 @@ class Plugin(babase.Plugin):
|
||||||
|
|
||||||
# Pause
|
# Pause
|
||||||
gnode.paused = True
|
gnode.paused = True
|
||||||
self._pause_timer = bs.DisplayTimer(0.01, bs.CallPartial(setattr, gnode, 'paused', True), True)
|
self._pause_timer = bs.DisplayTimer(
|
||||||
|
0.01, bs.CallPartial(setattr, gnode, 'paused', True), True)
|
||||||
|
|
||||||
delay = 0.06
|
delay = 0.06
|
||||||
|
|
||||||
|
|
@ -217,12 +227,14 @@ class Plugin(babase.Plugin):
|
||||||
|
|
||||||
# Slow Motion
|
# Slow Motion
|
||||||
gnode.slow_motion = True
|
gnode.slow_motion = True
|
||||||
self._slow_motion_timer = bs.DisplayTimer(0.01, bs.CallPartial(setattr, gnode, 'slow_motion', True), True)
|
self._slow_motion_timer = bs.DisplayTimer(
|
||||||
|
0.01, bs.CallPartial(setattr, gnode, 'slow_motion', True), True)
|
||||||
|
|
||||||
delay += 0.14
|
delay += 0.14
|
||||||
|
|
||||||
bs.displaytimer(delay, bs.CallPartial(setattr, self, '_slow_motion_timer', None))
|
bs.displaytimer(delay, bs.CallPartial(setattr, self, '_slow_motion_timer', None))
|
||||||
bs.displaytimer(delay, bs.CallPartial(setattr, gnode, 'slow_motion', activity.slow_motion))
|
bs.displaytimer(delay, bs.CallPartial(
|
||||||
|
setattr, gnode, 'slow_motion', activity.slow_motion))
|
||||||
|
|
||||||
Blast.__init__ = new_init
|
Blast.__init__ = new_init
|
||||||
|
|
||||||
|
|
@ -233,58 +245,61 @@ class Plugin(babase.Plugin):
|
||||||
org_handlemessage(self, msg, *args, **kwargs)
|
org_handlemessage(self, msg, *args, **kwargs)
|
||||||
|
|
||||||
if isinstance(msg, ExplodeHitMessage):
|
if isinstance(msg, ExplodeHitMessage):
|
||||||
node = bs.getcollision().opposingnode
|
node = bs.getcollision().opposingnode
|
||||||
delegate = node.getdelegate(PlayerSpaz) or node.getdelegate(SpazBot)
|
delegate = node.getdelegate(PlayerSpaz) or node.getdelegate(SpazBot)
|
||||||
if (delegate and not delegate.shield) and not node.invincible:
|
if (delegate and not delegate.shield) and not node.invincible:
|
||||||
if not hasattr(delegate, '_original_color'):
|
if not hasattr(delegate, '_original_color'):
|
||||||
delegate._original_color = node.color
|
delegate._original_color = node.color
|
||||||
delegate._original_highlight = node.highlight
|
delegate._original_highlight = node.highlight
|
||||||
|
|
||||||
original_color = delegate._original_color
|
original_color = delegate._original_color
|
||||||
original_highlight = delegate._original_highlight
|
original_highlight = delegate._original_highlight
|
||||||
|
|
||||||
|
blend_time = 1.0
|
||||||
|
start_time = 6.0
|
||||||
|
end_time = 7.0
|
||||||
|
|
||||||
|
bs.emitfx(
|
||||||
|
position=node.position,
|
||||||
|
velocity=node.velocity,
|
||||||
|
count=int(4.0 + random.random() * 4),
|
||||||
|
emit_type='tendrils',
|
||||||
|
tendril_type='ice' if self.blast_type == 'ice' else 'smoke',
|
||||||
|
)
|
||||||
|
|
||||||
|
explosion_intensity = 0.70 if not self.blast_type == 'tnt' else 0.96
|
||||||
|
|
||||||
|
if self.blast_type == 'ice':
|
||||||
|
explosion_intensity = 0.91
|
||||||
|
explosion_color = (0.07, 0.6, 1.5)
|
||||||
|
elif self.blast_type == 'sticky':
|
||||||
|
explosion_intensity = 0.91
|
||||||
|
explosion_color = (0.07, 0.9, 0.07)
|
||||||
blend_time = 1.0
|
blend_time = 1.0
|
||||||
start_time = 6.0
|
start_time = 1.2
|
||||||
end_time = 7.0
|
end_time = 3.0
|
||||||
|
else:
|
||||||
|
explosion_color = (0.07, 0.03, 0.0)
|
||||||
|
|
||||||
bs.emitfx(
|
blend_color = blend_toward(node.color, explosion_color,
|
||||||
position=node.position,
|
explosion_intensity, True)
|
||||||
velocity=node.velocity,
|
blend_highlight = blend_toward(
|
||||||
count=int(4.0 + random.random() * 4),
|
node.highlight, explosion_color, explosion_intensity-0.03, True)
|
||||||
emit_type='tendrils',
|
|
||||||
tendril_type='ice' if self.blast_type == 'ice' else 'smoke',
|
|
||||||
)
|
|
||||||
|
|
||||||
explosion_intensity = 0.70 if not self.blast_type == 'tnt' else 0.96
|
bs.animate_array(node, 'color', 3, {
|
||||||
|
blend_time: blend_color,
|
||||||
|
start_time: blend_color,
|
||||||
|
end_time: original_color
|
||||||
|
})
|
||||||
|
bs.animate_array(node, 'highlight', 3, {
|
||||||
|
blend_time: blend_highlight,
|
||||||
|
start_time: blend_highlight,
|
||||||
|
end_time: original_highlight
|
||||||
|
})
|
||||||
|
|
||||||
if self.blast_type == 'ice':
|
delegate._color_timer = bs.Timer(
|
||||||
explosion_intensity = 0.91
|
end_time, bs.CallPartial(delattr, delegate, '_original_color'))
|
||||||
explosion_color = (0.07, 0.6, 1.5)
|
delegate._highlight_timer = bs.Timer(
|
||||||
elif self.blast_type == 'sticky':
|
end_time, bs.CallPartial(delattr, delegate, '_original_highlight'))
|
||||||
explosion_intensity = 0.91
|
|
||||||
explosion_color = (0.07, 0.9, 0.07)
|
|
||||||
blend_time = 1.0
|
|
||||||
start_time = 1.2
|
|
||||||
end_time = 3.0
|
|
||||||
else:
|
|
||||||
explosion_color = (0.07, 0.03, 0.0)
|
|
||||||
|
|
||||||
|
|
||||||
blend_color = blend_toward(node.color, explosion_color, explosion_intensity, True)
|
|
||||||
blend_highlight = blend_toward(node.highlight, explosion_color, explosion_intensity-0.03, True)
|
|
||||||
|
|
||||||
bs.animate_array(node, 'color', 3, {
|
|
||||||
blend_time: blend_color,
|
|
||||||
start_time: blend_color,
|
|
||||||
end_time: original_color
|
|
||||||
})
|
|
||||||
bs.animate_array(node, 'highlight', 3, {
|
|
||||||
blend_time: blend_highlight,
|
|
||||||
start_time: blend_highlight,
|
|
||||||
end_time: original_highlight
|
|
||||||
})
|
|
||||||
|
|
||||||
delegate._color_timer = bs.Timer(end_time, bs.CallPartial(delattr, delegate, '_original_color'))
|
|
||||||
delegate._highlight_timer = bs.Timer(end_time, bs.CallPartial(delattr, delegate, '_original_highlight'))
|
|
||||||
|
|
||||||
Blast.handlemessage = new_handlemessage
|
Blast.handlemessage = new_handlemessage
|
||||||
|
|
@ -16,27 +16,34 @@ plugman = dict(
|
||||||
version="1.0.0",
|
version="1.0.0",
|
||||||
)
|
)
|
||||||
|
|
||||||
INGAME_TIME = 40 # (in seconds)
|
INGAME_TIME = 40 # (in seconds)
|
||||||
|
|
||||||
# Spaz Changes
|
# Spaz Changes
|
||||||
|
|
||||||
|
|
||||||
def _afk_sleep_knockout(self, value: float) -> None:
|
def _afk_sleep_knockout(self, value: float) -> None:
|
||||||
if not self.node:
|
if not self.node:
|
||||||
return
|
return
|
||||||
if not self.is_alive() and hasattr(self.getplayer(self), 'sessionplayer'):
|
if not self.is_alive() and hasattr(self.getplayer(self), 'sessionplayer'):
|
||||||
current_activity = self.getactivity()
|
current_activity = self.getactivity()
|
||||||
player = self.getplayer(self).sessionplayer
|
player = self.getplayer(self).sessionplayer
|
||||||
#Pop timer data if the player is dead
|
# Pop timer data if the player is dead
|
||||||
if current_activity.customdata.get(str(player.id) +'_knockoutTimer') is not None:
|
if current_activity.customdata.get(str(player.id) + '_knockoutTimer') is not None:
|
||||||
current_activity.customdata.pop(str(player.id) +'_knockoutTimer')
|
current_activity.customdata.pop(str(player.id) + '_knockoutTimer')
|
||||||
return
|
return
|
||||||
|
|
||||||
self.node.handlemessage('knockout', value)
|
self.node.handlemessage('knockout', value)
|
||||||
|
|
||||||
Spaz._afk_sleep_knockout = _afk_sleep_knockout # type: ignore
|
|
||||||
|
Spaz._afk_sleep_knockout = _afk_sleep_knockout # type: ignore
|
||||||
|
|
||||||
# Idle Checker
|
# Idle Checker
|
||||||
|
|
||||||
|
|
||||||
def idle_start(activity: bs.Activity):
|
def idle_start(activity: bs.Activity):
|
||||||
activity.customdata['afk_timer'] = bs.Timer(0.5, bs.CallStrict(idle_check, activity), repeat=True)
|
activity.customdata['afk_timer'] = bs.Timer(
|
||||||
|
0.5, bs.CallStrict(idle_check, activity), repeat=True)
|
||||||
|
|
||||||
|
|
||||||
def idle_check(current_activity: bs.Activity):
|
def idle_check(current_activity: bs.Activity):
|
||||||
current_session = current_activity.session
|
current_session = current_activity.session
|
||||||
|
|
@ -66,22 +73,24 @@ def idle_check(current_activity: bs.Activity):
|
||||||
if player_node.move_up_down != 0.0 or player_node.move_left_right != 0.0:
|
if player_node.move_up_down != 0.0 or player_node.move_left_right != 0.0:
|
||||||
player_data['last_input'] = current
|
player_data['last_input'] = current
|
||||||
elif player_turbo_times:
|
elif player_turbo_times:
|
||||||
highest_turbo_time = player_turbo_times.get(max(player_turbo_times, key=player_turbo_times.get))
|
highest_turbo_time = player_turbo_times.get(
|
||||||
|
max(player_turbo_times, key=player_turbo_times.get))
|
||||||
if highest_turbo_time > player_data.get('last_input', current):
|
if highest_turbo_time > player_data.get('last_input', current):
|
||||||
player_data.update({'last_input': highest_turbo_time })
|
player_data.update({'last_input': highest_turbo_time})
|
||||||
player_data['last_input'] = player_data.get('last_input', current)
|
player_data['last_input'] = player_data.get('last_input', current)
|
||||||
|
|
||||||
last_input = max(0, player_data['last_input'])
|
last_input = max(0, player_data['last_input'])
|
||||||
afk_time = int((current - last_input) / 1000)
|
afk_time = int((current - last_input) / 1000)
|
||||||
|
|
||||||
#print(player_data)
|
# print(player_data)
|
||||||
#print(last_input)
|
# print(last_input)
|
||||||
#print(current)
|
# print(current)
|
||||||
#print(player.getname() + ": " + str(afk_time))
|
# print(player.getname() + ": " + str(afk_time))
|
||||||
#print(wait_time)
|
# print(wait_time)
|
||||||
|
|
||||||
if afk_time >= wait_time:
|
if afk_time >= wait_time:
|
||||||
current_activity.customdata[str(player.id) +'_knockoutTimer'] = bs.Timer(0.1, bs.WeakCallStrict(player_actor._afk_sleep_knockout, 100.0), repeat=True)
|
current_activity.customdata[str(player.id) + '_knockoutTimer'] = bs.Timer(
|
||||||
|
0.1, bs.WeakCallStrict(player_actor._afk_sleep_knockout, 100.0), repeat=True)
|
||||||
|
|
||||||
# Make the player's node not an area of interest if it was one
|
# Make the player's node not an area of interest if it was one
|
||||||
if not getattr(player_actor, '_previous_is_area_of_interest', False):
|
if not getattr(player_actor, '_previous_is_area_of_interest', False):
|
||||||
|
|
@ -90,8 +99,8 @@ def idle_check(current_activity: bs.Activity):
|
||||||
if player_actor._previous_is_area_of_interest:
|
if player_actor._previous_is_area_of_interest:
|
||||||
player_node.is_area_of_interest = False
|
player_node.is_area_of_interest = False
|
||||||
|
|
||||||
elif current_activity.customdata.get(str(player.id) +'_knockoutTimer') is not None:
|
elif current_activity.customdata.get(str(player.id) + '_knockoutTimer') is not None:
|
||||||
current_activity.customdata.pop(str(player.id) +'_knockoutTimer')
|
current_activity.customdata.pop(str(player.id) + '_knockoutTimer')
|
||||||
|
|
||||||
# Restore the player's node area of interest if necessary
|
# Restore the player's node area of interest if necessary
|
||||||
if getattr(player_actor, '_previous_is_area_of_interest', False):
|
if getattr(player_actor, '_previous_is_area_of_interest', False):
|
||||||
|
|
@ -100,17 +109,21 @@ def idle_check(current_activity: bs.Activity):
|
||||||
if hasattr(player_actor, "_previous_is_area_of_interest"):
|
if hasattr(player_actor, "_previous_is_area_of_interest"):
|
||||||
delattr(player_actor, "_previous_is_area_of_interest")
|
delattr(player_actor, "_previous_is_area_of_interest")
|
||||||
|
|
||||||
|
|
||||||
# Setup new activity
|
# Setup new activity
|
||||||
org_on_begin = bs.Activity.on_begin
|
org_on_begin = bs.Activity.on_begin
|
||||||
|
|
||||||
|
|
||||||
def patched_on_begin(self, *args, **kwargs):
|
def patched_on_begin(self, *args, **kwargs):
|
||||||
idle_start(self)
|
idle_start(self)
|
||||||
|
|
||||||
return org_on_begin(self, *args, **kwargs)
|
return org_on_begin(self, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
bs.Activity.on_begin = patched_on_begin
|
bs.Activity.on_begin = patched_on_begin
|
||||||
|
|
||||||
# ba_meta export babase.Plugin
|
# ba_meta export babase.Plugin
|
||||||
|
|
||||||
|
|
||||||
class Plugin(babase.Plugin):
|
class Plugin(babase.Plugin):
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue