Jump to content

Photo

Fire Rod & Dark Rooms


  • Please log in to reply
14 replies to this topic

#1 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 12 September 2017 - 11:32 PM

*Hiya you're been busy huh ?
*i have a request to ask.
*You see... a certain quest have a dark rooms that the fire rod can lit a little bit a dark room (like banana quest). Well i do like to use those scripts (i don't know if it's global or not )

FireRod item script for the custom itemclasse

and maybe Dark Room (ffc or global) and then use the Script 3 (100) combo flag to lit the room a little bite (for a torchs for exemple.)

#2 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 16 September 2017 - 01:01 AM

I have a fire rod script for the Z3 header pack, but it depends on quite a few things. Dark Room + Fire Rod must be global.

The general form of it, is:

Draw a black rectangle to a bitmap target.
Use a global loop to track all flag based light sources.
Use a global timer to include a flicker effect.
Use a global for loop to track all fire lweapons.
Decide on a base intensity of illumination for the flags, and for the lweapons.
Create an item that fires a specific script lweapon type, that you are tracking.
If that collides with a trigger, change the combo to a flame combo and add the flag to it.
If it collides with an enemy, generate a flame weapon on the enemy.
Draw colour 0 circles to the various tracked flag and weapon positions on the bitmap.
These are sized based on the intensity value, and modified by the timers, to produce an 'aura' effct.
Blit that bitmap to layer 6 or 7 of the screen.

Note also that ZC 2.50.x (and 2.53) cannot do translucent blits, so the 'dark' area will be solid black. 2.54 and above, can do translucent blits. Look forward to that, around the 'holiday season'.

I believe that there is a section in this video that showcases how this looks, and works.

https://m.youtube.co...1&v=6LRTAq-phgU

Edited by ZoriaRPG, 16 September 2017 - 01:04 AM.


#3 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 17 September 2017 - 04:41 PM

good. 



#4 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 18 September 2017 - 04:47 AM

good. 

 

Sans, if you can't detail precisely how you want it to work, I cannot help you. Please re-read the post above, and scan the parts that detail what you need to supply.



#5 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 18 September 2017 - 08:59 AM

Well simply the dark room where the light stay and follow Link's position and on torchs too.
The fire rod could be a update version of the candle and then lit up the distence torch.
I was planing to use it to make the only weapon usefull against a boss (the Ice Golem) with 2 phase that the first phase the fire rod is the only way to defeat his first phase. His 2 phase after the golem's died could be a giant darknut and his shield must be destroyed (10 hits) before use the sword.

I was planning that but i don't find good boss for this.

Anyway the fire rod could be compatible with the dark room script. If Link let charge the fire rod the player could see the dark room a little more better.

The fire rod when Link finish to charge the rod he'll throw many fires that can be usefull for some puzzles. (The Wand (Magic) flag could works) however i cannot make that as the wand type cause i already use the wand type for the deku leaf.

#6 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 24 September 2017 - 08:09 AM

Well simply the dark room where the light stay and follow Link's position and on torchs too.
The fire rod could be a update version of the candle and then lit up the distence torch.
I was planing to use it to make the only weapon usefull against a boss (the Ice Golem) with 2 phase that the first phase the fire rod is the only way to defeat his first phase. His 2 phase after the golem's died could be a giant darknut and his shield must be destroyed (10 hits) before use the sword.

I was planning that but i don't find good boss for this.

Anyway the fire rod could be compatible with the dark room script. If Link let charge the fire rod the player could see the dark room a little more better.

The fire rod when Link finish to charge the rod he'll throw many fires that can be usefull for some puzzles. (The Wand (Magic) flag could works) however i cannot make that as the wand type cause i already use the wand type for the deku leaf.


The following is completely untested, may (probably will) have some bugs or typos, and is imperfect, but it is essentially complete. It uses a script weapon type, and spawns LW_FIRE over fire triggers, or when it collides with enemies. It also includes an automatic light source generation function, but be warned that this may use quite a lot of draws. In fact, it is possible to use up all of your draws with this single call, if you manage to have enough light sources; although it is extremely unlikely that this would ever happen.

The light sources are refreshed every frame, which can also be slow.
 
////////////////////////////
/// Simple Firerod       ///
/// v0.3                 ///
/// By: ZoriaRPG         ///
/// 24th September, 2017 ///
////////////////////////////
/// Note: All of this is ugly. In 2.54, you will be able to set NPCs to specific script defences, so you can use a real
///       FLAME weapon that you set up, and 2.54 may add SCRIPT weapon triggers to combos, as well. 


int LightSources[3120]; //All the light source metrics for drawing, per frame. 
//x, y, diameter: 176 combos * 3 layers, (255 weapons * 2) * 3

//Settings
const int LW_CUST_FLAME 	= 31; //Script 1
const int FIREROD_MIN_STEP 	= 100;
const int FIREROD_DAMAGE 	= 4;
const int FIREROD_MISC_INDEX 	= 1;
const int FIREROD_FLAME_FLAG 	= 00001000b;
const int FIREROD_FLAME_SPRITE 	= 89;
const int BLANK_FIRE_SPRITE 	= 90; //Should be a blank tile sprite.  

//The diameter of the light source for combos.
const int LIGHT_SOURCE_COMBO_RADIUS_MIN = 29;
const int LIGHT_SOURCE_COMBO_RADIUS_MAX = 33;
//The diameter of the light source for weapons. 
const int LIGHT_SOURCE_WPN_RADIUS_MIN = 22;
const int LIGHT_SOURCE_WPN_RADIUS_MAX = 26;

const int BITMAP_DARKNESS = 2; //The bitmap ID to use for the darkness effect.
const int DARKROOM_LAYER = 7; //The layer to blit the output bitmap.
const int COLOUR_BLACK = 0x0F; //A  black colour swatch in your palette. 

const int LIGHT_SOURCE_CIRCLE_SCALE = 1; //Scale and layer args for the colour-0 circles. 
const int LIGHT_SOURCE_CIRCLE_LAYER = 0;

item script BasicFireRod{
	void run(int sprite, int damage, int step_speed){
		Link->Action = LA_ATTACKING;
		lweapon flame = Screen->CreateLWeapon(LW_CUST_FLAME);
		flame->X = Link->X;
		flame->Y = Link->Y;
		flame->UseSprite(Cond(sprite > 0, sprite, FIREROD_FLAME_SPRITE));
		flame->Dir = Link->Dir;
		if ( Link->Dir == DIR_UP ) {
			flame->Y -= 16;
		}
		if ( Link->Dir == DIR_DOWN ) {
			flame->Flip = FLIP_VERTICAL;
			flame->Y += 16;
			
		}
		if ( Link->Dir == DIR_RIGHT ) {
			flame->Flip = ROT_CCW;
			flame->X += 16;
		}
		if ( Link->Dir == DIR_RIGHT ) {
			flame->Flip = ROT_CW;
			flame->X -= 16;
		}
		//Ternary would help here, as it would jus tbe:
		//flame->Step = step_speed > 0 ? step_speed : FIREROD_MIN_STEP; 
		//sigh. 
		flame->Step = Cond(step_speed > 0, step_speed, FIREROD_MIN_STEP); 
		flame->Damage = Cond(damage > 0, damage, FIREROD_DAMAGE); 
		//! Damage is forwarded to the real fire weapon via the global active script.
		flame->Misc[FIREROD_MISC_INDEX] |= FIREROD_FLAME_FLAG; //Mark it for detection. 
		flame->HitYOffset = -214747; //Move the true hitbox offscreen so that it cannot trigger or hit anything. 
		//! The global active script handles real collisions. 
	}
}

//Returns true if the combo at '(x, y)' has either an inherent or place flag of type 'flag'
bool ____LayerComboFI(int pos, int flag, int layer){
	return GetLayerComboF(layer,pos) == flag || GetLayerComboI(layer,pos) == flag;
}



//Call before Waitdraw. 
void DoFireRod(){
	int cmb_pos; bool makeflame; int flags[3]={CF_CANDLE1, CF_CANDLE2};
	for ( int q = Screen->NumLWeapons(); q > 0; q-- ) {
		lweapon l = Screen->LoadLWeapon(q);
		if ( l->ID == LW_CUST_FLAME ){
			if ( l->Misc[FIREROD_MISC_INDEX]&FIREROD_FLAME_FLAG ) {
				//We make a real dire weapon on top of fire trigger combos. 
				cmb_pos = ComboAt(l->X, l->X);
				for ( int q = 0; q < 3; q++ ) {
					for ( int w = 0; w < 2; w++ ) {
						if ( ____LayerComboFI(cmb_pos, flags[w] , q ) ) {
							lweapon makefire = Screen->CreateLWeapon(LW_FIRE);
							makefire->X = ComboX(cmb_pos);
							makefire->Y = ComboY(cmb_pos);
							makefire->UseSprite(BLANK_FIRE_SPRITE);
							makefire->Misc[FIREROD_MISC_INDEX] |= FIREROD_FLAME_FLAG;
							SetLayerComboF(LAYER_TORCH_FLAG, cmb_pos, CF_LIT_TORCH);
						}
					}
				}
				//Make fire weapon on enemies on collision if the enemy has its hitbox enabled, and on-screen.
				for ( int e = Screen->NumNPCs(); e > 0; e-- ) {
					npc n = Screen->LoadNPC(e);
					if ( !n->CollDetection ) continue; 
					if ( n->HitXOffset < 0 ) continue;
					if ( n->HitXOffset > 255 ) continue;
					if ( n->HitYOffset < 0 ) continue;
					if ( n->HitYOffset > 255 ) continue;
					if ( Collision(l,n) ){
						lweapon makefire = Screen->CreateLWeapon(LW_FIRE);
						makefire->Damage = l->Damage;
						makefire->X = n->X + n->HitXOffset;
						makefire->Y = n->Y + n->HitYOffset;
						Remove(l); //Remove the fire rod object.
						//Fire weapons on enemies should be real gfx. 
						//makefire->UseSprite = BLANK_FIRE_SPRITE;
					}
				}
			}
		}
	}
}

const int CF_LIT_TORCH = 99; //script 2. 
const int LAYER_TORCH_FLAG = 0; //Look for them on his layer. 


//Call before Waitdraw()
//DarkDroom(DARKROOM_LAYER, false, BITMAP_DARKNESS);
void DarkRoom(int layer, bool trans, int bitmap_id)
{
	int q[16]; int src; int cnt; 
	int lightsourceflags[]={CF_LIT_TORCH}; 
	q[9] = SizeOfArray(lightsourceflags);
	int lightsourceflaglayers[]={LAYER_TORCH_FLAG};
	q[15] = SizeOfArray(lightsourceflaglayers);
	
	for ( q[10] = SizeOfArray(LightSources); q[10] >= 0; q[10]-- ) { LightSources[ q[10] ] = -1; } //Wipe it every frame. 
	Screen->SetRenderTarget(bitmap_id);
	Screen->Rectangle(layer, 0, 0, 256, 256, COLOUR_BLACK, 100, 0, 0, 0, true, OP_OPAQUE);
	//Add light sources to the array for combos. 
	for ( q[0] = 0; q[0] < q[15]; q[0]++ ) 
	{
		//Check for light sources on layers
		for ( q[1] = 0; q[1] < 176; q[1]++ ) 
		{
			//check all positions.
			for ( q[2] = 0; q[2] < q[9]; q[2]++ ) 
			{	//and all flags
				if (  ____LayerComboFI(q[1], lightsourceflags[ q[2] ], lightsourceflaglayers[ q[0] ] ) ) 
				{
					LightSources[src] = ComboX(q[1]);
					LightSources[src+1] = ComboY(q[1]);
					LightSources[src+2] = Rand(LIGHT_SOURCE_COMBO_RADIUS_MIN, LIGHT_SOURCE_COMBO_RADIUS_MAX);
					cnt++; 
					src+=3;
				}
			}
		}
	}
	//add light sources to the array for weapons
	for ( q[4] = Screen->NumLWeapons(); q[4] > 0; q[4] -- )
	{
		lweapon l = Screen->LoadLWeapon(q[4]);
		//for special fire rod weapons
		if ( l->ID == LW_CUST_FLAME )
		{
			LightSources[src] = l->X + 8;
			LightSources[src+1] = l->Y + 8;
			LightSources[src+2] = Rand(LIGHT_SOURCE_WPN_RADIUS_MIN, LIGHT_SOURCE_WPN_RADIUS_MAX);
			cnt++; 
			src+=3;
		}
		//for fire weapons that are not dummy weapons
		if ( l->ID == LW_FIRE )
		{
			if ( (l->Misc[FIREROD_MISC_INDEX]&FIREROD_FLAME_FLAG) != 0 ) 
			{
				LightSources[src] = l->X + 8;
				LightSources[src+1] = l->Y + 8;
				LightSources[src+2] = Rand(LIGHT_SOURCE_WPN_RADIUS_MIN, LIGHT_SOURCE_WPN_RADIUS_MAX);
				cnt++; 
				src+=3;	
			}
		}
	}
	
	q[13] = cnt*3;
	//Draw all light sources to the bitmap.
	for ( q[12] = 0; q[12] <= q[13]; q[12] += 3 )
	{
		Screen->Circle(LIGHT_SOURCE_CIRCLE_LAYER, LightSources[ q[12] ], LightSources[ q[12]+1 ], LightSources[ q[12]+2 ], 0, LIGHT_SOURCE_CIRCLE_SCALE,
		0,0,0, true, OP_OPAQUE);
		if ( LightSources[ q[12] ] == -1 ) break; //Sanity check. 
	}
	
	//! Blits
	Screen->SetRenderTarget(RT_SCREEN);
	// if ( trans )  //2.54+ stuff t/b/a
	// {
	//	Screen->DrawBitmapEx()
	// }
	// else {
	Screen->DrawBitmap(layer, bitmap_id, 0, 0, 256, 176, 0, 0, 256, 176, 0, true);
}
			

		
Once we have this set up and proven, you might want to try it.

See: https://github.com/Z...ster/Firerod.zs

Edited by ZoriaRPG, 24 September 2017 - 09:48 AM.


#7 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 24 September 2017 - 08:54 AM

*thanks alot.

#8 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 24 September 2017 - 09:32 AM

However i got a compilation error.

Line 57: Syntax error, unexpected bracket, on token [ TMP, Line 15: Error p01 : Failure to prase imported file FireRod.z

-- Press a key --

i have no clues for what i must do.

Edited by Sans, 24 September 2017 - 10:34 AM.


#9 judasrising

judasrising

    I play guitar

  • Members
  • Gender:Male
  • Location:Sweden but born in Finland

Posted 24 September 2017 - 10:37 AM

However i got a compilation error.
Line 57: Syntax error, unexpected bracket, on token [ TMP, Line 15: Error p01 : Failure to prase imported file FireRod.z
-- Press a key --
i have no clues for what i must do.


Would you mind post the scripfile here,easier to assist

#10 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 24 September 2017 - 11:00 AM

Rpg Zoria was post the script. I used the script file exactly like what rpg Zoria was post here

Note: Rpg Zoria i think you forget a = somewhere in the script file i was adding the missing =.
Here's something on the line 149 that cause that error but i find nothing but commentary.

#11 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 24 September 2017 - 12:53 PM

Rpg Zoria was post the script. I used the script file exactly like what rpg Zoria was post here

Note: Rpg Zoria i think you forget a = somewhere in the script file i was adding the missing =.
Here's something on the line 149 that cause that error but i find nothing but commentary.

 

 

Would you mind post the scripfile here,easier to assist

 

You may be using an older version. I updated it a few times. I did a test compile (in 2.53) and it compiles, but some constants (FLIP_* and ROT_*) are new to 2.53.0. Grab the new beta, and replace std_constants.zh in your 2.50.2 install with the one at ./std_zh/std_constants.zh, to make use of them.

 

My last edit fixed two glaring bugs, but I have not tested it yet.

 

@JudasRising: If you want to set up a test file for this, I can work on getting it working fully, tomorrow, and push it to the GitHub repo. I'll be adding some constants for all  of the  *q[] indices, to make it easier to follow, next, but I'm retiring to bed--in fact, I am already there.

 

 

If the code above is not compiling, fetch the latest commit in the Zelda3 repo on GitHub, as that  is the absolute latest versionof the code. It does not have a global script included, as it will be linked into the main global file for the package, but here is a temporary testing global active script:

 

global script TestFireRod{
    void run(){
        while(1){
            DarkRoom(DARKROOM_LAYER, false, BITMAP_DARKNESS);
            Waitdraw(); Waitframe();
        }
    }
}

 

Obviously, you will need to set up the sprites. I may have the rotation inverted on the item, but that is easy to fix.

 

 


This will also need revision for engine integration, to handle other flag-based light sources, and to merge all of the weapon, flag, and enemy checking loops (active script loop optimisation), but that will occur closer to the end.

 

For  single-purpose applications, you need to do separate loops, but when you are going to have a big engine with many events occurring with various for loops, folding them together vastly improves runtime performance.



#12 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 24 September 2017 - 01:04 PM

*Alright thanks i'll try it.

#13 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Gender:Male
  • Location:Judgement Hall

Posted 24 September 2017 - 03:53 PM

*Nope this time i got the function GetLayerComboi is undeclared.

Edited by Sans, 24 September 2017 - 06:06 PM.


#14 judasrising

judasrising

    I play guitar

  • Members
  • Gender:Male
  • Location:Sweden but born in Finland

Posted 24 September 2017 - 05:55 PM

You may be using an older version. I updated it a few times. I did a test compile (in 2.53) and it compiles, but some constants (FLIP_* and ROT_*) are new to 2.53.0. Grab the new beta, and replace std_constants.zh in your 2.50.2 install with the one at ./std_zh/std_constants.zh, to make use of them.
 
My last edit fixed two glaring bugs, but I have not tested it yet.
 
@JudasRising: If you want to set up a test file for this, I can work on getting it working fully, tomorrow, and push it to the GitHub repo. I'll be adding some constants for all  of the  *q[] indices, to make it easier to follow, next, but I'm retiring to bed--in fact, I am already there.
 
 
If the code above is not compiling, fetch the latest commit in the Zelda3 repo on GitHub, as that  is the absolute latest versionof the code. It does not have a global script included, as it will be linked into the main global file for the package, but here is a temporary testing global active script:
 

global script TestFireRod{
    void run(){
        while(1){
            DarkRoom(DARKROOM_LAYER, false, BITMAP_DARKNESS);
            Waitdraw(); Waitframe();
        }
    }
}
 
Obviously, you will need to set up the sprites. I may have the rotation inverted on the item, but that is easy to fix.
 
 This will also need revision for engine integration, to handle other flag-based light sources, and to merge all of the weapon, flag, and enemy checking loops (active script loop optimisation), but that will occur closer to the end.
 
For  single-purpose applications, you need to do separate loops, but when you are going to have a big engine with many events occurring with various for loops, folding them together vastly improves runtime performance.

Of course i make a test file for it.

#15 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 26 September 2017 - 05:35 AM

Of course i make a test file for it.


I pushed an update (v0.4) to GitHub. It includes a minor fix, style cleanup, and a new feature:

Link will now hold out a fire rod, and the fireball will shoot from the rod, rather than from Link. This uses an LW_SPARKLE weapon for the wand sprite.


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users