extends Node enum TEAMS { DEFENCE, ATTACK, SPECTATE, UNASSIGNED } const ATTACK_LAYER: int = 0b10000 const DEFENCE_LAYER: int = 0b100000 var player_nodes: Dictionary[int,Player] = {} var dynamic_objects_spawner: MultiplayerSpawner var plants: Array[PlantSite] var plant_deadzones: Dictionary[StringName, Area3D] ## Spawns dynamic object at game scene [br] ## Dictionary keys: [br] ## (Required) scene - path/uuid to scene [br] ## (Optional) position - position to spawn [br] ## (Optional) impulse - impulse to apply [br] ## (Optional but required for each other) [br] ## ammo, remaining_ammo, slot - data for dropped weapon [br] ## for more, see dyn_objects_spawner.gd func spawn(data: Dictionary) -> void: spawn_internal.rpc_id(1,data) @rpc("any_peer","call_local","reliable") func spawn_internal(data: Dictionary) -> void: if multiplayer.is_server() == false: printerr(str(multiplayer.get_remote_sender_id())+" tried to spawn internally on "+str(multiplayer.get_unique_id())) return var object = dynamic_objects_spawner.spawn(data) if data.has("position"): object.global_position = data.position func despawn(path: NodePath): despawn_internal.rpc_id(1,path) @rpc("any_peer","call_local","reliable") func despawn_internal(path: NodePath) -> void: if multiplayer.is_server() == false: printerr(str(multiplayer.get_remote_sender_id())+" tried to despawn internally on "+str(multiplayer.get_unique_id())) return get_node(path).queue_free() func shoot(damage: int) -> void: if multiplayer.get_unique_id() == 1: shoot_internal(1,damage) else: shoot_internal.rpc_id(1,multiplayer.get_unique_id(),damage) @rpc("any_peer","call_local","reliable") func shoot_internal(id:int , damage: int) -> void: if multiplayer.is_server() == false: return var player: Player = player_nodes[id] var player_camera: Camera3D = player.get_node("Camera3D") var space: PhysicsDirectSpaceState3D = player.get_world_3d().direct_space_state var endpoint: Vector3 = player_camera.global_position - player_camera.global_basis.z * 100 var ray = PhysicsRayQueryParameters3D.create(player_camera.global_position,endpoint,1) ray.exclude = [player.get_rid()] ray.collide_with_areas = false match player.team: TEAMS.DEFENCE: ray.collision_mask |= ATTACK_LAYER TEAMS.ATTACK: ray.collision_mask |= DEFENCE_LAYER _: ray.collision_mask |= ATTACK_LAYER | DEFENCE_LAYER var collision = space.intersect_ray(ray) if collision != {} and collision["collider"] is Player: collision["collider"].take_damage.rpc_id(int(collision["collider"].name),damage) func is_on_site() -> bool: for plant in plants: if plant.is_player_on_site(multiplayer.get_unique_id()): return true return false func get_site() -> PlantSite: for plant in plants: if plant.is_player_on_site(multiplayer.get_unique_id()): return plant return null func kill_site(site: StringName) -> void: if multiplayer.is_server() == false: return for body in plant_deadzones[site].get_overlapping_bodies(): if body is Player: body.kill_request.rpc()