package robombs.game.view; import java.util.*; import java.awt.Color; import com.threed.jpct.*; import com.threed.jpct.util.ShadowHelper; import robombs.game.model.*; import robombs.game.util.SimpleStream; import robombs.game.*; public class CrateManager { private static Color[] glowColors=new Color[200]; private List<CrateView> crates=null; private World world=null; // The "glow" marks crates in bomb's range. private Object3D[] glows=new Object3D[4]; private static Object3D bluePrintGlow=null; private int colorIndex=0; static { try { SimpleStream ss = new SimpleStream("data/crate.3ds"); bluePrintGlow = new ClientObject(Loader.load3DS(ss.getStream(), 0.095f)[0]); ss.close(); bluePrintGlow.translate(0, -4.3f, -5.2f); bluePrintGlow.translateMesh(); bluePrintGlow.getTranslationMatrix().setIdentity(); bluePrintGlow.setTexture("glow"); bluePrintGlow.getMesh().compress(); bluePrintGlow.build(); } catch(Exception e) { throw new RuntimeException("Unable to load glow object!"); } for (int i=0; i<(glowColors.length>>1); i++) { Color col=new Color(i+28,0,0); glowColors[i]=col; glowColors[glowColors.length-1-i]=col; } } public CrateManager(World world) { crates=new ArrayList<CrateView>(); this.world=world; for (int i=0; i<glows.length; i++) { Object3D glow=new Object3D(bluePrintGlow); glow.setTransparency(10); glow.setTransparencyMode(Object3D.TRANSPARENCY_MODE_ADD); glow.setVisibility(false); world.addObject(glow); glow.build(); glow.setLighting(Object3D.LIGHTING_NO_LIGHTS); glows[i]=glow; } } public void addCrate(SimpleVector position, int id, DecalManager decMan, ClientEventQueue eventQueue, boolean botUsage) { CrateView e=null; for (CrateView ex: crates) { if (!ex.getVisibility()) { e=ex; break; } } if (e==null) { e=(CrateView) ClientObjectFactory.getInstance().create(Types.CRATE); e.setEventQueue(eventQueue); crates.add(e); e.addToWorld(world); e.init(id); e.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS); e.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED); e.addCollisionListener(new ClientObjectCollisionListener(e.getLocalObject(), decMan, true)); } if (botUsage) { e.botUsage(); } e.setDecalManager(decMan); e.translate(position); } public void processGlows(long ticks, Level level, LocalPlayerObject player) { PlayerPowers powers=player.getPlayerPowers(); int width=powers.getFirePower(); SimpleVector pos=player.getPosition(); colorIndex+=ticks; colorIndex%=glowColors.length; for (int i=0; i<glows.length; i++) { glows[i].setVisibility(false); } MapMask mask=level.getMask(); GridPosition gp=mask.getGrid(pos.x, pos.z); int x=gp.getX(); int z=gp.getZ(); boolean bl=false; boolean br=false; boolean bu=false; boolean bo=false; int wi=(int)((float)width/(float)MapMask.TILE_SIZE+0.5f)+1; for (int i=0; i<=wi; i++) { // x+ int ml=mask.getMaskAt(x+i, z); if (!bl) { if (ml==MapMask.UNKNOWN) { bl=true; } } float delta=3f; if (Globals.useBombingGrid) { delta=Globals.bombingGridWidth; } if (!bl && !glows[0].getVisibility() && (ml==MapMask.CRATE || MapMask.isItem(ml))) { GridPosition gp2=new GridPosition(x+i,z); if (hasCrateAt(gp2, mask)) { SimpleVector posc=gp2.convertTo3D(); if (Math.abs(pos.x-posc.x)<=width+MapMask.TILE_SIZE/2+2f && Math.abs(pos.z-posc.z)<=delta) { glows[0].setVisibility(true); glows[0].getTranslationMatrix().setIdentity(); posc.y=0; glows[0].translate(posc); glows[0].setAdditionalColor(glowColors[colorIndex]); } } else { bl=true; } } //x- int mr=mask.getMaskAt(x-i, z); if (!br) { if (mr==MapMask.UNKNOWN) { br=true; } } if (!br && !glows[1].getVisibility() && (mr==MapMask.CRATE || MapMask.isItem(mr))) { GridPosition gp2=new GridPosition(x-i,z); if (hasCrateAt(gp2, mask)) { SimpleVector posc=gp2.convertTo3D(); if (Math.abs(pos.x-posc.x)<=width+MapMask.TILE_SIZE/2+2f && Math.abs(pos.z-posc.z)<=delta) { glows[1].setVisibility(true); glows[1].getTranslationMatrix().setIdentity(); posc.y=0; glows[1].translate(posc); glows[1].setAdditionalColor(glowColors[colorIndex]); } }else { br=true; } } //z+ int mu=mask.getMaskAt(x, z+i); if (!bu) { if (mu==MapMask.UNKNOWN) { bu=true; } } if (!bu && !glows[2].getVisibility() && (mu==MapMask.CRATE || MapMask.isItem(mu))) { GridPosition gp2=new GridPosition(x,z+i); if (hasCrateAt(gp2, mask)) { SimpleVector posc=gp2.convertTo3D(); if (Math.abs(pos.z-posc.z)<=width+MapMask.TILE_SIZE/2+2f && Math.abs(pos.x-posc.x)<=delta) { glows[2].setVisibility(true); glows[2].getTranslationMatrix().setIdentity(); posc.y=0; glows[2].translate(posc); glows[2].setAdditionalColor(glowColors[colorIndex]); } }else { bu=true; } } //z- int mo=mask.getMaskAt(x, z-i); if (!bo) { if (mo==MapMask.UNKNOWN) { bo=true; } } if (!bo && !glows[3].getVisibility() && (mo==MapMask.CRATE || MapMask.isItem(mo))) { GridPosition gp2=new GridPosition(x,z-i); if (hasCrateAt(gp2, mask)) { SimpleVector posc=gp2.convertTo3D(); if (Math.abs(pos.z-posc.z)<=width+MapMask.TILE_SIZE/2+2f && Math.abs(pos.x-posc.x)<=delta) { glows[3].setVisibility(true); glows[3].getTranslationMatrix().setIdentity(); posc.y=0; glows[3].translate(posc); glows[3].setAdditionalColor(glowColors[colorIndex]); } }else { bo=true; } } } } public void makeCaster(ShadowHelper sh) { for (CrateView cv:crates) { sh.addCaster(cv); cv.setShadowHelper(sh); } } public void explode(Event event, Level level) { int id=event.getTargetID(); for (CrateView cv:crates) { if (!cv.isInactive() && cv.getLocalObject().getObjectID()==id) { cv.explode(event.getOrigin()); clearGrid(level, cv); break; } } } public void removeUponServerRequest(int id, Level level) { for (CrateView cv:crates) { if (!cv.isInactive() && cv.getLocalObject().getObjectID()==id) { cv.removeUponServerRequest(); cv.removeFromWorld(world); clearGrid(level, cv); break; } } } public void process(long ticks, Level level) { if (ticks>0) { for (CrateView ex: crates) { if (ex.isExploding()) { ex.process(ticks, level); if (ex.isGone()) { // Crate exploded and animation is done? ex.removeFromWorld(world); } } } } } public List<SimpleVector> getCratePositions() { List<SimpleVector> res=new ArrayList<SimpleVector>(); for (CrateView cr: crates) { if (!cr.isGone()) { res.add(cr.getTranslation()); } } return res; } public boolean hasCrateAt(GridPosition gp, MapMask mask) { for (CrateView cr: crates) { SimpleVector pos=cr.getTranslation(); GridPosition gpb=mask.getGrid(pos.x, pos.z); if (gp.equals(gpb) && !cr.isGone()) { return true; } } return false; } private void clearGrid(Level level, CrateView crate) { SimpleVector pos=crate.getTransformedCenter(); GridPosition gp=level.getMask().getGrid(pos.x, pos.z); if (level.getMask().getMaskAt(gp)==MapMask.CRATE) { // if crate is empty try to generate random item float it=(float) Math.random(); if (it<1) { level.getMask().setMaskAt(gp, MapMask.FLOOR); } if (it<0.4) { level.getMask().setMaskAt(gp, MapMask.DISEASE_ITEM); } if (it<0.3) { level.getMask().setMaskAt(gp, MapMask.FIREPOWER_ITEM); } if (it<0.2) { level.getMask().setMaskAt(gp, MapMask.BOMB_ITEM); } if (it<0.1) { level.getMask().setMaskAt(gp, MapMask.KICK_ITEM); } } } }