Converting Actor.lua code into hooks

A place to post your add ons and ideas for them

Moderator: Moderator

Post Reply
Message
Author
daftigod
Archmage
Posts: 300
Joined: Fri Feb 18, 2011 6:15 am

Converting Actor.lua code into hooks

#1 Post by daftigod »

Hi, could someone walk me through this problem I've been having? I know nothing about code, so treat me like a total noob. :)

I want to convert the code for a skill in Dekar's Ranger addon into a hook. Here's the stuff I stripped out of Dekar's edited Actor.lua file with (what I think) is all the relevant code for the skill that tells the pet to defend the ranger at certain times.

Code: Select all

function _M:onTakeHit(value, src)
	if self:attr("protect") then
			
		if rng.percent(self.protect_chance) and not (self.ranger_pet==nil or self.ranger_pet.dead)then
			local distance = core.fov.distance(self.x, self.y, self.ranger_pet.x, self.ranger_pet.y )
			if (distance < 2) then
				game.logSeen(self, "%s protects %s!", self.ranger_pet.name, self.name)
					self.ranger_pet:takeHit(value, src)
					value = 0
			end
		end
		
	end
end
I don't know what most of it means, but what I'm concerned with is how to get it into hook format. Here is the stripped code from the example addon:

Code: Select all

class:bindHook("Actor:takeHit", function(self, data)
	if self:hasEffect(self.EFF_DIPLOMATIC_IMMUNITY) then data.value = 0 return true end
end)
Or, a working example from greyswandir's Monk addon:

Code: Select all

local takeHit_hook = function(self, data)
   
   -- Ki Shield
   if self.isTalentActive and 
      self:knowTalent(self.T_KI_SHIELD) and
      self:isTalentActive(self.T_KI_SHIELD)
   then
      local t = self:getTalentFromId(self.T_KI_SHIELD)
      local pct = t.getPercent(self, t)

      local absorb = math.min(data.value * 0.5, self:getStamina() / pct)
      self:incStamina(-absorb * pct)
      data.value = data.value - absorb
   end

   return true
end
class:bindHook("Actor:takeHit", takeHit_hook)
I'm mostly interested in knowing how to tell which functions to call and how to name them and such. Any help would be greatly appreciated and I think a few other addon authors around here would find this information valuable too. I'm trying to put together a player class pack without any compatibility issues, and I'm pretty close but this is the only thing holding me back right now. Thanks in advance!

marvalis
Uruivellas
Posts: 683
Joined: Sun Sep 05, 2010 5:11 am

Re: Converting Actor.lua code into hooks

#2 Post by marvalis »

Perhaps try something like this? Goes in hooks/load.lua

Code: Select all

local takeHit_hook = function(self, data)
	if self:attr("protect") then
		if rng.percent(self.protect_chance) and not (self.ranger_pet==nil or self.ranger_pet.dead)then
			local distance = core.fov.distance(self.x, self.y, self.ranger_pet.x, self.ranger_pet.y )
			if (distance < 2) then
				game.logSeen(self, "%s protects %s! %s hits %s for %s damage", self.ranger_pet.name,self.name, data.src.name, self.ranger_pet.name, data.value)
				self.ranger_pet:takeHit(data.value, data.src, data.death_note)
      				data.value = 0
			end
		end
		
	end
   return true
end
class:bindHook("Actor:takeHit", takeHit_hook)
This gives me an idea BTW, a nature theme talent that plants a tree that absorbs damage while you are next/near to it, but also takes damage (from AoE effects and/or others).

marvalis
Uruivellas
Posts: 683
Joined: Sun Sep 05, 2010 5:11 am

Re: Converting Actor.lua code into hooks

#3 Post by marvalis »

daftigod wrote:I'm mostly interested in knowing how to tell which functions to call and how to name them and such.
You call the functions that you want to hook.
You name the local function whatever you want

In the example above:

Code: Select all

local takeHit_hook = function(self, data)
That is the new function that will be hooked to the original one, stored in a local variable to be called by:

Code: Select all

class:bindHook("Actor:takeHit", takeHit_hook)
This is the function that is hooked: _M:takeHit in actor.lua
I think the code in takeHit_hook is attached above (not below) the code in _M:takeHit

About the tome programming class system... I can't tell you much about that, except that bindhook is coded in
game/engines/te4/engine/class.lua

daftigod
Archmage
Posts: 300
Joined: Fri Feb 18, 2011 6:15 am

Re: Converting Actor.lua code into hooks

#4 Post by daftigod »

Thank you Marv! That advice helped me greatly.

I've managed to extract the actor and combat data from the illusionist addon, and it seems to be working as a hook so far. I've already combined the barbarian and monk addons successfully, so next I am going to try to merge the illusionist and see how that goes. The ranger is also on the list, but I still have to get the hooks working there.

Now I have to think of a Class name for all these sub classes! I've been using "Zigurath" so far, thinking that the barbarian/monk/ranger could fit that theme, but the illusionist uses spells so there goes that idea. I have no idea really for a group name... "New" or "Others" would fit I suppose.

I guess I could also try to write a hook for the birth files like warrior, wilder, etc. Is that even possible?

Thanks again!

grayswandir
Uruivellas
Posts: 708
Joined: Wed Apr 30, 2008 5:55 pm

Re: Converting Actor.lua code into hooks

#5 Post by grayswandir »

Actually, now that you mention it it should be pretty easy. I haven't tested it yet, but I'll move monk over to warrior next chance I get.

Theoretically:

Code: Select all

getBirthDescriptor("class", "Warrior").descriptor_choices.subclass.Monk = "allow"
Edit: I've uploaded the next version (v4). The above worked, and Monk is now under Warrior.
Addons: Arcane Blade Tweaks, Fallen Race, Monk Class, Weapons Pack
Currently working on Elementals. It's a big project, so any help would be appreciated. :)

Post Reply