/** * Cause a general explosion in the world */ public static void explode(GameObject inflictor, GameObject attacker, NativeEntity ent, int damage, float radius) { int effect; Point3f explodeOrigin = ent.getOrigin(); if ((Engine.getPointContents(explodeOrigin) & Engine.MASK_WATER) == 0) { if (ent.getGroundEntity() != null) effect = Engine.TE_GRENADE_EXPLOSION; else effect = Engine.TE_ROCKET_EXPLOSION; } else { if (ent.getGroundEntity() != null) effect = Engine.TE_GRENADE_EXPLOSION_WATER; else effect = Engine.TE_ROCKET_EXPLOSION_WATER; } MiscUtil.radiusDamage(inflictor, attacker, damage, ent, radius, "g_splash"); Engine.writeByte(Engine.SVC_TEMP_ENTITY); Engine.writeByte(effect); Engine.writePosition(explodeOrigin); Engine.multicast(explodeOrigin, Engine.MULTICAST_PHS); }
public static void blinkDeathmatchScoreboard( Player client ) { // if during intermission, we must blink our header if we're the winning team (or tie) //if ( inIntermission && ((int)Game.getGameTime()%2 == 0 ) ) // blink every second if ( (int)Game.getGameTime()%2 == 0 ) // blink every second { if ( TEAM1.getCaptures() > TEAM2.getCaptures() ) client.fEntity.setPlayerStat( STAT_CTF_TEAM1_HEADER, (short)0 ); else if ( TEAM2.getCaptures() > TEAM1.getCaptures() ) client.fEntity.setPlayerStat( STAT_CTF_TEAM2_HEADER, (short)0 ); // Capture tie, check total frags else if ( TEAM1.getScore() > TEAM2.getScore() ) client.fEntity.setPlayerStat( STAT_CTF_TEAM1_HEADER, (short)0 ); else if ( TEAM2.getScore() > TEAM1.getScore() ) client.fEntity.setPlayerStat( STAT_CTF_TEAM2_HEADER, (short)0 ); else { // tie game client.fEntity.setPlayerStat( STAT_CTF_TEAM1_HEADER, (short)0 ); client.fEntity.setPlayerStat( STAT_CTF_TEAM2_HEADER, (short)0 ); } } else { // show both if not blinked client.fEntity.setPlayerStat( STAT_CTF_TEAM1_HEADER, (short)Engine.getImageIndex("ctfsb1") ); client.fEntity.setPlayerStat( STAT_CTF_TEAM2_HEADER, (short)Engine.getImageIndex("ctfsb2") ); } }
public static final void fireEvent(GenericEvent e, Method m, Vector listeners) throws PropertyVetoException { Object[] snapshot = null; synchronized (listeners) { snapshot = new Object[listeners.size()]; listeners.copyInto(snapshot); } // leighd 04/14/99 - modified for event debugging if (gDebugEvents) Engine.debugLog("Event : " + e.toString()); Object params[] = new Object[] {e}; for (int i = 0; i < snapshot.length; i++) { if ((e instanceof Consumable) && ((Consumable) e).isConsumed()) { // leighd 04/14/99 // note that we don't catch the consumption of the // event until we've passed through the loop again, // so we reference i-1 if (gDebugEvents) Engine.debugLog("Consumed By : " + snapshot[i - 1]); return; } try { m.invoke(snapshot[i], params); } catch (IllegalAccessException iae) { iae.printStackTrace(); } catch (InvocationTargetException ite) { Throwable t = ite.getTargetException(); if (t instanceof PropertyVetoException) throw ((PropertyVetoException) t); else t.printStackTrace(); } } }
public void addPlayer( Player p ) { if (fPlayers.contains(p)) return; // already joined this team fPlayers.addElement( p ); // make sure we find out if the team member disconnects p.addPlayerStateListener(this); // act as a damage filter for this member p.addDamageListener(this); // assign new skin assignSkinTo( p ); Object[] args = {p.getName(), fTeamIndex}; Game.localecast("q2java.ctf.CTFMessages", "join_team", args, Engine.PRINT_HIGH); //update players stats that he joined this team (the yellow line around team-icon) int index1 = ( this == Team.TEAM1 ? STAT_CTF_JOINED_TEAM1_PIC : STAT_CTF_JOINED_TEAM2_PIC ); int index2 = ( this == Team.TEAM1 ? STAT_CTF_JOINED_TEAM2_PIC : STAT_CTF_JOINED_TEAM1_PIC ); int picnum = Engine.getImageIndex("i_ctfj"); p.fEntity.setPlayerStat( index1, (short)picnum ); p.fEntity.setPlayerStat( index2, (short)0 ); }
public void assignSkinTo( Player p ) { String skin; //System.out.println( p.getUserInfo("skin") ); // assign skin based on team skin = ( p.isFemale() ? "female/" : "male/" ); skin += ( this == TEAM1 ? CTF_TEAM1_SKIN : CTF_TEAM2_SKIN ); Engine.setConfigString( Engine.CS_PLAYERSKINS + p.fEntity.getPlayerNum(), p.getName() + "\\" + skin ); //Engine.debugLog( p.getName() + "\\" + skin ); }
/** * Fire an event to the registered listeners, but stop on a PropertyVetoException. Subclasses may * choose to implement their own fire method, and just use this class for the add/remove methods. * * @param evt the Event we're going to pass to the listeners * @throws java.beans.PropertyVetoException */ protected final void firePropertyEvent(Object evt, Method m) throws PropertyVetoException { // grab a reference to the listeners Object[] array = fListeners; if (array.length == 0) return; Object[] params = fCachedParams; if (params == null) params = new Object[] {evt}; // wasn't available, make a new array else { fCachedParams = null; // set to null in case fire is called re-entrantly params[0] = evt; } try { for (int i = 0; i < array.length; i++) { try { m.invoke(array[i], params); } catch (IllegalAccessException iae) { iae.printStackTrace(); } catch (InvocationTargetException ite) { Throwable t = ite.getTargetException(); if (t instanceof PropertyVetoException) throw ((PropertyVetoException) t); else t.printStackTrace(); } if ((evt instanceof Consumable) && ((Consumable) evt).isConsumed()) { if (gDebugEvents) Engine.debugLog("Consumed By : " + array[i]); return; } } } finally { // make our param array available for re-use // doesn't matter if we made it fresh, or already // reused it from a previous fire call params[0] = null; fCachedParams = params; } }
public String getDeathmatchScoreboardMessage( GameObject victim, GameObject killer, boolean inIntermission ) { int xOffset, statHeader, statCaps, headerIndex; String s; Team otherTeam; otherTeam = ( this == TEAM1 ? TEAM2 : TEAM1 ); xOffset = ( this == TEAM1 ? 0 : 160 ); statHeader = ( this == TEAM1 ? STAT_CTF_TEAM1_HEADER : STAT_CTF_TEAM2_HEADER ); headerIndex = ( this == TEAM1 ? Engine.getImageIndex("ctfsb1") : Engine.getImageIndex("ctfsb2") ); statCaps = ( this == TEAM1 ? STAT_CTF_TEAM1_CAPS : STAT_CTF_TEAM2_CAPS ); // display our teamheader victim.fEntity.setPlayerStat( statHeader, (short)headerIndex ); /* // if during intermission, we must blink our header if we're the winning team (or tie) if ( inIntermission && ((int)Game.getGameTime()%2 == 0 ) ) // blink every second { if ( this.getCaptures() > otherTeam.getCaptures() ) victim.fEntity.setPlayerStat( statHeader, (short)0 ); // Capture tie, check total frags else if ( this.getScore() >= otherTeam.getScore() ) victim.fEntity.setPlayerStat( statHeader, (short)0 ); } */ s = "if " + statHeader + " xv " + (8+xOffset) + " yv 8 pic " + statHeader + " endif " + "xv " + (40+xOffset) + " yv 28 string \"" + getScore() + "/" + fCaptures + "\" " + "xv " + (98+xOffset) + " yv 12 num 2 " + statCaps + " "; // TODO: sort players by score Player[] players = getPlayers(); /* int begin = 0; int i = begin; while ( i < players.length-1 ) { if ( players[i].getScore() < players[i+1].getScore() ) { Player dummy = players[i]; players[i] = players[i+1]; players[i+1] = dummy; } if ( i == players.length-2 ) i = ++begin; } */ for ( int i=0; i<8 && i<players.length; i++ ) { Player p = players[i]; int ping = Math.min( p.fEntity.getPlayerPing(), 999 ); s += "ctf " + xOffset + " " + (42+i*8) + " " + p.fEntity.getPlayerNum() + " " + p.getScore() + " " + ping + " "; GenericFlag flag = (GenericFlag)p.getInventory( "flag" ); if ( flag != null ) // flag IS other teams flag... { s += "xv " + (56+xOffset) + " picn " + flag.getSmallIconName() + " "; } } if ( players.length > 8 ) { s += "xv " + (8+xOffset) + " yv " + (42+8*8) + " string \"...and " + (players.length-8) + " more\" "; } return s; }
/** * Fire a railgun slug. * @param p q2jgame.Player * @param start q2java.Vec3 * @param forward q2java.Vec3 * @param damage int * @param kick int */ public static void fireRail(GameObject p, Point3f start, Vector3f aimDir, int damage, int kick) { TraceResults tr = null; NativeEntity ignore; int mask; boolean water; Point3f from = new Point3f(start); Point3f end = new Point3f(); end.scaleAdd(8192, aimDir, start); ignore = p.fEntity; water = false; mask = Engine.MASK_SHOT | Engine.CONTENTS_SLIME | Engine.CONTENTS_LAVA; while (ignore != null) { tr = Engine.trace(from, end, ignore, mask); if ((tr.fContents & (Engine.CONTENTS_SLIME | Engine.CONTENTS_LAVA)) != 0) { mask &= ~(Engine.CONTENTS_SLIME | Engine.CONTENTS_LAVA); water = true; } else { /* if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client)) ignore = tr.ent; else */ ignore = null; if ((tr.fEntity.getReference() != p) && (tr.fEntity.getReference() instanceof GameObject)) ((GameObject)tr.fEntity.getReference()).damage(p, p, aimDir, tr.fEndPos, tr.fPlaneNormal, damage, kick, 0, Engine.TE_NONE, "railgun"); } from.set(tr.fEndPos); } // send gun puff / flash Engine.writeByte(Engine.SVC_TEMP_ENTITY); Engine.writeByte(Engine.TE_RAILTRAIL); Engine.writePosition(start); Engine.writePosition(tr.fEndPos); Engine.multicast(p.fEntity.getOrigin(), Engine.MULTICAST_PHS); if (water) { Engine.writeByte(Engine.SVC_TEMP_ENTITY); Engine.writeByte(Engine.TE_RAILTRAIL); Engine.writePosition(start); Engine.writePosition(tr.fEndPos); Engine.multicast(tr.fEndPos, Engine.MULTICAST_PHS); } }
/** * Fire a lead projectile. * @param p q2jgame.Player * @param start q2java.Vec3 * @param aimDir q2java.Vec3 * @param damage int * @param kick int * @param teImpact int * @param hSpread int * @param vSpread int */ public static void fireLead(GameObject p, Point3f start, Vector3f aimDir, int damage, int kick, int teImpact, int hSpread, int vSpread, String obitKey) { TraceResults tr; Vector3f forward = new Vector3f(); Vector3f right = new Vector3f(); Vector3f up = new Vector3f(); Point3f end = new Point3f(); float r; float u; Point3f waterStart = null; boolean water = false; int content_mask = Engine.MASK_SHOT | Engine.MASK_WATER; tr = Engine.trace(p.fEntity.getOrigin(), start, p.fEntity, Engine.MASK_SHOT); if (!(tr.fFraction < 1.0)) { // limit the scope of "dir" { Angle3f dir = Q2Recycler.getAngle3f(); dir.set(aimDir); dir.getVectors(forward, right, up); Q2Recycler.put(dir); } r = (float) (GameUtil.cRandom() * hSpread); u = (float) (GameUtil.cRandom() * vSpread); end.scaleAdd(8192, forward, start); end.scaleAdd(r, right, end); end.scaleAdd(u, up, end); if ((Engine.getPointContents(start) & Engine.MASK_WATER) != 0) { water = true; waterStart = new Point3f(start); content_mask &= ~Engine.MASK_WATER; } tr = Engine.trace(start, end, p.fEntity, content_mask); // see if we hit water if ((tr.fContents & Engine.MASK_WATER) != 0) { int color; water = true; waterStart = new Point3f(tr.fEndPos); if (!start.equals(tr.fEndPos)) { if ((tr.fContents & Engine.CONTENTS_WATER) != 0) { if (tr.fSurfaceName.equals("*brwater")) color = Engine.SPLASH_BROWN_WATER; else color = Engine.SPLASH_BLUE_WATER; } else if ((tr.fContents & Engine.CONTENTS_SLIME) != 0) color = Engine.SPLASH_SLIME; else if ((tr.fContents & Engine.CONTENTS_LAVA) != 0) color = Engine.SPLASH_LAVA; else color = Engine.SPLASH_UNKNOWN; if (color != Engine.SPLASH_UNKNOWN) { Engine.writeByte(Engine.SVC_TEMP_ENTITY); Engine.writeByte(Engine.TE_SPLASH); Engine.writeByte(8); Engine.writePosition(tr.fEndPos); Engine.writeDir(tr.fPlaneNormal); Engine.writeByte(color); Engine.multicast(tr.fEndPos, Engine.MULTICAST_PVS); } // change bullet's course when it enters water Vector3f diff = Q2Recycler.getVector3f(); Angle3f ang = Q2Recycler.getAngle3f(); diff.sub(end, start); ang.set(diff); ang.getVectors(forward, right, up); r = (float)(GameUtil.cRandom() * hSpread * 2); u = (float)(GameUtil.cRandom() * vSpread * 2); end.scaleAdd(8192, forward, waterStart); end.scaleAdd(r, right, end); end.scaleAdd(u, up, end); Q2Recycler.put(ang); Q2Recycler.put(diff); } // re-trace ignoring water this time tr = Engine.trace(waterStart, end, p.fEntity, Engine.MASK_SHOT); } } // send gun puff / flash if ((tr.fSurfaceName == null) || ((tr.fSurfaceFlags & Engine.SURF_SKY) == 0)) { if ((tr.fFraction < 1.0) && (!tr.fSurfaceName.startsWith("sky"))) { if (tr.fEntity.getReference() instanceof GameObject) ((GameObject)tr.fEntity.getReference()).damage(p, p, aimDir, tr.fEndPos, tr.fPlaneNormal, damage, kick, GameObject.DAMAGE_BULLET, teImpact, obitKey); } } // if went through water, determine where the end and make a bubble trail if (water) { Point3f pos = Q2Recycler.getPoint3f(); Vector3f leadDir = Q2Recycler.getVector3f(); leadDir.sub(tr.fEndPos, waterStart); leadDir.normalize(); pos.scaleAdd(-2, leadDir, tr.fEndPos); // = tr.fEndPos.vectorMA(-2, dir); if ((Engine.getPointContents(pos) & Engine.MASK_WATER) != 0) tr.fEndPos = new Point3f(pos); else tr = Engine.trace(pos, waterStart, tr.fEntity, Engine.MASK_WATER); pos.add(tr.fEndPos, waterStart); pos.scale(0.5F); Engine.writeByte(Engine.SVC_TEMP_ENTITY); Engine.writeByte(Engine.TE_BUBBLETRAIL); Engine.writePosition(waterStart); Engine.writePosition(tr.fEndPos); Engine.multicast(pos, Engine.MULTICAST_PVS); Q2Recycler.put(leadDir); Q2Recycler.put(pos); } }