Jump to content

Photo

Problem with bug or possibly engine


  • Please log in to reply
9 replies to this topic

#1 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Location:I wish I knew

Posted 15 September 2020 - 05:28 AM

In building my sand digging script I've ran into a few bugs that I'm having trouble making any sense of. The code compiles fine and work correctly other than these bugs.

 

Engine: 2.55 Alpha 83

 

The code works by checking if Link is using the item "diggingclaws" on the position of a combo running one of the three scripts. The combos are then either changed to 0 (if removed) or to another combo of a sandwall type depending on it's position and neighbors.

 

The problems I'm having other than the script failing to run when a combo is changed, which I have traced to be the engine, are as follows: (from the ZScript Debug Console)

When digging up I get the error after 3 or more triggers: "Combo script 4 (SandWall_Top): Invalid pointer (0) passed to array (don't change the values of your array pointers)" repeating or the game will completely crash.

When digging down I get the error after 3 or more tiggers: "Combo script 3 (SandWall_Base): Invalid position [-1] used to read to 'Screen->ComboT[]'"

When digging to the side I get the error on the first trigger: "Combo script 3 (SandWall_Base): Invalid position [-1] used to read to 'Screen->ComboT[]'" and "Combo script 6 (): Invalid ZASM command 22629 reached" (repeats with various numbers) and "Combo script 6 (): FFSScript::InvalidError - Invalid pointer (91444) passed to array (don't change the values of your array pointers)"

 

 

Uses ffcscript.zh

Spoiler


#2 Emily

Emily

    Scripter / Dev

  • ZC Developers

Posted 17 September 2020 - 10:21 AM

Sounds like you have some bad array accessing happening, which would be a bug in your script.

Wish I could help, but don't have time to debug right now.



#3 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 17 September 2020 - 06:41 PM

Please post the script files.



#4 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Location:I wish I knew

Posted 17 September 2020 - 07:10 PM

Here is a google drive link. I just uploaded the entire project, including all scripts and quest file.

 

https://drive.google...AwE?usp=sharing

 

please note that the invalid ZASM command now occurs on any direction.


Edited by cavthena, 17 September 2020 - 07:12 PM.


#5 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 19 September 2020 - 01:39 AM

Here is a google drive link. I just uploaded the entire project, including all scripts and quest file.

 

https://drive.google...AwE?usp=sharing

 

please note that the invalid ZASM command now occurs on any direction.

 

That google drive link presents me with Access Denied.

 

Just as a note on the script in the OP, you must be very careful with stuff like while(combo) in combodata scripts, as if the combo changes then the script aborts on the next frame. You cannot expect say, a combo script to continue running if you do ++ComboD[n] or otherwise change the combo grid. These scripts only run when the combo has the script attached, and if you change the combo to another ID of any kind, even if it has the same script ID, it will restart as a new script, with a clean/new stack.

 

The instant that you call something like this:

SetLayerComboD(0, position, 0);

 

..on the combo pos running a script, that script dies.

 

None of the arrays or variables from a prior instance of the script carry over, nor will they ever carry over. As soon as you call something like SetLayerComboD, you potentially abort the script and invalidate its arrays. That function is also quasi-deprecated, as are all of the LayerCombo functions, between mapdata and combodata types. They had issues in older versions that could not be fixed without breaking things, and are preserved purely for compatibility.

 

One other thing to note, is that you can call this->Pos(), this->PosX(), and this->PosY(), to get the combo screen grid index, combo screen x corner, and combo screen Y corner, respectively, from combodata scripts.

 

The best option is to script the gloves here. Itemdata scripts can now run for multiple frames.

 

I'm not sure on your ultimate goal here, but you want something more like this:

combodata script SandWall_Fill
{
    void run()
    {
        while(1)
        {
            if(Hero->ItemB == DIGGINGCLAWS && Hero->PressB)
            {
                if ( Abs(Player->X-this->PosX()) <= 8 )
                {
                    if ( Abs(Player->Y-this->PosY()) <= 8 )
                    {
                        
                        ++Screen->ComboD[this->Pos()];
                    }
                }
            }
            Waitframe();
        }
    }
}

There are no code comments, so I do not fully comprehend your intent.

 

In any case, I feel as if you are fundamentally misunderstanding the purpose of combo scripts here. They should be small, simple, and direct. If you want complex interactions that live beyond the scope of a combo on the grid, this is outside their scope and purpose. They exist fundamentally to run only if either (1) the combo running them either never changes, or (2) the combo changes but does not need to continue running its current script.


  • cavthena likes this

#6 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Location:I wish I knew

Posted 19 September 2020 - 01:42 AM

That google drive link presents me with Access Denied.

Ok blasted google. I can try that again. I guess Google needs you to sign into a google account. If that's an issue Ill use some other host.

 

https://drive.google...AwE?usp=sharing

 

The explanation helps. I was not aware that itemdata can now run multiple frames and yes I did expect a little to much from combodata. I want to avoid messy FFC and global setups to get something like this working.


Edited by cavthena, 19 September 2020 - 02:24 AM.


#7 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 19 September 2020 - 04:21 AM

Ok blasted google. I can try that again. I guess Google needs you to sign into a google account. If that's an issue Ill use some other host.

 

https://drive.google...AwE?usp=sharing

 

The explanation helps. I was not aware that itemdata can now run multiple frames and yes I did expect a little to much from combodata. I want to avoid messy FFC and global setups to get something like this working.

 

Not only can itemdata run for multiple frames, but they support Waitdraw, and the engine supports continual scripts on passive items. As this is used by an active item, you can simply use a normal itemdata script. If you used an old tileset or quest, go to ZScript->Quest Script Settings->Scripts, an enable Item Scripts Continue to Run.

 

All script types other than item collect support multiple frames, and collect scripts are on the to do list.

 

The google drive link now works, but you have a lot of timed saves/backups in it and I am low on drive space, so, unless you want me to script it from scratch (request if so), I think that you should examine your methods and re-evaluate how to approach your desired outcome.

 

Passive item scripts (Set Passive Script flag in item editor), run like global scripts. If an item has a script attached and the flag enabled, these run every frame where that item is in the player inventory, until they run out of scope or call Quit.

 

You can also run itemdata scripts ad-hoc with itemdata->RunScript().

 

e.g.

itemdata id = Game->LoadItemData(255);
id->Script = Game->GetItemScript("scriptname"); //Can be arbitrary if desired. Otherwise, runs the script set in the editor.
id->RunScript();

 

There is absolutely no need for hackish methods for items, weapons, or npcs now. Every major sprite type runs its own scripts, and most game objects can run scripts.

 

You can also lookup combos by a label, via Game->GatCombo("name"), and you have a list of flags to use when checking them (requires combodata pointer for access, via combodata->Flags). Further, there are now twenty custom/script combo types and twenty custom/script combo flags, IIRC.

 

All major script types support Waitdraw, should that ever matter.


  • cavthena likes this

#8 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Location:I wish I knew

Posted 19 September 2020 - 08:12 AM

Excellent! I'll have blast with that then.

 

I can script it myself. I should be able to condense it and improve the efficiency now that I have a better understanding.



#9 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Location:I wish I knew

Posted 21 September 2020 - 11:54 PM

I have another question @ZoriaRPG can a combodata pointer be created in another script via finding the combo on the screen based on it's position to grab data contained in a combo?

 

Disregard found it.


Edited by cavthena, 22 September 2020 - 09:22 PM.


#10 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 24 September 2020 - 03:05 AM

I have another question @ZoriaRPG can a combodata pointer be created in another script via finding the combo on the screen based on it's position to grab data contained in a combo?

 

Disregard found it.

 

combodata->Pos* functions only work inside a combodata script for the this-> pointer, if that was what you were asking. there is no logitical way to allow ->Pos(), PosX(), PosY() without the this->, as in a combodata script, the exact information is known as part of the pointer/script linkage.

 

If you mean loading a known position into a pointer, then it's just one of the following

 

combodata cd = Game->LoadComboData(Screen->ComboD[pos]); //Current screen, layer 0.

 

combodata cd = Game->LoadComboData(Game->LoadMapData(map,scr)->ComboD[pos]); //Combos on any internal mapscreen. (Retained until the quest is reloaded).

 

combodata cd = Game->LoadComboData(Game->LoadTempScreen(layer)->ComboD[pos]); //Layers of the current temporary screen (A temporary change to any layer, not retained when the screen reloads).

 

Note: Temporary layer changes are a ZScript feature new to 2.55 that has not been particularly advertised. It is one of the hidden gems of mapdata that makes it far better than SetLayer*** commands, as you can now write temporary changes to layers > 0.

 

combodata cd = Game->LoadComboData(Game->LoadScrollingScreen(layer)->ComboD[pos]); (Only valid during screen transitions).

 

mapdata LoadMapData(int map, int screen);
 * Loads a screen data ref for screen ID 'screen', of Map ID 'map', to a 'mapdata' typed pointer.

mapdata LoadTempScreen(int layer);
 * Loads a screen data ref for the TEMPORARY data of the layer 'layer'.
 * This can be used to make temporary changes to layers of the current screen, which will not
 *     persist upon leaving the screen.
 * NOTE: All changes to this pointer are lost upon changing screens.

mapdata LoadScrollingScreen(int layer);
 * Loads a screen data ref for the TEMPORARY data of the layer 'layer' used for scrolling.
 * During scrolling, this can be used to change things on the screen you are presently scrolling away from.
 * Not during scrolling, this will point to the last screen you scrolled away from.
 * This pointer will include any temporary changes made while you were on the screen.
 * NOTE: All changes to this pointer are lost upon changing screens.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users