aboutsummaryrefslogtreecommitdiff
path: root/game/src/Game/Model/UnitModel.gd
blob: 0a4fe2f8686ad237a3a2b816e21f45d3701b0fde (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class_name UnitModel
extends Node3D

var skeleton : Skeleton3D = null
var anim_player : AnimationPlayer = null
var anim_lib : AnimationLibrary = null
var sub_units : Array[UnitModel]
var meshes : Array[MeshInstance3D]

# COLOUR VARIABLES
@export_group("Colors")
@export var primary_colour : Color:
   set(col_in):
      primary_colour = col_in
      change_colour_prop(&"colour_primary", primary_colour)
      for unit : UnitModel in sub_units:
         unit.primary_colour = col_in

@export var secondary_colour: Color:
   set(col_in):
      secondary_colour = col_in
      change_colour_prop(&"colour_secondary", secondary_colour)
      for unit : UnitModel in sub_units:
         unit.secondary_colour = col_in

@export var tertiary_colour : Color:
   set(col_in):
      tertiary_colour = col_in
      change_colour_prop(&"colour_tertiary", tertiary_colour)
      for unit : UnitModel in sub_units:
         unit.tertiary_colour = col_in

# ANIMATION VARIABLES
@export_group("Animation")
@export var idle_anim : Animation:
   set(anim_in):
      load_animation("idle", anim_in)
      idle_anim = anim_in

@export var move_anim : Animation:
   set(anim_in):
      load_animation("move", anim_in)
      move_anim = anim_in

@export var attack_anim : Animation:
   set(anim_in):
      load_animation("attack", anim_in)
      attack_anim = anim_in

enum Anim { NONE, IDLE, MOVE, ATTACK }

const ANIMATION_LIBRARY : StringName = &"default_lib"
const ANIMATION_IDLE : String = ANIMATION_LIBRARY + "/idle"
const ANIMATION_MOVE : String = ANIMATION_LIBRARY + "/move"
const ANIMATION_ATTACK : String = ANIMATION_LIBRARY + "/attack"

@export var current_anim : Anim:
   set(anim_in):
      for unit : UnitModel in sub_units:
         unit.current_anim = anim_in

      if anim_player:
         match anim_in:
            Anim.IDLE:
               if idle_anim:
                  anim_player.set_current_animation(ANIMATION_IDLE)
                  current_anim = Anim.IDLE
                  return
            Anim.MOVE:
               if move_anim:
                  anim_player.set_current_animation(ANIMATION_MOVE)
                  current_anim = Anim.MOVE
                  return
            Anim.ATTACK:
               if attack_anim:
                  anim_player.set_current_animation(ANIMATION_ATTACK)
                  current_anim = Anim.ATTACK
                  return
            _: #None
               pass

         anim_player.stop()

      current_anim = Anim.NONE

# TEXTURE SCROLL SPEEDS (TANKS TRACKS AND SMOKE)
@export_subgroup("Texture_Scroll")
@export var scroll_speed_idle : float = 0.0
@export var scroll_speed_move : float = 0.0
@export var scroll_speed_attack : float = 0.0

func unit_init() -> void:
   for child : Node in get_children():
      if child is MeshInstance3D:
         meshes.append(child)
      elif child is Skeleton3D:
         skeleton = child

func add_anim_player() -> void:
   anim_player = AnimationPlayer.new()
   anim_player.name = "anim_player"

   anim_lib = AnimationLibrary.new()
   anim_lib.resource_name = ANIMATION_LIBRARY
   anim_player.add_animation_library(ANIMATION_LIBRARY, anim_lib)

   add_child(anim_player)

func has_bone(bone_name : String) -> bool:
   return skeleton and skeleton.find_bone(bone_name) > -1

func attach_model(bone_name : String, model : Node3D) -> Error:
   if not model:
      push_error("Cannot attach null model to bone \"", bone_name, "\" of UnitModel ", get_name())
      return FAILED

   if not skeleton:
      push_error("Cannot attach model \"", model.get_name(), "\" to bone \"", bone_name, "\" of UnitModel ", get_name(), " - has no skeleton!")
      return FAILED

   var bone_idx : int = skeleton.find_bone(bone_name)
   if bone_idx < 0 or bone_idx >= skeleton.get_bone_count():
      push_error("Invalid bone \"", bone_name, "\" (index ", bone_idx, ") for attachment \"", model.get_name(), "\" to UnitModel \"", get_name(), "\"")
      return FAILED

   var bone_attachment := BoneAttachment3D.new()
   bone_attachment.name = bone_name
   bone_attachment.bone_idx = bone_idx
   bone_attachment.add_child(model)
   skeleton.add_child(bone_attachment)

   if model is UnitModel:
      sub_units.push_back(model)
      model.current_anim = current_anim
      model.primary_colour = primary_colour
      model.secondary_colour = secondary_colour
      model.tertiary_colour = tertiary_colour

   return OK

func _set_tex_scroll(speed : float) -> void:
   for mesh : MeshInstance3D in meshes:
      if mesh.get_active_material(0) is ShaderMaterial:
         mesh.set_instance_shader_parameter(&"scroll", Vector2(0, speed))

func set_flag_index(index : int) -> void:
   for mesh : MeshInstance3D in meshes:
      mesh.set_instance_shader_parameter(&"flag_index", index)

func change_colour_prop(prop_name : StringName, prop_val : Color) -> void:
   for mesh : MeshInstance3D in meshes:
      if mesh.get_active_material(0) is ShaderMaterial:
         mesh.set_instance_shader_parameter(prop_name, prop_val)

func load_animation(prop_name : String, animIn : Animation) -> void:
   if not animIn:
      return
   if not anim_player:
      add_anim_player()
   anim_lib.add_animation(prop_name,animIn)