Merge branch 'phase/44-quarrel-fight'
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # docs/phases/README.md # src/HSchool.Content/PeopleDefs.cs # src/HSchool.People/Roster.cs # src/HSchool.People/Seed.cs
This commit is contained in:
@@ -333,7 +333,7 @@ internal static class PresenceSystem
|
||||
: slot.Kind == DaySlotKind.Lesson && lessons.Any(lesson => lesson.Period == slot.Index);
|
||||
if (activity.IsActive && TalkActions.IsTalk(activity.ActionId))
|
||||
{
|
||||
if (!bound || TalkActions.IsWhisper(activity.ActionId))
|
||||
if (!bound || TalkActions.IsWhisper(activity.ActionId) || TalkActions.IsFight(activity.ActionId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -434,7 +434,25 @@ internal static class PresenceSystem
|
||||
|
||||
if (decision.StartAction is not null && !activity.IsActive)
|
||||
{
|
||||
return decision.StartAction;
|
||||
var start = decision.StartAction;
|
||||
var location = state.NodeId is null ? null : school.Map?.NodeDef(state.NodeId);
|
||||
if (TalkActions.IsQuarrel(start)
|
||||
&& location is not null
|
||||
&& Conflict.CanFightHere(location)
|
||||
&& Conflict.RollFight(
|
||||
person.Traits,
|
||||
school.Catalog!,
|
||||
school.Catalog.BehaviorRules,
|
||||
Seed.Mix(
|
||||
school.PeopleSeed,
|
||||
person.Id,
|
||||
DateOnly.FromDateTime(school.Clock.Time).DayNumber,
|
||||
Seed.ConflictSalt + 2)))
|
||||
{
|
||||
start = Conflict.FightActionFor(location);
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
if (!activity.IsActive
|
||||
@@ -444,6 +462,20 @@ internal static class PresenceSystem
|
||||
return TalkActions.Whisper;
|
||||
}
|
||||
|
||||
if (!activity.IsActive
|
||||
&& decision.WalkTo is null
|
||||
&& ShouldStartFightOnPe(school, person, state))
|
||||
{
|
||||
return TalkActions.FightGym;
|
||||
}
|
||||
|
||||
if (!activity.IsActive
|
||||
&& decision.WalkTo is null
|
||||
&& ShouldStartApology(school, person, state))
|
||||
{
|
||||
return TalkActions.Apologize;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -476,6 +508,82 @@ internal static class PresenceSystem
|
||||
return TalkCircles.WhisperCaught(roll, chance, 0.5f, 1f);
|
||||
}
|
||||
|
||||
private static bool ShouldStartFightOnPe(School school, Person person, ActorState state)
|
||||
{
|
||||
if (!state.BoundToLesson
|
||||
|| !person.IsStudent
|
||||
|| state.IsWalking
|
||||
|| state.NodeId is null
|
||||
|| school.Catalog is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var location = school.Map?.NodeDef(state.NodeId);
|
||||
if (location is null || !location.Equals("GymHall", StringComparison.Ordinal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Conflict.HasRival(state.Talk))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Conflict.RollFight(
|
||||
person.Traits,
|
||||
school.Catalog,
|
||||
school.Catalog.BehaviorRules,
|
||||
Seed.Mix(
|
||||
school.PeopleSeed,
|
||||
person.Id,
|
||||
DateOnly.FromDateTime(school.Clock.Time).DayNumber,
|
||||
Seed.ConflictSalt + 3 + (school.Clock.Time.Minute / 2)));
|
||||
}
|
||||
|
||||
private static bool ShouldStartApology(School school, Person person, ActorState state)
|
||||
{
|
||||
if (!person.IsStudent || state.IsWalking || state.NodeId is null || school.Catalog is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var hasDebtHere = false;
|
||||
foreach (var debt in school.ApologyDebts.Values)
|
||||
{
|
||||
if (!debt.FromId.Equals(person.Id, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!state.Talk.PersonNodes.TryGetValue(debt.ToId, out var node)
|
||||
|| !node.Equals(state.NodeId, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasDebtHere = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasDebtHere)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var chance = Math.Clamp(
|
||||
Conflict.ApologyChance(person.Traits, school.Catalog),
|
||||
0f,
|
||||
1f);
|
||||
return Conflict.RollStarts(
|
||||
chance,
|
||||
Seed.Mix(
|
||||
school.PeopleSeed,
|
||||
person.Id,
|
||||
DateOnly.FromDateTime(school.Clock.Time).DayNumber,
|
||||
Seed.ConflictSalt + 4));
|
||||
}
|
||||
|
||||
private static Dictionary<(string Node, string Thing), int> SnapshotOccupied(School school, string exceptId)
|
||||
{
|
||||
var occupied = new Dictionary<(string Node, string Thing), int>();
|
||||
@@ -597,7 +705,8 @@ internal static class PresenceSystem
|
||||
person.ClassId,
|
||||
TalkCircles.HasPhone(person.Items),
|
||||
friendPull,
|
||||
school.Catalog?.BehaviorRules);
|
||||
school.Catalog?.BehaviorRules,
|
||||
person.BullyVictimId);
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> SnapshotPersonNodes(School school)
|
||||
|
||||
Reference in New Issue
Block a user