224 lines
5.6 KiB
GDScript
224 lines
5.6 KiB
GDScript
class_name Adventurer extends Node
|
|
|
|
|
|
enum Gender{
|
|
MASC,
|
|
FEMME,
|
|
NONBINARY
|
|
}
|
|
|
|
var given_name : String = "Test"
|
|
var surname : String = "Testing"
|
|
var gender : Gender = Gender.MASC
|
|
var life : int = 1
|
|
var max_life : int = 1
|
|
var energy : int = 1
|
|
var max_energy : int = 1
|
|
var level : int = 1
|
|
var exp : int = 0
|
|
var job : JobData
|
|
var appearance : Dictionary
|
|
var stats : StatBlock
|
|
var gold : int = 0
|
|
var quest : Quest
|
|
var equipment : Array = [null, null, null]
|
|
var inventory : Dictionary[Vector2, Item] = {}
|
|
var inventory_size : Vector2i = Vector2i(3,2)
|
|
var inventory_count : int = 0
|
|
|
|
var quest_sprite : QuestSprite
|
|
|
|
signal changed()
|
|
signal levelled()
|
|
signal died()
|
|
|
|
func _init() -> void:
|
|
stats = StatBlock.new()
|
|
|
|
func generate() -> void:
|
|
if job == null:
|
|
return
|
|
stats.STR = randi_range(job.min_STR, job.max_STR)
|
|
stats.DEX = randi_range(job.min_DEX, job.max_DEX)
|
|
stats.INT = randi_range(job.min_INT, job.max_INT)
|
|
stats.CHA = randi_range(job.min_CHA, job.max_CHA)
|
|
stats.FAI = randi_range(job.min_FAI, job.max_FAI)
|
|
stats.LUK = randi_range(job.min_LUK, job.max_LUK)
|
|
generate_appearance()
|
|
max_life = stats.STR * 10 + stats.CHA * 10
|
|
max_energy = stats.INT * 10 + stats.FAI * 10
|
|
life = max_life
|
|
energy = max_energy
|
|
changed.emit()
|
|
|
|
func assign_quest(quest : Quest) -> void:
|
|
self.quest = quest
|
|
quest.initiate(self)
|
|
changed.emit()
|
|
|
|
func full_name() -> String:
|
|
return given_name + " " + surname
|
|
|
|
func gain_level() -> void:
|
|
level += 1
|
|
#TODO: Make stats improve based on job
|
|
Game.notice("%s has reached level %d!" % [full_name(), level])
|
|
changed.emit()
|
|
levelled.emit()
|
|
|
|
func gain_exp(amount : int) -> void:
|
|
exp += amount
|
|
while exp >= get_tnl():
|
|
exp -= get_tnl()
|
|
gain_level()
|
|
changed.emit()
|
|
|
|
func gain_gold(amount :int) -> void:
|
|
gold += amount
|
|
changed.emit()
|
|
|
|
func get_tnl() -> int:
|
|
if job:
|
|
return job.get_tnl(level)
|
|
else:
|
|
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 equip_item(from : Vector2, slot : Item.Slots) -> void:
|
|
if !inventory.has(from):
|
|
printerr("Cannot equip item from %s, it is empty!" % [from])
|
|
|
|
var itm = inventory[from]
|
|
if !itm.can_equip_slot(slot):
|
|
printerr("Cannot equip item from %s to %s, it is the wrong type!" % [from, Item.slot_name(slot)])
|
|
|
|
if !job.can_equip(itm):
|
|
printerr("Cannot equip item from %s to %s, %s cannot equip it!" % [from, Item.slot_name(slot), job.name])
|
|
|
|
if equipment[slot] != null:
|
|
inventory[from] = equipment[slot]
|
|
remove_stats_from_item(itm)
|
|
else:
|
|
inventory.erase(from)
|
|
equipment[slot] = itm
|
|
apply_stats_from_item(itm)
|
|
#Apply Stats from
|
|
|
|
func remove_stats_from_item(itm : Item) -> void:
|
|
stats.STR -= stats.STR
|
|
stats.DEX-= stats.DEX
|
|
stats.INT-= stats.INT
|
|
stats.CHA-= stats.CHA
|
|
stats.FAI-= stats.FAI
|
|
stats.LUK-= stats.LUK
|
|
stats.PATK-= stats.PATK
|
|
stats.MATK-= stats.MATK
|
|
stats.PDEF-= stats.PDEF
|
|
stats.MDEF-= stats.MDEF
|
|
|
|
func apply_stats_from_item(itm : Item) -> void:
|
|
stats.STR += stats.STR
|
|
stats.DEX+= stats.DEX
|
|
stats.INT+= stats.INT
|
|
stats.CHA+= stats.CHA
|
|
stats.FAI+= stats.FAI
|
|
stats.LUK+= stats.LUK
|
|
stats.PATK+= stats.PATK
|
|
stats.MATK+= stats.MATK
|
|
stats.PDEF+= stats.PDEF
|
|
stats.MDEF+= stats.MDEF
|
|
|
|
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()
|
|
|
|
func generate_appearance(features=null) -> void:
|
|
if features == null:
|
|
appearance = {
|
|
"hair":{
|
|
"color":"",
|
|
"type":""
|
|
},
|
|
"skin":{
|
|
"color":"",
|
|
"type":""
|
|
},
|
|
"eyes":{
|
|
"color":"",
|
|
"type":""
|
|
}
|
|
}
|
|
#TODO: Handle different types of hair and eyes
|
|
appearance.hair.color = AdventurerPortrait.random_color(ColorVariant.Types.HAIR)
|
|
#appearance.hair_type = randi_range(0,len(job.portrait.hair_types) - 1)
|
|
appearance.eyes.color = AdventurerPortrait.random_color(ColorVariant.Types.EYES)
|
|
#appearance.eye_type = randi_range(0,len(job.portrait.eye_types) - 1)
|
|
appearance.skin.color = AdventurerPortrait.random_color(ColorVariant.Types.SKIN)
|
|
changed.emit()
|
|
|
|
func save_inventory() -> Dictionary:
|
|
return {}
|
|
|
|
func save_equipment() -> Dictionary:
|
|
return {}
|
|
|
|
func save() -> Dictionary:
|
|
var dict = {}
|
|
dict.name = [given_name, surname]
|
|
dict.gender = gender
|
|
dict.gold = gold
|
|
if quest:
|
|
dict.quest = quest.id
|
|
dict.exp = exp
|
|
dict.level = level
|
|
dict.appearance = appearance.duplicate()
|
|
dict.stats = stats.duplicate()
|
|
dict.life = [life, max_life]
|
|
dict.energy = [energy, max_energy]
|
|
#TODO: Prepare for more on these later
|
|
dict.job = {}
|
|
dict.abilities = {}
|
|
dict.inventory = save_inventory()
|
|
dict.equipment = save_equipment()
|
|
return dict
|
|
|
|
func load(dict : Dictionary) -> void:
|
|
return
|