Read out the EffectList
Hi, I'm new to this Forum and LUA programming, so sorry if I've done any stupid mistake ;)
Ok, I'm pretty f***** up and I have no more ideas. I took Jackdaws LowWarn and tried to modify it, so it will show when you get the Effects that Saruman applies to you in Orthanc. (Because I didn't knew how the Effects are named I took charge for testing) So this is what I did (used Disease as example, to make it less confusing): EffectList = Turbine.Gameplay.EffectList AddCallback(EffectList,"EffectAdded", function(sender, args) DiseaseWindow:SetOpacity(Disease()) end) AddCallback(EffectList,"EffectRemoved", function(sender, args) DiseaseWindow:SetOpacity(Disease()) end) --These are the Callbacks, I think they aren't the problem, it's the Disease function function Disease() if (EffectList:Contains(charge)) then -- This is line 30 Disease = 0.5 else Disease = 0 end end The plugin starts without problems, but when I use charge the game prints an errormessage: ...the Rings Online\Plugins\Kunter\EffectWarn\Main.lua:30: Invaild member function call. What have I done wrong? Greeting Kunter |
The contains function interests me - I didn't know it existed!
|
Oh the Master himself :D
Found it in the Isengard-Documentation... I thought this would bei a good command. |
I'm not sure how familiar with object oriented programming you are, so I'll start my explanation from there.
In object oriented programming, there's two major things - Classes and Instances. Classes are templates or instructions on how to build something. So a Window class might contain all of the information to display some sort of window. Instances are actual individual objects of a particular class - so there might be multiple Window instances, and each represents a different window on your display. Turbine.Gameplay.EffectList is a class. So you've just tried to ask the template if it has the charge effect - and it has no idea which actor's EffectList you want, because the class itself isn't associated with any particular actor. What you probably want is the LocalPlayer's EffectList, so you should probably say: EffectList = Turbine.Gameplay.LocalPlayer:GetInstance():GetEffe cts(); The second thing is (and it probably hasn't caused you problems, but I suspect it will) "charge" never gets defined. So your EffectList:Contains(charge) is asking if the EffectList contains a nil value (undefined variables are always nil) - which will always be false. The list only contains actual Effects. You've got two options - one, scan the EffectList (see :GetCount() and :Get(index)), or two use args.Effect and args.Index to keep track of which effect is being added or removed. I'd do the first one - it's clunkier to handle, and once you've got that working, think about using the args.Effect and args.Index arguments. |
Quote:
Consider the code: Code:
import "Turbine" Code:
Type before call:function The below code demonstrates using a local value for the return value, initializing it to the default and explicitly returning it. Note that you should always create variables with the narrowest possible scope, so the return value is scoped as local to the function to avoid conflict with any other variable with the same name. Code:
-- assumes that "EffectList" is properly assigned an instance of an EffectList and that "charge" is properly defined |
Quote:
I mean it's the name of the buff the plugin should look for, whats wrong about this? Ok, just a try concerning moebius post: What about this line: if (EffectList:Get(EffectList:GetCount()) == "charge") then The Get function needs the Index of the effect, cause it's the last added effect I use Get count (schould return a number/index of last added effect). EffectList:Get returns an effect, but how can I get the name of the effect, so I can compare it to the strin "charge"? if (EffectList:Get(EffectList:GetCount()):GetName() == "charge") then |
for loops. for loops are your friend.
You'll want something like... for i = 1, EffectList:GetCount(), 1 do if EffectList:Get(i):GetName() == "Charge" then dostuff(); break; end end Actually, what you might want to start with is: for i = 1, EffectList:GetCount(), 1 do Turbine.Shell.WriteLine(EffectList:Get(i):GetName( )); end ...so you can check the names of all of the effects. It probably is called "Charge", but you never know. And remember that string comparisons with == are case sensitive, so you'll want to get the case right. Edit: Lua Reference manual is also your friend. Feel free to keep asking questions, but there's a good chance I'll be looking up the answer in the reference manual. |
Code:
function Disease() Many Thanks! Now I have to find the debuffs names... |
Quote:
Second is more a matter of efficiency. As moebius showed in his example, when using a loop and looking for a specific condition, it is beneficial to use a break statement to exit the loop once the condition has been met if such a condition should only be true for one iteration or if only the first occurence is relevant (if more than one match can occur and all matches must be processed then a break statement is not useful). This can significantly increase the efficiency of your code, since on average you can cut the iterations in half or if you can reasonably expect your match to be at the end of the iteration, perform the iteration in reverse and get even better efficiency. |
Actually, the loop variable of a for loop always has a scope that is local to the for loop itself. So I think Kunter's okay in this case.
As for finding debuff names - look up Turbine.Gameplay.Effect - specifically GetCategory. And then look up Turbine.Gameplay.EffectCategory. You ought to be able to cobble something together to look for specific types of debuffs. Edit: Mind you, var should be local. Heck, I'd probably skip naming it, and just return 0.5 from inside the if statement, and then have a second return at the end of the function. |
Quote:
|
Code:
function Disease() |
Ok, tested the plugin today, works fine, if Jackdaw is ok with it I will publish it in a few days.
|
Catching effects
There is 2 ways to catch an effect on the player...
- 1st one as above is to scan "EffectList = LocalPlayer:GetEffects();" at regular intervals (ie: onTimer or on Refresh ) - 2nd, I'd say a cleaner way is to catch events AddCallback(EffectList, "EffectAdded", MyEffectChangedCallback); and "EffectRemoved" |
Quote:
I used this: EffectList = Turbine.Gameplay.LocalPlayer:GetInstance():GetEffe cts(); and this AddCallback(EffectList,"EffectAdded", --function to handle event--); So pretty much the same. EffectWarn works very fast and by the time 5 evenings at Saruman show that it is reliable (anyhow for me). |
All times are GMT -5. The time now is 11:39 PM. |
vBulletin® - Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
© MMOUI