Blood moon (#1270)

* some setup

* fix dayccle events, add basic gamerules

* carcat guidebook update

* pfpf

* wawa

* fnish
This commit is contained in:
Ed
2025-05-15 17:32:26 +03:00
committed by GitHub
parent 26e4088cdd
commit e0a4f5592f
28 changed files with 444 additions and 75 deletions

View File

@@ -64,7 +64,7 @@ public sealed partial class ChatSystem : SharedChatSystem
public const int VoiceRange = 10; // how far voice goes in world units
public const int WhisperClearRange = 2; // how far whisper goes while still being understandable, in world units
public const int WhisperMuffledRange = 5; // how far whisper goes at all, in world units
public const string DefaultAnnouncementSound = "/Audio/Announcements/announce.ogg";
public const string DefaultAnnouncementSound = "/Audio/_CP14/Ambience/event_boom.ogg"; //CP14 replaced default sound
private bool _loocEnabled = true;
private bool _deadLoocEnabled;

View File

@@ -42,6 +42,7 @@ public sealed class DiscordAuthManager
"1294276016117911594",
"1278755078315970620",
"1330772249644630157",
"1274951101464051846",
};
public event EventHandler<ICommonSession>? PlayerVerified;

View File

@@ -0,0 +1,92 @@
using Content.Server._CP14.GameTicking.Rules.Components;
using Content.Server.Antag;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking.Rules;
using Content.Server.Popups;
using Content.Server.Station.Components;
using Content.Server.Stunnable;
using Content.Shared._CP14.BloodMoon;
using Content.Shared._CP14.DayCycle;
using Content.Shared.Examine;
using Content.Shared.GameTicking.Components;
using Content.Shared.Popups;
using Content.Shared.Station.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
namespace Content.Server._CP14.GameTicking.Rules;
public sealed class CP14BloodMoonCurseRule : GameRuleSystem<CP14BloodMoonCurseRuleComponent>
{
[Dependency] private readonly AntagSelectionSystem _antag = default!;
[Dependency] private readonly StunSystem _stun = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly TransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14StartDayEvent>(OnStartDay);
SubscribeLocalEvent<CP14BloodMoonCurseRuleComponent, AfterAntagEntitySelectedEvent>(AfterAntagEntitySelected);
SubscribeLocalEvent<CP14BloodMoonCurseComponent, ExaminedEvent>(CurseExamined);
}
private void CurseExamined(Entity<CP14BloodMoonCurseComponent> ent, ref ExaminedEvent args)
{
args.PushMarkup(Loc.GetString("cp14-bloodmoon-curse-examined"));
}
private void AfterAntagEntitySelected(Entity<CP14BloodMoonCurseRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
{
SpawnAttachedTo(ent.Comp.CurseEffect, Transform(args.EntityUid).Coordinates);
var curseComp = EnsureComp<CP14BloodMoonCurseComponent>(args.EntityUid);
var effect = SpawnAttachedTo(curseComp.CurseEffect, Transform(args.EntityUid).Coordinates);
curseComp.SpawnedEffect = effect;
_transform.SetParent(effect, args.EntityUid);
}
protected override void Started(EntityUid uid,
CP14BloodMoonCurseRuleComponent component,
GameRuleComponent gameRule,
GameRuleStartedEvent args)
{
Filter allPlayersInGame = Filter.Empty().AddWhere(GameTicker.UserHasJoinedGame);
_chatSystem.DispatchFilteredAnnouncement(allPlayersInGame, Loc.GetString(component.StartAnnouncement), colorOverride: component.AnnouncementColor);
}
protected override void Ended(EntityUid uid,
CP14BloodMoonCurseRuleComponent component,
GameRuleComponent gameRule,
GameRuleEndedEvent args)
{
Filter allPlayersInGame = Filter.Empty().AddWhere(GameTicker.UserHasJoinedGame);
_chatSystem.DispatchFilteredAnnouncement(allPlayersInGame, Loc.GetString(component.EndAnnouncement), colorOverride: component.AnnouncementColor);
var aliveAntags = _antag.GetAliveAntags(uid);
foreach (var antag in aliveAntags)
{
_stun.TryParalyze(antag, component.EndStunDuration, true);
_popup.PopupEntity(Loc.GetString("cp14-bloodmoon-curse-removed"), antag, PopupType.SmallCaution);
SpawnAttachedTo(component.CurseEffect, Transform(antag).Coordinates);
if (TryComp<CP14BloodMoonCurseComponent>(antag, out var curseComp))
{
QueueDel(curseComp.SpawnedEffect);
RemCompDeferred<CP14BloodMoonCurseComponent>(antag);
}
}
GameTicker.EndRound();
}
private void OnStartDay(CP14StartDayEvent ev)
{
var query = QueryActiveRules();
while (query.MoveNext(out var uid, out _, out var comp, out _))
{
if (HasComp<BecomesStationComponent>(ev.Map) || HasComp<StationMemberComponent>(ev.Map))
ForceEndSelf(uid);
}
}
}

View File

@@ -0,0 +1,48 @@
using Content.Server._CP14.GameTicking.Rules.Components;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking.Rules;
using Content.Shared._CP14.DayCycle;
using Robust.Shared.Player;
namespace Content.Server._CP14.GameTicking.Rules;
public sealed class CP14BloodMoonRule : GameRuleSystem<CP14BloodMoonRuleComponent>
{
[Dependency] private readonly ChatSystem _chatSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14StartDayEvent>(OnStartDay);
SubscribeLocalEvent<CP14StartNightEvent>(OnStartNight);
}
private void OnStartDay(CP14StartDayEvent ev)
{
var query = QueryActiveRules();
while (query.MoveNext(out var uid, out _, out var comp, out _))
{
if (!comp.Announced)
{
comp.Announced = true;
Filter allPlayersInGame = Filter.Empty().AddWhere(GameTicker.UserHasJoinedGame);
_chatSystem.DispatchFilteredAnnouncement(allPlayersInGame, Loc.GetString(comp.StartAnnouncement), playSound: false, sender: Loc.GetString("cp14-announcement-gamemaster"), colorOverride: comp.AnnouncementColor);
}
}
}
private void OnStartNight(CP14StartNightEvent ev)
{
var query = QueryActiveRules();
while (query.MoveNext(out var uid, out _, out var comp, out _))
{
if (!comp.Announced)
continue;
GameTicker.AddGameRule(comp.CurseRule);
ForceEndSelf(uid);
}
}
}

View File

@@ -0,0 +1,22 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.GameTicking.Rules.Components;
[RegisterComponent, Access(typeof(CP14BloodMoonCurseRule))]
public sealed partial class CP14BloodMoonCurseRuleComponent : Component
{
[DataField]
public LocId StartAnnouncement = "cp14-bloodmoon-start";
[DataField]
public LocId EndAnnouncement = "cp14-bloodmoon-end";
[DataField]
public Color? AnnouncementColor;
[DataField]
public TimeSpan EndStunDuration = TimeSpan.FromSeconds(60f);
[DataField]
public EntProtoId CurseEffect = "CP14ImpactEffectMagicSplitting";
}

View File

@@ -0,0 +1,19 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.GameTicking.Rules.Components;
[RegisterComponent, Access(typeof(CP14BloodMoonRule))]
public sealed partial class CP14BloodMoonRuleComponent : Component
{
[DataField]
public EntProtoId CurseRule = "CP14BloodMoonCurseRule";
[DataField]
public bool Announced = false;
[DataField]
public LocId StartAnnouncement = "cp14-bloodmoon-raising";
[DataField]
public Color? AnnouncementColor = Color.FromHex("#e32759");
}

View File

@@ -1,3 +1,4 @@
using Content.Shared._CP14.DayCycle;
using Content.Shared.Light.Components;
using Robust.Shared.Map.Components;
@@ -14,6 +15,10 @@ public abstract class SharedLightCycleSystem : EntitySystem
protected virtual void OnCycleMapInit(Entity<LightCycleComponent> ent, ref MapInitEvent args)
{
//CP14DayCycleSystem
EnsureComp<CP14DayCycleComponent>(ent);
//CP14DayCycleSystem end
if (TryComp(ent.Owner, out MapLightComponent? mapLight))
{
ent.Comp.OriginalColor = mapLight.AmbientLightColor;

View File

@@ -0,0 +1,15 @@
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.BloodMoon;
[RegisterComponent, NetworkedComponent]
public sealed partial class CP14BloodMoonCurseComponent : Component
{
[DataField]
public EntProtoId CurseEffect = "CP14BloodMoonCurseEffect";
[DataField]
public EntityUid? SpawnedEffect;
}

View File

@@ -4,8 +4,8 @@ namespace Content.Shared._CP14.DayCycle;
[RegisterComponent]
public sealed partial class CP14DayCycleComponent : Component
{
public double LastLightLevel = 0f;
public float LastLightLevel = 0f;
[DataField]
public double Threshold = 0.5f;
public float Threshold = 0.6f;
}

View File

@@ -41,30 +41,42 @@ public sealed class CP14DayCycleSystem : EntitySystem
var oldLightLevel = dayCycle.LastLightLevel;
var newLightLevel = GetLightLevel((uid, lightCycle));
dayCycle.LastLightLevel = newLightLevel;
// Going into darkness
if (oldLightLevel < newLightLevel && oldLightLevel > dayCycle.Threshold && newLightLevel < dayCycle.Threshold)
if (oldLightLevel > newLightLevel)
{
var ev = new CP14StartNightEvent(map.MapId);
RaiseLocalEvent(uid, ref ev, true);
if (oldLightLevel > dayCycle.Threshold)
{
if (newLightLevel < dayCycle.Threshold)
{
var ev = new CP14StartNightEvent(uid);
RaiseLocalEvent(ev);
}
}
}
// Going into light
if (oldLightLevel > newLightLevel && oldLightLevel < dayCycle.Threshold && newLightLevel > dayCycle.Threshold)
if (oldLightLevel < newLightLevel)
{
var ev = new CP14StartDayEvent(map.MapId);
RaiseLocalEvent(uid, ref ev, true);
if (oldLightLevel < dayCycle.Threshold)
{
if (newLightLevel > dayCycle.Threshold)
{
var ev = new CP14StartDayEvent(uid);
RaiseLocalEvent(ev);
}
}
}
dayCycle.LastLightLevel = newLightLevel;
}
}
public double GetLightLevel(Entity<LightCycleComponent?> map)
public float GetLightLevel(Entity<LightCycleComponent?> map)
{
if (!Resolve(map.Owner, ref map.Comp, false))
return 0;
var time = (float) _timing.CurTime
var time = (float)_timing.CurTime
.Add(map.Comp.Offset)
.Subtract(_ticker.RoundStartTimeSpan)
.Subtract(_metaData.GetPauseTime(map))
@@ -72,7 +84,7 @@ public sealed class CP14DayCycleSystem : EntitySystem
var normalizedTime = time % map.Comp.Duration.TotalSeconds;
var lightLevel = Math.Sin((normalizedTime / map.Comp.Duration.TotalSeconds) * MathF.PI);
return lightLevel;
return (float)lightLevel;
}
/// <summary>
@@ -98,21 +110,21 @@ public sealed class CP14DayCycleSystem : EntitySystem
if (!_mapGridQuery.TryComp(grid, out var gridComp))
return day;
if (!_weather.CanWeatherAffect(grid.Value, gridComp, _maps.GetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates)))
if (!_weather.CanWeatherAffect(grid.Value,
gridComp,
_maps.GetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates)))
return false;
return day;
}
}
[ByRefEvent]
public record struct CP14StartNightEvent(MapId Map)
public sealed class CP14StartNightEvent(EntityUid map) : EntityEventArgs
{
public readonly MapId Map = Map;
public EntityUid? Map = map;
}
[ByRefEvent]
public record struct CP14StartDayEvent(MapId Map)
public sealed class CP14StartDayEvent(EntityUid map) : EntityEventArgs
{
public readonly MapId Map = Map;
public EntityUid? Map = map;
}

View File

@@ -1,3 +1,7 @@
cp14-roles-antag-vampire-name = Vampire
cp14-roles-antag-vampire-objective = You are a parasite on the body of society, hated by those around you, burned by the sun, and eternally hungry. You need to feed on the blood of the sentient to survive. And finding those who will volunteer to be your feeder is not easy...
cp14-roles-antag-vampire-briefing = You are a parasite on society. It hates and fears you, but the blood of the living is your only food. Nature destroys you with sunlight, so you have to hide in the shadows. It's like the whole world is trying to destroy you, but your will to live is stronger than all of that. SURVIVE. That's all you have to do.
cp14-roles-antag-vampire-briefing = You are a parasite on society. It hates and fears you, but the blood of the living is your only food. Nature destroys you with sunlight, so you have to hide in the shadows. It's like the whole world is trying to destroy you, but your will to live is stronger than all of that. SURVIVE. That's all you have to do.
cp14-roles-antag-blood-moon-cursed-name = Cursed by the blood moon
cp14-roles-antag-blood-moon-cursed-objective = Some creatures lose their minds, and can commit unthinkable atrocities when a bloody blood moon rises from behind the horizon ...
cp14-roles-antag-blood-moon-cursed-briefing = The blood moon takes control of your thoughts. Your bloodlust awakens and the voices in your head say only one thing: Kill, kill, kill... kill while the moon is in its prime. Kill before the sun restores your sanity.

View File

@@ -1,2 +1,5 @@
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.
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.
cp14-judge-night-title = Judgment Night
cp14-judge-night-desc = Once a decade, a blood moon rises in the heavens, twisting minds and blackening hearts. On this night, brother goes against brother, blood is shed and terrible crimes are committed. Will the curse of the moon consume you tonight? Will you survive this night of judgment?

View File

@@ -0,0 +1,6 @@
cp14-bloodmoon-raising = A blood moon rises on the horizon. The next night will be terrible.
cp14-bloodmoon-start = The blood moon shines in full force, enslaving minds.
cp14-bloodmoon-end = The blood moon sets over the horizon, losing its power.
cp14-bloodmoon-curse-removed = The curse of the blood moon is dispelled.
cp14-bloodmoon-curse-examined = The aura of the blood moon hovers around this creature. Be careful, for his mind is unstable.

View File

@@ -1,3 +1,7 @@
cp14-roles-antag-vampire-name = Вампир
cp14-roles-antag-vampire-objective = Вы - паразит на теле общества, ненавидимый окружающими, сгораемый под солнцем и вечно голодный. Вам необходимо питаться кровью разумных, чтобы выжить. И найти тех, кто добровольно будет готов стать вашей кормушкой непросто...
cp14-roles-antag-vampire-briefing = Вы - паразит на теле общества. Оно вас ненавидит и боится, но кровь живых - ваша единственная пища. Природа уничтожает вас солнечным светом, и вам приходится скрываться в тени. Словно весь мир пытается вас уничтожить, но ваше желание жить сильнее всего этого. ВЫЖИВИТЕ. Это все что от вас требуется.
cp14-roles-antag-vampire-briefing = Вы - паразит на теле общества. Оно вас ненавидит и боится, но кровь живых - ваша единственная пища. Природа уничтожает вас солнечным светом, и вам приходится скрываться в тени. Словно весь мир пытается вас уничтожить, но ваше желание жить сильнее всего этого. ВЫЖИВИТЕ. Это все что от вас требуется.
cp14-roles-antag-blood-moon-cursed-name = Проклятый кровавой луны
cp14-roles-antag-blood-moon-cursed-objective = Некоторые существа теряют голову, и могут совершать немыслимые зверства, когда из-за горизонта всходит проклятая кровавая луна...
cp14-roles-antag-blood-moon-cursed-briefing = Кровавая луна обретает контроль над вашими помыслами. В вас просыпается жажда крови, и голоса в вашей голове твердят только одно: Убивай, убивай, убивай... убивай, пока луна в расцвете сил. Убивай, пока солнце не восстановило твой рассудок.

View File

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

View File

@@ -0,0 +1,6 @@
cp14-bloodmoon-raising = На горизонте поднимается кровавая луна. Следующая ночь будет ужасной.
cp14-bloodmoon-start = Кровавая луна сияет в полную силу, порабощая разумы.
cp14-bloodmoon-end = Кровавая луна заходит за горизонт, теряя свою силу.
cp14-bloodmoon-curse-removed = Проклятье кровавой луны развеивается.
cp14-bloodmoon-curse-examined = [color=red]Аура кровавой луны витает вокруг этого существа. Будьте осторожны, ибо его разум нестабилен.[/color]

View File

@@ -96,4 +96,27 @@
lifetime: 2
- type: Tag
tags:
- HideContextMenu
- HideContextMenu
- type: entity
id: CP14BloodMoonCurseEffect
categories: [ HideSpawnMenu ]
components:
- type: Sprite
noRot: true
sprite: /Textures/_CP14/Effects/Magic/blood_moon_curse.rsi
drawdepth: Effects
layers:
- state: icon
shader: unshaded
- type: Physics
canCollide: false
- type: Tag
tags:
- HideContextMenu
- type: PointLight
color: "#a83256"
enabled: true
radius: 2
energy: 2
netsync: false

View File

@@ -0,0 +1,39 @@
- type: entity
id: CP14BloodMoonRule
parent: CP14BaseGameRule
components:
- type: CP14BloodMoonRule
curseRule: CP14BloodMoonCurseRule
- type: GameRule
minPlayers: 0
- type: entity
id: CP14BloodMoonCurseRule
parent: CP14BaseGameRule
components:
- type: CP14BloodMoonCurseRule
announcementColor: "#e32759"
- type: StationEvent
maxOccurrences: 0 #We dont wanna random start it
startAnnouncement: cp14-bloodmoon-start
startAudio:
path: /Audio/_CP14/Ambience/event_boom.ogg
startAnnouncementColor: "#e32759"
endAnnouncement: cp14-bloodmoon-end
endAudio:
path: /Audio/_CP14/Ambience/event_boom.ogg
endAnnouncementColor: "#e32759"
- type: AntagSelection
definitions:
- prefRoles: [ CP14BloodMoonCursed ]
max: 15
playerRatio: 2
multiAntagSetting: NotExclusive
lateJoinAdditional: true
allowNonHumans: true
mindRoles:
- CP14MindRoleBloodMoonCursed
briefing:
text: cp14-roles-antag-blood-moon-cursed-briefing
color: "#630f24"
sound: "/Audio/_CP14/Ambience/Antag/bandit_start.ogg"

View File

@@ -1,13 +0,0 @@
- type: antag
id: CP14DemiplaneAntag
name: cp14-role-type-demiplane-antag-name
antagonist: true
setPreference: false
objective: cp14-ghost-role-information-rules-demiplane
- type: antag
id: CP14RaidAntag
name: cp14-role-type-raid-antag-name
antagonist: true
setPreference: false
objective: cp14-ghost-role-information-rules-raid

View File

@@ -0,0 +1,31 @@
- type: antag
id: CP14DemiplaneAntag
name: cp14-role-type-demiplane-antag-name
antagonist: true
setPreference: false
objective: cp14-ghost-role-information-rules-demiplane
- type: antag
id: CP14RaidAntag
name: cp14-role-type-raid-antag-name
antagonist: true
setPreference: false
objective: cp14-ghost-role-information-rules-raid
- type: antag
id: CP14Vampire
name: cp14-roles-antag-vampire-name
antagonist: true
setPreference: false #Impossible and boring gameplay ATM
objective: cp14-roles-antag-vampire-objective
requirements:
- !type:OverallPlaytimeRequirement
time: 7200 # 2h
#guides: TODO
- type: antag
id: CP14BloodMoonCursed
name: cp14-roles-antag-blood-moon-cursed-name
antagonist: true
setPreference: true
objective: cp14-roles-antag-blood-moon-cursed-objective

View File

@@ -1,10 +0,0 @@
- type: antag
id: CP14Vampire
name: cp14-roles-antag-vampire-name
antagonist: true
setPreference: false #Impossible and boring gameplay ATM
objective: cp14-roles-antag-vampire-objective
requirements:
- !type:OverallPlaytimeRequirement
time: 7200 # 2h
#guides: TODO

View File

@@ -1,7 +1,7 @@
- type: entity
parent: BaseMindRoleAntag
id: CP14MindRoleDemiplaneAntag
name: Demiplane Antag Role
name: Demiplane antag role
components:
- type: MindRole
roleType: CP14DemiplaneAntagonist
@@ -20,7 +20,7 @@
parent: BaseMindRoleAntag
id: CP14MindRoleVampire
categories: [ ForkFiltered ]
name: Vampire Role
name: Vampire role
components:
- type: MindRole
antagPrototype: CP14Vampire
@@ -28,4 +28,15 @@
exclusiveAntag: true
- type: CP14VampireRole
- type: RoleBriefing
briefing: cp14-roles-antag-vampire-briefing
briefing: cp14-roles-antag-vampire-briefing
- type: entity
parent: BaseMindRoleAntag
id: CP14MindRoleBloodMoonCursed
categories: [ ForkFiltered ]
name: Blood moon cursed role
components:
- type: MindRole
antagPrototype: CP14BloodMoonCursed
roleType: SoloAntagonist
exclusiveAntag: false

View File

@@ -10,6 +10,19 @@
rules:
- Secret
- type: gamePreset
id: CP14Sandbox
alias:
- sandbox
name: sandbox-title
description: sandbox-description
showInVote: false
cP14Allowed: true
rules:
- CP14RoundObjectivesRule
- CP14BasicStationEventScheduler
- Sandbox
- type: gamePreset
id: CP14Greenshift
name: greenshift-title
@@ -17,19 +30,16 @@
showInVote: true
cP14Allowed: true
rules:
- CP14SubGamemodesRule
- CP14RoundObjectivesRule
- CP14BasicStationEventScheduler
- type: gamePreset
id: CP14Sandbox
alias:
- sandbox
name: sandbox-title
description: sandbox-description
showInVote: true # For playtest period only
id: CP14JudgmentNight
name: cp14-judge-night-title
description: cp14-judge-night-desc
showInVote: true
cP14Allowed: true
rules:
- CP14RoundObjectivesRule
- CP14BasicStationEventScheduler
- Sandbox
- CP14BloodMoonRule

View File

@@ -1,3 +1,7 @@
#- type: roundAnnouncement
# id: Welcome
# sound: /Audio/Announcements/welcome.ogg #REPLACED By CrystallEdge
- type: roundAnnouncement
id: Welcome
sound: /Audio/Announcements/welcome.ogg
sound: /Audio/_CP14/Effects/round_start.ogg

View File

@@ -5,14 +5,18 @@
<GuideEntityEmbed Entity="CP14MobCarcat" Caption="Carcat"/>
</Box>
TODO: Lorekeeper awaiting
The Carkats are a desert nation inhabiting the harsh expanse of the Great Dune Desert. They are known for their endurance, isolation, and deep connection to their ancestors. Their homeland is Bafamir, a state that rose from the ashes of war, disaster and harsh conditions, held together by the iron will of the Sultan and the overriding clans. In other lands they are often found as mercenaries, traders and artisans.
## Night vision
## Game Features
- Carkats are naturally endowed with sharp claws that deal enhanced damage in melee combat.
- Wearing shoes? Not for them. Where have you seen shoes that will fit over clawed paws?
- Soft paws - soft pads ensure a completely silent footstep.
- Night vision - nature has given carcats excellent night vision - they see in the dark almost as well as they do in daylight. Combined with their silent walk, this makes them ideal hunters.
As natural predators, darkness is no problem for the Carkat.
## Soft feet
The unusual shape of a Carkat's feet is both an advantage and a disadvantage. The soft pads make for a silent footstep. But the inability to wear shoes makes their paws vulnerable to sharp objects.
## Cultural Features
- Ancestral nation: the Karkats do not worship gods - they honor the spirits of their ancestors, believing them to be the guardians of boundaries and law.
- Anonymity of power: the Sultans of Bafamir have no name, clan or face. Their figure is a symbol of the will of the entire desert.
- Accent of terrain: Carkats from different areas of Bafamir may have their own particular accent.
- Tribal ties: far from their homeland, the Carkats are very warm towards tribesmen, setting them apart from other races.
</Document>

View File

@@ -5,14 +5,18 @@
<GuideEntityEmbed Entity="CP14MobCarcat" Caption="Каркат"/>
</Box>
TODO: Ожидаем лор лороведов
Каркаты — пустынный народ, обитающий в суровых просторах Пустыни Великих Дюн. Они известны своей выносливостью, замкнутостью и глубокой связью с предками. Их родина — Бафамир, государство, выросшее из пепла войны, бедствий и тяжелых условий, удерживаемое железной волей султана и главенствующих кланов. В других странах они часто встречаются в роли наемников, торговцев и ремесленников.
## Ночное зрение
## Игровые особенности
- Каркаты от природы наделены острыми когтями, которые наносят усиленный урон в ближнем бою.
- Ношение обуви? Не для них. Где вы видели ботинки, которые налезут на лапы с когтями?
- Мягкие лапы - мягкие подушечки обеспечивают абсолютно бесшумную поступь.
- Ночное зрение - природа наградила каркатов отличным ночным зрением — они видят в темноте почти так же хорошо, как при свете дня. Вкупе с бесшумной ходьбой, это делает их идеальными охотниками.
Будучи прирожденными хищниками, темнота для Каркатов - не помеха.
## Мягкая поступь
Необычная форма ног у Каркатов, одновременно является их преимуществом и недостатком. Мягкие подушечки обеспечивают абсолютно бесшумную поступь. Но невозможность носить обувь делает их лапы уязвимыми для острых предметов.
## Культурные особенности
- Народ предков: каркаты не поклоняются богам — они чтят духов своих предков, считая их хранителями границ и закона.
- Анонимность власти: султаны Бафамира не имеют имени, рода или лица. Их фигура — символ воли всей пустыни.
- Акцент местности: у каркатов из разных районов Бафамира может быть свой особенный акцент.
- Соплеменнические связи: вдали от своей родины, каркаты очень тепло относятся к соплеменникам, выделяя их от остальных рас.
</Document>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,26 @@
{
"version": 1,
"size": {
"x": 48,
"y": 48
},
"license": "CC-BY-SA-4.0",
"copyright": "Created by TheShuEd",
"states": [
{
"name": "icon",
"delays": [
[
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2
]
]
}
]
}