Downloads containing mortar.mut

Downloads
Name Author Game Mode Rating
JJ2+ Only: Arcane WeaponsFeatured Download PurpleJazz Mutator 10 Download file

File preview

#pragma name "Mortar Launcher"
#pragma require "Mortar.j2a"
#pragma require "f_gren4.wav"

bool gameIsActive() {
	return jjGameState == GAME::STARTED || jjGameState == GAME::OVERTIME;
}

void onLevelLoad() {
	jjAnimSets[ANIM::CUSTOM[24]].load(0, "Mortar.j2a");
	jjAnimations[jjAnimSets[ANIM::AMMO] + 34] = jjAnimations[jjAnimSets[ANIM::CUSTOM[24]] + 1];
	jjAnimations[jjAnimSets[ANIM::AMMO] + 33] = jjAnimations[jjAnimSets[ANIM::CUSTOM[24]] + 3];
	
	jjObjectPresets[OBJECT::SEEKERBULLET].behavior = jjObjectPresets[OBJECT::SEEKERBULLETPU].behavior = Mortar();
	jjObjectPresets[OBJECT::SEEKERBULLET].xSpeed = 7;
	jjObjectPresets[OBJECT::SEEKERBULLET].ySpeed = -9;
	jjObjectPresets[OBJECT::SEEKERBULLETPU].xSpeed = 7;
	jjObjectPresets[OBJECT::SEEKERBULLETPU].ySpeed = -10;
	jjObjectPresets[OBJECT::SEEKERBULLET].counterEnd = 90;
	jjObjectPresets[OBJECT::SEEKERBULLETPU].counterEnd = 105;
	
	jjObjectPresets[OBJECT::SEEKERAMMO15].determineCurAnim(ANIM::CUSTOM[24], 4);
	jjObjectPresets[OBJECT::SEEKERAMMO15].determineCurFrame();
	
	jjObjectPresets[OBJECT::SEEKERPOWERUP].determineCurAnim(ANIM::CUSTOM[24], 5);
	jjObjectPresets[OBJECT::SEEKERPOWERUP].determineCurFrame();
	
	jjWeapons[WEAPON::SEEKER].defaultSample = false;
	
	jjSampleLoad(SOUND::P2_TONG, "f_gren4.wav");
}

class Mortar : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) {
		obj.behave(obj.state == STATE::EXPLODE? BEHAVIOR::RFBULLET : BEHAVIOR::BULLET, false);
		jjPLAYER@ creator = jjPlayers[obj.creatorID];
		obj.var[0] = int(atan2(-obj.ySpeed, obj.xSpeed) * (512.f * 0.318309886142228f));
		obj.var[5] = obj.eventID == OBJECT::SEEKERBULLETPU? 2:1;
		
		switch (obj.state) {
			case STATE::START:
				obj.state = STATE::FLY;
				obj.lightType = LIGHT::POINT;
				obj.var[2] = 0;
			break;
			
			case STATE::FLY:
				if (obj.counter == 1 && creator.isLocal) {
					jjSample(creator.xPos, creator.yPos, SOUND::P2_TONG, 0, 0);
				}
				
				jjDrawRotatedSprite(obj.xPos, obj.yPos, ANIM::CUSTOM[24], obj.eventID == OBJECT::SEEKERBULLETPU? 2:0, jjGameTicks >> 2, obj.var[0], 0.75, 0.75, SPRITE::NORMAL);
				
				if (obj.counter % 5 == 0 && !jjLowDetail) {
					jjOBJ@ trail = jjObjects[jjAddObject(OBJECT::EXPLOSION, int(obj.xPos - jjCos(obj.var[0])), int(obj.yPos - jjSin(obj.var[0])))];
					trail.determineCurAnim(ANIM::AMMO, 3);
					trail.lightType = LIGHT::NONE;
					trail.playerHandling = HANDLING::PARTICLE;
					trail.bulletHandling = HANDLING::IGNOREBULLET;
					trail.isBlastable = false;
				}
				
				switch (obj.direction) {
					case 1: obj.xSpeed -= 0.275; obj.ySpeed += 0.225; break;
					case -1: obj.xSpeed += 0.275; obj.ySpeed += 0.225; break;
				}
				if (obj.xSpeed == 0) obj.ySpeed += 0.3;
				if (obj.ySpeed > 12) obj.ySpeed = 12;
			break;
			
			case STATE::EXPLODE:
				jjDrawResizedSprite(obj.xPos, obj.yPos, ANIM::AMMO, 5, obj.curFrame + 5, 2, 2, SPRITE::NORMAL);
			
				if (obj.var[2] == 0) {
					Shockwave temp;
					jjOBJ@ blast = jjObjects[jjAddObject(OBJECT::BULLET, obj.xPos, obj.yPos, obj.creatorID, CREATOR::PLAYER, jjVOIDFUNCOBJ(temp.onBehave))];
					obj.var[2] = 1;
					blast.var[2] = 1;
					blast.var[5] = obj.var[5];
				}
			break;
		}
	}
}

class Shockwave : jjBEHAVIORINTERFACE {
	void onBehave(jjOBJ@ obj) {
		jjPLAYER@ creator = jjPlayers[obj.creatorID];
		
		obj.playerHandling = HANDLING::PARTICLE;
		obj.bulletHandling = HANDLING::IGNOREBULLET;
		obj.animSpeed = 1;
		
		if (obj.var[2] == 1) {
			obj.lightType = obj.var[2] == 1? LIGHT::RING2 : LIGHT::NONE;
			obj.var[1] = obj.var[1] + 1;
			obj.light += 2;
			obj.var[4] = obj.light * 4;
			
			for (int i = 1; i < jjObjectCount; i++) {
				jjOBJ@ target = jjObjects[i];
				float dx = target.xPos - obj.xPos, dy = target.yPos - obj.yPos;
				if ((target.eventID == OBJECT::TNT || target.behavior == BEHAVIOR::MONITOR || target.behavior == BEHAVIOR::AMMO15 || target.eventID == OBJECT::GUNCRATE || target.eventID == OBJECT::GEMCRATE || target.eventID == OBJECT::CARROTCRATE || target.playerHandling == HANDLING::ENEMY || target.eventID == OBJECT::DESTRUCTSCENERY) && target.var[4] == 0) {
					if (dx * dx + dy * dy < obj.var[4] * obj.var[4]) {
						if (target.eventID != OBJECT::TNT) {
							obj.objectHit(target, target.playerHandling == HANDLING::ENEMY? HANDLING::ENEMY : HANDLING::SPECIAL);
							if (target.playerHandling != HANDLING::ENEMY) target.state = STATE::KILL;
						}
						else target.state = STATE::EXPLODE;
						if (target.playerHandling != HANDLING::ENEMY) target.var[4] = 1;
					}
					else target.var[4] = 0;
				}
				else if ((target.behavior == BEHAVIOR::PICKUP || target.eventID == OBJECT::TNTAMMO3 || target.eventID == OBJECT::GUN9AMMO3) && target.state == STATE::FLOAT) {
					if (dx * dx + dy * dy < obj.var[4] * obj.var[4])
						target.state = STATE::FLOATFALL;
				}
			}
			
			float pdx = jjLocalPlayers[0].xPos - obj.xPos, pdy = jjLocalPlayers[0].yPos - obj.yPos;
			if ((pdx * pdx + pdy * pdy < 64 * 64) && obj.curFrame < 2105) {
				jjLocalPlayers[0].xSpeed = jjLocalPlayers[0].xPos > obj.xPos? 8:-8;
				jjLocalPlayers[0].ySpeed = jjLocalPlayers[0].yPos > obj.yPos? 8:-8;
			}
			
			if (jjIsServer && gameIsActive()) {
				for (int i = 0; i < 32; i++) {
					jjPLAYER@ player = jjPlayers[i];
					if (
						player.isActive && player.isInGame && player.health > 0 && player !is creator && creator.blink == 0 && 
							(jjGameMode != GAME::CTF || jjFriendlyFire || player.team != creator.team)
					) {
						float dx = player.xPos - obj.xPos, dy = player.yPos - obj.yPos;
						if (dx * dx + dy * dy < obj.var[4] * obj.var[4]) {
							if (obj.var[8] & 1 << i == 0) {
								player.hurt(obj.var[5], false, creator);
								obj.var[8] = obj.var[8] | 1 << i;
							}
						}
					}
				}
			}
		}
		
		if (obj.var[1] == 14) {
			obj.var[1] = 0;
			obj.var[2] = 0;
			obj.var[4] = 0;
			obj.delete();
		}
	}
}