org.jtrfp.trcl.obj.ProjectileFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.jtrfp.trcl.obj.ProjectileFactory.java

Source

/*******************************************************************************
 * This file is part of TERMINAL RECALL
 * Copyright (c) 2012-2014 Chuck Ritola
 * Part of the jTRFP.org project
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     chuck - initial API and implementation
 ******************************************************************************/
package org.jtrfp.trcl.obj;

import java.awt.Dimension;
import java.util.List;

import javax.media.opengl.GL3;

import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.jtrfp.trcl.AnimatedTexture;
import org.jtrfp.trcl.RenderMode;
import org.jtrfp.trcl.Sequencer;
import org.jtrfp.trcl.Triangle;
import org.jtrfp.trcl.beh.DestroysEverythingBehavior;
import org.jtrfp.trcl.core.ResourceManager;
import org.jtrfp.trcl.core.TR;
import org.jtrfp.trcl.core.Texture;
import org.jtrfp.trcl.core.TextureDescription;
import org.jtrfp.trcl.file.ModelingType;
import org.jtrfp.trcl.file.Weapon;
import org.jtrfp.trcl.flow.GameVersion;
import org.jtrfp.trcl.gpu.Model;
import org.jtrfp.trcl.img.vq.ColorPaletteVectorList;
import org.jtrfp.trcl.math.Vect3D;
import org.jtrfp.trcl.obj.Explosion.ExplosionType;
import org.jtrfp.trcl.snd.SoundSystem;
import org.jtrfp.trcl.snd.SoundTexture;

public class ProjectileFactory {
    private int projectileIndex = 0;
    private final TR tr;
    private final Projectile[] projectiles = new Projectile[20];
    private final double projectileSpeed;
    private final Weapon weapon;
    private final SoundTexture soundTexture;

    public ProjectileFactory(TR tr, Weapon weapon, ExplosionType explosionType) {
        this.tr = tr;
        this.weapon = weapon;
        this.projectileSpeed = weapon.getSpeed() / TR.crossPlatformScalar;
        Model modelToUse;
        TextureDescription t;
        Triangle[] tris;
        final int damageOnImpact = weapon.getDamage();
        try {
            modelToUse = new Model(false, tr);
            final ModelingType modelingType = weapon.getModelingType();
            if (modelingType instanceof ModelingType.FlatModelingType) {
                ModelingType.FlatModelingType mt = (ModelingType.FlatModelingType) modelingType;
                Dimension dims = mt.getSegmentSize();
                final int laserplaneLength = (int) (dims.getWidth() / TR.crossPlatformScalar);
                final int laserplaneWidth = (int) (dims.getHeight() / TR.crossPlatformScalar);
                t = tr.getResourceManager()
                        .getRAWAsTexture(tr.config.getGameVersion() != GameVersion.TV ? mt.getF3RawFileName()
                                : mt.getTvRawFileName(), tr.getDarkIsClearPaletteVL(), null, false);
                final double Y_SLANT = 1024;
                tris = (Triangle.quad2Triangles(
                        new double[] { -laserplaneLength / 2., laserplaneLength / 2., laserplaneLength / 2.,
                                -laserplaneLength / 2. }, //X
                        new double[] { 0, 0, Y_SLANT, Y_SLANT },
                        new double[] { -laserplaneWidth / 2., -laserplaneWidth / 2., laserplaneWidth / 2.,
                                laserplaneWidth / 2. }, //YZ
                        new double[] { 1, 0, 0, 1 }, new double[] { 0, 0, 1, 1 }, t, RenderMode.STATIC,
                        Vector3D.ZERO, "ProjectileFactory:" + weapon.toString()));//UVtr
                tris[0].setAlphaBlended(true);
                tris[1].setAlphaBlended(true);
                modelToUse.addTriangles(tris);
                modelToUse.finalizeModel();
                for (int i = 0; i < projectiles.length; i++) {
                    projectiles[i] = new ProjectileObject3D(tr, modelToUse, weapon, explosionType);
                }
            } //end if(isLaser)
            else if (modelingType instanceof ModelingType.BillboardModelingType) {
                final ModelingType.BillboardModelingType mt = (ModelingType.BillboardModelingType) modelingType;
                final Texture[] frames = new Texture[mt.getRawFileNames().length];
                final String[] fileNames = mt.getRawFileNames();
                final ResourceManager mgr = tr.getResourceManager();
                final ColorPaletteVectorList pal = tr.getGlobalPaletteVL();
                GL3 gl = tr.gpu.get().getGl();
                for (int i = 0; i < frames.length; i++) {
                    frames[i] = (Texture) mgr.getRAWAsTexture(fileNames[i], pal, null, false);
                } //end for(frames)
                TextureDescription tex = new AnimatedTexture(
                        new Sequencer(mt.getTimeInMillisPerFrame(), frames.length, false), frames);
                for (int i = 0; i < projectiles.length; i++) {
                    projectiles[i] = new ProjectileBillboard(tr, weapon, tex, ExplosionType.Billow);
                }
            } //end (billboard)
            else if (modelingType instanceof ModelingType.BINModelingType) {
                final ModelingType.BINModelingType mt = (ModelingType.BINModelingType) modelingType;
                modelToUse = tr.getResourceManager().getBINModel(mt.getBinFileName(), tr.getGlobalPaletteVL(), null,
                        tr.gpu.get().getGl());
                for (int i = 0; i < projectiles.length; i++) {
                    projectiles[i] = new ProjectileObject3D(tr, modelToUse, weapon, explosionType);
                }
            } //end BIN Modeling Type
            else {
                throw new RuntimeException("Unhandled ModelingType: " + modelingType.getClass().getName());
            }
        } //end try
        catch (Exception e) {
            e.printStackTrace();
        }
        //CLAUSE: FFF needs destroysEvertyhing behavior
        if (weapon == Weapon.DAM) {
            for (int i = 0; i < projectiles.length; i++) {
                ((WorldObject) projectiles[i]).addBehavior(new DestroysEverythingBehavior());
            }
        } //end if(DAM)

        //Sound
        String soundFile = null;
        switch (weapon) {
        //PEW!!!
        case PAC: {
            soundFile = "LASER2.WAV";
            break;
        }
        case ION: {
            soundFile = "LASER3.WAV";
            break;
        }
        case RTL: {
            soundFile = "LASER4.WAV";
            break;
        }
        case DAM:
        case redLaser:
        case blueLaser:
        case greenLaser:
        case purpleLaser:
        case purpleRing: {
            soundFile = "LASER5.WAV";
            break;
        }
        //Missile
        case enemyMissile:
        case SWT:
        case MAM:
        case SAD: {
            soundFile = "MISSILE.WAV";
            break;
        }
        //SILENT
        case purpleBall:
        case goldBall:
        case fireBall:
        case blueFireBall:
        case bullet:
        case bossW8:
        case bossW7:
        case bossW6:
        case atomWeapon:
        default:
            break;
        }//end case()
        soundTexture = soundFile != null ? tr.getResourceManager().soundTextures.get(soundFile) : null;
    }//end constructor(...)

    public Projectile fire(double[] newPosition, Vector3D heading, WorldObject objectOfOrigin) {
        assert !Vect3D.isAnyNaN(newPosition);
        assert heading.getNorm() != 0 && heading.getNorm() != Double.NaN;

        final Projectile result = projectiles[projectileIndex];
        result.destroy();
        result.reset(newPosition, heading.scalarMultiply(projectileSpeed), objectOfOrigin);
        ((WorldObject) result).setTop(objectOfOrigin.getTop());
        tr.getDefaultGrid().add((WorldObject) result);
        tr.mainRenderer.get().temporarilyMakeImmediatelyRelevant((PositionedRenderable) result);
        if (soundTexture != null)
            tr.soundSystem.get()
                    .enqueuePlaybackEvent(tr.soundSystem.get().getPlaybackFactory().create(soundTexture,
                            (WorldObject) result, tr.mainRenderer.get().getCamera(),
                            (objectOfOrigin instanceof Player ? .6 : 1) * SoundSystem.DEFAULT_SFX_VOLUME));//TODO: Use configuration volume instead
        final List<WorldObject> cL = tr.getCollisionManager().getCurrentlyActiveCollisionList();
        synchronized (cL) {
            cL.add((WorldObject) result);
        }
        projectileIndex++;
        projectileIndex %= projectiles.length;
        return result;
    }//end fire(...)

    public Projectile[] getProjectiles() {
        return projectiles;
    }

    public Weapon getWeapon() {
        return weapon;
    }
}//end ProjectileFactory