Healing Over Time

Place to get help with not working mods / modding interface.
Post Reply
hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Healing Over Time

Post by hackamod »

I am trying to make fish that do healing over time, and an item that heals all players within range, and trying to find the cleanest way to implement them.

Looking at fish, the healing is done with an "instant" effect and a negative damage.
Is there an effect that is less than instant, or an effect that can repeat n times? Is there a list of effects? Can a new effect be defined?

Looking at poison capsules I do not see how damage is being passed along or where the area of effect is defined.
Any idea how this works? Is this something that mods are able to adjust? The range, damage amount, how long the effect can last?

Thinking about the character not shooting or taking damage, after a short time healing begins without using fish.
Is there a way to trigger that healing and control how much/fast it heals as it heals? I do not know enough about what I am looking for to be able to find anything on that automatic healing (yet)

User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 490
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: Healing Over Time

Post by Silari »

You SHOULD be able to just change the "raw-fish" capsule - change the target_effects to spawn a sticker instead of instant damage, and make that sticker heal that player for however much you want, repeating however fast you want. For example:

Code: Select all

target_effects = {
	{
		sticker = "healing-sticker",
		type = "create-sticker"
	}
}
Would make raw fish spawn a sticker called 'healing-'sticker'. Then you just need to make a sticker that causes a negative damage (thus healing) and adjust how long it'll last and how often it'll tick.

hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Re: Healing Over Time

Post by hackamod »

Yes, Sticker. Thank you.
I was just reading on that and come back here to ask how to connect it to a character, and you answered that question already.

On the character page i found healing_per_tick.
(I like the sticker solution for individual healing, that will be easy to extend but...)
Any idea how this value is being used or if it is fine to

Code: Select all

healing_per_tick += areaHealingAmount 
and

Code: Select all

healing_per_tick -= areaHealingAmount
as this would be a nice solution for the area effect because I will already know when a player enters/leaves the area

PFQNiet
Filter Inserter
Filter Inserter
Posts: 289
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Healing Over Time

Post by PFQNiet »

Look at how poison clouds do damage over time, and give that negative damage to make a heal-over-time area.

hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Re: Healing Over Time

Post by hackamod »

PFQNiet wrote:
Fri Apr 28, 2023 10:57 pm
how poison clouds do damage over time
I have been looking for that... still can not find the damage part
Here we have the capsule from prototypes.lua

Code: Select all

  {
    type = "capsule",
    name = "poison-capsule",
    icon = "__base__/graphics/icons/poison-capsule.png",
    icon_size = 64, icon_mipmaps = 4,
    capsule_action =
    {
      type = "throw",
      attack_parameters =
      {
        type = "projectile",
        activation_type = "throw",
        ammo_category = "capsule",
        cooldown = 30,
        projectile_creation_distance = 0.6,
        range = 25,
        ammo_type =
        {
          category = "capsule",
          target_type = "position",
          action =
          {
            {
              type = "direct",
              action_delivery =
              {
                type = "projectile",
                projectile = "poison-capsule",
                starting_speed = 0.3
              }
            },
            {
              type = "direct",
              action_delivery =
              {
                type = "instant",
                target_effects =
                {
                  {
                    type = "play-sound",
                    sound = sounds.throw_projectile
                  }
                }
              }
            }
          }
        }
      }
    },
    subgroup = "capsule",
    order = "b[poison-capsule]",
    stack_size = 100
   },
and here we have the projectile with the smoke cloud from projectiles.lua

Code: Select all

  {
    type = "projectile",
    name = "poison-capsule",
    flags = {"not-on-map"},
    acceleration = 0.005,
    action =
    {
      {
        type = "direct",
        action_delivery =
        {
          type = "instant",
          target_effects =
          {
            {
              type = "create-smoke",
              show_in_tooltip = true,
              entity_name = "poison-cloud",
              initial_height = 0
            },
            {
              type = "create-particle",
              particle_name = "poison-capsule-metal-particle",
              repeat_count = 8,
              initial_height = 1,
              initial_vertical_speed = 0.1,
              initial_vertical_speed_deviation = 0.05,
              offset_deviation = {{-0.1, -0.1}, {0.1, 0.1}},
              speed_from_center = 0.05,
              speed_from_center_deviation = 0.01
            }
          }
        }
      }
    },
    --light = {intensity = 0.5, size = 4},
    animation =
    {
      filename = "__base__/graphics/entity/poison-capsule/poison-capsule.png",
      draw_as_glow = true,
      frame_count = 16,
      line_length = 8,
      animation_speed = 0.250,
      width = 29,
      height = 29,
      shift = util.by_pixel(1, 0.5),
      priority = "high",
      hr_version =
      {
        filename = "__base__/graphics/entity/poison-capsule/hr-poison-capsule.png",
        draw_as_glow = true,
        frame_count = 16,
        line_length = 8,
        animation_speed = 0.250,
        width = 58,
        height = 59,
        shift = util.by_pixel(1, 0.5),
        priority = "high",
        scale = 0.5
      }

    },
    shadow =
    {
      filename = "__base__/graphics/entity/poison-capsule/poison-capsule-shadow.png",
      frame_count = 16,
      line_length = 8,
      animation_speed = 0.250,
      width = 27,
      height = 21,
      shift = util.by_pixel(1, 2),
      priority = "high",
      draw_as_shadow = true,
      hr_version =
      {
        filename = "__base__/graphics/entity/poison-capsule/hr-poison-capsule-shadow.png",
        frame_count = 16,
        line_length = 8,
        animation_speed = 0.250,
        width = 54,
        height = 42,
        shift = util.by_pixel(1, 2),
        priority = "high",
        draw_as_shadow = true,
        scale = 0.5
      }
    },
    smoke =
    {
      {
        name = "poison-capsule-smoke",
        deviation = {0.15, 0.15},
        frequency = 1,
        position = {0, 0},
        starting_frame = 3,
        starting_frame_deviation = 5,
        starting_frame_speed_deviation = 5
      }
    }
  },
I still have not found where/when/how the damage is done, but not due to lack of looking, I am just not familiar with the way factorio is organized yet

PFQNiet
Filter Inserter
Filter Inserter
Posts: 289
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Healing Over Time

Post by PFQNiet »

I don't remember it exactly myself, but the projectile creates a "poison-cloud" entity, which I believe is a "smoke with triggers" I think?

User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 490
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: Healing Over Time

Post by Silari »

Yeah it's a capsule that makes a projectile that makes a smoke-with-trigger cloud that is set to cause the damage. But pretty sure that means it doesn't move from where it spawns - probably not how you want a healing capsule to work.

hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Re: Healing Over Time

Post by hackamod »

I looked some more and found this in smoke.lua but still no damage

Code: Select all


  {
    type = "trivial-smoke",
    name = "poison-capsule-smoke",
    animation = smoke_fast_animation(
      {
        scale = 0.5
      }
    ),
    duration = 60,
    fade_away_duration = 60,
    render_layer = "higher-object-above",
    color = {r = 0.239, g = 0.875, b = 0.992, a = 0.690}
  },

  {
    type = "trivial-smoke",
    name = "poison-capsule-particle-smoke",
    animation = smoke_fast_animation(
      {
        scale = 0.2
      }
    ),
    duration = 60,
    fade_away_duration = 60,
    render_layer = "higher-object-above",
    color = {r = 0.239, g = 0.875, b = 0.992, a = 0.690}
  },
However, this does not answer the question for the "easy way"... What happens if I use healing_per_tick?
If I can just add and subtract from that value as they enter and leave that is the simple fix... I will continue to chase this damage on capsule just to see it

As far as the capsule healing over time, using the sticker, that is all working now. Thank you very much for your input.
Here is everything except the text in the locale file to make it work (using vanilla icons)

Code: Select all


data:extend({

  {
    type = "recipe",
    name = "charred-fish-recipe",
    category = "smelting",
    energy_required = 8,
    enabled = true,
    ingredients = {{"raw-fish", 1}},
    result = "charred-fish"
  },

  {
    duration_in_ticks = 800,
    damage_per_tick = 
    {
      type = "physical",
      amount = -0.2
    },
    type = "sticker",
    name = "charred-fish-sticker",
    order = "[a]food[a]fish[a]charred-fish"
  },

  {
    type = "capsule",
    name = "charred-fish",
    icon = "__base__/graphics/icons/fish.png",
    icon_size = 64, icon_mipmaps = 4,
    subgroup = "raw-resource",
    capsule_action =
    {
      type = "use-on-self",
      attack_parameters =
      {
        type = "projectile",
        activation_type = "consume",
        ammo_category = "capsule",
        cooldown = 200,
        range = 0,
        ammo_type =
        {
          category = "capsule",
          target_type = "position",
          action =
          {
            type = "direct",
            action_delivery =
            {
              type = "instant",
              target_effects =
              {
                sticker = "charred-fish-sticker",
                type = "create-sticker"
              }
            }
          }
        }
      }
    },
    order = "h[food][charred-fish]",
    stack_size = 10
  }
})
I have noticed something that I have not been able to fix.
If you mouse over "raw-fish" in your inventory, it says:
______________________
Consumed
Consumption speed: 2/s
_______________________
Effects
Heal: 80 Physical
but if you mouse over the charred fish in inventory it says:
_______________________
Consumed
Consumption speed: 0.05/s
and nothing about the Effect for healing.
The text seems to be generated, as I can not find it in the locale file, and I can not find where this is being added so I am guessing somewhere out of sight, but it would be nice if I could get it to automatically describe the effect, as different fish give different effects

Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Healing Over Time

Post by Pi-C »

Silari wrote:
Sat Apr 29, 2023 1:45 am
Yeah it's a capsule that makes a projectile that makes a smoke-with-trigger cloud that is set to cause the damage. But pretty sure that means it doesn't move from where it spawns - probably not how you want a healing capsule to work.
The poison-cloud is a smoke-with-trigger prototype. It's action is an AreaTriggerItem, which has the special property "radius" for its area of effect. Types/AreaTriggerItem is an extension of Types/TriggerItem, which has the property action_delivery (Types/TriggerDelivery). The type used here is "instant", which has the property target_effects. This, finally, is a Types/DamageTriggerEffectItem which applies damage to all eligible entities within the radius of Types/AreaTriggerItem:
poison-cloud.png
poison-cloud.png (100.63 KiB) Viewed 2173 times
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 490
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: Healing Over Time

Post by Silari »

hackamod wrote:
Sat Apr 29, 2023 5:08 am
I looked some more and found this in smoke.lua but still no damage
You really should go to the wiki and grab the data.raw download it has. It's a complete dump of the entirety of the data table, so every single prototype defined in the base game is there. Much faster than trying to comb through lua files looking for things.

Also, you can use the prototype explorer in game to browse everything from the currently loaded save. Ctrl+Shift+E is the default hotkey. That's what Pi-C's screenshot is from. It lists everything, is easily searchable, and lets you double check any modifications you tried to make actually made it into the game.

hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Re: Healing Over Time

Post by hackamod »

I keep a tab for Data.raw and a tab to the version linked from the top of that page.
Being as new to Lua and modding Factorio... even with those tools at my disposal... and the ability to search folders and files...
When you are new and completely lost, no tool is better than a pro standing on a mountain of knowledge looking down across the lands and saying, Hey, 10 steps past those trees is a lake full of the fish you are looking for.
That lake is hard to find when you are in the valley looking through the trees.
I can not thank you enough for taking the time to be that pro on the hill.
Until I can as a search engine "How does factorio implement damage or healing over time" and the search engine shows me the sticker prototype and then explains the intended use of healing-per-tick on the character.... forum replies are priceless, so thank you all again for the replies. I promise to have fewer questions over time ;)

Another quick example of Data.raw being ... not as useful as it could/should be...
If you look up a prototype, look down the list of variables, find one of interest (this happend to me more times than I can count) and click on that variable for more information ... in the most recent case it was a boolean, and I was not sure what it is used for...
The description simply said boolean value. ..... Like.... seriously ...What happens if i set it to false? does the world end? do I go to bed without ice-cream? What is the boolean's intended purpose?
From the perspective of the author, it is obvious, for too many reasons. But from outside looking in, it is just another 1 or 0. What READS the value and WHEN are things Data.raw and Ctrl Alt E just do not have the ability to convey to the reader.

For example it is not possible to see if healing-per-tick is automatically set to 0 when the entity reaches max_health.
So if i use += as they enter and -= as they leave, but they were fully healed, then the -= would set them with damage over time.
On the other hand if i simply set it to 0 as they exit, it would remove any long term buff the character might have like a very small healing buff that lasts for 30 minutes or an hour or whatever

I scribbled up some code to test healing-per-tick and see if I can make sense of its use, I will post what I find on that
Thanks again for the help through the trees

Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Healing Over Time

Post by Pi-C »

hackamod wrote:
Sat Apr 29, 2023 4:43 pm
I scribbled up some code to test healing-per-tick and see if I can make sense of its use
You must distinguish between prototype and entity. Prototypes are defined in the data stage, entities are used in the control stage. All entities of type X with name Y will have the properties defined in data.raw[X][Y].

The property healing_per_tick defined in a prototype will be applied to all entities based on that prototype. You don't have to care about it at all in control -- if an entity based on Prototype/EntityWithHealth is damaged (but not killed), the game will automatically restore the defined amount of health points on each tick until LuaEntity.health == LuaEntity.prototype.max_health.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Re: Healing Over Time

Post by hackamod »

Pi-C wrote:
Sat Apr 29, 2023 5:01 pm
You must distinguish between prototype and entity.
Yes that does destroy the plan I had in mind.
That is fine, now I understand how it is used and it does not work the way I wanted.
I can use a sticker to do it. Probably best to do it that way anyway.
Thanks for explaining that... it does make sense

Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Healing Over Time

Post by Pi-C »

hackamod wrote:
Sat Apr 29, 2023 9:21 pm
I can use a sticker to do it. Probably best to do it that way anyway.
You could use "script" instead of "sticker". You assign a name; then, whenever any trigger fires, on_script_trigger_effect will be raised and you can check the name against event.effect_id to determine whether the event was raised for your trigger.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Re: Healing Over Time

Post by hackamod »

Pi-C wrote:
Sat Apr 29, 2023 10:55 pm
You could use "script" instead of "sticker".
That is the type of idea I had in mind with the heals-per-tick.
I was assuming that each entity had a unique value there, and I was going to +/- the value as the player is teleported in/out

I do not really need the area detection, I know when they teleport.

Thanks for the suggestions as I get familiar with Lua and Factorio both...
What do you suggest for a setup where it only needs to heal them when they are teleported in?

hackamod
Long Handed Inserter
Long Handed Inserter
Posts: 62
Joined: Mon Apr 25, 2022 2:39 pm
Contact:

Re: Healing Over Time

Post by hackamod »

hackamod wrote:
Sun Apr 30, 2023 2:00 am
What do you suggest for a setup where it only needs to heal them when they are teleported in?
I mean... I still do not see how to apply the healing with script. For sure I want to write as little code as necessary

Post Reply

Return to “Modding help”