diff --git a/Content/ExampleMod/Localization/En.json b/Content/ExampleMod/Localization/En.json index fb9139d..18281ea 100644 --- a/Content/ExampleMod/Localization/En.json +++ b/Content/ExampleMod/Localization/En.json @@ -4,5 +4,11 @@ }, "Clothes": { "ExampleMod.DarkShirt": "Dark Shirt" + }, + "Emotions": { + "ExampleMod.GrassSitting": "Comfy Green Ground" + }, + "Actions": { + "ExampleMod.SitOnGrass": "Sit in Grass" } } \ No newline at end of file diff --git a/Content/ExampleMod/UiTextures.png b/Content/ExampleMod/UiTextures.png index 572184c..325ece4 100644 Binary files a/Content/ExampleMod/UiTextures.png and b/Content/ExampleMod/UiTextures.png differ diff --git a/ExampleMod.cs b/ExampleMod.cs index 54696ff..06cabe1 100644 --- a/ExampleMod.cs +++ b/ExampleMod.cs @@ -6,6 +6,8 @@ using MLEM.Data; using MLEM.Data.Content; using MLEM.Textures; using TinyLife; +using TinyLife.Actions; +using TinyLife.Emotions; using TinyLife.Mods; using TinyLife.Objects; using TinyLife.Utilities; @@ -16,6 +18,8 @@ namespace ExampleMod { // the logger that we can use to log info about this mod public static Logger Logger { get; private set; } + public static EmotionModifier GrassSittingModifier; + // visual data about this mod public override string Name => "Example Mod"; public override string Description => "This is the example mod for Tiny Life!"; @@ -47,6 +51,23 @@ namespace ExampleMod { }; } }; + + // adding a simple action: sitting down in the grass, which also gives us a nice emotion modifier + ActionType.Register(new ActionType.TypeSettings("ExampleMod.SitOnGrass", ObjectCategory.Ground, + (t, i) => new SitDownOnGrassAction(t, i)) { + // we set this action to be executable only on grass tiles, not on other ground + CanExecute = (info, automatic) => { + var tile = info.Map.GetTile(info.ActionLocation.ToPoint()); + if (tile.Name.StartsWith("Grass")) + return ActionType.CanExecuteResult.Valid; + // hidden means the action won't be displayed in the ring menu + return ActionType.CanExecuteResult.Hidden; + }, + // since this action doesn't use objects (like chairs etc.), we set a texture to display instead + Texture = this.uiTextures[1, 0] + }); + GrassSittingModifier = EmotionModifier.Register( + new EmotionModifier("ExampleMod.GrassSitting", this.uiTextures[1, 0], EmotionType.Happy)); } public override void Initialize(Logger logger, RawContentManager content, RuntimeTexturePacker texturePacker) { diff --git a/SitDownOnGrassAction.cs b/SitDownOnGrassAction.cs new file mode 100644 index 0000000..16c70f9 --- /dev/null +++ b/SitDownOnGrassAction.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using TinyLife; +using TinyLife.Actions; +using TinyLife.Emotions; +using TinyLife.Objects; +using Action = TinyLife.Actions.Action; + +namespace ExampleMod { + // we use a multi action because we want to walk to the location, and then execute the main sitting part + public class SitDownOnGrassAction : MultiAction { + + public SitDownOnGrassAction(ActionType type, ActionInfo info) : base(type, info) { + } + + protected override IEnumerable CreateFirstActions() { + // we want to walk to the location clicked, so we use the current action info + yield return ActionType.GoHere.Construct(this.Info); + } + + protected override void AndThenInitialize() { + // this is called when the main action starts (after going to the location, in our case) + // but we don't need to do anything here for our action + } + + protected override void AndThenUpdate(GameTime time, TimeSpan passedInGame, GameSpeed speed) { + base.AndThenUpdate(time, passedInGame, speed); + // this method gets called every update frame while the action is active + + // set our person to look like they're sitting on the ground + this.Person.CurrentPose = Person.Pose.SittingLegsClose; + + // restore need and lower emotions + this.Person.RestoreNeed(NeedType.Energy, 0.5F, speed); + this.Person.LowerEmotion(EmotionType.Uncomfortable, 0.0001F, speed); + } + + protected override CompletionType AndThenIsCompleted() { + // we want to complete our action once 10 minutes of sitting time have passed + return this.CompleteInTime(TimeSpan.FromMinutes(10)); + } + + protected override void AndThenOnCompleted(CompletionType type) { + base.AndThenOnCompleted(type); + // this method is called when the action completes in any way, even if it fails + if (type == CompletionType.Completed) { + // once we're finished sitting, we want to get a nice emotion modifier for it + this.Person.AddEmotion(ExampleMod.GrassSittingModifier, 1, TimeSpan.FromHours(1)); + } + } + + } +} \ No newline at end of file