Added rpg system for combat

added lots of loot to find
added level up system
This commit is contained in:
2026-01-11 23:12:09 +01:00
parent ab16194c39
commit 3a7fb29d58
32 changed files with 5076 additions and 96 deletions

View File

@@ -7,7 +7,8 @@ enum LootType {
APPLE,
BANANA,
CHERRY,
KEY
KEY,
ITEM # Item instance (equipment, consumables, etc.)
}
@export var loot_type: LootType = LootType.COIN
@@ -29,6 +30,7 @@ var bounce_timer: float = 0.0 # Prevent rapid bounce sounds
var coin_value: int = 1
var heal_amount: float = 20.0
var collected: bool = false
var item: Item = null # Item instance (for LootType.ITEM)
@onready var sprite = $Sprite2D
@onready var shadow = $Shadow
@@ -125,6 +127,20 @@ func _setup_sprite():
sprite.hframes = 20
sprite.vframes = 14
sprite.frame = (13 * 20) + 10
LootType.ITEM:
# Item instance - use item's spritePath and spriteFrame
if item and item.spritePath != "":
var items_texture = load(item.spritePath)
if items_texture:
sprite.texture = items_texture
sprite.hframes = item.spriteFrames.x if item.spriteFrames.x > 0 else 20
sprite.vframes = item.spriteFrames.y if item.spriteFrames.y > 0 else 14
sprite.frame = item.spriteFrame
print("Loot: Set up item sprite for ", item.item_name, " frame=", sprite.frame)
else:
print("Loot: ERROR - Could not load texture from spritePath: ", item.spritePath)
else:
print("Loot: ERROR - Item loot has no item instance or spritePath! item=", item)
func _setup_collision_shape():
if not collision_shape:
@@ -278,6 +294,21 @@ func _animate_coin(delta):
func _on_pickup_area_body_entered(body):
if body and body.is_in_group("player") and not body.is_dead:
# Check if this item was dropped by this player recently (5 second cooldown)
if has_meta("dropped_by_peer_id") and has_meta("drop_time"):
var dropped_by_peer_id = get_meta("dropped_by_peer_id")
var drop_time = get_meta("drop_time")
var current_time = Time.get_ticks_msec()
var time_since_drop = (current_time - drop_time) / 1000.0 # Convert to seconds
# Check if this player dropped the item and cooldown hasn't expired
if body.has_method("get_multiplayer_authority"):
var player_peer_id = body.get_multiplayer_authority()
if player_peer_id == dropped_by_peer_id and time_since_drop < 5.0:
# Player can't pick up their own dropped item for 5 seconds
print("Loot: Player ", body.name, " cannot pick up item they dropped (", time_since_drop, "s ago, need 5s cooldown)")
return
print("Loot: Pickup area entered by player: ", body.name, " is_local: ", body.is_local_player if "is_local_player" in body else "unknown", " is_server: ", multiplayer.is_server())
_pickup(body)
@@ -456,6 +487,61 @@ func _process_pickup_on_server(player: Node):
if sfx_key_collect and sfx_key_collect.playing:
await $SfxKeyCollect.finished
queue_free()
LootType.ITEM:
# Item instance pickup
if not item:
print("Loot: ERROR - Item loot has no item instance!")
queue_free()
return
if sfx_loot_collect:
sfx_loot_collect.play()
# Handle item pickup based on type
if item.item_type == Item.ItemType.Equippable:
# Equippable item - add to inventory
if player.character_stats:
player.character_stats.add_item(item)
print(name, " picked up item: ", item.item_name, " (added to inventory)")
elif item.item_type == Item.ItemType.Restoration:
# Consumable item - use immediately
if player.character_stats:
# Apply modifiers (hp, mp, etc.)
if item.modifiers.has("hp"):
var hp_heal = item.modifiers["hp"]
if player.has_method("heal"):
player.heal(hp_heal)
if item.modifiers.has("mp"):
var mana_amount = item.modifiers["mp"]
player.character_stats.restore_mana(mana_amount)
# TODO: Handle other modifiers (dodge_chance, res_all, etc.) - these would need duration tracking
print(name, " used item: ", item.item_name)
# Show floating text with item name
var items_texture = load(item.spritePath)
var display_text = item.item_name
var text_color = Color.WHITE
# Color code based on item type
if item.item_type == Item.ItemType.Equippable:
text_color = Color.CYAN # Cyan for equipment
elif item.item_type == Item.ItemType.Restoration:
text_color = Color.GREEN # Green for consumables
_show_floating_text(player, display_text, text_color, 0.5, 0.5, items_texture, item.spriteFrames.x, item.spriteFrames.y, item.spriteFrame)
# Sync floating text to client
if multiplayer.has_multiplayer_peer() and player.get_multiplayer_authority() != 1:
_sync_show_floating_text.rpc_id(player.get_multiplayer_authority(), loot_type, display_text, text_color, 0, item.spriteFrame, player.get_multiplayer_authority())
self.visible = false
# Wait for sound to finish before removing
if sfx_loot_collect and sfx_loot_collect.playing:
await sfx_loot_collect.finished
queue_free()
var processing_pickup: bool = false # Mutex to prevent concurrent pickup processing
@@ -526,7 +612,7 @@ func _sync_remove():
LootType.COIN:
if sfx_coin_collect:
sfx_coin_collect.play()
LootType.APPLE, LootType.BANANA, LootType.CHERRY:
LootType.APPLE, LootType.BANANA, LootType.CHERRY, LootType.ITEM:
if sfx_loot_collect:
sfx_loot_collect.play()
@@ -543,7 +629,7 @@ func _sync_remove():
if loot_type == LootType.COIN and sfx_coin_collect and sfx_coin_collect.playing:
_sound_playing = true
await sfx_coin_collect.finished
elif loot_type in [LootType.APPLE, LootType.BANANA, LootType.CHERRY] and sfx_loot_collect and sfx_loot_collect.playing:
elif loot_type in [LootType.APPLE, LootType.BANANA, LootType.CHERRY, LootType.ITEM] and sfx_loot_collect and sfx_loot_collect.playing:
_sound_playing = true
await sfx_loot_collect.finished
@@ -582,6 +668,13 @@ func _sync_show_floating_text(loot_type_value: int, text: String, color_value: C
item_texture = load("res://assets/gfx/pickups/items_n_shit.png")
sprite_hframes = 20
sprite_vframes = 14
LootType.ITEM:
# Item instance - use item's sprite path
# Note: item data is not available on client in this sync, so we use default
# The actual item sprite is set when the loot is created
item_texture = load("res://assets/gfx/pickups/items_n_shit.png")
sprite_hframes = 20
sprite_vframes = 14
# Show floating text on client
_show_floating_text(player, text, color_value, 0.5, 0.5, item_texture, sprite_hframes, sprite_vframes, sprite_frame_value)