Jump to content

Photo

stdWeapons.zh

library beta

  • Please log in to reply
93 replies to this topic

#16 Alucard648

Alucard648

    Adept

  • Members
  • Gender:Male
  • Location:castle Dracula

Posted 06 December 2015 - 01:01 PM

After discussing this with ZoriaRPG, I'd like to request an explanation of how to set up lweapons that are blocked by certain combos and trigger certain combos. Or flags that can be set to them so that they handle it on their own. Demonstration scripts would be helpful.
 
I'm creating a scripted boomerang and while my script works, it doesn't seem to handle item pickup even with the example script included in stdWeapons. My script can be found here- Super Boomerang

 

I tried using stdWeapons whenever I first thought of it, but couldn't figure out how to get it to work. So I scripted this from scratch. It works like a normal boomerang, except for item pickup.

 

Discussing it with ZoriaRPG, I don't think either of us was quite certain to set up a similar item using stdWeapons. Any help you could give would be greatly appreciated.

Update! Beta #3! http://www.mediafire...Weaponsv1_2.zip
Details in readme.

New version includes particles, expanded trigger and blocked combo interaction. Also new sample script inside: Master Boomerang.



#17 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 10 December 2015 - 07:16 AM

I see that you started adding sparkles to items. I presume this is via the particles engine, and it's a good step forward. Now we just need trails, be they sparkles, or other sprites/particles. That would be good for any weapon type, arrows, magic, swords (think of leaving trails during the slash movement). I;m not sure how best to hande it, as there are two approaches:

 

1. Purely visual effect. This makes things look more interesting, but has no impact on the item itself.

2. Potential damage. While this seems like it would be good, some items suffer by it, such as the stock Fire Boomerang. Being hit by a trail object, gives enemies invincibility frames under normal circumstances, that can, and often do, negate collision with the weapon itself. If you ever wondered why the fire boomerang doesn;t always stun, this is why.

 

If using method two, it would be best to apply the damage directly, rather than enforcing normal enemy collision, with trails; and of course, making that an argument. I think that trails of this sort could be made by generating a series of drawtiles along the path of where any object last was, with an offset of distance, and an argument for low long the sprite should persist. ( That would set the fade-out period. )

 

I have some preliminary tile collision things, if you want to play with them.



#18 Alucard648

Alucard648

    Adept

  • Members
  • Gender:Male
  • Location:castle Dracula

Posted 10 December 2015 - 02:11 PM

I see that you started adding sparkles to items. I presume this is via the particles engine, and it's a good step forward. Now we just need trails, be they sparkles, or other sprites/particles. That would be good for any weapon type, arrows, magic, swords (think of leaving trails during the slash movement). I;m not sure how best to hande it, as there are two approaches:

 

1. Purely visual effect. This makes things look more interesting, but has no impact on the item itself.

2. Potential damage. While this seems like it would be good, some items suffer by it, such as the stock Fire Boomerang. Being hit by a trail object, gives enemies invincibility frames under normal circumstances, that can, and often do, negate collision with the weapon itself. If you ever wondered why the fire boomerang doesn;t always stun, this is why.

 

If using method two, it would be best to apply the damage directly, rather than enforcing normal enemy collision, with trails; and of course, making that an argument. I think that trails of this sort could be made by generating a series of drawtiles along the path of where any object last was, with an offset of distance, and an argument for low long the sprite should persist. ( That would set the fade-out period. )

 

I have some preliminary tile collision things, if you want to play with them.

The particles in StdWeapons.zh are separate lweapons, which, if not set as damaging particle with specific function, have collision detection turned off.

As for methods, applying damage directly is not feasible at all, as it ignores all defenses. Using default collision detection is the best as you can also set particles to work against different enemy defenses.



#19 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 10 December 2015 - 03:36 PM

The particles in StdWeapons.zh are separate lweapons, which, if not set as damaging particle with specific function, have collision detection turned off.
As for methods, applying damage directly is not feasible at all, as it ignores all defenses. Using default collision detection is the best as you can also set particles to work against different enemy defenses.

 
I'm actually working on a method to do direct damage, whilst still respecting NPCDs, and invincibility frames. i try to avoid making streams of weapons, due to the system limits on the max number of them, if you're curious.
 
I's pretty early, but you might want to read TileCollision.zh (v0.2.2).

Perhaps you'd be interested in collaboration on that? I have several uses for it, but I'm not sure how I want to handle pointer returns, or if I want to include damage and trigger functions in the main functions. The base DrawTileCollision() and DrawComboCollision() that affect Link should work as-is. It's how to affect enemies, items,, and weapons that poses difficulty, but with regard to enemy defs, reading them on collision and applying a virtual type to the tiles/combos would work.

 

I still feel that pure tile based anims for some weapons (special effects) as system defaults for stdWeapons.zh would be brilliant. A ghost/echo of a slash animation would look fantastic.

 

I'm planning to use some of this for custom enemies, and enemy attacks in the EnemyAI.zlib sub-header, which would work wonders for scrolling engines. I also have an idea for a SHMUP that could take advantage of it. You might also be interested in the Enemy AI stuff.


Edited by ZoriaRPG, 12 December 2015 - 06:41 AM.


#20 Alucard648

Alucard648

    Adept

  • Members
  • Gender:Male
  • Location:castle Dracula

Posted 11 December 2015 - 01:55 AM

 
I'm actually working on a method to do direct damage, whilst still respecting NPCDs, and invincibility frames. i try to avoid making streams of weapons, due to the system limits on the max number of them, if you're curious.

I don`t think, it`s even possible to check enemy`s invincibility frames after hit outside ghost.zh.

 

 

I's pretty early, but you might want to read TileCollision.zh (v0.2.2).

Perhaps you'd be interested in collaboration on that? I have several uses for it, but I'm not sure how I want to handle pointer returns, or if I want to include damage and trigger functions in the main functions. The base DrawTileCollision() and DrawComboCollision() that affect Link should work as-is. It's how to affect enemies, items,, and weapons that poses difficulty, but with regard to enemy defs, reading them on collision and applying a virtual type to the tiles/combos would work.

Checked that library. Nothing interesting. Damage from drawn tiles, again, disrecpects defenses and invisibility frames. And functions for detecting collision with drawn tiles is just a DrawTile & RectCollision combinations.

 

I still feel that pure tile based anims for some weapons (special effects) as system defaults for stdWeapons.zh would be brilliant. A ghost/echo of a slash animation would llook fantastic.

Nice idea of giving particle animation to melee weapon activities. I might consider that.

 

I'm planning to use some of this for custom enemies, and enemy attacks in the EnemyAI.zlib sub-header, which would work wonders for scrolling engines. I also have an idea for a SHMUP* that could take advantage of it. You might also be interested in the Enemy AI stuff.

Why not just use ghost.zh?



#21 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 12 December 2015 - 06:25 AM


Why not just use ghost.zh?

 

... ghost.zh for scrolling games just doesn't work as-is. No internal enemy mechanic does.

 

The AI engine will be ghost compatible, or even ghost-reliant, but not for H/V scrolling. :P

 

Respecting enemy defs, boils down to reading them, and applying the damage only if the type of the effect is a match, via a modifier. Enemy shields are another matter, but still possible. That's really why I think that doing a separate set of routines inside each function to handle those factors, is best.

 

 


I don`t think, it`s even possible to check enemy`s invincibility frames after hit outside ghost.zh.

 

Read for CSet changes. The enemy CSet should change when damaged, and you can create your own frames by setting one of its Misc[] indices to a countdown timer. In any event, tile collision becomes hellishly important when you start doing scrolling engines, as you are somewhat limited in how to construct objects. With that type of...thing...doing DrawTile() if a combo of X type, with X flag is drawn to the screen, to create enemies, items, or other objects, is practical.

 

I'm unsure if you can read invincibility frames if the QR 'Flickers when hit' is enabled. I think that just changes the sprite rapidly,. but I'm not sure. Ordinary CSet flashing though, should always be a value that you can read.

 

You can always set up a global ticker that tracks when an enemy is injured, and stores that in a desired index, and count down that index in frames, to match its invincibility frame duration. In so doing, you can reliably read, or store that it is temporarily invincible, no-matter what hurt it.


Edited by ZoriaRPG, 12 December 2015 - 06:39 AM.

  • Alucard648 likes this

#22 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 15 December 2015 - 12:50 PM

Here's how I plan to handle that, if you want it for anything:
 
//////////////////////////////////
/// Enemy Invincibility Frames ///
//////////////////////////////////

//Settings for Enemy Invincibility Frames
const int ENEMY_INVINCIBILITY_FRAMES_DURATION = 180;
const int INVINCIBLE_ENEMIES_PHANTOM = 1; //Setting to enable or disable phantoming injured enemies.
const int STORE_ORIGINAL_ENEMY_PALETTE = 1; //Setting to enable storing original enemy palette or cset. 

//You may enable *ONE* of these two rules, to match your quest rule settings. 
//! If one is enabled, the other MUST be disabled. 
const int ENEMIES_FLICKER_WHEN_HIT = 0; //Use the OriginalSprite, and store it instead of CSet or BPal
const int ENEMIES_FLASH_WHEN_HIT = 0; //Use the CSet or BPal to make an enemy flash, when hit. 

//Values For Enemy Invincibility Frames

//n->Misc Indices
const int ENEM_HP_LAST = 1; //n->Mics[] holds last enemy HP. Adjusted when damaged. 
const int ENEM_INV_FRAMES = 2; //n->Misc[] holds the present nth frame of invincibility as a countdown timer. 
const int ENEM_ORIG_PAL = 3; //original CSet or Palette, or OriginalSprite

const int ENEM_BLANK_TILE = 65260; //Set to a tile at the head of a FULL PAGE of BLANK tiles. 
//const int ENEM_FLASH_TIMER = 4;

//Framecount for each enemy flash or flicker.
const int ENEM_FLASH_1 = 180; //Will change on frame 180
const int ENEM_FLASH_2 = 150; //...frame 150
const int ENEM_FLASH_3 = 120;
const int ENEM_FLASH_4 = 90; 
const int ENEM_FLASH_5 = 60; 
const int ENEM_FLASH_6 = 30; //...frame 30

//Cset or BPal to use when flashing
const int ENEM_BPAL_FLASH = 6;
const int ENEM_CSET_FLASH = 6;

//Run before Waitdraw, and before EnemyInvincibilityFrames()
void InitEnemyLastHP(){
	for ( int q = 1; q <= Screen->NumNPCs(); q++ ) {
		npc n = Screen->LoadNPC(q);
		if (!n->Misc[ENEM_HP_LAST] && n->HP > 0) {
			n->Misc[ENEM_HP_LAST] = n->HP;
			if ( STORE_ORIGINAL_ENEMY_PALETTE && !n->Misc[ENEM_ORIG_PAL] ) {
				if ( n->CSet == 14 ) n->Misc[ENEM_ORIG_PAL] = n->BossPal;
				else n->Misc[ENEM_ORIG_PAL] = n->CSet;
			}
			if ( ENEMIES_FLICKER_WHEN_HIT && !n->Misc[ENEM_ORIG_PAL] ) {
				n->Misc[ENEM_ORIG_PAL] = n->OriginalTile;
			}
		}
	}
}

void _InitEnemyLastHP(){
    for ( int q = 1; q <= Screen->NumNPCs(); q++ ) {
        npc n = Screen->LoadNPC(q);
        if (!n->Misc[ENEM_HP_LAST] && n->HP > 0) n->Misc[ENEM_HP_LAST] = n->HP;
    }
}

//Run before Waitdraw and before any collision/damage functions that need to read these values. 
void _EnemyInvincibilityFrames(){
	for ( int q = 1; q <= Screen->NumNPCs(); q++ ) {
		npc n = Screen->LoadNPC(q);
		if ( n->Misc[ENEM_HP_LAST] > n->HP ) {
			n->Misc[ENEM_HP_LAST] = n->HP;
			n->Misc[ENEM_INV_FRAMES] = ENEMY_INVINCIBILITY_FRAMES_DURATION;
		}
		if ( n->Misc[ENEM_INV_FRAMES] > 0 ) n->Misc[ENEM_INV_FRAMES]--;
		if ( n->Misc[ENEM_INV_FRAMES] < 0 ) n->Misc[ENEM_INV_FRAMES] = 0;
	}
}

//Run after InitEnemyLastHP, before Waitdraw and before any collision/damage functions that need to read these values. 
void EnemyInvincibilityFrames(){
	for ( int q = 1; q <= Screen->NumNPCs(); q++ ) {
		npc n = Screen->LoadNPC(q);
		if ( n->Misc[ENEM_HP_LAST] > n->HP ) {
			n->Misc[ENEM_HP_LAST] = n->HP;
			n->Misc[ENEM_INV_FRAMES] = ENEMY_INVINCIBILITY_FRAMES_DURATION;
		}
		if ( n->Misc[ENEM_INV_FRAMES] > 0 ) n->Misc[ENEM_INV_FRAMES]--;
		if ( n->Misc[ENEM_INV_FRAMES] < 0 ) n->Misc[ENEM_INV_FRAMES] = 0;
		
		if ( INVINCIBLE_ENEMIES_PHANTOM ) {
			if ( EnemyInvincible(n) && n->DrawStyle != DS_PHANTOM ) n->DrawStyle = DS_PHANTOM;
			if ( !EnemyInvincible(n) && n->DrawStyle == DS_PHANTOM 
				&& !GetNPCMiscFlag(n,NPCM_TRANSLUCENT) && !GetNPCMiscFlag(n,NPCM_FLICKERING) 
				&& !GetNPCMiscFlag(n,NPCM_FLASHING) ) n->DrawStyle = DS_NORMAL;

		}
	}
}



//Run IMMEDIATELY AFTER EnemyInvincibilityFrames() if you have flashing, or flickering settings enabled. 
void FlashEnemyWhenHit(npc n) {
	if ( ENEMIES_FLASH_WHEN_HIT && n->Misc[ENEM_INV_FRAMES] > 0 ) {
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_1 ) {
			if ( n->CSet == 14 ) n->BossPal = ENEM_BPAL_FLASH;
			else n->CSet = ENEM_CSET_FLASH;
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_2 ) {
			if ( n->CSet == 14 ) n->BossPal = n->Misc[ENEM_ORIG_PAL];
			else n->CSet = n->Misc[ENEM_ORIG_PAL];
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_3 ) {
			if ( n->CSet == 14 ) n->BossPal = ENEM_BPAL_FLASH;
			else n->CSet = ENEM_CSET_FLASH;
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_4 ) {
			if ( n->CSet == 14 ) n->BossPal = n->Misc[ENEM_ORIG_PAL];
			else n->CSet = n->Misc[ENEM_ORIG_PAL];
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_5 ) {
			if ( n->CSet == 14 ) n->BossPal = ENEM_BPAL_FLASH;
			else n->CSet = ENEM_CSET_FLASH;
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_6 ) {
			if ( n->CSet == 14 ) n->BossPal = n->Misc[ENEM_ORIG_PAL];
			else n->CSet = n->Misc[ENEM_ORIG_PAL];
		}
	}
	if ( ENEMIES_FLICKER_WHEN_HIT && n->Misc[ENEM_INV_FRAMES] > 0 ) {
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_1 ) {
			n->OriginalTile = ENEM_BLANK_TILE;
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_2 ) {
			n->OriginalTIle = n->Misc[ENEM_ORIG_PAL];
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_3 ) {
			n->OriginalTile = ENEM_BLANK_TILE;
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_4 ) {
			n->OriginalTIle = n->Misc[ENEM_ORIG_PAL];
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_5 ) {
			n->OriginalTile = ENEM_BLANK_TILE;
		}
		if ( n->Misc[ENEM_INV_FRAMES] == ENEM_FLASH_6 ) {
			n->OriginalTIle = n->Misc[ENEM_ORIG_PAL];
		}
	}
}

//Returns if an enemy is invincible.
int EnemyInvincible(npc n){
	return n->Misc[ENEM_INV_FRAMES];
}

//Immediately sets, or resets enemy invincibility to on.
void SetEnemyInvincible(npc n) {
	n->Misc[ENEM_INV_FRAMES] = ENEMY_INVINCIBILITY_FRAMES_DURATION;
}

//Immediately disables mock enemy invincibility. 
void SetEnemyNotInvincible(npc n) {
	n->Misc[ENEM_INV_FRAMES] = 0;
}

Edited by ZoriaRPG, 15 December 2015 - 01:50 PM.


#23 Alucard648

Alucard648

    Adept

  • Members
  • Gender:Male
  • Location:castle Dracula

Posted 16 December 2015 - 05:29 AM

Coming soon with the fourth beta of stdWeapons.zh

Qi7JCWa.png

Guess the item name.



#24 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 16 December 2015 - 06:28 AM

Coming soon with the fourth beta of stdWeapons.zh
Qi7JCWa.png
Guess the item name.


Why, the Gropeshot, of course.

#25 Alucard648

Alucard648

    Adept

  • Members
  • Gender:Male
  • Location:castle Dracula

Posted 16 December 2015 - 06:44 AM

Why, the Gropeshot, of course.

Almost guessed! Think if would fit like it was built-in ZC item.



#26 Dimentio

Dimentio

    Edgy unwanted opinions

  • Members
  • Real Name:Joshua
  • Gender:Male
  • Location:America's Hat.

Posted 16 December 2015 - 07:58 AM

The frosthook? The Iceshot?


  • Alucard648 likes this

#27 Alucard648

Alucard648

    Adept

  • Members
  • Gender:Male
  • Location:castle Dracula

Posted 16 December 2015 - 08:03 AM

The frosthook? The Iceshot?

Direct Hit! It`s the Ice Hookshot!

EDIT: Fourth Beta!

http://www.mediafire...dWeapons1_3.zip

Changelog in readme.

Next weapon will be a really awesome one. Guess what is that!


Edited by Alucard648, 16 December 2015 - 12:32 PM.


#28 Dimentio

Dimentio

    Edgy unwanted opinions

  • Members
  • Real Name:Joshua
  • Gender:Male
  • Location:America's Hat.

Posted 16 December 2015 - 02:38 PM

Hurray! New update! This will be incredibly useful for collision detection for enemies.



#29 ZoriaRPG

ZoriaRPG

    ZC Contributor & Wiki Editor

  • Members
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 17 December 2015 - 05:49 AM

Direct Hit! It`s the Ice Hookshot!

EDIT: Fourth Beta!

http://www.mediafire...dWeapons1_3.zip

Changelog in readme.

Next weapon will be a really awesome one. Guess what is that!

 

The Portable Abei?

 

Perhaps the Pot-Shot? --Really, this is one of my things.



#30 Alucard648

Alucard648

    Adept

  • Members
  • Gender:Male
  • Location:castle Dracula

Posted 17 December 2015 - 06:55 AM

The Portable Abei?

 

Perhaps the Pot-Shot? --Really, this is one of my things.

No, It`s very cold... Keep guessing.


Edited by Alucard648, 17 December 2015 - 08:37 AM.




Also tagged with one or more of these keywords: library, beta

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users