Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Threed Realms | Violet CLM | Single player | 9.7 | |||||
Anniversary Bash 25 CTF | Jazz2Online | Capture the flag | N/A | |||||
Anniversary Bash 22 levels | Jazz2Online | Multiple | N/A | |||||
Tech Tree | Violet CLM | Capture the flag | 7.8 | |||||
Custom Weapons... | Violet CLM | Other | 10 |
#pragma require "lockOnMissile.asc"
#pragma require "lockOnMissile.j2a"
#pragma offer "lock-on.wav"
#include "MLLE-Weapons.asc"
/***Lock-on Missile**/
/**Author: szmol96**/
namespace SzmolWeaponPack {
namespace LockOnMissile {
class PlayerX {
int prevClosest = 0;
int missileCounter = 0;
uint mCounterDelay = 0;
}
array<PlayerX> PlayersX(jjLocalPlayerCount);
array<int> closestPlayers(32, -1); //needed even for non-local players
class Weapon : MLLEWeapons::WeaponInterface {
Weapon() {
super(
regularObjectTemplate: MLLEWeapons::ObjectTemplate(
xSpeed: 7,
animSpeed: 2,
curAnim: 0
),
powerupObjectTemplate: MLLEWeapons::ObjectTemplate(
xSpeed: 7.5,
animSpeed: 3,
curAnim: 1,
doesHurt: 8
),
sampleFilenames: array<string> = {"lock-on.wav"},
animSetFilename: "lockOnMissile.j2a",
pickupAnimation: 3,
poweredUpPickupAnimation: 4,
powerupAnimation: 5,
style: WEAPON::MISSILE,
traits: se::weapon_default_traits,
onDrawAmmo: se::DrawingCallback(DrawMissiles),
onMain: TrackNearestPlayers,
onPlayer: se::PlayerCallback(DoLockOnTarget),
weaponHookRequired: false, //it can get by
behavior: function(obj, powerup) { obj.behavior = Behavior; }
);
}
bool DrawMissiles(jjPLAYER@ p, jjCANVAS@ canvas, const jjANIMATION@) const {
for (int i = 0; i != PlayersX[p.localPlayerID].missileCounter; ++i)
canvas.drawSprite(jjSubscreenWidth - 64, jjSubscreenHeight - 32 - i * 8, SetID,2,1, (i % 2 == 0) ? 1 : -1);
return false;
}
void DoLockOnTarget(jjPLAYER@ p, int number) {
const int closestID = closestPlayers[p.playerID];
PlayerX@ px = PlayersX[p.localPlayerID];
if (int(p.currWeapon) == number) {
if (closestID >= 0) {
const jjPLAYER@ target = jjPlayers[closestID];
jjDrawSprite(target.xPos, target.yPos, SetID,2,0, 0, SPRITE::NORMAL,0, 1,4, p.playerID);
if (SamplesLoaded[0] && closestID != px.prevClosest)
jjSample(p.xPos, p.yPos, Samples[0]);
}
if (p.keyFire) {
if (px.mCounterDelay++ > 70 && px.mCounterDelay % 17 == 0 && px.missileCounter < 8 && px.missileCounter < p.ammo[WEAPON::CURRENT])
px.missileCounter += 1;
} else {
if (px.missileCounter > 0) {
for (int i = 0; i < px.missileCounter; ++i)
p.fireBullet(number, true, true, i * 6.2831853 / px.missileCounter);
px.missileCounter = 0;
p.keySelect = p.ammo[WEAPON::CURRENT] == 0;
}
px.mCounterDelay = 0;
}
}
px.prevClosest = closestID;
}
}
void TrackNearestPlayers(int) {
if (jjGameMode <= GAME::COOP)
return;
jjOBJ@ bogus = jjObjects[0];
bogus.creator = CREATOR::PLAYER;
for (uint playerID = 0; playerID < 32; ++playerID, ++bogus.creator) {
const jjPLAYER@ p = jjPlayers[playerID];
if (p.isInGame) {
bogus.xPos = p.xPos;
bogus.yPos = p.yPos;
closestPlayers[playerID] = MLLEWeapons::HelpfulBulletFunctions::GetNearestEnemyPlayer(bogus, 450);
}
}
}
void Behavior(jjOBJ@ obj) {
if (obj.state == STATE::START) {
obj.points = int(atan2(obj.xSpeed, obj.ySpeed) * 162.974636 /*+ (jjCos(jjRandom() % 512) * 10)*/); //angle
obj.state = STATE::FLY;
obj.xSpeed += obj.var[7] / 65536.f;
} else if (obj.age > 17) { //redirect
array<float>@ target = null;
if (obj.creatorType == CREATOR::PLAYER && jjGameMode > GAME::COOP) {
const int targetPlayerID = closestPlayers[obj.creatorID]; //closest to player who fired this
if (targetPlayerID >= 0)
@target = array<float> = { jjPlayers[targetPlayerID].xPos, jjPlayers[targetPlayerID].yPos };
}
if (target is null)
@target = MLLEWeapons::HelpfulBulletFunctions::GetNearestEnemyPosition(obj, 450); //closest to bullet itself... this part is new to the .asc reimplementation
if (target !is null) {
int difference = ((int(atan2(obj.xPos - target[0], obj.yPos - target[1]) * 162.974636) + 512 - obj.points) & 1023);
if (difference >= 512) difference -= 1024;
obj.points += difference / 8;
const float speed = MLLEWeapons::HelpfulBulletFunctions::IsPowerup(obj) ? 7.5f : 7;
obj.xSpeed = speed * jjSin(obj.points);
obj.ySpeed = speed * jjCos(obj.points);
}
}
obj.xPos += obj.xSpeed;
obj.yPos += obj.ySpeed;
++obj.age;
if (obj.age > 105 || obj.state == STATE::EXPLODE || MLLEWeapons::HelpfulBulletFunctions::MaskedPixel(obj)) {
for (uint8 i = 0; i < 10; ++i) {
jjPARTICLE@ spark1 = jjAddParticle(PARTICLE::SPARK);
if (spark1 !is null) {
spark1.spark.color = 32 + obj.doesHurt;
spark1.spark.colorDelta = 1;
spark1.spark.colorStop = 38 + obj.doesHurt;
spark1.xPos = obj.xPos;
spark1.yPos = obj.yPos;
spark1.xSpeed = obj.xSpeed / 3 + (jjCos(jjRandom() % 512));
spark1.ySpeed = obj.ySpeed / 3 + (jjCos(jjRandom() % 512));
}
}
obj.delete();
} else {
jjAddObject(OBJECT::EXPLOSION, obj.xPos, obj.yPos, obj.objectID, CREATOR::OBJECT, missileTrail);
obj.draw();
}
}
void missileTrail(jjOBJ@ trail) {
if (trail.state == STATE::START) {
trail.age = 0;
trail.curAnim = jjObjects[trail.creatorID].curAnim;
trail.direction = jjObjects[trail.creatorID].direction;
trail.lightType = LIGHT::NONE;
trail.playerHandling = HANDLING::EXPLOSION;
trail.state = STATE::FLY;
}
if (trail.age > 15)
trail.delete();
else
jjDrawSpriteFromCurFrame(trail.xPos, trail.yPos, jjAnimations[trail.curAnim] + (trail.age++ / 3), trail.direction, SPRITE::TRANSLUCENT);
}
}
}
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.