示例#1
0
/**
 * 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);
	}
示例#2
0
/**
 * 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);
		}
	}