Jump to content

Photo

2.54 scripting questions


  • Please log in to reply
7 replies to this topic

#1 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 20 June 2018 - 01:09 AM

So, I was looking through the ZC changelog, and I saw that there is ZScript data now for DMap data, such as the palette, level number, and so on. Can this data be written to on the fly, now? I've wanted to do a day/night thing for a while, but I didn't like the idea of having to change DMaps with timed warps, because of the whole enemy respawning thing, and using translucent layers never seems to work out right unless you change the underlying palette, too. So, yeah, does this mean smooth, bug-free day/night cycles are now a thing? Yes, I know I'm way out of the loop. School's been a nightmare.



#2 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 20 June 2018 - 01:50 AM

So, I was looking through the ZC changelog, and I saw that there is ZScript data now for DMap data, such as the palette, level number, and so on. Can this data be written to on the fly, now? I've wanted to do a day/night thing for a while, but I didn't like the idea of having to change DMaps with timed warps, because of the whole enemy respawning thing, and using translucent layers never seems to work out right unless you change the underlying palette, too. So, yeah, does this mean smooth, bug-free day/night cycles are now a thing? Yes, I know I'm way out of the loop. School's been a nightmare.

 

You can instantly flip dmap palettes with Game->DMapPalette[id] = pal; IDR if the dmapdata palette var does this, but if not, I'll fix it.


  • Binx likes this

#3 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 20 June 2018 - 02:27 AM

Awesome. I'm gonna see if I can whip up a working script, tonight. Gonna have to run through documentation to remember how to call the current DMap id number directly and fix my temporary pseudocode, but then I should have something workable. Still gonna need that layer for the nighttime effects, so the constant-palette objects don't stand out, but I can do that, just fine.

Er... how do I check for the DMap's type (overworld, interior, etc)?
 
Also, DMap palette numbers, is it just a straight conversion from hexadecimal, or are all main, sprite and level palettes in one index?
 
One more thing, cuz I'm running into a small math error, trying to tie the system to Game->Time: is there a way to force the system to round a number down to the nearest lower integer? So, for example, 1.9999 would be counted as 1. Game->Time returns an int in frames, 60fps, so 216,000 = 1 hour. I'm trying for 12-minute, or 43,200-frame, "days" This is what I've got:
int DAYNUMBER = (43200 + (Game->Time * 0.2))/43200;
The problem is that most of the time this is going to return a decimal value, not an integer, but I can't have the system rounding up once it gets past .5, and later math depends on this returning a whole number value.

Everything I have so far:

 

const int SUNRISE = 1;
const int DAY = 0;
const int SUNSET = 2;
const int NIGHT = 3;
const int DAY_PAL = 0;
const int SUNRISET_PAL = 32;
const int NIGHT_PAL = 33;
const int NIGHT_OVERLAY_LAYER = 6;

int DAYNUMBER = (Game->Time * 0.2 - CURRENT_TIME) / 43200;
int CURRENT_TIME = Game->Time *0.2 - 43200 * DAYNUMBER;
int CYCLE = 0;
int CURRENTDMAP = Game->GetCurDMap();

//if Game->GetCurDMapType(CURRENTDMAP)=overworld //Uncomment this when it's not pseudocode
if (CURRENT_TIME >= 0) && CURRENT_TIME < 21600))
{
    CYCLE = DAY;
    Game->DMapPalette[CURRENTDMAP] = DAY_PAL;
}
else if (CURRENT_TIME >= 21600) && CURRENT_TIME < 23400))
{
    CYCLE = SUNSET;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}
else if (CURRENT_TIME >= 23400) && CURRENT_TIME < 41400))
{
    CYCLE = NIGHT;
    Game->DMapPalette[CURRENTDMAP] = NIGHT_PAL;
}
else if (CURRENT_TIME >= 41400) && CURRENT_TIME <= 43199))
{
    CYCLE = SUNRISE;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}

Wait... No, my math is still off... EDITED, but I think it's still wrong.

Ok, so I figured out these three formulas, and I think I did them right, but I can't figure out how to remove CURRENT_TIME from the DAYNUMBER formula so that CURRENT_TIME can actually be calculated.
Game->Time = CURRENT_TIME + 43200 * DAYNUMBER
DAYNUMBER = (Game->Time * 0.2 - CURRENT_TIME) / 43200
CURRENT_TIME = Game->Time *0.2 - 43200 * DAYNUMBER


Edited by Binx, 20 June 2018 - 04:37 AM.


#4 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 20 June 2018 - 04:25 PM

Question: Would changing large numbers of combos onscreen periodically cause a massive slowdown in ZC? Was debating, for an added bit of polish, redoing all of the environment tiles in two additional light angles (the light angle and shadows on all Koten tiles comes from the upper-left, so I'd be adding versions that have it in the upper middle, and upper right), then expanding the script so that, depending on the time of "day", it may replace combos using those times with ones from a different angle (e.g. in the morning, from about 6:00 AM til 11:00 AM, the combos will remain untouched, light in the upper-left, shadows in the bottom right; from 11:00 AM until 2:00 PM, the environment tiles will change so that the light area is the top-center, and the shadows are minimal, mostly seeming to be behind the tree and at the bottom, then from 2:00 PM until 8:00 PM the combos will be "flipped"- in reality, replaced with separate combos because flipping 2x2 combos results in messed up trees- so that the shadows are in the lower-left and the light is in the upper-right). then I can just shift the palette for CSet 3, rather than replacing mountain tiles. Anyways, doing this, assuming it won't reduce the framerate to 1, would give the impression that the sun is moving across the sky during the day.

NOTE: In order to do this, I'd probably need to remove shading from all character and NPC sprites, because, otherwise, the lighting of the sprite won't match the background.



#5 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 20 June 2018 - 10:34 PM

Okay, I got it to compile, and... It bricks the game. Freezes everything except music. I used a snippet of Zoria's game clock code function as a model for building mine, and there shouldn't be any real difference, other than I'm using counters, instead of a custom array (for testing purposes, primarily. I mean, it does use like 5 counters, that'd probably be much better in an array, but I'm just trying to get the damned thing to work, first.)
 
Anywho, here's my code (EDITED which fixed the freezing. But now it's not changing from night):

import "std.zh"
import "ffcscript.zh"
import "string.zh"


const int SUNRISE = 1;
const int DAY = 0;
const int SUNSET = 2;
const int NIGHT = 3;
const int DAY_PAL = 0;
const int SUNRISET_PAL = 32;
const int NIGHT_PAL = 33;
const int NIGHT_OVERLAY_LAYER = 6;
const int CR_FRAMES = 31;
const int CR_SECONDS = 30;
const int CR_MINUTES = 29;
const int CR_HOURS = 28;
const int CR_DAYS = 27;
int CYCLE = 0;
int CURRENTDMAP = 0;

global script slot2
{
void run()
{
    while (true)
{
    CURRENTDMAP = Game->GetCurDMap();
    Game->Counter[CR_FRAMES] +=1;
    if ( Game->Time == 0)
    {
        Game->Counter[CR_HOURS] = 7;
    }
    if ( Game->Counter[CR_FRAMES] == 5 ) 
    {
        Game->Counter[CR_FRAMES] = 0;
        Game->Counter[CR_SECONDS] +=1;
    }
    if ( Game->Counter[CR_SECONDS] == 60 ) 
    {
        Game->Counter[CR_SECONDS] = 0;
        Game->Counter[CR_MINUTES] +=1;
    }
    if ( Game->Counter[CR_MINUTES] == 60 ) 
    {
        Game->Counter[CR_MINUTES] = 0;
        Game->Counter[CR_HOURS] +=1;
    }
    if ( Game->Counter[CR_HOURS] == 24 ) 
    {
        Game->Counter[CR_HOURS] = 0;
        Game->Counter[CR_DAYS] +=1;
    }


if ((Game->Counter[CR_HOURS] >= 0) && (Game->Counter[CR_HOURS] < 6))
{
    CYCLE = NIGHT;
    Game->DMapPalette[CURRENTDMAP] = NIGHT_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 6) && (Game->Counter[CR_HOURS] <= 7))
{
    CYCLE = SUNRISE;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 7) && (Game->Counter[CR_HOURS] < 19))
{
    CYCLE = DAY;
    Game->DMapPalette[CURRENTDMAP] = DAY_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 19) && (Game->Counter[CR_HOURS] < 20))
{
    CYCLE = SUNSET;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 20) && (Game->Counter[CR_HOURS] < 24))
{
    CYCLE = NIGHT;
    Game->DMapPalette[CURRENTDMAP] = NIGHT_PAL;
}

Waitframe();
}
}
}

Edited by Binx, 21 June 2018 - 01:42 AM.


#6 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 21 June 2018 - 02:39 AM

import "std.zh"
import "ffcscript.zh"
import "string.zh"


const int SUNRISE = 1;
const int DAY = 0;
const int SUNSET = 2;
const int NIGHT = 3;
const int DAY_PAL = 0;
const int SUNRISET_PAL = 32;
const int NIGHT_PAL = 33;
const int NIGHT_OVERLAY_LAYER = 6;
const int CR_FRAMES = 31;
const int CR_SECONDS = 30;
const int CR_MINUTES = 29;
const int CR_HOURS = 28;
const int CR_DAYS = 27;
int CYCLE = 0;
int CURRENTDMAP = 0;

global script slot2
{
void run()
{
    while (true)
    {
    CURRENTDMAP = Game->GetCurDMap();
    Game->Counter[CR_FRAMES] +=1;
    if ( Game->Counter[CR_FRAMES] == 1 ) 
    {
        Game->Counter[CR_FRAMES] = 0;
        Game->Counter[CR_SECONDS] +=2;
    }
    if ( Game->Counter[CR_SECONDS] == 60 ) 
    {
        Game->Counter[CR_SECONDS] = 0;
        Game->Counter[CR_MINUTES] +=1;
    }
    if ( Game->Counter[CR_MINUTES] == 60 ) 
    {
        Game->Counter[CR_MINUTES] = 0;
        Game->Counter[CR_HOURS] +=1;
    }
    if ( Game->Counter[CR_HOURS] == 24 ) 
    {
        Game->Counter[CR_HOURS] = 0;
        Game->Counter[CR_DAYS] +=1;
    }


if ((Game->Counter[CR_HOURS] >= 0) && (Game->Counter[CR_HOURS] < 6))
{
    CYCLE = NIGHT;
    Game->DMapPalette[CURRENTDMAP] = NIGHT_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 6) && (Game->Counter[CR_HOURS] < 7))
{
    CYCLE = SUNRISE;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 7) && (Game->Counter[CR_HOURS] < 19))
{
    CYCLE = DAY;
    Game->DMapPalette[CURRENTDMAP] = DAY_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 19) && (Game->Counter[CR_HOURS] < 20))
{
    CYCLE = SUNSET;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}
else if ((Game->Counter[CR_HOURS] >= 20) && (Game->Counter[CR_HOURS] < 24))
{
    CYCLE = NIGHT;
    Game->DMapPalette[CURRENTDMAP] = NIGHT_PAL;
}

Waitframe();
}
}
}

Functional version. This one works, I just need to clean it up, convert the counters to an array, and add a check for DMap type and level, so it doesn't mess around with dungeons and caves.



#7 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 21 June 2018 - 02:39 AM

Awesome. I'm gonna see if I can whip up a working script, tonight. Gonna have to run through documentation to remember how to call the current DMap id number directly and fix my temporary pseudocode, but then I should have something workable. Still gonna need that layer for the nighttime effects, so the constant-palette objects don't stand out, but I can do that, just fine.

Er... how do I check for the DMap's type (overworld, interior, etc)?


It should be this:


dmapdata dm = Game->LoadDMapData(Game->GetCurDMap()); 
int dmap_type = dm-Type;
 

Also, DMap palette numbers, is it just a straight conversion from hexadecimal, or are all main, sprite and level palettes in one index?


It's the number of the palette in the Level Palette Editor.

You may also want to look at mapdata->Layer*[] qand Screen->Layer*[].

One more thing, cuz I'm running into a small math error, trying to tie txt's not pseudocode

[...]

Wait... No, my math is still off... EDITED, but I think it's still wrong.

Ok, so I figured out these three formulas, and I think I did them right, but I can't figure out how to remove CURRENT_TIME from the DAYNUMBER formula so that CURRENT_TIME can actually be calculated.
[...]


Try this, with the time system that I provied.

void DoDayNightPalette()
{
	if ( Time[TIME_HOUR] <= 5 ) 
	{
		CYCLE = SUNRISE;
		Game->DMapPalette[Game->GetCurDMap()] = SUNRISE_PAL;
		return;
	}
	else if (  Time[TIME_HOUR] <= 11 )
	{
		CYCLE = DAY;
		Game->DMapPalette[Game->GetCurDMap()] = DAY_PAL;
		return;
	}
	else if (  Time[TIME_HOUR] <= 17 )
	{
		CYCLE = SUNSET;
		Game->DMapPalette[Game->GetCurDMap()] = SUNRISET_PAL;
		return;
	}
	else
	{
		CYCLE = NIGHT;
		Game->DMapPalette[Game->GetCurDMap()] = NIGHT_PAL;
		return;
	}
}


#8 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 21 June 2018 - 03:22 PM

Ok, so I looked at everything you provided me (thank you very much, btw) and now I've got this:

import "std.zh"
import "string.zh"


const int SUNRISE = 1;
const int DAY = 0;
const int SUNSET = 2;
const int NIGHT = 3;
const int DAY_PAL = 0;
const int SUNRISET_PAL = 32;
const int NIGHT_PAL = 33;
const int NIGHT_OVERLAY_LAYER = 6;
const int CLOCK_SECONDS = 0;
const int CR_SECONDS = 30;
const int CLOCK_MINUTES = 1;
const int CR_MINUTES = 29;
const int CLOCK_HOURS = 2;
const int CR_HOURS = 28;
const int CLOCK_DAYS = 3;
const int CLOCK_MAX = 4;
const int DMT_INTERIOR = 2;
const int DMT_DUNGEON = 0;
int InGameClock[4]={-1, 0, 0, 1};
int CYCLE = 0;
int CURRENTDMAP = 0;


global script slot2
{
void run()
{
    while (true)
    {
    Game->Counter[CR_SECONDS] = InGameClock[CLOCK_SECONDS];
    Game->Counter[CR_MINUTES] = InGameClock[CLOCK_MINUTES];
    Game->Counter[CR_HOURS] = InGameClock[CLOCK_HOURS];
    CURRENTDMAP = Game->GetCurDMap();   
    InGameClock();
    DayNightCycle();
    Waitframe();
}
}
}

void DayNightCycle()
{
    dmapdata dm = Game->LoadDMapData(Game->GetCurDMap());
    int type = dm->Type; TraceNL(); TraceS("Detected DMap Type: "); Trace(type); 
    
if ( type == DMT_INTERIOR )
    {
        return;
    }
if ( type == DMT_DUNGEON )
    {
        return;
    } 
else
    {
if ((InGameClock[CLOCK_HOURS] >= 6) && (InGameClock[CLOCK_HOURS] < 7) && (CYCLE != SUNRISE))
{
    CYCLE = SUNRISE;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}
else if ((InGameClock[CLOCK_HOURS] >= 7) && (InGameClock[CLOCK_HOURS] < 19) && (CYCLE != DAY))
{
    CYCLE = DAY;
    Game->DMapPalette[CURRENTDMAP] = DAY_PAL;
}
else if ((InGameClock[CLOCK_HOURS] >= 19) && (InGameClock[CLOCK_HOURS] < 20) && (CYCLE != SUNSET))
{
    CYCLE = SUNSET;
    Game->DMapPalette[CURRENTDMAP] = SUNRISET_PAL;
}
else if (CYCLE != NIGHT)
{
    CYCLE = NIGHT;
    Game->DMapPalette[CURRENTDMAP] = NIGHT_PAL;
}   
}
}

void InGameClock()
{
        InGameClock[CLOCK_SECONDS] +=2;
    if ( InGameClock[CLOCK_SECONDS] == 60 ) 
    {
        InGameClock[CLOCK_SECONDS] = 0;
        InGameClock[CLOCK_MINUTES] +=1;
    }
    if ( InGameClock[CLOCK_MINUTES] == 60 ) 
    {
        InGameClock[CLOCK_MINUTES] = 0;
        InGameClock[CLOCK_HOURS] +=1;
    }
    if ( InGameClock[CLOCK_HOURS] == 24 ) 
    {
        InGameClock[CLOCK_HOURS] = 0;
        InGameClock[CLOCK_DAYS] +=1;
    }
}


 
 
It looks almost exactly like the materials you provided me with, but it seems to be having trouble with the DMap data:
"LINE 49: SYNTAX ERROR, UNEXPECTED IDENTIFIER, EXPECTING SEMICOLON OR OR, ON TOKEN DM"

I'm not sure, but is it possible that I have an outdated version of 2.54? The folder I have it in says beta 52, and it seems to be a  little over a year old.

EDIT: Okay, that WAS the problem (I downloaded alpha 30, just now), but now I'm getting told that the DMT_ variables are undeclared, and I can't actually find them in the documentation, either. Also, Alpha 30 (actually, all the alpha builds I've tried, so far, which is all of them after 20) corrupts, like, all of my data, rendering it unusable for building my quest. Dmaps, enemies, etc. all of it is messed up, and it was all fine in 2.54b52


Edited in the new code. It compiles, but no longer changes the palette.

Okay, it seems to work, now


Edited by Binx, 22 June 2018 - 01:40 AM.



1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users