|
|
|
|
Reply From: |
Inces |
It looks very similar to problem I had lately.
Ensure if your turn variable wasn’t translated to float during loading. You can’t tell the difference when printing variable, but You can print typeof(turn).
Ok, So You are saying that variable is correctly being assigned integers after loading, but despite this, turn state is always idle, as it WOULD be 0 ? Do You have some setters or getters inbetween, can You show this turn state changing code ?
Is it happening after loading, or after reentering the room ? Is there additional code doing something with NPCs upon reentering the room ? If so, show it too
yes, it’s 0 after loading, but only in the turn function.
no I don’t have setters or getter and I haven’t modified the state variable anywhere near the turn function, I’ve checked the whole script and scripts outside of it the only place I switch the state to idle is when combat ends and the npc still has hp, it’s just 0 inside the function but everywhere else it’s still working properly properly. I also tried to turn the turn function into a singaled function or have just have it being called from a different places but it still gives the exact same result
zen3001 | 2021-02-24 14:28
Ok but I still don’t get how is this error connected to loading ? You are saying it breaks after reentering the room after succesfully loading, but it works after loading and staying in the same room ?
I need a piece of code where loaded state value is transferred inside functions and used for determining behavior. There must be match statement somewhere, does it work, does it recognize loaded integer ?
at first everything works just fine, but when I exit the room and reenter it(which basically just saves the room and loads the save state of it), the turn function allways thinks that the variables value is 0 but in the rest of script it’s what I actually need it to be. the turn function is just a basic match case, where I’ve written the ai behaviour. I might not be the best coder but I’ve been looking at this script for days and nowhere in there does the script turn the state into 0 from the start of the function and takes it back to the original state when it ends.
zen3001 | 2021-02-24 15:50
I suspect match statement is not reading integer as enum constant somehow, or there might be an issue with _ready() function setting your enum to base 0 after it has been correctly set in _init(). Something like that, I can’t really imagine it without the code.
Again, ready can’t have anything to do with this since the variable is still working properly in every other function, I have a _process function that prints the variable name and the turn function does, and the console is filled with the proper state the character is supposed to be in but just when the turn function is executed the console puts out a 0 but if you insist, here’s the whole turn function:
func turn_ex():
if name == "Herberg":
print(npc_state)
glow(false)
match npc_state:
npc_states.idle:
if not $Area2D.get_overlapping_bodies().empty():
var player = $Area2D.get_overlapping_bodies()[0]
var p_pos = Vector2(player.map_pos()-map_pos()).normalized()
var closest = 3
var closest_key
for key in al_b.dir_vectors:
if al_b.dir_vectors[key].distance_to(p_pos) < closest:
closest = al_b.dir_vectors[key].distance_to(p_pos)
closest_key = key
direction = closest_key
change_sprite()
else:
if go_to.distance_to(global_position) < wander_distance:
var connections:Array = n_level.get_connections_from_glob(map_pos())
if name == "Herberg":
print(connections)
update_target(vec2dir(connections[int(rand_range(0, connections.size()))]-map_pos()))
else:
var path:Array = astar_path(go_to, true)
if path.size() > 1:
update_target(vec2dir(path[1]-map_pos()))
npc_states.run_away:
var connections:Array = get_parent().get_connections_from_glob(map_pos())
var bully_distances:Array
for con in connections:
bully_distances.append(con.distance_to(attackers[0].map_pos()))
update_target(vec2dir(connections[bully_distances.find(bully_distances.max())]-map_pos()))
npc_states.combat:
if weapon == null:
state_changed(npc_states.run_away)
if [al_b.types.PISTOL].has(weapon.type) and weapon.empty():
weapon.reload()
print(name+" is Reloading.")
else:
n_los.cast_to = n_los.to_local(victims[0].global_position)
yield(get_tree().create_timer(.1), "timeout")
var collider = n_los.get_collider()
var hit_chance = al_b.hit_chance(self, victims[0])
if collider != victims[0] or hit_chance < 25:
var connections = n_level.get_connections_from_glob(victims[0].map_pos())
var distances = []
for con in connections:
distances.append(con.distance_to(map_pos()))
var path = astar_path(connections[distances.find(distances.min())])
var chase_vec = vec2dir(path[1]-map_pos())
update_target(chase_vec)
else:
al_b.attack(victims[0], self)
update_victims()
update_attackers()
return npc_state
zen3001 | 2021-02-26 13:12
I’m sorry for demanding code, it is just too complicated to work with it in just theory
So there is nothing in turn function, that changes states, yet print insists, that change of state to 0 happens in the moment of turn() execution ?
It may be too much for me, I could only think of some outer sources influencing this function… Do You have setters or getters for state variable ? Why does turn function return state back ? Is anything using this returned state ? Is state variable assigned default value when it is defined ?
I manage to find a fix. the turn function is executed from an autoload, everytime an npc is loaded, it appends itself to an “ai” array in that autoload and everytime the player does something the turn function gets every node in the array and executes their turn function from there. I printed the state in that function and it game the same result the npc_turn function did. I seems to create a duplicate or something, I don’t what exactly or why it does that but the way I fixed it was instead having the ai array be full of nodes, it’s instead just the names of the NPCs and I calculate the path to them in the autoload and that somehow fixes it…
here’s the relevent code, hope you can figure out the issue with the array:
the autoload turn function:
onready var ai = []
var combat_speed = 2
func next_turn():
player.get_tree().get_root().set_disable_input(true)
for node in ai:
node = player.get_parent().get_node(node)
node.turn()
if node.npc_state == node.npc_states.combat:
yield(get_tree().create_timer(combat_speed/10), "timeout")
player.get_tree().get_root().set_disable_input(false)
the ready function where the npc appends itself to the array:
func after_astar():#parent map node executes this after generating the astar map.
al_b.ai.append(name)
match npc_state:
npc_states.dead, npc_states.gib:
die()
zen3001 | 2021-03-06 14:37
I get it that it is fixed code.
I see You never saved node references : so new node was created anew from loaded values and then it appended itself to array with new node reference ? It should be legit, did you print this array, did it have all nodes, were old nodes removed ?
You say some kind of duplicate was made inbetween those to functions. I had that little suspicion when I was asking about why NPC turn function returns state back. I was thinking if aren’t you by chance print(turn()) or x = turn() somewhere, thus unknowingly calling whole turn function additional time.
I changed the saving and loading code at somepoint it never made much of a difference related to the main issue in this thread only improved some different thing which I doubt are related to this. read top comment again for the new code.
I don’t know how this duplicate is supposed to have happened. In game, visually there is no evidence of any duplication, actually there’s no other evidence at all other than the issue I was having and how I managed to fix it.
zen3001 | 2021-03-06 17:13