Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
violetclm DOM Episodes I... | Violet CLM | Custom / Concept | 9 | |||||
Custom Weapons... | Violet CLM | Other | 10 |
#pragma require "weaponVMega4.asc"
#include "MLLE-Weapons.asc"
#pragma require "weaponVMega.j2a"
namespace WeaponVMega {
namespace Pathfinder {
class Weapon : MLLEWeapons::WeaponInterface {
uint node1 = 1, node2 = 4, node3 = 2, node4 = 6;
Weapon() {
super(
regularObjectTemplate: MLLEWeapons::ObjectTemplate(
xSpeed: 2,
xAcc: 0.125,
killAnim: jjAnimSets[ANIM::AMMO].firstAnim + 80,
counterEnd: 46,
lightType: LIGHT::POINT2,
isBlastable: false,
playerHandling: HANDLING::PARTICLE
),
powerupObjectTemplate: MLLEWeapons::ObjectTemplate(
xSpeed: 1.5,
xAcc: 0.1875,
killAnim: jjAnimSets[ANIM::AMMO].firstAnim + 80,
counterEnd: 32,
lightType: LIGHT::POINT2,
curAnim: 1,
isBlastable: false,
playerHandling: HANDLING::PARTICLE
),
animSetFilename: "weaponVMega.j2a",
animSetID: 3,
pickupAnimation: 4,
poweredUpPickupAnimation: 5,
style: WEAPON::MISSILE,
replacedByBubbles: true,
traits: se::weapon_default_traits | se::weapon_melts_ice | se::weapon_fails_underwater,
behavior: MLLEWeapons::behaviorFunction(DetermineBehavior),
apply: MLLEWeapons::applyFunction(DetermineNodeCount)
);
}
void DetermineBehavior(jjOBJ@ obj, bool powerup) const {
obj.behavior = Behavior(
obj,
!powerup ?
array<uint>={node1,node2} :
array<uint>={node3,node4}
);
}
bool DetermineNodeCount(uint, se::WeaponHook@, jjSTREAM@ parameter) {
if (parameter !is null && parameter.getSize() >= 16) {
int p;
parameter.pop(p); node1 = p;
parameter.pop(p); node2 = p;
parameter.pop(p); node3 = p;
parameter.pop(p); node4 = p;
}
return true;
}
}
class Behavior : jjBEHAVIORINTERFACE {
jjOBJ@ obj;
array<jjOBJ@> nodes;
bool waiting = false;
bool foundAtLeastOneTarget = false;
uint counter = 0;
bool powerup;
array<uint> nodeLimits;
Behavior(jjOBJ@ objectOfAttachment, array<uint> nl) {
@obj = @objectOfAttachment;
obj.state = STATE::FLY;
powerup = MLLEWeapons::HelpfulBulletFunctions::IsPowerup(obj);
jjSample(obj.xPos, obj.yPos, powerup ? SOUND::AMMO_LASER3 : SOUND::AMMO_LASER2);
nodeLimits = nl;
}
void destroy() {
jjSample(obj.xPos, obj.yPos, SOUND::COMMON_ELECTRIC2);
for (uint i = 0; i < nodes.length; ++i)
nodes[i].delete();
obj.delete();
}
void onBehave(jjOBJ@) {
if (obj.state == STATE::EXPLODE) {
destroy();
return;
}
obj.frameID = (obj.objectID + jjGameTicks / 3) % 3;
if (++counter >= obj.counterEnd) {
if (waiting = !waiting) { //stop moving
addNode();
counter = obj.counterEnd / 2;
} else { //start moving
if (nodes.length > (nodeLimits[foundAtLeastOneTarget ? 1 : 0]) || obj.state == STATE::DONE) {
destroy();
return;
}
const array<float>@ target = MLLEWeapons::HelpfulBulletFunctions::GetNearestEnemyPosition(obj, 200);
if (target !is null) {
obj.var[7] = 0;
const float standardSpeed = (powerup ? 3.f : 2.5f);
const float dx = target[0] - obj.xPos, dy = target[1] - obj.yPos;
foundAtLeastOneTarget = true;
if (abs(dx) > abs(dy)) {
obj.xSpeed = (dx > 0) ? standardSpeed : -standardSpeed;
obj.ySpeed = 0;
} else {
obj.xSpeed = 0;
obj.ySpeed = (dy > 0) ? standardSpeed : -standardSpeed;
}
}
counter = 0;
}
}
if (!waiting) {
obj.xPos += obj.xSpeed + obj.var[7] / 65536.f;
obj.yPos += obj.ySpeed;
if (obj.var[7] > 0x100000)
obj.var[7] = obj.var[7] - 0x80000;
else if (obj.var[7] < -0x100000)
obj.var[7] = obj.var[7] + 0x80000;
if (MLLEWeapons::HelpfulBulletFunctions::MaskedPixel(obj) && jjEventAtLastMaskedPixel != AREA::ONEWAY && jjEventAtLastMaskedPixel != AREA::HOOK && jjEventAtLastMaskedPixel != AREA::VINE) {
counter = obj.counterEnd / 2;
waiting = true;
addNode();
obj.state = STATE::DONE;
}
}
}
void addNode() {
jjOBJ@ node = jjObjects[jjAddObject(OBJECT::BEES, obj.xPos, obj.yPos, obj.creatorID, obj.creatorType, BEHAVIOR::BEES)];
node.playerHandling = HANDLING::PLAYERBULLET;
node.var[6] = 2 | (powerup ? 8 : 0) | 16; //fireball
node.animSpeed = powerup ? 2 : 1;
node.curFrame = jjAnimations[obj.curAnim + 2];
node.state = STATE::FLY;
node.lightType = LIGHT::BRIGHT;
node.light = powerup ? 10 : 8;
node.isTarget = false;
nodes.insertLast(node);
jjSample(obj.xPos, obj.yPos, SOUND::COMMON_ELECTRIC1);
}
void onDraw(jjOBJ@) {
jjDrawSpriteFromCurFrame(obj.xPos, obj.yPos, obj.curFrame + obj.frameID);
for (uint i = 0; i < nodes.length; ++i) {
const jjOBJ@ node = nodes[i];
const jjOBJ@ node2 = (i < nodes.length - 1) ? nodes[i + 1] : obj;
if (node.xPos == node2.xPos || node.yPos == node2.yPos) //non-diagonal
jjDrawRectangle(node.xPos, node.yPos, int(node2.xPos - node.xPos) + 1, int(node2.yPos - node.yPos) + 1, 15);
jjDrawSpriteFromCurFrame(node.xPos, node.yPos, node.curFrame + obj.frameID);
}
}
}
}
}
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.