extends BTAction class_name BTSetAction export var min_distance = 9.0 #func utility_player_nearby(tick): # var player = global.player # var npc = tick.actor # if combat.player_nearby(npc, min_distance): # var player_pos = player.global_transform.origin # var npc_pos = npc.global_transform.origin # var dst = player_pos.distance_to(npc_pos) # if dst < min_distance: # return 1.0 - dst / min_distance # return 0.0 func utility_enemy_nearby(tick: Tick): var bb = tick.blackboard var npc = tick.actor var enemy = bb.get("closest_enemy") # var enemy_dist = bb.get("closest_enemy_distance") if !enemy: return 0.0 var enemy_pos = enemy.global_transform.origin var npc_pos = npc.global_transform.origin var dst = enemy_pos.distance_to(npc_pos) if dst < min_distance: # print("nearby: ", 1.0 - dst / min_distance) return clamp(1.0 - dst / min_distance, 0.0, 1.0) return clamp(1.0 / (1.0 + 10.0 * dst * dst), 0.0, 1.0) func utility_attack(tick): var npc = tick.actor var ret = utility_enemy_nearby(tick) * npc.get_meta("agression") / 100.0 if npc.get_meta("weapon") == false: ret = 0.0 if utility_enemy_nearby(tick) > 0.5: ret *= 0.2 if utility_enemy_nearby(tick) > 0.5 && npc.is_in_group("guard"): ret = 1.0 if npc.is_in_group("maid"): ret = 0.0 return clamp(ret, 0.0, 1.0) func utility_can_hide(tick): var npc = tick.actor var ret = 0.0 if rpg.get_stamina(npc) * rpg.get_health(npc) > 0.1: ret = 1.0 if utility_enemy_nearby(tick) > 0.85: ret = 0.1 return ret func utility_hide(tick): var npc = tick.actor if npc.is_in_group("guard"): return 0.0 if utility_enemy_nearby(tick) > 0.9: return 0.0 return clamp(utility_can_hide(tick) * (0.1 + utility_enemy_nearby(tick)), 0.0, 1.0) func utility_run_away(tick): var npc = tick.actor var ret = utility_enemy_nearby(tick) * (1.0 + npc.get_meta("panic")) print(ret) # if npc.is_in_group("maid"): # ret = utility_player_nearby(tick) * 0.1 * npc.get_meta("panic") if npc.get_meta("weapon") == false: ret *= 2.5 if npc.is_in_group("guard"): return 0.0 if npc.is_in_group("maid"): return clamp(ret, 0.0, 0.1) return clamp(ret, 0.0, 1.0) func utility_find_weapon(tick): var npc = tick.actor if npc.get_meta("weapon") == true: return 0.0 if get_tree().get_nodes_in_group("weapons").size() == 0: return 0.0 if npc.is_in_group("guard"): return 0.0 if npc.is_in_group("maid"): return 0.0 return 1.0 / (1.0 + utility_enemy_nearby(tick)) func utility_wash_floor(tick): var npc = tick.actor if npc.is_in_group("maid"): return 1.0 return 0.0 func utility_patrol(tick): var npc = tick.actor if npc.is_in_group("guard"): return 1.0 return 0.0 func utility_unstuck(tick): var npc = tick.actor if npc.has_meta("stuck"): var stuck = npc.get_meta("stuck") if stuck > 0.0: return 1.0 else: npc.set_meta("stuck", null) return 0.0 func utility_give_up(tick): var npc = tick.actor if npc.is_in_group("guard"): return 0.0 elif npc.is_in_group("maid"): return clamp(rpg.get_panic(npc) / 100.0, 0.0, 1.0) else: return clamp(rpg.get_panic(npc) / 1000.0, 0.0, 1.0) func utility_deliver_captive(tick): var npc = tick.actor if npc.get_meta("grabbing"): var item = grabbing.get_grabbed(npc) if item.is_in_group("captive"): return 1.0 else: return 0.0 func utility_forcing(tick): var npc = tick.actor var bb = tick.blackboard if npc.is_in_group("female"): return 0.0 if npc.get_meta("grabbing"): return 0.0 if npc.get_meta("grabbed"): return 0.0 if !npc.is_in_group("guard"): if utility_enemy_nearby(tick) * 100.0 > 1.0: return 0.0 var closest_f = bb.get("closest_visible_female") var xd = bb.get("closest_visible_female_distance") if !closest_f: closest_f = bb.get("closest_female") xd = bb.get("closest_female_distance") if !closest_f: return 0.0 var d = (1.0 + 0.1 * rpg.get_lust(npc)) / (1.0 + xd) return clamp(d, 0.0, 1.0) var actions = { "unstuck": 200.0, "attack": 40.0, "hide": 40.0, "run_away": 6500.0, "find_weapon": 30.0, "wash_floor": 30.0, "patrol": 20.0, "deliver_captive": 20.0, "forcing": 4000.0, "give_up": 210.0 } func tick(tick: Tick) -> int: var npc = tick.actor if !npc.has_meta("action"): npc.set_meta("action", "") var current_action = npc.get_meta("action") var current_score = 0.0 # var old_action = current_action # if actions.has(current_action): # current_score = actions[current_action] * 1.5 if current_action == "": print("score: ", current_score) for k in actions.keys(): var score = call("utility_" + k, tick) * actions[k] if k == current_action: score *= 1.5 if current_score < score: current_score = score current_action = k if current_action == "": print("utility_" + k, " ", actions[k], " ", score) npc.set_meta("action", current_action) print(npc.name) assert(npc.get_meta("action").length() > 0) print(npc.name, " ", current_action) assert(current_action.length() > 0) return OK