class_name CharacterStats
extends Resource

signal health_changed(new_health: float, max_health: float)
signal mana_changed(new_mana: float, max_mana: float)
signal level_changed(new_level: int)
signal level_up_stats(stats_increased: Array)  # Emitted when leveling up, contains array of stat names that were increased
signal xp_changed(new_xp: float, xp_to_next: float)
signal no_health

signal character_changed(char: CharacterStats)

signal signal_drop_item(item: Item)

var character_type: String = "enemy"
var race: String = "Human"  # "Dwarf", "Elf", or "Human"
@export var level: int = 1
@export var character_name: String = ""
@export var xp: float = 0
@export var hp: float = 30.0
@export var mp: float = 20.0

# default skin is human1
var skin:String = "res://assets/gfx/Puny-Characters/Layer 0 - Skins/Human1.png"
# default no values for these:
var facial_hair:String = ""
var facial_hair_color:Color = Color.WHITE
var hairstyle:String = ""
var hair_color:Color = Color.WHITE
var eyes:String = ""
var eye_color:Color = Color.WHITE
var eye_lashes:String = ""
var eyelash_color:Color = Color.WHITE
var add_on:String = ""

var bonusmaxhp: float = 0.0
var bonusmaxmp: float = 0.0

@export var coin: int = 0
@export var is_invulnerable: bool = false
var kills: int = 0
var deaths: int = 0

# Level-up stat allocation: when true, player must open inventory and choose a stat to +1
var pending_level_up: bool = false
var pending_stat_points: int = 0
const LEVEL_UP_STAT_NAMES: Array = ["str", "dex", "int", "end", "wis", "lck", "per"]

#calculated values
var stats:Array = [
	5,
	4,
	5,
	3,
	1,
	1,
	0,
	10,
	10
]

var inventory: Array = []

# mainhand, offhand, headgear, body, feet, accessory (6 total)
var equipment:Dictionary = {
	"mainhand": null,
	"offhand": null,
	"headgear": null,
	"armour": null,
	"boots": null,
	"accessory": null
}

@export var baseStats = {
	"str": 10,
	"dex": 10,
	"int": 10,
	"end": 10,
	"wis": 10,
	"cha": 10,
	"lck": 10,
	"per": 10  # Perception - affects trap detection
}

@export var def: int = 0

@export var resistances = {
	"fire": 0,
	"cold": 0,
	"lightning": 0,
	"poison": 0,
	"magic": 0,
	"holy": 0,
	"dark": 0
}

# Calculate total inventory weight (including equipped items)
func get_total_weight() -> float:
	var total = 0.0
	# Count inventory items (stacked items count their quantity)
	for item in inventory:
		if item:
			total += item.weight * item.quantity
	# Count equipped items (also multiply by quantity for stackable items like arrows)
	for slot in equipment.values():
		if slot:
			if slot.can_have_multiple_of:
				total += slot.weight * slot.quantity
			else:
				total += slot.weight
	return total

# Calculate carrying capacity based on STR
func get_carrying_capacity() -> float:
	# Base capacity: 7 + (STR * 1.75) - reduced to 35% of original
	# Example: 10 STR = 24.5, 20 STR = 42
	return 7.0 + (baseStats.str * 1.75)

# Check if over-encumbered
func is_over_encumbered() -> bool:
	return get_total_weight() > get_carrying_capacity()

func getCalculatedStats():
	var _res = {
		"str": self.str,
		"dex": self.dex,
		"int": self.int,
		"end": self.end,
		"wis": self.wis,
		"cha": self.cha,
		"lck": self.lck,
		"damage": self.damage,
		"defense": self.defense
	}
	if equipment["mainhand"] != null:
		pass
		
	pass
	
func get_pass(iStr:String):
	var cnt = 0
	if equipment["mainhand"] != null:
		for key in equipment["mainhand"].modifiers.keys():
			if key == iStr:
				cnt += equipment["mainhand"].modifiers[key]
			pass
		pass
	if equipment["offhand"] != null:
		for key in equipment["offhand"].modifiers.keys():
			if key == iStr:
				cnt += equipment["offhand"].modifiers[key]
			pass
		pass
	if equipment["headgear"] != null:
		for key in equipment["headgear"].modifiers.keys():
			if key == iStr:
				cnt += equipment["headgear"].modifiers[key]
			pass
		pass
	if equipment["armour"] != null:
		for key in equipment["armour"].modifiers.keys():
			if key == iStr:
				cnt += equipment["armour"].modifiers[key]
			pass
		pass
	if equipment["boots"] != null:
		for key in equipment["boots"].modifiers.keys():
			if key == iStr:
				cnt += equipment["boots"].modifiers[key]
			pass
		pass
	if equipment["accessory"] != null:
		for key in equipment["accessory"].modifiers.keys():
			if key == iStr:
				cnt += equipment["accessory"].modifiers[key]
			pass
		pass
	return cnt

# Derived stats as properties
var maxhp: float:
	get:
		return (baseStats.end + get_pass("end")) * 3.0 + bonusmaxhp + get_pass("maxhp")

var maxmp: float:
	get:
		return (baseStats.wis + get_pass("wis")) * 2.0 + bonusmaxmp + get_pass("maxmp")

var damage: float:
	get:
		# Increased damage scaling: 0.25 per STR point (was 0.2) - makes players stronger
		return (baseStats.str + get_pass("str")) * 0.25 + get_pass("dmg")

var defense: float:
	get:
		# Further reduced DEF scaling: 0.15 per END point (was 0.2) - makes defense weaker overall
		# In D&D/Baldur's Gate, AC affects hit chance, not damage. Defense here provides minimal flat reduction.
		return ((baseStats.end + get_pass("end")) * 0.15) + get_pass("def")

var spell_amp: float:
	get:
		return (baseStats.int + get_pass("int")) * 0.5

var move_speed: float:
	get:
		return 2.0 + ((baseStats.dex + get_pass("dex")) * 0.01)

var attack_speed: float:
	get:
		return 1.0 + ((baseStats.dex + get_pass("dex")) * 0.04)

var sight: float:
	get:
		return 5.0 + ((baseStats.int + get_pass("int")) * 0.05)

var crit_chance: float:
	get:
		return (baseStats.lck + get_pass("lck")) * 1.2

var dodge_chance: float:
	get:
		# Dodge chance based on DEX (very low % per point, as per user request)
		# Each point of DEX gives 0.5% dodge chance (so 20 DEX = 10% dodge)
		return (baseStats.dex + get_pass("dex")) * 0.005

var hit_chance: float:
	get:
		# Hit chance based on DEX (higher DEX = better accuracy)
		# Base hit chance is 95%, each DEX point adds 0.3% (so ~17 DEX = 100% base hit chance)
		# Formula: 95% base + (DEX * 0.3%)
		return 0.95 + ((baseStats.dex + get_pass("dex")) * 0.003)

var xp_to_next_level: float:
	get:
		# Scale EXP requirements more aggressively - gets harder to level as you go
		return pow(level * 15, 1.6)

func _init() -> void:
	hp = maxhp
	mp = maxmp

func add_xp(amount: float) -> void:
	xp += amount
	xp = max(0.0, xp)
	xp_changed.emit(xp, xp_to_next_level)
	
	while xp >= xp_to_next_level:
		level_up()
	xp = max(0.0, xp)
	xp_changed.emit(xp, xp_to_next_level)

# Level up - grant pending stat point(s); player allocates in inventory
func level_up() -> void:
	# Subtract threshold for current level *before* incrementing (xp_to_next_level uses level)
	var xp_threshold = xp_to_next_level
	level += 1
	xp -= xp_threshold
	xp = max(0.0, xp)
	
	pending_level_up = true
	pending_stat_points += 1
	
	# Restore health and mana on level up
	hp = maxhp
	mp = maxmp
	
	level_changed.emit(level)
	level_up_stats.emit([])
	health_changed.emit(hp, maxhp)
	mana_changed.emit(mp, maxmp)

func allocate_stat_point(stat_name: String) -> bool:
	if not pending_level_up or pending_stat_points <= 0:
		return false
	if stat_name not in LEVEL_UP_STAT_NAMES:
		return false
	baseStats[stat_name] += 1
	pending_stat_points -= 1
	if pending_stat_points <= 0:
		pending_level_up = false
	character_changed.emit(self)
	return true

func modify_health(amount: float, allow_overheal: bool = false) -> void:
	hp += amount
	if allow_overheal:
		hp = max(0.0, hp)
	else:
		hp = clamp(hp, 0.0, maxhp)
	# Fix floating point precision: if HP is very close to 0 (within epsilon), set it to exactly 0.0
	# This ensures death checks work correctly when HP reaches exactly 0
	if hp <= 0.001:
		hp = 0.0
	health_changed.emit(hp, maxhp)
	character_changed.emit(self)

func modify_mana(amount: float) -> void:
	mp = clamp(mp + amount, 0, maxmp)
	mana_changed.emit(mp, maxmp)
	character_changed.emit(self)

func calculate_damage(base_damage: float, is_magical: bool = false, is_critical: bool = false) -> float:
	# Apply defense reduction - more like D&D where defense provides minimal protection
	# Defense now provides percentage reduction (like armor) rather than flat reduction
	# This prevents complete damage negation while still providing meaningful protection
	var final_damage = base_damage
	if not is_magical:
		# Physical damage: defense provides percentage reduction (like D&D armor)
		# Defense value is converted to percentage: 1 DEF = 2% reduction, max 50% reduction
		var defense_percentage = min(0.5, defense * 0.02)  # Max 50% reduction
		var effective_defense = defense_percentage
		if is_critical:
			# Critical hits pierce 80% of DEF (only 20% applies)
			effective_defense = defense_percentage * 0.2
		# Apply percentage reduction, but ensure at least 10% of damage gets through
		final_damage = base_damage * (1.0 - effective_defense)
		# Ensure minimum damage (at least 10% of base damage, or 1.0, whichever is higher)
		final_damage = max(1.0, max(base_damage * 0.1, final_damage))
	else:
		# Magical damage: reduce by magic resistance percentage
		final_damage = base_damage * (1 - (resistances.magic / 100.0))
	return final_damage

func take_damage(amount: float, is_magical: bool = false) -> float:
	# Calculate damage after DEF reduction
	var actual_damage = calculate_damage(amount, is_magical)
	modify_health(-actual_damage)
	# Check if dead (use epsilon to handle floating point precision)
	if hp <= 0.001:
		hp = 0.0  # Ensure exactly 0
		no_health.emit() # Emit when health reaches 0
	character_changed.emit(self)
	return actual_damage

func heal(amount: float, allow_overheal: bool = false) -> void:
	modify_health(amount, allow_overheal)

func use_mana(amount: float) -> bool:
	if mp >= amount:
		modify_mana(-amount)
		return true
	return false

func restore_mana(amount: float) -> void:
	modify_mana(amount)
	
func saveInventory() -> Array:
	var inventorySave = []
	for it:Item in inventory:
		inventorySave.push_back(it.save())
	return inventorySave
	
func saveEquipment() -> Dictionary:
	var eqSave = {
		"mainhand": equipment["mainhand"].save() if equipment["mainhand"] != null else null,
		"offhand": equipment["offhand"].save() if equipment["offhand"] != null else null,
		"headgear": equipment["headgear"].save() if equipment["headgear"] != null else null,
		"armour": equipment["armour"].save() if equipment["armour"] != null else null,
		"boots": equipment["boots"].save() if equipment["boots"] != null else null,
		"accessory": equipment["accessory"].save() if equipment["accessory"] != null else null
	}
	return eqSave
	
func loadInventory(iArr: Array):
	inventory.clear() # remove previous content
	for iDic in iArr:
		if iDic != null:
			inventory.push_back( Item.new(iDic) )
	pass
	
func loadEquipment(iDic: Dictionary):
	equipment["mainhand"] = Item.new(iDic.get("mainhand")) if iDic.has("mainhand") and iDic.get("mainhand") != null else null
	equipment["offhand"] = Item.new(iDic.get("offhand")) if iDic.has("offhand") and iDic.get("offhand") != null else null
	equipment["headgear"] = Item.new(iDic.get("headgear")) if iDic.has("headgear") and iDic.get("headgear") != null else null
	equipment["armour"] = Item.new(iDic.get("armour")) if iDic.has("armour") and iDic.get("armour") != null else null
	equipment["boots"] = Item.new(iDic.get("boots")) if iDic.has("boots")  and iDic.get("boots") != null else null
	equipment["accessory"] = Item.new(iDic.get("accessory")) if iDic.has("accessory") and iDic.get("accessory") != null else null
	pass

func save() -> Dictionary:
	var json = {
		"level": level,
		"character_type": character_type,
		"character_name": character_name,
		
		"race": race,  # Save race
		"baseStats": baseStats,
		
		"hp": hp,
		"mp": mp,
		"bonusmaxhp": bonusmaxhp,
		"bonusmaxmp": bonusmaxmp,
		
		"exp": xp,
		"coin": coin,
		
		"kills": kills,
		"deaths": deaths,
		"pending_level_up": pending_level_up,
		"pending_stat_points": pending_stat_points,
		
		"skin": skin,
		"facial_hair": facial_hair,
		"hairstyle": hairstyle,
		"eyes": eyes,
		"eye_lashes": eye_lashes,
		"add_on": add_on,
		
		"facial_hair_color": facial_hair_color.to_html(true),
		"hair_color": hair_color.to_html(true),
		"eye_color": eye_color.to_html(true),  # Save eye color
		"eyelash_color": eyelash_color.to_html(true),  # Save eyelash color
			
		"inventory": saveInventory(),
		"equipment": saveEquipment()
	}

	return json
	
func load(iDic: Dictionary) -> void:
	if iDic.has("level"):
		level = iDic.get("level")
	if iDic.has("character_type"):
		character_type = iDic.get("character_type")
	if iDic.has("character_name"):
		character_name = iDic.get("character_name")
	if iDic.has("hp"):
		hp = iDic.get("hp")
	if iDic.has("mp"):
		mp = iDic.get("mp")
	if iDic.has("bonusmaxhp"):
		bonusmaxhp = iDic.get("bonusmaxhp")
	if iDic.has("bonusmaxmp"):
		bonusmaxmp = iDic.get("bonusmaxmp")
	if iDic.has("baseStats"):
		baseStats = iDic.get("baseStats")
	if iDic.has("coin"):
		coin = iDic.get("coin")
	if iDic.has("exp"):
		xp = max(0.0, float(iDic.get("exp")))
	if iDic.has("kills"):
		kills = iDic.get("kills")
	if iDic.has("deaths"):
		deaths = iDic.get("deaths")
	if iDic.has("pending_level_up"):
		pending_level_up = bool(iDic.get("pending_level_up"))
	if iDic.has("pending_stat_points"):
		pending_stat_points = int(iDic.get("pending_stat_points"))
		
	inventory.clear()
	if iDic.has("inventory"):
		loadInventory(iDic.get("inventory"))
		
	# reset equipment
	equipment = {
		"mainhand": null,
		"offhand": null,
		"headgear": null,
		"armour": null,
		"boots": null,
		"accessory": null
	}
	if iDic.has("equipment"):
		loadEquipment(iDic.get("equipment"))
	if iDic.has("skin"):
		skin = iDic.get("skin")
	if iDic.has("facial_hair"):
		facial_hair = iDic.get("facial_hair")
	if iDic.has("hairstyle"):
		hairstyle = iDic.get("hairstyle")
	if iDic.has("eyes"):
		eyes = iDic.get("eyes")
	if iDic.has("eye_lashes"):
		eye_lashes = iDic.get("eye_lashes")	
	if iDic.has("add_on"):
		add_on = iDic.get("add_on")
	if iDic.has("facial_hair_color"):
		facial_hair_color = Color(iDic.get("facial_hair_color"))
	if iDic.has("hair_color"):
		hair_color = Color(iDic.get("hair_color"))
	if iDic.has("eye_color"):
		eye_color = Color(iDic.get("eye_color"))
	if iDic.has("eyelash_color"):
		eyelash_color = Color(iDic.get("eyelash_color"))
	if iDic.has("race"):
		race = iDic.get("race")
		
	pass
	'
func calculateStats():
	for i in stats.size():
		stats[i] = baseStats[i]
		pass
	stats[PlayerData.STAT.STAT_ATK] = 1 # defaults to 1
	
	# add equipment modifiers:
	for eq in equipped:
		if eq >= 0:
			for modifier in equipment[eq]["equipment"].modifiers:
				stats[modifier["stat"] as PlayerData.STAT] += modifier["change"]
				pass
		pass
	
	
	pass'
	
func add_coin(iAmount:int):
	coin += iAmount
	emit_signal("character_changed", self)
	pass
	
func drop_item(iItem:Item):
	var index = 0
	for item in inventory:
		if item == iItem:
			break
		index+=1
	inventory.remove_at(index)
	emit_signal("signal_drop_item", iItem)
	emit_signal("character_changed", self)
	pass
	
func drop_equipment(iItem:Item):
	unequip_item(iItem, false)
	# directly remove the item from the inventory
	drop_item(iItem)
	pass

func add_item(iItem:Item):
	# Try to stack with existing items if possible
	if iItem.can_have_multiple_of:
		for existing_item in inventory:
			# Check if items are the same (same name and properties)
			if existing_item and existing_item.item_name == iItem.item_name and existing_item.spriteFrame == iItem.spriteFrame:
				# Stack the items
				existing_item.quantity += iItem.quantity
				emit_signal("character_changed", self)
				return
	
	# If not stackable or no matching item found, add as new item
	self.inventory.push_back(iItem)
	
	# Auto-equip if slot is empty (only for equippable items)
	# BUT: Do NOT auto-equip BOW weapons (they require arrows in off-hand)
	if iItem.item_type == Item.ItemType.Equippable and iItem.equipment_type != Item.EquipmentType.NONE:
		# Skip auto-equip for BOW weapons
		if iItem.equipment_type == Item.EquipmentType.MAINHAND and iItem.weapon_type == Item.WeaponType.BOW:
			emit_signal("character_changed", self)
			return
		
		var slot_key = ""
		match iItem.equipment_type:
			Item.EquipmentType.MAINHAND:
				slot_key = "mainhand"
			Item.EquipmentType.OFFHAND:
				slot_key = "offhand"
			Item.EquipmentType.HEADGEAR:
				slot_key = "headgear"
			Item.EquipmentType.ARMOUR:
				slot_key = "armour"
			Item.EquipmentType.BOOTS:
				slot_key = "boots"
			Item.EquipmentType.ACCESSORY:
				slot_key = "accessory"
		
		# Auto-equip if slot is empty
		if slot_key != "" and equipment[slot_key] == null:
			equip_item(iItem)
	
	emit_signal("character_changed", self)
	pass
	
func unequip_item(iItem:Item, updateChar:bool = true):
	if iItem.equipment_type == Item.EquipmentType.NONE:
		return
	
	# Check if we can stack with existing item in inventory (for stackable items like arrows)
	var stacked = false
	if iItem.can_have_multiple_of:
		for inv_item in inventory:
			if inv_item and inv_item.can_have_multiple_of and inv_item.item_name == iItem.item_name:
				# Found matching stackable item in inventory - merge quantities
				inv_item.quantity += iItem.quantity
				stacked = true
				print("Unequipped ", iItem.quantity, " ", iItem.item_name, " and stacked with inventory (new total: ", inv_item.quantity, ")")
				break
	
	# If not stacked, add to inventory normally
	if not stacked:
		self.inventory.push_back(iItem)
	
	# Clear equipment slot
	match iItem.equipment_type:
		Item.EquipmentType.MAINHAND:
			equipment["mainhand"] = null
		Item.EquipmentType.OFFHAND:
			equipment["offhand"] = null
		Item.EquipmentType.HEADGEAR:
			equipment["headgear"] = null
		Item.EquipmentType.ARMOUR:
			equipment["armour"] = null
		Item.EquipmentType.BOOTS:
			equipment["boots"] = null
		Item.EquipmentType.ACCESSORY:
			equipment["accessory"] = null
	
	if updateChar:
		emit_signal("character_changed", self)
	pass
	
func forceUpdate():
	emit_signal("character_changed", self)
	pass

func equip_item(iItem:Item, insert_index: int = -1):
	# insert_index: if >= 0, place old item at this index instead of at the end
	if iItem.equipment_type == Item.EquipmentType.NONE:
		return
	
	var old_item = null
	var item_index = self.inventory.find(iItem)
	
	# Check if we can stack with already equipped item (for stackable items like arrows)
	var can_stack = false
	var equipped_item = null
	
	match iItem.equipment_type:
		Item.EquipmentType.MAINHAND:
			equipped_item = equipment["mainhand"]
		Item.EquipmentType.OFFHAND:
			equipped_item = equipment["offhand"]
		Item.EquipmentType.HEADGEAR:
			equipped_item = equipment["headgear"]
		Item.EquipmentType.ARMOUR:
			equipped_item = equipment["armour"]
		Item.EquipmentType.BOOTS:
			equipped_item = equipment["boots"]
		Item.EquipmentType.ACCESSORY:
			equipped_item = equipment["accessory"]
	
	# Check if items can stack (same item name, both stackable)
	if equipped_item and iItem.can_have_multiple_of and equipped_item.can_have_multiple_of:
		if iItem.item_name == equipped_item.item_name:
			can_stack = true
	
	if can_stack:
		# Stack quantities together
		equipped_item.quantity += iItem.quantity
		# Remove the item from inventory since we merged it
		if item_index >= 0:
			self.inventory.remove_at(item_index)
		print("Stacked ", iItem.quantity, " ", iItem.item_name, " with equipped (new total: ", equipped_item.quantity, ")")
	else:
		# Normal equip (swap items)
		match iItem.equipment_type:
			Item.EquipmentType.MAINHAND:
				if equipment["mainhand"] != null:
					old_item = equipment["mainhand"]
				equipment["mainhand"] = iItem
			Item.EquipmentType.OFFHAND:
				if equipment["offhand"] != null:
					old_item = equipment["offhand"]
				equipment["offhand"] = iItem
			Item.EquipmentType.HEADGEAR:
				if equipment["headgear"] != null:
					old_item = equipment["headgear"]
				equipment["headgear"] = iItem
			Item.EquipmentType.ARMOUR:
				if equipment["armour"] != null:
					old_item = equipment["armour"]
				equipment["armour"] = iItem
			Item.EquipmentType.BOOTS:
				if equipment["boots"] != null:
					old_item = equipment["boots"]
				equipment["boots"] = iItem
			Item.EquipmentType.ACCESSORY:
				if equipment["accessory"] != null:
					old_item = equipment["accessory"]
				equipment["accessory"] = iItem
		
		# Remove the item being equipped from inventory first
		if item_index >= 0:
			self.inventory.remove_at(item_index)
		
		# Add old item back to inventory at the specified position (or end if -1)
		if old_item != null:
			if insert_index >= 0 and insert_index <= self.inventory.size():
				self.inventory.insert(insert_index, old_item)
			else:
				self.inventory.push_back(old_item)
	
	emit_signal("character_changed", self)
	pass
	
func setSkin(iValue:int):
	if iValue < 0 or iValue > 6:
		return
	skin = "res://assets/gfx/Puny-Characters/Layer 0 - Skins/Human" + str(iValue+1) + ".png"
	emit_signal("character_changed", self)
	pass
	
func setFacialHair(iType:int):
	if iType < 0 or iType > 3:
		return
	
	match iType:
		0:
			facial_hair = ""
			emit_signal("character_changed", self)
			return
		1:
			facial_hair = "res://assets/gfx/Puny-Characters/Layer 4 - Hairstyle/Facial Hairstyles/Beardstyle1"
			pass
		2:
			facial_hair = "res://assets/gfx/Puny-Characters/Layer 4 - Hairstyle/Facial Hairstyles/Beardstyle2"
			pass
		3:
			facial_hair = "res://assets/gfx/Puny-Characters/Layer 4 - Hairstyle/Facial Hairstyles/Mustache1"
			pass
	facial_hair += "White.png"
	emit_signal("character_changed", self)
	pass


func setHair(iType:int):
	if iType < 0 or iType > 12:
		return
	if iType == 0:
		hairstyle = ""
		emit_signal("character_changed", self)
		return
	hairstyle = "res://assets/gfx/Puny-Characters/Layer 4 - Hairstyle/Hairstyles/FHairstyle" + str(iType)
	if iType >= 5: # male hairstyles
		hairstyle = "res://assets/gfx/Puny-Characters/Layer 4 - Hairstyle/Hairstyles/MHairstyle" + str(iType-4)
	hairstyle += "White.png"
	emit_signal("character_changed", self)
	pass
	
func setEyeLashes(iEyeLashes: int):
	if iEyeLashes < 0 or iEyeLashes > 8:
		return
	if iEyeLashes == 0:
		eye_lashes = ""
	else:
		match iEyeLashes:
			1:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/FEyelash1.png"
				pass
			2:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/FEyelash2.png"
				pass
			3:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/FEyelash3.png"
				pass
			4:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/MEyelash1.png"
				pass
			5:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/MEyelash2.png"
				pass
			6:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/NEyelash1.png"
				pass
			7:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/NEyelash2.png"
				pass
			8:
				eye_lashes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eyelashes/NEyelash3.png"
				pass
	emit_signal("character_changed", self)
	pass

func setEyes(iEyes: int):
	if iEyes < 0 or iEyes > 14:
		return
	if iEyes == 0:
		eyes = ""
	else:
		match iEyes:
			1:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorBlack.png"
				pass
			2:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorBlue.png"
				pass
			3:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorCyan.png"
				pass
			4:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorDarkBlue.png"
				pass
			5:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorDarkCyan.png"
				pass
			6:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorDarkLime.png"
				pass
			7:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorDarkRed.png"
				pass
			8:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorFullBlack.png"
				pass
			9:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorFullWhite.png"
				pass
			10:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorGray.png"
				pass
			11:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorLightLime.png"
				pass
			12:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorOrange.png"
				pass
			13:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorRed.png"
				pass
			14:
				eyes = "res://assets/gfx/Puny-Characters/Layer 5 - Eyes/Eye Color/EyecolorYellow.png"
				pass
	emit_signal("character_changed", self)
	pass
	
func setEars(iEars: int):
	if iEars < 0 or iEars > 7:
		return
	if iEars == 0:
		add_on = ""
	else:
		add_on = "res://assets/gfx/Puny-Characters/Layer 7 - Add-ons/Elf Add-ons/ElfEars" + str(iEars) + ".png"
	
	emit_signal("character_changed", self)
	pass

func setFacialHairColor(iColor: Color):
	facial_hair_color = iColor
	emit_signal("character_changed", self)
	pass
func setHairColor(iColor:Color):
	hair_color = iColor
	emit_signal("character_changed", self)
	pass
func setEyeColor(iColor: Color):
	eye_color = iColor
	emit_signal("character_changed", self)
	pass
func setEyelashColor(iColor: Color):
	eyelash_color = iColor
	emit_signal("character_changed", self)
	pass
func setRace(iRace: String):
	race = iRace
	emit_signal("character_changed", self)
	pass
