Downloads containing ScaryMonsters.asc

Downloads
Name Author Game Mode Rating
JJ2 1.23 vanilla: Miscellaneous stuff Violet CLM Multiple N/A Download file

File preview

#pragma require "ScaryMonsters.asc"
#pragma require "ScaryMonsters.j2a"

namespace ScaryMonsters {
	void BeAClown(uint8 eventID) {
		jjOBJ@ preset = jjObjectPresets[eventID];
		preset.behavior = Clown;
		preset.playerHandling = HANDLING::ENEMY;
		preset.scriptedCollisions = false;
		preset.bulletHandling = HANDLING::HURTBYBULLET;
		preset.energy = 100;
		preset.isTarget = true;
		preset.isBlastable = true;
		preset.isFreezable = true;
		preset.triggersTNT = true;
		preset.points = 500;
		preset.counter = 0;
		preset.state = STATE::START;
		preset.killAnim = jjAnimSets[ANIM::AMMO] + 81;
		preset.curAnim = jjAnimSets[ANIM::CUSTOM[0]].load(0, "ScaryMonsters.j2a");
		preset.curFrame = jjAnimations[preset.curAnim];
		preset.frameID = 0;
	}
	const int ClownFrequency = 6000;
	void Clown(jjOBJ@ obj) {
		++obj.counter;
		if (obj.energy < 100 && obj.bulletHandling == HANDLING::HURTBYBULLET) { //hurt!
			jjOBJ@ ball = jjObjects[jjAddObject(obj.eventID, obj.xPos, obj.yPos - 4, obj.objectID, CREATOR::OBJECT, ClownBall)];
			ball.xSpeed = obj.xSpeed * 3 * obj.direction;
			if (ball.xSpeed == 0)
				ball.behavior = BEHAVIOR::BOUNCEONCE;
			ball.curAnim = obj.curAnim;
			ball.determineCurFrame();
			ball.ySpeed = -3;
			ball.energy = 1;
			ball.points = 100;
			
			obj.bulletHandling = HANDLING::IGNOREBULLET;
			obj.counter = 0;
			if (obj.state == STATE::FREEZE)
				obj.unfreeze(0);
			obj.state = STATE::FALL;
			obj.xSpeed = obj.direction * -3;
			obj.xAcc = obj.direction / 24.f;
			obj.ySpeed = -2;
			obj.yPos -= 30;
			obj.curFrame = jjAnimations[obj.curAnim += 3];
			obj.creatorType = CREATOR::OBJECT; //don't come back to life anymore if deactivated
		} else switch (obj.state) {
			case STATE::START:
				obj.putOnGround(false);
				obj.var[0] = jjMaskedTopVLine(int(obj.xPos), int(obj.yPos) - 40, 50);
				obj.state = STATE::ROTATE;
				obj.direction = 1;
				break;
			case STATE::DEACTIVATE:
				obj.deactivate();
				break;
			case STATE::FREEZE:
				--obj.counter;
				if (--obj.freeze == 0)
					obj.state = obj.oldState;
				if (obj.oldState != STATE::WAIT && obj.oldState != STATE::FALL)
					jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, jjAnimations[obj.curAnim], obj.direction);
				jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, SPRITE::FROZEN);
				break;
			case STATE::ROTATE: {
				const auto sine = jjSin(obj.counter << 1);
				obj.xSpeed = sine * (3 + jjDifficulty / 2.f);
				const float targetX = obj.xPos + obj.xSpeed * obj.direction;
				if (jjMaskedTopVLine(int(targetX), int(obj.yPos) - 40, 50) == obj.var[0] && jjEventAtLastMaskedPixel != AREA::STOPENEMY)
					obj.xPos = targetX;
				else {
					obj.direction = -obj.direction;
					jjSample(obj.xPos, obj.yPos, SOUND::Sample(SOUND::SPAZSOUNDS_HAHAHA + (jjRandom() & 1)), 0, ClownFrequency);
				}
				obj.xAcc += sine;
				obj.frameID = int(obj.xAcc) / 4;
				obj.curAnim += 1;
				obj.determineCurFrame(true);
				obj.curAnim -= 1;
				jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.determineCurFrame(false), obj.direction);
				const int angle = int(sine * obj.direction * 96);
				const float asin = jjSin(angle), acos = jjCos(angle);
				const int xdiff = 6 * obj.direction;
				jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, angle, obj.direction,1, obj.justHit == 0 ? SPRITE::NORMAL : SPRITE::SINGLECOLOR, 15);
				jjDrawSpriteFromCurFrame(obj.xPos - (asin * 33 + acos * xdiff), obj.yPos - (acos * 33 - asin * xdiff), jjAnimations[obj.curAnim + 5] + ((jjGameTicks >> 2) % 12), obj.direction);
				if (obj.counter == 256) {
					obj.counter = 0;
					obj.state = STATE::ATTACK;
				}
				break; }
			case STATE::ATTACK:
				obj.curFrame = jjAnimations[obj.curAnim + 2] + obj.counter / 10;
				jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, jjAnimations[obj.curAnim], obj.direction);
				jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction);
				if (obj.counter == 20) {
					jjSample(obj.xPos, obj.yPos, SOUND::SPAZSOUNDS_HIHI, 0, ClownFrequency * 3 / 5);
					jjOBJ@ bomb = jjObjects[obj.fireBullet(OBJECT::BOMB)];
					bomb.curAnim = obj.curAnim + 6;
					bomb.xSpeed = obj.direction * 2.5;
					bomb.ySpeed = -3;
					bomb.state = STATE::FLY;
					if (jjDifficulty > 2) {
						bomb.playerHandling = HANDLING::ENEMYBULLET;
						bomb.animSpeed = 1;
					}
				} else if (obj.counter == 49) {
					obj.counter = 0;
					obj.state = STATE::ROTATE;
				}
				break;
			case STATE::FALL: {
				if ((obj.xSpeed > 0) == (obj.direction == -1)) {
					const float targetX = obj.xPos + (obj.xSpeed += obj.xAcc);
					if (!jjMaskedVLine(int(targetX), int(obj.yPos) - 12, 24))
						obj.xPos = targetX;
					else
						obj.xSpeed = obj.xAcc = 0;
				}
				const float targetY = obj.yPos + (obj.ySpeed += 0.09);
				if (!jjMaskedHLine(int(obj.xPos) - 24, 24, int(targetY) + 18)) {
					obj.yPos = targetY;
					if (obj.counter == 20)
						++obj.curFrame;
				} else {
					obj.curFrame = jjAnimations[obj.curAnim] + 2;
					obj.state = STATE::WAIT;
					obj.counter = 0;
				}
				jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction, obj.justHit == 0 ? SPRITE::NORMAL : SPRITE::SINGLECOLOR, 15);
				break; }
			case STATE::WAIT:
				jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame, obj.direction);
				if (obj.counter == 35)
					obj.curFrame += 1;
				else if (obj.counter == 50) {
					jjSample(obj.xPos, obj.yPos, SOUND::Sample(SOUND::SPAZSOUNDS_HAHAHA + (jjRandom() & 1)), 0, ClownFrequency);
					obj.bulletHandling = HANDLING::HURTBYBULLET;
					obj.curAnim += 1;
					obj.frameID = 0;
					obj.determineCurFrame();
					obj.state = STATE::WALK;
					obj.behavior = BEHAVIOR::WALKINGENEMY;
					obj.xSpeed = 4;
					obj.xAcc = 0;
					obj.energy = (jjDifficulty > 2) ? 4 : 3;
				}
				break;
		}
	}
	void ClownBall(jjOBJ@ obj) { //minimally edited from BEHAVIOR::TURTLESHELL to avoid killing enemies


		if (obj.state==STATE::START)
			obj.state=STATE::FLY;
		else if (obj.state==STATE::KILL || obj.state==STATE::DEACTIVATE)
			obj.delete();
		else if (obj.state == STATE::FREEZE) {
			if (--obj.freeze == 0)
				obj.state = STATE::FLY;
		} else {
			if (abs(obj.xSpeed) > 2) {
				if (obj.yPos>jjWaterLevel)
				{
					obj.xSpeed=(obj.xSpeed*7)/8;
					obj.ySpeed=(obj.ySpeed*7)/8;
				}
				else
					obj.xSpeed=(obj.xSpeed*63)/64;
			}

			obj.xPos+=obj.xSpeed;
			obj.yPos+=obj.ySpeed;



			const bool nogoup=jjMaskedPixel(int(obj.xPos),int(obj.yPos)-4);
			const bool nogodown=jjMaskedPixel(int(obj.xPos),int(obj.yPos)+10);
			const bool nogoleft=jjMaskedPixel(int(obj.xPos)-8,int(obj.yPos));
			const bool nogoright=jjMaskedPixel(int(obj.xPos)+8,int(obj.yPos));
			int calc, calc2;

			if ((obj.xSpeed>0) && nogoright)
			{
				calc=1+int(obj.xSpeed);

				calc2=jjMaskedTopVLine(int(obj.xPos+8),int(obj.yPos)+10-calc,calc);

				if ((calc2<=1) || (calc2>=calc))
				{
					obj.xPos-=obj.xSpeed;
					obj.xSpeed=-obj.xSpeed;
				} else
				{
					obj.yPos-=calc;
					obj.xSpeed=(obj.xSpeed*15)/16;
				};
			} else
			if ((obj.xSpeed<0) && nogoleft)
			{
				calc=1-int(obj.xSpeed);

				calc2=jjMaskedTopVLine(int(obj.xPos-8),int(obj.yPos)+10-calc,calc);

				if ((calc2<=1) || (calc2>=calc))
				{
					obj.xPos-=obj.xSpeed;
					obj.xSpeed=-obj.xSpeed;
				} else
				{
					obj.yPos-=calc;
					obj.xSpeed=(obj.xSpeed*15)/16;
				};
			};

			if (nogoup && (obj.ySpeed<0))
			{
				obj.yPos-=obj.ySpeed; //reset to last location!
				obj.ySpeed=-obj.ySpeed/2;
			} else
			if (nogodown)
			{
				calc=jjMaskedTopVLine(int(obj.xPos),int(obj.yPos),10);

				if (calc != 0)
					obj.yPos-=(10-calc);
				else
					obj.yPos-=obj.ySpeed;

				if (obj.ySpeed>1)
					jjSample(obj.xPos, obj.yPos, SOUND::Sample(SOUND::COMMON_IMPACT1 + (jjRandom() & 7)));

				obj.ySpeed=-(obj.ySpeed/2);
			} else
			{
				if (obj.yPos>jjWaterLevel)
				{
					obj.ySpeed+=0.125/4;
					if (obj.ySpeed>4) obj.ySpeed=4;
					else
					if (obj.ySpeed<-4) obj.ySpeed=-4;
				}
				else
				{
					obj.ySpeed+=0.125;
					if (obj.ySpeed>8) obj.ySpeed=8;
				};
			};
		}

		obj.direction = (obj.xSpeed >= 0) ? 1 : -1;
		if (jjGameTicks & 3 == 0) {
			++obj.frameID;
			obj.determineCurFrame();
		}
		obj.draw();
	}
}