class_name MonsterData extends Resource @warning_ignore("unused_signal") signal on_level_up @export var unique_id : String = "" @export var name : String = "" @export var description: String = "" @export var thumbnail: CompressedTexture2D = preload("res://assets/logo/logo.png") @export var model: PackedScene @export var primary_type: MonsterType.Type = MonsterType.Type.NORMAL @export var secondary_type: MonsterType.Type = MonsterType.Type.NONE # Base Values @export var base_attack: int = 1 @export var base_health: int = 1 @export var base_defense: int = 1 @export var base_tempo: int = 1 @export var base_xp: int = 1 # Current Values @export var attack: int = 1 @export var current_health: int = 1 @export var health: int = 1 @export var defense: int = 1 @export var tempo: int = 1 @export var level: int = 1 @export var xp: int = 0 @export var nickname: String = "" @export var xp_for_levelup: int = 1 # The ID is the filename of the monster from res://entities/monsters/.tres func set_values(p_unique_id : String = "", current_values: Dictionary = {}, p_level: int = 1) -> void: if p_unique_id.is_empty(): printerr("Monster.gd: No ID given") return # Get an instance of the base monster data var base_monster: MonsterData = Utils.load_base_monster_data(p_unique_id) # Set the values self.name = base_monster.name self.description = base_monster.description self.thumbnail = base_monster.thumbnail self.model = base_monster.model self.primary_type = base_monster.primary_type self.secondary_type = base_monster.secondary_type # Set base values self.base_attack = base_monster.base_attack self.base_health = base_monster.base_health self.base_defense = base_monster.base_defense self.base_tempo = base_monster.base_tempo self.base_xp = base_monster.base_xp set_level(p_level) # If there are not values to edit, return if current_values.is_empty(): return # else, set custom values here for key: String in current_values: self[key] = current_values[key] ## This sets the monster to the specified level func set_level(p_level: int) -> void: self.level = p_level #print("old: %s/%s" % [self.current_health, self.health]) update() #print("new: %s/%s" % [self.current_health, self.health]) # Updates the values according to the current level of the monster func update() -> void: # INFO: the "current" values like the current_health should keep the percentage ratio # of the new and increased values like max_health var health_ratio: float = float(current_health) / float(self.health) #print("Ratio is %s" % str(health_ratio)) var new_current_health_value: int = round( float(self.health) * health_ratio ) #print(new_current_health_value) if new_current_health_value > self.current_health: self.current_health = new_current_health_value self.attack = int((((base_attack * 2.0) * level ) / 100) + (level + 5)) self.health = int((((base_health * 2.0) * level ) / 100) + (level + 5)) self.defense = int((((base_defense * 2.0) * level ) / 100) + (level + 5)) self.tempo = int((((base_tempo * 2.0) * level ) / 100) + (level + 5)) # This is the default growth rate formula: n^3 # It calculates the total cumulative xp needed to reach level n # To determine the XP needed for levelup, subtract the needed absolute xp # for the current level from the next level self.xp_for_levelup = int( (pow(level + 1, 3) - pow(level, 3)) ) func level_up() -> void: print("monster_data.gd: %s leveled up!" % self.name) set_level(level + 1) # reset the gained XP self.xp = 0 emit_signal("on_level_up") func calculate_gained_xp(enemy_data: MonsterData) -> int: var calculated_xp: int = 0 calculated_xp = 1 + int( (enemy_data.base_xp * enemy_data.level / 5.0) * ( float(enemy_data.level) / float(level) ) ) return calculated_xp func add_xp(amount: int = 0) -> void: xp += amount if(xp >= xp_for_levelup): level_up() func attack_enemy(enemy_data: MonsterData) -> int: var damage: int = 0 var base_damage: int = 2 damage = floor(floor((level * 2.0/5 + 2)) * base_damage * (float(attack) / (2 * enemy_data.defense)) + 2) enemy_data.take_damage(damage) return damage func take_damage(amount: int) -> void: current_health = max(current_health - amount, 0) func heal(amount: int) -> void: current_health = min(current_health + amount, health)