PDA

View Full Version : Future ZScript needs to allow NON-CONSTANT globals to be set



Anarchy_Balsac
08-31-2015, 01:47 PM
See topic.

That is VERY annoying.

For the non-programmer types, globals have a TON of advantages over locals. Locals have a small advantage if you want to reuse the name, or a big advantage if you want to have, say, one defined variable track multiple health bars or such. In all other circumstances, globals are more efficient. Some people cry foul that it makes your code "sloppy" or "unreadable", but that's stupid.

Gleeok
08-31-2015, 05:25 PM
ZScript actually does allow global variables and arrays. std.zh just doesn't define any since there is a limit of 256 currently. Also const int is basically the script version of a c #define in case anyone was wondering; can't recall if they obey normal scope rules though.

Anarchy_Balsac
08-31-2015, 05:56 PM
ZScript actually does allow global variables and arrays. std.zh just doesn't define any since there is a limit of 256 currently. Also const int is basically the script version of a c #define in case anyone was wondering; can't recall if they obey normal scope rules though.

IIRC, it was when I tried to set one to a value that I encountered the problem, and it said something about defining non-constant globals.

Tamamo
09-09-2015, 02:38 PM
Is it an int or float?
As far as I know, only those work.

Anarchy_Balsac
09-09-2015, 10:11 PM
TBH, I don't remember at this point. I just remember it was a restriction that I didn't have to deal with in C#.

Tamamo
09-09-2015, 10:39 PM
Here's the deal though a bunch of the types have a scope to one screen. So making a global pointer would cause it to return god only knows what when you change screens. It could be valid or not valid. There's no telling because ZASM is awful. Correct me if I'm wrong here Gleeok.

Gleeok
09-09-2015, 10:51 PM
I would of prefered globals of all types, actually. Error prone? Maybe. Smaller scripts and less typing? Sure.

Anarchy_Balsac
09-09-2015, 11:04 PM
I would of prefered globals of all types, actually. Error prone? Maybe. Smaller scripts and less typing? Sure.

Exactly, besides which programming involves a LOT of trial and Error, and a LOT of bug aversions in the first place. I understand some gamers need their hands held, but by the time you're at the level of an actual programmer, it's just annoying.

Tamamo
09-09-2015, 11:49 PM
Me too Omae, me too. I would make backbeard if i could have global npcs.

Anarchy_Balsac
09-10-2015, 02:28 AM
Me too Omae, me too. I would make backbeard if i could have global npcs.

Backbeard eh? Is that a pirate with a really hairy back?

Tamamo
09-10-2015, 10:22 AM
http://vignette1.wikia.nocookie.net/creepypasta/images/6/69/Backbeard_by_12brainbread-d34g56z.jpg

Digdoggers inspiration.
He chases people and can do all sorts of stuff with his eye. He is basically a DMAP boss rather then a screen boss.

ZoriaRPG
10-14-2015, 03:43 PM
I would of prefered globals of all types, actually. Error prone? Maybe. Smaller scripts and less typing? Sure.


Agreed. Global objects would be ideal. The only way to do this at present, is through cheating via the global active script, which is absolutely horrible, and evil, and...you know.

@ Anarchy_Balsac It would be useful if you posted the exact error that you saw, and the related code. I have never seen an error like that, except when trying to declare a complex object type at a global scope (i.e. ffc, item, npc, weapon).

Before we muck with making all those types possible as global declarations, we need to expand the size of the array that holds the ZASM gd registers, and modify the bytecode to reflect that change. Placing them at the end of a much larger array would work, but you'd need to keep the first 256 where they are, and map the rest elsewhere, for the sake of compatibility.

Anarchy_Balsac
10-14-2015, 04:51 PM
@ Anarchy_Balsac It would be useful if you posted the exact error that you saw, and the related code. I have never seen an error like that, except when trying to declare a complex object type at a global scope (i.e. ffc, item, npc, weapon).

I was so furious when I posted that I didn't even think about it. Too late now though.

ZoriaRPG
10-16-2015, 02:06 AM
I was so furious when I posted that I didn't even think about it. Too late now though.

No chance of recompiling it the way that you had it before?

Here's a little bonus... How to make a global complex object, of sorts.

RPG.zh/RPG_Player_Sprites.zlib


///Player Sprites v1.1 for RPG.zh 0.97.6

//This .zlib creates a weapon sprite, using lweapon Player, that is always above Link, and acts as a stNad-in for his sprite.
//The reason for using a sprite, is that it is animated.

import "std.zh"
int PlayerSprites[3074] = {88}; //Why 3074? It's a merged array. See constants at 136 to 143.

const int OLD_LINK_TILE = 1;
const int ZQ_LAST_TILE = 65519;
const int ZQ_BLANK_TILE = 65518;

const int TILES_BACKUP = 62560;
const int TILES_BLANK = 65000;

const int BASE_TILE = 35620;
const int TILE_LENGTH = 260; //EACH TILE PAGE CONTAINS 259 TILES.

const int ZQ_SPRITE_BLANK = 255;

//Conditional Constants
const int COND_DALEK = 4;
const int SPRITE_DALEK_SAUCER = 0;

//bool IsInvisible;
//bool TilesCopiedInvis;
//bool TilesCopiedVis = true;

//int LastLinkX; //These are no longer needed.
//int LastLinkY;
//bool LinkMoved;
//int PlayerFrameDelay; //These need to be in an array, to match the size of PlayerSprites (512)
//int PlayerFrame;

//int IsInvisible[512]; //Array to hold if Link should be invisible, per DMAP.
//int SpriteAnimFrameDelay[512];
//int SpriteAnimFrames[512];



//Sets the starting frame.
void SetPlayerSpriteFrames(int dmap, int frames){
PlayerSprites[dmap+EW_PLAYER_SPRITE_ANIM] = frames;
}

int GetPlayerSpriteFrames(int dmap){
return PlayerSprites[dmap+EW_PLAYER_SPRITE_ANIM];
}

void IncreasePSF(int dmap){
PlayerSprites[dmap+EW_PLAYER_SPRITE_ANIM]++;
}

void SetPlayerSpriteAnimDelay(int dmap, int delay){
PlayerSprites[dmap+EW_PLAYER_SPRITE_ANIM_DELAY] = delay;
}

int GetPlayerSpriteAnimDelay(int dmap){
return PlayerSprites[dmap+EW_PLAYER_SPRITE_ANIM_DELAY];
}

void SetPlayerSpriteAnimDelayDuration(int dmap, int dur){
PlayerSprites[dmap+EW_PLAYER_TIME_OF_DELAY] = dur;
}

int GetPlayerSpriteAnimDelayDuration(int dmap){
return PlayerSprites[dmap+EW_PLAYER_TIME_OF_DELAY];
}

//Sets the number of frames.
void SetPlayerSpriteNumberOfFrames(int dmap, int frames){
PlayerSprites[dmap+EW_PLAYER_NUMBER_OF_FRAMES] = frames;
}

int GetPlayerSpriteNumberOfFrames(int dmap){
return PlayerSprites[dmap+EW_PLAYER_NUMBER_OF_FRAMES];
}



void IncreasePSAD(int dmap){
PlayerSprites[dmap+EW_PLAYER_SPRITE_ANIM_DELAY]++;
}

void SetIsInvisible(int dmap, bool setting){
int set;
if ( setting ) set = 1;
PlayerSprites[dmap+EW_PLAYER_INVISIBLE] = set;
}

void SetIsInvisible(int dmap, int value){
PlayerSprites[dmap+EW_PLAYER_INVISIBLE] = value;
}

bool GetIsInvisible(int dmap){
bool set = PlayerSprites[dmap+EW_PLAYER_INVISIBLE];
if ( set ) return true;
else return false;
}

//Call in ~Init to set up sprites for each DMAP.
void SetPlayerSpriteOptions(int dmap, int sprite, bool invis, int frames, int delay, int numFrames, int framesDur){
SetPlayerSprite(dmap,sprite);
SetIsInvisible(dmap,invis);
SetPlayerSpriteFrames(dmap,frames);
SetPlayerSpriteAnimDelay(dmap,delay);
SetPlayerSpriteNumberOfFrames(dmap,numFrames);
SetPlayerSpriteAnimDelayDuration(dmap,framesDur);
}

global script Init{
void run(){
Link->Invisible = true;
SetPlayerSpriteOptions(0,88,true,0,0,6,10);
}
}

void PlayerTilesCopied(int setting){
PlayerSprites[SPRITES_COPIED] = setting;
}

int PlayerTilesCopied(){
return PlayerSprites[SPRITES_COPIED];
}

void PlayerTilesRestored(int setting){
PlayerSprites[SPRITES_RESTORED] = setting;
}

int PlayerTilesRestored(){
return PlayerSprites[SPRITES_RESTORED];
}

//condense these all into one array, and then use these constants:

const int EW_PLAYER_SPRITE = 0;
const int EW_PLAYER_INVISIBLE = 512;
const int EW_PLAYER_SPRITE_ANIM = 1024;
const int EW_PLAYER_SPRITE_ANIM_DELAY = 1536;
const int EW_PLAYER_NUMBER_OF_FRAMES = 2048;
const int EW_PLAYER_TIME_OF_DELAY = 2560;
const int SPRITES_COPIED = 3072;
const int SPRITES_RESTORED = 3073;

const int INVIS_NOT_COPIED = 1;
const int INVIS_COPIED = 2;
const int VIS_NOT_COPIED = 3;
const int VIS_COPIED = 0;



global script active{
void run(){
SetPlayerSpriteOptions(0,88,true,0,0,6,10);
Link->Invisible = true;
int SpriteLink[512]={88}; //Populate with the sprite for Link, based on the DMAP.
int LinkTile;
int curDMAP;
while ( true ) {
//Trace(Link->Tile);
if ( Game->GetCurDMap() != curDMAP ) curDMAP = Game->GetCurDMap();
if ( Link->PressEx1 ) {
if ( !GetIsInvisible( Game->GetCurDMap() ) ) {
SetIsInvisible(Game->GetCurDMap(),true);
}
else SetIsInvisible(Game->GetCurDMap(),false);
}

//if ( Link->X == LastLinkX && Link->Y == LastLinkY ) LinkMoved = false;
//if ( Link->X != LastLinkX || Link->Y != LastLinkY ) {
// LastLinkY = Link->Y;
// LastLinkX = Link->X;
// LinkMoved = true;
//}
//PlayerFrameDelay++;
PlayerSprites[curDMAP+EW_PLAYER_SPRITE_ANIM_DELAY]++;

if ( PlayerSprites[curDMAP+EW_PLAYER_SPRITE_ANIM_DELAY] >= PlayerSprites[curDMAP+EW_PLAYER_TIME_OF_DELAY] ) {
PlayerSprites[curDMAP+EW_PLAYER_SPRITE_ANIM]++;
PlayerSprites[curDMAP+EW_PLAYER_SPRITE_ANIM_DELAY] = 0;

}
if ( PlayerSprites[curDMAP+EW_PLAYER_SPRITE_ANIM] >= PlayerSprites[curDMAP+EW_PLAYER_NUMBER_OF_FRAMES] ) PlayerSprites[curDMAP+EW_PLAYER_SPRITE_ANIM] = 0;


if ( GetIsInvisible( Game->GetCurDMap() ) && !PlayerTilesCopied() ) {
for ( int q = 0; q < TILE_LENGTH; q++ ) {
CopyTile(BASE_TILE+q, TILES_BACKUP+q);
CopyTile(TILES_BLANK+q, BASE_TILE+q);
}
PlayerTilesCopied(1);
PlayerTilesRestored(0);
}

if ( !GetIsInvisible(Game->GetCurDMap() ) && !PlayerTilesRestored() ) {
for ( int q = 0; q < TILE_LENGTH; q++ ) {
CopyTile(TILES_BACKUP+q, BASE_TILE+q);
}
PlayerTilesCopied(0);
PlayerTilesRestored(1);
}


LinkTile = Link->Tile;
//if ( IsInvisible && !TilesCopiedInvis && TilesCopiedVis ) {
// TilesCopiedVis = false;
// TilesCopiedInvis = true;
// for ( int q = 0; q < TILE_LENGTH; q++ ) {
// CopyTile(BASE_TILE+q, TILES_BACKUP+q);
// CopyTile(TILES_BLANK+q, BASE_TILE+q);
// }
//
//}
//if ( !IsInvisible && TilesCopiedInvis && !TilesCopiedVis ) {
// TilesCopiedInvis = false;
// TilesCopiedVis = true;
//
// int S_Rest[]="Restoring Tiles";
// TraceS(S_Rest);
// for ( int q = 0; q < TILE_LENGTH; q++ ) {
// CopyTile(TILES_BACKUP+q, BASE_TILE+q);
// //CopyTile(TILES_BLANK+q, TILES_BACKUP+q);
// }


//}

//if ( Link->Tile != ZQ_BLANK_TILE ) {
// CopyTile(LinkTile,ZQ_LAST_TILE);
// CopyTile(ZQ_BLANK_TILE,LinkTile);
//}
eweapon PlayerSprite = Screen->CreateEWeapon(EW_SCRIPT10);
PlayerSprite->X = Link->X;
PlayerSprite->Y = Link->Y;
PlayerSprite->CollDetection = false;
PlayerSprite->Dir = Link->Dir;
PlayerSprite->Flip = Link->Flip;
PlayerSprite->Frame = PlayerSprites[curDMAP+EW_PLAYER_SPRITE_ANIM];

int player_sprite;
if ( PlayerSprites[curDMAP] == 0 ) player_sprite = ZQ_SPRITE_BLANK;
else player_sprite = PlayerSprites[curDMAP];
PlayerSprite->UseSprite(player_sprite);
Waitdraw();
//if ( LinkMoved)
PlayerSprite->DeadState = WDS_DEAD;
//PlayerSprite(PlayerSprite,SpriteLink);
Waitframe();
}
}
void PlayerSprite(int SpriteLink, int sprite){
SpriteLink[0] = sprite;
}

}

void SetPlayerSprite(int dmap, int sprite){
PlayerSprites[dmap] = sprite;
}

item script PlayerSprites{
void run(int SpriteLink){
//PlayerSprites[0]=Rand(1,50);
//if ( !IsInvisible ) {
// IsInvisible = true;
//}
//else IsInvisible = false;

}
}


//Link->Invisible = true; //Set Link to be invisible.



//This cannot be imported. The functions must be made local (in scope) to the global active script, for the pointers to work.
void PlayerSprite(int condition){ //Condition should be tied to one index of GameDynamics, and called as:
// PlayerSprite(Val(PLAYER_SPRITE));
if ( Player->Collision ) {
Player->Collision = false; //Turn collision off go
}
if ( Player->X != Link->X ){ //Mirror Link's position, and direction.
Player->X = Link->X;
}
if ( Player->X != Link->Y ){
Player->X = Link->Y;
}
if ( Player->X != Link->Z ){
Player->X = Link->Z;
}
if ( Player->X != Link->Dir ){
Player->X = Link->Dir;
}
if ( Player->X != Link->Flip ){
Player->X = Link->Flip;
}
if ( ! UseSprite( Val(PLAYER_SPRITE) ) ){
Player->UseSprite(Val(PLAYER_SPRITE));
}
}

void ChangePlayerSprite(int sprite){
Val(PLAYER_SPRITE,sprite);
}

void SetSpriteCondition(int condition){
if ( COND_DALEK ) {
ChangePlayerSprite(SPRITE_DALEK_SAUCER);
}
//else if
}

const int BACKUP_LINK_TILES = 32000; //First tile for backup tiles.

void WriteLinkTile(int firstTile){
//rEADS PRESENT TILE USED BY lINK
//Uses CopyTile to make backup of original tile to specified location
//Then copies specied tile to Tile used by Link
//effectivel changing Link->Tile
}

int LinkTileOnExit[256]; //Store Link tiles on exit in array.



You can do this with weapons, and ffcs. It'd also work with npcs, but I'm not certain if there's a point to that.