Downloads containing SEweapon.asc

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

File preview

namespace se {
funcdef void PacketCallback(::jjSTREAM& packet, int clientID);
funcdef ::jjSTREAM PacketConstructor();
shared interface NetworkHook {
	PacketConstructor@ addCallback(PacketCallback@ callback);
	bool process(::jjSTREAM &in packet, int clientID);
}
shared interface AmmoDisplayHook {
	void setWeaponSprite(uint number, bool powerup, const ::jjANIMATION@ anim);
	bool draw(const ::jjPLAYER@ player, ::jjCANVAS@ canvas);
}
shared interface WeaponInterface {
	::jjANIMSET@ loadAnims(::jjANIMSET@ animSet);
	::array<bool>@ loadSamples(const ::array<SOUND::Sample>& samples);
	uint getSampleCount() const;
	bool setAsWeapon(uint number, AmmoDisplayHook@ ammoDisplayHook, NetworkHook@ networkHook);
}
shared bool isValidWeapon(uint number) {
	return number != 0 && number <= WEAPON::GUN9;
}
shared uint getBasicBulletOfWeapon(uint number) {
	if (isValidWeapon(number)) {
		if (number < WEAPON::TNT)
			return OBJECT::BLASTERBULLET + number - WEAPON::BLASTER;
		if (number > WEAPON::TNT)
			return OBJECT::FIREBALLBULLET + number - WEAPON::GUN8;
		return OBJECT::TNT;
	}
	return 0;
}
shared uint getPoweredBulletOfWeapon(uint number) {
	if (isValidWeapon(number)) {
		if (number < WEAPON::TNT)
			return OBJECT::BLASTERBULLETPU + number - WEAPON::BLASTER;
		if (number > WEAPON::TNT)
			return OBJECT::FIREBALLBULLETPU + number - WEAPON::GUN8;
		return OBJECT::TNT;
	}
	return 0;
}
shared uint getAmmoPickupOfWeapon(uint number) {
	if (isValidWeapon(number) && number != WEAPON::BLASTER) {
		if (number == WEAPON::BOUNCER)
			return OBJECT::BOUNCERAMMO3;
		if (number == WEAPON::ICE)
			return OBJECT::ICEAMMO3;
		return OBJECT::SEEKERAMMO3 + number - WEAPON::SEEKER;
	}
	return 0;
}
shared uint getAmmoCrateOfWeapon(uint number) {
	if (number > WEAPON::BLASTER && number < WEAPON::TNT) {
		if (number == WEAPON::BOUNCER)
			return OBJECT::BOUNCERAMMO15;
		if (number == WEAPON::ICE)
			return OBJECT::ICEAMMO15;
		return OBJECT::SEEKERAMMO15 + number - WEAPON::SEEKER;
	}
	return 0;
}
shared uint getPowerupMonitorOfWeapon(uint number) {
	if (isValidWeapon(number)) {
		if (number < WEAPON::TNT)
			return OBJECT::BLASTERPOWERUP + number - WEAPON::BLASTER;
		return OBJECT::TNTPOWERUP + number - WEAPON::TNT;
	}
	return 0;
}
shared class DefaultPacketConstructor {
	private ::jjSTREAM result;
	DefaultPacketConstructor(const ::jjSTREAM &in value) {
		result = value;
	}
	::jjSTREAM opCall() const {
		return result;
	}
}
shared class DefaultNetworkHook : NetworkHook {
	bool usePacketID;
	uint8 packetID;
	::array<PacketCallback@> callbacks;
	DefaultNetworkHook() {
		usePacketID = false;
	}
	DefaultNetworkHook(uint8 id) {
		packetID = id;
		usePacketID = true;
	}
	PacketConstructor@ addCallback(PacketCallback@ callback) {
		::jjSTREAM packet;
		uint index = callbacks.length();
		callbacks.insertLast(@callback);
		if (usePacketID)
			packet.push(packetID);
		if (index >= 0x80) {
			packet.push(uint8(index >> 24) | 0x80);
			packet.push(uint8(index >> 16));
			packet.push(uint8(index >> 8));
		}
		packet.push(uint8(index));
		DefaultPacketConstructor result(packet);
		return @PacketConstructor(result.opCall);
	}
	bool process(::jjSTREAM &in packet, int clientID) {
		uint8 id, index;
		if ((!usePacketID || packet.pop(id) && id == packetID) && packet.pop(index)) {
			uint fullIndex;
			if (index & 0x80 != 0) {
				index &= ~0x80;
				uint8 u1, u2, u3;
				if (packet.pop(u1) && packet.pop(u2) && packet.pop(u3))
					fullIndex = uint(index) << 24 | uint(u1) << 16 | uint(u2) << 8 | u3;
				else
					fullIndex = callbacks.length();
			} else {
				fullIndex = index;
			}
			if (fullIndex < callbacks.length()) {
				PacketCallback@ callback = @callbacks[fullIndex];
				if (callback !is null)
					callback(packet, clientID);
				return true;
			}
		}
		return false;
	}
}
shared class DefaultAmmoDisplayHook : AmmoDisplayHook {
	private ::array<::array<const ::jjANIMATION@>> m_anims(9, ::array<const ::jjANIMATION@>(2));
	void setWeaponSprite(uint number, bool powerup, const ::jjANIMATION@ anim) {
		if (isValidWeapon(number))
			@m_anims[number - 1][powerup ? 1 : 0] = @anim;
	}
	bool draw(const ::jjPLAYER@ player, ::jjCANVAS@ canvas) {
		if (player !is null) {
			uint number = player.currWeapon;
			if (isValidWeapon(number)) {
				const ::jjANIMATION@ anim = @m_anims[number - 1][player.powerup[number] ? 1 : 0];
				if (anim !is null) {
					if (canvas !is null) {
						int x, y;
						STRING::Size font;
						::string text;
						const ::jjWEAPON@ weapon = ::jjWeapons[number];
						if (::jjSubscreenWidth > 400) {
							x = ::jjSubscreenWidth - 88;
							y = ::jjSubscreenHeight - 14;
							font = STRING::MEDIUM;
						} else {
							x = ::jjSubscreenWidth - 48;
							y = ::jjSubscreenHeight - 9;
							font = STRING::SMALL;
						}
						if (weapon.infinite || weapon.replacedByShield && player.shieldTime > 0) {
							text = "x^";
						} else {
							int ammo = player.ammo[number] / weapon.multiplier;
							text = "x" + (ammo > 0 ? ammo : 0);
						}	
						canvas.drawSpriteFromCurFrame(x, y, anim + (::jjGameTicks >> 2) % anim.frameCount);
						canvas.drawString(x + 8, y, text, font);
					}
					return true;
				}
			}
		}
		return false;
	}
}
shared class AmmoPickup : ::jjBEHAVIORINTERFACE {
	private const ::jjANIMATION@ m_basic, m_powered;
	private uint m_count;
	AmmoPickup(const ::jjANIMATION@ basic, const ::jjANIMATION@ powered, uint count = 3) {
		@m_basic = @basic;
		@m_powered = @powered;
		m_count = count;
	}
	protected void draw(float x, float y, uint sprite, int direction, bool translucent, int playerID) const {
		::jjDrawSpriteFromCurFrame(x, y, sprite, direction, translucent ? SPRITE::TRANSLUCENT : SPRITE::NORMAL, 0, 4, 4, playerID);
	}
	protected float getY(const ::jjOBJ@ obj) const {
		int arg = (((obj.objectID << 3) + ::jjGameTicks) << (obj.yPos > ::jjWaterLevel ? 1 : 4)) + (int(obj.xPos) << 4);
		return obj.yPos + ::jjSin(arg) * 4.f;
	}
	void onBehave(::jjOBJ@ obj) override {
		obj.behave(BEHAVIOR::PICKUP, false);
		for (int i = 0; i < ::jjLocalPlayerCount; i++) {
			const ::jjPLAYER@ player = @::jjLocalPlayers[i];
			const ::jjANIMATION@ anim = @(player.powerup[obj.var[3] + 1] ? @m_powered : @m_basic);
			uint sprite = anim + obj.frameID % anim.frameCount;
			draw(obj.xPos, getY(obj), sprite, obj.direction, ::jjAnimFrames[sprite].transparent, player.playerID);
		}
	}
	bool onObjectHit(::jjOBJ@ obj, ::jjOBJ@ bullet, ::jjPLAYER@ player, int) {
		if (bullet is null) {
			bool sp = ::jjGameMode == GAME::SP || ::jjGameMode == GAME::COOP;
			int type = obj.var[3] + 1;
			if (::jjAutoWeaponChange && player.ammo[type] == 0 && (player.shieldType == 0 || !::jjWeapons[player.currWeapon].replacedByShield) && m_count != 0)
				player.currWeapon = type;
			int maximum = ::jjWeapons[type].maximum, multiplier = ::jjWeapons[type].multiplier;
			if (maximum == -1)
				maximum = sp ? 99 : 50;
			maximum *= multiplier;
			if (player.ammo[type] >= maximum) {
				player.ammo[type] = maximum;
			} else {
				player.ammo[type] = player.ammo[type] + m_count;
				if (player.ammo[type] >= maximum)
					player.ammo[type] = maximum;
				obj.frameID = 0;
				obj.behavior = BEHAVIOR::EXPLOSION2;
				::jjSample(obj.xPos, obj.yPos, SOUND::COMMON_PICKUPW1);
				if (sp && obj.points != 0) {
					player.score += obj.points;
					::jjPARTICLE@ part = ::jjAddParticle(PARTICLE::STRING);
					if (part !is null) {
						part.xPos = obj.xPos;
						part.yPos = obj.yPos;
						part.xSpeed = -0.5f - (jjRandom() & 0x3FFF) / 65536.f;
						part.ySpeed = -1.f - (jjRandom() & 0x7FFF) / 65536.f;
						part.string.text = ::formatInt(obj.points);
					}
					obj.points = 0;
				}
			}
			return true;
		}
		return false;
	}
}
}