extends Node2D @export var savePrefix:String = "" var materialInvName var smokeScene = preload("res://Skills/Arson/Smoke.tscn") var groundItemScene = preload("res://Objects/GroundItems/GroundItem.tscn") const damFireStarterClass = preload("res://Items/Artificial/Products/DamFireStarter.gd") var buildingMaterial:Item var buildingHealth = 0 var buildingProgress = -1 var fireSound:AudioStreamPlayer2D var onFire = false var fireDamage = 10 var flintSoundPlayer var lastSoundIndex = -1 var flintSounds = [] var health = 0 var maxHealth = 0 var fireXpCounter = 10 var fireXpCollected = 0 var complete = false var rng = RandomNumberGenerator.new() func _ready(): fireSound = $FireSound initialize_flint_sounds() load_build() if buildingMaterial != null and buildingProgress >= get_stages_for_item(buildingMaterial): fully_built(true) else: if buildingMaterial != null: %BuildingBar.value = 0 %BuildingBar.max_value = get_stages_for_item(buildingMaterial) $MainSprite.visible = false complete = false hide_other_visuals() func load_build(): materialInvName = savePrefix + "Material" var materialInv = InventoryManager.get_inventory(materialInvName) if materialInv.items.size() > 0: buildingMaterial = materialInv.items[0] buildingProgress = SaveManager.get_save_value(savePrefix + "Progress", -1) func save_build(): var materialInv = InventoryManager.get_inventory(materialInvName) materialInv.clear() if buildingMaterial != null: materialInv.add_item(buildingMaterial) SaveManager.set_save_value(savePrefix + "Progress", buildingProgress) func _process(delta): if onFire: if !complete: onFire = false else: $Fires.visible = true if !fireSound.playing: fireSound.play() take_damage(fireDamage * delta, true) else: $Fires.visible = false if fireSound != null and fireSound.playing: fireSound.stop() if complete: %StageCounter.visible = false %BuildingBar.visible = false if health >= maxHealth: %HealthBar.visible = false else: %HealthBar.visible = true %HealthBar.max_value = maxHealth %HealthBar.value = health else: if buildingProgress == -1: %StageCounter.visible = false %BuildingBar.visible = false %HealthBar.visible = false elif buildingProgress >= 0: %StageCounter.visible = true %BuildingBar.visible = true %HealthBar.visible = false %StageCounter.text = "Stages: " + str(buildingProgress) + "/" + str(get_stages_for_item(buildingMaterial)) %BuildingBar.value = buildingProgress func take_damage(damage, fireDamage = false): health -= damage if fireDamage: fireXpCounter -= damage if fireXpCounter <= 0: LevelManager.add_XP("arson", 6) fireXpCounter += 10 fireXpCollected += damage if health <= 0: if onFire and fireXpCollected > 0: LevelManager.add_XP("arson", fireXpCollected) if onFire: LevelManager.get_skill("appreciating").experience_event("Dam", "burned a", 230) else: LevelManager.get_skill("appreciating").experience_event("Dam", "overloaded a", 230) experiencing_destruction(buildingMaterial) if get_gumption(buildingMaterial) <= 0: AchievementManager.complete_achievement("Dunk Trap") var itemToDrop = buildingMaterial.duplicate() if onFire: itemToDrop = AshGenerator.generate_ash(itemToDrop) drop_items(itemToDrop) unbuilt() func experiencing_destruction(item): pass func stage_complete(): buildingProgress += 1 var xp = 0 if buildingProgress >= get_stages_for_item(buildingMaterial): xp += get_completion_xp() else: xp += get_stage_xp() LevelManager.add_XP("building", xp) save_build() if buildingProgress < get_stages_for_item(buildingMaterial): return true else: fully_built() return false func demolish(): if demolish_check(): var player:Cow = GameVariables.player player.demolish(self) func demolish_check(): if !complete and buildingProgress > 0: return true return false func get_demolishing_speed(): if buildingProgress <= 1: return 100 else: var speed = 100/(buildingProgress/2) return speed func demolished(): unbuilt() func arson(): if arson_check(): play_flint_sound() if arson_skill_check(): burn() func arson_check(): if complete and !onFire: return true return false func arson_skill_check(): var fireChance = buildingMaterial.get_flammability()*0.5 fireChance -= 30 var currentLevel = LevelManager.get_skill("arson").currentLevel fireChance += currentLevel*1.5 var penalty = floor(((70-buildingMaterial.get_flammability()) - currentLevel)/10) if penalty > 0: for i in range(penalty): fireChance = fireChance * 0.75 if InventoryManager.check_if_in_inventory(damFireStarterClass.new(), 1, "keyItems"): if fireChance < 0: fireChance = 0 fireChance += 3 if rng.randi_range(0, 100) <= fireChance: return true else: if fireChance >= 1: smoke() return false func initialize_flint_sounds(): flintSoundPlayer = $FlintSounds flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint1.mp3")) flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint2.mp3")) flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint3.mp3")) flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint4.mp3")) flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint5.mp3")) flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint6.mp3")) flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint7.mp3")) flintSounds.append(load("res://Sounds/SFX/Fire/Flint/flint8.mp3")) func play_flint_sound(): var newIndex = rng.randi_range(0, flintSounds.size() - 1) if newIndex == lastSoundIndex: newIndex = rng.randi_range(0, flintSounds.size() - 1) flintSoundPlayer.stream = flintSounds[newIndex] flintSoundPlayer.play() lastSoundIndex = newIndex func burn(): onFire = true func smoke(): var smokeOffsets = [Vector2(-156, 20), Vector2(-7, -14), Vector2(148, 17)] for offset in smokeOffsets: var newSmoke = smokeScene.instantiate() newSmoke.position = position + offset newSmoke.emitting = true get_parent().add_child(newSmoke) func unbuilt(): $MainSprite.visible = false complete = false buildingProgress = -1 buildingMaterial = null hide_other_visuals() save_build() func drop_items(item): var groundItemOffsets = [Vector2(80, 10), Vector2(-80, 10), Vector2(0, -20), Vector2(-160, 20), Vector2(160, 20)] var itemsBack = 0 var itemsUsed = get_stages_for_item(buildingMaterial) if itemsUsed >= 2: itemsBack += 1 if itemsUsed >= 5: itemsBack += 1 if itemsUsed >= 25: itemsBack += 3 for offset in groundItemOffsets: if itemsBack <= 0: break else: itemsBack -= 1 var newGroundItem = groundItemScene.instantiate() newGroundItem.set_item(item.duplicate()) newGroundItem.global_position = global_position + offset LocationManager.currentLocation.add_child(newGroundItem) func hide_other_visuals(): pass func fully_built(loadedState = false): if !loadedState: LevelManager.get_skill("appreciating").experience_item(buildingMaterial, "dammed") maxHealth = get_max_health() health = maxHealth complete = true fireXpCollected = ceili(get_completion_xp()/4) fireXpCounter = 10 func get_max_health(): var newMaxHealth = 20 newMaxHealth += get_gumption(buildingMaterial) * 2 if newMaxHealth > 500: newMaxHealth = 500 if newMaxHealth <= 5: newMaxHealth = 5 return newMaxHealth func get_stage_xp(): var difficulty = abs(buildingMaterial.get_hardness() - 30) var xpReward = 1 xpReward += difficulty * 0.2 xpReward = floori(xpReward) return xpReward func get_completion_xp(): var difficulty = abs(buildingMaterial.get_hardness() - 30) var xpReward = 250 xpReward += get_stages_for_item(buildingMaterial) * 2 xpReward += difficulty * 8 xpReward = floori(xpReward) return xpReward func build(): if build_check(): var player:Cow = GameVariables.player player.build(buildingMaterial, self) func build_check(): if buildingProgress >= 0 and !complete: return true return false func plan(): if plan_check(): open_planning_menu() func open_planning_menu(): $PlanningWindow.popup_centered() $PlanningWindow.opened() func plan_check(): if buildingProgress <= 0: return true return false func set_plan(material:Item): buildingMaterial = material buildingProgress = 0 %BuildingBar.value = 0 %BuildingBar.max_value = get_stages_for_item(buildingMaterial) save_build() func get_success_chance(item:Item): var chance = 100 var playerLevel = LevelManager.get_skill("building").currentLevel var difficulty = abs(item.get_hardness() - 30) var difficultyDif = difficulty - playerLevel if difficultyDif <= 0: difficultyDif = 0 var difficultySteps = floori(difficultyDif/5) chance -= difficultySteps * 5 chance -= difficultyDif * 2 if difficultyDif > 5: chance -= 15 if difficultyDif > 10: chance -= 10 if chance <= 1: chance = 1 elif chance > 100: chance = 100 return chance func get_stages_for_item(item:Item): if item == null: return 0 var stages = 0 if item.get_weight() <= 0: stages = 10 elif item.get_weight() <= 0.2: stages = 250 else: stages = ceili(float(50)/float(item.get_weight())) if item.get_name(false) == "Worm on a String" or item.get_name(false) == "Basket on a String": stages = 80 return stages func get_gumption(item:Item): var gumption = 0 gumption += item.get_hardness() * 2 if item.get_hardness() > 30: gumption += (item.get_hardness() - 30) * 2 if item.get_hardness() > 50: gumption += (item.get_hardness() - 50) * 5 if item.get_hardness() > 70: gumption += (item.get_hardness() - 70) * 10 if item.get_hardness() > 90: gumption += (item.get_hardness() - 90) * 50 return gumption