400 lines
9.5 KiB
GDScript
400 lines
9.5 KiB
GDScript
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
|
|
|