feat: generate animal-care quests and render them in the journal

This commit is contained in:
2026-08-08 20:27:59 +02:00
parent 089fef9968
commit 6cdeea6e46
8 changed files with 314 additions and 38 deletions
+57 -32
View File
@@ -1,10 +1,12 @@
class_name PlayerQuestRecord
extends RefCounted
const SCHEMA_VERSION := 1
const SCHEMA_VERSION := 2
const LEGACY_SCHEMA_VERSION := 1
const STATUS_OPEN := &"open"
const STATUS_COMPLETED := &"completed"
const STATUS_EXPIRED := &"expired"
const NO_OPPORTUNITY := -1
var data: Dictionary
@@ -22,7 +24,8 @@ static func create(
target_id: StringName,
target_amount: float,
created_tick: int,
standing_reward: float
standing_reward: float,
animal_id: StringName = &""
) -> PlayerQuestRecord:
return (
PlayerQuestRecord
@@ -41,16 +44,22 @@ static func create(
"standing_reward": standing_reward,
"resolution_event_id": -1,
"resolved_tick": -1,
"animal_id": String(animal_id),
}
)
)
static func from_dictionary(record_data: Dictionary) -> PlayerQuestRecord:
if int(record_data.get("schema_version", -1)) != SCHEMA_VERSION:
var version := int(record_data.get("schema_version", -1))
if version not in [LEGACY_SCHEMA_VERSION, SCHEMA_VERSION]:
return null
var normalized := record_data.duplicate(true)
if version == LEGACY_SCHEMA_VERSION:
normalized["schema_version"] = SCHEMA_VERSION
normalized["animal_id"] = ""
if not (
record_data
normalized
. has_all(
[
"quest_id",
@@ -65,25 +74,26 @@ static func from_dictionary(record_data: Dictionary) -> PlayerQuestRecord:
"standing_reward",
"resolution_event_id",
"resolved_tick",
"animal_id",
]
)
):
return null
var quest_id := int(record_data["quest_id"])
var opportunity_id := int(record_data["opportunity_id"])
var requester_npc_id := int(record_data["requester_npc_id"])
var quest_type := StringName(record_data["quest_type"])
var resource_id := StringName(record_data["resource_id"])
var target_id := StringName(record_data["target_id"])
var target_amount := float(record_data["target_amount"])
var status := StringName(record_data["status"])
var created_tick := int(record_data["created_tick"])
var standing_reward := float(record_data["standing_reward"])
var resolution_event_id := int(record_data["resolution_event_id"])
var resolved_tick := int(record_data["resolved_tick"])
var quest_id := int(normalized["quest_id"])
var opportunity_id := int(normalized["opportunity_id"])
var requester_npc_id := int(normalized["requester_npc_id"])
var quest_type := StringName(normalized["quest_type"])
var resource_id := StringName(normalized["resource_id"])
var target_id := StringName(normalized["target_id"])
var target_amount := float(normalized["target_amount"])
var status := StringName(normalized["status"])
var created_tick := int(normalized["created_tick"])
var standing_reward := float(normalized["standing_reward"])
var resolution_event_id := int(normalized["resolution_event_id"])
var resolved_tick := int(normalized["resolved_tick"])
var animal_id := StringName(normalized["animal_id"])
if (
quest_id < 0
or opportunity_id < 0
or requester_npc_id < 0
or quest_type.is_empty()
or resource_id.is_empty()
@@ -94,6 +104,8 @@ static func from_dictionary(record_data: Dictionary) -> PlayerQuestRecord:
or not is_finite(standing_reward)
or standing_reward <= 0.0
or resolution_event_id < -1
or (opportunity_id < 0 and animal_id.is_empty())
or (not animal_id.is_empty() and opportunity_id != NO_OPPORTUNITY)
):
return null
match status:
@@ -108,22 +120,27 @@ static func from_dictionary(record_data: Dictionary) -> PlayerQuestRecord:
return null
_:
return null
var record := create(
quest_id,
opportunity_id,
requester_npc_id,
quest_type,
resource_id,
target_id,
target_amount,
created_tick,
standing_reward
return (
PlayerQuestRecord
. new(
{
"schema_version": SCHEMA_VERSION,
"quest_id": quest_id,
"opportunity_id": opportunity_id,
"requester_npc_id": requester_npc_id,
"quest_type": String(quest_type),
"resource_id": String(resource_id),
"target_id": String(target_id),
"target_amount": target_amount,
"status": String(status),
"created_tick": created_tick,
"standing_reward": standing_reward,
"resolution_event_id": resolution_event_id,
"resolved_tick": resolved_tick,
"animal_id": String(animal_id),
}
)
)
if status == STATUS_COMPLETED:
record.complete(resolution_event_id, resolved_tick)
elif status == STATUS_EXPIRED:
record.expire(resolved_tick)
return record
func get_quest_id() -> int:
@@ -174,6 +191,14 @@ func get_resolved_tick() -> int:
return int(data["resolved_tick"])
func get_animal_id() -> StringName:
return StringName(data["animal_id"])
func has_animal_target() -> bool:
return not get_animal_id().is_empty()
func is_open() -> bool:
return get_status() == STATUS_OPEN