3D spaceshooter with online scoreboard, online demos, ship building. Now entirely defunct, but might be resurrected
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
sector/src/net/sector/entities/natural/EntityAsteroid.java

184 lines
4.5 KiB

package net.sector.entities.natural;
import static org.lwjgl.opengl.GL11.*;
import net.sector.Constants;
import net.sector.collision.ColliderSphere;
import net.sector.entities.EEntity;
import net.sector.entities.Entity;
import net.sector.entities.orbs.EntityOrbShield;
import net.sector.models.Models;
import net.sector.models.PhysModel;
import com.porcupine.coord.Coord;
import com.porcupine.coord.Vec;
import com.porcupine.math.Calc;
/**
* Asteroid entity
*
* @author Ondřej Hruška (MightyPork)
*/
public class EntityAsteroid extends EntityNatural {
private int texture = 0;
/** Rotation speed */
protected double rotSpeed = 0;
private PhysModel rock;
private double renderScale = 0;
private double scale = 1;
private double healthMax;
/**
* Asteroid entity
*
* @param scale asteroid scale
* @param pos asteroid center position
* @param motion asteroid motion
* @param texture asteroid texture index
*/
public EntityAsteroid(double scale, Coord pos, Vec motion, int texture) {
this.texture = texture;
this.rotDir.setTo(-1 + rand.nextDouble() * 2, -1 + rand.nextDouble() * 2, -1 + rand.nextDouble() * 2);
this.rotAngle.set(rand.nextDouble() * 360);
this.rotSpeed = -5 + rand.nextDouble() * 10;
this.collidePriority = 0;
this.scale = scale;
rock = Models.pickAsteroidOfType(texture);
this.renderScale = rock.renderScale * scale;
this.healthMax = this.health = rock.health * scale;
this.lifetime = -1;
this.mass = rock.getMass(scale);
collider = new ColliderSphere(pos, rock.colliderRadius * scale);
this.motion.setTo(motion);
this.scoreValue = (int) Math.round(rock.getScore(scale));
this.MAX_SPEED = 0.2 * (0.3 / mass);
setGlobalMovement(true);
}
@Override
public double getHealthMax() {
return healthMax;
}
//private static Object3D model = new Object3D("res/models/asteroid03.obj", true);
/**
* Asteroid entity
*
* @param scale asteroid scale
* @param pos asteroid position
* @param motion asteroid motion
*/
public EntityAsteroid(double scale, Coord pos, Vec motion) {
this(scale, pos, motion, rand.nextInt(Models.rockTypes.length));
}
@Override
public void onImpact(Entity hitBy) {
defaultOnImpact(hitBy);
this.rotSpeed = Calc.clampd(this.rotSpeed + rand.nextGaussian(), -5, 5);
if (hitBy instanceof EntityAsteroid) {
((EntityAsteroid) hitBy).rotSpeed = Calc.clampd(((EntityAsteroid) hitBy).rotSpeed + rand.nextGaussian(), -5, 5);
}
}
@Override
public void onUpdate() {
rotAngle.add(rotSpeed * Constants.SPEED_MUL);
}
@Override
public void render(double delta) {
glPushMatrix();
glLoadIdentity();
Coord p = getPos().getDelta(delta);
glTranslated(p.x, p.y, -p.z);
glRotated(rotAngle.delta(delta), rotDir.x, rotDir.y, rotDir.z);
glScaled(renderScale, renderScale, renderScale);
rock.model.render();
glPopMatrix();
}
@Override
public boolean belongsToZone(double zFrom, double zTo) {
return Calc.inRange(collider.pos.z, zFrom - collider.radius, zTo + collider.radius);
}
@Override
public void onDeath() {
explodeForce(getPos(), getRadius() * 14, true);
//explodeForce(getPos(), mass / 2, true);
if (scale > 0.4) {
int pieces = 2 + rand.nextInt(7);
double vol = Calc.sphereGetVolume(scale) * 0.4;
double approxPerPart = vol / pieces;
double[] volumes = new double[pieces];
for (int i = 0; i < pieces; i++) {
double v = 0.05 + ((rand.nextDouble() + rand.nextDouble()) / 2) * approxPerPart;
if (v > vol) v = vol;
vol -= v;
if (v < 0) v = Calc.sphereGetVolume(0.05 + rand.nextDouble() * 0.1);
volumes[i] = v;
}
for (int i = 0; i < pieces; i++) {
double newScale = Calc.sphereGetRadius(volumes[i]);
if (newScale < 0.05) newScale = 0.05;
Coord apos = this.getPos();
double r = getRadius() * 0.6;
apos.add_ip(-r + rand.nextDouble() * (r) * 2, 0, -r + rand.nextDouble() * (r) * 2);
Vec amotion = getPos().vecTo(apos).norm(0.05 + rand.nextDouble() * 0.1);
Entity e;
scene.add(e = new EntityAsteroid(newScale, apos, amotion, texture));
e.health *= 0.1;
e.scoreValue *= 0.6;
e.healthMul = healthMul * 0.8;
// tiny rocks will eventually disappear.
if (newScale < 0.15) e.lifetime = (int) (Constants.FPS_UPDATE * (0.3 + rand.nextDouble() * 5));
}
}
if (lastDamageSource.getType() == EEntity.SHOT_GOOD && rand.nextInt(3) == 0 && scale > 0.5) {
if (scene.playerShip.body.shieldSystem.getLoadRatio() < 1) {
scene.add(new EntityOrbShield(getPos(), scale * 600 * (0.6 + rand.nextDouble() * 0.7)));
}
}
}
@Override
public EEntity getType() {
return EEntity.NATURAL;
}
}