Jump to content

Photo

[2.55] Overriding Engine Enemy Movement with Ghost Scripts Crashes ZC.


  • Please log in to reply
1 reply to this topic

#1 Great Glass

Great Glass

    Newbie

  • Members
  • Location:Kansas

Posted 30 May 2020 - 08:07 AM

Once again, as it says on the tin. Using something like a Ghost script to override an enemy's in-engine movement (To get stuff like touch effects and make it move in ways the enemy type is not supposed to) will CRASH ZC when the enemy spawns.

Edit: This is on 2.55 Alpha 70. Whoops.

Edit 2: Here's the full script that caused the crash:

// import "std.zh"

// import "string.zh"
// import "ghost.zh"
 
// npc->Attributes[] indices
const int WB_ATTR_TILE_WIDTH = 2;
const int WB_ATTR_TILE_HEIGHT = 3;
const int WB_ATTR_IGNORE_WATER = 4;
const int WB_ATTR_IGNORE_PITS = 5;
 
ffc script WallBouncer
{
    void run(int enemyID)
    {
        npc ghost;
        int flags;
        int angle;
        float step;
        float xStep;
        float yStep;
        
        // Initialize
        ghost=Ghost_InitAutoGhost(this, enemyID, GHF_NO_FALL);
        Ghost_TileWidth=Ghost_GetAttribute(ghost, WB_ATTR_TILE_WIDTH, 1, 1, 4);
        Ghost_TileHeight=Ghost_GetAttribute(ghost, WB_ATTR_TILE_HEIGHT, 1, 1, 4);
        
        
        // Set flags
        flags=GHF_STUN|GHF_CLOCK;
        if(ghost->Attributes[WB_ATTR_IGNORE_WATER]>0)
            flags|=GHF_IGNORE_WATER;
        if(ghost->Attributes[WB_ATTR_IGNORE_PITS]>0)
            flags|=GHF_IGNORE_PITS;
        Ghost_SetFlags(flags);
        
        // Get initial movement
        angle=45+90*Rand(4);
step=ghost->Step/100;
        ghost->Step=0; // In case it's a walker
        
        xStep=step*Cos(angle);
        yStep=step*Sin(angle);
        
        while(true)
        {
            // Bounce
            if(xStep<0)
            {
                if(!Ghost_CanMove(DIR_LEFT, -xStep, 3))
                   xStep*=-1;
            }
            else
            {
                if(!Ghost_CanMove(DIR_RIGHT, xStep, 3))
                   xStep*=-1;
            }
            
            if(yStep<0)
            {
                if(!Ghost_CanMove(DIR_UP, -yStep, 3))
                   yStep*=-1;
            }
            else
            {
                if(!Ghost_CanMove(DIR_DOWN, yStep, 3))
                   yStep*=-1;
            }
            
            // And move
            Ghost_MoveXY(xStep, yStep, 3);
            Ghost_Waitframe(this, ghost, true, true);
        }
    }
}

Edited by Great Glass, 30 May 2020 - 08:20 AM.


#2 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 30 May 2020 - 10:52 AM

This has been fixed, and the next build will be out soon.

 

The offending line is:

 

ghost->Step=0; // In case it's a walker

 

Setting step=0 caused a crash because the new coordinates class didn't handle division by zero, and the engine divides by step.

 

The old fix class returned NAN (C++ float behaviour), but the new zfix class is integer-based, so we now do the equivalent with a sanity guard.

 

Thank you for the report.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users