Farming WIP (#269)
* setup planting doafter * spawn plants after use seed * some work * move comps to separate folder * public check daylight * daylight plant energy regeneration * some fixes * bruh, im thinking * added ingame soil * added hoe * attaching plants * hoe system * block plant dublicating * some planting refactor * shovel as pant + soil remover * plant growing visualizer * soil resprite * split farming system to second partial class * update throught event refactor * tring sync update plant with update visuals * finish visual sync * plants growing * more partial splitting, naming work, clean up * Update FARMINGTEST.yml * Update FARMINGTEST.yml * fix typo * prototype value validating * Оно бухает воду! * solution visualizer in soil * forgot some fix * part of Tornado review fix * destroy RemovePlantComponent * more fixes * simple harvesting * refactor plant component values changing * harvest redo * gather on destroyByTool * sickle resprite * plant fading * fading per minute! * wheat sprites * YML restruct * fixes * auto root plants * add comments * move sprites * split structures from object textures * wheat farming! * Update CP14FarmingSystem.Interactions.cs * seedbed (#297) seedbed :^) * a * Update soil.yml --------- Co-authored-by: Jaraten <116667537+Jaraten@users.noreply.github.com>
23
Content.Client/_CP14/Farming/CP14PlantVisualsComponent.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace Content.Client._CP14.Farming;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the visual display of plant growth
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14PlantVisualsComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public int GrowthSteps = 3;
|
||||
|
||||
[DataField]
|
||||
public string? GrowState;
|
||||
|
||||
[DataField]
|
||||
public string? GrowUnshadedState;
|
||||
}
|
||||
|
||||
public enum PlantVisualLayers : byte
|
||||
{
|
||||
Base,
|
||||
BaseUnshaded,
|
||||
}
|
||||
48
Content.Client/_CP14/Farming/ClientCP14FarmingSystem.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using Content.Shared._CP14.Farming;
|
||||
using Content.Shared.Rounding;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client._CP14.Farming;
|
||||
|
||||
public sealed class ClientCP14FarmingSystem : CP14SharedFarmingSystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14PlantVisualsComponent, ComponentInit>(OnPlantVisualInit);
|
||||
SubscribeLocalEvent<CP14PlantComponent, AfterAutoHandleStateEvent>(OnAutoHandleState);
|
||||
}
|
||||
|
||||
private void OnAutoHandleState(Entity<CP14PlantComponent> plant, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (!TryComp<CP14PlantVisualsComponent>(plant, out var visuals))
|
||||
return;
|
||||
|
||||
UpdateVisuals(new Entity<CP14PlantVisualsComponent>(plant, visuals));
|
||||
}
|
||||
|
||||
private void OnPlantVisualInit(Entity<CP14PlantVisualsComponent> visuals, ref ComponentInit args)
|
||||
{
|
||||
UpdateVisuals(visuals);
|
||||
}
|
||||
|
||||
private void UpdateVisuals(Entity<CP14PlantVisualsComponent> visuals)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(visuals, out var sprite))
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14PlantComponent>(visuals, out var plant))
|
||||
return;
|
||||
|
||||
var growthState = ContentHelpers.RoundToNearestLevels(plant.GrowthLevel, 1, visuals.Comp.GrowthSteps);
|
||||
if (growthState == 0)
|
||||
growthState++;
|
||||
|
||||
if (sprite.LayerMapTryGet(PlantVisualLayers.Base, out _))
|
||||
sprite.LayerSetState(PlantVisualLayers.Base, $"{visuals.Comp.GrowState}{growthState}");
|
||||
|
||||
if (sprite.LayerMapTryGet(PlantVisualLayers.BaseUnshaded, out _))
|
||||
sprite.LayerSetState(PlantVisualLayers.BaseUnshaded, $"{visuals.Comp.GrowUnshadedState}{growthState}");
|
||||
}
|
||||
}
|
||||
153
Content.Server/_CP14/Farming/CP14FarmingSystem.Interactions.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using Content.Server._CP14.Farming.Components;
|
||||
using Content.Server.Gatherable.Components;
|
||||
using Content.Shared._CP14.Farming;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
|
||||
namespace Content.Server._CP14.Farming;
|
||||
|
||||
public sealed partial class CP14FarmingSystem
|
||||
{
|
||||
private void InitializeInteractions()
|
||||
{
|
||||
SubscribeLocalEvent<CP14SeedComponent, AfterInteractEvent>(OnSeedInteract);
|
||||
SubscribeLocalEvent<CP14PlantGatherableComponent, ActivateInWorldEvent>(OnActivate);
|
||||
SubscribeLocalEvent<CP14PlantGatherableComponent, AttackedEvent>(OnAttacked);
|
||||
|
||||
SubscribeLocalEvent<CP14SoilComponent, PlantSeedDoAfterEvent>(OnSeedPlantedDoAfter);
|
||||
}
|
||||
|
||||
private void OnAttacked(Entity<CP14PlantGatherableComponent> gatherable, ref AttackedEvent args)
|
||||
{
|
||||
if (_whitelist.IsWhitelistFailOrNull(gatherable.Comp.ToolWhitelist, args.Used))
|
||||
return;
|
||||
|
||||
TryHarvestPlant(gatherable, out _);
|
||||
}
|
||||
|
||||
private void OnActivate(Entity<CP14PlantGatherableComponent> gatherable, ref ActivateInWorldEvent args)
|
||||
{
|
||||
if (args.Handled || !args.Complex)
|
||||
return;
|
||||
|
||||
if (_whitelist.IsWhitelistFailOrNull(gatherable.Comp.ToolWhitelist, args.User))
|
||||
return;
|
||||
|
||||
TryHarvestPlant(gatherable, out _);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
public bool TryHarvestPlant(Entity<CP14PlantGatherableComponent> gatheredPlant, out HashSet<EntityUid> result, EntityUid? gatherer = null)
|
||||
{
|
||||
result = new();
|
||||
|
||||
if (!TryComp<CP14PlantComponent>(gatheredPlant, out var plant))
|
||||
return false;
|
||||
|
||||
if (plant.GrowthLevel < gatheredPlant.Comp.GrowthLevelToHarvest)
|
||||
return false;
|
||||
|
||||
|
||||
if (TryComp<SoundOnGatherComponent>(gatheredPlant, out var soundComp))
|
||||
{
|
||||
_audio.PlayPvs(soundComp.Sound, Transform(gatheredPlant).Coordinates);
|
||||
}
|
||||
|
||||
if (gatheredPlant.Comp.Loot == null)
|
||||
return false;
|
||||
|
||||
var pos = _transform.GetMapCoordinates(gatheredPlant);
|
||||
|
||||
foreach (var (tag, table) in gatheredPlant.Comp.Loot)
|
||||
{
|
||||
if (tag != "All")
|
||||
{
|
||||
if (gatherer != null && !_tag.HasTag(gatherer.Value, tag))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_proto.TryIndex(table, out var getLoot))
|
||||
continue;
|
||||
|
||||
var spawnLoot = getLoot.GetSpawns(_random);
|
||||
var spawnPos = pos.Offset(_random.NextVector2(gatheredPlant.Comp.GatherOffset));
|
||||
result.Add(Spawn(spawnLoot[0], spawnPos)); //TODO почему то не спавнится больше 1 пшенички. Кажись проблема оффов
|
||||
}
|
||||
|
||||
if (gatheredPlant.Comp.DeleteAfterHarvest)
|
||||
_destructible.DestroyEntity(gatheredPlant);
|
||||
else
|
||||
AffectGrowth((gatheredPlant, plant), -gatheredPlant.Comp.GrowthCostHarvest);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnSeedInteract(Entity<CP14SeedComponent> seed, ref AfterInteractEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14SoilComponent>(args.Target, out var soil))
|
||||
return;
|
||||
|
||||
if (EntityManager.EntityExists(soil.PlantUid))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cp14-farming-soil-interact-plant-exist"), args.Target.Value, args.User);
|
||||
return;
|
||||
}
|
||||
var doAfterArgs =
|
||||
new DoAfterArgs(EntityManager, args.User, seed.Comp.PlantingTime, new PlantSeedDoAfterEvent(), args.Target, args.Used, args.Target)
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BlockDuplicate = true,
|
||||
BreakOnMove = true,
|
||||
BreakOnHandChange = true,
|
||||
};
|
||||
_doAfter.TryStartDoAfter(doAfterArgs);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
public bool TryPlantSeed(EntityUid seed, EntityUid soil, EntityUid? user)
|
||||
{
|
||||
if (!TryComp<CP14SoilComponent>(soil, out var soilComp))
|
||||
return false;
|
||||
|
||||
if (!TryComp<CP14SeedComponent>(seed, out var seedComp))
|
||||
return false;
|
||||
|
||||
if (Exists(soilComp.PlantUid))
|
||||
{
|
||||
if (user is not null)
|
||||
_popup.PopupEntity(Loc.GetString("cp14-farming-soil-interact-plant-exist"), soil, user.Value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var plant = SpawnAttachedTo(seedComp.PlantProto, Transform(soil).Coordinates);
|
||||
|
||||
if (!TryComp<CP14PlantComponent>(plant, out var plantComp))
|
||||
return false;
|
||||
|
||||
_transform.SetParent(plant, soil);
|
||||
soilComp.PlantUid = plant;
|
||||
plantComp.SoilUid = soil;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnSeedPlantedDoAfter(Entity<CP14SoilComponent> soil, ref PlantSeedDoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Handled || args.Args.Used == null || args.Target == null)
|
||||
return;
|
||||
|
||||
if (!TryPlantSeed(args.Target.Value, soil, args.User))
|
||||
return;
|
||||
|
||||
//Audio
|
||||
QueueDel(args.Target); //delete seed
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
87
Content.Server/_CP14/Farming/CP14FarmingSystem.Resourse.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Content.Server._CP14.Farming.Components;
|
||||
using Content.Shared._CP14.Farming;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
|
||||
namespace Content.Server._CP14.Farming;
|
||||
|
||||
public sealed partial class CP14FarmingSystem
|
||||
{
|
||||
private void InitializeResources()
|
||||
{
|
||||
SubscribeLocalEvent<CP14PlantEnergyFromLightComponent, CP14PlantUpdateEvent>(OnTakeEnergyFromLight);
|
||||
SubscribeLocalEvent<CP14PlantMetabolizerComponent, CP14PlantUpdateEvent>(OnPlantMetabolizing);
|
||||
SubscribeLocalEvent<CP14PlantFadingComponent, CP14PlantUpdateEvent>(OnPlantFade);
|
||||
|
||||
SubscribeLocalEvent<CP14PlantGrowingComponent, CP14AfterPlantUpdateEvent>(OnPlantGrowing);
|
||||
}
|
||||
|
||||
private void OnPlantFade(Entity<CP14PlantFadingComponent> ent, ref CP14PlantUpdateEvent args)
|
||||
{
|
||||
var realFade = ent.Comp.ResourcePerMinute * (float)args.Plant.Comp.Age.TotalMinutes;
|
||||
if (args.Plant.Comp.Resource < realFade)
|
||||
{
|
||||
_damageable.TryChangeDamage(ent, ent.Comp.FadeDamage, true);
|
||||
}
|
||||
AffectResource(args.Plant, -realFade);
|
||||
}
|
||||
|
||||
private void OnTakeEnergyFromLight(Entity<CP14PlantEnergyFromLightComponent> regeneration, ref CP14PlantUpdateEvent args)
|
||||
{
|
||||
var gainEnergy = false;
|
||||
var daylight = _dayCycle.TryDaylightThere(regeneration, true);
|
||||
|
||||
if (regeneration.Comp.Daytime && daylight)
|
||||
gainEnergy = true;
|
||||
|
||||
if (regeneration.Comp.Nighttime && !daylight)
|
||||
gainEnergy = true;
|
||||
|
||||
if (gainEnergy)
|
||||
args.EnergyDelta += regeneration.Comp.Energy;
|
||||
}
|
||||
|
||||
private void OnPlantGrowing(Entity<CP14PlantGrowingComponent> growing, ref CP14AfterPlantUpdateEvent args)
|
||||
{
|
||||
if (args.Plant.Comp.Energy < growing.Comp.EnergyCost)
|
||||
return;
|
||||
|
||||
if (args.Plant.Comp.Resource < growing.Comp.ResourceCost)
|
||||
return;
|
||||
|
||||
if (args.Plant.Comp.GrowthLevel >= 1)
|
||||
return;
|
||||
|
||||
AffectEnergy(args.Plant, -growing.Comp.EnergyCost);
|
||||
AffectResource(args.Plant, -growing.Comp.ResourceCost);
|
||||
|
||||
AffectGrowth(args.Plant, growing.Comp.GrowthPerUpdate);
|
||||
}
|
||||
|
||||
private void OnPlantMetabolizing(Entity<CP14PlantMetabolizerComponent> ent, ref CP14PlantUpdateEvent args)
|
||||
{
|
||||
if (args.Plant.Comp.SoilUid == null ||
|
||||
!TryComp<CP14SoilComponent>(args.Plant.Comp.SoilUid, out var soil) ||
|
||||
!TryComp<CP14PlantComponent>(ent, out var plant) ||
|
||||
!TryComp<SolutionContainerManagerComponent>(args.Plant.Comp.SoilUid, out var solmanager))
|
||||
return;
|
||||
|
||||
var solEntity = new Entity<SolutionContainerManagerComponent?>(args.Plant.Comp.SoilUid.Value, solmanager);
|
||||
if (!_solutionContainer.TryGetSolution(solEntity, soil.Solution, out var soln, out var solution))
|
||||
return;
|
||||
|
||||
if (!_proto.TryIndex(ent.Comp.MetabolizerId, out var metabolizer))
|
||||
return;
|
||||
|
||||
var splitted = _solutionContainer.SplitSolution(soln.Value, ent.Comp.SolutionPerUpdate);
|
||||
foreach (var reagent in splitted)
|
||||
{
|
||||
if (!metabolizer.Metabolization.ContainsKey(reagent.Reagent.ToString()))
|
||||
continue;
|
||||
|
||||
foreach (var effect in metabolizer.Metabolization[reagent.Reagent.ToString()])
|
||||
{
|
||||
effect.Effect((ent, plant), reagent.Quantity, EntityManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
Content.Server/_CP14/Farming/CP14FarmingSystem.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using Content.Server._CP14.Farming.Components;
|
||||
using Content.Server.Destructible;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared._CP14.DayCycle;
|
||||
using Content.Shared._CP14.Farming;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._CP14.Farming;
|
||||
|
||||
public sealed partial class CP14FarmingSystem : CP14SharedFarmingSystem
|
||||
{
|
||||
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly CP14DayCycleSystem _dayCycle = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly DestructibleSystem _destructible = default!;
|
||||
[Dependency] private readonly SharedMapSystem _map = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
InitializeInteractions();
|
||||
InitializeResources();
|
||||
|
||||
SubscribeLocalEvent<CP14PlantComponent, EntityUnpausedEvent>(OnUnpaused);
|
||||
SubscribeLocalEvent<CP14PlantComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<CP14PlantAutoRootComponent, MapInitEvent>(OnAutoRootMapInit);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var query = EntityQueryEnumerator<CP14PlantComponent>();
|
||||
while (query.MoveNext(out var uid, out var plant))
|
||||
{
|
||||
if (_timing.CurTime <= plant.NextUpdateTime)
|
||||
continue;
|
||||
|
||||
var newTime = _random.NextFloat(plant.UpdateFrequency);
|
||||
plant.NextUpdateTime = _timing.CurTime + TimeSpan.FromSeconds(newTime);
|
||||
plant.Age += TimeSpan.FromSeconds(plant.UpdateFrequency);
|
||||
|
||||
var ev = new CP14PlantUpdateEvent((uid, plant));
|
||||
RaiseLocalEvent(uid, ev);
|
||||
|
||||
AffectResource((uid, plant), ev.ResourceDelta);
|
||||
AffectEnergy((uid, plant), ev.EnergyDelta);
|
||||
|
||||
var ev2 = new CP14AfterPlantUpdateEvent((uid, plant));
|
||||
RaiseLocalEvent(uid, ev2);
|
||||
|
||||
Dirty(uid, plant);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnpaused(Entity<CP14PlantComponent> ent, ref EntityUnpausedEvent args)
|
||||
{
|
||||
ent.Comp.NextUpdateTime += args.PausedTime;
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<CP14PlantComponent> plant, ref MapInitEvent args)
|
||||
{
|
||||
var newTime = _random.NextFloat(plant.Comp.UpdateFrequency);
|
||||
plant.Comp.NextUpdateTime = _timing.CurTime + TimeSpan.FromSeconds(newTime);
|
||||
}
|
||||
|
||||
private void OnAutoRootMapInit(Entity<CP14PlantAutoRootComponent> autoRoot, ref MapInitEvent args)
|
||||
{
|
||||
var grid = Transform(autoRoot).GridUid;
|
||||
if (grid == null || !TryComp<MapGridComponent>(grid, out var gridComp))
|
||||
return;
|
||||
|
||||
|
||||
var targetPos = new EntityCoordinates(grid.Value,Transform(autoRoot).LocalPosition);
|
||||
var anchored = _map.GetAnchoredEntities(grid.Value, gridComp, targetPos);
|
||||
|
||||
foreach (var entt in anchored)
|
||||
{
|
||||
if (!TryComp<CP14SoilComponent>(entt, out var soil))
|
||||
continue;
|
||||
|
||||
_transform.SetParent(autoRoot, entt);
|
||||
soil.PlantUid = autoRoot;
|
||||
|
||||
if (TryComp<CP14PlantComponent>(autoRoot, out var plantComp))
|
||||
{
|
||||
plantComp.SoilUid = entt;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Content.Server._CP14.Farming.Components;
|
||||
|
||||
/// <summary>
|
||||
/// when it init, it automatically attaches itself by its roots to the soil beneath it.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14FarmingSystem))]
|
||||
public sealed partial class CP14PlantAutoRootComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Content.Server._CP14.Farming.Components;
|
||||
|
||||
/// <summary>
|
||||
/// allows the plant to receive energy passively, depending on daylight
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14FarmingSystem))]
|
||||
public sealed partial class CP14PlantEnergyFromLightComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float Energy = 0f;
|
||||
|
||||
[DataField]
|
||||
public bool Daytime = true;
|
||||
|
||||
[DataField]
|
||||
public bool Nighttime = false;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.FixedPoint;
|
||||
|
||||
namespace Content.Server._CP14.Farming.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Gradually wastes the plant's resources, killing it if there aren't enough. The waste gradually increases over time, reflecting the "Old Age" of the plant
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14FarmingSystem))]
|
||||
public sealed partial class CP14PlantFadingComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float ResourcePerMinute = 0f;
|
||||
|
||||
[DataField]
|
||||
public DamageSpecifier FadeDamage = new()
|
||||
{
|
||||
DamageDict = new Dictionary<string, FixedPoint2>
|
||||
{
|
||||
{ "Cellular", 0.05 },
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Content.Server._CP14.Farming.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Is trying to use up the plant's energy and resources to grow.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14FarmingSystem))]
|
||||
public sealed partial class CP14PlantGrowingComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float EnergyCost = 0f;
|
||||
|
||||
[DataField]
|
||||
public float ResourceCost = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// for each plant renewal. It is not every frame, it depends on the refresh rate in PlantComponent
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float GrowthPerUpdate = 0f;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Content.Shared._CP14.Farming.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Farming.Components;
|
||||
|
||||
/// <summary>
|
||||
/// allows the plant to obtain resources by absorbing liquid from the ground
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14FarmingSystem))]
|
||||
public sealed partial class CP14PlantMetabolizerComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public FixedPoint2 SolutionPerUpdate = 5f;
|
||||
|
||||
[DataField(required: true)]
|
||||
public ProtoId<CP14PlantMetabolizerPrototype> MetabolizerId;
|
||||
}
|
||||
16
Content.Server/_CP14/Farming/Components/CP14SeedComponent.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Farming.Components;
|
||||
|
||||
/// <summary>
|
||||
/// a component that allows for the creation of the plant entity on the soil
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14FarmingSystem))]
|
||||
public sealed partial class CP14SeedComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan PlantingTime = TimeSpan.FromSeconds(2f);
|
||||
|
||||
[DataField(required: true)]
|
||||
public EntProtoId PlantProto;
|
||||
}
|
||||
13
Content.Server/_CP14/Farming/Components/CP14SoilComponent.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Content.Server._CP14.Farming.Components;
|
||||
|
||||
/// <summary>
|
||||
/// a component that provides a link to a liquid storage that can be used by the plant
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14FarmingSystem))]
|
||||
public sealed partial class CP14SoilComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public string Solution = string.Empty;
|
||||
|
||||
public EntityUid? PlantUid;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Content.Shared._CP14.SpawnOnTileTool;
|
||||
|
||||
namespace Content.Server._CP14.SpawnOnTileTool;
|
||||
|
||||
public sealed partial class CP14SpawnOnTileToolSystem : SharedCP14SpawnOnTileToolSystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<CP14SpawnOnTileToolComponent, SpawnOnTileToolAfterEvent>(AfterDoAfter);
|
||||
}
|
||||
|
||||
private void AfterDoAfter(Entity<CP14SpawnOnTileToolComponent> ent, ref SpawnOnTileToolAfterEvent args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled)
|
||||
return;
|
||||
|
||||
SpawnAtPosition(args.Spawn, GetCoordinates(args.Coordinates));
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -9,6 +12,9 @@ public sealed partial class CP14DayCycleSystem : EntitySystem
|
||||
private const float MaxTimeDiff = 0.05f;
|
||||
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -102,6 +108,35 @@ public sealed partial class CP14DayCycleSystem : EntitySystem
|
||||
Dirty(dayCycle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the specified entity is on the map where it's daytime.
|
||||
/// </summary>
|
||||
/// <param name="target">An entity being tested to see if it is in daylight</param>
|
||||
/// <param name="checkRoof">Checks if the tile covers the weather (the only "roof" factor at the moment)</param>
|
||||
/// <param name="isDaylight">daylight test result returned</param>
|
||||
public bool TryDaylightThere(EntityUid target, bool checkRoof)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(target, out var xform))
|
||||
return false;
|
||||
|
||||
if (!TryComp<CP14DayCycleComponent>(xform.MapUid, out var dayCycle))
|
||||
return false;
|
||||
|
||||
if (checkRoof)
|
||||
{
|
||||
if (!TryComp<MapGridComponent>(xform.GridUid, out var mapGrid))
|
||||
return !dayCycle.IsNight;
|
||||
|
||||
var tileRef = _maps.GetTileRef(xform.GridUid.Value, mapGrid, xform.Coordinates);
|
||||
var tileDef = (ContentTileDefinition) _tileDefManager[tileRef.Tile.TypeId];
|
||||
|
||||
if (!tileDef.Weather)
|
||||
return false;
|
||||
}
|
||||
|
||||
return !dayCycle.IsNight;
|
||||
}
|
||||
|
||||
private void SetAmbientColor(Entity<MapLightComponent> light, Color color)
|
||||
{
|
||||
if (color == light.Comp.AmbientLightColor)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using Content.Shared.Tools;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.DestroyedByTool;
|
||||
|
||||
/// <summary>
|
||||
/// abstract ability to destroy objects by using the right kind of tool on them
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14DestroyedByToolSystem))]
|
||||
public sealed partial class CP14DestroyedByToolComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public ProtoId<ToolQualityPrototype>? Tool;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan RemoveTime = TimeSpan.FromSeconds(1f);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Tools.Components;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.DestroyedByTool;
|
||||
|
||||
public sealed partial class CP14DestroyedByToolSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedToolSystem _tool = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14DestroyedByToolComponent, CP14DestroyedByToolDoAfterEvent>(OnDestroyDoAfter);
|
||||
SubscribeLocalEvent<CP14DestroyedByToolComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
}
|
||||
|
||||
private void OnInteractUsing(Entity<CP14DestroyedByToolComponent> ent, ref InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (ent.Comp.Tool == null || !_tool.HasQuality(args.Used, ent.Comp.Tool))
|
||||
return;
|
||||
|
||||
if (TryComp<ToolComponent>(args.Used, out var tool))
|
||||
{
|
||||
_tool.PlayToolSound(args.Used, tool, args.User);
|
||||
}
|
||||
|
||||
var doAfterArgs =
|
||||
new DoAfterArgs(EntityManager, args.User, ent.Comp.RemoveTime, new CP14DestroyedByToolDoAfterEvent(), args.Target)
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BlockDuplicate = true,
|
||||
BreakOnMove = true,
|
||||
BreakOnHandChange = true,
|
||||
};
|
||||
_doAfter.TryStartDoAfter(doAfterArgs);
|
||||
}
|
||||
|
||||
private void OnDestroyDoAfter(Entity<CP14DestroyedByToolComponent> ent, ref CP14DestroyedByToolDoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Handled)
|
||||
return;
|
||||
|
||||
QueueDel(ent);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class CP14DestroyedByToolDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
75
Content.Shared/_CP14/Farming/CP14PlantComponent.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._CP14.Farming;
|
||||
|
||||
/// <summary>
|
||||
/// The backbone of any plant. Provides common variables for the plant to other components, and a link to the soil
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true), Access(typeof(CP14SharedFarmingSystem))]
|
||||
public sealed partial class CP14PlantComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Soil link. May be null, as not all plants in the world grow on entity soil (e.g. wild shrubs)
|
||||
/// </summary>
|
||||
public EntityUid? SoilUid;
|
||||
|
||||
/// <summary>
|
||||
/// The ability to consume a resource for growing
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float Energy = 0f;
|
||||
|
||||
[DataField]
|
||||
public float EnergyMax = 100f;
|
||||
|
||||
/// <summary>
|
||||
/// resource consumed for growth
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float Resource = 0f;
|
||||
|
||||
[DataField]
|
||||
public float ResourceMax = 100f;
|
||||
|
||||
/// <summary>
|
||||
/// Plant growth status, 0 to 1
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float GrowthLevel = 0f;
|
||||
|
||||
[DataField(serverOnly: true)]
|
||||
public float UpdateFrequency = 60f;
|
||||
|
||||
[DataField(serverOnly: true)]
|
||||
public TimeSpan NextUpdateTime = TimeSpan.Zero;
|
||||
|
||||
[DataField(serverOnly: true)]
|
||||
public TimeSpan Age = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called periodically at random intervals on the plant.
|
||||
/// </summary>
|
||||
public sealed class CP14PlantUpdateEvent : EntityEventArgs
|
||||
{
|
||||
public readonly Entity<CP14PlantComponent> Plant;
|
||||
public float EnergyDelta = 0f;
|
||||
public float ResourceDelta = 0f;
|
||||
|
||||
public CP14PlantUpdateEvent(Entity<CP14PlantComponent> comp)
|
||||
{
|
||||
Plant = comp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// is called after CP14PlantUpdateEvent when all value changes have already been calculated.
|
||||
/// </summary>
|
||||
public sealed class CP14AfterPlantUpdateEvent : EntityEventArgs
|
||||
{
|
||||
public readonly Entity<CP14PlantComponent> Plant;
|
||||
public CP14AfterPlantUpdateEvent(Entity<CP14PlantComponent> comp)
|
||||
{
|
||||
Plant = comp;
|
||||
}
|
||||
}
|
||||
63
Content.Shared/_CP14/Farming/CP14PlantGatherableComponent.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
using Content.Shared.EntityList;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Farming;
|
||||
|
||||
/// <summary>
|
||||
/// Means that the plant can be harvested.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14PlantGatherableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Whitelist for specifying the kind of tools can be used on a resource
|
||||
/// Supports multiple tags.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public EntityWhitelist ToolWhitelist = new();
|
||||
|
||||
/// <summary>
|
||||
/// YAML example below
|
||||
/// (Tag1, Tag2, LootTableID1, LootTableID2 are placeholders for example)
|
||||
/// --------------------
|
||||
/// useMappedLoot: true
|
||||
/// toolWhitelist:
|
||||
/// tags:
|
||||
/// - Tag1
|
||||
/// - Tag2
|
||||
/// loot:
|
||||
/// Tag1: LootTableID1
|
||||
/// Tag2: LootTableID2
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Dictionary<string, ProtoId<EntityLootTablePrototype>>? Loot = new();
|
||||
|
||||
/// <summary>
|
||||
/// Random shift of the appearing entity during gathering
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float GatherOffset = 0.3f;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan Time = TimeSpan.FromSeconds(1f);
|
||||
|
||||
/// <summary>
|
||||
/// after harvesting, should the plant be completely removed?
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool DeleteAfterHarvest = false;
|
||||
|
||||
/// <summary>
|
||||
/// after harvest, the growth level of the plant will be reduced by the specified value
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float GrowthCostHarvest = 0.4f;
|
||||
|
||||
/// <summary>
|
||||
/// what level of growth does a plant need to have before it can be harvested?
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float GrowthLevelToHarvest = 0.9f;
|
||||
}
|
||||
37
Content.Shared/_CP14/Farming/CP14SharedFarmingSystem.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Farming;
|
||||
|
||||
public abstract partial class CP14SharedFarmingSystem : EntitySystem
|
||||
{
|
||||
public void AffectEnergy(Entity<CP14PlantComponent> ent, float energyDelta)
|
||||
{
|
||||
if (energyDelta == 0)
|
||||
return;
|
||||
|
||||
ent.Comp.Energy = MathHelper.Clamp(ent.Comp.Energy + energyDelta, 0, ent.Comp.EnergyMax);
|
||||
}
|
||||
public void AffectResource(Entity<CP14PlantComponent> ent, float resourceDelta)
|
||||
{
|
||||
if (resourceDelta == 0)
|
||||
return;
|
||||
|
||||
ent.Comp.Resource = MathHelper.Clamp(ent.Comp.Resource + resourceDelta, 0, ent.Comp.ResourceMax);
|
||||
}
|
||||
|
||||
public void AffectGrowth(Entity<CP14PlantComponent> ent, float growthDelta)
|
||||
{
|
||||
if (growthDelta == 0)
|
||||
return;
|
||||
|
||||
ent.Comp.GrowthLevel = MathHelper.Clamp01(ent.Comp.GrowthLevel + growthDelta);
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class PlantSeedDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared._CP14.Farming.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
|
||||
namespace Content.Shared._CP14.Farming.Metabolizer;
|
||||
|
||||
public sealed partial class AffectPlantValues : CP14MetabolizerEffect
|
||||
{
|
||||
[DataField]
|
||||
public float Energy = 0f;
|
||||
[DataField]
|
||||
public float Resource = 0f;
|
||||
[DataField]
|
||||
public float Growth = 0f;
|
||||
|
||||
public override void Effect(Entity<CP14PlantComponent> plant, FixedPoint2 amount, EntityManager entityManager)
|
||||
{
|
||||
var farmingSystem = entityManager.System<CP14SharedFarmingSystem>();
|
||||
|
||||
farmingSystem.AffectEnergy(plant, Energy * (float)amount);
|
||||
farmingSystem.AffectResource(plant,Resource * (float)amount);
|
||||
farmingSystem.AffectGrowth(plant, Growth * (float)amount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Farming.Prototypes;
|
||||
|
||||
/// <summary>
|
||||
/// Allows the plant to drink chemicals from the soil. The effect of the drank reagents depends on the selected metabolizer.
|
||||
/// </summary>
|
||||
[Prototype("CP14PlantMetabolizer")]
|
||||
public sealed partial class CP14PlantMetabolizerPrototype : IPrototype
|
||||
{
|
||||
[ViewVariables]
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = string.Empty;
|
||||
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<ReagentPrototype>, HashSet<CP14MetabolizerEffect>> Metabolization = new();
|
||||
}
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14MetabolizerEffect
|
||||
{
|
||||
public abstract void Effect(Entity<CP14PlantComponent> plant, FixedPoint2 amount, EntityManager entityManager);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.SpawnOnTileTool;
|
||||
|
||||
/// <summary>
|
||||
/// Allows using an item on a certain type of tile to spawn entities on it.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(SharedCP14SpawnOnTileToolSystem))]
|
||||
public sealed partial class CP14SpawnOnTileToolComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<ContentTileDefinition>, EntProtoId> Spawns = new();
|
||||
|
||||
[DataField]
|
||||
public bool NeedEmptySpace = true;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan DoAfter = TimeSpan.FromSeconds(1f);
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class SpawnOnTileToolAfterEvent : DoAfterEvent
|
||||
{
|
||||
public override DoAfterEvent Clone() => this;
|
||||
public readonly NetCoordinates Coordinates;
|
||||
public readonly EntProtoId Spawn;
|
||||
|
||||
public SpawnOnTileToolAfterEvent(IEntityManager entManager, EntityCoordinates coord, EntProtoId spawn)
|
||||
{
|
||||
Spawn = spawn;
|
||||
Coordinates = entManager.GetNetCoordinates(coord);
|
||||
}
|
||||
|
||||
public SpawnOnTileToolAfterEvent(NetCoordinates coord, EntProtoId spawn)
|
||||
{
|
||||
Spawn = spawn;
|
||||
Coordinates = coord;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._CP14.Farming;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
namespace Content.Shared._CP14.SpawnOnTileTool;
|
||||
|
||||
public partial class SharedCP14SpawnOnTileToolSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedMapSystem _map = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly ITileDefinitionManager _tileDef = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<CP14SpawnOnTileToolComponent, AfterInteractEvent>(OnAfterInteract);
|
||||
}
|
||||
|
||||
private void OnAfterInteract(Entity<CP14SpawnOnTileToolComponent> tool, ref AfterInteractEvent args)
|
||||
{
|
||||
var grid = _transform.GetGrid(args.ClickLocation);
|
||||
|
||||
if (grid == null || !TryComp<MapGridComponent>(grid, out var gridComp))
|
||||
return;
|
||||
|
||||
var tile = _map.GetTileRef(grid.Value, gridComp, args.ClickLocation);
|
||||
var tileDef = (ContentTileDefinition) _tileDef[tile.Tile.TypeId];
|
||||
|
||||
if (tool.Comp.NeedEmptySpace && _map.GetAnchoredEntities(grid.Value, gridComp, args.ClickLocation).Count() > 0)
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString("cp14-insufficient-space"), args.ClickLocation, args.User);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var pair in tool.Comp.Spawns)
|
||||
{
|
||||
if (tileDef.ID != pair.Key)
|
||||
continue;
|
||||
|
||||
var doAfterArgs =
|
||||
new DoAfterArgs(EntityManager, args.User, tool.Comp.DoAfter, new SpawnOnTileToolAfterEvent(EntityManager, args.ClickLocation, pair.Value), tool)
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BlockDuplicate = true,
|
||||
BreakOnMove = true,
|
||||
BreakOnHandChange = true
|
||||
};
|
||||
_doAfter.TryStartDoAfter(doAfterArgs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# Crystal
|
||||
|
||||
popup-cp14crystal-ding = *ding*
|
||||
1
Resources/Locale/en-US/_CP14/farming/farming.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-farming-soil-interact-plant-exist = There's already something planted here!
|
||||
3
Resources/Locale/en-US/_CP14/misc/interaction.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
popup-cp14crystal-ding = *ding*
|
||||
|
||||
cp14-insufficient-space = Insufficient space!
|
||||
@@ -1,3 +0,0 @@
|
||||
# Crystal
|
||||
|
||||
popup-cp14crystal-ding = *дзынь*
|
||||
1
Resources/Locale/ru-RU/_CP14/farming/farming.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-farming-soil-interact-plant-exist = Здесь уже что-то посажено!
|
||||
3
Resources/Locale/ru-RU/_CP14/misc/interaction.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
popup-cp14crystal-ding = *дзынь*
|
||||
|
||||
cp14-insufficient-space = Недостаточно места!
|
||||
10
Resources/Prototypes/_CP14/Entities/FARMINGTEST.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
- type: entity
|
||||
id: CP14SeedTest
|
||||
name: FUCK test SEED
|
||||
parent: BaseItem
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Hydroponics/seeds.rsi
|
||||
state: seed
|
||||
- type: CP14Seed
|
||||
plantProto: CP14PlantWheat
|
||||
@@ -8,7 +8,7 @@
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: _CP14/Objects/Specific/Alchemy/Herbal/agaric.rsi
|
||||
- sprite: _CP14/Structures/Specific/Farming/Herbals/agaric.rsi
|
||||
state: world1
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
- type: entity
|
||||
id: CP14Wheat
|
||||
parent: ProduceBase
|
||||
name: wheat bushel
|
||||
description: You have the choice of either planting the grains again or grinding them into flour.
|
||||
components:
|
||||
- type: Item
|
||||
size: Tiny
|
||||
- type: Produce
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Specific/Farming/Produce/wheat.rsi
|
||||
layers:
|
||||
- state: base1
|
||||
map: ["random"]
|
||||
- type: RandomSprite
|
||||
available:
|
||||
- random:
|
||||
base1: ""
|
||||
base2: ""
|
||||
@@ -12,7 +12,7 @@
|
||||
size: Tiny
|
||||
- type: Produce
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/bloodgrass.rsi
|
||||
sprite: _CP14/Objects/Specific/Farming/Produce/bloodgrass.rsi
|
||||
layers:
|
||||
- state: base1
|
||||
map: ["random"]
|
||||
@@ -54,7 +54,7 @@
|
||||
size: Tiny
|
||||
- type: Produce
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/agaric.rsi
|
||||
sprite: _CP14/Objects/Specific/Farming/Produce/agaric.rsi
|
||||
layers:
|
||||
- state: base1
|
||||
map: ["random"]
|
||||
@@ -93,7 +93,7 @@
|
||||
size: Tiny
|
||||
- type: Produce
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/chromium_slime.rsi
|
||||
sprite: _CP14/Objects/Specific/Farming/Produce/chromium_slime.rsi
|
||||
layers:
|
||||
- state: base1
|
||||
map: ["random"]
|
||||
@@ -131,7 +131,7 @@
|
||||
- 0,0,0,1
|
||||
- type: Produce
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/wild_sage.rsi
|
||||
sprite: _CP14/Objects/Specific/Farming/Produce/wild_sage.rsi
|
||||
layers:
|
||||
- state: base1
|
||||
map: ["random"]
|
||||
@@ -197,7 +197,7 @@
|
||||
size: Tiny
|
||||
- type: Produce
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/lumishroom.rsi
|
||||
sprite: _CP14/Objects/Specific/Farming/Produce/lumishroom.rsi
|
||||
layers:
|
||||
- state: base1
|
||||
map: ["random"]
|
||||
@@ -0,0 +1,53 @@
|
||||
- type: entity
|
||||
id: CP14Shovel
|
||||
parent: BaseItem
|
||||
name: shovel
|
||||
description: An implement for digging up earth, digging beds or graves.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Tools/shovel.rsi
|
||||
state: icon
|
||||
- type: MeleeWeapon
|
||||
wideAnimationRotation: 65
|
||||
damage:
|
||||
types:
|
||||
Blunt: 5
|
||||
Slash: 2
|
||||
soundHit:
|
||||
collection: MetalThud
|
||||
- type: Item
|
||||
size: Normal
|
||||
sprite: _CP14/Objects/Tools/shovel.rsi
|
||||
- type: ToolTileCompatible
|
||||
- type: Tool
|
||||
qualities:
|
||||
- CP14Digging
|
||||
useSound:
|
||||
collection: CP14Digging
|
||||
params:
|
||||
variation: 0.03
|
||||
volume: 2
|
||||
|
||||
- type: entity
|
||||
id: CP14Hoe
|
||||
parent: BaseItem
|
||||
name: hoe
|
||||
description: A gardening tool to prepare the soil for planting, or to clear weeds
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Tools/hoe.rsi
|
||||
state: icon
|
||||
- type: MeleeWeapon
|
||||
wideAnimationRotation: 65
|
||||
damage:
|
||||
types:
|
||||
Piercing: 5
|
||||
Slash: 2
|
||||
soundHit:
|
||||
collection: MetalThud
|
||||
- type: Item
|
||||
size: Normal
|
||||
sprite: _CP14/Objects/Tools/hoe.rsi
|
||||
- type: CP14SpawnOnTileTool
|
||||
spawns:
|
||||
CP14FloorDirt: CP14PloughedGround
|
||||
@@ -1,29 +0,0 @@
|
||||
- type: entity
|
||||
id: CP14Shovel
|
||||
parent: BaseItem
|
||||
name: shovel
|
||||
description: An implement for digging up earth, digging beds or graves.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Objects/Tools/shovel.rsi
|
||||
state: icon
|
||||
- type: MeleeWeapon
|
||||
wideAnimationRotation: 45
|
||||
damage:
|
||||
types:
|
||||
Blunt: 7
|
||||
Slash: 3
|
||||
soundHit:
|
||||
collection: MetalThud
|
||||
- type: Item
|
||||
size: Normal
|
||||
sprite: _CP14/Objects/Tools/shovel.rsi
|
||||
- type: ToolTileCompatible
|
||||
- type: Tool
|
||||
qualities:
|
||||
- CP14Digging
|
||||
useSound:
|
||||
collection: CP14Digging
|
||||
params:
|
||||
variation: 0.03
|
||||
volume: 2
|
||||
@@ -0,0 +1,70 @@
|
||||
- type: entity
|
||||
id: CP14GatherableBase
|
||||
parent: BaseStructure
|
||||
abstract: true
|
||||
components:
|
||||
- type: Sprite
|
||||
snapCardinals: true
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Physics
|
||||
canCollide: false
|
||||
bodyType: Static
|
||||
- type: CP14DestroyedByTool
|
||||
tool: CP14Digging
|
||||
- type: CP14PlantAutoRoot
|
||||
- type: Damageable
|
||||
damageContainer: Biological
|
||||
- type: MeleeSound
|
||||
soundGroups:
|
||||
Brute:
|
||||
collection: CP14GrassGathering
|
||||
params:
|
||||
variation: 0.03
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 25
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- trigger:
|
||||
!type:DamageTypeTrigger
|
||||
damageType: Cellular
|
||||
damage: 1
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
|
||||
- type: entity
|
||||
id: CP14GatherableWildBase
|
||||
parent: CP14GatherableBase
|
||||
abstract: true
|
||||
components:
|
||||
- type: Tag
|
||||
tags:
|
||||
- HideContextMenu
|
||||
- type: Gatherable
|
||||
toolWhitelist:
|
||||
tags:
|
||||
- CP14HerbalGathering
|
||||
|
||||
- type: entity
|
||||
id: CP14GatherablePlantBase
|
||||
parent: CP14GatherableBase
|
||||
abstract: true
|
||||
components:
|
||||
- type: InteractionOutline
|
||||
- type: Appearance
|
||||
- type: CP14PlantVisuals
|
||||
growthSteps: 5
|
||||
growState: "grow-"
|
||||
- type: CP14Plant
|
||||
resource: 10
|
||||
energy: 0
|
||||
growthLevel: 0
|
||||
- type: CP14PlantGatherable
|
||||
toolWhitelist:
|
||||
tags:
|
||||
- CP14HerbalGathering
|
||||
@@ -0,0 +1,67 @@
|
||||
- type: entity
|
||||
id: CP14PlantWheat
|
||||
parent: CP14GatherablePlantBase
|
||||
name: wheat
|
||||
description: Most popular crop. Unpretentious, it opens the way to an abundance of flour products.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Structures/Specific/Farming/Herbals/wheat.rsi
|
||||
layers:
|
||||
- state: grow-1
|
||||
map: ["enum.PlantVisualLayers.Base"]
|
||||
- type: CP14PlantMetabolizer
|
||||
metabolizerId: Base
|
||||
- type: CP14PlantEnergyFromLight
|
||||
energy: 1
|
||||
daytime: true
|
||||
- type: CP14PlantGrowing
|
||||
energyCost: 1
|
||||
resourceCost: 1
|
||||
growthPerUpdate: 0.1 # 10 minute to full grow
|
||||
- type: CP14PlantFading
|
||||
resourcePerMinute: 0.25 #20 minute from water
|
||||
- type: CP14PlantGatherable
|
||||
deleteAfterHarvest: true
|
||||
loot:
|
||||
All: CP14GatherWheat
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 25
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- trigger:
|
||||
!type:DamageTypeTrigger
|
||||
damageType: Cellular
|
||||
damage: 1
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- !type:SpawnEntitiesBehavior
|
||||
spawn:
|
||||
CP14PlantWheatDeath:
|
||||
min: 1
|
||||
max: 1
|
||||
|
||||
- type: entity
|
||||
id: CP14PlantWheatDeath
|
||||
name: dead wheat
|
||||
description: The sad spectacle of wasted food.
|
||||
parent: CP14GatherableBase
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Structures/Specific/Farming/Herbals/wheat.rsi
|
||||
state: death
|
||||
- type: Gatherable
|
||||
toolWhitelist:
|
||||
tags:
|
||||
- CP14HerbalGathering
|
||||
|
||||
- type: entityLootTable
|
||||
id: CP14GatherWheat
|
||||
entries:
|
||||
- id: CP14Wheat
|
||||
amount: 2
|
||||
maxAmount: 4
|
||||
@@ -1,36 +1,3 @@
|
||||
- type: entity
|
||||
id: CP14GatherableHerbalBase
|
||||
parent: BaseStructure
|
||||
abstract: true
|
||||
components:
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Physics
|
||||
canCollide: false
|
||||
- type: Gatherable
|
||||
toolWhitelist:
|
||||
tags:
|
||||
- CP14HerbalGathering
|
||||
- type: Damageable
|
||||
damageContainer: Inorganic
|
||||
damageModifierSet: Wood
|
||||
- type: MeleeSound
|
||||
soundGroups:
|
||||
Brute:
|
||||
collection: CP14GrassGathering
|
||||
params:
|
||||
variation: 0.03
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 25
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- type: Tag
|
||||
tags:
|
||||
- HideContextMenu
|
||||
|
||||
# Bloodgrass
|
||||
|
||||
@@ -43,15 +10,14 @@
|
||||
|
||||
- type: entity
|
||||
id: CP14GatherableBloodgrass
|
||||
parent: CP14GatherableHerbalBase
|
||||
parent: CP14GatherableWildBase
|
||||
name: bloodgrass
|
||||
description: The dullest and most common plant to be found in the wild is the dark brown grass.
|
||||
suffix: Gatherable
|
||||
components:
|
||||
- type: Sprite
|
||||
snapCardinals: true
|
||||
drawdepth: FloorTiles
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/bloodgrass.rsi
|
||||
sprite: _CP14/Structures/Specific/Farming/Herbals/bloodgrass.rsi
|
||||
layers:
|
||||
- state: grass1
|
||||
map: ["random"]
|
||||
@@ -78,15 +44,14 @@
|
||||
|
||||
- type: entity
|
||||
id: CP14GatherableFlyAgaric
|
||||
parent: CP14GatherableHerbalBase
|
||||
parent: CP14GatherableWildBase
|
||||
name: fly agaric
|
||||
description: This poisonous mushroom can often be found near bodies of water or other wet areas. It is not recommended for consumption.
|
||||
suffix: Gatherable
|
||||
components:
|
||||
- type: Sprite
|
||||
snapCardinals: true
|
||||
drawdepth: FloorTiles
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/agaric.rsi
|
||||
sprite: _CP14/Structures/Specific/Farming/Herbals/agaric.rsi
|
||||
layers:
|
||||
- state: world1
|
||||
map: ["random"]
|
||||
@@ -119,15 +84,14 @@
|
||||
|
||||
- type: entity
|
||||
id: CP14GatherableChromiumSlime
|
||||
parent: CP14GatherableHerbalBase
|
||||
parent: CP14GatherableWildBase
|
||||
name: chromium slime
|
||||
description: This rare thick substance can be found in a stream of water as if it has a mind of its own. When trying to change the slime itself - the slime changes the reagent it interacts with.
|
||||
suffix: Gatherable
|
||||
components:
|
||||
- type: Sprite
|
||||
snapCardinals: true
|
||||
drawdepth: FloorTiles
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/chromium_slime.rsi
|
||||
sprite: _CP14/Structures/Specific/Farming/Herbals/chromium_slime.rsi
|
||||
layers:
|
||||
- state: world1
|
||||
map: ["random"]
|
||||
@@ -155,15 +119,14 @@
|
||||
|
||||
- type: entity
|
||||
id: CP14GatherableWildSage
|
||||
parent: CP14GatherableHerbalBase
|
||||
parent: CP14GatherableWildBase
|
||||
name: wild sage
|
||||
description: Root of this ubiquitous medicinal plant not bad at healing physical injuries, and inducing coughing.
|
||||
suffix: Gatherable
|
||||
components:
|
||||
- type: Sprite
|
||||
snapCardinals: true
|
||||
drawdepth: FloorTiles
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/wild_sage.rsi
|
||||
sprite: _CP14/Structures/Specific/Farming/Herbals/wild_sage.rsi
|
||||
layers:
|
||||
- state: world1
|
||||
map: ["random"]
|
||||
@@ -188,15 +151,14 @@
|
||||
|
||||
- type: entity
|
||||
id: CP14GatherableLumiMushroom
|
||||
parent: CP14GatherableHerbalBase
|
||||
parent: CP14GatherableWildBase
|
||||
name: lumishroom
|
||||
description: A faintly luminous mushroom. Often used by alchemists as a means of concentrating solutions.
|
||||
suffix: Gatherable
|
||||
components:
|
||||
- type: Sprite
|
||||
snapCardinals: true
|
||||
drawdepth: FloorTiles
|
||||
sprite: _CP14/Objects/Specific/Alchemy/Herbal/lumishroom.rsi
|
||||
sprite: _CP14/Structures/Specific/Farming/Herbals/lumishroom.rsi
|
||||
layers:
|
||||
- state: world1
|
||||
map: ["random"]
|
||||
@@ -0,0 +1,88 @@
|
||||
- type: entity
|
||||
id: CP14BaseFarmingSoil
|
||||
abstract: true
|
||||
placement:
|
||||
mode: SnapgridCenter
|
||||
components:
|
||||
- type: Clickable
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.45,-0.45,0.45,0.1"
|
||||
density: 190
|
||||
hard: false
|
||||
mask:
|
||||
- FullTileMask
|
||||
layer:
|
||||
- FullTileMask
|
||||
- type: Appearance
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
soil:
|
||||
maxVol: 200
|
||||
- type: RefillableSolution
|
||||
solution: soil
|
||||
maxRefill: 50
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: CP14Soil
|
||||
solution: soil
|
||||
- type: CP14DestroyedByTool
|
||||
tool: CP14Digging
|
||||
|
||||
- type: entity
|
||||
name: ploughed ground
|
||||
parent: CP14BaseFarmingSoil
|
||||
id: CP14PloughedGround
|
||||
components:
|
||||
- type: Sprite
|
||||
drawdepth: FloorTiles
|
||||
sprite: _CP14/Structures/Specific/Farming/soil.rsi
|
||||
layers:
|
||||
- state: soil1
|
||||
map: ["random"]
|
||||
- state: liq-1 #Resprite this shit
|
||||
map: ["enum.SolutionContainerLayers.Fill"]
|
||||
visible: false
|
||||
snapCardinals: true
|
||||
- type: SolutionContainerVisuals
|
||||
maxFillLevels: 4
|
||||
fillBaseName: liq-
|
||||
- type: RandomSprite
|
||||
available:
|
||||
- random:
|
||||
soil1: ""
|
||||
soil2: ""
|
||||
soil3: ""
|
||||
soil4: ""
|
||||
|
||||
- type: entity
|
||||
name: seedbed
|
||||
id: CP14SeedbedDefault
|
||||
parent: CP14BaseFarmingSoil
|
||||
components:
|
||||
- type: Icon
|
||||
sprite: _CP14/Structures/Specific/Farming/seedbed.rsi
|
||||
state: seedbed_default
|
||||
- type: SmoothEdge
|
||||
- type: IconSmooth
|
||||
key: walls
|
||||
mode: NoSprite
|
||||
- type: Sprite
|
||||
drawdepth: FloorTiles
|
||||
sprite: _CP14/Structures/Specific/Farming/seedbed.rsi
|
||||
layers:
|
||||
- state: seedbed_default
|
||||
- map: [ "enum.EdgeLayer.South" ]
|
||||
state: seedbed_default_south
|
||||
- map: [ "enum.EdgeLayer.East" ]
|
||||
state: seedbed_default_east
|
||||
- map: [ "enum.EdgeLayer.North" ]
|
||||
state: seedbed_default_north
|
||||
- map: [ "enum.EdgeLayer.West" ]
|
||||
state: seedbed_default_west
|
||||
# snapCardinals: true (when you flip it over, you get a swastika)
|
||||
@@ -0,0 +1,6 @@
|
||||
- type: CP14PlantMetabolizer
|
||||
id: Base
|
||||
metabolization:
|
||||
CP14Water:
|
||||
- !type:AffectPlantValues
|
||||
resource: 1
|
||||
|
Before Width: | Height: | Size: 447 B After Width: | Height: | Size: 447 B |
|
Before Width: | Height: | Size: 488 B After Width: | Height: | Size: 488 B |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 572 B |
|
Before Width: | Height: | Size: 368 B After Width: | Height: | Size: 368 B |
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd (Github) for CrystallPunk14",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
},
|
||||
{
|
||||
"name": "base4"
|
||||
},
|
||||
{
|
||||
"name": "base5"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 396 B |
|
Before Width: | Height: | Size: 503 B After Width: | Height: | Size: 503 B |
|
Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 452 B |
|
Before Width: | Height: | Size: 412 B After Width: | Height: | Size: 412 B |
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Base Created by TheShuEd (Github) for CrystallPunk14, Grass taken from tgstation at commits https://github.com/tgstation/tgstation/commit/729d858807905263adab8b5a331c1d8a04982dd3, and recolored",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
},
|
||||
{
|
||||
"name": "base4"
|
||||
},
|
||||
{
|
||||
"name": "base5"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 216 B |
|
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 300 B |
|
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 307 B |
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd (Github) for CrystallPunk14",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 367 B |
|
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 380 B |
|
Before Width: | Height: | Size: 467 B After Width: | Height: | Size: 467 B |
|
Before Width: | Height: | Size: 375 B After Width: | Height: | Size: 375 B |
|
Before Width: | Height: | Size: 379 B After Width: | Height: | Size: 379 B |
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd (Github) for CrystallPunk14",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
},
|
||||
{
|
||||
"name": "base4"
|
||||
},
|
||||
{
|
||||
"name": "base5"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 465 B |
|
After Width: | Height: | Size: 467 B |
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd for CrystallPunk14",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 654 B After Width: | Height: | Size: 654 B |
|
Before Width: | Height: | Size: 743 B After Width: | Height: | Size: 743 B |
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by Prazar for CrystallPunk14",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/_CP14/Objects/Tools/hoe.rsi/icon.png
Normal file
|
After Width: | Height: | Size: 377 B |
BIN
Resources/Textures/_CP14/Objects/Tools/hoe.rsi/inhand-left.png
Normal file
|
After Width: | Height: | Size: 819 B |
BIN
Resources/Textures/_CP14/Objects/Tools/hoe.rsi/inhand-right.png
Normal file
|
After Width: | Height: | Size: 807 B |
22
Resources/Textures/_CP14/Objects/Tools/hoe.rsi/meta.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd (Github) for CrystallPunk",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "icon"
|
||||
},
|
||||
{
|
||||
"name": "inhand-left",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "inhand-right",
|
||||
"directions": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 362 B |
|
Before Width: | Height: | Size: 748 B After Width: | Height: | Size: 777 B |
|
Before Width: | Height: | Size: 749 B After Width: | Height: | Size: 795 B |
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 400 B |
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 397 B |
|
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 372 B |
|
Before Width: | Height: | Size: 526 B After Width: | Height: | Size: 583 B |
|
Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 587 B |
@@ -7,21 +7,6 @@
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd (Github) for CrystallPunk14",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
},
|
||||
{
|
||||
"name": "base4"
|
||||
},
|
||||
{
|
||||
"name": "base5"
|
||||
},
|
||||
{
|
||||
"name": "world1"
|
||||
},
|
||||
|
Before Width: | Height: | Size: 910 B After Width: | Height: | Size: 910 B |
|
Before Width: | Height: | Size: 692 B After Width: | Height: | Size: 692 B |
|
Before Width: | Height: | Size: 709 B After Width: | Height: | Size: 709 B |
|
Before Width: | Height: | Size: 644 B After Width: | Height: | Size: 644 B |
|
Before Width: | Height: | Size: 806 B After Width: | Height: | Size: 806 B |
|
Before Width: | Height: | Size: 566 B After Width: | Height: | Size: 566 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 705 B After Width: | Height: | Size: 705 B |
|
Before Width: | Height: | Size: 710 B After Width: | Height: | Size: 710 B |
@@ -7,21 +7,6 @@
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Base Created by TheShuEd (Github) for CrystallPunk14, Grass taken from tgstation at commits https://github.com/tgstation/tgstation/commit/729d858807905263adab8b5a331c1d8a04982dd3, and recolored",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
},
|
||||
{
|
||||
"name": "base4"
|
||||
},
|
||||
{
|
||||
"name": "base5"
|
||||
},
|
||||
{
|
||||
"name": "grass1"
|
||||
},
|
||||
@@ -7,15 +7,6 @@
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd (Github) for CrystallPunk14",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
},
|
||||
{
|
||||
"name": "world1",
|
||||
"delays": [
|
||||
|
Before Width: | Height: | Size: 340 B After Width: | Height: | Size: 340 B |
|
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 489 B |
|
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 290 B |
@@ -7,21 +7,6 @@
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd (Github) for CrystallPunk14",
|
||||
"states": [
|
||||
{
|
||||
"name": "base1"
|
||||
},
|
||||
{
|
||||
"name": "base2"
|
||||
},
|
||||
{
|
||||
"name": "base3"
|
||||
},
|
||||
{
|
||||
"name": "base4"
|
||||
},
|
||||
{
|
||||
"name": "base5"
|
||||
},
|
||||
{
|
||||
"name": "world1"
|
||||
},
|
||||
|
Before Width: | Height: | Size: 590 B After Width: | Height: | Size: 590 B |