Jump to content

Photo

Modified Day/Night Script


  • Please log in to reply
33 replies to this topic

#1 ywkls

ywkls

    Master

  • Members

Posted 20 January 2015 - 10:24 AM

I working in 2.5 using the Dance of Remembrance Hybrid Tileset and I'd like to see if there is a way to change an existing script where I could use it to do something a little different from what it was originally designed to do. Anyways, this is the script in question.

 

http://www.purezc.ne...ay night&page=2

 

Spoiler

 

If I understand correctly about the way this is set up, the time of day will automatically change after a certain length of time has passed. However, in my game the time of day can only be changed by warping at certain special screens which would take you to a different time of day. So to avoid having to create duplicate versions of all houses, caves and dungeons; I'd like to be able to have the game detect what time it was when you last left the world map and automatically take you to the correct overworld map when leaving caves, houses and dungeons..

 

There are 8 overworld maps this would currently be used on, set up in the order Dawn South, Dawn North, Day South, Day North, Twilight South, Twilight North, Night South and Night North. (The order of the maps could be changed if needed for the purposes of this script.)

 

I think it would be easier to have this inside each cave, near the exit. Whenever you enter the room, an FFC would check the value of the int saved by the global script, then make it so you warped to the proper screen whenever you stepped outside. Of course, these are merely suggestions. I'd appreciate any contributions and would like to express my thanks in advance to anybody who helps!



#2 justin

justin

    Adept

  • Members

Posted 20 January 2015 - 10:42 AM

i have a day/night script that changes timeperiod only on screen changes.  it has a ffc script that you place on warpreturn screens to ensure you are on the correct timeperiod.  it is based off a slightly different Moosh script.

 

const int DAYNIGHT_NUM_STATES = 3;     //Set this to the number of states you want to use. All states last an equal length of time.
const int DAYNIGHT_STATE_LENGTH = 720; //Set this to the number of frames (60ths of a second) a state should last. 12 seconds by default for testing purposes.
 
int DayNightDMaps[2] = {0, 3}; //This array tells the script which DMaps to check for. 
                               //Put the first DMap of every set of states separated by a comma inside the {}. 
                               //Put the number of things inside the {} inside the []. 
                               //****You'll want to make a new save file every time you change this.
 
int DayNightCounter = 0;       //counts upto DAYNIGHT_CYCLE_LENGTH, then changes
int DayNightCurrentState = 0;  //tracks which state you are in
 
 
 
//This is the function that handles the Day/Night script. Put it before the Waitframe() in your global script.
void DayNight(){
   if(Link->Action == LA_SCROLLING){
      while(Link->Action == LA_SCROLLING) Waitframe();     // this isn't good form to have a second waitframe in your global loop.  i don't have a good solution
      DayNightCheckandWarp();
   }
 
   DayNightCounter++;
   if(DayNightCounter>=DAYNIGHT_CYCLE_LENGTH){
      DayNightCounter = 0;
      DayNightCurrentState++;
      if(DayNightCurrentState>=DAYNIGHT_NUM_STATES) DayNightCurrentState = 0;
   }
}
 
void DayNightCheckandWarp(){
   int curDMap = Game->GetCurDMap();
 
   for(int i=0; i<SizeOfArray(DayNightDMaps); i++){
      if(curDMap>=DayNightDMaps[i]&&curDMap<DayNightDMaps[i]+DAYNIGHT_NUM_STATES){
         if(DayNightDMaps[i] + DayNightCurrentState != curDMap){
            Link->PitWarp(DayNightDMaps[i] + DayNightCurrentState, Game->GetCurDMapScreen());
            return;
         }
      }
   }
}
 
 
// put this on day/night screens where you return from a warp, script run on screen init
ffc script WarpReturnOnDayNight{
   void run(){
      DayNightCheckandWarp();
   }
}

Edited by justin, 20 January 2015 - 11:00 AM.


#3 ywkls

ywkls

    Master

  • Members

Posted 20 January 2015 - 10:59 AM

i have a day/night script that changes timeperiod only on screen changes.  it has a ffc script that you place on warpreturn screens to ensure you are on the correct timeperiod.

 

The one I provided the link to was one you requested... you're saying it doesn't automatically change time of day on the overworld after a certain amount of time has passed but only whenever you go from one screen to another? If that is the case, can it be set up in the way I'm thinking; where all corresponding cave/house/dungeon entrances on whatever world map take you to the same cave/house/dungeon but they exit back to whatever time of day it previously was? I'm using a mechanic similar to Oracle of Ages, where you have to find a spot to warp from one time of day to another and play your Whistle there to change the time of day.

 

Or is this a different script entirely? Either way, I'd appreciate any help you can offer.


Edited by ywkls, 20 January 2015 - 10:59 AM.


#4 justin

justin

    Adept

  • Members

Posted 20 January 2015 - 11:05 AM

i should have just looked at the link, instead of just looking at the code you posted...

 

yes, you can have all your day/night overworld screens point to the same cave/house/dungeon dmaps.  when you leave (warp out) place the ffc script on the screen you return to.

 

as for OoA, are you asking for the script to not change time period on its own, only when you play the whistle?  should be an easy modification.



#5 ywkls

ywkls

    Master

  • Members

Posted 20 January 2015 - 11:08 AM

Exactly... if you could do that I'd appreciate it since it would simplify the process immensely. As for when to change the time, the script should never change it unless it has already been changed. Example: you find a warp spot outside a cave, play the whistle and warp to a different time of day. When you enter the cave, that cave is the same no matter what time of day it is. But when you leave you're back on the time of day you were before you entered unless you changed it at another warp spot somewhere else.



#6 justin

justin

    Adept

  • Members

Posted 20 January 2015 - 11:14 AM

sure, should be easy.  you already have a method for switching time period when stepping on the warp spot and playing the whistle, or you need that scripted too?

 

remind me if i don't post it up in the next day or two.  working on a few other scripts right now.



#7 ywkls

ywkls

    Master

  • Members

Posted 20 January 2015 - 11:26 AM

sure, should be easy.  you already have a method for switching time period when stepping on the warp spot and playing the whistle, or you need that scripted too?

 

remind me if i don't post it up in the next day or two.  working on a few other scripts right now.

 

Since the time period will only switch when you play the whistle on special warp spots, the easiest way I could think to do it was to have the spot with an inherent flag 3 (whistle), then a placed flag 16 (Secret Flag 1) and have the secret combo be an identical-looking combo that is a direct warp. Since the direct warp for that screen will be set up to warp to the corresponding screen at the next time of day, all the script would have to do is detect that you're on a DMap that is a particular time of day and change the variable that sets what time of day it is for the warps to caves and such. This is all part of my latest quest project which is currently in the earliest stages of development; but since I could see that this would be an issue at some point I was trying to get it solves as soon as I could. Thanks for your efforts again!



#8 justin

justin

    Adept

  • Members

Posted 20 January 2015 - 02:15 PM

i figured it was pretty quick and easy to write, so here it is...  it compiles but is untested.

 

Edit the constants, and the TS_Dmaps[] array.  

 

Set the I_ACT_TS_TimeChange as an action script on any item that changes the Time Period.  Has to be an item that you can equip to A or B.  You can have multiple time change items.  For instance, an item that only warps to Future, and if in future warps back to Present.  Another another item that warps between past/present.

 

Place the FFC script on every TimePeriod screen where you return from a warp.

 

Could be modified to have the TimeWarpSquare itself handle what time period to send Link to.

 

 

// OoA style multiple Time Period dmap warping
 
const int TS_NUM_TIMEPERIODS = 3;     //Set this to the number of time periods.  I.e. Past/Present/Future = 3
 
//Set any combination of these for how you want to designate a TimeWarp combo.  Leave at -1 if not using.  At least one needs to not be -1.
const int TS_TIMEWARPCOMBO = -1;   // use a specific Combo#
const int TS_TIMEWARPTYPE  = -1;   // use a specific ComboType
const int TS_TIMEWARPFLAG  = -1;   // use a specific ComboFlag - placed or inherent doesn't matter
 
int TS_DMaps[2] = {0, 3};   //This array tells the script which DMaps are involved in the Time System. 
                            //Put the first DMap of every set of time periods separated by a comma inside the {}. 
                            //Put the number of things inside the {} inside the []. 
                            //****You'll want to make a new save file every time you change this.
 
int TS_CurrentState = 0;  //tracks which time period you are in
 
 
// handles actually changing the Time Period dmap 
void TS_CheckandWarp(){
   int curDMap = Game->GetCurDMap();
 
   for(int i=0; i<SizeOfArray(TS_DMaps); i++){
      if(curDMap >= TS_DMaps[i] && curDMap < TS_DMaps[i]+TS_NUM_TIMEPERIODS){
         if(TS_DMaps[i] + TS_CurrentState != curDMap){
            Link->PitWarp(TS_DMaps[i] + TS_CurrentState, Game->GetCurDMapScreen());
            return;
         }
      }
   }
}
 
// put this on any Time Period screens where you return from a warp, script run on screen init
ffc script FFC_TS_WarpReturnCheck{
   void run(){
      TS_CheckandWarp();
   }
}
 
 
// D0 = select time period.  Between 0 and TS_NUM_TIMEPERIODS.
//      Set to -1 if you to cycle in reverse, set to TS_NUM_TIMEPERIODS+1 if you want to cycle forwards
// D1 = if setting the time period above (not cycling), and already in the D0 time period, warp to this instead.
 
item script I_ACT_TS_TimeChange{
   void run(int TS_SelectTP, int TS_WarpBack){
      if(isTimeWarp( ComboAt(Link->X+8,Link->Y+12)) ){
         if(TS_SelectTP < 0){
            TS_CurrentState--;
            if(TS_CurrentState<=0) TS_CurrentState = TS_NUM_TIMEPERIODS;
         }
         else if(TS_SelectTP > TS_NUM_TIMEPERIODS){
            TS_CurrentState++;
            if(TS_CurrentState>=TS_NUM_TIMEPERIODS) TS_CurrentState = 0;
         }
         else if(TS_CurrentState == TS_SelectTP) TS_CurrentState = TS_WarpBack;
         else TS_CurrentState = TS_SelectTP;
 
         TS_CheckandWarp();
      }  
   }
}
 
bool isTimeWarp(int loc){
   return (Cond(TS_TIMEWARPFLAG == -1, true, ComboFI(loc,TS_TIMEWARPFLAG) ) 
        && Cond(TS_TIMEWARPTYPE == -1, true, Screen->ComboT[loc] == TS_TIMEWARPTYPE)
        && Cond(TS_TIMEWARPCOMBO == -1, true, Screen->ComboD[loc] == TS_TIMEWARPCOMBO) );
}
 


#9 ywkls

ywkls

    Master

  • Members

Posted 20 January 2015 - 11:53 PM

The way I understand it, the DMaps for the TS_Dmaps would have to be set up in the order of the times of day (for example, dawn, day, twilight and night) so to set up two sets of DMaps I'd have to put in the first DMap number of the first set in the array first, then the first DMap of the second set in the array would follow (separated by a comma). As for the items to detect the switching times of day, I was thinking of something like this.

 

Spoiler

 

If I'm right about the way Game->GetCurDMap() works, then whenever you're on the DMap in question, you automatically get those items and keep them until you enter one of the other indicated Dmaps. Then the FFC would detect which of those items you had and warp you to the Dmap you were supposed to be on whenever you left the dungeon. I mostly conceived of this global script as a way of automatically changing which of the items that told the FFC what time of day of it was depending on which DMap you were last on. (For example, on DMap 3 (dawn) you enter a cave, travel through it and change to DMap 4 (day). Whenever you go back to that cave, you warp to the same cave but the FFC by its exit would tell it that you were supposed to be going to DMap 4 instead of 3.

 

The reason I feel it would be easier to set up inside the cave rather than outside would be that you would need far fewer FFCs to do it. However, if there is a way to have it switch the item in your possession automatically when you warp; I'd like to hear about it since my ideas are more theoretical than practical.



#10 justin

justin

    Adept

  • Members

Posted 21 January 2015 - 12:05 AM

I don't understand what you're trying to do now. You're just using items as variables - 4 items instead of one variable with my script. Did my script not work?

You'd be using the same number of FFCs whether you are checking inside the cave or outside. And frankly outside is easier. With outside you have the cave warp you to your first dmap in the time period system, and the script just warps you to the correct dmap in the exact location you are standing. Inside would have to set the scroll warp and have a warp return on each dmap screen you could warp back to.

As for what DMaps to put in the array. Let's say you had
Dmap #1 - overworld south Morning
Dmap #2 - overworld south Daytime
Dmap #3 - overworld south Night
Dmap #4 - overworld north Morning
Dmap #5 - overworld north Daytime
Dmap #6 - overworld north Night
You're array would be
int TS_DMAPS[2] = {1,4};

Edited by justin, 21 January 2015 - 12:16 AM.


#11 ywkls

ywkls

    Master

  • Members

Posted 21 January 2015 - 10:09 AM

I see... I didn't really understand the part about the item script I guess. So I'd assign that script to the action slot of whatever item triggers the warp, right? From what you said, I'd only need the one FFC, placed on the outside of the cave/house/dungeon on the first map in the set for the array that would then automatically send you to the correct map. (I thought I was going to have to have a different FFC for every time of day which was why i thought of the other method.)

 

I'll probably still have the four items in addition to the one that switches the time, but only so one of them would appear on my subscreen for each of the different DMaps,  with the item for that time period in the same position. (To do this would probably require a different subscreen for each DMap, but since this quest is just getting starting I've got time to spend on that.) It may take me a little while to actually test this out since I haven't created any interior areas yet, but once I do I'll let you know if I have any trouble with it.

 

One question of setup- If I have 4 time periods would TS_NUM_TIMEPERIODS be 3 or 4? (I've seen some things count from zero so I wanted to be certain.)

 

I think that's all for now. Time to test out things as they are and see how they work!

 

Edit: I've got it all set up (my guesses on how to do that were right) and it works seemlessly! Instantly, you warp from one time of day to the next, but the cave can be precisely the same and when you exit there isn't even a one second lag before the right screen is loaded. The only thing I think I would add is some sort of effect whenever you change time periods (for example, whatever causes the warp with zap effects). I don't know if that would have to be part of the item script or something else or whether it is even possible. Either way, it is perfectly fine now! 

 

I am deeply indebted to justin for his work on this. (Helped on two quests in a row, thanks!) And I must say that this is the fastest I've gotten a script request answered. I don't expect this result every time, naturally; but it is still very nice when it happens.


Edited by ywkls, 21 January 2015 - 11:03 AM.


#12 justin

justin

    Adept

  • Members

Posted 21 January 2015 - 11:03 AM

The item script in my code can be attached to any item that you can use on A/B buttons.  You can attach it to a whistle, a sword or a custom item.  

Note: if you attach the item script to a non-custom item you might still have that item's function happen - i.e. the whistle might still play and create a whirlwind.  Not sure because i didn't test it.

 

You set the time change behaviour of the item depending on how you want your time system to work - you can have it always just cycle you forward to next time period, always cycle you backward to previous time period, or always send you to a specific timeperiod and if already there send you back to specific timeperiod instead.  So you could have an item that always sends you to the future, and if in the future sends you to the present, and have a second item doing the same thing but between the past/present, so that you could slowly unlock the different time periods as the game progresses.  

 

I just did the item like that so it was flexible.  It could be totally scraped and have the warpcombo itself have a designated destination.  Then the item would only activate the warp, not have anything to do with where it warps you.

 

 

4 time periods means that TS_NUM_TIMEPERIODS = 4.

 

You don't need the items to be able to show which time period you're in.  Since the time periods are on different dmaps, they can show different subscreens.  I'd just put a text box on the subscreen saying what time it is.  If you want the items instead, go for it.  Since this function TS_CheckandWarp() handles all the time changes, you would include something like the following inside that function.

 

Link->Item[ timeitem0 ] = false;
Link->Item[ timeiitem1 ] = false;
// etc for however many items you have representing which time it is.  with timeitem# being the item# itself, or a constant representing that.
 
if(TS_CurrentState==0) Link->Item[ timeitem0 ] = true;
else if(TS_CurrentState==1) Link->Item[ timeitem1 ] = true;
//etc. 

 

This could be made a lot cleaner and simpler if all your timeitems were in numerical order.  Then you'd just have a constant representing the value of timeitem0, and use a for loop to run through and remove all of them, and one statement like Link->Item[ TIMEITEM0 + TS_CurrentState ] = true;   instead of the if/else statements. 



#13 ywkls

ywkls

    Master

  • Members

Posted 21 January 2015 - 11:24 AM

So let's see if I understand correctly. In my global constants I would declare this.

const int I_ITEM_DAWN = 149; 

Then for the other items, they'd need to be the next 3 numbers (150, 151 and 152).

Then inside the TS_Checkand Warp() I'd have this.

for (i = I_ITEM_DAWN; 4; i++){
    Link->Item[i] = false;
}
Link->Item[I_ITEM_DAWN +TS_CurrentState] = true;

The only part I'm uncertain about is the for loop. (I've had trouble setting up those on my own before.)



#14 justin

justin

    Adept

  • Members

Posted 21 January 2015 - 11:31 AM

So let's see if I understand correctly. In my global constants I would declare this.

const int I_ITEM_DAWN = 149; 

Then for the other items, they'd need to be the next 3 numbers (150, 151 and 152).

Then inside the TS_Checkand Warp() I'd have this.

for (i = I_ITEM_DAWN; 4; i++){
    Link->Item[i] = false;
}
Link->Item[I_ITEM_DAWN +TS_CurrentState] = true;

The only part I'm uncertain about is the for loop. (I've had trouble setting up those on my own before.)

 

nice!  you were so close...  the for loop needs to know when to stop, and you just put 4, but it won't know what you mean by that.  we know it means you want it to do it 4 times, but the compiler doesn't.  also, the first part needs to actually declare the variable i.

 

for (int i = I_ITEM_DAWN; i<I_ITEM_DAWN+TS_NUM_TIMEPERIODS; i++){


#15 ywkls

ywkls

    Master

  • Members

Posted 21 January 2015 - 11:41 AM

I'm getting there... so far I've created two scripts (one's a combo of other scripts and the second was an original one that I modified to include a method that somebody else was using to do one of the things I wanted it to do). I must keep forgetting that int before the first i, then that the middle needs to be i < something (where something is the total number of things that i can be). Gonna keep it up, but until then I'll probably continue making requests like this one. (One day and it works! One day!) Any thoughts on creating warp effects?

 

In std_constants the effect is listed as

const int WT_IWARPZAP = 7;	

I don't know exactly how you'd insert this to make the zap effect when you warp (via the warp combo spot), but it is the last thing to make this perfect! (So many Zscript commands, so hard to remember them all...)




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users