feat: add player standing and quest generation from village needs
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
class_name PlayerQuestSystem
|
||||
extends RefCounted
|
||||
|
||||
const PANTRY_STANDING_REWARD := 8.0
|
||||
const WOOD_STANDING_REWARD := 8.0
|
||||
|
||||
var quests: Array[PlayerQuestRecord] = []
|
||||
var next_quest_id := 0
|
||||
var standing := PlayerStandingRecord.create()
|
||||
|
||||
|
||||
func consider_opportunity_opened(
|
||||
opportunity: OpportunityStateRecord,
|
||||
player_response: OpportunityPlayerResponseResult,
|
||||
current_tick: int
|
||||
) -> PlayerQuestRecord:
|
||||
if (
|
||||
opportunity == null
|
||||
or not opportunity.is_open()
|
||||
or player_response == null
|
||||
or current_tick < 0
|
||||
):
|
||||
return null
|
||||
if _find_open_quest_for_opportunity(opportunity.get_opportunity_id()) != null:
|
||||
return null
|
||||
var reward := _standing_reward_for(opportunity)
|
||||
if reward <= 0.0:
|
||||
return null
|
||||
var quest := PlayerQuestRecord.create(
|
||||
next_quest_id,
|
||||
opportunity.get_opportunity_id(),
|
||||
opportunity.get_interested_npc_id(),
|
||||
opportunity.get_opportunity_type(),
|
||||
opportunity.get_resource_id(),
|
||||
opportunity.get_target_id(),
|
||||
opportunity.get_target_amount(),
|
||||
current_tick,
|
||||
reward
|
||||
)
|
||||
next_quest_id += 1
|
||||
quests.append(quest)
|
||||
return quest
|
||||
|
||||
|
||||
func on_opportunity_resolved(
|
||||
opportunity: OpportunityStateRecord, resolution_event: EconomicEventRecord, current_tick: int
|
||||
) -> Dictionary:
|
||||
var quest := _find_open_quest_for_opportunity(opportunity.get_opportunity_id())
|
||||
if quest == null or resolution_event == null:
|
||||
return {}
|
||||
var event_id := int(resolution_event.data["event_id"])
|
||||
var actor_id := int(resolution_event.data["actor_id"])
|
||||
if actor_id < 0:
|
||||
if not quest.complete(event_id, current_tick):
|
||||
return {}
|
||||
standing.grant_standing(quest.get_standing_reward(), quest.get_requester_npc_id())
|
||||
return {"quest": quest, "completed": true}
|
||||
if quest.expire(current_tick):
|
||||
return {"quest": quest, "completed": false}
|
||||
return {}
|
||||
|
||||
|
||||
func on_opportunity_invalidated(
|
||||
opportunity: OpportunityStateRecord, current_tick: int
|
||||
) -> PlayerQuestRecord:
|
||||
var quest := _find_open_quest_for_opportunity(opportunity.get_opportunity_id())
|
||||
if quest == null:
|
||||
return null
|
||||
if quest.expire(current_tick):
|
||||
return quest
|
||||
return null
|
||||
|
||||
|
||||
func get_active_quest() -> PlayerQuestRecord:
|
||||
for quest in quests:
|
||||
if quest.is_open():
|
||||
return quest
|
||||
return null
|
||||
|
||||
|
||||
func get_all_sorted() -> Array[PlayerQuestRecord]:
|
||||
var sorted := quests.duplicate()
|
||||
sorted.sort_custom(_sort_by_id)
|
||||
return sorted
|
||||
|
||||
|
||||
func get_latest_for_requester(requester_npc_id: int) -> PlayerQuestRecord:
|
||||
for index in range(quests.size() - 1, -1, -1):
|
||||
var quest := quests[index]
|
||||
if quest.get_requester_npc_id() == requester_npc_id:
|
||||
return quest
|
||||
return null
|
||||
|
||||
|
||||
func restore(
|
||||
records: Array[PlayerQuestRecord], restored_next_id: int, standing_record: PlayerStandingRecord
|
||||
) -> void:
|
||||
quests = records.duplicate()
|
||||
quests.sort_custom(_sort_by_id)
|
||||
next_quest_id = maxi(restored_next_id, 0)
|
||||
standing = standing_record if standing_record != null else PlayerStandingRecord.create()
|
||||
|
||||
|
||||
func _find_open_quest_for_opportunity(opportunity_id: int) -> PlayerQuestRecord:
|
||||
for quest in quests:
|
||||
if quest.is_open() and quest.get_opportunity_id() == opportunity_id:
|
||||
return quest
|
||||
return null
|
||||
|
||||
|
||||
func _standing_reward_for(opportunity: OpportunityStateRecord) -> float:
|
||||
match opportunity.get_opportunity_type():
|
||||
SimulationIds.OPPORTUNITY_RESTOCK_EMPTY_PANTRY:
|
||||
return PANTRY_STANDING_REWARD
|
||||
SimulationIds.OPPORTUNITY_SUPPLY_MISSING_WOOD:
|
||||
return WOOD_STANDING_REWARD
|
||||
return 0.0
|
||||
|
||||
|
||||
static func _sort_by_id(first: PlayerQuestRecord, second: PlayerQuestRecord) -> bool:
|
||||
return first.get_quest_id() < second.get_quest_id()
|
||||
@@ -0,0 +1 @@
|
||||
uid://cojertujqx8ts
|
||||
Reference in New Issue
Block a user