diff options
| author | Anson Bridges <bridges.anson@gmail.com> | 2022-10-07 15:49:57 -0400 |
|---|---|---|
| committer | Anson Bridges <bridges.anson@gmail.com> | 2022-10-07 15:49:57 -0400 |
| commit | 7dbec964a375598d454e04719576eb6c469a5d7b (patch) | |
| tree | fa819e5e843ecdd88375ad1806ab43358b1ea670 | |
| parent | 62c33688cf2f48d7669790a89e3d1cdec16798be (diff) | |
ai work
24 files changed, 225 insertions, 119 deletions
diff --git a/godot/project.godot b/godot/project.godot index a6d3c33..8c82ff3 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -8,6 +8,28 @@ config_version=4 +_global_script_classes=[ { +"base": "RigidBody", +"class": "NetChar", +"language": "GDScript", +"path": "res://scripts/characters/NetworkedCharacter.gd" +}, { +"base": "RigidBody", +"class": "NetMachine", +"language": "GDScript", +"path": "res://scripts/machines/NetworkedMachineGDS.gd" +}, { +"base": "RigidBody", +"class": "NetObject", +"language": "GDScript", +"path": "res://scripts/ballistics/NetworkedProjectile.gd" +} ] +_global_script_class_icons={ +"NetChar": "", +"NetMachine": "", +"NetObject": "" +} + [application] config/name="boats" @@ -20,6 +42,10 @@ config/icon="res://icon.png" default_bus_layout="" +[autoload] + +CharacterAIManager="*res://scripts/CharacterAIManager.gd" + [debug] settings/profiler/max_functions=65535 @@ -28,6 +54,7 @@ settings/gdscript/max_call_stack=4096 [display] +window/size/resizable=false window/vsync/use_vsync=false window/stretch/mode="2d" diff --git a/godot/scenes/ballistics/Rocket.gd b/godot/scenes/ballistics/Rocket.gd index e475f9b..c10b5b5 100644 --- a/godot/scenes/ballistics/Rocket.gd +++ b/godot/scenes/ballistics/Rocket.gd @@ -40,6 +40,7 @@ remotesync func explode(): for body in $BlastArea.get_overlapping_bodies(): if body.has_method("damage"): body.rpc("damage", 20, "EXPLOSIVE", [shooter_id, shooter], "using 'rocket'") + if body.has_method("net_apply_impulse"): body.rpc_id(body.get_network_master(), "net_apply_impulse", (1300*(body.global_transform.origin+Vector3(0,1,0) - global_transform.origin).normalized())) $AnimationPlayer.play("explode") diff --git a/godot/scenes/characters/PlayerRigid.tscn b/godot/scenes/characters/PlayerRigid.tscn index 87a463d..bc5f588 100644 --- a/godot/scenes/characters/PlayerRigid.tscn +++ b/godot/scenes/characters/PlayerRigid.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=2] [ext_resource path="res://scripts/characters/player_controller_new.gd" type="Script" id=1] -[ext_resource path="res://theming/FreeMono.otf" type="DynamicFontData" id=2] +[ext_resource path="res://theming/Rapscallion-q341.ttf" type="DynamicFontData" id=2] [ext_resource path="res://scenes/characters/PlayerAreaDetect.gd" type="Script" id=3] [ext_resource path="res://scenes/characters/viewmodel_arms.tscn" type="PackedScene" id=4] [ext_resource path="res://scenes/weapons/hands.res" type="Resource" id=5] @@ -20,9 +20,9 @@ extents = Vector3( 0.325, 0.9, 0.325 ) size = Vector3( 0.6, 1.8, 0.6 ) [sub_resource type="DynamicFont" id=5] -size = 20 -outline_size = 3 -use_filter = true +size = 128 +outline_size = 1 +use_mipmaps = true font_data = ExtResource( 2 ) [sub_resource type="BoxShape" id=1] @@ -97,9 +97,11 @@ path_desired_distance = 1.5 target_desired_distance = 1.5 agent_height_offset = -0.5 path_max_distance = 1.0 +neighbor_dist = 15.0 [node name="Nametag" type="Label3D" parent="."] transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.08522, 0 ) +pixel_size = 0.0023 billboard = 1 font = SubResource( 5 ) diff --git a/godot/scenes/vehicles/Airplane.tscn b/godot/scenes/vehicles/Airplane.tscn index 43c3a17..a94e7e3 100644 --- a/godot/scenes/vehicles/Airplane.tscn +++ b/godot/scenes/vehicles/Airplane.tscn @@ -161,4 +161,4 @@ shape = SubResource( 9 ) transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2.72698, -0.196514, 0 ) [node name="PilotExit" type="Spatial" parent="."] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2.50863, 2.36377, 0 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 3.89608, 1.46682, 0 ) diff --git a/godot/scenes/vehicles/Gunbrig.tscn b/godot/scenes/vehicles/Gunbrig.tscn index 91900c3..70a30ad 100644 --- a/godot/scenes/vehicles/Gunbrig.tscn +++ b/godot/scenes/vehicles/Gunbrig.tscn @@ -357,3 +357,5 @@ shape = SubResource( 36 ) [node name="GunwhaleR2" type="CollisionShape" parent="."] transform = Transform( 0.999486, 0, 0.0320562, 0, 1, 0, -0.0320562, 0, 0.999486, -0.646409, 0.658986, -3.46571 ) shape = SubResource( 36 ) + +[connection signal="navigation_mesh_changed" from="NavigationMeshInstance" to="NavigationMeshInstance" method="mesh_changed"] diff --git a/godot/scripts/AIManager.gd b/godot/scripts/AIManager.gd deleted file mode 100644 index e93067b..0000000 --- a/godot/scripts/AIManager.gd +++ /dev/null @@ -1,13 +0,0 @@ -extends Object - -var calcs_per_tick: int = 15 -var WORLD_MAP_RID -# Called when the node enters the scene tree for the first time. -func _ready(): - pass # Replace with function body. - -func find_path() -> PoolVector3Array: - return NavigationServer.map_get_path(WORLD_MAP_RID, start_pos, end_pos, true) -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass diff --git a/godot/scripts/CharacterAIManager.gd b/godot/scripts/CharacterAIManager.gd new file mode 100644 index 0000000..fb86a48 --- /dev/null +++ b/godot/scripts/CharacterAIManager.gd @@ -0,0 +1,28 @@ +extends Node + +var calcs_per_tick: int = 15 +var request_queue: Array = [] #array of dictionaries +var cur_req: Dictionary +var cur_req_args: Dictionary +var WORLD_MAP_RID + +enum Task {PATHFIND, FINDITEM} + +#tasks: find path, find object +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + +func _physics_process(_delta): + for i in calcs_per_tick: + if len(request_queue) == 0: + return + cur_req = request_queue.pop_front() + cur_req_args = cur_req["args"] + if cur_req["type"] == Task.PATHFIND: + var dest_vec: Vector3 = cur_req_args["dest"] if cur_req_args["obj"] == null else cur_req_args["obj"].global_transform.origin + var path: PoolVector3Array = NavigationServer.map_get_path(WORLD_MAP_RID, cur_req["char"].global_transform.origin, dest_vec, cur_req_args["optimize"]) + +#will request a path from character to dest_g, or to the global origin of obj if passed +func request_find_path(character: NetChar, dest_g: Vector3, precise: bool, obj: Spatial = null) -> void: + request_queue.append({"char" : character, "type" : Task.PATHFIND, "args" : {"dest" : dest_g, "obj" : obj, "optimize" : !precise}}) diff --git a/godot/scripts/ballistics/NetworkedProjectile.gd b/godot/scripts/ballistics/NetworkedProjectile.gd index a7de71a..a1d73ac 100644 --- a/godot/scripts/ballistics/NetworkedProjectile.gd +++ b/godot/scripts/ballistics/NetworkedProjectile.gd @@ -1,9 +1,9 @@ extends RigidBody +class_name NetObject var shooter = "WORLD" var shooter_id = 1 - # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. diff --git a/godot/scripts/characters/NetworkedCharacter.gd b/godot/scripts/characters/NetworkedCharacter.gd new file mode 100644 index 0000000..c8e90a4 --- /dev/null +++ b/godot/scripts/characters/NetworkedCharacter.gd @@ -0,0 +1,85 @@ +extends RigidBody +class_name NetChar + +# Game +export var team: String = "RED" +export var health: int = 100 +export var weapon_slot1: Resource = null +export var weapon_slot2: Resource = null +export var weapon_slot3: Resource = null +export var weapon_slot4: Resource = null +export var weapon_slot5: Resource = null +var weapons = [null,null,null,null,null] +var weapon: Resource = null +var world: Spatial = null +var carrying: bool = false +var carrying_object: NetObject = null + +# Control +var controlling_machine: bool = false #whether character is riding/controlling something +var machine: RigidBody = null +export var is_player: bool = false #whether character is currently controlled by a player +var ladder_m: Spatial = null + +func get_init_info() -> Dictionary: + return {"linear_velocity" : linear_velocity, "angular_velocity" : angular_velocity, "controlling_machine" : controlling_machine, "team" : team, "health" : health, "nametag" : $Nametag.text} + +func mp_init(init_info: Dictionary): + for variable in init_info.keys(): + set(variable, init_info[variable]) + $Nametag.text = init_info["nametag"] + +remote func set_phys_transform(trfrm: Transform, lvel: Vector3): + transform = trfrm + linear_velocity = lvel + +remotesync func set_net_owner(owner_id: int): + $Nametag.text = "" + set_network_master(owner_id) + if owner_id != 1: + $Nametag.text = world.players_info[owner_id][0] + if get_tree().get_network_unique_id() != 1: + if owner_id == world.client_id: + $Nametag.visible = false + world.player_char = self + is_player = true + world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") + else: + $Nametag.visible = true + is_player = false + world.get_node("HUD").update_characters() + +func deselect_character(): + if is_network_master(): + world.player_char = null + if world.client_id != 1: world.cam.attach(world, "STATIC", "./DEFAULTCAM") + rpc("set_net_owner", 1) + +func take_control_of_machine(slave_machine: RigidBody): + machine = slave_machine + controlling_machine = true + +func lose_machine(): + if is_network_master(): world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") + controlling_machine = false + machine = null + +remotesync func damage(dmg_amt: int, _type: String, shooter: Array, extra: String): + health -= dmg_amt + if health <= 0 and is_network_master(): + if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_killsound") + if get_network_master() == 1: + world._call_on_server("_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) + else: + world.rpc_id(1, "_call_on_server", "_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) + elif is_network_master(): + if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_hitsound") + +remotesync func remove_dead_character(): + if is_network_master() and machine != null: + machine.relinquish_control() + deselect_character() + queue_free() + +remotesync func net_apply_impulse(impulse_v: Vector3): + apply_central_impulse(impulse_v) diff --git a/godot/scripts/characters/player_controller_new.gd b/godot/scripts/characters/player_controller_new.gd index b1a8718..6e2a28b 100644 --- a/godot/scripts/characters/player_controller_new.gd +++ b/godot/scripts/characters/player_controller_new.gd @@ -1,18 +1,4 @@ -extends RigidBody - -# Game -export var team: String = "RED" -export var health: int = 100 -export var weapon_slot1: Resource = null -export var weapon_slot2: Resource = null -export var weapon_slot3: Resource = null -export var weapon_slot4: Resource = null -export var weapon_slot5: Resource = null -var weapons = [null,null,null,null,null] -var weapon: Resource = null -var world: Spatial = null -var carrying: bool = false -var carrying_object: RigidBody = null +extends "res://scripts/characters/NetworkedCharacter.gd" # Camera export var mouse_sensitivity:float = 12.0 @@ -41,12 +27,6 @@ var in_water: bool = false var swim_speed: float = 450.0 var climb_speed: float = 5.0 -# Control -var controlling_machine: bool = false #whether character is riding/controlling something -var machine: RigidBody = null -export var is_player: bool = false #whether character is currently controlled by a player -var ladder_m: Spatial = null - #physics var player_state: PhysicsDirectBodyState = null var is_on_floor:bool = false @@ -56,6 +36,18 @@ export var walk_speed:float = 5.0 var c_friction:float = 4.0 var air_control:float = 0.3 +#ai +var ai_state: String = "IDLE" + +var ai_should_pathfind: bool = false +var ai_path_target_global: Vector3 = Vector3.ZERO + +var ai_look_target: Vector3 = Vector3.ZERO +var ai_should_look: bool = false +var ai_should_track: bool = false +var ai_track_object: Spatial = null +const AI_LOOK_SPEED: float = 4.0 + # Called when the node enters the scene tree func _ready() -> void: if weapon_slot1 == null: @@ -76,18 +68,6 @@ func add_weapon_vm(weapon_vm: Spatial, trfrm: Transform): viewmodel.get_node("Skeleton/GunBone").add_child(weapon_vm) weapon_vm.transform = trfrm -func get_init_info() -> Dictionary: - return {"linear_velocity" : linear_velocity, "angular_velocity" : angular_velocity, "controlling_machine" : controlling_machine, "team" : team, "health" : health, "nametag" : $Nametag.text} - -func mp_init(init_info: Dictionary): - for variable in init_info.keys(): - set(variable, init_info[variable]) - $Nametag.text = init_info["nametag"] - -remote func set_phys_transform(trfrm: Transform, lvel: Vector3): - transform = trfrm - linear_velocity = lvel - # Called every frame. 'delta' is the elapsed time since the previous frame func _process(_delta: float) -> void: if is_player and !world.is_chatting: @@ -159,37 +139,6 @@ func initiate_use(): _: pass -remotesync func set_net_owner(owner_id: int): - $Nametag.text = "" - set_network_master(owner_id) - if owner_id != 1: - $Nametag.text = world.players_info[owner_id][0] - if get_tree().get_network_unique_id() != 1: - if owner_id == world.client_id: - $Nametag.visible = false - world.player_char = self - is_player = true - world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") - else: - $Nametag.visible = true - is_player = false - world.get_node("HUD").update_characters() - -func deselect_character(): - if is_network_master(): - world.player_char = null - if world.client_id != 1: world.cam.attach(world, "STATIC", "./DEFAULTCAM") - rpc("set_net_owner", 1) - -func take_control_of_machine(slave_machine: RigidBody): - machine = slave_machine - controlling_machine = true - -func lose_machine(): - if is_network_master(): world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") - controlling_machine = false - machine = null - func carry_process() -> void: if !is_instance_valid(carrying_object): carrying_object = null @@ -208,6 +157,8 @@ func carry_process() -> void: # Called every physics tick. 'delta' is constant func _physics_process(delta: float) -> void: if is_network_master(): + if !is_player: #ai behavior + if ai_should_look: ai_look_at() if carrying: carry_process() if ladder_m != null: @@ -247,10 +198,10 @@ func _integrate_forces(state: PhysicsDirectBodyState) -> void: break if i == player_state.get_contact_count() - 1: friction = 1 - + nav.set_velocity(velocity) rpc("set_phys_transform", transform, linear_velocity) if global_transform.origin.y < -30: - rpc("damage", 500000, "drown", [1, "Davy Jones"]) + rpc("damage", 500000, "drown", [1, "Davy Jones"], "") func walk(_delta: float) -> void: # Input @@ -345,26 +296,6 @@ func leave_ladder(): ladder_m.queue_free() ladder_m = null -remotesync func damage(dmg_amt: int, _type: String, shooter: Array, extra: String): - health -= dmg_amt - if health <= 0 and is_network_master(): - if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_killsound") - if get_network_master() == 1: - world._call_on_server("_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) - else: - world.rpc_id(1, "_call_on_server", "_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) - elif is_network_master(): - if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_hitsound") - -remotesync func remove_dead_character(): - if is_network_master() and machine != null: - machine.relinquish_control() - deselect_character() - queue_free() - -remotesync func net_apply_impulse(impulse_v: Vector3): - apply_central_impulse(impulse_v) - remotesync func anim_event(event: Dictionary): $"%VIEWMODEL_ARMS".get_node("AnimationPlayer").play(event["VMANIMPLAY"]) @@ -380,3 +311,34 @@ remotesync func add_rocket_to_scene(pos, dir, id): rocket.global_transform.origin = pos rocket.global_transform.basis = Basis(-1*dir.z, dir.y, dir.x) rocket.add_collision_exception_with(self) + +func set_look_status(target, type="STATIC"): + if type == "STATIC": + ai_look_target = target + ai_should_look = true + elif type == "TRACK": + ai_track_object = target + ai_should_look = true + ai_should_track = true + else: + ai_should_track = false + +func set_path_target(target): + ai_path_target_global = target + +func ai_look_at(): + if ai_should_track: + if is_instance_valid(ai_track_object): + ai_look_target = ai_track_object.global_transform.origin + else: + ai_track_object = null + ai_should_track = false + var p_neck: float = Vector3(ai_look_target.x - neck.global_transform.origin.x, 0, ai_look_target.z - neck.global_transform.origin.z).signed_angle_to(-neck.global_transform.basis.z, neck.global_transform.basis.y ) + var p_head: float = Vector3(ai_look_target.x - neck.global_transform.origin.x, ai_look_target.y - head.global_transform.origin.y, ai_look_target.z - neck.global_transform.origin.z).signed_angle_to( -head.global_transform.basis.z, head.global_transform.basis.x) + if abs(p_neck) > 0.01: + neck.rotation_degrees.y = lerp(neck.rotation_degrees.y, neck.rotation_degrees.y-p_neck, AI_LOOK_SPEED+abs(p_neck/3.1415)) + if abs(p_head) > 0.01: + head.rotation_degrees.x = lerp(head.rotation_degrees.x, head.rotation_degrees.x-p_head, AI_LOOK_SPEED+abs(p_head/3.1415)) + + if abs(p_neck) <= 0.01 and abs(p_head) <= 0.01 and !ai_should_track: + ai_should_look = false diff --git a/godot/scripts/machines/NetworkedMachineGDS.gd b/godot/scripts/machines/NetworkedMachineGDS.gd index a8ee1da..91dbeb4 100644 --- a/godot/scripts/machines/NetworkedMachineGDS.gd +++ b/godot/scripts/machines/NetworkedMachineGDS.gd @@ -1,8 +1,9 @@ extends RigidBody +class_name NetMachine var in_use: bool = false var controllable: bool = false -var user: RigidBody = null +var user: NetChar = null var world: Spatial = null func _ready(): diff --git a/godot/scripts/vehicles/Airplane.gd b/godot/scripts/vehicles/Airplane.gd index 9762457..8ac755b 100644 --- a/godot/scripts/vehicles/Airplane.gd +++ b/godot/scripts/vehicles/Airplane.gd @@ -23,9 +23,10 @@ var parentvel = [Vector3.ZERO, Vector3.ZERO] export var roll_curve : CurveTexture #net machine variables -var in_use : bool = false -var user = null -var world = null +var in_use: bool = false +var user: RigidBody = null +var world: Spatial = null +var controllable: bool = true func get_init_info(): return {"linear_velocity" : linear_velocity, "angular_velocity" : angular_velocity, "in_use" : in_use} @@ -81,7 +82,7 @@ func direction_input(fwd,bwd,left,right,_left2,_right2): func misc_input(_ctrl,space,shift): brake_control = shift if space > 0.1 and !boosting: #if boost is pressed - trigger_boost() + rpc("trigger_boost") func mouse_input(_m1,_m3,_m2): #used for long-press actions pass @@ -91,32 +92,36 @@ func _ready(): countdown = boost_length brake = 5 -func trigger_boost(): - print("boosting") +remotesync func trigger_boost(): boosting = true $"%RocketTrail".emitting = true +remotesync func end_boost(): + $"%RocketTrail".emitting = false + print("stopped boosting") + boosting = false + countdown = boost_length + func _process(delta): if is_network_master(): if boosting and countdown <= 0: - $"%RocketTrail".emitting = false - print("stopped boosting") - boosting = false - countdown = boost_length + rpc("end_boost") func _physics_process(delta): + if boosting: + add_force(global_transform.basis.x*booster_force,Vector3.ZERO) + countdown -= delta if in_use and user.get_network_master() == world.client_id: user.global_transform.origin = $Cockpit.global_transform.origin user.global_transform.basis = $Cockpit.global_transform.basis.orthonormalized() + user.set_linear_velocity(get_linear_velocity()) if is_network_master(): $rearwheel.brake = lerp($rearwheel.brake, brake_force*brake_control, 0.05) v_angle = atan2(global_transform.basis.x.y,sqrt(global_transform.basis.x.z*global_transform.basis.x.z + global_transform.basis.x.x*global_transform.basis.x.x)) roll_angle = global_transform.basis.x.cross(Vector3.UP).angle_to($rightaileron.global_transform.origin-$wingcenter.global_transform.origin) if $rightaileron.global_transform.origin.y < $leftaileron.global_transform.origin.y: roll_angle *= -1 - if boosting: - add_force(global_transform.basis.x*booster_force,Vector3.ZERO) - countdown -= delta + #print(linear_velocity.length()) #slow plane by drag and gravity diff --git a/godot/theming/Rapscallion-q341.ttf b/godot/theming/Rapscallion-q341.ttf Binary files differnew file mode 100644 index 0000000..5bb8cc0 --- /dev/null +++ b/godot/theming/Rapscallion-q341.ttf diff --git a/godot/theming/main_menu_theme.tres b/godot/theming/main_menu_theme.tres new file mode 100644 index 0000000..17e1404 --- /dev/null +++ b/godot/theming/main_menu_theme.tres @@ -0,0 +1,6 @@ +[gd_resource type="Theme" load_steps=2 format=2] + +[sub_resource type="StyleBoxTexture" id=1] + +[resource] +Button/styles/disabled = SubResource( 1 ) diff --git a/work/facetex_base.png b/work/facetex_base.png Binary files differnew file mode 100644 index 0000000..50be3a6 --- /dev/null +++ b/work/facetex_base.png diff --git a/work/headbase.png b/work/headbase.png Binary files differnew file mode 100644 index 0000000..8e920e2 --- /dev/null +++ b/work/headbase.png diff --git a/work/human_male.blend b/work/human_male.blend Binary files differindex 83a9e7e..c7a0b7a 100644 --- a/work/human_male.blend +++ b/work/human_male.blend diff --git a/work/human_male.blend1 b/work/human_male.blend1 Binary files differindex 2dafae3..83a9e7e 100644 --- a/work/human_male.blend1 +++ b/work/human_male.blend1 diff --git a/work/man.blend b/work/man.blend Binary files differindex 9c3a7fe..3ba0b4c 100644 --- a/work/man.blend +++ b/work/man.blend diff --git a/work/man.blend1 b/work/man.blend1 Binary files differindex 984ac41..63e8d99 100644 --- a/work/man.blend1 +++ b/work/man.blend1 diff --git a/work/man.blend11 b/work/man.blend11 Binary files differnew file mode 100644 index 0000000..08e7644 --- /dev/null +++ b/work/man.blend11 diff --git a/work/mariner_tex.png b/work/mariner_tex.png Binary files differnew file mode 100644 index 0000000..87c34ff --- /dev/null +++ b/work/mariner_tex.png diff --git a/work/mariner_tex.xcf b/work/mariner_tex.xcf Binary files differnew file mode 100644 index 0000000..4668932 --- /dev/null +++ b/work/mariner_tex.xcf diff --git a/work/mariner_uv.png b/work/mariner_uv.png Binary files differnew file mode 100644 index 0000000..bea5a49 --- /dev/null +++ b/work/mariner_uv.png |
