Copy to Clipboard Test

FF Dodongo Code

const int SFX_FFDODONGO_BOMB_SWALLOW = 0;//Sound to play when Dodongo swallows a bomb

const int FFDODONGO_BOMB_HITBOX_MARGIN = 4;//Hitbox margin for Dodongo/bomb interaction.

//FF Dodongo
//Extended variant of Dodongo. Walks around, fires eweapons straightforward. Invincible by default. You can either feed him bombs, or stun him by causing the monster to walk into smoke cloud created by explosion, afterward he will be vulnerable for short period of time.

//Step speed, Homing factor, hunger, random rate used. Tile setup is similar to engine Dodongo, up/down direction in the same row, rest are below. Defenses that are set in enemy editor used when Dodongo is stunned.

ffc script FFDodongo{
	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 sizex = Ghost_GetAttribute(ghost, 0, 1);//Enemy X size, in tiles
		int sizey = Ghost_GetAttribute(ghost, 1, 2);//Enemy Y size, in tiles
		int smokestun = Ghost_GetAttribute(ghost, 2, 120);//Duration of the stun caused by walking into smoke caused by explosion. ("Dodongo dislikes smoke"). 0 for immunity to this effect.
		int Swallowdamage  = Ghost_GetAttribute(ghost, 3, 4);//Damage dealt to Dodongo by feeding him a noemal bomb. 
		int SSwallowdamage  = Ghost_GetAttribute(ghost, 4, 16);//Damage dealt to Dodongo by feeding him a super bomb. 
		int stundropset = Ghost_GetAttribute(ghost, 5, 5);//Item dropset used to generate item dropped by Dodongo when killed while stunned.
		int shotdelay = Ghost_GetAttribute(ghost, 6, 90);//Delay between shooting eweapons, in frames.
		int WPNS = Ghost_GetAttribute(ghost, 7, -1);// Eweapon sprite.
		int stunframe = Ghost_GetAttribute(ghost, 8, ghost->OriginalTile+8);//Frames used to render Dodongo swallowing an explosive, exact the same setup for walking Dodongo.
		int finalboom = Ghost_GetAttribute(ghost, 9, 0);//Power (and damage) of explosion generated by Dodongo on death, 0 for no explosion, <0 for fake explosion, >=8 for superbomb boom.
		
		
		ghost->Extend=3;
		Ghost_SetSize(this, ghost, sizex, sizey);
		Ghost_SetHitOffsets(ghost, 4, 4, 4, 4);
		
		Ghost_SetFlag(GHF_NORMAL);
		
		int OrigTile = ghost->OriginalTile;
		int State = 0;
		int statecounter = 0;
		int haltcounter = -1;
		int shootcounter = shotdelay;
		int origdrop = ghost->ItemSet;
		lweapon l;
		eweapon e;
		int swallowdam = 0;
		
		int coll[4] = {0,0,0,0};
		
		int defs[18];
		Ghost_StoreDefenses(ghost,defs);
		Ghost_SetAllDefenses(ghost, NPCDT_BLOCK);
		ghost->Defense[NPCD_SBOMB]=NPCDT_IGNORE;
		ghost->Defense[NPCD_BOMB]=NPCDT_IGNORE;
		
		while(true){
			if (State==0){
				haltcounter = Ghost_ConstantWalk4(haltcounter, SPD, RR, HF, HNG);
				if (Ghost_Dir>1)Ghost_SetSize(this, ghost, sizey, sizex);
				else Ghost_SetSize(this, ghost, sizex, sizey);
				UpdateDodongoSpecialCollision(coll);
				if (Ghost_Dir<2)Ghost_SetSize(this, ghost, sizex, sizey);
				else Ghost_SetSize(this, ghost, sizey, sizex);
				Ghost_SetHitOffsets(ghost, 4, 4, 4, 4);
				for (int i=1;i<=Screen->NumLWeapons();i++){
					l = Screen->LoadLWeapon(i);
					// Screen->Rectangle(3, l->X+FFDODONGO_BOMB_HITBOX_MARGIN, l->Y+FFDODONGO_BOMB_HITBOX_MARGIN, l->X+15-FFDODONGO_BOMB_HITBOX_MARGIN, l->Y+15-FFDODONGO_BOMB_HITBOX_MARGIN,1, 1, 0, 0, 0,false, OP_OPAQUE);
					if (!RectCollision(l->X+FFDODONGO_BOMB_HITBOX_MARGIN, l->Y+FFDODONGO_BOMB_HITBOX_MARGIN,l->X+15-FFDODONGO_BOMB_HITBOX_MARGIN, l->Y+15-FFDODONGO_BOMB_HITBOX_MARGIN,coll[0],coll[1],coll[2],coll[3])) continue;
					if (l->ID==LW_BOMB || l->ID==LW_SBOMB){
						Game->PlaySound(SFX_FFDODONGO_BOMB_SWALLOW);
						statecounter = 90;
						State=1;
						if (l->ID==LW_SBOMB) swallowdam = SSwallowdamage;
						else swallowdam = Swallowdamage;
						Remove(l);
					}
					if (l->ID==LW_BOMBBLAST || l->ID==LW_SBOMBBLAST){
						if (smokestun<=0) continue;
						statecounter = smokestun;
						State=2;
						Ghost_SetDefenses(ghost,defs);
						ghost->ItemSet = stundropset;
					}
				}
				shootcounter--;
				if (shootcounter<=0){
					shootcounter = shotdelay;
					if (WPND>0)e =  FireNonAngularEWeapon(ghost->Weapon, coll[0], coll[1], Ghost_Dir, 200, WPND, WPNS, -1, 0);
				}
			}
			if (State==1){
				statecounter--;
				if (statecounter<=0){
					Ghost_HP-=swallowdam;
					State=0;
				}
			}
			if (State==2){
				statecounter--;
				if (statecounter<=0){
					Ghost_SetAllDefenses(ghost, NPCDT_BLOCK);
					ghost->Defense[NPCD_SBOMB]=NPCDT_IGNORE;
					ghost->Defense[NPCD_BOMB]=NPCDT_IGNORE;
					ghost->ItemSet = origdrop;
					State=0;
				}
			}
			// Screen->Rectangle(3, coll[0], coll[1], coll[2], coll[3],1, 1, 0, 0, 0,false, OP_OPAQUE);
			DodongoAnimation(ghost, OrigTile, State,stunframe, sizex, sizey);
			if (!Ghost_Waitframe(this, ghost, false, false)){
				if (finalboom!=0){
					e = FireNonAngularEWeapon(Cond(finalboom>=8, EW_SBOMBBLAST,EW_BOMBBLAST), CenterX(ghost)-8, CenterY(ghost)-8, Ghost_Dir, 0, Abs(finalboom), WPNS, -1, 0);
					if (finalboom<0)e->CollDetection=false;
				}
				Quit();
			}
		}
	}
}

void UpdateDodongoSpecialCollision(int coll){
	if (Ghost_Dir==DIR_UP){
		coll[0] = Ghost_X+Ghost_TileWidth*8-8;
		coll[1] = Ghost_Y;
		coll[2] = Ghost_X+Ghost_TileWidth*8+8;
		coll[3] = Ghost_Y+15;
	}
	if (Ghost_Dir==DIR_DOWN){
		coll[0] = Ghost_X+Ghost_TileWidth*8-8;
		coll[1] = Ghost_Y+Ghost_TileHeight*16-16;
		coll[2] = Ghost_X+Ghost_TileWidth*8+8;
		coll[3] = Ghost_Y+Ghost_TileHeight*16;
	}
	if (Ghost_Dir==DIR_LEFT){
		coll[0] = Ghost_X;
		coll[1] = Ghost_Y+Ghost_TileHeight*8-8;
		coll[2] = Ghost_X+16;
		coll[3] = Ghost_Y+Ghost_TileHeight*8+8;
	}
	if (Ghost_Dir==DIR_RIGHT){
		coll[0] = Ghost_X+Ghost_TileWidth*16-16;
		coll[1] = Ghost_Y+Ghost_TileHeight*8-8;
		coll[2] = Ghost_X+Ghost_TileWidth*16;
		coll[3] = Ghost_Y+Ghost_TileHeight*8+8;
	}
}



void DodongoAnimation(npc ghost, int origtile, int State, int stunframe, int sizex, int sizey){
	int offset = 0;
	if (Ghost_Dir==DIR_UP){
		offset = 0;
	}
	if (Ghost_Dir==DIR_DOWN){
		offset = sizex*4;
	}
	if (Ghost_Dir==DIR_LEFT){
		offset = sizey*20;
	}
	if (Ghost_Dir==DIR_RIGHT){
		offset = sizey*20+sizex*20;
	}
	if (State==1)ghost->OriginalTile = stunframe + offset;
	else ghost->OriginalTile = origtile + offset;
}