AI can 'die' now; blackboard work
This commit is contained in:
@@ -5,7 +5,7 @@ var blood = preload("res://scenes/decals/blood.tscn")
|
||||
var blood_decal = preload("res://scenes/decals/blood1-decal.gltf")
|
||||
var rnd
|
||||
var initialized = false
|
||||
func init():
|
||||
func init(tick):
|
||||
assert(!initialized)
|
||||
if initialized:
|
||||
return
|
||||
@@ -61,7 +61,7 @@ func area_hit(area, e):
|
||||
# TODO: add delay
|
||||
bi.queue_free()
|
||||
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
assert(initialized)
|
||||
var root = get_character()
|
||||
if !root:
|
||||
@@ -98,6 +98,6 @@ func update_physics(delta):
|
||||
# decal.global_transform.basis = Basis(normal).scaled(Vector3(scale, 1.0, scale)).rotated(normal, rot)
|
||||
return ERR_BUSY
|
||||
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
return ERR_BUSY
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ extends AIScriptModule
|
||||
|
||||
var animtree: AnimationTree
|
||||
var root_motion_track
|
||||
func init():
|
||||
func init(tick):
|
||||
# process_priority = 0
|
||||
pass
|
||||
|
||||
@@ -23,7 +23,7 @@ func can_walk_there(dest: Vector3) -> bool:
|
||||
else:
|
||||
return true
|
||||
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
var root = get_character()
|
||||
var orientation: Transform
|
||||
assert(root.has_meta("skeleton"))
|
||||
@@ -258,5 +258,5 @@ func update_physics(delta):
|
||||
root.remove_meta("cmdqueue")
|
||||
return ERR_BUSY
|
||||
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
return ERR_BUSY
|
||||
|
||||
@@ -29,7 +29,7 @@ const guard_distance = 2.0
|
||||
const engage_distance = 10.0
|
||||
const flee_distance = 5.0
|
||||
|
||||
var blackboard = {
|
||||
var init_blackboard = {
|
||||
"stamina": 100.0,
|
||||
"health": 100.0,
|
||||
"melee_weapon_equipped": false,
|
||||
@@ -62,7 +62,7 @@ func combat_event(ev, data):
|
||||
var dst = where.distance_squared_to(curpos)
|
||||
if dst < guard_distance * guard_distance:
|
||||
if who == player:
|
||||
blackboard.guard = true
|
||||
blackboard_set("guard", true)
|
||||
"damage":
|
||||
var who = data[0]
|
||||
var weapon = data[1]
|
||||
@@ -72,13 +72,15 @@ func combat_event(ev, data):
|
||||
var dst = where.distance_squared_to(curpos)
|
||||
if dst < attack_distance * attack_distance:
|
||||
if who == player:
|
||||
blackboard.melee_damage = true
|
||||
blackboard_set("melee_damage", true)
|
||||
|
||||
var initialized = false
|
||||
func init():
|
||||
func init(tick):
|
||||
assert(!initialized)
|
||||
name = "bandit_ai"
|
||||
root = get_character()
|
||||
for e in init_blackboard.keys():
|
||||
blackboard_set(e, init_blackboard[e])
|
||||
assert(root.has_meta("skeleton"))
|
||||
rnd = RandomNumberGenerator.new()
|
||||
rnd.randomize()
|
||||
@@ -377,6 +379,39 @@ class rest extends base_bhv:
|
||||
assert(root)
|
||||
active = false
|
||||
finished = false
|
||||
class unconcious extends base_bhv:
|
||||
var root
|
||||
var anim1
|
||||
var anim2
|
||||
var state = 0
|
||||
func start(root: Node, anim1: String, anim2: String):
|
||||
self.root = root
|
||||
self.anim1 = anim1
|
||||
self.anim2 = anim2
|
||||
active = true
|
||||
state = 0
|
||||
|
||||
func run(delta: float, bb: Dictionary):
|
||||
assert(active)
|
||||
assert(root)
|
||||
assert(anim1)
|
||||
assert(anim2)
|
||||
match state:
|
||||
0:
|
||||
characters.animation_node_travel(root, anim1)
|
||||
state = 1
|
||||
# if finished:
|
||||
# return
|
||||
# if bb.stamina < 100.0:
|
||||
# print("rest: stamina: ", bb.stamina)
|
||||
# bb.stamina += 15500.0 * delta
|
||||
# else:
|
||||
# finished = true
|
||||
func stop():
|
||||
assert(active)
|
||||
assert(root)
|
||||
active = false
|
||||
finished = false
|
||||
|
||||
#var walk_to: walkto
|
||||
#var flee_to: walkto
|
||||
@@ -392,76 +427,78 @@ var conf_behaviors: = {
|
||||
"melee_attack": attack,
|
||||
"guard": guard,
|
||||
"rest": rest,
|
||||
"get_melee_damage": get_damage
|
||||
"get_melee_damage": get_damage,
|
||||
"unconcious": unconcious
|
||||
}
|
||||
|
||||
var pdst = INF
|
||||
static func calc_utility(utility: String, bb: Dictionary):
|
||||
func calc_utility(utility: String):
|
||||
match utility:
|
||||
"take_melee_weapon":
|
||||
if bb.health <= 0.0:
|
||||
if blackboard_get("health") <= 0.0:
|
||||
return 0.0
|
||||
if bb.melee_weapon_equipped:
|
||||
if blackboard_get("melee_weapon_equipped"):
|
||||
return 0.0
|
||||
else:
|
||||
if bb.enemy_distance < engage_distance * engage_distance:
|
||||
if blackboard_get("enemy_distance") < engage_distance * engage_distance:
|
||||
return 110.0
|
||||
"approach":
|
||||
if bb.health <= 0.0:
|
||||
if blackboard_get("health") <= 0.0:
|
||||
return 0.0
|
||||
if bb.enemy_distance < 1.6 * 1.6:
|
||||
if blackboard_get("enemy_distance") < 1.6 * 1.6:
|
||||
return 0.0
|
||||
if bb.stamina > 50.0 && bb.enemy_distance < engage_distance * engage_distance:
|
||||
return 10.0 + (bb.enemy_distance - 10.0) / 6.0
|
||||
if blackboard_get("stamina") > 50.0 && blackboard_get("enemy_distance") < engage_distance * engage_distance:
|
||||
return 10.0 + (blackboard_get("enemy_distance") - 10.0) / 6.0
|
||||
"melee_attack":
|
||||
if bb.health <= 0.0:
|
||||
if blackboard_get("health") <= 0.0:
|
||||
return 0.0
|
||||
if bb.melee_weapon_equipped:
|
||||
if bb.attack_cooldown <= 0.0:
|
||||
if blackboard_get("melee_weapon_equipped"):
|
||||
if blackboard_get("attack_cooldown") <= 0.0:
|
||||
var d = attack_distance * attack_distance
|
||||
if bb.stamina > 20.0 && bb.enemy_distance <= d:
|
||||
if blackboard_get("stamina") > 20.0 && blackboard_get("enemy_distance") <= d:
|
||||
return 50.0
|
||||
"flee":
|
||||
if bb.health <= 0.0:
|
||||
if blackboard_get("health") <= 0.0:
|
||||
return 0.0
|
||||
if bb.flee_cooldown > 0.0:
|
||||
if blackboard_get("flee_cooldown") > 0.0:
|
||||
return 0.0
|
||||
if bb.stamina <= 50.0 && bb.stamina > 10.0 && bb.enemy_distance < flee_distance * flee_distance:
|
||||
return 100.0 + clamp((100.0 - bb.stamina), 0, 90.0) * 2.0
|
||||
if bb.stamina <= 10.0 && bb.enemy_distance <= flee_distance * flee_distance * 0.5:
|
||||
if blackboard_get("stamina") <= 50.0 && blackboard_get("stamina") > 10.0 && blackboard_get("enemy_distance") < flee_distance * flee_distance:
|
||||
return 100.0 + clamp((100.0 - blackboard_get("stamina")), 0, 90.0) * 2.0
|
||||
if blackboard_get("stamina") <= 10.0 && blackboard_get("enemy_distance") <= flee_distance * flee_distance * 0.5:
|
||||
return 250.0
|
||||
if bb.stamina <= 50.0 && bb.enemy_distance < engage_distance * engage_distance:
|
||||
if bb.randf < 0.3:
|
||||
if blackboard_get("stamina") <= 50.0 && blackboard_get("enemy_distance") < engage_distance * engage_distance:
|
||||
if blackboard_get("randf") < 0.3:
|
||||
return 100.0
|
||||
if bb.enemy_distance < 1.4 * 1.4:
|
||||
if blackboard_get("enemy_distance") < 1.4 * 1.4:
|
||||
return 150.0
|
||||
if bb.health < 50 && bb.health > 15:
|
||||
if blackboard_get("health") < 50 && blackboard_get("health") > 15:
|
||||
return 160
|
||||
"guard":
|
||||
if bb.health <= 0.0:
|
||||
if blackboard_get("health") <= 0.0:
|
||||
return 0.0
|
||||
if bb.guard_cooldown > 0.0:
|
||||
if blackboard_get("guard_cooldown") > 0.0:
|
||||
return 0.0
|
||||
elif bb.guard:
|
||||
bb.guard = false
|
||||
elif blackboard_get("guard"):
|
||||
blackboard_set("guard", false)
|
||||
return 300.0
|
||||
# elif bb.enemy_distance < guard_distance * guard_distance * 0.3 && bb.stamina > 10.0:
|
||||
# elif blackboard_get("enemy_distance") < guard_distance * guard_distance * 0.3 && blackboard_get("stamina") > 10.0:
|
||||
# return 80
|
||||
# elif bb.enemy_distance < attack_distance * attack_distance * 0.3:
|
||||
# elif blackboard_get("enemy_distance") < attack_distance * attack_distance * 0.3:
|
||||
# return 10.0
|
||||
"rest":
|
||||
if bb.stamina >= 100.0:
|
||||
return 0.0
|
||||
if bb.stamina <= 10.0 && bb.enemy_distance >= flee_distance * flee_distance:
|
||||
return 100.0 + bb.enemy_distance / 10.0
|
||||
if bb.health < 10:
|
||||
"unconcious":
|
||||
if blackboard_get("health") < 10:
|
||||
return 2000
|
||||
"get_melee_damage":
|
||||
if bb.health <= 0.0:
|
||||
"rest":
|
||||
if blackboard_get("stamina") >= 100.0:
|
||||
return 0.0
|
||||
if bb.melee_damage:
|
||||
bb.melee_damage = false
|
||||
print("DAMAGE2 ", bb.health)
|
||||
if blackboard_get("stamina") <= 10.0 && blackboard_get("enemy_distance") >= flee_distance * flee_distance:
|
||||
return 100.0 + blackboard_get("enemy_distance") / 10.0
|
||||
"get_melee_damage":
|
||||
if blackboard_get("health") <= 0.0:
|
||||
return 0.0
|
||||
if blackboard_get("melee_damage"):
|
||||
blackboard_set("melee_damage", false)
|
||||
print("DAMAGE2 ", blackboard_get("health"))
|
||||
return 1000
|
||||
_:
|
||||
assert(false)
|
||||
@@ -473,7 +510,7 @@ func select_behavior():
|
||||
best_behavior = "rest"
|
||||
best_utility = 0.0
|
||||
for e in conf_behaviors.keys():
|
||||
var utility = calc_utility(e, blackboard)
|
||||
var utility = calc_utility(e)
|
||||
if e == last_behavior:
|
||||
utility *= 2.0
|
||||
if best_utility < utility:
|
||||
@@ -486,7 +523,7 @@ var last_bhv
|
||||
var last_running = []
|
||||
var current_running = []
|
||||
var run_behaviors = {}
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
assert(initialized)
|
||||
assert(root)
|
||||
var cam = root.get_viewport().get_camera()
|
||||
@@ -498,10 +535,10 @@ func update_physics(delta):
|
||||
var o = root.global_transform.origin
|
||||
var p = cam.get_meta("player").global_transform
|
||||
pdst = o.distance_squared_to(p.origin)
|
||||
blackboard.enemy_distance = pdst
|
||||
blackboard.randf = rnd.randf()
|
||||
blackboard.enemy_pos = p.origin
|
||||
blackboard.space = space
|
||||
blackboard_set("enemy_distance", pdst)
|
||||
blackboard_set("randf", rnd.randf())
|
||||
blackboard_set("enemy_pos", p.origin)
|
||||
blackboard_set("space", space)
|
||||
# var adest = o + (p.origin - o).normalized() * min(2.0, sqrt(pdst))
|
||||
var adest = p.origin
|
||||
var away = (o - p.origin).normalized()
|
||||
@@ -511,7 +548,7 @@ func update_physics(delta):
|
||||
var enemy_dir: Vector3 = Transform(p.basis, Vector3()).xform(Vector3(0, 0, -1))
|
||||
var root_dir: Vector3 = Transform(root.global_transform.basis, Vector3()).xform(Vector3(0, 0, -1))
|
||||
var dot = root_dir.dot(enemy_dir)
|
||||
blackboard.dot = dot
|
||||
blackboard_set("dot", dot)
|
||||
|
||||
var prev_state = state
|
||||
match state:
|
||||
@@ -544,6 +581,8 @@ func update_physics(delta):
|
||||
run_behaviors[bhv].start(root, "guard-melee1", "guard-front-melee1")
|
||||
"get_melee_damage":
|
||||
run_behaviors[bhv].start(root, "guard-melee1", "guard-front-melee1", 10.0)
|
||||
"unconcious":
|
||||
run_behaviors[bhv].start(root, "fall-front", "fall-back")
|
||||
_:
|
||||
assert(false)
|
||||
# print("adding behavior: ", bhv)
|
||||
@@ -552,10 +591,10 @@ func update_physics(delta):
|
||||
if !e in last_running:
|
||||
if !e.active:
|
||||
e.activate()
|
||||
e.run(delta, blackboard)
|
||||
e.run(delta, blackboard_get_dict())
|
||||
#FIXME: mess :(
|
||||
if e == run_behaviors["flee"]:
|
||||
blackboard.flee_cooldown = 2.0 + rnd.randf() * 3.0
|
||||
blackboard_set("flee_cooldown", 2.0 + rnd.randf() * 3.0)
|
||||
if e.finished && e.active:
|
||||
# print("in current run but finished")
|
||||
e.stop()
|
||||
@@ -570,18 +609,18 @@ func update_physics(delta):
|
||||
state = 3
|
||||
3:
|
||||
state = 0
|
||||
if blackboard.stamina < 100.0:
|
||||
blackboard.stamina += delta
|
||||
if blackboard.attack_cooldown > 0.0:
|
||||
blackboard.attack_cooldown -= delta
|
||||
if blackboard.guard_cooldown > 0.0:
|
||||
blackboard.guard_cooldown -= delta
|
||||
if blackboard.flee_cooldown > 0.0:
|
||||
blackboard.flee_cooldown -= delta
|
||||
blackboard.stamina = clamp(blackboard.stamina, 0, 100.0)
|
||||
blackboard.health = clamp(blackboard.health, 0, 100.0)
|
||||
if blackboard_get("stamina") < 100.0:
|
||||
blackboard_set("stamina", blackboard_get("stamina") + delta)
|
||||
if blackboard_get("attack_cooldown") > 0.0:
|
||||
blackboard_set("attack_cooldown", blackboard_get("attack_cooldown") - delta)
|
||||
if blackboard_get("guard_cooldown") > 0.0:
|
||||
blackboard_set("guard_cooldown", blackboard_get("guard_cooldown") - delta)
|
||||
if blackboard_get("flee_cooldown") > 0.0:
|
||||
blackboard_set("flee_cooldown", blackboard_get("flee_cooldown") - delta)
|
||||
blackboard_set("stamina", clamp(blackboard_get("stamina"), 0, 100.0))
|
||||
blackboard_set("health", clamp(blackboard_get("health"), 0, 100.0))
|
||||
return ERR_BUSY
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
return ERR_BUSY
|
||||
|
||||
##
|
||||
|
||||
@@ -6,7 +6,7 @@ extends AIScriptModule
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func init():
|
||||
func init(tick):
|
||||
var root = get_character()
|
||||
assert(root.has_meta("skeleton"))
|
||||
var cmdq = []
|
||||
@@ -38,7 +38,7 @@ func action(data):
|
||||
# print(data)
|
||||
# marker_hips_action(data)
|
||||
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
return ERR_BUSY
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
return ERR_BUSY
|
||||
|
||||
@@ -24,7 +24,7 @@ var material = preload("res://scenes/clothes/mystress_clothes.material")
|
||||
# ACTION
|
||||
#}
|
||||
#var state = PRAYING
|
||||
func init():
|
||||
func init(tick):
|
||||
root = get_character()
|
||||
assert(root.has_meta("skeleton"))
|
||||
root.add_to_group("mystress")
|
||||
@@ -74,7 +74,7 @@ func get_dest(pt: Vector3, exclusions: Array) -> Vector3:
|
||||
if !r.empty():
|
||||
ret = r.position - offt
|
||||
return ret
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
var cmdq = []
|
||||
if !skel:
|
||||
skel = root.get_meta("skeleton")
|
||||
@@ -226,5 +226,5 @@ func update_physics(delta):
|
||||
## cmdq.push_back(["equip", "wrist_r/weapon_right", "s_dagger"])
|
||||
## other.set_meta("cmdqueue", cmdq)
|
||||
## group_manager.submit_player_npc_event_arot(root, "sacrificed-a", root, "sacrificed", root)
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
return ERR_BUSY
|
||||
|
||||
@@ -22,7 +22,7 @@ var basedir = "res://scenes/clothes/"
|
||||
var material_female = preload("res://scenes/clothes/nun-clothes.material")
|
||||
var material_male = preload("res://scenes/clothes/clothes-male.material")
|
||||
|
||||
func init():
|
||||
func init(tick):
|
||||
name = "student_ai"
|
||||
root = get_character()
|
||||
assert(root.has_meta("skeleton"))
|
||||
@@ -42,8 +42,8 @@ func init():
|
||||
g += garments_male_main
|
||||
h += garments_head_male
|
||||
characters.call_deferred("setup_garments", root, g, h, material_male)
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
return ERR_BUSY
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
return ERR_BUSY
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ var garments = ["male-panties1", "male-shirt1"]
|
||||
var garments_head = []
|
||||
var basedir = "res://scenes/clothes/"
|
||||
var material = preload("res://scenes/clothes/clothes-male.material")
|
||||
func init():
|
||||
func init(tick):
|
||||
root = get_character()
|
||||
assert(root.has_meta("skeleton"))
|
||||
|
||||
@@ -81,8 +81,8 @@ func setup_garments():
|
||||
# cmdq.push_back(["equip", "wrist_r/weapon_right", "s_dagger"])
|
||||
# other.set_meta("cmdqueue", cmdq)
|
||||
# group_manager.submit_player_npc_event_arot(root, "sacrificed-a", root, "sacrificed", root)
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
return ERR_BUSY
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
return ERR_BUSY
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ extends AIScriptModule
|
||||
var cam
|
||||
var fps_cam
|
||||
var motion = Vector2()
|
||||
func init():
|
||||
func init(tick):
|
||||
var root = get_character()
|
||||
assert(root.has_meta("skeleton"))
|
||||
|
||||
@@ -19,7 +19,7 @@ var jump = false
|
||||
var equipped = false
|
||||
var vjump = Vector3()
|
||||
|
||||
func update(delta):
|
||||
func update(tick, delta):
|
||||
if !controls.is_gui:
|
||||
if !attack:
|
||||
if Input.is_action_just_pressed("attack"):
|
||||
@@ -31,7 +31,7 @@ func update(delta):
|
||||
return ERR_BUSY
|
||||
|
||||
|
||||
func update_physics(delta):
|
||||
func update_physics(tick, delta):
|
||||
var orientation: Transform
|
||||
var root = get_character()
|
||||
if !root.has_meta("cam"):
|
||||
|
||||
Reference in New Issue
Block a user