diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs index 4cbe92a844..986a20422f 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs @@ -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); diff --git a/Content.Server/_CP14/GameTicking/Rules/CP14ExpeditionObjectivesRule.cs b/Content.Server/_CP14/GameTicking/Rules/CP14ExpeditionObjectivesRule.cs new file mode 100644 index 0000000000..9d8bc646d0 --- /dev/null +++ b/Content.Server/_CP14/GameTicking/Rules/CP14ExpeditionObjectivesRule.cs @@ -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 +{ + [Dependency] private readonly MindSystem _mind = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnPlayerSpawning); + } + + private void OnPlayerSpawning(PlayerSpawnCompleteEvent args) + { + var query = EntityQueryEnumerator(); + 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); + } + } + } +} diff --git a/Content.Server/_CP14/GameTicking/Rules/Components/CP14ExpeditionObjectivesRuleComponent.cs b/Content.Server/_CP14/GameTicking/Rules/Components/CP14ExpeditionObjectivesRuleComponent.cs new file mode 100644 index 0000000000..aea613c194 --- /dev/null +++ b/Content.Server/_CP14/GameTicking/Rules/Components/CP14ExpeditionObjectivesRuleComponent.cs @@ -0,0 +1,14 @@ +using Content.Server.GameTicking.Rules; +using Robust.Shared.Prototypes; + +namespace Content.Server._CP14.GameTicking.Rules.Components; + +/// +/// A rule issuing a common goal for all expedition participants +/// +[RegisterComponent, Access(typeof(CP14ExpeditionObjectivesRule))] +public sealed partial class CP14ExpeditionObjectivesRuleComponent : Component +{ + [DataField] + public List Objectives = new(); +} diff --git a/Content.Server/_CP14/Objectives/Components/CP14ExpeditionCollectConditionComponent.cs b/Content.Server/_CP14/Objectives/Components/CP14ExpeditionCollectConditionComponent.cs new file mode 100644 index 0000000000..0aec39305f --- /dev/null +++ b/Content.Server/_CP14/Objectives/Components/CP14ExpeditionCollectConditionComponent.cs @@ -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 CollectGroup; + + /// + /// When enabled, disables generation of this target if there is no entity on the map (disable for objects that can be created mid-round). + /// + [DataField] + public bool VerifyMapExistence = true; + + /// + /// The minimum number of items you need to steal to fulfill a objective + /// + [DataField] + public int MinCollectionSize = 1; + + /// + /// The maximum number of items you need to steal to fulfill a objective + /// + [DataField] + public int MaxCollectionSize = 1; + + /// + /// Target collection size after calculation + /// + [DataField] + public int CollectionSize; + + [DataField(required: true)] + public LocId ObjectiveText; + + [DataField(required: true)] + public LocId DescriptionText; + + [DataField(required: true)] + public LocId DescriptionMultiplyText; +} diff --git a/Content.Server/_CP14/Objectives/Systems/CP14ExpeditionCollectConditionSystem.cs b/Content.Server/_CP14/Objectives/Systems/CP14ExpeditionCollectConditionSystem.cs new file mode 100644 index 0000000000..53cf55f3d8 --- /dev/null +++ b/Content.Server/_CP14/Objectives/Systems/CP14ExpeditionCollectConditionSystem.cs @@ -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(OnAssigned); + SubscribeLocalEvent(OnAfterAssign); + SubscribeLocalEvent(OnGetProgress); + } + + private void OnAssigned(Entity condition, ref ObjectiveAssignedEvent args) + { + List targetList = new(); + + var query = AllEntityQuery(); + 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 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 condition, ref ObjectiveGetProgressEvent args) + { + var count = 0; + + if (!_cp14Expedition.TryGetExpeditionShip(out var ship)) + return; + + var query = EntityQueryEnumerator(); + 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(entity, out var target)) + return false; + + if (target.StealGroup != condition.CollectGroup) + return false; + + return true; + } +} diff --git a/Content.Server/_CP14/Shuttles/CP14ExpeditionSystem.cs b/Content.Server/_CP14/Shuttles/CP14ExpeditionSystem.cs index fbf08181b3..306d072b40 100644 --- a/Content.Server/_CP14/Shuttles/CP14ExpeditionSystem.cs +++ b/Content.Server/_CP14/Shuttles/CP14ExpeditionSystem.cs @@ -38,6 +38,7 @@ public sealed class CP14ExpeditionSystem : EntitySystem SubscribeLocalEvent(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(); - while (arrivalsQuery.MoveNext(out uid, out _)) + while (arrivalsQuery.MoveNext(out var tempUid, out _)) { + uid = tempUid; return true; } diff --git a/Resources/Locale/en-US/_CP14/gameTicking/game-preserts.ftl b/Resources/Locale/en-US/_CP14/gameTicking/game-preserts.ftl index b3f8716be7..a3cb69bbb9 100644 --- a/Resources/Locale/en-US/_CP14/gameTicking/game-preserts.ftl +++ b/Resources/Locale/en-US/_CP14/gameTicking/game-preserts.ftl @@ -1,2 +1,2 @@ -cp14-playtest-name = Playtest arena -cp14-playtest-desc = Test game mechanics and features... until you die. \ No newline at end of file +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. \ No newline at end of file diff --git a/Resources/Locale/en-US/_CP14/objectives/condition/expedition.ftl b/Resources/Locale/en-US/_CP14/objectives/condition/expedition.ftl new file mode 100644 index 0000000000..aadf69c3b4 --- /dev/null +++ b/Resources/Locale/en-US/_CP14/objectives/condition/expedition.ftl @@ -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. \ No newline at end of file diff --git a/Resources/Locale/en-US/_CP14/objectives/condition/issuers.ftl b/Resources/Locale/en-US/_CP14/objectives/condition/issuers.ftl new file mode 100644 index 0000000000..8146b593eb --- /dev/null +++ b/Resources/Locale/en-US/_CP14/objectives/condition/issuers.ftl @@ -0,0 +1 @@ +objective-issuer-ExpeditionObjective = [color=#d6853a]Expedition Objective[/color] \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_CP14/gameTicking/game-preserts.ftl b/Resources/Locale/ru-RU/_CP14/gameTicking/game-preserts.ftl index ddd04a1c6c..a8758e813a 100644 --- a/Resources/Locale/ru-RU/_CP14/gameTicking/game-preserts.ftl +++ b/Resources/Locale/ru-RU/_CP14/gameTicking/game-preserts.ftl @@ -1,2 +1,2 @@ -cp14-playtest-name = Плейтест арена -cp14-playtest-desc = Тестируйте игровые механики и возможности... пока не умрете. \ No newline at end of file +cp14-gamepreset-resource-harvest = Сбор ресурсов +cp14-gamepreset-resource-harvest-desc = Ваша экспедиция была направлена в опасное место для сбора ценных природных ресурсов. Добудьте необходимые материалы, и возвращайтесь. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_CP14/objectives/condition/expedition.ftl b/Resources/Locale/ru-RU/_CP14/objectives/condition/expedition.ftl new file mode 100644 index 0000000000..31f933aa17 --- /dev/null +++ b/Resources/Locale/ru-RU/_CP14/objectives/condition/expedition.ftl @@ -0,0 +1,3 @@ +cp14-objective-expedition-collect-title = Добыть { $itemName } +cp14-objective-expedition-collect-desc = Ваша задача - добыть и доставить { $itemName } на Элементальный корабль. +cp14-objective-expedition-collect-multiply-desc = Ваша задача - добыть и доставить { $count } { $itemName } на Элементальный корабль. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_CP14/objectives/condition/issuers.ftl b/Resources/Locale/ru-RU/_CP14/objectives/condition/issuers.ftl new file mode 100644 index 0000000000..db0e261384 --- /dev/null +++ b/Resources/Locale/ru-RU/_CP14/objectives/condition/issuers.ftl @@ -0,0 +1 @@ +objective-issuer-ExpeditionObjective = [color=#d6853a]Цель экспедиции[/color] \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Objects/ores.yml b/Resources/Prototypes/_CP14/Entities/Objects/ores.yml index f5c92c28cd..5e63f234a6 100644 --- a/Resources/Prototypes/_CP14/Entities/Objects/ores.yml +++ b/Resources/Prototypes/_CP14/Entities/Objects/ores.yml @@ -59,4 +59,6 @@ sprite: _CP14/Objects/Ores/ore_gold.rsi layers: - state: ore1 - map: ["random"] \ No newline at end of file + map: ["random"] + - type: StealTarget + stealGroup: CP14Gold \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/GameRules/roundstart.yml b/Resources/Prototypes/_CP14/GameRules/roundstart.yml index e02ae4f5ab..d6a9f5cd1d 100644 --- a/Resources/Prototypes/_CP14/GameRules/roundstart.yml +++ b/Resources/Prototypes/_CP14/GameRules/roundstart.yml @@ -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 \ No newline at end of file + - type: CP14ExpeditionObjectivesRule + objectives: + - CP14ExpeditionCollectGoldObjective + # Expedition random objectives + # main objective + sub objective? + # motivations + # antags \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Objectives/expedition_objectives.yml b/Resources/Prototypes/_CP14/Objectives/expedition_objectives.yml new file mode 100644 index 0000000000..1869329027 --- /dev/null +++ b/Resources/Prototypes/_CP14/Objectives/expedition_objectives.yml @@ -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 \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Objectives/steal_target_groups.yml b/Resources/Prototypes/_CP14/Objectives/steal_target_groups.yml new file mode 100644 index 0000000000..8f98b2b895 --- /dev/null +++ b/Resources/Prototypes/_CP14/Objectives/steal_target_groups.yml @@ -0,0 +1,6 @@ +- type: stealTargetGroup + id: CP14Gold + name: gold ore + sprite: + sprite: _CP14/Objects/Ores/ore_gold.rsi + state: ore1 \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/game_presets.yml b/Resources/Prototypes/_CP14/game_presets.yml index 4dd1e6b9ef..20b5c7f5c0 100644 --- a/Resources/Prototypes/_CP14/game_presets.yml +++ b/Resources/Prototypes/_CP14/game_presets.yml @@ -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 \ No newline at end of file + - CP14ResourceHarvesting \ No newline at end of file diff --git a/Resources/Prototypes/secret_weights.yml b/Resources/Prototypes/secret_weights.yml index 55ca73569a..c55fc3754f 100644 --- a/Resources/Prototypes/secret_weights.yml +++ b/Resources/Prototypes/secret_weights.yml @@ -1,7 +1,7 @@ - type: weightedRandom id: Secret weights: - CP14Playtest: 1 + CP14ResourceHarvesting: 1 #Nukeops: 0.20 #Traitor: 0.60 #Zombie: 0.05