Quote Originally Posted by Lelouche Vi Britannia View Post
Whoops at the changed the wrong one, lol. I saw CCW and figured that was supposed to be the left one. Yeah seeing a visible rod would be cool and please, take your time. You're helping a lot as it is.

The only real error correction then was just a typo... DarkDroom was supposed to be DarkRoom. Haven't tested that part of it yet.

Revisions to add the rod weapon.
Spoiler: show
Code:
////////////////////////////
/// Simple Firerod       ///
/// v0.4                 ///
/// By: ZoriaRPG         ///
/// 26th 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; // The weapon type used by the fireball itself. The default is LW_SCRIPT1
const int FIREROD_MIN_STEP 			= 100; //The default step speed. 
const int FIREROD_DAMAGE 			= 4; //The damage forwarded to LW_FIRE when the weapon creates a flame. 
const int FIREROD_MISC_INDEX 			= 1; //The l->Misc[index] used to store flags. 
const int FIREROD_FLAME_FLAG 			= 00001000b; //This flag marks the fireball projectile as spawned by this script. 
							//! Change ONLY if you need this flag for another weapon of type LW_CUST_FLAME or LW_FIRE. 
const int SPRITE_FIREROD 			= 88; //The sprite for the Fire Rod Handle: 
							//! This will persist on-screen for a number of frames equal to 
							//! the ANIMATION FRAMES of the sprite.
const int FIREROD_FLAME_SPRITE 			= 89; //The sprite for the fireball projectile.
const int BLANK_FIRE_SPRITE 			= 90; //Should be a blank tile sprite.  



const int CF_LIT_TORCH 				= 99; //The flag placed on torches when they light from DoFireRod() to find light sources.
							//! Script 2 by default. 
const int LAYER_TORCH_FLAG 			= 0; //Look for lit torch flags on this layer. 

//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; //Draw colour 0 circles to this layer of the bitmap. 

const int FIREROD_BALL_CENTRE_OFFSET 		= 10;  //How many pixels to offset the fireball so that it flys from the rod.
const int FIREROD_HANDLE_TO_FIREBALL_DIST 	= 16; //Length of the fire rod wand sprite. 

//Array Indicws: Do not change!!
const int FIREROD_WEAP_BALL 			= 0;
const int FIREROD_WEAP_ROD 			= 1;

item script BasicFireRod{
	void run(int sprite, int damage, int step_speed, int rod_sprite){
		Link->Action = LA_ATTACKING;
		lweapon flame[2];
		flame[FIREROD_WEAP_BALL] = Screen->CreateLWeapon(LW_CUST_FLAME);
		
		flame[FIREROD_WEAP_BALL]->UseSprite(Cond(sprite > 0, sprite, FIREROD_FLAME_SPRITE));
		flame[FIREROD_WEAP_BALL]->Dir = Link->Dir;
		
		flame[FIREROD_WEAP_ROD] = Screen->CreateLWeapon(LW_SPARKLE);
		flame[FIREROD_WEAP_ROD]->UseSprite(Cond(rod_sprite > 0, rod_sprite, SPRITE_FIREROD));
		flame[FIREROD_WEAP_ROD]->CollDetection = false; //The rod itself does no damage. 
		
		//Set initial positions of weapons. 
		flame[FIREROD_WEAP_ROD]->X = Link->X;
		flame[FIREROD_WEAP_ROD]->Y = Link->Y;
		
		if ( Link->Dir == DIR_UP ) {
			flame[FIREROD_WEAP_ROD]->Y -= 16; //Rod in front of Link
			flame[FIREROD_WEAP_BALL]->X = flame[FIREROD_WEAP_ROD]->X + FIREROD_BALL_CENTRE_OFFSET; //
			flame[FIREROD_WEAP_BALL]->Y = flame[FIREROD_WEAP_ROD]->Y - FIREROD_HANDLE_TO_FIREBALL_DIST;
		}
		if ( Link->Dir == DIR_DOWN ) {
			flame[FIREROD_WEAP_ROD]->Y += 16; //Rod in front of Link
			flame[FIREROD_WEAP_ROD]->Flip = FLIP_VERTICAL; 
			flame[FIREROD_WEAP_BALL]->Flip = FLIP_VERTICAL;
			flame[FIREROD_WEAP_BALL]->X = flame[FIREROD_WEAP_ROD]->X - FIREROD_BALL_CENTRE_OFFSET; //
			flame[FIREROD_WEAP_BALL]->Y = flame[FIREROD_WEAP_ROD]->Y + FIREROD_HANDLE_TO_FIREBALL_DIST;
			
		}
		if ( Link->Dir == DIR_LEFT ) {
			flame[FIREROD_WEAP_BALL]->Flip = ROT_CCW;
			flame[FIREROD_WEAP_ROD]->Flip = ROT_CCW;
			flame[FIREROD_WEAP_ROD]->X -= 16;
			flame[FIREROD_WEAP_BALL]->Y = flame[FIREROD_WEAP_ROD]->Y - FIREROD_BALL_CENTRE_OFFSET; //
			flame[FIREROD_WEAP_BALL]->X = flame[FIREROD_WEAP_ROD]->X + FIREROD_HANDLE_TO_FIREBALL_DIST;
		}
		if ( Link->Dir == DIR_RIGHT ) {
			flame[FIREROD_WEAP_BALL]->Flip = ROT_CW;
			flame[FIREROD_WEAP_ROD]->Flip = ROT_CW;
			flame[FIREROD_WEAP_ROD]->X += 16;
			flame[FIREROD_WEAP_BALL]->Y = flame[FIREROD_WEAP_ROD]->Y + FIREROD_BALL_CENTRE_OFFSET; //
			flame[FIREROD_WEAP_BALL]->X = flame[FIREROD_WEAP_ROD]->X - FIREROD_HANDLE_TO_FIREBALL_DIST;

		}
		//Ternary would help here, as it would jus tbe:
		//flame[FIREROD_WEAP_BALL]->Step = step_speed > 0 ? step_speed : FIREROD_MIN_STEP; 
		//sigh. 
		flame[FIREROD_WEAP_BALL]->Step = Cond(step_speed > 0, step_speed, FIREROD_MIN_STEP); 
		flame[FIREROD_WEAP_BALL]->Damage = Cond(damage > 0, damage, FIREROD_DAMAGE); 
		//! Damage is forwarded to the real fire weapon via the global active script.
		flame[FIREROD_WEAP_BALL]->Misc[FIREROD_MISC_INDEX] |= FIREROD_FLAME_FLAG; //Mark it for detection. 
		flame[FIREROD_WEAP_BALL]->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;
}

//Array indices for DoFireRod() : Do not change!!
const int DOFIREROD_COMBO_POS 		= 0;
const int DOFIREROD_LOOP_LWPNS_SCAN 	= 1;
const int DOFIREROD_LOOP_LAYERS 	= 2;
const int DOFIREROD_LOOP_FLAGS 		= 3;
const int DOFIREROD_LOOP_NPCS 		= 4;

//Call before Waitdraw. 
void DoFireRod(){
	int q[DOFIREROD_COMBO_POS]; bool makeflame; int flags[2]={CF_CANDLE1, CF_CANDLE2};
	int q[5];
	for ( q[DOFIREROD_LOOP_LWPNS_SCAN] = Screen->NumLWeapons(); q[DOFIREROD_LOOP_LWPNS_SCAN] > 0; q[DOFIREROD_LOOP_LWPNS_SCAN]-- ) {
		lweapon l = Screen->LoadLWeapon(q[DOFIREROD_LOOP_LWPNS_SCAN]);
		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. 
				q[DOFIREROD_COMBO_POS] = ComboAt(l->X, l->X);
				for ( q[DOFIREROD_LOOP_LAYERS] = 0; q[DOFIREROD_LOOP_LAYERS] < 3; q[DOFIREROD_LOOP_LAYERS]++ ) { //layers
					for ( q[DOFIREROD_LOOP_FLAGS] = 0; q[DOFIREROD_LOOP_FLAGS] < 2; q[DOFIREROD_LOOP_FLAGS]++ ) { //flags
						if ( ____LayerComboFI(q[DOFIREROD_COMBO_POS], flags[ q[DOFIREROD_LOOP_FLAGS] ] , q[DOFIREROD_LOOP_LAYERS] ) ) {
							lweapon makefire = Screen->CreateLWeapon(LW_FIRE);
							makefire->X = ComboX(q[DOFIREROD_COMBO_POS]);
							makefire->Y = ComboY(q[DOFIREROD_COMBO_POS]);
							makefire->UseSprite(BLANK_FIRE_SPRITE);
							makefire->Misc[FIREROD_MISC_INDEX] |= FIREROD_FLAME_FLAG;
							SetLayerComboF(LAYER_TORCH_FLAG, q[DOFIREROD_COMBO_POS], CF_LIT_TORCH);
						}
					}
				}
				//Make fire weapon on enemies on collision if the enemy has its hitbox enabled, and on-screen.
				for ( q[DOFIREROD_LOOP_NPCS] = Screen->NumNPCs(); q[DOFIREROD_LOOP_NPCS] > 0; q[DOFIREROD_LOOP_NPCS]-- ) {
					npc n = Screen->LoadNPC(q[DOFIREROD_LOOP_NPCS]);
					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;
					}
				}
			}
		}
	}
}


//DarkRoom() array indices : Do not touch!!

const int DARKROOM_LOOP_LIGHTSRC_ADD 		= 0;
const int DARKROOM_LOOP_LIGHTSRC_LAYER 		= 1;
const int DARKROOM_LOOP_CHECKPOS 		= 2;
const int DARKROOM_LOOP_LWPNS_ADD 		= 3;
const int DARKROOM_ARRAYSZ_LIGHTSRCFLAGS 	= 4;
const int DARKROOM_LOOP_LIGHTSOURCE_WIPE 	= 5;
const int DARKROOM_LOOP_BITMAP_DRAW 		= 6;
const int DARKROOM_LIGHTSOURCE_COUNT 		= 7;
const int DARKROOM_ARRAYSZ_LIGHTFLAGLAYERS 	= 8;
const int DARKROOM_SRC 				= 9;
const int DARKROOM_LIGHTSOURCE_COUNTS 		= 10;


//Call before Waitdraw()
//DarkDroom(DARKROOM_LAYER, false, BITMAP_DARKNESS);
void DarkRoom(int layer, bool trans, int bitmap_id)
{
	int q[11];
	int lightsourceflags[]={CF_LIT_TORCH}; 
	q[DARKROOM_ARRAYSZ_LIGHTSRCFLAGS] = SizeOfArray(lightsourceflags);
	int lightsourceflaglayers[]={LAYER_TORCH_FLAG};
	q[DARKROOM_ARRAYSZ_LIGHTFLAGLAYERS] = SizeOfArray(lightsourceflaglayers);
	
	for ( q[DARKROOM_LOOP_LIGHTSOURCE_WIPE] = SizeOfArray(LightSources); q[DARKROOM_LOOP_LIGHTSOURCE_WIPE] >= 0; q[DARKROOM_LOOP_LIGHTSOURCE_WIPE]-- ) { LightSources[ q[DARKROOM_LOOP_LIGHTSOURCE_WIPE] ] = -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[DARKROOM_LOOP_LIGHTSRC_ADD] = 0; q[DARKROOM_LOOP_LIGHTSRC_ADD] < q[DARKROOM_ARRAYSZ_LIGHTFLAGLAYERS]; q[DARKROOM_LOOP_LIGHTSRC_ADD]++ ) 
	{
		//Check for light sources on layers
		for ( q[DARKROOM_LOOP_LIGHTSRC_LAYER] = 0; q[DARKROOM_LOOP_LIGHTSRC_LAYER] < 176; q[DARKROOM_LOOP_LIGHTSRC_LAYER]++ ) 
		{
			//check all positions.
			for ( q[DARKROOM_LOOP_CHECKPOS] = 0; q[DARKROOM_LOOP_CHECKPOS] < q[DARKROOM_ARRAYSZ_LIGHTSRCFLAGS]; q[DARKROOM_LOOP_CHECKPOS]++ ) 
			{	//and all flags
				if (  ____LayerComboFI(q[DARKROOM_LOOP_LIGHTSRC_LAYER], lightsourceflags[ q[DARKROOM_LOOP_CHECKPOS] ], lightsourceflaglayers[ q[DARKROOM_LOOP_LIGHTSRC_ADD] ] ) ) 
				{
					LightSources[ q[DARKROOM_SRC] ] = ComboX(q[DARKROOM_LOOP_LIGHTSRC_LAYER]);
					LightSources[ q[DARKROOM_SRC] +1] = ComboY(q[DARKROOM_LOOP_LIGHTSRC_LAYER]);
					LightSources[ q[DARKROOM_SRC] +2] = Rand(LIGHT_SOURCE_COMBO_RADIUS_MIN, LIGHT_SOURCE_COMBO_RADIUS_MAX);
					 q[DARKROOM_LIGHTSOURCE_COUNTS]++; 
					 q[DARKROOM_SRC] +=3;
				}
			}
		}
	}
	//add light sources to the array for weapons
	for ( q[DARKROOM_LOOP_LWPNS_ADD] = Screen->NumLWeapons(); q[DARKROOM_LOOP_LWPNS_ADD] > 0; q[DARKROOM_LOOP_LWPNS_ADD] -- )
	{
		lweapon l = Screen->LoadLWeapon(q[DARKROOM_LOOP_LWPNS_ADD]);
		//for special fire rod weapons
		if ( l->ID == LW_CUST_FLAME )
		{
			LightSources[ q[DARKROOM_SRC] ] = l->X + 8;
			LightSources[ q[DARKROOM_SRC] +1] = l->Y + 8;
			LightSources[ q[DARKROOM_SRC] +2] = Rand(LIGHT_SOURCE_WPN_RADIUS_MIN, LIGHT_SOURCE_WPN_RADIUS_MAX);
			 q[DARKROOM_LIGHTSOURCE_COUNTS]++; 
			 q[DARKROOM_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[ q[DARKROOM_SRC] ] = l->X + 8;
				LightSources[ q[DARKROOM_SRC] +1] = l->Y + 8;
				LightSources[ q[DARKROOM_SRC] +2] = Rand(LIGHT_SOURCE_WPN_RADIUS_MIN, LIGHT_SOURCE_WPN_RADIUS_MAX);
				 q[DARKROOM_LIGHTSOURCE_COUNTS]++; 
				 q[DARKROOM_SRC] +=3;	
			}
		}
	}
	
	q[DARKROOM_LIGHTSOURCE_COUNT] =  q[DARKROOM_LIGHTSOURCE_COUNTS]*3;
	//Draw all light sources to the bitmap.
	for ( q[DARKROOM_LOOP_BITMAP_DRAW] = 0; q[DARKROOM_LOOP_BITMAP_DRAW] <= q[DARKROOM_LIGHTSOURCE_COUNT]; q[DARKROOM_LOOP_BITMAP_DRAW] += 3 )
	{
		Screen->Circle(LIGHT_SOURCE_CIRCLE_LAYER, LightSources[ q[DARKROOM_LOOP_BITMAP_DRAW] ], LightSources[ q[DARKROOM_LOOP_BITMAP_DRAW]+1 ], LightSources[ q[DARKROOM_LOOP_BITMAP_DRAW]+2 ], 0, LIGHT_SOURCE_CIRCLE_SCALE,
		0,0,0, true, OP_OPAQUE);
		if ( LightSources[ q[DARKROOM_LOOP_BITMAP_DRAW] ] == -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);
}