cannot override worldTick()?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
ramon.dexter
Posts: 1520
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

cannot override worldTick()?

Post 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?
User avatar
Apeirogon
Posts: 1605
Joined: Mon Jun 12, 2017 12:57 am

Re: cannot override worldTick()?

Post 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.
User avatar
gwHero
Posts: 360
Joined: Mon May 08, 2017 3:23 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: The Netherlands

Re: cannot override worldTick()?

Post 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.
User avatar
ramon.dexter
Posts: 1520
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: cannot override worldTick()?

Post 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.
User avatar
Apeirogon
Posts: 1605
Joined: Mon Jun 12, 2017 12:57 am

Re: cannot override worldTick()?

Post 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;
		}
User avatar
ramon.dexter
Posts: 1520
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: cannot override worldTick()?

Post 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 :)
Post Reply

Return to “Scripting”