Downloads containing hsmf.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Anniversary Bash 19 Levels Jazz2Online Multiple N/A Download file
TSF with JJ2+ Only: Hyperspace FireSworD Capture the flag N/A Download file

File preview

int elapsed = 0;

void onPlayer(jjPLAYER@ player) {
	float xPixelLimit = 1, yPixelLimit = 1;
	float levelWidth = jjLayers[4].width * 32, levelHeight = jjLayers[4].height * 32;
	if (player.xPos > levelWidth - (xPixelLimit + 1) && player.xSpeed > 0) {
		player.offsetPosition(int(-(player.xPos - xPixelLimit)), 0);
	} else if (player.xPos < xPixelLimit && player.xSpeed < 0) {
		player.offsetPosition(int(-(player.xPos - levelWidth - (xPixelLimit + 1))), 0);
	}
	if (player.yPos > levelHeight - (yPixelLimit + 1) && player.ySpeed > 0) {
		player.offsetPosition(0, int(-(player.yPos - yPixelLimit)));
	} else if (player.yPos < yPixelLimit && player.ySpeed < 0) {
		player.offsetPosition(0, int(-(player.yPos - levelHeight - (yPixelLimit + 1))));
	}
	player.lightType = LIGHT::NONE;

	if (player.buttstomp == 41) {
		elapsed++;
		if (elapsed == 140) player.buttstomp = 121;
	}
	else elapsed = 0;
}

void onMain() {
	for (int i = 1; i < jjObjectCount; i++) {
		jjOBJ@ obj = jjObjects[i];
		if (obj.behavior == BEHAVIOR::PEPPERBULLET)
			obj.behavior = ObjectWrapper(obj.behavior);
	}
	float levelWidth = jjLayers[4].width * 32, levelHeight = jjLayers[4].height * 32;
	for (int i = 0; i < jjLocalPlayerCount; i++) {
		const jjPLAYER@ player = jjLocalPlayers[i];
		for (int j = 1; j < jjObjectCount; j++) {
			const jjOBJ@ obj = jjObjects[j];
			if (obj.isActive) {
				float x1 = obj.xPos;
				float x2 = x1 + (x1 > levelWidth / 2.f ? -levelWidth : levelWidth);
				float y1 = obj.yPos;
				const ObjectWrapper@ wrapper = cast<ObjectWrapper>(cast<jjBEHAVIORINTERFACE>(obj.behavior));
				jjBEHAVIOR behavior = wrapper is null ? obj.behavior : wrapper.underlyingBehavior();
				if (behavior == BEHAVIOR::PICKUP)
					y1 += jjSin((((j << 3) + jjGameTicks) << (y1 > jjWaterLevel ? 1 : 4)) + (int(x1) << 4)) * 4.f;
				float y2 = y1 + (y1 > levelHeight / 2.f ? -levelHeight : levelHeight);
				if (behavior != BEHAVIOR::ELECTROBULLET) {
					SPRITE::Mode mode;
					uint8 param = 0;
					if (obj.freeze != 0) {
						mode = SPRITE::FROZEN;
					} else if (obj.justHit != 0) {
						mode = SPRITE::SINGLECOLOR;
						param = 15;
					} else if (uint(obj.curAnim) == jjAnimSets[ANIM::PICKUPS] + 34 || uint(obj.curAnim) == jjAnimSets[ANIM::PICKUPS] + 35 || uint(obj.curAnim) == jjAnimSets[ANIM::PICKUPS] + 22) {
						mode = SPRITE::SINGLECOLOR;
						param = obj.var[0] == 0 ? 0 : obj.var[0] - 1;
					} else if (obj.curFrame > 0 && obj.curFrame < 15000 && jjAnimFrames[obj.curFrame].transparent) {
						mode = SPRITE::TRANSLUCENT;
					} else {
						mode = SPRITE::NORMAL;
					}
					if (obj.curAnim != obj.special && (behavior == BEHAVIOR::BULLET || behavior == BEHAVIOR::RFBULLET)) {
						bool left = obj.xSpeed < 0;
						float xScale = left ? -1.f : 1.f;
						int angle = int(atan2(left ? -obj.ySpeed : obj.ySpeed, left ? -obj.xSpeed : obj.xSpeed) * -512.f / 3.14159265f);
						jjDrawRotatedSpriteFromCurFrame(x2, y1, obj.curFrame, angle, xScale, 1.f, mode, param, 4, 4, player.playerID);
						jjDrawRotatedSpriteFromCurFrame(x1, y2, obj.curFrame, angle, xScale, 1.f, mode, param, 4, 4, player.playerID);
						jjDrawRotatedSpriteFromCurFrame(x2, y2, obj.curFrame, angle, xScale, 1.f, mode, param, 4, 4, player.playerID);
					} else {
						jjDrawSpriteFromCurFrame(x2, y1, obj.curFrame, obj.direction, mode, param, 4, 4, player.playerID);
						jjDrawSpriteFromCurFrame(x1, y2, obj.curFrame, obj.direction, mode, param, 4, 4, player.playerID);
						jjDrawSpriteFromCurFrame(x2, y2, obj.curFrame, obj.direction, mode, param, 4, 4, player.playerID);
					}
				} else {
					int angle = obj.var[0] + (obj.direction > 0 ? 32 : -32);
					uint random = jjRandom();
					uint8 param = obj.var[1] - 80;
					float radius = 1.f + obj.counter / 8.f;
					for (int k = 0; k < 8; k++) {
						float x = radius * jjCos(angle);
						float y = radius * jjSin(angle);
						float x3 = x1 + x;
						float y3 = y1 + y;
						float x4 = x2 + x;
						float y4 = y2 + y;
						jjDrawSpriteFromCurFrame(x4, y3, obj.curFrame, 0, SPRITE::TRANSLUCENTPALSHIFT, param, 4, 4, player.playerID);
						jjDrawSpriteFromCurFrame(x3, y4, obj.curFrame, 0, SPRITE::TRANSLUCENTPALSHIFT, param, 4, 4, player.playerID);
						jjDrawSpriteFromCurFrame(x4, y4, obj.curFrame, 0, SPRITE::TRANSLUCENTPALSHIFT, param, 4, 4, player.playerID);
						if (random & 3 == 0) {
							for (int l = 0; l < 3; l++) {
								jjPARTICLE@ part = jjAddParticle(PARTICLE::SPARK);
								if (part !is null) {
									switch (l) {
										case 0:
											part.xPos = x4;
											part.yPos = y3;
											break;
										case 1:
											part.xPos = x3;
											part.yPos = y4;
											break;
										case 2:
											part.xPos = x4;
											part.yPos = y4;
											break;
									}
									part.xSpeed = x / 4.f;
									part.ySpeed = y / 4.f;
									part.spark.color = obj.var[1];
									part.spark.colorStop = obj.var[1] + 6;
								}
							}
						}
						random >>= 2;
						angle += 96;
					}
				}
			}
		}
		for (int j = 0; j < 32; j++) {
			const jjPLAYER@ other = jjPlayers[j];
			if (other.isInGame && other !is player && !other.invisibility) {
				float x1 = other.xPos;
				float x2 = x1 + (x1 > levelWidth / 2.f ? -levelWidth : levelWidth);
				float y1 = other.yPos;
				float y2 = y1 + (y1 > levelHeight / 2.f ? -levelHeight : levelHeight);
				if (other.blink == 0 || jjUnixTimeMs() >> 6 & 1 != 0) {
					SPRITE::Mode mode = other.frozen == 0 ? other.spriteMode : SPRITE::FROZEN;
					jjDrawSpriteFromCurFrame(x2, y1, other.curFrame, other.direction, mode, other.spriteParam, 4, 4, player.playerID);
					jjDrawSpriteFromCurFrame(x1, y2, other.curFrame, other.direction, mode, other.spriteParam, 4, 4, player.playerID);
					jjDrawSpriteFromCurFrame(x2, y2, other.curFrame, other.direction, mode, other.spriteParam, 4, 4, player.playerID);
				}
				if (jjGameConnection != GAME::LOCAL && other.frozen == 0) {
					y1 -= 28.f;
					y2 -= 28.f;
					string name = "\xA70";
					if (jjGameMode == GAME::CTF) {
						for (int k = 4 - (other.team + 1 & 3); k-- > 0;) {
							name += '|';
						}
					}
					name += other.name;
					jjTEXTAPPEARANCE style(STRING::NORMAL);
					style.align = STRING::CENTER;
					jjDrawString(x2, y1, name, STRING::SMALL, style, 0, SPRITE::PALSHIFT, 0, 4, 4, player.playerID);
					jjDrawString(x1, y2, name, STRING::SMALL, style, 0, SPRITE::PALSHIFT, 0, 4, 4, player.playerID);
					jjDrawString(x2, y2, name, STRING::SMALL, style, 0, SPRITE::PALSHIFT, 0, 4, 4, player.playerID);
				}
			}
		}
	}
}

void onLevelLoad() {
	jjUseLayer8Speeds = true;
	float levelWidth = jjLayers[4].width * 32, levelHeight = jjLayers[4].height * 32;
	float backgroundWidth = jjLayers[8].width * 32, backgroundHeight = jjLayers[8].height * 32;
	float backgroundXSpeed = jjLayers[8].xSpeed, backgroundYSpeed = jjLayers[8].ySpeed;
	float modX = levelWidth * backgroundXSpeed % backgroundWidth;
	float x1 = backgroundXSpeed - modX / levelWidth;
	float x2 = backgroundXSpeed + (backgroundWidth - modX) / levelWidth;
	float modY = levelHeight * backgroundYSpeed % backgroundHeight;
	jjLayers[8].xSpeed = backgroundXSpeed - x1 < x2 - backgroundXSpeed ? x1 : x2;
	float y1 = backgroundYSpeed - modY / levelHeight;
	float y2 = backgroundYSpeed + (backgroundHeight - modY) / levelHeight;
	jjLayers[8].ySpeed = backgroundYSpeed - y1 < y2 - backgroundYSpeed ? y1 : y2;
	for (int eventID = OBJECT::BLASTERBULLET; eventID < OBJECT::BULLET; ++eventID) {
		jjObjectPresets[eventID].behavior = ObjectWrapper(jjObjectPresets[eventID].behavior);
	}
	for (int eventID = 1; eventID < 256; ++eventID) {
		if (jjObjectPresets[eventID].behavior == BEHAVIOR::PICKUP)
			jjObjectPresets[eventID].behavior = ObjectWrapper(jjObjectPresets[eventID].behavior);
	}
	jjObjectPresets[OBJECT::CTFBASE].behavior = Flag();
}

class ObjectWrapper : jjBEHAVIORINTERFACE {
	private jjBEHAVIOR nativeBehavior;
	ObjectWrapper(const jjBEHAVIOR &in nb) {
		nativeBehavior = nb;
	}

	void onBehave(jjOBJ@ obj) {
		float levelWidth = jjLayers[4].width * 32, levelHeight = jjLayers[4].height * 32;
		if (nativeBehavior == BEHAVIOR::PICKUP || nativeBehavior == BEHAVIOR::ICEBULLETPU || nativeBehavior == BEHAVIOR::SEEKERBULLET || nativeBehavior == BEHAVIOR::RFBULLET || nativeBehavior == BEHAVIOR::TOASTERBULLET || nativeBehavior == BEHAVIOR::PEPPERBULLET) {
			float x = obj.xPos, y = obj.yPos;
			if (nativeBehavior == BEHAVIOR::TOASTERBULLET) {
				const float acc = 1.f / 64.f;
				float xs = obj.xSpeed, ys = obj.ySpeed;
				if (abs(xs) > abs(ys)) {
					if (xs > 0.f) {
						if (xs > 6.f)
							xs = 6.f;
						else if (xs > acc)
							xs -= acc;
						else
							xs = 0.f;
					} else {
						if (xs < -6.f)
							xs = -6.f;
						else if (xs < -acc)
							xs += acc;
						else
							xs = 0.f;
					}
				} else {
					if (ys > 0.f) {
						if (ys > acc)
							ys -= acc;
						else
							ys = 0;
					} else {
						if (ys < -acc)
							ys += acc;
						else
							ys = 0;
					}
				}
				x += xs + obj.xAcc + obj.var[7] / 65536.f;
				y += ys + obj.yAcc;
			} else {
				x += obj.xSpeed;
				y += obj.ySpeed;
				if (nativeBehavior == BEHAVIOR::PICKUP) {
					jjANIMFRAME@ frame = jjAnimFrames[obj.curFrame];
					x += frame.hotSpotX;
					y += frame.hotSpotY + frame.height + 2;
				} else if (nativeBehavior != BEHAVIOR::SEEKERBULLET) {
					x += obj.var[7] / 65536.f;
					if (nativeBehavior == BEHAVIOR::ICEBULLETPU) {
						if (obj.xSpeed == 0.f)
							x += jjSin(obj.var[0]);
						else
							y += jjSin(obj.var[0]) - obj.ySpeed;
					} else if (nativeBehavior == BEHAVIOR::PEPPERBULLET) {
						x += obj.xAcc;
						y += obj.yAcc;
					}
				}
			}
			if (x < 0.f)
				obj.xPos += levelWidth;
			else if (x >= levelWidth)
				obj.xPos -= levelWidth;
			if (y < 0.f)
				obj.yPos += levelHeight;
			else if (y >= levelHeight)
				obj.yPos -= levelHeight;
		}
		obj.behave(nativeBehavior);
		float x = obj.xPos, y = obj.yPos;
		if (x < 0.f)
			obj.xPos += levelWidth;
		else if (x >= levelWidth)
			obj.xPos -= levelWidth;
		if (y < 0.f)
			obj.yPos += levelHeight;
		else if (y >= levelHeight)
			obj.yPos -= levelHeight;
	}
	bool onIsRFBullet(jjOBJ@) {
		return nativeBehavior == BEHAVIOR::RFBULLET;
	}
	const jjBEHAVIOR& underlyingBehavior() const {
		return nativeBehavior;
	}
}

class Flag : jjBEHAVIORINTERFACE {
	private jjOBJ@ prevFlag = null;
	private int prevTick = -1;
	void onBehave(jjOBJ@ obj) {
		obj.behave(BEHAVIOR::FLAG);
		if (prevTick == jjGameTicks && jjGameMode == GAME::CTF && jjGameCustom != GAME::DOM && jjGameCustom != GAME::FR && jjGameConnection != GAME::LOCAL) {
			for (int i = 0; i < jjLocalPlayerCount; i++) {
				const jjPLAYER@ player = jjLocalPlayers[i];
				if (player.isInGame) {
					bool isTarget = obj.var[1] == player.team;
					if (jjGameCustom != GAME::HEAD)
						isTarget = isTarget ^^ ((isTarget ? @prevFlag : @obj).state == STATE::SLEEP);
					jjOBJ@ target = isTarget ? @obj : @prevFlag;
					float levelWidth = jjLayers[4].width * 32, levelHeight = jjLayers[4].height * 32;
					float x1 = target.xPos;
					float x2 = x1 + (x1 > levelWidth / 2.f ? -levelWidth : levelWidth);
					float y1 = target.yPos;
					float y2 = y1 + (y1 > levelHeight / 2.f ? -levelHeight : levelHeight);
					if (abs(x2 - player.xPos) < abs(x1 - player.xPos))
						target.xPos = x2;
					if (abs(y2 - player.yPos) < abs(y1 - player.yPos))
						target.yPos = y2;
					break;
				}
			}
		}
		@prevFlag = obj;
		prevTick = jjGameTicks;
	}
}