Downloads containing saldr-devan.asc

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Devan's Revenge (Intro)Featured Download sAlAmAnDeR Single player 9.6 Download file

File preview

class Timer {
	private int inter;
	private int endTime;
	private bool running;
	private int startTime;
	
	Timer() {
		this.running = false;
	}
	
	void start(int interval) {
		if(interval < 0) {
			start();
			return;
		}
		this.inter = interval;
		this.startTime = jjGameTicks;
		this.endTime = this.startTime + this.inter;
		this.running = true;
	}
	
	void start() {
		this.startTime = jjGameTicks;
		this.running = true;
		this.endTime = -1;
		this.inter = -1;
	}
	
	void stop() {
		this.running = false;
	}
	
	bool finished() {
		if(!this.running) return false;
		if(this.endTime == -1) return false;
		return jjGameTicks >= this.endTime;
	}
	
	int elapsedTime() {
		return jjGameTicks-this.startTime;
	}
	
	int getEndTime() {
		return endTime;
	}
	
	int remainingTime() {
		if(this.interval() == -1) return -1;
		return this.interval() - this.elapsedTime();
	}
	
	int interval() {
		return this.inter;
	}
	
	void reset() {
		start(this.inter);
	}
	
	bool isRunning() {
		return this.running;
	}
}

enum DevanAnim {
	DEVIL_FIRE_BREATH = 0,
	STARS = 1,
	FALLING = 2,
	STARS_SQUISH = 3,
	FIREBALL = 4,
	DEVIL_FLY = 5,
	DEVIL_TRANSFORM = 6,
	DEVIL_REVERT = 7,
	IDLE = 8,
	DEVIL_TURN = 9,
	WARP_IN = 10,
	WARP_OUT = 11,
	BLASTER_DISSAPEAR = 12,
	DUCK = 13,
	FIRE = 14,
	BLASTER = 15,
	RUN_JUMP = 16,
	BLASTERBULLET = 17,
	RUN = 18,
	RAISE_GUN = 19,
	FALL = 20,
	IDLE_GUN = 21,
	WARP_IN_GUN = 22,
	WARP_OUT_GUN = 23
}

uint numFrames(DevanAnim anim) {
	switch(anim) {
		case DEVIL_FIRE_BREATH: return 11;
		case STARS: return 6;
		case FALLING: return 2;
		case STARS_SQUISH: return 1;
		case FIREBALL: return 3;
		case DEVIL_FLY: return 11;
		case DEVIL_TRANSFORM: return 38;
		case DEVIL_REVERT: return 14;
		case IDLE: return 4;
		case DEVIL_TURN: return 11;
		case WARP_IN: return 8;
		case WARP_OUT: return 8;
		case BLASTER_DISSAPEAR: return 7;
		case DUCK: return 9;
		case FIRE: return 10;
		case BLASTER: return 8;
		case RUN_JUMP: return 26;
		case BLASTERBULLET: return 8;
		case RUN: return 13;
		case RAISE_GUN: return 3;
		case FALL: return 2;
		case IDLE_GUN: return 4;
		case WARP_IN_GUN: return 8;
		case WARP_OUT_GUN: return 8;
	}
	return 0;
}

class Position {
	float xPos;
	float yPos;
	
	void get(jjPLAYER@ player) {
		xPos = player.xPos;
		yPos = player.yPos;
	}
	
	void set(jjPLAYER@ player) {
		player.xPos = xPos;
		player.yPos = yPos;
	}
}

DevanShell@ devanPlayer;
class DevanShell : COMMON::IFocalPoint {
	private jjPLAYER@ play;
	private bool shooting = false;
	bool canFire = true;
	private bool ducking = false;
	private bool jumping = true;
	private bool falling = false;
	private bool special = false;
	private bool devilMode = false;
	private bool reverting = false;
	private bool warpingOut = false;
	private bool warpingIn = false;
	private bool stars = false;
	private bool growArms = false;
	private bool gunMagic = false;
	private bool raiseGun = false;
	private Timer animTimer();
	private Timer idleTimer();
	private Timer devilTimer();
	private Position oldPos();
	
	private DevanAnim anim;
	private uint frame;
	
	bool allowInput = true;
	
	DevanShell(jjPLAYER@ play) {
		@this.play = @play;
		play.fastfire = 6;
		jjOBJ@ obj = jjObjects[jjAddObject(OBJECT::CARROT, 0,0)];
		obj.determineCurAnim(ANIM::DEVILDEVAN,0,false);
		obj.determineCurAnim(ANIM::DEVAN,0,false);
		jjWeapons[1].defaultSample = false;
		jjObjectPresets[OBJECT::BLASTERBULLET].var[6] = jjObjectPresets[OBJECT::BLASTER].var[6] | 2 | 8;
	}
	
	float get_xPos() const { return play.xPos; }
	float get_yPos() const { return play.yPos; }
	bool  get_isActive() const { return true; }
	
	float get_xSpeed() { return play.xSpeed; }
	float get_ySpeed() { return play.ySpeed; }
	void set_xSpeed(float xSpeed) { play.xSpeed = xSpeed; }
	void set_ySpeed(float ySpeed) { play.ySpeed = ySpeed; }

	void update() {
		play.spriteMode = SPRITE::Mode::INVISIBLE; //Make player invisible
		if(!idleTimer.isRunning() && jjGameTicks > 1) idleTimer.start(1200);
		
		if(warpingOut) { warpingOut = playAnim(DevanAnim::WARP_OUT);}
		else if(warpingIn) { warpingIn = playAnim(DevanAnim::WARP_IN);}
		else if(!devilMode) {
			if(idleTimer.finished()) {
				randomIdleAnimation();
				idleTimer.reset();
			}
			
			//Idle animations
			if(growArms) { handleGrowArms(); }
			else if(gunMagic) { handleGunMagic(); }
			
			//Actions
			else if(raiseGun)		{handleRaiseGun();}
			else if(reverting) 		{handleRevert();  }
			else if(shooting)       {handleShooting();}
			else if(jumping)  		{handleJumping(); }
			else if(ducking)  		{handleDucking(); }
			else if(special)  		{handleSpecial(); }
			else if(stars)    		{handleStars();   }
			else if(play.xSpeed == 0) {
				anim = DevanAnim::IDLE;
				frame = (jjGameTicks/9)%7;
			} else {
				int speed;
				if(play.running) 
					if(abs(play.xSpeed) <= 16) speed = 4;
					else speed = 2;
				else
					speed = 8;

				anim = DevanAnim::RUN;
				frame = (jjGameTicks/speed)%13;
			}
			
		} else {
			if(shooting) {handleShootingDevil();}
			else { 
				anim = DevanAnim::DEVIL_FLY; 
				frame = animTimer.elapsedTime()/7; 
				play.fly = FLIGHT::FLYCARROT;
			}
			
			if(devilTimer.isRunning())
				jjDrawString(int(p.xPos-16), int(p.yPos-64), devilTimer.remainingTime() + "");
			if(devilTimer.finished()) {
				jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_VANISH1);
				devilTimer.stop();
				animTimer.start();
				play.fly = FLIGHT::NONE;
				oldPos.get(play);
				reverting = true;
				devilMode = false;
			}
		}
		drawSprite(anim, frame);
		/*if(!warpingOut && jjEventGet(play.xPos/32,play.yPos/32) == AREA::WARP) {jjDebug("WARP");warpingOut = true; animTimer.start();}
		if(jjEventGet(play.xPos/32,play.yPos/32) == AREA::WARPTARGET) {jjDebug("WARPTARGET");warpingIn = true;warpingOut=false; animTimer.start();}
		if(jjEventGet(play.xPos/32,play.yPos/32) == AREA::VINE) jjDebug("VINE");
		if(jjEventGet(play.xPos/32,play.yPos/32) == AREA::HPOLE) jjDebug("HPOLE");
		if(jjEventGet(play.xPos/32,play.yPos/32) == AREA::VPOLE) jjDebug("VPOLE");
		if(jjEventGet(play.xPos/32,play.yPos/32) == OBJECT::REDSPRING) jjDebug("REDSPRING");
		if(jjEventGet(play.xPos/32,play.yPos/32) == OBJECT::GREENSPRING) jjDebug("GREENSPRING");
		if(jjEventGet(play.xPos/32,play.yPos/32) == OBJECT::BLUESPRING) jjDebug("BLUESPRING");
		if(jjEventGet(play.xPos/32,play.yPos/32) == OBJECT::HORREDSPRING) jjDebug("HORREDSPRING");
		if(jjEventGet(play.xPos/32,play.yPos/32) == OBJECT::HORGREENSPRING) jjDebug("HORGREENSPRING");
		if(jjEventGet(play.xPos/32,play.yPos/32) == OBJECT::HORBLUESPRING) jjDebug("HORBLUESPRING");
		if(jjEventGet(play.xPos/32,play.yPos/32) == OBJECT::COPTER) jjDebug("COPTER");*/
	}
	
	bool playAnim(DevanAnim devanAnim) {
		anim = devanAnim;
		frame = animTimer.elapsedTime()/7;
		return frame < numFrames(anim);
	}
	
	bool onGround() {
		return jjMaskedHLine(int(player.xPos-12),24,int(player.yPos+21)) || player.platform > 0;
	}
	
	/*bool onGround() {
		return play.ySpeed == 0;
	}*/
	
	void randomIdleAnimation() {
		idleTimer.stop();
		stars = false;
		int rand = jjRandom() % 3;
		animTimer.start();
		if(rand == 0) {
			growArms = true;
		} else if(rand == 1) {
			gunMagic = true;
		} else if(rand == 2) {
			jjSample(play.xPos, play.yPos, SOUND::P2_POEP);
			stars = true;
		}
	}
	
	void handleShooting() {
		anim = DevanAnim::FIRE;
		if((animTimer.elapsedTime()/8) < 4) {
			frame = (animTimer.elapsedTime()/8);
		} else {
			int bigBlast = (((animTimer.elapsedTime()/(play.fastfire-3))-4)%2);
			frame = max(0,bigBlast+5);
			
			if(bigBlast == 0) {
				if(canFire) {
					play.fireBullet(WEAPON::CURRENT,true,true,p.direction == -1 ? DIRECTION::LEFT : DIRECTION::RIGHT); 
					canFire = false;
				}
			} else { 
				canFire = true;
			}
		}
	}
	
	void handleDucking() {
		anim = DevanAnim::DUCK;
		if((animTimer.elapsedTime()/7) < 5) {
			frame = (animTimer.elapsedTime()/7);
		} else {
			frame = 5;
		}
	}
	
	void handleJumping() {
		if(onGround()) jumping = false;
		anim = DevanAnim::RUN_JUMP;
		if(!falling) {
			frame = 18;
			if(play.ySpeed > 0) {
				animTimer.start();
				falling = true;
			} 
		} else {
			frame = min(22,(animTimer.elapsedTime()/7)+18);
		}
	}
	
	void handleSpecial() {
		anim = DevanAnim::DEVIL_TRANSFORM;
		frame = animTimer.elapsedTime()/7;
		if(frame < numFrames(DevanAnim::DEVIL_TRANSFORM)) {
			if(frame == 0)
				jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_STRETCH1);
			else if(frame == 7)
				jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_STRECH2);
			else if(frame == 12)
				jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_STRETCH3);
			else if(frame == 22)
				jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_STRECHTAIL);
			else if(frame == 28)
				jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_WINGSOUT);
		} else {
			jjDebug("S=F1");
			devilMode = true;
			special = false;
			devilTimer.start(700);
		}
	}
	
	void handleShootingDevil() {
		anim = DevanAnim::DEVIL_FIRE_BREATH;
		frame = (animTimer.elapsedTime()/7);
		if(frame > numFrames(DevanAnim::DEVIL_FIRE_BREATH)) {
			animTimer.reset();
		}
		if(frame == 8) {
			if(canFire) {
				float direction = play.direction == 1 ? .75 * pi : 1.25 * pi;
				
				play.fireBullet(WEAPON::TOASTER,false,false,direction);
				canFire = false;
			}
		} else canFire = true;
	}
	
	void handleRevert() {
		frame = animTimer.elapsedTime()/7;
		special = true;
		if(onGround()) {
			jjDebug("S=F2");
			special = false;
			stars = true;
			reverting = false;
			devilMode = false;
			idleTimer.reset();
			return;
		}
		if(frame < numFrames(DevanAnim::DEVIL_REVERT)) {
			oldPos.set(play);
			play.xSpeed = play.ySpeed = play.xAcc = play.yAcc = 0;
			anim = DevanAnim::DEVIL_REVERT;
		} else {
			anim = DevanAnim::FALLING;
		}
	}
	
	void handleStars() {
		anim = DevanAnim::STARS;
		frame = animTimer.elapsedTime()/7;
	}
	
	void handleGrowArms() {
		int tick = animTimer.elapsedTime()/7;
		anim = DevanAnim::DEVIL_TRANSFORM;
		
		int animLen = 10;//or 14 maybe
		int shakeLen = 16;
		
		if(tick < animLen) {
			frame = tick;
		} else if(tick < animLen + shakeLen) {
			frame = tick % 2 + animLen;
		} else if(tick < 2*animLen+shakeLen+1) {
			frame = 2*animLen+shakeLen-tick;
		} else 
			growArms = false;
		
		if(frame == 0)
			jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_STRETCH1);
		else if(frame == 7)
			jjSample(play.xPos, play.yPos, SOUND::DEVILDEVAN_STRECH2);
		else if(tick == 14 && animTimer.elapsedTime()%7 == 0)
			jjSample(p.xPos,p.yPos,SOUND::DEVILDEVAN_LAUGH);
	}
	
	void handleGunMagic() {
		uint tick = animTimer.elapsedTime()/10;
		anim = DevanAnim::BLASTER_DISSAPEAR;
		
		if(tick < numFrames(DevanAnim::BLASTER_DISSAPEAR)) {
			frame = tick;
		}  else {
			gunMagic = false;
		}
		if(tick == 4 && animTimer.elapsedTime() % 10 == 0)
			jjSample(p.xPos,p.yPos,SOUND::COMMON_ITEMTRE);
	}
	
	void handleRaiseGun() {
		int startFrame = 6;
		uint tick = animTimer.elapsedTime()/8 + startFrame;
		anim = DevanAnim::FIRE;
		
		if(tick < numFrames(DevanAnim::FIRE)) {
			frame = tick;
		}  else {
			raiseGun = false;
		}
	}
	
	void drawSprite(uint anim, uint frame) {
		if((play.blink/2) % 4 == 0 || (play.blink/2) % 4 == 1)
			if(play.direction > 0)
				jjDrawSprite(int(play.xPos+10),int(play.yPos-16),ANIM::DEVILDEVAN,anim,frame,play.direction);
			else
				jjDrawSprite(int(play.xPos-10),int(play.yPos-16),ANIM::DEVILDEVAN,anim,frame,play.direction);
	}
	
	void handleInput() {
		if(special || !allowInput) {
			play.keyFire = play.keyDown = play.keyJump = play.keyLeft = 
			play.keyRight = play.keyRun = play.keySelect = play.keyUp = false;
		}
		if(!devilMode) {
			if(play.keyDown && onGround()) {
				if(ducking == false) animTimer.start();
				ducking = true;
			} else {
				ducking = false;
				play.keyDown = false;
			}
			if(play.keyJump && !play.keyFire && !jumping) {
				jumping = true;
				falling = false;
			}
			if(play.keyDown && onGround() && play.keyJump) {
				play.keyJump = false;
				play.keyDown = false;
				if(special == false) animTimer.start();
				special = true;
				jumping = false;
				shooting = false;
				ducking = false;
			} //else {special = false;} //TODO: Why was this here? 

			if(play.keyFire || play.keyDown || play.keyJump || play.keyLeft || 
			   play.keyRight || play.keyRun || play.keySelect || play.keyUp) {
			    stars = false;
				growArms = false;
				gunMagic = false;
				raiseGun = false;
				idleTimer.reset();
			}
		}
		if(!play.keyFire && shooting) {
			animTimer.reset();
			raiseGun = true;
		}
		if(play.keyFire) {
			play.keyFire = false;
			if(shooting == false) animTimer.start();
			shooting = true;
			return;
		} else shooting = false;
	}
	
	bool get_isDevil() {
		return this.devilMode;
	}
	
	jjPLAYER@ get_player() {
		return this.play;
	}
}

class DevanBlasterBullet : CUSTOM::Object {
	DevanBlasterBullet(jjOBJ@ object) {
		super(object);
		yPos = yPos -16;
		xPos = direction*15 + xPos;
		xSpeed = xSpeed * .9;
		ySpeed = ySpeed * .9;
		jjSample(xPos, yPos, SOUND::DEVILDEVAN_PHASER2);
	}
	
	void behavior() {
		if(state != STATE::EXPLODE) {
			jjDrawSprite(int(xPos),int(yPos),ANIM::DEVILDEVAN,DevanAnim::BLASTERBULLET,(jjGameTicks/9)%9,direction);
			behave(BEHAVIOR::BULLET,false);
		} else
			behave(BEHAVIOR::BULLET,true);
	}
}
CUSTOM::Object@ devanBlaster(jjOBJ@ object) {return DevanBlasterBullet(object);}

class DevanFireBreath : CUSTOM::Object {
	DevanFireBreath(jjOBJ@ object) {
		super(object);
		yPos = yPos - 12;
		xPos = direction*32+ xPos;
		jjSample(xPos, yPos,SOUND::DEVILDEVAN_DRAGONFIRE);
	}
	
	void behavior() {
		if(state != STATE::EXPLODE) {
			jjDrawSprite(int(xPos),int(yPos),ANIM::DEVILDEVAN,DevanAnim::FIREBALL,(jjGameTicks/9)%3,direction);
			behave(BEHAVIOR::BULLET,false);
		} else
			behave(BEHAVIOR::BULLET,true);
	}
}
CUSTOM::Object@ devanFireBreath(jjOBJ@ object) {return DevanFireBreath(object);}

void onPlayerInput(jjPLAYER@ play) {
	if(jjGameTicks < 70) {
		play.keyFire = play.keyDown = play.keyJump = play.keyLeft = 
			play.keyRight = play.keyRun = play.keySelect = play.keyUp = false;
	}
	if(devanPlayer !is null && play is devanPlayer.player) devanPlayer.handleInput();
}

class DevanLivesUI : CUSTOM::IInterfaceElement {
	private DevanShell@ devanPlayer;
	
	DevanLivesUI(DevanShell@ shell) {
		@this.devanPlayer = shell;
	}
	
	void draw(jjPLAYER@ player, jjCANVAS@ canvas) {
		if(devanPlayer !is null && player is devanPlayer.player) {
			if(devanPlayer.isDevil) {
				canvas.drawSprite(int(24),int(.95 * jjSubscreenHeight), ANIM::DEVILDEVAN,DevanAnim::DEVIL_FLY,jjRenderFrame/7,0,SPRITE::RESIZED, 16);
				canvas.drawString(int(32),int(.972 * jjSubscreenHeight),"x666", STRING::MEDIUM, STRING::NORMAL);
			} else {
				canvas.drawSprite(int(16),int(.95 * jjSubscreenHeight), ANIM::DEVAN,1,0,0,SPRITE::RESIZED, 26);
				canvas.drawString(int(32),int(.972 * jjSubscreenHeight),"x^", STRING::MEDIUM, STRING::NORMAL);
			}
		}
	}
}

class DevanBlasterUI : CUSTOM::IInterfaceElement {
	private	DevanShell@ devanPlayer;
	
	DevanBlasterUI(DevanShell@ shell) {
		@this.devanPlayer = shell;
	}
	
	void draw(jjPLAYER@ player, jjCANVAS@ canvas) {
		if(player.currWeapon == WEAPON::BLASTER) { 
				canvas.drawSprite(int(.865 * jjSubscreenWidth),  int(.97 * jjSubscreenHeight + jjSin(jjRenderFrame << 5)*2),ANIM::DEVILDEVAN,DevanAnim::BLASTER,7,0);
				//canvas.drawSprite(int(.86 * jjSubscreenWidth), int(.97 * jjSubscreenHeight + jjSin(jjRenderFrame << 5)*2),ANIM::DEVILDEVAN,DevanAnim::BLASTER,0-jjRenderFrame/7);
				canvas.drawString(int(.875 * jjSubscreenWidth),  int(.972 * jjSubscreenHeight),"x^", STRING::MEDIUM, STRING::NORMAL);
			}
	}
}

class DevanFireBreathUI : CUSTOM::IInterfaceElement {
	private	DevanShell@ devanPlayer;
	
	DevanFireBreathUI(DevanShell@ shell) {
		@this.devanPlayer = shell;
	}
	
	void draw(jjPLAYER@ player, jjCANVAS@ canvas) {
		if(devanPlayer !is null && player is devanPlayer.player) {
			if(devanPlayer.isDevil) {
				canvas.drawSprite(int(.865 * jjSubscreenWidth),  int(.97 * jjSubscreenHeight + jjSin(jjRenderFrame << 5)*2),ANIM::DEVILDEVAN,DevanAnim::FIREBALL,jjRenderFrame/7,0);
				canvas.drawString(int(.875 * jjSubscreenWidth),  int(.972 * jjSubscreenHeight),"x^", STRING::MEDIUM, STRING::NORMAL);
			}
		} 
	}
}