def __init__(self, position=(0, 5, 0), direction=(0, 2, 0), source_player=None, owner=None, color=(1, 1, 1)) -> None: super().__init__() self._color = color self.node = ba.newnode('light', delegate=self, attrs={ 'position': position, 'color': self._color }) ba.animate(self.node, 'radius', {0: 0, 0.1: 0.5, 0.5: 0}) self.source_player = source_player self.owner = owner self._life_timer = ba.Timer( 0.5, ba.WeakCall(self.handlemessage, ba.DieMessage())) pos = position vel = tuple(i / 5 for i in ba.Vec3(direction).normalized()) for _ in range(500): # Optimization :( ba.newnode('explosion', owner=self.node, attrs={ 'position': pos, 'radius': 0.2, 'color': self._color }) pos = (pos[0] + vel[0], pos[1] + vel[1], pos[2] + vel[2]) for node in _ba.getnodes(): if node and node.getnodetype() == 'spaz': # pylint: disable=invalid-name m3 = ba.Vec3(position) a = ba.Vec3(direction[2], direction[1], direction[0]) m1 = ba.Vec3(node.position) # pylint: enable=invalid-name # distance between node and line dist = (a * (m1 - m3)).length() / a.length() if dist < 0.3: if node and node != self.owner and node.getdelegate( PlayerSpaz, True).getplayer( ba.Player, True).team != self.owner.team: node.handlemessage(ba.FreezeMessage()) pos = self.node.position hit_dir = (0, 10, 0) node.handlemessage( ba.HitMessage(pos=pos, magnitude=50, velocity_magnitude=50, radius=0, srcnode=self.node, source_player=self.source_player, force_direction=hit_dir))
def handlemessage(self, msg: Any) -> Any: if __debug__: self._handlemessage_sanity_check() if isinstance(msg, ba.DieMessage): if self.node: self.node.delete() elif isinstance(msg, ExplodeHitMessage): node = ba.get_collision_info('opposing_node') if node: assert self.node nodepos = self.node.position # new mag = 2000.0 if self.blast_type == 'ice': mag *= 0.5 elif self.blast_type == 'land_mine': mag *= 2.5 elif self.blast_type == 'tnt': mag *= 2.0 node.handlemessage( ba.HitMessage(pos=nodepos, velocity=(0, 0, 0), magnitude=mag, hit_type=self.hit_type, hit_subtype=self.hit_subtype, radius=self.radius, source_player=ba.existing( self.source_player))) if self.blast_type == 'ice': ba.playsound(get_factory().freeze_sound, 10, position=nodepos) node.handlemessage(ba.FreezeMessage()) else: super().handlemessage(msg)
def handlemessage(self, msg: Any) -> Any: assert not self.expired if isinstance(msg, ba.DieMessage): if self.node: self.node.delete() elif isinstance(msg, ExplodeHitMessage): node = ba.getcollision().opposingnode assert self.node nodepos = self.node.position mag = 2000.0 if self.blast_type == 'ice': mag *= 0.5 elif self.blast_type == 'land_mine': mag *= 2.5 elif self.blast_type == 'tnt': mag *= 2.0 node.handlemessage( ba.HitMessage(pos=nodepos, velocity=(0, 0, 0), magnitude=mag, hit_type=self.hit_type, hit_subtype=self.hit_subtype, radius=self.radius, source_player=ba.existing(self._source_player))) if self.blast_type == 'ice': ba.playsound(BombFactory.get().freeze_sound, 10, position=nodepos) node.handlemessage(ba.FreezeMessage()) else: return super().handlemessage(msg) return None