Killer tomatoes (#26053)
* make tomatoes * many friends! many mommies * finish * renaming system * fix * Update miscellaneous.yml * Update Content.Server/NPC/Systems/NPCImpritingBehaviourSystem.cs Co-authored-by: faint <46868845+ficcialfaint@users.noreply.github.com> * N * deleete exception? * merge conflict fix * fix? * fuck you * sloth fixes * fixess? * fix --------- Co-authored-by: faint <46868845+ficcialfaint@users.noreply.github.com> Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
@@ -0,0 +1,34 @@
|
|||||||
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Collections;
|
||||||
|
|
||||||
|
namespace Content.Server.NPC.Components;
|
||||||
|
/// <summary>
|
||||||
|
/// A component that makes the entity friendly to nearby creatures it sees on init.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class NPCImprintingOnSpawnBehaviourComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// filter who can be a friend to this creature
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public EntityWhitelist? Whitelist;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// when a creature appears, it will memorize all creatures in the radius to remember them as friends
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float SpawnFriendsSearchRadius = 3f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// if there is a FollowCompound in HTN, the target of the following will be selected from random nearby targets when it appears
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public bool Follow = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// is used to determine who became a friend from this component
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public List<EntityUid> Friends = new();
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Shared.NPC.Components;
|
||||||
|
using Content.Shared.NPC.Systems;
|
||||||
|
using Robust.Shared.Collections;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using NPCImprintingOnSpawnBehaviourComponent = Content.Server.NPC.Components.NPCImprintingOnSpawnBehaviourComponent;
|
||||||
|
|
||||||
|
namespace Content.Server.NPC.Systems;
|
||||||
|
|
||||||
|
public sealed partial class NPCImprintingOnSpawnBehaviourSystem : SharedNPCImprintingOnSpawnBehaviourSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||||
|
[Dependency] private readonly NPCSystem _npc = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<NPCImprintingOnSpawnBehaviourComponent, MapInitEvent>(OnMapInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMapInit(Entity<NPCImprintingOnSpawnBehaviourComponent> imprinting, ref MapInitEvent args)
|
||||||
|
{
|
||||||
|
HashSet<EntityUid> friends = new();
|
||||||
|
_lookup.GetEntitiesInRange(imprinting, imprinting.Comp.SpawnFriendsSearchRadius, friends);
|
||||||
|
|
||||||
|
foreach (var friend in friends)
|
||||||
|
{
|
||||||
|
if (imprinting.Comp.Whitelist?.IsValid(friend) != false)
|
||||||
|
{
|
||||||
|
AddImprintingTarget(imprinting, friend, imprinting.Comp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imprinting.Comp.Follow && imprinting.Comp.Friends.Count > 0)
|
||||||
|
{
|
||||||
|
var mommy = _random.Pick(imprinting.Comp.Friends);
|
||||||
|
_npc.SetBlackboard(imprinting, NPCBlackboard.FollowTarget, new EntityCoordinates(mommy, Vector2.Zero));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddImprintingTarget(EntityUid entity, EntityUid friend, NPCImprintingOnSpawnBehaviourComponent component)
|
||||||
|
{
|
||||||
|
component.Friends.Add(friend);
|
||||||
|
var exception = EnsureComp<FactionExceptionComponent>(entity);
|
||||||
|
exception.Ignored.Add(friend);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ using Content.Shared.CCVar;
|
|||||||
using Content.Shared.Mobs;
|
using Content.Shared.Mobs;
|
||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
using Content.Shared.NPC;
|
using Content.Shared.NPC;
|
||||||
|
using Content.Shared.NPC.Systems;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Content.Shared.NPC.Components;
|
|||||||
/// Prevents an NPC from attacking ignored entities from enemy factions.
|
/// Prevents an NPC from attacking ignored entities from enemy factions.
|
||||||
/// Can be added to if pettable, see PettableFriendComponent.
|
/// Can be added to if pettable, see PettableFriendComponent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSystem))]
|
[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSystem), typeof(SharedNPCImprintingOnSpawnBehaviourSystem))] // TO DO (Metalgearsloth): If we start adding a billion access overrides they should be going through a system as then there's no reason to have access, but I'll fix this when I rework npcs.
|
||||||
public sealed partial class FactionExceptionComponent : Component
|
public sealed partial class FactionExceptionComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
namespace Content.Shared.NPC.Systems;
|
||||||
|
|
||||||
|
public abstract partial class SharedNPCImprintingOnSpawnBehaviourSystem : EntitySystem
|
||||||
|
{
|
||||||
|
}
|
||||||
5
Content.Shared/NPC/Systems/SharedNPCSystem.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
namespace Content.Shared.NPC.Systems;
|
||||||
|
|
||||||
|
public abstract partial class SharedNPCSystem : EntitySystem
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -41,6 +41,8 @@ seeds-bluetomato-name = blue tomato
|
|||||||
seeds-bluetomato-display-name = blue tomato plant
|
seeds-bluetomato-display-name = blue tomato plant
|
||||||
seeds-bloodtomato-name = blood tomato
|
seeds-bloodtomato-name = blood tomato
|
||||||
seeds-bloodtomato-display-name = blood tomato plant
|
seeds-bloodtomato-display-name = blood tomato plant
|
||||||
|
seeds-killertomato-name = tomato killer
|
||||||
|
seeds-killertomato-display-name = tomato killer plant
|
||||||
seeds-eggplant-name = eggplant
|
seeds-eggplant-name = eggplant
|
||||||
seeds-eggplant-display-name = eggplants
|
seeds-eggplant-display-name = eggplants
|
||||||
seeds-apple-name = apple
|
seeds-apple-name = apple
|
||||||
|
|||||||
@@ -66,3 +66,98 @@
|
|||||||
interactFailureString: petting-failure-generic
|
interactFailureString: petting-failure-generic
|
||||||
interactSuccessSound:
|
interactSuccessSound:
|
||||||
path: /Audio/Animals/lizard_happy.ogg
|
path: /Audio/Animals/lizard_happy.ogg
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: MobTomatoKiller
|
||||||
|
parent:
|
||||||
|
- BaseSimpleMob
|
||||||
|
- MobDamageable
|
||||||
|
- MobBloodstream
|
||||||
|
- MobFlammable
|
||||||
|
- MobCombat
|
||||||
|
name: tomato killer
|
||||||
|
description: it seems today it's not you eating tomatoes, it's the tomatoes eating you.
|
||||||
|
components:
|
||||||
|
- type: Item
|
||||||
|
size: Huge
|
||||||
|
- type: NpcFactionMember
|
||||||
|
factions:
|
||||||
|
- SimpleHostile
|
||||||
|
- type: HTN
|
||||||
|
rootTask:
|
||||||
|
task: KillerTomatoCompound
|
||||||
|
- type: NPCImprintingOnSpawnBehaviour
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- HumanoidAppearance
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Mobs/Demons/tomatokiller.rsi
|
||||||
|
noRot: true
|
||||||
|
layers:
|
||||||
|
- map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||||
|
state: alive
|
||||||
|
- type: Bloodstream
|
||||||
|
bloodReagent: JuiceTomato
|
||||||
|
bloodMaxVolume: 50
|
||||||
|
chemicalMaxVolume: 30
|
||||||
|
- type: DamageStateVisuals
|
||||||
|
states:
|
||||||
|
Alive:
|
||||||
|
Base: alive
|
||||||
|
Dead:
|
||||||
|
Base: dead
|
||||||
|
- type: Butcherable
|
||||||
|
spawned:
|
||||||
|
- id: FoodMeatTomato
|
||||||
|
amount: 2
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTypeTrigger
|
||||||
|
damageType: Blunt
|
||||||
|
damage: 100
|
||||||
|
behaviors:
|
||||||
|
- !type:GibBehavior { }
|
||||||
|
- type: MobThresholds
|
||||||
|
thresholds:
|
||||||
|
0: Alive
|
||||||
|
24: Dead
|
||||||
|
- type: Fixtures
|
||||||
|
fixtures:
|
||||||
|
fix1:
|
||||||
|
shape:
|
||||||
|
!type:PhysShapeCircle
|
||||||
|
radius: 0.30
|
||||||
|
density: 80
|
||||||
|
mask:
|
||||||
|
- MobMask
|
||||||
|
layer:
|
||||||
|
- MobLayer
|
||||||
|
- type: MeleeWeapon
|
||||||
|
hidden: true
|
||||||
|
damage:
|
||||||
|
groups:
|
||||||
|
Brute: 4
|
||||||
|
animation: WeaponArcBite
|
||||||
|
- type: Climbing
|
||||||
|
- type: NameIdentifier
|
||||||
|
group: GenericNumber
|
||||||
|
- type: SlowOnDamage
|
||||||
|
speedModifierThresholds:
|
||||||
|
60: 0.7
|
||||||
|
80: 0.5
|
||||||
|
- type: FootstepModifier
|
||||||
|
footstepSoundCollection:
|
||||||
|
path: /Audio/Effects/Footsteps/slime1.ogg
|
||||||
|
params:
|
||||||
|
volume: 3
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- FootstepSound
|
||||||
|
- Fruit
|
||||||
|
- type: Extractable
|
||||||
|
grindableSolutionName: bloodstream
|
||||||
|
- type: PotencyVisuals
|
||||||
|
- type: Appearance
|
||||||
|
- type: Produce
|
||||||
|
seedId: killerTomato
|
||||||
|
|||||||
@@ -213,6 +213,16 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Specific/Hydroponics/blood_tomato.rsi
|
sprite: Objects/Specific/Hydroponics/blood_tomato.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of killer tomato seeds
|
||||||
|
id: KillerTomatoSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seedId: killerTomato
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/tomatokiller.rsi
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SeedBase
|
parent: SeedBase
|
||||||
name: packet of eggplant seeds
|
name: packet of eggplant seeds
|
||||||
|
|||||||
@@ -479,8 +479,10 @@
|
|||||||
packetPrototype: BloodTomatoSeeds
|
packetPrototype: BloodTomatoSeeds
|
||||||
productPrototypes:
|
productPrototypes:
|
||||||
- FoodBloodTomato
|
- FoodBloodTomato
|
||||||
|
mutationPrototypes:
|
||||||
|
- killerTomato
|
||||||
harvestRepeat: Repeat
|
harvestRepeat: Repeat
|
||||||
lifespan: 25
|
lifespan: 60
|
||||||
maturation: 8
|
maturation: 8
|
||||||
production: 6
|
production: 6
|
||||||
yield: 2
|
yield: 2
|
||||||
@@ -500,6 +502,38 @@
|
|||||||
Max: 4
|
Max: 4
|
||||||
PotencyDivisor: 25
|
PotencyDivisor: 25
|
||||||
|
|
||||||
|
- type: seed
|
||||||
|
id: killerTomato
|
||||||
|
name: seeds-killertomato-name
|
||||||
|
noun: seeds-noun-seeds
|
||||||
|
displayName: seeds-killertomato-display-name
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/tomatokiller.rsi
|
||||||
|
packetPrototype: KillerTomatoSeeds
|
||||||
|
productPrototypes:
|
||||||
|
- MobTomatoKiller
|
||||||
|
harvestRepeat: Repeat
|
||||||
|
lifespan: 25
|
||||||
|
maturation: 15
|
||||||
|
production: 6
|
||||||
|
yield: 2
|
||||||
|
potency: 10
|
||||||
|
waterConsumption: 0.60
|
||||||
|
nutrientConsumption: 0.70
|
||||||
|
idealLight: 8
|
||||||
|
idealHeat: 298
|
||||||
|
juicy: true
|
||||||
|
growthStages: 2
|
||||||
|
splatPrototype: PuddleSplatter
|
||||||
|
chemicals:
|
||||||
|
Blood:
|
||||||
|
Min: 1
|
||||||
|
Max: 10
|
||||||
|
PotencyDivisor: 10
|
||||||
|
JuiceTomato:
|
||||||
|
Min: 1
|
||||||
|
Max: 4
|
||||||
|
PotencyDivisor: 25
|
||||||
|
|
||||||
- type: seed
|
- type: seed
|
||||||
id: eggplant
|
id: eggplant
|
||||||
name: seeds-eggplant-name
|
name: seeds-eggplant-name
|
||||||
|
|||||||
@@ -77,3 +77,16 @@
|
|||||||
- tasks:
|
- tasks:
|
||||||
- !type:HTNCompoundTask
|
- !type:HTNCompoundTask
|
||||||
task: IdleCompound
|
task: IdleCompound
|
||||||
|
|
||||||
|
- type: htnCompound
|
||||||
|
id: KillerTomatoCompound
|
||||||
|
branches:
|
||||||
|
- tasks:
|
||||||
|
- !type:HTNCompoundTask
|
||||||
|
task: MeleeCombatCompound
|
||||||
|
- tasks:
|
||||||
|
- !type:HTNCompoundTask
|
||||||
|
task: FollowCompound
|
||||||
|
- tasks:
|
||||||
|
- !type:HTNCompoundTask
|
||||||
|
task: IdleCompound
|
||||||
|
|||||||
BIN
Resources/Textures/Mobs/Demons/tomatokiller.rsi/alive.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Resources/Textures/Mobs/Demons/tomatokiller.rsi/dead.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
40
Resources/Textures/Mobs/Demons/tomatokiller.rsi/meta.json
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": " taken from TG on commit https://github.com/tgstation/tgstation/commit/7e5f13f558253e76865e81c9641b7ec68e57754b",
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "alive",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dead"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 475 B |
|
After Width: | Height: | Size: 352 B |
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Taken from https://github.com/vgstation-coders/vgstation13 at 1dbcf389b0ec6b2c51b002df5fef8dd1519f8068",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "dead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "harvest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "seed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stage-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stage-2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 423 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 290 B |