Completed Script | Demo Quest
You can use either the ffc script screenmessage, or an enemy on the screen, using the npc script screenguy. I did the latter of these two, in the example quest, as it is obviously more useful to show people how to set up npc scripts.
Don't forget to assign Link's scripts!
//v0.5 - 9th march, 2019
//Revision History
//v0.2
//v0.3
//v0.4 Fix compile
//v0.5 Update DMaps after Levels in Link Active
script typedef ffc struct;
script typedef ffc class;
struct script locations
{
enum{ curDMAP, curSCREEN, curLEVEL, pvsDMAP, pvsSCREEN, pvsLEVEL, locLAST};
int data[locLAST];
void run(){}
void clear() { for ( int q = 0; q < locLAST; ++q ) data[q] = 0; }
bool changed() { return ( Game->GetCurDMap() != data[curDMAP] || Game->GetCurScreen() != data[curSCREEN] ); }
bool dmapchanged() { return ( Game->GetCurDMap() != data[curDMAP] ); }
bool screenchanged() { return ( Game->GetCurScreen() != data[curSCREEN] ); }
bool levelchanged() { return ( Game->GetCurLevel() != data[curLEVEL] ); }
int priorDMap() { return ( data[pvsDMAP] ); }
void update()
{
data[pvsSCREEN] = data[curSCREEN];
data[pvsDMAP] = data[curDMAP];
data[curSCREEN] = Game->GetCurScreen();
data[curDMAP] = Game->GetCurDMap();
}
void update_dmap()
{
data[pvsDMAP] = data[curDMAP];
data[curDMAP] = Game->GetCurDMap();
}
void update_level()
{
data[pvsLEVEL] = data[curLEVEL];
data[curLEVEL] = Game->GetCurLevel();
}
void update_screen()
{
data[pvsSCREEN] = data[curSCREEN];
data[curSCREEN] = Game->GetCurScreen();
}
}
class script screenintros
{
const int REGISTER = 6;
const int BIT = 2;
void run(){}
void clear()
{
for ( int q = 0; q < 0x80; ++q )
{
SetScreenDBit(locations.data[locations.pvsDMAP], q, REGISTER, BIT, false);
}
}
void update()
{
if ( locations.levelchanged() )
{
locations.update_level();
locations.update_dmap();
clear(); //Re-display after changing dmaps, like DMap intros repeat, but for screens.
}
}
}
link script active
{
void run()
{
while(1)
{
screenintros.update();
Waitframe();
}
}
}
//Does not repeat if you revisit the screen, unless you change dmaps.
ffc script screenmessage
{
const int REGISTER = 6;
const int BIT = 2;
const int DELAY_DEFAULT = 1;
void run(int delay, int reg, int bit )
{
reg = ( reg > 0 ) ? reg : REGISTER;
bit = ( bit > 0 ) ? reg : BIT;
delay = ( delay > 0 ) ? delay : DELAY_DEFAULT;
while(1)
{
if ( !(GetScreenDBit(Game->GetCurDMap(), Game->GetCurScreen(), reg, bit)) )
{
Waitframes(delay);
Screen->Message(Screen->String);
SetScreenDBit(Game->GetCurDMap(), Game->GetCurScreen(), reg, bit, true);
}
Waitframe();
}
}
}
link script init
{
void run()
{
locations.clear();
locations.clear(); //Call twice to push the previous screen down.
}
}
///////////////////////////
/// NPC Script Room Guy ///
/// v0.3 ///
/// 8th March, 2019 ///
/// By: ZoriaRPG ///
///////////////////////////
//ZQuest Screen Menu Sets Options
//Set Screen->String to the string to display
//Set Screen->Catchall to the delay time, if the roomtype is none.
//Otherwise, you can set a default delay on the enemy using D0.
//v0.2 Initial Fixes
//v0.3 Added Once Only Behavioural Flag
npc script screenguy
{
const int DELAY = 20; //Time to spawn.
const int BFLAG_ONCE = 4;
const int REGISTER = 6;
const int BIT = 2;
void run(int delay, int reg, int bit)
{
delay = this->InitD[0] > 0 ? delay : DELAY;
reg = this->InitD[1] > 0 ? reg : REGISTER;
bit = this->InitD[2] > 0 ? bit : BIT;
if ( !Screen->RoomType )
{
if ( Screen->Catchall )
{
delay = Screen->Catchall;
}
}
this->CollDetection = false;
//this->DrawYOffset = -32768;
//Waitframes(Screen->Catchall); //might be in use depending on room type
Waitframes(delay);
if ( this->BFlags[BFLAG_ONCE] )
{
if ( !(GetScreenDBit(Game->GetCurDMap(), Game->GetCurScreen(), reg, bit)) )
{
Screen->Message(Screen->String);
SetScreenDBit(Game->GetCurDMap(), Game->GetCurScreen(), reg, bit, true);
}
}
else Screen->Message(Screen->String);
}
}