├── .gitignore ├── Helpers.gd ├── Multiplayer ├── Fonts │ └── Other F.ttf ├── Levels │ └── Misc │ │ ├── Main.tscn │ │ └── Main_Menu.tscn ├── Objects │ └── player.tscn ├── Other F.ttf ├── Scripts │ ├── Client.gd │ ├── Main_Menu.gd │ ├── Network.gd │ └── Server.gd ├── Textures │ ├── Nametag Test.kra │ ├── Nametag Test.png │ └── icon.png ├── default_env.tres ├── export_presets.cfg └── project.godot ├── README.md ├── Spatial.tscn ├── Testing ├── Scenario.tscn └── cambase.tscn ├── Themes └── Terminal.tres ├── assets ├── green-crosshair-png-4.png ├── radar │ ├── Player_GUI.gd │ ├── Player_HUD.gd │ ├── Player_Radar.gd │ └── Player_Weapon.gd └── ui │ ├── Blur.tres │ ├── Enemy.tscn │ ├── Player_GUI.tscn │ └── Radar.gd ├── autoload └── Lobby.gd ├── core ├── AI_TEST.tscn ├── Animation │ ├── BoneHandler.gd │ ├── CopyAttachment.gd │ ├── HelperSkeleton.gd │ ├── HelperSkeleton.tscn │ ├── PrimarySkeleton.gd │ └── test.tscn ├── AutoIK │ ├── AutoIK.gd │ ├── BoneHandler.gd │ ├── Changer.gd │ └── HandlerCopy.gd ├── Object Info │ └── Decoder.gd ├── Player_prefab │ ├── Player.gd │ └── Player.tscn ├── Systems │ ├── Inventory │ │ ├── Inventory.gd │ │ └── Objects │ │ │ ├── JOYAmmo.gd │ │ │ └── JOYObject.gd │ ├── Navigation │ │ ├── Navigation_Waypoint.gd │ │ ├── Navmesh_Path.gd │ │ ├── Sound_Smell_system.gd │ │ ├── WorldNavigation.gd │ │ ├── WorldNavigation.gd~Moved WorldNavigation to Systems │ │ └── WorldNavigation.gd~master │ ├── Physics │ │ └── GravityArea.gd │ ├── Sound │ │ └── Auto_play_sound.gd │ └── SpawnPoint.gd ├── actors │ ├── Character.gd │ └── Player.gd ├── component.gd ├── npc_ai │ ├── AI_Group.gd │ ├── AI_Individual.gd │ ├── JxAI.gd │ ├── NPC1.tscn │ └── components │ │ ├── AwakeArea.gd │ │ ├── Eyes.tscn │ │ ├── NPCMovement.gd │ │ └── vision_colliders.gd ├── weapons │ ├── explosion.tscn │ ├── large_explosion.tscn │ ├── projectile.gd │ ├── raycast_weapon.gd │ ├── squib.gd │ ├── squib.tscn │ └── weapon.gd └── workstations │ ├── Workstation.gd │ ├── Workstation.tscn │ └── worker.gd ├── icons ├── Gravicon.png ├── IA_icon.png ├── SH_SYSTEM.png ├── icon.png ├── player.png └── workstation.png ├── pl3d ├── 3RDPersCamera.gd ├── 3RDPersonCamera.gd ├── Camera.gd ├── FPSCamera.gd ├── Player3d.gd ├── Player3d.tscn ├── TopDownCamera.gd └── label.gd └── travis.yml /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.import 3 | *.import 4 | Framework/addons/WorldManagement/IA_icon.png.import 5 | Framework/addons/WorldManagement/Gravicon.png.import 6 | Framework/addons/WorldManagement/IA_icon.png.import 7 | Framework/addons/WorldManagement/icon.png.import 8 | -------------------------------------------------------------------------------- /Helpers.gd: -------------------------------------------------------------------------------- 1 | class_name RAD 2 | static func map(x, in_min, in_max, out_min, out_max): 3 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min 4 | #Usage: val = map(val, 0, 1023, 0, 255) 5 | 6 | 7 | 8 | static func randv(vector:Vector3): 9 | return Vector3( 10 | rand_range(-vector.x,vector.x), 11 | rand_range(-vector.y,vector.y), 12 | rand_range(-vector.z,vector.z) 13 | ) 14 | 15 | 16 | static func rotation_from_to(A,B): 17 | var output=Vector3() 18 | output.x=rad2deg(atan2((B.y-A.y),(B.z-A.z))) 19 | output.y=rad2deg(atan2((B.z-A.z),(B.x-A.x))) 20 | output.z=rad2deg(atan2((B.y-A.y),(B.x-A.x))) 21 | return output 22 | #Returns a Vector3 containing cilindircal relative coordinates. 23 | #Both Coordinates must be the same type (either local or global) 24 | 25 | 26 | static func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn): 27 | var n = p_target # Normal 28 | var t = n.cross(current_gn).normalized() 29 | 30 | var x = n.dot(p_facing) 31 | var y = t.dot(p_facing) 32 | 33 | var ang = atan2(y,x) 34 | 35 | if (abs(ang) < 0.001): # Too small 36 | return p_facing 37 | 38 | var s = sign(ang) 39 | ang = ang*s 40 | var turn = ang*p_adjust_rate*p_step 41 | var a 42 | if (ang < turn): 43 | a = ang 44 | else: 45 | a = turn 46 | ang = (ang - a)*s 47 | 48 | return (n*cos(ang) + t*sin(ang))*p_facing.length() 49 | 50 | 51 | static func _get_object_info(object:Node): 52 | var propetries = {} 53 | if object.has_method("get_global_transform"): 54 | if object is StaticBody: 55 | return 56 | else: 57 | propetries = { 58 | "position" : object.translation, 59 | "type" : object.type, 60 | "health" : object.health, 61 | "team" : object.team 62 | } 63 | return propetries.values() 64 | 65 | static func debug_print(what): 66 | print(what) 67 | -------------------------------------------------------------------------------- /Multiplayer/Fonts/Other F.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/Multiplayer/Fonts/Other F.ttf -------------------------------------------------------------------------------- /Multiplayer/Levels/Misc/Main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [sub_resource type="GDScript" id=1] 4 | script/source = "extends Node 5 | 6 | # Declare member variables here. Examples: 7 | # var a = 2 8 | # var b = \"text\" 9 | 10 | # Called when the node enters the scene tree for the first time. 11 | func _ready(): 12 | var loader = load(\"res://Levels/Misc/Main_Menu.tscn\").instance() 13 | get_node(\"/root/Main\").add_child(loader) 14 | pass # Replace with function body. 15 | 16 | # Called every frame. 'delta' is the elapsed time since the previous frame. 17 | #func _process(delta): 18 | # pass 19 | " 20 | 21 | [node name="Main" type="Node"] 22 | script = SubResource( 1 ) 23 | 24 | -------------------------------------------------------------------------------- /Multiplayer/Objects/player.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://icon.png" type="Texture" id=1] 4 | 5 | [node name="KinematicBody2D" type="KinematicBody2D"] 6 | 7 | [node name="Sprite" type="Sprite" parent="."] 8 | scale = Vector2( 4, 4 ) 9 | texture = ExtResource( 1 ) 10 | 11 | -------------------------------------------------------------------------------- /Multiplayer/Other F.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/Multiplayer/Other F.ttf -------------------------------------------------------------------------------- /Multiplayer/Scripts/Client.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | # Declare member variables here. Examples: 4 | # var a = 2 5 | # var b = "text" 6 | 7 | var SERVER_IP = "9.0.0.1" 8 | var SERVER_PORT = 3591 9 | 10 | # Called when the node enters the scene tree for the first time. 11 | func _ready(): 12 | var peer = NetworkedMultiplayerENet.new() 13 | peer.create_server(SERVER_IP, SERVER_PORT) 14 | get_tree().set_network_peer(peer) 15 | get_tree().set_meta("network_peer", peer) 16 | get_tree().is_network_server() 17 | pass # Replace with function body. 18 | 19 | # Called every frame. 'delta' is the elapsed time since the previous frame. 20 | #func _process(delta): 21 | # pass 22 | 23 | func _input(event): 24 | if Input.is_action_just_pressed("ui_accept"): 25 | get_tree().set_network_peer(null) 26 | var loader = load("res://Main_Menu.tscn").instance() 27 | get_node("/root/Main") 28 | self.queue_free() -------------------------------------------------------------------------------- /Multiplayer/Scripts/Main_Menu.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | # Declare member variables here. Examples: 4 | # var a = 2 5 | # var b = "text" 6 | 7 | # Called when the node enters the scene tree for the first time. 8 | func _ready(): 9 | # Called every time the node is added to the scene. 10 | Network.connect("connection_failed", self, "_on_connection_failed") 11 | Network.connect("connection_succeeded", self, "_on_connection_success") 12 | Network.connect("player_list_changed", self, "refresh_lobby") 13 | Network.connect("game_ended", self, "_on_game_ended") 14 | Network.connect("game_error", self, "_on_game_error") 15 | 16 | # Called every frame. 'delta' is the elapsed time since the previous frame. 17 | #func _process(delta): 18 | # pass 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ######################## MISC #################################### 27 | 28 | func refresh_lobby(): #This line of code is used to refresh the Player list (Currently Broken W.I.P.) 29 | var players = Network.get_player_list() 30 | var updater = [] 31 | players.sort() 32 | # get_node("players/list").clear() 33 | # get_node("players/list").add_item(Network.get_player_info().name + " (You)") 34 | # for p in players: 35 | # get_node("players/list").add_item(p.name) 36 | updater.clear() 37 | updater.insert(0,Network.get_player_info().name + " (You)") 38 | for p in players: 39 | updater.append(p.name) 40 | #updater.append() 41 | 42 | var playercount = 0 43 | 44 | for m in get_node("PlayerList").get_children(): 45 | if updater[playercount] != null: 46 | #get_node("PlayerList" + "/" + m.name + "/" + "Name_Tag").set_text = updater[playercount] 47 | print(updater[playercount]) 48 | playercount += 1 49 | else: 50 | break 51 | 52 | #print(m.name) 53 | #print(updater[playercount]) 54 | 55 | #get_node("players/start").disabled = not get_tree().is_network_server() 56 | pass -------------------------------------------------------------------------------- /Multiplayer/Scripts/Network.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | 4 | # [0] Setup for const, signals, and variables before assigning signal connections 5 | # to "_ready()". registered_name is to update "name" at the my_info variable in [2] 6 | # for player list/ nameplate lobby update. 7 | 8 | var registered_name = "" 9 | 10 | const SERVER_IP = '127.0.0.1' 11 | const SERVER_PORT = 35910 12 | const MAX_PLAYERS = 16 13 | 14 | signal player_list_changed() 15 | 16 | func _ready(): 17 | get_tree().connect("network_peer_connected", self, "_player_connected") 18 | get_tree().connect("network_peer_disconnected", self, "_player_disconnected") 19 | get_tree().connect("connected_to_server", self, "_connected_ok") 20 | get_tree().connect("connection_failed", self, "_connected_fail") 21 | get_tree().connect("server_disconnected", self, "_server_disconnected") 22 | 23 | 24 | 25 | 26 | # [1] Functions to Host or Join a server from the Player Lobby. 27 | # Joining server will send "_connected_ok()" signal to update Player list/ Nametag plates 28 | 29 | func _host_game(): 30 | var peer = NetworkedMultiplayerENet.new() 31 | peer.create_server(SERVER_PORT, MAX_PLAYERS) 32 | get_tree().set_network_peer(peer) 33 | #print(get_tree().is_network_server()) 34 | 35 | func _join_game(): # If connected, Sends signal to "connected_to_server"/"_connected_ok" 36 | var peer = NetworkedMultiplayerENet.new() 37 | peer.create_client(SERVER_IP, SERVER_PORT) 38 | get_tree().set_network_peer(peer) 39 | #print(get_tree().is_network_server()) 40 | 41 | 42 | 43 | 44 | #[2] Signals to detect from Godot High-Level Multiplayer API 45 | # that sends executable commands to other online players such as exiting the game 46 | # server shutdowns, etc. 47 | 48 | # Player info, associate ID to data 49 | var player_info = {} 50 | # Info we send to other players 51 | var my_info = { name = registered_name, favorite_color = Color8(255, 0, 255) } 52 | 53 | func _player_connected(id): 54 | pass # Will go unused; not useful here. 55 | 56 | func _player_disconnected(id): 57 | player_info.erase(id) # Erase player from info. 58 | 59 | func _connected_ok(): 60 | # Only called on clients, not server. Send my ID and info to all the other peers. 61 | print("Incoming Player...") 62 | rpc("register_player", get_tree().get_network_unique_id(), my_info) 63 | 64 | func _server_disconnected(): 65 | pass # Server kicked us; show error and abort. 66 | 67 | func _connected_fail(): 68 | pass # Could not even connect to server; abort. 69 | 70 | 71 | 72 | 73 | # [3] Recieves online executable either from main player or joining player to update 74 | # the playerlist after recieveing the "_connected_ok()" command from [2]. 75 | 76 | # NOTE: This is currently broken since for some strange reason, while the Server prints 77 | # out the list of joining players, Clients(Joined-Players) will end up printing the same 78 | # list twice, or possibly more. Regardless though, joining the server does still work. Just 79 | # updating the lobby list is currently broken. 80 | 81 | remote func register_player(id, info): 82 | # Store the info 83 | player_info[id] = info 84 | # If I'm the server, let the new guy know about existing players. 85 | if get_tree().is_network_server(): 86 | # Send my info to new player 87 | rpc_id(id, "register_player", 1, my_info) 88 | # Send the info of existing players 89 | for peer_id in player_info: #For adding Friends to the incoming list 90 | rpc_id(id, "register_player", peer_id, player_info[peer_id]) 91 | 92 | # Call function to update lobby UI here 93 | #for i in get_node("/root/Main/Main_Menu/PlayerList").get_children(): 94 | #get_node("/root/Main/Main_Menu/PlayerList/Label/Name_Tag").set_text(info.name) 95 | #get_node("/root/Main/Main_Menu/PlayerList/Label/Plate").self_modulate = info.favorite_color 96 | emit_signal("player_list_changed") 97 | 98 | 99 | 100 | 101 | # [4] Command to tell both the server and rest of the remaining players that a new player is incoming. 102 | # could potentially be upgraded/updated to allow players to join game in-progress, though this is 103 | # not recommended due to possible network errors. 104 | 105 | remote func pre_configure_game(): 106 | get_tree().set_pause(true) #Pauses game to sync the world and player setup [OPTIONAL] 107 | var selfPeerID = get_tree().get_network_unique_id() 108 | 109 | # Load world 110 | var world = load("res://Level.tscn").instance() 111 | get_node("/root").add_child(world) 112 | 113 | # Load my player 114 | var my_player = load("res://Objects/player.tscn").instance() 115 | my_player.set_name(str(selfPeerID)) 116 | my_player.set_network_master(selfPeerID) # Will be explained later 117 | get_node("/root/world/players").add_child(my_player) 118 | 119 | # Load other players 120 | for p in player_info: 121 | var player = load("res://Objects/player.tscn").instance() 122 | player.set_name(str(p)) 123 | player.set_network_master(p) # Will be explained later 124 | get_node("/root/world/players").add_child(player) 125 | 126 | # Tell server (remember, server is always ID=1) that this peer is done pre-configuring. 127 | rpc_id(1, "done_preconfiguring", selfPeerID) 128 | 129 | 130 | 131 | var players_done = [] 132 | remote func done_preconfiguring(who): 133 | # Here are some checks you can do, for example 134 | assert(get_tree().is_network_server()) 135 | assert(who in player_info) # Exists 136 | assert(not who in players_done) # Was not added yet 137 | 138 | players_done.append(who) 139 | 140 | if players_done.size() == player_info.size(): 141 | rpc("post_configure_game") 142 | 143 | remote func post_configure_game(): 144 | get_tree().set_pause(false) 145 | # Game starts now! 146 | 147 | 148 | 149 | 150 | 151 | ########## MISC ###################### 152 | # [5] Additonal functions for part of updating Player Lobby, finding nametags. etc... 153 | 154 | func get_player_list(): #Part of refreshing Lobby List 155 | return player_info.values() 156 | 157 | func get_player_info(): #Part of refreshing Lobby List 158 | return my_info 159 | 160 | func name_update(n): 161 | registered_name = n -------------------------------------------------------------------------------- /Multiplayer/Scripts/Server.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | # Declare member variables here. Examples: 4 | # var a = 2 5 | # var b = "text" 6 | 7 | var MAX_PLAYERS = 4 8 | var SERVER_PORT = 3591 9 | 10 | # Called when the node enters the scene tree for the first time. 11 | func _ready(): 12 | var peer = NetworkedMultiplayerENet.new() 13 | peer.create_server(SERVER_PORT, MAX_PLAYERS) 14 | get_tree().set_network_peer(peer) 15 | get_tree().set_meta("network_peer", peer) 16 | get_tree().is_network_server() 17 | pass # Replace with function body. 18 | 19 | # Called every frame. 'delta' is the elapsed time since the previous frame. 20 | #func _process(delta): 21 | # pass 22 | 23 | func _input(event): 24 | if Input.is_action_just_pressed("ui_accept"): 25 | get_tree().set_network_peer(null) 26 | var loader = load("res://Main_Menu.tscn").instance() 27 | get_node("/root/Main") 28 | self.queue_free() -------------------------------------------------------------------------------- /Multiplayer/Textures/Nametag Test.kra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/Multiplayer/Textures/Nametag Test.kra -------------------------------------------------------------------------------- /Multiplayer/Textures/Nametag Test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/Multiplayer/Textures/Nametag Test.png -------------------------------------------------------------------------------- /Multiplayer/Textures/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/Multiplayer/Textures/icon.png -------------------------------------------------------------------------------- /Multiplayer/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | 5 | [resource] 6 | background_mode = 2 7 | background_sky = SubResource( 1 ) 8 | 9 | -------------------------------------------------------------------------------- /Multiplayer/export_presets.cfg: -------------------------------------------------------------------------------- 1 | [preset.0] 2 | 3 | name="Windows Desktop" 4 | platform="Windows Desktop" 5 | runnable=true 6 | custom_features="" 7 | export_filter="all_resources" 8 | include_filter="" 9 | exclude_filter="" 10 | export_path="C:/Users/The Corruptinator/Documents/Godot2019/Export_Tests/High-Level Multiplayer Test.exe" 11 | patch_list=PoolStringArray( ) 12 | script_export_mode=1 13 | script_encryption_key="" 14 | 15 | [preset.0.options] 16 | 17 | texture_format/bptc=false 18 | texture_format/s3tc=true 19 | texture_format/etc=false 20 | texture_format/etc2=false 21 | texture_format/no_bptc_fallbacks=true 22 | binary_format/64_bits=true 23 | custom_template/release="" 24 | custom_template/debug="" 25 | application/icon="" 26 | application/file_version="" 27 | application/product_version="" 28 | application/company_name="" 29 | application/product_name="" 30 | application/file_description="" 31 | application/copyright="" 32 | application/trademarks="" 33 | -------------------------------------------------------------------------------- /Multiplayer/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | _global_script_classes=[ ] 12 | _global_script_class_icons={ 13 | 14 | } 15 | 16 | [application] 17 | 18 | config/name="Multiplayer" 19 | run/main_scene="res://Levels/Misc/Main.tscn" 20 | config/icon="res://Textures/icon.png" 21 | 22 | [autoload] 23 | 24 | Network="*res://Scripts/Network.gd" 25 | 26 | [display] 27 | 28 | window/size/width=3840 29 | window/size/height=2160 30 | window/size/test_width=1920 31 | window/size/test_height=1080 32 | window/dpi/allow_hidpi=true 33 | window/stretch/mode="2d" 34 | 35 | [memory] 36 | 37 | limits/message_queue/max_size_kb=2048 38 | 39 | [rendering] 40 | 41 | quality/driver/driver_name="GLES2" 42 | vram_compression/import_etc=true 43 | vram_compression/import_etc2=false 44 | environment/default_environment="res://default_env.tres" 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Joyeuse 2 | FPS Framework for Godot. Provides nodes for AI, Navigation and interactions with areas and *Workstations*. 3 | NOTE: This framework is work in progress, most things won't work out of the box. 4 | # Editors 5 | ## Character Editor 6 | This works as a cohesive dedicated program to create characters ready to be placed into a world so they can make it vivid and functional. 7 | This is archived through: 8 | 9 | ### AI 10 | This is acomplished using a node based Behavior Tree editor, then taking information of connections and "compiling" them into a script which is attached to a model. 11 | 12 | ### Model 13 | The users are given certain parameters to make sure the model they selected is on scale with other characters and its colliders are correct. It also gives the user the option to create ragdolls for them, a better, easier to understand gizmo is to be implemented. 14 | 15 | ### Parameters 16 | Even if the system already uses a Behavior Tree to explain how certain AI works, there are still some things that must be adressed, like health, strenght, speed, jump height, etc. This Tab serves to contain them and allow the user to modify them, with sections and categories easy to remember. 17 | 18 | ## Level Editor 19 | This level editor is archieved through a series of different methods, the main editor will allow the users to prototype their levels using CSG shapes and use Grid Maps if they desire to, providing a layered approach. 20 | 21 | 22 | # Prefabs, nodes and addons 23 | 24 | ## Workstations 25 | Workstations (Or objectives) serve as a reference point for AI, so it looks for it, be it whatever you need it to be, from resources, food, water, terminals, reactors, etc. Anything that can serve for a Character to look for will be archievable with workstations. 26 | 27 | ## KinematicMovable 28 | Inherits from KinematicBody, allows easier implementation of characters through simplified functions that allow gravity, acceleration, deacceleration and other parameters to be changed from code. 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Spatial.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://Basics/General_systems/Sound_Smell_system.gd" type="Script" id=1] 4 | 5 | 6 | [node name="Spatial" type="Spatial"] 7 | script = ExtResource( 1 ) 8 | 9 | -------------------------------------------------------------------------------- /Testing/Scenario.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=29 format=2] 2 | 3 | [ext_resource path="res://addons/WorldManagement/WorldNavigation.gd" type="Script" id=1] 4 | [ext_resource path="res://Basics/Characters/AI.gd" type="Script" id=2] 5 | [ext_resource path="res://Basics/General_systems/Sound_Smell_system.gd" type="Script" id=3] 6 | [ext_resource path="res://Basics/Characters/Eyes.gd" type="Script" id=4] 7 | [ext_resource path="res://Basics/Characters/Player.gd" type="Script" id=5] 8 | [ext_resource path="res://Basics/Characters/Character.gd" type="Script" id=6] 9 | [ext_resource path="res://Basics/AI_TEST.tscn" type="PackedScene" id=7] 10 | [ext_resource path="res://addons/WorldManagement/MeshTracer.tscn" type="PackedScene" id=8] 11 | [ext_resource path="res://Testing/cambase.tscn" type="PackedScene" id=9] 12 | 13 | [sub_resource type="SphereMesh" id=1] 14 | 15 | [sub_resource type="SpatialMaterial" id=2] 16 | albedo_color = Color( 1, 0, 0, 1 ) 17 | 18 | [sub_resource type="CubeMesh" id=3] 19 | 20 | [sub_resource type="SpatialMaterial" id=4] 21 | albedo_color = Color( 0.627451, 0.521569, 1, 1 ) 22 | 23 | [sub_resource type="ConvexPolygonShape" id=5] 24 | points = PoolVector3Array( -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1 ) 25 | 26 | [sub_resource type="Curve3D" id=6] 27 | _data = { 28 | "points": PoolVector3Array( 0, 0, 0, 0, 0, 0, -14.0254, 0.138672, 13.1599, 0, 0, 0, 0, 0, 0, -17.9116, 1.00537, 1.39918, 0, 0, 0, 0, 0, 0, -14.0126, 1.56201, -10.4623, 0, 0, 0, 0, 0, 0, -1.99743, 0.991211, -14.0669, 0, 0, 0, 0, 0, 0, 14.4782, 1.3976, -12.9638, 0, 0, 0, 0, 0, 0, 16.7536, 0.964815, -0.0920887, 0, 0, 0, 0, 0, 0, 13.3219, 0.255371, 10.8646, 0, 0, 0, 0, 0, 0, 1.90749, 0.486816, 17.4729, 0, 0, 0, 0, 0, 0, 1.39053, 0.486816, 23.4568, 0, 0, 0, 0, 0, 0, -1.8285, 0.486816, 23.725, 0, 0, 0, 0, 0, 0, -2.81405, 0.486816, 15.6576, 0, 0, 0, 0, 0, 0, -10.7624, 0.486816, 14.7745, 0, 0, 0, 0, 0, 0, -11.1638, 0.486816, 19.7786, 0, 0, 0, 0, 0, 0, -14.6718, 0.486816, 19.669, 0, 0, 0, 0, 0, 0, -14.4345, 0.486816, 13.8758 ), 29 | "tilts": PoolRealArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) 30 | } 31 | 32 | [sub_resource type="NavigationMesh" id=7] 33 | vertices = PoolVector3Array( 1, 0, 1, -1, 0, 1, 1, 0, -1, -1, 0, -1 ) 34 | polygons = [ PoolIntArray( 0, 1, 2 ), PoolIntArray( 1, 3, 2 ) ] 35 | 36 | [sub_resource type="CubeMesh" id=8] 37 | 38 | [sub_resource type="SpatialMaterial" id=9] 39 | 40 | [sub_resource type="BoxShape" id=10] 41 | 42 | [sub_resource type="ProceduralSky" id=11] 43 | sky_top_color = Color( 0.729412, 0.713726, 0.709804, 1 ) 44 | sky_horizon_color = Color( 0.917647, 0.878431, 0.666667, 1 ) 45 | sun_latitude = 7.2 46 | 47 | [sub_resource type="Environment" id=12] 48 | background_mode = 2 49 | background_sky = SubResource( 11 ) 50 | 51 | [sub_resource type="CapsuleShape" id=13] 52 | radius = 0.679838 53 | height = 1.87215 54 | 55 | [sub_resource type="CapsuleMesh" id=14] 56 | 57 | [sub_resource type="SpatialMaterial" id=15] 58 | albedo_color = Color( 0, 0.180392, 1, 1 ) 59 | 60 | [sub_resource type="SphereMesh" id=16] 61 | radius = 0.25 62 | height = 0.5 63 | 64 | [sub_resource type="SpatialMaterial" id=17] 65 | flags_unshaded = true 66 | albedo_color = Color( 0.666667, 0.780392, 0, 1 ) 67 | 68 | [sub_resource type="BoxShape" id=18] 69 | extents = Vector3( 1, 3.45485, 2.43955 ) 70 | 71 | [sub_resource type="CubeMesh" id=19] 72 | 73 | [node name="world" type="Navigation"] 74 | script = ExtResource( 1 ) 75 | 76 | [node name="MeshInstance" type="MeshInstance" parent="."] 77 | transform = Transform( 0.292406, 0, 0, 0, 0.292406, 0, 0, 0, 0.292406, 0, 1.03778, -10.95 ) 78 | mesh = SubResource( 1 ) 79 | material/0 = SubResource( 2 ) 80 | 81 | [node name="MeshInstance2" type="MeshInstance" parent="."] 82 | transform = Transform( 0.292406, 0, 0, 0, 0.292406, 0, 0, 0, 0.292406, 0, 1.03778, 11.8002 ) 83 | mesh = SubResource( 1 ) 84 | material/0 = SubResource( 2 ) 85 | 86 | [node name="MeshInstance3" type="MeshInstance" parent="."] 87 | transform = Transform( 0.292406, 0, 0, 0, 0.292406, 0, 0, 0, 0.292406, -18.4993, 1.03778, 11.8002 ) 88 | mesh = SubResource( 1 ) 89 | material/0 = SubResource( 2 ) 90 | 91 | [node name="MeshInstance4" type="MeshInstance" parent="."] 92 | transform = Transform( 0.292406, 0, 0, 0, 0.292406, 0, 0, 0, 0.292406, 16.9114, 1.03778, 0.172875 ) 93 | mesh = SubResource( 1 ) 94 | material/0 = SubResource( 2 ) 95 | 96 | [node name="MeshInstance5" type="MeshInstance" parent="."] 97 | transform = Transform( 20.9951, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, 0, 0, 0 ) 98 | mesh = SubResource( 3 ) 99 | material/0 = SubResource( 4 ) 100 | 101 | [node name="StaticBody" type="StaticBody" parent="MeshInstance5"] 102 | 103 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance5/StaticBody"] 104 | shape = SubResource( 5 ) 105 | 106 | [node name="MeshInstance6" type="MeshInstance" parent="."] 107 | transform = Transform( -4.21349, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, 0, -0.019855, 32.9108 ) 108 | mesh = SubResource( 3 ) 109 | material/0 = SubResource( 4 ) 110 | 111 | [node name="StaticBody" type="StaticBody" parent="MeshInstance6"] 112 | 113 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance6/StaticBody"] 114 | shape = SubResource( 5 ) 115 | 116 | [node name="MeshInstance7" type="MeshInstance" parent="."] 117 | transform = Transform( -4.21349, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, -13.2617, -0.019855, 32.9108 ) 118 | mesh = SubResource( 3 ) 119 | material/0 = SubResource( 4 ) 120 | 121 | [node name="StaticBody" type="StaticBody" parent="MeshInstance7"] 122 | 123 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance7/StaticBody"] 124 | shape = SubResource( 5 ) 125 | 126 | [node name="MeshInstance8" type="MeshInstance" parent="."] 127 | transform = Transform( -4.21349, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, -7.03461, -0.019855, 72.1262 ) 128 | mesh = SubResource( 3 ) 129 | material/0 = SubResource( 4 ) 130 | 131 | [node name="StaticBody" type="StaticBody" parent="MeshInstance8"] 132 | 133 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance8/StaticBody"] 134 | shape = SubResource( 5 ) 135 | 136 | [node name="Path" type="Path" parent="."] 137 | curve = SubResource( 6 ) 138 | 139 | [node name="cambase" parent="." instance=ExtResource( 9 )] 140 | 141 | [node name="draw" type="ImmediateGeometry" parent="."] 142 | 143 | [node name="NavigationMeshInstance" type="NavigationMeshInstance" parent="."] 144 | transform = Transform( -4.21349, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, -7.03461, 0.221089, 72.1262 ) 145 | navmesh = SubResource( 7 ) 146 | 147 | [node name="NavigationMeshInstance2" type="NavigationMeshInstance" parent="."] 148 | transform = Transform( 20.9951, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, 0, 0.240944, 0 ) 149 | navmesh = SubResource( 7 ) 150 | 151 | [node name="NavigationMeshInstance3" type="NavigationMeshInstance" parent="."] 152 | transform = Transform( -4.21349, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, 0, 0.221089, 32.9108 ) 153 | navmesh = SubResource( 7 ) 154 | 155 | [node name="NavigationMeshInstance4" type="NavigationMeshInstance" parent="."] 156 | transform = Transform( -4.21349, 0, 0, 0, 0.0906191, 0, 0, 0, 17.7935, -13.2617, 0.221089, 32.9108 ) 157 | navmesh = SubResource( 7 ) 158 | 159 | [node name="MeshInstance9" type="MeshInstance" parent="."] 160 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, 20.6291, 4.23713, 0 ) 161 | mesh = SubResource( 8 ) 162 | material/0 = SubResource( 9 ) 163 | 164 | [node name="StaticBody" type="StaticBody" parent="MeshInstance9"] 165 | 166 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance9/StaticBody"] 167 | shape = SubResource( 10 ) 168 | 169 | [node name="MeshInstance14" type="MeshInstance" parent="."] 170 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, 6.6045, 4.23713, 35.1215 ) 171 | mesh = SubResource( 8 ) 172 | material/0 = SubResource( 9 ) 173 | 174 | [node name="StaticBody" type="StaticBody" parent="MeshInstance14"] 175 | 176 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance14/StaticBody"] 177 | shape = SubResource( 10 ) 178 | 179 | [node name="MeshInstance21" type="MeshInstance" parent="."] 180 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, 5.18802, 4.23713, 35.1215 ) 181 | mesh = SubResource( 8 ) 182 | material/0 = SubResource( 9 ) 183 | 184 | [node name="StaticBody" type="StaticBody" parent="MeshInstance21"] 185 | 186 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance21/StaticBody"] 187 | shape = SubResource( 10 ) 188 | 189 | [node name="MeshInstance16" type="MeshInstance" parent="."] 190 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, -4.80835, 4.23713, 35.1215 ) 191 | mesh = SubResource( 8 ) 192 | material/0 = SubResource( 9 ) 193 | 194 | [node name="StaticBody" type="StaticBody" parent="MeshInstance16"] 195 | 196 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance16/StaticBody"] 197 | shape = SubResource( 10 ) 198 | 199 | [node name="MeshInstance17" type="MeshInstance" parent="."] 200 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, -6.30744, 4.23713, 35.1215 ) 201 | mesh = SubResource( 8 ) 202 | material/0 = SubResource( 9 ) 203 | 204 | [node name="StaticBody" type="StaticBody" parent="MeshInstance17"] 205 | 206 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance17/StaticBody"] 207 | shape = SubResource( 10 ) 208 | 209 | [node name="MeshInstance18" type="MeshInstance" parent="."] 210 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, -7.90516, 4.23713, 35.1215 ) 211 | mesh = SubResource( 8 ) 212 | material/0 = SubResource( 9 ) 213 | 214 | [node name="StaticBody" type="StaticBody" parent="MeshInstance18"] 215 | 216 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance18/StaticBody"] 217 | shape = SubResource( 10 ) 218 | 219 | [node name="MeshInstance19" type="MeshInstance" parent="."] 220 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, -16.758, 4.23713, 35.1215 ) 221 | mesh = SubResource( 8 ) 222 | material/0 = SubResource( 9 ) 223 | 224 | [node name="StaticBody" type="StaticBody" parent="MeshInstance19"] 225 | 226 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance19/StaticBody"] 227 | shape = SubResource( 10 ) 228 | 229 | [node name="MeshInstance10" type="MeshInstance" parent="."] 230 | transform = Transform( 1, 0, 0, 0, 5.13801, 0, 0, 0, 17.6156, -20.6217, 4.23713, 0 ) 231 | mesh = SubResource( 8 ) 232 | material/0 = SubResource( 9 ) 233 | 234 | [node name="StaticBody" type="StaticBody" parent="MeshInstance10"] 235 | 236 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance10/StaticBody"] 237 | shape = SubResource( 10 ) 238 | 239 | [node name="MeshInstance11" type="MeshInstance" parent="."] 240 | transform = Transform( 0.488264, 2.19318e-07, 8.32981, -8.74228e-08, 5.13801, 0, 0.872696, 3.91997e-07, -4.66044, 13.3326, 4.23713, 14.4565 ) 241 | mesh = SubResource( 8 ) 242 | material/0 = SubResource( 9 ) 243 | 244 | [node name="StaticBody" type="StaticBody" parent="MeshInstance11"] 245 | 246 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance11/StaticBody"] 247 | transform = Transform( 1, 0, 0, 0, 1, 0, -2.22045e-16, 0, 1, 0, 0, 0 ) 248 | shape = SubResource( 10 ) 249 | 250 | [node name="MeshInstance15" type="MeshInstance" parent="."] 251 | transform = Transform( 1.75489e-08, 0, 7.07219, 0, 5.13801, 0, 1, 0, -7.70004e-07, 0.276352, 4.23713, 45.9515 ) 252 | mesh = SubResource( 8 ) 253 | material/0 = SubResource( 9 ) 254 | 255 | [node name="StaticBody" type="StaticBody" parent="MeshInstance15"] 256 | 257 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance15/StaticBody"] 258 | shape = SubResource( 10 ) 259 | 260 | [node name="MeshInstance20" type="MeshInstance" parent="."] 261 | transform = Transform( 1.75489e-08, 0, 7.07219, 0, 5.13801, 0, 1, 0, -7.70004e-07, -11.8175, 4.23713, 45.9515 ) 262 | mesh = SubResource( 8 ) 263 | material/0 = SubResource( 9 ) 264 | 265 | [node name="StaticBody" type="StaticBody" parent="MeshInstance20"] 266 | 267 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance20/StaticBody"] 268 | shape = SubResource( 10 ) 269 | 270 | [node name="MeshInstance12" type="MeshInstance" parent="."] 271 | transform = Transform( 6.94211e-09, 0, 2.79766, 0, 5.13801, 0, 1, 0, -7.70004e-07, -19.2296, 4.23713, 17.853 ) 272 | mesh = SubResource( 8 ) 273 | material/0 = SubResource( 9 ) 274 | 275 | [node name="StaticBody" type="StaticBody" parent="MeshInstance12"] 276 | 277 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance12/StaticBody"] 278 | shape = SubResource( 10 ) 279 | 280 | [node name="MeshInstance13" type="MeshInstance" parent="."] 281 | transform = Transform( 4.894e-08, 0, 19.7228, 0, 5.13801, 0, 1, 0, -7.70004e-07, 0.2981, 4.23713, -16.3709 ) 282 | mesh = SubResource( 8 ) 283 | material/0 = SubResource( 9 ) 284 | 285 | [node name="StaticBody" type="StaticBody" parent="MeshInstance13"] 286 | 287 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance13/StaticBody"] 288 | shape = SubResource( 10 ) 289 | 290 | [node name="Spatial" parent="." instance=ExtResource( 8 )] 291 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 19.1914, 0.799701, 4.70566 ) 292 | 293 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."] 294 | environment = SubResource( 12 ) 295 | 296 | [node name="Sound_Smell_Manager" type="Spatial" parent="."] 297 | script = ExtResource( 3 ) 298 | 299 | [node name="KinematicBody" parent="Sound_Smell_Manager" instance=ExtResource( 7 )] 300 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 11.1497, 1.33161, 11.9211 ) 301 | 302 | [node name="KinematicBody2" type="KinematicBody" parent="Sound_Smell_Manager"] 303 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 11.1497, 1.33161, -10.3227 ) 304 | collision_mask = 3 305 | script = ExtResource( 2 ) 306 | 307 | [node name="CollisionShape" type="CollisionShape" parent="Sound_Smell_Manager/KinematicBody2"] 308 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0.945411, 0 ) 309 | shape = SubResource( 13 ) 310 | 311 | [node name="MeshInstance" type="MeshInstance" parent="Sound_Smell_Manager/KinematicBody2"] 312 | transform = Transform( 0.674556, 0, 0, 0, -4.59801e-08, 1.0519, 0, -0.674556, -2.94858e-08, 0, 0.996896, 0 ) 313 | mesh = SubResource( 14 ) 314 | material/0 = SubResource( 15 ) 315 | 316 | [node name="Eyes" type="Spatial" parent="Sound_Smell_Manager/KinematicBody2"] 317 | transform = Transform( -1.2358e-06, 0, 1, 0, 1, 0, -1, 0, -1.2358e-06, -1.05526, 2.01, 0 ) 318 | script = ExtResource( 4 ) 319 | 320 | [node name="RayCast" type="RayCast" parent="Sound_Smell_Manager/KinematicBody2/Eyes"] 321 | enabled = true 322 | cast_to = Vector3( 0, 0, -5 ) 323 | collision_mask = 2 324 | 325 | [node name="RayCast2" type="RayCast" parent="Sound_Smell_Manager/KinematicBody2/Eyes"] 326 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0529401, 0, -1.19209e-07 ) 327 | enabled = true 328 | cast_to = Vector3( -2, 0, -4.5 ) 329 | 330 | [node name="RayCast3" type="RayCast" parent="Sound_Smell_Manager/KinematicBody2/Eyes"] 331 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0664887, 0, 1.19209e-07 ) 332 | enabled = true 333 | cast_to = Vector3( 2, 0, -4.5 ) 334 | 335 | [node name="MeshInstance2" type="MeshInstance" parent="Sound_Smell_Manager/KinematicBody2/Eyes/RayCast3"] 336 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.00155115, 0.0153136, -5.05121 ) 337 | mesh = SubResource( 16 ) 338 | material/0 = SubResource( 17 ) 339 | 340 | [node name="Mouth" type="AudioStreamPlayer3D" parent="Sound_Smell_Manager/KinematicBody2"] 341 | 342 | [node name="Player" type="KinematicBody" parent="Sound_Smell_Manager"] 343 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.38519, 0 ) 344 | collision_layer = 3 345 | collision_mask = 3 346 | script = ExtResource( 5 ) 347 | 348 | [node name="CollisionShape" type="CollisionShape" parent="Sound_Smell_Manager/Player"] 349 | shape = SubResource( 18 ) 350 | 351 | [node name="MeshInstance" type="MeshInstance" parent="Sound_Smell_Manager/Player"] 352 | mesh = SubResource( 19 ) 353 | material/0 = null 354 | 355 | [node name="Character" type="KinematicBody" parent="."] 356 | script = ExtResource( 6 ) 357 | [connection signal="sight" from="Sound_Smell_Manager/KinematicBody2/Eyes" to="Sound_Smell_Manager/KinematicBody2" method="_on_Eyes_sight"] 358 | -------------------------------------------------------------------------------- /Testing/cambase.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene format=2] 2 | 3 | [node name="cambase" type="Spatial"] 4 | 5 | [node name="Camera" type="Camera" parent="."] 6 | transform = Transform( -0.997337, 3.71537e-09, 0.0729351, 0.0363292, 0.867118, 0.496776, -0.0632434, 0.498103, -0.864809, 0, 9.74089, -30.7822 ) 7 | -------------------------------------------------------------------------------- /assets/green-crosshair-png-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/assets/green-crosshair-png-4.png -------------------------------------------------------------------------------- /assets/radar/Player_GUI.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | 4 | export(float) var rotary_min_angle = -180 setget set_rotary_min_angle 5 | export(float) var rotary_max_angle = 135.0 setget set_rotary_max_angle 6 | export(float) var radius = 85.0 setget set_radius 7 | 8 | const REFERENCE_WIDTH = 225 9 | 10 | const ROTARY_BASE_WIDTH = 25.0 11 | 12 | var rotary_width = 25.0 13 | 14 | export (float, 0, 1) var indicator_value = 0.0 setget set_indicator_value 15 | 16 | export(float) var indicator_line = 0.75 17 | export(float) var indicator_line_width = 2.0 18 | export(Color) var fill_post_line_color = Color(0.0,0.0,0.0,1.0) 19 | export(Color) var base_post_line_color = Color(0.0,0.0,0.0,0.25) 20 | export(Color) var fill_color = Color(1.0, 1.0, 1.0) setget set_fill_color 21 | 22 | func set_fill_color(value): 23 | fill_color = value 24 | update() 25 | 26 | func set_indicator_value(value): 27 | indicator_value = value 28 | update() 29 | 30 | func set_radius(value): 31 | radius = value 32 | update() 33 | 34 | func set_rotary_max_angle(value): 35 | rotary_max_angle = value 36 | update() 37 | 38 | func set_rotary_min_angle(value): 39 | rotary_max_angle = value 40 | update() 41 | 42 | func draw_circle_arc(center, radius, angle_from, angle_to, width, color, post_line_color=fill_post_line_color): 43 | var total_degrees = angle_to-angle_from 44 | var post_line = indicator_line 45 | var nb_points = int((total_degrees/270)*1000) # Subdivision of the Circular Arc / Lowest Decimal point for below 0.02 for health and oxygen 46 | var points_arc = PoolVector2Array() 47 | var post_line_points = PoolVector2Array() 48 | if nb_points > 0: 49 | for i in range(nb_points+1): 50 | var angle_point = angle_from + i * (angle_to-angle_from) / nb_points - 90 51 | if deg2completion(angle_point+90) >= post_line and post_line != -1: 52 | post_line_points.push_back(anglepoint2pos(center, angle_point, radius)) 53 | else: 54 | points_arc.push_back(anglepoint2pos(center, angle_point, radius)) 55 | if deg2completion(angle_to) >= post_line and post_line != -1: 56 | # ensure that the last and first point of the two indicator segments are always at 57 | # the middle of the orgasm line, this avoids some weird artifacting we had before 58 | var final_post_line_array = PoolVector2Array() 59 | var rotary_line_angle = indicator_line*(rotary_max_angle-rotary_min_angle) 60 | rotary_line_angle = rotary_min_angle + rotary_line_angle 61 | var common_point = anglepoint2pos(center, rotary_line_angle-90, radius) 62 | final_post_line_array.append(common_point) 63 | #final_post_line_array.append(Vector2(0,0)) 64 | final_post_line_array.append_array(post_line_points) 65 | points_arc.push_back(common_point) 66 | points_arc.push_back(common_point) 67 | points_arc.push_back(common_point) 68 | draw_polyline(final_post_line_array, post_line_color, width, true) 69 | 70 | draw_polyline(points_arc, color, width, true) 71 | print(points_arc.size()) 72 | 73 | func anglepoint2pos(center, angle_point, radius): 74 | return center + Vector2(cos(deg2rad(angle_point)), sin(deg2rad(angle_point))) * radius 75 | 76 | 77 | func _draw(): 78 | rotary_width = (ROTARY_BASE_WIDTH/REFERENCE_WIDTH)*rect_size.x 79 | draw_rotary_indicator((radius/REFERENCE_WIDTH)*rect_size.x, indicator_value, rotary_width) 80 | draw_rotary_line((radius/REFERENCE_WIDTH)*rect_size.x, 0.75, rotary_width) 81 | func deg2completion(completion_angle): 82 | var total_degrees = rotary_max_angle-rotary_min_angle 83 | completion_angle = completion_angle-rotary_min_angle 84 | return completion_angle / total_degrees 85 | 86 | func draw_rotary_indicator(radius, completion, width, draw_base=true): 87 | var completion_angle = completion*(rotary_max_angle-rotary_min_angle) 88 | completion_angle = rotary_min_angle + completion_angle 89 | # Draws the base 90 | if draw_base: 91 | draw_circle_arc(rect_size/2, radius, rotary_min_angle, rotary_max_angle, width, Color(0,0,0, 0.5), base_post_line_color) 92 | # Draws the completed part 93 | draw_circle_arc(rect_size/2, radius, rotary_min_angle, completion_angle, width, fill_color) 94 | 95 | func draw_rotary_line(radius, completion, width): 96 | var completion_angle = completion*(rotary_max_angle-rotary_min_angle) 97 | completion_angle = rotary_min_angle + completion_angle 98 | 99 | var angle_point = deg2rad(completion_angle - 50) 100 | 101 | var position_start = rect_size/2 + Vector2(cos(angle_point), sin(angle_point)) * (radius-rotary_width/2) 102 | var position_end = rect_size/2 + Vector2(cos(angle_point), sin(angle_point)) * (radius+rotary_width/2+4) 103 | 104 | #draw_line(position_start, position_end, Color(1.0,1.0,1.0), 4.0) 105 | -------------------------------------------------------------------------------- /assets/radar/Player_HUD.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | # class member variables go here, for example: 4 | # var a = 2 5 | # var b = "textvar" 6 | 7 | var health = 100 8 | var oxygen = 1000 9 | var debug = false 10 | onready var x1 : Control = get_node("VBoxContainer/HBoxContainer/HealthRadar/Container/x1") 11 | onready var x2 : Control = get_node("VBoxContainer/HBoxContainer/HealthRadar/Container/x2") 12 | onready var x3 : Control = get_node("VBoxContainer/HBoxContainer/HealthRadar/Container/x3") 13 | onready var Ox : Control = get_node("VBoxContainer/HBoxContainer/HealthRadar/Container/Oxygen") 14 | export(NodePath) var radarpath = null 15 | 16 | 17 | func _ready(): 18 | get_node("VBoxContainer/HBoxContainer/HealthRadar/Container/Radar").Ppath = radarpath 19 | # Called every time the node is added to the scene. 20 | # Initialization here 21 | #print(get_viewport().size) 22 | get_tree().get_root().connect("size_changed", self, "myfunc") 23 | # scale.x = (get_viewport().size.x/1920) 24 | # scale.y = (get_viewport().size.y/1080) 25 | if health >= 101: 26 | x2.visible = true 27 | if health >= 201: 28 | x3.visible = true 29 | change_health() 30 | change_oxygen(oxygen) 31 | 32 | 33 | func myfunc(): 34 | # scale.x = (get_viewport().size.x/1920) 35 | # scale.y = (get_viewport().size.y/1080) 36 | #print("Resizing: ", get_viewport().size) 37 | pass 38 | 39 | func _input(event): 40 | #print(health) 41 | #print(oxygen) 42 | 43 | if debug == false: 44 | pass 45 | elif debug == true: 46 | if event.is_action_pressed("healthup"): 47 | if health >= 300: 48 | health = 300 49 | pass 50 | else: 51 | health += 1 52 | elif event.is_action_pressed("healthdown"): 53 | if health <= 0: 54 | health = 0 55 | pass 56 | else: 57 | health -= 1 58 | 59 | if event.is_action_pressed("oxygenup"): 60 | if oxygen >= 1000: 61 | oxygen = 1000 62 | pass 63 | else: 64 | oxygen += 1 65 | elif event.is_action_pressed("oxygendown"): 66 | if oxygen <= 0: 67 | oxygen = 0 68 | pass 69 | else: 70 | oxygen -= 1 71 | 72 | else: 73 | pass 74 | 75 | change_health() 76 | change_oxygen(oxygen) 77 | pass 78 | 79 | #func _process(delta): 80 | # # Called every frame. Delta is time since last frame. 81 | # # Update game logic here. 82 | # pass 83 | 84 | func change_health(): 85 | 86 | if health >= 1 and health <= 100: 87 | #get_node("Health|Radar/x1/T_health").interpolate_property(x1,"indicator_value", null ,float(health)/100 ,1.5,Tween.TRANS_LINEAR,Tween.EASE_OUT,0) 88 | x1.indicator_value = float(health)/100 89 | elif health <= 0: 90 | x1.indicator_value = 0 91 | #get_node("Health|Radar/x1/T_health").interpolate_property(x1,"indicator_value", null ,0 ,1.5,Tween.TRANS_LINEAR,Tween.EASE_OUT,0) 92 | elif health >= 100: 93 | x1.indicator_value = 1 94 | #get_node("Health|Radar/x1/T_health").interpolate_property(x1,"indicator_value", null ,1 ,1.5,Tween.TRANS_LINEAR,Tween.EASE_OUT,0) 95 | 96 | if health >= 101 and health <= 200: 97 | x2.visible = true 98 | #get_node("Health|Radar/x2/T_health").interpolate_property(get_node("Health|Radar/x2"),"indicator_value", health ,float(health-100)/100 ,1,Tween.TRANS_LINEAR,Tween.EASE_OUT_IN,0) 99 | x2.indicator_value = float(health-100)/100 100 | elif health <= 100: 101 | #get_node("Health|Radar/x2/T_health").interpolate_property(get_node("Health|Radar/x2"),"indicator_value", health ,0 ,1,Tween.TRANS_LINEAR,Tween.EASE_OUT_IN,0) 102 | x2.indicator_value = 0 103 | x2.visible = false 104 | elif health >= 200: 105 | #get_node("Health|Radar/x2/T_health").interpolate_property(get_node("Health|Radar/x2"),"indicator_value", health ,1 ,1,Tween.TRANS_LINEAR,Tween.EASE_OUT_IN,0) 106 | x2.indicator_value = 1 107 | if health >= 201 and health <= 300: 108 | x3.visible = true 109 | x3.indicator_value = float(health-200)/100 110 | elif health <= 200: 111 | x3.indicator_value = 0 112 | x3.visible = false 113 | elif health >= 300: 114 | x3.indicator_value = 1 115 | 116 | if health <= 0: 117 | x1.indicator_value = 0 118 | x1.indicator_value = 0 119 | x3.indicator_value = 0 120 | pass 121 | 122 | 123 | 124 | func change_oxygen(oxygen): 125 | if oxygen >= 1 and oxygen <= 1000: 126 | Ox.indicator_value = float(oxygen)/1000 127 | elif oxygen <= 0: 128 | Ox.indicator_value = 0 129 | elif oxygen >= 1000: 130 | Ox.indicator_value = 1 131 | 132 | pass 133 | -------------------------------------------------------------------------------- /assets/radar/Player_Radar.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | var E_icon = preload("../ui/Enemy.tscn") 4 | var P_icon 5 | export(NodePath) var Ppath = null 6 | var E_Area 7 | # class member variables go here, for example: 8 | # var a = 2 9 | # var b = "textvar" 10 | var circle_size = 1 11 | 12 | func _ready(): 13 | 14 | #E_Area = get_tree().get_root().get_node("Area") 15 | #E_Area.connect("body_entered", self, "on_body_entered") 16 | #E_Area.connect("body_exited", self, "on_body_exit") 17 | #update() 18 | #draw_circle(Vector2(0,0),20,Color(1,1,1,1)) 19 | pass 20 | 21 | 22 | func _draw(): 23 | draw_circle(Vector2(circle_size/2,circle_size/2),circle_size/2,Color(0,0,0,.2)) 24 | $Blur.draw_circle(Vector2(circle_size/2,circle_size/2),circle_size/2,Color(0,0,0,.2)) 25 | 26 | func _on_body_entered(body): 27 | #if body.has_group("Enemy"): 28 | var Instanced = E_icon.instance() 29 | Instanced.name = str(body) 30 | Instanced.position = rect_position 31 | Instanced.represents = body 32 | Instanced.parentarea = E_Area 33 | add_child(Instanced) 34 | print("Icon created") 35 | 36 | func _on_body_exit(body): 37 | if body.is_in_group("Enemy") or body.is_in_group("Ally") or body.is_in_group("Player"): 38 | find_node(str(body)).queue_free() 39 | 40 | 41 | 42 | func _on_Radar_item_rect_changed(): 43 | if get_rect().size.x > get_rect().size.y: 44 | circle_size = get_rect().size.y 45 | elif get_rect().size.x < get_rect().size.y: 46 | circle_size = get_rect().size.x 47 | else: 48 | if circle_size != get_rect().size.x and circle_size != get_rect().size.y: 49 | circle_size = get_rect().size.x 50 | else: 51 | circle_size = circle_size 52 | 53 | -------------------------------------------------------------------------------- /assets/radar/Player_Weapon.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | 4 | # class member variables go here, for example: 5 | # var a = 2 6 | # var b = "textvar" 7 | 8 | func _ready(): 9 | # Called every time the node is added to the scene. 10 | # Initialization here 11 | pass 12 | 13 | func _draw(): 14 | draw_rect(Rect2(Vector2(get_rect().size.x-get_rect().size.x,get_rect().size.y-get_rect().size.y),Vector2(get_rect().size.x,get_rect().size.y)),Color(0,0,0,.2)) 15 | pass 16 | 17 | #func _process(delta): 18 | # # Called every frame. Delta is time since last frame. 19 | # # Update game logic here. 20 | # pass 21 | -------------------------------------------------------------------------------- /assets/ui/Blur.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="ShaderMaterial" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://assets/Shaders/Blur.shader" type="Shader" id=1] 4 | 5 | [resource] 6 | shader = ExtResource( 1 ) 7 | shader_param/blurSize = 10 8 | -------------------------------------------------------------------------------- /assets/ui/Enemy.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [sub_resource type="GDScript" id=1] 4 | script/source = "extends Polygon2D 5 | 6 | var represents = null 7 | var parentarea = null 8 | var zero 9 | 10 | func _ready(): 11 | pass 12 | 13 | func _process(delta): 14 | var rep = represents.translation - parentarea.translation 15 | position = get_parent().position + (Vector2(rep.x, rep.z)/25) 16 | " 17 | 18 | [node name="Polygon2D" type="Polygon2D"] 19 | position = Vector2( 0, 4.64218 ) 20 | scale = Vector2( 0.467832, 0.42772 ) 21 | color = Color( 1, 0, 0, 1 ) 22 | antialiased = true 23 | polygon = PoolVector2Array( 0, -30, -10, 0, 10, 0 ) 24 | script = SubResource( 1 ) 25 | -------------------------------------------------------------------------------- /assets/ui/Player_GUI.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://joyeuse/assets/radar/Player_HUD.gd" type="Script" id=1] 4 | [ext_resource path="res://joyeuse/assets/radar/Player_GUI.gd" type="Script" id=2] 5 | [ext_resource path="res://joyeuse/assets/radar/Player_Radar.gd" type="Script" id=3] 6 | [ext_resource path="res://joyeuse/assets/ui/Blur.tres" type="Material" id=4] 7 | [ext_resource path="res://joyeuse/assets/radar/Player_Weapon.gd" type="Script" id=5] 8 | 9 | [node name="HUD" type="Control"] 10 | anchor_right = 1.0 11 | anchor_bottom = 1.0 12 | script = ExtResource( 1 ) 13 | __meta__ = { 14 | "_edit_use_anchors_": false 15 | } 16 | 17 | [node name="VBoxContainer" type="VBoxContainer" parent="."] 18 | anchor_right = 1.0 19 | anchor_bottom = 1.0 20 | __meta__ = { 21 | "_edit_use_anchors_": false 22 | } 23 | 24 | [node name="Control" type="Control" parent="VBoxContainer"] 25 | margin_right = 1024.0 26 | margin_bottom = 146.0 27 | size_flags_vertical = 3 28 | 29 | [node name="Control2" type="Control" parent="VBoxContainer"] 30 | margin_top = 150.0 31 | margin_right = 1024.0 32 | margin_bottom = 297.0 33 | size_flags_vertical = 3 34 | 35 | [node name="Control3" type="Control" parent="VBoxContainer"] 36 | margin_top = 301.0 37 | margin_right = 1024.0 38 | margin_bottom = 448.0 39 | size_flags_vertical = 3 40 | 41 | [node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] 42 | margin_top = 452.0 43 | margin_right = 1024.0 44 | margin_bottom = 600.0 45 | size_flags_vertical = 3 46 | 47 | [node name="HealthRadar" type="Control" parent="VBoxContainer/HBoxContainer"] 48 | margin_right = 120.0 49 | margin_bottom = 148.0 50 | rect_min_size = Vector2( 120, 148 ) 51 | 52 | [node name="Container" type="Node2D" parent="VBoxContainer/HBoxContainer/HealthRadar"] 53 | position = Vector2( 60, 60 ) 54 | 55 | [node name="x1" type="Control" parent="VBoxContainer/HBoxContainer/HealthRadar/Container"] 56 | margin_left = -15.7676 57 | margin_top = -24.6559 58 | margin_right = 54.2324 59 | margin_bottom = 45.3441 60 | script = ExtResource( 2 ) 61 | __meta__ = { 62 | "_edit_use_anchors_": false 63 | } 64 | rotary_max_angle = 0.0 65 | radius = 200.0 66 | indicator_value = 1.0 67 | indicator_line = 0.0 68 | fill_post_line_color = Color( 1, 0, 0, 1 ) 69 | base_post_line_color = Color( 0, 0, 0, 0.2 ) 70 | fill_color = Color( 0, 0, 0, 0 ) 71 | 72 | [node name="T_health" type="Tween" parent="VBoxContainer/HBoxContainer/HealthRadar/Container/x1"] 73 | 74 | [node name="x2" type="Control" parent="VBoxContainer/HBoxContainer/HealthRadar/Container"] 75 | margin_left = -15.7676 76 | margin_top = -24.6559 77 | margin_right = 54.2324 78 | margin_bottom = 45.3441 79 | script = ExtResource( 2 ) 80 | rotary_max_angle = 0.0 81 | radius = 200.0 82 | indicator_value = 1.0 83 | indicator_line = 0.0 84 | fill_post_line_color = Color( 1, 0.726563, 0, 1 ) 85 | base_post_line_color = Color( 0, 0, 0, 0 ) 86 | fill_color = Color( 0, 0, 0, 0.0663137 ) 87 | 88 | [node name="T_health" type="Tween" parent="VBoxContainer/HBoxContainer/HealthRadar/Container/x2"] 89 | 90 | [node name="x3" type="Control" parent="VBoxContainer/HBoxContainer/HealthRadar/Container"] 91 | margin_left = -15.7676 92 | margin_top = -24.6559 93 | margin_right = 54.2324 94 | margin_bottom = 45.3441 95 | rect_pivot_offset = Vector2( 50, 50 ) 96 | script = ExtResource( 2 ) 97 | __meta__ = { 98 | "_edit_use_anchors_": false 99 | } 100 | rotary_max_angle = 0.0 101 | radius = 200.0 102 | indicator_value = 1.0 103 | indicator_line = 0.0 104 | fill_post_line_color = Color( 0.768066, 0, 0.8125, 1 ) 105 | base_post_line_color = Color( 0, 0, 0, 0 ) 106 | fill_color = Color( 0, 0, 0, 0.0663137 ) 107 | 108 | [node name="Oxygen" type="Control" parent="VBoxContainer/HBoxContainer/HealthRadar/Container"] 109 | margin_left = -27.3589 110 | margin_top = -36.3948 111 | margin_right = 42.6411 112 | margin_bottom = 33.6052 113 | rect_scale = Vector2( 0.25, 0.25 ) 114 | rect_pivot_offset = Vector2( 50, 50 ) 115 | script = ExtResource( 2 ) 116 | rotary_max_angle = 0.0 117 | radius = 900.0 118 | indicator_value = 1.0 119 | indicator_line = 0.0 120 | indicator_line_width = 0.0 121 | fill_post_line_color = Color( 0, 1, 0.953125, 1 ) 122 | base_post_line_color = Color( 0, 0, 0, 0.2 ) 123 | fill_color = Color( 0, 0, 0, 0.0663137 ) 124 | 125 | [node name="Radar" type="Control" parent="VBoxContainer/HBoxContainer/HealthRadar/Container"] 126 | margin_left = -29.2345 127 | margin_top = -36.6128 128 | margin_right = 70.7655 129 | margin_bottom = 63.3872 130 | script = ExtResource( 3 ) 131 | __meta__ = { 132 | "_edit_use_anchors_": false 133 | } 134 | Ppath = null 135 | 136 | [node name="Blur" type="Control" parent="VBoxContainer/HBoxContainer/HealthRadar/Container/Radar"] 137 | modulate = Color( 1, 1, 1, 0.784314 ) 138 | material = ExtResource( 4 ) 139 | margin_left = -32.0 140 | margin_top = -28.0 141 | margin_right = 183.0 142 | margin_bottom = 194.0 143 | __meta__ = { 144 | "_edit_use_anchors_": false 145 | } 146 | 147 | [node name="Control2" type="CenterContainer" parent="VBoxContainer/HBoxContainer"] 148 | margin_left = 124.0 149 | margin_right = 1024.0 150 | margin_bottom = 148.0 151 | size_flags_horizontal = 3 152 | size_flags_vertical = 3 153 | 154 | [node name="Weapon" type="Control" parent="VBoxContainer/HBoxContainer/Control2"] 155 | margin_left = 450.0 156 | margin_top = 74.0 157 | margin_right = 450.0 158 | margin_bottom = 74.0 159 | size_flags_horizontal = 3 160 | size_flags_vertical = 3 161 | script = ExtResource( 5 ) 162 | 163 | [node name="Blur" type="ColorRect" parent="VBoxContainer/HBoxContainer/Control2"] 164 | modulate = Color( 1, 1, 1, 0.784314 ) 165 | material = ExtResource( 4 ) 166 | margin_left = 450.0 167 | margin_top = 74.0 168 | margin_right = 450.0 169 | margin_bottom = 74.0 170 | size_flags_horizontal = 3 171 | size_flags_vertical = 3 172 | color = Color( 0, 0, 0, 0 ) 173 | 174 | [node name="Weapon|Ammo" type="Node2D" parent="."] 175 | position = Vector2( 1612.46, 945.77 ) 176 | 177 | [node name="T_oxygen" type="Tween" parent="."] 178 | [connection signal="item_rect_changed" from="VBoxContainer/HBoxContainer/HealthRadar/Container/Radar" to="VBoxContainer/HBoxContainer/HealthRadar/Container/Radar" method="_on_Radar_item_rect_changed"] 179 | -------------------------------------------------------------------------------- /assets/ui/Radar.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | # class member variables go here, for example: 4 | # var a = 2 5 | # var b = "textvar" 6 | 7 | func _ready(): 8 | # Called every time the node is added to the scene. 9 | # Initialization here 10 | pass 11 | 12 | #func _process(delta): 13 | # # Called every frame. Delta is time since last frame. 14 | # # Update game logic here. 15 | # pass 16 | -------------------------------------------------------------------------------- /core/AI_TEST.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=2] 2 | 3 | [ext_resource path="res://joyeuse/core/npc_ai/AI_Individual.gd" type="Script" id=1] 4 | [ext_resource path="res://joyeuse/core/npc_ai/components/vision_colliders.gd" type="Script" id=2] 5 | 6 | 7 | 8 | 9 | 10 | [sub_resource type="CapsuleShape" id=1] 11 | radius = 0.679838 12 | height = 1.87215 13 | 14 | [sub_resource type="CapsuleMesh" id=2] 15 | 16 | [sub_resource type="SpatialMaterial" id=3] 17 | albedo_color = Color( 0, 0.180392, 1, 1 ) 18 | 19 | [sub_resource type="SphereMesh" id=4] 20 | radius = 0.25 21 | height = 0.5 22 | 23 | [sub_resource type="SpatialMaterial" id=5] 24 | flags_unshaded = true 25 | albedo_color = Color( 0.666667, 0.780392, 0, 1 ) 26 | 27 | [node name="AI_Character" type="KinematicBody"] 28 | collision_mask = 3 29 | script = ExtResource( 1 ) 30 | 31 | [node name="CollisionShape" type="CollisionShape" parent="."] 32 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0.945411, 0 ) 33 | shape = SubResource( 1 ) 34 | 35 | [node name="MeshInstance" type="MeshInstance" parent="."] 36 | transform = Transform( 0.674556, 0, 0, 0, -4.59801e-08, 1.0519, 0, -0.674556, -2.94858e-08, 0, 0.996896, 0 ) 37 | mesh = SubResource( 2 ) 38 | material/0 = SubResource( 3 ) 39 | 40 | [node name="Eyes" type="Spatial" parent="."] 41 | transform = Transform( -1.2358e-06, 0, 1, 0, 1, 0, -1, 0, -1.2358e-06, -1.05526, 2.01, 0 ) 42 | script = ExtResource( 2 ) 43 | 44 | [node name="RayCast" type="RayCast" parent="Eyes"] 45 | transform = Transform( 1, 1.42109e-14, 0, 0, 1, -1.75618e-20, 0, 0, 1, 0, 0, 0 ) 46 | enabled = true 47 | cast_to = Vector3( 0, 0, -5 ) 48 | collision_mask = 2 49 | 50 | [node name="RayCast4" type="RayCast" parent="Eyes"] 51 | transform = Transform( 1, 3.19849e-07, 4.21089e-08, -3.19849e-07, 0.965926, 0.258819, 4.21089e-08, -0.258819, 0.965926, 0, 0, 0 ) 52 | enabled = true 53 | cast_to = Vector3( 0, 0, -5 ) 54 | collision_mask = 2 55 | 56 | [node name="RayCast12" type="RayCast" parent="Eyes"] 57 | transform = Transform( 1, -6.17903e-07, 1.65566e-07, 6.17903e-07, 0.866025, -0.5, 1.65567e-07, 0.5, 0.866025, 0, 0, 0 ) 58 | enabled = true 59 | cast_to = Vector3( 0, 0, -5 ) 60 | collision_mask = 2 61 | 62 | [node name="RayCast9" type="RayCast" parent="Eyes"] 63 | transform = Transform( 1, -3.19849e-07, 4.21089e-08, 3.19849e-07, 0.965926, -0.258819, 4.21089e-08, 0.258819, 0.965926, 0, 0, 0 ) 64 | enabled = true 65 | cast_to = Vector3( 0, 0, -5 ) 66 | collision_mask = 2 67 | 68 | [node name="RayCast2" type="RayCast" parent="Eyes"] 69 | transform = Transform( 0.965926, 0, 0.258819, 0, 1, 0, -0.258819, 0, 0.965926, -0.0529401, 0, -1.19209e-07 ) 70 | enabled = true 71 | cast_to = Vector3( -2, 0, -4.5 ) 72 | 73 | [node name="RayCast5" type="RayCast" parent="Eyes"] 74 | transform = Transform( 1, 3.19849e-07, 4.21089e-08, -3.19849e-07, 0.965926, 0.258819, 4.21089e-08, -0.258819, 0.965926, -0.0529401, 0, -1.19209e-07 ) 75 | enabled = true 76 | cast_to = Vector3( -2, 0, -4.5 ) 77 | 78 | [node name="RayCast11" type="RayCast" parent="Eyes"] 79 | transform = Transform( 1, -6.17903e-07, 1.65566e-07, 6.17903e-07, 0.866025, -0.5, 1.65567e-07, 0.5, 0.866025, -0.0529401, 5.96046e-08, -1.19209e-07 ) 80 | enabled = true 81 | cast_to = Vector3( -2, 0, -4.5 ) 82 | 83 | [node name="RayCast8" type="RayCast" parent="Eyes"] 84 | transform = Transform( 1, -3.19849e-07, 4.21089e-08, 3.19849e-07, 0.965926, -0.258819, 4.21089e-08, 0.258819, 0.965926, -0.0529401, 0, -1.19209e-07 ) 85 | enabled = true 86 | cast_to = Vector3( -2, 0, -4.5 ) 87 | 88 | [node name="RayCast3" type="RayCast" parent="Eyes"] 89 | transform = Transform( 0.965926, 0, -0.258819, 0, 1, 0, 0.258819, 0, 0.965926, 0.0664887, 0, 1.19209e-07 ) 90 | enabled = true 91 | cast_to = Vector3( 2, 0, -4.5 ) 92 | 93 | [node name="RayCast6" type="RayCast" parent="Eyes"] 94 | transform = Transform( 1, 3.19849e-07, 4.21089e-08, -3.19849e-07, 0.965926, 0.258819, 4.21089e-08, -0.258819, 0.965926, 0.0664887, 0, 1.19209e-07 ) 95 | enabled = true 96 | cast_to = Vector3( 2, 0, -4.5 ) 97 | 98 | [node name="MeshInstance2" type="MeshInstance" parent="Eyes/RayCast6"] 99 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.00155115, 0.0153136, -5.05121 ) 100 | mesh = SubResource( 4 ) 101 | material/0 = SubResource( 5 ) 102 | 103 | [node name="RayCast10" type="RayCast" parent="Eyes"] 104 | transform = Transform( 1, -6.17903e-07, 1.65566e-07, 6.17903e-07, 0.866025, -0.5, 1.65567e-07, 0.5, 0.866025, 0.0664887, 0, 8.9407e-08 ) 105 | enabled = true 106 | cast_to = Vector3( 2, 0, -4.5 ) 107 | 108 | [node name="MeshInstance2" type="MeshInstance" parent="Eyes/RayCast10"] 109 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.00155115, 0.0153136, -5.05121 ) 110 | mesh = SubResource( 4 ) 111 | material/0 = SubResource( 5 ) 112 | 113 | [node name="RayCast7" type="RayCast" parent="Eyes"] 114 | transform = Transform( 1, -3.19849e-07, 4.21089e-08, 3.19849e-07, 0.965926, -0.258819, 4.21089e-08, 0.258819, 0.965926, 0.0664887, 0, 1.19209e-07 ) 115 | enabled = true 116 | cast_to = Vector3( 2, 0, -4.5 ) 117 | 118 | [node name="MeshInstance2" type="MeshInstance" parent="Eyes/RayCast7"] 119 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.00155115, 0.0153136, -5.05121 ) 120 | mesh = SubResource( 4 ) 121 | material/0 = SubResource( 5 ) 122 | 123 | [node name="Mouth" type="AudioStreamPlayer3D" parent="."] 124 | [connection signal="sight" from="Eyes" to="." method="_on_Eyes_sight"] 125 | -------------------------------------------------------------------------------- /core/Animation/BoneHandler.gd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/core/Animation/BoneHandler.gd -------------------------------------------------------------------------------- /core/Animation/CopyAttachment.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends BoneAttachment 3 | 4 | export(NodePath) var Target 5 | var reference : Spatial 6 | var bone_idx : int = 0 7 | var target_skeleton : Skeleton 8 | onready var current_skeleton : Skeleton = get_parent() 9 | func _ready(): 10 | reference = get_node_or_null(Target) 11 | for bones in range(0, current_skeleton.get_bone_count()): 12 | if current_skeleton.get_bone_name(bones) == bone_name: 13 | bone_idx = bones 14 | if reference!= null: 15 | target_skeleton = reference.get_parent() 16 | 17 | func _process(delta): 18 | # parent.set_bone_custom_pose(bone_idx, reference.transform) 19 | get_parent().set_bone_global_pose_override(bone_idx, reference.get_parent().get_bone_global_pose(bone_idx),1,false) 20 | 21 | -------------------------------------------------------------------------------- /core/Animation/HelperSkeleton.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Skeleton 3 | 4 | """ 5 | This is the code for a helper skeleton, which manages all the IK solvings and 6 | complex animations systems, to be delivered to the main skeleton which cannot 7 | do these operations, otherwise the mesh will be deformed 8 | """ 9 | 10 | var R_Hand_Target : Spatial 11 | var L_Hand_Target : Spatial 12 | var R_Foot_Target : Spatial 13 | var L_Foot_Target : Spatial 14 | 15 | export(NodePath) var R_Hand_IK 16 | export(NodePath) var L_Hand_IK 17 | export(NodePath) var R_Foot_IK 18 | export(NodePath) var L_Foot_IK 19 | 20 | export(NodePath) var L_Hand_Magnet 21 | export(NodePath) var R_Hand_Magnet 22 | 23 | var RHANDIK : SkeletonIK 24 | var LHANDIK : SkeletonIK 25 | var RFOOTIK : SkeletonIK 26 | var LFOOTIK : SkeletonIK 27 | 28 | var RHANDMAGNET : Spatial 29 | var LHANDMAGNET : Spatial 30 | 31 | func _ready(): 32 | setup_IK() 33 | 34 | func setup_IK(): 35 | RHANDIK = get_node_or_null(R_Hand_IK) 36 | LHANDIK = get_node_or_null(L_Hand_IK) 37 | RFOOTIK = get_node_or_null(R_Foot_IK) 38 | LFOOTIK = get_node_or_null(L_Foot_IK) 39 | RHANDMAGNET = get_node_or_null(R_Hand_Magnet) 40 | LHANDMAGNET = get_node_or_null(L_Hand_Magnet) 41 | if RHANDIK != null and R_Hand_Target != null: 42 | if RHANDMAGNET!=null: 43 | RHANDIK.use_magnet = true 44 | RHANDIK.start() 45 | if LHANDIK != null and L_Hand_Target != null: 46 | if LHANDMAGNET!=null: 47 | LHANDIK.use_magnet = true 48 | LHANDIK.start() 49 | if RFOOTIK!= null and R_Foot_Target != null: 50 | RFOOTIK.start() 51 | if LFOOTIK != null and L_Foot_Target != null: 52 | LFOOTIK.start() 53 | 54 | func _process(_delta): 55 | if LHANDIK != null and L_Hand_Target != null: 56 | LHANDIK.target = L_Hand_Target.global_transform 57 | if LHANDMAGNET!=null: 58 | LHANDIK.magnet = LHANDMAGNET.translation 59 | 60 | if RHANDIK != null and R_Hand_Target != null: 61 | RHANDIK.target = R_Hand_Target.global_transform 62 | if RHANDMAGNET!=null: 63 | RHANDIK.magnet = RHANDMAGNET.translation 64 | 65 | if RFOOTIK!= null and R_Foot_Target != null: 66 | RFOOTIK.target = R_Foot_Target.global_transform 67 | 68 | if LFOOTIK != null and L_Foot_Target != null: 69 | LFOOTIK.target = L_Foot_Target.transform 70 | -------------------------------------------------------------------------------- /core/Animation/HelperSkeleton.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://Joyeuse/core/Animation/HelperSkeleton.gd" type="Script" id=1] 4 | 5 | 6 | [node name="Skeleton2" type="Skeleton"] 7 | bones/0/name = "pelvis" 8 | bones/0/parent = -1 9 | bones/0/rest = Transform( 1, 2.38419e-07, 7.8381e-14, -1.13687e-13, 4.76837e-07, -1, -2.38419e-07, 1, 3.28753e-07, 1.95042e-08, 1.57899, 0.0818062 ) 10 | bones/0/enabled = true 11 | bones/0/bound_children = [ ] 12 | bones/1/name = "abdomen" 13 | bones/1/parent = 0 14 | bones/1/rest = Transform( 0.999973, -0.00408914, -0.00610207, 0.00555876, 0.964307, 0.264728, 0.00480177, -0.264755, 0.964304, -8.79564e-08, 2.30968e-07, -0.367955 ) 15 | bones/1/enabled = true 16 | bones/1/bound_children = [ ] 17 | bones/2/name = "chest" 18 | bones/2/parent = 1 19 | bones/2/rest = Transform( 0.999998, -1.13952e-05, -0.00178645, -0.000428647, 0.96924, -0.246118, 0.00173426, 0.246119, 0.969238, 8.84756e-08, 5.96046e-08, -0.471769 ) 20 | bones/2/enabled = true 21 | bones/2/bound_children = [ ] 22 | bones/3/name = "neck" 23 | bones/3/parent = 2 24 | bones/3/rest = Transform( -0.999963, -0.00826893, 0.00253562, 0.00547623, -0.83225, -0.554373, 0.00669423, -0.554338, 0.832265, -3.57628e-07, -1.45286e-07, -0.430027 ) 25 | bones/3/enabled = true 26 | bones/3/bound_children = [ ] 27 | bones/4/name = "head" 28 | bones/4/parent = 3 29 | bones/4/rest = Transform( -1, -2.3964e-07, -1.35695e-13, 3.56474e-07, -0.842796, -0.538234, 1.28979e-07, -0.538234, 0.842796, -4.20958e-07, -1.19209e-07, -0.128967 ) 30 | bones/4/enabled = true 31 | bones/4/bound_children = [ ] 32 | bones/5/name = "head_end" 33 | bones/5/parent = 4 34 | bones/5/rest = Transform( 1, 1.16816e-07, 6.81598e-14, -1.16816e-07, 1, 1.7236e-08, 6.14371e-15, -1.72359e-08, 1, 2.32831e-09, 3.72529e-09, -0.239423 ) 35 | bones/5/enabled = true 36 | bones/5/bound_children = [ ] 37 | bones/6/name = "L_clav" 38 | bones/6/parent = 2 39 | bones/6/rest = Transform( 0.00560379, 0.395863, -0.918293, 0.999799, 0.0154522, 0.0127625, 0.0192418, -0.91818, -0.395697, 1.78814e-07, -1.41561e-07, -0.430027 ) 40 | bones/6/enabled = true 41 | bones/6/bound_children = [ ] 42 | bones/7/name = "L_bicep" 43 | bones/7/parent = 6 44 | bones/7/rest = Transform( 0.996001, -0.0889112, 0.00875284, 0.0788885, 0.921226, 0.380946, -0.0419336, -0.378732, 0.924556, 1.30385e-07, 0, -0.283718 ) 45 | bones/7/enabled = true 46 | bones/7/bound_children = [ NodePath("L_bicep") ] 47 | bones/8/name = "L_forearn" 48 | bones/8/parent = 7 49 | bones/8/rest = Transform( 0.94204, 0.00641634, -0.335439, 0.0134767, 0.998287, 0.0569432, 0.335229, -0.0581634, 0.94034, 1.49012e-07, 9.53674e-07, -0.520194 ) 50 | bones/8/enabled = true 51 | bones/8/bound_children = [ NodePath("L_forearm") ] 52 | bones/9/name = "L_hand" 53 | bones/9/parent = 8 54 | bones/9/rest = Transform( 0.997437, 0.0661197, 0.0273358, -0.070673, 0.970053, 0.232383, -0.0111521, -0.233719, 0.97224, 0, -8.34465e-07, -0.571641 ) 55 | bones/9/enabled = true 56 | bones/9/bound_children = [ NodePath("L_Hand") ] 57 | bones/10/name = "L_00" 58 | bones/10/parent = 9 59 | bones/10/rest = Transform( -0.60031, 0.538941, -0.590907, -0.791832, -0.504342, 0.344443, -0.112384, 0.674671, 0.729512, 0.0516528, -0.0297257, -0.046725 ) 60 | bones/10/enabled = true 61 | bones/10/bound_children = [ ] 62 | bones/11/name = "L_01_end" 63 | bones/11/parent = 10 64 | bones/11/rest = Transform( 0.717622, -0.540703, -0.438929, 0.694396, 0.603693, 0.391624, 0.0532261, -0.585829, 0.808685, -1.07288e-06, -3.12924e-07, -0.0955379 ) 65 | bones/11/enabled = true 66 | bones/11/bound_children = [ ] 67 | bones/12/name = "L_10" 68 | bones/12/parent = 9 69 | bones/12/rest = Transform( 0.928197, -0.312087, -0.202614, 0.358296, 0.896546, 0.260441, 0.100372, -0.314336, 0.94399, 0.0467919, -0.0096457, -0.192794 ) 70 | bones/12/enabled = true 71 | bones/12/bound_children = [ ] 72 | bones/13/name = "L_12" 73 | bones/13/parent = 12 74 | bones/13/rest = Transform( 0.99033, 0.124617, 0.060973, -0.129973, 0.987088, 0.0936157, -0.0485197, -0.100635, 0.99374, -7.15256e-07, 3.57628e-07, -0.0481131 ) 75 | bones/13/enabled = true 76 | bones/13/bound_children = [ ] 77 | bones/14/name = "L_12_end" 78 | bones/14/parent = 13 79 | bones/14/rest = Transform( 0.994341, 0.0076049, 0.105964, -0.00634952, 0.999906, -0.012179, -0.106046, 0.0114372, 0.994295, 1.78814e-07, 3.57628e-07, -0.0425063 ) 80 | bones/14/enabled = true 81 | bones/14/bound_children = [ ] 82 | bones/15/name = "L_20" 83 | bones/15/parent = 9 84 | bones/15/rest = Transform( 0.938004, -0.322528, 0.126975, 0.297822, 0.93734, 0.18082, -0.177339, -0.131794, 0.975285, 0.00882375, -0.00676274, -0.179934 ) 85 | bones/15/enabled = true 86 | bones/15/bound_children = [ ] 87 | bones/16/name = "L_22" 88 | bones/16/parent = 15 89 | bones/16/rest = Transform( 0.968022, 0.240616, -0.0709719, -0.210757, 0.933483, 0.290157, 0.136067, -0.26592, 0.954344, 0, -3.57628e-07, -0.0644745 ) 90 | bones/16/enabled = true 91 | bones/16/bound_children = [ ] 92 | bones/17/name = "L_22_end" 93 | bones/17/parent = 16 94 | bones/17/rest = Transform( 0.997054, -0.00333062, -0.0766305, 0.00567102, 0.999524, 0.0303441, 0.0764929, -0.0306893, 0.996598, 0, 4.76837e-07, -0.050398 ) 95 | bones/17/enabled = true 96 | bones/17/bound_children = [ ] 97 | bones/18/name = "L_30" 98 | bones/18/parent = 9 99 | bones/18/rest = Transform( 0.921026, -0.251371, 0.29753, 0.211216, 0.964135, 0.160725, -0.327261, -0.085189, 0.941086, -0.0349067, -0.013962, -0.173918 ) 100 | bones/18/enabled = true 101 | bones/18/bound_children = [ ] 102 | bones/19/name = "L_32" 103 | bones/19/parent = 18 104 | bones/19/rest = Transform( 0.949941, 0.303744, -0.0731544, -0.268026, 0.912596, 0.308756, 0.160543, -0.273693, 0.948323, -1.78814e-07, 1.19209e-07, -0.0660194 ) 105 | bones/19/enabled = true 106 | bones/19/bound_children = [ ] 107 | bones/20/name = "L_32_end" 108 | bones/20/parent = 19 109 | bones/20/rest = Transform( 1, 1.93715e-06, 1.69873e-06, -1.80304e-06, 1, -5.31785e-06, -1.69873e-06, 5.33648e-06, 1, 1.19209e-07, 2.38419e-07, -0.0409808 ) 110 | bones/20/enabled = true 111 | bones/20/bound_children = [ ] 112 | bones/21/name = "L_40" 113 | bones/21/parent = 9 114 | bones/21/rest = Transform( 0.891949, -0.252803, 0.374856, 0.190899, 0.962122, 0.194623, -0.409859, -0.102034, 0.906424, -0.0770637, -0.026847, -0.166466 ) 115 | bones/21/enabled = true 116 | bones/21/bound_children = [ ] 117 | bones/22/name = "L_43" 118 | bones/22/parent = 21 119 | bones/22/rest = Transform( 0.967554, 0.252662, 0.000608429, -0.248917, 0.952793, 0.173855, 0.043347, -0.168366, 0.984771, -5.96046e-08, -1.19209e-07, -0.0481071 ) 120 | bones/22/enabled = true 121 | bones/22/bound_children = [ ] 122 | bones/23/name = "L_43_end" 123 | bones/23/parent = 22 124 | bones/23/rest = Transform( 0.999963, 0.000358008, -0.00863832, -0.000336304, 0.999997, 0.00251644, 0.0086392, -0.00251341, 0.999959, 2.98023e-08, 2.38419e-07, -0.0465863 ) 125 | bones/23/enabled = true 126 | bones/23/bound_children = [ ] 127 | bones/24/name = "R_clav" 128 | bones/24/parent = 2 129 | bones/24/rest = Transform( 0.00560444, 0.407922, 0.912999, 0.999799, -0.0198532, 0.0027332, 0.0192409, 0.912801, -0.407951, -0.0115149, 6.29723e-05, -0.42995 ) 130 | bones/24/enabled = true 131 | bones/24/bound_children = [ ] 132 | bones/25/name = "R_bicep" 133 | bones/25/parent = 24 134 | bones/25/rest = Transform( 0.996823, 0.0791707, 0.00875312, -0.0698793, 0.921953, -0.380945, -0.0382296, 0.379123, 0.924556, 8.9407e-08, 4.76837e-07, -0.283719 ) 135 | bones/25/enabled = true 136 | bones/25/bound_children = [ NodePath("R_bicep") ] 137 | bones/26/name = "R_forearn" 138 | bones/26/parent = 25 139 | bones/26/rest = Transform( -0.941864, -0.00334956, -0.335977, 0.0226969, -0.9983, -0.0536753, -0.335226, -0.0581802, 0.94034, -1.49012e-07, -4.76837e-07, -0.520192 ) 140 | bones/26/enabled = true 141 | bones/26/bound_children = [ NodePath("R_forearm") ] 142 | bones/27/name = "R_hand" 143 | bones/27/parent = 26 144 | bones/27/rest = Transform( 0.997437, -0.0661308, -0.0273368, 0.070684, 0.970055, 0.232375, 0.011151, -0.233712, 0.972242, 5.96046e-08, 0, -0.571643 ) 145 | bones/27/enabled = true 146 | bones/27/bound_children = [ NodePath("R_Hand") ] 147 | bones/28/name = "L_00.001" 148 | bones/28/parent = 27 149 | bones/28/rest = Transform( -0.6448, 0.442711, 0.62309, -0.315114, -0.896655, 0.310988, 0.696374, 0.00418098, 0.717667, -0.0542897, -0.0384948, -0.0469518 ) 150 | bones/28/enabled = true 151 | bones/28/bound_children = [ ] 152 | bones/29/name = "L_01.001_end" 153 | bones/29/parent = 28 154 | bones/29/rest = Transform( -0.648837, 0.585895, 0.485528, -0.734415, -0.649146, -0.198104, 0.19911, -0.485116, 0.85148, 1.19209e-07, 2.38419e-07, -0.09934 ) 155 | bones/29/enabled = true 156 | bones/29/bound_children = [ ] 157 | bones/30/name = "L_10.001" 158 | bones/30/parent = 27 159 | bones/30/rest = Transform( -0.872182, -0.414465, 0.259843, 0.403075, -0.909868, -0.0983433, 0.277182, 0.0189628, 0.96063, -0.0444485, -0.0217496, -0.195378 ) 160 | bones/30/enabled = true 161 | bones/30/bound_children = [ ] 162 | bones/31/name = "L_12.001" 163 | bones/31/parent = 30 164 | bones/31/rest = Transform( 0.918721, -0.0969104, 0.382832, 0.234264, 0.914171, -0.330774, -0.317918, 0.393573, 0.862571, 1.19209e-07, -4.76837e-07, -0.0495548 ) 165 | bones/31/enabled = true 166 | bones/31/bound_children = [ ] 167 | bones/32/name = "L_12.001_end" 168 | bones/32/parent = 31 169 | bones/32/rest = Transform( 0.996255, -0.00178878, -0.086445, -0.00178004, 0.99915, -0.0411893, 0.0864452, 0.0411888, 0.995405, -5.96046e-08, 2.38419e-07, -0.041351 ) 170 | bones/32/enabled = true 171 | bones/32/bound_children = [ ] 172 | bones/33/name = "L_20.001" 173 | bones/33/parent = 27 174 | bones/33/rest = Transform( -0.910872, -0.391513, 0.1305, 0.395454, -0.918474, 0.00470007, 0.118021, 0.0558878, 0.991438, 0.00211921, -0.014021, -0.192293 ) 175 | bones/33/enabled = true 176 | bones/33/bound_children = [ ] 177 | bones/34/name = "L_22.001" 178 | bones/34/parent = 33 179 | bones/34/rest = Transform( 0.952911, -0.0680335, 0.295522, 0.14481, 0.958308, -0.246324, -0.266443, 0.277519, 0.923034, 2.38419e-07, -1.19209e-07, -0.0516621 ) 180 | bones/34/enabled = true 181 | bones/34/bound_children = [ ] 182 | bones/35/name = "L_22.001_end" 183 | bones/35/parent = 34 184 | bones/35/rest = Transform( 0.999861, -0.000765011, -0.0166212, -0.000752933, 0.995839, -0.0911272, 0.0166217, 0.0911271, 0.9957, -1.78814e-07, 1.19209e-07, -0.0546975 ) 185 | bones/35/enabled = true 186 | bones/35/bound_children = [ ] 187 | bones/36/name = "L_30.001" 188 | bones/36/parent = 27 189 | bones/36/rest = Transform( -0.9613, -0.273636, 0.0320197, 0.274394, -0.96136, 0.0222503, 0.0246938, 0.0301752, 0.999239, 0.0544452, -0.0119429, -0.187626 ) 190 | bones/36/enabled = true 191 | bones/36/bound_children = [ ] 192 | bones/37/name = "L_32.001" 193 | bones/37/parent = 36 194 | bones/37/rest = Transform( 0.9453, 0.0751013, 0.317439, 0.0461986, 0.932504, -0.358191, -0.322914, 0.353263, 0.878027, 2.98023e-07, 4.76837e-07, -0.0455583 ) 195 | bones/37/enabled = true 196 | bones/37/bound_children = [ ] 197 | bones/38/name = "L_32.001_end" 198 | bones/38/parent = 37 199 | bones/38/rest = Transform( 0.999986, -0.000269614, -0.00535556, -0.000280678, 0.994734, -0.102493, 0.00535502, 0.102493, 0.994719, -1.49012e-07, -2.38419e-07, -0.0536799 ) 200 | bones/38/enabled = true 201 | bones/38/bound_children = [ ] 202 | bones/39/name = "L_40.001" 203 | bones/39/parent = 27 204 | bones/39/rest = Transform( -0.939032, -0.245311, -0.240919, 0.160239, -0.932177, 0.324606, -0.304208, 0.266211, 0.914653, 0.0900128, -0.0214027, -0.183516 ) 205 | bones/39/enabled = true 206 | bones/39/bound_children = [ ] 207 | bones/40/name = "L_43.001" 208 | bones/40/parent = 39 209 | bones/40/rest = Transform( 0.994953, -0.0306129, 0.0955643, 0.0404439, 0.993891, -0.102695, -0.0918368, 0.106042, 0.990112, -1.78814e-07, 4.76837e-07, -0.0382582 ) 210 | bones/40/enabled = true 211 | bones/40/bound_children = [ ] 212 | bones/41/name = "L_43.001_end" 213 | bones/41/parent = 40 214 | bones/41/rest = Transform( 0.999979, 0.000394732, -0.00642987, -0.000552479, 0.999698, -0.0245595, 0.00641828, 0.0245626, 0.999678, -2.98023e-08, 1.19209e-07, -0.0382974 ) 215 | bones/41/enabled = true 216 | bones/41/bound_children = [ ] 217 | bones/42/name = "L_thigh" 218 | bones/42/parent = 0 219 | bones/42/rest = Transform( 0.00430408, -0.997893, -0.0647155, -0.993225, 0.00325025, -0.11616, 0.116125, 0.064777, -0.99112, 0.191584, -0.0999925, -0.158152 ) 220 | bones/42/enabled = true 221 | bones/42/bound_children = [ ] 222 | bones/43/name = "L_leg" 223 | bones/43/parent = 42 224 | bones/43/rest = Transform( 0.925577, -0.0108849, -0.378402, -0.00290825, 0.999353, -0.0358604, 0.378548, 0.0342921, 0.924947, -2.98023e-08, -1.49012e-07, -0.750492 ) 225 | bones/43/enabled = true 226 | bones/43/bound_children = [ ] 227 | bones/44/name = "L_foot" 228 | bones/44/parent = 43 229 | bones/44/rest = Transform( -0.325346, -0.129336, 0.936708, 0.945378, -0.0232361, 0.325149, -0.020288, 0.991329, 0.129831, 2.98023e-08, 1.19209e-07, -0.883846 ) 230 | bones/44/enabled = true 231 | bones/44/bound_children = [ ] 232 | bones/45/name = "L_toe" 233 | bones/45/parent = 44 234 | bones/45/rest = Transform( 0.990278, -0.134574, -0.035192, 0.111829, 0.920687, -0.373938, 0.0827232, 0.366367, 0.926786, -2.98023e-08, -3.72529e-08, -0.295576 ) 235 | bones/45/enabled = true 236 | bones/45/bound_children = [ ] 237 | bones/46/name = "R_thigh" 238 | bones/46/parent = 0 239 | bones/46/rest = Transform( 0.00425147, 0.99789, 0.0646546, 0.993209, 0.00331102, -0.116273, -0.116243, 0.0647098, -0.99111, -0.191584, -0.0999926, -0.158152 ) 240 | bones/46/enabled = true 241 | bones/46/bound_children = [ ] 242 | bones/47/name = "R_leg" 243 | bones/47/parent = 46 244 | bones/47/rest = Transform( -0.925526, 0.0142203, 0.378417, -0.029996, -0.998908, -0.0358265, 0.377494, -0.0445093, 0.924942, 1.49012e-08, -5.96046e-08, -0.750493 ) 245 | bones/47/enabled = true 246 | bones/47/bound_children = [ ] 247 | bones/48/name = "R_foot" 248 | bones/48/parent = 47 249 | bones/48/rest = Transform( 0.35113, -0.12924, 0.927365, 0.936084, 0.0258863, -0.350824, 0.0213343, 0.991275, 0.130069, -4.47035e-08, -2.98023e-08, -0.883846 ) 250 | bones/48/enabled = true 251 | bones/48/bound_children = [ ] 252 | bones/49/name = "R_toe" 253 | bones/49/parent = 48 254 | bones/49/rest = Transform( 0.990137, 0.135589, 0.0352719, -0.112725, 0.920501, -0.374127, -0.0831954, 0.366461, 0.926706, -8.9407e-08, -1.49012e-08, -0.295451 ) 255 | bones/49/enabled = true 256 | bones/49/bound_children = [ ] 257 | script = ExtResource( 1 ) 258 | R_Hand_IK = NodePath("RHand") 259 | L_Hand_IK = NodePath("LHand") 260 | L_Hand_Magnet = NodePath("LHand_Magnet") 261 | R_Hand_Magnet = NodePath("RHand_Magnet") 262 | 263 | [node name="L_bicep" type="BoneAttachment" parent="."] 264 | transform = Transform( 0.0701033, 0.717047, -0.693491, 0.0553826, 0.691332, 0.720413, 0.996001, -0.0889107, 0.00875278, 0.265552, 2.71778, -0.0513586 ) 265 | bone_name = "L_bicep" 266 | 267 | [node name="L_forearm" type="BoneAttachment" parent="."] 268 | transform = Transform( -0.156775, 0.756604, -0.634801, 0.302993, 0.648601, 0.698222, 0.940009, -0.0828768, -0.33093, 0.626303, 2.34303, -0.0559117 ) 269 | bone_name = "L_forearn" 270 | 271 | [node name="L_Hand" type="BoneAttachment" parent="."] 272 | transform = Transform( -0.202765, 0.871946, -0.445643, 0.248591, 0.486023, 0.837846, 0.947147, 0.0591028, -0.315307, 0.989181, 1.9439, 0.133262 ) 273 | bone_name = "L_hand" 274 | 275 | [node name="R_bicep" type="BoneAttachment" parent="."] 276 | transform = Transform( -0.0630907, 0.717693, 0.693494, 0.048623, -0.691844, 0.720408, 0.996823, 0.0791712, 0.00875266, -0.265554, 2.71778, -0.0513586 ) 277 | bone_name = "R_bicep" 278 | 279 | [node name="R_forearm" type="BoneAttachment" parent="."] 280 | transform = Transform( -0.156765, -0.756609, 0.634795, -0.302998, 0.648592, 0.698227, -0.940009, -0.0828847, -0.330929, -0.626304, 2.34303, -0.0559118 ) 281 | bone_name = "R_forearn" 282 | 283 | [node name="R_Hand" type="BoneAttachment" parent="."] 284 | transform = Transform( -0.202765, -0.871945, 0.445643, -0.248591, 0.486023, 0.837845, -0.947149, 0.0591028, -0.315306, -0.98918, 1.9439, 0.133261 ) 285 | bone_name = "R_hand" 286 | 287 | [node name="BoneAttachment4" type="BoneAttachment" parent="."] 288 | 289 | [node name="LHand_Magnet" type="Position3D" parent="."] 290 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.549075, 2.20321, -0.451942 ) 291 | 292 | [node name="RHand_Magnet" type="Position3D" parent="."] 293 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -3.94636, 1.36667, 0.133073 ) 294 | 295 | [node name="LHand" type="SkeletonIK" parent="."] 296 | process_priority = 1 297 | root_bone = "L_bicep" 298 | tip_bone = "L_hand" 299 | max_iterations = 30 300 | 301 | [node name="RHand" type="SkeletonIK" parent="."] 302 | process_priority = 1 303 | root_bone = "R_bicep" 304 | tip_bone = "R_hand" 305 | max_iterations = 30 306 | -------------------------------------------------------------------------------- /core/Animation/PrimarySkeleton.gd: -------------------------------------------------------------------------------- 1 | extends Skeleton 2 | 3 | 4 | func _ready(): 5 | for child in get_children(): 6 | if child is Changer: 7 | child.rise_handlers() 8 | -------------------------------------------------------------------------------- /core/Animation/test.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://assets/wep_models/ZeuzClass/zeuss_class_fusion_pistol.tscn" type="PackedScene" id=1] 4 | 5 | [node name="RHand_Pos" type="Position3D"] 6 | transform = Transform( -0.0968052, -0.975619, -0.196968, -0.994886, 0.100582, -0.00923918, 0.0288254, 0.195066, -0.980366, -0.0851523, 0.355555, -0.340549 ) 7 | 8 | [node name="Model" parent="." instance=ExtResource( 1 )] 9 | transform = Transform( -0.0222655, -0.228827, 0.00662993, -0.224395, 0.0231342, 0.0448659, -0.0453033, -0.00212504, -0.225487, 0.355309, -0.052409, -0.34735 ) 10 | 11 | [node name="aperture" type="Position3D" parent="Model"] 12 | transform = Transform( -4.34777, 3.30092e-08, 3.52098e-07, -1.48541e-08, 4.34777, 1.20294e-15, -2.11259e-07, -8.80244e-09, -4.34777, -1.19209e-07, 2.46053, 1.63845 ) 13 | -------------------------------------------------------------------------------- /core/AutoIK/AutoIK.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends SkeletonIK 3 | class_name AutoIK 4 | export(NodePath) var Magnet 5 | func _enter_tree(): 6 | start() 7 | 8 | 9 | 10 | func _process(delta): 11 | if get_node_or_null(Magnet) != null: 12 | magnet = get_node(Magnet).translation 13 | -------------------------------------------------------------------------------- /core/AutoIK/BoneHandler.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Position3D 3 | class_name BoneHandler 4 | 5 | var bone_idx 6 | var bone_attachment : BoneAttachment 7 | var skeleton : Skeleton 8 | 9 | func _ready(): 10 | bone_attachment = get_parent() 11 | skeleton = bone_attachment.get_parent() 12 | if get_parent() is BoneAttachment: 13 | for idx in range(0, skeleton.get_bone_count()): 14 | if get_parent().bone_name == get_parent().get_parent().get_bone_name(idx): 15 | bone_idx = idx 16 | 17 | 18 | func _physics_process(delta): 19 | if skeleton != null: 20 | skeleton.set_bone_custom_pose(bone_idx, transform) 21 | -------------------------------------------------------------------------------- /core/AutoIK/Changer.gd: -------------------------------------------------------------------------------- 1 | extends BoneAttachment 2 | class_name Changer 3 | var ready = false 4 | 5 | 6 | # Called when the node enters the scene tree for the first time. 7 | func rise_handlers(): 8 | for child in get_children(): 9 | remove_child(child) 10 | get_parent().add_child(child) 11 | print(child.get_parent()) 12 | 13 | 14 | -------------------------------------------------------------------------------- /core/AutoIK/HandlerCopy.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Position3D 3 | class_name BoneHandler 4 | 5 | """ 6 | This class overrides the current pose of a bone with the one set by the target, 7 | this class along a secondary skeleton can help avoid visual glitches introduced 8 | in godot 3.2 and also allows for extended functionality. 9 | """ 10 | 11 | export(NodePath) var target 12 | export(NodePath) var pose_match_node : NodePath 13 | export(bool) var use_pose_match : bool = false 14 | var bone_idx 15 | onready var bone_attachment : BoneAttachment = get_parent() 16 | var pose_match : Spatial 17 | var skeleton : Skeleton 18 | var last_transform : Transform = Transform() 19 | func _ready(): 20 | pose_match = get_node(pose_match_node) 21 | target = get_node(target) 22 | bone_attachment = get_parent() 23 | skeleton = bone_attachment.get_parent() 24 | if get_parent() is BoneAttachment: 25 | for idx in range(0, skeleton.get_bone_count()): 26 | if get_parent().bone_name == get_parent().get_parent().get_bone_name(idx): 27 | bone_idx = idx 28 | 29 | func lerp_transform(from : Transform, to : Transform, amount) -> Transform: 30 | return Transform(lerp(from.basis.x, to.basis.x, amount), 31 | lerp(from.basis.y, to.basis.y, amount), 32 | lerp(from.basis.z, to.basis.z, amount), 33 | lerp(from.origin, to.origin, amount)) 34 | 35 | func _physics_process(delta): 36 | if target is Spatial: 37 | if target.global_transform == Transform.IDENTITY: 38 | global_transform = last_transform 39 | else: 40 | global_transform = target.global_transform 41 | last_transform = global_transform 42 | if skeleton != null: 43 | 44 | if target.get_parent() is Skeleton: 45 | if use_pose_match and pose_match != null: 46 | print(pose_match) 47 | 48 | skeleton.set_bone_global_pose_override(bone_idx, lerp_transform( target.get_parent().get_bone_global_pose(bone_idx),pose_match.transform, delta), 1, true) 49 | 50 | else: 51 | skeleton.set_bone_global_pose_override(bone_idx, target.get_parent().get_bone_global_pose(bone_idx), 1, true)#, delta) 52 | 53 | -------------------------------------------------------------------------------- /core/Object Info/Decoder.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | class_name Decoder 3 | """ 4 | Takes nodes and returns structured static information, useful to use as 5 | networked packages. 6 | """ 7 | 8 | enum OBJECT_TYPE { 9 | NULL = -1, 10 | CHARACTER = 0, 11 | BULLET = 1, 12 | MISC = 2 13 | } 14 | var projectile_structure_template : Dictionary = { 15 | "owner_id" : 0, 16 | "team" : 0, 17 | "type" : OBJECT_TYPE.BULLET, 18 | "position" : Vector3(), 19 | "rotation" : Vector3(), 20 | "damage" : 1 21 | } 22 | static func get_object_info(object : Node): 23 | pass 24 | -------------------------------------------------------------------------------- /core/Player_prefab/Player.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | onready var Cam = $Camera.translation 3 | var Player = Transform() 4 | onready var Player_Node = $Player 5 | onready var Camera_Node = $Camera 6 | onready var target = $"Player/Model/animatedglb/Character/Riggus Universalis/Skeleton/BoneAttachment/Aim_Target" 7 | 8 | 9 | 10 | func _process(delta): 11 | 12 | target.global_transform.origin = lerp(target.global_transform.origin, 13 | Camera_Node.project_position(get_tree().root.get_visible_rect().size/2, 1) 14 | , delta*5) 15 | 16 | 17 | Player.origin = $"Player/Model/animatedglb/Character/Riggus Universalis/Skeleton/Head/Camera".global_transform.origin 18 | Player.basis = $"Player/Model/animatedglb/Character/Riggus Universalis/Skeleton/Head/Camera".global_transform.basis 19 | 20 | Camera_Node.global_transform.origin = (lerp(Player.origin, Camera_Node.get_global_transform().origin, delta)) 21 | $Player/weapons.global_transform = Transform(Camera_Node.global_transform.basis, Camera_Node.global_transform.origin) 22 | # $Camera.global_transform.basis.x = (lerp($Camera.get_global_transform().basis.x, Player.basis.x, 0.5)) 23 | # $Camera.global_transform.basis.y = (lerp($Camera.get_global_transform().basis.y, Player.basis.y, 0.5)) 24 | # $Camera.global_transform.basis.z = (lerp($Camera.get_global_transform().basis.z, Player.basis.z, 0.5)) 25 | 26 | func _physics_process(delta): 27 | Player_Node.turn_transform(Camera_Node.rotation_degrees) 28 | Player_Node.camera_dir = -Camera_Node.transform.basis.z 29 | 30 | -------------------------------------------------------------------------------- /core/Player_prefab/Player.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=2] 2 | 3 | [ext_resource path="res://assets/Characters/Models/M2 Officer/animated.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://Joyeuse/core/Player_prefab/Player.gd" type="Script" id=2] 5 | [ext_resource path="res://weapons/fusion_pistol.tscn" type="PackedScene" id=3] 6 | [ext_resource path="res://Joyeuse/pl3d/FPSCamera.gd" type="Script" id=4] 7 | [ext_resource path="res://Joyeuse/core/actors/Player.gd" type="Script" id=5] 8 | 9 | [sub_resource type="CapsuleShape" id=1] 10 | radius = 0.694511 11 | height = 2.06866 12 | 13 | [sub_resource type="GDScript" id=2] 14 | script/source = "extends RayCast 15 | 16 | export(NodePath) var exclude : String = \"\" 17 | onready var node_exclude = get_node(exclude) 18 | 19 | func _ready(): 20 | add_exception(node_exclude) 21 | " 22 | 23 | [sub_resource type="GDScript" id=3] 24 | script/source = "extends RayCast 25 | 26 | export(NodePath) var exclude : String = \"\" 27 | onready var node_exclude = get_node(exclude) 28 | 29 | func _ready(): 30 | add_exception(node_exclude) 31 | " 32 | 33 | [node name="Player" type="Spatial"] 34 | script = ExtResource( 2 ) 35 | 36 | [node name="Player" type="KinematicBody" parent="."] 37 | script = ExtResource( 5 ) 38 | max_speed = 14.0 39 | accel = 10.0 40 | deaccel = 9.0 41 | speedfactor = 1.0 42 | 43 | [node name="CollisionShape" type="CollisionShape" parent="Player"] 44 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 1.70857, 0 ) 45 | shape = SubResource( 1 ) 46 | 47 | [node name="Model" type="Position3D" parent="Player"] 48 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.09797, 0 ) 49 | 50 | [node name="animatedglb" parent="Player/Model" instance=ExtResource( 1 )] 51 | transform = Transform( -4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, -1.10455, 0 ) 52 | 53 | [node name="Arm_IK_L" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton" index="17"] 54 | magnet = Vector3( 1.072, -0.7145, 0.4949 ) 55 | 56 | [node name="Arm_IK_R" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton" index="18"] 57 | magnet = Vector3( -1.08787, -0.917614, 0.496171 ) 58 | 59 | [node name="BoneAttachment" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton" index="19"] 60 | transform = Transform( 0.999975, 0.00434626, -0.00515679, -0.00401404, 0.998022, 0.0627332, 0.00541991, -0.0627115, 0.998016, -0.00362554, 1.50189, 0.111137 ) 61 | 62 | [node name="L_hand" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton" index="20"] 63 | transform = Transform( -0.171693, 0.230204, -0.957876, -0.984321, -0.000224453, 0.176379, 0.0403883, 0.97314, 0.226633, 0.717302, 1.86407, 0.997763 ) 64 | 65 | [node name="R_hand" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton" index="21"] 66 | transform = Transform( -0.318973, -0.401576, 0.858471, 0.919795, 0.0872567, 0.382576, -0.228544, 0.911662, 0.34154, -0.665023, 1.8466, 1.04375 ) 67 | 68 | [node name="Position3D" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton/R_hand/Weapons" index="0"] 69 | transform = Transform( -0.0552248, 0.59502, -0.801861, -0.996985, -0.0762917, 0.0120584, -0.0539949, 0.800109, 0.597473, 1.24843, 0.228105, -0.556549 ) 70 | 71 | [node name="LightArm" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton" index="22"] 72 | transform = Transform( -0.974006, 0.00715169, -0.226401, -0.226184, 0.0232304, 0.973807, 0.0122226, 0.999703, -0.0210097, 0.232817, 2.16483, -0.161519 ) 73 | 74 | [node name="Head" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton" index="23"] 75 | transform = Transform( 0.999956, 0.000840086, 0.00932748, -0.000908935, 0.999972, 0.0073796, -0.00932102, -0.00738775, 0.999929, -0.000240401, 2.18796, 0.163155 ) 76 | 77 | [node name="R_Hand_Pos" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton/Head" index="1"] 78 | transform = Transform( -0.317668, -0.410141, 0.854911, 0.921194, 0.0801687, 0.380758, -0.224702, 0.908493, 0.352352, -0.705423, -0.348313, 0.952479 ) 79 | 80 | [node name="IKMagnet" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton/Head" index="2"] 81 | transform = Transform( 0.970892, -0.00147721, -0.239521, 0.0499409, 0.979252, 0.196396, 0.234262, -0.20264, 0.950821, 1.072, -0.7145, 0.4949 ) 82 | 83 | [node name="IKMagnet2" parent="Player/Model/animatedglb/Character/Riggus Universalis/Skeleton/Head" index="3"] 84 | transform = Transform( 0.970892, -0.00147722, -0.239521, 0.049941, 0.979254, 0.196395, 0.234261, -0.20264, 0.950822, -1.08787, -0.917614, 0.496171 ) 85 | 86 | [node name="Floor_target_L" parent="Player/Model/animatedglb/Character/Foot_Height_L" index="0"] 87 | transform = Transform( 0.999598, -0.0283578, 0, 0.0283578, 0.999598, 0, 0, 0, 1, 0.393544, 0.16871, -0.0393329 ) 88 | 89 | [node name="Left" parent="Player/Model/animatedglb/Character/Foot_Height_L/Floor_target_L" index="1"] 90 | script = SubResource( 2 ) 91 | exclude = NodePath("../../../../../..") 92 | 93 | [node name="Floor_target_R" parent="Player/Model/animatedglb/Character/Foot_Height_R" index="0"] 94 | transform = Transform( 0.999598, -0.0283578, 0, 0.0283578, 0.999598, 0, 0, 0, 1, -0.436975, 0.170461, 0.17387 ) 95 | 96 | [node name="Right" parent="Player/Model/animatedglb/Character/Foot_Height_R/Floor_target_R" index="1"] 97 | script = SubResource( 3 ) 98 | exclude = NodePath("../../../../../..") 99 | 100 | [node name="AnimationTree" parent="Player/Model/animatedglb" index="2"] 101 | parameters/Shotgun/Single/blend_amount = 0 102 | 103 | [node name="CamPos" type="Position3D" parent="Player"] 104 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.85774, 0 ) 105 | 106 | [node name="weapons" type="Position3D" parent="Player"] 107 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.85774, 0 ) 108 | 109 | [node name="fusion_pistol" parent="Player/weapons" instance=ExtResource( 3 )] 110 | 111 | [node name="Objective" type="Position3D" parent="Player/weapons"] 112 | transform = Transform( -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0, -7.42106 ) 113 | 114 | [node name="Camera" type="Camera" parent="."] 115 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.84616, 0 ) 116 | cull_mask = 1048571 117 | current = true 118 | fov = 90.0 119 | near = 0.1 120 | script = ExtResource( 4 ) 121 | view_sensitivity = 1.0 122 | 123 | [editable path="Player/Model/animatedglb"] 124 | 125 | [editable path="Player/weapons/fusion_pistol"] 126 | -------------------------------------------------------------------------------- /core/Systems/Inventory/Inventory.gd: -------------------------------------------------------------------------------- 1 | class_name Inventory 2 | var weapons : Dictionary = {} 3 | var ammo : Dictionary = {} 4 | var misc : Dictionary = {} 5 | var weilder_ref : Spatial 6 | 7 | 8 | func add_ammo(id : int, amount : int): #Ammo works by cartidges, ammo has their own id's 9 | if ammo.has(id): 10 | ammo[id] += amount 11 | else: 12 | ammo[id] = amount 13 | 14 | func reload_weapon(id : int, secondary : bool = false): #reloads the weapon with "id" 15 | var ammo_id : int = 0 16 | if weapons.has(id): 17 | var weapon : JOYWeapon = weapons[id].node_ref 18 | ammo_id = weapons[id]["primary_ammo_id"] 19 | if secondary: 20 | ammo_id = weapons[id]["secondary_ammo_id"] 21 | if ammo[ammo_id] > 0: 22 | ammo[ammo_id] -= 1 23 | if secondary: 24 | weapon.restore_uses(weapon.secondary_magazine_size) 25 | else: 26 | weapon.restore_uses(weapon.primary_magazine_size) 27 | 28 | func use_item(id, uses) -> bool: #Returns the success of the action. 29 | if misc.has(id): 30 | misc[id].node_ref.primary_use(uses) 31 | return true 32 | return false 33 | 34 | func _register_weapon(node : JOYWeapon): 35 | print("registering a gun! ") 36 | if weapons.has(node.id): 37 | if weapons[node.id].amount < 2 and weapons[node.id].dual_weildable == true: 38 | weapons[node.id].amount = 2 39 | return 40 | else: 41 | add_ammo(node.id, node.primary_uses/node.primary_magazine_size) 42 | node.remove_uses(node.primary_uses, false) #Removes the primary ammo from the gun 43 | add_ammo(node.id, node.secondary_uses/node.secondary_magazine_size) #adds the ammo from the gun 44 | node.remove_uses(node.secondary_uses, true) #Removes the secondary ammo from the gun 45 | node.primary_initial_ammo = 0 46 | node.secondary_initial_ammo = 0 47 | return 48 | else: 49 | node.setup(weilder_ref) 50 | var new_weapon : Dictionary 51 | new_weapon["id"] = node.id 52 | new_weapon["amount"] = 1 53 | new_weapon["node_ref"] = node 54 | new_weapon["primary_ammo_id"] = node.primary_ammo_id 55 | new_weapon["secondary_ammo_id"] = node.secondary_ammo_id 56 | weapons[node.id] = new_weapon 57 | add_ammo(node.primary_ammo_id, node.primary_initial_ammo) 58 | add_ammo(node.secondary_ammo_id, node.secondary_initial_ammo) 59 | 60 | 61 | func _register_misc(node : JOYObject) -> void: 62 | print("Registering something I don't quite know!'") 63 | if misc.has(node.id): 64 | misc[node.id].amount += 1 65 | else: 66 | var new_object : Dictionary 67 | new_object["id"] = node.id 68 | new_object["amount"] = 1 69 | new_object["node_ref"] = node 70 | 71 | func register_object(node : JOYObject) -> void: 72 | if node is JOYWeapon: 73 | _register_weapon(node) 74 | 75 | elif node is JOYObject: 76 | _register_misc(node) 77 | elif node is JOYAmmo: 78 | add_ammo(node.id, node.amout) 79 | else: 80 | print("object is none! ", node) 81 | -------------------------------------------------------------------------------- /core/Systems/Inventory/Objects/JOYAmmo.gd: -------------------------------------------------------------------------------- 1 | extends JOYObject 2 | class_name JOYAmmo 3 | #ID should be the same id as the projectile that's linked to it 4 | 5 | var amount : int = 0 6 | 7 | func _ready(): 8 | pass # Replace with function body. 9 | -------------------------------------------------------------------------------- /core/Systems/Inventory/Objects/JOYObject.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | class_name JOYObject 3 | 4 | signal empty #emmited when emptied and not broken 5 | signal broken #emmited when breaks 6 | 7 | var id : int = 0 # unique object id, 0 for default 8 | 9 | var primary_uses : int = 1 10 | var secondary_uses : int = 1 11 | var remain_use_percent : float = 100 12 | 13 | 14 | # the folloiwing variables handle basic naming and flavor. 15 | var identity : String = "default weapon" 16 | var description : String = "Default description, none has provided yet." 17 | 18 | var breaks : bool = false 19 | 20 | func set_usage(breaks : bool, uses = 1, remain_use_percent : float = 100): 21 | self.breaks = breaks 22 | self.uses = uses 23 | self.remain_use_percent = remain_use_percent 24 | 25 | func restore_uses(_uses : int = 1, secondary : bool = false) -> void: 26 | if secondary: 27 | secondary_uses += _uses 28 | else: 29 | primary_uses += _uses 30 | 31 | func remove_uses(_uses : int = 0, secondary : bool = false) -> void: 32 | if secondary: 33 | secondary_uses -= _uses 34 | else: 35 | primary_uses -= _uses 36 | 37 | func restore_use_percent(percent : float = 1): 38 | remain_use_percent += percent 39 | 40 | func secondary_use(_decrease : int = 1) -> void: 41 | pass 42 | 43 | func secondary_release() -> void: 44 | pass 45 | func primary_use(_times : int = 1) -> void: 46 | pass 47 | 48 | func primary_release() -> void: 49 | pass 50 | 51 | -------------------------------------------------------------------------------- /core/Systems/Navigation/Navigation_Waypoint.gd: -------------------------------------------------------------------------------- 1 | extends Position3D 2 | class_name NavigationWaypoint 3 | 4 | func _ready(): 5 | pass # Replace with function body. 6 | 7 | -------------------------------------------------------------------------------- /core/Systems/Navigation/Navmesh_Path.gd: -------------------------------------------------------------------------------- 1 | extends Path 2 | class_name Navigation_Path 3 | 4 | func _ready(): 5 | pass 6 | -------------------------------------------------------------------------------- /core/Systems/Navigation/Sound_Smell_system.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | class_name SoundSmellManager, "../../icons/SH_SYSTEM.png" 3 | 4 | var active_ai_actors : Array = [] 5 | signal smell_emitted(where, intensity, soundfile) 6 | signal sound_emitted(where, intensity) 7 | 8 | 9 | func _ready(): 10 | connect("sound_emitted",self,"_on_sound_emitted") 11 | connect("smell_emitted",self,"_on_smell_emitted") 12 | 13 | func _is_valid_character(node:Node): 14 | var output = false 15 | if not (node.has_user_signal("heard_something") and node._get("hearing_capability")!=null): 16 | return true 17 | if not (node.has_user_signal("smell_smothing") and node._get("smelling_capability")!=null): 18 | return true 19 | 20 | func _register_ai_actor(node): 21 | if _is_valid_character(node): 22 | active_ai_actors.append(node) 23 | active_ai_actors.sort() 24 | else: 25 | print("Error registering Actor, please verify") 26 | 27 | func _unregister_ai_actor(node): 28 | var key = active_ai_actors.find(node) 29 | if key != -1: 30 | active_ai_actors.remove(key) 31 | 32 | func get_aprox_pos(position, intensity, property, signal_name): 33 | var final_intensity 34 | var pos_aprox 35 | var distance 36 | for AI_Actor in active_ai_actors: 37 | distance = (AI_Actor.translation-position).length() 38 | if distance >= 0.2: 39 | final_intensity = intensity / pow(distance,2) 40 | else: 41 | final_intensity = intensity 42 | if final_intensity >= 0.8: 43 | pos_aprox = ( 44 | position + 45 | (RAD.randv(Vector3(0.5,0.5,0.5)*distance) 46 | /(final_intensity+0.1*AI_Actor.get(property)))) 47 | AI_Actor.emit_signal(signal_name, pos_aprox) 48 | 49 | 50 | func _on_sound_emitted(position, intensity, soundfile = null): 51 | get_aprox_pos(position, intensity, "hearing_capability", "heard_something") 52 | if soundfile != null: 53 | var Sound = AudioStreamPlayer3D.new() 54 | Sound.stream = load(soundfile) 55 | Sound.translation = position 56 | add_child(Sound) 57 | Sound.play() 58 | yield(Sound, "finished") 59 | Sound.queue_free() 60 | 61 | func _on_smell_emitted(position, intensity): 62 | get_aprox_pos(position, intensity, "smelling_capability", "smell_something") 63 | -------------------------------------------------------------------------------- /core/Systems/Navigation/WorldNavigation.gd: -------------------------------------------------------------------------------- 1 | extends Navigation 2 | class_name World_Navigator, "../../../icons/icon.png" 3 | 4 | var astar : AStar = AStar.new() 5 | 6 | ####################### TEMP ############################### 7 | var camrot= 0.0 8 | var camrot2 = 0.0 9 | var m = SpatialMaterial.new() 10 | 11 | func calculate_nav_mesh(): 12 | var vertices = PoolVector3Array() 13 | for node in get_children(): 14 | if node is Position3D: 15 | vertices.push_back(node.translation) 16 | if node is Navigation_Path: 17 | for point in range(0, node.get_curve().get_point_count()): 18 | vertices.push_back(node.get_curve().get_point_position(point)) 19 | vertices[0]=(node.get_curve().get_point_position(0)) 20 | vertices.push_back(node.get_curve().get_point_position(0)) 21 | #vertices = node.get_curve().get_baked_points() 22 | var mesh = ArrayMesh.new() 23 | var arrays = [] 24 | if vertices.size() >= 0: 25 | print("Enter mesh generation") 26 | arrays.resize(vertices.size()) 27 | arrays[ArrayMesh.ARRAY_VERTEX] = vertices 28 | mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_FAN, arrays) 29 | mesh.generate_triangle_mesh() 30 | var NavMesh = NavigationMesh.new() 31 | var MeshVis = MeshInstance.new() 32 | MeshVis.mesh = mesh 33 | NavMesh.create_from_mesh(mesh) 34 | NavMesh.set_vertices(vertices) 35 | var NavMeshInstance = NavigationMeshInstance.new() 36 | NavMeshInstance.navmesh = NavMesh 37 | add_child(NavMeshInstance) 38 | add_child(MeshVis) 39 | print(NavMeshInstance.navmesh) 40 | print(MeshVis.mesh) 41 | 42 | 43 | func _ready(): 44 | if name != "World": 45 | name = "World" 46 | if not has_node("AI_SH_SYSTEM"): 47 | var newnode = Spatial.new() 48 | newnode.name = "AI_SH_SYSTEM" 49 | add_child(newnode) 50 | 51 | 52 | #calculate_astar() 53 | #set_process_input(true) 54 | 55 | m.flags_unshaded = true 56 | m.flags_use_point_size = true 57 | m.albedo_color = Color(1.0, 1.0, 1.0, 1.0) 58 | #calculate_nav_mesh() 59 | 60 | #func _input(event): 61 | ## if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed: 62 | # if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed: 63 | # var from = get_node("cambase/Camera").project_ray_origin(event.position) 64 | # var to = from + get_node("cambase/Camera").project_ray_normal(event.position)*100 65 | # var p = get_closest_point_to_segment(from, to) 66 | # 67 | # var PATH = get_node("SoundSmellManager/AI_Character").update_path(p) 68 | # get_node("SoundSmellManager/AI_Character").has_destination = true 69 | 70 | 71 | # var im = get_node("draw") 72 | # im.set_material_override(m) 73 | # im.clear() 74 | # im.begin(Mesh.PRIMITIVE_POINTS, null) 75 | # im.add_vertex(PATH[0]) 76 | # im.add_vertex(p) 77 | # im.end() 78 | # im.begin(Mesh.PRIMITIVE_LINE_STRIP, null) 79 | # for x in PATH: 80 | # im.add_vertex(x) 81 | # im.end() 82 | # pass 83 | # if event is InputEventMouseMotion: 84 | # if event.button_mask&(BUTTON_MASK_MIDDLE+BUTTON_MASK_RIGHT): 85 | # camrot += event.relative.x * 0.005 86 | # camrot2 += event.relative.y * 0.005 87 | # get_node("cambase").set_rotation(Vector3(camrot2, camrot, 0)) 88 | # print("camrot ", camrot) 89 | # 90 | 91 | func find_shortest_path(from: Vector3, to : Vector3): 92 | var absoulut = get_absolute_path(from, to) 93 | var navmesh = get_navmesh_path(from, to) 94 | if min(absoulut.size(), navmesh.size()) == absoulut.size(): 95 | return absoulut 96 | else: 97 | if navmesh.size()>1: 98 | return navmesh 99 | else: 100 | return absoulut 101 | 102 | 103 | func get_navmesh_path(from: Vector3, to: Vector3): 104 | var path_points = get_simple_path(from, to, true) 105 | return path_points 106 | 107 | 108 | func get_astar_path(from: Vector3, to: Vector3): 109 | var path_points = astar.get_point_path(astar.get_closest_point(from), astar.get_closest_point(to)) 110 | return path_points 111 | 112 | 113 | func get_absolute_path(from:Vector3, to:Vector3): 114 | #First we calculate the Astar path 115 | var astar_path : Array = get_astar_path(from, to) 116 | if astar_path.size() < 1: 117 | astar_path = get_navmesh_path(from, to) 118 | print("First Astar point is" + str(astar_path[0])) 119 | print("Last Astar point is" + str(astar_path[astar_path.size()-1])) 120 | print("origin is" + str(from)) 121 | print("destination is" + str(to)) 122 | var first_point = astar_path[0] 123 | #We get the first point of the path 124 | (astar_path.invert()) 125 | var last_point = astar_path[0] #The astar path is backwards 126 | 127 | #astar_path.invert() 128 | #We get the last point of the path 129 | 130 | if (from - first_point).length() > 0: 131 | #If the first point is too far from the kinematic, calculates a Navmesh Path 132 | var Initial_path : Array = get_navmesh_path(from, first_point) 133 | Initial_path.invert() 134 | #Then we add the points to the front of the array 135 | for points in Initial_path: 136 | astar_path.push_back(points) 137 | 138 | astar_path.invert() #The astarpath is forwards 139 | 140 | if (to - last_point).length() > 0: 141 | #If the path is away from the destination, make a Navmesh path to the destination 142 | var Final_path : Array = get_navmesh_path(last_point, to) 143 | #Add the points at the end of the array 144 | for point in Final_path: 145 | astar_path.append(point) 146 | 147 | #Finally, we return the full path to the given position. 148 | return astar_path 149 | 150 | func calculate_astar(): 151 | var AstarPath = $Path.get_curve().get_baked_points() 152 | for x in AstarPath.size(): #Get all points in the Curve 3D 153 | var Point = AstarPath[x] #Get their positions 154 | astar.add_point(x, Point) #Add them to the A* calculation 155 | if x != 0: 156 | astar.connect_points(x,x-1) #If they are not out of index, connect them 157 | astar.connect_points(0,astar.get_points()[-1]) 158 | -------------------------------------------------------------------------------- /core/Systems/Navigation/WorldNavigation.gd~Moved WorldNavigation to Systems: -------------------------------------------------------------------------------- 1 | extends Navigation 2 | class_name World_Navigator, "../../icons/icon.png" 3 | 4 | var astar : AStar = AStar.new() 5 | 6 | ####################### TEMP ############################### 7 | var camrot= 0.0 8 | var camrot2 = 0.0 9 | var m = SpatialMaterial.new() 10 | 11 | func calculate_nav_mesh(): 12 | var vertices = PoolVector3Array() 13 | for node in get_children(): 14 | if node is Position3D: 15 | vertices.push_back(node.translation) 16 | if node is Navigation_Path: 17 | for point in range(0, node.get_curve().get_point_count()): 18 | vertices.push_back(node.get_curve().get_point_position(point)) 19 | vertices[0]=(node.get_curve().get_point_position(0)) 20 | vertices.push_back(node.get_curve().get_point_position(0)) 21 | #vertices = node.get_curve().get_baked_points() 22 | var mesh = ArrayMesh.new() 23 | var arrays = [] 24 | if vertices.size() >= 0: 25 | print("Enter mesh generation") 26 | arrays.resize(vertices.size()) 27 | arrays[ArrayMesh.ARRAY_VERTEX] = vertices 28 | mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_FAN, arrays) 29 | mesh.generate_triangle_mesh() 30 | var NavMesh = NavigationMesh.new() 31 | var MeshVis = MeshInstance.new() 32 | MeshVis.mesh = mesh 33 | NavMesh.create_from_mesh(mesh) 34 | NavMesh.set_vertices(vertices) 35 | var NavMeshInstance = NavigationMeshInstance.new() 36 | NavMeshInstance.navmesh = NavMesh 37 | add_child(NavMeshInstance) 38 | add_child(MeshVis) 39 | print(NavMeshInstance.navmesh) 40 | print(MeshVis.mesh) 41 | 42 | 43 | func _ready(): 44 | if not has_node("AI_SH_SYSTEM"): 45 | var newnode = Spatial.new() 46 | newnode.name = "AI_SH_SYSTEM" 47 | add_child(newnode) 48 | 49 | 50 | #calculate_astar() 51 | #set_process_input(true) 52 | 53 | m.flags_unshaded = true 54 | m.flags_use_point_size = true 55 | m.albedo_color = Color(1.0, 1.0, 1.0, 1.0) 56 | #calculate_nav_mesh() 57 | 58 | func _input(event): 59 | # if event extends InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed: 60 | # if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed: 61 | # var from = get_node("cambase/Camera").project_ray_origin(event.position) 62 | # var to = from + get_node("cambase/Camera").project_ray_normal(event.position)*100 63 | # var p = get_closest_point_to_segment(from, to) 64 | # 65 | # var PATH = get_node("Sound_Smell_Manager/KinematicBody").update_path(p) 66 | # get_node("Sound_Smell_Manager/KinematicBody").has_destination = true 67 | 68 | 69 | # var im = get_node("draw") 70 | # im.set_material_override(m) 71 | # im.clear() 72 | # im.begin(Mesh.PRIMITIVE_POINTS, null) 73 | # im.add_vertex(PATH[0]) 74 | # im.add_vertex(p) 75 | # im.end() 76 | # im.begin(Mesh.PRIMITIVE_LINE_STRIP, null) 77 | # for x in PATH: 78 | # im.add_vertex(x) 79 | # im.end() 80 | pass 81 | # if event is InputEventMouseMotion: 82 | # if event.button_mask&(BUTTON_MASK_MIDDLE+BUTTON_MASK_RIGHT): 83 | # camrot += event.relative.x * 0.005 84 | # camrot2 += event.relative.y * 0.005 85 | # get_node("cambase").set_rotation(Vector3(camrot2, camrot, 0)) 86 | # print("camrot ", camrot) 87 | 88 | 89 | func find_shortest_path(from: Vector3, to : Vector3): 90 | var absoulut = get_absolute_path(from, to) 91 | var navmesh = get_navmesh_path(from, to) 92 | if min(absoulut.size(), navmesh.size()) == absoulut.size(): 93 | return absoulut 94 | else: 95 | if navmesh.size()>1: 96 | return navmesh 97 | else: 98 | return absoulut 99 | 100 | 101 | func get_navmesh_path(from: Vector3, to: Vector3): 102 | var path_points = get_simple_path(from, to, true) 103 | return path_points 104 | 105 | 106 | func get_astar_path(from: Vector3, to: Vector3): 107 | var path_points = astar.get_point_path(astar.get_closest_point(from), astar.get_closest_point(to)) 108 | return path_points 109 | 110 | 111 | func get_absolute_path(from:Vector3, to:Vector3): 112 | #First we calculate the Astar path 113 | var astar_path : Array = get_astar_path(from, to) 114 | print("First Astar point is" + str(astar_path[0])) 115 | print("Last Astar point is" + str(astar_path[astar_path.size()-1])) 116 | print("origin is" + str(from)) 117 | print("destination is" + str(to)) 118 | var first_point = astar_path[0] 119 | #We get the first point of the path 120 | var last_point = (astar_path.invert()) #The astar path is backwards 121 | last_point = astar_path[0] 122 | #astar_path.invert() 123 | #We get the last point of the path 124 | 125 | if (from - first_point).length() > 0: 126 | #If the first point is too far from the kinematic, calculates a Navmesh Path 127 | var Initial_path : Array = get_navmesh_path(from, first_point) 128 | Initial_path.invert() 129 | #Then we add the points to the front of the array 130 | for points in Initial_path: 131 | astar_path.push_back(points) 132 | 133 | astar_path.invert() #The astarpath is forwards 134 | 135 | if (to - last_point).length() > 0: 136 | #If the path is away from the destination, make a Navmesh path to the destination 137 | var Final_path : Array = get_navmesh_path(last_point, to) 138 | #Add the points at the end of the array 139 | for point in Final_path: 140 | astar_path.append(point) 141 | 142 | #Finally, we return the full path to the given position. 143 | return astar_path 144 | 145 | func calculate_astar(): 146 | var AstarPath = $Path.get_curve().get_baked_points() 147 | for x in AstarPath.size(): #Get all points in the Curve 3D 148 | var Point = AstarPath[x] #Get their positions 149 | astar.add_point(x, Point) #Add them to the A* calculation 150 | if x != 0: 151 | astar.connect_points(x,x-1) #If they are not out of index, connect them 152 | astar.connect_points(0,astar.get_points()[-1]) 153 | -------------------------------------------------------------------------------- /core/Systems/Navigation/WorldNavigation.gd~master: -------------------------------------------------------------------------------- 1 | extends Navigation 2 | class_name World_Navigator, "../../icons/icon.png" 3 | 4 | var astar : AStar = AStar.new() 5 | 6 | ####################### TEMP ############################### 7 | var camrot= 0.0 8 | var camrot2 = 0.0 9 | var m = SpatialMaterial.new() 10 | 11 | func calculate_nav_mesh(): 12 | var vertices = PoolVector3Array() 13 | for node in get_children(): 14 | if node is Position3D: 15 | vertices.push_back(node.translation) 16 | if node is Navigation_Path: 17 | for point in range(0, node.get_curve().get_point_count()): 18 | vertices.push_back(node.get_curve().get_point_position(point)) 19 | vertices[0]=(node.get_curve().get_point_position(0)) 20 | vertices.push_back(node.get_curve().get_point_position(0)) 21 | #vertices = node.get_curve().get_baked_points() 22 | var mesh = ArrayMesh.new() 23 | var arrays = [] 24 | if vertices.size() >= 0: 25 | print("Enter mesh generation") 26 | arrays.resize(vertices.size()) 27 | arrays[ArrayMesh.ARRAY_VERTEX] = vertices 28 | mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_FAN, arrays) 29 | mesh.generate_triangle_mesh() 30 | var NavMesh = NavigationMesh.new() 31 | var MeshVis = MeshInstance.new() 32 | MeshVis.mesh = mesh 33 | NavMesh.create_from_mesh(mesh) 34 | NavMesh.set_vertices(vertices) 35 | var NavMeshInstance = NavigationMeshInstance.new() 36 | NavMeshInstance.navmesh = NavMesh 37 | add_child(NavMeshInstance) 38 | add_child(MeshVis) 39 | print(NavMeshInstance.navmesh) 40 | print(MeshVis.mesh) 41 | 42 | 43 | func _ready(): 44 | if not has_node("AI_SH_SYSTEM"): 45 | var newnode = Spatial.new() 46 | newnode.name = "AI_SH_SYSTEM" 47 | add_child(newnode) 48 | 49 | 50 | #calculate_astar() 51 | #set_process_input(true) 52 | 53 | m.flags_unshaded = true 54 | m.flags_use_point_size = true 55 | m.albedo_color = Color(1.0, 1.0, 1.0, 1.0) 56 | #calculate_nav_mesh() 57 | 58 | func _input(event): 59 | # if event extends InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed: 60 | # if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed: 61 | # var from = get_node("cambase/Camera").project_ray_origin(event.position) 62 | # var to = from + get_node("cambase/Camera").project_ray_normal(event.position)*100 63 | # var p = get_closest_point_to_segment(from, to) 64 | # 65 | # var PATH = get_node("Sound_Smell_Manager/KinematicBody").update_path(p) 66 | # get_node("Sound_Smell_Manager/KinematicBody").has_destination = true 67 | 68 | 69 | # var im = get_node("draw") 70 | # im.set_material_override(m) 71 | # im.clear() 72 | # im.begin(Mesh.PRIMITIVE_POINTS, null) 73 | # im.add_vertex(PATH[0]) 74 | # im.add_vertex(p) 75 | # im.end() 76 | # im.begin(Mesh.PRIMITIVE_LINE_STRIP, null) 77 | # for x in PATH: 78 | # im.add_vertex(x) 79 | # im.end() 80 | pass 81 | # if event is InputEventMouseMotion: 82 | # if event.button_mask&(BUTTON_MASK_MIDDLE+BUTTON_MASK_RIGHT): 83 | # camrot += event.relative.x * 0.005 84 | # camrot2 += event.relative.y * 0.005 85 | # get_node("cambase").set_rotation(Vector3(camrot2, camrot, 0)) 86 | # print("camrot ", camrot) 87 | 88 | 89 | func find_shortest_path(from: Vector3, to : Vector3): 90 | var absoulut = get_absolute_path(from, to) 91 | var navmesh = get_navmesh_path(from, to) 92 | if min(absoulut.size(), navmesh.size()) == absoulut.size(): 93 | return absoulut 94 | else: 95 | if navmesh.size()>1: 96 | return navmesh 97 | else: 98 | return absoulut 99 | 100 | 101 | func get_navmesh_path(from: Vector3, to: Vector3): 102 | var path_points = get_simple_path(from, to, true) 103 | return path_points 104 | 105 | 106 | func get_astar_path(from: Vector3, to: Vector3): 107 | var path_points = astar.get_point_path(astar.get_closest_point(from), astar.get_closest_point(to)) 108 | return path_points 109 | 110 | 111 | func get_absolute_path(from:Vector3, to:Vector3): 112 | #First we calculate the Astar path 113 | var astar_path : Array = get_astar_path(from, to) 114 | print("First Astar point is" + str(astar_path[0])) 115 | print("Last Astar point is" + str(astar_path[astar_path.size()-1])) 116 | print("origin is" + str(from)) 117 | print("destination is" + str(to)) 118 | var first_point = astar_path[0] 119 | #We get the first point of the path 120 | var last_point = (astar_path.invert()) #The astar path is backwards 121 | last_point = astar_path[0] 122 | #astar_path.invert() 123 | #We get the last point of the path 124 | 125 | if (from - first_point).length() > 0: 126 | #If the first point is too far from the kinematic, calculates a Navmesh Path 127 | var Initial_path : Array = get_navmesh_path(from, first_point) 128 | Initial_path.invert() 129 | #Then we add the points to the front of the array 130 | for points in Initial_path: 131 | astar_path.push_back(points) 132 | 133 | astar_path.invert() #The astarpath is forwards 134 | 135 | if (to - last_point).length() > 0: 136 | #If the path is away from the destination, make a Navmesh path to the destination 137 | var Final_path : Array = get_navmesh_path(last_point, to) 138 | #Add the points at the end of the array 139 | for point in Final_path: 140 | astar_path.append(point) 141 | 142 | #Finally, we return the full path to the given position. 143 | return astar_path 144 | 145 | func calculate_astar(): 146 | var AstarPath = $Path.get_curve().get_baked_points() 147 | for x in AstarPath.size(): #Get all points in the Curve 3D 148 | var Point = AstarPath[x] #Get their positions 149 | astar.add_point(x, Point) #Add them to the A* calculation 150 | if x != 0: 151 | astar.connect_points(x,x-1) #If they are not out of index, connect them 152 | astar.connect_points(0,astar.get_points()[-1]) 153 | -------------------------------------------------------------------------------- /core/Systems/Physics/GravityArea.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | class_name GravityArea 3 | var prev_grav = 0 4 | var c_grav = Vector3(0,1,0) 5 | var storage = [] 6 | 7 | const yaxis = Vector3(0,1,0) 8 | const xaxis = Vector3(1,0,0) 9 | const zaxis = Vector3(0,0,1) 10 | # class member variables go here, for example: 11 | # var a = 2 12 | # var b = "textvar" 13 | 14 | func _ready(): 15 | connect("body_entered",self,"_on_body_entered") 16 | connect("body_exited",self,"_on_body_exited") 17 | space_override = SPACE_OVERRIDE_COMBINE_REPLACE 18 | 19 | #Starts gravity vector calculation. 20 | c_grav = gravity_vec 21 | c_grav = c_grav.rotated(xaxis,deg2rad(rotation_degrees.x)) 22 | c_grav = c_grav.rotated(yaxis,deg2rad(rotation_degrees.y)) 23 | c_grav = c_grav.rotated(zaxis,deg2rad(rotation_degrees.z)) 24 | c_grav = c_grav*-gravity 25 | #Gravity vectors calculation ends. 26 | 27 | 28 | func _on_body_entered(object): 29 | print("Entered") 30 | if object is JOYCharacter: 31 | var obj_ID = object.get_instance_id() 32 | if storage.size() <= obj_ID: 33 | storage.resize(obj_ID) 34 | prev_grav = Vector3(object.gravity.x,object.gravity.y,object.gravity.z) 35 | storage.insert(obj_ID,prev_grav) #Store the previous gravity value of the current object. 36 | object.gravity = c_grav 37 | 38 | func _on_body_exited(object): 39 | if object is JOYCharacter: 40 | var ext_ID = object.get_instance_id() 41 | object.gravity = storage[ext_ID] #Sets gravity to it's original default 42 | 43 | 44 | -------------------------------------------------------------------------------- /core/Systems/Sound/Auto_play_sound.gd: -------------------------------------------------------------------------------- 1 | extends AudioStreamPlayer3D 2 | class_name AutoSound3D 3 | 4 | func _init(sound_resource, offset): 5 | if sound_resource is String: 6 | stream = load(sound_resource) 7 | elif sound_resource is AudioStream: 8 | stream = sound_resource 9 | translation = offset 10 | doppler_tracking = AudioStreamPlayer3D.DOPPLER_TRACKING_PHYSICS_STEP 11 | attenuation_model = AudioStreamPlayer3D.ATTENUATION_INVERSE_SQUARE_DISTANCE 12 | unit_db = 20 13 | unit_size = 2 14 | 15 | func _ready(): 16 | play() 17 | yield(self, "finished") 18 | queue_free() 19 | -------------------------------------------------------------------------------- /core/Systems/SpawnPoint.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | class_name SpawnPoint 3 | 4 | enum TEAM { 5 | NO_TEAM, 6 | PLAYER_TEAM1, 7 | PLAYER_TEAM2, 8 | PLAYER_TEAM3, 9 | PLAYER_TEAM4, 10 | AI_TEAM1, 11 | AI_TEAM2, 12 | AI_TEAM3, 13 | AI_TEAM4 14 | } 15 | 16 | export(PackedScene) var Entity : PackedScene = null 17 | export(bool) var respawns : bool = false 18 | export(int) var lifes : int = 1 #-1 for infinite 19 | export(TEAM) var team : int = TEAM.NO_TEAM 20 | 21 | var current_instance : Node 22 | var root : Node 23 | #Standard SpawnPoint implementation, use for any type. 24 | 25 | 26 | 27 | func _ready(): 28 | current_instance = Entity.instance() 29 | if current_instance is JOYCharacter: 30 | root = get_node("/root/World/AI_SH_SYSTEM") 31 | elif current_instance is RigidBody: 32 | root = get_node("/root/World") 33 | 34 | 35 | func spawn(): 36 | if lifes > 1: 37 | root.add_child(current_instance) 38 | -------------------------------------------------------------------------------- /core/actors/Character.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | class_name JOYCharacter 3 | 4 | enum { 5 | OBJECTIVE_POSITION = 0, 6 | OBJECTIVE_TYPE = 1, 7 | OBJECTIVE_HEALTH = 2, 8 | OBJECTIVE_TEAM = 3 9 | } 10 | 11 | 12 | #### Character variables #### 13 | # warning-ignore-all:unused_class_variable 14 | # warning-ignore-all:unused_variable 15 | 16 | var type : String = "Character" 17 | var team : int = 0 18 | var health : int = 100 19 | var shield : int = 0 20 | var maxhealth : int = 100 21 | var maxshield : int = 100 22 | export(bool) var jumping : bool = false 23 | var hearing_capability : int = 1 24 | var smelling_capablity : int = 1 25 | var bleeds : bool = true 26 | var bleeding_smell_intensity : int = 10 27 | var step_sound_intensity : float = 0 # This is calculated from physics values 28 | var object_list : Array = [] 29 | var current_object = 0 30 | var active_object : Object 31 | var weapon_point : Node 32 | var hspeed : float = 0.0 33 | 34 | var camera_dir : Vector3 = Vector3.ZERO 35 | ##Weapons and Object Handling 36 | var inventory : Inventory = Inventory.new() # inventory to store the objects we are currently holding 37 | 38 | 39 | #### Movement and physics variables #### 40 | 41 | export(bool) var flies = false 42 | export(bool) var fixed_up = true 43 | export(float) var weight = 1 44 | export(float) var max_speed = 10 45 | export(int) var turn_speed = 40 46 | export(float) var accel = 19.0 47 | export(float) var deaccel = 14.0 48 | export(bool) var keep_jump_inertia = true 49 | export(bool) var air_idle_deaccel = false 50 | export(bool) var gravity_increase = true 51 | export(float) var JumpHeight = 7.0 52 | var jump_attempt : bool = false 53 | var shoot_attempt : bool = false 54 | export(float) var grav = 9.8 55 | 56 | var linear_velocity = Vector3() 57 | var gravity = Vector3(0,-grav,0) 58 | var up = Vector3() 59 | export(float) var speedfactor = 0.8 60 | var sharp_turn_threshold = 140 61 | 62 | 63 | #### Network vars ##################### 64 | puppet var puppet_linear_vel : Vector3 65 | puppet var puppet_translation : Vector3 66 | puppet var puppet_transform : Transform 67 | ####################################### 68 | 69 | func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn): 70 | var n = p_target # Normal 71 | var t = n.cross(current_gn).normalized() 72 | 73 | var x = n.dot(p_facing) 74 | var y = t.dot(p_facing) 75 | 76 | var ang = atan2(y,x) 77 | 78 | if (abs(ang) < 0.001): # Too small 79 | return p_facing 80 | 81 | var s = sign(ang) 82 | ang = ang*s 83 | var turn = ang*p_adjust_rate*p_step 84 | var a 85 | if (ang < turn): 86 | a = ang 87 | else: 88 | a = turn 89 | ang = (ang - a)*s 90 | return (n*cos(ang) + t*sin(ang))*p_facing.length() 91 | 92 | func turn_character(delta, target_dir): 93 | var mesh_xform = $Model.get_transform() 94 | var facing_mesh = -mesh_xform.basis[0].normalized() 95 | facing_mesh = (facing_mesh - up*facing_mesh.dot(up)).normalized() 96 | if (hspeed>0): 97 | facing_mesh = adjust_facing(facing_mesh, target_dir, delta, 1.0/hspeed*turn_speed, up) 98 | var m3 = Basis(-facing_mesh, up, -facing_mesh.cross(up).normalized()).scaled(scale) 99 | var ModelTransform = Transform(m3, mesh_xform.origin) 100 | $Model.set_transform(ModelTransform) 101 | 102 | func turn_transform(look_dir : Vector3): 103 | $Model.rotation_degrees.y = look_dir.y - 90 104 | # var o = global_transform.origin 105 | # var t = look_dir 106 | # var theta = atan2(o.x - t.x, o.z - t.z) 107 | # $Model.set_rotation(Vector3(0, theta, 0)) 108 | 109 | # $Model.global_transform.basis.rotated(Vector3(0,1,0),$Model.global_transform.basis.z.angle_to(camera_basis.z)) 110 | # $Model.global_transform.origin = global_transform.origin 111 | # pass 112 | 113 | func _ready(): 114 | inventory.weilder_ref = self 115 | 116 | func _physics_process(delta): 117 | step_sound_intensity = (weight*(gravity/9.8) * linear_velocity).length() 118 | 119 | func apply_impulse(position, direction): 120 | linear_velocity += direction 121 | 122 | func spatial_move_to(vector,delta,locked=true): 123 | 124 | if not flies: 125 | if linear_velocity.length() > 0.1: 126 | linear_velocity += gravity*2*delta/linear_velocity.length() 127 | else: 128 | linear_velocity += gravity*delta 129 | 130 | if fixed_up: 131 | up = Vector3(0,1,0) # (up is against gravity) 132 | else: 133 | up = -gravity.normalized() 134 | var vertical_velocity = up.dot(linear_velocity) # Vertical velocity 135 | var horizontal_velocity = linear_velocity - up*vertical_velocity # Horizontal velocity 136 | var hdir = horizontal_velocity.normalized() # Horizontal direction 137 | hspeed = horizontal_velocity.length()*speedfactor 138 | 139 | #look_at(vector, Vector3(0,1,0)) #Change to something that turns to the player or something they have to see 140 | 141 | var target_dir = (vector - up*vector.dot(up)).normalized() 142 | if vector.length() <= 0: 143 | target_dir = (linear_velocity - up*vector.dot(up)).normalized() 144 | 145 | if (is_on_floor()): #Only lets the character change it's facing direction when it's on the floor. 146 | gravity = Vector3(0,-grav,0) 147 | var sharp_turn = hspeed > 0.1 and rad2deg(acos(target_dir.dot(hdir))) > sharp_turn_threshold 148 | if (vector.length() > 0.1 and !sharp_turn): 149 | # if (hspeed > 0.001): 150 | #linear_dir = linear_h_velocity/linear_vel 151 | #if (linear_vel > brake_velocity_limit and linear_dir.dot(ctarget_dir) < -cos(Math::deg2rad(brake_angular_limit))) 152 | # brake = true 153 | #else 154 | # hdir = adjust_facing(hdir, target_dir, delta, 1.0/hspeed*turn_speed, up) 155 | # else: 156 | hdir = target_dir 157 | if (hspeed < max_speed): 158 | hspeed += accel*delta 159 | else: 160 | hspeed -= deaccel*delta 161 | if (hspeed < 0): 162 | hspeed = 0 163 | horizontal_velocity = hdir*hspeed 164 | 165 | if (not jumping and jump_attempt) and is_on_floor(): 166 | vertical_velocity = JumpHeight 167 | jumping = true 168 | #get_node("sound_jump").play() 169 | else: 170 | if gravity_increase: 171 | gravity += gravity/2*delta 172 | if (vector.length() > 0.1): 173 | horizontal_velocity += target_dir*accel*delta 174 | if (horizontal_velocity.length() > max_speed): 175 | horizontal_velocity = horizontal_velocity.normalized()*max_speed 176 | else: 177 | if (air_idle_deaccel): 178 | hspeed -= (deaccel*0.2)*delta 179 | if (hspeed < 0): 180 | hspeed = 0 181 | horizontal_velocity = hdir*hspeed 182 | if (jumping and vertical_velocity < 0): 183 | jumping = false 184 | if not flies: 185 | linear_velocity = horizontal_velocity + up*vertical_velocity 186 | else: 187 | linear_velocity = horizontal_velocity 188 | if (is_on_floor()): 189 | var movement_dir = linear_velocity 190 | #turn_character(delta, camera_dir) 191 | linear_velocity = move_and_slide(linear_velocity, up) 192 | 193 | func hit(damage): 194 | health -= damage 195 | 196 | func add_health(mnt, FillsShield): 197 | if not FillsShield and health < maxhealth: 198 | health += mnt 199 | if FillsShield: 200 | if health < maxhealth: 201 | health += mnt 202 | elif shield < maxshield: 203 | shield += mnt 204 | shield = clamp(shield, 0, maxshield) 205 | health = clamp(health, 0, maxhealth) 206 | 207 | 208 | func update_visibility(): 209 | return 210 | # for i in range(inventory.weapons.size()): 211 | # if inventory.weapons[i].amount == 1: 212 | # inventory.arsenal_links[i].set_visible(false) 213 | # if inventory.weapons[i] == 1: 214 | # inventory.arsenal_links[i].set_visible(true) 215 | # active_object = inventory.arsenal_links[i] 216 | # if inventory.weapons[i] == 2: 217 | # pass #Handle dual handling here 218 | 219 | func pick_up(object, kind = "default", id = 0, dual_pickable=false): 220 | inventory.register_object(object.instance()) 221 | return true 222 | 223 | 224 | 225 | func secondary_use(): 226 | if active_object != null: 227 | if active_object.has_method("secondary_use"): 228 | active_object.secondary_use() 229 | 230 | func secondary_release(): 231 | if active_object != null: 232 | if active_object.has_method("secondary_release"): 233 | active_object.secondary_release() 234 | 235 | func primary_use(): 236 | if active_object != null: 237 | if active_object.has_method("primary_use"): 238 | active_object.primary_use() 239 | 240 | func primary_release(): 241 | if active_object != null: 242 | if active_object.has_method("primary_release"): 243 | active_object.primary_release() 244 | -------------------------------------------------------------------------------- /core/actors/Player.gd: -------------------------------------------------------------------------------- 1 | extends JOYCharacter 2 | class_name Player, "../../icons/player.png" 3 | 4 | var current_state = 0 5 | enum { 6 | IDLE = 1, 7 | WALK = 2, 8 | RUN = 3, 9 | COMBAT = 4, 10 | DEAD = 6 11 | } 12 | export(bool) var AlowCameraChange 13 | export(PackedScene) var Gun 14 | onready var cam = get_parent().get_node("Camera") 15 | func _ready(): 16 | set_process_input(true) 17 | weapon_point = $weapons 18 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 19 | type = "Player" 20 | team = 1 21 | maxhealth = 300 22 | current_state = IDLE 23 | update_inventory() 24 | 25 | #func _init(_type, _team, _gun): 26 | # type = _type 27 | # team = _team 28 | # Gun = _gun 29 | 30 | 31 | 32 | 33 | 34 | 35 | func _physics_process(delta): 36 | var dir = Vector3() 37 | #THIS BLOCK IS INTENDED FOR FPS CONTROLLER USE ONLY 38 | var aim = cam.get_global_transform().basis 39 | if ( not get_tree().has_network_peer()): 40 | get_parent().Camera_Node.make_current() 41 | 42 | if Input.is_action_pressed("shoot"): 43 | primary_use() 44 | 45 | if Input.is_action_pressed("shoot_secondary"): 46 | secondary_use() 47 | 48 | if Input.is_action_just_released("shoot_secondary"): 49 | secondary_release() 50 | 51 | if Input.is_action_just_pressed("prev_weapon"): 52 | last_weapon() 53 | 54 | if Input.is_action_just_pressed("next_weapon"): 55 | next_weapon() 56 | 57 | if (Input.is_action_pressed("move_forwards")): 58 | dir -= aim[2] 59 | if (Input.is_action_pressed("move_backwards")): 60 | dir += aim[2] 61 | if (Input.is_action_pressed("move_left")): 62 | dir -= aim[0] 63 | 64 | # $Pivot/FPSCamera.Znoice = 1*hspeed 65 | 66 | if (Input.is_action_pressed("move_right")): 67 | dir += aim[0] 68 | # $Pivot/FPSCamera.Znoice = -1*hspeed 69 | if get_tree().has_network_peer(): 70 | rset("slave_linear_vel", linear_velocity) 71 | rset("slave_translation", translation) 72 | rset("slave_transform", get_parent().get_node("Player/Model").transform) 73 | else: 74 | get_parent().get_node("Player/Model").transform = puppet_transform 75 | translation = puppet_translation 76 | linear_velocity = puppet_linear_vel 77 | 78 | jump_attempt = Input.is_action_pressed("jump") 79 | shoot_attempt = Input.is_action_pressed("shoot") 80 | 81 | 82 | spatial_move_to(dir, delta, false) 83 | $"Model/animatedglb".linear_speed = linear_velocity.length()/max_speed 84 | # $Model.transform = ModelTransform 85 | 86 | func update_inventory(): 87 | for gun in weapon_point.get_children(): 88 | if gun is JOYObject: 89 | gun.setup(self) 90 | inventory.register_object(gun) 91 | next_weapon() 92 | update_visibility() 93 | 94 | func select_weapon(id = -1): 95 | print("id is: ", id) 96 | if id != -1: 97 | inventory.weapons[id].node_ref.visible = true 98 | active_object = inventory.weapons[id].node_ref 99 | 100 | func next_weapon(attempts = 0): 101 | print(inventory.weapons) 102 | for weapon in inventory.weapons: 103 | print(weapon) 104 | if inventory.weapons[weapon].node_ref.visible == true: 105 | inventory.weapons[weapon].node_ref.visible = false 106 | else: 107 | print("found the gun") 108 | select_weapon(inventory.weapons[weapon].id) 109 | return 110 | pass 111 | """ 112 | if inventory.weapons[current_gun] != -1: 113 | print("Current gun, index: ", current_gun, " exists, setting it to 0") 114 | inventory.weapons[current_gun] = 0 115 | print("attempt to get next gun") 116 | if attempts < inventory.weapons.size(): 117 | print("attempts available") 118 | if current_gun == inventory.weapons.size()-1: 119 | print("returning to the front of the array at attempt :", attempts) 120 | current_gun = 0 121 | else: 122 | print("going to the next id in the array") 123 | current_gun += 1 124 | 125 | if inventory.weapons[current_gun] == -1: 126 | print("this one isn't available yet") 127 | var t = next_weapon(attempts+1) 128 | if t == -1: 129 | print("No gun was found") 130 | return 131 | else: 132 | print("Found an available gun") 133 | inventory.weapons[current_gun] = 1 134 | holding() 135 | else: 136 | print("Attempts have run out") 137 | return -1 138 | 139 | 140 | """ 141 | func last_weapon(attempts = 0): 142 | pass 143 | """ 144 | if inventory.weapons[current_gun] != -1: 145 | inventory.weapons[current_gun] = 0 146 | if attempts < inventory.weapons.size(): 147 | if current_gun == 0: 148 | current_gun = inventory.weapons.size()-1 149 | else: 150 | current_gun -= 1 151 | 152 | if inventory.weapons[current_gun] == -1: 153 | var t = last_weapon(attempts+1) 154 | if t == -1: 155 | return 156 | else: 157 | inventory.weapons[current_gun] = 1 158 | holding() 159 | else: 160 | return -1 161 | """ 162 | -------------------------------------------------------------------------------- /core/component.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | class_name Component 3 | 4 | onready var actor : Spatial = get_parent() 5 | -------------------------------------------------------------------------------- /core/npc_ai/AI_Group.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | class_name JOYAIAbstraction 3 | 4 | """ 5 | This class is an abstraction of AI, must be used for controlling groups of AI or 6 | a single AI character, this can also be extended to allow various behaviors and 7 | routes. Currently extends an existing steering framework. 8 | """ 9 | var coordinated_agents : Array = [] 10 | 11 | 12 | 13 | 14 | #------------------------------------ 15 | 16 | 17 | func setup_agent(node : JOYCharacter): 18 | var agent := GSAIKinematicBody3DAgent.new(node) 19 | agent.linear_speed_max = node.max_speed 20 | agent.linear_acceleration_max = node.aceleration_max 21 | agent.angular_speed_max = deg2rad(node.angular_speed_max) 22 | agent.angular_acceleration_max = deg2rad(node.angular_acceleration_max) 23 | agent.bounding_radius = node.get_collision_shape_radius 24 | # update_agent() 25 | # Maximum possible linear velocity 26 | var speed_max := 450.0 27 | # Maximum change in linear velocity 28 | var acceleration_max := 50.0 29 | # Maximum rotation velocity represented in degrees 30 | var angular_speed_max := 240 31 | # Maximum change in rotation velocity represented in degrees 32 | var angular_acceleration_max := 40 33 | var health_max := 100 34 | var flee_health_threshold := 20 35 | var velocity := Vector2.ZERO 36 | var angular_velocity := 0.0 37 | var linear_drag := 0.1 38 | var angular_drag := 0.1 39 | # Holds the linear and angular components calculated by our steering behaviors. 40 | var acceleration := GSAITargetAcceleration.new() 41 | var current_health := health_max 42 | # GSAISteeringAgent holds our agent's position, orientation, maximum speed and acceleration. 43 | var player: Node = get_tree().get_nodes_in_group("Player")[0] 44 | # This assumes that our player class will keep its own agent updated. 45 | var player_agent: GSAISteeringAgent = player.agent 46 | # GSAIBlend combines behaviors together, calculating all of their acceleration together and adding 47 | # them together, multiplied by a strength. We will have one for fleeing, and one for pursuing, 48 | # toggling them depending on the agent's health. Since we want the agent to rotate AND move, then 49 | # we aim to blend them together. 50 | var flee_blend := GSAIBlend.new(agent) 51 | var pursue_blend := GSAIBlend.new(agent) 52 | # GSAIPriority will be the main steering behavior we use. It holds sub-behaviors and will pick the 53 | # first one that returns non-zero acceleration, ignoring any afterwards. 54 | var priority := GSAIPriority.new(agent) 55 | # Proximities represent an area with which an agent can identify where neighbors in its relevant 56 | # group are. In our case, the group will feature the player, which will be used to avoid a 57 | # collision with them. We use a radius proximity so the player is only relevant inside 100 pixels 58 | var proximity := GSAIRadiusProximity.new(agent, [player_agent], 100) 59 | 60 | ##################Compiled behavior############################ 61 | 62 | func _ready(): 63 | for child in get_children(): 64 | if child is JOYCharacter: 65 | setup_agent(child) 66 | get_parent()._register_ai_actor(child) 67 | 68 | func _unregister_ai_actor(node : JOYCharacter): 69 | get_parent()._unregister_ai_actor(node) 70 | -------------------------------------------------------------------------------- /core/npc_ai/AI_Individual.gd: -------------------------------------------------------------------------------- 1 | extends JOYCharacter 2 | ################### 3 | ## AI STEERING ## 4 | var agent : GSAISteeringAgent 5 | var behaviors = { 6 | "flee" : GSAIBlend.new(agent), 7 | #flee includes: 8 | # Evade 9 | # Flee 10 | # Separation 11 | "pursue" : GSAIBlend.new(agent), 12 | #pursue includes: 13 | # Cohesion 14 | # Pursue 15 | "keep_range" : GSAIBlend.new(agent) 16 | # includes: 17 | # stay at certain distance 18 | } 19 | 20 | ################### 21 | var current_point : Vector3 = Vector3(0,0,0) 22 | var point_number :int = 0 23 | var AI_PATH : Array = [] 24 | var has_destination : bool = false 25 | var has_target : bool = false 26 | 27 | onready var world : Node = get_node("root/world") 28 | #### Properties #### 29 | export(float) var attack_min_range = 10 30 | export(float) var attack_max_range = 50 31 | 32 | #### Signals #### 33 | signal saw_object(object_info) 34 | signal got_shot(damage, type) 35 | signal heard_something(position) 36 | signal smell_something(position) 37 | 38 | ###############Basic Movement Functions#################### 39 | func update_path(to): 40 | world = get_node("/root/world") 41 | has_destination =false 42 | AI_PATH = world.find_shortest_path(translation, to) 43 | current_point = AI_PATH[0] 44 | point_number = 0 45 | has_destination = true 46 | print(AI_PATH) 47 | return AI_PATH 48 | 49 | """ 50 | func setup_world(): 51 | if get_parent() is SoundSmellManager: 52 | SSM = get_parent() 53 | elif get_parent().get_parent() is SoundSmellManager: 54 | SSM = get_parent().get_parent() 55 | else: 56 | return 57 | """ 58 | 59 | func _ready(): 60 | # setup_world() 61 | for node in get_children(): 62 | if node is JOYCharacter: 63 | node.type = "AI_Character" 64 | func _physics_process(delta): 65 | move_in_path(delta) 66 | func move_in_path(delta): 67 | if has_destination: 68 | var vector = (current_point-translation) 69 | 70 | if (vector).length() > 2: 71 | vector = current_point-translation 72 | 73 | spatial_move_to(vector, delta) 74 | else: 75 | if point_number < AI_PATH.size()-1: 76 | point_number += 1 77 | current_point = AI_PATH[point_number] 78 | 79 | else: 80 | spatial_move_to(Vector3(), delta) 81 | 82 | 83 | 84 | func update_direction(path_points: Array): 85 | var i : int = 0 86 | var point = path_points[i] 87 | var direction = point - translation 88 | while direction.lenght() > 0: 89 | direction = point - translation 90 | if direction.lenght() <= 0.1: 91 | i+=1 92 | return direction 93 | 94 | func move(to): 95 | update_path(to) 96 | has_destination = true 97 | 98 | 99 | ##############Behavioral Functions########################## 100 | 101 | func walk(to): 102 | 103 | pass 104 | 105 | func flee(from): 106 | pass 107 | 108 | func shoot(to): 109 | pass 110 | 111 | func decide_dual(motivation, signal1, signal2): 112 | if motivation < 0.5: 113 | emit_signal(signal1) 114 | if motivation > 0.5: 115 | emit_signal(signal2) 116 | 117 | func play_sound(name:String, intensity): 118 | var stream = load(name) 119 | if is_valid_sound(stream): 120 | add_child(AutoSound3D.new(stream, Vector3(0,0,0))) 121 | world.emit_signal("sound_emitted",translation,intensity) 122 | 123 | func is_valid_sound(res): 124 | var valid_types = [ 125 | AudioStream, 126 | AudioStreamSample, 127 | AudioStreamRandomPitch, 128 | AudioStreamOGGVorbis, 129 | AudioStreamMicrophone, 130 | AudioStreamGenerator] 131 | for type in valid_types: 132 | if res is type: 133 | return true 134 | return false 135 | 136 | func decide_fuzzy(motiv1,motiv2,motiv3, signal1, signal2, signal3): 137 | if motiv3 == max(max(motiv1,motiv2),motiv3): 138 | emit_signal(signal3) 139 | if motiv2 == max(max(motiv1,motiv2),motiv3): 140 | emit_signal(signal2) 141 | if motiv1 == max(max(motiv1,motiv2),motiv3): 142 | emit_signal(signal1) 143 | 144 | func dead(): 145 | get_parent()._unregister_AI_Actor(self) 146 | if bleeds: 147 | get_parent().emit_signal("smell_emitted",translation,bleeding_smell_intensity) 148 | 149 | func nothing(var1 = null, var2 = null, var4= null, var5 = null, var6=null): 150 | pass 151 | 152 | func _on_Eyes_sight(objects, points, normals): 153 | for object in objects: 154 | if object is JOYCharacter or object is JOYWorkstation: 155 | var Objective_info = Decoder.get_object_info(object) 156 | print_debug("Saw an objective") 157 | emit_signal("saw_object", Objective_info) 158 | 159 | # Called every frame. 'delta' is the elapsed time since the previous frame. 160 | #func _process(delta): 161 | # pass 162 | -------------------------------------------------------------------------------- /core/npc_ai/JxAI.gd: -------------------------------------------------------------------------------- 1 | extends JOYCharacter 2 | class_name AI 3 | """ 4 | Interface/Integrator to connect all signals to a behavior tree and provide its functionality 5 | """ 6 | 7 | export(String, FILE, "*.jsm") var NPC_File : String = "" #This works just fine! :D 8 | export(String) var initial_state : String = "" 9 | #export(NodePath) var Interactable_Path : NodePath = "" 10 | 11 | 12 | 13 | var BehaviorTree : JxNPC = null 14 | var worker : Worker = Worker.new() 15 | 16 | 17 | func _ready(): 18 | 19 | BehaviorTree = JxNPC.new(NPC_File, initial_state) 20 | BehaviorTree.actor = self 21 | BehaviorTree.navigator = $MovementIntegrator 22 | 23 | #Worker related functions and signals, setup 24 | BehaviorTree.worker = worker 25 | for child in get_children(): 26 | if child is Component: 27 | child._setup() 28 | BehaviorTree._create_signal("workstation_assigned") 29 | BehaviorTree._create_signal("stopped_working") 30 | BehaviorTree._create_signal("request_rejected") 31 | worker.connect("request_rejected", self, "_on_request_rejected") 32 | worker.connect("stopped_working", self, "_on_worker_stopped") 33 | worker.connect("workstation_assigned", self, "_on_worker_assigned") 34 | $MovementIntegrator.connect("sight", self, "_on_sight") 35 | #Workstation setup 36 | BehaviorTree._create_signal("interacted_by") 37 | add_child(BehaviorTree) 38 | #Load settings 39 | # BehaviorTree.load_colors() 40 | 41 | func _process_server(delta): 42 | worker.work(delta) 43 | 44 | func _on_sight(info): 45 | BehaviorTree.emit_signal("sight", info) 46 | 47 | func _on_interacted(anything): 48 | BehaviorTree.emit_signal("interacted_by", anything) 49 | 50 | func _on_worker_stopped(category): 51 | BehaviorTree.emit_signal("stopped_working", category) 52 | 53 | func _on_request_rejected(): 54 | BehaviorTree.emit_signal("request_rejected", null) #Signals must carry at least 1 variable 55 | 56 | func _on_worker_assigned(where): 57 | BehaviorTree.emit_signal("workstation_assigned", where) 58 | -------------------------------------------------------------------------------- /core/npc_ai/NPC1.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://joyeuse/core/npc_ai/components/NPCMovement.gd" type="Script" id=1] 4 | [ext_resource path="res://joyeuse/core/npc_ai/JxAI.gd" type="Script" id=2] 5 | [ext_resource path="res://joyeuse/core/npc_ai/components/Eyes.tscn" type="PackedScene" id=3] 6 | [ext_resource path="res://joyeuse/core/npc_ai/components/AwakeArea.gd" type="Script" id=4] 7 | 8 | 9 | [sub_resource type="CapsuleShape" id=1] 10 | radius = 0.416147 11 | height = 1.74176 12 | 13 | [sub_resource type="SphereShape" id=2] 14 | radius = 4.43012 15 | 16 | [node name="AI" type="KinematicBody"] 17 | script = ExtResource( 2 ) 18 | 19 | [node name="CollisionShape" type="CollisionShape" parent="."] 20 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 1.30227, 0 ) 21 | shape = SubResource( 1 ) 22 | 23 | [node name="MovementIntegrator" type="Spatial" parent="."] 24 | script = ExtResource( 1 ) 25 | 26 | [node name="Eyes" parent="." instance=ExtResource( 3 )] 27 | transform = Transform( -1.2358e-06, 0, 1, 0, 1, 0, -1, 0, -1.2358e-06, -1.05526, 2.30971, 0 ) 28 | 29 | [node name="AreaAwake" type="Area" parent="."] 30 | script = ExtResource( 4 ) 31 | 32 | [node name="CollisionShape" type="CollisionShape" parent="AreaAwake"] 33 | shape = SubResource( 2 ) 34 | [connection signal="body_entered" from="AreaAwake" to="AreaAwake" method="_on_Area_body_entered"] 35 | [connection signal="body_exited" from="AreaAwake" to="AreaAwake" method="_on_Area_body_exited"] 36 | -------------------------------------------------------------------------------- /core/npc_ai/components/AwakeArea.gd: -------------------------------------------------------------------------------- 1 | extends Component 2 | 3 | func _setup(): 4 | actor.BehaviorTree._create_signal("character_entered") 5 | actor.BehaviorTree._create_signal("character_exited") 6 | 7 | func _on_Area_body_entered(body): 8 | actor.BehaviorTree.emit_signal("character_entered") 9 | 10 | func _on_Area_body_exited(body): 11 | actor.BehaviorTree.emit_signal("character_exited") 12 | -------------------------------------------------------------------------------- /core/npc_ai/components/Eyes.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://joyeuse/core/npc_ai/components/vision_colliders.gd" type="Script" id=1] 4 | 5 | [sub_resource type="SphereMesh" id=1] 6 | radius = 0.25 7 | height = 0.5 8 | 9 | [sub_resource type="SpatialMaterial" id=2] 10 | flags_unshaded = true 11 | albedo_color = Color( 0.666667, 0.780392, 0, 1 ) 12 | 13 | [node name="Eyes" type="Spatial"] 14 | transform = Transform( -1.2358e-06, 0, 1, 0, 1, 0, -1, 0, -1.2358e-06, -1.05526, 2.01, 0 ) 15 | script = ExtResource( 1 ) 16 | 17 | [node name="RayCast" type="RayCast" parent="."] 18 | transform = Transform( 1, 1.42109e-14, 0, 0, 1, -1.75618e-20, 0, 0, 1, 0, 0, 0 ) 19 | enabled = true 20 | cast_to = Vector3( 0, 0, -5 ) 21 | collision_mask = 2 22 | 23 | [node name="RayCast4" type="RayCast" parent="."] 24 | transform = Transform( 1, 3.19849e-07, 4.21089e-08, -3.19849e-07, 0.965926, 0.258819, 4.21089e-08, -0.258819, 0.965926, 0, 0, 0 ) 25 | enabled = true 26 | cast_to = Vector3( 0, 0, -5 ) 27 | collision_mask = 2 28 | 29 | [node name="RayCast12" type="RayCast" parent="."] 30 | transform = Transform( 1, -6.17903e-07, 1.65566e-07, 6.17903e-07, 0.866025, -0.5, 1.65567e-07, 0.5, 0.866025, 0, 0, 0 ) 31 | enabled = true 32 | cast_to = Vector3( 0, 0, -5 ) 33 | collision_mask = 2 34 | 35 | [node name="RayCast9" type="RayCast" parent="."] 36 | transform = Transform( 1, -3.19849e-07, 4.21089e-08, 3.19849e-07, 0.965926, -0.258819, 4.21089e-08, 0.258819, 0.965926, 0, 0, 0 ) 37 | enabled = true 38 | cast_to = Vector3( 0, 0, -5 ) 39 | collision_mask = 2 40 | 41 | [node name="RayCast2" type="RayCast" parent="."] 42 | transform = Transform( 0.965926, 0, 0.258819, 0, 1, 0, -0.258819, 0, 0.965926, -0.0529401, 0, -1.19209e-07 ) 43 | enabled = true 44 | cast_to = Vector3( -2, 0, -4.5 ) 45 | 46 | [node name="RayCast5" type="RayCast" parent="."] 47 | transform = Transform( 1, 3.19849e-07, 4.21089e-08, -3.19849e-07, 0.965926, 0.258819, 4.21089e-08, -0.258819, 0.965926, -0.0529401, 0, -1.19209e-07 ) 48 | enabled = true 49 | cast_to = Vector3( -2, 0, -4.5 ) 50 | 51 | [node name="RayCast11" type="RayCast" parent="."] 52 | transform = Transform( 1, -6.17903e-07, 1.65566e-07, 6.17903e-07, 0.866025, -0.5, 1.65567e-07, 0.5, 0.866025, -0.0529401, 5.96046e-08, -1.19209e-07 ) 53 | enabled = true 54 | cast_to = Vector3( -2, 0, -4.5 ) 55 | 56 | [node name="RayCast8" type="RayCast" parent="."] 57 | transform = Transform( 1, -3.19849e-07, 4.21089e-08, 3.19849e-07, 0.965926, -0.258819, 4.21089e-08, 0.258819, 0.965926, -0.0529401, 0, -1.19209e-07 ) 58 | enabled = true 59 | cast_to = Vector3( -2, 0, -4.5 ) 60 | 61 | [node name="RayCast3" type="RayCast" parent="."] 62 | transform = Transform( 0.965926, 0, -0.258819, 0, 1, 0, 0.258819, 0, 0.965926, 0.0664887, 0, 1.19209e-07 ) 63 | enabled = true 64 | cast_to = Vector3( 2, 0, -4.5 ) 65 | 66 | [node name="RayCast6" type="RayCast" parent="."] 67 | transform = Transform( 1, 3.19849e-07, 4.21089e-08, -3.19849e-07, 0.965926, 0.258819, 4.21089e-08, -0.258819, 0.965926, 0.0664887, 0, 1.19209e-07 ) 68 | enabled = true 69 | cast_to = Vector3( 2, 0, -4.5 ) 70 | 71 | [node name="RayCast10" type="RayCast" parent="."] 72 | transform = Transform( 1, -6.17903e-07, 1.65566e-07, 6.17903e-07, 0.866025, -0.5, 1.65567e-07, 0.5, 0.866025, 0.0664887, 0, 8.9407e-08 ) 73 | enabled = true 74 | cast_to = Vector3( 2, 0, -4.5 ) 75 | 76 | [node name="RayCast7" type="RayCast" parent="."] 77 | transform = Transform( 1, -3.19849e-07, 4.21089e-08, 3.19849e-07, 0.965926, -0.258819, 4.21089e-08, 0.258819, 0.965926, 0.0664887, 0, 1.19209e-07 ) 78 | enabled = true 79 | cast_to = Vector3( 2, 0, -4.5 ) 80 | 81 | [node name="DebugShapes" type="Spatial" parent="."] 82 | 83 | [node name="MeshInstance2" type="MeshInstance" parent="DebugShapes"] 84 | transform = Transform( 1, -4.21089e-08, 3.19849e-07, -3.19849e-07, -0.258819, 0.965926, 4.21089e-08, -0.965926, -0.258819, 0.0680396, -1.29256, -4.88306 ) 85 | mesh = SubResource( 1 ) 86 | material/0 = SubResource( 2 ) 87 | 88 | [node name="MeshInstance3" type="MeshInstance" parent="DebugShapes"] 89 | transform = Transform( 1, -1.65566e-07, -6.17903e-07, 6.17903e-07, 0.5, 0.866025, 1.65567e-07, -0.866025, 0.5, 0.068039, 2.53887, -4.36682 ) 90 | mesh = SubResource( 1 ) 91 | material/0 = SubResource( 2 ) 92 | 93 | [node name="MeshInstance4" type="MeshInstance" parent="DebugShapes"] 94 | transform = Transform( 1, -4.21089e-08, -3.19849e-07, 3.19849e-07, 0.258819, 0.965926, 4.21089e-08, -0.965926, 0.258819, 0.0680396, 1.32214, -4.87513 ) 95 | mesh = SubResource( 1 ) 96 | material/0 = SubResource( 2 ) 97 | -------------------------------------------------------------------------------- /core/npc_ai/components/NPCMovement.gd: -------------------------------------------------------------------------------- 1 | extends Component 2 | """This node should be child of a KinematicBody""" 3 | # Holds extra information and our character 4 | var Agent : GSAIKinematicBody3DAgent 5 | export (float, 0, 100, 5) var linear_speed_max := 10.0 6 | export (float, 0, 100, 0.1) var linear_acceleration_max := 1.0 7 | export (float, 0, 50, 0.1) var arrival_tolerance := 0.7 8 | export (float, 0, 50, 0.1) var deceleration_radius := 1.0 9 | export (int, 0, 1080, 10) var angular_speed_max := 270 10 | export (int, 0, 2048, 10) var angular_accel_max := 45 11 | export (int, 0, 178, 2) var align_tolerance := 5 12 | export (int, 0, 180, 2) var angular_deceleration_radius := 45 13 | # Holds the linear and angular components calculated by our steering behaviors. 14 | onready var acceleration := GSAITargetAcceleration.new() 15 | var world_ref : WorldNavigator = null 16 | var path : Array = [] 17 | var current_target : GSAIAgentLocation = GSAIAgentLocation.new() 18 | var facing_target : GSAIAgentLocation = GSAIAgentLocation.new() 19 | var special_target : GSAISteeringAgent = GSAISteeringAgent.new() 20 | var current_path : GSAIPath = GSAIPath.new([Vector3(1,1,1), Vector3(2,2,5)]) 21 | var personal_space : float = 1.5 22 | 23 | # First, we setup our NPCs personal space, so they don't hit each other 24 | # and get hard feelings 25 | var Proximity : GSAIRadiusProximity 26 | 27 | # NOTE: From now on, steering behaviors are relative to the target point 28 | 29 | # NPCs avoid each other, but just a bit, enough to keep walking space between them 30 | var Avoid : GSAIAvoidCollisions 31 | 32 | # Fleeing a particular place can be used in emergency simulacrum emergencies 33 | var FleeTarget : GSAIFlee 34 | 35 | var Seek : GSAISeek 36 | 37 | # Facing is more of an educated gesture towards someone you're listening to 38 | var Face : GSAIFace 39 | var Face2 : GSAIFace 40 | 41 | # NPCs may evade their problems, may evade you, or may evade another NPC 42 | # (the only limit is your imagination :D) 43 | var Evade : GSAIEvade 44 | 45 | # As you pursue your dreams, NPCs pursue whatever their target is 46 | var Pursue : GSAIPursue 47 | 48 | #This behavior sets the NPC in an specific path that it will follow 49 | var Follow : GSAIFollowPath 50 | 51 | # Takes away the cost of looking towards a specific thing and just 52 | # makes the NPC look where it's going to 53 | var LookAhead : GSAILookWhereYouGo 54 | # The name is too long for me... 55 | 56 | # Behavior mixing occurs ahead, for the previous behaviors to work, this is 57 | # necessary 58 | 59 | onready var PathBlend : GSAIBlend = GSAIBlend.new(Agent) 60 | 61 | onready var FollowBlend : GSAIBlend = GSAIBlend.new(Agent) 62 | 63 | onready var FleeBlend : GSAIBlend = GSAIBlend.new(Agent) 64 | 65 | # This one is important, as will tell the NPC what to do first when various 66 | # movement options are present 67 | onready var Priority : GSAIPriority = GSAIPriority.new(Agent) 68 | 69 | func _enter_tree(): 70 | var check = load("res://addons/com.gdquest.godot-steering-ai-framework/GSAISteeringAgent.gd") 71 | if not check is Resource: 72 | print_debug("This node depends on Steering AI Framework") 73 | #This is just a small explaination that should popup if used as tool 74 | #you would notice something's wrong when you try to use this node and errors 75 | #pop up 76 | var world = get_tree().get_nodes_in_group("Navigator") 77 | if world.size() > 0: 78 | world_ref = world [0] 79 | Agent = GSAIKinematicBody3DAgent.new(get_parent()) 80 | var NPCAgents = [] 81 | for node in get_tree().get_nodes_in_group("NPC"): 82 | if node.get("Agent"): 83 | NPCAgents.append(node.Agent) 84 | Proximity = GSAIRadiusProximity.new(Agent, NPCAgents, personal_space) 85 | Avoid = GSAIAvoidCollisions.new(Agent, Proximity) 86 | FleeTarget = GSAIFlee.new(Agent, current_target) 87 | Seek = GSAISeek.new(Agent, current_target) 88 | Face = GSAIFace.new(Agent, current_target, true) 89 | Face2 = GSAIFace.new(Agent, facing_target, true) 90 | Evade = GSAIEvade.new(Agent, special_target) 91 | Pursue = GSAIPursue.new(Agent, special_target) 92 | Follow = GSAIFollowPath.new(Agent, current_path) 93 | LookAhead = GSAILookWhereYouGo.new(Agent, true) 94 | 95 | func _ready(): 96 | Agent.linear_speed_max = linear_speed_max 97 | Agent.linear_acceleration_max = linear_acceleration_max 98 | Agent.linear_drag_percentage = 0.05 99 | Agent.angular_acceleration_max = angular_accel_max 100 | Agent.angular_speed_max = angular_speed_max 101 | Agent.angular_drag_percentage = 0.1 102 | FleeBlend.add(Evade, 1) 103 | FleeBlend.add(FleeTarget, 1) 104 | FleeBlend.add(Avoid, 1) #Avoid is added everywhere, to get better consistency 105 | 106 | FollowBlend.add(Seek, 1) 107 | FollowBlend.add(Face, 1) 108 | FollowBlend.add(Avoid, 1) 109 | 110 | # PathBlend.add(Follow, 1) 111 | PathBlend.add(LookAhead, 1) 112 | PathBlend.add(Avoid, 1) 113 | PathBlend.is_enabled = true 114 | # The order these are added has importance so the NPC behaves like this: 115 | Priority.add(Face2) 116 | Priority.add(FollowBlend)#Priority 1: Follow who I am supposed to (if i am supposed to) 117 | Priority.add(FleeBlend)#2: Run away if i am supposed to 118 | Priority.add(PathBlend) #3 : Follow a path 119 | 120 | get_navpath(actor.translation) 121 | 122 | 123 | func _process_server(delta): 124 | if PathBlend and FollowBlend and FleeBlend and Priority: 125 | if (current_target.position - actor.translation).length() < arrival_tolerance: 126 | var temp = path.pop_front() 127 | if temp != null: 128 | update_target(temp) 129 | else: 130 | actor.input = Vector3.ZERO 131 | Face2.is_enabled = true 132 | yield(get_tree().create_timer(2), "timeout") 133 | Face2.is_enabled = false 134 | else: 135 | Priority.calculate_steering(acceleration) 136 | 137 | _handle_npc_input(acceleration, delta) 138 | 139 | func _handle_npc_input(acceleration : GSAITargetAcceleration, delta : float): 140 | update_agent(acceleration.linear, acceleration.angular) 141 | actor.spatial_move_to(acceleration, delta) 142 | # Agent._apply_steering(acceleration, delta) 143 | # actor.look_dir = actor.global_transform.origin-acceleration.linear 144 | # actor.input.z = acceleration.linear.normalized().length() 145 | #actor.input.y = acceleration.linear.normalized().y 146 | 147 | func _process_client(delta): 148 | actor.global_transform.origin = actor.srv_pos 149 | 150 | func update_target(pos : Vector3): 151 | # Remember to update the target of the NPCs! Otherwise they could run away 152 | # to their workstation instead of following your character (just an example) 153 | current_target.position = pos 154 | special_target.position = pos 155 | 156 | func get_navpath(to : Vector3): 157 | path = Array(world_ref.get_navmesh_path(actor.translation, to)) 158 | print(path) 159 | current_path.create_path(path) 160 | var temp = path.pop_front() 161 | if temp != null: 162 | update_target(temp) 163 | func _setup(): 164 | pass 165 | 166 | func update_agent(velocity : Vector3, angular_velocity : float): 167 | Agent.position = actor.translation 168 | Agent.orientation = actor.rotation_degrees.y 169 | Agent.linear_velocity = velocity 170 | Agent.angular_velocity = angular_velocity 171 | -------------------------------------------------------------------------------- /core/npc_ai/components/vision_colliders.gd: -------------------------------------------------------------------------------- 1 | extends Component 2 | signal sight(sight_info) 3 | 4 | export(bool) var is_debug : bool = false 5 | 6 | var colliders : Array = [] 7 | 8 | func _ready(): 9 | for rays in get_children(): 10 | if rays is RayCast: 11 | colliders.append(rays) 12 | 13 | func _get_collision_info(): 14 | var sight : Dictionary= {} 15 | var objects : Array = [] 16 | var points : Array = [] 17 | var normals : Array = [] 18 | for ray in colliders: 19 | objects.append(ray.get_collider()) 20 | points.append(ray.get_collision_point()) 21 | normals.append(ray.get_collision_normal()) 22 | sight["objects"] = objects 23 | sight["points"] = points 24 | sight["normals"] = normals 25 | actor.BehaviorTree.emit_signal("sight", sight) 26 | 27 | func _is_any_colliding(): 28 | var collides = false 29 | for rays in colliders: 30 | collides = rays.is_colliding() 31 | if collides: 32 | return collides 33 | return collides 34 | 35 | func _setup(): 36 | actor.BehaviorTree._create_signal("sight") 37 | if not is_debug: 38 | $DebugShapes.queue_free() 39 | 40 | func _process(delta): 41 | if _is_any_colliding(): 42 | _get_collision_info() 43 | 44 | func set_lenght(length : float): 45 | for child in get_children(): 46 | if child is RayCast: 47 | child.cast_to = child.cast_to.normalized() * length 48 | -------------------------------------------------------------------------------- /core/weapons/explosion.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Joyeuse/core/weapons/squib.gd" type="Script" id=1] 4 | 5 | 6 | [sub_resource type="SphereMesh" id=1] 7 | 8 | [sub_resource type="SpatialMaterial" id=2] 9 | albedo_color = Color( 0.875, 1, 0, 1 ) 10 | roughness = 0.0 11 | emission_enabled = true 12 | emission = Color( 1, 0.515625, 0, 1 ) 13 | emission_energy = 1.0 14 | emission_operator = 0 15 | emission_on_uv2 = false 16 | 17 | [node name="squib" type="Spatial"] 18 | script = ExtResource( 1 ) 19 | 20 | [node name="dismiss" type="Timer" parent="."] 21 | wait_time = 0.3 22 | 23 | [node name="MeshInstance" type="MeshInstance" parent="."] 24 | transform = Transform( 0.88656, 0, 0, 0, 0.88656, 0, 0, 0, 0.88656, 0, 0, 0 ) 25 | mesh = SubResource( 1 ) 26 | material/0 = SubResource( 2 ) 27 | 28 | [node name="OmniLight" type="OmniLight" parent="."] 29 | light_energy = 2.5 30 | omni_range = 4.62203 31 | [connection signal="timeout" from="dismiss" to="." method="_on_dismiss_timeout"] 32 | -------------------------------------------------------------------------------- /core/weapons/large_explosion.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Joyeuse/core/weapons/squib.gd" type="Script" id=1] 4 | 5 | 6 | [sub_resource type="SphereMesh" id=1] 7 | radius = 3.0 8 | height = 6.0 9 | 10 | [sub_resource type="SpatialMaterial" id=2] 11 | albedo_color = Color( 0.875, 1, 0, 1 ) 12 | roughness = 0.0 13 | emission_enabled = true 14 | emission = Color( 1, 0.515625, 0, 1 ) 15 | emission_energy = 1.0 16 | emission_operator = 0 17 | emission_on_uv2 = false 18 | 19 | [node name="squib" type="Spatial"] 20 | script = ExtResource( 1 ) 21 | 22 | [node name="dismiss" type="Timer" parent="."] 23 | wait_time = 0.3 24 | 25 | [node name="MeshInstance" type="MeshInstance" parent="."] 26 | transform = Transform( 0.88656, 0, 0, 0, 0.88656, 0, 0, 0, 0.88656, 0, 0, 0 ) 27 | mesh = SubResource( 1 ) 28 | material/0 = SubResource( 2 ) 29 | 30 | [node name="OmniLight" type="OmniLight" parent="."] 31 | light_energy = 2.5 32 | omni_range = 7.02512 33 | [connection signal="timeout" from="dismiss" to="." method="_on_dismiss_timeout"] 34 | -------------------------------------------------------------------------------- /core/weapons/projectile.gd: -------------------------------------------------------------------------------- 1 | # This script determines the behaviour of any projectile 2 | extends RigidBody 3 | class_name Projectile 4 | 5 | 6 | # following variables initiate information about the projectile itself. 7 | 8 | # determines the type of effect the weapon exerts on impact 9 | enum projectile_types {explosive, energy, flame} 10 | export(bool) var use_physics : bool 11 | export(bool) var splash_damage : bool = false 12 | export(float) var shot_sound_intensity : float = 1.2 13 | export(float) var hit_sound_intensity : float = 1.2 14 | export (projectile_types) var type : int 15 | # determines initial speed of weapon 16 | export(float) var speed : float = 25 17 | var pos 18 | # sets whether the weapon constantly exerts thrust (like a rocket propelled weapon) or not. 19 | export var propelled : bool = false 20 | 21 | export(PackedScene) var explosion : PackedScene = preload("explosion.tscn") 22 | 23 | export(PackedScene) var splash : PackedScene = preload("explosion.tscn") 24 | 25 | export var damage : float = 10 26 | 27 | var wielder : JOYCharacter 28 | 29 | 30 | func setup(wieldee): 31 | wielder = wieldee 32 | 33 | func _integrate_forces(state): 34 | if propelled: 35 | propel() 36 | 37 | 38 | func propel(): 39 | 40 | # determine basis for flight 41 | var dir = get_global_transform().basis*Vector3(0,0,-1).normalized() 42 | 43 | # exert impulse on bolt to propel it. 44 | set_linear_velocity(dir*speed) 45 | apply_impulse(Vector3(),dir * speed ) 46 | 47 | func _ready(): 48 | 49 | # set transform relative to global 50 | set_as_toplevel(true) 51 | set_use_custom_integrator(not use_physics) 52 | 53 | # get current position/orientation 54 | # pos = get_transform() 55 | 56 | propel() 57 | 58 | # when the hitbox collides with something: 59 | func _on_Area_body_entered(body): 60 | # if its a character or object (wall, etc) 61 | if body is PhysicsBody or body is GridMap and not body is Area: 62 | # so long as the object is NOT the bolt itself (since the bolt is a rigid body) 63 | if body == wielder: 64 | pass 65 | else: 66 | var splode = explosion.instance() 67 | splode.set_as_toplevel(true) 68 | splode.set_global_transform(get_global_transform()) 69 | 70 | 71 | #var splodepos = splode.get_global_transform() 72 | #squibpos.origin = squibpoint 73 | #thissquib.set_global_transform(squibpos) 74 | if body.owner == null: 75 | pass 76 | else: 77 | print(type) 78 | if type == 0: 79 | body.owner.add_child(splode) 80 | # have some effect (right now it just queues free. 81 | queue_free() 82 | 83 | if body.has_method("hit"): 84 | body.hit(damage) 85 | queue_free() 86 | 87 | 88 | func _on_killtimer_timeout(): 89 | queue_free() 90 | 91 | -------------------------------------------------------------------------------- /core/weapons/raycast_weapon.gd: -------------------------------------------------------------------------------- 1 | extends JOYWeapon 2 | class_name RaycastWeapon 3 | 4 | # class member variables go here, for example: 5 | # var a = 2 6 | # var b = "textvar" 7 | 8 | func _ready(): 9 | # Called when the node is added to the scene for the first time. 10 | # Initialization here 11 | pass 12 | 13 | #func _process(delta): 14 | # # Called every frame. Delta is time since last frame. 15 | # # Update game logic here. 16 | # pass 17 | -------------------------------------------------------------------------------- /core/weapons/squib.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | # class member variables go here, for example: 4 | # var a = 2 5 | # var b = "textvar" 6 | 7 | func _ready(): 8 | $dismiss.start() 9 | # Called when the node is added to the scene for the first time. 10 | # Initialization here 11 | pass 12 | 13 | #func _process(delta): 14 | # # Called every frame. Delta is time since last frame. 15 | # # Update game logic here. 16 | # pass 17 | 18 | 19 | func _on_dismiss_timeout(): 20 | queue_free() 21 | pass # replace with function body 22 | -------------------------------------------------------------------------------- /core/weapons/squib.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Joyeuse/core/weapons/squib.gd" type="Script" id=1] 4 | 5 | 6 | [sub_resource type="SphereMesh" id=1] 7 | 8 | [sub_resource type="SpatialMaterial" id=2] 9 | albedo_color = Color( 0.875, 1, 0, 1 ) 10 | roughness = 0.0 11 | emission_enabled = true 12 | emission = Color( 1, 0.820312, 0, 1 ) 13 | emission_energy = 1.0 14 | emission_operator = 0 15 | emission_on_uv2 = false 16 | 17 | [node name="squib" type="Spatial"] 18 | script = ExtResource( 1 ) 19 | 20 | [node name="dismiss" type="Timer" parent="."] 21 | wait_time = 0.3 22 | 23 | [node name="MeshInstance" type="MeshInstance" parent="."] 24 | transform = Transform( 0.142724, 0, 0, 0, 0.142724, 0, 0, 0, 0.142724, 0, 0, 0 ) 25 | mesh = SubResource( 1 ) 26 | material/0 = SubResource( 2 ) 27 | 28 | [node name="OmniLight" type="OmniLight" parent="."] 29 | omni_range = 1.98613 30 | [connection signal="timeout" from="dismiss" to="." method="_on_dismiss_timeout"] 31 | -------------------------------------------------------------------------------- /core/weapons/weapon.gd: -------------------------------------------------------------------------------- 1 | # This script attempts to unify the base behaviours of all weapons. 2 | # it is extended by each weapon to facilitate their specific functions 3 | # for example: the fusion pistol is a projectile weapon that has overload events, the pistol can be dual wielded. 4 | 5 | extends JOYObject 6 | class_name JOYWeapon 7 | 8 | # sets the readiness of the weapon to fire 9 | var reloading : bool = false 10 | var can_shoot : bool = true 11 | var can_shoot_secondary : bool = true 12 | 13 | # if homing sets target 14 | var target = null 15 | 16 | 17 | 18 | # stores various parameters for the weapon 19 | var sound_intensity = 1 20 | var primary_initial_ammo = 0 # The initial ammuntion cartidges for the gun 21 | var secondary_initial_ammo = 0 # The initial ammuntion cartidges for the gun 22 | var primary_ammo_id = 0 # kind of ammo for primary fire 23 | var secondary_ammo_id = 0 # kind of ammo for secondary fire 24 | # primary_uses; how much ammo we have in the gun (not total ammo) 25 | # secondary_uses; how much secondary ammo we have in the gun (not total ammo) 26 | var primary_magazine_size = 0 # how much ammo the primary magazine canhold. 27 | var secondary_magazine_size = 0 # how much ammo the secondary magazine canhold. 28 | 29 | 30 | 31 | var wielder : Node 32 | 33 | export var dual_wieldable = false 34 | var dual_wielding = false 35 | 36 | 37 | func setup(wieldee : Spatial) -> void: 38 | wielder = wieldee 39 | if get_parent() == null: 40 | wielder.add_child(self) 41 | elif get_parent()!=wieldee: 42 | get_parent().remove_child(self) 43 | wielder.add_child(self) 44 | 45 | 46 | func primary_use(_use : int = 0): 47 | pass 48 | 49 | func secondary_use(_use : int = 0): 50 | pass 51 | 52 | func secondary_release(): 53 | pass 54 | func primary_release(): 55 | pass 56 | 57 | # Reloads the weapon from the wielders inventory when called. 58 | func reload_primary(): 59 | if wielder.inventory.weapons.has(id): 60 | wielder.inventory.reload_weapon(id, false) #id = weapon id, secondary = false 61 | return 62 | 63 | func reload_secondary(): 64 | if wielder.inventory.weapons.has(id): 65 | wielder.inventory.reload_weapon(id, true) #id = weapon id, secondary = true 66 | return 67 | 68 | 69 | func ammo_check_primary(size = 1): 70 | if primary_uses >= size: 71 | primary_uses -= size 72 | return true 73 | else: 74 | reload_primary() 75 | return false 76 | 77 | 78 | func ammo_check_secondary(size = 1): 79 | if secondary_uses >= size: 80 | secondary_uses -= size 81 | return true 82 | else: 83 | reload_secondary() 84 | return false 85 | 86 | 87 | func dual_wield(): 88 | 89 | pass 90 | 91 | -------------------------------------------------------------------------------- /core/workstations/Workstation.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | class_name JOYWorkstation, "../../icons/workstation.png" 3 | 4 | """ 5 | Base class for the NPC Interactors, namely Workstations. 6 | This class contains methods that must be overriden. 7 | """ 8 | enum CATEGORY { 9 | WORK, 10 | FOOD, 11 | ENTERTAINMENT, 12 | PERSON, 13 | OTHERS 14 | } 15 | 16 | onready var timer = Timer.new() 17 | onready var timer2 = Timer.new() 18 | onready var pos = $NPCPosition 19 | 20 | export(float) var health = 100 21 | export(float) var progress_per_second = 1 22 | export(bool) var degrades_with_time = false 23 | export(float) var degradation = 0 24 | export(bool) var perma_death = true 25 | export(bool) var inmortal = false 26 | 27 | var available = true 28 | 29 | var progress : float = 0.0 30 | var in_queue_for_use : Array = [] 31 | var current_worker : Worker = null 32 | var lookdir : Vector3 = Vector3.ZERO 33 | var position : Vector3 = Vector3.ZERO 34 | export(bool) var usable_by_players = false 35 | export(bool) var uses_queue : bool = false 36 | export(bool) var call_best_first : bool = false 37 | export(bool) var gives_xp : bool = false 38 | export(int) var maximum_progress : int = 10 39 | export(bool) var is_available : bool = true 40 | export(CATEGORY) var category : int = CATEGORY.WORK 41 | export(String) var subcategory : String = "" 42 | export(Array, NodePath) var Exclude : Array = [] 43 | 44 | signal unusable(idx,something, something) 45 | signal just_fully_repaired() 46 | signal just_destroyed() 47 | 48 | 49 | func _enter_tree() -> void: 50 | add_to_group("Workstations") 51 | connect("body_entered", self, "_on_body_entered") 52 | set_active(true) 53 | 54 | func _ready() -> void: 55 | timer.name = "delay" 56 | timer.time_left = 0.5 57 | timer.autostart = false 58 | timer.connect("timeout",self,"on_timer") 59 | self.add_child(timer) 60 | if degrades_with_time: 61 | timer2.name = "damage" 62 | timer2.time_left = progress_per_second 63 | timer2.autostart = true 64 | timer2.connect("timeout",self,"on_damage_timer") 65 | self.add_child(timer2) 66 | 67 | if not usable_by_players: 68 | set_active(false) 69 | set_collision_mask_bit(16, true) 70 | set_collision_layer_bit(16, true) 71 | 72 | for path in Exclude: 73 | if path is Object: 74 | continue 75 | else: 76 | Exclude.append(get_node(path)) 77 | Exclude.erase(path) 78 | if pos: 79 | position = get_parent().to_local(to_global(pos.translation)) 80 | lookdir = (translation - pos.translation)/2 81 | 82 | func set_active(toggle : bool): 83 | if toggle: 84 | is_available = true 85 | else: 86 | is_available = false 87 | 88 | func check_for_next() -> void: 89 | progress = 0 90 | if not uses_queue: 91 | return 92 | if call_best_first: 93 | assign(select_best_from_queue()) 94 | else: 95 | assign(select_neareast()) 96 | 97 | func do_work(amount: float, experience : float) -> float: 98 | progress += (amount + 1 * experience)/100 99 | print(progress) 100 | if progress >= maximum_progress: 101 | is_available = true 102 | current_worker.stop_working(category) 103 | check_for_next() 104 | if gives_xp: 105 | return amount/100 106 | return 0.0 107 | 108 | func select_best_from_queue() -> Worker: 109 | var best_worker : Worker = null 110 | if in_queue_for_use.size() < 1: 111 | return null 112 | best_worker = in_queue_for_use[0] 113 | for worker in in_queue_for_use: 114 | if worker.experience > best_worker.experience: 115 | best_worker = worker 116 | return best_worker 117 | 118 | func select_neareast() -> Worker: 119 | var nearest_worker : Worker = null 120 | if in_queue_for_use.size() < 1: 121 | return null 122 | nearest_worker = in_queue_for_use[0] 123 | for worker in in_queue_for_use: 124 | if (worker.entity.translation - translation).length() < (nearest_worker.entity.translation - translation).length(): 125 | nearest_worker = worker 126 | return nearest_worker 127 | 128 | func assign(worker : Worker) -> void: 129 | if worker == null: 130 | return 131 | is_available = false 132 | current_worker = worker 133 | worker.emit_signal("workstation_assigned", position) 134 | 135 | func request_workstation(worker : Worker) -> bool: 136 | print("Workstation: request recived from ", worker) 137 | if get_parent() is JOYCharacter: 138 | if get_parent().get_component("AI handler") != null: 139 | if get_parent().get_component("AI handler").worker == worker: 140 | return false 141 | if uses_queue: 142 | in_queue_for_use.append(worker) 143 | return true 144 | elif is_available: 145 | assign(worker) 146 | return true 147 | else: 148 | print("Busy!") 149 | return false 150 | 151 | func _on_body_entered(entity) -> void: 152 | print("A worker arrived!") 153 | if entity == get_parent(): 154 | return 155 | var worker : Worker = entity.get_component("AI handler").worker 156 | if worker: 157 | if worker == current_worker: 158 | entity.get_component("NPCInput").get_navpath(translation) 159 | print("The worker has arrived") 160 | worker.start_working(self) 161 | _change_state_on_user(worker) 162 | 163 | func _change_state_on_user(worker : Worker): 164 | #This is meant for changing animation states, so it changes depending on the 165 | #type of workstation 166 | pass 167 | 168 | func on_timer(): 169 | available = not available 170 | 171 | func on_damage_timer(): 172 | health -= degradation 173 | 174 | func damage(mult = 1): 175 | timer.start() 176 | if available: 177 | health -= progress_per_second*mult 178 | 179 | func repair(mult = 1): 180 | timer.start() 181 | if available: 182 | health += progress_per_second*mult 183 | -------------------------------------------------------------------------------- /core/workstations/Workstation.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://joyeuse/core/workstations/Workstation.gd" type="Script" id=1] 4 | 5 | [sub_resource type="BoxShape" id=1] 6 | extents = Vector3( 0.581019, 1, 0.235292 ) 7 | 8 | [sub_resource type="SpatialMaterial" id=2] 9 | flags_transparent = true 10 | albedo_color = Color( 1, 0, 0, 0.415686 ) 11 | emission_enabled = true 12 | emission = Color( 0.2, 0.537255, 0, 1 ) 13 | emission_energy = 1.0 14 | emission_operator = 0 15 | emission_on_uv2 = false 16 | 17 | [sub_resource type="SphereMesh" id=3] 18 | material = SubResource( 2 ) 19 | flip_faces = true 20 | radial_segments = 8 21 | rings = 4 22 | 23 | [sub_resource type="SpatialMaterial" id=4] 24 | flags_transparent = true 25 | flags_unshaded = true 26 | albedo_color = Color( 0.890196, 0.611765, 0.0784314, 0.52549 ) 27 | 28 | [node name="Workstation" type="Area"] 29 | collision_layer = 0 30 | collision_mask = 0 31 | script = ExtResource( 1 ) 32 | display_info = "Example Workstation" 33 | title = "Work" 34 | 35 | [node name="CollisionShape" type="CollisionShape" parent="."] 36 | transform = Transform( 1.5264, 0, 0, 0, 1.5264, 0, 0, 0, 1.5264, 2.07061, 1, 0 ) 37 | shape = SubResource( 1 ) 38 | 39 | [node name="NPCPosition" type="Position3D" parent="."] 40 | transform = Transform( -4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 2.67144, 0.182675, 7.30611e-08 ) 41 | 42 | [node name="DebugShapes" type="Spatial" parent="."] 43 | 44 | [node name="MeshInstance4" type="MeshInstance" parent="DebugShapes"] 45 | transform = Transform( 0.162052, 0, 1.02141e-14, 0, 0.162052, 0, -1.02141e-14, 0, 0.162052, 0, 0.349, 0 ) 46 | mesh = SubResource( 3 ) 47 | material/0 = null 48 | 49 | [node name="MeshInstance" type="MeshInstance" parent="DebugShapes"] 50 | transform = Transform( 0.431875, 0, 4.08562e-14, 0, 0.431875, 0, -4.08562e-14, 0, 0.431875, 1.83768, -0.000324994, 7.30611e-08 ) 51 | mesh = SubResource( 3 ) 52 | material/0 = SubResource( 4 ) 53 | 54 | [node name="MeshInstance2" type="MeshInstance" parent="DebugShapes"] 55 | transform = Transform( 0.431875, 0, 4.08562e-14, 0, 0.431875, 0, -4.08562e-14, 0, 0.431875, 1.83768, 0.533675, 7.30611e-08 ) 56 | mesh = SubResource( 3 ) 57 | material/0 = SubResource( 4 ) 58 | 59 | [node name="MeshInstance3" type="MeshInstance" parent="DebugShapes"] 60 | transform = Transform( 0.431875, 0, 4.08562e-14, 0, 0.431875, 0, -4.08562e-14, 0, 0.431875, 1.83768, 1.04467, 7.30611e-08 ) 61 | mesh = SubResource( 3 ) 62 | material/0 = SubResource( 4 ) 63 | -------------------------------------------------------------------------------- /core/workstations/worker.gd: -------------------------------------------------------------------------------- 1 | class_name Worker 2 | 3 | const types = [ 4 | "WORK", 5 | "FOOD", 6 | "ENTERTAINMENT", 7 | "PERSON", 8 | "OTHERS" 9 | ] 10 | 11 | signal workstation_assigned(where) 12 | signal request_rejected() 13 | signal stopped_working(type) 14 | 15 | var working : bool = false 16 | var current_station : Area = null 17 | var experience : float = 0.0 18 | 19 | func start_working(station : Area): 20 | if working: 21 | return 22 | working = true 23 | current_station = station 24 | 25 | func stop_working(type : int): 26 | working = false 27 | current_station = null 28 | emit_signal("stopped_working", types[type]) 29 | 30 | func work(delta): 31 | if working: 32 | experience += current_station.do_work(1, experience) 33 | -------------------------------------------------------------------------------- /icons/Gravicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/icons/Gravicon.png -------------------------------------------------------------------------------- /icons/IA_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/icons/IA_icon.png -------------------------------------------------------------------------------- /icons/SH_SYSTEM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/icons/SH_SYSTEM.png -------------------------------------------------------------------------------- /icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/icons/icon.png -------------------------------------------------------------------------------- /icons/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/icons/player.png -------------------------------------------------------------------------------- /icons/workstation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiseRobotRise/JoyeuseCodeBase/8aa79f9ccba5bd94756c0db59405e2765783568d/icons/workstation.png -------------------------------------------------------------------------------- /pl3d/3RDPersCamera.gd: -------------------------------------------------------------------------------- 1 | extends Camera 2 | 3 | # class member variables go here, for example: 4 | # var a = 2 5 | # var b = "textvar" 6 | 7 | func _ready(): 8 | pass 9 | 10 | func _process(delta): 11 | translation = get_node("../CameraCollision").translation 12 | -------------------------------------------------------------------------------- /pl3d/3RDPersonCamera.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | # class member variables go here, for example: 4 | var linear_velocity = Vector3() 5 | var gravity = Vector3() 6 | var Target = Vector3() 7 | var originalpos = Vector3() 8 | var origin = Vector3() 9 | var cameramovement 10 | func _ready(): 11 | gravity = get_parent().get_parent().gravity 12 | cameramovement = get_node("../..").fixpos 13 | 14 | func _process(delta): 15 | linear_velocity = move_and_slide(linear_velocity,-gravity.normalized()) 16 | Target = get_node("../../target").translation 17 | origin = get_node("../../CameraOrigin") 18 | translation.x = clamp(translation.x, Target.x-5, Target.x+5) 19 | translation.y = clamp(translation.y, Target.y-5, Target.y+5) 20 | translation.z = clamp(translation.z, Target.z-5, Target.z+5) 21 | 22 | 23 | 24 | if translation != Vector3(-0.001374,0.516047,1.64668) and not (is_on_floor() or is_on_ceiling() or is_on_wall()): 25 | if translation.x <= -0.001374-0.2: 26 | translation.x = translation.x + delta 27 | if translation.x >= -0.001374+0.2: 28 | translation.x = translation.x - delta 29 | 30 | if translation.y <= 0.516047-0.2: 31 | translation.y = translation.y + delta 32 | if translation.y >= 0.516047+0.2: 33 | translation.y = translation.y - delta 34 | 35 | if translation.z <= 1.64668-0.2: 36 | translation.z = translation.z + delta 37 | if translation.z >= 1.64668+0.2: 38 | translation.z = translation.z - delta 39 | 40 | 41 | -------------------------------------------------------------------------------- /pl3d/Camera.gd: -------------------------------------------------------------------------------- 1 | 2 | extends Camera 3 | 4 | # Member variables 5 | var collision_exception = [] 6 | export var min_distance = 0.5 7 | export var max_distance = 4.0 8 | export var angle_v_adjust = 0.0 9 | export var autoturn_ray_aperture = 25 10 | export var autoturn_speed = 50 11 | var max_height = 2.0 12 | var min_height = 0 13 | 14 | func _physics_process(dt): 15 | var target = get_parent().get_global_transform().origin 16 | var pos = get_global_transform().origin 17 | var up = -(get_parent().get_parent().gravity) 18 | 19 | var delta = pos - target 20 | 21 | # Regular delta follow 22 | 23 | # Check ranges 24 | if (delta.length() < min_distance): 25 | delta = delta.normalized()*min_distance 26 | elif (delta.length() > max_distance): 27 | delta = delta.normalized()*max_distance 28 | 29 | # Check upper and lower height 30 | if (delta.y > max_height): 31 | delta.y = max_height 32 | if (delta.y < min_height): 33 | delta.y = min_height 34 | 35 | # Check autoturn 36 | var ds = PhysicsServer.space_get_direct_state(get_world().get_space()) 37 | 38 | var col_left = ds.intersect_ray(target, target + Basis(up, deg2rad(autoturn_ray_aperture)).xform(delta), collision_exception) 39 | var col = ds.intersect_ray(target, target + delta, collision_exception) 40 | var col_right = ds.intersect_ray(target, target + Basis(up, deg2rad(-autoturn_ray_aperture)).xform(delta), collision_exception) 41 | 42 | if (!col.empty()): 43 | # If main ray was occluded, get camera closer, this is the worst case scenario 44 | delta = col.position - target 45 | elif (!col_left.empty() and col_right.empty()): 46 | # If only left ray is occluded, turn the camera around to the right 47 | delta = Basis(up, deg2rad(-dt*autoturn_speed)).xform(delta) 48 | elif (col_left.empty() and !col_right.empty()): 49 | # If only right ray is occluded, turn the camera around to the left 50 | delta = Basis(up, deg2rad(dt*autoturn_speed)).xform(delta) 51 | else: 52 | # Do nothing otherwise, left and right are occluded but center is not, so do not autoturn 53 | pass 54 | 55 | # Apply lookat 56 | if (delta == Vector3()): 57 | delta = (pos - target).normalized()*0.0001 58 | 59 | pos = target + delta 60 | 61 | look_at(target, up) 62 | 63 | # Turn a little up or down 64 | var t = get_transform() 65 | t.basis = Basis(t.basis[0], deg2rad(angle_v_adjust))*t.basis 66 | set_transform(t) 67 | 68 | 69 | func _ready(): 70 | # Find collision exceptions for ray 71 | var node = self 72 | while(node): 73 | if (node is RigidBody): 74 | collision_exception.append(node.get_rid()) 75 | break 76 | else: 77 | node = node.get_parent() 78 | set_physics_process(true) 79 | # This detaches the camera transform from the parent spatial node 80 | set_as_toplevel(true) -------------------------------------------------------------------------------- /pl3d/FPSCamera.gd: -------------------------------------------------------------------------------- 1 | extends Camera 2 | 3 | # class member variables go here, for example: 4 | # var a = 2 5 | var yaw = 0.0 6 | var pitch = 0.0 7 | export(float) var view_sensitivity = 0.5 8 | export(bool) var restrictaxis = false 9 | var originaltranslation = Vector3() 10 | var originalrotation = Vector3() 11 | var time = 0.0 12 | var Znoice = 0.0 13 | var Zholder = 0.0 14 | var v_off = 0.0 15 | 16 | 17 | 18 | 19 | 20 | 21 | func _ready(): 22 | set_process_input(true) 23 | originaltranslation = Vector3(translation.x,translation.y,translation.z) 24 | originalrotation = Vector3(rotation_degrees.x,rotation_degrees.y,rotation_degrees.z) 25 | func bobbing_effect(time, speed, delta): 26 | if speed == null: 27 | speed = 0 28 | if speed >= 0.1 and get_parent().get_parent().is_on_floor(): 29 | var Oscillation = sin(time * speed*3.1416) 30 | 31 | v_offset = clamp(v_offset + delta*0.5*Oscillation, -0.2,0.2) 32 | #calculate_z_rotation(Oscillation, delta) 33 | 34 | 35 | else: 36 | if v_offset < -0.001: 37 | v_offset += 0.01 38 | if v_offset > 0.001: 39 | v_offset -= 0.01 40 | if rotation_degrees.z < -0.01: 41 | Znoice += 10*delta 42 | if rotation_degrees.z > 0.01: 43 | Znoice -= 10*delta 44 | else: 45 | pass 46 | 47 | 48 | 49 | func _input(ev): 50 | #view_sensitivity = get_parent().Player_Node.view_sensitivity 51 | if (ev is InputEventMouseMotion): 52 | yaw = yaw - ev.relative.x * view_sensitivity 53 | pitch = restrict(pitch - ev.relative.y * view_sensitivity) 54 | 55 | 56 | 57 | 58 | 59 | 60 | func _process(delta): 61 | yaw = yaw - (Input.get_action_strength("look_right")-Input.get_action_strength("look_left"))* view_sensitivity*3 62 | pitch = restrict(pitch - (Input.get_action_strength("look_down")-Input.get_action_strength("look_up")) * view_sensitivity*3) 63 | rotation_degrees.x = pitch 64 | rotation_degrees.y = yaw 65 | 66 | func restrict(axis : float): 67 | if restrictaxis: 68 | return clamp(axis,-0.5,0.5) 69 | return clamp(axis, -70, 70) 70 | 71 | func calculate_z_rotation(Oscc, delta): 72 | 73 | 74 | rotation_degrees.z = Znoice*delta 75 | -------------------------------------------------------------------------------- /pl3d/Player3d.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | 3 | # Member variables 4 | const ANIM_FLOOR = 0 5 | const ANIM_AIR_UP = 1 6 | const ANIM_AIR_DOWN = 2 7 | 8 | const SHOOT_TIME = 1.5 9 | const SHOOT_SCALE = 2 10 | 11 | const CHAR_SCALE = Vector3(0.3, 0.3, 0.3) 12 | var health2 13 | var facing_dir = Vector3(1, 0, 0) 14 | var movement_dir = Vector3() 15 | var jumping = false 16 | export(float) var health = 100 17 | var aimrotation = Vector3() 18 | export(int) var turn_speed = 40 19 | export(bool) var keep_jump_inertia = true 20 | export(bool) var air_idle_deaccel = false 21 | export(bool) var fixed_up = true 22 | export(float) var accel = 19.0 23 | export(float) var deaccel = 14.0 24 | export(float) var sharp_turn_threshold = 140 25 | export(float) var JumpHeight = 7.0 26 | 27 | export(int) var Team = 1 28 | export(bool) var AllowChangeCamera = false 29 | export(bool) var FPSCamera = true 30 | export(bool) var thRDPersCamera = false 31 | export(float) var fixpos = 0.5 32 | export(bool) var RPGCamera = false 33 | export(bool) var TopDownCamera = false 34 | var translationcamera 35 | 36 | var prev_shoot = false 37 | var ismoving = false 38 | var up 39 | 40 | 41 | 42 | var shoot_blend = 0 43 | #Signals 44 | signal hit 45 | signal shooting 46 | signal dead 47 | signal HasObjective 48 | signal paused 49 | signal reload_weapon 50 | 51 | 52 | #Options 53 | export(float) var WALKSPEED = 3.1 54 | export(float) var RUNSPEED = 4.5 55 | export(PackedScene) var Playermodel 56 | export(bool) var active=true 57 | export(float) var view_sensitivity = 5 58 | export var weight= 1 59 | 60 | ##Physics 61 | export(float) var grav = 9.8 62 | var gravity = Vector3(0,-grav,0) 63 | 64 | var max_speed = 0.0 65 | var velocity = Vector3() 66 | var linear_velocity=Vector3() 67 | var hspeed 68 | 69 | 70 | ##Networking 71 | slave var slave_translation 72 | slave var slave_transform 73 | slave var slave_linear_vel 74 | 75 | 76 | ##Weapons and Object Handling 77 | var inventory = [] # inventory array to store the objects we are currently holding 78 | var arsenal = [] # inventory array to store the weapons we are currently holding 79 | var arsenal_links = [] 80 | var weapon_point 81 | 82 | #Rotates the model to where the camera points 83 | func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn): 84 | var n = p_target # Normal 85 | var t = n.cross(current_gn).normalized() 86 | 87 | var x = n.dot(p_facing) 88 | var y = t.dot(p_facing) 89 | 90 | var ang = atan2(y,x) 91 | 92 | if (abs(ang) < 0.001): # Too small 93 | return p_facing 94 | 95 | var s = sign(ang) 96 | ang = ang*s 97 | var turn = ang*p_adjust_rate*p_step 98 | var a 99 | if (ang < turn): 100 | a = ang 101 | else: 102 | a = turn 103 | ang = (ang - a)*s 104 | 105 | return (n*cos(ang) + t*sin(ang))*p_facing.length() 106 | 107 | func _process(delta): 108 | 109 | #print(inventory) 110 | #holding is called every loop to refresh whatever gun is being held and hide the gun that was put away. 111 | holding() 112 | 113 | # if the node has a HUD 114 | if self.has_node("HUD"): 115 | get_node("HUD").health = health 116 | get_node("HUD") 117 | # if there is a weapon in hand 118 | if is_held().size() > 0: 119 | # update the HUD with its proper name 120 | $HUD/Inventory/VBoxContainer/current_weapon.set_text(is_held()[0].identity) 121 | $HUD/Inventory/VBoxContainer/in_magazine.set_text(str(is_held()[0].in_magazine)) 122 | $HUD/Inventory/VBoxContainer/ammo.set_text(str(inventory[is_held()[0].primary_ammo_id])) 123 | 124 | func _physics_process(delta): 125 | # var d = 1.0 - delta*state.get_total_density() 126 | # if (d < 0): 127 | # d = 0 128 | #Changes acceleration and max speed. 129 | if (Input.is_action_pressed("run")): 130 | max_speed=RUNSPEED 131 | else: 132 | max_speed=WALKSPEED 133 | 134 | 135 | linear_velocity += gravity*delta/weight # Apply gravity 136 | 137 | var anim = ANIM_FLOOR 138 | if fixed_up: 139 | up = Vector3(0,1,0) # (up is against gravity) 140 | else: 141 | up = -gravity.normalized() 142 | var vertical_velocity = up.dot(linear_velocity) # Vertical velocity 143 | var horizontal_velocity = linear_velocity - up*vertical_velocity # Horizontal velocity 144 | var hdir = horizontal_velocity.normalized() # Horizontal direction 145 | hspeed = horizontal_velocity.length() # Horizontal speed 146 | 147 | 148 | 149 | #Movement 150 | var dir = Vector3() # Where does the player intend to walk to 151 | 152 | 153 | #THIS BLOCK IS INTENDED FOR FPS CONTROLLER USE ONLY 154 | var aim = $Pivot/FPSCamera.get_global_transform().basis 155 | if (is_network_master() or not get_tree().has_network_peer()): 156 | $Pivot/FPSCamera.make_current() 157 | 158 | if Input.is_action_pressed("shoot"): 159 | primary_fire() 160 | 161 | if Input.is_action_pressed("shoot_secondary"): 162 | secondary_fire() 163 | 164 | if Input.is_action_just_released("shoot_secondary"): 165 | secondary_release() 166 | 167 | if Input.is_action_just_pressed("last_weapon"): 168 | last_weapon() 169 | 170 | if Input.is_action_just_pressed("next_weapon"): 171 | next_weapon() 172 | 173 | if (Input.is_action_pressed("move_forwards")): 174 | dir -= aim[2] 175 | ismoving = true 176 | else: 177 | ismoving = false 178 | if (Input.is_action_pressed("move_backwards")): 179 | dir += aim[2] 180 | ismoving = true 181 | else: 182 | ismoving = false 183 | if (Input.is_action_pressed("move_left")): 184 | dir -= aim[0] 185 | 186 | $Pivot/FPSCamera.Znoice = 1*hspeed 187 | 188 | if (Input.is_action_pressed("move_right")): 189 | dir += aim[0] 190 | $Pivot/FPSCamera.Znoice = -1*hspeed 191 | rset("slave_linear_vel", linear_velocity) 192 | rset("slave_translation", translation) 193 | rset("slave_transform", $Yaw.transform) 194 | else: 195 | $Yaw.transform = slave_transform 196 | translation = slave_translation 197 | linear_velocity = slave_linear_vel 198 | 199 | var jump_attempt = Input.is_action_pressed("jump") 200 | var shoot_attempt = Input.is_action_pressed("shoot") 201 | #END OF THE BLOCK 202 | 203 | 204 | var target_dir = (dir - up*dir.dot(up)).normalized() 205 | 206 | if (is_on_floor()): #Only lets the character change it's facing direction when it's on the floor. 207 | var sharp_turn = hspeed > 0.1 and rad2deg(acos(target_dir.dot(hdir))) > sharp_turn_threshold 208 | 209 | if (dir.length() > 0.1 and !sharp_turn): 210 | if (hspeed > 0.001): 211 | #linear_dir = linear_h_velocity/linear_vel 212 | #if (linear_vel > brake_velocity_limit and linear_dir.dot(ctarget_dir) < -cos(Math::deg2rad(brake_angular_limit))) 213 | # brake = true 214 | #else 215 | hdir = adjust_facing(hdir, target_dir, delta, 1.0/hspeed*turn_speed, up) 216 | facing_dir = hdir 217 | 218 | else: 219 | hdir = target_dir 220 | 221 | 222 | if (hspeed < max_speed): 223 | hspeed += accel*delta 224 | else: 225 | if hspeed > 0: 226 | hspeed -= deaccel*delta 227 | else: 228 | hspeed -= deaccel*delta 229 | if (hspeed < 0): 230 | hspeed = 0 231 | 232 | horizontal_velocity = hdir*hspeed 233 | 234 | #Yaw is a placeholder for the actual model that is going to be used 235 | var mesh_xform = $Yaw.get_transform() 236 | var facing_mesh = -mesh_xform.basis[0].normalized() 237 | facing_mesh = (facing_mesh - up*facing_mesh.dot(up)).normalized() 238 | 239 | if (hspeed>0): 240 | facing_mesh = adjust_facing(facing_mesh, target_dir, delta, 1.0/hspeed*turn_speed, up) 241 | var m3 = Basis(-facing_mesh, up, -facing_mesh.cross(up).normalized()).scaled(CHAR_SCALE) 242 | 243 | $Yaw.set_transform(Transform(m3, mesh_xform.origin)) 244 | 245 | if (not jumping and jump_attempt): 246 | vertical_velocity = JumpHeight 247 | jumping = true 248 | #get_node("sound_jump").play() 249 | else: 250 | if (vertical_velocity > 0): 251 | pass 252 | #print(ANIM_AIR_UP) #Placeholder 253 | else: 254 | pass 255 | #print(ANIM_AIR_DOWN) 256 | if (dir.length() > 0.1): 257 | horizontal_velocity += target_dir*accel*delta 258 | if (horizontal_velocity.length() > max_speed): 259 | horizontal_velocity = horizontal_velocity.normalized()*max_speed 260 | else: 261 | if (air_idle_deaccel): 262 | hspeed = hspeed - (deaccel*0.2)*delta 263 | if (hspeed < 0): 264 | hspeed = 0 265 | 266 | horizontal_velocity = hdir*hspeed 267 | 268 | if (jumping and vertical_velocity < 0): 269 | jumping = false 270 | 271 | linear_velocity = horizontal_velocity + up*vertical_velocity 272 | 273 | if (is_on_floor()): 274 | movement_dir = linear_velocity 275 | 276 | linear_velocity = move_and_slide(linear_velocity,-gravity.normalized()) 277 | 278 | if (shoot_blend > 0): 279 | shoot_blend -= delta*SHOOT_SCALE 280 | if (shoot_blend < 0): 281 | shoot_blend = 0 282 | 283 | #if (shoot_attempt and not prev_shoot): 284 | #shoot_blend = SHOOT_TIME 285 | #var bullet = preload("res://bullet.scn").instance() 286 | # bullet.set_transform(get_node("Armature/bullet").get_global_transform().orthonormalized()) 287 | # get_parent().add_child(bullet) 288 | #bullet.set_linear_velocity(get_node("Armature/bullet").get_global_transform().basis[2].normalized()*20) 289 | #bullet.add_collision_exception_with(self) # Add it to bullet 290 | #get_node("sound_shoot").play() 291 | 292 | prev_shoot = shoot_attempt 293 | 294 | if AllowChangeCamera: 295 | if Input.is_action_pressed("cameraFPS"): 296 | $Pivot/FPSCamera.make_current() 297 | $Pivot/FPSCamera.restrictaxis = false 298 | 299 | 300 | if Input.is_action_pressed("camera3RD"): 301 | get_node("Pivot/3RDPersCamera").make_current() 302 | $Pivot/FPSCamera.restrictaxis = false 303 | 304 | #if Input.is_action_pressed("cameraPlat"): 305 | # get_node("target/camera").make_current() 306 | # $Pivot/FPSCamera.restrictaxis = true 307 | 308 | 309 | if Input.is_action_pressed("cameraTop"): 310 | $TopDownCamera.make_current() 311 | $Pivot/FPSCamera.restrictaxis = true 312 | 313 | 314 | #if (is_on_floor()): 315 | #get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed/max_speed) 316 | 317 | #get_node("AnimationTreePlayer").transition_node_set_current("state", anim) 318 | #get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0)) 319 | # state.set_angular_velocity(Vector3()) 320 | aimrotation = $Pivot/FPSCamera.rotation_degrees 321 | translationcamera=$Pivot/FPSCamera.get_global_transform().origin 322 | 323 | 324 | func _ready(): 325 | weapon_point = $Pivot/weapon_point 326 | health2 = health 327 | #get_node("AnimationTreePlayer").set_active(true) 328 | set_process_input(true) 329 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 330 | 331 | for i in range(10): 332 | inventory.append(0) 333 | arsenal.append(0) 334 | arsenal_links.append(0) 335 | 336 | func set_player_name(new_name): 337 | get_node("label").set_text(new_name) 338 | 339 | #returns the current weapons 340 | func is_held(): 341 | 342 | var held = $Pivot/weapon_point.get_children() 343 | 344 | return held 345 | 346 | # called to update the visibility of objects currently in inventory. 347 | func holding(): 348 | 349 | var holding = is_held() 350 | #print(is_held()) 351 | for i in range(holding.size()): 352 | if i == 0: 353 | holding[i].set_visible(true) 354 | else: 355 | holding[i].set_visible(false) 356 | 357 | func primary_fire(): 358 | #print("attempting to fire!") 359 | var held_weapon = weapon_point.get_children() 360 | if held_weapon.size() > 0: 361 | if held_weapon[0].has_method("primary_fire"): 362 | #print("click!") 363 | held_weapon[0].primary_fire() 364 | 365 | func secondary_fire(): 366 | #print("attempting to fire!") 367 | var held_weapon = weapon_point.get_children() 368 | if held_weapon.size() > 0: 369 | if held_weapon[0].has_method("primary_fire"): 370 | #print("click!") 371 | held_weapon[0].secondary_fire() 372 | 373 | func secondary_release(): 374 | #print("attempting to fire!") 375 | var held_weapon = weapon_point.get_children() 376 | if held_weapon.size() > 0: 377 | if held_weapon[0].has_method("secondary_release"): 378 | #print("click!") 379 | held_weapon[0].secondary_release() 380 | 381 | # when an object on the ground triggers this it passes the object that it is, the kind of object (weapon, ammo, etc) and what id it is. 382 | func pick_up(object, kind = "default", id = 0): 383 | 384 | 385 | match kind: 386 | "ammo": 387 | inventory.add_ammo(id, 1) 388 | return true 389 | "weapon": 390 | # does the player have this item yet? 391 | # checks the player arsenal to see if it is already there. 392 | if arsenal[id] == 0: #no 393 | # increment this item inventory id 394 | arsenal[id] += 1 395 | 396 | # add object to holding node 397 | var pickup = object.instance() 398 | 399 | # tell the weapon who we are (to account for who hit who, etc). 400 | pickup.setup(self) 401 | arsenal_links[id] = pickup 402 | 403 | $Pivot/weapon_point.add_child(pickup) 404 | return true 405 | else: 406 | var pickup = object.instance() 407 | if pickup.dual_wieldable: 408 | arsenal_links[id].dual_wield() 409 | return false 410 | 411 | 412 | func last_weapon(): 413 | var held = is_held() 414 | var size = is_held().size() 415 | $Pivot/weapon_point.move_child(held[size-1], 0) 416 | 417 | func next_weapon(): 418 | var held = is_held() 419 | var size = is_held().size() 420 | $Pivot/weapon_point.move_child(held[0], size) 421 | -------------------------------------------------------------------------------- /pl3d/Player3d.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=18 format=2] 2 | 3 | [ext_resource path="res://Joyeuse/Basics/pl3d/Player3d.gd" type="Script" id=1] 4 | [ext_resource path="res://Joyeuse/Basics/pl3d/TopDownCamera.gd" type="Script" id=2] 5 | [ext_resource path="res://weapons/fusion_pistol.gd" type="Script" id=3] 6 | [ext_resource path="res://Joyeuse/Basics/pl3d/FPSCamera.gd" type="Script" id=4] 7 | [ext_resource path="res://Joyeuse/Basics/pl3d/3RDPersCamera.gd" type="Script" id=5] 8 | [ext_resource path="res://Joyeuse/Basics/pl3d/3RDPersonCamera.gd" type="Script" id=6] 9 | [ext_resource path="res://Joyeuse/Basics/pl3d/label.gd" type="Script" id=7] 10 | [ext_resource path="res://assets/ui/Player_GUI.tscn" type="PackedScene" id=8] 11 | [ext_resource path="res://assets/green-crosshair-png-4.png" type="Texture" id=9] 12 | 13 | 14 | [sub_resource type="CapsuleShape" id=1] 15 | radius = 0.39852 16 | height = 1.2 17 | 18 | [sub_resource type="CapsuleMesh" id=2] 19 | radius = 0.348 20 | 21 | [sub_resource type="SpatialMaterial" id=3] 22 | albedo_color = Color( 0.773438, 0.126892, 0.126892, 1 ) 23 | roughness = 0.0 24 | 25 | [sub_resource type="SphereMesh" id=4] 26 | 27 | [sub_resource type="SpatialMaterial" id=5] 28 | roughness = 0.0 29 | 30 | [sub_resource type="SphereShape" id=6] 31 | radius = 0.245702 32 | 33 | [sub_resource type="GDScript" id=7] 34 | script/source = "extends Area 35 | 36 | func _ready(): 37 | var target = get_tree().get_root().get_node(\"HUD/Health|Radar/Radar\") 38 | connect(\"body_entered\", target, \"_on_body_entered\") 39 | connect(\"body_exited\" , target, \"_on_body_exit\") 40 | pass 41 | " 42 | 43 | [sub_resource type="SphereShape" id=8] 44 | radius = 20.0 45 | 46 | [node name="Player" type="KinematicBody" groups=[ 47 | "Player", 48 | ]] 49 | script = ExtResource( 1 ) 50 | health = null 51 | turn_speed = null 52 | keep_jump_inertia = null 53 | air_idle_deaccel = null 54 | fixed_up = null 55 | accel = null 56 | deaccel = null 57 | sharp_turn_threshold = null 58 | JumpHeight = null 59 | Team = null 60 | AllowChangeCamera = null 61 | FPSCamera = null 62 | thRDPersCamera = null 63 | fixpos = null 64 | RPGCamera = null 65 | TopDownCamera = null 66 | WALKSPEED = null 67 | RUNSPEED = null 68 | active = null 69 | view_sensitivity = 0.3 70 | weight = null 71 | grav = null 72 | 73 | [node name="Collision" type="CollisionShape" parent="."] 74 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0.000270128, 0.991905, -8.33273e-05 ) 75 | shape = SubResource( 1 ) 76 | 77 | [node name="Yaw" type="Spatial" parent="."] 78 | editor/display_folded = true 79 | visible = false 80 | 81 | [node name="MeshInstance" type="MeshInstance" parent="Yaw"] 82 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 1.05647, 0 ) 83 | mesh = SubResource( 2 ) 84 | material/0 = SubResource( 3 ) 85 | 86 | [node name="MeshInstance2" type="MeshInstance" parent="Yaw"] 87 | transform = Transform( 0.246564, 0, 0, 0, -0.0585672, -0.239508, 0, 0.239508, -0.0585672, 0, 1.59028, -1.27401 ) 88 | mesh = SubResource( 4 ) 89 | material/0 = SubResource( 5 ) 90 | 91 | [node name="TopDownCamera" type="Camera" parent="."] 92 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 14.246, 0 ) 93 | current = true 94 | script = ExtResource( 2 ) 95 | 96 | [node name="target" type="Spatial" parent="."] 97 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26883, 0 ) 98 | 99 | [node name="CameraOrigin" type="Spatial" parent="."] 100 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.489479, 2.14343, 1.44329 ) 101 | 102 | [node name="Pivot" type="Position3D" parent="."] 103 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.58644, 0 ) 104 | 105 | [node name="weapon_point" type="Position3D" parent="Pivot"] 106 | transform = Transform( 1, 0, 0, 0, 0.999999, 0.00161846, 0, -0.00161846, 0.999999, 0, -0.391506, -0.342788 ) 107 | script = ExtResource( 3 ) 108 | 109 | [node name="FPSCamera" type="Camera" parent="Pivot"] 110 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0436552, -0.265905 ) 111 | current = true 112 | fov = 90.0 113 | script = ExtResource( 4 ) 114 | 115 | [node name="SpotLight" type="SpotLight" parent="Pivot/FPSCamera"] 116 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0102543, 0.265905 ) 117 | 118 | [node name="3RDPersCamera" type="Camera" parent="Pivot"] 119 | transform = Transform( 0.997858, -0.0247958, 0.0605398, 0.0132274, 0.982746, 0.184489, -0.0640698, -0.183292, 0.980968, 0.497637, 0.54344, 1.31724 ) 120 | fov = 90.0 121 | script = ExtResource( 5 ) 122 | 123 | [node name="CameraCollision" type="KinematicBody" parent="Pivot"] 124 | transform = Transform( 0.999903, -1.86265e-09, -0.0139474, -0.00282001, 0.979347, -0.202169, 0.0136593, 0.202189, 0.979251, -0.00137392, 0.472392, 1.50019 ) 125 | input_ray_pickable = false 126 | script = ExtResource( 6 ) 127 | 128 | [node name="CollisionShape" type="CollisionShape" parent="Pivot/CameraCollision"] 129 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.476892, 0.0157118, -0.0391517 ) 130 | shape = SubResource( 6 ) 131 | 132 | [node name="label" type="Label" parent="."] 133 | margin_right = 46.0 134 | margin_bottom = 14.0 135 | rect_scale = Vector2( 3, 3 ) 136 | text = "Default" 137 | align = 1 138 | script = ExtResource( 7 ) 139 | 140 | [node name="TextPoint" type="Position3D" parent="."] 141 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.07561, 0 ) 142 | 143 | [node name="HUD" parent="." instance=ExtResource( 8 )] 144 | radarpath = NodePath("") 145 | 146 | [node name="Inventory" type="ColorRect" parent="HUD"] 147 | anchor_left = 1.0 148 | anchor_top = 1.0 149 | anchor_right = 1.0 150 | anchor_bottom = 1.0 151 | margin_left = 84.0 152 | margin_top = 145.0 153 | margin_right = 584.0 154 | margin_bottom = 310.0 155 | color = Color( 0.00854492, 0.15625, 0, 0.491726 ) 156 | 157 | [node name="VBoxContainer" type="VBoxContainer" parent="HUD/Inventory"] 158 | margin_right = 40.0 159 | margin_bottom = 40.0 160 | 161 | [node name="current_weapon" type="Label" parent="HUD/Inventory/VBoxContainer"] 162 | margin_right = 103.0 163 | margin_bottom = 14.0 164 | text = "Current Weapon" 165 | 166 | [node name="in_magazine" type="Label" parent="HUD/Inventory/VBoxContainer"] 167 | margin_top = 18.0 168 | margin_right = 103.0 169 | margin_bottom = 32.0 170 | text = "Current Weapon" 171 | 172 | [node name="ammo" type="Label" parent="HUD/Inventory/VBoxContainer"] 173 | margin_top = 36.0 174 | margin_right = 103.0 175 | margin_bottom = 50.0 176 | text = "Current Weapon" 177 | 178 | [node name="TextureRect" type="TextureRect" parent="HUD"] 179 | modulate = Color( 1, 1, 1, 0.353608 ) 180 | anchor_left = 0.5 181 | anchor_top = 0.5 182 | anchor_right = 0.5 183 | anchor_bottom = 0.5 184 | margin_left = -13.0 185 | margin_top = -12.0 186 | margin_right = 12.0 187 | margin_bottom = 11.0 188 | texture = ExtResource( 9 ) 189 | expand = true 190 | 191 | [node name="Area" type="Area" parent="."] 192 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 ) 193 | input_ray_pickable = false 194 | script = SubResource( 7 ) 195 | 196 | [node name="CollisionShape" type="CollisionShape" parent="Area"] 197 | shape = SubResource( 8 ) 198 | 199 | [editable path="HUD"] 200 | -------------------------------------------------------------------------------- /pl3d/TopDownCamera.gd: -------------------------------------------------------------------------------- 1 | extends Camera 2 | 3 | # class member variables go here, for example: 4 | # var a = 2 5 | # var b = "textvar" 6 | 7 | func _ready(): 8 | pass 9 | 10 | func _process(delta): 11 | rotation_degrees.x = clamp(rotation_degrees.x,-90,-90) 12 | rotation_degrees.y = clamp(rotation_degrees.y,0,0) 13 | rotation_degrees.z = clamp(rotation_degrees.z,0,0) 14 | -------------------------------------------------------------------------------- /pl3d/label.gd: -------------------------------------------------------------------------------- 1 | extends Label 2 | 3 | 4 | sync func _process(delta): 5 | 6 | var pos = get_node("../TextPoint").to_global(get_node("../TextPoint").translation) 7 | if (get_viewport().get_camera().is_position_behind( pos )): 8 | visible = false 9 | else: 10 | show() 11 | var positione = get_viewport().get_camera().unproject_position(pos) 12 | positione = positione -(rect_size*rect_scale/2) 13 | rect_position = (positione) 14 | print(rect_position) 15 | 16 | #rect_scale = int(3/(camera.translation.distance_to(pos)))*Vector2(1,1) 17 | -------------------------------------------------------------------------------- /travis.yml: -------------------------------------------------------------------------------- 1 | services: 2 | - docker 3 | 4 | env: 5 | # Use this to set your game's name. It is being used 6 | # throughout this file for naming exported artifacts. 7 | - GAME_NAME="Joyeuse" 8 | 9 | install: 10 | - docker pull gamedrivendesign/godot-export 11 | 12 | # Each of the following lines exports the game for a given platform. 13 | # You can specify the platform in the EXPORT_NAME variable 14 | # The exported game will be written to the folder specified after the second "-v" flag 15 | # "-v $(pwd)/output/html5:/build/output" writes the exported game to the "output/html5" folder. 16 | script: 17 | - docker run -e EXPORT_NAME="HTML5" -e OUTPUT_FILENAME="index.html" -v $(pwd):/build/src -v $(pwd)/output/html5:/build/output gamedrivendesign/godot-export 18 | - docker run -e EXPORT_NAME="Linux/X11" -e OUTPUT_FILENAME="${GAME_NAME}" -v $(pwd):/build/src -v $(pwd)/output/linux:/build/output gamedrivendesign/godot-export 19 | - docker run -e EXPORT_NAME="Windows Desktop" -e OUTPUT_FILENAME="${GAME_NAME}.exe" -v $(pwd):/build/src -v $(pwd)/output/windows:/build/output gamedrivendesign/godot-export 20 | - docker run -e EXPORT_NAME="Mac OSX" -e OUTPUT_FILENAME="${GAME_NAME}-mac.zip" -v $(pwd):/build/src -v $(pwd)/output/mac:/build/output gamedrivendesign/godot-export 21 | 22 | # Now comes deployment related code. 23 | # To make this work, you need to set a GITHUB_TOKEN environment variable through 24 | # the TravisCI web ui. For more information take a look at the TravisCI docs: 25 | # https://docs.travis-ci.com/user/deployment/pages/#Setting-the-GitHub-token 26 | 27 | # This creates zip files from the exported game builds for the 28 | # three desktop platforms 29 | before_deploy: 30 | - zip -j "${GAME_NAME}-linux.zip" output/linux/* 31 | - zip -j "${GAME_NAME}-windows.zip" output/windows/* 32 | # No need to zip the mac game, because it already is a zip 33 | - cp -R output/mac/* . 34 | 35 | deploy: 36 | # The following block is responsible to upload the zip files 37 | # created above to GitHub Releases whenever a new git tag 38 | # is created. 39 | - provider: releases 40 | skip-cleanup: true 41 | api_key: $GITHUB_TOKEN 42 | file: 43 | - "${GAME_NAME}-linux.zip" 44 | - "${GAME_NAME}-windows.zip" 45 | - "${GAME_NAME}-mac.zip" 46 | on: 47 | # Create GitHub Releases for new git tags 48 | # regardless of the branch. 49 | all_branches: true 50 | tags: true 51 | 52 | # The following block is responsible for pushing the HTML5 version of the game 53 | # to GitHub Pages. To do so, Travis will commit the contents specified in "local-dir" 54 | # to a "gh-pages" branch in your repository. It will then be accessible at: 55 | # username.github.io/reponame if your repo is at github.com/username/reponame. 56 | - provider: pages 57 | skip-cleanup: true 58 | github-token: $GITHUB_TOKEN 59 | local-dir: output/html5 60 | on: 61 | # This will only update the game with new commits from the master branch 62 | # You can optionally only update the game on new git tags. 63 | branch: master 64 | # tags: true --------------------------------------------------------------------------------