Merge branch 'master' into vulp-screams-ops

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
This commit is contained in:
Vanessa 2026-07-20 17:25:16 -05:00 committed by GitHub
commit 403a4ea4b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
222 changed files with 4268 additions and 264 deletions

View File

@ -34,6 +34,9 @@ namespace Content.Client.Input
common.AddFunction(ContentKeyFunctions.RotateStoredItem);
common.AddFunction(ContentKeyFunctions.SaveItemLocation);
common.AddFunction(ContentKeyFunctions.Point);
// Floofstation section
common.AddFunction(ContentKeyFunctions.OfferItem);
// Floofstation section end
common.AddFunction(ContentKeyFunctions.ZoomOut);
common.AddFunction(ContentKeyFunctions.ZoomIn);
common.AddFunction(ContentKeyFunctions.ResetZoom);

View File

@ -75,9 +75,11 @@ public sealed partial class CrewMonitoringNavMapControl : NavMapControl
if (!LocalizedNames.TryGetValue(netEntity, out var name))
name = Loc.GetString("navmap-unknown-entity");
var pos = _xform.ToMapCoordinates(blip.Coordinates); // DeltaV - map-coordinates
var message = name + "\n" + Loc.GetString("navmap-location",
("x", MathF.Round(blip.Coordinates.X)),
("y", MathF.Round(blip.Coordinates.Y)));
("x", MathF.Round(pos.X)), // DeltaV - map-coordinates
("y", MathF.Round(pos.Y))); // DeltaV - map-coordinates
_trackedEntityLabel.Text = message;
_trackedEntityPanel.Visible = true;

View File

@ -208,6 +208,7 @@ namespace Content.Client.Options.UI.Tabs
AddButton(ContentKeyFunctions.MovePulledObject);
AddButton(ContentKeyFunctions.ReleasePulledObject);
AddButton(ContentKeyFunctions.Point);
AddButton(ContentKeyFunctions.OfferItem); // Floofstation
AddButton(ContentKeyFunctions.RotateObjectClockwise);
AddButton(ContentKeyFunctions.RotateObjectCounterclockwise);
AddButton(ContentKeyFunctions.FlipObject);

View File

@ -0,0 +1,71 @@
using System.Numerics;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Shared.Enums;
using Robust.Shared.Utility;
namespace Content.Client._Floof.OfferItem;
public sealed class OfferItemIndicatorsOverlay : Overlay
{
private readonly IInputManager _inputManager;
private readonly IEntityManager _entMan;
private readonly IEyeManager _eye;
private readonly OfferItemSystem _offer;
private readonly Texture _sight;
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
private readonly Color _mainColor = Color.White.WithAlpha(0.3f);
private readonly Color _strokeColor = Color.Black.WithAlpha(0.5f);
private readonly float _scale = 0.6f; // 1 is a little big
public OfferItemIndicatorsOverlay(IInputManager input, IEntityManager entMan,
IEyeManager eye, OfferItemSystem offerSys)
{
_inputManager = input;
_entMan = entMan;
_eye = eye;
_offer = offerSys;
var spriteSys = _entMan.EntitySysManager.GetEntitySystem<SpriteSystem>();
_sight = spriteSys.Frame0(new SpriteSpecifier.Rsi(new("/Textures/_Floof/Interface/Misc/give_item.rsi"), "give_item"));
}
protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (!_offer.IsInOfferMode())
return false;
return base.BeforeDraw(in args);
}
protected override void Draw(in OverlayDrawArgs args)
{
var mouseScreenPosition = _inputManager.MouseScreenPosition;
var mousePosMap = _eye.PixelToMap(mouseScreenPosition);
if (mousePosMap.MapId != args.MapId)
return;
var mousePos = mouseScreenPosition.Position;
var uiScale = (args.ViewportControl as Control)?.UIScale ?? 1f;
var limitedScale = uiScale > 1.25f ? 1.25f : uiScale;
DrawSight(_sight, args.ScreenHandle, mousePos, limitedScale * _scale);
}
private void DrawSight(Texture sight, DrawingHandleScreen screen, Vector2 centerPos, float scale)
{
var sightSize = sight.Size * scale;
var expandedSize = sightSize + new Vector2(7f, 7f);
screen.DrawTextureRect(sight,
UIBox2.FromDimensions(centerPos - sightSize * 0.5f, sightSize), _strokeColor);
screen.DrawTextureRect(sight,
UIBox2.FromDimensions(centerPos - expandedSize * 0.5f, expandedSize), _mainColor);
}
}

View File

@ -0,0 +1,39 @@
using Content.Shared._Floof.OfferItem;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
namespace Content.Client._Floof.OfferItem;
public sealed class OfferItemSystem : SharedOfferItemSystem
{
[Dependency] private readonly IOverlayManager _overlayManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IEyeManager _eye = default!;
public override void Initialize()
{
base.Initialize();
_overlayManager.AddOverlay(new OfferItemIndicatorsOverlay(
_inputManager,
EntityManager,
_eye,
this));
}
public override void Shutdown()
{
_overlayManager.RemoveOverlay<OfferItemIndicatorsOverlay>();
base.Shutdown();
}
public bool IsInOfferMode()
{
var entity = _playerManager.LocalEntity;
if (entity == null)
return false;
return IsInOfferMode(entity.Value);
}
}

View File

@ -23,6 +23,7 @@ using Robust.Shared.Timing;
using System.Linq;
using Content.Shared.EntityEffects.Effects.Solution;
using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent;
using Content.Server.Body.Components; // Delta V
namespace Content.Server.Fluids.EntitySystems;
@ -267,7 +268,8 @@ public sealed class SmokeSystem : EntitySystem
if (!_solutionContainerSystem.ResolveSolution(entity, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution) || bloodSolution.AvailableVolume <= 0)
return;
var blockIngestion = _internals.AreInternalsWorking(entity);
var blockIngestion = _internals.AreInternalsWorking(entity)
|| !HasComp<RespiratorComponent>(entity); // Starlight - Shadekin does not breathe and "AreInternalsWorking" does not check for that
var cloneSolution = solution.Clone();
var availableTransfer = FixedPoint2.Min(cloneSolution.Volume, component.TransferRate);

View File

@ -41,6 +41,7 @@ using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Content.Server.Mobs; // Starlight
namespace Content.Server.Ghost
{
@ -619,7 +620,15 @@ namespace Content.Server.Ghost
_damageable.GetTotalDamage((playerEntity.Value, damageable));
}
DamageSpecifier damage = new(_prototypeManager.Index(AsphyxiationDamageType), dealtDamage);
// Starlight - Start
//DamageSpecifier damage = new(_prototypeManager.Index(AsphyxiationDamageType), dealtDamage);
var damageType = _prototypeManager.Index(AsphyxiationDamageType);
if (TryComp<DeathgaspComponent>(playerEntity, out var deathgasp))
damageType = _prototypeManager.Index(deathgasp.DamageType);
DamageSpecifier damage = new(damageType, dealtDamage);
// Starlight - End
_damageable.ChangeDamage(playerEntity.Value, damage, true);
}

View File

@ -1,4 +1,6 @@
using Content.Shared.Chat.Prototypes;
using Content.Shared.Chat.Prototypes; // Starlight
using Content.Shared.Damage.Prototypes; // Starlight
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Mobs;
@ -21,4 +23,10 @@ public sealed partial class DeathgaspComponent : Component
/// </summary>
[DataField]
public bool NeedsCritical = true;
/// <summary>
/// Starlight - The damage that is taken when succumbing
/// </summary>
[DataField]
public ProtoId<DamageTypePrototype> DamageType = "Asphyxiation";
}

View File

@ -55,9 +55,13 @@ public sealed class PseudoItemSystem : SharedPseudoItemSystem
protected override void OnGettingPickedUpAttempt(EntityUid uid, PseudoItemComponent component, GettingPickedUpAttemptEvent args)
{
// Floof - changed this a bit to actually start a do-after
// Try to pick the entity up instead first
if (args.User != args.Item && _carrying.TryCarry(args.User, uid))
if (args.User != args.Item
&& TryComp<CarriableComponent>(uid, out var carriable)
&& _carrying.CanCarry(args.User, (uid, carriable)))
{
_carrying.StartCarryDoAfter(args.User, (uid, carriable));
args.Cancel();
return;
}

View File

@ -209,20 +209,24 @@ namespace Content.Server.Psionics.Glimmer
private void OnDestroyed(EntityUid uid, SharedGlimmerReactiveComponent component, DestructionEventArgs args)
{
Spawn("MaterialBluespace1", Transform(uid).Coordinates);
var proberCoords = Transform(uid).Coordinates;
var tier = _glimmerSystem.GetGlimmerTier();
if (tier < GlimmerTier.High)
return;
var totalIntensity = (float) (_glimmerSystem.Glimmer * 2);
var slope = (float) (11 - _glimmerSystem.Glimmer / 100);
var maxIntensity = 20;
var explosionMultiplier = 2;
if (_glimmerSystem.GetGlimmerTier() == GlimmerTier.Critical) // YOU DONE FUCKED UP
explosionMultiplier = 3;
var removed = (float) _glimmerSystem.Glimmer * _random.NextFloat(0.06f, 0.08f);
_glimmerSystem.Glimmer -= (int) removed;
var totalIntensity = (float)(_glimmerSystem.Glimmer * explosionMultiplier);
var slope = (float)(11 - _glimmerSystem.Glimmer / 100);
var maxIntensity = 75; // Same as syndicate bomb
var removed = _glimmerSystem.Glimmer * _random.NextFloat(0.06f, 0.08f);
_glimmerSystem.Glimmer -= (int)removed;
BeamRandomNearProber(uid, _glimmerSystem.Glimmer / 350, _glimmerSystem.Glimmer / 50);
_explosionSystem.QueueExplosion(uid, "Default", totalIntensity, slope, maxIntensity);
_explosionSystem.QueueExplosion(uid, "Default", totalIntensity, slope, maxIntensity, addLog: true);
Spawn("MaterialBluespace1", proberCoords); // Congrats on your bluespace!
}
private void OnUnanchorAttempt(EntityUid uid, SharedGlimmerReactiveComponent component, UnanchorAttemptEvent args)
@ -230,7 +234,7 @@ namespace Content.Server.Psionics.Glimmer
if (component.Locked)
{
_sharedAudioSystem.PlayPvs(component.ShockNoises, args.User);
_electrocutionSystem.TryDoElectrocution(args.User, null, _glimmerSystem.Glimmer / 200, TimeSpan.FromSeconds((float) _glimmerSystem.Glimmer / 100), false);
_electrocutionSystem.TryDoElectrocution(args.User, uid, _glimmerSystem.Glimmer / 200, TimeSpan.FromSeconds((float) _glimmerSystem.Glimmer / 100), false);
args.Cancel();
}
}

View File

@ -184,7 +184,8 @@ public sealed class OracleSystem : EntitySystem
while (i != 0)
{
Spawn("MaterialBluespace1", Transform(user).Coordinates);
var entityToSpawn = _random.Next(0, 2) == 0 ? "MaterialBluespace1" : "CrystalNormality";
Spawn(entityToSpawn, Transform(user).Coordinates);
i--;
}

View File

@ -0,0 +1,5 @@
using Content.Shared._Floof.OfferItem;
namespace Content.Server._Floof.OfferItem;
public sealed partial class OfferItemSystem : SharedOfferItemSystem;

View File

@ -0,0 +1,290 @@
using Content.Shared.Humanoid;
using Content.Shared.Alert;
using Robust.Server.GameObjects;
using Content.Shared.Examine;
using Robust.Server.Containers;
using Content.Shared._Starlight;
using Content.Shared.Damage.Components;
using Content.Shared.Mobs;
using Content.Shared.Movement.Systems;
using Content.Shared.Movement.Components;
using Content.Shared.Damage;
using Content.Server.Chat.Managers;
using Content.Shared.Damage.Systems;
using Content.Shared._Goobstation.Overlays;
using Robust.Shared.Timing;
using Content.Server.Body.Components;
using System.Linq;
using Content.Shared._Goobstation.Flashbang;
using Content.Shared._Starlight.Flash.Components;
using Content.Shared.Body.Components;
using Content.Shared.Flash; // Delta V - Flash Work
namespace Content.Server._Starlight;
public sealed class ShadekinSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly MovementSpeedModifierSystem _speed = default!;
[Dependency] private readonly SharedFlashSystem _flashSystem = default!;
private sealed class LightCone
{
public float Direction { get; set; }
public float InnerWidth { get; set; }
public float OuterWidth { get; set; }
}
private readonly Dictionary<string, List<LightCone>> lightMasks = new()
{
["/Textures/Effects/LightMasks/cone.png"] = new List<LightCone>
{
new LightCone { Direction = 0, InnerWidth = 30, OuterWidth = 60 }
},
["/Textures/Effects/LightMasks/double_cone.png"] = new List<LightCone>
{
new LightCone { Direction = 0, InnerWidth = 30, OuterWidth = 60 },
new LightCone { Direction = 180, InnerWidth = 30, OuterWidth = 60 }
}
};
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ShadekinComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<ShadekinComponent, EyeColorInitEvent>(OnEyeColorChange);
SubscribeLocalEvent<ShadekinComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
SubscribeLocalEvent<ShadekinComponent, AfterFlashedEvent>(OnShadekinFlashed); // Delta V - Prevent Chain Flashing
SubscribeLocalEvent<ShadekinComponent, FlashDurationMultiplierEvent>(GetFlashModifier); // Delta V - Flash Modifier to Shadekin
}
private void OnInit(EntityUid uid, ShadekinComponent component, ComponentStartup args)
{
UpdateAlert(uid, component, (short)component.CurrentState);
RemComp<InternalsComponent>(uid);
}
private void OnEyeColorChange(EntityUid uid, ShadekinComponent component, EyeColorInitEvent args)
{
if (!TryComp<HumanoidProfileComponent>(uid, out var humanoid))
return;
// humanoid.EyeColor = Color.Black;
Dirty(uid, humanoid);
}
public void UpdateAlert(EntityUid uid, ShadekinComponent component, short state)
{
_alerts.ShowAlert(uid, component.ShadekinAlert, state);
}
private Angle GetAngle(EntityUid lightUid, SharedPointLightComponent lightComp, EntityUid targetUid)
{
var (lightPos, lightRot) = _transform.GetWorldPositionRotation(lightUid);
lightPos += lightRot.RotateVec(lightComp.Offset);
var (targetPos, targetRot) = _transform.GetWorldPositionRotation(targetUid);
var mapDiff = targetPos - lightPos;
var oppositeMapDiff = (-lightRot).RotateVec(mapDiff);
var angle = oppositeMapDiff.ToWorldAngle();
if (angle == double.NaN && _transform.ContainsEntity(targetUid, lightUid) || _transform.ContainsEntity(lightUid, targetUid))
{
angle = 0f;
}
return angle;
}
/// <summary>
/// Return an illumination float value with is how many "energy" of light is hitting our ent.
/// WARNING: This function might be expensive, Avoid calling it too much and CACHE THE RESULT!
/// </summary>
/// <param name="uid"></param>
/// <returns></returns>
public float GetLightExposure(EntityUid uid)
{
var illumination = 0f;
var lightQuery = _lookup.GetEntitiesInRange<PointLightComponent>(Transform(uid).Coordinates, 20, LookupFlags.Uncontained);
foreach (var light in lightQuery)
{
if (!light.Comp.Enabled
|| light.Comp.Radius < 1
|| light.Comp.Energy <= 0)
continue;
var (lightPos, lightRot) = _transform.GetWorldPositionRotation(light);
lightPos += lightRot.RotateVec(light.Comp.Offset);
if (!_examine.InRangeUnOccluded(light, uid, light.Comp.Radius, null))
continue;
Transform(uid).Coordinates.TryDistance(EntityManager, Transform(light).Coordinates, out var dist);
var denom = dist / light.Comp.Radius;
var attenuation = 1 - (denom * denom);
var calculatedLight = 0f;
if (light.Comp.MaskPath is not null)
{
var angleToTarget = GetAngle(light, light.Comp, uid);
foreach (var cone in lightMasks[light.Comp.MaskPath])
{
var coneLight = 0f;
var angleAttenuation = (float)Math.Min((float)Math.Max(cone.OuterWidth - angleToTarget, 0f), cone.InnerWidth) / cone.OuterWidth;
if (angleToTarget.Degrees - cone.Direction > cone.OuterWidth)
continue;
else if (angleToTarget.Degrees - cone.Direction > cone.InnerWidth
&& angleToTarget.Degrees - cone.Direction < cone.OuterWidth)
coneLight = light.Comp.Energy * attenuation * attenuation * angleAttenuation;
else
coneLight = light.Comp.Energy * attenuation * attenuation;
calculatedLight = Math.Max(calculatedLight, coneLight);
}
}
else
calculatedLight = light.Comp.Energy * attenuation * attenuation;
illumination += calculatedLight; //Math.Max(illumination, calculatedLight);
}
return illumination;
}
private void SetPassiveBuff(EntityUid uid, ShadekinState state)
{
if (!TryComp<PassiveDamageComponent>(uid, out var passive))
return;
if (state == ShadekinState.Extreme || state == ShadekinState.Annoying || state == ShadekinState.High)
{
// passive.DamageCap = 1;
}
else if (state == ShadekinState.Low)
{
// passive.DamageCap = 20;
passive.AllowedStates.Clear();
passive.AllowedStates.Add(MobState.Alive);
passive.Interval = 1f;
}
else if (state != ShadekinState.Dark)
{
// passive.DamageCap = 0;
passive.AllowedStates.Clear();
passive.AllowedStates.Add(MobState.Alive);
passive.AllowedStates.Add(MobState.Critical);
passive.AllowedStates.Add(MobState.Dead);
passive.Interval = 0.5f;
}
}
private void ToggleNightVision(EntityUid uid, ShadekinState state)
{
if (state == ShadekinState.Dark)
{
var nightVisionComponent = EnsureComp<NightVisionComponent>(uid);
nightVisionComponent.Color = Color.FromHex("#808080"); // Delta V - Change Night Vision Color
}
else
{
if (TryComp<NightVisionComponent>(uid, out var nightVision) && nightVision.IsActive)
_flashSystem.Flash(uid, uid, uid, TimeSpan.FromSeconds(0.5 * (int)state), 0.5f);
RemComp<NightVisionComponent>(uid);
}
}
private void ApplyLightDamage(EntityUid uid, float dmg)
{
var damage = new DamageSpecifier();
damage.DamageDict.Add("Heat", dmg);
_damageable.TryChangeDamage(uid, damage, true, false);
}
private void OnRefreshMovementSpeedModifiers(EntityUid uid, ShadekinComponent component, RefreshMovementSpeedModifiersEvent args)
{
if (component.CurrentState == ShadekinState.Low || component.CurrentState == ShadekinState.Annoying ||
component.CurrentState == ShadekinState.Dark || component.CurrentState == ShadekinState.Invalid)
return;
if (!TryComp<MovementSpeedModifierComponent>(uid, out var movement))
return;
var sprintDif = movement.BaseWalkSpeed / movement.BaseSprintSpeed;
args.ModifySpeed(1f, sprintDif);
}
private ShadekinState GetStateByThreshold(ShadekinComponent component, float lightExposure)
{
var returnState = ShadekinState.Dark;
foreach (var (threshold, shadekinState) in component.Thresholds.Reverse())
{
if (threshold <= lightExposure)
{
returnState = shadekinState;
break;
}
}
return returnState;
}
// Delta V - Begin Shadekin Flash Changes
private void GetFlashModifier(EntityUid uid, ShadekinComponent comp, FlashDurationMultiplierEvent args)
{
if (!TryComp<FlashModifierComponent>(uid, out var flashModifier))
return;
args.Multiplier = flashModifier.Modifier;
}
private void OnShadekinFlashed(EntityUid uid, ShadekinComponent comp, AfterFlashedEvent ev)
{
RemComp<NightVisionComponent>(uid);
}
// Delta V - End
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<ShadekinComponent>();
while (query.MoveNext(out var uid, out var component))
{
if (_timing.CurTime < component.NextUpdate)
continue;
component.NextUpdate = _timing.CurTime + component.UpdateCooldown;
var lightExposure = 0f;
if (!_container.IsEntityInContainer(uid))
lightExposure = GetLightExposure(uid);
component.CurrentState = GetStateByThreshold(component, lightExposure);
UpdateAlert(uid, component, (short)component.CurrentState);
SetPassiveBuff(uid, component.CurrentState);
ToggleNightVision(uid, component.CurrentState);
_speed.RefreshMovementSpeedModifiers(uid);
if (component.CurrentState == ShadekinState.Extreme)
ApplyLightDamage(uid, 5);
}
}
}

View File

@ -26,6 +26,7 @@ using System.Linq;
using Content.Shared.Movement.Systems;
using Content.Shared.Random.Helpers;
using Content.Shared.Clothing.Components;
using Content.Shared._Starlight.Flash.Components; // Delta V - For Flash Duration
namespace Content.Shared.Flash;
@ -173,7 +174,7 @@ public abstract class SharedFlashSystem : EntitySystem
// Goobstation end
// don't paralyze, slowdown or convert to rev if the target is immune to flashes
if (!_statusEffectsSystem.TryAddStatusEffect<FlashedComponent>(target, FlashedKey, flashDuration, true) && !ignoreProtection) //DeltaV: allow flashing to ignore flash protection
if (!_statusEffectsSystem.TryAddStatusEffect<FlashedComponent>(target, FlashedKey, flashDuration * multiplier, true) && !ignoreProtection) //DeltaV: allow flashing to ignore flash protection. Added Flashduration Multiplier
return;
if (stunDuration != null)

View File

@ -68,6 +68,7 @@ namespace Content.Shared.Input
public static readonly BoundKeyFunction TakeScreenshotNoUI = "TakeScreenshotNoUI";
public static readonly BoundKeyFunction ToggleFullscreen = "ToggleFullscreen";
public static readonly BoundKeyFunction Point = "Point";
public static readonly BoundKeyFunction OfferItem = "OfferItem"; // Floofstation
public static readonly BoundKeyFunction ZoomOut = "ZoomOut";
public static readonly BoundKeyFunction ZoomIn = "ZoomIn";
public static readonly BoundKeyFunction ResetZoom = "ResetZoom";

View File

@ -1,4 +1,5 @@
using Content.Shared._ST.Interaction; // Stellar - interaction particles
using Content.Shared._Floof.OfferItem; // Floof
using Content.Shared.ActionBlocker;
using Content.Shared.Administration.Logs;
using Content.Shared.Alert;
@ -117,10 +118,11 @@ public sealed class PullingSystem : EntitySystem
if (TryComp(args.PullerUid, out PullerComponent? pullerComp) && !pullerComp.NeedsHands)
return;
if (!_virtual.TrySpawnVirtualItemInHand(args.PulledUid, uid))
if (!_virtual.TrySpawnVirtualItemInHand(args.PulledUid, uid, out var virt)) // Floofstation - store item
{
DebugTools.Assert("Unable to find available hand when starting pulling??");
}
EnsureComp<OfferableVirtualItemComponent>(virt.Value); // Floofstation - add a special component to allow offering it
}
private void HandlePullStopped(EntityUid uid, HandsComponent component, PullStoppedMessage args)

View File

@ -1,8 +1,7 @@
using Content.Shared.Actions;
using Content.Shared.Bed.Sleep;
using Content.Shared.DoAfter;
using Content.Shared.Hands;
using Content.Shared.IdentityManagement;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction.Events;
using Content.Shared.Item;
using Content.Shared.Item.PseudoItem;
@ -24,7 +23,8 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedContainerSystem _container = default!; // Floofstation
[Dependency] private readonly SharedHandsSystem _hands = default!; // Floofstation
private readonly ProtoId<TagPrototype> PreventTag = "PreventLabel";
private readonly EntProtoId SleepActionId = "ActionSleep"; // The action used for sleeping inside bags. Currently uses the default sleep action (same as beds)
@ -116,17 +116,35 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
protected virtual void OnGettingPickedUpAttempt(EntityUid uid, PseudoItemComponent component,
GettingPickedUpAttemptEvent args)
{
if (args.User == args.Item)
return;
args.Cancel(); // Floof - this is a terrible idea. This triggers every time ANY system checks if a pseudo-item can be picked up.
// WHY DID YOU DO THAT, NYANOTRASEN???
_transform.AttachToGridOrMap(uid);
args.Cancel();
// if (args.User == args.Item)
// return;
//
// _transform.AttachToGridOrMap(uid);
// args.Cancel();
}
private void OnDropAttempt(EntityUid uid, PseudoItemComponent component, DropAttemptEvent args)
{
if (component.Active)
args.Cancel();
if (!component.Active)
return;
// Floof - we try to get the containing container and try to drop it into it
// If possible, we do it, since a bagged cat probably can put things back into the bag just like they can pick them up.
string? failReason = null;
if (_hands.GetActiveItem(uid) is { Valid: true, } droppedItem
&& _container.TryGetContainingContainer(Transform(uid).ParentUid, uid, out var pseudoItemContainer)
&& TryComp<StorageComponent>(pseudoItemContainer.Owner, out var targetStorage)
&& _storage.CanInsert(pseudoItemContainer.Owner, droppedItem, out failReason, targetStorage, ignoreStacks: true)
)
_storage.Insert(pseudoItemContainer.Owner, droppedItem, out _, uid, targetStorage, stackAutomatically: false);
if (failReason != null)
_popupSystem.PopupEntity(Loc.GetString(failReason), uid, uid);
args.Cancel();
}
private void OnInsertAttempt(EntityUid uid, PseudoItemComponent component,
@ -141,8 +159,9 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
// Prevents moving within the bag :)
private void OnInteractAttempt(EntityUid uid, PseudoItemComponent component, InteractionAttemptEvent args)
{
if (args.Uid == args.Target && component.Active)
args.Cancelled = true;
// Floof - why the fuck.
// if (args.Uid == args.Target && component.Active)
// args.Cancelled = true;
}
private void OnDoAfter(EntityUid uid, PseudoItemComponent component, DoAfterEvent args)

View File

@ -28,6 +28,7 @@ using Robust.Shared.Network;
using Robust.Shared.Physics.Components;
using System.Numerics;
using Content.Shared._DV.Polymorph;
using Content.Shared._Floof.OfferItem;
using Content.Shared.Hands.EntitySystems;
namespace Content.Shared._DV.Carrying;
@ -181,14 +182,15 @@ public sealed class CarryingSystem : EntitySystem
/// </summary>
private void OnInteractionAttempt(Entity<BeingCarriedComponent> ent, ref InteractionAttemptEvent args)
{
if (args.Target is not {} target)
return;
var targetParent = Transform(target).ParentUid;
var carrier = ent.Comp.Carrier;
if (target != carrier && targetParent != carrier && targetParent != ent.Owner)
args.Cancelled = true;
// Floofstation - no - this prevents the person from escaping and more.
// if (args.Target is not {} target)
// return;
//
// var targetParent = Transform(target).ParentUid;
//
// var carrier = ent.Comp.Carrier;
// if (target != carrier && targetParent != carrier && targetParent != ent.Owner)
// args.Cancelled = true;
}
private void OnMoveAttempt(Entity<BeingCarriedComponent> ent, ref UpdateCanMoveEvent args)
@ -203,8 +205,9 @@ public sealed class CarryingSystem : EntitySystem
private void OnInteractedWith(Entity<BeingCarriedComponent> ent, ref GettingInteractedWithAttemptEvent args)
{
if (args.Uid != ent.Comp.Carrier)
args.Cancelled = true;
// Floofstation - why?
// if (args.Uid != ent.Comp.Carrier)
// args.Cancelled = true;
}
private void OnPullAttempt(Entity<BeingCarriedComponent> ent, ref PullAttemptEvent args)
@ -242,7 +245,8 @@ public sealed class CarryingSystem : EntitySystem
args.Handled = true;
}
private void StartCarryDoAfter(EntityUid carrier, Entity<CarriableComponent> carried)
// Floofstation - made public
public void StartCarryDoAfter(EntityUid carrier, Entity<CarriableComponent> carried)
{
TimeSpan length = GetPickupDuration(carrier, carried);
@ -299,7 +303,8 @@ public sealed class CarryingSystem : EntitySystem
for (var x = 0; x < Comp<CarriableComponent>(carried).FreeHandsRequired; x++)
{
_virtualItem.TrySpawnVirtualItemInHand(carried, carrier);
if (_virtualItem.TrySpawnVirtualItemInHand(carried, carrier, out var virtualItem))
EnsureComp<OfferableVirtualItemComponent>(virtualItem.Value);
}
}

View File

@ -0,0 +1,5 @@
using Content.Shared.Alert;
namespace Content.Shared._Floof.OfferItem;
public sealed partial class AcceptOfferAlertEvent : BaseAlertEvent;

View File

@ -0,0 +1,52 @@
using Content.Shared.Alert;
using Content.Shared.Inventory.VirtualItem;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._Floof.OfferItem;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedOfferItemSystem))]
public sealed partial class OfferItemComponent : Component
{
/// <summary>
/// Apparently this indicates whether the entity is currently choosing an entity to offer (right after pressing F).
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool IsInOfferMode;
/// <summary>
/// If this is true, then someone is currently offering an item to this entity, and <see cref="ReceivingFrom"/>
/// stores the ID of that entity.
/// </summary>
[DataField, AutoNetworkedField]
public bool IsInReceiveMode;
[DataField, AutoNetworkedField]
public string? Hand;
[DataField, AutoNetworkedField]
public EntityUid? Item;
/// <summary>
/// Floofstation note. So, this is EE shitcode, so prepare for an emotional rollercoaster.
/// This field can mean TWO things. It's either the target entity this entity is offering an item to,
/// or an entity that is offering an item to this entity.
/// Whether it's one or the other is distinguished by <see cref="IsInReceiveMode"/>.<br/><br/>
///
/// In rare cases it can be both. According to my research, if entity A offers an item to entity B, and entity B offers to entity A,
/// then both entities will end up in receive mode, and they will have each other as targets. There's a check preventing offer loops
/// of length more than 2.
/// </summary>
[DataField, AutoNetworkedField]
public EntityUid? ReceivingFrom;
[DataField]
public float MaxOfferDistance = 2f;
[DataField]
public ProtoId<AlertPrototype> OfferAlert = "Offer";
public EntityUid GetRealEntity(EntityManager entityManager) =>
entityManager.GetComponentOrNull<VirtualItemComponent>(Item)?.BlockingEntity ?? Item ?? EntityUid.Invalid;
}

View File

@ -0,0 +1,11 @@
using Robust.Shared.GameStates;
namespace Content.Shared._Floof.OfferItem;
/// <summary>
/// A marker component that, when applied to a virtual item, allows it to be offered using item offering.
/// Implementors have to listen on ItemTransferredEvent.
/// </summary>
[RegisterComponent]
[NetworkedComponent]
public sealed partial class OfferableVirtualItemComponent : Component;

View File

@ -0,0 +1,93 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Alert;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Input;
using Content.Shared.Popups;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
namespace Content.Shared._Floof.OfferItem;
public abstract partial class SharedOfferItemSystem
{
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
private void InitializeInteractions()
{
base.Initialize();
CommandBinds.Builder
.Bind(ContentKeyFunctions.OfferItem, InputCmdHandler.FromDelegate(SetInOfferMode, handle: false, outsidePrediction: false))
.Register<SharedOfferItemSystem>();
}
public override void Shutdown()
{
base.Shutdown();
CommandBinds.Unregister<SharedOfferItemSystem>();
}
/// <summary>
/// This sets IsInOfferMode to true, allowing the player to select whom to offer an item to with interaction.
/// </summary>
private void SetInOfferMode(ICommonSession? offerer)
{
if (offerer is not { } playerSession)
return;
if (playerSession.AttachedEntity is not { Valid: true } uid)
return;
if (!Exists(uid))
return;
if (!_actionBlocker.CanInteract(uid, null))
return;
if (!TryComp<OfferItemComponent>(uid, out var offerItem))
return;
if (!TryComp<HandsComponent>(uid, out var hands))
return;
if (_hands.GetActiveHand((uid, hands)) is not { } activeHandName)
return;
if (!_hands.TryGetHeldItem((uid, hands), activeHandName, out var heldItem))
return;
offerItem.Item = heldItem;
if (!offerItem.IsInOfferMode)
{
if (offerItem.Item == null)
{
_popup.PopupEntity(Loc.GetString("offer-item-empty-hand"), uid, uid);
return;
}
if (offerItem.Hand == null || offerItem.ReceivingFrom == null)
{
offerItem.IsInOfferMode = true;
offerItem.Hand = activeHandName;
Dirty(uid, offerItem);
return;
}
}
// If we're already offering an item to someone, cancel that offer
if (offerItem.ReceivingFrom != null)
{
UnReceive(offerItem.ReceivingFrom.Value, offererComp: offerItem);
offerItem.IsInOfferMode = false;
Dirty(uid, offerItem);
return;
}
UnOffer(uid, offerItem);
}
}

View File

@ -0,0 +1,414 @@
using Content.Shared._DV.Carrying;
using Content.Shared.Alert;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Movement.Pulling.Components;
using Content.Shared.Movement.Pulling.Systems;
using Content.Shared.Nutrition.EntitySystems;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;
// Dear contributor.
// This system is fucking unmaintainable.
// If you ever happen to touch this again, please do your best to document your changes and try to resolve mysteries surrounding this code.
// I did what I could to document the parts I managed to understand, but there is still more truth to be unveiled.
//
// HOURS_WASTED_HERE_FLOOFSTATION = 10
// HOURS_WASTED_HERE_DELTAV = 1
namespace Content.Shared._Floof.OfferItem;
public abstract partial class SharedOfferItemSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly CarryingSystem _carrying = default!;
[Dependency] private readonly PullingSystem _pulling = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<OfferItemComponent, AcceptOfferAlertEvent>(OnAcceptOffer);
SubscribeLocalEvent<OfferItemComponent, InteractUsingEvent>(OnInteractWithReceiver, before: [typeof(IngestionSystem)]);
SubscribeLocalEvent<OfferableVirtualItemComponent, BeforeRangedInteractEvent>(OnRangedInteractWithReceiver);
SubscribeLocalEvent<OfferItemComponent, MoveEvent>(OnMove);
SubscribeLocalEvent<BeingCarriedComponent, ItemTransferredEvent>(OnCarryTransfer);
SubscribeLocalEvent<PullableComponent, ItemTransferredEvent>(OnPulledTransfer);
InitializeInteractions();
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<OfferItemComponent, HandsComponent>();
while (query.MoveNext(out var uid, out var offerItem, out var hands))
{
// If the mob no longer holds an item in the original offering hand, clear offering mode
if (offerItem.Hand != null && !_hands.TryGetHeldItem((uid, hands), offerItem.Hand, out _))
{
if (offerItem.ReceivingFrom != null)
{
UnReceive(offerItem.ReceivingFrom.Value, offererComp: offerItem);
offerItem.IsInOfferMode = false;
Dirty(uid, offerItem);
}
else
UnOffer(uid, offerItem);
}
if (!offerItem.IsInReceiveMode)
{
_alertsSystem.ClearAlert(uid, offerItem.OfferAlert);
continue;
}
_alertsSystem.ShowAlert(uid, offerItem.OfferAlert);
}
}
#region Events
private void OnAcceptOffer(Entity<OfferItemComponent> ent, ref AcceptOfferAlertEvent args)
{
Receive((ent, ent.Comp));
}
private void OnInteractWithReceiver(Entity<OfferItemComponent> receiver, ref InteractUsingEvent args)
{
if (!_timing.IsFirstTimePredicted || _timing.ApplyingState || args.Handled)
return;
if (!TryComp<OfferItemComponent>(args.User, out var offererComponent))
return;
args.Handled = CreateOffer(receiver, (args.User, offererComponent));
}
private void OnRangedInteractWithReceiver(Entity<OfferableVirtualItemComponent> virtItem, ref BeforeRangedInteractEvent args)
{
// If the entity being offered is a virtual item, InteractUsing will not be raised
// because virtual items exclude themselves from being marked as used
// If this is the case, InteractHand will be raised instead, which we can use anyway because OfferItem.Item stores the offered item
//
// We also can't check Handled here because VirtualItemSystem handles it, ffs
// This won't lead you to accidentally offering someone your gun
//
// This is shitcode, this time my shitcode. My changes to the offering system allow you to transfer carrying and pulling,
// but in order to handle these, we need to be able to intercept interactions with virtual items.
//
// Ideally this code should be rewritten to:
// a) Have each different virtual item have a distinct component (e.g. CarryingVirtualItem) which would allow to distinguish them from the rest
// b) Not rely on the InteractionSystem.
// However, I'm not in the mood to do either. And I'm too deep into the rabbit hole of getting this shit to work.
if (!_timing.IsFirstTimePredicted || _timing.ApplyingState)
return;
var receiver = args.Target;
if (!TryComp<OfferItemComponent>(receiver, out var receiverComponent))
return;
var offerer = args.User;
if (!TryComp<OfferItemComponent>(offerer, out var offererComponent) || offererComponent.Item == null)
return;
// Since this is ranged, we must also check distance, because the interaction system wont check it for us in this case
if (!Transform(offerer).Coordinates.TryDistance(EntityManager, _transform, Transform(receiver.Value).Coordinates, out var dst)
|| dst > offererComponent.MaxOfferDistance)
return;
args.Handled = CreateOffer((receiver.Value, receiverComponent), (offerer, offererComponent));
}
private void OnMove(EntityUid uid, OfferItemComponent component, MoveEvent args)
{
if (_net.IsClient) // Client often mispredicts movement, we cant trust it here
return;
if (component.ReceivingFrom == null)
return;
if (_transform.InRange(args.NewPosition, Transform(component.ReceivingFrom.Value).Coordinates, component.MaxOfferDistance))
return;
UnOffer(uid, component);
}
private void OnCarryTransfer(Entity<BeingCarriedComponent> ent, ref ItemTransferredEvent args)
{
if (args.Handled
|| args.PassedItem == args.RealItem // Means the entity is transferred NOT via carrying
|| args.RealItem is not { Valid: true } carried
|| ent.Comp.Carrier is not { Valid: true } oldCarrier)
return;
_carrying.DropCarried(oldCarrier, ent);
args.Handled = _carrying.TryCarry(args.Target, carried);
}
private void OnPulledTransfer(Entity<PullableComponent> ent, ref ItemTransferredEvent args)
{
if (args.Handled
|| args.PassedItem == args.RealItem // Means the entity is transferred NOT via pulling
|| args.RealItem is not { Valid: true } pulled)
return;
_pulling.TryStopPull(pulled, ent);
args.Handled = _pulling.TryStartPull(args.Target, ent, null, ent.Comp);
}
#endregion
#region Offering / Recieving
/// <summary>
/// Attempts to create an offer. Expects offerer.Item to already be set to the offered item, offererComponent.InReceiveMode == true.
/// Will fail if offerer == receiver or if receiver already has a set TargetOrOfferer, and that person is not the current offerer
/// </summary>
private bool CreateOffer(Entity<OfferItemComponent> receiver, Entity<OfferItemComponent> offerer)
{
var offererComponent = offerer.Comp;
var receiverComponent = receiver.Comp;
if (offerer == receiver || receiverComponent.IsInReceiveMode || !offererComponent.IsInOfferMode)
return false;
if (offererComponent.IsInReceiveMode && offererComponent.ReceivingFrom != receiver)
return false;
receiverComponent.IsInReceiveMode = true;
receiverComponent.ReceivingFrom = offerer;
Dirty(receiver, receiverComponent);
offererComponent.ReceivingFrom = receiver; // TODO this is ee shitcode, may not be necessary?
offererComponent.IsInOfferMode = false;
Dirty(offerer, offererComponent);
if (offererComponent.Item == null)
return false;
// Sender popup (client-side only)
_popup.PopupClient(
Loc.GetString("offer-item-try-give",
("item", Identity.Entity(offererComponent.GetRealEntity(EntityManager), EntityManager)),
("target", Identity.Entity(receiver, EntityManager))),
offerer,
offerer);
// Receiver popup (server side only, not predicted because recipient != local player)
_popup.PopupEntity(
Loc.GetString("offer-item-try-give-target",
("user", Identity.Entity(receiverComponent.ReceivingFrom.Value, EntityManager)),
("item", Identity.Entity(offererComponent.GetRealEntity(EntityManager), EntityManager))),
offerer,
receiver,
Popups.PopupType.Medium);
return true;
}
/// <summary>
/// Resets the <see cref="OfferItemComponent"/> of the user and the target
/// </summary>
protected void UnOffer(EntityUid thisEntity, OfferItemComponent offererComp)
{
if (!TryComp<HandsComponent>(thisEntity, out var hands) || _hands.GetActiveHand((thisEntity, hands)) is null)
return;
if (offererComp.ReceivingFrom is { } otherEntity && TryComp<OfferItemComponent>(otherEntity, out var otherOfferer))
{
// So this tries to figure out which of these entities do what...
// if A.OfferItemComponent.Item != null, then A is currently offering an item to A.OfferItemComponent.TargetOrOfferer
// If it is null, then it is ONLY being offered an item TO.
if (offererComp.Item != null && _net.IsServer)
{
_popup.PopupEntity(
Loc.GetString("offer-item-no-give",
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager)), // Floof - resolve virtual items
("target", Identity.Entity(otherEntity, EntityManager))),
thisEntity,
thisEntity);
_popup.PopupEntity(
Loc.GetString("offer-item-no-give-target",
("user", Identity.Entity(thisEntity, EntityManager)),
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager))),
thisEntity,
otherEntity);
}
else if (otherOfferer.Item != null && _net.IsServer)
{
_popup.PopupEntity(
Loc.GetString("offer-item-no-give",
("item", Identity.Entity(otherOfferer.GetRealEntity(EntityManager), EntityManager)), // Floof - resolve virtual items
("target", Identity.Entity(thisEntity, EntityManager))),
otherEntity,
otherEntity);
_popup.PopupEntity(
Loc.GetString("offer-item-no-give-target",
("user", Identity.Entity(otherEntity, EntityManager)),
("item", Identity.Entity(otherOfferer.GetRealEntity(EntityManager), EntityManager))),
otherEntity,
thisEntity);
}
otherOfferer.IsInOfferMode = false;
otherOfferer.IsInReceiveMode = false;
otherOfferer.Hand = null;
otherOfferer.ReceivingFrom = null;
otherOfferer.Item = null;
Dirty(otherEntity, otherOfferer);
}
offererComp.IsInOfferMode = false;
offererComp.IsInReceiveMode = false;
offererComp.Hand = null;
offererComp.ReceivingFrom = null;
offererComp.Item = null;
Dirty(thisEntity, offererComp);
}
/// <summary>
/// Cancels the transfer of the item
/// </summary>
protected void UnReceive(EntityUid receiver, OfferItemComponent? receiverComp = null, OfferItemComponent? offererComp = null)
{
if (!Resolve(receiver, ref receiverComp)
|| receiverComp.ReceivingFrom is not {} offerer
|| !Resolve(offerer, ref offererComp))
return;
// Idk why this check is here
if (!TryComp<HandsComponent>(receiver, out var hands) || _hands.GetActiveHand((receiver, hands)) == null || receiverComp.ReceivingFrom == null)
return;
// If offererComp.Item != null, then they are actively offering to TargetOrOfferer
// Normally this method is called right after a transfer is done, but this part can be called from SetInOfferMode when the player presses F again to cancel an ongoing offer
if (offererComp.Item != null)
{
_popup.PopupClient(
Loc.GetString("offer-item-no-give",
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager)), // Floof - resolve virtual items
("target", Identity.Entity(receiver, EntityManager))),
offerer,
offerer);
_popup.PopupEntity(
Loc.GetString("offer-item-no-give-target",
("user", Identity.Entity(receiverComp.ReceivingFrom.Value, EntityManager)), // Floof - resolve virtual items
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager))),
offerer,
receiver);
}
if (!offererComp.IsInReceiveMode)
{
offererComp.ReceivingFrom = null;
receiverComp.ReceivingFrom = null;
}
offererComp.Item = null;
offererComp.Hand = null;
receiverComp.IsInReceiveMode = false;
Dirty(receiver, receiverComp);
}
/// <summary>
/// Accepting the offer and receive item
/// </summary>
public void Receive(Entity<OfferItemComponent?> receiver)
{
if (!_timing.IsFirstTimePredicted)
return;
if (!Resolve(receiver, ref receiver.Comp))
return;
if (!TryComp<OfferItemComponent>(receiver.Comp.ReceivingFrom, out var offererComponent) ||
offererComponent.Hand == null ||
receiver.Comp.ReceivingFrom is not {} sender ||
!TryComp<HandsComponent>(receiver, out var hands))
return;
if (offererComponent.Item != null)
{
// Floof - check if there's something else handling it first
var realItem = offererComponent.GetRealEntity(EntityManager);
if (!TryHandleExtendedTransfer(sender, receiver, offererComponent.Item.Value, realItem)
&& !_hands.TryPickup(receiver, offererComponent.Item.Value, handsComp: hands))
{
_popup.PopupEntity(Loc.GetString("offer-item-full-hand"), receiver, receiver);
return;
}
_popup.PopupEntity(
Loc.GetString("offer-item-give",
("item", Identity.Entity(realItem, EntityManager)), // FLoof - resolve virtual items
("target", Identity.Entity(receiver, EntityManager))),
sender,
sender);
_popup.PopupEntity(
Loc.GetString("offer-item-give-other",
("user", Identity.Entity(receiver.Comp.ReceivingFrom.Value, EntityManager)),
("item", Identity.Entity(realItem, EntityManager)), // FLoof - resolve virtual items
("target", Identity.Entity(receiver, EntityManager))),
sender,
Filter.PvsExcept(sender, entityManager: EntityManager),
true);
}
offererComponent.Item = null;
UnReceive(receiver, receiver.Comp, offererComponent);
}
#endregion
/// <summary>
/// Returns true if <see cref="OfferItemComponent.IsInOfferMode"/> = true
/// </summary>
protected bool IsInOfferMode(Entity<OfferItemComponent?> ent)
{
return Resolve(ent, ref ent.Comp, false) && ent.Comp.IsInOfferMode;
}
private bool TryHandleExtendedTransfer(EntityUid user, EntityUid target, EntityUid offeredItem, EntityUid realItem)
{
var ev = new ItemTransferredEvent
{
User = user,
Target = target,
PassedItem = offeredItem,
RealItem = realItem,
};
RaiseLocalEvent(realItem, ref ev);
return ev.Handled;
}
}
/// <summary>
/// Raised on the entity that was transferred via item offering.
/// </summary>
[ByRefEvent]
public sealed class ItemTransferredEvent : HandledEntityEventArgs
{
public EntityUid User;
public EntityUid Target;
/// <summary>
/// The actual item being passed around. Can be a virtual item.
/// </summary>
public EntityUid PassedItem;
/// <summary>
/// If <see cref="PassedItem"/> is a virtual item, this field contains the real item that was transferred.
/// </summary>
public EntityUid? RealItem;
}

View File

@ -0,0 +1,66 @@
using Robust.Shared.GameStates;
namespace Content.Shared._Impstation.Clothing;
/// <summary>
/// Adds examine text to the entity that wears item, for making things obvious.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(WearerGetsExamineTextSystem))]
public sealed partial class WearerGetsExamineTextComponent : Component
{
/// <summary>
/// The LocId that specifies what category of object this is.
/// i.e. "pin" or "scarf"
/// Should be redefined on a per-category basis, naturally.
/// </summary>
[DataField("thing")]
public LocId Category = "obvious-thing-default";
/// <summary>
/// The LocId that specifies what member of the category this is.
/// i.e. "lesbian pride"
/// Can be used to define text colors that are copied to all things
/// which share this specifier (i.e. the other items of the same pride).
/// (And summarily, makes accessibility-based changes for these colors a cinch.)
/// Should be defined by each thing that has this component.
/// </summary>
[DataField("thingType")]
public LocId Specifier = "obvious-type-default";
/// <summary>
/// The LocId that will be added to any wearing entity's examination.
/// Typically only needs redefining on a per-category basis,
/// but items that should have totally-unique obvious text can simply specify them here.
/// </summary>
[DataField("examineText", required: true)]
public LocId ExamineOnWearer = "obvious-desc-default";
/// <summary>
/// Reference to the entity wearing this clothing.
/// </summary>
[DataField, AutoNetworkedField]
public EntityUid? Wearer;
/// <summary>
/// The string that is attached to this item's ExamineOnWearer.
/// Typically doesn't need to be redefined.
/// </summary>
[DataField]
public LocId PrefixExamineOnWearer = "obvious-prefix-wearing";
/// <summary>
/// If true, an entity with this item in any slot (i.e. in pockets) will gain the examine text,
/// instead of when just equipped as clothing.
/// Should be used sparingly only when truly appropriate; this is effectively a half-measure for lack of a special pin slot.
/// </summary>
[DataField]
public bool PocketEvident;
/// <summary>
/// If true, the entity's description will inform examiners what others will see on the wearer (before they equip it).
/// If the item is contraband, the item will also warn that displaying it may cause undue attention.
/// Keep this false for good-natured jokes (i.e. the pride cloaks having funny, non-pride names)
/// </summary>
[DataField]
public bool WarnExamine = true;
}

View File

@ -0,0 +1,111 @@
using Content.Shared.Clothing.Components;
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory.Events;
using Content.Shared.Contraband;
using Content.Shared._Impstation.Examine;
using System.Text;
namespace Content.Shared._Impstation.Clothing;
/// <summary>
/// Adds examine text to the entity that wears item, for making things obvious.
/// </summary>
public sealed class WearerGetsExamineTextSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WearerGetsExamineTextComponent, GotEquippedEvent>(OnEquipped);
SubscribeLocalEvent<WearerGetsExamineTextComponent, GotUnequippedEvent>(OnUnequipped);
SubscribeLocalEvent<WearerGetsExamineTextComponent, ExaminedEvent>(OnExamine);
}
private void OnEquipped(Entity<WearerGetsExamineTextComponent> entity, ref GotEquippedEvent args)
{
if (!TryComp(entity, out ClothingComponent? clothing))
return;
var isCorrectSlot = (clothing.Slots & args.SlotFlags) != Inventory.SlotFlags.NONE;
if (!entity.Comp.PocketEvident) //if it can't be evident in our pockets
{
// Make sure the clothing item was equipped to the right slot, and not just held in a hand.
if (!isCorrectSlot)
return;
}
entity.Comp.Wearer = args.Equipee;
Dirty(entity);
//GIVE THEM INSPECT TEXT
var obviousExamine = EnsureComp<ExtraExamineTextComponent>(args.Equipee);
obviousExamine.Lines.TryAdd(entity.Owner, //using try so that we don't cause an error if we move something from slot to slot
ConstructExamineText(entity, !isCorrectSlot, args.Equipee));
}
private string ConstructExamineText(Entity<WearerGetsExamineTextComponent> entity, bool prefixFallback, EntityUid affecting)
{
//parameters (these are the same between both constructions)
var user = Identity.Entity(affecting, EntityManager);
var nomen = Identity.Name(affecting, EntityManager);
var thing = Loc.GetString(entity.Comp.Category);
var type = Loc.GetString(entity.Comp.Specifier);
var stringSpec = entity.Comp.Specifier.ToString();
var shortType = stringSpec.Substring(stringSpec.LastIndexOf('-')); // necessary for working with colored text...
var prefix = Loc.GetString(prefixFallback ? "obvious-prefix-default" : entity.Comp.PrefixExamineOnWearer, // uses a different prefix if worn / displayed
("user", user),
("name", nomen),
("thing", thing),
("type", type));
var suffix = Loc.GetString(entity.Comp.ExamineOnWearer,
("user", user),
("name", nomen),
("thing", thing),
("type", type),
("short-type", shortType));
return prefix + " " + suffix;
}
private void OnUnequipped(Entity<WearerGetsExamineTextComponent> entity, ref GotUnequippedEvent args)
{
if (entity.Comp.Wearer is not { } wearer)
return;
if (TryComp(wearer, out ExtraExamineTextComponent? obviousExamine))
{
obviousExamine.Lines.Remove(entity.Owner);
}
entity.Comp.Wearer = null;
Dirty(entity);
}
private void OnExamine(Entity<WearerGetsExamineTextComponent> entity, ref ExaminedEvent args)
{
var currentlyWorn = entity.Comp.Wearer != null;
var outString = new StringBuilder(Loc.GetString(currentlyWorn ? "obvious-on-item-currently" : "obvious-on-item",
("used", Loc.GetString(entity.Comp.PocketEvident ? "obvious-reveal-pockets" : "obvious-reveal-default")),
("thing", entity.Comp.Category),
("me", Identity.Entity(entity, EntityManager))));
if (entity.Comp.WarnExamine)
{
if (!currentlyWorn && TryComp(entity, out ContrabandComponent? contra)) // if the item's contra and we're not wearing it yet
{
var contraLocId = "obvious-on-item-contra-" + contra.Severity; // apply additional text if the item is contraband to note that displaying it might be really bad
if (Loc.HasString(contraLocId)) // saves us the trouble of making a switch block for this
outString.Append(" " + Loc.GetString(contraLocId));
}
var affecting = currentlyWorn ? entity.Comp.Wearer.GetValueOrDefault() : args.Examiner;
var testOut = ConstructExamineText(entity, false, affecting);
outString.Append("\n" + Loc.GetString("obvious-on-item-for-others",
("will", currentlyWorn ? "can" : "will"), // i love hardcoding strings it's my favorite thing ever
("output", testOut)));
}
args.PushMarkup(outString.ToString());
}
}

View File

@ -0,0 +1,40 @@
using Robust.Shared.GameStates;
namespace Content.Shared._Impstation.Examine;
[RegisterComponent, NetworkedComponent]
public sealed partial class DetailedInspectComponent : Component
{
[DataField]
public LocId VerbText = "verbs-detailed-inspect";
[DataField]
public LocId VerbMessage = "verbs-detailed-inspect-message";
[DataField(required: true)]
public List<LocId> ExamineText;
/// <summary>
/// Whether or not the entries in ExamineText are separated by linebreaks.
/// </summary>
[DataField]
public bool LineBreak = true;
/// <summary>
/// Whether or not the entries in ExamineText are preceded by ticks.
/// </summary>
[DataField]
public bool TickEntries = false;
/// <summary>
/// Whether or not entries in the list are numbered.
/// </summary>
[DataField]
public bool NumberedEntries = false;
/// <summary>
/// Rooted directory of the icon for the verb.
/// </summary>
[DataField]
public string Icon = "/Textures/Interface/VerbIcons/dot.svg.192dpi.png";
}

View File

@ -0,0 +1,50 @@
using Content.Shared.Examine;
using Content.Shared.Verbs;
using Robust.Shared.Network;
using Robust.Shared.Utility;
namespace Content.Shared._Impstation.Examine;
public sealed partial class DetailedInspectSystem : EntitySystem
{
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DetailedInspectComponent, GetVerbsEvent<ExamineVerb>>(OnGetVerb);
}
public void OnGetVerb(Entity<DetailedInspectComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
{
if (!args.CanInteract || !args.CanAccess || !_net.IsServer)
return;
var msg = new FormattedMessage();
var numberedIndex = 1;
foreach (var locId in ent.Comp.ExamineText)
{
if (ent.Comp.TickEntries)
msg.AddMarkupOrThrow("- ");
if (ent.Comp.NumberedEntries)
{
msg.AddMarkupOrThrow($"{numberedIndex}. ");
numberedIndex++;
}
msg.AddMarkupOrThrow(Loc.GetString(locId));
if (ent.Comp.LineBreak)
msg.PushNewline();
else
msg.AddMarkupOrThrow(" ");
}
_examine.AddDetailedExamineVerb(args, ent.Comp, msg, Loc.GetString(ent.Comp.VerbText), ent.Comp.Icon, Loc.GetString(ent.Comp.VerbMessage));
}
}

View File

@ -0,0 +1,24 @@
using Robust.Shared.GameStates;
using Content.Shared._Impstation.Clothing;
namespace Content.Shared._Impstation.Examine;
/// <summary>
/// Adds examine text to the entity, intentionally "obvious details".
/// Like, that's it. It's basic -- all it does is add the lines to the attached entity.
/// This is particularly used for assigning players unique examine text.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(ExtraExamineTextSystem), typeof(WearerGetsExamineTextSystem))]
public sealed partial class ExtraExamineTextComponent : Component
{
/// <summary>
/// The LocIds that will be added to the attached entity's examination.
///
/// The key is the source of the line, and the value is the text
/// (built by the component that creates this one).
/// </summary>
[DataField, AutoNetworkedField]
public Dictionary<EntityUid, LocId> Lines { get; set; } = new();
}

View File

@ -0,0 +1,33 @@
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
namespace Content.Shared._Impstation.Examine;
/// <summary>
/// Adds examine text to the entity, intentionally "obvious details".
/// Like, that's it. It's basic -- all it does is add the line to the attached entity.
/// This is particularly used for assigning players unique examine text.
/// </summary>
public sealed class ExtraExamineTextSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ExtraExamineTextComponent, ExaminedEvent>(OnExamine);
}
private void OnExamine(Entity<ExtraExamineTextComponent> entity, ref ExaminedEvent args)
{
if (entity.Comp.Lines.Count == 0)
{
RemCompDeferred<ExtraExamineTextComponent>(entity); // no more need for me!
return;
}
foreach (var l in entity.Comp.Lines)
{
args.PushMarkup(l.Value);
}
}
}

View File

@ -0,0 +1,8 @@
namespace Content.Shared._Starlight.Flash.Components;
[RegisterComponent]
public sealed partial class FlashModifierComponent : Component
{
[DataField]
public float Modifier = 1f;
}

View File

@ -0,0 +1,51 @@
namespace Content.Shared.Humanoid;
public static class EyeColor
{
public const float ShadekinBrightness = 0.251f;
public static bool VerifyShadekin(Color color)
{
var colorHsv = Color.ToHsv(color);
if (colorHsv.Z > ShadekinBrightness)
return false;
return true;
}
public static Color MakeShadekinValid(Color color)
{
var hsv = Color.ToHsv(color);
hsv.Z = Math.Clamp(hsv.Z, 0, ShadekinBrightness);
return Color.FromHsv(hsv);
}
public static bool VerifyEyeColor(HumanoidEyeColor type, Color color)
{
return type switch
{
HumanoidEyeColor.Shadekin => VerifyShadekin(color),
_ => false,
};
}
public static Color ValidEyeColor(HumanoidEyeColor type, Color color)
{
return type switch
{
HumanoidEyeColor.Shadekin => MakeShadekinValid(color),
_ => color
};
}
}
public enum HumanoidEyeColor : byte
{
Shadekin,
}
[ByRefEvent]
public record struct EyeColorInitEvent();

View File

@ -0,0 +1,45 @@
using Content.Shared.Alert;
using Content.Shared.FixedPoint;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared._Starlight;
#region Shadekin
[RegisterComponent, NetworkedComponent, AutoGenerateComponentPause, AutoGenerateComponentState]
public sealed partial class ShadekinComponent : Component
{
[DataField]
public ProtoId<AlertPrototype> ShadekinAlert = "Shadekin";
[ViewVariables(VVAccess.ReadOnly), AutoPausedField]
public TimeSpan NextUpdate = TimeSpan.Zero;
[DataField]
public TimeSpan UpdateCooldown = TimeSpan.FromSeconds(1f);
[AutoNetworkedField, ViewVariables]
public ShadekinState CurrentState { get; set; } = ShadekinState.Dark;
[DataField("thresholds", required: true)]
public SortedDictionary<FixedPoint2, ShadekinState> Thresholds = new();
/// <summary>
/// whether to flicker lights or not. default on
/// </summary>
[DataField] public bool DoLightFlicker = true;
}
[Serializable, NetSerializable]
public enum ShadekinState : byte
{
Invalid = 0,
Dark = 1,
Low = 2,
Annoying = 3,
High = 4,
Extreme = 5
}
#endregion

View File

@ -0,0 +1,29 @@
- files: ["wurble.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/wurble.ogg"
- files: ["mar.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/mar.ogg"
- files: ["scream_f1.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_f1.ogg"
- files: ["scream_f2.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_f2.ogg"
- files: ["scream_m1.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_m1.ogg"
- files: ["scream_m2.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_f2.ogg"

Binary file not shown.

Binary file not shown.

View File

@ -1,79 +1,4 @@
Entries:
- author: Toby222
changes:
- message: Removed footprint prediction (for now)
type: Remove
id: 2074
time: '2026-01-16T19:07:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5224
- author: Velcroboy
changes:
- message: Prisoners can find dull bread knives in the ChefVend.
type: Tweak
id: 2075
time: '2026-01-17T21:13:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5234
- author: Halo3moth
changes:
- message: The T1 armored vest (slim) can now once again be picked in security loadouts.
type: Add
id: 2076
time: '2026-01-17T21:36:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5220
- author: biddygelson
changes:
- message: 'Academy: added anti-meteor zones and anti-anomaly zone, AI restoration
console in Mystagogue, Robotics Console in robo, fishing hole added to park,
materials is cargo at roundstart.'
type: Add
- message: 'Academy: station starts with distro and waste enabled, spare atmos chambers
start as vacuums, split artifacts'' APCs for power management, botany has more
trays and is slightly larger, department-front holopads in the department.'
type: Tweak
id: 2077
time: '2026-01-18T01:54:56.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5130
- author: DisposableCrewmember42
changes:
- message: You can no longer drink the deep fryer.
type: Fix
id: 2078
time: '2026-01-18T04:40:48.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5238
- author: snowywinters
changes:
- message: Reinforced cameras can now be built! They have additional HP and are
more resistant to explosions and meteors.
type: Add
- message: The AI has its own section in the security cameras console.
type: Add
id: 2079
time: '2026-01-18T17:18:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5027
- author: Dorragon
changes:
- message: Ready Manifest added to the lobby
type: Add
id: 2080
time: '2026-01-18T18:47:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5187
- author: MilonPL
changes:
- message: Added a new traits system, supporting conditions and new effects. Make
sure to check out the Traits tab in the character editor!
type: Add
- message: All character traits have been reset.
type: Remove
id: 2081
time: '2026-01-20T11:49:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5208
- author: pootslap
changes:
- message: You can now examine character descriptions from much further away.
type: Tweak
id: 2082
time: '2026-01-20T11:49:48.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5219
- author: Eternally-Confused
changes:
- message: (TEST MERGE) Space pens now contain a chemical called Stabilizine instead
@ -4369,4 +4294,80 @@
id: 2574
time: '2026-07-20T00:24:43.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6310
- author: kotobdev
changes:
- message: The Ardent Censer no longer requires fuel for deconversions.
type: Tweak
id: 2575
time: '2026-07-20T17:38:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5016
- author: Halo3rat, kotobdev
changes:
- message: The Freighter Crew's Jumpsuit is now available in the AutoDrobe, for
those who value their dental hygiene.
type: Add
id: 2576
time: '2026-07-20T20:06:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6331
- author: Mnemotechnician, kotobdev, ShepardToTheStars
changes:
- message: You can now offer items to other players by pressing F, and then clicking
on them! They can accept by clicking on the alert on the side of their screen.
type: Add
id: 2577
time: '2026-07-20T20:13:58.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5597
- author: ShepardToTheStars
changes:
- message: Glimmer probers can once again turn on and lock into place when glimmer
is over 750.
type: Add
- message: Glimmer prober explosions are 1.5x bigger if glimmer is over 900. You
better build drainers! :)
type: Tweak
- message: The oracle can now give normality crystals when completing her requests.
type: Tweak
id: 2578
time: '2026-07-20T20:29:02.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6292
- author: keekee38
changes:
- message: Added the novice mark, to help show that you're new! It is on intern
roles by default, and optional for everyone
type: Add
- message: Some clothes now have examine text, in particular pride clothes.
type: Tweak
id: 2579
time: '2026-07-20T22:08:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6118
- author: Coryler
changes:
- message: Shadekin has arrived in the DeltaV sector.
type: Add
id: 2580
time: '2026-07-20T22:10:50.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5481
- author: sowelipililimute
changes:
- message: The crew monitor now reports global coordinate positions.
type: Tweak
id: 2581
time: '2026-07-20T22:20:12.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6326
- author: keekee38
changes:
- message: Vulpkanins can yip now.
type: Tweak
id: 2582
time: '2026-07-20T22:21:24.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6301
- author: pootslap
changes:
- message: Improvised shotgun shells use the old upstream crafting recipe.
type: Tweak
- message: The improvised shotgun is craftable once again.
type: Fix
id: 2583
time: '2026-07-20T22:22:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6327
Order: 1

View File

@ -16,3 +16,4 @@ delta-chat-emote-name-harpysquish = Squish
delta-chat-emote-name-quack = Quack
delta-chat-emote-name-squawk = Squawk
delta-chat-emote-name-horn = Horn
delta-chat-emote-name-yip = Yip

View File

@ -0,0 +1,154 @@
# Ears
marking-EarsShadekinMotley = Motley Ears
marking-EarsShadekinMotley-shadowkin = Ears
marking-EarsShadekinMotley-motley_secondary = Pattern
marking-EarsShadekinShady = Dark Ears
marking-EarsShadekinShady-shady = Ears
marking-EarsShadekinStriped = Striped Ears
marking-EarsShadowkinStriped-shadowkin = Ears
marking-EarsShadowkinStriped-shadowkin_stripes = Stripes
marking-EarsShadekinPiercingAll = Ears with Piercings
marking-EarsShadekinPiercingAll-shadowkin = Ears
marking-EarsShadekinPiercingAll-piercing_all = Piercings
marking-EarsShadekinPiercingLeft = Ears with Piercing (L)
marking-EarsShadekinPiercingLeft-shadowkin = Ears
marking-EarsShadekinPiercingLeft-piercing_left = Piercing
marking-EarsShadekinPiercingRight = Ears with Piercing (R)
marking-EarsShadekinPiercingRight-shadowkin = Ears
marking-EarsShadekinPiercingRight-piercing_right = Piercing
marking-EarsShadekinRingedAll = Ears with Rings
marking-EarsShadekinRingedAll-shadowkin = Ears
marking-EarsShadekinRingedAll-ringed_all_secondary = Rings
marking-EarsShadekinRingedLeft = Ears with Ring (L)
marking-EarsShadekinRingedLeft-shadowkin = Ears
marking-EarsShadekinRingedLeft-ringed_left_secondary = Ring
marking-EarsShadekinRingedRight = Ears with Ring (R)
marking-EarsShadekinRingedRight-shadowkin = Ears
marking-EarsShadekinRingedRight-ringed_right_secondary = Ring
marking-EarsShadekinGauzedAll = Gauzed Ears
marking-EarsShadekinGauzedAll-shadowkin = Ears
marking-EarsShadekinGauzedAll-gauze_ear_all_default = Gauze
marking-EarsShadekinGauzedLeft = Ear Bandage (L)
marking-EarsShadekinGauzedLeft-shadowkin = Ears
marking-EarsShadekinGauzedLeft-gauze_ear_l_default = Bandage
marking-EarsShadekinGauzedRight = Ear Bandage (R)
marking-EarsShadekinGauzedRight-shadowkin = Ears
marking-EarsShadekinGauzedRight-gauze_ear_r_default = Bandage
marking-EarsShadekinFluffy = Fluffy Ears
marking-EarsShadekinFluffy-fluffy_default = Ears
marking-EarsShadekinFluffyButterfly = Fluffy Ears, Butterfly
marking-EarsShadekinFluffyButterfly-fluffy_default = Ears
marking-EarsShadekinFluffyButterfly-fluffy_butterfly = Pattern
marking-EarsShadekinFluffyCowling = Fluffy Ears, Spotted
marking-EarsShadekinFluffyCowling-fluffy_default = Ears
marking-EarsShadekinFluffyCowling-fluffy_cowling = Pattern
marking-EarsShadekinFluffyCrow = Fluffy Ears, Crow
marking-EarsShadekinFluffyCrow-fluffy_default = Ears
marking-EarsShadekinFluffyCrow-fluffy_crow = Pattern
marking-EarsShadekinFluffyMotley = Fluffy Ears, Bright
marking-EarsShadekinFluffyMotley-fluffy_default = Ears
marking-EarsShadekinFluffyMotley-fluffy_motley = Pattern
marking-EarsShadekinFluffySpidy = Fluffy Ears, Spidy
marking-EarsShadekinFluffySpidy-fluffy_default = Ears
marking-EarsShadekinFluffySpidy-fluffy_spidy = Pattern
marking-EarsShadekinFluffyRingedAll = Fluffy Ears, with Rings
marking-EarsShadekinFluffyRingedAll-fluffy_default = Ears
marking-EarsShadekinFluffyRingedAll-fluffy_ringed_all = Rings
marking-EarsShadekinFluffyRingedLeft = Fluffy Ears, with Ring (L)
marking-EarsShadekinFluffyRingedLeft-fluffy_default = Ears
marking-EarsShadekinFluffyRingedLeft-fluffy_ringed_left = Ring
marking-EarsShadekinFluffyRingedRight = Fluffy Ears, with Ring (R)
marking-EarsShadekinFluffyRingedRight-fluffy_default = Ears
marking-EarsShadekinFluffyRingedRight-fluffy_ringed_right = Ring
marking-EarsShadekinSaggy = Drooping Ears
marking-EarsShadekinSaggy-saggy_default = Ears
marking-EarsShadekinSaggyBrawly = Drooping Ears, Patterned
marking-EarsShadekinSaggyBrawly-saggy_default = Ears
marking-EarsShadekinSaggyBrawly-saggy_brawly = Pattern
marking-EarsShadekinSaggyZebra = Drooping Ears, Striped
marking-EarsShadekinSaggyZebra-saggy_default = Ears
marking-EarsShadekinSaggyZebra-saggy_zebra = Stripes
marking-EarsShadekinSaggyGradient = Drooping Ears, Gradient
marking-EarsShadekinSaggyGradient-saggy_default = Ears
marking-EarsShadekinSaggyGradient-saggy_gradient = Gradient
marking-EarsShadekinSaggyGauzedAll = Drooping Ears, Gauzed
marking-EarsShadekinSaggyGauzedAll-saggy_default = Ears
marking-EarsShadekinSaggyGauzedAll-saggy_gauze_all = Gauze
marking-EarsShadekinSaggyGauzedLeft = Drooping Ears, Ear Bandage (L)
marking-EarsShadekinSaggyGauzedLeft-saggy_default = Ears
marking-EarsShadekinSaggyGauzedLeft-saggy_gauze_l = Bandage
marking-EarsShadekinSaggyGauzedRight = Drooping Ears, Ear Bandage (R)
marking-EarsShadekinSaggyGauzedRight-saggy_default = Ears
marking-EarsShadekinSaggyGauzedRight-saggy_gauze_r = Bandage
marking-EarsShadekinShort = Short Ears
marking-EarsShadekinShort-short_default = Ears
marking-EarsShadekinShortButterfly = Short Ears, Decorated
marking-EarsShadekinShortButterfly-short_default = Ears
marking-EarsShadekinShortButterfly-short_butterfly = Pattern
marking-EarsShadekinShortRingedAll = Short Ears, with Rings
marking-EarsShadekinShortRingedAll-short_default = Ears
marking-EarsShadekinShortRingedAll-short_ringed_all = Rings
marking-EarsShadekinShortRingedLeft = Short Ears, with Ring (L)
marking-EarsShadekinShortRingedLeft-short_default = Ears
marking-EarsShadekinShortRingedLeft-short_ringed_left = Ring
marking-EarsShadekinShortRingedRight = Short Ears, with Ring (R)
marking-EarsShadekinShortRingedRight-short_default = Ears
marking-EarsShadekinShortRingedRight-short_ringed_right = Ring
marking-EarsShadekinBull = Straight Ears
marking-EarsShadekinBull-bull_default = Ears
marking-EarsShadekinBullSmooth = Straight Ears, Outlined
marking-EarsShadekinBullSmooth-bull_default = Ears
marking-EarsShadekinBullSmooth-bull_smooth = Inner ears
marking-EarsShadekinAqua = Aqua Ears
marking-EarsShadekinAqua-aqua_default = Ears
marking-EarsShadekinAquaIncolor = Aqua Ears, Colored
marking-EarsShadekinAquaIncolor-aqua_default = Ears
marking-EarsShadekinAquaIncolor-aqua_incolor = Inner ears
# Tails
marking-TailShadekin = Long Tail
marking-TailShadekinBig = Big Tail
marking-TailShadekinShorter = Short Tail
marking-TailShadekinShorter-shadekin_shorter_over = Tail
marking-TailShadekinShorterBrush = Short Tail, Furry
marking-TailShadekinShorterBrush-shadekin_shorter_over = Tail
marking-TailShadekinShorterBrush-shorter_brush_over = Tail tip
marking-TailShadekinMedium = Medium Tail
marking-TailShadekinMedium-shadekin_medium_front = Tail
marking-TailShadekinMediumTwoColored = Medium Tail, Two-Toned
marking-TailShadekinMediumTwoColored-shadekin_medium_front = Tail
marking-TailShadekinMediumTwoColored-medium_twocolored_over = Tail underside
# Overlays
marking-BodyShadekinArrow = Arrow Marking
marking-BodyShadekinArrow-body_arrow = Marking
marking-BodyShadekinBlackHole = Black Hole Marking
marking-BodyShadekinBlackHole-body_blackhole = Marking
marking-BodyShadekinBrace = Bracelet Marking
marking-BodyShadekinBrace-body_brace = Marking
marking-BodyShadekinBrawly = Combat Marking
marking-BodyShadekinBrawly-body_brawly = Marking
marking-BodyShadekinHeart = Heart Marking
marking-BodyShadekinHeart-body_heart = Marking
marking-BodyShadekinInk = Ink Marking
marking-BodyShadekinInk-body_ink = Marking
marking-BodyShadekinInk2 = Ink Marking 2
marking-BodyShadekinInk2-body_ink2 = Marking
marking-BodyShadekinInk3 = Ink Marking 3
marking-BodyShadekinInk3-body_ink3 = Marking
marking-BodyShadekinInk4 = Ink Marking 4
marking-BodyShadekinInk4-body_ink4 = Marking
marking-BodyShadekinInk5 = Ink Marking 5
marking-BodyShadekinInk5-body_ink5 = Marking
marking-BodyShadekinInk6 = Spiritual Ink Marking
marking-BodyShadekinInk6-body_ink6 = Marking
marking-BodyShadekinInkAnim = Spiral Ink Marking
marking-BodyShadekinInkAnim-body_ink_anim = Marking
marking-BodyShadekinLines = Lines Marking
marking-BodyShadekinLines-body_lines = Marking
marking-BodyShadekinNeck = Neck Marking
marking-BodyShadekinNeck-body_neck = Marking
marking-BodyShadekinShield = Protective Marking
marking-BodyShadekinShield-body_shield = Marking
marking-BodyShadekinVacuum = Open Marking
marking-BodyShadekinVacuum-body_vacuum = Marking

View File

@ -0,0 +1,17 @@
offer-item-empty-hand = You don't have anything in your hand to give!
offer-item-full-hand = Your hand isn't free to receive the item.
offer-item-try-give = You offer {THE($item)} to {$target}.
offer-item-try-give-target = {CAPITALIZE(THE($user))} offers you {THE($item)}.
offer-item-give = You handed {THE($item)} to {$target}.
offer-item-give-other = {CAPITALIZE(THE($user))} handed {THE($item)} to {$target}.
offer-item-give-target = {CAPITALIZE(THE($user))} handed you {THE($item)}.
offer-item-no-give = You stop offering {THE($item)} to {$target}.
offer-item-no-give-target = {CAPITALIZE(THE($user))} is no longer offering {THE($item)} to you.
alerts-offer-name = Accept Offer
alerts-offer-desc = Click this alert to accept the item offered to you.

View File

@ -0,0 +1,65 @@
obvious-on-item = When {$used}, { SUBJECT($me) } will be [color=white]obvious[/color] to casual examination.
obvious-on-item-currently = { CAPITALIZE(SUBJECT($me)) } { CONJUGATE-BE($me) } [color=white]obvious[/color] to casual examination.
obvious-on-item-for-others = [italic][color=#777777]Others {$will} see:[/color] "{$output}"[/italic]
obvious-reveal-default = worn
obvious-reveal-pockets = worn or pocketed
obvious-on-item-contra-Syndicate = Might make you seem [color=#ff0000]evil[/color].
obvious-on-item-contra-Magical = Might make you seem [color=blue]mystical[/color].
obvious-on-item-contra-Major = Don't be surprised if [color=#cb0000]some people[/color] aren't a fan.
obvious-prefix-default = { CAPITALIZE(SUBJECT($user)) } { CONJUGATE-HAVE($user) }
obvious-prefix-wearing = { CAPITALIZE(SUBJECT($user)) } { CONJUGATE-BE($user) } wearing
## general descriptions
obvious-desc-default = { INDEFINITE($short-type) } { $type } { $thing }.
obvious-desc-colors = { INDEFINITE($thing) } { $thing } in { $type } colors.
obvious-desc-proves = { INDEFINITE($thing) } [color=white]{ $thing }[/color] that proves { SUBJECT($user) } { CONJUGATE-BE($user) } { INDEFINITE($short-type) } { $type }.
## item categories
obvious-thing-default = [italic]something-or-another[/italic]
obvious-thing-cloak = cloak
obvious-thing-pin = pin
obvious-thing-scarf = scarf
obvious-thing-badge = badge
obvious-thing-armband = armband
obvious-thing-medal = medal
## item types
obvious-type-default = [italic]nothing[/italic]
# prides
obvious-type-pride = [color=#d479d4]LGBTQ[/color] [color=white]pride[/color]
obvious-type-pride-aro = [color=#3DA542]aromantic[/color] [color=white]pride[/color]
obvious-type-pride-ace = [color=#efefef]asexual[/color] [color=#800080]pride[/color]
obvious-type-pride-aroace = [color=#efc337]aroace[/color] [color=#45bcee]pride[/color]
obvious-type-pride-lesbian = [color=#EF7627]lesbian[/color] [color=#B55690]pride[/color]
obvious-type-pride-bi = [color=#D60270]bisexual[/color] [color=#0038A8]pride[/color]
obvious-type-pride-pan = [color=#FF218C]pansexual[/color] [color=#21B1FF]pride[/color]
obvious-type-pride-gay = [color=#078D70]gay[/color] [color=#5049CC]pride[/color]
obvious-type-pride-omni = [color=#FE9ACE]omnisexual[/color] [color=8EA6FF]pride[/color]
obvious-type-pride-bear = [color=#FDDC62]bear[/color] [color=#613704]pride[/color]
obvious-type-pride-intersex = [color=#FFD800]intersex[/color] [color=#7902AA]pride[/color]
obvious-type-pride-nonbinary = [color=#FCF434]nonbinary[/color] [color=#9C59D1]pride[/color]
obvious-type-pride-trans = [color=#5BCEFA]transgender[/color] [color=#F5A9B8]pride[/color]
obvious-type-pride-gf = [color=#FF76A4]genderfluid[/color] [color=#2F3CBE]pride[/color]
obvious-type-pride-aut = [color=#FFD700]autism[/color] [color=white]pride[/color]
obvious-type-pride-straightally = [color=#7c7c7c]straight[/color] [color=#d479d4]LGBTQ ally[/color]
obvious-type-pride-gq = [color=#B57EDC]genderqueer[/color] [color=#4A8123]pride[/color]
# lawyers
obvious-type-law = [color=white]certified[/color] [color=#FFD700]lawyer[/color]
obvious-type-law-defense = [color=white]certified[/color] [color=#00C0C0]defense attorney[/color]
obvious-type-law-prosecution = [color=white]certified[/color] [color=#FF2222]prosecuting attorney[/color]
## SPECIFIC DESCRIPTIONS (skips the above description-builders)
obvious-x-scarf-lesbian-long = some [color=#EF7627]long[/color] [color=white]ba[/color][color=#B55690]con[/color].
obvious-x-medal-nothing = a [color=#FFD700]gleaming medal[/color]!
# medals should be in the description building functions but there's too many of them and this feature is already over-scope
# imp only items
obvious-x-pin-straight = a [color=#7c7c7c]straight[/color] [color=white]pride[/color] pin... [italic]Ew.[/italic]
obvious-x-cloak-straight = a cloak in the [color=#7c7c7c]straight[/color] [color=white]pride[/color] colors... [italic]Ew.[/italic]
obvious-x-pin-novice = a [color=#F4EE12]novice[/color] [color=#1CAC99]mark[/color], identifying as [color=#efefef]unskilled[/color]. [color=#1CAC99][italic]Be patient and considerate with { OBJECT($user) }.[/italic][/color]

View File

@ -0,0 +1,58 @@
# Sad
names-shadekin-dataset-1 = Fragile
names-shadekin-dataset-2 = Heartbreak
names-shadekin-dataset-3 = Inferior
names-shadekin-dataset-4 = Lone
names-shadekin-dataset-5 = Lonesome
names-shadekin-dataset-6 = Loss
names-shadekin-dataset-7 = Solitary
names-shadekin-dataset-8 = Solitude
names-shadekin-dataset-9 = Sorrow
names-shadekin-dataset-10 = Shade
# Angry
names-shadekin-dataset-11 = Fear
names-shadekin-dataset-12 = Fearful
names-shadekin-dataset-13 = Fury
names-shadekin-dataset-14 = Pain
names-shadekin-dataset-15 = Rage
names-shadekin-dataset-16 = Rush
names-shadekin-dataset-17 = Wrath
# Happy
names-shadekin-dataset-18 = Calm
names-shadekin-dataset-19 = Content
names-shadekin-dataset-20 = Contented
names-shadekin-dataset-21 = Happy
names-shadekin-dataset-22 = Hope
names-shadekin-dataset-23 = Joyous
names-shadekin-dataset-24 = Lovely
names-shadekin-dataset-25 = Peace
names-shadekin-dataset-26 = Peaceful
names-shadekin-dataset-27 = Quiet
names-shadekin-dataset-28 = Serene
names-shadekin-dataset-29 = Serenity
names-shadekin-dataset-30 = Tranquil
names-shadekin-dataset-31 = Tranquility
# Memory
names-shadekin-dataset-32 = Dillusioned
names-shadekin-dataset-33 = Forgotten
names-shadekin-dataset-34 = Focusless
names-shadekin-dataset-35 = Lost
names-shadekin-dataset-36 = Memory
names-shadekin-dataset-37 = Recollection
names-shadekin-dataset-38 = Remembrance
names-shadekin-dataset-39 = Reminisce
names-shadekin-dataset-40 = Reminiscence
# Other
names-shadekin-dataset-41 = Apathy
names-shadekin-dataset-42 = Collected
names-shadekin-dataset-43 = Curiosity
names-shadekin-dataset-44 = Free
names-shadekin-dataset-45 = Interest
names-shadekin-dataset-46 = Jax
names-shadekin-dataset-47 = Still
names-shadekin-dataset-48 = Unbound
names-shadekin-dataset-49 = Shadows

View File

@ -0,0 +1,5 @@
chat-emote-name-marr = Marr
chat-emote-name-wurble = Wurble
chat-emote-msg-marr = marrs!
chat-emote-msg-wurble = wurbles!

View File

@ -0,0 +1,14 @@
alerts-shadekin-name = Light Exposure
alerts-shadekin-desc = How much light is around you.
shadekin-alert-0 = [color=green]Light Exposure: Darkness...[/color]
The darkness is nice... It's like home... I feel my wounds healing...
shadekin-alert-1 = [color=green]Light Exposure: Low[/color]
shadekin-alert-2 = [color=green]Light Exposure: Annoying[/color]
The light is annoying in this place... I feel my wounds will not heal properly...
shadekin-alert-3 = [color=green]Light Exposure: High[/color]
Too many lights... too many! I feel exausted...
shadekin-alert-4 = [color=green]Light Exposure:[/color] [color=red]EXTREME[/color]
LIGHTS... I NEED DARKNESS! It burns!
phase-fail-generic = I can't phase!

View File

@ -0,0 +1 @@
species-name-shadekin = Shadekin

View File

@ -0,0 +1,8 @@
trait-clumsy-name = Clumsy
trait-clumsy-desc = You are a bit accident-prone
trait-highlightsensitivity-name = High Light Sensitivity
trait-highlightsensitivity-desc = You are much more sensitive to light than most shadekins
trait-extremelightsensitivity-name = Extreme Light Sensitivity
trait-extremelightsensitivity-desc = You are extremely more sensitive to light than most shadekins.

View File

@ -6,6 +6,7 @@
order:
- category: Health
- category: Stamina
- alertType: Shadeskin # Starlight
- alertType: SuitPower
- category: Internals
- alertType: Fire
@ -28,6 +29,7 @@
- alertType: Rooted
- alertType: Pacified
- alertType: Stealthy
- alertType: Offer # Floofstation - port from EE
- type: entity
id: AlertSpriteView

View File

@ -149,7 +149,7 @@
- type: Speech
speechSounds: Vulpkanin
speechVerb: Vulpkanin
allowedEmotes: [ 'Bark', 'Snarl', 'Whine', 'Howl', 'Growl' ]
allowedEmotes: [ 'Bark', 'Snarl', 'Whine', 'Howl', 'Growl', 'Yip' ] # DeltaV - Added Yip Emote
- type: Vocal
sounds:
Male: MaleVulpkanin

View File

@ -97,3 +97,4 @@
type: HumanoidMarkingModifierBoundUserInterface
enum.StrippingUiKey.Key:
type: StrippableBoundUserInterface
- type: OfferItem # Floofstation

View File

@ -6,6 +6,7 @@
PassengerIDCard: 5
ClothingHeadsetGrey: 5
ClothingHeadsetService: 5 # Delta-V
ClothingNeckNoviceMark: 5 # imp
RubberStampApproved: 1
RubberStampDenied: 1
BoxFolderPlasticClipboardEmpty: 2

View File

@ -72,6 +72,7 @@
ClothingUniformJumpskirtWaitstaffFormal: 2
ClothingUniformJumpsuitWaitstaffFormal: 2
ClothingUniformJumpsuitWorkvest: 2
ClothingUniformJumpsuitFreighterCrew: 2
ClothingOuterDusterCoat: 2
ClothingOuterCoatNavalCoat: 2
ClothingNeckCloakWitchCloak: 2

View File

@ -136,7 +136,7 @@
sprite: Clothing/Neck/Cloaks/miner.rsi
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakTrans
name: vampire cloak
description: Worn by high ranking vampires of the transylvanian society of vampires.
@ -145,6 +145,8 @@
sprite: Clothing/Neck/Cloaks/trans.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakTrans # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-trans
- type: entity
parent: ClothingNeckBase
@ -214,7 +216,7 @@
proto: alien
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakAce
name: pilot's cloak
description: Cloak awarded to Nanotrasen's finest space aces.
@ -223,9 +225,11 @@
sprite: Clothing/Neck/Cloaks/ace.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakAce # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-ace
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakAro
name: werewolf cloak
description: This cloak lets others know you're a lone wolf.
@ -234,9 +238,11 @@
sprite: Clothing/Neck/Cloaks/aro.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakAro # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aro
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakAroace
name: aeropilot's cloak # thank you happyman442 this was the best name idea ever
description: Cloak awarded to Nanotrasen's finest pilots on planets with inhabitable atmospheres.
@ -245,9 +251,11 @@
sprite: Clothing/Neck/Cloaks/aroace.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakAroace # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aroace
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakBi
name: poison cloak
description: The purple color is a clear indicator you are poisonous.
@ -256,9 +264,11 @@
sprite: Clothing/Neck/Cloaks/bi.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakBi # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-bi
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakIntersex
name: cyclops cloak
description: The circle on this cloak represents a cyclops' eye.
@ -267,9 +277,11 @@
sprite: Clothing/Neck/Cloaks/intersex.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakIntersex # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-intersex
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakLesbian
name: poet cloak
description: This cloak belonged to an ancient poet, you forgot which one.
@ -278,9 +290,11 @@
sprite: Clothing/Neck/Cloaks/les.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakLesbian # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-lesbian
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakGay
name: multi-level marketing cloak
description: This cloak is highly sought after in the Nanotrasen Marketing Offices.
@ -289,9 +303,11 @@
sprite: Clothing/Neck/Cloaks/gay.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakGay # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-gay
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakEnby
name: treasure hunter cloak
description: This cloak belonged to a greedy treasure hunter.
@ -300,9 +316,11 @@
sprite: Clothing/Neck/Cloaks/enby.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakEnby # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-nonbinary
- type: entity
parent: ClothingGenderCloakBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderCloakBase, BaseObviousCloak ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckCloakPan
name: chef's cloak
description: Meant to be worn alongside a frying pan.
@ -311,4 +329,7 @@
sprite: Clothing/Neck/Cloaks/pan.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckCloakPan # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-pan

View File

@ -13,6 +13,11 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true
- type: entity
parent: ClothingNeckBase
@ -30,6 +35,10 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true
- type: entity
parent: ClothingNeckBase
@ -45,6 +54,10 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true
- type: entity
parent: ClothingNeckBase
@ -60,6 +73,10 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true
- type: entity
parent: ClothingNeckBase
@ -75,6 +92,10 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true
- type: entity
parent: ClothingNeckBase
@ -90,6 +111,10 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true
- type: entity
parent: ClothingNeckBase
@ -105,6 +130,10 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true
- type: entity
parent: ClothingNeckBase
@ -122,3 +151,8 @@
tags:
- Medal
- WhitelistChameleon
- type: WearerGetsExamineText # imp
thing: obvious-thing-medal
examineText: obvious-x-medal-nothing
pocketEvident: true

View File

@ -46,7 +46,7 @@
sprite: Clothing/Neck/Misc/bling.rsi
- type: entity
parent: ClothingNeckBase
parent: [ ClothingNeckBase, BaseObviousBadge ] # imp
id: ClothingNeckLawyerbadge
name: lawyer badge
description: A badge to show that the owner is a 'legitimate' lawyer who passed the NT bar exam required to practice law.
@ -57,6 +57,8 @@
sprite: Clothing/Neck/Misc/lawyerbadge.rsi
- type: TypingIndicatorClothing
proto: lawyer
- type: WearerGetsExamineText # imp
thingType: obvious-type-law
- type: entity
parent: ClothingNeckBase

View File

@ -11,6 +11,10 @@
sprite: Clothing/Neck/Misc/pins.rsi
- type: Clothing
sprite: Clothing/Neck/Misc/pins.rsi
- type: WearerGetsExamineText # imp
thing: obvious-thing-pin
examineText: obvious-desc-default
pocketEvident: true
- type: entity
parent: ClothingNeckPinBase
@ -46,6 +50,8 @@
equippedPrefix: lgbt
- type: ChameleonClothing
default: ClothingNeckLGBTPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride
- type: entity
parent: ClothingGenderPinBase
@ -59,6 +65,8 @@
equippedPrefix: ally
- type: ChameleonClothing
default: ClothingNeckAllyPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-straightally
- type: entity
parent: ClothingGenderPinBase
@ -72,6 +80,8 @@
equippedPrefix: aro
- type: ChameleonClothing
default: ClothingNeckAromanticPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aro
- type: entity
parent: ClothingGenderPinBase
@ -85,6 +95,8 @@
equippedPrefix: aroace
- type: ChameleonClothing
default: ClothingNeckAroacePin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aroace
- type: entity
parent: ClothingGenderPinBase
@ -98,6 +110,8 @@
equippedPrefix: asex
- type: ChameleonClothing
default: ClothingNeckAsexualPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-ace
- type: entity
parent: ClothingGenderPinBase
@ -111,6 +125,8 @@
equippedPrefix: bi
- type: ChameleonClothing
default: ClothingNeckBisexualPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-bi
- type: entity
parent: ClothingGenderPinBase
@ -124,6 +140,8 @@
equippedPrefix: gay
- type: ChameleonClothing
default: ClothingNeckGayPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-gay
- type: entity
parent: ClothingGenderPinBase
@ -137,6 +155,8 @@
equippedPrefix: inter
- type: ChameleonClothing
default: ClothingNeckIntersexPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-intersex
- type: entity
parent: ClothingGenderPinBase
@ -150,6 +170,8 @@
equippedPrefix: les
- type: ChameleonClothing
default: ClothingNeckLesbianPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-lesbian
- type: entity
parent: ClothingGenderPinBase
@ -163,6 +185,8 @@
equippedPrefix: non
- type: ChameleonClothing
default: ClothingNeckNonBinaryPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-nonbinary
- type: entity
parent: ClothingGenderPinBase
@ -176,6 +200,8 @@
equippedPrefix: pan
- type: ChameleonClothing
default: ClothingNeckPansexualPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-pan
- type: entity
parent: ClothingGenderPinBase
@ -202,6 +228,8 @@
equippedPrefix: omni
- type: ChameleonClothing
default: ClothingNeckOmnisexualPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-omni
- type: entity
parent: ClothingGenderPinBase
@ -215,6 +243,8 @@
equippedPrefix: gender
- type: ChameleonClothing
default: ClothingNeckGenderqueerPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-gq
- type: entity
parent: ClothingGenderPinBase
@ -241,6 +271,8 @@
equippedPrefix: trans
- type: ChameleonClothing
default: ClothingNeckTransPin
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-trans
- type: entity
parent: ClothingNeckPinBase
@ -252,6 +284,8 @@
state: autism
- type: Clothing
equippedPrefix: autism
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aut
- type: entity
parent: ClothingNeckPinBase
@ -263,6 +297,8 @@
state: goldautism
- type: Clothing
equippedPrefix: goldautism
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aut
- type: entity
parent: BaseItem

View File

@ -136,7 +136,7 @@
# Pride Scarves
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedAce
name: striped asexual scarf
description: A stylish striped asexual scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -147,9 +147,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/ace.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedAce # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-ace
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedAro
name: striped aromantic scarf
description: A stylish striped aromantic scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -160,9 +162,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/aro.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedAro # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aro
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedAroace
name: striped aroace scarf
description: A stylish striped aroace scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -173,9 +177,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/aroace.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedAroace # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-aroace
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedBiSexual
name: striped bisexual scarf
description: A stylish striped bisexual scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -186,9 +192,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/bi.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedBiSexual # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-bi
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedGay
name: striped gay scarf
description: A stylish striped gay scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -199,9 +207,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/gay.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedGay # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-gay
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedInter
name: striped intersex scarf
description: A stylish striped intersex scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -212,9 +222,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/inter.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedInter # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-intersex
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedLesbian
name: striped lesbian scarf
description: A stylish striped lesbian scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -225,9 +237,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/lesbian.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedLesbian # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-lesbian
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedPan
name: striped pan scarf
description: A stylish striped pan scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -238,9 +252,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/pan.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedPan # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-pan
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedNonBinary
name: striped non-binary scarf
description: A stylish striped non-binary scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -251,9 +267,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/non.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedNonBinary # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-nonbinary
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedRainbow
name: rainbow scarf
description: A stylish rainbow scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -264,9 +282,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/rainbow.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedRainbow # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedTrans
name: striped trans scarf
description: A stylish striped trans scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks.
@ -277,9 +297,11 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/trans.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedTrans # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
thingType: obvious-type-pride-trans
- type: entity
parent: ClothingGenderScarfBase # DeltaV - Chameleon pride clothing
parent: [ ClothingGenderScarfBase, BaseObviousScarf ] # DeltaV - Chameleon pride clothing, porting imp's examine
id: ClothingNeckScarfStripedLesbianLong
name: long bacon
description: Long bacon! Perfect for sharing with your girlfriend!
@ -290,3 +312,6 @@
sprite: Clothing/Neck/Scarfs/PrideScarfs/lesbian-long.rsi
- type: ChameleonClothing # DeltaV - Chameleon pride clothing
default: ClothingNeckScarfStripedLesbianLong # DeltaV - Chameleon pride clothing
- type: WearerGetsExamineText # imp
examineText: obvious-x-scarf-lesbian-long

View File

@ -1,7 +1,7 @@
- type: marking
id: TattooHiveChest
bodyPart: Chest
groupWhitelist: [Human, Slime, Felinid, Oni, Kitsune, Avali] # DeltaV - SlimePerson-Avali
groupWhitelist: [Human, Slime, Felinid, Oni, Kitsune, Avali, Shadekin] # DeltaV - SlimePerson-Avali # Starlight - Shadekin
sexRestriction: [Male] # DeltaV: Splitting the scars and tattoos
coloring:
default:
@ -15,7 +15,7 @@
- type: marking
id: TattooNightlingChest
bodyPart: Chest
groupWhitelist: [Human, Slime, Felinid, Oni, Kitsune, Avali] # DeltaV - SlimePerson-Avali
groupWhitelist: [Human, Slime, Felinid, Oni, Kitsune, Avali, Shadekin] # DeltaV - SlimePerson-Avali # Starlight - Shadekin
sexRestriction: [Male] # DeltaV: Splitting the scars and tattoos
coloring:
default:
@ -23,13 +23,13 @@
!type:TattooColoring
fallbackColor: "#666666"
sprites:
- sprite: _DV/Mobs/Customization/tattoos.rsi # DeltaV: Splitting the scars and tattoos
- sprite: _DV/Mobs/Customization/tattoos.rsi # DeltaV: Splitting the scars and tattoos # Starlight - Shadekin
state: tattoo_nightling
- type: marking
id: TattooSilverburghLeftLeg
bodyPart: LLeg
groupWhitelist: [Human, Felinid, Oni, Kitsune] # DeltaV - Felinid-Kitsune
groupWhitelist: [Human, Felinid, Oni, Kitsune, Shadekin] # DeltaV - Felinid-Kitsune # Starlight - Shadekin
coloring:
default:
type:
@ -42,7 +42,7 @@
- type: marking
id: TattooSilverburghRightLeg
bodyPart: RLeg
groupWhitelist: [Human, Felinid, Oni, Kitsune] # DeltaV - Felinid-Kitsune
groupWhitelist: [Human, Felinid, Oni, Kitsune, Shadekin] # DeltaV - Felinid-Kitsune # Starlight - Shadekin
coloring:
default:
type:
@ -55,7 +55,7 @@
- type: marking
id: TattooCampbellLeftArm
bodyPart: LArm
groupWhitelist: [Human, Felinid, Oni, Kitsune] # DeltaV - Felinid-Kitsune
groupWhitelist: [Human, Felinid, Oni, Kitsune, Shadekin] # DeltaV - Felinid-Kitsune # Starlight - Shadekin
coloring:
default:
type:
@ -68,7 +68,7 @@
- type: marking
id: TattooCampbellRightArm
bodyPart: RArm
groupWhitelist: [Human, Felinid, Oni, Kitsune] # DeltaV - Felinid-Kitsune
groupWhitelist: [Human, Felinid, Oni, Kitsune, Shadekin] # DeltaV - Felinid-Kitsune # Starlight - Shadekin
coloring:
default:
type:
@ -81,7 +81,7 @@
- type: marking
id: TattooCampbellLeftLeg
bodyPart: LLeg
groupWhitelist: [Human, Felinid, Oni, Kitsune] # DeltaV - Felinid-Kitsune
groupWhitelist: [Human, Felinid, Oni, Kitsune, Shadekin] # DeltaV - Felinid-Kitsune # Starlight - Shadekin
coloring:
default:
type:
@ -94,7 +94,7 @@
- type: marking
id: TattooCampbellRightLeg
bodyPart: RLeg
groupWhitelist: [Human, Felinid, Oni, Kitsune] # DeltaV - Felinid-Kitsune
groupWhitelist: [Human, Felinid, Oni, Kitsune, Shadekin] # DeltaV - Felinid-Kitsune # Starlight - Shadekin
coloring:
default:
type:

View File

@ -26,6 +26,8 @@
- Thaven
# Den addition
- Ovinia
# Starlight addition
- Shadekin
- type: guideEntry
id: Arachnid
@ -66,3 +68,8 @@
id: Vox
name: species-name-vox
text: "/ServerInfo/Guidebook/Mobs/Vox.xml"
- type: guideEntry
id: Shadekin
name: species-name-shadekin
text: "/ServerInfo/_Starlight/Guidebook/Mobs/Shadekin.xml"

View File

@ -31,6 +31,7 @@
- Ovinia
# End DeltaV additions
- Allulalo #imp
- Shadekin # Delta V - Starlight Addition
- type: loadoutEffectGroup
id: EffectSpeciesVox

View File

@ -85,6 +85,7 @@
- LighterInterdyne
- LighterNanotrasen
- MatchboxGorlex
- NoviceMark # from imp
# End DeltaV Additions
- type: loadoutGroup

View File

@ -6,11 +6,11 @@
edges:
- to: shotgun
steps:
- tag: ModularBarrel #Starlight
- tag: Pipe
icon:
sprite: _Starlight/Objects/Misc/modular_barrel.rsi
state: icon
name: crafting-menu-name-MB
sprite: Structures/Piping/Atmospherics/pipe.rsi
state: pipeStraight
name: construction-graph-tag-pipe
- tag: ModularReceiver
icon:
sprite: Objects/Misc/modular_receiver.rsi

View File

@ -2,82 +2,75 @@
id: ImprovisedShotgunShellGraph
start: start
graph:
- node: start
edges:
- to: shell
steps:
- material: Steel
amount: 1
doAfter: 0.5
- material: Plastic
amount: 1
doAfter: 0.5
# Starlight - Makeshift Weapons Update
- material: Glass
amount: 3
doAfter: 1.5
- material: CrushedPhosphorus
amount: 4
# - tag: GlassShard
# name: construction-graph-tag-glass-shard
# icon:
# sprite: Objects/Materials/Shards/shard.rsi
# state: shard1
# doAfter: 0.5
# - tag: GlassShard
# name: construction-graph-tag-glass-shard
# icon:
# sprite: Objects/Materials/Shards/shard.rsi
# state: shard2
# doAfter: 0.5
# - tag: GlassShard
# name: construction-graph-tag-glass-shard
# icon:
# sprite: Objects/Materials/Shards/shard.rsi
# state: shard1
# doAfter: 0.5
# - tag: GlassShard
# name: construction-graph-tag-glass-shard
# icon:
# sprite: Objects/Materials/Shards/shard.rsi
# state: shard3
# doAfter: 0.5
# - tag: Matchstick
# name: construction-graph-tag-match-stick
# icon:
# sprite: Objects/Tools/matches.rsi
# state: match_unlit
# doAfter: 0.5
# - tag: Matchstick
# name: construction-graph-tag-match-stick
# icon:
# sprite: Objects/Tools/matches.rsi
# state: match_unlit
# doAfter: 0.5
# - tag: Matchstick
# name: construction-graph-tag-match-stick
# icon:
# sprite: Objects/Tools/matches.rsi
# state: match_unlit
# doAfter: 0.5
# - tag: Matchstick
# name: construction-graph-tag-match-stick
# icon:
# sprite: Objects/Tools/matches.rsi
# state: match_unlit
# doAfter: 0.5
# - tag: Matchstick
# name: construction-graph-tag-match-stick
# icon:
# sprite: Objects/Tools/matches.rsi
# state: match_unlit
# doAfter: 0.5
# - tag: Matchstick
# name: construction-graph-tag-match-stick
# icon:
# sprite: Objects/Tools/matches.rsi
# state: match_unlit
# END Starlight
doAfter: 0.5
- node: shell
entity: ShellShotgunImprovised
- node: start
edges:
- to: shell
steps:
- material: Steel
amount: 1
doAfter: 0.5
- material: Plastic
amount: 1
doAfter: 0.5
- tag: GlassShard
name: construction-graph-tag-glass-shard
icon:
sprite: Objects/Materials/Shards/shard.rsi
state: shard1
doAfter: 0.5
- tag: GlassShard
name: construction-graph-tag-glass-shard
icon:
sprite: Objects/Materials/Shards/shard.rsi
state: shard2
doAfter: 0.5
- tag: GlassShard
name: construction-graph-tag-glass-shard
icon:
sprite: Objects/Materials/Shards/shard.rsi
state: shard1
doAfter: 0.5
- tag: GlassShard
name: construction-graph-tag-glass-shard
icon:
sprite: Objects/Materials/Shards/shard.rsi
state: shard3
doAfter: 0.5
- tag: Matchstick
name: construction-graph-tag-match-stick
icon:
sprite: Objects/Tools/matches.rsi
state: match_unlit
doAfter: 0.5
- tag: Matchstick
name: construction-graph-tag-match-stick
icon:
sprite: Objects/Tools/matches.rsi
state: match_unlit
doAfter: 0.5
- tag: Matchstick
name: construction-graph-tag-match-stick
icon:
sprite: Objects/Tools/matches.rsi
state: match_unlit
doAfter: 0.5
- tag: Matchstick
name: construction-graph-tag-match-stick
icon:
sprite: Objects/Tools/matches.rsi
state: match_unlit
doAfter: 0.5
- tag: Matchstick
name: construction-graph-tag-match-stick
icon:
sprite: Objects/Tools/matches.rsi
state: match_unlit
doAfter: 0.5
- tag: Matchstick
name: construction-graph-tag-match-stick
icon:
sprite: Objects/Tools/matches.rsi
state: match_unlit
doAfter: 0.5
- node: shell
entity: ShellShotgunImprovised

View File

@ -25,6 +25,7 @@
equipment:
shoes: ClothingShoesBootsWork
id: TechnicalAssistantPDA
neck: ClothingNeckNoviceMark # imp
belt: ClothingBeltUtilityEngineering
ears: ClothingHeadsetEngineering
pocket2: BookEngineersHandbook

View File

@ -21,6 +21,7 @@
equipment:
shoes: ClothingShoesColorWhite
#id: MedicalInternPDA # DeltaV: different PDAs in loadouts
neck: ClothingNeckNoviceMark # imp
ears: ClothingHeadsetMedical
belt: ClothingBeltMedicalFilled
pocket2: BookMedicalReferenceBook

View File

@ -20,6 +20,7 @@
id: ResearchAssistantGear
equipment:
shoes: ClothingShoesColorWhite
neck: ClothingNeckNoviceMark # imp
id: ResearchAssistantPDA
ears: ClothingHeadsetScience
pocket2: BookScientistsGuidebook

View File

@ -28,6 +28,7 @@
id: SecurityCadetGear
equipment:
shoes: ClothingShoesBootsJackFilled
neck: ClothingNeckNoviceMark # imp
outerClothing: ClothingOuterArmorDuraVest # DeltaV - ClothingOuterArmorBasic replaced in favour of stab vest. Sucks to suck, cadets
id: SecurityCadetPDA
ears: ClothingHeadsetSecurity

View File

@ -15,3 +15,4 @@
Moth: 4
#Dwarf: 2 # DeltaV - No Dwarfs
Vox: 1
Shadekin: 2 # DeltaV - Shadekin from Starlight

View File

@ -0,0 +1,327 @@
- type: markingsGroup
id: Shadekin
limits:
enum.HumanoidVisualLayers.Hair:
limit: 0
required: false
enum.HumanoidVisualLayers.FacialHair:
limit: 0
required: false
enum.HumanoidVisualLayers.Chest:
limit: 2
required: false
enum.HumanoidVisualLayers.Snout:
limit: 1
required: false
enum.HumanoidVisualLayers.LArm:
limit: 1
required: false
enum.HumanoidVisualLayers.RArm:
limit: 1
required: false
enum.HumanoidVisualLayers.LHand:
limit: 1
required: false
enum.HumanoidVisualLayers.RHand:
limit: 1
required: false
enum.HumanoidVisualLayers.LLeg:
limit: 1
required: false
enum.HumanoidVisualLayers.RLeg:
limit: 1
required: false
enum.HumanoidVisualLayers.LFoot:
limit: 1
required: false
enum.HumanoidVisualLayers.RFoot:
limit: 1
required: false
enum.HumanoidVisualLayers.Tail:
limit: 1
required: true
default: [TailShadekin]
enum.HumanoidVisualLayers.HeadTop:
limit: 1
required: true
default: [EarsShadekin]
- type: entity
parent: BaseSpeciesAppearance
id: AppearanceShadekin
name: shadekin appearance
components:
- type: InitialBody
organs:
Torso: OrganShadekinTorso
Head: OrganShadekinHead
ArmLeft: OrganShadekinArmLeft
ArmRight: OrganShadekinArmRight
HandRight: OrganShadekinHandRight
HandLeft: OrganShadekinHandLeft
LegLeft: OrganShadekinLegLeft
LegRight: OrganShadekinLegRight
FootLeft: OrganShadekinFootLeft
FootRight: OrganShadekinFootRight
Brain: OrganShadekinBrain
Eyes: OrganShadekinEyes
Tongue: OrganShadekinTongue
Appendix: OrganShadekinAppendix
Ears: OrganShadekinEars
Lungs: OrganShadekinLungs
Heart: OrganShadekinHeart
Stomach: OrganShadekinStomach
Liver: OrganShadekinLiver
Kidneys: OrganShadekinKidneys
- type: HumanoidProfile
species: Shadekin
- type: ScaleVisuals
scale: 0.9, 0.9
- type: entity
save: false
name: Urist McShadow
parent:
- AppearanceShadekin
- BaseSpeciesMob
id: MobShadekin
components:
- type: Shadekin
thresholds:
0.8: Low
5: Annoying
10: High
15: Extreme
# - type: Absorbable # Delta-V: Commented out, we got no Absorbable
- type: Hunger
- type: Thirst
- type: Icon
sprite: _Starlight/Mobs/Species/Shadekin/parts.rsi
state: full
- type: Speech
allowedEmotes: ["Marr", "Wurble", "Hiss", "Growl", "Purr"]
- type: Vocal
sounds:
Male: MaleShadekin
Female: FemaleShadekin
Unsexed: MaleShadekin
- type: MeleeWeapon
soundHit:
collection: AlienClaw
angle: 30
animation: WeaponArcClaw
damage:
types:
Slash: 5
- type: FlashModifier
modifier: 2
- type: Damageable
damageContainer: Biological
damageModifierSet: Shadekin
- type: Deathgasp
damageType: Bloodloss
- type: Reactive
groups:
Flammable: [Touch]
Extinguish: [Touch]
reactions:
- reagents: [Water, SpaceCleaner]
methods: [Touch]
effects:
- !type:WashCreamPie
- reagents: [ Water ]
methods: [Touch]
effects:
- !type:Emote
emote: Hiss
showInChat: false
- type: Bloodstream
bloodlossDamage:
types:
Bloodloss: 1
bloodlossHealDamage:
types:
Bloodloss: -0.25
- type: Flammable
damage:
types:
Heat: 1.5
- type: TypingIndicator
proto: alien
# - type: Destructible
# thresholds:
# - trigger: !type:DamageTypeTrigger
# damageType: Blunt
# damage: 400
# behaviors:
# - !type:GibBehavior {}
# - !type:SpawnEntitiesBehavior
# spawn:
# ShadekinShadow:
# min: 1
# max: 1
# - trigger: !type:DamageTypeTrigger
# damageType: Heat
# damage: 1500
# behaviors:
# - !type:SpawnEntitiesBehavior
# spawnInContainer: true
# spawn:
# Ash:
# min: 1
# max: 1
# ShadekinShadow:
# min: 1
# max: 1
# - !type:BurnBodyBehavior {}
# BaseMobSpeciesOrganic // Because we dont want respirator to be used.
- type: Barotrauma
damage:
types:
Blunt: 0.85 #per second, scales with pressure and other constants.
Heat: 0.1
- type: PassiveDamage # Slight passive regen. Assuming one damage type, comes out to about 4 damage a minute.
allowedStates:
- Alive
damage:
types:
Heat: -0.07
Blunt: -0.07
Piercing: -0.07
Slash: -0.07
- type: TemperatureSpeed
thresholds:
293: 0.8
280: 0.6
260: 0.4
- type: ThermalRegulator
metabolismHeat: 800
radiatedHeat: 100
implicitHeatRegulation: 500
sweatHeatRegulation: 2000
shiveringHeatRegulation: 2000
normalBodyTemperature: 310.15
thermalRegulationTemperatureThreshold: 2
- type: Perishable
- type: entity
parent: OrganBase
id: OrganShadekin
abstract: true
suffix: shadekin
- type: entity
id: OrganShadekinMetabolizer
abstract: true
components:
- type: Metabolizer
metabolizerTypes: [ Human ]
- type: entity
parent: OrganShadekin
id: OrganShadekinInternal
abstract: true
components:
- type: Sprite
sprite: _Starlight/Mobs/Species/Shadekin/organs.rsi
- type: entity
id: OrganShadekinVisual
abstract: true
components:
- type: VisualOrgan
data:
sprite: _Starlight/Mobs/Species/Shadekin/parts.rsi # Delta V - Changed to our sprites
- type: VisualOrganMarkings
markingData:
group: Shadekin
- type: entity
parent: [ OrganShadekin, OrganShadekinVisual ]
id: OrganShadekinExternal
abstract: true
components:
- type: Sprite
sprite: _Starlight/Mobs/Species/Shadekin/parts.rsi # Delta V - Changed to our Sprites
- type: entity
parent: [ OrganBaseTorsoSexed, OrganBaseTorso, OrganShadekinExternal ]
id: OrganShadekinTorso
- type: entity
parent: [ OrganBaseHeadSexed, OrganBaseHead, OrganShadekinExternal ]
id: OrganShadekinHead
- type: entity
parent: [ OrganBaseArmLeft, OrganShadekinExternal ]
id: OrganShadekinArmLeft
- type: entity
parent: [ OrganBaseArmRight, OrganShadekinExternal ]
id: OrganShadekinArmRight
- type: entity
parent: [ OrganBaseHandLeft, OrganShadekinExternal ]
id: OrganShadekinHandLeft
- type: entity
parent: [ OrganBaseHandRight, OrganShadekinExternal ]
id: OrganShadekinHandRight
- type: entity
parent: [ OrganBaseLegLeft, OrganShadekinExternal ]
id: OrganShadekinLegLeft
- type: entity
parent: [ OrganBaseLegRight, OrganShadekinExternal ]
id: OrganShadekinLegRight
- type: entity
parent: [ OrganBaseFootLeft, OrganShadekinExternal ]
id: OrganShadekinFootLeft
- type: entity
parent: [ OrganBaseFootRight, OrganShadekinExternal ]
id: OrganShadekinFootRight
- type: entity
parent: [ OrganBaseBrain, OrganShadekinInternal ]
id: OrganShadekinBrain
- type: entity
parent: [ OrganShadekinVisual, OrganSpriteHumanInternal, OrganBaseEyes, OrganShadekinInternal ]
id: OrganShadekinEyes
- type: entity
parent: [ OrganBaseTongue, OrganShadekinInternal ]
id: OrganShadekinTongue
- type: entity
parent: [ OrganBaseAppendix, OrganSpriteHumanInternal, OrganShadekinInternal ]
id: OrganShadekinAppendix
- type: entity
parent: [ OrganBaseEars, OrganSpriteHumanInternal, OrganShadekinInternal ]
id: OrganShadekinEars
- type: entity
parent: [ OrganBaseLungs, OrganSpriteHumanInternal, OrganShadekinInternal, OrganShadekinMetabolizer ]
id: OrganShadekinLungs
- type: entity
parent: [ OrganBaseHeart, OrganSpriteHumanInternal, OrganShadekinInternal, OrganShadekinMetabolizer ]
id: OrganShadekinHeart
- type: entity
parent: [ OrganBaseStomach, OrganSpriteHumanInternal, OrganShadekinInternal, OrganShadekinMetabolizer ]
id: OrganShadekinStomach
- type: entity
parent: [ OrganBaseLiver, OrganSpriteHumanInternal, OrganShadekinInternal, OrganShadekinMetabolizer ]
id: OrganShadekinLiver
- type: entity
parent: [ OrganBaseKidneys, OrganSpriteHumanInternal, OrganShadekinInternal, OrganShadekinMetabolizer ]
id: OrganShadekinKidneys

View File

@ -37,22 +37,7 @@
Cold: 80
- type: Tool
qualities: Censer
- type: Welder
fuelSolutionName: Censer
fuelReagent: MindbreakerToxin
fuelConsumption: 0.5
- type: RefillableSolution
solution: Censer
- type: SolutionContainerManager
solutions:
Censer:
reagents:
- ReagentId: MindbreakerToxin
Quantity: 50
maxVol: 50
- type: ItemTogglePointLight
- type: Spillable
solution: Censer
- type: ToggleableVisuals
spriteLayer: flame
inhandVisuals:

View File

@ -1,5 +1,5 @@
- type: entity
parent: ClothingNeckBase
parent: [ ClothingNeckBase, BaseObviousBadge ] # imp
id: ClothingNeckProsecutorbadge
name: prosecutor badge
description: A badge to show that the owner is a 'legitimate' prosecutor who passed the NT bar exam required to practice law.
@ -10,6 +10,8 @@
sprite: _DV/Clothing/Neck/Misc/prosecutorbadge.rsi
- type: TypingIndicatorClothing
proto: lawyer
- type: WearerGetsExamineText # imp
thingType: obvious-type-law-prosecution
- type: entity
parent: ClothingNeckBase

View File

@ -240,6 +240,17 @@
- type: Clothing
sprite: Nyanotrasen/Clothing/Uniforms/Jumpsuit/lawyergalaxyblue.rsi
- type: entity
parent: ClothingUniformBase
id: ClothingUniformJumpsuitFreighterCrew
name: freighter crew's jumpsuit
description: Smells minty.
components:
- type: Sprite
sprite: _DV/Clothing/Uniforms/Jumpsuit/freighter_crew.rsi
- type: Clothing
sprite: _DV/Clothing/Uniforms/Jumpsuit/freighter_crew.rsi
# Formal uniforms
- type: entity

View File

@ -0,0 +1,631 @@
# Ears
- type: marking
id: EarsShadekin
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- type: marking
id: EarsShadekinStriped
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
shadekin_stripes:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin_stripes
- type: marking
id: EarsShadekinMotley
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
motley_secondary:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: motley_secondary
- type: marking
id: EarsShadekinShady
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shady
- type: marking
id: EarsShadekinPiercingAll
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
piercing_all:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: piercing_all
- type: marking
id: EarsShadekinPiercingLeft
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
piercing_left:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: piercing_left
- type: marking
id: EarsShadekinPiercingRight
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
piercing_right:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: piercing_right
- type: marking
id: EarsShadekinRingedAll
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
ringed_all_secondary:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: ringed_all_secondary
- type: marking
id: EarsShadekinRingedLeft
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
ringed_left_secondary:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: ringed_left_secondary
- type: marking
id: EarsShadekinRingedRight
bodyPart: HeadTop
groupWhitelist: [Shadekin]
coloring:
default:
type:
!type:SkinColoring
layers:
ringed_right_secondary:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: ringed_right_secondary
- type: marking
id: EarsShadekinGauzedAll
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: gauze_ear_all_default
- type: marking
id: EarsShadekinGauzedLeft
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: gauze_ear_l_default
- type: marking
id: EarsShadekinGauzedRight
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: shadekin
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: gauze_ear_r_default
- type: marking
id: EarsShadekinFluffy
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- type: marking
id: EarsShadekinFluffyButterfly
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_butterfly
- type: marking
id: EarsShadekinFluffyCowling
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_cowling
- type: marking
id: EarsShadekinFluffyCrow
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_crow
- type: marking
id: EarsShadekinFluffyMotley
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_motley
- type: marking
id: EarsShadekinFluffySpidy
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_spidy
- type: marking
id: EarsShadekinFluffyRingedAll
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_ringed_all
- type: marking
id: EarsShadekinFluffyRingedLeft
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_ringed_left
- type: marking
id: EarsShadekinFluffyRingedRight
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: fluffy_ringed_right
- type: marking
id: EarsShadekinSaggy
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_default
- type: marking
id: EarsShadekinSaggyBrawly
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_brawly
- type: marking
id: EarsShadekinSaggyZebra
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_zebra
- type: marking
id: EarsShadekinSaggyGradient
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_gradient
- type: marking
id: EarsShadekinSaggyGauzedAll
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_gauze_all
- type: marking
id: EarsShadekinSaggyGauzedLeft
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_gauze_l
- type: marking
id: EarsShadekinSaggyGauzedRight
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: saggy_gauze_r
- type: marking
id: EarsShadekinShort
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_default
- type: marking
id: EarsShadekinShortButterfly
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_butterfly
- type: marking
id: EarsShadekinShortRingedAll
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_ringed_all
- type: marking
id: EarsShadekinShortRingedLeft
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_ringed_left
- type: marking
id: EarsShadekinShortRingedRight
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: short_ringed_right
- type: marking
id: EarsShadekinBull
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: bull_default
- type: marking
id: EarsShadekinBullSmooth
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: bull_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: bull_smooth
- type: marking
id: EarsShadekinAqua
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: aqua_default
- type: marking
id: EarsShadekinAquaIncolor
bodyPart: HeadTop
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: aqua_default
- sprite: _Starlight/Mobs/Customization/shadekin/ears.rsi
state: aqua_incolor
# Tails
- type: marking
id: TailShadekin
bodyPart: Tail
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/tails64x32.rsi
state: shadekin
- type: marking
id: TailShadekinBig
bodyPart: Tail
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/tails64x32.rsi
state: shadekin_big
# - type: marking
# id: TailShadekinBigFluff
# bodyPart: Tail
# groupWhitelist: [Shadekin]
# sprites:
# - sprite: _Starlight/Mobs/Customization/shadekin/tails64x32.rsi
# state: shadekin_big_fluff
- type: marking
id: TailShadekinShorter
bodyPart: Tail
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/tails32x32.rsi
state: shadekin_shorter
- type: marking
id: TailShadekinShorterBrush
bodyPart: Tail
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/tails32x32.rsi
state: shadekin_shorter
- sprite: _Starlight/Mobs/Customization/shadekin/tails32x32.rsi
state: shorter_brush
- type: marking
id: TailShadekinMedium
bodyPart: Tail
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/tails32x32.rsi
state: shadekin_medium
- type: marking
id: TailShadekinMediumTwoColored
bodyPart: Tail
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/tails32x32.rsi
state: shadekin_medium
- sprite: _Starlight/Mobs/Customization/shadekin/tails32x32.rsi
state: medium_twocolored
# Overlays
- type: marking
id: BodyShadekinArrow
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_arrow
- type: marking
id: BodyShadekinBlackHole
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_blackhole
- type: marking
id: BodyShadekinBrace
bodyPart: RArm
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_brace
- type: marking
id: BodyShadekinBrawly
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_brawly
- type: marking
id: BodyShadekinHeart
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_heart
- type: marking
id: BodyShadekinInk
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_ink
- type: marking
id: BodyShadekinInk2
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_ink2
- type: marking
id: BodyShadekinInk3
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_ink3
- type: marking
id: BodyShadekinInk4
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_ink4
- type: marking
id: BodyShadekinInk5
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_ink5
- type: marking
id: BodyShadekinInk6
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_ink6
- type: marking
id: BodyShadekinInkAnim
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_ink_anim
- type: marking
id: BodyShadekinLines
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_lines
- type: marking
id: BodyShadekinNeck
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_neck
- type: marking
id: BodyShadekinShield
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_shield
- type: marking
id: BodyShadekinVacuum
bodyPart: Chest
groupWhitelist: [Shadekin]
sprites:
- sprite: _Starlight/Mobs/Customization/shadekin/overlay.rsi
state: body_vacuum

View File

@ -8,15 +8,15 @@
- id: NoosphericSilence
- id: MassMindSwap
- id: GlimmerWispSpawn
- id: FreeProber
- id: GlimmerSpawnProber
- id: GlimmerRevenantSpawn
- id: GlimmerMiteSpawn
- id: GlimmerRandomSentience
- id: GlimmerRandomAnimation
- id: ThavenMoodUpset
#- id: LockProbers
- id: GlimmerLockProbers
- id: PsionicNosebleedEvent
- id: MinorMassMindSwap # Delta V
- id: MinorMassMindSwap
- id: GlimmerFoxfireSpawn
- id: GlimmerRestyle
@ -121,7 +121,7 @@
- type: entity
parent: BaseGlimmerSignaturesEvent
id: FreeProber
id: GlimmerSpawnProber
components:
- type: FreeProberRule
@ -184,13 +184,13 @@
glimmerBurnUpper: 70
- type: ThavenMoodUpsetRule
#- type: entity
# parent: BaseGlimmerEvent
# id: LockProbers
# components:
# - type: GlimmerEvent
# minimumGlimmer: 500
# - type: LockProbersRule
- type: entity
parent: BaseGlimmerEvent
id: GlimmerLockProbers
components:
- type: GlimmerEvent
minimumGlimmer: 750
- type: LockProbersRule
- type: entity
parent: BaseGlimmerEvent

View File

@ -14,6 +14,7 @@
id: CargoAssistantGear
equipment:
id: CargoAssistantPDA
neck: ClothingNeckNoviceMark # imp
ears: ClothingHeadsetCargo
pocket1: BookLogistics

View File

@ -38,3 +38,7 @@
- /Audio/Voice/Vulpkanin/vulp_scream1.ogg
- /Audio/Voice/Vulpkanin/vulp_scream2.ogg
- /Audio/Voice/Vulpkanin/vulp_scream4.ogg
id: VulpkaninYips
files:
- /Audio/Animals/fox_squeak.ogg

View File

@ -0,0 +1,19 @@
- type: species
id: Shadekin
name: species-name-shadekin
roundStart: true
prototype: MobShadekin
dollPrototype: AppearanceShadekin
defaultSkinTone: "#ffffff"
skinColoration: Hues
# eyeColoration: Shadekin
maleFirstNames: names_shadekin
femaleFirstNames: names_shadekin
naming: First
baseScale: "0.9, 0.9"
# Delta V - Comment out
# minAge: 18
# maxAge: 300
# youngAge: 30
# oldAge: 250
# customName: true

View File

@ -286,6 +286,8 @@
collection: VulpkaninHowls
Awoo:
collection: VulpkaninHowls
Yip:
collection: VulpkaninYips
Gasp:
collection: MaleGasp
DefaultDeathgasp:
@ -332,6 +334,8 @@
collection: VulpkaninHowls
Awoo:
collection: VulpkaninHowls
Yip:
collection: VulpkaninYips
Gasp:
collection: FemaleGasp
DefaultDeathgasp:

View File

@ -231,6 +231,24 @@
- awooing
- awooed
- type: emote
id: Yip
name: delta-chat-emote-name-yip
category: Vocal
available: false
whitelist:
components:
- Vocal
blacklist:
components:
- BorgChassis
chatMessages: ["delta-chat-emote-msg-yip"]
chatTriggers:
- yip
- yips
- yipping
- yipped
# Feroxi
- type: emote
id: Gnash

View File

@ -0,0 +1,8 @@
- type: alert
id: Offer
clickEvent: !type:AcceptOfferAlertEvent { }
icons:
- sprite: /Textures/_Floof/Interface/Alerts/offer_item.rsi
state: offer_item
name: alerts-offer-name
description: alerts-offer-desc

View File

@ -0,0 +1,8 @@
- type: entity
id: BaseObviousCloak
abstract: true
components:
- type: WearerGetsExamineText
examineText: obvious-desc-colors
thing: obvious-thing-cloak
warnExamine: false # for funny jokes!

View File

@ -0,0 +1,7 @@
- type: entity
id: BaseObviousBadge
abstract: true
components:
- type: WearerGetsExamineText
examineText: obvious-desc-proves
thing: obvious-thing-badge

View File

@ -0,0 +1,12 @@
- type: entity
parent: ClothingNeckPinBase
id: ClothingNeckNoviceMark
name: novice's mark
description: A mark in CentComm's green and gold, for identifying yourself as unskilled to others. Take it (as a trinket) if you need to! # the rest of the description is handled by WearerGetsExamineText
components:
- type: Sprite
sprite: _Impstation/Clothing/Neck/Misc/novicemark.rsi
- type: Clothing
sprite: _Impstation/Clothing/Neck/Misc/novicemark.rsi
- type: WearerGetsExamineText
examineText: obvious-x-pin-novice

View File

@ -0,0 +1,7 @@
- type: entity
id: BaseObviousScarf
abstract: true
components:
- type: WearerGetsExamineText
examineText: obvious-desc-colors
thing: obvious-thing-scarf

View File

@ -0,0 +1,5 @@
- type: loadout
id: NoviceMark # no playtime lockout for needing time :)
storage:
back:
- ClothingNeckNoviceMark

View File

@ -0,0 +1,19 @@
- type: alert
id: Shadekin
icons:
- sprite: error.rsi
state: error
- sprite: /Textures/_Starlight/Interface/Alerts/shadekin.rsi
state: dark
- sprite: /Textures/_Starlight/Interface/Alerts/shadekin.rsi
state: low
- sprite: /Textures/_Starlight/Interface/Alerts/shadekin.rsi
state: normal
- sprite: /Textures/_Starlight/Interface/Alerts/shadekin.rsi
state: high
- sprite: /Textures/_Starlight/Interface/Alerts/shadekin.rsi
state: dangerous
minSeverity: 0
maxSeverity: 5
name: alerts-shadekin-name
description: alerts-shadekin-desc

View File

@ -0,0 +1,10 @@
- type: damageModifierSet
id: Shadekin
coefficients:
Asphyxiation: 0
Cold: 0.75
Heat: 1.2
# Cellular: 0.25 # Delta V - Commented out after Direction Request
Bloodloss: 1.35
Shock: 1.25
Radiation: 1.3

View File

@ -0,0 +1,5 @@
- type: localizedDataset
id: names_shadekin
values:
prefix: names-shadekin-dataset-
count: 49

View File

@ -0,0 +1,66 @@
- type: entity
name: Shadekin Haze
id: ShadekinShadow
parent: BaseShadow
placement:
mode: SnapgridCenter
snap:
- Wall
components:
- type: Appearance
- type: Transform
anchored: true
# - type: EmitSoundOnSpawn
# sound:
# path: null # Delta-V commented out, as file misisng for nullphase.ogg
- type: TimedDespawn
lifetime: 30
- type: Physics
canCollide: false
- type: Occluder
- type: Sprite
drawdepth: Effects
sprite: Effects/spookysmoke.rsi
layers:
- state: spookysmoke
color: "#793a80dd"
map: [base]
- type: Tag
tags:
- HideContextMenu
- SpookyFog
- type: OptionsVisualizer
visuals:
base:
- options: Default
data: { state: spookysmoke }
- options: ReducedMotion
data: { state: spookysmoke_static }
- type: entity
id: ShadekinPhaseInEffect
name: Shadekin Phase in
components:
- type: TimedDespawn
lifetime: 0.5
- type: Sprite
layers:
- sprite: _Starlight/Effects/shadekin.rsi
state: tp_in
shader: unshaded
netsync: false
drawdepth: Effects
- type: entity
id: ShadekinPhaseOutEffect
name: Shadekin Phase out
components:
- type: TimedDespawn
lifetime: 0.5
- type: Sprite
layers:
- sprite: _Starlight/Effects/shadekin.rsi
state: tp_out
shader: unshaded
netsync: false
drawdepth: Effects

View File

@ -0,0 +1,25 @@
- type: entity
parent: BasePlushie
id: BaseShadekinPlushie
abstract: true
components:
- type: EmitSoundOnUse
sound:
path: /Audio/_Starlight/Voice/Shadekin/mar.ogg
- type: EmitSoundOnLand
sound:
path: /Audio/_Starlight/Voice/Shadekin/mar.ogg
- type: EmitSoundOnActivate
sound:
path: /Audio/_Starlight/Voice/Shadekin/mar.ogg
- type: EmitSoundOnTrigger
sound:
path: /Audio/_Starlight/Voice/Shadekin/mar.ogg
- type: MeleeWeapon
wideAnimationRotation: 180
soundHit:
path: /Audio/_Starlight/Voice/Shadekin/wurble.ogg
- type: Edible
requiresSpecialDigestion: true
useSound:
collection: FelinidScreams

View File

@ -0,0 +1,12 @@
- type: entity
parent: BaseShadekinPlushie
id: PlushieShadekin
name: Shadekin Plushie
description: A plushie of a Shadekin. It's very soft.
components:
- type: Item
size: Small
sprite: _Starlight/Objects/Fun/Plushies/shadekin_plushie.rsi
- type: Sprite
sprite: _Starlight/Objects/Fun/Plushies/shadekin_plushie.rsi
state: icon

View File

@ -0,0 +1,11 @@
- type: soundCollection
id: ShadekinMaleScreams
files:
- /Audio/_Starlight/Voice/Shadekin/scream_m1.ogg
- /Audio/_Starlight/Voice/Shadekin/scream_m2.ogg
- type: soundCollection
id: ShadekinFemaleScreams
files:
- /Audio/_Starlight/Voice/Shadekin/scream_f1.ogg
- /Audio/_Starlight/Voice/Shadekin/scream_f2.ogg

View File

@ -0,0 +1,41 @@
- type: trait
id: HighLightSensitivity
name: trait-highlightsensitivity-name
description: trait-highlightsensitivity-desc
category: Disabilities
cost: -1
effects:
- !type:OverrideCompsEffect
components:
- type: Shadekin
thresholds:
0.7: Low
0.8: Annoying
5: High
10: Extreme
conditions:
- !type:IsSpeciesCondition
species: Shadekin
conflicts:
- ExtremeLightSensitivity
- type: trait
id: ExtremeLightSensitivity
name: trait-extremelightsensitivity-name
description: trait-extremelightsensitivity-desc
category: Disabilities
cost: -2
effects:
- !type:OverrideCompsEffect
components:
- type: Shadekin
thresholds:
0.6: Low
0.7: Annoying
0.8: High
5: Extreme
conditions:
- !type:IsSpeciesCondition
species: Shadekin
conflicts:
- HighLightSensitivity

View File

@ -0,0 +1,80 @@
# species
- type: emoteSounds
id: MaleShadekin
params:
variation: 0.125
sounds:
Scream:
collection: ShadekinMaleScreams
Laugh:
collection: MaleLaugh
Sneeze:
collection: MaleSneezes
Cough:
collection: MaleCoughs
Yawn:
collection: MaleYawn
Snore:
collection: Snores
Sigh:
collection: MaleSigh
Crying:
collection: MaleCry
Whistle:
collection: Whistles
Weh:
collection: Weh
Gasp:
collection: MaleGasp
DefaultDeathgasp:
collection: MaleDeathGasp
Marr:
path: /Audio/_Starlight/Voice/Shadekin/mar.ogg
Wurble:
path: /Audio/_Starlight/Voice/Shadekin/wurble.ogg
Hiss:
collection: FelinidHisses
Purr:
collection: FelinidPurrs
Growl:
collection: FelinidGrowls
- type: emoteSounds
id: FemaleShadekin
params:
variation: 0.125
sounds:
Scream:
collection: ShadekinFemaleScreams
Laugh:
collection: FemaleLaugh
Sneeze:
collection: FemaleSneezes
Cough:
collection: FemaleCoughs
Yawn:
collection: FemaleYawn
Snore:
collection: Snores
Sigh:
collection: FemaleSigh
Crying:
collection: FemaleCry
Whistle:
collection: Whistles
Weh:
collection: Weh
Gasp:
collection: FemaleGasp
DefaultDeathgasp:
collection: FemaleDeathGasp
Marr:
path: /Audio/_Starlight/Voice/Shadekin/mar.ogg
Wurble:
path: /Audio/_Starlight/Voice/Shadekin/wurble.ogg
Hiss:
collection: FelinidHisses
Purr:
collection: FelinidPurrs
Growl:
collection: FelinidGrowls

View File

@ -0,0 +1,35 @@
- type: emote
id: Marr
name: chat-emote-name-marr
category: Vocal
whitelist:
components:
- Vocal
blacklist:
components:
- BorgChassis
chatMessages: ["chat-emote-msg-marr"]
chatTriggers:
- marr
- marr.
- marr!
- marr?
- marrs
- marrs.
- marrs!
- marrs?
- type: emote
id: Wurble
name: chat-emote-name-wurble
category: Vocal
whitelist:
components:
- Vocal
blacklist:
components:
- BorgChassis
chatMessages: ["chat-emote-msg-wurble"]
chatTriggers:
- wurble
- wurbles

View File

@ -29,5 +29,6 @@
<GuideEntityEmbed Entity="AppearanceKitsune" Caption="Kitsune"/>
<GuideEntityEmbed Entity="AppearanceOvinia" Caption="Ovinia"/>
<GuideEntityEmbed Entity="AppearanceAllulalo" Caption="Allulalo"/>
<GuideEntityEmbed Entity="AppearanceShadekin" Caption="Shadekin"/>
</Box>
</Document>

View File

@ -6,10 +6,7 @@
When mounting an effort to thwart the [color=#4cabb3]Cosmic Cult[/color], there are several methods the crew might employ to ensure their survival and safety. One of these methods is [color=Yellow]Deconversion[/color].
To [color=Yellow]Deconvert[/color] a cosmic cultist, an [bold]Ardent Censer[/bold] must be used. Censers are fueled with Mindbreaker Toxin, which can be brewed at your chemist.
<GuideReagentEmbed Reagent="MindbreakerToxin"/>
<GuideReagentEmbed Reagent="Dylovene"/>
To [color=Yellow]Deconvert[/color] a cosmic cultist, an [bold]Ardent Censer[/bold] must be used.
## Suppression Methods
<Box>

View File

@ -0,0 +1,65 @@
<Document>
# Shadekin
<Box>
<GuideEntityEmbed Entity="MobShadekin" Caption=""/>
</Box>
Shadekin are a species whom originally dwell and are from another dimension called “The Dark”.
Most if not all Shadekin that are employed or under contract from NT are afflicted with a condition they call “Black-eye” and or as the Shadekin themselves refer to as being “Burnt”.
This affliction and condition supposedly is the cause of them being incapable of returning to the aforementioned “The Dark”.
Adapted to their home dimension of which is one absent of light, their vision is highly reactive to light levels.
Dim lights being a source of passive annoyance or discomfort, bright lights ail them much more noticeably, being a source of pain and harm to them.
## Racial Features
- Receive [color=#ffa500]20% more heat damage[/color]
- Receive [color=#1e90ff]25% less cold damage[/color]
- Receive [color=#ffa500]170% more bloodloss damage[/color]
- Receive [color=#ffa500]30% more radiation damage[/color]
- Receive [color=#ffa500]25% more shock damage[/color].
- Heal [color=#ffa500]bloodloss damage 75% slower[/color]
- They do not breathe and thus require no air.
- Flash stun times are doubled.
- Deal [color=red]5[/color] slashing damage with claws.
## Marish
Shadekin have a language shared amongst them all, composed of only a singular word: “Mar”, whilst it can be altered in length and or composition, from potential additional As or Rs in the pronunciation. With this one and simple word however, Shadekin can convey and provide complex thought, and deep emotion alike.
Simplistic but endlessly deep for the Shadekin.
## Age & Names
Shadekin are an example of a very slow biological aging process.
Whilst maturity and eligible employment are known to standard to be 18.
Often Shadekin are considered young up until the age range of around 100, the ranges of 100-200 are what would be considered middle-aged, 200-300 being the instance of them starting to enter a elderly state.
Names are of great significance to Shadekin. Often these names are considered titles and bear them upon entering the physical from their home of “The Dark”.
These titles are often provided and or given to them by the attributes or qualities they exhibit, however there are other cases where it can be even items, passions, or ideas they are fond of.
There are instances as well of some Shadekin whom have become acclimated to provide their own titles, replacing previous ones.
This is not an aspect taken lightly by them nor other Shadekin, such a decision is akin to throwing away their previous selves.
## Nightvision
Shadekin due to their natural adaptation to their home dimension have innate Night-vision.
Capable of seeing and viewing things even in the most abyss-like darknesses, not needing any form of light providing device.
When wearing flash resistant equipment their vision will be normal.
This can be easily sorted by the Shadekin wearing a HUD variant, no longer having flash resistance, but keeping the utility that their nightvision and the HUD provide.
<Box>
<GuideEntityEmbed Entity="ClothingEyesGlassesSecurity" Scale="5" Caption="Security Glasses\nNo Nightvision\nHas flash immunity"/>
<GuideEntityEmbed Entity="ClothingEyesHudSecurity" Scale="5" Caption="Security Hud\nNightvision\nNo flash immunity"/>
</Box>
## LIGHT SENSITIVITY
[color=yellow]Light Exposure: Dark[/color]
- Passive Regeneration is increased.
- Nightvision.
[color=yellow]Light Exposure: Low[/color]
- No changes.
[color=yellow]Light Exposure: Annoying[/color]
- Passive Regeneration is disabled.
[color=yellow]Light Exposure: High[/color]
- Heavy Slowdown.
[color=yellow]Light Exposure:[/color] [color=red]EXTREME[/color]
- Get burned [color=red]1[/color] heat damage per second.
</Document>

Some files were not shown because too many files have changed in this diff Show More