Copy to Clipboard Test

Generic Jumping Enemy Code

//Constant Walk. Every Nth frame, he jumps. His every Mth jtmp is higher than normal.

//Random rate, hunger, homing factor, step speed are used. If Weapon Damage is >0, this enemy will fire eweapon after landing every jump. Also explodes on death.
//Jumping animation uses tiles right below original.
ffc script TweeterSMB2{
	void run(int enemyID){
		npc ghost = Ghost_InitAutoGhost(this, enemyID);
		
		int HF = ghost->Homing;
		int HR = ghost->Haltrate;
		int RR = ghost->Rate;
		int HNG = ghost->Hunger;
		int SPD = ghost->Step;
		int WPND = ghost->WeaponDamage;
		
		int minjump = Ghost_GetAttribute(ghost, 0, 2);//Attribute 0 - normal jump height.
		int maxjump = Ghost_GetAttribute(ghost, 1, 3);//Attribute 1 - max jump height
		int jumpdelay = Ghost_GetAttribute(ghost, 2, 20);//Attribute 2 - delay between jumps, in frames, counted after landing.
		int jumpcount = Ghost_GetAttribute(ghost, 3, 3);//Attribute 3 - every X jump is big one.
		int jumpsfx = Ghost_GetAttribute(ghost, 4, 0);//Jump SFX
		int flags = Ghost_GetAttribute(ghost, 5, 0);//Add together: +1 - whistle kills, +2 - 8 way movement, +4 - no knmockback, +8 - use tiles below original ones for jumping
		int boomondeath = Ghost_GetAttribute(ghost, 6, 0);//>0 - explosion on death, superbomb-sized. Attribute value - explosion damage.
		int sizex =Ghost_GetAttribute(ghost, 7, 1);//Tile width
		int sizey =Ghost_GetAttribute(ghost, 8, 1);//Tile height
		int WPNS = Ghost_GetAttribute(ghost, 9, -1);//EWeapon sprite
		
		ghost->Extend=3;
		Ghost_SetSize(this, ghost, sizex, sizey);
		if (sizex>2 && sizey>2)Ghost_SetHitOffsets(ghost, 8, 8, 8, 8);
		
			bool whistlekill = (flags&1)>0;
		bool eightway = (flags&2)>0;
		bool jumpanim = (flags&8)>0;
		
		Ghost_SetFlag(GHF_NORMAL);
		if (eightway)Ghost_SetFlag(GHF_8WAY);
		if ((flags&4)>0)Ghost_UnsetFlag(GHF_KNOCKBACK);
		
	
		
		int State = 0;
		int haltcounter = -1;
		int jumpcounter = jumpdelay;
		int jc = jumpcount;
		int OldZ=0;
		int origtile = ghost->OriginalTile;
		
		while(true){
			if (State==0){
				if (eightway)haltcounter = Ghost_ConstantWalk8(haltcounter, SPD, RR, HF, HNG);
				else haltcounter = Ghost_ConstantWalk4(haltcounter, SPD, RR, HF, HNG);
				if (jumpcounter<=0 && Ghost_Z==0){
					Game->PlaySound(jumpsfx);
					if (jc==1) Ghost_Jump = maxjump;
					else Ghost_Jump = minjump;
					jc--;
					if (jc==0)jc = jumpcount;
					jumpcounter = jumpdelay;
				}
				else if (Ghost_Z==0){
					if (WPND>0 && OldZ>Ghost_Z){
						eweapon e = FireAimedEWeapon(ghost->Weapon, Ghost_X, Ghost_Y, 0, Cond(ghost->Weapon==EW_BOMBBLAST, 0, 200), WPND, WPNS, -1, EWF_ROTATE);
					}
					jumpcounter--;
				}
				for (int i=1; i<=Screen->NumLWeapons();i++){
					if (whistlekill==0)break;
					lweapon m = Screen->LoadLWeapon(i);
					if (m->ID!=LW_WHISTLE)continue;
					Ghost_HP=0;
				}
			}
			if (Ghost_Z>0 && jumpanim)ghost->OriginalTile = origtile+Cond(eightway, 40, 20);
			else ghost->OriginalTile = origtile;
			OldZ=Ghost_Z;
			if (!Ghost_Waitframe(this, ghost, false, false)){
				if (boomondeath>0) eweapon e = FireAimedEWeapon(EW_SBOMBBLAST, Ghost_X, Ghost_Y, 0, 0, boomondeath, -1, -1, EWF_ROTATE);
				Quit();
			}
		}
	}
}