Skip to content

Instantly share code, notes, and snippets.

@spajus
Created October 18, 2022 05:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spajus/cf79e7491020d29248805700db8fc3a8 to your computer and use it in GitHub Desktop.
Save spajus/cf79e7491020d29248805700db8fc3a8 to your computer and use it in GitHub Desktop.
Stardeus Species Traits example C# code
using System.Collections.Generic;
using Game.Components;
using Game.Constants;
using Game.Data;
using KL.Collections;
using Game.Utils;
using KL.Randomness;
using UnityEngine;
namespace Game.AI.Traits {
public sealed class TraitCat : Trait, ITickableTrait {
public const string Id = "cat";
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Register() {
Add(Id, new TraitCat());
}
public void Tick(long ticks, List<Being> cats) {
foreach (var c in cats) {
if (!Trait.CanTick(c)) { continue; }
if (c.Brain.CurrentAd != null) { continue; }
var fun = c.Needs.GetNeed(NeedId.Fun);
if (c.S.Rng.Chance(fun.Demand * 0.5f)) {
TryRideCleaningBot(c);
}
}
}
private void TryRideCleaningBot(Being cat) {
var bot = cat.S.Beings.FindClosestMatching(cat.PosIdx, IsRidableBot, 20, 5);
if (bot != null && cat.Brain.IsFeelingSafeAt(bot.PosIdx, false)) {
var ridable = bot.GetComponent<RidableComp>();
var ad = ridable.CreateRidingAd(T.RidingABot);
if (ad != null) {
cat.Brain.TakeAd(ad, "Cat trait ride");
}
}
}
private bool IsRidableBot(Being bot) {
if (!bot.IsActive || bot.IsHidden || !bot.Worker.IsOn) {
return false;
}
if (bot.TryGetComponent<RidableComp>(out var ridable)) {
return ridable.CanBeRiddenBy(SpeciesType.Cat);
}
return false;
}
private TraitCat() {
IsAutoAssigned = false;
IsHidden = true;
}
}
}
using System.Collections.Generic;
using Game.Constants;
using Game.Data;
using KL.Collections;
using Game.Utils;
using KL.Randomness;
using UnityEngine;
namespace Game.AI.Traits {
public sealed class TraitHuman : Trait, ITickableTrait {
public const string Id = "human";
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Register() {
Add(Id, new TraitHuman());
}
private TraitHuman() {
IsAutoAssigned = false;
IsHidden = true;
}
public override void ApplyAfterCreate(Being being) {
var jt = being.Worker.JobTypes;
var rng = being.S.Rng.Fork();
var typeSkipChance = rng.Range(0f, 0.5f);
var verySkilledAtChance = rng.Range(0f, 0.1f);
for (int i = 0; i < jt.Length; i++) {
var job = jt[i];
if (rng.Chance(typeSkipChance)) {
if (job == JobType.Operations) {
// No chance to skip operations
being.Worker.SetPriorityFor(job, 1);
} else {
being.Worker.SetPriorityFor(job, 0);
}
} else {
if (rng.Chance(verySkilledAtChance)) {
being.Worker.AdjustPriorityFor(job, being.S.Rng.Range(2, 6));
} else {
var newPrio = being.S.Rng.Range(-2, 3);
being.Worker.AdjustPriorityFor(job, newPrio);
if (job == JobType.Operations
&& being.Worker.PriorityFor(JobType.Operations) < 1) {
being.Worker.SetPriorityFor(job, 1);
}
}
}
}
}
private long nextTickMood;
public void Tick(long ticks, List<Being> beingsWithThisTrait) {
if (ticks < nextTickMood) {
return;
}
nextTickMood = ticks + Consts.TicksPerHour;
for (int i = 0; i < beingsWithThisTrait.Count; i++) {
var b = beingsWithThisTrait[i];
if (!CanTick(b)) { continue; }
var isNudist = b.Traits.HasTrait(TraitNudist.Id);
var isNaked = b.Equipment.IsNaked;
if (!isNudist && isNaked) {
if (b.S.Rng.Chance(0.5f)) {
b.Mood.AddEffect(MoodEffect.Create(ticks, Ticks1h, T.Naked, -5));
}
} else if (isNudist && isNaked) {
if (b.S.Rng.Chance(0.5f)) {
b.Mood.AddEffect(MoodEffect.Create(ticks, Ticks1h, T.Naked, +1));
}
}
var isHatPerson = b.Traits.HasTrait(TraitHatPerson.Id);
if (isHatPerson && b.Equipment.HasHat) {
if (b.S.Rng.Chance(0.5f)) {
b.Mood.AddEffect(MoodEffect.Create(ticks, Ticks1h, T.WearingAHat, +1));
}
}
}
}
}
}
using System.Collections.Generic;
using Game.Constants;
using Game.Data;
using KL.Collections;
using Game.Utils;
using KL.Randomness;
using UnityEngine;
namespace Game.AI.Traits {
public sealed class TraitRobot : Trait {
public const string Id = "robot";
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Register() {
Add(Id, new TraitRobot());
}
private TraitRobot() {
IsAutoAssigned = false;
IsHidden = true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment