├── icon.png ├── remap_files.rar ├── bannedimplant.png ├── models ├── online.glb ├── intro_guy.glb ├── Material.material ├── Phone_mat.material ├── glasses.material ├── basement_blades.glb ├── Phone_screen.material ├── Nude_Material_001.material ├── Nude_Material001_001.material ├── weapon_spawner.mtl └── weapon_spawner.obj.import ├── target_white.png ├── crus_online_logo.png ├── maps ├── greyface1.png ├── greyface2.png ├── greyface1.png.import ├── greyface2.png.import ├── Benchmark.gd ├── benchmark.tscn └── look.tres ├── sadbannedimplant.png ├── maps_stuff ├── respawn_point.tscn └── WeaponSpawner.gd ├── WIKI.md ├── remaped ├── Tutorial_Exit.gd ├── killbox.gd ├── Message_Area.gd ├── Special_Destroy.gd ├── Radiation.gd ├── garbage_destroyer.gd ├── Rotator_Y_Spatial.gd ├── Rotator_Y.gd ├── coin.gd ├── Asset_Pickup.gd ├── Implant_Object.gd ├── Random_Mesh.gd ├── Abraxas_Head.gd ├── Level_Painting.gd ├── Radio.gd ├── Generic_Shell.tscn ├── soulll.gd ├── Shell.tscn ├── Player_Manager.gd ├── Player_Test.tscn ├── 20_mm_shell.tscn ├── Berries.gd ├── Elevator.gd ├── down_switch_door.gd ├── Explosion.gd ├── Exit.gd ├── Terror_Door.gd ├── Cutscene.gd ├── down_door.gd ├── Pushblock.gd ├── snakehead.gd ├── Special_Pushblock.gd ├── Profane_Door.gd ├── weapon_pickup_new.gd ├── vendingmachine.gd ├── Elevator_Door.gd ├── Destructible_Armored.gd ├── Item_Slotmachine.gd ├── Fire.gd ├── Abraxas_Rocket.gd ├── Divine_Door.gd ├── Destructible_Static.gd ├── Slotmachine.gd ├── Destructible.gd ├── abraxas.gd ├── Fire_Child.gd ├── Abraxas_Laser.gd ├── grid_enemy.gd ├── Weapon_Slotmachine.gd ├── MissileKinematic.gd └── Door.gd ├── redpanel.tres ├── BenchmarkBall.tscn ├── BenchmarkBall.gd ├── multiplayer_init.gd ├── effects ├── fake_Fire_Child.tscn ├── fake_Fire.tscn ├── fake_explosion.tscn ├── fake_Radiation.tscn ├── fake_Missile_Kinematic.tscn ├── fake_self_destruct_explosion.tscn ├── fake_Grenade.tscn └── fake_poison_gas.tscn ├── icon.png.import ├── UPnP.gd ├── bannedimplant.png.import ├── crus_online_logo.png.import ├── sadbannedimplant.png.import ├── target_white.png.import ├── BloodParticles.tscn ├── player_model └── player_anim_example.gd ├── entities ├── material_randomizer.gd ├── Enemy_Melee_Weapon.gd └── Enemy_Controller.gd ├── Players.gd ├── shell_physics.gd ├── Stats.gd ├── help.txt.gd ├── Menu.gd ├── Steam.gd ├── ChatBox.gd ├── Button.tscn ├── RelayServer.gd ├── README.md ├── WIKI_RU.md ├── README_RU.md └── extramenu.tres /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/icon.png -------------------------------------------------------------------------------- /remap_files.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/remap_files.rar -------------------------------------------------------------------------------- /bannedimplant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/bannedimplant.png -------------------------------------------------------------------------------- /models/online.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/online.glb -------------------------------------------------------------------------------- /target_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/target_white.png -------------------------------------------------------------------------------- /crus_online_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/crus_online_logo.png -------------------------------------------------------------------------------- /maps/greyface1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/maps/greyface1.png -------------------------------------------------------------------------------- /maps/greyface2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/maps/greyface2.png -------------------------------------------------------------------------------- /models/intro_guy.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/intro_guy.glb -------------------------------------------------------------------------------- /sadbannedimplant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/sadbannedimplant.png -------------------------------------------------------------------------------- /models/Material.material: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/Material.material -------------------------------------------------------------------------------- /models/Phone_mat.material: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/Phone_mat.material -------------------------------------------------------------------------------- /models/glasses.material: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/glasses.material -------------------------------------------------------------------------------- /models/basement_blades.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/basement_blades.glb -------------------------------------------------------------------------------- /models/Phone_screen.material: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/Phone_screen.material -------------------------------------------------------------------------------- /maps_stuff/respawn_point.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene format=2] 2 | 3 | [node name="RespawnPoint" type="Position3D" groups=["Respawn"]] 4 | -------------------------------------------------------------------------------- /models/Nude_Material_001.material: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/Nude_Material_001.material -------------------------------------------------------------------------------- /models/Nude_Material001_001.material: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TriggeredP/crus-online/HEAD/models/Nude_Material001_001.material -------------------------------------------------------------------------------- /WIKI.md: -------------------------------------------------------------------------------- 1 | # Cruelty Squad Online Development Wiki 2 | 3 |
4 | 5 | Cruelty Squad Online logo 6 | 7 | English | [Русский](WIKI_RU.md) -------------------------------------------------------------------------------- /remaped/Tutorial_Exit.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | onready var Multiplayer = Global.get_node("Multiplayer") 6 | 7 | func player_use(): 8 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 9 | Multiplayer.goto_menu_host() 10 | -------------------------------------------------------------------------------- /remaped/killbox.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | func _ready(): 4 | set_collision_mask_bit(0, 0) 5 | set_collision_mask_bit(1, 1) 6 | 7 | connect("body_entered", self, "_on_Body_Entered") 8 | 9 | func _on_Body_Entered(body): 10 | if body.has_method("damage"): 11 | body.damage(1000, Vector3.ZERO, global_transform.origin, global_transform.origin) 12 | -------------------------------------------------------------------------------- /remaped/Message_Area.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | export (String, MULTILINE) var message = "N/A" 4 | export var tutorial = false 5 | 6 | func _ready(): 7 | if tutorial and Global.LEVELS_UNLOCKED > 1: 8 | queue_free() 9 | 10 | func _on_Message_Area_body_entered(body): 11 | if body == Global.player: 12 | body.UI.message(message, false) 13 | queue_free() 14 | -------------------------------------------------------------------------------- /models/weapon_spawner.mtl: -------------------------------------------------------------------------------- 1 | # Blender 3.6.4 MTL File: 'crus models.blend' 2 | # www.blender.org 3 | 4 | newmtl Material.001 5 | Ns 250.000000 6 | Ka 1.000000 1.000000 1.000000 7 | Ks 0.500000 0.500000 0.500000 8 | Ke 0.000000 0.000000 0.000000 9 | Ni 1.450000 10 | d 1.000000 11 | illum 2 12 | map_Kd C:/Users/Vital/OneDrive/Рабочий стол/CRuS multiplayer/Maps/textures/base/switch.png 13 | -------------------------------------------------------------------------------- /redpanel.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StyleBoxTexture" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://Textures/Menu/background_1.png" type="Texture" id=1] 4 | 5 | [resource] 6 | texture = ExtResource( 1 ) 7 | region_rect = Rect2( 0, 0, 256, 256 ) 8 | margin_left = 10.0 9 | margin_right = 10.0 10 | margin_top = 5.0 11 | margin_bottom = 5.0 12 | modulate_color = Color( 0.298039, 0.0352941, 0.0352941, 1 ) 13 | -------------------------------------------------------------------------------- /BenchmarkBall.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Materials/Freak_Snake.tres" type="Material" id=1] 4 | [ext_resource path="res://MOD_CONTENT/CruS Online/BenchmarkBall.gd" type="Script" id=2] 5 | 6 | [sub_resource type="SphereMesh" id=1] 7 | material = ExtResource( 1 ) 8 | 9 | [node name="BenchmarkBall" type="Spatial"] 10 | script = ExtResource( 2 ) 11 | 12 | [node name="MeshInstance" type="MeshInstance" parent="."] 13 | mesh = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /remaped/Special_Destroy.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | func _ready(): 6 | NetworkBridge.register_rpcs(self, [ 7 | ["remove", NetworkBridge.PERMISSION.SERVER] 8 | ]) 9 | 10 | puppet func remove(id): 11 | queue_free() 12 | 13 | func special_destroy(): 14 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 15 | queue_free() 16 | NetworkBridge.n_rpc(self, "remove") 17 | -------------------------------------------------------------------------------- /BenchmarkBall.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var Multiplayer = Global.get_node("Multiplayer") 4 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 5 | 6 | func _ready(): 7 | NetworkBridge.register_rpcs(self, [ 8 | ["test_rpc", NetworkBridge.PERMISSION.SERVER] 9 | ]) 10 | 11 | func _physics_process(delta): 12 | if NetworkBridge.n_is_network_master(): 13 | NetworkBridge.n_rpc_unreliable(self, "test_rpc", [[Vector3.ONE, Vector3.ONE, Vector3.ONE]]) 14 | 15 | puppet func test_rpc(id, garbage_data): 16 | pass 17 | -------------------------------------------------------------------------------- /multiplayer_init.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | func _init(): 4 | ProjectSettings.set_setting("debug/gdscript/warnings/enable", true) 5 | 6 | Global.add_child(preload("res://MOD_CONTENT/CruS Online/multiplayer.tscn").instance()) 7 | Global.add_child(preload("res://MOD_CONTENT/CruS Online/death_screen.tscn").instance()) 8 | Global.get_node("Menu").add_child(preload("res://MOD_CONTENT/CruS Online/menu.tscn").instance()) 9 | 10 | # $'/root/Global/Multiplayer' 11 | # Global.get_node('Multiplayer') 12 | # get_tree().get_nodes_in_group("Multiplayer")[0] 13 | -------------------------------------------------------------------------------- /effects/fake_Fire_Child.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Materials/Fire.tres" type="Material" id=2] 4 | [ext_resource path="res://Entities/Particles/fire.tres" type="Material" id=3] 5 | 6 | [sub_resource type="QuadMesh" id=2] 7 | 8 | [node name="Particles" type="Particles"] 9 | transform = Transform( 2.052, 0, 0, 0, 2.292, 0, 0, 0, 2.02, 0, 0, 0 ) 10 | material_override = ExtResource( 2 ) 11 | emitting = false 12 | amount = 5 13 | lifetime = 0.27 14 | fract_delta = false 15 | process_material = ExtResource( 3 ) 16 | draw_pass_1 = SubResource( 2 ) 17 | -------------------------------------------------------------------------------- /remaped/Radiation.gd: -------------------------------------------------------------------------------- 1 | extends Particles 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var damage = 0.4 6 | 7 | func _physics_process(delta): 8 | if NetworkBridge.n_is_network_master(self): 9 | for body in $Area.get_overlapping_bodies(): 10 | if body == Global.player and Global.death: 11 | return 12 | if body.has_method("player_damage"): 13 | body.player_damage(damage, Vector3.ZERO, body.global_transform.origin, global_transform.origin, "radiation") 14 | elif body.has_method("damage"): 15 | body.damage(damage, Vector3.ZERO, body.global_transform.origin, global_transform.origin) 16 | -------------------------------------------------------------------------------- /remaped/garbage_destroyer.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | var particle_node 4 | var particle = false 5 | 6 | func _ready(): 7 | connect("body_entered", self, "_on_body_entered") 8 | particle_node = get_node_or_null("Particles") 9 | if is_instance_valid(particle_node): 10 | particle = true 11 | 12 | func _on_body_entered(body): 13 | if body == get_parent() or body.get_collision_layer_bit(0) or "sound" in body: 14 | return 15 | if particle: 16 | particle_node.emitting = true 17 | if "soul" in body: 18 | body.soul.hide() 19 | body.soul.global_transform.origin = Vector3(-1000,-1000,-1000) 20 | else : 21 | body.hide() 22 | body.global_transform.origin = Vector3(-1000,-1000,-1000) 23 | -------------------------------------------------------------------------------- /models/weapon_spawner.obj.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wavefront_obj" 4 | type="Mesh" 5 | path="res://.import/weapon_spawner.obj-f70445d7240aaa7dc3225e4498299fd6.mesh" 6 | 7 | [deps] 8 | 9 | files=[ "res://.import/weapon_spawner.obj-f70445d7240aaa7dc3225e4498299fd6.mesh" ] 10 | 11 | source_file="res://MOD_CONTENT/CruS Online/models/weapon_spawner.obj" 12 | dest_files=[ "res://.import/weapon_spawner.obj-f70445d7240aaa7dc3225e4498299fd6.mesh", "res://.import/weapon_spawner.obj-f70445d7240aaa7dc3225e4498299fd6.mesh" ] 13 | 14 | [params] 15 | 16 | generate_tangents=true 17 | scale_mesh=Vector3( 1, 1, 1 ) 18 | offset_mesh=Vector3( 0, 0, 0 ) 19 | octahedral_compression=true 20 | optimize_mesh_flags=4286 21 | -------------------------------------------------------------------------------- /remaped/Rotator_Y_Spatial.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var rotation_speed = 1 6 | 7 | func _ready(): 8 | NetworkBridge.register_rpcs(self, [ 9 | ["network_set_rotation", NetworkBridge.PERMISSION.SERVER] 10 | ]) 11 | 12 | rotation.y += rand_range(0, TAU) 13 | 14 | var tick = 0 15 | 16 | func _physics_process(delta): 17 | rotation.y -= rotation_speed * delta 18 | 19 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 20 | tick += 1 21 | if tick % 30 == 0: 22 | NetworkBridge.n_rpc_unreliable(self, "network_set_rotation", [rotation.y]) 23 | tick = 0 24 | 25 | puppet func network_set_rotation(id, recived_y): 26 | rotation.y = recived_y 27 | -------------------------------------------------------------------------------- /remaped/Rotator_Y.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var rotation_speed:float = 1 6 | 7 | func _ready(): 8 | NetworkBridge.register_rpcs(self, [ 9 | ["network_set_rotation", NetworkBridge.PERMISSION.SERVER] 10 | ]) 11 | 12 | rotation.y += rand_range(0, TAU) 13 | 14 | var tick = 0 15 | 16 | func _physics_process(delta): 17 | rotation.y -= rotation_speed * delta 18 | 19 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 20 | tick += 1 21 | if tick % 30 == 0: 22 | NetworkBridge.n_rpc_unreliable(self, "network_set_rotation", [rotation.y]) 23 | tick = 0 24 | 25 | puppet func network_set_rotation(id, recived_y): 26 | rotation.y = recived_y 27 | -------------------------------------------------------------------------------- /remaped/coin.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var value = 10 6 | export var id = "N" 7 | 8 | var fromSlotMachine = false 9 | 10 | func _ready(): 11 | NetworkBridge.register_rpcs(self, [ 12 | ["hide_coin", NetworkBridge.PERMISSION.ALL] 13 | ]) 14 | 15 | if Global.MONEY_ITEMS.find(id) != - 1: 16 | get_parent().queue_free() 17 | 18 | func player_use(): 19 | Global.player.UI.notify("$" + str(value) + " picked up", Color(1, 1, 0)) 20 | Global.money += value 21 | if id != "N": 22 | Global.MONEY_ITEMS.append(id) 23 | Global.save_game() 24 | 25 | if fromSlotMachine: 26 | NetworkBridge.n_rpc(self, "hide_coin") 27 | get_parent().queue_free() 28 | 29 | remote func hide_coin(id): 30 | get_parent().queue_free() 31 | -------------------------------------------------------------------------------- /remaped/Asset_Pickup.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | # WARN: По какой-то причине загружается до инициализации стима 4 | 5 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 6 | 7 | export var value = "Liver" 8 | 9 | func _ready(): 10 | NetworkBridge.register_rpcs(self, [ 11 | ["hide_asset", NetworkBridge.PERMISSION.ALL] 12 | ]) 13 | 14 | func player_use(): 15 | Global.player.UI.notify(value + " acquisition complete", Color(1, 1, 0)) 16 | for stock in Global.STOCKS.stocks: 17 | if stock.s_name == value: 18 | stock.owned += 1 19 | if Global.STOCKS.ORGANS_FOUND.find(value) == - 1: 20 | Global.STOCKS.ORGANS_FOUND.append(value) 21 | Global.STOCKS.save_stocks("user://stocks.save") 22 | NetworkBridge.n_rpc(self, "hide_asset") 23 | get_parent().queue_free() 24 | 25 | remote func hide_asset(id): 26 | get_parent().queue_free() 27 | -------------------------------------------------------------------------------- /icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-18e2a1fd5b08b0cedda4cbca39838751.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://MOD_CONTENT/CruS Online/icon.png" 13 | dest_files=[ "res://.import/icon.png-18e2a1fd5b08b0cedda4cbca39838751.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=true 23 | flags/filter=false 24 | flags/mipmaps=true 25 | flags/anisotropic=false 26 | flags/srgb=0 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=false 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /remaped/Implant_Object.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var implant_name = "Hazmat Suit" 6 | 7 | func _ready(): 8 | if Global.implants.purchased_implants.find(implant_name) == - 1: 9 | for i in Global.implants.IMPLANTS: 10 | if i.i_name == implant_name: 11 | 12 | var new_mat = $implant_object / Cube.mesh.surface_get_material(1).duplicate() 13 | new_mat.albedo_texture = i.texture 14 | $implant_object / Cube.set_surface_material(1, new_mat) 15 | else : 16 | get_parent().hide() 17 | $CollisionShape.disabled = true 18 | 19 | func player_use(): 20 | Global.implants.purchased_implants.append(implant_name) 21 | Global.player.UI.notify(implant_name + " acquired.", Color(0.2, 1, 0)) 22 | Global.save_game() 23 | get_parent().hide() 24 | $CollisionShape.disabled = true 25 | -------------------------------------------------------------------------------- /maps/greyface1.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/greyface1.png-6571da76d3da90565fe8856c71892a9d.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://MOD_CONTENT/CruS Online/maps/greyface1.png" 13 | dest_files=[ "res://.import/greyface1.png-6571da76d3da90565fe8856c71892a9d.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=3 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=true 23 | flags/filter=false 24 | flags/mipmaps=true 25 | flags/anisotropic=false 26 | flags/srgb=1 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=false 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /maps/greyface2.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/greyface2.png-997b25d1762a6fe563c73a4b51ea023e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://MOD_CONTENT/CruS Online/maps/greyface2.png" 13 | dest_files=[ "res://.import/greyface2.png-997b25d1762a6fe563c73a4b51ea023e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=3 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=true 23 | flags/filter=false 24 | flags/mipmaps=true 25 | flags/anisotropic=false 26 | flags/srgb=1 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=false 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /UPnP.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | var thread = null 4 | 5 | signal upnp_completed(error) 6 | 7 | func _upnp_setup(server_port): 8 | var upnp = UPNP.new() 9 | var err = upnp.discover() 10 | 11 | if err != OK: 12 | push_error("[CRUS ONLINE / UPnP]: ERROR " + str(err)) 13 | emit_signal("upnp_completed", err) 14 | return 15 | 16 | if upnp.get_gateway() and upnp.get_gateway().is_valid_gateway(): 17 | upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "UDP") 18 | upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "TCP") 19 | print("[CRUS ONLINE / UPnP]: UPnP enabled") 20 | emit_signal("upnp_completed", OK) 21 | 22 | func upnp_setup(server_port): 23 | thread = Thread.new() 24 | thread.start(self, "_upnp_setup", server_port) 25 | 26 | func _exit_tree(): 27 | thread.wait_to_finish() 28 | -------------------------------------------------------------------------------- /bannedimplant.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/bannedimplant.png-309313e794cbfa18f174c26e593cc3d6.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://MOD_CONTENT/CruS Online/bannedimplant.png" 13 | dest_files=[ "res://.import/bannedimplant.png-309313e794cbfa18f174c26e593cc3d6.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=1 23 | flags/filter=false 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=1 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=false 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /crus_online_logo.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/crus_online_logo.png-33af213939e9b15b39ea86e451ab26c4.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://MOD_CONTENT/CruS Online/crus_online_logo.png" 13 | dest_files=[ "res://.import/crus_online_logo.png-33af213939e9b15b39ea86e451ab26c4.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=3 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=true 23 | flags/filter=false 24 | flags/mipmaps=true 25 | flags/anisotropic=false 26 | flags/srgb=0 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=false 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /sadbannedimplant.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/sadbannedimplant.png-bf7e2c2f56c852eb4c6e9cf459809f07.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://MOD_CONTENT/CruS Online/sadbannedimplant.png" 13 | dest_files=[ "res://.import/sadbannedimplant.png-bf7e2c2f56c852eb4c6e9cf459809f07.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=true 23 | flags/filter=false 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=1 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=false 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /remaped/Random_Mesh.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var foodType = 0 6 | 7 | onready var collision = get_node("../Area/CollisionShape") 8 | 9 | func _ready(): 10 | NetworkBridge.register_rpcs(self, [ 11 | ["set_food", NetworkBridge.PERMISSION.SERVER], 12 | ["get_food", NetworkBridge.PERMISSION.ALL] 13 | ]) 14 | 15 | collision.disabled = true 16 | 17 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 18 | if randi() % 2 != 0: 19 | foodType = randi() % get_child_count() 20 | get_child(foodType).show() 21 | collision.disabled = false 22 | else: 23 | get_food(null) 24 | 25 | master func get_food(id): 26 | if not collision.disabled: 27 | NetworkBridge.n_rpc(self, "set_food", [foodType]) 28 | 29 | puppet func set_food(id, type): 30 | get_child(type).show() 31 | collision.disabled = false 32 | -------------------------------------------------------------------------------- /remaped/Abraxas_Head.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var type = 1 6 | var active = false 7 | export var health = 10 8 | var destroyed = false 9 | 10 | func _ready(): 11 | NetworkBridge.register_rpcs(self, [ 12 | ["died", NetworkBridge.PERMISSION.SERVER], 13 | ["network_damage", NetworkBridge.PERMISSION.ALL] 14 | ]) 15 | 16 | puppet func died(id): 17 | get_parent().get_node("Sphere").hide() 18 | get_parent().get_node("Particle").show() 19 | 20 | func damage(dmg, nrml, pos, shoot_pos): 21 | network_damage(null, dmg, nrml, pos, shoot_pos) 22 | 23 | master func network_damage(id, dmg, nrml, pos, shoot_pos): 24 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 25 | if not active: 26 | return 27 | health -= dmg 28 | if health <= 0: 29 | destroyed = true 30 | died(null) 31 | NetworkBridge.n_rpc(self, "died") 32 | else: 33 | NetworkBridge.n_rpc(self, "network_damage", [dmg, nrml, pos, shoot_pos]) 34 | 35 | func get_type(): 36 | return type 37 | -------------------------------------------------------------------------------- /target_white.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path.s3tc="res://.import/target_white.png-fbe3b145510ca3e5a6967b8d63309f01.s3tc.stex" 6 | path.etc2="res://.import/target_white.png-fbe3b145510ca3e5a6967b8d63309f01.etc2.stex" 7 | metadata={ 8 | "imported_formats": [ "s3tc", "etc2" ], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://MOD_CONTENT/CruS Online/target_white.png" 15 | dest_files=[ "res://.import/target_white.png-fbe3b145510ca3e5a6967b8d63309f01.s3tc.stex", "res://.import/target_white.png-fbe3b145510ca3e5a6967b8d63309f01.etc2.stex" ] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/lossy_quality=0.7 21 | compress/hdr_mode=0 22 | compress/bptc_ldr=0 23 | compress/normal_map=0 24 | flags/repeat=true 25 | flags/filter=false 26 | flags/mipmaps=false 27 | flags/anisotropic=false 28 | flags/srgb=1 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/HDR_as_SRGB=false 32 | process/invert_color=false 33 | process/normal_map_invert_y=false 34 | stream=false 35 | size_limit=0 36 | detect_3d=false 37 | svg/scale=1.0 38 | -------------------------------------------------------------------------------- /maps/Benchmark.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var ball = preload("res://MOD_CONTENT/CruS Online/BenchmarkBall.tscn") 4 | 5 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 6 | 7 | func _ready(): 8 | NetworkBridge.register_rpcs(self,[ 9 | ["_create_object", NetworkBridge.PERMISSION.SERVER], 10 | ["spawn_ball", NetworkBridge.PERMISSION.ALL] 11 | ]) 12 | 13 | puppet func _create_object(id, recivedName, recivedOrigin): 14 | var newObject = ball.instance() 15 | newObject.set_name(recivedName) 16 | $Balls.add_child(newObject) 17 | 18 | newObject.global_transform.origin = recivedOrigin 19 | 20 | master func spawn_ball(id, count = 1): 21 | if NetworkBridge.n_is_network_master(self): 22 | for i in range(count): 23 | var newObject = ball.instance() 24 | newObject.set_name(newObject.name + "#" + str(newObject.get_instance_id())) 25 | $Balls.add_child(newObject) 26 | 27 | newObject.global_transform.origin += Vector3(rand_range(-10.0, 10.0), rand_range(-10.0, 10.0), rand_range(-10.0, 10.0)) 28 | 29 | NetworkBridge.n_rpc(self, "_create_object", [newObject.name, newObject.global_transform.origin]) 30 | else: 31 | NetworkBridge.n_rpc(self, "spawn_ball", [count]) 32 | -------------------------------------------------------------------------------- /remaped/Level_Painting.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var level_index = 13 6 | export var level_name = "Darkworld" 7 | 8 | onready var Multiplayer = Global.get_node("Multiplayer") 9 | 10 | func _ready(): 11 | NetworkBridge.register_rpcs(self, [ 12 | ["unlock_level", NetworkBridge.PERMISSION.SERVER] 13 | ]) 14 | 15 | var new_mat = $level_painting / Cube.mesh.surface_get_material(1).duplicate() 16 | new_mat.albedo_texture = Global.LEVEL_IMAGES[level_index] 17 | $level_painting / Cube.set_surface_material(1, new_mat) 18 | 19 | func _on_Area_body_entered(body): 20 | if body == Global.player: 21 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 22 | if Global.BONUS_UNLOCK.find(level_name) == -1: 23 | Global.BONUS_UNLOCK.append(level_name) 24 | NetworkBridge.n_rpc(self, "unlock_level") 25 | Global.save_game() 26 | Multiplayer.goto_scene_host(Global.LEVELS[level_index]) 27 | else: 28 | Global.UI.notify("It feels like a normal painting", Color(1, 0, 0)) 29 | 30 | puppet func unlock_level(id): 31 | if Global.BONUS_UNLOCK.find(level_name) == -1: 32 | Global.BONUS_UNLOCK.append(level_name) 33 | -------------------------------------------------------------------------------- /remaped/Radio.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var static_noise = 0 6 | var current_track = 0 7 | 8 | func _ready(): 9 | NetworkBridge.register_rpcs(self, [ 10 | ["change_track", NetworkBridge.PERMISSION.SERVER], 11 | ["get_track", NetworkBridge.PERMISSION.ALL], 12 | ["player_use", NetworkBridge.PERMISSION.ALL] 13 | ]) 14 | 15 | if NetworkBridge.n_is_network_master(self): 16 | current_track = randi() % Global.LEVEL_SONGS.size() 17 | $Radio.stream = Global.LEVEL_SONGS[current_track] 18 | $Radio.play() 19 | else: 20 | NetworkBridge.n_rpc(self, "get_track") 21 | 22 | master func player_use(id): 23 | if NetworkBridge.n_is_network_master(self): 24 | current_track += 1 25 | current_track = wrapi(current_track, 0, Global.LEVEL_SONGS.size()) 26 | $Radio.stream = Global.LEVEL_SONGS[current_track] 27 | $Radio.play() 28 | 29 | NetworkBridge.n_rpc(self, "change_track", [current_track]) 30 | else: 31 | NetworkBridge.n_rpc(self, "player_use") 32 | 33 | master func get_track(id): 34 | NetworkBridge.n_rpc(self, "change_track", [current_track]) 35 | 36 | puppet func change_track(id, recivedTrack): 37 | $Radio.stream = Global.LEVEL_SONGS[recivedTrack] 38 | $Radio.play() 39 | -------------------------------------------------------------------------------- /effects/fake_Fire.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://Materials/Fire.tres" type="Material" id=2] 4 | [ext_resource path="res://Entities/Particles/fire.tres" type="Material" id=3] 5 | 6 | [sub_resource type="GDScript" id=3] 7 | script/source = "extends Spatial 8 | 9 | onready var NetworkBridge = Global.get_node(\"Multiplayer/NetworkBridge\") 10 | 11 | func _ready(): 12 | NetworkBridge.register_rpcs(self,[ 13 | [\"_set_transform\", NetworkBridge.PERMISSION.SERVER], 14 | [\"_delete\", NetworkBridge.PERMISSION.SERVER] 15 | ]) 16 | 17 | puppet func _set_transform(id, recivedTransform): 18 | global_transform = recivedTransform 19 | 20 | puppet func _delete(id): 21 | hide() 22 | global_translation = Vector3(-1000, -1000, -1000) 23 | 24 | set_process(false) 25 | set_physics_process(false) 26 | " 27 | 28 | [sub_resource type="QuadMesh" id=2] 29 | 30 | [node name="Fire" type="Spatial"] 31 | script = SubResource( 3 ) 32 | 33 | [node name="Particles" type="Particles" parent="."] 34 | transform = Transform( 0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0 ) 35 | material_override = ExtResource( 2 ) 36 | emitting = false 37 | fixed_fps = 30 38 | fract_delta = false 39 | process_material = ExtResource( 3 ) 40 | draw_pass_1 = SubResource( 2 ) 41 | -------------------------------------------------------------------------------- /BloodParticles.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://Textures/Decals/blood2.png" type="Texture" id=1] 4 | 5 | [sub_resource type="Curve" id=1] 6 | _data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ] 7 | 8 | [sub_resource type="CurveTexture" id=2] 9 | curve = SubResource( 1 ) 10 | 11 | [sub_resource type="ParticlesMaterial" id=3] 12 | lifetime_randomness = 0.2 13 | direction = Vector3( 0, 1, 0 ) 14 | spread = 180.0 15 | initial_velocity = 2.0 16 | initial_velocity_random = 0.3 17 | angular_velocity = 5.0 18 | angular_velocity_random = 0.38 19 | linear_accel = 5.0 20 | radial_accel = 5.0 21 | scale = 1.5 22 | scale_curve = SubResource( 2 ) 23 | 24 | [sub_resource type="SpatialMaterial" id=4] 25 | flags_transparent = true 26 | flags_unshaded = true 27 | params_billboard_mode = 3 28 | particles_anim_h_frames = 1 29 | particles_anim_v_frames = 1 30 | particles_anim_loop = false 31 | albedo_texture = ExtResource( 1 ) 32 | 33 | [sub_resource type="QuadMesh" id=5] 34 | material = SubResource( 4 ) 35 | 36 | [node name="BloodParticles" type="Particles"] 37 | emitting = false 38 | amount = 16 39 | lifetime = 0.75 40 | one_shot = true 41 | explosiveness = 1.0 42 | process_material = SubResource( 3 ) 43 | draw_pass_1 = SubResource( 5 ) 44 | -------------------------------------------------------------------------------- /effects/fake_explosion.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://Entities/Particles/Explosion_Green1.tscn" type="PackedScene" id=2] 4 | [ext_resource path="res://Sfx/WeaponsPickups/Rocket launcher/missile_explosion.wav" type="AudioStream" id=3] 5 | 6 | [sub_resource type="GDScript" id=4] 7 | script/source = "extends Spatial 8 | 9 | func _ready(): 10 | $Particle.emitting = true 11 | $Sound.play() 12 | 13 | func delete(): 14 | queue_free() 15 | " 16 | 17 | [sub_resource type="SpatialMaterial" id=2] 18 | albedo_color = Color( 1, 0.352941, 0, 1 ) 19 | 20 | [sub_resource type="SphereMesh" id=3] 21 | material = SubResource( 2 ) 22 | radius = 1.967 23 | height = 4.081 24 | 25 | [node name="Explosion" type="Spatial"] 26 | script = SubResource( 4 ) 27 | 28 | [node name="Timer" type="Timer" parent="."] 29 | one_shot = true 30 | autostart = true 31 | 32 | [node name="MeshInstance" type="MeshInstance" parent="."] 33 | visible = false 34 | mesh = SubResource( 3 ) 35 | 36 | [node name="Particle" parent="." instance=ExtResource( 2 )] 37 | 38 | [node name="Sound" type="AudioStreamPlayer3D" parent="."] 39 | stream = ExtResource( 3 ) 40 | unit_size = 20.0 41 | max_db = 2.0 42 | autoplay = true 43 | bus = "SFX" 44 | 45 | [connection signal="timeout" from="Timer" to="." method="delete"] 46 | -------------------------------------------------------------------------------- /player_model/player_anim_example.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var anim_tree = $"../anim_tree" 4 | 5 | func _ready(): 6 | ### UPPER BODY 7 | #set look direction. -1 = straight up, 0 = forward, 1 = straight down 8 | anim_tree.set("parameters/LOOK_DIRECTION/blend_amount", 0.0) 9 | #set arm animation. -1 = Phone, 0 = None, 1 = Aiming Gun 10 | anim_tree.set("parameters/ARMS_BLEND/blend_amount", 1.0) 11 | 12 | ### LOWER BODY 13 | #set leg movement type. 0 = Standing, 1 = Crouching 14 | anim_tree.set("parameters/MOVE_BLEND/blend_amount", 0.0) 15 | #set crouch speed. 0 = Not moving, 1 = max speed 16 | anim_tree.set("parameters/CROUCHMOVE_AMOUNT/blend_amount", 1.0) 17 | #set run speed. 0 = Not moving, 1 = max speed 18 | anim_tree.set("parameters/STANDMOVE_AMOUNT/blend_amount", 1.0) 19 | #set run direction (optional). -1 = running left, 0 = running forward, 1 = running right 20 | anim_tree.set("parameters/RUN_DIRECTION/blend_amount", 0.0) 21 | #special legs animation. 0 = None, -1 = Sitting, 1 = Jumping 22 | anim_tree.set("parameters/LEGS_BLEND/blend_amount", 0.0) 23 | 24 | ### ONE SHOT ANIMATIONS 25 | #trigger death 1 26 | anim_tree.set("parameters/DEATH1/active", false) 27 | #trigger death 2 28 | anim_tree.set("parameters/DEATH2/active", false) 29 | #trigger kick 30 | anim_tree.set("parameters/KICK/active", false) 31 | 32 | -------------------------------------------------------------------------------- /remaped/Generic_Shell.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://MOD_CONTENT/CruS Online/shell_physics.gd" type="Script" id=1] 4 | [ext_resource path="res://Imported_Mesh/Generic_Shell.glb" type="PackedScene" id=2] 5 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_1.wav" type="AudioStream" id=3] 6 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_2.wav" type="AudioStream" id=4] 7 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_3.wav" type="AudioStream" id=5] 8 | 9 | [sub_resource type="CylinderShape" id=1] 10 | height = 0.06 11 | radius = 0.01 12 | 13 | [node name="Shell" type="KinematicBody"] 14 | collision_layer = 0 15 | script = ExtResource( 1 ) 16 | 17 | [node name="CollisionShape" type="CollisionShape" parent="."] 18 | shape = SubResource( 1 ) 19 | 20 | [node name="Sound1" type="AudioStreamPlayer3D" parent="."] 21 | stream = ExtResource( 3 ) 22 | bus = "SFX" 23 | 24 | [node name="Sound2" type="AudioStreamPlayer3D" parent="."] 25 | stream = ExtResource( 4 ) 26 | bus = "SFX" 27 | 28 | [node name="Sound3" type="AudioStreamPlayer3D" parent="."] 29 | stream = ExtResource( 5 ) 30 | bus = "SFX" 31 | 32 | [node name="Generic_Shell" parent="." instance=ExtResource( 2 )] 33 | 34 | [node name="Remove" type="Timer" parent="."] 35 | wait_time = 15.0 36 | one_shot = true 37 | autostart = true 38 | 39 | [connection signal="timeout" from="Remove" to="." method="remove"] 40 | -------------------------------------------------------------------------------- /remaped/soulll.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var soul = true 6 | var gib = preload("res://Entities/Physics_Objects/Chest_Gib.tscn") 7 | 8 | func _ready(): 9 | NetworkBridge.register_rpcs(self, [ 10 | ["spawn_gib", NetworkBridge.PERMISSION.ALL] 11 | ]) 12 | 13 | func player_use(): 14 | if soul: 15 | Global.set_soul() 16 | else : 17 | Global.set_hope() 18 | Global.player.suicide() 19 | Global.save_game() 20 | get_parent().get_node("MeshInstance").hide() 21 | if not soul: 22 | for i in range(10): 23 | var new_gib = gib.instance() 24 | new_gib.set_name(new_gib.name + "#" + str(new_gib.get_instance_id())) 25 | get_parent().get_parent().add_child(new_gib) 26 | new_gib.global_transform.origin = global_transform.origin 27 | new_gib.damage(20, Vector3.FORWARD.rotated(Vector3.UP, rand_range( - PI, PI)), global_transform.origin, global_transform.origin) 28 | NetworkBridge.n_rpc(self, "spawn_gib", [get_parent().get_parent().get_path(), new_gib.name]) 29 | get_parent().get_node("AudioStreamPlayer3D").play() 30 | queue_free() 31 | return 32 | get_parent().get_node("Particles").emitting = true 33 | get_parent().get_node("AudioStreamPlayer3D").play() 34 | queue_free() 35 | 36 | master func spawn_gib(id, recivedPath, recivedName): 37 | var new_gib = gib.instance() 38 | get_node(recivedPath).add_child(new_gib) 39 | new_gib.set_name(recivedName) 40 | -------------------------------------------------------------------------------- /entities/material_randomizer.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export (Array, String) var materials 6 | export var head_only = false 7 | export var cutscene = false 8 | onready var anim = $AnimationPlayer 9 | 10 | var materialId = 0 11 | 12 | puppet func set_material(id, recived_material_id, head_only_recived): 13 | var material = load(materials[recived_material_id]) 14 | $Armature / Skeleton / Head_Mesh.material_override = material 15 | if not head_only_recived: 16 | $Armature / Skeleton / Torso_Mesh.material_override = material 17 | 18 | master func get_material(id): 19 | NetworkBridge.n_rpc_id(self, id, "set_material", [materialId, head_only]) 20 | 21 | func _ready(): 22 | NetworkBridge.register_rpcs(self,[ 23 | ["get_material", NetworkBridge.PERMISSION.ALL], 24 | ["set_material", NetworkBridge.PERMISSION.SERVER] 25 | ]) 26 | 27 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 28 | materialId = randi() % materials.size() 29 | var material = load(materials[materialId]) 30 | $Armature / Skeleton / Head_Mesh.material_override = material 31 | if not head_only: 32 | $Armature / Skeleton / Torso_Mesh.material_override = material 33 | else: 34 | NetworkBridge.n_rpc_id(self, 0, "get_material") 35 | 36 | func _process(delta): 37 | if not cutscene: 38 | return 39 | set_process(false) 40 | translate(Vector3.FORWARD * delta) 41 | anim.play("Walk") 42 | -------------------------------------------------------------------------------- /remaped/Shell.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://MOD_CONTENT/CruS Online/shell_physics.gd" type="Script" id=1] 4 | [ext_resource path="res://Imported_Mesh/Shotgun_Shell.glb" type="PackedScene" id=2] 5 | [ext_resource path="res://Entities/Physics_Objects/flesh_sound.tscn" type="PackedScene" id=3] 6 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_2.wav" type="AudioStream" id=4] 7 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_3.wav" type="AudioStream" id=5] 8 | 9 | [sub_resource type="CylinderShape" id=1] 10 | height = 0.06 11 | radius = 0.01 12 | 13 | [node name="Shell" type="KinematicBody"] 14 | collision_layer = 0 15 | script = ExtResource( 1 ) 16 | 17 | [node name="CollisionShape" type="CollisionShape" parent="."] 18 | shape = SubResource( 1 ) 19 | 20 | [node name="Shotgun_Shell" parent="." instance=ExtResource( 2 )] 21 | 22 | [node name="Sound1" parent="." instance=ExtResource( 3 )] 23 | stream = ExtResource( 4 ) 24 | unit_db = 0.0 25 | unit_size = 2.0 26 | max_db = 0.0 27 | pitch_scale = 0.76 28 | 29 | [node name="Sound2" type="AudioStreamPlayer3D" parent="."] 30 | stream = ExtResource( 4 ) 31 | bus = "SFX" 32 | 33 | [node name="Sound3" type="AudioStreamPlayer3D" parent="."] 34 | stream = ExtResource( 5 ) 35 | bus = "SFX" 36 | 37 | [node name="Remove" type="Timer" parent="."] 38 | wait_time = 15.0 39 | one_shot = true 40 | autostart = true 41 | 42 | [connection signal="timeout" from="Remove" to="." method="remove"] 43 | -------------------------------------------------------------------------------- /Players.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | onready var parent = get_parent() 4 | 5 | func load_players(): 6 | print("[CRUS ONLINE / PLAYERS]: Load players") 7 | 8 | reload_players() 9 | 10 | var puppetsNames = [] 11 | for puppetNode in get_children(): 12 | puppetsNames.append(int(puppetNode.name)) 13 | 14 | for key in parent.players.keys(): 15 | if not puppetsNames.has(key): 16 | var player = preload("res://MOD_CONTENT/CruS Online/multiplayer_player.tscn").instance() 17 | player.set_name(key) 18 | player.set_network_master(key) 19 | player.setup_puppet(key) 20 | player.nickname = parent.players[key].nickname 21 | player.skinPath = parent.players[key].skinPath 22 | player.color = parent.players[key].color 23 | player.singleton = parent 24 | add_child(player) 25 | parent.players[key]["puppet"] = player 26 | player.global_transform.origin = Vector3(-1000,-1000,-1000) 27 | player.transform_lerp.origin = Vector3(-1000,-1000,-1000) 28 | 29 | func reload_players(): 30 | print("[CRUS ONLINE / PLAYERS]: Reload players") 31 | for player in get_children(): 32 | player.player_restart() 33 | 34 | func remove_players(): 35 | print("[CRUS ONLINE / PLAYERS]: Remove players") 36 | for player in get_children(): 37 | player.queue_free() 38 | 39 | func sync_players(): 40 | print("[CRUS ONLINE / PLAYERS]: Sync players") 41 | print(get_children()) 42 | 43 | for player in get_children(): 44 | if parent.players[player.name] == null: 45 | player.queue_free() 46 | -------------------------------------------------------------------------------- /shell_physics.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | var velocity = Vector3.ZERO 4 | var angular_velocity 5 | 6 | var water : bool 7 | var gravity = 22 8 | 9 | var impact_sound : Array 10 | 11 | func _ready(): 12 | impact_sound = [ 13 | $Sound1, 14 | $Sound2, 15 | $Sound3 16 | ] 17 | 18 | func _physics_process(delta): 19 | var collision = move_and_collide(velocity * delta) 20 | 21 | global_rotation += angular_velocity 22 | 23 | if water: 24 | gravity = 2 25 | else : 26 | gravity = 22 27 | 28 | if collision: 29 | velocity = velocity.bounce(collision.normal) * 0.6 30 | 31 | if abs(velocity.length()) > 2: 32 | var current_sound = randi() % 3 33 | 34 | impact_sound[current_sound].pitch_scale += rand_range( - 0.1, 0.1) 35 | impact_sound[current_sound].pitch_scale = clamp(impact_sound[current_sound].pitch_scale, 0.8, 1.2) 36 | impact_sound[current_sound].unit_db = velocity.length() * 0.1 - 1 37 | impact_sound[current_sound].play() 38 | 39 | velocity.y -= gravity * delta 40 | angular_velocity = lerp(angular_velocity, Vector3.ZERO, delta * 2) 41 | 42 | func damage(damage, collision_n, collision_p, shooter_pos): 43 | if damage < 3: 44 | return 45 | velocity -= collision_n * damage 46 | 47 | angular_velocity = Vector3(rand_range(1,5),rand_range(1,5),rand_range(1,5)) 48 | 49 | func remove(): 50 | var tween = create_tween().set_trans(Tween.TRANS_QUINT).set_ease(Tween.EASE_IN) 51 | tween.tween_property(self,"scale",Vector3.ZERO,1) 52 | 53 | yield(tween,"finished") 54 | queue_free() 55 | -------------------------------------------------------------------------------- /Stats.gd: -------------------------------------------------------------------------------- 1 | extends PanelContainer 2 | 3 | onready var Multiplayer = Global.get_node("Multiplayer") 4 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 5 | 6 | onready var playersList = $VBoxContainer/PanelContainer/RichTextLabel 7 | 8 | var sizeRatio = 16 9 | 10 | func _ready(): 11 | hide() 12 | 13 | func set_size_ratio(): 14 | sizeRatio = 16 * (Global.resolution[0] / 1280) 15 | 16 | $VBoxContainer/PanelContainer/RichTextLabel.get_font("normal_font").size = sizeRatio 17 | $VBoxContainer/Label.get_font("font").size = sizeRatio 18 | 19 | func open_stats(type): 20 | show() 21 | set_size_ratio() 22 | $"../OpenStats".button_disable() 23 | $"../CloseStats".button_enable() 24 | 25 | func close_stats(type): 26 | hide() 27 | $"../OpenStats".button_enable() 28 | $"../CloseStats".button_disable() 29 | 30 | var tick = 0 31 | 32 | func _physics_process(delta): 33 | if visible and $"..".visible: 34 | tick += 1 35 | if tick % 15 == 0: 36 | var playerNumber = 1 37 | playersList.bbcode_text = "" 38 | 39 | for player in Multiplayer.players: 40 | playersList.bbcode_text += str(playerNumber) + ": [color=#" + Multiplayer.players[player].color + "]" + Multiplayer.players[player].nickname + "[/color]" 41 | 42 | if player == NetworkBridge.get_host_id(): 43 | playersList.bbcode_text += " (host)\n" 44 | else: 45 | playersList.bbcode_text += "\n" 46 | 47 | playerNumber += 1 48 | 49 | $VBoxContainer/PanelContainer/RichTextLabel.text += player.nickname 50 | 51 | print(playersList.bbcode_text) 52 | tick = 0 53 | -------------------------------------------------------------------------------- /help.txt.gd: -------------------------------------------------------------------------------- 1 | extends Node # extends my balls 2 | 3 | # TODO: Не забыть убрать весь этот мусор... 4 | 5 | # Desine sperare qui hic intras 6 | 7 | var frustration_count = 312 8 | 9 | # https://datatracker.ietf.org/doc/html/rfc2795 10 | 11 | var objectInstance 12 | 13 | func sync_object_spawn(objectParent): 14 | var object = objectInstance.instance() 15 | object.set_name(object.name + "#" + str(object.get_instance_id())) 16 | objectParent.add_child(object) 17 | rpc("_spawn_object", objectParent.get_path(), object.name, object.global_transform) 18 | 19 | puppet func _spawn_object(parentPath, recivedName, recivedTransform): 20 | var object = objectInstance.instance() 21 | object.set_name(recivedName) 22 | get_node(parentPath).add_child(object) 23 | object.global_transform = recivedTransform 24 | 25 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 26 | 27 | func _ready(): 28 | NetworkBridge.register_rpcs(self, [ 29 | ["_ass", NetworkBridge.PERMISSION.ALL], 30 | ["ass", NetworkBridge.PERMISSION.SERVER] 31 | ]) 32 | 33 | # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 34 | 35 | # 9 + 10 = 21 36 | # ^ you are stupid 37 | -------------------------------------------------------------------------------- /remaped/Player_Manager.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var player = $Player 4 | onready var cam_pos = $Position3D 5 | 6 | func _ready(): 7 | if Global.implants.head_implant.shrink: 8 | scale = Vector3(0.1, 0.1, 0.1) 9 | 10 | var respawnPoint = load("res://MOD_CONTENT/CruS Online/respawn_point.tscn").instance() 11 | get_node("..").call_deferred("add_child", respawnPoint) 12 | respawnPoint.global_transform.origin = self.global_transform.origin 13 | 14 | var respawnPoints = get_tree().get_nodes_in_group("Respawn") 15 | respawnPoints.shuffle() 16 | 17 | player.global_transform.origin = respawnPoints[0].global_transform.origin 18 | player.global_rotation.y = respawnPoints[0].global_rotation.y 19 | 20 | func _process(delta): 21 | if Input.is_action_just_pressed("Stocks"): 22 | $Stock_Menu.visible = not $Stock_Menu.visible 23 | if $Stock_Menu.visible: 24 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) 25 | $Position3D / Rotation_Helper / Weapon.disabled = true 26 | else : 27 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 28 | $Position3D / Rotation_Helper / Weapon.disabled = false 29 | var offset = Vector3(0, 1.481, 0) 30 | if Global.implants.head_implant.shrink: 31 | offset *= 0.1 32 | if player.max_gravity < 0: 33 | offset = Vector3(0, 0, 0) 34 | if Engine.get_frames_per_second() <= 30: 35 | cam_pos.global_transform.origin = player.global_transform.origin + offset 36 | else : 37 | cam_pos.global_transform.origin = lerp(cam_pos.global_transform.origin, player.global_transform.origin + offset, clamp(delta * 30, 0, 1)) 38 | 39 | cam_pos.rotation.y = player.rotation.y 40 | -------------------------------------------------------------------------------- /remaped/Player_Test.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://Entities/Player.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://Player_Manager.gd" type="Script" id=2] 5 | [ext_resource path="res://Entities/Rotation_Helper.tscn" type="PackedScene" id=3] 6 | [ext_resource path="res://Menu/Stock_Menu2.tscn" type="PackedScene" id=4] 7 | 8 | [node name="Player" type="Spatial"] 9 | script = ExtResource( 2 ) 10 | 11 | [node name="Player" parent="." groups=["Player"] instance=ExtResource( 1 )] 12 | interpolated_camera = true 13 | 14 | [node name="BoneAttachment" parent="Player/Body_Mesh/Armature/Skeleton" index="0"] 15 | transform = Transform( 0.999961, 0.000690037, 0.00876781, 0.000670931, 0.988027, -0.154278, -0.0087693, 0.154278, 0.987988, 0.000147821, 0.615141, 0.0506348 ) 16 | 17 | [node name="BoneAttachment 2" parent="Player/Body_Mesh/Armature/Skeleton" index="1"] 18 | transform = Transform( -0.0871775, 0.91109, 0.402883, -0.166965, -0.412065, 0.895726, 0.982101, 0.0108198, 0.188043, 0.696529, 0.397017, 0.0232771 ) 19 | 20 | [node name="Position3D" type="Position3D" parent="."] 21 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.481, 0 ) 22 | 23 | [node name="Rotation_Helper" parent="Position3D" instance=ExtResource( 3 )] 24 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) 25 | 26 | [node name="Camera" parent="Position3D/Rotation_Helper" index="1"] 27 | cull_mask = 1048567 28 | 29 | [node name="Stock_Menu" parent="." instance=ExtResource( 4 )] 30 | visible = false 31 | 32 | [editable path="Player"] 33 | [editable path="Player/Body_Mesh"] 34 | [editable path="Position3D/Rotation_Helper"] 35 | [editable path="Stock_Menu"] 36 | -------------------------------------------------------------------------------- /entities/Enemy_Melee_Weapon.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var damage:float = 75 6 | export var toxic = false 7 | onready var raycast:RayCast = $RayCast 8 | export var velocity_booster = false 9 | 10 | func _ready(): 11 | NetworkBridge.register_rpcs(self,[ 12 | ["play_sound", NetworkBridge.PERMISSION.SERVER], 13 | ]) 14 | 15 | puppet func play_sound(id): 16 | $Attack_Sound.play() 17 | 18 | func AI_shoot()->void : 19 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 20 | if raycast.is_colliding(): 21 | if raycast.get_collider().name == "Player" or raycast.get_collider().has_meta("puppet"): 22 | if velocity_booster: 23 | Global.player.player_velocity -= (global_transform.origin - Vector3.UP * 0.5 - Global.player.global_transform.origin).normalized() * damage 24 | var collider = raycast.get_collider() 25 | raycast.force_raycast_update() 26 | if toxic and collider.has_method("set_toxic"): 27 | collider.set_toxic() 28 | if collider.has_method("damage"): 29 | collider.damage(damage, Vector3(0, 0, 0), Vector3(0, 0, 0), global_transform.origin) 30 | raycast.enabled = false 31 | if is_instance_valid($Attack_Sound) and not $Attack_Sound.playing: 32 | $Attack_Sound.play() 33 | NetworkBridge.n_rpc(self, "play_sound") 34 | if get_parent().get_parent().anim_player.current_animation != "Attack": 35 | get_parent().get_parent().anim_player.play("Attack", - 1, 2) 36 | NetworkBridge.n_rpc(get_parent().get_parent(), "set_animation", "Attack", 2) 37 | yield (get_tree().create_timer(0.5), "timeout") 38 | raycast.enabled = true 39 | -------------------------------------------------------------------------------- /remaped/20_mm_shell.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=2] 2 | 3 | [ext_resource path="res://MOD_CONTENT/CruS Online/shell_physics.gd" type="Script" id=1] 4 | [ext_resource path="res://Imported_Mesh/20mmshell.obj" type="ArrayMesh" id=2] 5 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_1.wav" type="AudioStream" id=3] 6 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_2.wav" type="AudioStream" id=4] 7 | [ext_resource path="res://Sfx/WeaponsPickups/ammo_shell_3.wav" type="AudioStream" id=5] 8 | [ext_resource path="res://Textures/Particles/Generic_Shell.png" type="Texture" id=6] 9 | 10 | [sub_resource type="CylinderShape" id=1] 11 | height = 0.255391 12 | radius = 0.0372182 13 | 14 | [sub_resource type="SpatialMaterial" id=2] 15 | albedo_texture = ExtResource( 6 ) 16 | 17 | [node name="Shell" type="KinematicBody"] 18 | collision_layer = 0 19 | script = ExtResource( 1 ) 20 | 21 | [node name="CollisionShape" type="CollisionShape" parent="."] 22 | shape = SubResource( 1 ) 23 | 24 | [node name="Sound1" type="AudioStreamPlayer3D" parent="."] 25 | stream = ExtResource( 3 ) 26 | bus = "SFX" 27 | 28 | [node name="Sound2" type="AudioStreamPlayer3D" parent="."] 29 | stream = ExtResource( 4 ) 30 | bus = "SFX" 31 | 32 | [node name="Sound3" type="AudioStreamPlayer3D" parent="."] 33 | stream = ExtResource( 5 ) 34 | bus = "SFX" 35 | 36 | [node name="Generic_Shell" type="Spatial" parent="."] 37 | 38 | [node name="Shell" type="MeshInstance" parent="Generic_Shell"] 39 | material_override = SubResource( 2 ) 40 | mesh = ExtResource( 2 ) 41 | 42 | [node name="Remove" type="Timer" parent="."] 43 | wait_time = 15.0 44 | one_shot = true 45 | autostart = true 46 | 47 | [connection signal="timeout" from="Remove" to="." method="remove"] 48 | -------------------------------------------------------------------------------- /effects/fake_Radiation.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [sub_resource type="SpatialMaterial" id=1] 4 | flags_transparent = true 5 | params_blend_mode = 2 6 | albedo_color = Color( 1, 0.47451, 0.356863, 0.0862745 ) 7 | metallic_specular = 0.0 8 | transmission_enabled = true 9 | transmission = Color( 1, 0, 0, 1 ) 10 | 11 | [sub_resource type="Curve" id=2] 12 | max_value = 1.98 13 | _data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.533679, 1.90578 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ] 14 | 15 | [sub_resource type="CurveTexture" id=3] 16 | curve = SubResource( 2 ) 17 | 18 | [sub_resource type="ParticlesMaterial" id=4] 19 | emission_shape = 1 20 | emission_sphere_radius = 1.89 21 | spread = 180.0 22 | gravity = Vector3( 0, 0, 0 ) 23 | initial_velocity = 0.29 24 | scale_curve = SubResource( 3 ) 25 | 26 | [sub_resource type="SphereMesh" id=5] 27 | radial_segments = 4 28 | rings = 4 29 | 30 | [sub_resource type="GDScript" id=6] 31 | script/source = "extends Particles 32 | 33 | onready var NetworkBridge = Global.get_node(\"Multiplayer/NetworkBridge\") 34 | 35 | func _ready(): 36 | NetworkBridge.register_rpcs(self,[ 37 | [\"_set_transform\", NetworkBridge.PERMISSION.SERVER], 38 | [\"_delete\", NetworkBridge.PERMISSION.SERVER], 39 | ]) 40 | 41 | puppet func _set_transform(id, recivedTransform): 42 | global_transform = recivedTransform 43 | 44 | puppet func _delete(id): 45 | hide() 46 | global_translation = Vector3(-1000, -1000, -1000) 47 | 48 | set_process(false) 49 | set_physics_process(false) 50 | " 51 | 52 | [node name="Particles" type="Particles"] 53 | material_override = SubResource( 1 ) 54 | amount = 4 55 | lifetime = 3.27 56 | preprocess = 1.0 57 | process_material = SubResource( 4 ) 58 | draw_pass_1 = SubResource( 5 ) 59 | script = SubResource( 6 ) 60 | -------------------------------------------------------------------------------- /effects/fake_Missile_Kinematic.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Entities/Particles/Smoke_1.tscn" type="PackedScene" id=2] 4 | [ext_resource path="res://Sfx/WeaponsPickups/Rocket launcher/missile_flying_loop.wav" type="AudioStream" id=3] 5 | 6 | [sub_resource type="GDScript" id=1] 7 | script/source = "extends Spatial 8 | 9 | onready var NetworkBridge = Global.get_node(\"Multiplayer/NetworkBridge\") 10 | 11 | func _ready(): 12 | NetworkBridge.register_rpcs(self,[ 13 | [\"_set_transform\", NetworkBridge.PERMISSION.SERVER], 14 | [\"_delete\", NetworkBridge.PERMISSION.SERVER], 15 | [\"_create_object\", NetworkBridge.PERMISSION.SERVER] 16 | ]) 17 | 18 | 19 | puppet func _set_transform(id, recivedTransform): 20 | global_transform = recivedTransform 21 | 22 | puppet func _delete(id): 23 | hide() 24 | global_translation = Vector3(-1000, -1000, -1000) 25 | 26 | set_process(false) 27 | set_physics_process(false) 28 | 29 | puppet func _create_object(id, recivedPath, recivedObject, recivedName, recivedTransform, recivedShrapnel = null): 30 | var newObject = load(recivedObject).instance() 31 | newObject.set_name(recivedName) 32 | get_node(recivedPath).add_child(newObject) 33 | newObject.global_transform = recivedTransform 34 | if recivedShrapnel != null: 35 | newObject.shrapnel_flag = recivedShrapnel 36 | " 37 | 38 | [node name="Spatial" type="Spatial"] 39 | script = SubResource( 1 ) 40 | 41 | [node name="Smoke_Particle" parent="." instance=ExtResource( 2 )] 42 | transform = Transform( 0.123153, 0, 0, 0, 0.123153, 0, 0, 0, 0.123153, 0.00448698, 0, 0 ) 43 | lifetime = 7.54 44 | speed_scale = 8.53 45 | fixed_fps = 30 46 | 47 | [node name="Sound" type="AudioStreamPlayer3D" parent="."] 48 | stream = ExtResource( 3 ) 49 | unit_size = 8.2 50 | max_db = 1.956 51 | autoplay = true 52 | bus = "SFX" 53 | -------------------------------------------------------------------------------- /Menu.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | onready var NetworkBridge = $"../NetworkBridge" 4 | 5 | onready var parent = get_parent() 6 | 7 | func _ready(): 8 | rect_scale = Vector2(Global.resolution[0] / 1280 ,Global.resolution[1] / 720 ) 9 | hide() 10 | set_process_input(false) 11 | 12 | func hide_menu(type = null): 13 | hide() 14 | get_parent().Hint.hide() 15 | Input.mouse_mode = Input.MOUSE_MODE_CAPTURED 16 | Global.player.weapon.disabled = false 17 | 18 | Global.player.set_process(true) 19 | Global.player.set_physics_process(true) 20 | Global.player.set_process_input(true) 21 | Global.player.set_process_unhandled_key_input(true) 22 | 23 | func show_menu(type = null): 24 | rect_scale = Vector2(Global.resolution[0] / 1280 ,Global.resolution[1] / 720 ) 25 | show() 26 | Input.mouse_mode = Input.MOUSE_MODE_VISIBLE 27 | Global.player.weapon.disabled = true 28 | 29 | Global.player.set_process(false) 30 | Global.player.set_physics_process(false) 31 | Global.player.set_process_input(false) 32 | Global.player.set_process_unhandled_key_input(false) 33 | 34 | func _input(event): 35 | if Input.is_action_just_pressed("ui_cancel"): 36 | if visible: 37 | hide_menu() 38 | else: 39 | show_menu() 40 | 41 | func leave_server(type): 42 | hide_menu() 43 | set_process_input(false) 44 | Input.mouse_mode = Input.MOUSE_MODE_VISIBLE 45 | 46 | if NetworkBridge.n_is_network_master(self): 47 | parent.goto_menu_host() 48 | else: 49 | for child in parent.Players.get_children(): 50 | child.queue_free() 51 | 52 | parent.goto_menu_client(null) 53 | parent.leave_server() 54 | 55 | func leave_game(type): 56 | hide_menu() 57 | set_process_input(false) 58 | Input.mouse_mode = Input.MOUSE_MODE_VISIBLE 59 | 60 | for child in parent.Players.get_children(): 61 | child.queue_free() 62 | 63 | parent.leave_server() 64 | get_tree().quit() 65 | -------------------------------------------------------------------------------- /effects/fake_self_destruct_explosion.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=2] 2 | 3 | [ext_resource path="res://Textures/Particles/Explosion1.png" type="Texture" id=1] 4 | 5 | [sub_resource type="GDScript" id=9] 6 | script/source = "extends Spatial 7 | 8 | func _ready(): 9 | $Particle.emitting = true 10 | 11 | func delete(): 12 | queue_free() 13 | " 14 | 15 | [sub_resource type="Curve" id=4] 16 | _data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 0.0, 0.0, 0, 0 ] 17 | 18 | [sub_resource type="CurveTexture" id=5] 19 | curve = SubResource( 4 ) 20 | 21 | [sub_resource type="ParticlesMaterial" id=6] 22 | lifetime_randomness = 0.09 23 | trail_divisor = 6 24 | trail_size_modifier = SubResource( 5 ) 25 | emission_shape = 1 26 | emission_sphere_radius = 0.82 27 | flag_rotate_y = true 28 | direction = Vector3( 0, 1, 0 ) 29 | spread = 180.0 30 | gravity = Vector3( 0, 0, 0 ) 31 | initial_velocity = 24.95 32 | initial_velocity_random = 0.34 33 | scale = 5.22 34 | scale_random = 0.21 35 | 36 | [sub_resource type="SpatialMaterial" id=7] 37 | flags_unshaded = true 38 | params_blend_mode = 1 39 | params_billboard_mode = 1 40 | params_billboard_keep_scale = true 41 | params_use_alpha_scissor = true 42 | params_alpha_scissor_threshold = 0.98 43 | albedo_color = Color( 0.152941, 0.898039, 0, 1 ) 44 | albedo_texture = ExtResource( 1 ) 45 | 46 | [sub_resource type="QuadMesh" id=8] 47 | material = SubResource( 7 ) 48 | 49 | [node name="Explosion" type="Spatial"] 50 | script = SubResource( 9 ) 51 | 52 | [node name="Particle" type="Particles" parent="."] 53 | emitting = false 54 | amount = 200 55 | lifetime = 0.28 56 | one_shot = true 57 | randomness = 1.0 58 | fract_delta = false 59 | local_coords = false 60 | process_material = SubResource( 6 ) 61 | draw_pass_1 = SubResource( 8 ) 62 | 63 | [node name="Timer" type="Timer" parent="."] 64 | wait_time = 5.0 65 | one_shot = true 66 | autostart = true 67 | 68 | [connection signal="timeout" from="Timer" to="." method="delete"] 69 | -------------------------------------------------------------------------------- /effects/fake_Grenade.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://Textures/Weapons/Gas_Launcher.png" type="Texture" id=2] 4 | [ext_resource path="res://Imported_Mesh/Weapon_Mesh_Only/Gas_Grenade.obj" type="ArrayMesh" id=4] 5 | 6 | [sub_resource type="GDScript" id=2] 7 | script/source = "extends KinematicBody 8 | 9 | onready var NetworkBridge = Global.get_node(\"Multiplayer/NetworkBridge\") 10 | 11 | func _ready(): 12 | NetworkBridge.register_rpcs(self,[ 13 | [\"_set_transform\", NetworkBridge.PERMISSION.SERVER], 14 | [\"_delete\", NetworkBridge.PERMISSION.SERVER], 15 | [\"_spawn_shrapnel\", NetworkBridge.PERMISSION.SERVER], 16 | [\"_create_object\", NetworkBridge.PERMISSION.SERVER] 17 | ]) 18 | 19 | puppet func _set_transform(id, recivedTransform): 20 | global_transform = recivedTransform 21 | 22 | puppet func _delete(id): 23 | hide() 24 | global_translation = Vector3(-1000, -1000, -1000) 25 | 26 | set_process(false) 27 | set_physics_process(false) 28 | 29 | puppet func _spawn_shrapnel(id, recivedPath, recivedObject,recivedName,recivedTransform,recivedShrapnel): 30 | var newObject = load(recivedObject).instance() 31 | newObject.set_name(recivedName) 32 | get_node(recivedPath).add_child(newObject) 33 | newObject.global_transform = recivedTransform 34 | newObject.shrapnel_flag = recivedShrapnel 35 | 36 | puppet func _create_object(id, recivedPath, recivedObject, recivedName, recivedTransform): 37 | var newObject = load(recivedObject).instance() 38 | newObject.set_name(recivedName) 39 | get_node(recivedPath).add_child(newObject) 40 | newObject.global_transform = recivedTransform 41 | " 42 | 43 | [sub_resource type="SpatialMaterial" id=1] 44 | albedo_texture = ExtResource( 2 ) 45 | 46 | [node name="Spatial" type="KinematicBody"] 47 | collision_layer = 0 48 | collision_mask = 17 49 | collision/safe_margin = 0.002 50 | script = SubResource( 2 ) 51 | 52 | [node name="MeshInstance" type="MeshInstance" parent="."] 53 | material_override = SubResource( 1 ) 54 | mesh = ExtResource( 4 ) 55 | -------------------------------------------------------------------------------- /Steam.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | onready var Multiplayer = Global.get_node("Multiplayer") 4 | 5 | onready var Steam = preload("res://addons/godotsteam/godotsteam.gdns").new() 6 | 7 | var is_on_steam_deck: bool = false 8 | var is_online: bool = false 9 | var is_owned: bool = false 10 | var steam_app_id: int = 1388770 11 | var steam_id: int = 0 12 | var steam_username: String = "" 13 | 14 | onready var SteamNetwork = $SteamNetwork 15 | onready var SteamLobby = $SteamLobby 16 | 17 | func _ready() -> void: 18 | OS.set_environment("SteamAppId", str(steam_app_id)) 19 | OS.set_environment("SteamGameId", str(steam_app_id)) 20 | 21 | var args = OS.get_cmdline_args() 22 | 23 | if args.size() > 0: 24 | for arg in args: 25 | if arg == "+crus_online_debug_1": 26 | print("[CRUS ONLINE / DEBUG] ipc name: crus_online_debug_1") 27 | OS.set_environment("steam_master_ipc_name_override", "crus_online_debug_1") 28 | elif arg == "+crus_online_debug_2": 29 | print("[CRUS ONLINE / DEBUG] ipc name: crus_online_debug_2") 30 | OS.set_environment("steam_master_ipc_name_override", "crus_online_debug_2") 31 | 32 | var initialize_response = Steam.steamInit() 33 | 34 | print("[CRUS ONLINE / STEAM]\n") 35 | 36 | print("Did Steam initialize?: %s" % initialize_response) 37 | 38 | # if initialize_response['status'] > 0: 39 | # print("Failed to initialize Steam, shutting down: %s" % initialize_response) 40 | # get_tree().quit() 41 | 42 | is_on_steam_deck = Steam.isSteamRunningOnSteamDeck() 43 | is_online = Steam.loggedOn() 44 | is_owned = Steam.isSubscribed() 45 | steam_id = Steam.getSteamID() 46 | steam_username = Steam.getPersonaName() 47 | 48 | print("Is on steam deck?: %s" % is_on_steam_deck) 49 | print("Is online?: %s" % is_online) 50 | print("Is is owned?: %s" % is_owned) 51 | print("Steam ID: %s" % steam_id) 52 | print("Steam Username: %s" % steam_username) 53 | 54 | # Check if account owns the game 55 | if is_owned == false: 56 | print("User does not own this game") 57 | #get_tree().quit() 58 | 59 | print("\n[ CRUS ONLINE / STEAM ]") 60 | 61 | $SteamLobby.lobby_init() 62 | 63 | func _process(_delta: float) -> void: 64 | Steam.run_callbacks() 65 | -------------------------------------------------------------------------------- /effects/fake_poison_gas.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=2] 2 | 3 | [ext_resource path="res://Sfx/NPCs/Melee mutant/poison_mist.wav" type="AudioStream" id=1] 4 | [ext_resource path="res://Textures/Particles/Explosion1.png" type="Texture" id=2] 5 | 6 | [sub_resource type="GDScript" id=8] 7 | script/source = "extends Spatial 8 | 9 | func _ready(): 10 | $Particle.emitting = true 11 | 12 | func delete(): 13 | queue_free() 14 | " 15 | 16 | [sub_resource type="Curve" id=9] 17 | max_value = 1.88 18 | _data = [ Vector2( 0, 0.401649 ), 0.0, 0.0, 0, 0, Vector2( 1, 1.88 ), 0.0, 0.0, 0, 0 ] 19 | 20 | [sub_resource type="CurveTexture" id=5] 21 | curve = SubResource( 9 ) 22 | 23 | [sub_resource type="ParticlesMaterial" id=10] 24 | emission_shape = 1 25 | emission_sphere_radius = 1.55 26 | flag_rotate_y = true 27 | direction = Vector3( 0, 1, 0 ) 28 | spread = 180.0 29 | gravity = Vector3( 0, 0, 0 ) 30 | initial_velocity = 0.59 31 | damping = 0.41 32 | scale = 3.44 33 | scale_curve = SubResource( 5 ) 34 | 35 | [sub_resource type="SpatialMaterial" id=7] 36 | flags_transparent = true 37 | flags_unshaded = true 38 | params_blend_mode = 1 39 | params_billboard_mode = 1 40 | params_billboard_keep_scale = true 41 | params_use_alpha_scissor = true 42 | params_alpha_scissor_threshold = 0.98 43 | albedo_color = Color( 0, 0.341176, 0.00392157, 1 ) 44 | albedo_texture = ExtResource( 2 ) 45 | 46 | [sub_resource type="QuadMesh" id=11] 47 | material = SubResource( 7 ) 48 | 49 | [node name="Gas" type="Spatial"] 50 | script = SubResource( 8 ) 51 | 52 | [node name="Particle" type="Particles" parent="."] 53 | emitting = false 54 | amount = 58 55 | lifetime = 4.03 56 | one_shot = true 57 | randomness = 1.0 58 | fract_delta = false 59 | local_coords = false 60 | process_material = SubResource( 10 ) 61 | draw_pass_1 = SubResource( 11 ) 62 | 63 | [node name="Timer" type="Timer" parent="."] 64 | wait_time = 10.0 65 | one_shot = true 66 | autostart = true 67 | 68 | [node name="Sound" type="AudioStreamPlayer3D" parent="."] 69 | stream = ExtResource( 1 ) 70 | unit_db = 4.0 71 | unit_size = 6.5 72 | max_db = 4.0 73 | autoplay = true 74 | 75 | [connection signal="timeout" from="Timer" to="." method="delete"] 76 | -------------------------------------------------------------------------------- /remaped/Berries.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | enum {SPEED, FLOATY, TOXIC, PSYCHOSIS, CANCER, GRAVITY} 6 | 7 | export var pills = false 8 | export var toxic = false 9 | export var healing = false 10 | export var healing_amount = 25 11 | export var kinematic = false 12 | 13 | func _ready(): 14 | NetworkBridge.register_rpcs(self, [ 15 | ["check_food", NetworkBridge.PERMISSION.ALL], 16 | ["delete", NetworkBridge.PERMISSION.ALL], 17 | ["kinematic_delete", NetworkBridge.PERMISSION.ALL] 18 | ]) 19 | 20 | if not NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 21 | NetworkBridge.n_rpc(self, "check_food") 22 | 23 | master func check_food(id): 24 | if $CollisionShape.disabled: 25 | if kinematic: 26 | NetworkBridge.n_rpc_id(self, id, "kinematic_delete") 27 | else: 28 | NetworkBridge.n_rpc_id(self, id, "delete") 29 | 30 | remote func delete(id): 31 | $CollisionShape.disabled = true 32 | hide() 33 | 34 | remote func kinematic_delete(id): 35 | $CollisionShape.disabled = true 36 | get_parent().hide() 37 | 38 | func player_use(): 39 | if pills: 40 | match randi() % 6: 41 | SPEED: 42 | Global.player.drug_speed = 50 43 | FLOATY: 44 | Global.player.drug_slowfall = 150 45 | TOXIC: 46 | Global.player.set_toxic() 47 | PSYCHOSIS: 48 | Global.player.psychocounter = 200 49 | CANCER: 50 | Global.player.cancer_count = 9 51 | Global.player.cancer() 52 | GRAVITY: 53 | Global.player.drug_gravity_flag = true 54 | get_parent().get_node("AudioStreamPlayer3D").play() 55 | get_parent().hide() 56 | Global.player.UI.notify("You ate pills.", Color(1, 0.0, 1.0)) 57 | delete(null) 58 | NetworkBridge.n_rpc(self, "delete") 59 | if healing: 60 | Global.player.add_health(healing_amount) 61 | if kinematic: 62 | kinematic_delete(null) 63 | NetworkBridge.n_rpc(self, "kinematic_delete") 64 | delete(null) 65 | NetworkBridge.n_rpc(self, "delete") 66 | if toxic: 67 | Global.player.set_toxic() 68 | delete(null) 69 | NetworkBridge.n_rpc(self, "delete") 70 | else : 71 | Global.player.detox() 72 | delete(null) 73 | NetworkBridge.n_rpc(self, "delete") 74 | -------------------------------------------------------------------------------- /ChatBox.gd: -------------------------------------------------------------------------------- 1 | extends PanelContainer 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var in_game_chat = true 6 | 7 | onready var textBox = $VBoxContainer/PanelContainer/RichTextLabel 8 | onready var lineEdit = $VBoxContainer/LineEdit 9 | onready var labelText = $VBoxContainer/Label 10 | 11 | onready var parent = Global.get_node("Multiplayer") 12 | 13 | var sizeRatio = 16 14 | 15 | func _ready(): 16 | NetworkBridge.register_rpcs(self,[ 17 | ["send_message_host", NetworkBridge.PERMISSION.ALL], 18 | ["send_message", NetworkBridge.PERMISSION.SERVER] 19 | ]) 20 | 21 | if in_game_chat: 22 | hide() 23 | 24 | func set_size_ratio(): 25 | sizeRatio = 16 * (Global.resolution[0] / 1280) 26 | 27 | textBox.get_font("normal_font").size = sizeRatio 28 | lineEdit.get_font("font").size = sizeRatio 29 | labelText.get_font("font").size = sizeRatio 30 | 31 | master func send_message_host(id, message, author, img = "null", color = "ff0000"): 32 | NetworkBridge.n_rpc(self, "send_message", [message, author, img, color]) 33 | send_message(null, message, author, img, color) 34 | 35 | puppet func send_message(id, message, author, img = "null", color = "ff0000"): 36 | var rawText = '\n' 37 | 38 | if img != "null": 39 | rawText = rawText + '[img=32]' + img + '[/img] ' 40 | 41 | if color != "ff0000": 42 | rawText = rawText + '[color=#' + color + ']' 43 | 44 | rawText = rawText + author + ': ' + message 45 | 46 | textBox.bbcode_text = textBox.bbcode_text + rawText 47 | $AudioStreamPlayer.play() 48 | 49 | if in_game_chat: 50 | Global.UI.notify(message, Color(1, 0, 0)) 51 | Global.UI.notify(author + ":", Color(color)) 52 | 53 | func _text_entered(new_text): 54 | if new_text != "": 55 | if NetworkBridge.n_is_network_master(self): 56 | send_message_host(null, new_text, parent.playerInfo.nickname, parent.playerInfo.image, parent.playerInfo.color) 57 | else: 58 | NetworkBridge.n_rpc(self, "send_message_host", [new_text, parent.playerInfo.nickname, parent.playerInfo.image, parent.playerInfo.color]) 59 | lineEdit.text = "" 60 | 61 | func open_chat(type): 62 | show() 63 | set_size_ratio() 64 | $"../OpenChat".button_disable() 65 | $"../CloseChat".button_enable() 66 | 67 | func close_chat(type): 68 | hide() 69 | $"../OpenChat".button_enable() 70 | $"../CloseChat".button_disable() 71 | -------------------------------------------------------------------------------- /remaped/Elevator.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var stopped = true 6 | var speed = - 2 7 | var initpos = true 8 | var last_pos 9 | var col = false 10 | var mesh_instance:MeshInstance 11 | var collision_area:Area 12 | var collision_object:CollisionShape 13 | var bell_audio:AudioStreamPlayer3D 14 | var move_audio:AudioStreamPlayer3D 15 | 16 | func _ready(): 17 | NetworkBridge.register_rpcs(self, [ 18 | ["stop", NetworkBridge.PERMISSION.ALL], 19 | ["network_use", NetworkBridge.PERMISSION.ALL] 20 | ]) 21 | 22 | NetworkBridge.register_rset(self, "global_transform", NetworkBridge.PERMISSION.SERVER) 23 | rset_config("global_transform",MultiplayerAPI.RPC_MODE_PUPPET) 24 | 25 | for child in get_children(): 26 | if child is MeshInstance: 27 | mesh_instance = child 28 | set_collision_mask_bit(9, 1) 29 | set_collision_mask_bit(8, 1) 30 | set_collision_layer_bit(8, 1) 31 | set_collision_mask_bit(0, 0) 32 | bell_audio = AudioStreamPlayer3D.new() 33 | add_child(bell_audio) 34 | bell_audio.unit_size = 10 35 | bell_audio.unit_db = 3 36 | bell_audio.global_transform.origin = global_transform.origin 37 | move_audio = bell_audio.duplicate() 38 | add_child(move_audio) 39 | move_audio.unit_db = 2 40 | bell_audio.stream = load("res://Sfx/Environment/Elevator_Bell.wav") 41 | move_audio.stream = load("res://Sfx/Environment/Elevator_Move.wav") 42 | 43 | func _process(delta): 44 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 45 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 46 | 47 | last_pos = global_transform.origin 48 | if not stopped: 49 | if not move_audio.playing: 50 | move_audio.play() 51 | translate(Vector3(0, speed * delta, 0)) 52 | 53 | master func stop(id): 54 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 55 | stopped = true 56 | initpos = not initpos 57 | speed = - speed 58 | bell_audio.play() 59 | move_audio.stop() 60 | else: 61 | NetworkBridge.n_rpc(self, "stop") 62 | 63 | func use(): 64 | network_use(null) 65 | 66 | master func network_use(id): 67 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 68 | stopped = false 69 | else: 70 | NetworkBridge.n_rpc(self, "network_use") 71 | -------------------------------------------------------------------------------- /remaped/down_switch_door.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var door_health = 100 6 | export var speed = 2 7 | var open = false 8 | var stop = true 9 | var initrot = rotation 10 | var movement_counter = 0 11 | var mesh_instance 12 | var collision_shape 13 | var collision = false 14 | var found_overlap 15 | var sfx = preload("res://Sfx/Environment/door_concrete.wav") 16 | var audio_player:AudioStreamPlayer3D 17 | 18 | func _ready(): 19 | rset_config("global_transform", MultiplayerAPI.RPC_MODE_PUPPET) 20 | NetworkBridge.register_rset(self, "global_transform", NetworkBridge.PERMISSION.SERVER) 21 | 22 | NetworkBridge.register_rpcs(self, [ 23 | ["switch_use", NetworkBridge.PERMISSION.ALL] 24 | ]) 25 | 26 | audio_player = AudioStreamPlayer3D.new() 27 | audio_player.stream = sfx 28 | add_child(audio_player) 29 | for child in get_children(): 30 | if child is MeshInstance: 31 | mesh_instance = child 32 | if child is CollisionShape: 33 | collision_shape = child 34 | var t = mesh_instance.transform 35 | global_transform.origin.x -= mesh_instance.get_aabb().position.x 36 | global_transform.origin.z -= mesh_instance.get_aabb().position.z 37 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x, 0, mesh_instance.get_aabb().position.z)) 38 | mesh_instance.transform = t 39 | collision_shape.transform = t 40 | 41 | func _physics_process(delta): 42 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 43 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 44 | 45 | if not open and not stop: 46 | if not audio_player.playing: 47 | audio_player.play() 48 | translation.y += speed * delta 49 | movement_counter += speed * delta 50 | if open and not stop: 51 | if not audio_player.playing: 52 | audio_player.play() 53 | translation.y -= speed * delta 54 | movement_counter += speed * delta 55 | if movement_counter > mesh_instance.get_aabb().size.y + 0.1: 56 | audio_player.stop() 57 | movement_counter = 0 58 | stop = true 59 | 60 | master func switch_use(id): 61 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 62 | if stop and not open: 63 | open = not open 64 | stop = not stop 65 | else: 66 | NetworkBridge.n_rpc(self, "switch_use") 67 | -------------------------------------------------------------------------------- /remaped/Explosion.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var damage = 50 6 | export var gas = false 7 | export var sleep = false 8 | export var piercing = true 9 | var c_shape 10 | var particle 11 | 12 | var gas_timer = 0 13 | 14 | func _delete(): 15 | queue_free() 16 | 17 | func _ready(): 18 | particle = $Particle 19 | c_shape = $CollisionShape 20 | particle.emitting = true 21 | 22 | func _physics_process(delta): 23 | if NetworkBridge.n_is_network_master(self): 24 | if particle.emitting == false: 25 | if not gas: 26 | c_shape.disabled = true 27 | c_shape.visible = false 28 | else : 29 | gas_timer += delta 30 | if gas_timer >= 3: 31 | _delete() 32 | if gas and not sleep: 33 | for overlap_body in get_overlapping_bodies(): 34 | if overlap_body.has_method("player_damage"): 35 | overlap_body.player_damage(damage, Vector3.ZERO, overlap_body.global_transform.origin, global_transform.origin, "gas") 36 | elif overlap_body.has_method("damage"): 37 | overlap_body.damage(damage, Vector3.ZERO, overlap_body.global_transform.origin, global_transform.origin) 38 | 39 | func _on_Explosion_area_entered(area): 40 | if NetworkBridge.n_is_network_master(self): 41 | do_damage(area) 42 | 43 | func _on_Explosion_body_entered(body): 44 | if NetworkBridge.n_is_network_master(self): 45 | do_damage(body) 46 | if sleep and body.has_method("tranquilize"): 47 | body.tranquilize(true) 48 | 49 | func do_damage(body): 50 | if gas: 51 | return 52 | var state = get_world().direct_space_state 53 | var result = state.intersect_ray(global_transform.origin, body.global_transform.origin, [self]) 54 | if result: 55 | if result.collider.get_class() == "StaticBody": 56 | if result.collider.has_method("damage"): 57 | return 58 | if body.has_method("damage"): 59 | if body == Global.player and Global.implants.torso_implant.explosive_shield: 60 | Global.player.player_velocity -= (global_transform.origin - body.global_transform.origin).normalized() * damage * 0.05 61 | return 62 | body.damage(damage, (global_transform.origin - body.global_transform.origin).normalized(), body.global_transform.origin, global_transform.origin) 63 | if body.has_method("piercing_damage") and piercing: 64 | body.piercing_damage(damage, (global_transform.origin - body.global_transform.origin).normalized(), body.global_transform.origin, global_transform.origin) 65 | -------------------------------------------------------------------------------- /maps_stuff/WeaponSpawner.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var activeWeapon = null 6 | onready var weaponModels = get_node("Weapons").get_children() 7 | 8 | const maxAmmo = [24, 60, 5, 0, 25, 5, 6, 90, 50, 20, 0, 0, 20, 9, 0, 100, 0, 0, 200, 90, 72, 72, 18, 0, 0, 30, 200, 20, 90] 9 | 10 | export var rotateSpeed = 0.1 11 | export var respawnWeaponIds = [0] 12 | export var respawnTime = 5 13 | 14 | remote func _disable(id, disable): 15 | $Collect/CollisionShape.disabled = disable 16 | 17 | if NetworkBridge.n_is_network_master(self): 18 | NetworkBridge.n_rpc(self, "_disable", [disable]) 19 | 20 | remote func _set_weapon(id, weaponId): 21 | if activeWeapon != null: 22 | weaponModels[activeWeapon].hide() 23 | 24 | activeWeapon = weaponId 25 | 26 | if activeWeapon != null: 27 | weaponModels[activeWeapon].show() 28 | 29 | if NetworkBridge.n_is_network_master(self): 30 | NetworkBridge.n_rpc(self, "_set_weapon", [weaponId]) 31 | 32 | remote func _enable_timer(id): 33 | if NetworkBridge.n_is_network_master(self): 34 | $Timer.start() 35 | else: 36 | NetworkBridge.n_rpc(self, "_enable_timer") 37 | 38 | func _ready(): 39 | NetworkBridge.register_rpcs(self,[ 40 | ["_set_weapon", NetworkBridge.PERMISSION.ALL], 41 | ["_disable", NetworkBridge.PERMISSION.ALL], 42 | ["_enable_timer", NetworkBridge.PERMISSION.ALL] 43 | ]) 44 | 45 | $Timer.wait_time = respawnTime 46 | $Timer.connect("timeout", self, "_selectWeapon") 47 | 48 | func _physics_process(delta): 49 | $Weapons.rotate_y(rotateSpeed) 50 | 51 | func collected(): 52 | if activeWeapon != null: 53 | if (activeWeapon != Global.player.weapon.weapon1 and activeWeapon != Global.player.weapon.weapon2) or Global.player.weapon.current_weapon == activeWeapon: 54 | Global.player.weapon.magazine_ammo[activeWeapon] = Global.player.weapon.MAX_MAG_AMMO[activeWeapon] 55 | if Global.player.weapon.ammo[activeWeapon] < maxAmmo[activeWeapon]: 56 | Global.player.weapon.ammo[activeWeapon] = maxAmmo[activeWeapon] 57 | Global.player.weapon.set_weapon(activeWeapon) 58 | 59 | if not NetworkBridge.n_is_network_master(self): 60 | NetworkBridge.n_rpc(self, "_disable", [true]) 61 | NetworkBridge.n_rpc(self, "_set_weapon", [null]) 62 | 63 | _set_weapon(null, null) 64 | _disable(null, true) 65 | 66 | _enable_timer(null) 67 | 68 | func _selectWeapon(): 69 | respawnWeaponIds.shuffle() 70 | _set_weapon(null, respawnWeaponIds[0]) 71 | _disable(null, false) 72 | -------------------------------------------------------------------------------- /remaped/Exit.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var Multiplayer = Global.get_node("Multiplayer") 6 | 7 | var exitPlayers = [] 8 | var exitTimer 9 | 10 | var exiting = false 11 | 12 | func _ready(): 13 | connect("body_entered", self, "_on_Body_entered") 14 | connect("body_exited", self, "_on_Body_exited") 15 | 16 | NetworkBridge.register_rpcs(self, [ 17 | ["send_player_count", NetworkBridge.PERMISSION.SERVER], 18 | ["send_exit_message", NetworkBridge.PERMISSION.SERVER], 19 | ["player_exited", NetworkBridge.PERMISSION.ALL], 20 | ["player_entered", NetworkBridge.PERMISSION.ALL] 21 | ]) 22 | 23 | exitTimer = Timer.new() 24 | add_child(exitTimer) 25 | exitTimer.wait_time = 5 26 | exitTimer.connect("timeout", self , "exit_to_menu") 27 | 28 | func _on_Body_exited(body): 29 | if body.name == "Player": 30 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 31 | player_exited(NetworkBridge.get_host_id()) 32 | else: 33 | NetworkBridge.n_rpc(self, "player_exited") 34 | 35 | func _on_Body_entered(body): 36 | if body.name == "Player": 37 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 38 | player_entered(NetworkBridge.get_host_id()) 39 | else: 40 | NetworkBridge.n_rpc(self, "player_entered") 41 | 42 | master func player_exited(id): 43 | if exitPlayers.has(id): 44 | exitPlayers.erase(id) 45 | 46 | master func player_entered(id): 47 | if not exitPlayers.has(id): 48 | exitPlayers.append(id) 49 | 50 | var all_player_entered = true 51 | 52 | for player in Multiplayer.players: 53 | if not exitPlayers.has(player): 54 | all_player_entered = false 55 | 56 | if Global.objective_complete: 57 | if all_player_entered: 58 | if not exiting: 59 | exiting = true 60 | send_exit_message(null) 61 | NetworkBridge.n_rpc(self, "send_exit_message") 62 | exitTimer.start() 63 | else: 64 | if NetworkBridge.n_is_network_master(self): 65 | send_player_count(null, len(exitPlayers), len(Multiplayer.players)) 66 | else: 67 | NetworkBridge.n_rpc_id(self, id, "send_player_count", [len(exitPlayers), len(Multiplayer.players)]) 68 | 69 | puppet func send_player_count(id, exitCount, hostCount): 70 | Global.UI.notify(str(exitCount) + "/" + str(hostCount) + " need to exit", Color(1, 0, 0)) 71 | 72 | puppet func send_exit_message(id): 73 | Global.UI.notify("Exiting...", Color(1, 0, 0)) 74 | Global.UI.notify("All players are at the exit", Color(1, 0, 0)) 75 | 76 | func exit_to_menu(): 77 | Multiplayer.goto_menu_host(true) 78 | -------------------------------------------------------------------------------- /remaped/Terror_Door.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var GIB = preload("res://Entities/Physics_Objects/Chest_Gib.tscn") 6 | 7 | export var door_health = 100 8 | export var rotation_speed = 2 9 | var open = false 10 | var stop = true 11 | var initrot = rotation 12 | var rotation_counter = 0 13 | var mesh_instance 14 | var collision_shape 15 | var collision = false 16 | var found_overlap 17 | var type = 0 18 | var audio_player 19 | 20 | func _ready(): 21 | NetworkBridge.register_rpcs(self, [ 22 | ["remove_on_ready", NetworkBridge.PERMISSION.SERVER], 23 | ["remove", NetworkBridge.PERMISSION.SERVER], 24 | ["spawn_gib", NetworkBridge.PERMISSION.SERVER] 25 | ]) 26 | 27 | set_collision_layer_bit(8, 1) 28 | audio_player = AudioStreamPlayer3D.new() 29 | get_parent().call_deferred("add_child", audio_player) 30 | yield (get_tree(), "idle_frame") 31 | audio_player.global_transform.origin = global_transform.origin 32 | audio_player.stream = load("res://Sfx/Flesh/gibbing_3.wav") 33 | audio_player.unit_size = 10 34 | audio_player.unit_db = 4 35 | audio_player.max_db = 4 36 | audio_player.pitch_scale = 0.6 37 | 38 | func get_type(): 39 | return type 40 | 41 | func player_use(): 42 | if not Global.hope_discarded: 43 | Global.player.UI.notify("zvhvhivj jidv ijvdkjaeui djvhduhekj vduihkeu", Color(1, 0, 0)) 44 | else : 45 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 46 | for i in range(10): 47 | var new_gib = GIB.instance() 48 | 49 | new_gib.set_name(new_gib.name + "#" + str(new_gib.get_instance_id())) 50 | 51 | get_parent().add_child(new_gib) 52 | new_gib.global_transform.origin = global_transform.origin 53 | new_gib.velocity = Vector3.FORWARD.rotated(Vector3.UP, rand_range( - PI, PI)) 54 | NetworkBridge.n_rpc(self, "spawn_gib", [get_parent().get_path(), new_gib.name]) 55 | 56 | remove(null) 57 | NetworkBridge.n_rpc(self, "remove") 58 | else: 59 | Global.player.UI.notify("Something is keeping you from opening this door", Color(1, 0, 0)) 60 | 61 | puppet func remove_on_ready(id): 62 | set_collision_layer_bit(0,false) 63 | set_collision_mask_bit(0,false) 64 | set_collision_layer_bit(8, false) 65 | hide() 66 | 67 | puppet func remove(id): 68 | set_collision_layer_bit(0,false) 69 | set_collision_mask_bit(0,false) 70 | set_collision_layer_bit(8, false) 71 | hide() 72 | 73 | puppet func spawn_gib(id, recivedPath, recivedName): 74 | var new_gib = GIB.instance() 75 | get_node(recivedPath).add_child(new_gib) 76 | new_gib.set_name(recivedName) 77 | -------------------------------------------------------------------------------- /remaped/Cutscene.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var next_scene = "" 6 | export (Array, String, MULTILINE) var LINES:Array = [""] 7 | export (Array, float) var DURATION:Array = [1] 8 | export (String) var music 9 | export var instant = false 10 | export var line_skip = true 11 | export var introskip = false 12 | var CAMERAS 13 | onready var TIMER = $Timer 14 | onready var SUBTITLE = $MarginContainer / CenterContainer / Subtitle 15 | var current_scene = 0 16 | var t = 0 17 | 18 | onready var Multiplayer = Global.get_node('Multiplayer') 19 | var oneshot = false 20 | 21 | func _ready(): 22 | $MarginContainer / CenterContainer / Subtitle.get_font("font").size = 32 * (Global.resolution[0] / 1280) 23 | 24 | Global.menu.hide() 25 | if music != "": 26 | if music == "NO": 27 | Global.music.stop() 28 | else : 29 | Global.music.stream = load(music) 30 | Global.music.play() 31 | Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN) 32 | Global.cutscene = true 33 | Global.border.hide() 34 | CAMERAS = $Cameras.get_children() 35 | if introskip: 36 | Multiplayer.goto_menu_host() 37 | elif get_tree().network_peer == null: 38 | oneshot = true 39 | Multiplayer.host_server(23753) 40 | get_tree().network_peer.refuse_new_connections = true 41 | 42 | func _process(delta): 43 | if instant: 44 | t += 1 45 | SUBTITLE.modulate = Color((cos(t * 0.01) + 1) * 0.5, 0, 0) 46 | if TIMER.is_stopped() and current_scene != LINES.size(): 47 | current_scene = clamp(current_scene, 0, LINES.size() - 1) 48 | TIMER.wait_time = DURATION[current_scene] 49 | if CAMERAS.size() > 0: 50 | CAMERAS[current_scene].current = true 51 | SUBTITLE.text = LINES[current_scene] 52 | if not instant: 53 | SUBTITLE.speech() 54 | else : 55 | SUBTITLE.visible_characters = - 1 56 | current_scene += 1 57 | TIMER.start() 58 | if TIMER.is_stopped() and current_scene == LINES.size(): 59 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 60 | if oneshot: 61 | get_tree().network_peer = null 62 | if next_scene == "res://Menu/Main_Menu.tscn": 63 | Multiplayer.goto_menu_host() 64 | else: 65 | Multiplayer.goto_scene_host(next_scene) 66 | 67 | func _input(event): 68 | if event is InputEventKey: 69 | if Input.is_action_just_pressed("ui_cancel") or Input.is_action_just_pressed("ui_accept"): 70 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 71 | if oneshot: 72 | get_tree().network_peer = null 73 | if next_scene == "res://Menu/Main_Menu.tscn": 74 | Multiplayer.goto_menu_host() 75 | else: 76 | Multiplayer.goto_scene_host(next_scene) 77 | if Input.is_action_just_pressed("movement_jump") and line_skip: 78 | TIMER.stop() 79 | -------------------------------------------------------------------------------- /remaped/down_door.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var door_health = 100 6 | export var speed = 2 7 | var open = false 8 | var stop = true 9 | var initrot = rotation 10 | var movement_counter = 0 11 | var mesh_instance 12 | var collision_shape 13 | var collision = false 14 | var found_overlap 15 | var sfx = preload("res://Sfx/Environment/door_concrete.wav") 16 | var audio_player:AudioStreamPlayer3D 17 | var timer:Timer 18 | 19 | func _ready(): 20 | NetworkBridge.register_rpcs(self, [ 21 | ["network_use", NetworkBridge.PERMISSION.ALL] 22 | ]) 23 | 24 | rset_config("global_transform", MultiplayerAPI.RPC_MODE_PUPPET) 25 | NetworkBridge.register_rset(self, "global_transform", NetworkBridge.PERMISSION.SERVER) 26 | 27 | timer = Timer.new() 28 | add_child(timer) 29 | timer.wait_time = 5 30 | timer.one_shot = true 31 | timer.connect("timeout", self, "timeout") 32 | set_collision_layer_bit(8, 1) 33 | audio_player = AudioStreamPlayer3D.new() 34 | audio_player.stream = sfx 35 | add_child(audio_player) 36 | for child in get_children(): 37 | if child is MeshInstance: 38 | mesh_instance = child 39 | if child is CollisionShape: 40 | collision_shape = child 41 | var t = mesh_instance.transform 42 | global_transform.origin.x -= mesh_instance.get_aabb().position.x 43 | global_transform.origin.z -= mesh_instance.get_aabb().position.z 44 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x, 0, mesh_instance.get_aabb().position.z)) 45 | mesh_instance.transform = t 46 | collision_shape.transform = t 47 | 48 | func _physics_process(delta): 49 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 50 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 51 | 52 | if not open and not stop: 53 | if not audio_player.playing: 54 | audio_player.play() 55 | translation.y += speed * delta 56 | movement_counter += speed * delta 57 | if open and not stop: 58 | if not audio_player.playing: 59 | audio_player.play() 60 | translation.y -= speed * delta 61 | movement_counter += speed * delta 62 | if movement_counter > mesh_instance.get_aabb().size.y + 0.1: 63 | audio_player.stop() 64 | movement_counter = 0 65 | stop = true 66 | 67 | func switch_use(): 68 | if stop and not open: 69 | open = not open 70 | stop = not stop 71 | 72 | func timeout(): 73 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 74 | stop = not stop 75 | open = not open 76 | 77 | func use(): 78 | network_use(null) 79 | 80 | master func network_use(id): 81 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 82 | if stop and not open: 83 | open = not open 84 | stop = not stop 85 | timer.start() 86 | else: 87 | NetworkBridge.n_rpc(self, "network_use") 88 | -------------------------------------------------------------------------------- /remaped/Pushblock.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | func _ready(): 6 | rset_config("global_transform", MultiplayerAPI.RPC_MODE_PUPPET) 7 | NetworkBridge.register_rset(self, "global_transform", NetworkBridge.PERMISSION.SERVER) 8 | 9 | set_collision_mask_bit(0, 1) 10 | set_collision_mask_bit(1, 1) 11 | set_collision_mask_bit(4, 1) 12 | 13 | func get_near_player(object) -> Dictionary: 14 | var oldDistance = null 15 | var checkPlayer = null 16 | 17 | for selectedPlayer in get_tree().get_nodes_in_group("Player"): 18 | var distance = object.global_transform.origin.distance_to(selectedPlayer.global_transform.origin) 19 | if oldDistance == null or oldDistance > distance: 20 | oldDistance = distance 21 | checkPlayer = selectedPlayer 22 | 23 | return { 24 | "player" : checkPlayer, 25 | "distance" : oldDistance 26 | } 27 | 28 | func _physics_process(delta): 29 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 30 | 31 | var space_state = get_world().direct_space_state 32 | var result_down = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.DOWN * 1) 33 | 34 | if not result_down: 35 | translate(Vector3.DOWN * 0.1) 36 | NetworkBridge.n_rset(self, "global_transform", global_transform) 37 | 38 | if get_near_player(self).distance > 3: 39 | return 40 | 41 | var result_forward = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.FORWARD * 1.1) 42 | var result_back = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.BACK * 1.1) 43 | var result_left = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.LEFT * 1.1) 44 | var result_right = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.RIGHT * 1.1) 45 | 46 | if result_forward and not result_back: 47 | if result_forward.collider == Global.player or result_forward.collider.has_meta("puppet"): 48 | translate(Vector3.BACK * 2) 49 | NetworkBridge.n_rset(self, "global_transform", global_transform) 50 | 51 | if result_back and not result_forward: 52 | if result_back.collider == Global.player or result_back.collider.has_meta("puppet"): 53 | translate(Vector3.FORWARD * 2) 54 | NetworkBridge.n_rset(self, "global_transform", global_transform) 55 | 56 | if result_left and not result_right: 57 | if result_left.collider == Global.player or result_left.collider.has_meta("puppet"): 58 | translate(Vector3.RIGHT * 2) 59 | NetworkBridge.n_rset(self, "global_transform", global_transform) 60 | 61 | if result_right and not result_left: 62 | if result_right.collider == Global.player or result_right.collider.has_meta("puppet"): 63 | translate(Vector3.LEFT * 2) 64 | NetworkBridge.n_rset(self, "global_transform", global_transform) 65 | -------------------------------------------------------------------------------- /remaped/snakehead.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | enum I{GOLEM, WEAPON, MONEY} 6 | export (I) var index = I.GOLEM 7 | var type = 1 8 | var laser 9 | var health = 2500 10 | var death_flag = false 11 | var follow_speed = 0.02 12 | var particle 13 | var active = false 14 | var destroyed = false 15 | var look_towards = Vector3.ZERO 16 | var t = 0 17 | var disabled = false 18 | var gib = preload("res://Entities/Physics_Objects/Snake_Gib.tscn") 19 | export var line = "Triagon 01 is gone. (Golem Exosystem Received)" 20 | export var line2 = "I bestow upon you power." 21 | 22 | func _ready(): 23 | NetworkBridge.register_rpcs(self, [ 24 | ["network_damage", NetworkBridge.PERMISSION.ALL] 25 | ]) 26 | 27 | if Global.DEAD_CIVS.find(line) != - 1: 28 | get_parent().hide() 29 | queue_free() 30 | look_towards = Global.player.global_transform.origin 31 | laser = $Laser 32 | particle = $Particles 33 | 34 | func _process(delta): 35 | t += 1 36 | if destroyed: 37 | hide() 38 | return 39 | if disabled: 40 | particle.hide() 41 | if laser.scale.z < 3: 42 | hide() 43 | laser.scale.z = lerp(laser.scale.z, 1, 0.2) 44 | return 45 | show() 46 | look_towards = lerp(look_towards, Global.player.global_transform.origin, follow_speed) 47 | var space = get_world().direct_space_state 48 | 49 | if not active: 50 | return 51 | 52 | var result = space.intersect_ray(global_transform.origin, global_transform.origin - (global_transform.origin - look_towards).normalized() * 1000, [self]) 53 | if result: 54 | particle.show() 55 | particle.global_transform.origin = result.position 56 | laser.scale.z = lerp(laser.scale.z, global_transform.origin.distance_to(result.position) * 0.5, 0.2) 57 | laser.look_at(result.position, Vector3.UP) 58 | if result.collider == Global.player: 59 | Global.player.damage(20, result.normal, result.position, global_transform.origin) 60 | else : 61 | particle.hide() 62 | laser.scale.z = 400 63 | 64 | func damage(dmg, nrml, pos, shoot_pos): 65 | network_damage(null, dmg, nrml, pos, shoot_pos) 66 | 67 | master func network_damage(id, dmg, nrml, pos, shoot_pos): 68 | if death_flag: 69 | return 70 | active = true 71 | health -= dmg 72 | if health <= 0: 73 | death_flag = true 74 | if index == I.GOLEM: 75 | Global.implants.purchased_implants.append("CSIJ Level VI Golem Exosystem") 76 | if index == I.MONEY: 77 | Global.money += 1000000 78 | if index == I.WEAPON: 79 | Global.WEAPONS_UNLOCKED[Global.player.weapon.W_SHOCK] = true 80 | var new_gib = gib.instance() 81 | Global.player.get_parent().add_child(new_gib) 82 | new_gib.global_transform.origin = global_transform.origin 83 | Global.player.UI.notify(line, Color(0, 1, 0)) 84 | Global.player.UI.message(line2, true) 85 | Global.DEAD_CIVS.append(line) 86 | Global.save_game() 87 | get_parent().queue_free() 88 | 89 | func get_type(): 90 | return type; 91 | -------------------------------------------------------------------------------- /Button.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=11 format=2] 2 | 3 | [ext_resource path="res://Textures/Menu/Disabled_Button/4.png" type="Texture" id=1] 4 | [ext_resource path="res://Textures/Menu/Disabled_Button/3.png" type="Texture" id=2] 5 | [ext_resource path="res://Sfx/Flesh/flesh_slap.wav" type="AudioStream" id=3] 6 | [ext_resource path="res://Textures/Menu/hover.png" type="Texture" id=4] 7 | [ext_resource path="res://Textures/Menu/Disabled_Button/1.png" type="Texture" id=5] 8 | [ext_resource path="res://Textures/Menu/Disabled_Button/2.png" type="Texture" id=6] 9 | [ext_resource path="res://Textures/Menu/retry_normal.png" type="Texture" id=7] 10 | 11 | [sub_resource type="GDScript" id=4] 12 | script/source = "extends TextureRect 13 | 14 | export (Texture) var idleTexture 15 | export (Texture) var hoverTexture 16 | export (Texture) var disabledTexture 17 | 18 | export var enalbed = true 19 | 20 | export var labelText = \"Cruelty Squad Online\" 21 | export var buttonType = \"Menu\" 22 | 23 | onready var hint = get_tree().get_nodes_in_group(\"Hint\")[0] 24 | 25 | signal button_pressed(type) 26 | 27 | func _ready(): 28 | if enalbed: 29 | button_enable() 30 | else: 31 | button_disable() 32 | 33 | func _on_mouse_enter(): 34 | if enalbed: 35 | texture = hoverTexture 36 | hint.show() 37 | 38 | func _on_mouse_exit(): 39 | if enalbed: 40 | texture = idleTexture 41 | hint.hide() 42 | 43 | func button_enable(): 44 | enalbed = true 45 | texture = idleTexture 46 | 47 | func button_disable(): 48 | enalbed = false 49 | texture = disabledTexture 50 | 51 | func _mouse_input(event): 52 | if event is InputEventMouseMotion and enalbed: 53 | hint.change_pos(event.global_position + Vector2(50,30)) 54 | hint.change_text(labelText) 55 | if event is InputEventMouseButton and event.pressed and enalbed: 56 | texture = idleTexture 57 | emit_signal(\"button_pressed\",buttonType) 58 | $ClickSound.play() 59 | hint.hide() 60 | " 61 | 62 | [sub_resource type="AnimatedTexture" id=5] 63 | flags = 19 64 | frames = 4 65 | frame_0/texture = ExtResource( 5 ) 66 | frame_0/delay_sec = 0.19 67 | frame_1/texture = ExtResource( 6 ) 68 | frame_1/delay_sec = 0.06 69 | frame_2/texture = ExtResource( 2 ) 70 | frame_2/delay_sec = 0.32 71 | frame_3/texture = ExtResource( 1 ) 72 | frame_3/delay_sec = 0.25 73 | 74 | [sub_resource type="AudioStreamRandomPitch" id=10] 75 | audio_stream = ExtResource( 3 ) 76 | 77 | [node name="Button" type="TextureRect"] 78 | margin_right = 128.0 79 | margin_bottom = 128.0 80 | rect_scale = Vector2( 0.5, 0.5 ) 81 | texture = ExtResource( 7 ) 82 | stretch_mode = 1 83 | script = SubResource( 4 ) 84 | idleTexture = ExtResource( 7 ) 85 | hoverTexture = ExtResource( 4 ) 86 | disabledTexture = SubResource( 5 ) 87 | 88 | [node name="ClickSound" type="AudioStreamPlayer" parent="."] 89 | stream = SubResource( 10 ) 90 | volume_db = -5.0 91 | pitch_scale = 0.43 92 | 93 | [connection signal="gui_input" from="." to="." method="_mouse_input"] 94 | [connection signal="mouse_entered" from="." to="." method="_on_mouse_enter"] 95 | [connection signal="mouse_exited" from="." to="." method="_on_mouse_exit"] 96 | -------------------------------------------------------------------------------- /RelayServer.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | export var enabled = true 4 | 5 | export var virtual_server_port = 25568 6 | export var true_server_port = 25567 7 | 8 | export var fake_latency_ms = 0 9 | export var fake_loss = 0.0 10 | 11 | # Mental picture : 12 | # 13 | # (True) Server <--> Virtual Client -[Laggy bridge]- Virtual Server <--> (True) Client 14 | # 15 | 16 | var vserver_peer 17 | var vserver_has_dest_address = false 18 | var vserver_first_client_port = -1 19 | var vclient_peer 20 | 21 | class QueEntry: 22 | var byte_array 23 | var qued_at 24 | 25 | func _init(packet, time_now): 26 | self.byte_array = packet 27 | self.qued_at = time_now 28 | 29 | var client_to_server_que = [] 30 | var server_to_client_que = [] 31 | 32 | func _ready(): 33 | set_process(false) 34 | 35 | func setup(): 36 | if enabled: 37 | print("[CRUS ONLINE / DEBUG / UDP LAGGER]: Setting up") 38 | 39 | vserver_peer = PacketPeerUDP.new() 40 | vserver_peer.listen(virtual_server_port, "127.0.0.1") 41 | 42 | vclient_peer = PacketPeerUDP.new() 43 | vclient_peer.set_dest_address("127.0.0.1", true_server_port) 44 | 45 | set_process(true) 46 | 47 | func _process(delta): 48 | var now = Time.get_ticks_msec() 49 | var send_at_ms = now - fake_latency_ms 50 | 51 | # Handle packets Client -> Server 52 | while vserver_peer.get_available_packet_count() > 0: 53 | var packet = vserver_peer.get_packet() 54 | var err = vserver_peer.get_packet_error() 55 | if err != OK : 56 | push_error("[CRUS ONLINE / DEBUG / UDP LAGGER]: Incoming packet error : " + str(err)) 57 | continue 58 | 59 | var from_port = vserver_peer.get_packet_port() 60 | 61 | if not vserver_has_dest_address: 62 | vserver_peer.set_dest_address("127.0.0.1", from_port) 63 | vserver_first_client_port = from_port 64 | vserver_has_dest_address = true 65 | elif vserver_first_client_port != from_port : 66 | push_warning("[CRUS ONLINE / DEBUG / UDP LAGGER]: VServer got packet from unknown port, ignored.") 67 | continue 68 | 69 | client_to_server_que.push_back(QueEntry.new(packet, now)) 70 | _process_que(client_to_server_que, vclient_peer, send_at_ms) 71 | 72 | if not vserver_has_dest_address: 73 | return 74 | 75 | # Handle packets Server -> Client 76 | while vclient_peer.get_available_packet_count() > 0: 77 | var packet = vclient_peer.get_packet() 78 | var err = vclient_peer.get_packet_error() 79 | if err != OK : 80 | push_error("[CRUS ONLINE / DEBUG / UDP LAGGER]: Incoming packet error: " + str(err)) 81 | continue 82 | 83 | var from_port = vclient_peer.get_packet_port() 84 | if from_port != true_server_port : 85 | push_warning("[CRUS ONLINE / DEBUG / UDP LAGGER]: VClient got packet from unknown port, ignored.") 86 | continue 87 | 88 | server_to_client_que.push_back(QueEntry.new(packet, now)) 89 | _process_que(server_to_client_que, vserver_peer, send_at_ms) 90 | 91 | func _process_que(que, to_peer, send_at_ms): 92 | while not que.empty(): 93 | var front = que.front() 94 | if send_at_ms >= front.qued_at : 95 | if fake_loss <= 0 or randf() >= fake_loss: 96 | to_peer.put_packet(front.byte_array) 97 | que.pop_front() 98 | else: 99 | break 100 | -------------------------------------------------------------------------------- /remaped/Special_Pushblock.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | func _ready(): 6 | NetworkBridge.register_rpcs(self, [ 7 | ["remove", NetworkBridge.PERMISSION.SERVER] 8 | ]) 9 | 10 | rset_config("global_transform", MultiplayerAPI.RPC_MODE_PUPPET) 11 | NetworkBridge.register_rset(self, "global_transform", NetworkBridge.PERMISSION.SERVER) 12 | 13 | set_collision_mask_bit(0, 1) 14 | set_collision_mask_bit(1, 1) 15 | set_safe_margin(0) 16 | 17 | puppet func remove(id): 18 | queue_free() 19 | 20 | func get_near_player(object) -> Dictionary: 21 | var oldDistance = null 22 | var checkPlayer = null 23 | 24 | for selectedPlayer in get_tree().get_nodes_in_group("Player"): 25 | var distance = object.global_transform.origin.distance_to(selectedPlayer.global_transform.origin) 26 | if oldDistance == null or oldDistance > distance: 27 | oldDistance = distance 28 | checkPlayer = selectedPlayer 29 | 30 | return { 31 | "player" : checkPlayer, 32 | "distance" : oldDistance 33 | } 34 | 35 | 36 | func _physics_process(delta): 37 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 38 | 39 | var space_state = get_world().direct_space_state 40 | var result_down = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.DOWN * 1) 41 | 42 | if not result_down: 43 | translate(Vector3.DOWN * 0.1) 44 | NetworkBridge.n_rset(self, "global_transform", global_transform) 45 | 46 | if result_down: 47 | if result_down.collider.has_method("special_destroy"): 48 | result_down.collider.special_destroy() 49 | queue_free() 50 | NetworkBridge.n_rpc(self, "remove") 51 | 52 | if get_near_player(self).distance > 3: 53 | return 54 | 55 | var result_forward = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.FORWARD * 1.1) 56 | var result_back = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.BACK * 1.1) 57 | var result_left = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.LEFT * 1.1) 58 | var result_right = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.RIGHT * 1.1) 59 | 60 | if result_forward and not result_back: 61 | if result_forward.collider == Global.player or result_forward.collider.has_meta("puppet"): 62 | translate(Vector3.BACK * 2) 63 | NetworkBridge.n_rset(self, "global_transform", global_transform) 64 | 65 | if result_back and not result_forward: 66 | if result_back.collider == Global.player or result_back.collider.has_meta("puppet"): 67 | translate(Vector3.FORWARD * 2) 68 | NetworkBridge.n_rset(self, "global_transform", global_transform) 69 | 70 | if result_left and not result_right: 71 | if result_left.collider == Global.player or result_left.collider.has_meta("puppet"): 72 | translate(Vector3.RIGHT * 2) 73 | NetworkBridge.n_rset(self, "global_transform", global_transform) 74 | 75 | if result_right and not result_left: 76 | if result_right.collider == Global.player or result_right.collider.has_meta("puppet"): 77 | translate(Vector3.LEFT * 2) 78 | NetworkBridge.n_rset(self, "global_transform", global_transform) 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cruelty Squad Online 2 | 3 |
4 | 5 | Cruelty Squad Online logo 6 | 7 | English | [Русский](README_RU.md) 8 | 9 |
10 | 11 | > [!WARNING] 12 | > This modification is in open **Beta** testing 13 | > 14 | > You may encounter bugs and poor performance. 15 | 16 | ## About 17 | Cruelty Squad Online (CruS Online) is a huge modification for game [Cruelty Squad](https://store.steampowered.com/app/1388770/Cruelty_Squad/) that add a lobby style Steam and LAN multiplayer 18 | 19 | ## Installation 20 | CruS Online is installed in the same way as other modifications 21 | 22 | 1. Install [CruS Modloader](https://github.com/CruS-Modding-Infrastructure/crus-modloader) 23 | 2. Download latest version of CruS Online from [here](https://github.com/TriggeredP/crus-online/releases) 24 | 3. Extract CruS Online folder into this directory: `%appdata%\Godot\app_userdata\Cruelty Squad\mods` 25 | 4. Launch the game 26 | 27 | > [!CAUTION] 28 | > CruS Online is currently incompatible with other modifications 29 | 30 | ## Hosting lobby 31 | This modification provides two ways to connect players.: 32 | 33 | 1. Steam 34 | 2. LAN 35 | 36 | **Steam:** 37 | To create a lobby in the game, you need to: 38 | 39 | 1. Open the CruS Online menu (The second icon in the main menu) 40 | 2. Select Steam connection mode 41 | 3. Click on the 'Create` button to create a lobby 42 | 43 | **LAN:** 44 | There are two ways to create a lobby via LAN connection: 45 | 46 | 1. Port forwarding 47 | 2. Using a VPN software (like Radmin VPN) 48 | 49 | The best way would be to port forwarding because this will help improve performance, but if you can't forward ports, you can use Radmin VPN or similar applications 50 | 51 | Also, the host must have a good computer, otherwise it may affect performance 52 | 53 | To create a lobby in the game, you need to: 54 | 55 | 1. Open the CruS Online menu (The second icon in the main menu) 56 | 2. Go to the `Host` tab and set the port (It doesn't matter if Radmin VPN is used) 57 | 3. Go to the `Main` tab and click to a `Host` button 58 | 4. Share IP and port with those you are going to play with 59 | 60 | ## Connecting to lobby 61 | After the host has created the lobby, the players must: 62 | 63 | **Steam:** 64 | 65 | 1. Open the CruS Online menu (The second icon in the main menu) 66 | 2. Select Steam connection mode 67 | 3. Select the lobby from the list (Or receive an invitation from the host) 68 | 4. Click on the `Join` button to connect to the lobby 69 | 70 | **LAN:** 71 | 72 | 1. Open the CruS Online menu (The second icon in the main menu) 73 | 2. Enter the IP and port received from the host 74 | 3. Press `Join` button 75 | 76 | ## Starting game 77 | After everyone has entered the lobby, players must choose weapons and implants 78 | 79 | Once all the players are ready the host must select a level and press `Start misson` button to play map from the main game 80 | 81 | You can also play maps embedded in the modification, they can be found in the CruS Online menu in the `DM` tab 82 | 83 | After the game starts, players will not be able to join the lobby 84 | 85 | ## Usefull information 86 | 87 | You can change the nickname, color and skin in the `Player` tab 88 | The `Host` tab has a bunch of parameters that can be changed 89 | 90 | ## Links 91 | My site: https://triggeredp.site 92 | 93 | YouTube: https://www.youtube.com/@triggeredp 94 | 95 | Boosty: https://boosty.to/triggeredp 96 | -------------------------------------------------------------------------------- /remaped/Profane_Door.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var PARTICLE = preload("res://Entities/Particles/Destruction_Particle.tscn") 6 | 7 | export var door_health = 100 8 | export var rotation_speed = 2 9 | var open = false 10 | var stop = true 11 | var initrot = rotation 12 | var rotation_counter = 0 13 | var mesh_instance 14 | var collision_shape 15 | var collision = false 16 | var found_overlap 17 | var type = 1 18 | var audio_player 19 | 20 | var isDestroyed = false 21 | 22 | func _ready(): 23 | NetworkBridge.register_rpcs(self, [ 24 | ["player_use", NetworkBridge.PERMISSION.ALL], 25 | ["door_use", NetworkBridge.PERMISSION.ALL] 26 | ]) 27 | 28 | rset_config("global_transform",MultiplayerAPI.RPC_MODE_PUPPET) 29 | 30 | set_process(false) 31 | set_collision_layer_bit(8, 1) 32 | for child in get_children(): 33 | if child is MeshInstance: 34 | mesh_instance = child 35 | if child is CollisionShape: 36 | collision_shape = child 37 | var t = mesh_instance.transform 38 | 39 | if mesh_instance.get_aabb().size.x > mesh_instance.get_aabb().size.z: 40 | global_transform.origin.x -= mesh_instance.get_aabb().position.x 41 | global_transform.origin.z -= mesh_instance.get_aabb().position.z + mesh_instance.get_aabb().size.z * 0.5 42 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x, 0, mesh_instance.get_aabb().position.z + mesh_instance.get_aabb().size.z * 0.5)) 43 | else : 44 | global_transform.origin.x -= mesh_instance.get_aabb().position.x + mesh_instance.get_aabb().size.x * 0.5 45 | global_transform.origin.z -= mesh_instance.get_aabb().position.z 46 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x + mesh_instance.get_aabb().size.x * 0.5, 0, mesh_instance.get_aabb().position.z)) 47 | 48 | mesh_instance.transform = t 49 | collision_shape.transform = t 50 | 51 | audio_player = AudioStreamPlayer3D.new() 52 | get_parent().call_deferred("add_child", audio_player) 53 | yield (get_tree(), "idle_frame") 54 | audio_player.global_transform.origin = global_transform.origin 55 | audio_player.stream = load("res://Sfx/Environment/doorkick.wav") 56 | audio_player.unit_size = 10 57 | audio_player.unit_db = 4 58 | audio_player.max_db = 4 59 | audio_player.pitch_scale = 0.6 60 | 61 | func _physics_process(delta): 62 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 63 | if not open and not stop: 64 | rotation.y += rotation_speed * delta 65 | rotation_counter += rad2deg(rotation_speed * delta) 66 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 67 | if open and not stop: 68 | rotation.y -= rotation_speed * delta 69 | rotation_counter += rad2deg(rotation_speed * delta) 70 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 71 | if rotation_counter > 90: 72 | rotation_counter = 0 73 | stop = true 74 | 75 | func get_type(): 76 | return type; 77 | 78 | master func player_use(id): 79 | if Global.husk_mode: 80 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 81 | door_use(null) 82 | else: 83 | NetworkBridge.n_rpc(self, "door_use") 84 | else: 85 | Global.player.UI.notify("It repulses you.", Color(0.5, 0.5, 0)) 86 | Global.player.player_velocity -= (global_transform.origin - Global.player.global_transform.origin).normalized() * 5 87 | 88 | master func door_use(id): 89 | stop = not stop 90 | open = not open 91 | -------------------------------------------------------------------------------- /WIKI_RU.md: -------------------------------------------------------------------------------- 1 | # Cruelty Squad Online: Development Wiki 2 | 3 |
4 | 5 | Cruelty Squad Online logo 6 | 7 | [English](WIKI.md) | Русский 8 | 9 |
10 | 11 | [TOC] 12 | 13 | ## Структура модификации 14 | 15 | ``` 16 | Multiplayer: Главная нода мода 17 | ├── NetworkBridge: Используется для работы с функциями LAN и Steam мултиплеера 18 | ├── SteamInit: Инициализирует Steam 19 | │ ├── SteamNetwork: Используется для обмена пакетами 20 | │ └── SteamLobby: Используется для взаимодествия с лобби 21 | ├── Players: Создает, удаляет и обновляет игроков 22 | └── UDPLagger: Эмулирует пинг и потерю пакетов для отладки LAN мултиплеера 23 | ``` 24 | 25 | ## Импорт функций мултиплеера 26 | Для использования функций мултиплеера нужно импортировать главные ноды мода 27 | ``` python 28 | onready var Multiplayer = Global.get_node("Multiplayer") 29 | 30 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 31 | 32 | onready var SteamInit = Global.get_node("SteamInit") 33 | onready var SteamLobby = Global.get_node("SteamInit/SteamLobby") 34 | onready var SteamNetwork = Global.get_node("SteamInit/SteamNetwork") 35 | ``` 36 | 37 | ## Регистрация RPC функций 38 | Для регистрации RPC функций Steam мултиплеера используются функция register_rpcs ноды NetworkBridge 39 | 40 | ``` python 41 | func _ready(): 42 | NetworkBridge.register_rpcs(self,[ 43 | ["function_a", NetworkBridge.PERMISSION.ALL], # Сервер <-> Клиент 44 | ["function_b", NetworkBridge.PERMISSION.SERVER] # Сервер -> Клиент 45 | ]) 46 | ``` 47 | 48 | Для регистрации RPC функций LAN мултиплеера используются стандартные кейворды Godot (remote, puppet и master) 49 | 50 | ``` python 51 | # Сервер -> Клиент 52 | puppet func function_a(id): 53 | pass 54 | 55 | # Сервер <- Клиент 56 | master func function_b(id): 57 | pass 58 | 59 | # Сервер <-> Клиент 60 | remote func function_с(id): 61 | pass 62 | ``` 63 | 64 | ## Основные функции NetworkBridge 65 | 66 | |Возращение|Функции| 67 | |--------|--------| 68 | |void |n_rpc(caller : Node, method = null, args = [])| 69 | |void |n_rpc_unreliable(caller : Node, method = null, args = [])| 70 | |void |n_rpc_id(caller : Node, id = 0, method = null, args = [])| 71 | |void |n_rpc_unreliable_id(caller : Node, id = 0, method = null, args = [])| 72 | |void |set_mode(mode : int)| 73 | |bool |is_lan()| 74 | |bool |is_steam()| 75 | |bool |check_connection()| 76 | |array |get_peers()| 77 | |int |get_id()| 78 | |int |get_host_id()| 79 | 80 | ### void n\_rpc(caller : Node, method = null, args = []) 81 | Отправляет RPC пакет 82 | ### void n\_rpc\_unreliable(caller : Node, method = null, args = []) 83 | ### void n\_rpc\_id(caller : Node, id = 0, method = null, args = []) 84 | ### void n\_rpc\_unreliable\_id(caller : Node, id = 0, method = null, args = []) 85 | ### void set\_mode(mode : int) 86 | Устанавливает режим работы мултиплеера: 87 | 0 - LAN 88 | 1 - Steam 89 | ### bool is\_lan() 90 | Возращает **True** если выбран режим LAN мултиплеера 91 | ### bool is\_steam() 92 | Возращает **True** если выбран режим Steam мултиплеера 93 | ### bool check\_connection() 94 | Возращает **True** если игрок подключён к серверу или лобби 95 | ### array get\_peers() 96 | Возращает массив подключённых пиров 97 | ### int get\_id() 98 | Возращает ID игрока в мултиплеере 99 | ### int get\_host\_id() 100 | Возращает ID хоста сервера или лобби -------------------------------------------------------------------------------- /README_RU.md: -------------------------------------------------------------------------------- 1 | # Cruelty Squad Online 2 | 3 |
4 | 5 | Cruelty Squad Online logo 6 | 7 | [English](README.md) | Русский 8 | 9 |
10 | 11 | > [!WARNING] 12 | > Данная модификация находится в открытом **Бета** тестировании 13 | > 14 | > Вы можете столкнуться с багами и плохой производительностью 15 | 16 | ## Описание 17 | Cruelty Squad Online (CruS Online) это большая модификация для игры [Cruelty Squad](https://store.steampowered.com/app/1388770/Cruelty_Squad/) которая добавляет в игру Steam и LAN мултиплеер на базе лобби 18 | 19 | ## Установка 20 | CruS Online устанавливается таким-же образом как и другие модификации 21 | 22 | 1. Установить [CruS Modloader](https://github.com/CruS-Modding-Infrastructure/crus-modloader) 23 | 2. Скачать последнию версию CruS Online [отсюда](https://github.com/TriggeredP/crus-online/releases) 24 | 3. Распаковать архив CruS Online по пути: `%appdata%\Godot\app_userdata\Cruelty Squad\mods` 25 | 4. Запустить игру 26 | 27 | > [!CAUTION] 28 | > CruS Online на данный момент не совместим с другими модификациями 29 | 30 | ## Создание лобби 31 | Данная модификация предоставляет два способа соединения игроков: 32 | 33 | 1. Через Steam 34 | 2. Через LAN 35 | 36 | **Steam:** 37 | Что-бы создать лобби в игре нужно: 38 | 39 | 1. Открыть меню CruS Online (Вторая иконка в главном меню) 40 | 2. Выбрать Steam режим подключения 41 | 3. Нажать на кнопкку `Create` для того что-бы создать лобби 42 | 43 | **LAN:** 44 | Есть два способа создания лобби через LAN подключение: 45 | 46 | 1. Переадресация портов 47 | 2. Использование VPN приложения (По типу Radmin VPN) 48 | 49 | Лучшим способом была бы переадресация портов, поскольку это поможет повысить производительность, но если вы не можете переадресовывать порты, вы можете использовать Radmin VPN или аналогичные приложения 50 | 51 | Так-же, у хоста должен быть хороший компьютер, иначе это может повлиять на производительность 52 | 53 | Что-бы создать лобби в игре нужно: 54 | 55 | 1. Открыть меню CruS Online (Вторая иконка в главном меню) 56 | 2. Выбрать LAN режим подключения 57 | 2. Перейти во вкладку `Host` и указать открытый порт (Не важно если вы используете Radmin VPN) 58 | 3. Перейти во вкладку `Main` и нажать на кнопку `Host` 59 | 4. Поделится своим IP и портом с теми, с кем вы собираетесь играть 60 | 61 | ## Подключение к лобби 62 | После того как хост создал лобби, игроки должны: 63 | 64 | **Steam:** 65 | 66 | 1. Открыть меню CruS Online (Вторая иконка в главном меню) 67 | 2. Выбрать Steam режим подключения 68 | 3. Выбрать нужное лобби из списка (Или получить приглашение от хоста) 69 | 4. Нажать на кнопку `Join` что-бы подключится к лобби 70 | 71 | **LAN:** 72 | 73 | 1. Открыть меню CruS Online (Вторая иконка в главном меню) 74 | 2. Выбрать LAN режим подключения 75 | 2. Ввести полученный от хоста IP и порт 76 | 3. Нажать на кнопку `Join` 77 | 78 | ## Запуск игры 79 | После того как все подключились к лобби, игроки должны выбрать оружие и импланты 80 | 81 | После того как все игроки готовы, хост должен выбрать уровень и нажать на кнопку `Start misson` для игры в уровни основной игры 82 | 83 | Так-же вы можете сыграть на картах которые есть в модификации, найти вы можете их во вкладке `DM` 84 | 85 | После того как игра начнется, новые игроки не смогут подключится к лобби 86 | 87 | ## Полезная информация 88 | 89 | Вы можете сменить ник, цвет и скин во вкладке `Player` 90 | Во вкладке `Host` есть кучу параметров которые можно поменять по своему вкусу 91 | 92 | ## Ссылки 93 | Мой сайт: https://triggeredp.site 94 | 95 | YouTube: https://www.youtube.com/@triggeredp 96 | 97 | Boosty: https://boosty.to/triggeredp 98 | -------------------------------------------------------------------------------- /remaped/weapon_pickup_new.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | # WARN: По какой-то причине загружается до инициализации стима 4 | 5 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 6 | 7 | enum WEAPON{W_PISTOL, W_SMG, W_TRANQ, W_BLACKJACK, W_SHOTGUN, W_ROCKET_LAUNCHER, W_SNIPER, W_AR, W_SILENCED_SMG, W_NAMBU, W_GAS, W_MG3, W_AUTOSHOTGUN, W_MAUSER, W_BORE, W_MKR, W_RADIATOR, W_FLASHLIGHT, W_ZIPPY, W_AN94, W_VAG72, W_STEYR, W_DNA, W_ROD, W_FLAMETHROWER, W_SKS, W_NAILER, W_SHOCK, W_LIGHT} 8 | onready var MESH = [$Pistol_Mesh, $SMG_Mesh, $Tranq_Mesh, $Baton_Mesh, $Shotgun_Mesh, $RL_Mesh, $Sniper_Mesh, $AR_Mesh, $S_SMG_Mesh, $Nambu_Mesh, $Gas_Mesh, $MG3_Mesh, $Autoshotgun_Mesh, $Mauser_Mesh, $Bore_Mesh, $MKR_Mesh, $Rad_Mesh, $Flashlight_Mesh, $Zippy_Mesh, $AN94_Mesh, $VAG72_Mesh, $Steyr_Mesh, $DNA_Mesh, $Rod_Mesh, $FT_Mesh, $SKS_Mesh, $Nailer_Mesh, $SHOCK_Mesh, $Light_Mesh] 9 | export (WEAPON) var current_weapon = 0 10 | export var menu = false 11 | var ammo = 0 12 | 13 | ################################################################################ 14 | 15 | remote func _update_vars(id, recivedWeapon,recivedAmmo): 16 | current_weapon = recivedWeapon 17 | ammo = recivedAmmo 18 | 19 | remote func _change_visible(id, mesh, visibility): 20 | mesh.visible = visibility 21 | 22 | ################################################################################ 23 | 24 | remote func syncUpdate(id): 25 | for meshGun in MESH: 26 | meshGun.hide() 27 | MESH[current_weapon].show() 28 | 29 | func _ready(): 30 | register_all_rpcs() 31 | 32 | MESH[current_weapon].show() 33 | if not menu: 34 | ammo = Global.player.weapon.MAX_MAG_AMMO[current_weapon] 35 | 36 | func register_all_rpcs(): 37 | NetworkBridge.register_rpcs(self, [ 38 | ["_update_vars", NetworkBridge.PERMISSION.ALL], 39 | ["_change_visible", NetworkBridge.PERMISSION.ALL], 40 | ["syncUpdate", NetworkBridge.PERMISSION.ALL] 41 | ]) 42 | 43 | func player_use(): 44 | if not menu: 45 | var rot = rand_range(0, deg2rad(180)) 46 | 47 | get_parent().rotation.y = rot 48 | get_parent().rot_changed.y = rot 49 | 50 | if Global.player.weapon.current_weapon == current_weapon: 51 | if current_weapon == WEAPON.W_RADIATOR or current_weapon == WEAPON.W_BLACKJACK or current_weapon == WEAPON.W_BORE or current_weapon == WEAPON.W_FLASHLIGHT or current_weapon == WEAPON.W_ROD: 52 | return 53 | Global.player.weapon.add_ammo(ammo, current_weapon, Spatial.new()) 54 | ammo = 0 55 | NetworkBridge.n_rpc(self, "_update_vars", [current_weapon, ammo]) 56 | return 57 | if Global.player.weapon.weapon1 == current_weapon or Global.player.weapon.weapon2 == current_weapon: 58 | return 59 | var last_weapon 60 | var last_ammo 61 | if Global.player.weapon.current_weapon != null: 62 | last_weapon = Global.player.weapon.current_weapon 63 | last_ammo = Global.player.weapon.magazine_ammo[last_weapon] 64 | else : 65 | last_weapon = null 66 | var a = ammo 67 | Global.player.weapon.magazine_ammo[current_weapon] = a 68 | Global.player.weapon.set_weapon(current_weapon) 69 | Global.player.weapon.set_UI_ammo() 70 | Global.player.weapon.player_weapon.show() 71 | MESH[current_weapon].hide() 72 | NetworkBridge.n_rpc(self, "_change_visible", [MESH[current_weapon], false]) 73 | current_weapon = last_weapon 74 | NetworkBridge.n_rpc(self, "_update_vars", [current_weapon, ammo]) 75 | if current_weapon == null: 76 | NetworkBridge.n_rpc(get_parent(), "_remove") 77 | get_parent()._remove() 78 | return 79 | ammo = last_ammo 80 | NetworkBridge.n_rpc(self, "_update_vars", [current_weapon, ammo]) 81 | MESH[current_weapon].show() 82 | NetworkBridge.n_rpc(self, "_change_visible", [MESH[current_weapon], true]) 83 | NetworkBridge.n_rpc(self, "syncUpdate") 84 | -------------------------------------------------------------------------------- /remaped/vendingmachine.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var type = 1 6 | var items = [preload("res://Entities/Physics_Objects/can1.tscn"), preload("res://Entities/Physics_Objects/chips1.tscn")] 7 | var items_paths = ["res://Entities/Physics_Objects/can1.tscn", "res://Entities/Physics_Objects/chips1.tscn"] 8 | var item_names = ["Hungry Human Soda", "Super Crunchers"] 9 | export var max_items = 10 10 | var item_count = 0 11 | var broken = false 12 | 13 | puppet func _create_object(id, recivedPath, recivedObject, recivedName, recivedTransform): 14 | var newObject = load(recivedObject).instance() 15 | newObject.set_name(recivedName) 16 | get_node(recivedPath).add_child(newObject) 17 | newObject.global_transform = recivedTransform 18 | 19 | func _ready(): 20 | NetworkBridge.register_rpcs(self, [ 21 | ["_create_object", NetworkBridge.PERMISSION.SERVER], 22 | ["stop_sound", NetworkBridge.PERMISSION.SERVER], 23 | ["notify", NetworkBridge.PERMISSION.SERVER], 24 | ["activation", NetworkBridge.PERMISSION.ALL], 25 | ["network_damage", NetworkBridge.PERMISSION.ALL] 26 | ]) 27 | 28 | rset_config("item_count", MultiplayerAPI.RPC_MODE_PUPPET) 29 | rset_config("broken", MultiplayerAPI.RPC_MODE_PUPPET) 30 | 31 | NetworkBridge.register_rset(self, "item_count", NetworkBridge.PERMISSION.SERVER) 32 | NetworkBridge.register_rset(self, "broken", NetworkBridge.PERMISSION.SERVER) 33 | 34 | master func activation(id, violence): 35 | if NetworkBridge.n_is_network_master(self): 36 | if broken: 37 | return 38 | if item_count < max_items: 39 | item_count += 1 40 | NetworkBridge.n_rset(self, "item_count", item_count) 41 | var rand = randi() % items.size() 42 | var new_item = items[rand].instance() 43 | new_item.set_name(new_item.name + "#" + str(new_item.get_instance_id())) 44 | add_child(new_item) 45 | new_item.global_transform.origin = $Position3D.global_transform.origin 46 | new_item.damage(10, (global_transform.origin - $Position3D.global_transform.origin).normalized(), global_transform.origin, global_transform.origin) 47 | 48 | NetworkBridge.n_rpc(self, "_create_object", [get_path(), items_paths[rand], new_item.name, new_item.global_transform]) 49 | 50 | if not violence: 51 | NetworkBridge.n_rpc(self, "notify", ["Purchased " + str(item_names[rand]) + " for " + "$10", Color(0, 1, 1)]) 52 | Global.player.UI.notify("Purchased " + str(item_names[rand]) + " for " + "$10", Color(0, 1, 1)) 53 | else: 54 | NetworkBridge.n_rpc(self, "activation", [violence]) 55 | 56 | func player_use(): 57 | if Global.money < 10: 58 | Global.player.UI.notify("You don't have enough money.", Color(1, 0, 0)) 59 | return 60 | if broken: 61 | Global.player.UI.notify("It's broken.", Color(1, 0, 0)) 62 | return 63 | if item_count >= max_items: 64 | Global.player.UI.notify("It's empty.", Color(1, 0, 0)) 65 | return 66 | if Global.money >= 10: 67 | Global.money -= 10 68 | activation(null, false) 69 | 70 | func damage(dmg, nrml, pos, shoot_pos): 71 | network_damage(null, dmg, nrml, pos, shoot_pos) 72 | 73 | master func network_damage(id, a, n, p, sp): 74 | if NetworkBridge.n_is_network_master(self): 75 | if broken: 76 | return 77 | if randi() % 3 == 0: 78 | broken = true 79 | NetworkBridge.n_rset(self, "broken", true) 80 | $AudioStreamPlayer3D.playing = false 81 | NetworkBridge.n_rpc(self, "stop_sound") 82 | activation(null, true) 83 | else: 84 | NetworkBridge.n_rpc(self, "network_damage", [a, n, p, sp]) 85 | 86 | puppet func stop_sound(id): 87 | $AudioStreamPlayer3D.playing = false 88 | 89 | puppet func notify(id, value, color): 90 | Global.player.UI.notify(value, color) 91 | 92 | func get_type(): 93 | return type 94 | -------------------------------------------------------------------------------- /remaped/Elevator_Door.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var door_health = 100 6 | export var speed = 2 7 | var open = false 8 | var stop = true 9 | var initrot = rotation 10 | var movement_counter = 0 11 | var mesh_instance 12 | var collision_shape 13 | var collision = false 14 | var found_overlap 15 | var sfx = preload("res://Sfx/Environment/door_concrete.wav") 16 | var audio_player:AudioStreamPlayer3D 17 | var timer:Timer 18 | 19 | var lerp_translation 20 | 21 | func _ready(): 22 | NetworkBridge.register_rpcs(self, [ 23 | ["set_door", NetworkBridge.PERMISSION.SERVER], 24 | ["network_use", NetworkBridge.PERMISSION.ALL] 25 | ]) 26 | 27 | timer = Timer.new() 28 | add_child(timer) 29 | timer.wait_time = 5 30 | timer.one_shot = true 31 | timer.connect("timeout", self, "timeout") 32 | set_collision_layer_bit(8, 1) 33 | audio_player = AudioStreamPlayer3D.new() 34 | audio_player.stream = sfx 35 | add_child(audio_player) 36 | for child in get_children(): 37 | if child is MeshInstance: 38 | mesh_instance = child 39 | if child is CollisionShape: 40 | collision_shape = child 41 | var t = mesh_instance.transform 42 | global_transform.origin.x -= mesh_instance.get_aabb().position.x 43 | global_transform.origin.z -= mesh_instance.get_aabb().position.z 44 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x, 0, mesh_instance.get_aabb().position.z)) 45 | mesh_instance.transform = t 46 | collision_shape.transform = t 47 | 48 | lerp_translation = translation 49 | 50 | func _physics_process(delta): 51 | if not open and not stop: 52 | if not audio_player.playing: 53 | audio_player.play() 54 | if mesh_instance.get_aabb().size.x > mesh_instance.get_aabb().size.z: 55 | translation.x += speed * delta 56 | elif mesh_instance.get_aabb().size.x < mesh_instance.get_aabb().size.z: 57 | translation.z += speed * delta 58 | else : 59 | translation.z += speed * delta 60 | translation.x += speed * delta 61 | movement_counter += speed * delta 62 | if open and not stop: 63 | if not audio_player.playing: 64 | audio_player.play() 65 | if mesh_instance.get_aabb().size.x > mesh_instance.get_aabb().size.z: 66 | translation.x -= speed * delta 67 | elif mesh_instance.get_aabb().size.x < mesh_instance.get_aabb().size.z: 68 | translation.z -= speed * delta 69 | else : 70 | translation.z -= speed * delta 71 | translation.x -= speed * delta 72 | movement_counter += speed * delta 73 | if movement_counter > mesh_instance.get_aabb().size.x + 0.1 and movement_counter > mesh_instance.get_aabb().size.z + 0.1: 74 | audio_player.stop() 75 | movement_counter = 0 76 | stop = true 77 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 78 | NetworkBridge.n_rpc(self, "set_door", [stop, open, translation]) 79 | 80 | puppet func set_door(id, recived_stop, recived_open, recived_translation = null): 81 | stop = recived_stop 82 | open = recived_open 83 | 84 | if recived_translation != null: 85 | translation = recived_translation 86 | 87 | func timeout(): 88 | stop = not stop 89 | open = not open 90 | 91 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 92 | NetworkBridge.n_rpc(self, "set_door", [stop, open, translation]) 93 | 94 | func use(): 95 | network_use(null) 96 | 97 | master func network_use(id): 98 | if NetworkBridge.check_connection(): 99 | if stop and not open: 100 | open = not open 101 | stop = not stop 102 | 103 | timer.start() 104 | if NetworkBridge.n_is_network_master(self): 105 | NetworkBridge.n_rpc(self, "set_door", [stop, open]) 106 | else: 107 | NetworkBridge.n_rpc(self, "network_use") 108 | -------------------------------------------------------------------------------- /maps/benchmark.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=14 format=2] 2 | 3 | [ext_resource path="res://Maps/textures/base/cobble1.png" type="Texture" id=1] 4 | [ext_resource path="res://Player_Test.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://Textures/sky3.png" type="Texture" id=3] 6 | [ext_resource path="res://MOD_CONTENT/CruS Online/BenchmarkBall.tscn" type="PackedScene" id=4] 7 | [ext_resource path="res://Imported_Mesh/Fish/agon.glb" type="PackedScene" id=5] 8 | [ext_resource path="res://MOD_CONTENT/CruS Online/maps/Benchmark.gd" type="Script" id=6] 9 | 10 | [sub_resource type="BoxShape" id=4] 11 | extents = Vector3( 250, 0.1, 250 ) 12 | 13 | [sub_resource type="SpatialMaterial" id=2] 14 | albedo_texture = ExtResource( 1 ) 15 | uv1_scale = Vector3( 250, 250, 1 ) 16 | 17 | [sub_resource type="PlaneMesh" id=3] 18 | material = SubResource( 2 ) 19 | size = Vector2( 500, 500 ) 20 | 21 | [sub_resource type="PanoramaSky" id=5] 22 | panorama = ExtResource( 3 ) 23 | 24 | [sub_resource type="Environment" id=6] 25 | background_mode = 2 26 | background_sky = SubResource( 5 ) 27 | 28 | [sub_resource type="GDScript" id=8] 29 | script/source = "extends StaticBody 30 | 31 | export var spawn_value = 1 32 | onready var parent = get_parent() 33 | 34 | func player_use(): 35 | parent.spawn_ball(null, spawn_value) 36 | " 37 | 38 | [sub_resource type="BoxShape" id=7] 39 | 40 | [node name="TestMap" type="Spatial"] 41 | 42 | [node name="Player" parent="." instance=ExtResource( 2 )] 43 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -3 ) 44 | 45 | [node name="StaticBody" type="StaticBody" parent="."] 46 | 47 | [node name="CollisionShape" type="CollisionShape" parent="StaticBody"] 48 | shape = SubResource( 4 ) 49 | 50 | [node name="MeshInstance" type="MeshInstance" parent="StaticBody"] 51 | mesh = SubResource( 3 ) 52 | 53 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."] 54 | environment = SubResource( 6 ) 55 | 56 | [node name="DirectionalLight" type="DirectionalLight" parent="."] 57 | transform = Transform( 0.866025, 0.433013, 0.25, 0, -0.5, 0.866025, 0.5, -0.75, -0.433013, 0, 8.08222, 0 ) 58 | light_color = Color( 0.45098, 0.882353, 1, 1 ) 59 | 60 | [node name="Benchmark" type="Spatial" parent="."] 61 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 40 ) 62 | script = ExtResource( 6 ) 63 | 64 | [node name="Spawn1" type="StaticBody" parent="Benchmark"] 65 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 3, -8, -25 ) 66 | collision_layer = 256 67 | collision_mask = 0 68 | script = SubResource( 8 ) 69 | 70 | [node name="CollisionShape" type="CollisionShape" parent="Benchmark/Spawn1"] 71 | shape = SubResource( 7 ) 72 | 73 | [node name="agon" parent="Benchmark/Spawn1" instance=ExtResource( 5 )] 74 | 75 | [node name="Spawn10" type="StaticBody" parent="Benchmark"] 76 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -8, -25 ) 77 | collision_layer = 256 78 | collision_mask = 0 79 | script = SubResource( 8 ) 80 | spawn_value = 10 81 | 82 | [node name="CollisionShape" type="CollisionShape" parent="Benchmark/Spawn10"] 83 | shape = SubResource( 7 ) 84 | 85 | [node name="agon" parent="Benchmark/Spawn10" instance=ExtResource( 5 )] 86 | 87 | [node name="Spawn50" type="StaticBody" parent="Benchmark"] 88 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -3, -8, -25 ) 89 | collision_layer = 256 90 | collision_mask = 0 91 | script = SubResource( 8 ) 92 | spawn_value = 50 93 | 94 | [node name="CollisionShape" type="CollisionShape" parent="Benchmark/Spawn50"] 95 | shape = SubResource( 7 ) 96 | 97 | [node name="agon" parent="Benchmark/Spawn50" instance=ExtResource( 5 )] 98 | 99 | [node name="Balls" type="Spatial" parent="Benchmark"] 100 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0 ) 101 | 102 | [node name="BenchmarkBall" parent="Benchmark/Balls" instance=ExtResource( 4 )] 103 | -------------------------------------------------------------------------------- /remaped/Destructible_Armored.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var PARTICLE = preload("res://Entities/Particles/Destruction_Particle.tscn") 6 | 7 | export var door_health = 100 8 | var mesh_instance 9 | var type = 1 10 | var audio_player 11 | 12 | var isDestroyed = false 13 | 14 | var destroy_check_timer 15 | 16 | func _ready(): 17 | rset_config("door_health", MultiplayerAPI.RPC_MODE_PUPPET) 18 | NetworkBridge.register_rset(self, "door_health", NetworkBridge.PERMISSION.SERVER) 19 | 20 | NetworkBridge.register_rpcs(self, [ 21 | ["remove_on_ready", NetworkBridge.PERMISSION.SERVER], 22 | ["remove", NetworkBridge.PERMISSION.SERVER], 23 | ["check_removed", NetworkBridge.PERMISSION.ALL], 24 | ["network_piercing_damage", NetworkBridge.PERMISSION.ALL] 25 | ]) 26 | 27 | for child in get_children(): 28 | if child is MeshInstance: 29 | mesh_instance = child 30 | var t = mesh_instance.transform 31 | audio_player = AudioStreamPlayer3D.new() 32 | get_parent().call_deferred("add_child", audio_player) 33 | yield (get_tree(), "idle_frame") 34 | audio_player.global_transform.origin = global_transform.origin 35 | audio_player.stream = load("res://Sfx/Environment/doorkick.wav") 36 | audio_player.unit_size = 10 37 | audio_player.unit_db = 2 38 | audio_player.max_db = 3 39 | set_collision_layer_bit(8, 1) 40 | 41 | destroy_check_timer = Timer.new() 42 | destroy_check_timer.wait_time = 2.0 43 | destroy_check_timer.one_shot = true 44 | destroy_check_timer.connect("timeout", self, "respawn") 45 | 46 | if not NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 47 | NetworkBridge.n_rpc(self, "check_removed") 48 | 49 | master func check_removed(id): 50 | if isDestroyed: 51 | NetworkBridge.n_rpc_id(self, id, "remove_on_ready") 52 | 53 | func piercing_damage(damage, collision_n, collision_p, shooter_pos): 54 | network_piercing_damage(null, damage, collision_n, collision_p, shooter_pos) 55 | 56 | master func network_piercing_damage(id, damage, collision_n, collision_p, shooter_pos): 57 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 58 | door_health -= damage 59 | if door_health <= 0: 60 | remove(null, collision_n, collision_p) 61 | NetworkBridge.n_rpc(self, "remove", [collision_n, collision_p, true]) 62 | NetworkBridge.n_rset(self, "door_health", door_health) 63 | else: 64 | door_health -= damage 65 | if door_health <= 0: 66 | remove(null, collision_n, collision_p) 67 | destroy_check_timer.start() 68 | NetworkBridge.n_rpc(self, "network_piercing_damage", [damage, collision_n, collision_p, shooter_pos]) 69 | 70 | func get_type(): 71 | return type; 72 | 73 | puppet func remove_on_ready(id): 74 | set_collision_layer_bit(0,false) 75 | set_collision_mask_bit(0,false) 76 | set_collision_layer_bit(8, false) 77 | hide() 78 | 79 | func player_use(): 80 | Global.player.UI.notify("Small cracks permeate the surface", Color(1, 1, 1)) 81 | 82 | puppet func remove(id, collision_n, collision_p, from_host = false): 83 | if not visible and from_host: 84 | destroy_check_timer.stop() 85 | else: 86 | isDestroyed = true 87 | audio_player.global_transform.origin = collision_p 88 | audio_player.play() 89 | var new_particle = PARTICLE.instance() 90 | get_parent().add_child(new_particle) 91 | new_particle.global_transform.origin = collision_p 92 | new_particle.look_at(global_transform.origin + collision_n * 5 + Vector3(1e-06, 0, 0), Vector3.UP) 93 | new_particle.material_override = mesh_instance.mesh.surface_get_material(0) 94 | new_particle.emitting = true 95 | set_collision_layer_bit(0,false) 96 | set_collision_mask_bit(0,false) 97 | hide() 98 | 99 | func respawn(): 100 | isDestroyed = false 101 | set_collision_layer_bit(0,true) 102 | set_collision_mask_bit(0,true) 103 | show() 104 | -------------------------------------------------------------------------------- /remaped/Item_Slotmachine.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var rotation_counter = - 1 6 | var coin = preload("res://Entities/Physics_Objects/Coin.tscn") 7 | var junk_items:Array = [ 8 | preload("res://Entities/Physics_Objects/Chest_Gib.tscn"), 9 | preload("res://Entities/Physics_Objects/Head_Gib.tscn"), 10 | preload("res://Entities/Props/Plant_1.tscn"), 11 | preload("res://Entities/Props/Trashcan.tscn"), 12 | preload("res://Entities/Props/Monitor.tscn") 13 | ] 14 | 15 | master func set_rotation_counter(id, recived_value): 16 | rotation_counter = recived_value 17 | 18 | func _ready(): 19 | NetworkBridge.register_rpcs(self, [ 20 | ["set_mech_rotation", NetworkBridge.PERMISSION.SERVER], 21 | ["set_rotation_counter", NetworkBridge.PERMISSION.ALL], 22 | ["notify", NetworkBridge.PERMISSION.SERVER], 23 | ["play_audio", NetworkBridge.PERMISSION.SERVER], 24 | ["client_spawn_item", NetworkBridge.PERMISSION.SERVER], 25 | ["money_check", NetworkBridge.PERMISSION.SERVER], 26 | ["check_use", NetworkBridge.PERMISSION.ALL] 27 | ]) 28 | 29 | puppet func set_mech_rotation(id, value): 30 | $MeshInstance2.rotation.x = value 31 | 32 | puppet func notify(id, value, color): 33 | Global.player.UI.notify(value, color) 34 | 35 | puppet func play_audio(id): 36 | $Audio.play() 37 | 38 | func _physics_process(delta): 39 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 40 | if rotation_counter >= 0: 41 | rotation_counter -= 1 42 | if not $Audio.playing: 43 | $Audio.play() 44 | NetworkBridge.n_rpc(self, "play_audio") 45 | $MeshInstance2.rotation.x += 1 46 | NetworkBridge.n_rpc_unreliable(self, "set_mech_rotation", [$MeshInstance2.rotation.x]) 47 | if rotation_counter == 0: 48 | randomize() 49 | if randi() % 1000 == 500: 50 | spawn_item() 51 | elif randi() % 10 == 1: 52 | spawn_item() 53 | elif randi() % 2 == 1: 54 | spawn_item() 55 | else : 56 | Global.player.UI.notify("You lose", Color(1, 0, 0)) 57 | NetworkBridge.n_rpc(self, "notify", ["You lose", Color(1, 0, 0)]) 58 | else: 59 | set_physics_process(false) 60 | 61 | func spawn_item(): 62 | var selectedItem = randi() % junk_items.size() 63 | var new_coin = junk_items[selectedItem].instance() 64 | new_coin.set_name(new_coin.name + "#" + str(new_coin.get_instance_id())) 65 | add_child(new_coin) 66 | new_coin.global_transform.origin = $Position3D.global_transform.origin 67 | new_coin.damage(20, (global_transform.origin - ($Forward_Position.global_transform.origin + Vector3(rand_range( - 0.1, 0.1), rand_range( - 0.1, 0.1), rand_range( - 0.1, 0.1)))).normalized(), global_transform.origin, Vector3.ZERO) 68 | NetworkBridge.n_rpc(self, "client_spawn_item", [selectedItem, get_path(), new_coin.name, new_coin.global_transform]) 69 | 70 | puppet func client_spawn_item(id, recivedItem, recivedPath, recivedName, recivedTransform): 71 | var new_coin = junk_items[recivedItem].instance() 72 | new_coin.set_name(recivedName) 73 | get_node(recivedPath).add_child(new_coin) 74 | new_coin.global_transform = recivedTransform 75 | 76 | func player_use(): 77 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 78 | check_use(null, true) 79 | else: 80 | NetworkBridge.n_rpc(self, "check_use") 81 | 82 | master func check_use(id, host = false): 83 | if rotation_counter >= 0: 84 | return 85 | 86 | if host: 87 | money_check(null) 88 | else: 89 | NetworkBridge.n_rpc(self, "money_check") 90 | 91 | puppet func money_check(id): 92 | if Global.money < 10: 93 | Global.player.UI.notify("$10 required to play", Color(1, 1, 1)) 94 | return 95 | Global.money -= 10 96 | 97 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 98 | rotation_counter = 50 99 | else: 100 | NetworkBridge.n_rpc(self, "set_rotation_counter", [50]) 101 | -------------------------------------------------------------------------------- /remaped/Fire.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var velocity = Vector3.ZERO 6 | 7 | var f = preload("res://Entities/Bullets/Fire_Child.tscn") 8 | onready var p = $Particles 9 | var wep 10 | 11 | var last_transform 12 | var lerp_transform 13 | 14 | var tick = 0 15 | 16 | func host_tick(): 17 | tick += 1 18 | if (global_transform.origin - last_transform.origin).length() > 0.01 and tick % 2 == 0: 19 | last_transform = global_transform 20 | 21 | NetworkBridge.n_rpc_unreliable(self, "_set_transform", [global_transform, p.scale]) 22 | 23 | tick = 0 24 | 25 | puppet func _set_transform(id, recivedTransform, recivedScale): 26 | lerp_transform = recivedTransform 27 | p.scale = recivedScale 28 | 29 | puppet func _delete(id): 30 | queue_free() 31 | 32 | puppet func _create_object(id, recivedPath, recivedObject, recivedName, recivedTransform): 33 | var newObject = load(recivedObject).instance() 34 | newObject.set_name(recivedName) 35 | get_node(recivedPath).add_child(newObject) 36 | newObject.global_transform = recivedTransform 37 | 38 | func _ready(): 39 | lerp_transform = global_transform 40 | 41 | set_collision_mask_bit(1, 1) 42 | 43 | NetworkBridge.register_rpcs(self, [ 44 | ["_set_transform", NetworkBridge.PERMISSION.SERVER], 45 | ["_delete", NetworkBridge.PERMISSION.SERVER], 46 | ["_create_object", NetworkBridge.PERMISSION.SERVER] 47 | ]) 48 | 49 | func _physics_process(delta): 50 | if NetworkBridge.n_is_network_master(self): 51 | host_tick() 52 | 53 | var col = move_and_collide(velocity * delta) 54 | if col: 55 | var body = col.collider 56 | var new_fire_child = f.instance() 57 | new_fire_child.set_name("FireChild#" + str(new_fire_child.get_instance_id())) 58 | 59 | if body.has_meta("puppet_body"): 60 | if not body.onFire: 61 | body.set_fire(true) 62 | body.add_child(new_fire_child) 63 | new_fire_child.global_transform.origin = global_transform.origin 64 | NetworkBridge.n_rpc(self, "_create_object", [body.get_path(), "res://Entities/Bullets/Fire_Child.tscn", new_fire_child.name, new_fire_child.global_transform]) 65 | else: 66 | if "soul" in body: 67 | if body.soul.on_fire: 68 | pass 69 | else : 70 | body.soul.on_fire = true 71 | body.add_child(new_fire_child) 72 | new_fire_child.scale.y = 2.0 73 | new_fire_child.global_transform.origin = body.global_transform.origin - Vector3.UP * 0.5 74 | NetworkBridge.n_rpc(self, "_create_object", [body.get_path(), "res://Entities/Bullets/Fire_Child.tscn", new_fire_child.name, new_fire_child.global_transform]) 75 | elif "random_line" in body: 76 | if body.get_parent().on_fire: 77 | pass 78 | else : 79 | body.get_parent().on_fire = true 80 | body.add_child(new_fire_child) 81 | new_fire_child.scale.y = 2.0 82 | new_fire_child.global_transform.origin = body.global_transform.origin - Vector3.UP * 0.5 83 | NetworkBridge.n_rpc(self, "_create_object", [body.get_path(), "res://Entities/Bullets/Fire_Child.tscn", new_fire_child.name, new_fire_child.global_transform]) 84 | else : 85 | body.add_child(new_fire_child) 86 | new_fire_child.global_transform.origin = global_transform.origin 87 | NetworkBridge.n_rpc(self, "_create_object", [body.get_path(), "res://Entities/Bullets/Fire_Child.tscn", new_fire_child.name, new_fire_child.global_transform]) 88 | NetworkBridge.n_rpc(self, "_delete") 89 | queue_free() 90 | velocity.y -= 4 * delta 91 | velocity *= 0.98 92 | p.scale += Vector3(0.1, 0.1, 0.1) 93 | if velocity.length() < 6: 94 | NetworkBridge.n_rpc(self, "_delete") 95 | queue_free() 96 | else: 97 | global_transform = global_transform.interpolate_with(lerp_transform, delta * 10.0) 98 | 99 | func set_water(value): 100 | if NetworkBridge.n_is_network_master(self): 101 | NetworkBridge.n_rpc(self, "_delete") 102 | queue_free() 103 | -------------------------------------------------------------------------------- /remaped/Abraxas_Rocket.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var health = 300 6 | var type = 1 7 | var frequency = 50 8 | var destroyed = false 9 | var disabled = true 10 | var BULLETS = preload("res://Entities/Bullets/Homing_Missile.tscn") 11 | var fakeBULLETS = preload("res://MOD_CONTENT/CruS Online/effects/fake_Homing_Missile.tscn") 12 | var t = 0 13 | var activated = false 14 | 15 | func get_near_player(object) -> Dictionary: 16 | var oldDistance = null 17 | var checkPlayer = null 18 | 19 | for selectedPlayer in get_tree().get_nodes_in_group("Player"): 20 | var distance = object.global_transform.origin.distance_to(selectedPlayer.global_transform.origin) 21 | if oldDistance == null or oldDistance > distance: 22 | oldDistance = distance 23 | checkPlayer = selectedPlayer 24 | 25 | return { 26 | "player" : checkPlayer, 27 | "distance" : oldDistance 28 | } 29 | 30 | func _ready(): 31 | NetworkBridge.register_rpcs(self, [ 32 | ["create_missile", NetworkBridge.PERMISSION.SERVER], 33 | ["died", NetworkBridge.PERMISSION.SERVER], 34 | ["network_damage", NetworkBridge.PERMISSION.ALL] 35 | ]) 36 | 37 | func _physics_process(delta): 38 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 39 | t += 1 40 | if destroyed: 41 | return 42 | if disabled: 43 | return 44 | show() 45 | if not activated and fmod(t, 50) == 0: 46 | var space = get_world().direct_space_state 47 | var result = space.intersect_ray(global_transform.origin, get_near_player(self).player.global_transform.origin + Vector3.UP * 1.0, [self]) 48 | if result: 49 | if result.collider == Global.player or result.collider.has_meta("puppet"): 50 | activated = true 51 | if activated: 52 | if fmod(t, frequency) == 0: 53 | for i in range(4): 54 | yield (get_tree(), "idle_frame") 55 | yield (get_tree(), "idle_frame") 56 | yield (get_tree(), "idle_frame") 57 | yield (get_tree(), "idle_frame") 58 | yield (get_tree(), "idle_frame") 59 | yield (get_tree(), "idle_frame") 60 | yield (get_tree(), "idle_frame") 61 | yield (get_tree(), "idle_frame") 62 | rocket_launcher() 63 | else: 64 | set_physics_process(false) 65 | 66 | puppet func create_missile(id, parentPath, missileName, missileTransform): 67 | var missile_new = fakeBULLETS.instance() 68 | 69 | missile_new.set_name(missileName) 70 | get_node(parentPath).add_child(missile_new) 71 | missile_new.global_transform = missileTransform 72 | 73 | func rocket_launcher()->void : 74 | var missile_new = BULLETS.instance() 75 | 76 | missile_new.set_name(missile_new.name + "#" + str(missile_new.get_instance_id())) 77 | 78 | get_parent().get_parent().get_parent().add_child(missile_new) 79 | missile_new.add_collision_exception_with(self) 80 | missile_new.global_transform.origin = global_transform.origin 81 | missile_new.set_velocity(30, (global_transform.origin - (Global.player.global_transform.origin + Vector3.UP * 50 + Vector3(0, 0, sin(t * 0.5) * 25))).normalized(), global_transform.origin) 82 | 83 | NetworkBridge.n_rpc(self, "create_missile", [get_parent().get_parent().get_parent().get_path(), missile_new.name, missile_new.global_transform]) 84 | 85 | puppet func died(id): 86 | get_parent().get_node("Sphere001").hide() 87 | get_parent().get_node("Particle").show() 88 | 89 | func damage(dmg, nrml, pos, shoot_pos): 90 | network_damage(null, dmg, nrml, pos, shoot_pos) 91 | 92 | master func network_damage(id, dmg, nrml, pos, shoot_pos): 93 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 94 | if not activated: 95 | return 96 | health -= dmg 97 | if health <= 0: 98 | destroyed = true 99 | died(null) 100 | NetworkBridge.n_rpc(self, "died") 101 | else: 102 | NetworkBridge.n_rpc(self, "network_damage", [dmg, nrml, pos, shoot_pos]) 103 | 104 | func get_type(): 105 | return type; 106 | -------------------------------------------------------------------------------- /remaped/Divine_Door.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var PARTICLE = preload("res://Entities/Particles/Destruction_Particle.tscn") 6 | 7 | export var door_health = 100 8 | export var rotation_speed = 2 9 | var open = false 10 | var stop = true 11 | var initrot = rotation 12 | var rotation_counter = 0 13 | var mesh_instance 14 | var collision_shape 15 | var collision = false 16 | var found_overlap 17 | var type = 1 18 | var audio_player 19 | 20 | var isDestroyed = false 21 | 22 | func _ready(): 23 | rset_config("global_transform",MultiplayerAPI.RPC_MODE_PUPPET) 24 | 25 | NetworkBridge.register_rpcs(self, [ 26 | ["_get_transform", NetworkBridge.PERMISSION.ALL], 27 | ["player_use", NetworkBridge.PERMISSION.ALL], 28 | ["door_use", NetworkBridge.PERMISSION.ALL] 29 | ]) 30 | 31 | set_process(false) 32 | set_collision_layer_bit(8, 1) 33 | for child in get_children(): 34 | if child is MeshInstance: 35 | mesh_instance = child 36 | if child is CollisionShape: 37 | collision_shape = child 38 | var t = mesh_instance.transform 39 | 40 | if mesh_instance.get_aabb().size.x > mesh_instance.get_aabb().size.z: 41 | global_transform.origin.x -= mesh_instance.get_aabb().position.x 42 | global_transform.origin.z -= mesh_instance.get_aabb().position.z + mesh_instance.get_aabb().size.z * 0.5 43 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x, 0, mesh_instance.get_aabb().position.z + mesh_instance.get_aabb().size.z * 0.5)) 44 | else : 45 | global_transform.origin.x -= mesh_instance.get_aabb().position.x + mesh_instance.get_aabb().size.x * 0.5 46 | global_transform.origin.z -= mesh_instance.get_aabb().position.z 47 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x + mesh_instance.get_aabb().size.x * 0.5, 0, mesh_instance.get_aabb().position.z)) 48 | 49 | mesh_instance.transform = t 50 | collision_shape.transform = t 51 | 52 | audio_player = AudioStreamPlayer3D.new() 53 | get_parent().call_deferred("add_child", audio_player) 54 | yield (get_tree(), "idle_frame") 55 | audio_player.global_transform.origin = global_transform.origin 56 | audio_player.stream = load("res://Sfx/Environment/doorkick.wav") 57 | audio_player.unit_size = 10 58 | audio_player.unit_db = 4 59 | audio_player.max_db = 4 60 | audio_player.pitch_scale = 0.6 61 | 62 | if not NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 63 | NetworkBridge.n_rpc(self, "_get_transform") 64 | 65 | master func _get_transform(id): 66 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 67 | 68 | func _physics_process(delta): 69 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 70 | if not open and not stop: 71 | rotation.y += rotation_speed * delta 72 | rotation_counter += rad2deg(rotation_speed * delta) 73 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 74 | if open and not stop: 75 | rotation.y -= rotation_speed * delta 76 | rotation_counter += rad2deg(rotation_speed * delta) 77 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 78 | if rotation_counter > 90: 79 | rotation_counter = 0 80 | stop = true 81 | 82 | func get_type(): 83 | return type; 84 | 85 | master func player_use(id): 86 | if Global.soul_intact: 87 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 88 | door_use(null) 89 | else: 90 | NetworkBridge.n_rpc(self, "door_use") 91 | elif Global.hope_discarded: 92 | Global.player.UI.notify("It hurts.", Color(1, 0, 0)) 93 | Global.player.UI.notify("It hurts.", Color(1, 0, 0)) 94 | Global.player.UI.notify("It hurts.", Color(1, 0, 0)) 95 | Global.player.UI.notify("It hurts.", Color(1, 0, 0)) 96 | else : 97 | Global.player.UI.notify("Feels like something is missing. It won't budge.", Color(0.9, 0.9, 1)) 98 | 99 | master func door_use(id): 100 | stop = not stop 101 | open = not open 102 | -------------------------------------------------------------------------------- /remaped/Destructible_Static.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var PARTICLE = preload("res://Entities/Particles/Destruction_Particle.tscn") 6 | 7 | export var door_health = 100 8 | var mesh_instance 9 | var type = 1 10 | var audio_player 11 | 12 | var isDestroyed = false 13 | 14 | var destroy_check_timer 15 | 16 | func _ready(): 17 | rset_config("door_health", MultiplayerAPI.RPC_MODE_PUPPET) 18 | NetworkBridge.register_rset(self, "door_health", NetworkBridge.PERMISSION.SERVER) 19 | 20 | NetworkBridge.register_rpcs(self, [ 21 | ["remove_on_ready", NetworkBridge.PERMISSION.SERVER], 22 | ["remove", NetworkBridge.PERMISSION.SERVER], 23 | ["check_removed", NetworkBridge.PERMISSION.ALL], 24 | ["network_destroy", NetworkBridge.PERMISSION.ALL], 25 | ["network_damage", NetworkBridge.PERMISSION.ALL] 26 | ]) 27 | 28 | for child in get_children(): 29 | if child is MeshInstance: 30 | mesh_instance = child 31 | var t = mesh_instance.transform 32 | audio_player = AudioStreamPlayer3D.new() 33 | get_parent().call_deferred("add_child", audio_player) 34 | yield (get_tree(), "idle_frame") 35 | audio_player.global_transform.origin = global_transform.origin 36 | audio_player.stream = load("res://Sfx/Environment/doorkick.wav") 37 | audio_player.unit_size = 10 38 | audio_player.unit_db = 2 39 | audio_player.max_db = 3 40 | 41 | destroy_check_timer = Timer.new() 42 | destroy_check_timer.wait_time = 2.0 43 | destroy_check_timer.one_shot = true 44 | destroy_check_timer.connect("timeout", self, "respawn") 45 | 46 | if not NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 47 | NetworkBridge.n_rpc(self, "check_removed") 48 | 49 | master func check_removed(id): 50 | if isDestroyed: 51 | NetworkBridge.n_rpc_id(self, id, "remove_on_ready") 52 | 53 | func destroy(collision_n, collision_p): 54 | network_destroy(null, collision_n, collision_p) 55 | 56 | master func network_destroy(id, collision_n, collision_p): 57 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 58 | damage(200, collision_n, collision_p, Vector3.ZERO) 59 | else: 60 | NetworkBridge.n_rpc(self, "network_destroy", [collision_n, collision_p]) 61 | 62 | func damage(dmg, nrml, pos, shoot_pos): 63 | network_damage(null, dmg, nrml, pos, shoot_pos) 64 | 65 | master func network_damage(id, damage, collision_n, collision_p, shooter_pos): 66 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 67 | door_health -= damage 68 | if door_health <= 0: 69 | remove(null, collision_n, collision_p) 70 | NetworkBridge.n_rpc(self, "remove", [collision_n, collision_p, true]) 71 | NetworkBridge.n_rset(self, "door_health", door_health) 72 | else: 73 | door_health -= damage 74 | if door_health <= 0: 75 | remove(null, collision_n, collision_p) 76 | destroy_check_timer.start() 77 | NetworkBridge.n_rpc(self, "network_damage", [damage, collision_n, collision_p, shooter_pos]) 78 | 79 | func get_type(): 80 | return type; 81 | 82 | puppet func remove_on_ready(id): 83 | set_collision_layer_bit(0,false) 84 | set_collision_mask_bit(0,false) 85 | hide() 86 | 87 | puppet func remove(id, collision_n, collision_p, from_host = false): 88 | if not visible and from_host: 89 | destroy_check_timer.stop() 90 | else: 91 | isDestroyed = true 92 | audio_player.global_transform.origin = collision_p 93 | audio_player.play() 94 | var new_particle = PARTICLE.instance() 95 | get_parent().add_child(new_particle) 96 | new_particle.global_transform.origin = collision_p 97 | new_particle.look_at(global_transform.origin + collision_n * 5 + Vector3(1e-06, 0, 0), Vector3.UP) 98 | new_particle.material_override = mesh_instance.mesh.surface_get_material(0) 99 | new_particle.emitting = true 100 | set_collision_layer_bit(0,false) 101 | set_collision_mask_bit(0,false) 102 | hide() 103 | 104 | func respawn(): 105 | isDestroyed = false 106 | set_collision_layer_bit(0,true) 107 | set_collision_mask_bit(0,true) 108 | show() 109 | -------------------------------------------------------------------------------- /maps/look.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="VisualShader" load_steps=13 format=2] 2 | 3 | [ext_resource path="res://MOD_CONTENT/CruS Online/maps/greyface1.png" type="Texture" id=1] 4 | [ext_resource path="res://MOD_CONTENT/CruS Online/maps/greyface2.png" type="Texture" id=2] 5 | 6 | [sub_resource type="VisualShaderNodeScalarConstant" id=2758] 7 | constant = 0.05 8 | 9 | [sub_resource type="VisualShaderNodeInput" id=2759] 10 | input_name = "uv" 11 | 12 | [sub_resource type="VisualShaderNodeVectorOp" id=2760] 13 | default_input_values = [ 0, Vector3( 0, 0, 0 ), 1, Vector3( 5, 5, 5 ) ] 14 | operator = 2 15 | 16 | [sub_resource type="VisualShaderNodeVec3Uniform" id=2761] 17 | uniform_name = "UV_Scale" 18 | default_value_enabled = true 19 | default_value = Vector3( 1, 1, 1 ) 20 | 21 | [sub_resource type="VisualShaderNodeTexture" id=2749] 22 | texture = ExtResource( 1 ) 23 | texture_type = 1 24 | 25 | [sub_resource type="VisualShaderNodeTexture" id=2750] 26 | output_port_for_preview = 1 27 | texture = ExtResource( 2 ) 28 | texture_type = 1 29 | 30 | [sub_resource type="VisualShaderNodeVectorScalarMix" id=2751] 31 | 32 | [sub_resource type="VisualShaderNodeVectorOp" id=2752] 33 | 34 | [sub_resource type="VisualShaderNodeInput" id=2753] 35 | input_name = "view" 36 | 37 | [sub_resource type="VisualShaderNodeVectorOp" id=2755] 38 | default_input_values = [ 0, Vector3( 0, 0, 0 ), 1, Vector3( 0.025, 0.025, 0.025 ) ] 39 | operator = 2 40 | 41 | [resource] 42 | code = "shader_type spatial; 43 | render_mode specular_schlick_ggx, async_visible; 44 | 45 | uniform vec3 UV_Scale = vec3(1.000000, 1.000000, 1.000000); 46 | uniform sampler2D tex_frg_2 : hint_albedo; 47 | uniform sampler2D tex_frg_4 : hint_albedo; 48 | 49 | 50 | 51 | void vertex() { 52 | // Output:0 53 | 54 | } 55 | 56 | void fragment() { 57 | // Input:17 58 | vec3 n_out17p0 = vec3(UV, 0.0); 59 | 60 | // VectorUniform:19 61 | vec3 n_out19p0 = UV_Scale; 62 | 63 | // VectorOp:18 64 | vec3 n_out18p0 = n_out17p0 * n_out19p0; 65 | 66 | // Texture:2 67 | vec4 tex_frg_2_read = texture(tex_frg_2, n_out18p0.xy); 68 | vec3 n_out2p0 = tex_frg_2_read.rgb; 69 | float n_out2p1 = tex_frg_2_read.a; 70 | 71 | // Input:7 72 | vec3 n_out7p0 = VIEW; 73 | 74 | // Scalar:16 75 | float n_out16p0 = 0.050000; 76 | 77 | // VectorOp:9 78 | vec3 n_out9p0 = n_out7p0 * vec3(n_out16p0); 79 | 80 | // VectorOp:6 81 | vec3 n_out6p0 = n_out18p0 + n_out9p0; 82 | 83 | // Texture:4 84 | vec4 tex_frg_4_read = texture(tex_frg_4, n_out6p0.xy); 85 | vec3 n_out4p0 = tex_frg_4_read.rgb; 86 | float n_out4p1 = tex_frg_4_read.a; 87 | 88 | // VectorScalarMix:5 89 | vec3 n_out5p0 = mix(n_out2p0, n_out4p0, n_out4p1); 90 | 91 | // Output:0 92 | ALBEDO = n_out5p0; 93 | 94 | } 95 | 96 | void light() { 97 | // Output:0 98 | 99 | } 100 | " 101 | graph_offset = Vector2( -957.276, 28.5196 ) 102 | nodes/fragment/0/position = Vector2( 240, 120 ) 103 | nodes/fragment/2/node = SubResource( 2749 ) 104 | nodes/fragment/2/position = Vector2( -180, 120 ) 105 | nodes/fragment/4/node = SubResource( 2750 ) 106 | nodes/fragment/4/position = Vector2( -180, 380 ) 107 | nodes/fragment/5/node = SubResource( 2751 ) 108 | nodes/fragment/5/position = Vector2( 20, 280 ) 109 | nodes/fragment/6/node = SubResource( 2752 ) 110 | nodes/fragment/6/position = Vector2( -360, 480 ) 111 | nodes/fragment/7/node = SubResource( 2753 ) 112 | nodes/fragment/7/position = Vector2( -720, 500 ) 113 | nodes/fragment/9/node = SubResource( 2755 ) 114 | nodes/fragment/9/position = Vector2( -540, 560 ) 115 | nodes/fragment/16/node = SubResource( 2758 ) 116 | nodes/fragment/16/position = Vector2( -740, 660 ) 117 | nodes/fragment/17/node = SubResource( 2759 ) 118 | nodes/fragment/17/position = Vector2( -520, 180 ) 119 | nodes/fragment/18/node = SubResource( 2760 ) 120 | nodes/fragment/18/position = Vector2( -540, 260 ) 121 | nodes/fragment/19/node = SubResource( 2761 ) 122 | nodes/fragment/19/position = Vector2( -960, 180 ) 123 | nodes/fragment/connections = PoolIntArray( 4, 1, 5, 2, 2, 0, 5, 0, 4, 0, 5, 1, 5, 0, 0, 0, 7, 0, 9, 0, 6, 0, 4, 0, 9, 0, 6, 1, 16, 0, 9, 1, 18, 0, 2, 0, 18, 0, 6, 0, 17, 0, 18, 0, 19, 0, 18, 1 ) 124 | -------------------------------------------------------------------------------- /remaped/Slotmachine.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var rotation_counter = - 1 6 | var coin = preload("res://Entities/Physics_Objects/Coin.tscn") 7 | 8 | func _ready(): 9 | NetworkBridge.register_rpcs(self, [ 10 | ["set_mech_rotation", NetworkBridge.PERMISSION.SERVER], 11 | ["set_rotation_counter", NetworkBridge.PERMISSION.ALL], 12 | ["notify", NetworkBridge.PERMISSION.SERVER], 13 | ["play_audio", NetworkBridge.PERMISSION.SERVER], 14 | ["client_spawn_coin", NetworkBridge.PERMISSION.SERVER], 15 | ["money_check", NetworkBridge.PERMISSION.SERVER], 16 | ["check_use", NetworkBridge.PERMISSION.ALL] 17 | ]) 18 | 19 | master func set_rotation_counter(id, recived_value): 20 | rotation_counter = recived_value 21 | 22 | puppet func set_mech_rotation(id, value): 23 | $MeshInstance2.rotation.x = value 24 | 25 | puppet func notify(id, value, color): 26 | Global.player.UI.notify(value, color) 27 | 28 | puppet func play_audio(id): 29 | $Audio.play() 30 | 31 | func _physics_process(delta): 32 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 33 | if rotation_counter >= 0: 34 | rotation_counter -= 1 35 | if not $Audio.playing: 36 | $Audio.play() 37 | NetworkBridge.n_rpc(self, "play_audio") 38 | $MeshInstance2.rotation.x += 1 39 | NetworkBridge.n_rpc_unreliable(self, "set_mech_rotation", [$MeshInstance2.rotation.x]) 40 | if rotation_counter == 0: 41 | randomize() 42 | if randi() % 1000 == 500: 43 | Global.player.UI.notify("You win $1000!", Color(1, 0, 1)) 44 | NetworkBridge.n_rpc(self, "notify", ["You win $1000!", Color(1, 0, 1)]) 45 | spawn_coins(100) 46 | elif randi() % 10 == 1: 47 | Global.player.UI.notify("You win $100!", Color(0, 1, 0)) 48 | NetworkBridge.n_rpc(self, "notify", ["You win $100!", Color(0, 1, 0)]) 49 | spawn_coins(10) 50 | elif randi() % 2 == 1: 51 | Global.player.UI.notify("You win $10!", Color(0, 1, 0)) 52 | NetworkBridge.n_rpc(self, "notify", ["You win $10!", Color(0, 1, 0)]) 53 | spawn_coins(1) 54 | else : 55 | Global.player.UI.notify("You lose", Color(1, 0, 0)) 56 | NetworkBridge.n_rpc(self, "notify", ["You lose", Color(1, 0, 0)]) 57 | else: 58 | set_physics_process(false) 59 | 60 | func spawn_coins(amount): 61 | for i in range(amount): 62 | var new_coin = coin.instance() 63 | new_coin.set_name(new_coin.name + "#" + str(new_coin.get_instance_id())) 64 | add_child(new_coin) 65 | new_coin.fromSlotMachine = true 66 | new_coin.global_transform.origin = $Position3D.global_transform.origin 67 | new_coin.damage(20, (global_transform.origin - ($Forward_Position.global_transform.origin + Vector3(rand_range( - 0.1, 0.1), rand_range( - 0.1, 0.1), rand_range( - 0.1, 0.1)))).normalized(), global_transform.origin, Vector3.ZERO) 68 | NetworkBridge.n_rpc(self, "client_spawn_coin", [get_path(), new_coin.name, new_coin.global_transform]) 69 | yield (get_tree(), "idle_frame") 70 | yield (get_tree(), "idle_frame") 71 | 72 | puppet func client_spawn_coin(id, parentPath, recivedName, recivedTransform): 73 | var new_coin = coin.instance() 74 | new_coin.set_name(recivedName) 75 | new_coin.fromSlotMachine = true 76 | new_coin.global_transform = recivedTransform 77 | get_node(parentPath).add_child(new_coin) 78 | 79 | func player_use(): 80 | if NetworkBridge.check_connection(): 81 | if NetworkBridge.n_is_network_master(self): 82 | check_use(null, true) 83 | else: 84 | NetworkBridge.n_rpc(self, "check_use") 85 | 86 | master func check_use(id, host = false): 87 | if rotation_counter >= 0: 88 | return 89 | 90 | if host: 91 | money_check(null) 92 | else: 93 | NetworkBridge.n_rpc(self, "money_check") 94 | 95 | puppet func money_check(id): 96 | if Global.money < 10: 97 | Global.player.UI.notify("$10 required to play", Color(1, 1, 1)) 98 | return 99 | Global.money -= 10 100 | 101 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 102 | rotation_counter = 50 103 | else: 104 | NetworkBridge.n_rpc(self, "set_rotation_counter", [50]) 105 | -------------------------------------------------------------------------------- /remaped/Destructible.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var PARTICLE = preload("res://Entities/Particles/Destruction_Particle.tscn") 6 | 7 | export var door_health = 100 8 | var mesh_instance 9 | var type = 1 10 | var audio_player 11 | 12 | var isDestroyed = false 13 | 14 | var destroy_check_timer 15 | 16 | func _ready(): 17 | set_process(false) 18 | for child in get_children(): 19 | if child is MeshInstance: 20 | mesh_instance = child 21 | var t = mesh_instance.transform 22 | audio_player = AudioStreamPlayer3D.new() 23 | get_parent().call_deferred("add_child", audio_player) 24 | yield (get_tree(), "idle_frame") 25 | audio_player.global_transform.origin = global_transform.origin 26 | audio_player.stream = load("res://Sfx/Environment/doorkick.wav") 27 | audio_player.unit_size = 10 28 | audio_player.unit_db = 2 29 | audio_player.max_db = 3 30 | 31 | destroy_check_timer = Timer.new() 32 | destroy_check_timer.wait_time = 2.0 33 | destroy_check_timer.one_shot = true 34 | destroy_check_timer.connect("timeout", self, "respawn") 35 | 36 | rset_config("door_health", MultiplayerAPI.RPC_MODE_PUPPET) 37 | NetworkBridge.register_rset(self, "door_health", NetworkBridge.PERMISSION.SERVER) 38 | 39 | NetworkBridge.register_rpcs(self, [ 40 | ["check_removed", NetworkBridge.PERMISSION.ALL], 41 | ["network_destroy", NetworkBridge.PERMISSION.ALL], 42 | ["network_damage", NetworkBridge.PERMISSION.ALL], 43 | ["remove_on_ready", NetworkBridge.PERMISSION.SERVER], 44 | ["remove", NetworkBridge.PERMISSION.SERVER] 45 | ]) 46 | 47 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 48 | NetworkBridge.n_rpc(self, "check_removed") 49 | 50 | master func check_removed(id): 51 | if isDestroyed: 52 | NetworkBridge.n_rpc_id(self, id, "remove_on_ready") 53 | 54 | func destroy(collision_n, collision_p): 55 | network_destroy(null, collision_n, collision_p) 56 | 57 | master func network_destroy(id, collision_n, collision_p): 58 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 59 | damage(200, collision_n, collision_p, Vector3.ZERO) 60 | else: 61 | remove(null, collision_n, collision_p) 62 | NetworkBridge.n_rpc(self, "network_destroy", [collision_n, collision_p]) 63 | 64 | func damage(dmg, nrml, pos, shoot_pos): 65 | network_damage(null, dmg, nrml, pos, shoot_pos) 66 | 67 | master func network_damage(id, damage, collision_n, collision_p, shooter_pos): 68 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 69 | door_health -= damage 70 | if door_health <= 0: 71 | remove(null, collision_n, collision_p) 72 | NetworkBridge.n_rpc(self, "remove", [collision_n, collision_p, true]) 73 | NetworkBridge.n_rset(self, "door_health", door_health) 74 | else: 75 | door_health -= damage 76 | if door_health <= 0: 77 | remove(null, collision_n, collision_p) 78 | destroy_check_timer.start() 79 | NetworkBridge.n_rpc(self, "network_damage", [damage, collision_n, collision_p, shooter_pos]) 80 | 81 | func get_type(): 82 | return type; 83 | 84 | puppet func remove_on_ready(id): 85 | set_collision_layer_bit(0,false) 86 | set_collision_mask_bit(0,false) 87 | hide() 88 | 89 | puppet func remove(id, collision_n, collision_p, from_host = false): 90 | if not visible and from_host: 91 | destroy_check_timer.stop() 92 | else: 93 | isDestroyed = true 94 | audio_player.global_transform.origin = collision_p 95 | audio_player.play() 96 | var new_particle = PARTICLE.instance() 97 | get_parent().add_child(new_particle) 98 | new_particle.global_transform.origin = collision_p 99 | new_particle.look_at(global_transform.origin + collision_n * 5 + Vector3(1e-06, 0, 0), Vector3.UP) 100 | new_particle.material_override = mesh_instance.mesh.surface_get_material(0) 101 | new_particle.emitting = true 102 | set_collision_layer_bit(0,false) 103 | set_collision_mask_bit(0,false) 104 | hide() 105 | 106 | func respawn(): 107 | isDestroyed = false 108 | set_collision_layer_bit(0,true) 109 | set_collision_mask_bit(0,true) 110 | show() 111 | -------------------------------------------------------------------------------- /remaped/abraxas.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var t = 0 6 | 7 | onready var torus = $"Armature/Skeleton/BoneAttachment 2/Torus" 8 | onready var head = $Armature / Skeleton / BoneAttachment / Head 9 | onready var anim = $AnimationPlayer 10 | onready var laser = $"Armature/Skeleton/BoneAttachment 4/Right_Tail" 11 | onready var rocket = $"Armature/Skeleton/BoneAttachment 3/Left_Tail" 12 | const SPAWNS:Array = [preload("res://Entities/Enemies/E_Grunt_Meltdown.tscn"), preload("res://Entities/Enemies/E_Civilian_Meltdown.tscn"), preload("res://Entities/Enemies/E_Knifelord.tscn")] 13 | var head_disabled = false 14 | var enemy_spawn_frequency = 200 15 | var kill_flag = false 16 | var activated = false 17 | 18 | puppet func set_animation(id, animation:String, speed:float)->void : 19 | anim.play(animation) 20 | anim.playback_speed = speed 21 | 22 | func get_near_player(object) -> Dictionary: 23 | var oldDistance = null 24 | var checkPlayer = null 25 | 26 | for selectedPlayer in get_tree().get_nodes_in_group("Player"): 27 | var distance = object.global_transform.origin.distance_to(selectedPlayer.global_transform.origin) 28 | if oldDistance == null or oldDistance > distance: 29 | oldDistance = distance 30 | checkPlayer = selectedPlayer 31 | 32 | return { 33 | "player" : checkPlayer, 34 | "distance" : oldDistance 35 | } 36 | 37 | func _ready(): 38 | Global.objectives += 1 39 | 40 | NetworkBridge.register_rpcs(self, [ 41 | ["set_animation", NetworkBridge.PERMISSION.SERVER], 42 | ["die", NetworkBridge.PERMISSION.SERVER], 43 | ["spawn_enemy", NetworkBridge.PERMISSION.SERVER] 44 | ]) 45 | 46 | func _process(delta): 47 | torus.rotate_object_local(Vector3.BACK, deg2rad(1)) 48 | 49 | puppet func die(id): 50 | anim.play("Die") 51 | Global.remove_objective() 52 | 53 | func _physics_process(delta): 54 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 55 | t += 1 56 | 57 | if not activated and fmod(t, 20) == 0: 58 | var space = get_world().direct_space_state 59 | var result = space.intersect_ray(head.global_transform.origin, get_near_player(self).player.global_transform.origin + Vector3.UP * 1.0, [self, head]) 60 | if result: 61 | if result.collider == Global.player or result.collider.has_meta("puppet"): 62 | activated = true 63 | head.active = true 64 | return 65 | 66 | if not activated: 67 | return 68 | 69 | if head.destroyed and laser.destroyed and rocket.destroyed and not kill_flag: 70 | kill_flag = true 71 | anim.play("Die") 72 | Global.remove_objective() 73 | NetworkBridge.n_rpc(self, "die") 74 | 75 | elif not kill_flag: 76 | anim.play("Idle") 77 | NetworkBridge.n_rpc_unreliable(self, "set_animation", ["Idle", 1]) 78 | 79 | if laser.destroyed or rocket.destroyed: 80 | enemy_spawn_frequency = 150 81 | if laser.destroyed and rocket.destroyed: 82 | enemy_spawn_frequency = 100 83 | if rocket.destroyed or head.destroyed: 84 | laser.disabled = false 85 | if head.destroyed and laser.destroyed: 86 | rocket.frequency = 20 87 | if head.destroyed and rocket.destroyed: 88 | laser.follow_speed = 0.1 89 | elif fmod(t, 200) == 0: 90 | if is_instance_valid(laser): 91 | laser.disabled = not laser.disabled 92 | if laser.destroyed or head.destroyed: 93 | rocket.disabled = false 94 | elif fmod(t, 150) == 0: 95 | if is_instance_valid(rocket): 96 | rocket.disabled = not rocket.disabled 97 | if fmod(t, enemy_spawn_frequency) == 0: 98 | if head.destroyed: 99 | return 100 | 101 | var selectedEnemy = randi() % 3 102 | 103 | var new_enemy = SPAWNS[selectedEnemy].instance() 104 | 105 | new_enemy.set_name(new_enemy.name + "#" + str(new_enemy.get_instance_id())) 106 | 107 | get_parent().add_child(new_enemy) 108 | new_enemy.global_transform.origin = head.global_transform.origin 109 | 110 | NetworkBridge.n_rpc(self, "spawn_enemy", [selectedEnemy, get_parent().get_path(), new_enemy.name, new_enemy.global_transform]) 111 | 112 | yield (get_tree(), "idle_frame") 113 | new_enemy.add_velocity(40, (global_transform.origin - get_near_player(self).player.global_transform.origin).normalized()) 114 | else: 115 | set_physics_process(false) 116 | 117 | puppet func spawn_enemy(id, selectedEnemy, parentPath, enemyName, enemyTransform): 118 | var new_enemy = SPAWNS[selectedEnemy].instance() 119 | get_node(parentPath).add_child(new_enemy) 120 | new_enemy.set_name(enemyName) 121 | new_enemy.global_transform = enemyTransform 122 | 123 | -------------------------------------------------------------------------------- /remaped/Fire_Child.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var lifetime = 200 6 | var t = 0 7 | var player_fire = false 8 | 9 | onready var f = load("res://Entities/Bullets/Fire_Child.tscn") 10 | 11 | var last_transform 12 | var lerp_transform 13 | 14 | var tick = 0 15 | 16 | func host_tick(): 17 | tick += 1 18 | if (global_transform.origin - last_transform.origin).length() > 0.01 and tick % 2 == 0: 19 | last_transform = global_transform 20 | 21 | NetworkBridge.n_rpc_unreliable(self, "_set_transform", [global_transform]) 22 | 23 | tick = 0 24 | 25 | func _ready(): 26 | lerp_transform = global_transform 27 | 28 | NetworkBridge.register_rpcs(self, [ 29 | ["_set_transform", NetworkBridge.PERMISSION.SERVER], 30 | ["_delete", NetworkBridge.PERMISSION.SERVER], 31 | ["_create_object", NetworkBridge.PERMISSION.SERVER] 32 | ]) 33 | 34 | puppet func _set_transform(id, recivedTransform): 35 | lerp_transform = recivedTransform 36 | 37 | puppet func _delete(id): 38 | queue_free() 39 | 40 | puppet func _create_object(id, recivedPath, recivedObject, recivedName, recivedTransform, recivedPlayerFire = null): 41 | var newObject = load(recivedObject).instance() 42 | newObject.set_name(recivedName) 43 | get_node(recivedPath).add_child(newObject) 44 | newObject.global_transform = recivedTransform 45 | if recivedPlayerFire != null: 46 | newObject.player_fire = recivedPlayerFire 47 | 48 | func _physics_process(delta): 49 | if NetworkBridge.n_is_network_master(self): 50 | host_tick() 51 | 52 | t += 1 53 | if lifetime < t: 54 | var parent = get_parent() 55 | if parent.has_method("set_fire"): 56 | parent.set_fire(false) 57 | 58 | NetworkBridge.n_rpc(self, "_delete") 59 | queue_free() 60 | 61 | if fmod(t, 25) != 0: 62 | return 63 | 64 | var parent = get_parent() 65 | 66 | if parent.has_method("player_damage"): 67 | parent.player_damage(5, Vector3.ZERO, global_transform.origin, global_transform.origin, "fire") 68 | else: 69 | if "soul" in parent and not "random_line" in parent: 70 | if parent.soul.pain_sfx[0].stream != parent.soul.firesound: 71 | parent.soul.pain_sfx[0].stream = parent.soul.firesound 72 | parent.soul.damage(20.6, Vector3.ZERO, global_transform.origin, global_transform.origin) 73 | elif "random_line" in parent: 74 | if not "pain_sfx" in parent.get_parent(): 75 | return 76 | if parent.get_parent().pain_sfx[0].stream != parent.get_parent().firesound: 77 | parent.get_parent().pain_sfx[0].stream = parent.get_parent().firesound 78 | parent.get_parent().damage(5, Vector3.ZERO, global_transform.origin, global_transform.origin) 79 | else: 80 | if parent.has_method("damage"): 81 | parent.damage(5, Vector3.ZERO, global_transform.origin, global_transform.origin) 82 | else: 83 | global_transform = global_transform.interpolate_with(lerp_transform, delta * 10.0) 84 | 85 | func _on_Area_body_entered(body): 86 | if NetworkBridge.n_is_network_master(self): 87 | var parent = get_parent() 88 | 89 | if body != parent: 90 | if body.has_meta("puppet") and not body.has_meta("puppet_body"): 91 | return 92 | elif not body.has_meta("puppet_body") and "soul" in body: 93 | var new_fire_child = f.instance() 94 | new_fire_child.set_name("FireChild#" + str(new_fire_child.get_instance_id())) 95 | 96 | if body.soul.on_fire: 97 | return 98 | body.soul.on_fire = true 99 | body.soul.body.add_child(new_fire_child) 100 | new_fire_child.scale.y = 2.0 101 | new_fire_child.global_transform.origin = body.soul.body.global_transform.origin - Vector3.UP * 0.5 102 | 103 | NetworkBridge.n_rpc(self, "_create_object", [body.soul.body.get_path(), "res://Entities/Bullets/Fire_Child.tscn", new_fire_child.name, new_fire_child.global_transform, true]) 104 | elif (body == Global.player or body.has_meta("puppet_body")) and not player_fire: 105 | var new_fire_child = f.instance() 106 | new_fire_child.set_name("FireChild#" + str(new_fire_child.get_instance_id())) 107 | 108 | body.add_child(new_fire_child) 109 | player_fire = true 110 | new_fire_child.player_fire = true 111 | new_fire_child.scale.y = 2.0 112 | new_fire_child.global_transform.origin = body.global_transform.origin - Vector3.UP * 0.5 113 | 114 | NetworkBridge.n_rpc(self, "_create_object", [body.get_path(), "res://Entities/Bullets/Fire_Child.tscn", new_fire_child.name, new_fire_child.global_transform, true]) 115 | 116 | func set_water(value): 117 | if NetworkBridge.n_is_network_master(self): 118 | NetworkBridge.n_rpc(self, "_delete") 119 | queue_free() 120 | -------------------------------------------------------------------------------- /remaped/Abraxas_Laser.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var type = 1 6 | var laser 7 | var health = 300 8 | var follow_speed = 0.02 9 | var particle 10 | var active = false 11 | var destroyed = false 12 | var look_towards = Vector3.ZERO 13 | var t = 0 14 | var disabled = true 15 | 16 | func get_near_player(object) -> Dictionary: 17 | var oldDistance = null 18 | var checkPlayer = null 19 | 20 | for selectedPlayer in get_tree().get_nodes_in_group("Player"): 21 | var distance = object.global_transform.origin.distance_to(selectedPlayer.global_transform.origin) 22 | if oldDistance == null or oldDistance > distance: 23 | oldDistance = distance 24 | checkPlayer = selectedPlayer 25 | 26 | return { 27 | "player" : checkPlayer, 28 | "distance" : oldDistance 29 | } 30 | 31 | func _ready(): 32 | NetworkBridge.register_rpcs(self, [ 33 | ["particle_visible", NetworkBridge.PERMISSION.SERVER], 34 | ["died", NetworkBridge.PERMISSION.SERVER], 35 | ["network_damage", NetworkBridge.PERMISSION.ALL] 36 | ]) 37 | 38 | look_towards = Global.player.global_transform.origin 39 | laser = $Laser 40 | particle = $Particles 41 | 42 | laser.rset_config("global_transform", MultiplayerAPI.RPC_MODE_PUPPET) 43 | particle.rset_config("global_transform", MultiplayerAPI.RPC_MODE_PUPPET) 44 | 45 | NetworkBridge.register_rset(laser, "global_transform", NetworkBridge.PERMISSION.SERVER) 46 | NetworkBridge.register_rset(particle, "global_transform", NetworkBridge.PERMISSION.SERVER) 47 | 48 | NetworkBridge.register_rset(self, "visible", NetworkBridge.PERMISSION.SERVER) 49 | rset_config("visible", MultiplayerAPI.RPC_MODE_PUPPET) 50 | 51 | puppet func particle_visible(id, value = true): 52 | particle.visible = value 53 | 54 | func _physics_process(delta): 55 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 56 | t += 1 57 | if destroyed: 58 | if visible: 59 | hide() 60 | NetworkBridge.n_rset_unreliable(self, "visible", false) 61 | return 62 | if disabled: 63 | if particle.visible: 64 | particle.hide() 65 | NetworkBridge.n_rpc_unreliable(self, "particle_visible", [false]) 66 | if laser.scale.z < 3: 67 | hide() 68 | laser.scale.z = lerp(laser.scale.z, 1, 0.2) 69 | NetworkBridge.n_rset_unreliable(laser, "global_transform", laser.global_transform) 70 | return 71 | show() 72 | look_towards = lerp(look_towards, get_near_player(self).player.global_transform.origin + Vector3.UP * 1.0, follow_speed) 73 | var space = get_world().direct_space_state 74 | if not active: 75 | var active_result = space.intersect_ray(global_transform.origin, get_near_player(self).player.global_transform.origin + Vector3.UP * 1.0, [self]) 76 | if active_result: 77 | if active_result.collider == Global.player or active_result.collider.has_meta("puppet"): 78 | active = true 79 | else : 80 | return 81 | var result = space.intersect_ray(global_transform.origin, global_transform.origin - (global_transform.origin - look_towards).normalized() * 200, [self]) 82 | if result: 83 | particle.show() 84 | particle.global_transform.origin = result.position 85 | laser.scale.z = lerp(laser.scale.z, global_transform.origin.distance_to(result.position) * 0.5, 0.2) 86 | laser.look_at(result.position, Vector3.UP) 87 | NetworkBridge.n_rpc_unreliable(self, "particle_visible", [true]) 88 | NetworkBridge.n_rset_unreliable(laser, "global_transform", laser.global_transform) 89 | NetworkBridge.n_rset_unreliable(particle, "global_transform", particle.global_transform) 90 | if result.collider == Global.player or result.collider.has_meta("puppet"): 91 | result.collider.damage(20, result.normal, result.position, global_transform.origin) 92 | else : 93 | particle.hide() 94 | laser.scale.z = 400 95 | NetworkBridge.n_rpc_unreliable(self, "particle_visible", [false]) 96 | NetworkBridge.n_rset_unreliable(laser, "global_transform", laser.global_transform) 97 | else: 98 | set_physics_process(false) 99 | 100 | puppet func died(id): 101 | get_parent().get_node("Particle").show() 102 | get_parent().get_node("Sphere002").hide() 103 | 104 | func damage(dmg, nrml, pos, shoot_pos): 105 | network_damage(null, dmg, nrml, pos, shoot_pos) 106 | 107 | master func network_damage(id, dmg, nrml, pos, shoot_pos): 108 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 109 | if not active: 110 | return 111 | health -= dmg 112 | if health <= 0: 113 | destroyed = true 114 | died(null) 115 | NetworkBridge.n_rpc(self, "died") 116 | else: 117 | NetworkBridge.n_rpc(self, "network_damage", [dmg, nrml, pos, shoot_pos]) 118 | 119 | func get_type(): 120 | return type; 121 | -------------------------------------------------------------------------------- /remaped/grid_enemy.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | enum {FORWARD, RIGHT, BACK, LEFT} 6 | const DIR = [Vector3.FORWARD * 2, Vector3.RIGHT * 2, Vector3.BACK * 2, Vector3.LEFT * 2] 7 | var current_dir = DIR[FORWARD] 8 | var player_dir 9 | var step_count = 59 10 | var step_length = 100 11 | var last_pos 12 | var next_pos 13 | var space_state 14 | var result_forward 15 | var result_back 16 | var result_left 17 | var result_right 18 | var result_current 19 | onready var mesh = $crab 20 | var t = 0 21 | 22 | func get_near_player(object) -> Dictionary: 23 | var oldDistance = null 24 | var checkPlayer = null 25 | 26 | for selectedPlayer in get_tree().get_nodes_in_group("Player"): 27 | var distance = object.global_transform.origin.distance_to(selectedPlayer.global_transform.origin) 28 | if oldDistance == null or oldDistance > distance: 29 | oldDistance = distance 30 | checkPlayer = selectedPlayer 31 | 32 | return { 33 | "player" : checkPlayer, 34 | "distance" : oldDistance 35 | } 36 | 37 | func _ready(): 38 | rset_config("global_transform", MultiplayerAPI.RPC_MODE_PUPPET) 39 | NetworkBridge.register_rset(self, "global_transform", NetworkBridge.PERMISSION.SERVER) 40 | 41 | set_collision_mask_bit(1, 1) 42 | set_safe_margin(0) 43 | last_pos = global_transform.origin 44 | next_pos = global_transform.origin + current_dir 45 | 46 | func _physics_process(delta): 47 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 48 | if get_near_player(self).distance > 20: 49 | return 50 | 51 | look() 52 | 53 | NetworkBridge.n_rset(self, "global_transform", global_transform) 54 | 55 | step_count += 1 56 | if step_count == 60: 57 | space_state = get_world().direct_space_state 58 | result_forward = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.FORWARD * 1) 59 | result_back = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.BACK * 1) 60 | result_left = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.LEFT * 1) 61 | result_right = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.RIGHT * 1) 62 | result_current = space_state.intersect_ray(global_transform.origin, global_transform.origin + current_dir * 0.5) 63 | if result_current: 64 | if result_forward and not result_right: 65 | current_dir = DIR[RIGHT] 66 | if result_right and not result_back: 67 | current_dir = DIR[BACK] 68 | if result_back and not result_left: 69 | current_dir = DIR[LEFT] 70 | if result_left and not result_forward: 71 | current_dir = DIR[FORWARD] 72 | if player_dir != null: 73 | if not space_state.intersect_ray(global_transform.origin, global_transform.origin + player_dir * 0.5): 74 | current_dir = player_dir 75 | else : 76 | player_dir = null 77 | if step_count == 60: 78 | step_count = 0 79 | last_pos = global_transform.origin 80 | next_pos = global_transform.origin + current_dir 81 | mesh.look_at(global_transform.origin - current_dir, Vector3.UP) 82 | else : 83 | if result_back and result_forward and result_left and result_right: 84 | return 85 | global_transform.origin = lerp(global_transform.origin, next_pos, 0.3) 86 | 87 | func look(): 88 | var space_state = get_world().direct_space_state 89 | var result_forward = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.FORWARD * 100) 90 | var result_back = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.BACK * 100) 91 | var result_left = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.LEFT * 100) 92 | var result_right = space_state.intersect_ray(global_transform.origin, global_transform.origin + Vector3.RIGHT * 100) 93 | 94 | if result_forward: 95 | if result_forward.collider == Global.player or result_forward.collider.has_meta("puppet") or result_forward.collider.has_method("already_dead"): 96 | player_dir = DIR[FORWARD] 97 | 98 | if result_back: 99 | if result_back.collider == Global.player or result_back.collider.has_meta("puppet") or result_back.collider.has_method("already_dead"): 100 | player_dir = DIR[BACK] 101 | 102 | if result_right: 103 | if result_right.collider == Global.player or result_right.collider.has_meta("puppet") or result_right.collider.has_method("already_dead"): 104 | player_dir = DIR[RIGHT] 105 | 106 | if result_left: 107 | if result_left.collider == Global.player or result_left.collider.has_meta("puppet") or result_left.collider.has_method("already_dead"): 108 | player_dir = DIR[LEFT] 109 | 110 | func _on_Area_area_entered(area): 111 | pass 112 | 113 | func _on_Area_body_entered(body): 114 | if body.get_collision_layer_bit(0): 115 | return 116 | if body.has_method("damage") and NetworkBridge.n_is_network_master(self): 117 | body.damage(100, current_dir.normalized(), global_transform.origin, global_transform.origin) 118 | -------------------------------------------------------------------------------- /remaped/Weapon_Slotmachine.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var rotation_counter = - 1 6 | var coin = preload("res://Entities/Physics_Objects/Coin.tscn") 7 | 8 | var junk_items:Array = [ 9 | preload("res://Entities/Physics_Objects/Chest_Gib.tscn"), 10 | preload("res://Entities/Physics_Objects/Head_Gib.tscn"), 11 | preload("res://Entities/Props/Plant_1.tscn"), 12 | preload("res://Entities/Props/Trashcan.tscn"), 13 | preload("res://Entities/Props/Monitor.tscn") 14 | ] 15 | 16 | var weapon_drop = preload("res://Entities/Objects/Gun_Pickup.tscn") 17 | var weapon_indexes:Array = [[0, 1, 4, 7, 9], [2, 5, 6, 8, 12, 13, 17], [18]] 18 | var wep = 0 19 | 20 | master func set_rotation_counter(id, recived_value): 21 | rotation_counter = recived_value 22 | 23 | func _ready(): 24 | NetworkBridge.register_rpcs(self, [ 25 | ["set_mech_rotation", NetworkBridge.PERMISSION.SERVER], 26 | ["set_rotation_counter", NetworkBridge.PERMISSION.ALL], 27 | ["notify", NetworkBridge.PERMISSION.SERVER], 28 | ["play_audio", NetworkBridge.PERMISSION.SERVER], 29 | ["client_spawn_item", NetworkBridge.PERMISSION.SERVER], 30 | ["money_check", NetworkBridge.PERMISSION.SERVER], 31 | ["check_use", NetworkBridge.PERMISSION.ALL] 32 | ]) 33 | 34 | puppet func set_mech_rotation(id, value): 35 | $MeshInstance2.rotation.x = value 36 | 37 | puppet func notify(id, value, color): 38 | Global.player.UI.notify(value, color) 39 | 40 | puppet func play_audio(id): 41 | $Audio.play() 42 | 43 | func _physics_process(delta): 44 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 45 | if rotation_counter >= 0: 46 | rotation_counter -= 1 47 | if not $Audio.playing: 48 | $Audio.play() 49 | NetworkBridge.n_rpc(self, "play_audio") 50 | $MeshInstance2.rotation.x += 1 51 | NetworkBridge.n_rpc_unreliable(self, "set_mech_rotation", [$MeshInstance2.rotation.x]) 52 | if rotation_counter == 0: 53 | randomize() 54 | if randi() % 500 == 5: 55 | spawn_item() 56 | wep = 2 57 | elif randi() % 10 == 1: 58 | spawn_item() 59 | wep = 1 60 | elif randi() % 2 == 1: 61 | spawn_item() 62 | wep = 0 63 | else : 64 | Global.player.UI.notify("You lose", Color(1, 0, 0)) 65 | NetworkBridge.n_rpc(self, "notify", ["You lose", Color(1, 0, 0)]) 66 | else: 67 | set_physics_process(false) 68 | 69 | func spawn_item(): 70 | var new_weapon_drop = weapon_drop.instance() 71 | get_parent().add_child(new_weapon_drop) 72 | new_weapon_drop.gun.MESH[new_weapon_drop.gun.current_weapon].hide() 73 | var wepRand = randi() % weapon_indexes[wep].size() 74 | new_weapon_drop.set_name(new_weapon_drop.name + "#" + str(new_weapon_drop.get_instance_id())) 75 | new_weapon_drop.gun.current_weapon = weapon_indexes[wep][wepRand] 76 | new_weapon_drop.gun.ammo = Global.player.weapon.MAX_MAG_AMMO[new_weapon_drop.gun.current_weapon] 77 | new_weapon_drop.gun.MESH[new_weapon_drop.gun.current_weapon].show() 78 | new_weapon_drop.global_transform.origin = $Position3D.global_transform.origin 79 | new_weapon_drop.damage(5, (global_transform.origin - ($Forward_Position.global_transform.origin + Vector3(rand_range( - 0.1, 0.1), rand_range( - 0.1, 0.1), rand_range( - 0.1, 0.1)))).normalized(), global_transform.origin, Vector3.ZERO) 80 | 81 | new_weapon_drop.register_all_rpcs() 82 | new_weapon_drop.gun.register_all_rpcs() 83 | 84 | NetworkBridge.n_rpc(self, "client_spawn_item", [get_parent().get_path(), new_weapon_drop.name, new_weapon_drop.global_transform, wep, wepRand]) 85 | 86 | puppet func client_spawn_item(id, recivedPath, recivedName, recivedTransform, recivedIndexA, recivedIndexB): 87 | var new_weapon_drop = weapon_drop.instance() 88 | get_node(recivedPath).add_child(new_weapon_drop) 89 | new_weapon_drop.set_name(recivedName) 90 | new_weapon_drop.gun.MESH[new_weapon_drop.gun.current_weapon].hide() 91 | new_weapon_drop.gun.current_weapon = weapon_indexes[recivedIndexA][recivedIndexB] 92 | new_weapon_drop.gun.ammo = Global.player.weapon.MAX_MAG_AMMO[new_weapon_drop.gun.current_weapon] 93 | new_weapon_drop.gun.MESH[new_weapon_drop.gun.current_weapon].show() 94 | new_weapon_drop.global_transform = recivedTransform 95 | 96 | new_weapon_drop.register_all_rpcs() 97 | new_weapon_drop.gun.register_all_rpcs() 98 | 99 | func player_use(): 100 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 101 | check_use(null, true) 102 | else: 103 | NetworkBridge.n_rpc(self, "check_use") 104 | 105 | master func check_use(id, host = false): 106 | if rotation_counter >= 0: 107 | return 108 | 109 | if host: 110 | money_check(null) 111 | else: 112 | NetworkBridge.n_rpc(self, "money_check") 113 | 114 | puppet func money_check(id): 115 | if Global.money < 10: 116 | Global.player.UI.notify("$10 required to play", Color(1, 1, 1)) 117 | return 118 | Global.money -= 10 119 | 120 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 121 | rotation_counter = 50 122 | else: 123 | NetworkBridge.n_rpc(self, "set_rotation_counter", [50]) 124 | -------------------------------------------------------------------------------- /extramenu.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Theme" load_steps=20 format=2] 2 | 3 | [ext_resource path="res://Textures/Menu/background_1.png" type="Texture" id=1] 4 | [ext_resource path="res://MOD_CONTENT/CruS Online/redpanel.tres" type="StyleBox" id=2] 5 | [ext_resource path="res://Textures/Menu/fish_found.png" type="Texture" id=3] 6 | [ext_resource path="res://Textures/Menu/fish_not_found.png" type="Texture" id=4] 7 | 8 | [sub_resource type="DynamicFontData" id=12] 9 | font_path = "res://Fonts/gamefont(1).ttf" 10 | 11 | [sub_resource type="DynamicFont" id=13] 12 | outline_color = Color( 0, 0, 0, 1 ) 13 | use_mipmaps = true 14 | use_filter = true 15 | font_data = SubResource( 12 ) 16 | 17 | [sub_resource type="StyleBoxTexture" id=3] 18 | texture = ExtResource( 1 ) 19 | region_rect = Rect2( 0, 0, 256, 256 ) 20 | margin_top = 5.0 21 | margin_bottom = 5.0 22 | axis_stretch_vertical = 1 23 | modulate_color = Color( 0.356863, 0.054902, 0.054902, 1 ) 24 | 25 | [sub_resource type="DynamicFontData" id=14] 26 | font_path = "res://Fonts/gamefont(1).ttf" 27 | 28 | [sub_resource type="DynamicFont" id=15] 29 | use_mipmaps = true 30 | use_filter = true 31 | font_data = SubResource( 14 ) 32 | 33 | [sub_resource type="DynamicFontData" id=1] 34 | font_path = "res://Fonts/gamefont(1).ttf" 35 | 36 | [sub_resource type="DynamicFont" id=2] 37 | outline_color = Color( 0, 0, 0, 1 ) 38 | use_mipmaps = true 39 | use_filter = true 40 | font_data = SubResource( 1 ) 41 | 42 | [sub_resource type="DynamicFontData" id=4] 43 | font_path = "res://Fonts/gamefont(1).ttf" 44 | 45 | [sub_resource type="DynamicFont" id=5] 46 | outline_color = Color( 0, 0, 0, 1 ) 47 | use_mipmaps = true 48 | use_filter = true 49 | font_data = SubResource( 4 ) 50 | 51 | [sub_resource type="DynamicFontData" id=6] 52 | font_path = "res://Fonts/gamefont(1).ttf" 53 | 54 | [sub_resource type="DynamicFont" id=7] 55 | outline_color = Color( 0, 0, 0, 1 ) 56 | use_mipmaps = true 57 | use_filter = true 58 | font_data = SubResource( 6 ) 59 | 60 | [sub_resource type="DynamicFontData" id=8] 61 | font_path = "res://Fonts/gamefont(1).ttf" 62 | 63 | [sub_resource type="DynamicFont" id=9] 64 | outline_color = Color( 0, 0, 0, 1 ) 65 | use_mipmaps = true 66 | use_filter = true 67 | font_data = SubResource( 8 ) 68 | 69 | [sub_resource type="StyleBoxFlat" id=10] 70 | bg_color = Color( 0.6, 0.6, 0.6, 0 ) 71 | border_width_left = 1 72 | border_width_top = 1 73 | border_width_right = 1 74 | border_width_bottom = 1 75 | border_color = Color( 0.196078, 1, 0, 1 ) 76 | 77 | [sub_resource type="StyleBoxLine" id=11] 78 | color = Color( 1, 0, 0, 1 ) 79 | 80 | [resource] 81 | CheckBox/colors/font_color = Color( 1, 0, 0, 1 ) 82 | CheckBox/colors/font_color_focus = Color( 1, 0, 0, 1 ) 83 | CheckBox/colors/font_color_hover = Color( 0.14902, 1, 0, 1 ) 84 | CheckBox/colors/font_color_hover_pressed = Color( 0.0784314, 0.619608, 0, 1 ) 85 | CheckBox/colors/font_color_pressed = Color( 1, 0, 0, 1 ) 86 | CheckBox/fonts/font = SubResource( 13 ) 87 | CheckBox/styles/focus = SubResource( 3 ) 88 | CheckBox/styles/hover = SubResource( 3 ) 89 | CheckBox/styles/hover_pressed = SubResource( 3 ) 90 | CheckBox/styles/normal = SubResource( 3 ) 91 | CheckBox/styles/pressed = SubResource( 3 ) 92 | CheckButton/colors/font_color = Color( 1, 0, 0, 1 ) 93 | CheckButton/colors/font_color_focus = Color( 0, 1, 0.0627451, 1 ) 94 | CheckButton/colors/font_color_hover = Color( 0.101961, 1, 0, 1 ) 95 | CheckButton/colors/font_color_hover_pressed = Color( 1, 0, 0, 1 ) 96 | CheckButton/colors/font_color_pressed = Color( 1, 0, 0, 1 ) 97 | CheckButton/fonts/font = SubResource( 15 ) 98 | CheckButton/icons/off = ExtResource( 3 ) 99 | CheckButton/icons/on = ExtResource( 4 ) 100 | LineEdit/colors/cursor_color = Color( 1, 0, 0, 1 ) 101 | LineEdit/colors/font_color = Color( 1, 0, 0, 1 ) 102 | LineEdit/colors/font_color_selected = Color( 1, 0, 0, 0.588235 ) 103 | LineEdit/fonts/font = SubResource( 2 ) 104 | LineEdit/styles/normal = SubResource( 3 ) 105 | OptionButton/colors/font_color = Color( 1, 0, 0, 1 ) 106 | OptionButton/colors/font_color_disabled = Color( 0.431373, 0, 0, 1 ) 107 | OptionButton/colors/font_color_focus = Color( 1, 0, 0, 1 ) 108 | OptionButton/colors/font_color_hover = Color( 0, 1, 0.0627451, 1 ) 109 | OptionButton/colors/font_color_pressed = Color( 0.0156863, 0.52549, 0, 1 ) 110 | OptionButton/fonts/font = SubResource( 5 ) 111 | OptionButton/styles/disabled = ExtResource( 2 ) 112 | OptionButton/styles/focus = ExtResource( 2 ) 113 | OptionButton/styles/hover = ExtResource( 2 ) 114 | OptionButton/styles/normal = ExtResource( 2 ) 115 | OptionButton/styles/pressed = ExtResource( 2 ) 116 | PopupMenu/colors/font_color = Color( 1, 0, 0, 1 ) 117 | PopupMenu/colors/font_color_accel = Color( 0.0392157, 0.376471, 0, 0.8 ) 118 | PopupMenu/colors/font_color_disabled = Color( 0.321569, 0, 0, 0.8 ) 119 | PopupMenu/colors/font_color_hover = Color( 0.14902, 1, 0, 1 ) 120 | PopupMenu/colors/font_color_separator = Color( 1, 0, 0, 1 ) 121 | PopupMenu/fonts/font = SubResource( 7 ) 122 | PopupMenu/fonts/font_separator = SubResource( 9 ) 123 | PopupMenu/icons/radio_checked = ExtResource( 3 ) 124 | PopupMenu/icons/radio_unchecked = ExtResource( 4 ) 125 | PopupMenu/styles/hover = SubResource( 10 ) 126 | PopupMenu/styles/panel = ExtResource( 2 ) 127 | PopupMenu/styles/separator = SubResource( 11 ) 128 | -------------------------------------------------------------------------------- /entities/Enemy_Controller.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var thread 6 | var enemies 7 | var player 8 | var glob 9 | var delta 10 | var mutex 11 | 12 | # Multiplayer stuff 13 | ################################################################################ 14 | 15 | func get_near_player(object) -> Dictionary: 16 | var oldDistance = null 17 | var checkPlayer = null 18 | 19 | for selectedPlayer in get_tree().get_nodes_in_group("Player"): 20 | var distance = object.global_transform.origin.distance_to(selectedPlayer.global_transform.origin) 21 | if oldDistance == null or oldDistance > distance: 22 | oldDistance = distance 23 | checkPlayer = selectedPlayer 24 | 25 | return { 26 | "player" : checkPlayer, 27 | "distance" : oldDistance 28 | } 29 | 30 | ################################################################################ 31 | 32 | func _ready(): 33 | mutex = Mutex.new() 34 | thread = Thread.new() 35 | 36 | enemies = get_tree().get_nodes_in_group("enemies") 37 | player = Global.player 38 | delta = get_physics_process_delta_time() 39 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 40 | thread.start(self, "_AI") 41 | 42 | func AI(): 43 | while true: 44 | for enemy in get_tree().get_nodes_in_group("enemies"): 45 | var nearest_player = get_near_player(enemy) 46 | 47 | player = nearest_player.player 48 | 49 | mutex.lock() 50 | if player == null: 51 | return 52 | if nearest_player.distance > glob.draw_distance + 10: 53 | return 54 | if enemy.civ_killer: 55 | enemy.player_spotted = true 56 | if Global.every_20: 57 | enemy.player_distance = nearest_player.distance 58 | enemy.stealthed = glob.implants.torso_implant.stealth and enemy.player_distance > 20 59 | enemy.height_difference = player.global_transform.origin.y > enemy.global_transform.origin.y and abs(player.global_transform.origin.y - enemy.global_transform.origin.y) > 21 60 | enemy.anim_counter += 1 61 | enemy.time += 1 62 | if enemy.muzzleflash: 63 | enemy.muzzleflash.hide() 64 | if enemy.player_distance > enemy.ai_distance: 65 | return 66 | if enemy.player_distance > 50 and Global.every_2: 67 | return 68 | elif enemy.player_distance > 50 and not Global.every_2: 69 | delta *= 2 70 | if Global.every_55: 71 | if randi() % 2 == 1: 72 | enemy.shoot_mode = true 73 | elif not enemy.civ_killer: 74 | enemy.shoot_mode = false 75 | if enemy.move_speed == 0: 76 | if enemy.player_spotted and not enemy.dead and not enemy.tranq: 77 | enemy.rotate_towards = lerp(enemy.rotate_towards, player.global_transform.origin, 6 * delta) 78 | enemy.look_at(enemy.rotate_towards, Vector3.UP) 79 | enemy.rotation.x = 0 80 | enemy.shoot_mode = true 81 | if not enemy.player_spotted and not enemy.dead and not enemy.tranq: 82 | enemy.wait_for_player(delta) 83 | if Global.every_5: 84 | enemy.heading = - Vector3(player.global_transform.origin.x, 0, player.global_transform.origin.z).direction_to(Vector3(enemy.global_transform.origin.x, 0, enemy.global_transform.origin.z)) 85 | enemy.line_of_sight = enemy.global_transform.origin.direction_to(enemy.forward_helper.global_transform.origin).dot(enemy.heading) 86 | enemy.heading_y = (player.global_transform.origin - enemy.global_transform.origin).normalized() 87 | enemy.line_of_sight_y = enemy.transform.basis.xform(Vector3.UP).dot(enemy.heading_y) 88 | if Global.every_20 and enemy.player_distance < 30: 89 | if enemy.velocity_ray.is_colliding(): 90 | var collider = enemy.velocity_ray.get_collider() 91 | var normal = enemy.velocity_ray.get_collision_normal() 92 | var point = enemy.velocity_ray.get_collision_point() 93 | if is_instance_valid(collider): 94 | if collider.has_method("use") and collider.has_method("destroy") and not collider.get_collision_layer_bit(6) and (enemy.alerted or enemy.player_spotted): 95 | collider.destroy(normal, point) 96 | elif enemy.rand_patroller and collider.has_method("destroy") and collider.has_method("use") and ( not enemy.alerted and not enemy.player_spotted) and not enemy.pos_flag: 97 | if enemy.pos_flag: 98 | enemy.path = enemy.navigation.get_simple_path(enemy.global_transform.origin, enemy.pos2) 99 | enemy.pos_flag = not enemy.pos_flag 100 | else : 101 | enemy.path = enemy.navigation.get_simple_path(enemy.global_transform.origin, enemy.pos1) 102 | enemy.pos_flag = not enemy.pos_flag 103 | elif collider.has_method("use") and not collider.has_method("destroy") and not collider.get_collision_layer_bit(6) and Vector2(enemy.velocity.x, enemy.velocity.z).length() > 0.2: 104 | collider.use() 105 | elif collider.has_method("piercing_damage") and enemy.player_spotted: 106 | collider.piercing_damage(200, normal, point, enemy.global_transform.origin) 107 | enemy.velocity.y -= enemy.gravity * enemy.delta 108 | if not enemy.dead and not enemy.tranq: 109 | if enemy.player_spotted: 110 | enemy.player_spotted() 111 | enemy.track_player(delta) 112 | if not enemy.sight_potential and enemy.player_distance > 20 and not Global.every_20 and not enemy.alerted and not enemy.player_spotted: 113 | return 114 | if enemy.path.size() > 0 and ((enemy.player_distance > enemy.engage_distance and ( not enemy.shoot_mode or enemy.melee)) or not enemy.in_sight) and enemy.player_spotted: 115 | enemy.find_path(delta) 116 | else : 117 | if enemy.in_sight: 118 | enemy.active(delta) 119 | else : 120 | enemy.reaction_timer = clamp(enemy.reaction_timer, 0, enemy.reaction_time + 1) - 5 * delta 121 | elif enemy.is_on_floor(): 122 | enemy.velocity.x *= 0.95 123 | enemy.velocity.z *= 0.95 124 | mutex.unlock() 125 | yield (get_tree(), "physics_frame") 126 | 127 | func _exit_tree(): 128 | thread.wait_to_finish() 129 | -------------------------------------------------------------------------------- /remaped/MissileKinematic.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | export var speed = 10 6 | export var homing = false 7 | export var piercing = false 8 | 9 | var target 10 | var target_pos 11 | var collisions = 0 12 | var target_pos_prev 13 | var time = 0 14 | var velocity = Vector3(0, 0, 0) 15 | 16 | var explosion = preload("res://Entities/Bullets/Explosion.tscn") 17 | var shrapnel = preload("res://Entities/Bullets/Explosive_Grenade_Impact.tscn") 18 | var decal = preload("res://Entities/Decals/BigHole.tscn") 19 | 20 | puppet func _set_transform(id, recivedTransform): 21 | global_transform = recivedTransform 22 | 23 | puppet func _delete(id): 24 | hide() 25 | global_translation = Vector3(-1000, -1000, -1000) 26 | 27 | set_process(false) 28 | set_physics_process(false) 29 | 30 | puppet func _create_object(id, recivedPath, recivedObject, recivedName, recivedTransform, recivedShrapnel = null): 31 | var newObject = load(recivedObject).instance() 32 | newObject.set_name(recivedName) 33 | get_node(recivedPath).add_child(newObject) 34 | newObject.global_transform = recivedTransform 35 | if recivedShrapnel == null: 36 | newObject.shrapnel_flag = recivedShrapnel 37 | 38 | func align_up(node_basis, normal)->Basis: 39 | var result = Basis() 40 | var scale = node_basis.get_scale() 41 | 42 | result.x = normal.cross(node_basis.z) + Vector3(1e-05, 0, 0) 43 | result.y = normal + Vector3(0, 1e-05, 0) 44 | result.z = node_basis.x.cross(normal) + Vector3(0, 0, 1e-05) 45 | 46 | result = result.orthonormalized() 47 | result.x *= scale.x 48 | result.y *= scale.y 49 | result.z *= scale.z 50 | 51 | return result 52 | 53 | func _ready(): 54 | set_collision_mask_bit(1, 1) 55 | update_rpcs() 56 | 57 | func update_rpcs(): 58 | NetworkBridge.register_rpcs(self, [ 59 | ["_set_transform", NetworkBridge.PERMISSION.SERVER], 60 | ["_delete", NetworkBridge.PERMISSION.SERVER], 61 | ["_create_object", NetworkBridge.PERMISSION.SERVER], 62 | ["decal", NetworkBridge.PERMISSION.SERVER] 63 | ]) 64 | 65 | func _physics_process(delta): 66 | if piercing: 67 | $MeshInstance.scale = lerp($MeshInstance.scale, Vector3.ONE, 0.8) 68 | 69 | if NetworkBridge.check_connection(): 70 | if NetworkBridge.n_is_network_master(self): 71 | 72 | NetworkBridge.n_rpc(self, "_set_transform", [global_transform]) 73 | 74 | time += 1 75 | if speed < 25: 76 | speed *= 1.2 77 | if target != null and homing: 78 | target_pos = target.global_transform.origin + Vector3(0, 0.75, 0) 79 | target_pos_prev = lerp(target_pos_prev, target_pos, 0.1) 80 | look_at(target_pos_prev, Vector3.UP) 81 | rotate_object_local(Vector3(0, 1, 0), 3.14 + sin(time * 0.01) * 1.5) 82 | var collision = move_and_collide(velocity * delta) 83 | if collision: 84 | if not piercing: 85 | var smokeparticle = $Smoke_Particle 86 | remove_child(smokeparticle) 87 | get_parent().add_child(smokeparticle) 88 | smokeparticle.emitting = false 89 | smokeparticle.get_node("OmniLight").queue_free() 90 | var new_explosion = explosion.instance() 91 | 92 | new_explosion.set_name(new_explosion.name + "#" + str(new_explosion.get_instance_id())) 93 | 94 | collision.collider.get_parent().add_child(new_explosion) 95 | new_explosion.global_transform.origin = global_transform.origin - Vector3(0, 1, 0) 96 | NetworkBridge.n_rpc(self, "_create_object", [collision.collider.get_parent().get_path(), "res://Entities/Bullets/Explosion.tscn", new_explosion.name, new_explosion.global_transform]) 97 | $CollisionShape.disabled = true 98 | var shrapnel_rotation = Vector3(1, 1, 0).rotated(Vector3.UP, deg2rad(rand_range(0, 180))) 99 | for i in range(4): 100 | shrapnel_rotation = shrapnel_rotation.rotated(Vector3.UP, deg2rad(90)) 101 | var new_shrapnel = shrapnel.instance() 102 | get_parent().add_child(new_shrapnel) 103 | new_shrapnel.shrapnel_flag = true 104 | new_shrapnel.set_name(new_shrapnel.name + "#" + str(new_shrapnel.get_instance_id())) 105 | new_shrapnel.global_transform.origin = global_transform.origin + Vector3.UP 106 | new_shrapnel.set_velocity(rand_range(10, 30), (new_shrapnel.global_transform.origin - (new_shrapnel.global_transform.origin - shrapnel_rotation)).normalized(), global_transform.origin) 107 | NetworkBridge.n_rpc(self, "_create_object", [get_parent().get_path(), "res://Entities/Bullets/Explosive_Grenade_Impact.tscn", new_shrapnel.name, new_shrapnel.global_transform, true]) 108 | NetworkBridge.n_rpc(self, "_delete") 109 | _delete(null) 110 | else : 111 | collisions += 1 112 | if collisions > 10: 113 | NetworkBridge.n_rpc(self, "_delete") 114 | _delete(null) 115 | if collision.collider.has_method("piercing_damage"): 116 | collision.collider.piercing_damage(150, (global_transform.origin - collision.position).normalized(), global_transform.origin, global_transform.origin) 117 | if collision.collider.has_method("damage"): 118 | collision.collider.damage(150, (global_transform.origin - collision.position).normalized(), global_transform.origin, global_transform.origin) 119 | else : 120 | decal(null, collision.collider, collision.position, collision.normal) 121 | NetworkBridge.n_rpc(self, "_delete") 122 | _delete(null) 123 | 124 | func set_velocity(new_velocity, direction): 125 | transform.basis = direction 126 | 127 | puppet func decal(id, collider:Spatial, c_point, c_normal)->void : 128 | if NetworkBridge.n_is_network_master(self): 129 | if not is_instance_valid(collider): 130 | return 131 | if collider.get_collision_layer_bit(0) == true: 132 | var decal_new = decal.instance() 133 | collider.add_child(decal_new) 134 | decal_new.global_transform.basis = align_up(decal_new.global_transform.basis, c_normal) 135 | decal_new.global_transform.origin = c_point + c_normal * 1e-08 136 | 137 | NetworkBridge.n_rpc(self, "_create_object", [collider.get_path(), "res://Entities/Decals/BigHole.tscn", decal_new.name, decal_new.global_transform]) 138 | 139 | func _on_Area_body_entered(body): 140 | if NetworkBridge.n_is_network_master(self): 141 | if body.get("alive_head") != null and target == null: 142 | if body.alive_head == true: 143 | target_pos_prev = body.global_transform.origin + Vector3(0, 0.75, 0) 144 | target_pos = body.global_transform.origin + Vector3(0, 0.75, 0) 145 | target = body 146 | -------------------------------------------------------------------------------- /remaped/Door.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | onready var NetworkBridge = Global.get_node("Multiplayer/NetworkBridge") 4 | 5 | var PARTICLE = preload("res://Entities/Particles/Destruction_Particle.tscn") 6 | 7 | export var door_health = 100 8 | export var rotation_speed = 2 9 | var open = false 10 | var stop = true 11 | var initrot = rotation 12 | var rotation_counter = 0 13 | var mesh_instance 14 | var collision_shape 15 | var collision = false 16 | var found_overlap 17 | var type = 1 18 | var audio_player 19 | 20 | var isDestroyed = false 21 | 22 | var destroy_check_timer 23 | 24 | func _ready(): 25 | rset_config("global_transform",MultiplayerAPI.RPC_MODE_PUPPET) 26 | rset_config("door_health", MultiplayerAPI.RPC_MODE_PUPPET) 27 | NetworkBridge.register_rset(self, "global_transform", NetworkBridge.PERMISSION.SERVER) 28 | NetworkBridge.register_rset(self, "door_health", NetworkBridge.PERMISSION.SERVER) 29 | 30 | NetworkBridge.register_rpcs(self, [ 31 | ["remove_on_ready", NetworkBridge.PERMISSION.SERVER], 32 | ["remove", NetworkBridge.PERMISSION.SERVER], 33 | ["_get_transform", NetworkBridge.PERMISSION.ALL], 34 | ["check_removed", NetworkBridge.PERMISSION.ALL], 35 | ["network_destroy", NetworkBridge.PERMISSION.ALL], 36 | ["network_damage", NetworkBridge.PERMISSION.ALL], 37 | ["network_use", NetworkBridge.PERMISSION.ALL] 38 | ]) 39 | 40 | set_process(false) 41 | set_collision_layer_bit(8, 1) 42 | for child in get_children(): 43 | if child is MeshInstance: 44 | mesh_instance = child 45 | if child is CollisionShape: 46 | collision_shape = child 47 | var t = mesh_instance.transform 48 | 49 | if mesh_instance.get_aabb().size.x > mesh_instance.get_aabb().size.z: 50 | global_transform.origin.x -= mesh_instance.get_aabb().position.x 51 | global_transform.origin.z -= mesh_instance.get_aabb().position.z + mesh_instance.get_aabb().size.z * 0.5 52 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x, 0, mesh_instance.get_aabb().position.z + mesh_instance.get_aabb().size.z * 0.5)) 53 | else : 54 | global_transform.origin.x -= mesh_instance.get_aabb().position.x + mesh_instance.get_aabb().size.x * 0.5 55 | global_transform.origin.z -= mesh_instance.get_aabb().position.z 56 | t = t.translated(Vector3(mesh_instance.get_aabb().position.x + mesh_instance.get_aabb().size.x * 0.5, 0, mesh_instance.get_aabb().position.z)) 57 | 58 | mesh_instance.transform = t 59 | collision_shape.transform = t 60 | 61 | audio_player = AudioStreamPlayer3D.new() 62 | get_parent().call_deferred("add_child", audio_player) 63 | yield (get_tree(), "idle_frame") 64 | audio_player.global_transform.origin = global_transform.origin 65 | audio_player.stream = load("res://Sfx/Environment/doorkick.wav") 66 | audio_player.unit_size = 10 67 | audio_player.unit_db = 4 68 | audio_player.max_db = 4 69 | audio_player.pitch_scale = 0.6 70 | 71 | destroy_check_timer = Timer.new() 72 | destroy_check_timer.wait_time = 2.0 73 | destroy_check_timer.one_shot = true 74 | destroy_check_timer.connect("timeout", self, "respawn") 75 | 76 | if not NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 77 | NetworkBridge.n_rpc(self, "_get_transform") 78 | NetworkBridge.n_rpc(self, "check_removed") 79 | 80 | master func _get_transform(id): 81 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 82 | 83 | func _physics_process(delta): 84 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 85 | if not open and not stop: 86 | rotation.y += rotation_speed * delta 87 | rotation_counter += rad2deg(rotation_speed * delta) 88 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 89 | if open and not stop: 90 | rotation.y -= rotation_speed * delta 91 | rotation_counter += rad2deg(rotation_speed * delta) 92 | NetworkBridge.n_rset_unreliable(self, "global_transform", global_transform) 93 | if rotation_counter > 90: 94 | rotation_counter = 0 95 | stop = true 96 | 97 | master func check_removed(id): 98 | if isDestroyed: 99 | NetworkBridge.n_rpc_id(self, id, "remove_on_ready") 100 | 101 | func destroy(collision_n, collision_p): 102 | network_destroy(null, collision_n, collision_p) 103 | 104 | master func network_destroy(id, collision_n, collision_p): 105 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 106 | damage(200, collision_n, collision_p, Vector3.ZERO) 107 | else: 108 | remove(null, collision_n, collision_p) 109 | NetworkBridge.n_rpc(self, "network_destroy", [collision_n, collision_p]) 110 | 111 | func damage(dmg, nrml, pos, shoot_pos): 112 | network_damage(null, dmg, nrml, pos, shoot_pos) 113 | 114 | master func network_damage(id, damage, collision_n, collision_p, shooter_pos): 115 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 116 | door_health -= damage 117 | if door_health <= 0: 118 | remove(null, collision_n, collision_p) 119 | NetworkBridge.n_rpc(self, "remove", [collision_n, collision_p, true]) 120 | NetworkBridge.n_rset(self, "door_health", door_health) 121 | else: 122 | door_health -= damage 123 | if door_health <= 0: 124 | remove(null, collision_n, collision_p) 125 | destroy_check_timer.start() 126 | NetworkBridge.n_rpc(self, "network_damage", [damage, collision_n, collision_p, shooter_pos]) 127 | 128 | func get_type(): 129 | return type; 130 | 131 | func use(): 132 | network_use(null) 133 | 134 | master func network_use(id): 135 | if NetworkBridge.check_connection() and NetworkBridge.n_is_network_master(self): 136 | stop = not stop 137 | open = not open 138 | else: 139 | NetworkBridge.n_rpc(self, "network_use") 140 | 141 | puppet func remove_on_ready(id): 142 | set_collision_layer_bit(0,false) 143 | set_collision_mask_bit(0,false) 144 | set_collision_layer_bit(8, false) 145 | hide() 146 | 147 | puppet func remove(id, collision_n, collision_p, from_host = false): 148 | if not visible and from_host: 149 | destroy_check_timer.stop() 150 | else: 151 | isDestroyed = true 152 | audio_player.global_transform.origin = collision_p 153 | audio_player.play() 154 | var new_particle = PARTICLE.instance() 155 | get_parent().add_child(new_particle) 156 | new_particle.global_transform.origin = collision_p 157 | new_particle.look_at(global_transform.origin + collision_n * 5 + Vector3(1e-06, 0, 0), Vector3.UP) 158 | new_particle.material_override = mesh_instance.mesh.surface_get_material(0) 159 | new_particle.emitting = true 160 | set_collision_layer_bit(0,false) 161 | set_collision_mask_bit(0,false) 162 | set_collision_layer_bit(8, false) 163 | hide() 164 | 165 | func respawn(): 166 | isDestroyed = false 167 | set_collision_layer_bit(0,true) 168 | set_collision_mask_bit(0,true) 169 | set_collision_layer_bit(8, true) 170 | show() 171 | --------------------------------------------------------------------------------