Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Custom Weapons... | Violet CLM | Other | 10 |
#pragma require "autoTurret.j2a"
#pragma require "autoTurret.asc"
#include "MLLE-Weapons.asc"
/**Auto-Turret**/
/**Author: szmol96**/
namespace SzmolWeaponPack {
namespace AutoTurret {
enum packet_type {packet_getTurretData, packet_createTurret, packet_turretDeath};
const int turretBulletPointIdentifier = 21 + jjScriptModuleID;
class Weapon : MLLEWeapons::WeaponInterface {
Weapon() {
super(
regularObjectTemplate: MLLEWeapons::ObjectTemplate(
state: STATE::FLY,
xSpeed: 6,
points: turretBulletPointIdentifier,
curAnim: 1,
killAnim: jjAnimSets[ANIM::AMMO] + 4,
animSpeed: 2,
lightType: LIGHT::POINT,
counterEnd: 30
),
style: WEAPON::MISSILE,
animSetFilename: "autoTurret.j2a",
pickupAnimation: 0,
poweredUpPickupAnimation: 0,
generateSupplementalAnimations: false,
roundsPerPickup: 1,
traits: (se::weapon_default_traits | se::weapon_cannot_be_fired_by_key_press) & ~(se::weapon_has_powerup_monitors | se::weapon_has_distinct_powerup | se::weapon_has_ammo_crates),
onMain: se::MainCallback(RequestServerData),
onPlayerInput: se::PlayerCallback(PreventFiringAdditionalTurrets),
onReceive: se::PacketCallback(ProcessPacket),
onDrawAmmo: se::DrawingCallback(DrawAmmoIcon),
weaponHookRequired: true,
behavior: function(obj, powerup) { obj.behavior = BEHAVIOR::BULLET; obj.var[6] = 8; }
);
}
TurretBehavior@ MyTurretBehavior = TurretBehavior(this);
int AddTurret(float x, float y, uint16 crID, CREATOR::Type crType) {
if (crType == CREATOR::PLAYER) {
crID &= 31;
if (turrets[crID] !is null)
return 0;
}
const int objectID = jjAddObject(OBJECT::BULLET, x,y, crID, crType, BEHAVIOR::INACTIVE);
jjOBJ@ obj = jjObjects[objectID];
if (crType == CREATOR::PLAYER)
@turrets[crID] = @obj;
obj.behavior = MyTurretBehavior;
obj.playerHandling = HANDLING::SPECIAL;
obj.bulletHandling = HANDLING::DETECTBULLET;
obj.scriptedCollisions = true;
obj.energy = 50;
obj.freeze = 0;
obj.isTarget = false;
obj.state = STATE::WAIT;
obj.curFrame = jjAnimations[AnimSet];
obj.killAnim = jjAnimSets[ANIM::AMMO] + 5;
return objectID;
}
uint getMaxDamage(bool powerup) const override { return 2; }
array<jjOBJ@> turrets(32, null);
void sendTurretPacket(int32 playNum, uint8 playID = 0) const {
jjSTREAM packet = ConstructPacket();
packet.push(uint8(packet_createTurret));
packet.push(uint8(playNum));
const jjOBJ@ turret = turrets[playNum];
if (turret !is null) {
packet.push(int16(turret.xPos));
packet.push(int16(turret.yPos));
packet.push(turret.energy);
} else {
const jjPLAYER@ play = jjPlayers[playNum];
packet.push(int16(play.xPos));
packet.push(int16(play.yPos));
packet.push(int8(50));
}
jjSendPacket(packet, playID);
}
void sendDeathPacket(uint8 playNum) const {
jjSTREAM packet = ConstructPacket();
packet.push(uint8(packet_turretDeath));
packet.push(playNum);
jjSendPacket(packet);
}
array<bool> keyHeld(jjLocalPlayerCount);
void PreventFiringAdditionalTurrets(jjPLAYER@ p, int number) {
if (p.currWeapon == uint(number)) {
if (turrets[p.playerID] !is null)
p.keyFire = false;
else if (p.keyFire) {
if (jjIsServer || jjGameConnection == GAME::LOCAL)
AddTurret(p.xPos, p.yPos, p.playerID, CREATOR::PLAYER);
sendTurretPacket(p.playerID);
p.ammo[number] = 0;
keyHeld[p.localPlayerID] = true;
}
if (p.ammo[number] == 0) p.keySelect = true;
}
if (keyHeld[p.localPlayerID]) {
if (p.keyFire) p.keyFire = false;
else keyHeld[p.localPlayerID] = false;
}
}
bool RequestedServerData = false;
void RequestServerData(int) {
if (!RequestedServerData) {
jjAnimations[AnimSet].frameCount = 1; //makes pickup/ammoicon animation less ridiculous
RequestedServerData = true;
if (!jjIsServer && jjGameConnection != GAME::LOCAL) {
jjSTREAM packet = ConstructPacket();
packet.push(uint8(packet_getTurretData));
jjSendPacket(packet);
}
}
}
void ProcessPacket(jjSTREAM& packet, int clientID) {
uint8 type;
packet.pop(type);
if (type == packet_createTurret) {
uint8 playNum;
packet.pop(playNum);
if (jjIsServer && jjPlayers[playNum].clientID != clientID)
return;
int16 posX;
int16 posY;
packet.pop(posX);
packet.pop(posY);
AddTurret(posX, posY, playNum, CREATOR::PLAYER);
packet.pop(turrets[playNum].energy);
if (jjIsServer)
sendTurretPacket(playNum);
}
else if (jjIsServer) {
if (type == packet_getTurretData) {
for (uint8 i = 0; i < 32; ++i) {
jjOBJ@ turret = turrets[i];
if (turret !is null)
sendTurretPacket(i, clientID);
}
}
} else {
if (type == packet_turretDeath) {
uint8 playNum;
packet.pop(playNum);
if (turrets[playNum] !is null) //just to be safe
turrets[playNum].state = STATE::EXPLODE;
}
}
}
bool DrawAmmoIcon(jjPLAYER@ player, jjCANVAS@ canvas, const jjANIMATION@ anim) const {
if (player !is null && !player.noFire && player.charCurr != CHAR::FROG && player.charCurr != CHAR::BIRD) {
int x, y;
if (::jjSubscreenWidth > 400) {
x = ::jjSubscreenWidth - 88;
y = ::jjSubscreenHeight - 14;
} else {
x = ::jjSubscreenWidth - 48;
y = ::jjSubscreenHeight - 9;
}
canvas.drawSpriteFromCurFrame(x, y, anim + (::jjGameTicks >> 2) % anim.frameCount, 1, turrets[player.playerID] is null ? SPRITE::NORMAL : SPRITE::TRANSLUCENT);
}
return true;
}
}
class TurretBehavior : jjBEHAVIORINTERFACE {
Weapon@ weapon;
TurretBehavior(Weapon@ w) { @weapon = @w; }
void onBehave(jjOBJ@ obj) {
const array<float>@ target = MLLEWeapons::HelpfulBulletFunctions::GetNearestEnemyPosition(obj, 222, true);
if (target !is null) {
if (obj.freeze == 0) {
obj.special = int(atan2(obj.xPos - target[0], obj.yPos - target[1]) * 162.974662); //turret angle
if (obj.age % 15 == 0)
jjObjects[weapon.FireBullet(
obj.xPos - (jjSin(obj.special) * 20),
obj.yPos - (jjCos(obj.special) * 20),
768 - obj.special,
true,
obj.creatorID, obj.creatorType,
number: obj.var[3]
)[0]].var[7] = 0;
} //else remember previous angle
} else {
obj.special = int(jjSin(obj.age * 2) * 256);
}
if (!jjMaskedHLine(int(obj.xPos) - 10, 20, int(obj.yPos) + 16) && obj.ySpeed < 7.5) obj.ySpeed += 0.1;
else obj.ySpeed = 0;
if (obj.energy <= 0 || obj.state == STATE::EXPLODE || obj.state == STATE::DEACTIVATE) {
if (jjIsServer && obj.creatorType == CREATOR::PLAYER)
weapon.sendDeathPacket(obj.creatorID);
obj.particlePixelExplosion(0);
obj.behavior = BEHAVIOR::EXPLOSION2;
obj.frameID = 0;
if (obj.creatorType == CREATOR::PLAYER)
@weapon.turrets[obj.creatorID] = null;
}
obj.yPos += obj.ySpeed;
if (obj.freeze > 0) --obj.freeze;
else ++obj.age;
jjDrawRotatedSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame + 1, obj.special);
if (obj.creatorType == CREATOR::PLAYER)
jjDrawString(obj.xPos - 8, obj.yPos + 24, "" + obj.creatorID);
obj.draw();
}
bool onObjectHit(jjOBJ@ obj, jjOBJ@ bullet, jjPLAYER@ p, int force) {
if (bullet !is null && bullet.points != turretBulletPointIdentifier) {
if (jjIsServer || jjGameConnection == GAME::LOCAL)
obj.energy -= bullet.animSpeed;
obj.justHit = 5;
bullet.state = STATE::EXPLODE;
}
return true;
}
}
}
}
Jazz2Online © 1999-INFINITY (Site Credits). We have a Privacy Policy. Jazz Jackrabbit, Jazz Jackrabbit 2, Jazz Jackrabbit Advance and all related trademarks and media are ™ and © Epic Games. Lori Jackrabbit is © Dean Dodrill. J2O development powered by Loops of Fury and Chemical Beats.
Eat your lima beans, Johnny.