Page 1 of 1

cannot override worldTick()?

Posted: Tue May 08, 2018 11:13 am
by ramon.dexter
Hi, I'm trying to make an eventhandler.
Here's the code:

Code: Select all

class itemsWatcher : EventHandler
{
    int watcher_tick;	

    override void WorldTick(PlayerEvent e)
    {		
		let player = players[e.PlayerNumber].mo;
		
        watcher_tick++;

        if(watcher_tick == 35)
        {
            watcher_tick = 0;

            //night-eye device
            if(player.countinv("NightEyeDevice") <= 1) 
            {
                //A_Print("Night-Eye Device depleted!", 0, "smallfont");
                player.takeinventory("PowerLantern", 1);
                player.takeinventory("LanternActive", 1);
                return;
            }
        }
		
        super.WorldTick();
    }    
}
It gives me error: Attempt to override non-existent virtual function WorldTick
What's giong on? I think the inheritance should work...? Or what am I ding wrong?

Re: cannot override worldTick()?

Posted: Tue May 08, 2018 11:22 am
by Apeirogon
Each possible event is done as a virtual method in the StaticEventHandler/EventHandler classes which can be overridden.
Note that you don't need to call the original methods because the default implementation is empty and does nothing.

Re: cannot override worldTick()?

Posted: Tue May 08, 2018 11:23 am
by gwHero
Hi Ramon,

it's without argument PlayerEvent e:

Code: Select all

override void WorldTick()	
{		

    let player = players[consoleplayer].mo;
   ...
}
Btw, it's not necessary to call super.WorldTick(); it's empty and does nothing.

Re: cannot override worldTick()?

Posted: Wed May 09, 2018 10:15 am
by ramon.dexter
Yup, that fixes the error. But it seems that the handler doesnt do what it should do...
Is my syntax correct? I'm not fammiliar with C type syntax of zscript, so I'm not sure if I hadnt defined it correctly to actually DO what it should do...

What it should do?
Well, I found out that when I put the "if" check into item's DoEffect(), removing theis active item by itself's DoEffect() causes gzdoom VM to crash (with some zero division error), so I created another inv item, that simply performs the check (check to if supply item is depleted or not) and removes the active item under condition. My description is rather problematic, so here the item's code:

Code: Select all

class PowerLantern : PowerTorch //PowerLightAmp
{
	int lantern_tics; 

    override void attachtoowner(actor user)
    {
        lantern_tics = 0;
        super.attachtoowner(user);
    }

    override void doeffect()
    {
		Super.doEffect();
		if(owner.countinv("NightEyeDevice") <= 1)  //when this condition is met, causes crash of gzdoom zscript VM. So it seems that the Doeffect cannot remove itself. Removing it by another item works well.
        {
			A_Print("Night-Eye Device depleted!", 0, "smallfont");
            owner.takeinventory("PowerLantern", 1);
            owner.takeinventory("LanternActive", 1);
			return;
		}

        lantern_tics++;

        if(lantern_tics == 70)
        {
            owner.takeinventory("NightEyeDevice", 1);
            lantern_tics = 0;
        }

    }
	
	Default
	{
		powerup.Duration 0x7FFFFFFD;
		powerup.color "6fef67", 0.05;
		//inventory conf
		//==--------------------------
		Inventory.Icon "A_NEDV";
		//==--------------------------
	}
}
So, the description in the code says it.

Code for the item that makes the check is following:

Code: Select all

class LanternWatcher : Inventory
{
	 override void doeffect()
    {
		
        if(owner.countinv("NightEyeDevice") <= 1) 
        {
			A_Print("Night-Eye Device depleted!", 0, "smallfont");
            owner.takeinventory("PowerLantern", 1);
            owner.takeinventory("LanternActive", 1);
			return;
		}

    }

	Default
	{
		+INVENTORY.ALWAYSPICKUP
		
		Inventory.MaxAmount 1;
		Inventory.InterHubAmount 1;
	}
}
So, the mechanic is following: player activates inv item, that serves as a "ammo supply" for the active item. The active item could be powerup, or anything else (that doesnt matter here). Activation gives player the active item and the watcher. The active item has modified DoEffect() that drains the item supply. First, I wanted to define if the the supply item is depleted in the active item. But that causes VM crash, apparently doeffect() cannot be removed by itself. Removing it by another item (the *watcher above) is OK and works as intended.
I wanted to make a eventhandler to perform the work of the *watcher items. But I really dont know how to correctly write the zscript syntax... Could anyone help me to create this eventhandler? OR, is it possible? If not, I'll stick to the inv items.

Re: cannot override worldTick()?

Posted: Wed May 09, 2018 11:38 am
by Apeirogon
If I understood correct, error happens here

Code: Select all

      if(owner.countinv("NightEyeDevice") <= 1) 
        {
         A_Print("Night-Eye Device depleted!", 0, "smallfont");
            owner.takeinventory("PowerLantern", 1);
            owner.takeinventory("LanternActive", 1); //error is here!
        return;
		}
because in previous lines you take/destroy from inventori this item, inside of which this code wrote and run. So after destroing this item code in cpu know that after removing "power lantern" there are some lines, but it cant find it.

So, just do

Code: Select all

      if(owner.countinv("NightEyeDevice") <= 1)  
        {
         A_Print("Night-Eye Device depleted!", 0, "smallfont");
            //owner.takeinventory("PowerLantern", 1);
            owner.takeinventory("LanternActive", 1);
         self.destroy(); return;
		}

Re: cannot override worldTick()?

Posted: Wed May 09, 2018 12:42 pm
by ramon.dexter
Yes, that look like it! :D Great!

I knew that the problem was that it was removing itself, while doing the effect :)