//import "std.zh"
//Remove the comment before the import directive
//instruction if you do not elsewhere call this.
/////////////////////////////////////
// Scripted FADING Darkness Effect //
// v0.5 - 26th February, 2016 //
// By: ZoriaRPG //
///////////////////////////////////////////////////////////////////////////////////
// This script set creates a fading darkness effect when a lit torch set by the //
// constant 'CMB_LIT_TORCH'. //
// ----------------------------------------------------------------------------- //
// [ 1 ] Set-Up: Make a 'lit torch' combo, and assign its ID to the constant //
// CMB_LIT_TORCH. //
// [ 2 ] Set-Up: Make an 'unlit torch' combo, and assign its ID to the constant //
// CMB_UNLIT_TORCH. //
// [ 3 ] Find a colour swatch in your palette that is ALWAYS BLACK and assign //
// its value (in hex, pref.) to the constant 'COLOUR_BALCK'. //
// [ 4 ] Determine how many 'fading' laywrs of darkness you desire. //
// The default is '6', using layers 1 through 6. Enable ordisable what //
// Layers you want the darkness effect on, by setting their values to //
// '1' in the SETTINGS section (below). //
// [ 5 ] Assign timer values. This comes with defaults, but you may wish to //
// adjust them. //
// [ 6 ] Set up a combo ont he screenwith a secret flag (burn). //
// Set the 'burn' combo in Screen->Secret Combos to match the combo that //
// you selected as 'CMB_LIT_TORCH'. //
///////////////////////////////////////////////////////////////////////////////////
//////////////
// SETTINGS //
//////////////
//Combo and Colour Constants
const int CMB_LIT_TORCH = 0; //Set to the combo number of the torch in its lit state.
const int CMB_UNLIT_TORCH = 0; //Set tot he combo number of a torch to light.
const int DARK_OPACITY = 64; //Set to the opacity for darkness (64 is translucent;
//best to leave alone).
const int COLOUR_BLACK = 0x91; //Set to the colour for black in your palette in hex.
const int SFX_LIGHTING_TORCH = 0; //Set to sound effect to play when lighting a torch.
//Timer Values
const int TIME_INIT_DELAY_LIGHTING_ROOM = 10; //Initial delay before marking the room lit: 20 frames.
const int TIME_INTERPOLERATED_FADING_DARKNESS = 20; //30 frames per layer
//Settings: Draw darkness (for fade effect) on these layers (0 no, 1 yes)
const int DARK_LAYER_0 = 0;
const int DARK_LAYER_1 = 1;
const int DARK_LAYER_2 = 1;
const int DARK_LAYER_3 = 1;
const int DARK_LAYER_4 = 1;
const int DARK_LAYER_5 = 1;
const int DARK_LAYER_6 = 1;
/////////////////////
// ARRAYS AND VARS //
/////////////////////
float GRAM[214727]; //Global Array to hold values.
//Global RAM indices.
//1900 to 1999
const int GR_MAIN = 1900; //Dictates if the main loop should run.
const int GR_SCREENSHANGED = 1901; //Screen, DMap, and Map changes.
const int GR_LASTSCREEN = 1902;
const int GR_DMAPCHANGED = 1903;
const int GR_LASTDMAP = 1904;
const int GR_MAPCHANGED = 1905;
const int GR_LASTMAP = 1906;
const int GR_OLDSCREEN = 1907;
const int GR_OLDDMAP = 1908;
// 2000 to 2099
const int TORCH_LIT_THIS_SCREEN = 2000;
const int TORCH_LIGHT_TIMER = 2001;
const int TORCH_LIGHT_TIMER_LAYER0 = 2002;
const int TORCH_LIGHT_TIMER_LAYER1 = 2003;
const int TORCH_LIGHT_TIMER_LAYER2 = 2004;
const int TORCH_LIGHT_TIMER_LAYER3 = 2005;
const int TORCH_LIGHT_TIMER_LAYER4 = 2006;
const int TORCH_LIGHT_TIMER_LAYER5 = 2007;
const int TORCH_LIGHT_TIMER_LAYER6 = 2008;
const int ROOM_FULLY_LIT = 2009;
/////////////////////////////////////
// DARKNESS AND LIGHTING FUNCTIONS //
/////////////////////////////////////
//Resets timers for darkness effects.
//Call before main loop.
InitTorchTimers(){
GRAM[TORCH_LIT_THIS_SCREEN] = 0;
GRAM[TORCH_LIGHT_TIMER] = TIME_INIT_DELAY_LIGHTING_ROOM;
for ( int q = TIME_INIT_DELAY_LIGHTING_ROOM; q <= TORCH_LIGHT_TIMER_LAYER6; q++ ){
if ( q == 0 && DARK_LAYER_0 ) GRAM[q] = TIME_INTERPOLERATED_FADING_DARKNESS;
if ( q == 0 && DARK_LAYER_1 ) GRAM[q] = TIME_INTERPOLERATED_FADING_DARKNESS;
if ( q == 0 && DARK_LAYER_2 ) GRAM[q] = TIME_INTERPOLERATED_FADING_DARKNESS;
if ( q == 0 && DARK_LAYER_3 ) GRAM[q] = TIME_INTERPOLERATED_FADING_DARKNESS;
if ( q == 0 && DARK_LAYER_4 ) GRAM[q] = TIME_INTERPOLERATED_FADING_DARKNESS;
if ( q == 0 && DARK_LAYER_5 ) GRAM[q] = TIME_INTERPOLERATED_FADING_DARKNESS;
if ( q == 0 && DARK_LAYER_6 ) GRAM[q] = TIME_INTERPOLERATED_FADING_DARKNESS;
}
}
void LightUnlitTorches(){
for ( int q = 0; q <= Screen->NumLWeapons(); q++ ){
lweapon l = Screen->LoadLWeapon(q);
if ( l->ID == LW_FIRE ) {
//Layers
for ( int w = 0; w <= 6; w++ ) {
if (Screen->LayerMap(w) != -1) {
for ( int e = 0; e < 176; e++ ){
if ( Screen->ComboD[e] == CMB_UNLIT_TORCH && Collision(w,l) ) {
if ( SFX_LIGHTING_TORCH ) Game->PlaySound(SFX_LIGHTING_TORCH);
SetLayerComboD(w,e,CMB_LIT_TORCH);
}
}
}
}
}
}
}
//The primary function. Call before Waitdraw.
void Torches(){
ClearTorchTimersOnScreenChange();
LightRoom();
}
//Called by Torches(), but also stores if the screen changes.
void ClearTorchTimersOnScreenChange(){
if ( ScreenChanged() || DMapChanged() ) {
InitTorchTimers();
RoomLit(0,true); //Clears that the room is lit.
}
//The primarycomponent function, called by Torches()
void LightRoom(){
if ( !RoomLit() ) {
bool lit;
if ( !lit ) {
for ( int q = 0; q <= 6; q++ ) { //layers
if (Screen->LayerMap(q) != -1) {
for ( int w = 0; q < 176; w++ ){
if ( Screen->ComboD[q] == CMB_LIT_TORCH ) lit = true;
}
}
}
}
if ( lit ) {
if ( MainTorchTimer() ) MainTorchTimer(true);
else if ( !MainTorchTimer() {
if ( !(Screen->Lit ) ) Screen->Lit = true;
for ( int e = 0; e <= 6; e++ ) {
//Layer0
if ( LayerTorchTimer(e) && !RoomLit(e) ) {
Screen->Rectangle(e,0,0,256,176,COLOUR_BLACK,-1,0,0,0,true,DARK_OPACITY);
LayerTorchTimer(e,true);
break;
}
if ( !LayerTorchTimer(e) && RoomLit(e) < e+1 ) RoomLit(e,false);
}
}
}
}
}
}
//////////////////////////////////
// GlobalRAM ACCESSOR FUNCTIONS //
//////////////////////////////////
//Returns the timer value for system darkness release.
int MainTorchTimer(){
return GRAM[TORCH_LIGHT_TIMER];
}
//Decreases the main torch timer.
void MainTorchTimer(bool dec){
GRAM[TORCH_LIGHT_TIMER]--;
}
//Returns the fading timer for a specific layer.
int LayerTorchTimer(int layer){
return GRAM[TORCH_LIGHT_TIMER_LAYER0 + layer];
}
//Decreases the timer for fading darkness by '1' for a specific layer of scripted drawing.
//Note that you do not need to have these layers set up.
int LayerTorchTimer(int layer, bool dec){
GRAM[TORCH_LIGHT_TIMER_LAYER0 + layer]--;
}
//Returns true if a room is fully lit.
int RoomLit(){
return GRAM[ROOM_FULLY_LIT] == 7;
}
//Returns true if the darkness effect for a given layer is in effect.
bool RoomLit(int layer){
return RoomLit() == layer + 1;
}
//Sets what layer we're up to in removing all layers of darkness.
//Can clear all layers by calling RoomLit(0,true)
void RoomLit(int layer, bool clear){
if ( clear ) GRAM[ROOM_FULLY_LIT] = 0;
else GRAM[ROOM_FULLY_LIT] = layer+1;
}
//! Functions for checking screen and DMap changes.
//Returns if the screen has changed, and stores the values as an update at at one time.
bool ScreenChanged(){
if ( Game->GetCurScreen() != GRAM(GR_LASTSCREEN) ) {
GRAM(GR_OLDSCREEN,GRAM(GR_LASTSCREEN));
GRAM(GR_LASTSCREEN, Game->GetCurScreen());
GRAM(GR_SCREENCHANGED,1);
return true;
}
else {
GRAM(GR_SCREENCHANGED,0);
return false;
}
}
//Returns if the DMap has changed, and stores the values as an update at at one time.
bool DMapChanged(){
if ( Game->GetCurDMap() != GRAM(GR_LASTDMAP) ) {
GRAM(GR_OLDDMAP,GRAM(GR_LASTDMAP);
GRAM(GR_LASTDMAP, Game->GetCurDMap());
GRAM(GR_DMAPCHANGED,1);
return true;
}
else {
GRAM(GR_DMAPCHANGED,0);
return false;
}
}
//Returns if the Map (NOT DMap!) has changed, and stores the values as an update at at one time.
bool MapChanged(){
if ( Game->GetCurMap() != GRAM(GR_LASTMAP) ) {
GRAM(GR_OLDMAP,GRAM(GR_LASTMAP));
GRAM(GR_LASTMAP, Game->GetCurMap());
GRAM(GR_MAPCHANGED,1);
return true;
}
else {
GRAM(GR_MAPCHANGED,0);
return false;
}
}
///////////////////
// GLOBAL SCRIPT //
///////////////////
global script active_example_timed_fading_torch_darkness{
void run() {
main(true); //Enable the main loop.
InitTorchTimers(); //Initialise the timers for darkness.
while( main() ) { //! I do this, instead of while(true) to allow suspending it,
//! and changing to an alternate global loop, as an option.
LightUnlitTorches(); //Lights torches on collision with fire lweapon without needing a secret combo.
Torches(); //The main function for custom darkness.
Waitdraw();
Waitframe();
}
}
int main() { return GRAM(GR_MAIN); }
void main(bool enabled) {
if ( enabled ) GRAM(GR_MAIN,1);
else GRAM(GR_MAIN,0);
}
}