hmm... don't know what is that

Get Help on scripting in POL with configurations, config setups, script trouble shooting, etc.
Post Reply
RusseL
Forum Regular
Posts: 375
Joined: Fri Feb 20, 2009 8:30 pm

hmm... don't know what is that

Post 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?
OWHorus
Grandmaster Poster
Posts: 106
Joined: Sat Feb 04, 2006 1:24 pm

Re: hmm... don't know what is that

Post 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
Terciob
Master Poster
Posts: 90
Joined: Fri Nov 07, 2008 3:47 am

Re: hmm... don't know what is that

Post 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)
User avatar
CWO
POL Expert
Posts: 1160
Joined: Sat Feb 04, 2006 5:49 pm

Re: hmm... don't know what is that

Post 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.
User avatar
CWO
POL Expert
Posts: 1160
Joined: Sat Feb 04, 2006 5:49 pm

Re: hmm... don't know what is that

Post 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.
RusseL
Forum Regular
Posts: 375
Joined: Fri Feb 20, 2009 8:30 pm

Re: hmm... don't know what is that

Post 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... ?
User avatar
CWO
POL Expert
Posts: 1160
Joined: Sat Feb 04, 2006 5:49 pm

Re: hmm... don't know what is that

Post 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.
RusseL
Forum Regular
Posts: 375
Joined: Fri Feb 20, 2009 8:30 pm

Re: hmm... don't know what is that

Post 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
User avatar
CWO
POL Expert
Posts: 1160
Joined: Sat Feb 04, 2006 5:49 pm

Re: hmm... don't know what is that

Post 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
Terciob
Master Poster
Posts: 90
Joined: Fri Nov 07, 2008 3:47 am

Re: hmm... don't know what is that

Post by Terciob »

Thanks CWO.
Post Reply