70 lines
5.5 KiB
GDScript
70 lines
5.5 KiB
GDScript
extends RefCounted
|
|
# Every orb is consumed once. Further advancement requires another orb.
|
|
const IDS := ["piercing", "booster", "advancement", "replication", "electricity", "radiation", "kinetic", "atomic_engine", "polarization"]
|
|
const COMMON_IDS := ["piercing", "booster", "advancement", "electricity", "radiation", "kinetic", "atomic_engine", "polarization"]
|
|
const DAMAGE_ORBS := ["electricity", "radiation", "kinetic"]
|
|
const NAMES := {"piercing":"Orb przebicia", "booster":"Orb dopalacza", "advancement":"Orb awansu", "replication":"Orb replikacji", "electricity":"Orb elektryczności", "radiation":"Orb radiacji", "kinetic":"Orb kinetyczny", "atomic_engine":"Orb silników atomowych", "polarization":"Orb polaryzacyjny"}
|
|
const DESCRIPTIONS := {"replication":"Tworzy dokładną, niezależną kopię wyposażenia w magazynie frachtowca. Oryginał zostaje. Kopiuje poziom, addony i efekty orbów. Drop: dodatkowe 5% z bossa dalekiej wyprawy.", "electricity":"Trwale zmienia typ obrażeń broni na energetyczny (jak laser). Nie zwiększa obrażeń ani kosztu strzału. Zastępuje poprzedni orb typu obrażeń.", "radiation":"Trwale zmienia typ obrażeń broni na radiacyjny. Nie zwiększa obrażeń ani kosztu strzału. Zastępuje poprzedni orb typu obrażeń.", "kinetic":"Trwale zmienia typ obrażeń broni na kinetyczny. Nie zwiększa obrażeń ani kosztu strzału. Zastępuje poprzedni orb typu obrażeń.", "atomic_engine":"Tylko silnik. Trwale zmniejsza zużycie energii dopalacza TAB o 50%. Nie sumuje się. Orb darmowego dopalacza ma pierwszeństwo.", "polarization":"Tylko tarcze. Trafienie w tarcze odnawia do 5% maksymalnych tarcz jako energię, nie więcej niż faktycznie stracone tarcze. Tempo odzysku: do 5% pojemności generatora/s, z rezerwą na jedno takie odnowienie. Uniki i trafienia w sam kadłub nie aktywują efektu.", "piercing":"50% obrażeń broni omija tarcze i trafia bezpośrednio w kadłub. Tylko broń.", "booster":"Dopalacz pod TAB nie zużywa energii i działa również przy pustym generatorze. Tylko silnik.", "advancement":"Awansuje przedmiot o 1 poziom i ponownie losuje jego parametry oraz wartości obecnych addonów. Zachowuje ich typy, liczbę i efekty orbów. Wyniki losowania mogą być niższe. Jedna sztuka daje jeden awans. Kolejny awans wymaga nowego orba (główna progresja do 120; 1000 to limit techniczny). Nie działa na materiały zużywalne."}
|
|
static func icon(id: String) -> Texture2D:
|
|
return load("res://assets/icons/orbs/%s.%s" % [id, "png" if id in ["piercing", "booster", "advancement"] else "svg"]) as Texture2D
|
|
static func create_item(id: String, amount := 1) -> ItemInstance:
|
|
if id not in IDS or amount <= 0: return null
|
|
var definition := ItemDefinition.new()
|
|
definition.item_id = "orb_"+id
|
|
definition.orb_id = id
|
|
definition.display_name = NAMES[id]
|
|
definition.description = DESCRIPTIONS[id]
|
|
definition.icon = icon(id)
|
|
definition.category = ItemDefinition.Category.CONSUMABLE
|
|
var item := ItemInstance.new()
|
|
item.definition = definition
|
|
item.stack_count = amount
|
|
return item
|
|
|
|
static func count(progress: Resource, inventory: Node, id: String) -> int:
|
|
var total := int(progress.orbs.get(id,0))
|
|
if inventory != null:
|
|
for item in inventory.cargo.slice(0,inventory.unlocked_cargo_slots):
|
|
if item != null and item.definition.orb_id == id: total += item.stack_count
|
|
return total
|
|
static func accepts(item: ItemInstance, id: String) -> bool:
|
|
if id not in IDS or item == null or item.definition == null: return false
|
|
if id == "advancement": return preload("res://scripts/items/item_generator.gd").can_advance(item)
|
|
if id == "replication": return item.definition.category != ItemDefinition.Category.CONSUMABLE
|
|
if id in item.special_orbs: return false
|
|
if id in DAMAGE_ORBS:
|
|
return item.definition.category == ItemDefinition.Category.WEAPON
|
|
if id == "polarization": return item.definition.category == ItemDefinition.Category.SHIELD
|
|
return item.definition.category == (ItemDefinition.Category.WEAPON if id == "piercing" else ItemDefinition.Category.ENGINE)
|
|
static func apply(progress: Resource, inventory: Node, item: ItemInstance, id: String) -> bool:
|
|
if inventory == null or not accepts(item,id) or count(progress,inventory,id) <= 0: return false
|
|
var owned: Array = inventory.cargo.slice(0,inventory.unlocked_cargo_slots) + inventory.weapon_slots.slice(0,inventory.unlocked_weapon_slots) + inventory.module_slots + inventory.extension_slots.slice(0,inventory.unlocked_extension_slots) + progress.freighter_storage
|
|
if not owned.has(item): return false
|
|
if id == "advancement":
|
|
if not preload("res://scripts/items/item_generator.gd").advance(item): return false
|
|
elif id == "replication":
|
|
var copy := item.duplicate() as ItemInstance
|
|
copy.special_orbs = item.special_orbs.duplicate()
|
|
copy.additional_modifiers = []
|
|
for modifier in item.additional_modifiers:
|
|
copy.additional_modifiers.append(modifier.duplicate() as ItemStatModifier if modifier != null else null)
|
|
progress.freighter_storage.append(copy)
|
|
else:
|
|
if id in DAMAGE_ORBS:
|
|
for previous in DAMAGE_ORBS: item.special_orbs.erase(previous)
|
|
item.special_orbs.append(id)
|
|
var consumed := false
|
|
for index in inventory.get_cargo_capacity():
|
|
var orb: ItemInstance = inventory.cargo[index]
|
|
if orb == null or orb.definition.orb_id != id: continue
|
|
orb.stack_count -= 1
|
|
if orb.stack_count <= 0: inventory.cargo[index] = null
|
|
consumed = true
|
|
break
|
|
if not consumed: progress.orbs[id] = int(progress.orbs[id])-1
|
|
item.emit_changed()
|
|
inventory.call("_recalculate_ship_stats")
|
|
inventory.inventory_changed.emit()
|
|
progress.emit_changed()
|
|
return true
|