Downloads containing AmmoPraccy.j2as

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Ammo Cycle Practice... jjturbo9 Single player N/A Download file

File preview

const bool MLLESetupSuccessful = MLLE::Setup(); ///@MLLE-Generated
#include "MLLE-Include-1.8.asc" ///@MLLE-Generated
#pragma require "AmmoPraccy.j2l" ///@MLLE-Generated

// ==========================================
// WEAPON PRACTICE CONFIGURATION
// If you want to exclude some ammo from this exercise, you can do so at the start of the AngelScript. Ice ammo is disabled by default.
// ==========================================
array<bool> enabledWeapons = {
    false, // 1: Blaster
    true, // 2: Bouncer
    false, // 3: Ice Gun
    true, // 4: Seeker
    true, // 5: RF
    true, // 6: Toaster
    true, // 7: TNT
    true, // 8: Pepper Spray
    true  // 9: Electro
};
// ==========================================

bool targetActive = false;
uint8 targetWeapon = 1;
float targetX = 0;
float targetY = 0;
bool prevFire = false;

void onMain() {
    jjPLAYER@ p = jjLocalPlayers[0];

    // 1. Give infinite ammo and powerups for all weapons
    for (uint8 i = 1; i <= 9; i++) {
        p.ammo[i] = 99;
        p.powerup[i] = true;
    }

    // 2. Spawn a new block if one doesn't exist
    if (!targetActive) {
        uint8 newWeapon;
        int safetyCounter = 0; // Prevents infinite loop if all weapons are turned off
        
        do {
            newWeapon = (jjRandom() % 9) + 1; 
            safetyCounter++;
            if (safetyCounter > 100) break; // Fallback safety
        } while (newWeapon == targetWeapon || !enabledWeapons[newWeapon - 1]);
        
        targetWeapon = newWeapon;

        // Randomly pick a spawn zone: 0 = Left, 1 = Right, 2 = Up, 3 = Down
        int spawnZone = jjRandom() % 4; 
        
        // Level is 25x19 tiles. 25*32 = 800 width, 19*32 = 608 height.
        // Center point of the level in pixels: X = 400, Y = 304.
        const float centerX = 400.0f;
        const float centerY = 304.0f;

        switch(spawnZone) {
            case 0: // Left
                targetX = centerX - 256 - (jjRandom() % 64);
                targetY = centerY - 128 + (jjRandom() % 256);
                break;
            case 1: // Right
                targetX = centerX + 256 + (jjRandom() % 64);
                targetY = centerY - 128 + (jjRandom() % 256);
                break;
            case 2: // Up
                targetX = centerX - 160 + (jjRandom() % 320);
                targetY = centerY - 192 - (jjRandom() % 64);
                break;
            case 3: // Down
                targetX = centerX - 160 + (jjRandom() % 320);
                targetY = centerY + 192 + (jjRandom() % 64);
                break;
        }

        targetActive = true;
    }

    // 3. Check if the player fired the correct weapon
    if (p.keyFire && !prevFire) {
        if (p.currWeapon == targetWeapon) {
            targetActive = false; // Block destroyed, loop continues instantly!
        }
    }

    prevFire = p.keyFire; 
}

void onDrawLayer4(jjPLAYER@ p, jjCANVAS@ canvas) {
    if (targetActive) {
        int drawX = int(targetX - p.cameraX);
        int drawY = int(targetY - p.cameraY);

        // --- FIXED AMMO SPRITE LOGIC ---
        const int weaponID = targetWeapon;
        const bool powerup = p.powerup[weaponID];
        const CHAR::Char charCurr = p.charCurr != CHAR::BIRD2 ? p.charCurr : p.charOrig;
        jjANIMATION@ anim;

        if (weaponID == 1) { // BLASTER
            @anim = jjAnimations[
                charCurr == CHAR::SPAZ ? (powerup ? (jjAnimSets[ANIM::AMMO] + 19) : (jjAnimSets[ANIM::PICKUPS] + 30)) :
                (jjIsTSF && charCurr == CHAR::LORI) ? (powerup ? (jjAnimSets[ANIM::PLUS_AMMO] + 6) : (jjAnimSets[ANIM::PLUS_AMMO] + 5)) :
                (powerup ? (jjAnimSets[ANIM::AMMO] + 18) : (jjAnimSets[ANIM::PICKUPS] + 29))
            ];
        } else {
            // Correct mapping array offsets matching standard JJ2 animation layout
            int animOffset = 0;
            switch(weaponID) {
                case 2: animOffset = 25; break; // Bouncer
                case 3: animOffset = 29; break; // Ice
                case 4: animOffset = 34; break; // Seeker
                case 5: animOffset = 49; break; // RF
                case 6: animOffset = 57; break; // Toaster
                case 7: animOffset = 59; break; // TNT
                case 8: animOffset = 62; break; // Pepper
                case 9: animOffset = 68; break; // Electro
            }
            if (powerup && weaponID != 7) { // Adjust for powerup except TNT if applicable
                animOffset--;
            }
            @anim = jjAnimations[jjAnimSets[ANIM::AMMO] + animOffset];
        }

        // Draw the correct animated sprite standalone without the background box
        canvas.drawSpriteFromCurFrame(drawX, drawY, anim + (jjGameTicks >> 2) % anim.frameCount, 0, weaponID == 1 ? SPRITE::PLAYER : SPRITE::NORMAL, p.playerID);
    }
}