예제 #1
0
파일: MiscUtil.java 프로젝트: barryp/q2java
/**
 * Select a random spawnpoint, but exclude the two points closest
 * to other players.
 * @return q2jgame.GameEntity
 */
public static GenericSpawnpoint getSpawnpointRandom() 
	{
	GenericSpawnpoint spawnPoint = null;
	GenericSpawnpoint spot1 = null;
	GenericSpawnpoint spot2 = null;
	float range1 = Float.MAX_VALUE;
	float range2 = Float.MAX_VALUE;
	int count = 0;
	
	// find the two deathmatch spawnpoints that are closest to any players
	Vector list = Game.getLevelRegistryList(q2java.baseq2.spawn.info_player_deathmatch.REGISTRY_KEY);

	// if no deathmatch spawnpoint, try single-player ones
	if (list.size() < 1)
		list = Game.getLevelRegistryList(q2java.baseq2.spawn.info_player_start.REGISTRY_KEY);
		
	Enumeration enum = list.elements();
	while (enum.hasMoreElements())
		{
		count++;
		spawnPoint = (GenericSpawnpoint) enum.nextElement();
		float range = MiscUtil.nearestPlayerDistance(spawnPoint);

		if (range < range1)
			{
			range1 = range;
			spot1 = spawnPoint;
			}		
		else
			{
			if (range < range2)
				{
				range2 = range;
				spot2 = spawnPoint;
				}
			}			
			
		}

	if (count == 0)
		return null;
		
	if (count <= 2)
		spot1 = spot2 = null;
	else
		count -= 2;			

	int selection = (GameUtil.randomInt() & 0x0fff) % count;
	spawnPoint = null;

	enum = list.elements();
	while (enum.hasMoreElements())
		{
		spawnPoint = (GenericSpawnpoint) enum.nextElement();
		
		// skip the undesirable spots
		if ((spawnPoint == spot1) || (spawnPoint == spot2))
			continue;
			
		if ((selection--) == 0)					
			break;
		}

	return spawnPoint;
	}
예제 #2
0
파일: Team.java 프로젝트: barryp/q2java
	/**
	* This method finds a ctf spawnpoint for the TEAM,
	* but NOT the two points closest to other players.
	**/
	public GenericSpawnpoint getSpawnpoint()
	{
		GenericSpawnpoint spawnPoint = null;
		GenericSpawnpoint spot1 = null;
		GenericSpawnpoint spot2 = null;
		float range1 = Float.MAX_VALUE;
		float range2 = Float.MAX_VALUE;
		int count = 0;
		String regKey;

		regKey = ( this == TEAM1 ? info_player_team1.REGISTRY_KEY : info_player_team2.REGISTRY_KEY );

		// find the two ctf-team spawnpoints that are closest to any players
		Vector list = Game.getLevelRegistryList( regKey );
		Enumeration enum = list.elements();
		while (enum.hasMoreElements())
		{
			count++;
			spawnPoint = (GenericSpawnpoint) enum.nextElement();
			float range = q2java.baseq2.MiscUtil.nearestPlayerDistance(spawnPoint);

			if (range < range1)
			{
				range1 = range;
				spot1 = spawnPoint;
			}		
			else
			{
				if (range < range2)
				{
					range2 = range;
					spot2 = spawnPoint;
				}
			}			
		}

		if (count == 0)
			return null;
			
		if (count <= 2)
			spot1 = spot2 = null;
		else
			count -= 2;			

		int selection = (GameUtil.randomInt() & 0x0fff) % count;
		spawnPoint = null;

		enum = list.elements();
		while (enum.hasMoreElements())
		{
			spawnPoint = (GenericSpawnpoint) enum.nextElement();
			
			// skip the undesirable spots
			if ((spawnPoint == spot1) || (spawnPoint == spot2))
				continue;
				
			if ((selection--) == 0)					
				break;
		}
		return spawnPoint;
	}
예제 #3
0
파일: MiscUtil.java 프로젝트: barryp/q2java
/**
 * 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);
		}
	}