Read-only archive of the Armageddon Games Forums Archive (2000–2026) · About this archive

Fire Rod

22 replies · 51,802 views · Started 23 September 2017

Ok so here is the data from my first attempt.


const int BOLT_NOUSE = 64;//1 second pause
const int FLIP_NO = 0;//no flipping
const int FLIP_H = 1;//Flip Horrizontal
const int FLIP_V = 2;//Flip Vertical
const int FLIP_B = 3;//Rotate 180 degrees
const int BOLTCSET_NF = 6;
const int BOLTCSET_F = 0;

item script BoltSpell //basic use a wand and cast a spell stuff
{
void run(int power, int arrowSprite, int speed, int wandSprite)
{
int startX;
int startY;
lweapon l;
lweapon bolt;
startX = Link->X+8;
startY = Link->Y+4;
Link->Action = LA_ATTACKING;
l = NextToLink(LW_WAND,8);
l->Tile = wandSprite;
if (Link->Dir == DIR_UP)
{
l->Flip = FLIP_NO;
}
if (Link->Dir == DIR_DOWN)
{
l->Flip = FLIP_V;
}
if (Link->Dir == DIR_RIGHT)
{
l->Tile++;
l->Flip = FLIP_NO;
}
if (Link->Dir == DIR_LEFT)
{
l->Tile++;
l->Flip = FLIP_H;
}
bolt = NextToLink(LW_ARROW, 8);
bolt->UseSprite(arrowSprite);
if (Link->Dir == DIR_UP)
{
bolt->Flip = FLIP_NO;
}
if (Link->Dir == DIR_DOWN)
{
bolt->Flip = FLIP_V;
}
if (Link->Dir == DIR_RIGHT)
{
bolt->Tile++;
bolt->Flip = FLIP_NO;
}
if (Link->Dir == DIR_LEFT)
{
bolt->Tile++;
bolt->Flip = FLIP_H;
}
bolt->Damage = power;
bolt->Step = speed;
Link->ItemJinx = BOLT_NOUSE;
}
}

Problem 1: The wand is being rendered too high vertically on Link's spirte. I compared it to the sword location and it appears to be a good 6 pixels or so higher (about nose level instead of hand level). I tried reducing the Y position to +4 from +8 (line 18), but that had no visual effect at all on the placement of the sprite. How do I fix this so it looks like a normal use of the wand?

Problem 2: Not sure if this is possible but can the damage type of the attack be changed to fire? This is supposed to be a fire rod after all. Also would like to know how to get the bolt to render an actual flame at the impact point.

Next Steps: Currently contemplating using an advanced dark room script to make LttP style braziers. I thought it would be possible to allow the Fire Rod to light them either by using an invulnerable enemy that is invisible set on the brazier. However the thought also occurred that this would probably work better as an FFC script but I am rubbish at those currently.

Currently for the "Next Steps" portion I am considering using the "Subpar Dark Room Script" found on Pure, unless someone could suggest a better one?

I'm surprised that worked at all. Unless you're using 2.50.3. (In which case, I want to start working with it ASAP.)

Normally, you can't make LW_WAND via script. The best functions for placing an item, lweapon, etc. near Link are InFrontX and InFrontY. (They're in stdfunctions)

That'd look something like this...


lweapon wand;
wand->X=Link->X+InFrontX(Link->Dir,2);
wand->Y= Link->Y+InFrontY(Link->Dir,2);

The placement of the sprite may be due to the sprite itself.

As for enemy defenses, that's another matter entirely. It's not really possible without some heavy duty engine-level scripting to make it where a LWeapon is one type but does damage to an enemy based on a different type of defense.

I have a custom script header in the works which does a lot of this sort of thing automatically if you want to try and make sense of it.
It can be found here.

It has a custom fire rod included, though it doesn't always make fire as it should (and doesn't do that enemy defense thing).

Lelouche Vi Britannia wrote:Ok so here is the data from my first attempt.


const int BOLT_NOUSE = 64;//1 second pause
const int FLIP_NO = 0;//no flipping
const int FLIP_H = 1;//Flip Horrizontal
const int FLIP_V = 2;//Flip Vertical
const int FLIP_B = 3;//Rotate 180 degrees
const int BOLTCSET_NF = 6;
const int BOLTCSET_F = 0;

item script BoltSpell //basic use a wand and cast a spell stuff
{
void run(int power, int arrowSprite, int speed, int wandSprite)
{
int startX;
int startY;
lweapon l;
lweapon bolt;
startX = Link->X+8;
startY = Link->Y+4;
Link->Action = LA_ATTACKING;
l = NextToLink(LW_WAND,8);
l->Tile = wandSprite;
if (Link->Dir == DIR_UP)
{
l->Flip = FLIP_NO;
}
if (Link->Dir == DIR_DOWN)
{
l->Flip = FLIP_V;
}
if (Link->Dir == DIR_RIGHT)
{
l->Tile++;
l->Flip = FLIP_NO;
}
if (Link->Dir == DIR_LEFT)
{
l->Tile++;
l->Flip = FLIP_H;
}
bolt = NextToLink(LW_ARROW, 8);
bolt->UseSprite(arrowSprite);
if (Link->Dir == DIR_UP)
{
bolt->Flip = FLIP_NO;
}
if (Link->Dir == DIR_DOWN)
{
bolt->Flip = FLIP_V;
}
if (Link->Dir == DIR_RIGHT)
{
bolt->Tile++;
bolt->Flip = FLIP_NO;
}
if (Link->Dir == DIR_LEFT)
{
bolt->Tile++;
bolt->Flip = FLIP_H;
}
bolt->Damage = power;
bolt->Step = speed;
Link->ItemJinx = BOLT_NOUSE;
}
}

Problem 1: The wand is being rendered too high vertically on Link's spirte. I compared it to the sword location and it appears to be a good 6 pixels or so higher (about nose level instead of hand level). I tried reducing the Y position to +4 from +8 (line 18), but that had no visual effect at all on the placement of the sprite. How do I fix this so it looks like a normal use of the wand?

Problem 2: Not sure if this is possible but can the damage type of the attack be changed to fire? This is supposed to be a fire rod after all. Also would like to know how to get the bolt to render an actual flame at the impact point.

Next Steps: Currently contemplating using an advanced dark room script to make LttP style braziers. I thought it would be possible to allow the Fire Rod to light them either by using an invulnerable enemy that is invisible set on the brazier. However the thought also occurred that this would probably work better as an FFC script but I am rubbish at those currently.

Currently for the "Next Steps" portion I am considering using the "Subpar Dark Room Script" found on Pure, unless someone could suggest a better one?

In general, you want LW_SCRIPT for this, or LW_BEAM, or even LW_REFMAGIC.

There was a recent request on Pure for this sort of thing, but I frankly do not want to do it until 2.54 is out, and I can make it both cleaner, and easier.

This is the general idea for how I do this type of thing in 2.50.x:


////////////////////////////
/// Simple Firerod ///
/// v0.2 ///
/// 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(pos, flags[w] , layer ) ) {
lweapon makefire = Screen->CreateLWeapon(LW_FIRE);
makefire->X = ComboX(cmb_pos);
makefire->Y = ComboY(cmb_pos);
makefire->UseSprite = BLANK_FIRE_SPRITE;
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,e) ){
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->UseSprite != BLANK_FIRE_SPRITE )
{
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);
}


Keep an eye on this, if you want updates:

https://github.com/ZoriaRPG/Zelda3.zh/blob/master/Firerod.zs

Sounds like some exciting changes are coming in 2.54 that will make everyone's lives easier.

Code as it is doesn't compile, copied from the link you left. Not sure if its a version thing or a syntax thing. Made an attempt to fix it and ran into more errors. Seems to be syntax.

Lelouche Vi Britannia wrote:Sounds like some exciting changes are coming in 2.54 that will make everyone's lives easier.

Code as it is doesn't compile, copied from the link you left. Not sure if its a version thing or a syntax thing. Made an attempt to fix it and ran into more errors. Seems to be syntax.

IDK if you compiled the latest. I expect errors as this is pretty long, and I rewrote it from scratch today, based on the formula that I used in the past. You will have a number of errors if you are not using 2.53 though, as it relies on std.zh stuff such as FLIP_ and ROT_ . It'll give you missing identifiers for those, and then syntactical stuff, might follow.

For the most part, I wanted to outline it, and push it to the Z3 template package. I can fix it, or update it, later, but you can always have a look at how I did things and try to implement them on your own, if you wish. I have been putting this off because I wanted to make it for the Z3 package, which will use 2.54 or above for quite a lot. Nothing in it is 2.54-specific though, unless the array usage is a problem. I'll load it and see what happens.

Here is a version free of compiler errors:


////////////////////////////
/// 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);
}


It should be obvious, but, this does not mean that it works as-is. I fixed all of the actual syntactical issues, but I have not tested it. Any major issues at this stage, would most likely be from inappropriate pointers, calling stuff in loops using the wrong identifier, or the wrong array index; and similar. Then again, it might work. You never know.

You can view the diffs on GitHub if you want to see what I changed at each stage.

Well I am still trying to learn. Sadly my knowledge is woefully lacking. I'll give it a go tonight and see if I can fix any errors that pop up. If I'm successful, I'll repost the results.

Think I'm using 3.50.? Bit I'm pretty sure I downloaded 3.53.? . Currently in very early stages of my current project so I've been running code on my TestBed, then adding to the actual quest once I have confirmed it's working as intended.

Lelouche Vi Britannia wrote:Well I am still trying to learn. Sadly my knowledge is woefully lacking. I'll give it a go tonight and see if I can fix any errors that pop up. If I'm successful, I'll repost the results.

Think I'm using 3.50.? Bit I'm pretty sure I downloaded 3.53.? . Currently in very early stages of my current project so I've been running code on my TestBed, then adding to the actual quest once I have confirmed it's working as intended.

I think that you mean 2.53. 😃

Latest 2.53 Beta as of this post.

Let me know if it works. It's pretty complex, and will likely need me to do debugging.

[MENTION=61206]Lelouche Vi Britannia[/MENTION] : I also wanted to say that you are doing fine, picking up this stuff. You are quicky learning style elements, how to keepthings clean, and the syntax. Well done.

Ok let's begin...

First, still had a couple of minor errors but was easy to fix (one spelling error and two instances of Right direction instruction, I changed the first one to a Left and that fixed the graphic issue with the projectile).

During test, the bolt is appear just behind Link before flying forward. This is only visible when firing Left and Right.

Would still like to see an actual weapon held out when used, but I figured out how to do that with my earlier attempt. Is there an easier way to do it in 2.53?

The slightly modded code follows... only error corrected for now. Not sure what I would need to change to get the bolt to look right on the left/right firing, or if that can even be fixed at this stage.


import "std.zh"

global script Active
{
void run()
{
DoFireRod();
DarkRoom(DARKROOM_LAYER, false, BITMAP_DARKNESS);
Waitdraw();
Waitframe();
}
}

////////////////////////////
/// 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_LEFT ) {
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);
}

Lelouche Vi Britannia wrote:Ok let's begin...

First, still had a couple of minor errors but was easy to fix (one spelling error and two instances of Right direction instruction, I changed the first one to a Left and that fixed the graphic issue with the projectile).

During test, the bolt is appear just behind Link before flying forward. This is only visible when firing Left and Right.

This is because the first instance was supposed to be RIGHT, and the last, is LEFT. When you edited them, you accidentally transposed the offsets. Either flip the instances of flame->X += 16 and flame->X -= 16, or flip DIR_LEFT with DIR_RIGHT.


if ( Link->Dir == DIR_LEFT ) {
flame->Flip = ROT_CCW;
flame->X -= 16;
}
if ( Link->Dir == DIR_RIGHT ) {
flame->Flip = ROT_CW;
flame->X += 16;
}

Would still like to see an actual weapon held out when used, but I figured out how to do that with my earlier attempt. Is there an easier way to do it in 2.53?

The script already calls Link->Action = LA_ATTACKING. Is it not doing that, or did you want to see a physical wand item in his hands? That is relatively easy to add as a second lweapon, that uses a LW_SPARKLE type, and a sprite with the correct number of animation frames. The position of the fireball would need to be offset based on the LW_SPARKLE weapon as well.

I'll add that in, when I have a chance.

[The slightly modded code follows... only error corrected for now. Not sure what I would need to change to get the bolt to look right on the left/right firing, or if that can even be fixed at this stage.

Fair enough. I will look at a diff, and see what you changed.

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.

Lelouche Vi Britannia wrote: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]


////////////////////////////
/// 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);
}

[/spoiler]

Compile Error and I can't figure out what I need to do to fix it...

[spoiler]
LINE 138: Syntax Error, Unexpected Identifier, Expecting RBracket or Number, on Token DOFIREROD_COMBO_POS
FATAL ERROR P00: Can't open or parse input file!
[/spoiler]

The line in question is here, its the first line of the DoFireRod() function....


void DoFireRod(){
int q[DOFIREROD_COMBO_POS]; bool makeflame; int flags[2]={CF_CANDLE1, CF_CANDLE2}

Any ideas?

Lelouche Vi Britannia wrote:Compile Error and I can't figure out what I need to do to fix it...

[spoiler]
LINE 138: Syntax Error, Unexpected Identifier, Expecting RBracket or Number, on Token DOFIREROD_COMBO_POS
FATAL ERROR P00: Can't open or parse input file!
[/spoiler]

The line in question is here, its the first line of the DoFireRod() function....


void DoFireRod(){
int q[DOFIREROD_COMBO_POS]; bool makeflame; int flags[2]={CF_CANDLE1, CF_CANDLE2};
int q[5];

Any ideas?

The declaration of the array is a find-replace error.


bool makeflame; int flags[2]={CF_CANDLE1, CF_CANDLE2};
int q[5];

I pushed the change to GitHub, and I verified that it compiles in 2.53.

Lelouche Vi Britannia wrote:Awesome! Thanks. I won't have a chance to play with it till tomorrow.

The item script should be fine, although you may need to adjust the sprite metrics (constants). I am more worried that I might have some kind of minor error in the light sources code, or something of that nature. Unlike some users, I do not simply presume that my code will always work, but it should be sufficiently commented, and detailed, that you can see what it is doing at every stage.

The repo version on GitHub has a test global script with a debug feature that you may want to grab, and use, if you encounter problems.