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

Java tutorial

Introduction

Here is the source code for org.jtrfp.trcl.obj.SmokeSystem.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.util.Comparator;
import java.util.TreeSet;

import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.jtrfp.trcl.RenderableSpacePartitioningGrid;
import org.jtrfp.trcl.core.TR;
import org.jtrfp.trcl.math.Misc;
import org.jtrfp.trcl.obj.Explosion.ExplosionType;
import org.jtrfp.trcl.obj.Smoke.SmokeType;

public class SmokeSystem extends RenderableSpacePartitioningGrid {
    private final TR tr;
    private final int MAX_SMOKE_PER_POOL = 80;
    private final Smoke[][] allSmokes = new Smoke[SmokeType.values().length][];
    private final int[] indices = new int[SmokeType.values().length];

    public SmokeSystem(TR tr) {
        super(tr.getDefaultGrid());
        this.tr = tr;
        int i;
        for (SmokeType t : SmokeType.values()) {
            allSmokes[t.ordinal()] = new Smoke[MAX_SMOKE_PER_POOL];
            for (i = 0; i < MAX_SMOKE_PER_POOL; i++) {
                allSmokes[t.ordinal()][i] = new Smoke(tr, t);
            } //end for(MAX_SMOKE_PER_POOL)
        } //end for(SmokeType s)
    }//end constructor()

    public Smoke triggerSmoke(Vector3D pos, SmokeType type) {
        if (!isNewSmokeFeasible(pos, type))
            return null;
        indices[type.ordinal()]++;
        indices[type.ordinal()] %= MAX_SMOKE_PER_POOL;
        Smoke result = allSmokes[type.ordinal()][indices[type.ordinal()]];
        result.destroy();
        result.reset();
        result.setPosition(pos.toArray());
        add(result);
        return result;
    }//end triggerSmoke()

    private boolean isNewSmokeFeasible(final Vector3D loc, SmokeType type) {
        final TreeSet<Smoke> proximalSmokes = new TreeSet<Smoke>(new Comparator<Smoke>() {
            @Override
            public int compare(Smoke o1, Smoke o2) {
                return Misc.satCastInt(o1.getTimeOfLastReset() - o2.getTimeOfLastReset());
            }
        });
        for (int smokeTypeIndex = 0; smokeTypeIndex < allSmokes.length; smokeTypeIndex++) {
            Smoke[] explosionsOfThisType = allSmokes[smokeTypeIndex];
            for (Smoke thisSmoke : explosionsOfThisType) {
                if (thisSmoke.isActive()) {
                    final double distance = new Vector3D(thisSmoke.getPosition()).distance(loc);
                    if (distance < 1000)
                        return false;
                    if (distance < OneShotBillboardEvent.PROXIMITY_TEST_DIST)
                        proximalSmokes.add(thisSmoke);
                } // end if(isActive)
            } // end for(explosionsOfThisType)
        } // end for(explosions)
        if (proximalSmokes.size() + 1 > OneShotBillboardEvent.MAX_PROXIMAL_EVENTS)
            proximalSmokes.first().destroy();// Destroy oldest
        return true;
    }// end isNewSmokeFeasible(...)
}//end SmokeFactory