Add inventory system

This commit is contained in:
2025-01-05 12:05:55 -06:00
parent 750719ff88
commit e74878eb80
25 changed files with 247 additions and 46 deletions

View File

@@ -1,4 +1,5 @@
extends CharacterBody3D
class_name OverworldEntity
enum Direction {
NORTH,
@@ -16,6 +17,12 @@ var meshInstance:MeshInstance3D;
var underFootTile:int = -1;
var underFootPosition:Vector3;
var withinMapBounds:MapBounds;
var withinBoundsLastFrame:bool = true;
func getSystems() -> Systems:
return get_tree().current_scene.get_node("Systems") as Systems;
func getDirectionVector() -> Vector3:
match direction:
Direction.NORTH:
@@ -52,7 +59,7 @@ func _updateTileData() -> void:
var collider = result.collider;
var colliderMesh = collider.get_node("../");
if !colliderMesh or !colliderMesh.mesh or colliderMesh.mesh.get_surface_count() == 0:
if !colliderMesh or !(colliderMesh is ArrayMesh) or !colliderMesh.mesh or colliderMesh.mesh.get_surface_count() == 0:
return;
# Get the face index (triangle)
@@ -90,6 +97,14 @@ func _ready() -> void:
pass
func _process(delta:float) -> void:
# Handle entity leaving map bounds
if !withinMapBounds:
if !withinBoundsLastFrame:
print("Entity ", self.name, " was out of map bounds for two frames");
withinBoundsLastFrame = false;
else:
withinBoundsLastFrame = true;
# Update logic
updateOverworldLogic(delta)

View File

@@ -1,4 +1,4 @@
extends "res://scripts/OverworldEntity.gd"
class_name RosaController extends "res://scripts/Entities/OverworldEntity.gd"
var interactRange = 0.7;
@@ -27,7 +27,6 @@ func updateMovement(delta) -> void:
if(dir.x != 0 or dir.y != 0):
velocity.x = dir.x * speed * delta;
velocity.z = dir.y * speed * delta;
print(dir.length());
# Update direction
if(dir.x >= abs(dir.y) and(

View File

@@ -0,0 +1,11 @@
class_name TestNPCController extends "res://scripts/Entities/OverworldEntity.gd"
func interact(interactor) -> void:
var systems = getSystems();
systems.ITEM.addItem(systems.ITEM.ITEM_POTION, 1);
#var itemSystem = (get_node("Systems") as Systems).ITEM;
#itemSystem.addItem(itemSystem.ITEM_POTION, 1);
#pass
func updateMovement(delta) -> void:
pass

36
scripts/Items/Item.gd Normal file
View File

@@ -0,0 +1,36 @@
class_name Item
enum ItemCategory {
MEDICINE,
KEY_ITEM,
INGREDIENT
};
func getName() -> String:
push_error("getName() must be overridden in derived classes");
return "";
func isStackable() -> bool:
return true;
func isDroppable() -> bool:
return true;
func isSellable() -> bool:
return true;
func getSellPrice() -> int:
return 0;
func getBuyPrice() -> int:
return 0;
func isConsumable() -> bool:
return false;
func consume() -> void:
pass
func getCategory() -> ItemCategory:
push_error("getCategory() must be overriden in derived class");
return ItemCategory.MEDICINE;

View File

@@ -0,0 +1,8 @@
class_name ItemStack
var item:Item;
var quantity:int;
func _init(item:Item, quantity:int = 1):
self.item = item;
self.quantity = quantity;

13
scripts/Items/Potion.gd Normal file
View File

@@ -0,0 +1,13 @@
class_name Potion extends "res://scripts/Items/Item.gd"
func getName() -> String:
return "Potion"
func getCategory() -> ItemCategory:
return ItemCategory.MEDICINE;
func isConsumable() -> bool:
return true;
func consume() -> void:
print("Consuming Potion");

17
scripts/MapBounds.gd Normal file
View File

@@ -0,0 +1,17 @@
extends Area3D
class_name MapBounds
func _ready() -> void:
pass
func _on_body_entered(body: Node3D) -> void:
if (!body is OverworldEntity):
return
print("Entered overworld ent")
(body as OverworldEntity).withinMapBounds = self;
func _on_body_exited(body: Node3D) -> void:
if (!body is OverworldEntity):
return
print("Entered overworld ent")
(body as OverworldEntity).withinMapBounds = null;

1
scripts/MapBounds.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://dbah1pmk8jola

View File

@@ -0,0 +1 @@
uid://dr3asofxu1pep

View File

@@ -0,0 +1 @@
uid://cubx2asrudfyp

View File

@@ -0,0 +1 @@
uid://dnls1370w0gr4

View File

@@ -0,0 +1,86 @@
class_name ItemSystem
const Item = preload("res://scripts/Items/Item.gd");
const ItemStack = preload("res://scripts/Items/ItemStack.gd");
enum ItemSortType {
NAME,
TYPE
};
class ItemStackNameComparator:
static func _sort(a, b):
return a.item.getName().to_lower() < b.item.getName().to_lower()
class ItemStackTypeComparator:
static func _sort(a, b):
return a.item.getCategory() < b.item.getCategory()
# Constants
const ITEM_STACK_SIZE_MAX = 99;
var ITEM_POTION = preload("res://scripts/Items/Potion.gd").new()
var inventory:Array[ItemStack] = [];
# Methods
func addItem(item: Item, quantity: int = 1) -> void:
print("Adding ", quantity, "x ", item.getName());
if !item.isStackable():
# Item cannot be stacked, add each item to inv
for i in range(quantity):
inventory.append(ItemStack.new(item, 1))
return
# Check for existing stacks
for stack in inventory:
if stack.item != item or stack.quantity >= ITEM_STACK_SIZE_MAX:
continue
var spaceAvailable = ITEM_STACK_SIZE_MAX - stack.quantity
if quantity <= spaceAvailable:
stack.quantity += quantity;
return
stack.quantity = ITEM_STACK_SIZE_MAX;
quantity -= spaceAvailable;
# Add any remaining inventory as new stack.
while quantity > 0:
var newStackQuantity = min(quantity, ITEM_STACK_SIZE_MAX);
inventory.append(ItemStack.new(item, newStackQuantity));
quantity -= newStackQuantity;
func removeItem(item: Item, quantity: int) -> void:
var totalQuantity = 0
# Calculate total quantity of the item in the inventory
for stack in inventory:
if stack.item != item:
continue
totalQuantity += stack.quantity
if totalQuantity < quantity:
push_error("Not enough quantity to remove");
return
# Remove the quantity from the stacks
for stack in inventory:
if stack.item != item:
continue
if stack.quantity < quantity:
quantity -= stack.quantity
inventory.erase(stack)
stack.quantity -= quantity
if stack.quantity == 0:
inventory.erase(stack)
if quantity == 0:
return
func sortBy(by:ItemSortType) -> void:
match by:
ItemSortType.NAME:
inventory.sort_custom(ItemStackNameComparator._sort)
ItemSortType.TYPE:
inventory.sort_custom(ItemStackTypeComparator._sort)

View File

@@ -0,0 +1,3 @@
class_name Systems extends Node
var ITEM = preload("res://scripts/Systems/ItemSystem.gd").new()

View File

@@ -1,34 +0,0 @@
extends "res://scripts/OverworldEntity.gd"
func interact(interactor) -> void:
print("Hello, I am an NPC!")
pass
func updateMovement(delta) -> void:
pass
# User movement
#var dir:Vector2 = Input.get_vector("left", "right", "up", "down");
#if(dir.x != 0 or dir.y != 0):
#velocity.x = dir.x * speed * delta;
#velocity.z = dir.y * speed * delta;
#
## Update direction
#if(dir.x > 0):
#if(
#dir.y == 0 or
#(dir.y < 0 and direction == Direction.SOUTH) or
#(dir.y > 0 and direction == Direction.NORTH)
#):
#direction = Direction.EAST;
#elif (dir.x < 0):
#if(
#dir.y == 0 or
#(dir.y < 0 and direction == Direction.SOUTH) or
#(dir.y > 0 and direction == Direction.NORTH)
#):
#direction = Direction.WEST;
#elif (dir.y > 0):
#direction = Direction.SOUTH;
#elif (dir.y < 0):
#direction = Direction.NORTH;
#pass

View File

@@ -0,0 +1 @@
uid://dq7mgokmvo80u