Downloads containing DuoBouncers.asc

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Blood LibelFeatured Download Violet CLM Battle 8.8 Download file

File preview

#pragma require "DuoBouncers.asc"
#pragma require "DuoBouncers.j2a"
#include "MLLE-Weapons.asc"

namespace DuoBouncers { //edited from Naps' antigravity bouncer code/colors
	class Weapon : MLLEWeapons::WeaponInterface {
		bool ReverseBehaviors = false;
		bool BounceThroughWalls = true;
		Weapon() {
			super( //mostly unchanged, except with xSpeed 1 for easier math, and different animation numbers
				regularObjectTemplate: MLLEWeapons::ObjectTemplate(
					xSpeed: 1,
					killAnim: jjAnimSets[ANIM::AMMO].firstAnim + 4,
					curAnim: 0,
					lightType: LIGHT::POINT2,
					counterEnd: (70*3)/2
				),
				powerupObjectTemplate: MLLEWeapons::ObjectTemplate(
					xSpeed: 1,
					animSpeed: 2,
					killAnim: jjAnimSets[ANIM::AMMO].firstAnim + 4,
					curAnim: 2,
					lightType: LIGHT::POINT2,
					counterEnd: (70*3)/2
				),
				animSetFilename: "DuoBouncers.j2a",
				animSetID: 6,
				pickupAnimation: 5,
				poweredUpPickupAnimation: 4,
				//powerupAnimation: 6,
				//ammoCrateAnimation: 7,
				traits: se::weapon_default_traits | se::weapon_goes_through_thin_walls,
				behavior: MLLEWeapons::behaviorFunction(DetermineBehavior),
				apply: MLLEWeapons::applyFunction(DetermineReversedness)
			);
		}
		void DetermineBehavior(jjOBJ@ down, bool powerup) {
			DefaultWeapons::DefaultSample(down, WEAPON::BOUNCER);
			auto x = down.xSpeed, y = down.ySpeed; //radius of 1
			jjOBJ@ up = jjObjects[jjAddObject(down.eventID, down.xPos, down.yPos, down.creatorID, down.creatorType, BEHAVIOR::INACTIVE)];
			down.xAcc =		up.xAcc =	x * 0.25;
			down.xSpeed =	up.xSpeed =	x * 5;
			x = abs(x);
			down.yAcc =		x * 0.0915527344f + y * 0.25;
			down.ySpeed =	x * 1 + y * 5;
			down.curAnim += 1;
			up.yAcc =	x * -0.0915527344f + y * 0.25;
			up.ySpeed =	x * -1 + y * 5;
			up.var[7] = down.var[7]; //pxspeed
			up.behavior = jjVOIDFUNCOBJ(Behavior);
			if (BounceThroughWalls)
				down.behavior = (powerup != ReverseBehaviors) ? BEHAVIOR::BOUNCERBULLETPU : BEHAVIOR::BOUNCERBULLET;
			else
				down.behavior = (powerup != ReverseBehaviors) ? BouncerPUNoWallWrapper : BouncerNoWallWrapper;
			if (x == 0) {
				if (jjPlayers[down.creatorID & 31].direction >= 0) {
					down.xSpeed = 1;
					up.xSpeed = -1;
				} else {
					down.xSpeed = -1;
					up.xSpeed = 1;
				}
			}
		}
		void Behavior(jjOBJ@ obj) const { //copied directly from Naps' original
			bool goUp,goDown,goLeft,goRight;
			int frame;
			if (obj.state == STATE::START) {
				if (obj.creatorType == CREATOR::OBJECT) {
					jjOBJ@ enemyCreator = jjObjects[obj.creatorID];
					obj.direction = enemyCreator.direction;
					obj.xSpeed = (obj.direction*obj.xSpeed) + enemyCreator.xSpeed;
					obj.xAcc=(obj.direction*obj.xAcc);
				}
				if (obj.eventID == OBJECT::ICEBULLET)
					obj.eventID = OBJECT::BLASTERBULLET; //just in case...
				obj.state = STATE::BOUNCE;
			} else
			if (obj.state == STATE::EXPLODE) {
				obj.behavior = BEHAVIOR::EXPLOSION2;
				obj.frameID = 0;
			} else
			if ((obj.state == STATE::KILL) || (obj.state == STATE::DEACTIVATE)) {
				obj.delete();
			}
			
			obj.xPos += obj.xSpeed + (obj.var[7] / 65536.0);
			obj.yPos += obj.ySpeed;
			
			if (obj.var[7] > 8192)
				obj.var[7] =  obj.var[7] - 8192;
			else
			if (obj.var[7] < -8192)
				obj.var[7] = obj.var[7] + 8192 ;
			else
				obj.var[7] = 0;
				
			obj.xSpeed += obj.xAcc;
			
			if (obj.yPos > jjWaterLevel)
				obj.ySpeed +=obj.yAcc - 0.125/4;
			else
				obj.ySpeed+=obj.yAcc - 0.125;
			
			if (obj.counter > int(obj.counterEnd)) {
				obj.state = STATE::EXPLODE;
				obj.curFrame = 0;
				obj.counter = 0;
				obj.lightType = 0;
			}
		
			goUp=jjMaskedPixel(int(obj.xPos),int(obj.yPos) - 4);
			goDown=jjMaskedPixel(int(obj.xPos),int(obj.yPos) + 4);
			goLeft=jjMaskedPixel(int(obj.xPos) - 2,int(obj.yPos));
			goRight=jjMaskedPixel(int(obj.xPos) + 2,int(obj.yPos));
			
			obj.counter++;
			if ((obj.counter&3)==0) {
				obj.frameID++;
				if (obj.frameID >= int(jjAnimations[obj.curAnim].frameCount))
					obj.frameID = 0;
				obj.curFrame = jjAnimations[obj.curAnim].firstFrame + obj.frameID;
			}
			//
			if (obj.var[6] == (!ReverseBehaviors? 0 : 8)) {
				if (obj.xSpeed>8) obj.xSpeed=8;
				else
				if (obj.xSpeed<-8) obj.xSpeed=-8;

				if (obj.ySpeed>4) obj.ySpeed=4;
				else
				if (obj.ySpeed<-4) obj.ySpeed=-4;
			
				if ((obj.ySpeed < 0) && (goUp == true)) {
					obj.var[0] = obj.var[0] + 1;
					obj.yPos += obj.ySpeed;
					obj.ySpeed = -(obj.ySpeed*7)/8;
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,40,0);
				} else
				if ((obj.ySpeed > 0) && (goDown == true)) {
					obj.var[0] = obj.var[0] + 1;
					obj.ySpeed = -(obj.ySpeed*7)/8;
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,40,0);
				}
				
				if (obj.xSpeed < 0 && goLeft == true) {
					obj.var[0] = obj.var[0] + 1;
					obj.xSpeed = -(obj.xSpeed*7)/8;
					obj.xAcc = -obj.xAcc;
					if (!BounceThroughWalls) {
						obj.var[7] = -obj.var[7];
					}
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,40,0);
				} else
				if ((obj.xSpeed >0 ) && (goRight == true)) {
					obj.var[0] = obj.var[0] + 1;
					obj.xSpeed = -(obj.xSpeed*7)/8;
					obj.xAcc = -obj.xAcc;
					if (!BounceThroughWalls) {
						obj.var[7] = -obj.var[7];
					}
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,40,0);
				}
				
				if (obj.var[0] > 16) {
					obj.state = STATE::EXPLODE;
					obj.frameID = 0;
					obj.counter=-1;
					obj.lightType=0;
				}
			} else
			if (obj.var[6] == (!ReverseBehaviors? 8 : 0)) {
				if (obj.xSpeed>6) obj.xSpeed=6;
				else
				if (obj.xSpeed<-6) obj.xSpeed=-6;

				if (obj.ySpeed>6) obj.ySpeed=6;
				else
				if (obj.ySpeed<-6) obj.ySpeed=-6;
		
				if ((obj.ySpeed < 0) && (goUp == true)) {
					obj.var[0] = obj.var[0] + 1;
					obj.ySpeed = -(obj.ySpeed*9)/8;
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,0,0);
				} else
				if ((obj.ySpeed > 0) && (goDown == true)) {
					obj.var[0] = obj.var[0] + 1;
					obj.ySpeed = -(obj.ySpeed*(9+int(jjRandom() & 7)))/8;
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,0,0);
				}
			
				if (obj.xSpeed < 0 && goLeft == true) {
					obj.var[0] = obj.var[0] + 1;
					obj.xSpeed = -(obj.xSpeed*9)/8;
					if (int(jjRandom() & (3)) == 0) obj.xAcc = -obj.xAcc;
					if (!BounceThroughWalls) {
						obj.var[7] = -obj.var[7];
					}
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,0,0);
				} else
				if ((obj.xSpeed >0 ) && (goRight == true)) {
					obj.var[0] = obj.var[0] + 1;
					obj.xSpeed = -(obj.xSpeed*9)/8;
					if (int(jjRandom() & (3)) == 0) obj.xAcc = -obj.xAcc;
					if (!BounceThroughWalls) {
						obj.var[7] = -obj.var[7];
					}
					jjSample(obj.xPos,obj.yPos,SOUND::COMMON_BLOKPLOP,0,0);
				}
				if (obj.var[0] > 32) {
					obj.state = STATE::EXPLODE;
					obj.frameID = 0;
					obj.counter=-1;
					obj.lightType=0;
				}
			}
			if (obj.counter > 4)
			obj.draw();
		}
		bool DetermineReversedness(uint, se::WeaponHook@, jjSTREAM@ parameter) {
			if (parameter !is null && parameter.getSize() >= 2) {
				parameter.pop(ReverseBehaviors);
				parameter.pop(BounceThroughWalls);
			}
			return true;
		}
	}
	void BouncerNoWallWrapper(jjOBJ@ obj) { //from MLLE-DefaultWeapons.asc
		const bool right = obj.xSpeed >= 0;
		obj.behave(BEHAVIOR::BOUNCERBULLET);
		if (right != (obj.xSpeed >= 0))
			obj.var[7] = -obj.var[7];
	}
	void BouncerPUNoWallWrapper(jjOBJ@ obj) { //
		const bool right = obj.xSpeed >= 0;
		obj.behave(BEHAVIOR::BOUNCERBULLETPU);
		if (right != (obj.xSpeed >= 0))
			obj.var[7] = -obj.var[7];
	}
}