Jump to content

Recommended Posts

I want to make a script that would listen for the event of target getting hit by player. Once true, it would make the character say something(Note that it's not for a specific character but for all of them).

What i mean by "getting hit" is actually receiving damage, when a sound plays indicating player caused damage(You can hear it when hitting mobs: spiders sound wettish, clockworks have their own sound and so on).

I am struggling with the first part. From what I found on other threads, it seems like I need to listen to combat.lua's "onhitother" event, but I couldn't get it to work. 

Sure! Here is what I came up with:

modmain.lua:

Spoiler


AddComponentPostInit("onattackother", function(data, inst)
    inst:ListenForEvent("onattackother", printer) 

        local function printer(inst, data) 

        inst.components.talker:Say("Hit!") 
        
        end 

    end)

return inst
 

And modinfo.lua

Spoiler

name = "TalkOnHit"
author = ""
version = "1"
description = ""
description = description .. "\n\nVersion: " .. version

api_version = 6
api_version_dst = 10

dont_starve_compatible = true
reign_of_giants_compatible = true
shipwrecked_compatible = true
dst_compatible = true

client_only_mod = true
all_clients_require_mod = false


I changed onhitother event to onattackother because I think the second one stands for getting creatures hit. But I tried both, still did not work - it doesn't do anything.

Epic things Imma be referencing a few times.

	env.postinitfns.ComponentPostInit = {}
	env.AddComponentPostInit = function(component, fn)
		initprint("AddComponentPostInit", component)
		if env.postinitfns.ComponentPostInit[component] == nil then
			env.postinitfns.ComponentPostInit[component] = {}
		end
		table.insert(env.postinitfns.ComponentPostInit[component], fn)
	end

-- scripts/modutil
-- this is the function You're calling

self.inst:PushEvent("attacked", 
  { -- this is all the data that is given to the event
    attacker = attacker, 
    damage = damage, 
    damageresolved = damageresolved, 
    original_damage = original_damage, 
    weapon = weapon, 
    stimuli = stimuli, 
    redirected = damageredirecttarget, 
    noimpactsound = self.noimpactsound 
  })

-- this is the event you want to call
-- not gonna lie i'm not sure what half the data is but its' found in the combat.lua in scripts/components

So you're using the add component function, the purpose of this function is to add extra stuff to a function without replacing it.
however you want to call code when an event is called hence "inst:ListenForEvent("onattackother", printer)and I think you may have mistaken AddComponentPostInit for Events.

So you don't actually need to use this function to create this and I think it'd be better to use the addprefab thingy but the concept is basically the same so I'll show you the one you chose

Basically the lowdown of everything:

1. Adding to a component

Spoiler
-- How it Works: AddComponentPostInit("Component Name", Function)

------------- Combining the function into the code -----------

AddComponentPostInit("combat", function(self) 
    --code
end) -- Note: we have to close the AddComponentPostInit because we oponed a bracket to include the information

------------- Calling a Function we Created prior ---------------

local function OnHitSound (self)
  --code
end -- Note: we don't need to have bracket here because below its already closed.

AddComponentPostInit("combat", OnHitSound)

So we're using the modutil function AddComponentPostInit function to add to the component combat, the component is used to manage all the combat based stuff and hence getting attacked. I'm showing the two ways to use it but either work the same.

2. Events and listening for them

Spoiler
AddComponentPostInit("combat", function(self) -- in the case of a function we use self to refer to the class we created, you can learn more on the lua website
    self.inst:ListenForEvent("attacked", function(inst, data) -- Note: 'inst' just basically refers to the entity, 'data' is a list of data given when the event is called 
        -- code
        
   end) -- Note: Closing the ListenForEvent function
end)

Now that we've made a function to add to the component we want to listen for the event 'attacked', an event that is called when they're attacked. We're using the listen for event function and we can use the same method to separate them into different bits buts its not necessary but can be used to clean it up a bit.

 

To learn more about prefabs, components and modding altogether a I'll link them and if you want to learn more about the programming language you can click on my little Lua thing, I'm personally bad this whole coding things myself but its fun to create stuff and I see that's you've linked the code together without much knowledge which is great and half the fun of coding. 

These were given by the some of the Gods of dst modding.

ComponentsPrefabs and Modding

tell me if you don't understand anything me brain dumb and me bad at english. Sorry If i reply late i'm too busy eating petals.

Edited by Thomas Die
Me brain dumb, me edit mistake
  • Like 1
  • Thanks 1
On 3/27/2023 at 7:25 PM, Thomas Die said:

Sorry I misread the poste but 

You can still use the code but can use if attacker has the tag player to use the code.

Add to player function does exist and would be the best to use otherwise.

 


First of all, thank you very much for your responses and time!
I spent some time analyzing yours and game code thinking of how to implement my idea. 

Your code works perfect if the mode is all_clients_required - I put the print("") thing in ListenForEvent, and it prints in master_server_log.txt when I or enemy get hit, but I'm trying to make it client sided.

I'm not sure how to implement it without having access as a client to scripts/components/ folder. 

It must be possible tho: as players we can tell when we hit someone by the sound of it, so there must be an event calling that sound, thus we can listen to it and code to do something when it happens.

Talking about checking if attacker has the tag player, I found a snippet of code that excludes some entities with certain tags as enemies(By https://forums.kleientertainment.com/profile/537741-k1ngt1ger609/)

Spoiler
local function IsValidVictim(victim) --exclude these as enemies
    return victim ~= nil
        and not (victim:HasTag("veggie") or
                victim:HasTag("structure") or
                victim:HasTag("wall"))
        and victim.components.health ~= nil
        and victim.components.combat ~= nil
end

local function combatdrain(inst, data) --if you hit your enemy
local victim = data.victim
    if not IsValidVictim(victim) then
    inst.components.sanity:DoDelta(-1)
    end
end

 

But I think it's better to find a way how to implement the current idea into client mode first. 
I am not sure about that, looking at how other mods implemented it didn't give me an idea how to get it right in my example as I didn't find a simple enough mod or one that is similar to my concept.



EDIT: Found an easier way to fix crashes and stuff with 1 line instead of tags

I added 'if self.inst.components.talker ~= nil then' into the code

Spoiler
AddComponentPostInit("combat", function(self) -- in the case of a function we use self to refer to the class we created, you can learn more on the lua website
    self.inst:ListenForEvent("onhitother", function(inst, data) -- Note: 'inst' just basically refers to the entity, 'data' is a list of data given when the event is called 
	if self.inst.components.talker ~= nil then
	self.inst.components.talker:Say("Hit!")
	end
	end)
end)

 

Edited by Klosdir

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...