Jump to content

[Mod Idea] Damage Indicator


s1m13

Recommended Posts

Hey guys, i just had an idea about a nice mod, which adds a fancy action component to the game. Most of you may know this tiny little numbers appearing over the enemies head (or ur head :-/) after taking damage.

 

What do you think about that?

Link to comment
Share on other sites

Hey guys, i just had an idea about a nice mod, which adds a fancy action component to the game. Most of you may know this tiny little numbers appearing over the enemies head (or ur head :-/) after taking damage.

 

What do you think about that?

Is this what you had in mind? Health loss appears in red, health gain appears in green.

There are some design choices I'm unsure of:

  • Should a minus sign appear before the numbers on health loss? Currently I'm doing that.
  • Should the choice of colours for player health change be different than that for ordinary creatures? Currently it is not.
  • In the same spirit of the last remark, should the choice of colours also be different for player follower, such as pigs? Currently it is not.

DamageIndicator.zip

Link to comment
Share on other sites

Nooooooooooooooooooooooooooooo ... i wanted to implement it :D

 

I should stop posting my ideas here ;-P

 

I could not test ur mod, but to answer ur questions, i would say:

  • Yes
  • I would change the font size for the player-damage
  • Font size, too.
Link to comment
Share on other sites

Well, your OP sounded like a mod request? Do you still plan on implementing it? I just won't release my mod, then.

 

Ok, youre right. It really sounded like a request and i didnt say, that i want to do it on my own. Sorry for that.

I think, I will implement it by myself again. Thank you!

Link to comment
Share on other sites

Ahhhh... The modding forum seem so dead. No very visible release of mod, nothing, uh...
Still nobody could help me about making guns? I could even try to do metal gear solid character if I could give them guns at least.
Huhrmph... Maybe this dead's just an impressions though...

If I had an idea to put in, maybe a stupid one, would be to implement an urinary system, and build toilet to survive... Quite realistic way to survive too, when too full the bladder, we lost health, need keep it low. I know can seem very stupid idea, but maybe fun anyway.

Link to comment
Share on other sites

I just let it free. Thanks again simplex for some code. I just did a check after i finished my version and found a couple of helpful parts.

Thanks a lot.

 

http://forums.kleientertainment.com/files/file/439-damage-indicators/

 

So.. lets talk about the mod. At the moment, the numbers dont move as i would like them to see. (Best results when turning to 0 degrees (1x right)).

I implemented 2 versions of pathes the numbers can take. (Check the code for 'bounce around mode')

For both modes i will need TheCamera orientation (headingtarget). How can i access this variable inside of my mod?

Link to comment
Share on other sites

I'm just improving my Modification and run for some problems i would like to solve:

  1. Cause of health changes:

The healthdelta listener from component health gives access to a variable called cause. I checked it via console and found some simple strings to be provided by the listener function. All in all prefab names like "wilson", "hound", "carrot" or "regen" or "fire". So i thought about making a huge filter-list, to block health deltas from food or stuff like that. (As a configuration: I - by my self - would not want to see how much something healed me instantly)

  • Do you think, this is the only way to solve this issue?
  • Is there a function or variable storing lots of prefab names sorted by some criterias (all food prefabs e.g)?
  1. Fight: Distance and vector between attacker and target

I implemented a fancy feature, which displays the numbers in a different way than now (numbers bouncing around the floor). For a fluid feeling and physically correct displaying i need an approximate vector which represents the angle (and distance) between attacker and target.

  • Can this be implemented in component.Weapon.onattack?
  • Other ideas?

 

PS: I managed to access TheCamera via GLOBAL.TheCamera (previous post)

Link to comment
Share on other sites

I love this mod and it feels pretty natural but I found a few fairly serious bugs, which I actually think all share a similar root problem:

 

Issue1 - By far the most serious problem, whenever you take damage from freezing/overheating you will get massive spam of "000000000000" damage being taken. This obscures so much of the screen that you can't control your character well, and I wouldn't be surprised if it created a big slowdown for less powerful systems. In such an unforgiving game this could lead to you dying, so this should be a high priority to fix. I assume that this problem arises because the damage dealt from freezing is being dealt very frequently but for only 0.1HP or something - leading to a rounding problem where it shows an annoying stream of zeros.

 

Suggested fix: I'd probably recommend that you just change the script to ignore/not print any damage that is less than 1.00 HP. That should take care of the issue, and I can't think of any problems that would result from this. You wouldn't get damage numbers from freezing anymore of course, but that would be more of an annoyance anyway since the game itself is very clear on its feedback when you take freezing damage.

 

Issue2 - A minor annoyance: You seem to have a minor rounding error somewhere in the script. All damage (that I have tested at least) shows up as 1HP less than the actual damage that you took. For example when a spider hits you he deals 20 damage, but the damage number will show 19. I think this is consistent for all damage taken.

 

Suggested fix: It depends on what is causing the rounding error obviously, and if you can choose how rounding is done under whatever scripting language is used for the modding files, but since we only care about whole numbers here anyway the simple low-tech trick of adding +0.5 to each number before rounding might be all you need if you can't deal with it in some more elegant way. Hard to say anything more without seeing the script code, but I'm sure this is easy to fix for anyone who has the aptitude to create a mod in the first place :)

 

-Stigma

Link to comment
Share on other sites

Ok, I just took a quick look at the script and Issue1 with the freezing damage problem seems easy to fix.

 

I changed:

AddComponentPostInit("health", function(Health, inst)    inst:ListenForEvent("healthdelta", function(inst, data)        if inst.components.health then            local amount = (data.newpercent - data.oldpercent)*inst.components.health.maxhealth            if math.abs(amount) > 0.001 then                if not (TUNING.SHOW_DAMAGE_ONLY and amount > 0) then                    CreateDamageIndicator(inst, amount)                end            end        end    end)end)

 

to:

AddComponentPostInit("health", function(Health, inst)    inst:ListenForEvent("healthdelta", function(inst, data)        if inst.components.health then            local amount = (data.newpercent - data.oldpercent)*inst.components.health.maxhealth            if math.abs(amount) > 0.5 then                if not (TUNING.SHOW_DAMAGE_ONLY and amount > 0) then                    CreateDamageIndicator(inst, amount)                end            end        end    end)end)

 

That seemed to solve the whole problem at least in the short test that I did. Hunger damage still shows up as 1 pr tick. Freezing damage is no longer displayed at all. All other damage just shows normally.

 

I only glanced over the script quickly though so I hope this doesn't end up messing up something else - but it seems fine in quick testing at least.

 

There probably exists some more elegant way of fixing this that dosn't involve disabling the numbers from freezing damage entirely, but personally that's not something I'm going to miss much anyway, and I don't know the code well enough to begin rewriting it :)

 

-Stigma

Link to comment
Share on other sites

Ok, I've taken another look at the scipt to try to fix that rounding error too, and I think I've solved it. It seems to have been because of limitations in the variable types and no rounding being used. Solution: implement a simple up/down round function before saving the healthdelta to variable for output. This seems to have resolved the problem of damage/health sometimes being 1hp off from the actual amount.

 

I am just doing a slight bit of testing in actual play now to see that there aren't any huge bugs in the changes I made, and assuming everything goes well I will upload my fixed files here. The original author can update the mod with them if he feels my work is worthy (seriously though, please look over my code.... I am horrible lol, the fact that I feel smart now after fixing such a basic math coding error is a testament to how long it has been since I did any real programming =P )

 

-Stigma

Link to comment
Share on other sites

Ok, I've taken another look at the scipt to try to fix that rounding error too, and I think I've solved it. It seems to have been because of limitations in the variable types and no rounding being used. Solution: implement a simple up/down round function before saving the healthdelta to variable for output. This seems to have resolved the problem of damage/health sometimes being 1hp off from the actual amount.

 

I am just doing a slight bit of testing in actual play now to see that there aren't any huge bugs in the changes I made, and assuming everything goes well I will upload my fixed files here. The original author can update the mod with them if he feels my work is worthy (seriously though, please look over my code.... I am horrible lol, the fact that I feel smart now after fixing such a basic math coding error is a testament to how long it has been since I did any real programming =P )

 

-Stigma

function roundToNearestInteger(x)    return math.floor(x + 0.5)end
Link to comment
Share on other sites

Thanks simplex.

 

I'm going to post the modified code I have so far below so people can test/use it as they wish.

 

Notes for unofficial 0.21b version

- Fixed damage numbers sometimes being incorrect by 1HP due to rounding error

 

- Fixed message-spam that occurred from heating/freezing damage.

 

- You can now either have no damage-numbers for freezing/overheating (default) or you can choose to see a message saying "Freezing". These two new variables added to the configuration toggles the Freeze messages on/off and sets how frequently they display:

TUNING.SHOW_FREEZING_MESSAGE = false -- set to true, if you want to see the message "Freezing!" while receiving thermal damage
TUNING.FREEZE_MESSAGE_DELAY = 150 -- sets how frequently the "Freezing" message is displayed for thermal damage. Lower number = more frequently. Slower system may need a lower number, but on a fast system a low number may result in "spammed" messages. Adjust as needed.

 

Known bugs: Both overheating and freezing damage will show as "Freezing" (if the freeze-message is enabled in configuration). I don't know how to differensiate the two. You would probably need to poll the game and ask for the players temperature...

 

I've tried to consistently comment everything in the code that I've touched. Hit the spolier button below to show the modified code (modmain.lua)

 

--------------------------------------------------------------------- CONFIGURATION --------------------TUNING.SHOW_DAMAGE_ONLY = false        -- set to true, if you want to see damage only (no healing)TUNING.SHOW_FREEZING_MESSAGE = false -- set to true, if you want to see the message "Freezing!" while receiving thermal damageTUNING.FREEZE_MESSAGE_DELAY = 150 -- sets how frequently the "Freezing" message is displayed for thermal damage. Lower number = more frequently. Slower system may need a lower number, but on a fast system a low number may result in "spammed" messages. Adjust as needed.----------------------------------------------------TUNING.HEALTH_LOSE_COLOR = {    r = 0.7,    g = 0,    b = 0}TUNING.HEALTH_GAIN_COLOR = {    r = 0,    g = 0.7,    b = 0}TUNING.LABEL_FONT_SIZE = 70TUNING.LABEL_Y_START = 4TUNING.LABEL_TIME = 1.0TUNING.LABEL_TIME_DELTA = 0.01TUNING.GRAVITY = 0.1TUNING.FRICTION_PRESERVE = 0.9TUNING.LIFT_ACC = 0.003TUNING.SIDE_WAVE_RND = 0.15TUNING.LABEL_Y_START_VELO = 0.05TUNING.LABEL_MIN_AMPLITUDE_X = 0.8TUNING.LABEL_MAX_AMPLITUDE_X = 1.6-- Variable added by Stigma for limiting "Freezing" spam while not disabling the notifications of damage from freezing entirely-- Would be better implemented with a proper timer function but I'm not sure if there is a native function in lua and I don't want to involve extra librariesloopCounter = 0local function CreateLabel(inst, parent)    inst.persists = false    if not inst.Transform then        inst.entity:AddTransform()    end    inst.Transform:SetPosition( parent.Transform:GetWorldPosition() )    return instendlocal function CreateDamageIndicator(parent, amount)    local inst = CreateLabel(GLOBAL.CreateEntity(), parent)    local label = inst.entity:AddLabel()    label:SetFont(GLOBAL.NUMBERFONT)    label:SetFontSize( TUNING.LABEL_FONT_SIZE )    label:SetPos(0, TUNING.LABEL_Y_START, 0)    local color    if amount < 0 then        color = TUNING.HEALTH_LOSE_COLOR    else        color = TUNING.HEALTH_GAIN_COLOR    end    label:SetColour(color.r, color.g, color.b)    label:SetText( ("%d"):format(amount) )  -- wanna have .x ?    label:Enable(true)    inst:StartThread(function()        local label = inst.Label        local t = 0        local t_max = TUNING.LABEL_TIME        local dt = TUNING.LABEL_TIME_DELTA        -- swirr upon mode ------------------        local y = TUNING.LABEL_Y_START        local dy = TUNING.LABEL_Y_START_VELO        local ddy = 0.0                local side = (math.random() * (TUNING.LABEL_MAX_AMPLITUDE_X - TUNING.LABEL_MIN_AMPLITUDE_X) + TUNING.LABEL_MIN_AMPLITUDE_X) * (math.random() >= 0.5 and -1 or 1)        local dside = 0.0        local ddside = 0.0        -------------------------------------        -- bounce around mode ---------------        -- local y = TUNING.LABEL_Y_START        -- local dy = 0.05        -- local ddy = 0.0                -- local side = 0.0        -- local dside = 0.1        -- local ddside = 0.0        -------------------------------------        while inst:IsValid() and t < t_max do                    -- swirr upon mode ------------------            ddy = TUNING.LIFT_ACC * (math.random() * 0.5 + 0.5)            dy = dy + ddy            y = y + dy                        ddside = -side * math.random()*TUNING.SIDE_WAVE_RND            dside = dside + ddside            side = side + dside            -------------------------------------                        -- bounce around mode ---------------            -- ddy = -TUNING.GRAVITY            -- dy = dy + ddy            -- y = y + dy            -- if y < 0 then                -- y = -y                -- dy = -dy * TUNING.FRICTION_PRESERVE            -- end                        -- ddside = 0            -- dside = dside + ddside            -- side = side + dside            -------------------------------------                    local headingtarget = 45 --[[TheCamera.headingtarget]] % 180            if headingtarget == 0 then                label:SetPos(0, y, side)          -- from 3d plane x = 0            elseif headingtarget == 45 then                label:SetPos(side, y, -side)    -- from 3d plane x + z = 0            elseif headingtarget == 90 then                label:SetPos(side, y, 0)        -- from 3d plane z = 0            elseif headingtarget == 135 then                label:SetPos(side, y, side)        -- from 3d plane z - x = 0            end            t = t + dt            label:SetFontSize( TUNING.LABEL_FONT_SIZE * math.sqrt(1 - t / t_max))            GLOBAL.Sleep(dt)        end        inst:Remove()    end)    return instend-- by Stigma, a fugly copypasta hack-mod of the existing CreateDamageIndicator to output "Freezing!" message rather than damage number. This could obviously use some cleaning up...local function CreateFreezeIndicator(parent, amount)    local inst = CreateLabel(GLOBAL.CreateEntity(), parent)    local label = inst.entity:AddLabel()    label:SetFont(GLOBAL.NUMBERFONT)    label:SetFontSize( TUNING.LABEL_FONT_SIZE )    label:SetPos(0, TUNING.LABEL_Y_START, 0)    local color    if amount < 0 then        color = TUNING.HEALTH_LOSE_COLOR    else        color = TUNING.HEALTH_GAIN_COLOR    end    label:SetColour(color.r, color.g, color.b)    label:SetText('Freezing!')  -- wanna have .x ?    label:Enable(true)    inst:StartThread(function()        local label = inst.Label        local t = 0        local t_max = TUNING.LABEL_TIME        local dt = TUNING.LABEL_TIME_DELTA        -- swirr upon mode ------------------        local y = TUNING.LABEL_Y_START        local dy = TUNING.LABEL_Y_START_VELO        local ddy = 0.0                local side = (math.random() * (TUNING.LABEL_MAX_AMPLITUDE_X - TUNING.LABEL_MIN_AMPLITUDE_X) + TUNING.LABEL_MIN_AMPLITUDE_X) * (math.random() >= 0.5 and -1 or 1)        local dside = 0.0        local ddside = 0.0        -------------------------------------        -- bounce around mode ---------------        -- local y = TUNING.LABEL_Y_START        -- local dy = 0.05        -- local ddy = 0.0                -- local side = 0.0        -- local dside = 0.1        -- local ddside = 0.0        -------------------------------------        while inst:IsValid() and t < t_max do                    -- swirr upon mode ------------------            ddy = TUNING.LIFT_ACC * (math.random() * 0.5 + 0.5)            dy = dy + ddy            y = y + dy                        ddside = -side * math.random()*TUNING.SIDE_WAVE_RND            dside = dside + ddside            side = side + dside            -------------------------------------                        -- bounce around mode ---------------            -- ddy = -TUNING.GRAVITY            -- dy = dy + ddy            -- y = y + dy            -- if y < 0 then                -- y = -y                -- dy = -dy * TUNING.FRICTION_PRESERVE            -- end                        -- ddside = 0            -- dside = dside + ddside            -- side = side + dside            -------------------------------------                    local headingtarget = 45 --[[TheCamera.headingtarget]] % 180            if headingtarget == 0 then                label:SetPos(0, y, side)          -- from 3d plane x = 0            elseif headingtarget == 45 then                label:SetPos(side, y, -side)    -- from 3d plane x + z = 0            elseif headingtarget == 90 then                label:SetPos(side, y, 0)        -- from 3d plane z = 0            elseif headingtarget == 135 then                label:SetPos(side, y, side)        -- from 3d plane z - x = 0            end            t = t + dt            label:SetFontSize( TUNING.LABEL_FONT_SIZE * math.sqrt(1 - t / t_max))            GLOBAL.Sleep(dt)        end        inst:Remove()    end)    return instend-- By Stigma. Basic rounding function. Needed to correct damage numbers, otherwise they sometimes display as 1HP of actual values.function round(num, idp)  if idp and idp>0 then    local mult = 10^idp    return math.floor(num * mult + 0.5) / mult  end  return math.floor(num + 0.5)end-- Stigma added loopcounter for timing, rounding for correct damage numbers, and optional freeze message (enable in settings)AddComponentPostInit("health", function(Health, inst)    inst:ListenForEvent("healthdelta", function(inst, data)        if inst.components.health then            local amount = round(((data.newpercent - data.oldpercent)*inst.components.health.maxhealth)*100)            if not (amount == 0) then                if not (TUNING.SHOW_DAMAGE_ONLY and amount > 0) then                    if (math.abs(amount) > 5) then                        amount = round(amount/100)                        CreateDamageIndicator(inst, amount)                    else                        if (freezeLockout == false and TUNING.SHOW_FREEZING_MESSAGE == true) then                            CreateFreezeIndicator(inst, amount)                            freezeLockout = true                        end                    end                end            end            loopCounter = loopCounter+1            if loopCounter == TUNING.FREEZE_MESSAGE_DELAY then                freezeLockout = false                loopCounter = 1            end            end    end)end)

 

-Stigma

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...