Closed Nordsoft91 closed 5 months ago
@peter-kish Maybe item_slot_cleared() should give you the slot which is clearing as well like item_slot_cleared(slot)
?
Also, suggest to change signature of item_equipped() signal from slot to item_equipeed(item) to get infotmation about item was equipped.
@Nordsoft91 or should it be item_equipped(slot) and then you can slot.get_item()
on it.
I guess technically I can just bind the slots myself like:
head_slot.connect("item_equipped",_on_slot_item_equipped.bind(head_slot))
chest_slot.connect("item_equipped",_on_slot_item_equipped.bind(chest_slot))
However I would imagine most users would be connecting the signal from within the Godot editor :thinking: .
This is my current code to give you an idea:
Note: I was just trying to get something working; so its very much copy-pasta :spaghetti: . I think doing the bind slot thing should simplify the code.
@onready var head_slot := %head_slot
@onready var chest_slot := %chest_slot
@onready var boots_slot := %boots_slot
@onready var neck_slot := %neck_slot
@onready var belt_slot := %belt_slot
@onready var gloves_slot := %gloves_slot
@onready var main_weapon_slot := %main_weapon_slot
@onready var right_ring_slot := %right_ring_slot
@onready var offhand_slot := %offhand_slot
@onready var left_ring_slot := %left_ring_slot
head_slot.connect("item_equipped",_on_head_slot_item_equipped)
chest_slot.connect("item_equipped",_on_chest_slot_item_equipped)
boots_slot.connect("item_equipped",_on_boots_slot_item_equipped)
neck_slot.connect("item_equipped",_on_neck_slot_item_equipped)
belt_slot.connect("item_equipped",_on_belt_slot_item_equipped)
gloves_slot.connect("item_equipped",_on_gloves_slot_item_equipped)
main_weapon_slot.connect("item_equipped",_on_main_weapon_slot_item_equipped)
offhand_slot.connect("item_equipped",_on_offhand_slot_item_equipped)
left_ring_slot.connect("item_equipped",_on_left_ring_slot_item_equipped)
right_ring_slot.connect("item_equipped",_on_right_ring_slot_item_equipped)
head_slot.connect("cleared",_on_head_slot_cleared)
chest_slot.connect("cleared",_on_chest_slot_cleared)
boots_slot.connect("cleared",_on_boots_slot_cleared)
neck_slot.connect("cleared",_on_neck_slot_cleared)
belt_slot.connect("cleared",_on_belt_slot_cleared)
gloves_slot.connect("cleared",_on_gloves_slot_cleared)
main_weapon_slot.connect("cleared",_on_main_weapon_slot_cleared)
offhand_slot.connect("cleared",_on_offhand_slot_cleared)
left_ring_slot.connect("cleared",_on_left_ring_slot_cleared)
right_ring_slot.connect("cleared",_on_right_ring_slot_cleared)
func _on_head_slot_item_equipped() -> void:
var equpped_helm:InventoryItem = head_slot.get_item()
match equpped_helm.get_property("id"):
"wolf_cape":
print("wolfcape")
add_item_to_character(wolf_cape,player_head,manikan_head)
clear_item_if_no_match_type(["helm"],equpped_helm,head_slot)
pass
func _on_chest_slot_item_equipped() -> void:
var equipped_chest:InventoryItem = chest_slot.get_item()
match equipped_chest.get_property("id"):
"wolf_cape":
print("wolfcape")
add_item_to_character(wolf_cape,player_chest,manikan_chest)
clear_item_if_no_match_type(["helm"],equipped_chest,chest_slot)
pass
func _on_boots_slot_item_equipped() -> void:
var equipped_boots:InventoryItem = boots_slot.get_item()
match equipped_boots.get_property("id"):
"wolf_cape":
print("wolfcape")
add_item_to_character(wolf_cape,player_boots,manikan_boots)
clear_item_if_no_match_type(["helm"],equipped_boots,boots_slot)
pass
func _on_neck_slot_item_equipped() -> void:
var equipped_neck:InventoryItem = neck_slot.get_item()
match equipped_neck.get_property("id"):
"wolf_cape":
add_item_to_character(wolf_cape,player_neck,manikan_neck)
clear_item_if_no_match_type(["helm"],equipped_neck,neck_slot)
pass
func _on_belt_slot_item_equipped() -> void:
var equipped_belt:InventoryItem = belt_slot.get_item()
match equipped_belt.get_property("id"):
"wolf_cape":
add_item_to_character(wolf_cape,player_belt,manikan_belt)
clear_item_if_no_match_type(["helm"],equipped_belt,belt_slot)
pass
func _on_gloves_slot_item_equipped() -> void:
var equipped_gloves:InventoryItem = gloves_slot.get_item()
match equipped_gloves.get_property("id"):
"wolf_cape":
add_item_to_character(wolf_cape,player_gloves,manikan_gloves)
clear_item_if_no_match_type(["helm"],equipped_gloves,gloves_slot)
pass
func _on_main_weapon_slot_item_equipped() -> void:
var equipped_main_weapon:InventoryItem = main_weapon_slot.get_item()
match equipped_main_weapon.get_property("id"):
"wolf_cape":
add_item_to_character(wolf_cape,player_main_weapon,manikan_main_weapon)
clear_item_if_no_match_type(["helm"],equipped_main_weapon,main_weapon_slot)
pass
func _on_offhand_slot_item_equipped() -> void:
var equipped_offhand:InventoryItem = offhand_slot.get_item()
match equipped_offhand.get_property("id"):
"wolf_cape":
add_item_to_character(wolf_cape,player_offhand,manikan_offhand)
clear_item_if_no_match_type(["helm"],equipped_offhand,offhand_slot)
pass
func _on_left_ring_slot_item_equipped() -> void:
var equipped_left_ring:InventoryItem = left_ring_slot.get_item()
match equipped_left_ring.get_property("id"):
"wolf_cape":
add_item_to_character(wolf_cape,player_ring_left,manikan_ring_left)
clear_item_if_no_match_type(["helm"],equipped_left_ring,left_ring_slot)
pass
func _on_right_ring_slot_item_equipped() -> void:
var equipped_right_ring:InventoryItem = right_ring_slot.get_item()
match equipped_right_ring.get_property("id"):
"wolf_cape":
add_item_to_character(wolf_cape,player_ring_right,manikan_ring_right)
clear_item_if_no_match_type(["helm"],equipped_right_ring,right_ring_slot)
pass
func _on_head_slot_cleared() -> void:
remove_items_from_character(player_head,manikan_head)
pass # Replace with function body.
func _on_chest_slot_cleared() -> void:
remove_items_from_character(player_chest,manikan_chest)
pass # Replace with function body.
func _on_boots_slot_cleared() -> void:
remove_items_from_character(player_boots,manikan_boots)
pass # Replace with function body.
func _on_neck_slot_cleared() -> void:
remove_items_from_character(player_neck,manikan_neck)
pass
func _on_belt_slot_cleared() -> void:
remove_items_from_character(player_belt,manikan_belt)
pass
func _on_gloves_slot_cleared() -> void:
remove_items_from_character(player_gloves,manikan_gloves)
pass
func _on_main_weapon_slot_cleared() -> void:
remove_items_from_character(player_main_weapon,manikan_main_weapon)
pass
func _on_offhand_slot_cleared() -> void:
remove_items_from_character(player_offhand,manikan_offhand)
pass
func _on_right_ring_slot_cleared() -> void:
remove_items_from_character(player_ring_right,manikan_ring_right)
pass
func _on_left_ring_slot_cleared() -> void:
remove_items_from_character(player_ring_left,manikan_ring_left)
pass
func clear_item_if_no_match_type(match_types:Array[String],equipped_item:InventoryItem,slot:ItemSlot)->void:
for match_type in match_types:
if equipped_item.get_property("item_type") != match_type:
slot.clear()
InventoryItem.get_slot()
- Yeah, it makes sense. It would also be coherent with InventoryItem.get_inventory()
.InventoryItem.remove_from_inventory()
- I'll consider this one as well. It looks a lot more elegant than doing something like item.get_inventory().remove_item(item)
.InventoryItem.add_to_inventory(inv)
- Not sure about this one... I think item.add_to_inventory(inv)
is the same as inv.add_item(item)
and I'm trying to keep the interface minimal....ItemSlotBase.item_equipped(item)
- I don't really see the point in this since the equipped item can easily be obtained by ItemSlotBase.get_item()
once the signal has been triggered. Again, the purpose of this is to keep the interface small. It's also what Godot does. E.g. the Control.resized
signal has no parameters, because the newly set size can be read from Control.size
.Maybe item_slot_cleared() should give you the slot which is clearing as well like item_slot_cleared(slot)?
Not sure if I understand this. ItemSlot
defines the cleared
signal and you would definitely know which slot emitted the signal (the one you called connect
on). Or are you talking about a global signal?
Maybe item_slot_cleared() should give you the slot which is clearing as well like item_slot_cleared(slot)?
Not sure if I understand this.
ItemSlot
defines thecleared
signal and you would definitely know which slot emitted the signal (the one you calledconnect
on). Or are you talking about a global signal?
How do you know which slot was cleared?; when cleared signal is triggered/emitted if is using the same callback (assuming signals were connected to slots via editor not hard coded like below):
head_slot.connect("cleared",_on_slot_cleared)
chest_slot.connect("cleared",_on_slot_cleared)
boots_slot.connect("cleared",_on_slot_cleared)
neck_slot.connect("cleared",_on_slot_cleared)
belt_slot.connect("cleared",_on_slot_cleared)
gloves_slot.connect("cleared",_on_slot_cleared)
main_weapon_slot.connect("cleared",_on_slot_cleared)
offhand_slot.connect("cleared",_on_slot_cleared)
left_ring_slot.connect("cleared",_on_slot_cleared)
right_ring_slot.connect("cleared",_on_slot_cleared)
func _on_slot_cleared() -> void:
remove_item_from_character(slot.get_item())
pass
How do you know which slot was cleared?
The same way as with other Godot signals. If you're connecting signals from the editor then each object gets its own callback.
func _on_btn1_pressed():
pass # Replace with function body.
func _on_btn2_pressed():
pass # Replace with function body.
If you're connecting signals from code (your example) then you also have the options to bind parameters to the callback:
obj1.connect("signal", _on_signal.bind(obj1))
obj2.connect("signal", _on_signal.bind(obj2))
func _on_signal(obj):
pass # Replace with function body.
Maybe I'm missing something but this is not really different from native Godot signals.
Maybe I'm missing something but this is not really different from native Godot signals.
Well some signals do give you arguments. Like for example; area_shape_entered gives you four of them:
I think you can connect to the same callback from the editor as well. Like lets say you have two Area2D nodes and you connect them to the same callback:
You can do this by typing into the receiver method box the same callback name.
In this case you would get the Body entered from either Area2D nodes in the one callback function.
All I'm saying is, if you give the slot then you could achieve the same from the editor as connecting and binding the slots to the same callback from code.
The use case is that you probably have some of the same logic, so you probably don't need multiple different callbacks with the same logic.
Either way, I'm not worried, I'll just connect and bind them in code; but newbies might not know how to do this.
Well some signals do give you arguments. Like for example; area_shape_entered gives you four of them
Sure, signal arguments in general are totally fine. I'm just saying that it makes no sense to add them for values that are easily obtainable in other ways (e.g. the Control.resized
and Button.pressed
signals I mentioned previously). It only clutters the interface.
As for newbie friendliness, I prefer being consistent with the existing Godot API. I agree that the interface should be simple to use, but adding unnecessary parameters doesn't really contribute to its simplicity.
InventoryItem.get_slot()
is now available in v2.4.6.
I'm still unsure about InventoryItem.remove_from_inventory()
and decided to leave it out for now for the sake of a minimal interface. I will keep it in mind and might add it in a later release if it turns out to be super useful.
Suggest to add methods into InventoryItem class:
get_slot() -> ItemSlotBase
- returns slot where item is currently equipped. Why: while iterating overinventory.get_items()
it's unclear which items are already equipped. Also, currently it's impossible to get slot object without knowing all slot objects and storing them somewhere elseremove_from_inventory() / add_to_inventory(Inventory)
- changes current inventory. Useful for gameplay actions pickup item, use itemAlso, suggest to change signature of item_equipped() signal from slot to item_equipeed(item) to get infotmation about item was equipped