Downloads containing Shaddow3.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Shaddow Game ShaddowBlack0 Single player 6.5 Download file

File preview

//You can change these next 2 variables according to your needs. Unless you know what you are doing, leave the others as they are.
array<int> enemyBosses = { OBJECT::FATCHICK, OBJECT::FLOATLIZARD, OBJECT::RAPIER, OBJECT::PACMANGHOST, OBJECT::HATTER, OBJECT::WITCH, OBJECT::DEVILDEVAN, OBJECT::FENCER };
int BOSS_DISTANCE = 10; //distance from boss in tiles

dictionary defaultBosses = {{OBJECT::BILSY, true}, {OBJECT::BUBBA, true}, {OBJECT::DEVILDEVAN, true}, {OBJECT::QUEEN, true}, 
	{OBJECT::ROBOT, true}, {OBJECT::ROCKETTURTLE, true}, {OBJECT::TUFBOSS, true}, {OBJECT::TWEEDLEBOSS, true}, {OBJECT::UTERUS, true}};
dictionary enemyBehaviorsBackup;
void onLevelLoad()
{
	for(uint i=0; i<enemyBosses.length; i++)
	{
		jjObjectPresets[enemyBosses[i]].energy = 127;
		jjBEHAVIOR behaviorBackup = jjObjectPresets[enemyBosses[i]].behavior;
		enemyBehaviorsBackup.set(enemyBosses[i]+'', behaviorBackup);
		jjObjectPresets[enemyBosses[i]].behavior = function(obj) { obj.behavior = FatChickBoss(); };
	}
}
int nextLevelTimer = -1;
int bossObjId = -1;
int TIMER_TICKS = 210;
int bossesCount = 0;
dictionary defeatedBosses;
class FatChickBoss : jjBEHAVIORINTERFACE
{
	bool initialized = false, finalized = false, isDefaultBoss = false;
	int8 backupEnergy = 127;
	void onBehave(jjOBJ@ obj) 
	{
		if(!initialized)
		{
			//bossesCount++;
			initialized = true;
			defaultBosses.get(obj.eventID+'', isDefaultBoss);
			defeatedBosses.set(obj.objectID+'', false);
		}
	
		jjBEHAVIOR behaviorBackup;
		enemyBehaviorsBackup.get(obj.eventID+'', behaviorBackup);
		obj.behave(behaviorBackup, true);
		
		if(!isDefaultBoss)
		{
			if(backupEnergy != obj.energy)
			{
				if(abs(obj.energy - backupEnergy) > 1)
				{
					obj.energy = backupEnergy - 1;
				}
				else
				{
					backupEnergy = obj.energy;
				}
			}
		}
		else
		{
			for(int i=0; i<jjLocalPlayerCount; i++)
			{
				jjLocalPlayers[i].boss = bossForPlayer[i];
			}
		}
			
		if(obj.energy <= 1)
		{
			if(!finalized)
			{
				bossesCount--;
				finalized = true;
			}
			//deactivate boss
			for(int i=0; i<jjLocalPlayerCount; i++)
			{
				if(bossesCount <= 0) jjLocalPlayers[i].bossActivated = false;
			}
			//to destroy boss, instead of obj.delete(); you can use this to spawn a player bullet at the boss position
			//thus you will see the explosion, the object won't just disappear
			if(obj.energy == 1 && abs(obj.energy - backupEnergy) <= 1)
			{
				defeatedBosses.set(obj.objectID+'', true);
				jjAddObject(OBJECT::BLASTERBULLET, obj.xPos, obj.yPos, 0, CREATOR::PLAYER, BEHAVIOR::BULLET);
			}
			//next level:
			if(nextLevelTimer == -1 && bossesCount <= 0) nextLevelTimer = TIMER_TICKS;
		}
	}
}

bool bossSearchComplete = false;
void onMain()
{
	if(!bossSearchComplete)
	{
		for (int x = 0; x < jjLayerWidth[4]; ++x){
			for (int y = jjLayerHeight[4] - 1; y >= 0; --y){
				uint8 eventID = jjEventGet(x, y);
				for(uint i=0; i<enemyBosses.length; i++){
					if(int(eventID) == enemyBosses[i])
					{
						bossesCount++;
						break;
					}
				}
			}
		}
		bossSearchComplete = true;
	}
	else
	{
		if(nextLevelTimer == -1 && bossesCount <= 0 && jjGameTicks >= 300) nextLevelTimer = TIMER_TICKS;
		if(nextLevelTimer != -1)
		{
			nextLevelTimer--;
			if(nextLevelTimer == 0)
			{
				cycleLevel();
			}
		}
	}
}

void cycleLevel()
{
	for(int i=0; i<jjLocalPlayerCount; i++)
	{
		int x = int(jjLocalPlayers[i].xPos/32);
		int y = int(jjLocalPlayers[i].yPos/32);
		jjEventSet(x, y, AREA::EOL);
	}
}

array<int> bossForPlayer(4, 0);
void onPlayer(jjPLAYER@ play)
{
	if(play.bossActivated == true)
	{
		bool isDefeated = false;
		defeatedBosses.get(play.boss+'', isDefeated);
		if(isDefeated == true)
		{
			play.boss = -1;
			play.bossActivated = false;
		}
	}
	
	if(jjGameTicks % 35 == 0) //only do this each twice per second, not on each tick
	{
		int closestBossDistance = BOSS_DISTANCE * BOSS_DISTANCE * 32 * 32;
		int closestBossIndex = -1;
		array<string> bossesList = defeatedBosses.getKeys();
		for(uint i=0; i<bossesList.length; i++)
		{
			bool isDefeated = false;
			defeatedBosses.get(bossesList[i]+'', isDefeated);
			jjOBJ@ obj = jjObjects[parseInt(bossesList[i])];
			int distance = getDistanceFromObject(obj, play);
			if(!isDefeated && closestBossDistance > distance && obj.energy > 1)
			{
				closestBossDistance = distance;
				closestBossIndex = obj.objectID;
			}
		}
		if(closestBossIndex != -1)
		{
			bossForPlayer[play.localPlayerID] = closestBossIndex;
			play.boss = closestBossIndex;
			play.bossActivated = true;
		}
		else
		{
			play.boss = -1;
			play.bossActivated = false;
		}
	}
}
int getDistanceFromObject(jjOBJ@ obj, jjPLAYER@ play)
{
	return int(abs(obj.xPos - play.xPos)*abs(obj.xPos - play.xPos) + abs(obj.yPos - play.yPos)*abs(obj.yPos - play.yPos));
}