extends State enum ManCannonStates { INITIAL, OPERATE_CANNON, MOVE_TO_CANNON, FIND_CANNONBALL } var ai_substate: int var path_requested: bool = false var retry_timer: float = 0.0 var searching_for: String var cannon: NetMachine # Corresponds to the `_process()` callback. func update(delta: float) -> void: retry_timer -= delta # Virtual function. Corresponds to the `_physics_process()` callback. func physics_update(_delta: float) -> void: match ai_substate: ManCannonStates.INITIAL: _state_initial() ManCannonStates.MOVE_TO_CANNON: _state_move_to_cannon() ManCannonStates.FIND_CANNONBALL: _state_find_cannonball() ManCannonStates.OPERATE_CANNON: _state_operate_cannon() func _state_initial() -> void: if cannon.loaded: change_substate(ManCannonStates.MOVE_TO_CANNON) else: change_substate(ManCannonStates.FIND_CANNONBALL) func _state_move_to_cannon() -> void: if !path_requested: #CharacterAIManager.request_find_path(owner, Vector3.ZERO, true, cannon.get_node("AINavPoint")) owner.ai_set_path_target(cannon.get_node("AINavPoint").global_transform.origin) owner.ai_set_look_status(cannon.steer_area, "TRACK") path_requested = true if (owner.global_transform.origin - cannon.get_node("AINavPoint").global_transform.origin).length_squared() > 4: owner.ai_set_path_target(cannon.get_node("AINavPoint").global_transform.origin) if retry_timer <= 0 and owner.use_ray.is_colliding(): if owner.use_ray.get_collider() == cannon.steer_area: owner.use_held = false owner.initiate_use() if !cannon.loaded: owner.use_held = true retry_timer = 3.1 if owner.machine == cannon: owner.ai_set_look_status(null, "NONE") retry_timer = 1.0 change_substate(ManCannonStates.OPERATE_CANNON) func _state_find_cannonball() -> void: #CHECK FOR BALL BOX FIRST! /setaistate Player ManCannon if !path_requested: CharacterAIManager.request_find_object(owner, "BallBarrel", 50, true) searching_for = "BallBarrel" path_requested = true #if !path_requested: # CharacterAIManager.request_find_object(owner, "Cannonball", 50, false) # searching_for = "Cannonball" # path_requested = true if owner.use_ray.is_colliding(): if owner.use_ray.get_collider().name.begins_with("UseArea") and owner.use_ray.get_collider().get_parent().name.begins_with(searching_for): owner.initiate_use() #cannonball found if owner.inventory["cannonball"] > 0: change_substate(ManCannonStates.MOVE_TO_CANNON) func _state_operate_cannon() -> void: if owner.machine != cannon: #if control lost if is_instance_valid(cannon): change_substate(ManCannonStates.MOVE_TO_CANNON) else: state_machine.transition_to("Idle") return if retry_timer <= 0.0: cannon.attack1() owner.initiate_use() change_substate(ManCannonStates.FIND_CANNONBALL) func change_substate(to: int): path_requested = false ai_substate = to func enter(msg := {}) -> void: retry_timer = 0 ai_substate = ManCannonStates.INITIAL if "cannon" in msg.keys(): cannon = msg["cannon"] else: if owner.ai_target_machine != null: cannon = owner.ai_target_machine return var bodies = owner.get_node("AISearchArea").get_overlapping_bodies() for body in bodies: if body.name.begins_with("Cannon"): cannon = body return #if cannon not found print("cannon not found") state_machine.transition_to("Idle") func exit() -> void: pass