Devotion discussion

Wrote new code? Fixed a bug? Want to discuss technical stuff? Feel free to post it here.

Moderator: Moderators

Message
Author
Motivus
Developers
Developers
Posts: 157
Joined: 04 Apr 2008, 13:33
Noob?: Yes

Devotion discussion

#1 Post by Motivus »

How it works: Devotion status is managed entirely through the 01CF packet. Structure:

<word packetId> <dword sourceId> <dword targetId[4]>

When ever devotion is cast it gives you the sourceId and all players currently under devotion status. When a player walks on screen that is under devotion status from a paladin on screen you receive the 01 CF packet again, refreshing the status. The packet is sent at other times too, including when devotion expires. There is no on/off flag, just 4 target ids that are often null.

Tracking devotion status:
The best way I can come up with is a list of actor ids on the source of devotion, and then when ever 01 CF is received compare the list to the list on the source actor. If an actor is missing then remove status from that actor id, and if a new actor is present add devotion to their statuses.

The problem is devotion can work at > 20 tiles and expires after a certain time elapses while a player is out of distance. The other issue is simply that when the source is out of range you have no idea if devotion status is on or off a player.

I am thinking:

1) List of targetids under devotion on sourceid actor
2) When sourceid actor object is destroyed remove devotion from any targetids that still exist
3) Devotion flag that includes sourceid on targetid actors
[4] When targetid actor is destroyed remove them from sourceid's list. This is not needed because you will receive an 01CF packet if devotion really does break, or if the actor comes back on screen.

This allows no polling and no false positives on devotion. However, it will detect devotion is off some times when it is not. The client shows it as off under the same circumstances, so I think we are in the clear, but if someone ever were to revamp openkore's code to be more viable in pvp/woe/party situations it's something that would need to be changed for Actor::You only.

If anyone has a better idea for the implementation of this please post it. I don't plan on making this devotion specific because marionette control works similarly, although I am not sure if that status is given through a standard packet.
Oh no.

User avatar
kLabMouse
Administrator
Administrator
Posts: 1301
Joined: 24 Apr 2008, 12:02

Re: Devotion discussion

#2 Post by kLabMouse »

Hmm. Can you sniff some packets? from MapLogin till the Devotion End.
Use WPE Pro for it, so there will be no junk.

kali
OpenKore Monk
OpenKore Monk
Posts: 457
Joined: 04 Apr 2008, 10:10

Re: Devotion discussion

#3 Post by kali »

We can have the $player object have a field or method specifically made to track which source ID gave him the devotion status; however as you have mentioned when a player goes out of the screen and the player list cache is refreshed, kore will have no way of knowing which people have devotion on whom.

I'd assume the official client does polling? Whenever a new player goes on screen with devotion, check surrounding actors for the ids present in 01CF and establish relationships as necessary. Would this method really take a hit on processing time?

I'm also thinking of a way to add some information to the output of the pl command to show the devotion. How about:
Player Kali has devotion on you
-or-
Player Motivus has devotion on player kLabMouse

or something like that.
Got your topic trashed by a mod?

Trashing topics is one click, and moving a topic to its proper forum is a lot harder. You expend the least effort in deciding where to post, mods expend the least effort by trashing.

Have a nice day.

Motivus
Developers
Developers
Posts: 157
Joined: 04 Apr 2008, 13:33
Noob?: Yes

Re: Devotion discussion

#4 Post by Motivus »

kali wrote:We can have the $player object have a field or method specifically made to track which source ID gave him the devotion status; however as you have mentioned when a player goes out of the screen and the player list cache is refreshed, kore will have no way of knowing which people have devotion on whom.

I'd assume the official client does polling? Whenever a new player goes on screen with devotion, check surrounding actors for the ids present in 01CF and establish relationships as necessary. Would this method really take a hit on processing time?

I'm also thinking of a way to add some information to the output of the pl command to show the devotion. How about:
Player Kali has devotion on you
-or-
Player Motivus has devotion on player kLabMouse

or something like that.
when the player walks on screen you get 01 CF again

the packet is sent when ever an actor appears with devotion status on, when ever devotion ends, and when ever a paladin with people under devotion comes on screen

The only thing to poll is when a player walks out of devotion range when we are the paladin casting it, but because of eAthena's broken implentation and how much of a waste of resources polling for something like that is it's not worth adding. Generally you want to recast it often, so thinking it's off and recasting it in that situation is fine. Plus it will be off on eAthena servers, even in the latest svn.
Oh no.

Chontrad
Human
Human
Posts: 30
Joined: 23 Apr 2008, 10:11
Noob?: No
Location: Indonesia TANAH AIRKU
Contact:

Re: Devotion discussion

#5 Post by Chontrad »

Somehow i figured a shortcut [edit: workaround] for this problem.

1. Add player status to each ID when you receive [devotion] packet

2. Set devotion time to each ID to check for timeOut later -> This will keep updating as long as [devotion] packet received

3. Check for devotion timeOut before AI loop starts (I did this in functions.pl <sub mainLoop_initialized>)
Loop DEVOTION TIME for each ID
If TIMEOUT -> delete this ID's DEVOTION STATUS
-> delete this ID's DEVOTION TIME # So it won't check for un-devotion-ed ID

This is anyway just a shortcut [edit: workaround] not a real solution (coz it consumes much PC usage). Maybe it can be used for a quick-fix [edit: workaround] in your botting system.

Btw, I don't have time to submit the program source. But i will do it soon, be patient. Terima kasih
Last edited by Chontrad on 17 Jun 2008, 00:26, edited 1 time in total.

h4rry84
Moderators
Moderators
Posts: 234
Joined: 04 Apr 2008, 09:30
Noob?: Yes
Location: My House
Contact:

Re: Devotion discussion

#6 Post by h4rry84 »

that was a very bad implementation. that is a workaround not a FIX !

Chontrad
Human
Human
Posts: 30
Joined: 23 Apr 2008, 10:11
Noob?: No
Location: Indonesia TANAH AIRKU
Contact:

Re: Devotion discussion

#7 Post by Chontrad »

Yeah, I know. I'm still a script-kiddie here, so that's the best i can do til now. Also, I think there's still no workaround for this until now, so I make some. Btw, can anyone inform me if it's already fixed in SVN? Coz I never checked for SVN.

Here's the source code (sry, I still don't use DIFF coz it runs very slowly in my system):
LEGEND|Orange : changed part|Red : added part|

<Receive.pm, Line 2997>
sub devotion {
my ($self, $args) = @_;

my $source = Actor::get($args->{sourceID});
my $msg = '';

for (my $i = 0; $i < 5; $i++) {
my $ID = substr($args->{data}, $i*4, 4);
last if unpack("V", $ID) == 0;

my $actor = Actor::get($ID);
$actor->{statuses}{Devotion} = 1;
$mytimer{devotionTime}{$ID} = time;

$msg .= skillUseNoDamage_string($source, $actor, 0, 'devotion');
}

debug "$msg"; # Used debug coz the messge is annoying
}
<END OF EDIT>

<Functions.pl, Line 592>
# Process AI
if ($net->getState() == Network::IN_GAME && timeOut($timeout{ai}) && $net->serverAlive()) {
foreach (keys %{$mytimer{devotionTime}}) {
if (timeOut($mytimer{devotionTime}{$_},3)) {
delete Actor::get($_)->{statuses}{Devotion};
delete $mytimer{devotionTime}{$_};
}
}

Misc::checkValidity("AI (pre)");
Benchmark::begin("ai") if DEBUG;
AI::CoreLogic::iterate();
Benchmark::end("ai") if DEBUG;

Benchmark::begin("ai_homunculus") if DEBUG;
AI::Homunculus::iterate();
Benchmark::end("ai_homunculus") if DEBUG;

Misc::checkValidity("AI");
return if $quit;
}
<END OF EDIT>

Hope I found a real solution soon. Terima kasih.

Technology
Super Moderators
Super Moderators
Posts: 801
Joined: 06 May 2008, 12:47
Noob?: No

Re: Devotion discussion

#8 Post by Technology »

It should be functional now.
Players can use:
target_isNotMyDevotee 1
to check whether a target is currently not being devoted by our character.
Note that none of the following was used:
- statuses (since some actors get removed from a certain distance)
- timers (resource hogging and incorrect)

Just the packet + references in $devotionList

Devotion stays active when the character moves out of the range, tho it gets deactivated when the target is out of range and being hit.
Only on activation and on deactivation the packet is being sent which renews the devotionList.
One ST0 to rule them all? One PE viewer to find them!
One ST_kRO to bring them all and in the darkness bind them...

Mount Doom awaits us, fellowship of OpenKore!

Locked