Starting item and inventory tools, sketched spear animation templates.
This commit is contained in:
@@ -2,4 +2,7 @@ class_name Item extends Resource
|
|||||||
|
|
||||||
|
|
||||||
@export var image : Texture2D
|
@export var image : Texture2D
|
||||||
|
@export var name : StringName
|
||||||
@export var brief : String
|
@export var brief : String
|
||||||
|
@export var quantity : int = 1
|
||||||
|
@export var max_quantity : int = 1
|
||||||
|
|||||||
BIN
external/test-qsvchar.clip
vendored
BIN
external/test-qsvchar.clip
vendored
Binary file not shown.
@@ -25,9 +25,14 @@ var armor : Armor
|
|||||||
var accessory : Accessory
|
var accessory : Accessory
|
||||||
var inventory : Dictionary[Vector2, Item] = {}
|
var inventory : Dictionary[Vector2, Item] = {}
|
||||||
var inventory_size : Vector2i = Vector2i(6,1)
|
var inventory_size : Vector2i = Vector2i(6,1)
|
||||||
|
var inventory_count : int = 0
|
||||||
|
|
||||||
var quest_sprite : QuestSprite
|
var quest_sprite : QuestSprite
|
||||||
|
|
||||||
|
signal changed()
|
||||||
|
signal levelled()
|
||||||
|
signal died()
|
||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
stats = StatBlock.new()
|
stats = StatBlock.new()
|
||||||
|
|
||||||
@@ -45,10 +50,12 @@ func generate() -> void:
|
|||||||
max_energy = stats.INT * 10 + stats.FAI * 10
|
max_energy = stats.INT * 10 + stats.FAI * 10
|
||||||
life = max_life
|
life = max_life
|
||||||
energy = max_energy
|
energy = max_energy
|
||||||
|
changed.emit()
|
||||||
|
|
||||||
func assign_quest(quest : Quest) -> void:
|
func assign_quest(quest : Quest) -> void:
|
||||||
self.quest = quest
|
self.quest = quest
|
||||||
quest.initiate(self)
|
quest.initiate(self)
|
||||||
|
changed.emit()
|
||||||
|
|
||||||
func full_name() -> String:
|
func full_name() -> String:
|
||||||
return given_name + " " + surname
|
return given_name + " " + surname
|
||||||
@@ -57,18 +64,65 @@ func gain_level() -> void:
|
|||||||
level += 1
|
level += 1
|
||||||
#TODO: Make stats improve based on job
|
#TODO: Make stats improve based on job
|
||||||
Game.notice("%s has reached level %d!" % [full_name(), level])
|
Game.notice("%s has reached level %d!" % [full_name(), level])
|
||||||
|
#TODO: Make Sideview display level up
|
||||||
|
changed.emit()
|
||||||
|
levelled.emit()
|
||||||
|
|
||||||
func gain_exp(amount : int) -> void:
|
func gain_exp(amount : int) -> void:
|
||||||
exp += amount
|
exp += amount
|
||||||
while exp >= get_tnl():
|
while exp >= get_tnl():
|
||||||
exp -= get_tnl()
|
exp -= get_tnl()
|
||||||
gain_level()
|
gain_level()
|
||||||
|
changed.emit()
|
||||||
|
|
||||||
func gain_gold(amount :int) -> void:
|
func gain_gold(amount :int) -> void:
|
||||||
gold += amount
|
gold += amount
|
||||||
|
changed.emit()
|
||||||
|
|
||||||
func get_tnl() -> int:
|
func get_tnl() -> int:
|
||||||
if job:
|
if job:
|
||||||
return job.get_tnl(level)
|
return job.get_tnl(level)
|
||||||
else:
|
else:
|
||||||
return level * 10
|
return level * 10
|
||||||
|
|
||||||
|
func find_open_inventory_slot(item : Item) -> Vector2:
|
||||||
|
var first_open : Vector2 = Vector2(-1,-1)
|
||||||
|
for j in range(inventory_size.y):
|
||||||
|
for i in range(inventory_size.x):
|
||||||
|
var curr_slot : Item = inventory.get(Vector2(i,j))
|
||||||
|
if curr_slot != null:
|
||||||
|
#TODO: Figure out how to handle split stacking later?
|
||||||
|
if curr_slot.name == item.name and curr_slot.max_quantity < curr_slot.quantity + item.quantity:
|
||||||
|
return Vector2(i,j)
|
||||||
|
elif first_open == Vector2(-1,-1):
|
||||||
|
first_open = Vector2(i,j)
|
||||||
|
return first_open
|
||||||
|
|
||||||
|
func try_pickup_item(item : Item) -> bool:
|
||||||
|
if inventory_count >= inventory_size.x * inventory_size.y:
|
||||||
|
return false
|
||||||
|
pickup_item(item)
|
||||||
|
return true
|
||||||
|
|
||||||
|
func pickup_item(item : Item) -> void:
|
||||||
|
var open_slot = find_open_inventory_slot(item)
|
||||||
|
if inventory.has(open_slot):
|
||||||
|
inventory[open_slot].quantity += item.quantity
|
||||||
|
else:
|
||||||
|
if inventory_count >= inventory_size.x * inventory_size.y:
|
||||||
|
printerr("Cannot fit additional item!")
|
||||||
|
inventory[open_slot] = item
|
||||||
|
inventory_count+=1
|
||||||
|
changed.emit()
|
||||||
|
|
||||||
|
func move_item(from : Vector2, to: Vector2) -> void:
|
||||||
|
if !inventory.has(from):
|
||||||
|
printerr("Cannot move item from %s to %s, %s is empty!" % [from, to, from])
|
||||||
|
var itm = inventory[from]
|
||||||
|
if inventory.has(to):
|
||||||
|
var itm2 = inventory[to]
|
||||||
|
inventory[from] = itm2
|
||||||
|
else:
|
||||||
|
inventory.erase(from)
|
||||||
|
inventory[to] = itm
|
||||||
|
changed.emit()
|
||||||
|
|||||||
@@ -15,9 +15,19 @@ var data : Adventurer
|
|||||||
@onready var faiLabel :Label = %FAILabel
|
@onready var faiLabel :Label = %FAILabel
|
||||||
@onready var lukLabel :Label = %LUKLabel
|
@onready var lukLabel :Label = %LUKLabel
|
||||||
|
|
||||||
|
var item_slots : Array[ItemSlot]
|
||||||
|
|
||||||
func setup(adv : Adventurer) -> void:
|
func setup(adv : Adventurer) -> void:
|
||||||
data = adv
|
data = adv
|
||||||
|
data.changed.connect(_on_data_changed)
|
||||||
|
update_stats()
|
||||||
|
item_slots = []
|
||||||
|
for child : ItemSlot in %InventoryGrid.get_children():
|
||||||
|
item_slots.append(child)
|
||||||
|
#TODO: Show equipment
|
||||||
|
update_items()
|
||||||
|
|
||||||
|
func update_stats() -> void:
|
||||||
nameLabel.text = data.full_name()
|
nameLabel.text = data.full_name()
|
||||||
if data.job:
|
if data.job:
|
||||||
jobLabel.text = data.job.name
|
jobLabel.text = data.job.name
|
||||||
@@ -33,8 +43,21 @@ func setup(adv : Adventurer) -> void:
|
|||||||
chaLabel.text = str(data.stats.CHA)
|
chaLabel.text = str(data.stats.CHA)
|
||||||
faiLabel.text = str(data.stats.FAI)
|
faiLabel.text = str(data.stats.FAI)
|
||||||
lukLabel.text = str(data.stats.LUK)
|
lukLabel.text = str(data.stats.LUK)
|
||||||
#TODO: Show equipment
|
|
||||||
populate_items()
|
|
||||||
|
|
||||||
func populate_items() -> void:
|
func update_items() -> void:
|
||||||
pass
|
var isize = data.inventory_size.x * data.inventory_size.y
|
||||||
|
var islots = len(item_slots)
|
||||||
|
%InventoryGrid.columns = data.inventory_size.x
|
||||||
|
for crd in data.inventory.keys():
|
||||||
|
var idx = crd.y * data.inventory_size.x + crd.x
|
||||||
|
var item = data.inventory[crd]
|
||||||
|
item_slots[idx].update(item)
|
||||||
|
item_slots[idx].visible = true
|
||||||
|
|
||||||
|
for idx in range(isize, islots):
|
||||||
|
item_slots[idx].visible = false
|
||||||
|
|
||||||
|
|
||||||
|
func _on_data_changed() -> void:
|
||||||
|
update_stats()
|
||||||
|
update_items()
|
||||||
|
|||||||
1
scripts/item_display_window.gd
Normal file
1
scripts/item_display_window.gd
Normal file
@@ -0,0 +1 @@
|
|||||||
|
extends Window
|
||||||
1
scripts/item_display_window.gd.uid
Normal file
1
scripts/item_display_window.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cpiucydmov1qj
|
||||||
@@ -7,14 +7,25 @@ var item : Item
|
|||||||
@onready var item_sprite : TextureRect = $Item
|
@onready var item_sprite : TextureRect = $Item
|
||||||
|
|
||||||
func assign(itm : Item) -> void:
|
func assign(itm : Item) -> void:
|
||||||
item = item
|
item = itm
|
||||||
item_sprite.texture = item.image
|
if item.image != null:
|
||||||
|
item_sprite.texture = item.image
|
||||||
|
|
||||||
func swap(item_slot : ItemSlot) -> void:
|
func swap(item_slot : ItemSlot) -> void:
|
||||||
var itm = item
|
var itm = item
|
||||||
assign(itm)
|
assign(itm)
|
||||||
item_slot.assign(itm)
|
item_slot.assign(itm)
|
||||||
|
|
||||||
|
func update(itm : Item) -> void:
|
||||||
|
if itm == null:
|
||||||
|
clear()
|
||||||
|
elif itm != item:
|
||||||
|
assign(itm)
|
||||||
|
|
||||||
|
func clear() -> void:
|
||||||
|
item = null
|
||||||
|
item_sprite.texture = null
|
||||||
|
|
||||||
func _on_gui_input(event: InputEvent) -> void:
|
func _on_gui_input(event: InputEvent) -> void:
|
||||||
var mmevt = event as InputEventMouseMotion
|
var mmevt = event as InputEventMouseMotion
|
||||||
var mbevt = event as InputEventMouseButton
|
var mbevt = event as InputEventMouseButton
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ var data : Adventurer
|
|||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
Game.player = self
|
Game.player = self
|
||||||
data = Adventurer.new()
|
data = Adventurer.new()
|
||||||
|
data.inventory_size = Vector2(4,2)
|
||||||
data.name = "Player"
|
data.name = "Player"
|
||||||
setup.call_deferred()
|
setup.call_deferred()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extends Node2D
|
extends Node2D
|
||||||
var test_adv = preload("res://templates/test_adventurer.tscn")
|
var test_adv = preload("res://templates/test_adventurer.tscn")
|
||||||
|
var test_item = preload("res://data/items/pitchfork.tres")
|
||||||
@onready var door_player : AudioStreamPlayer = $AudioStreamPlayer
|
@onready var door_player : AudioStreamPlayer = $AudioStreamPlayer
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
#var adv : Adventurer = test_adv.instantiate() as Adventurer
|
#var adv : Adventurer = test_adv.instantiate() as Adventurer
|
||||||
@@ -13,6 +13,9 @@ func _ready() -> void:
|
|||||||
quest.events.append(evt)
|
quest.events.append(evt)
|
||||||
Guild.add_quest(quest)
|
Guild.add_quest(quest)
|
||||||
Guild.assign_quest(Game.player.data, quest)
|
Guild.assign_quest(Game.player.data, quest)
|
||||||
|
var itm = test_item.duplicate()
|
||||||
|
Game.player.data.pickup_item(itm)
|
||||||
|
Game.player.data.move_item(Vector2(0,0), Vector2(1,0))
|
||||||
#Game.end_shift()
|
#Game.end_shift()
|
||||||
#var tween = create_tween()
|
#var tween = create_tween()
|
||||||
#tween.tween_interval(3)
|
#tween.tween_interval(3)
|
||||||
|
|||||||
78
templates/item_display_window.tscn
Normal file
78
templates/item_display_window.tscn
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://dggjyxoa33r7y"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://cpiucydmov1qj" path="res://scripts/item_display_window.gd" id="1_n2g4t"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cjjtgrr56guj0" path="res://graphics/ui/item-slot.png" id="2_dxjvd"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://clrvwaqb61lpv" path="res://graphics/items/pitchfork.png" id="3_tsl8r"]
|
||||||
|
|
||||||
|
[node name="Item Display Window" type="Window"]
|
||||||
|
oversampling_override = 1.0
|
||||||
|
size = Vector2i(300, 300)
|
||||||
|
borderless = true
|
||||||
|
popup_window = true
|
||||||
|
script = ExtResource("1_n2g4t")
|
||||||
|
|
||||||
|
[node name="Panel" type="PanelContainer" parent="."]
|
||||||
|
custom_minimum_size = Vector2(300, 300)
|
||||||
|
anchors_preset = -1
|
||||||
|
offset_right = 300.0
|
||||||
|
offset_bottom = 300.0
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/margin_left = 2
|
||||||
|
theme_override_constants/margin_top = 2
|
||||||
|
theme_override_constants/margin_right = 0
|
||||||
|
theme_override_constants/margin_bottom = 0
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="Panel/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="CenterContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(71, 71)
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="TextureRect2" type="TextureRect" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/MarginContainer"]
|
||||||
|
custom_minimum_size = Vector2(71, 71)
|
||||||
|
layout_mode = 2
|
||||||
|
texture = ExtResource("2_dxjvd")
|
||||||
|
|
||||||
|
[node name="TextureRect" type="TextureRect" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
texture = ExtResource("3_tsl8r")
|
||||||
|
stretch_mode = 3
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "ITEM NAME"
|
||||||
|
|
||||||
|
[node name="Label2" type="Label" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "ITEM TYPE"
|
||||||
|
|
||||||
|
[node name="Label3" type="Label" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "ITEM GRADE"
|
||||||
|
|
||||||
|
[node name="Label2" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Primary Stat Goes Here"
|
||||||
|
|
||||||
|
[node name="Label3" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(0, 60)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Secondary Stats Go Here"
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="Panel/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(0, 150)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Brief Description Goes Here"
|
||||||
@@ -522,6 +522,7 @@ offset_bottom = 509.0
|
|||||||
texture = ExtResource("10_rldp4")
|
texture = ExtResource("10_rldp4")
|
||||||
|
|
||||||
[node name="InventoryGrid" type="GridContainer" parent="."]
|
[node name="InventoryGrid" type="GridContainer" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
anchors_preset = -1
|
anchors_preset = -1
|
||||||
offset_left = 325.0
|
offset_left = 325.0
|
||||||
offset_top = 513.0
|
offset_top = 513.0
|
||||||
|
|||||||
Reference in New Issue
Block a user