aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/json/\155
-rw-r--r--assets/json/modules.json90
-rw-r--r--docs/turret/modules.md4
-rw-r--r--scripts/load_turrets.gd12
-rw-r--r--scripts/turret.gd106
5 files changed, 344 insertions, 23 deletions
diff --git a/assets/json/\ b/assets/json/\
new file mode 100644
index 0000000..429251c
--- /dev/null
+++ b/assets/json/\
@@ -0,0 +1,155 @@
+[
+ {
+ "name": "cooldown",
+ "cost": { "k": 400 },
+ "mul": {
+ "cooldown": -0.05
+ }
+ },
+ {
+ "name": "turn speed",
+ "cost": { "k": 400 },
+ "mul": {
+ "turn_speed": -0.10
+ }
+ },
+ {
+ "name": "projectile speed",
+ "cost": { "k": 200 },
+ "mul": {
+ "projectile": {
+ "speed": 0.10
+ }
+ }
+ },
+ {
+ "name": "double damage",
+ "cost": { "a": 500 },
+ "add": {
+ "on_new_hit_double_damage": 1
+ }
+ },
+ {
+ "name": "damage",
+ "cost": { "a": 1000 },
+ "add": {
+ "projectile": {
+ "damage": 1
+ }
+ }
+ },
+ {
+ "name": "range",
+ "cost": { "a": 500 },
+ "mul": {
+ "range": 0.15
+ }
+ },
+ {
+ "name": "range",
+ "cost": { "d": 800 },
+ "add": {
+ "on_kill_double_resources": 1
+ }
+ },
+ {
+ "name": "double shot",
+ "cost": { "d": 1000 },
+ "add": {
+ "on_kill_double_shot": 1
+ }
+ },
+ {
+ "name": "slowness",
+ "cost": { "s": 300 },
+ "mul": {
+ "slowness_time": 0.20
+ }
+ },
+ {
+ "name": "armorbreaker",
+ "cost": { "s": 1000 },
+ "add": {
+ "if_half_lives_add_damage": 1
+ }
+ },
+ {
+ "name": "catalyst",
+ "cost": { "T": 200 },
+ "add": {
+ "resources_per_wave": { "T": 5 }
+ }
+ },
+ {
+ "name": "targeting",
+ "cost": { "T": 100 },
+ "add": {
+ "advanced_targeting": 1
+ }
+ },
+ {
+ "name": "heavy plastic",
+ "cost": { "T": 400 },
+ "cooldown": 1.5,
+ "turn_speed": 0.5,
+ "range": 6,
+ "upgrades": [ "plasma plastic" ],
+ "modules_max": 3,
+ "model_name": "plastic.glb",
+ "thumbnail_name": "plastic.png",
+ "projectile": {
+ "damage": 2,
+ "type": "bounce",
+ "model_name": "bullet_bounce.glb",
+ "speed": 7.5,
+ "max bounces": 4,
+ "amount": 1
+ }
+ },
+ {
+ "name": "blizzard",
+ "cost": { "T": 1000, "s": 3000 },
+ "cooldown": 0.5,
+ "turn_speed": 10,
+ "range": 7,
+ "modules_max": 5,
+ "model_name": "frost.glb",
+ "thumbnail_name": "frost.png",
+ "slowness": 10,
+ "projectile": {
+ "type": "ray",
+ "slowness_time": 5,
+ "slowness_effect": 0.7,
+ "model_name": "ray_slow.glb",
+ "amount": 1
+ }
+ },
+ {
+ "name": "heavy stopper",
+ "cost": { "T": 1000, "s": 2000 },
+ "cooldown": 3,
+ "range": 3,
+ "modules_max": 5,
+ "model_name": "frost.glb",
+ "thumbnail_name": "frost.png",
+ "projectile": {
+ "type": "bullet",
+ "area_of_effect": 3,
+ "slowness_time": 2,
+ "slowness_effect": 1,
+ "model_name": "ray_slow.glb",
+ "amount": 1,
+ "lifetime": 0,
+ "damage": 5
+ }
+ },
+ {
+ "name": "T generator",
+ "cost": { "T": 800 },
+ "resource_per_wave": { "T": 100 },
+ "upgrades": [ "kad generator" ],
+ "max_modules": 2,
+ "model_name": "finance.glb",
+ "thumbnail_name": "finance.png"
+ },
+]
diff --git a/assets/json/modules.json b/assets/json/modules.json
new file mode 100644
index 0000000..0e357d0
--- /dev/null
+++ b/assets/json/modules.json
@@ -0,0 +1,90 @@
+[
+ {
+ "name": "cooldown",
+ "cost": { "k": 400 },
+ "mul": {
+ "cooldown": -0.05
+ }
+ },
+ {
+ "name": "turn speed",
+ "cost": { "k": 400 },
+ "mul": {
+ "turn_speed": -0.10
+ }
+ },
+ {
+ "name": "projectile speed",
+ "cost": { "k": 200 },
+ "mul": {
+ "projectile": {
+ "speed": 0.10
+ }
+ }
+ },
+ {
+ "name": "double damage",
+ "cost": { "a": 500 },
+ "add": {
+ "on_new_hit_double_damage": 1
+ }
+ },
+ {
+ "name": "damage",
+ "cost": { "a": 1000 },
+ "add": {
+ "projectile": {
+ "damage": 1
+ }
+ }
+ },
+ {
+ "name": "range",
+ "cost": { "a": 500 },
+ "mul": {
+ "range": 0.15
+ }
+ },
+ {
+ "name": "range",
+ "cost": { "d": 800 },
+ "add": {
+ "on_kill_double_resources": 1
+ }
+ },
+ {
+ "name": "double shot",
+ "cost": { "d": 1000 },
+ "add": {
+ "on_kill_double_shot": 1
+ }
+ },
+ {
+ "name": "slowness",
+ "cost": { "s": 300 },
+ "mul": {
+ "slowness_time": 0.20
+ }
+ },
+ {
+ "name": "armorbreaker",
+ "cost": { "s": 1000 },
+ "add": {
+ "if_half_lives_add_damage": 1
+ }
+ },
+ {
+ "name": "catalyst",
+ "cost": { "T": 200 },
+ "add": {
+ "resources_per_wave": { "T": 5 }
+ }
+ },
+ {
+ "name": "targeting",
+ "cost": { "T": 100 },
+ "add": {
+ "advanced_targeting": 1
+ }
+ }
+]
diff --git a/docs/turret/modules.md b/docs/turret/modules.md
index 8367a9f..67fb564 100644
--- a/docs/turret/modules.md
+++ b/docs/turret/modules.md
@@ -20,10 +20,8 @@ Module list:
- double shot after killing an enemy
- s
- slowness time +20%
- - slowness effectiveness +10%
- - _works both for slower and stopper_
- if enemy has >50% hp, +1 damage
- T
- - +1 resource production
+ - +5 resource production
- advanced targeting
- _unlocks more targeting options_
diff --git a/scripts/load_turrets.gd b/scripts/load_turrets.gd
index e79a68c..10c6e44 100644
--- a/scripts/load_turrets.gd
+++ b/scripts/load_turrets.gd
@@ -4,6 +4,7 @@ var saveload : Node
var info : Dictionary
var models : Dictionary
+var modules : Dictionary
var thumbnails : Dictionary
var loaded : bool = false
@@ -13,6 +14,7 @@ func _ready():
get_saveload()
load_models()
load_info()
+ load_modules()
load_thumbnails()
emit_signal("done_loading")
loaded = true
@@ -58,3 +60,13 @@ func load_thumbnails():
var files = saveload.parse_dir("res://assets/textures/thumbnails/turrets", ".png")
for turr in files:
thumbnails[turr] = load("res://assets/textures/thumbnails/turrets/" + turr)
+
+func load_modules():
+ modules.clear()
+ var files = saveload.parse_dir("res://assets/json", ".json")
+ for f in files:
+ if f != "modules.json": continue
+ var parsed = saveload.load_parse_json("res://assets/json/" + f)
+ if parsed != null:
+ for tin in parsed:
+ modules[tin.name] = tin
diff --git a/scripts/turret.gd b/scripts/turret.gd
index fd44ce0..0d7302f 100644
--- a/scripts/turret.gd
+++ b/scripts/turret.gd
@@ -5,6 +5,7 @@ var _enemies : Node
var _fx_holder : Node
var _projectiles_holder : Node
var _enemies_holder : Node
+var load_turrets : Node
var pivot : Spatial
var base : Spatial
@@ -15,12 +16,73 @@ var _normal : Vector3
var aim_mode = "first"
var _target = null
+var cooldown_timer = 0
+
var projectile : PackedScene
var ray : PackedScene
var info : Dictionary
+var info_mod : Dictionary
-var cooldown_timer = 0
+var mods = ["damage", "double damage", "cooldown"]
+
+func make_info_mod ():
+ info_mod.clear()
+ var add_eff = {}
+ var mul_eff = {}
+ for k in info:
+ if info[k] is Dictionary:
+ info_mod[k] = {}
+ add_eff[k] = {}
+ mul_eff[k] = {}
+ for kk in info[k]:
+ info_mod[k][kk] = info[k][kk]
+ else:
+ info_mod[k] = info[k]
+
+ for m in mods:
+ var mod = load_turrets.modules[m]
+
+ for eff in mod.get("add", {}):
+ if mod.add[eff] is Dictionary:
+ for kk in mod.add[eff]:
+ if not eff in add_eff[eff]: add_eff[eff][kk] = 0
+ add_eff[eff][kk] += mod.add[eff][kk]
+ else:
+ if not eff in add_eff: add_eff[eff] = 0
+ add_eff[eff] += mod.add[eff]
+
+ for eff in mod.get("mul", {}):
+ if mod.mul[eff] is Dictionary:
+ for kk in mod.mul[eff]:
+ if not eff in mul_eff[eff]: mul_eff[eff][kk] = 0
+ mul_eff[eff][kk] *= mod.mul[eff][kk]
+ else:
+ if not eff in mul_eff: mul_eff[eff] = 0
+ mul_eff[eff] *= mod.mul[eff]
+
+ for k in add_eff:
+ if add_eff[k] is Dictionary:
+ for kk in add_eff[k]:
+ if not kk in info_mod[k]: info_mod[k][kk] = 0
+ info_mod[k][kk] += add_eff[k][kk]
+ else:
+ if not k in info_mod: info_mod[k] = 0
+ info_mod[k] += add_eff[k]
+
+ for k in mul_eff:
+ if mul_eff[k] is Dictionary:
+ for kk in mul_eff[k]:
+ if not kk in info_mod[k]: info_mod[k][kk] = 0
+ info_mod[k][kk] *= 1 + mul_eff[k][kk]
+ else:
+ if not k in info_mod: info_mod[k] = 0
+ info_mod[k] *= 1 + mul_eff[k]
+
+ print(add_eff)
+ print(mul_eff)
+ print(info)
+ print(info_mod)
func _ready():
var root = get_tree().root.get_node("world")
@@ -30,6 +92,9 @@ func _ready():
_enemies_holder = root.find_node("enemies")
_fx_holder = root.find_node("fx")
+ load_turrets = root.get_node("saveload").get_node("load_turrets")
+ if !load_turrets.loaded: yield(load_turrets, "done_loading")
+
projectile = load("res://scenes/projectiles/bullet.tscn")
ray = load("res://scenes/projectiles/ray.tscn")
@@ -45,13 +110,14 @@ func refresh_model():
func refresh_info(tinfo):
self.info = tinfo
+ make_info_mod()
func filter_in_range(set):
var filtered = []
for target in set:
var node = _enemies.node_from_id(target)
var dist = (node.transform.origin - _shooting_point).length_squared()
- if dist < info.range*info.range:
+ if dist < info_mod.range*info_mod.range:
filtered += [target]
return filtered
@@ -83,7 +149,7 @@ func get_target():
else: return null
func _physics_process(delta):
- if !info.has("projectile"): return
+ if !info_mod.has("projectile"): return
if !_enemies.enemies.has(_target):
_target = null
@@ -96,7 +162,7 @@ func _physics_process(delta):
_target = get_target()
- var turn_speed = info.get("turn_speed", 0)
+ var turn_speed = info_mod.get("turn_speed", 0)
if _target != null:
var enemy = _enemies.node_from_id(_target)
@@ -128,8 +194,8 @@ func _physics_process(delta):
gun.transform.basis = Basis(gun_basis.slerp(Basis(gun_rot), gun_amt))
cooldown_timer += delta
- if cooldown_timer > info.cooldown:
- cooldown_timer -= info.cooldown
+ if cooldown_timer > info_mod.cooldown:
+ cooldown_timer -= info_mod.cooldown
shoot()
func spread (amt : int) -> Array:
@@ -139,21 +205,21 @@ func spread (amt : int) -> Array:
var dir = gun.global_transform.basis
var x = floor(i%width)-width/2+(width+1)%2*0.5
var y = floor(i/width)-floor(sqrt(amt)-1)/2
- var spread = info.projectile.spread
+ var spread = info_mod.projectile.spread
dir = dir.rotated(_normal, deg2rad(x*spread))
dir = dir.rotated(_normal.cross(dir.z).normalized(), deg2rad(y*spread))
dirs.append(dir)
return dirs
func shoot ():
- if info.projectile.get("amount", 1) > 1:
- for dir in spread(info.projectile.amount):
+ if info_mod.projectile.get("amount", 1) > 1:
+ for dir in spread(info_mod.projectile.amount):
shoot_switch(dir)
else:
shoot_switch(gun.global_transform.basis)
func shoot_switch (dir : Basis):
- match info.projectile.type:
+ match info_mod.projectile.type:
"bullet": shoot_bullet(dir)
"ray": shoot_ray(dir)
"bounce": shoot_bullet(dir, true)
@@ -164,18 +230,18 @@ func shoot_bullet (dir : Basis, bounce = false):
instance.transform.basis = dir
instance.transform.origin = _shooting_point - dir.z*0.3;
instance.shooter = self
- instance.damage = info.projectile.get("damage", 0)
- instance.speed = info.projectile.get("speed", 0)
+ instance.damage = info_mod.projectile.get("damage", 0)
+ instance.speed = info_mod.projectile.get("speed", 0)
instance.bounce = bounce
- instance.aoe = info.projectile.get("area_of_effect", 0)
- instance.slowness_effect = info.projectile.get("slowness_effect", 0)
- instance.slowness_time = info.projectile.get("slowness_time", 0)
- instance.time_life = info.projectile.get("lifetime", 3)
+ instance.aoe = info_mod.projectile.get("area_of_effect", 0)
+ instance.slowness_effect = info_mod.projectile.get("slowness_effect", 0)
+ instance.slowness_time = info_mod.projectile.get("slowness_time", 0)
+ instance.time_life = info_mod.projectile.get("lifetime", 3)
func shoot_ray (dir : Basis):
var space: PhysicsDirectSpaceState = get_world().direct_space_state
var from = _shooting_point
- var to = _shooting_point - dir.z*info.range
+ var to = _shooting_point - dir.z*info_mod.range
var mask = 0b1101
var result = space.intersect_ray(from, to, _path.nodes, mask)
@@ -183,9 +249,9 @@ func shoot_ray (dir : Basis):
var parent = result.collider.get_parent()
var groups = parent.get_groups()
if "enemies" in groups:
- var dam = info.projectile.get("damage", 0)
- var eff = info.projectile.get("slowness_effect", 0)
- var tim = info.projectile.get("slowness_time", 0)
+ var dam = info_mod.projectile.get("damage", 0)
+ var eff = info_mod.projectile.get("slowness_effect", 0)
+ var tim = info_mod.projectile.get("slowness_time", 0)
_enemies_holder.damage(parent.name, dam, eff, tim)
var distance = result.position.distance_to(from)