merge: integrate remote player quest slices

This commit is contained in:
Rijad Zuzo
2026-08-16 16:53:30 +02:00
55 changed files with 3640 additions and 54 deletions
+97 -2
View File
@@ -19,6 +19,8 @@ const CONFLICT_SCHEMA_VERSION := 13
const PRE_EMERGENT_SCHEMA_VERSION := 14
const EMERGENT_SCHEMA_VERSION := 15
const PREVIOUS_SCHEMA_VERSION := 7
const PLAYER_LEGACY_SCHEMA_VERSION := 11
const PLAYER_STATE_LEGACY_SCHEMA_VERSION := 12
var simulation: Dictionary
var village: VillageStateRecord
@@ -37,6 +39,9 @@ var conversation_history: Array[ConversationActStateRecord] = []
var player: PlayerStateRecord
var combatants: Array[CombatantStateRecord] = []
var factions: Array[FactionStateRecord] = []
var player_standing: PlayerStandingRecord
var player_quests: Array[PlayerQuestRecord] = []
var player_state: PlayerStateRecord
func to_dictionary() -> Dictionary:
@@ -83,6 +88,9 @@ func to_dictionary() -> Dictionary:
var faction_data: Array[Dictionary] = []
for faction_record in factions:
faction_data.append(faction_record.to_dictionary())
var player_quest_data: Array[Dictionary] = []
for player_quest_record in player_quests:
player_quest_data.append(player_quest_record.to_dictionary())
return {
"schema": SCHEMA_NAME,
@@ -103,7 +111,10 @@ func to_dictionary() -> Dictionary:
"conversation_history": conversation_history_data,
"player": player.to_dictionary(),
"combatants": combatant_data,
"factions": faction_data
"factions": faction_data,
"player_standing": player_standing.to_dictionary(),
"player_quests": player_quest_data,
"player_state": player_state.to_dictionary()
}
@@ -140,6 +151,8 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
CONFLICT_SCHEMA_VERSION,
PRE_EMERGENT_SCHEMA_VERSION,
EMERGENT_SCHEMA_VERSION,
PLAYER_LEGACY_SCHEMA_VERSION,
PLAYER_STATE_LEGACY_SCHEMA_VERSION,
]
):
record_data = _migrate_legacy(record_data, version)
@@ -166,6 +179,9 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
"player",
"combatants",
"factions",
"player_standing",
"player_quests",
"player_state",
]
)
):
@@ -551,6 +567,7 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
record.relationships.append(relationship_record)
var opportunity_ids := {}
var opportunity_records_by_id := {}
var trigger_event_ids := {}
var resolution_event_ids := {}
var has_open_opportunity := false
@@ -585,6 +602,7 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
):
return null
opportunity_ids[opportunity_id] = true
opportunity_records_by_id[opportunity_id] = opportunity_record
trigger_event_ids[trigger_event_id] = true
highest_opportunity_id = maxi(highest_opportunity_id, opportunity_id)
record.opportunities.append(opportunity_record)
@@ -620,6 +638,72 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
record.conversation_history.append(conversation_act)
if saved_next_conversation_act_id <= highest_conversation_act_id:
return null
var standing_data = record_data["player_standing"]
if not standing_data is Dictionary:
return null
var standing_record := PlayerStandingRecord.from_dictionary(standing_data)
if standing_record == null:
return null
record.player_standing = standing_record
var player_quest_data = record_data["player_quests"]
if not player_quest_data is Array:
return null
var quest_ids := {}
var quest_opportunity_ids := {}
var highest_quest_id := -1
for item in player_quest_data:
if not item is Dictionary:
return null
var quest_record := PlayerQuestRecord.from_dictionary(item)
if quest_record == null:
return null
var quest_id := quest_record.get_quest_id()
var quest_opportunity_id := quest_record.get_opportunity_id()
var requester_id := quest_record.get_requester_npc_id()
var has_valid_requester := npc_ids.has(requester_id)
var has_valid_opportunity := (
quest_record.has_animal_target() or opportunity_ids.has(quest_opportunity_id)
)
if (
quest_ids.has(quest_id)
or quest_opportunity_ids.has(quest_opportunity_id)
or not has_valid_requester
or not has_valid_opportunity
):
return null
if (
quest_record.get_status() == PlayerQuestRecord.STATUS_OPEN
and (
(not quest_record.has_animal_target())
and not opportunity_records_by_id.has(quest_opportunity_id)
)
):
return null
if (
quest_record.get_resolution_event_id() >= 0
and not event_ids.has(quest_record.get_resolution_event_id())
):
return null
var dedup_key := (
"animal:%s" % String(quest_record.get_animal_id())
if quest_record.has_animal_target()
else "opp:%d" % quest_opportunity_id
)
if quest_ids.has(quest_id) or quest_opportunity_ids.has(dedup_key):
return null
quest_ids[quest_id] = true
quest_opportunity_ids[dedup_key] = true
highest_quest_id = maxi(highest_quest_id, quest_id)
record.player_quests.append(quest_record)
var player_state_data = record_data["player_state"]
if not player_state_data is Dictionary:
return null
var player_state_record := PlayerStateRecord.from_dictionary(player_state_data)
if player_state_record == null:
return null
record.player_state = player_state_record
return record
@@ -940,7 +1024,10 @@ static func _is_valid_supply_resolution(
return false
if event_type == SimulationIds.EVENT_STORAGE_DEPOSITED:
if actor_id == SimulationIds.PLAYER_ACTOR_ID:
return StringName(event.data["source_id"]) == SimulationIds.PLAYER_INVENTORY_ID
return (
StringName(event.data["source_id"])
in [SimulationIds.PLAYER_INVENTORY_ID, &"player_carry"]
)
return (
npc_ids.has(actor_id)
and StringName(event.data["source_id"]) == SimulationIds.npc_inventory_id(actor_id)
@@ -1066,6 +1153,14 @@ static func _migrate_legacy(legacy_data: Dictionary, version: int) -> Dictionary
var opportunity_simulation_data: Dictionary = migrated.get("simulation", {})
opportunity_simulation_data["next_opportunity_id"] = 0
migrated["simulation"] = opportunity_simulation_data
if version <= PLAYER_LEGACY_SCHEMA_VERSION:
migrated["player_standing"] = PlayerStandingRecord.create().to_dictionary()
migrated["player_quests"] = []
var quest_simulation_data: Dictionary = migrated.get("simulation", {})
quest_simulation_data["next_quest_id"] = 0
migrated["simulation"] = quest_simulation_data
if version <= PLAYER_STATE_LEGACY_SCHEMA_VERSION:
migrated["player_state"] = PlayerStateRecord.create().to_dictionary()
return migrated