Page 1 of 1
hmm... don't know what is that
Posted: Tue May 17, 2011 2:15 am
by RusseL
Code: Select all
[05/16 18:38:59] Script scripts/ai/spellkillpcs.ecl exceeded maximum call depth
Return path PCs: 5148 5116 3752 3273 1727 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 3251 3044 1903 3092 850 801
don't know why it's occur...
how can i fix that?
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 6:25 am
by OWHorus
A script calls a function, the function calls another function and so on. The maximum call depth can be adjusted, and is (without looking it up) 100, I think.
Usually this is not intentional, but a bug. Check the calls, and check if a function calls itself recursively. It looks like that. Recursive function calls are possible and even make sense in some cases, but you have to have clear abort criteria or you will run into a loop like this.
The PC numbers mean script program counters. Compile your scripts with the option -l, you will find the PC numbers in the listing. First you have to find out which script it is.
OWHorus
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 9:43 am
by Terciob
Enjoying the topic, i have a weird call depth insue in packet hook bellow, any one know what is worng?
Code: Select all
Packet 0x77
{
Length 17
SendFunction draw:updateplayer
}
Packet 0x20
{
Length 19
SendFunction draw:drawplayer
}
Packet 0x78
{
Length variable
SendFunction draw:drawobject
}
Code: Select all
use uo;
use os;
use polsys;
program draw_hook ()
return 1;
endprogram
exported function drawplayer (who, packet)
if (who.dead)
if (is_mg_region (who))
var serial := packet.getint32 (1);
if (serial == who.serial)
packet.sendpacket (who);
return 1;
endif
return 1;
endif
endif
endfunction
exported function updateplayer (who, packet)
if (who.dead)
if (is_mg_region (who))
var serial := packet.getint32 (1);
if (serial == who.serial)
packet.sendpacket (who);
return 1;
endif
return 1;
endif
endif
endfunction
exported function drawobject (who, packet)
if (who.dead)
if (is_mg_region (who))
var serial := packet.getint32 (1);
if (serial == who.serial)
packet.sendpacket (who);
return 1;
endif
return 1;
endif
endif
endfunction
function is_mg_region (who)
if (getregionname (who) ["Moongate"])
return 1;
endif
return 0;
endfunction
Pol.log:
Code: Select all
[05/17 11:56:37] Script pkg/server core/draw hook/draw.ecl exceeded maximum call depth
Return path PCs: 48 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39
Code: Select all
36: return
D:\Tercio\Pol099 Chaos Age\pkg\server core\draw hook\draw.src, Line 11
exported function drawplayer (who, packet)
37: makelocal
38: jmp userfunc @40
39: progend
40: pop param 'packet'
41: pop param 'who'
if (who.dead)
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 10:53 am
by CWO
Tericob, it could be that the packethook keeps calling itself because you keep sending the packet in the packethook. Let POL go on its normal sending routine after its done with the hook instead by returning 0...
Code: Select all
if (serial == who.serial)
packet.sendpacket (who);
return 1;
endif
change to
Code: Select all
if (serial == who.serial)
return 0;
endif
Never send the packet within its own packethook.
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 10:58 am
by CWO
RusseL this is your artificial loop - 3092 3251 3044 1903
if you notice, those four numbers repeat. The fix might be complicated though. Whatever function is at 3092 has to have a loop instead of the function at 1903 calling 3092 again to restart.
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 11:17 am
by RusseL
Code: Select all
1900: #
in_combat_event_loop(opponent, loops);
1901: local #0
1902: local #2
[b]1903: makelocal[/b]
1904: jmp userfunc @3034
1905: #
ev := wait_for_event( waittime );
1906: local #6
1907: Func(3,1): Wait_For_Event
........
3040: local #0
3041: 100L
3042: >
3043: if false goto 3049
post_combat();
[b]3044: makelocal[/b]
3045: jmp userfunc @3233
3046: #
return;
3047: ""
.........
3088: &&
3089: ||
3090: if false goto 3097
Fight( npc );
3091: local #0
[b]3092: makelocal[/b]
3093: jmp userfunc @1666
3094: #
return;
3095: ""
.........
3247: 1L
3248: makelocal
3249: jmp userfunc @3427
3250: #
look_around();
[b]3251: makelocal[/b]
3252: jmp userfunc @3051
3253: #
3254: 0L
Code: Select all
function look_around()
if (me.script == "spellkillpcs")
foreach hiders in ListMobilesNearLocationEx( me.x , me.y , me.z , HALT_THRESHOLD, LIST_HIDDEN, me.realm );
if (hiders.hidden)
hiders.hidden := 0;
SendSysMessage (hiders, "You have been discovered!");
endif
sleepms(1);
endforeach
endif
foreach npc in ListMobilesInLineOfSight( me, HALT_THRESHOLD )
if ( (!npc.npctemplate) or (npc.script == "tamed") and (npc.concealed == 0))
Fight( npc );
return;
endif
sleepms(1);
endforeach
endfunction
Code: Select all
function post_combat()
DisableCombatEvents();
EnableMainEvents();
SetWarMode( 0 );
SetOpponent( 0 );
sleep_ev(1);
look_around();
endfunction
i think that is because look_around() function called in post_combat... ?
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 11:33 am
by CWO
can you post Fight and in_combat_event_loop too
what we have to do is figure out where to put the loop and make all of these functions return to the loop instead of calling eachother again.
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 11:38 am
by RusseL
Code: Select all
function in_combat_event_loop(opponent, loops)
spellattack(opponent);
if ( loops > 100 )
post_combat();
return;
endif
endfunction
Code: Select all
function Fight (opponent)
var mob;
if ((me.npctemplate == "vortex") || (me.npctemplate == "bladespirit"))
return evFight(opponent);
endif;
if ((opponent.enabled ("invul")) or (opponent.serial == me.serial) or (opponent.concealed != 0) or (opponent.dead))
setwarmode(0);
opponent := 0;
return;
endif
opponent := HandleSummonedOpp (opponent);
set_priority(50);
OpenDoors(me);
SetOpponent( opponent );
TurnToward( opponent );
prepare_for_fight (opponent);
var loops := 0;
var CombatLoops:=0;
var ev;
var p_ev:={ };
var waittime := 0;
var StartOppHp;
var StartMeHp;
var tempsource;
StartOppHp:=GetHp(opponent);
StartMeHp:=GetHp(me);
var AttackPoints := {};
var AttackPosition := {};
while((opponent) && (!opponent.dead) && (!opponent.hidden) && (!opponent.concealed) && (dist(me,opponent) < 20))
OpenDoors(me);
if (!CloseDistance( opponent ) )
loops := loops + 1;
waittime := 0;
if ((loops>30) and (!CheckLineOfSight( me, opponent )))
post_combat();
return;
endif
else
loops := 0;
waittime := 1;
turntoward( opponent );
endif
if (opponent.npctemplate)
if (CombatLoops>10)
if ((GetHp(opponent)>=StartOppHp) and (GetHp(me)>=StartMeHp))
Set_Critical(1);
p_ev.+type:=EVID_PEACEMADE;
p_ev.+source:=me;
SendEvent(opponent, p_ev);
SetWarMode( 0 );
SetOpponent( 0 );
DisableCombatEvents();
EnableMainEvents();
Set_Critical(0);
return;
else
StartOppHp:=GetHp(opponent);
StartMeHp:=GetHp(me);
CombatLoops:=0;
endif
else
CombatLoops:=CombatLoops+1;
endif
endif
// START FIGHT
OpenDoors(me);
in_combat_event_loop(opponent, loops);
ev := wait_for_event( waittime );
cleareventqueue();
case (ev.type)
EVID_ENTEREDAREA:
EVID_ENGAGED:
EVID_DAMAGED:
OpenDoors(me);
mob := ev.source;
if ((mob) and (mob.serial != me.serial))
AddToHitList (ev);
if (mob.npctemplate)
if (GetObjProperty(mob, "good") || (mob.script == "tamed") || GetObjProperty(mob, "summoned"))
if (CheckLineOfSight(me, mob) and CheckLosAt(me, mob.x, mob.y, mob.z))
opponent := ev.source;
OpenDoors(me);
SetOpponent(opponent);
TurnToward(opponent);
endif
endif
else
if((!CheckLineOfSight(me, opponent) or
!CheckLosAt(me, opponent.x, opponent.y, opponent.z)) or (!opponent) or (RandomInt(3)<=1))
opponent := mob;
SetOpponent(opponent);
TurnToward(opponent);
OpenDoors(me);
endif
endif
process_combat_event(ev);
endif
EVID_PEACEMADE:
SetWarMode( 0 );
SetOpponent( 0 );
sleep_ev(1);
DisableCombatEvents();
EnableMainEvents();
return;
endcase
endwhile
post_combat();
endfunction
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 12:31 pm
by CWO
This is going to be a bit of a change and I'm not sure how it will affect the AI but try this...
make opponent a global variable. Wherever you have var me := self(); add var opponent;
Change
function Fight (opponent)
to
function Fight ()
Anywhere you call Fight, you'll have to change it to something like below...
in look_around() change
Code: Select all
foreach npc in ListMobilesInLineOfSight( me, HALT_THRESHOLD )
if ( (!npc.npctemplate) or (npc.script == "tamed") and (npc.concealed == 0))
Fight( npc );
return;
endif
sleepms(1);
to
Code: Select all
foreach npc in ListMobilesInLineOfSight( me, HALT_THRESHOLD )
if ( (!npc.npctemplate) or (npc.script == "tamed") and (npc.concealed == 0))
opponent := npc;
return;
endif
sleepms(1);
Notice instead of calling Fight(npc) I set opponent to npc and returned. From what I see, post_combat does nothing more after look_around so with look_around returning, post_combat will return, in_combat_event_loop will return and guess what they return to, Fight()... which is where you wanted to go.
Test extensively because this could still break other parts of your AI
Re: hmm... don't know what is that
Posted: Tue May 17, 2011 12:40 pm
by Terciob
Thanks CWO.