feat: generalize social memory and relationships
This commit is contained in:
@@ -5,6 +5,8 @@ const TRUSTED_HELP_THRESHOLD := 0.6
|
||||
const FOOD_AID_TRUST_GAIN := 0.15
|
||||
const SHARED_WORK_FAMILIARITY_GAIN := 0.1
|
||||
const PLAYER_FAMILIARITY_SEED := 0.5
|
||||
const DEFAULT_SALIENT_RELATIONSHIP_LIMIT := 4
|
||||
const MAX_BOUNDED_RELATIONSHIPS_PER_QUERY := 8
|
||||
|
||||
var relationships: Dictionary = {}
|
||||
|
||||
@@ -39,6 +41,86 @@ func get_relationship(observer_id: int, subject_id: int) -> RelationshipStateRec
|
||||
return relationships.get(_key(observer_id, subject_id)) as RelationshipStateRecord
|
||||
|
||||
|
||||
func get_or_create_relationship(
|
||||
observer_id: int, subject_id: int, initial_familiarity: float = 0.0
|
||||
) -> RelationshipStateRecord:
|
||||
if (
|
||||
not RelationshipStateRecord.is_valid_actor_id(observer_id)
|
||||
or not RelationshipStateRecord.is_valid_actor_id(subject_id)
|
||||
or observer_id == subject_id
|
||||
):
|
||||
return null
|
||||
var relationship := get_relationship(observer_id, subject_id)
|
||||
if relationship != null:
|
||||
return relationship
|
||||
relationship = RelationshipStateRecord.create(observer_id, subject_id, initial_familiarity)
|
||||
_add(relationship)
|
||||
return relationship
|
||||
|
||||
|
||||
func adjust_relationship_dimension(
|
||||
observer_id: int,
|
||||
subject_id: int,
|
||||
dimension: StringName,
|
||||
amount: float,
|
||||
cause_event_id: int,
|
||||
create_if_missing: bool = true
|
||||
) -> float:
|
||||
var relationship := get_relationship(observer_id, subject_id)
|
||||
if relationship == null and create_if_missing:
|
||||
relationship = get_or_create_relationship(observer_id, subject_id)
|
||||
if relationship == null:
|
||||
return 0.0
|
||||
return relationship.adjust_dimension(dimension, amount, cause_event_id)
|
||||
|
||||
|
||||
func get_relationship_dimension(observer_id: int, subject_id: int, dimension: StringName) -> float:
|
||||
var relationship := get_relationship(observer_id, subject_id)
|
||||
return -1.0 if relationship == null else relationship.get_dimension(dimension)
|
||||
|
||||
|
||||
func get_relationship_cause_event_id(
|
||||
observer_id: int, subject_id: int, dimension: StringName
|
||||
) -> int:
|
||||
var relationship := get_relationship(observer_id, subject_id)
|
||||
return (
|
||||
RelationshipStateRecord.NO_CAUSE_EVENT
|
||||
if relationship == null
|
||||
else relationship.get_last_cause_event_id(dimension)
|
||||
)
|
||||
|
||||
|
||||
func get_relationships_for_observer(observer_id: int) -> Array[RelationshipStateRecord]:
|
||||
var records: Array[RelationshipStateRecord] = []
|
||||
for relationship in relationships.values():
|
||||
if relationship.get_observer_id() == observer_id:
|
||||
records.append(relationship)
|
||||
records.sort_custom(_sort_relationships)
|
||||
return records
|
||||
|
||||
|
||||
func get_salient_relationships(
|
||||
observer_id: int,
|
||||
max_count: int = DEFAULT_SALIENT_RELATIONSHIP_LIMIT,
|
||||
minimum_salience: float = 0.0
|
||||
) -> Array[RelationshipStateRecord]:
|
||||
if max_count <= 0:
|
||||
return []
|
||||
var records: Array[RelationshipStateRecord] = []
|
||||
var bounded_minimum := clampf(minimum_salience, 0.0, 1.0)
|
||||
for relationship in relationships.values():
|
||||
if relationship.get_observer_id() != observer_id:
|
||||
continue
|
||||
if relationship.get_salience() < bounded_minimum:
|
||||
continue
|
||||
records.append(relationship)
|
||||
records.sort_custom(_is_more_salient)
|
||||
var bounded_count := mini(max_count, MAX_BOUNDED_RELATIONSHIPS_PER_QUERY)
|
||||
if records.size() > bounded_count:
|
||||
records.resize(bounded_count)
|
||||
return records
|
||||
|
||||
|
||||
func is_trusted_for_help(observer_id: int, subject_id: int) -> bool:
|
||||
var relationship := get_relationship(observer_id, subject_id)
|
||||
return (
|
||||
@@ -49,8 +131,10 @@ func is_trusted_for_help(observer_id: int, subject_id: int) -> bool:
|
||||
|
||||
|
||||
func increase_shared_work_familiarity(first_id: int, second_id: int) -> void:
|
||||
var first_to_second := _get_or_create(first_id, second_id)
|
||||
var second_to_first := _get_or_create(second_id, first_id)
|
||||
var first_to_second := get_or_create_relationship(first_id, second_id)
|
||||
var second_to_first := get_or_create_relationship(second_id, first_id)
|
||||
if first_to_second == null or second_to_first == null:
|
||||
return
|
||||
first_to_second.increase_familiarity(SHARED_WORK_FAMILIARITY_GAIN)
|
||||
second_to_first.increase_familiarity(SHARED_WORK_FAMILIARITY_GAIN)
|
||||
|
||||
@@ -174,15 +258,6 @@ func get_trusted_starving_subject(
|
||||
return effective_view.get_starving(best_relationship.get_subject_id())
|
||||
|
||||
|
||||
func _get_or_create(observer_id: int, subject_id: int) -> RelationshipStateRecord:
|
||||
var relationship := get_relationship(observer_id, subject_id)
|
||||
if relationship != null:
|
||||
return relationship
|
||||
relationship = RelationshipStateRecord.create(observer_id, subject_id, 0.0)
|
||||
_add(relationship)
|
||||
return relationship
|
||||
|
||||
|
||||
func _add(relationship: RelationshipStateRecord) -> void:
|
||||
relationships[_key(relationship.get_observer_id(), relationship.get_subject_id())] = relationship
|
||||
|
||||
@@ -207,3 +282,13 @@ static func _is_stronger(
|
||||
if not is_equal_approx(candidate.get_familiarity(), current.get_familiarity()):
|
||||
return candidate.get_familiarity() > current.get_familiarity()
|
||||
return candidate.get_subject_id() < current.get_subject_id()
|
||||
|
||||
|
||||
static func _is_more_salient(
|
||||
first: RelationshipStateRecord, second: RelationshipStateRecord
|
||||
) -> bool:
|
||||
if not is_equal_approx(first.get_salience(), second.get_salience()):
|
||||
return first.get_salience() > second.get_salience()
|
||||
if not is_equal_approx(first.get_trust(), second.get_trust()):
|
||||
return first.get_trust() > second.get_trust()
|
||||
return first.get_subject_id() < second.get_subject_id()
|
||||
|
||||
Reference in New Issue
Block a user