Jump to content

Photo

ghost.zh


  • Please log in to reply
645 replies to this topic

#631 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 15 July 2019 - 10:16 AM

tempGhostData is created just before it's assigned, at the beginning of Ghost_WaitframeLight(), and the pointer is cleared at the end of that function. The array only exists until the script resumes in the next frame; Set and GetEnemyProperty() are meant to be called from other scripts during that time.

It's a bit complicated, but there's nothing out of the ordinary going on there. As long as array pointers are still integers, it should be fine as long as they're not greater than 65535.


Ah-ha.

Moosh filed a report, bringing it to my attention, and when I tried using it within a ghost script to test the issue, I could easily replicate it.

Essentially, it doesn't have proper access to the pointer that it is trying to use, if called at the wrong time, and it floods the log with invalid array errors.

The behaviour is still spotty. If it's only intended to be used after the array generated by ghost_waitframe is called, that's fine-enough.

I think it breaks when a script with a higher priority than the ghosted ffc enemy that you are trying to affect calls it, as at that time the array pointer isn't established.


I sanity guarded it as follows:
 

void SetEnemyProperty(npc enemy, int property, float newValue)
{
	//LogPrint("Setting ghost property: %d\n", property);
	
	if((enemy->Misc[__GHI_NPC_DATA]&0x10000)!=0)
	{
		float ptr=enemy->Misc[__GHI_NPC_DATA]&0xFFFF;
		//LogPrint("ptr is: %f \n", ptr);
		
		if ( ptr > 0 )
		{
			//LogPrint("ptr size is: %f \n", SizeOfArray(ptr));
			if ( SizeOfArray(ptr) == 24 )
			{
				//TraceS("SET Pointer validated.\n");
				ptr[property]=newValue;
			}
		}
		//else TraceS("SET Pointer not validated.\n");
	}
	
	switch(property)
	{
		case ENPROP_X: enemy->X=newValue; return;
		case ENPROP_Y: enemy->Y=newValue; return;
		case ENPROP_Z:  enemy->Z=newValue; return;
		case ENPROP_JUMP: enemy->Jump=newValue; return;
		case ENPROP_DIR: enemy->Dir=newValue; return;
		case ENPROP_HP: enemy->HP=newValue; return;
		default: enemy->CSet=newValue; return;
	}
}

float GetEnemyProperty(npc enemy, int property)
{
	if((enemy->Misc[__GHI_NPC_DATA]&0x10000)!=0)
	{
		float ptr=enemy->Misc[__GHI_NPC_DATA]&0xFFFF;
		//LogPrint("ptr is: %f \n", ptr);
			
		if ( ptr > 0 )
		{
			//LogPrint("ptr size is: %f \n", SizeOfArray(ptr));
			if ( SizeOfArray(ptr) == 24 )
			{
				return ptr[property];
			}
		}
	
		else
		{
			//TraceS("GET Pointer not validated.\n");
			switch(property)
			{
				case ENPROP_X: return enemy->X;
				case ENPROP_Y: return enemy->Y;
				case ENPROP_Z: return enemy->Z;
				case ENPROP_JUMP: return enemy->Jump;
				case ENPROP_DIR: return enemy->Dir;
				case ENPROP_HP: return enemy->HP;
				default: return enemy->CSet;
				
			}
		}
	}
    
	else
	{
		switch(property)
		{
			case ENPROP_X: return enemy->X;
			case ENPROP_Y: return enemy->Y;
			case ENPROP_Z: return enemy->Z;
			case ENPROP_JUMP: return enemy->Jump;
			case ENPROP_DIR: return enemy->Dir;
			case ENPROP_HP: return enemy->HP;
			default: return enemy->CSet;
			
		}
	}
}
I used switch-case here purely for efficiency. I was thinking of going in and making the whole header more efficient in 2.55 (ZASM output), but this same if statements would work in 2.50.x, to verify the array pointer, prior to trying to access it.

#632 Saffith

Saffith

    IPv7 user

  • ZC Developers

Posted 15 July 2019 - 11:02 AM

It already does that. That's what if((enemy->Misc[__GHI_NPC_DATA]&0x10000)!=0) is for. But I do see how an invalid access might be possible; AutoGhost() sets enemy->Misc[__GHI_NPC_DATA] to 1 briefly so it's nonzero without being marked as in use. I'll see about fixing that.

Edit: Wait, no it doesn't. Apparently, I forgot how numbers work. Well, I'll deal with that, then.

#633 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 16 July 2019 - 10:32 AM

It already does that. That's what if((enemy->Misc[__GHI_NPC_DATA]&0x10000)!=0) is for. But I do see how an invalid access might be possible; AutoGhost() sets enemy->Misc[__GHI_NPC_DATA] to 1 briefly so it's nonzero without being marked as in use. I'll see about fixing that.

Edit: Wait, no it doesn't. Apparently, I forgot how numbers work. Well, I'll deal with that, then.

 

In some of my tests, the value of that Misc index was -1. I'm not too familiar with the internals of ghost.zh, but I found this quite off. This bypassed the nonzero check, too. It seems that you went only with ptr>0, which still doesn't validate that the value is an actual array. (SizeOfArray() does, however ensure that it is an array. I should probably add an internal IsValidArray() at some point.)

 

Anyway, see my comments on the header in the database.



#634 Saffith

Saffith

    IPv7 user

  • ZC Developers

Posted 16 July 2019 - 01:23 PM

In some of my tests, the value of that Misc index was -1. I'm not too familiar with the internals of ghost.zh, but I found this quite off.

There's nothing that should ever set it to a negative number. Where did you see that happen? Are you sure it wasn't done by some other script?
 

SizeOfArray() does, however ensure that it is an array.

But in 2.50, at least, it also logs an error if it's not. That's not something a validation function should do.

#635 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 17 July 2019 - 04:42 AM

There's nothing that should ever set it to a negative number. Where did you see that happen? Are you sure it wasn't done by some other script?
 
But in 2.50, at least, it also logs an error if it's not. That's not something a validation function should do.

 
I had a series of test scripts that were setting it, and indeed, it was from another script. Moosh was trying to do thst, and it probably was never meant to work that way.
 
Ah, yes, it'll log the same array pointer issue, at ArrayH::getArray(), because of this block:
 
 
 else
        {
            if(localRAM[ptr].Size() == 0)
                return InvalidError(ptr);
 
I'm going to need to add isValidArray(untyped ptr) at some point.

How do you feel about making github repos for the ghost and tango headers? If you have archives of the different versions, I'd be willing to set it up so that each version has a commit range, and so that it'd be possible to compare against versions as I have done with ZC and std.zh.

#636 Saffith

Saffith

    IPv7 user

  • ZC Developers

Posted 17 July 2019 - 12:48 PM

Other than fixing bugs, I'm done with them. If you want to make repos and keep working on them, go ahead. I do still have most of the older versions.
I'll be glad to send you the documentation sources, too, though there are bits of Tango's I was rewriting for the HTML version, and I'd still like to get that done first.

#637 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 18 July 2019 - 09:21 AM

Other than fixing bugs, I'm done with them. If you want to make repos and keep working on them, go ahead. I do still have most of the older versions.
I'll be glad to send you the documentation sources, too, though there are bits of Tango's I was rewriting for the HTML version, and I'd still like to get that done first.


Sure. Please ZIP up the different versions, as many as you have, and put them up somewhere.

HTML version of Tango?

#638 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 15 January 2020 - 07:45 AM

Note to All Users

 

he entire AGN dev team are now tasked with support and future releases of this header. We'll do our best, and if you have any requests, complaints, or suggestions, feel free to post them.

 

The current version of Ghost.zh is always here, alongside a full archive of historic versions, should you require them. Only the current version has full tech support..



#639 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 27 January 2020 - 12:40 AM

If you use EWM_Throw in sideview, ghost kills the weapon as soon as it exceeds its initial Y position.
 
Makeshift fix in the meantime is to set wpn->Misc[__EWI_WORK_2] to 176-wpn->Y on the first frame, and wpn->Y 176-wpn->Misc[__EWI_WORK_2] on every subsequent frame.

 
This may now be fixed [Ghost.zh v2.8.12]. This version is ready for testing. Please report any issues using it or compatibility issues with legacy scripts, and with legacy quests.

 

Ghost.zh Roadmap

2.8.13->2.8.x

  1. Use #include, not import, except in legacy header file. Support for thisfile may end before 2.9.0 and is guaranteed to end at 2.9.0.
  2. Bugfixes, as needed.
  3. Integrate functions from 'hacked' versions of Ghost.zh as needed, so that all users can upgrade to the current version without quest compatibility issues.
  4. Optimise as much as possible (optimal ZASM generation). In general, remove any checks such as:
if ( var != 0)

This will become:

if(var)

That saves opcodes and speeds up interpretation.

 

 

2.9.x

This will absolutely require ZC 2.53.1 (planned for Gamma+), as it will use a new command (IsValidArray(*ptr)) that we added to this version to validate array authenticity whenever the ZS uses arrays passed by reference. This function is better than if (arr>0) as it actually determines if a value passed as a pointer is valid and allocated.

e.g.

void foo(int ptr)
{
    if(ptr>0) ptr[3] = 6;
}
 
int A = 2;
foo(A);

That would still be an invalid array, but the function would not catch it.

 

v
void foo(int ptr)
{
    if(IsValidArray(ptr)) ptr[3] = 6;
}
 
int A = 2;
foo(A);

This would know that A is not an array.

Hence, the 2.9 version bump. per semver.org specs.

 

We'll also be optimising logical conjunctive statements so that they manually short-circuit, as well as cleaning up tabbing and spacing (in expressions and in statements) to be wholly uniform and following the C++ style standard.
 

 

3.0.x

A major rewrite for npc scripts and eweapon scripts for 2.55.x.

 

This will not use global pointers or variables, so you will be able to export .ZASM scripts and files such as.znpc to allow any user to immediately integrate an enemy into a quest with minimal fuss.

 

The 3.x.x spec will change the interface quite a bit, and while it will remain comprehensible to current users of Ghost.zh, it will not be directly compatible. We may provide a legacy layer, but Ghost.zh 2.xx will continue to receive support at least until the end of the LTS lifespan on 2.53.x (17th April, 2023) for those who need it.



#640 SparksTheUnicorn

SparksTheUnicorn

    Lonk, Hero of Lime

  • Members

Posted 03 June 2020 - 02:29 PM

Small question, do I have to have all scripted lweapons set to LW_GHOSTED. I ask because I have a wand where the melee attack and the magic should use different defenses, and I don't want them to use the magic or wand melee defense. The readme file says I can use the function UseThisDefense or something like that, but that if I do I should make sure to not having any other working lweapons of the same type.



#641 Mitchfork

Mitchfork

    no fun. not ever.

  • Contributors
  • Real Name:Mitch
  • Location:Alabama

Posted 21 November 2020 - 12:28 AM

I found a minor bug in ghost.zh.

 

In the ghost.zh DrawGhostFFCs() function, ghost will check if the screen flag "Layer 2 is Background" is checked to determine what layer to draw enemies on.  This does not check the DMap flag "Layer 2 is Background on All Screens", meaning that you can get unexpected invisible enemies.

 

Also, the latest version of ghost is not bundled with the newest 2.55 versions - I think it's on 2.8.5.



#642 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 21 November 2020 - 06:57 AM

I found a minor bug in ghost.zh.

 

In the ghost.zh DrawGhostFFCs() function, ghost will check if the screen flag "Layer 2 is Background" is checked to determine what layer to draw enemies on.  This does not check the DMap flag "Layer 2 is Background on All Screens", meaning that you can get unexpected invisible enemies.

 

Also, the latest version of ghost is not bundled with the newest 2.55 versions - I think it's on 2.8.5.

 

 

Thank you. I will build a BG layer check function into the next versions of <std 1.5> and <std 1.7> , for 2.53.1, and 2.55.0 respectively, and update <ghost 2.8>  to call the function from the <std> library, instead of using a hardcoded check.

 

The latest <ghost> should be included in the A85 package. I show version 2.8.15 in the ./headers path of the ZIP.



#643 Mitchfork

Mitchfork

    no fun. not ever.

  • Contributors
  • Real Name:Mitch
  • Location:Alabama

Posted 21 November 2020 - 09:14 AM

Thank you. I will build a BG layer check function into the next versions of <std 1.5> and <std 1.7> , for 2.53.1, and 2.55.0 respectively, and update <ghost 2.8>  to call the function from the <std> library, instead of using a hardcoded check.

 

The latest <ghost> should be included in the A85 package. I show version 2.8.15 in the ./headers path of the ZIP.

 

That's a good addition - there are definitely uses in my own code for those functions to draw shadows and such.

 

Actually, it's just that ghost.zh bundles in two changelogs.  One is "ghostZHchangelog" and shows the version up to 2.8.12.  The other is just "changelog" and only shows up to 2.8.5. - that's what I was basing that comment on.  The actual ghost code may be fully updated - I trust it if you checked it.


Edited by Mitchfork, 21 November 2020 - 09:18 AM.


#644 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 22 November 2020 - 07:27 AM

That's a good addition - there are definitely uses in my own code for those functions to draw shadows and such.

 

Actually, it's just that ghost.zh bundles in two changelogs.  One is "ghostZHchangelog" and shows the version up to 2.8.12.  The other is just "changelog" and only shows up to 2.8.5. - that's what I was basing that comment on.  The actual ghost code may be fully updated - I trust it if you checked it.

 

Oh, lovely, the logfiles are out of date., I will attend to that when I address the issues in both editions of <std>, as ghost also needs an update to use the new functions, so it'll be in the next patch set. Ghost v2.9 and v3.0 are both a WIP, with 2.9 being the 2.xx version exclusive for 2.55, and 3.0 a rework of the entire thing to use npc scripts

 

Here is the change history for 2.8.15:

 

https://github.com/A.../commits/2.8.15



#645 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 05 December 2020 - 10:52 AM

Minor update: dmapdata->Flags cannot access the right bit with 32b off. I can fix this in one of a few ways, but I think that we need dmapdata->Flags[] as an array instead of as an integer. 




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users