Heal function not working correctly, Signal isnt received

Godot Version

4.2.1

Question

I have made this HP system and it is done but for some reason, the heal function is not working at all. I use signals between scripts. the damage works but the heal doesnt.
this is the code for item:

var item=null

func use_item(item):
	if item["name"] == "beef":
		print("Emitting heal signal for beef")
		Globalinventory.emit_signal("heal", 10)  # Emit heal signal from the global inventory
		item["quantity"] -= 1
		if item["quantity"] <= 0:
			Globalinventory.inventory.erase(item)
		Globalinventory.inventory_updates.emit()


func _use_on_button_pressed():
	use_item(item)

this is the global HP script:

var player_health: float = 100.0

# Signal to notify when health changes
signal health_changed(new_health)

func take_damage(amount: float):
	player_health -= amount
	player_health = clamp(player_health, 0.0, 100.0)
	emit_signal("health_changed", player_health)

func heal(amount: float):
	print("Healing player by:", amount)
	player_health += amount
	player_health = clamp(player_health, 0.0, 100.0)
	print("New global health:", player_health)
	emit_signal("health_changed", player_health)

this is the code for heal and hp inside the player script:

func _ready():
	Globalinventory.set_player_ref(self)
	HpMofatesh.connect("health_changed", Callable(self, "health_changed"))
	
	if Globalinventory.connect("heal", Callable(self, "heal")) == OK:
		print("Heal signal connected successfully")
	else:
		print("Failed to connect heal signal")
	call_deferred("connect_to_monster")

func heal(amount: float):
	print("Heal function called with amount:", amount)
	HpMofatesh.heal(amount)  # Use global health
 # health = HpMofatesh.player_health  
	print("New health:", HpMofatesh.player_health) 
	emit_signal("health_changed", HpMofatesh.player_health)  # Emit signal for health change
	await flash_green()

func flash_green():
	modulate = Color(0, 1, 0, 0.81)  # Green color
	await get_tree().create_timer(0.3).timeout
	modulate = Color(0.816, 0.82, 0.816, 0.51)
	await get_tree().create_timer(0.3).timeout
	modulate = Color(0, 1, 0, 1)  # Green color
	await get_tree().create_timer(0.3).timeout
	modulate = Color(0.816, 0.82, 0.816, 0.51)
	await get_tree().create_timer(0.3).timeout
	modulate = Color(0, 1, 0, 1)  # Green color
	await get_tree().create_timer(0.3).timeout
	modulate = Color(1, 1, 1, 1)  # Reset to default color

now this heal function doesnt work, but the dmg code works perfectly. this is this is the code for the monster(enemy) give dmg:

func _on_dmg_body_entered(body):
	if body.name == "player" and spawn==true:
		print("he is in, signal sent")
		emit_signal("player_damaged", 20)

this is the code inside the player taking dmg:

func connect_to_monster():
	var monsters = get_tree().get_nodes_in_group("monster")
	print("Number of monsters found: ", monsters.size())  # Debugging
	for monster in monsters:
		if monster.has_signal("player_damaged"):
			monster.connect("player_damaged", Callable(self, "take_damage"))
			print("Connected to monster's player_damaged signal")  # Debugging
# Health-related functions
func take_damage(amount: float):
	print("Player received damage signal: ", amount)
	HpMofatesh.take_damage(amount)  # Use global health
	health = HpMofatesh.player_health  # Update local health variable
	if health <= 0:
		die()
	await flash_red()
func flash_red():
	# Set the player's modulate to red
	modulate = Color(1, 0, 0, .81)  # Red color
	await get_tree().create_timer(0.3).timeout
	modulate=Color(0.816,0.82,0.816,0.51)
	await get_tree().create_timer(0.3).timeout
	modulate = Color(1, 0, 0, 1)  # Red color
	await get_tree().create_timer(0.3).timeout
	modulate=Color(0.816,0.82,0.816,0.51)
	await get_tree().create_timer(0.3).timeout
	modulate = Color(1, 0, 0, 1)  # Red color
	await get_tree().create_timer(0.3).timeout
	modulate=Color(1,1,1,1)

can someone help? I have no idea whats wrong. the signal emits, but the player does not receive it.

What you are saying is that the signals connect correctly but this line is not printed. Right?

Also is there any reason you connect to signals this way?

I’ve never used a callable this way, I always either pass the function signature or define an anonymous callable in place. I’m not really sure it has anything to do with your problem but you might as well try just doing

Globalinventory.connect("heal",heal)

nothing happened, of course I added the line in the ready function. should I add the line somewhere else?

You have a lot of prints in your code, what does your output log look like? Have you tried using Godot 4.x signal connection style instead?

# connecting old 3.x
HpMofatesh.connect("health_changed", Callable(self, "health_changed"))
# new 4.x
HpMofatesh.health_changed.connect(health_changed)

# emitting old 3.x
emit_signal("health_changed", player_health)
# new 4.x
health_changed.emit(player_health)

ok I will try this, but what about the amount of heal?

and this gives me an error

What about it? Make sure to explain what you expect to happen versus what really happens, I’ve only translated a signal connection and a emission, if you think there is an error with it then could you explain why?

What is the error?

Cool, so your script doesn’t have a health_changed function, it’s another signal. What do you expect this to do?

1 Like

bro im a noob coder… what did you expect me to do? :joy:

I am not trying to come off aggressive, the problem really is the computer doesn’t know what you want it to do, for me to help I have to know what you wanted/expected it to do and I can try to bridge the gap. If you do not know why that line is there or what purpose it served then it could be best to remove it.

1 Like

oh sorry.
HpMofatesh.connect(“health_changed”, Callable(self, “health_changed”)) is to conncet the global script for HP to the player script, specifically for the signals.

What is it supposed to do? Can you explain what function is expected of once it recieves a signal? Updating UI? Should it call the flash_green function?

1 Like

the heal function. it should heal the player. the heal function calls flash green function

once the signal gets received, the heal function should excute

Then I think you will have an infinite loop. You don’t want to heal every time the health changes.

If you wrote: HpMofatesh.health_changed.connect(heal) This cycle would continue forever

  1. health_changed emitted
  2. HpMofatesh.heal is called through the connection
  1. adds the current player health, essentially doubling the health
  2. Global heal function re-emits the signal
  1. back at square 1

Maybe it is best to remove the line?

1 Like

I deleted the line, nothing changes tho… the player doesnt get healed or flash green function excutes… good eye to notice that tho

Can you share what your output log looks like, I think the print statements will be very helpful.

1 Like

the first line and last line are for the item use

1 Like

Cool, so this problem stems from the item specifically?

I can see that it states it failed to connect, we could use more verbose error messages and again change your signal connection to use the 4.x style

var err := Globalinventory.heal.connect(heal)
if err != OK:
    # Getting a error message with `error_string`
    print("Failed to connect heal signal: ", error_string(err))
1 Like