Expedition goals (#318)

* forgot this one

* disable dinosaurus

* expedition collect objective condition

* Update CP14ExpeditionSystem.cs

* add expedition objectives

* auto-issue of objectives to all expedition participants

* delete cp14playtest gamemode

* Update CP14ExpeditionObjectivesRule.cs
This commit is contained in:
Ed
2024-07-09 08:31:24 +03:00
committed by GitHub
parent f42546e0c6
commit ba03872c57
18 changed files with 272 additions and 20 deletions

View File

@@ -389,7 +389,7 @@ public sealed partial class ShuttleSystem
var uid = entity.Owner;
var comp = entity.Comp1;
var xform = _xformQuery.GetComponent(entity);
DoTheDinosaur(xform);
//DoTheDinosaur(xform); //CP14 without stunning
comp.State = FTLState.Travelling;
var fromMapUid = xform.MapUid;
@@ -475,7 +475,7 @@ public sealed partial class ShuttleSystem
var xform = _xformQuery.GetComponent(uid);
var body = _physicsQuery.GetComponent(uid);
var comp = entity.Comp1;
DoTheDinosaur(xform);
//DoTheDinosaur(xform); //CP14 without stunning
_dockSystem.SetDockBolts(entity, false);
_physics.SetLinearVelocity(uid, Vector2.Zero, body: body);

View File

@@ -0,0 +1,34 @@
using Content.Server._CP14.GameTicking.Rules.Components;
using Content.Server.Mind;
namespace Content.Server.GameTicking.Rules;
public sealed class CP14ExpeditionObjectivesRule : GameRuleSystem<CP14ExpeditionObjectivesRuleComponent>
{
[Dependency] private readonly MindSystem _mind = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(OnPlayerSpawning);
}
private void OnPlayerSpawning(PlayerSpawnCompleteEvent args)
{
var query = EntityQueryEnumerator<CP14ExpeditionObjectivesRuleComponent>();
while (query.MoveNext(out var uid, out var expedition))
{
if (!_mind.TryGetMind(args.Player.UserId, out var mindId, out var mind))
{
Log.Error($"{ToPrettyString(args.Mob):player} was trying to get the expedition objectives by {ToPrettyString(uid):rule} but had no mind attached!");
return;
}
foreach (var objective in expedition.Objectives)
{
_mind.TryAddObjective(mindId.Value, mind, objective);
}
}
}
}

View File

@@ -0,0 +1,14 @@
using Content.Server.GameTicking.Rules;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.GameTicking.Rules.Components;
/// <summary>
/// A rule issuing a common goal for all expedition participants
/// </summary>
[RegisterComponent, Access(typeof(CP14ExpeditionObjectivesRule))]
public sealed partial class CP14ExpeditionObjectivesRuleComponent : Component
{
[DataField]
public List<EntProtoId> Objectives = new();
}

View File

@@ -0,0 +1,45 @@
using Content.Server._CP14.Objectives.Systems;
using Content.Shared.Objectives;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Objectives.Components;
[RegisterComponent, Access(typeof(CP14ExpeditionCollectConditionSystem))]
public sealed partial class CP14ExpeditionCollectConditionComponent : Component
{
[DataField]
public ProtoId<StealTargetGroupPrototype> CollectGroup;
/// <summary>
/// When enabled, disables generation of this target if there is no entity on the map (disable for objects that can be created mid-round).
/// </summary>
[DataField]
public bool VerifyMapExistence = true;
/// <summary>
/// The minimum number of items you need to steal to fulfill a objective
/// </summary>
[DataField]
public int MinCollectionSize = 1;
/// <summary>
/// The maximum number of items you need to steal to fulfill a objective
/// </summary>
[DataField]
public int MaxCollectionSize = 1;
/// <summary>
/// Target collection size after calculation
/// </summary>
[DataField]
public int CollectionSize;
[DataField(required: true)]
public LocId ObjectiveText;
[DataField(required: true)]
public LocId DescriptionText;
[DataField(required: true)]
public LocId DescriptionMultiplyText;
}

View File

@@ -0,0 +1,108 @@
using Content.Server._CP14.Objectives.Components;
using Content.Server._CP14.Shuttles;
using Content.Server.Objectives.Components.Targets;
using Content.Shared.Objectives.Components;
using Content.Shared.Objectives.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server._CP14.Objectives.Systems;
public sealed class CP14ExpeditionCollectConditionSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly SharedObjectivesSystem _objectives = default!;
[Dependency] private readonly CP14ExpeditionSystem _cp14Expedition = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14ExpeditionCollectConditionComponent, ObjectiveAssignedEvent>(OnAssigned);
SubscribeLocalEvent<CP14ExpeditionCollectConditionComponent, ObjectiveAfterAssignEvent>(OnAfterAssign);
SubscribeLocalEvent<CP14ExpeditionCollectConditionComponent, ObjectiveGetProgressEvent>(OnGetProgress);
}
private void OnAssigned(Entity<CP14ExpeditionCollectConditionComponent> condition, ref ObjectiveAssignedEvent args)
{
List<StealTargetComponent?> targetList = new();
var query = AllEntityQuery<StealTargetComponent>();
while (query.MoveNext(out var target))
{
if (condition.Comp.CollectGroup != target.StealGroup)
continue;
targetList.Add(target);
}
// cancel if the required items do not exist
if (targetList.Count == 0 && condition.Comp.VerifyMapExistence)
{
args.Cancelled = true;
return;
}
//setup condition settings
var maxSize = condition.Comp.VerifyMapExistence
? Math.Min(targetList.Count, condition.Comp.MaxCollectionSize)
: condition.Comp.MaxCollectionSize;
var minSize = condition.Comp.VerifyMapExistence
? Math.Min(targetList.Count, condition.Comp.MinCollectionSize)
: condition.Comp.MinCollectionSize;
condition.Comp.CollectionSize = _random.Next(minSize, maxSize);
}
//Set the visual, name, icon for the objective.
private void OnAfterAssign(Entity<CP14ExpeditionCollectConditionComponent> condition, ref ObjectiveAfterAssignEvent args)
{
var group = _proto.Index(condition.Comp.CollectGroup);
var title = Loc.GetString(condition.Comp.ObjectiveText, ("itemName", group.Name));
var description = condition.Comp.CollectionSize > 1
? Loc.GetString(condition.Comp.DescriptionMultiplyText, ("itemName", group.Name), ("count", condition.Comp.CollectionSize))
: Loc.GetString(condition.Comp.DescriptionText, ("itemName", group.Name));
_metaData.SetEntityName(condition.Owner, title, args.Meta);
_metaData.SetEntityDescription(condition.Owner, description, args.Meta);
_objectives.SetIcon(condition.Owner, group.Sprite, args.Objective);
}
private void OnGetProgress(Entity<CP14ExpeditionCollectConditionComponent> condition, ref ObjectiveGetProgressEvent args)
{
var count = 0;
if (!_cp14Expedition.TryGetExpeditionShip(out var ship))
return;
var query = EntityQueryEnumerator<StealTargetComponent>();
while (query.MoveNext(out var uid, out _))
{
if (Transform(uid).GridUid != Transform(ship!.Value).GridUid)
continue;
if (CheckStealTarget(uid, condition))
count++;
}
var result = count / (float) condition.Comp.CollectionSize;
result = Math.Clamp(result, 0, 1);
args.Progress = result;
}
private bool CheckStealTarget(EntityUid entity, CP14ExpeditionCollectConditionComponent condition)
{
// check if this is the target
if (!TryComp<StealTargetComponent>(entity, out var target))
return false;
if (target.StealGroup != condition.CollectGroup)
return false;
return true;
}
}

View File

@@ -38,6 +38,7 @@ public sealed class CP14ExpeditionSystem : EntitySystem
SubscribeLocalEvent<CP14StationExpeditionTargetComponent, FTLCompletedEvent>(OnArrivalsDocked);
ArrivalTime = _cfgManager.GetCVar(CCVars.CP14ExpeditionArrivalTime);
_cfgManager.OnValueChanged(CCVars.CP14ExpeditionArrivalTime, time => ArrivalTime = time, true);
}
@@ -80,12 +81,14 @@ public sealed class CP14ExpeditionSystem : EntitySystem
//Some announsement logic?
}
private bool TryGetExpeditionShip(out EntityUid uid)
public bool TryGetExpeditionShip(out EntityUid? uid)
{
uid = null;
var arrivalsQuery = EntityQueryEnumerator<CP14ExpeditionShipComponent>();
while (arrivalsQuery.MoveNext(out uid, out _))
while (arrivalsQuery.MoveNext(out var tempUid, out _))
{
uid = tempUid;
return true;
}

View File

@@ -1,2 +1,2 @@
cp14-playtest-name = Playtest arena
cp14-playtest-desc = Test game mechanics and features... until you die.
cp14-gamepreset-resource-harvest = Resource Collection
cp14-gamepreset-resource-harvest-desc = Your expedition has been sent to a dangerous place to collect valuable natural resources. Get the necessary materials and return.

View File

@@ -0,0 +1,3 @@
cp14-objective-expedition-collect-title = Collect { $itemName }
cp14-objective-expedition-collect-desc = Your objective is to collect and deliver { $itemName } to the Elemental Ship.
cp14-objective-expedition-collect-multiply-desc = Your objective is to collect and deliver { $count } { $itemName } to the Elemental ship.

View File

@@ -0,0 +1 @@
objective-issuer-ExpeditionObjective = [color=#d6853a]Expedition Objective[/color]

View File

@@ -1,2 +1,2 @@
cp14-playtest-name = Плейтест арена
cp14-playtest-desc = Тестируйте игровые механики и возможности... пока не умрете.
cp14-gamepreset-resource-harvest = Сбор ресурсов
cp14-gamepreset-resource-harvest-desc = Ваша экспедиция была направлена в опасное место для сбора ценных природных ресурсов. Добудьте необходимые материалы, и возвращайтесь.

View File

@@ -0,0 +1,3 @@
cp14-objective-expedition-collect-title = Добыть { $itemName }
cp14-objective-expedition-collect-desc = Ваша задача - добыть и доставить { $itemName } на Элементальный корабль.
cp14-objective-expedition-collect-multiply-desc = Ваша задача - добыть и доставить { $count } { $itemName } на Элементальный корабль.

View File

@@ -0,0 +1 @@
objective-issuer-ExpeditionObjective = [color=#d6853a]Цель экспедиции[/color]

View File

@@ -59,4 +59,6 @@
sprite: _CP14/Objects/Ores/ore_gold.rsi
layers:
- state: ore1
map: ["random"]
map: ["random"]
- type: StealTarget
stealGroup: CP14Gold

View File

@@ -7,12 +7,14 @@
cP14Allowed: true
- type: entity
id: CP14Playtest
id: CP14ResourceHarvesting
parent: CP14BaseGameRule
noSpawn: true
components:
- type: RespawnDeadRule
- type: RespawnTracker
respawnDelay: 5
- type: KillCalloutRule
- type: PointManager
- type: CP14ExpeditionObjectivesRule
objectives:
- CP14ExpeditionCollectGoldObjective
# Expedition random objectives
# main objective + sub objective?
# motivations
# antags

View File

@@ -0,0 +1,30 @@
- type: entity
abstract: true
parent: BaseObjective
id: CP14BaseExpeditionObjective
components:
- type: Objective
issuer: ExpeditionObjective
- type: entity
abstract: true
parent: CP14BaseExpeditionObjective
id: CP14BaseExpeditionCollectObjective
components:
- type: Objective
- type: CP14ExpeditionCollectCondition
minCollectionSize: 5
maxCollectionSize: 10
objectiveText: cp14-objective-expedition-collect-title
descriptionText: cp14-objective-expedition-collect-desc
descriptionMultiplyText: cp14-objective-expedition-collect-multiply-desc
- type: entity
parent: CP14BaseExpeditionCollectObjective
id: CP14ExpeditionCollectGoldObjective
components:
- type: CP14ExpeditionCollectCondition
verifyMapExistence: false
collectGroup: CP14Gold
- type: Objective
difficulty: 1

View File

@@ -0,0 +1,6 @@
- type: stealTargetGroup
id: CP14Gold
name: gold ore
sprite:
sprite: _CP14/Objects/Ores/ore_gold.rsi
state: ore1

View File

@@ -1,8 +1,8 @@
- type: gamePreset
id: CP14Playtest
name: cp14-playtest-name
description: cp14-playtest-desc
id: CP14ResourceHarvesting
name: cp14-gamepreset-resource-harvest
description: cp14-gamepreset-resource-harvest-desc
showInVote: true
cP14Allowed: true
rules:
- CP14Playtest
- CP14ResourceHarvesting

View File

@@ -1,7 +1,7 @@
- type: weightedRandom
id: Secret
weights:
CP14Playtest: 1
CP14ResourceHarvesting: 1
#Nukeops: 0.20
#Traitor: 0.60
#Zombie: 0.05