Balance tweaks (#1741)

* disable lurker pulling

* fix pack

* fix pack

* fak pix

* vampire objective tweak

* buff vampire search

* Update air_saturation.yml

* fix

* fix

* Update EntityTest.cs

* Update EntityTest.cs

* tick

* Update EntityTest.cs

* remove forkfiltered filter

* Update EntityTest.cs
This commit is contained in:
Red
2025-09-07 14:22:30 +03:00
committed by GitHub
parent dd930f513c
commit ad46932d11
24 changed files with 132 additions and 61 deletions

View File

@@ -87,10 +87,6 @@ public sealed class CP14IdentityRecognitionBoundUserInterface : BoundUserInterfa
{
case CP14RememberNameUiState rememberNameUiState:
_rememberedTarget = rememberNameUiState.Target;
var currentName = CurrentName();
if (currentName is not null)
_window.SetCurrentLabel(currentName);
break;
}
}

View File

@@ -42,8 +42,10 @@ namespace Content.IntegrationTests.Tests
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Where(p => !p.Components.ContainsKey("RoomFill")) // This comp can delete all entities, and spawn others
.Where(p => !p.Components.ContainsKey("CP14BiomeSpawner")) // CP14 this component delete all entities on this tile
.Where(p => !p.Components.ContainsKey("CP14AreaEntityEffect")) // CP14 lightning detonates entities
//CP14
.Where(p => !p.Components.ContainsKey("CP14BiomeSpawner")) // this component delete all entities on this tile
.Where(p => !p.Components.ContainsKey("CP14AreaEntityEffect")) // lightning detonates entities
//CP14 end
.Select(p => p.ID)
.ToList();
@@ -58,7 +60,7 @@ namespace Content.IntegrationTests.Tests
}
});
await server.WaitRunTicks(15); // 15 seconds, enough to trigger most update loops //CP14 returned back to 15 ticks (operation was cancelled github issue)
await server.WaitRunTicks(15);
await server.WaitPost(() =>
{
@@ -107,8 +109,10 @@ namespace Content.IntegrationTests.Tests
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Where(p => !p.Components.ContainsKey("RoomFill")) // This comp can delete all entities, and spawn others
//CP14
.Where(p => !p.Components.ContainsKey("CP14BiomeSpawner")) // CP14 this component delete all entities on this tile
.Where(p => !p.Components.ContainsKey("CP14AreaEntityEffect")) // CP14 lightning detonates entities
//CP14 end
.Select(p => p.ID)
.ToList();
foreach (var protoId in protoIds)
@@ -116,7 +120,7 @@ namespace Content.IntegrationTests.Tests
entityMan.SpawnEntity(protoId, map.GridCoords);
}
});
await server.WaitRunTicks(15); // 15 seconds, enough to trigger most update loops //CP14 returned back to 15 ticks (operation was cancelled github issue)
await server.WaitRunTicks(15);
await server.WaitPost(() =>
{
static IEnumerable<(EntityUid, TComp)> Query<TComp>(IEntityManager entityMan)
@@ -169,6 +173,9 @@ namespace Content.IntegrationTests.Tests
.Where(p => !p.Abstract)
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
//CP14
.Where(p => !p.Components.ContainsKey("CP14VampireClanHeart")) //Spawn announcement sound entities on init
//CP14 end
.Select(p => p.ID)
.ToList();
@@ -248,6 +255,9 @@ namespace Content.IntegrationTests.Tests
// makes an announcement on mapInit.
"AnnounceOnSpawn",
//CP14
"CP14VampireClanHeart", //Also announce on spawn
//CP14 end
};
Assert.That(server.CfgMan.GetCVar(CVars.NetPVS), Is.False);
@@ -383,8 +393,6 @@ namespace Content.IntegrationTests.Tests
"DebugExceptionStartup",
"GridFill",
"RoomFill",
"CP14BiomeSpawner", // CP14 this component delete all entities on this tile
"CP14AreaEntityEffect", // CP14 lightning detonates entities
"Map", // We aren't testing a map entity in this test
"MapGrid",
"Broadphase",

View File

@@ -29,16 +29,16 @@ public sealed class CP14VampireRuleSystem : GameRuleSystem<CP14VampireRuleCompon
var aliveFactions = new HashSet<ProtoId<CP14VampireFactionPrototype>>();
var query = EntityQueryEnumerator<CP14VampireComponent, MobStateComponent>();
while (query.MoveNext(out var vampireUid, out var vampire, out var mobState))
var query = EntityQueryEnumerator<CP14VampireClanHeartComponent>();
while (query.MoveNext(out _, out var heart))
{
if (mobState.CurrentState != MobState.Alive)
if (heart.Faction is null)
continue;
if (vampire.Faction is null)
if (heart.Level < _condition.RequiredHeartLevel)
continue;
aliveFactions.Add(vampire.Faction.Value);
aliveFactions.Add(heart.Faction.Value);
}
args.AddLine($"[head=2][color=#ab1b3d]{Loc.GetString("cp14-vampire-clans-battle")}[/color][/head]");

View File

@@ -22,6 +22,7 @@ public sealed class CP14VampireObjectiveConditionsSystem : EntitySystem
[Dependency] private readonly IPrototypeManager _proto = default!;
public readonly float RequiredAlivePercentage = 0.5f;
public readonly int RequiredHeartLevel = 3;
public override void Initialize()
{
@@ -84,27 +85,37 @@ public sealed class CP14VampireObjectiveConditionsSystem : EntitySystem
ent.Comp.Faction = vampireComp.Faction;
_meta.SetEntityName(ent, Loc.GetString("cp14-objective-vampire-pure-bood-title"));
_meta.SetEntityDescription(ent, Loc.GetString("cp14-objective-vampire-pure-bood-desc"));
_meta.SetEntityName(ent, Loc.GetString("cp14-objective-vampire-pure-blood-title"));
_meta.SetEntityDescription(ent, Loc.GetString("cp14-objective-vampire-pure-blood-desc"));
_objectives.SetIcon(ent, ent.Comp.Icon);
}
private void OnBloodPurityGetProgress(Entity<CP14VampireBloodPurityConditionComponent> ent, ref ObjectiveGetProgressEvent args)
{
var query = EntityQueryEnumerator<CP14VampireComponent, MobStateComponent>();
var query = EntityQueryEnumerator<CP14VampireClanHeartComponent>();
while (query.MoveNext(out var uid, out var vampire, out var mobState))
var ourHeartReady = false;
var othersHeartsExist = false;
while (query.MoveNext(out var uid, out var vampire))
{
if (vampire.Faction != ent.Comp.Faction)
{
if (mobState.CurrentState == MobState.Dead)
continue;
if (vampire.Faction == ent.Comp.Faction && vampire.Level >= RequiredHeartLevel)
ourHeartReady = true;
args.Progress = 0f;
return;
if (vampire.Faction != ent.Comp.Faction && vampire.Level >= RequiredHeartLevel)
{
othersHeartsExist = true;
break;
}
}
args.Progress = 1f;
var progress = 0f;
if (ourHeartReady)
progress += 0.5f;
if (!othersHeartsExist)
progress += 0.5f;
args.Progress = progress;
}
}

View File

@@ -125,6 +125,13 @@ public sealed partial class CP14RoundEndSystem
sender: "Server"
);
}),
(22, 0, () =>
{
if (!ruDays)
return;
_consoleHost.ExecuteCommand("endround");
}),
(22, 2, () =>
{
if (!ruDays)
@@ -143,6 +150,13 @@ public sealed partial class CP14RoundEndSystem
sender: "Server"
);
}),
(23, 58, () =>
{
if (ruDays)
return;
_consoleHost.ExecuteCommand("endround");
}),
(23, 59, () =>
{
if (ruDays)

View File

@@ -1,11 +1,8 @@
using System.Text;
using Content.Server.Administration.Managers;
using Content.Server.Chat.Systems;
using Content.Shared._CP14.Vampire;
using Content.Shared._CP14.Vampire.Components;
using Content.Shared.Damage;
using Content.Shared.Destructible;
using Content.Shared.Examine;
using Content.Shared.Ghost;
using Robust.Shared.Audio;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
@@ -16,13 +13,26 @@ public sealed partial class CP14VampireSystem
{
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly IAdminManager _admin = default!;
private void InitializeAnnounces()
{
SubscribeLocalEvent<CP14VampireClanHeartComponent, MapInitEvent>(OnHeartCreate);
SubscribeLocalEvent<CP14VampireClanHeartComponent, DamageChangedEvent>(OnHeartDamaged);
SubscribeLocalEvent<CP14VampireClanHeartComponent, ComponentRemove>(OnHeartDestructed);
}
private void OnHeartCreate(Entity<CP14VampireClanHeartComponent> ent, ref MapInitEvent args)
{
if (ent.Comp.Faction is null)
return;
if (!Proto.TryIndex(ent.Comp.Faction, out var indexedFaction))
return;
AnnounceToFaction(ent.Comp.Faction.Value, Loc.GetString("cp14-vampire-tree-created", ("name", Loc.GetString(indexedFaction.Name))));
AnnounceToOpposingFactions(ent.Comp.Faction.Value, Loc.GetString("cp14-vampire-tree-created", ("name", Loc.GetString(indexedFaction.Name))));
}
private void OnHeartDamaged(Entity<CP14VampireClanHeartComponent> ent, ref DamageChangedEvent args)
{
@@ -84,6 +94,8 @@ public sealed partial class CP14VampireSystem
filter.AddPlayer(actor.PlayerSession);
}
filter.AddPlayers(_admin.ActiveAdmins);
if (filter.Count == 0)
return;

View File

@@ -170,7 +170,7 @@ public sealed partial class CP14VampireSystem : CP14SharedVampireSystem
heart.NextRegenTime = _timing.CurTime + heart.RegenFrequency;
AddEssence((uid, heart), heart.EssenceRegenPerLevel * heart.Level);
AddEssence((uid, heart), heart.EssenceRegen);
}
}
}

View File

@@ -1,9 +1,9 @@
using Content.Shared.Examine;
using Content.Shared.Ghost;
using Content.Shared.IdentityManagement;
using Content.Shared.IdentityManagement.Components;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Popups;
using Content.Shared.Verbs;
using Robust.Shared.Player;
using Robust.Shared.Serialization;
@@ -15,7 +15,7 @@ public abstract class CP14SharedIdentityRecognitionSystem : EntitySystem
{
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly SharedIdentitySystem _identity = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
@@ -68,11 +68,17 @@ public abstract class CP14SharedIdentityRecognitionSystem : EntitySystem
Priority = 2,
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/sentient.svg.192dpi.png")),
Text = Loc.GetString("cp14-remember-name-verb"),
Disabled = seeAttemptEv.Cancelled,
Act = () =>
{
_uiSystem.SetUiState(_args.User, CP14RememberNameUiKey.Key, new CP14RememberNameUiState(GetNetEntity(ent)));
_uiSystem.TryToggleUi(_args.User, CP14RememberNameUiKey.Key, actor.PlayerSession);
if (seeAttemptEv.Cancelled)
{
_popup.PopupClient(Loc.GetString("cp14-remember-fail-mask"), _args.Target, _args.User);
}
else
{
_uiSystem.SetUiState(_args.User, CP14RememberNameUiKey.Key, new CP14RememberNameUiState(GetNetEntity(ent)));
_uiSystem.TryToggleUi(_args.User, CP14RememberNameUiKey.Key, actor.PlayerSession);
}
},
};
args.Verbs.Add(verb);

View File

@@ -63,5 +63,29 @@ public sealed partial class CP14SpellPointerToVampireClan : CP14SpellEffect
transform.SetWorldRotation(pointer, angle + Angle.FromDegrees(90));
}
var heartsInRange = lookup.GetEntitiesInRange<CP14VampireClanHeartComponent>(originEntPosition, SearchRange);
foreach (var heart in heartsInRange)
{
if (!Inversed)
{
if (heart.Comp.Faction != vampireComponent.Faction)
continue;
}
else
{
if (heart.Comp.Faction == vampireComponent.Faction)
continue;
}
var targetPosition = transform.GetWorldPosition(heart);
//Calculate the rotation
Angle angle = new(targetPosition - originPosition);
var pointer = entManager.Spawn(PointerEntity, new MapCoordinates(originPosition, transform.GetMapId(originEntPosition)));
transform.SetWorldRotation(pointer, angle + Angle.FromDegrees(90));
}
}
}

View File

@@ -44,8 +44,7 @@ public sealed partial class CP14SpellTeleportToVampireSingleton : CP14SpellEffec
if (singleton.Key != indexedVampireFaction.SingletonTeleportKey)
continue;
var randomOffset = new Vector2(random.Next(-1, 1), random.Next(-1, 1));
var second = entManager.SpawnAtPosition(PortalProto, xform.Coordinates.Offset(randomOffset));
var second = entManager.SpawnAtPosition(PortalProto, xform.Coordinates);
linkSys.TryLink(first, second, true);
return;

View File

@@ -54,7 +54,7 @@ public abstract partial class CP14SharedTradingPlatformSystem : EntitySystem
var repComp = EnsureComp<CP14TradingReputationComponent>(args.User);
repComp.Reputation.TryAdd(ent.Comp.Faction, 0);
_audio.PlayLocal(new SoundCollectionSpecifier("CP14CoinImpact"), args.User, args.User);
_popup.PopupPredicted(Loc.GetString("cp14-trading-contract-use", ("name", Loc.GetString(indexedFaction.Name))), args.User, args.User);
_popup.PopupClient(Loc.GetString("cp14-trading-contract-use", ("name", Loc.GetString(indexedFaction.Name))), args.User, args.User);
if (_net.IsServer)
QueueDel(ent);

View File

@@ -32,7 +32,7 @@ public sealed partial class CP14VampireClanHeartComponent : Component
public FixedPoint2 Level4 = 21f;
[DataField]
public FixedPoint2 EssenceRegenPerLevel = 0.1f;
public FixedPoint2 EssenceRegen = 0.2f;
[DataField]
public TimeSpan RegenFrequency = TimeSpan.FromMinutes(1);

View File

@@ -2,4 +2,5 @@ cp14-remember-name-verb = Remember name
cp14-remember-name-name = Name
cp14-remember-name-examine = You remember this character as [color=yellow]{$name}[/color]
cp14-remember-name-examine = You remember this character as [color=yellow]{$name}[/color]
cp14-remember-fail-mask = You cannot remember those who hide their faces.

View File

@@ -1,7 +1,7 @@
cp14-objective-issuer-vampire = [color="#c20034"]Vampire clan[/color]
cp14-objective-vampire-pure-bood-title = Expel foreign vampire clans
cp14-objective-vampire-pure-bood-desc = Intruders from other vampire clans are hiding among the residents. Eliminate them so that the settlement belongs only to you.
cp14-objective-vampire-pure-blood-title = Expel foreign vampire clans
cp14-objective-vampire-pure-blood-desc = Build your clan's heart to at least level 3, and don't let other clans do it. Only your clan's heart should exist!
cp14-objective-vampire-defence-settlement-title = Keep your property
cp14-objective-vampire-defence-settlement-desc = The inhabitants of this city are your property and your food. Don't let them die. At least {$count}% of the inhabitants must survive.

View File

@@ -25,6 +25,7 @@ cp14-vampire-gather-essence-no-left = Здесь больше нет эссен
cp14-vampire-sender = Vampire instinct
cp14-vampire-tree-created = The heart of the “{$name}” clan has been created!
cp14-vampire-tree-growing = "{$name}" clan heart grows to level {$level}!
cp14-vampire-tree-growing-self = Your clan heart grows to level {$level}!
cp14-vampire-tree-damaged = Your clan's heart has been attacked!

View File

@@ -2,4 +2,5 @@ cp14-remember-name-verb = Запомнить имя
cp14-remember-name-name = Имя
cp14-remember-name-examine = Вы помните этого персонажа как [color=yellow]{$name}[/color]
cp14-remember-name-examine = Вы помните этого персонажа как [color=yellow]{$name}[/color]
cp14-remember-fail-mask = Вы не можете запомнить тех, кто скрывает свое лицо.

View File

@@ -1,7 +1,7 @@
cp14-objective-issuer-vampire = [color="#c20034"]Клан вампиров[/color]
cp14-objective-vampire-pure-bood-title = Изгнать чужие вампирские кланы
cp14-objective-vampire-pure-bood-desc = Чужаки из других вампирских кланов скрываются среди жителей. Уничтожьте их, чтобы поселение принадлежало только вам.
cp14-objective-vampire-pure-blood-title = Стать правителем этих земель
cp14-objective-vampire-pure-blood-desc = Постройте сердце своего клана минимум 3 уровня, и не позвольте это сделать другим кланам. Только сердце вашего клана должно существовать!
cp14-objective-vampire-defence-settlement-title = Сохранить своё имущество
cp14-objective-vampire-defence-settlement-desc = Жители этого города - ваше имущество и ваша еда. Не позвольте им умереть. Как минимум {$count}% жителей должны выжить.

View File

@@ -25,6 +25,7 @@ cp14-vampire-gather-essence-no-left = There is no more essence here!
cp14-vampire-sender = Вампирское чутье
cp14-vampire-tree-created = Создано сердце клана "{$name}"!
cp14-vampire-tree-growing = Сердце клана "{$name}" вырастает до {$level} уровня!
cp14-vampire-tree-growing-self = Ваше сердце клана вырастает до {$level} уровня!
cp14-vampire-tree-damaged = Ваше сердце клана атаковано!

View File

@@ -5,6 +5,8 @@
components:
- type: StorageFill
contents:
- id: CP14WeaponDaggerSickle
amount: 2
- id: CP14HandLabeler
- id: CP14Lighter
- id: CP14ManaOperationGlove
@@ -17,23 +19,16 @@
amount: 1
- id: CP14Dropper
amount: 1
- id: CP14VialTinyReinforced
amount: 1
- id: CP14VialTiny
amount: 3
- id: CP14VialSmallReinforced
amount: 1
- id: CP14VialSmall
amount: 3
- id: CP14VialSkullReinforced
prob: 0.3
- id: CP14VialSkull
prob: 0.5
- id: CP14PaperFolderBlue
- id: CP14PenFeather
amount: 1
- id: CP14WoodenPlanks20
#Random start resource
- id: CP14VialMediumEarthEssence
- id: CP14VialMediumFireEssence
- id: CP14VialMediumWaterEssence
@@ -106,16 +101,20 @@
components:
- type: StorageFill
contents:
- id: CP14WeaponFork
amount: 2
- id: CP14Fork
amount: 2
- id: CP14Spoon
amount: 2
- id: CP14WeaponDaggerHatchet
amount: 2
- id: CP14FryingPan
- id: CP14CookingPot
- id: CP14SackFarmingSeed
- id: CP14PlateWooden
amount: 2
- id: CP14BowlWooden
amount: 2
- id: CP14BookTieflingGambit
- id: CP14GuidebookCooking
- id: CP14SackFarmingSeedFull

View File

@@ -18,7 +18,7 @@
- !type:HealthChange
damage:
types:
Asphyxiation: -2
Asphyxiation: -5
- !type:Jitter
- type: CP14MagicEffectCastingVisual
proto: CP14RuneAirSaturation

View File

@@ -20,7 +20,7 @@
- !type:CP14SpellApplyEntityEffect
effects:
- !type:CP14ManaChange
manaDelta: -15
manaDelta: -5
safe: false
- type: CP14MagicEffectCastingVisual
proto: CP14RuneMagicSplitting

View File

@@ -29,7 +29,7 @@
parent: CP14ActionSpellBloodConnection
id: CP14ActionSpellBloodEnemySearch
name: Blood identification
description: You are searching within a large radius for all vampires from other factions.
description: You are searching within a large radius for all vampires from other factions and their clan hearts.
components:
- type: CP14MagicEffect
effects:

View File

@@ -81,8 +81,6 @@
- id: CP14ClothingMaskBoneHornedMask
amount: 1
- type: FloorOcclusion
- type: Puller
needsHands: false
- type: GhostTakeoverAvailable
- type: TypingIndicator
proto: alien

View File

@@ -238,7 +238,7 @@
- type: cp14Skill
id: BloodEnemySearch
skillUiPosition: 10, 10
skillUiPosition: 6, 10
learnCost: 1
tree: Vampire
icon:
@@ -251,7 +251,7 @@
- !type:NeedPrerequisite
prerequisite: BloodConnection
- !type:VampireClanLevel
level: 3
level: 2
- type: cp14Skill
id: PortalToVampireHome