Jump to content

Recommended Posts

Posted

Hello fellow Leadwerkers,

 

i have a little problem. I'm trying stuff and i have reached a place where i cannot continue further without help.

Basically i want to do the following:

 

Create a box,

that box has a script attached named "Damage" that's being run on "Use", so if i press "E" it's fired up,

the "Damage" script shall target the player and do random damage.

 

I got it all running if i add the target via "Script.target = nil --entity "Target" followed by dragging the "Player" onto that field in the assets tab. But now i'm lazy, i want to use that scrip on several places and i do not want to add the target "Player" every time by hand. So my idea was to look into the "MonsterAI.lua" script how that is solved.

 

I ended up with smth like this:

 

import "Scripts/Functions/GetEntityNeighbors.lua"

Script.target = nil --entity "Target"
Script.damage = 0 -- float "Damage"
Script.teamid = 2 --choice "Team" "Neutral,Good,Bad"

function Script:Use()

local entities = GetEntityNeighbors(self.entity,30,true)
local k,entity
for k,entity in pairs(entities) do
if entity.script.teamid == 1 then
if entity.script.health>0 then
local d = self.entity:GetDistance(entity)
local pickinfo=PickInfo()
self.target = entity
end
end
end

math.randomseed(os.time())
System:Print("I'm in the tree use function")
if self.target ~= nil then
if self.damage > 0 then
if self.damage > 5 then
minDmg = self.damage - 4
else
if self.damage > 2 and self.damage <= 5 then
minDmg = self.damage - 2
else
minDmg = self.damage
end
end
xDamage = math.floor(Math:Random(minDmg, self.damage + 1))
self.target:Hurt(xDamage)
end
end
end

 

My idea was to set the TeamID for that script to "bad" == 2 (whilst the player is "good" == 1), so it will only run if it has contact with the player. The Problem is, i have no idea how to get the result of "return entity.script" as a valid target to use it in the 2nd half of the script (following the lines after "self.target = entity.script").

 

I'm basically quite sure that i didn't understand how it works at all, so any help, especially if someone could explain my error, would be appreciated.

 

Thanks in advance!

 

[Edit]

Did some slight changes to the original code, so now the "self.target" points to the correct entity, but still i get a "called nil" when trying to access "self.target:Hurt(xDamage)". Even though i was able to see in debugmode that the adress stored in "self.target" is actually the player (and thus the target i want).

Posted

function script Hurt(damage, DistributorOfPain) --> that's actual in the basic "FPSPlayer.lua" script without changing it. I already thought, that the "nil" error might come due to the fact i only fill "damage" in the "Hurt()" function above, but i even tried to set the "DistributorOfPain" to self.target (since i lack another target i could use....) but that doesnt work either. Besides that, the value in "DistributorOfPain" is not used in the FPSPlayer script at all.

 

function Script:Hurt(damage,distributorOfPain)
if self.health>0 then
self.sound.damage[math.random(#self.sound.damage)]:Play()
self.health = self.health - damage
dmgReceived = damage
self.hurtoffset = Vec3(math.random(-1,1),math.random(-1,1),0):Normalize()*30
local blood = {}
local n=1
blood.texture=self.image.blood[math.random(1,4)]
blood.intensity=1
table.insert(self.bloodoverlay,blood)
if self.bloodindex>4 then self.bloodindex=1 end
if self.health<=0 then
self:Kill()
end
end
end

 

[Edit] Besides, it did work before when i set the Target via drag n drop into the script by hand that way. It's only not working since i tried to get the target automagically.

Posted

So in this code you have the entity not nil ?

 

local entities = GetEntityNeighbors(self.entity,30,true)

local k,entity

for k,entity in pairs(entities) do

if entity.script.teamid == 1 then

if entity.script.health>0 then

local d = self.entity:GetDistance(entity)

local pickinfo=PickInfo()

self.target = entity

end

end

end

 

 

Or could it be some parameter that is the problem ?

Could you call your Hurt function with simple fixed parameters ? like damage = 10 for example ?

I would say make a simple function test also : create another function like test() on Player entity and call it instead of Hurt() and see if the function is called without problem ?

Stop toying and make games

Posted

Oh, no sorry, i explained it wrong. The Code you posted above goes error free, i even get the "self.target" to point to the players entity in memory (i did see that in debug mode)

The error occurs on the last line of code:

self.target:Hurt(xDamage)

 

"attempt to call method 'Hurt' (a nil value)"

 

But the variable xDamage is filled with a number (even if i replace it by "5" it's the same error) and if i add (xDamage, self.target) it's still the same error

 

[Edit]

Tried to make a function Script:Test() --> printing a message to console. I do get the same error, so the problem seems to be the value in self.target .... do i have to convert the memory adress i do get to smth. else maybe?

Posted

But thanks for trying YouGroove smile.png

 

[Edit]

OMFG it's SO mega easy.... the problem was that i called "self.target:Hurt(xDamage)", but it actually has to be "self.target.script:Hurt(xDamage)".

 

Didnt see the forest due to all those trees :P well. in case someone else might be interested, i gonna add a few comments to my code and will post it as it works right now in a few hours.

Posted

here's the "streamlined" code with a few comments. Hopefully others may profit from it smile.png Again my thanks to YouGroove for trying to solve my issue, without his comment i wouldn't have tried to access "self.target.script:Hurt" smile.png

-- give access to code in "GetEntityNeighbors.lua"
import "Scripts/Functions/GetEntityNeighbors.lua"

Script.target = nil --entity "Target"
Script.damage = 0 -- float "Damage"
Script.teamid = 2 --choice "Team" "Neutral,Good,Bad"

function Script:Use()

   -- load entities within range (30) of self.entity into "entities", only load entities that have scripts attached
   local entities = GetEntityNeighbors(self.entity,30,true)
   local k,entity
   -- loop thrrough the result of "entities". k = key, entity = result
   for k,entity in pairs(entities) do
       -- only select entities with teamid == 1 ("good")
       if entity.script.teamid == 1 then
           -- and if the entity has at least 1 health remaining
           if entity.script.health>0 then
               local d = self.entity:GetDistance(entity)
               -- set self.target = resulting entity
               self.target = entity
           end
       end
   end

   -- prepare random function
   math.randomseed(os.time())
   if self.target ~= nil then
       -- randomize the damage dealt a bit, setting the "min damage" value
       if self.damage > 0 then    
           if self.damage > 5 then
               minDmg = self.damage - 4
           else
               if self.damage > 2 and self.damage <= 5 then
                   minDmg = self.damage - 2
               else
                   minDmg = self.damage
               end
           end
           -- actual code randomizing the damage. Damage is dealt between "minDmg" and "self.damage" (the value is set in the assets browser)
           xDamage = math.floor(Math:Random(minDmg, self.damage + 1))
           -- fire function "Hurt" at self.target --> thus the player or entite that was found before.
           self.target.script:Hurt(xDamage, self.target)

       end
   end
end

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...