Finding an element's method and returning that element.

yumel

Member
I can't wrap my head around why this isn't working.

Created an index of a custom made object to track spell timers. For whatever reason I can't find whatever method or call or argument that I use to return the specific element within the index that matches my search criteria. The script works and populates the index just fine. I just can't make a simple call to return the element so I can play with its methods.

Would someone mind taking a look at this and tell me where I am going wrong?

The function abilSearch returns the object because it has the methods and members of the obj_abilTimer but it doesn't return the object of the element it just found in the iteration loop.

And I am sure this looks hackish to some people so please comment on any changes that you would make. In my working version I am using arrays of obj_abilTimer and the function to find the matching tgtID returns the key. So I have something that does work, it's just lacks a lot of polish.

Thank you for your time.

objectdef obj_abilTimer
{
variable collection:uint abilDict
variable int64 ID

method Initialize()
{
This.ID:Set[0]
}

method Add(int64 tgtID, string abilName="", int abilT=0)
{
This.ID:Set[${tgtID}]
echo --- abilTimer --- adding ID ${This.ID}
if ${abilName.Length}>1 && ${abilT}>0
This:Set[${abilName}, ${abilT}]
}

method Set(string abilName, int abilTime)
{
variable int64 timeAdded
timeAdded:Set[${Math.Calc[${abilTime}*1000]}]
This.abilDict:Set[${abilName}, ${Math.Calc[${Script.RunningTime}+${timeAdded}]}]
echo verying object timer was added
if ${This.abilDict.Element[${abilName}](exists)}
echo tgtID - ${This.ID} abilDict - ${abilName} timeAdded - ${timeAdded} timeEnding - ${This.abilDict[${abilName}]}
}

method Clear()
{
This.abilDict:Clear
}

member:bool isReady(string abilName)
{
if ${Math.Calc[${This.TimeRemaining[${abilName}]}-${Math.Calc[${Me.Ability[${abilName}].CastTime}*1000]}]}<=0
return TRUE
else
return FALSE
}

member:int64 TimeRemaining(string abilName)
{
if ${This.abilDict.Element[${abilName}](exists)}
echo --- TimeRemaining --- ${abilName} --- ${Script.RunningTime} versus ${This.abilDict[${abilName}]}
if !${This.abilDict.Element[${abilName}](exists)} || ${Script.RunningTime}>=${This.abilDict[${abilName}]}
return 0
else
return ${Math.Calc[${This.abilDict[${abilName}]}-${Script.RunningTime}]}

}

}



function:eek:bj_abilTimer abilSearch(int64 tgtID)
{
echo --- abilSearch --- ${tgtID}
variable iterator abilIter2
abilTimers:GetIterator[abilIter2]
if ${abilIter2:First(exists)}
{
do
{
echo testing ${tgtID} vs ${abilIter2.Key} / ${abilIter2.Value.ID}
if ${abilIter2.Value.ID}==${tgtID}
{
echo found it key = ${abilIter2.Key} isReady ${abilIter2.Value.isReady["Recall"]}
return ${abilIter2.Value}
}
}
while ${abilIter2:Next(exists)}
}
}

variable obj_abilTimer obj_abilTimer
variable index:eek:bj_abilTimer abilTimers
 

pr517

Active Member
Well, now that is interesting... ${Return} is inheriting the script-defined object type obj_abilTimer, but it isn't doing anything beyond its Initialize method. I ruled out my suspicion of it running Initialize (which sets ID to 0) after copying the object, as ID is still 0 after commenting it out.

Perhaps the ${Return} object doesn't really get its value from a true memory copy and instead has some sort of implied :Set that occurs as the function ends. In that case, it makes sense why a script-defined object wouldn't work because it wouldn't know which methods to run other than Initialize.

I'd ask Lax.
 

pr517

Active Member
I dug a little deeper and found that when you instantiate an objectdef with ${} it is calling its ToText member. Essentially, ${abilIter2.Value} is equal to ${the object itself} which means you are really returning ${abilIter2.Value.ToText} which has not been defined. I'm not sure if there is a simpler way to copy an object entirely into the Return TLO, but what you could do is, in that ToText, return a string that has all of the information needed to reconstruct itself afterwards.

inside of objectdef obj_abilTimer:
Code:
	member:string ToText()
	{
		variable string a = "${This.ID}|${This.abilDict.Used}|"
		variable string b = ""
		variable iterator anIterator

		abilDict:GetIterator[anIterator]
		if ${anIterator:First(exists)}
			do
			{
				b:Set[${b}${anIterator.Key}\,${anIterator.Value}|]
			}
			while ${anIterator:Next(exists)}

		return "${a}${b}"
	}
And then what gets returned would be something like:
Code:
123|1|Recall,456015
edit: Forgot to mention, you also need to change the return type for abilSearch or you will be creating the same problem in a nested fashion.

Code:
function:string abilSearch(int64 tgtID)
 
Last edited:

yumel

Member
I dug a little deeper and found that when you instantiate an objectdef with ${} it is calling its ToText member. Essentially, ${abilIter2.Value} is equal to ${the object itself} which means you are really returning ${abilIter2.Value.ToText} which has not been defined. I'm not sure if there is a simpler way to copy an object entirely into the Return TLO, but what you could do is, in that ToText, return a string that has all of the information needed to reconstruct itself afterwards.
Actually that makes a lot of sense and thanks for going through it so thoroughly; never even thought to check that the ${} was returning the ToText.

I wish I knew how to build a TLO for script-defined objects as that would have made this loads easier. I've tried but never could get the TLO to parse in LavishScript so I'm thinking you have to compile it in C?

I ended up creating a separate scrtip-defined object that has an object scope container (can't remember whether I did indexes or collections) of the abilTimers with GetIndex and it returns what I need. So far haven't found any issues with it and that's over a few toons with abilities like HoTs, Necropsy, Group Buffs, etc.
 
Top Bottom