18 "description":
"+3 DEF"
26 "description":
"+3 ATK"
34 "description":
"+6 HP"
42 "description":
"+3 all stats"
50 "description":
"+10 HP, +2 ATK"
54 "rarity":
"Ultra Rare",
58 "description":
"+8 HP, +4 ATK, +4 DEF"
62const MAX_MERGES_BY_RARITY := {
68const GLOBAL_MAX_LEVEL := 5
74func make_card_instance(base_card:Dictionary, modifier_ids:Array = [], level:int = 1) -> Dictionary:
77 "base_id": str(base_card.get(
"id",
"")),
78 "modifier_ids": modifier_ids.duplicate(),
79 "level": max(1, level)
81 return apply_instance(base_card, instance)
85func roll_card_instance(base_card:Dictionary) -> Dictionary:
86 return make_card_instance(base_card, _roll_modifiers())
91func apply_instance(base_card:Dictionary, instance:Dictionary) -> Dictionary:
92 var card = base_card.duplicate(true)
93 var level = max(1,
int(instance.get(
"level", 1)))
94 var modifier_ids = instance.get(
"modifier_ids", [])
95 card[
"uid"] = str(instance.get(
"uid",
""))
96 card[
"base_id"] = str(instance.get(
"base_id", card.get(
"id",
"")))
97 card[
"base_card_id"] = str(card.get(
"base_id", card.get(
"id",
"")))
98 card[
"modifier_ids"] = modifier_ids.duplicate()
100 card[
"locked"] = bool(instance.get(
"locked", false))
101 card[
"health"] =
int(card.get(
"health", 0)) + ((level - 1) * 4)
102 card[
"attack"] =
int(card.get(
"attack", 0)) + (level - 1)
103 card[
"defense"] =
int(card.get(
"defense", 0)) +
int((level - 1) / 2)
104 for modifier_id
in modifier_ids:
105 var modifier = MODIFIERS.get(str(modifier_id), {})
106 card[
"health"] =
int(card.get(
"health", 0)) +
int(modifier.get(
"health", 0))
107 card[
"attack"] =
int(card.get(
"attack", 0)) +
int(modifier.get(
"attack", 0))
108 card[
"defense"] =
int(card.get(
"defense", 0)) +
int(modifier.get(
"defense", 0))
109 card[
"value"] = _calculate_value(base_card, card, level, modifier_ids)
110 card[
"name"] = _format_instance_name(base_card, level, modifier_ids)
115func get_modifier_names(modifier_ids:Array) -> Array:
117 for modifier_id
in modifier_ids:
118 var modifier = MODIFIERS.get(str(modifier_id), {})
119 if not modifier.is_empty():
120 names.append(str(modifier.get(
"name", modifier_id)))
125func get_modifier_summary(modifier_ids:Array) -> String:
127 for modifier_id
in modifier_ids:
128 var modifier = MODIFIERS.get(str(modifier_id), {})
129 if not modifier.is_empty():
130 parts.append(
"%s (%s)" % [modifier.get(
"name", modifier_id), modifier.get(
"description",
"")])
131 return ", ".join(parts)
if not parts.is_empty()
else "None"
135func get_instance_record(card:Dictionary) -> Dictionary:
137 "uid": str(card.get(
"uid",
"")),
138 "base_id": str(card.get(
"base_id", card.get(
"base_card_id", card.get(
"id",
"")))),
139 "modifier_ids": card.get(
"modifier_ids", []).duplicate(),
140 "level":
int(card.get(
"level", 1)),
141 "locked": bool(card.get(
"locked", false))
146func get_max_merges(base_card:Dictionary) -> int:
147 return int(MAX_MERGES_BY_RARITY.get(str(base_card.get(
"rarity",
"Common")), 1))
151func get_max_level(base_card:Dictionary) -> int:
152 return min(get_max_merges(base_card) + 1, GLOBAL_MAX_LEVEL)
156func can_upgrade(base_card:Dictionary, instance:Dictionary) -> bool:
157 return int(instance.get(
"level", 1)) < get_max_level(base_card)
161func preview_upgrade(base_card:Dictionary, instance:Dictionary, material_instance:Dictionary = {}) -> Dictionary:
162 var preview = instance.duplicate(true)
163 var material_level =
int(material_instance.get(
"level", 1))
164 preview[
"level"] = min(
int(preview.get(
"level", 1)) + material_level, get_max_level(base_card))
165 return apply_instance(base_card, preview)
168func reset_counter() -> void:
172func sync_counter(instances:Array) -> void:
174 for instance
in instances:
175 var uid = str(instance.get(
"uid",
""))
176 if uid.begins_with(
"card_"):
177 highest = max(highest,
int(uid.trim_prefix(
"card_")))
178 next_uid = highest + 1
181func _roll_modifiers() -> Array:
182 var roll = randi_range(1, 100)
186 return [[
"metal",
"sharp",
"hardy" ].pick_random()]
188 return [[
"blessed",
"giant" ].pick_random()]
189 return [
"mythic", [
"metal",
"sharp",
"hardy" ].pick_random()]
192func _make_uid() -> String:
193 var uid =
"card_%d" % next_uid
198func _format_instance_name(base_card:Dictionary, level:int, modifier_ids:Array) -> String:
199 var names = get_modifier_names(modifier_ids)
200 var prefix =
" ".join(names)
201 var base_name = str(base_card.get(
"name",
"Card"))
202 var level_suffix =
" +%d" % (level - 1)
if level > 1
else ""
203 return (
"%s %s%s" % [prefix, base_name, level_suffix]).strip_edges()
206func _calculate_value(base_card:Dictionary, card:Dictionary, level:int, modifier_ids:Array) -> int:
207 var base_value =
int(base_card.get(
"value", 0))
208 var stat_gain = max(0,
int(card.get(
"health", 0)) -
int(base_card.get(
"health", 0)))
209 stat_gain += max(0,
int(card.get(
"attack", 0)) -
int(base_card.get(
"attack", 0))) * 8
210 stat_gain += max(0,
int(card.get(
"defense", 0)) -
int(base_card.get(
"defense", 0))) * 8
211 return int(round((base_value + stat_gain + (modifier_ids.size() * 12)) * (1.0 + ((level - 1) * 0.25))))