use of micdoodle8.mods.galacticraft.core.dimension.SpinManager in project Galacticraft by micdoodle8.
the class FreefallHandler method postVanillaMotion.
@SideOnly(Side.CLIENT)
public void postVanillaMotion(EntityPlayerSP p) {
World world = p.worldObj;
WorldProvider worldProvider = world.provider;
if (!(worldProvider instanceof IZeroGDimension)) {
return;
}
ZeroGravityEvent zeroGEvent = new ZeroGravityEvent.Motion(p);
MinecraftForge.EVENT_BUS.post(zeroGEvent);
if (zeroGEvent.isCanceled()) {
return;
}
boolean freefall = stats.isInFreefall();
freefall = this.testFreefall(p, freefall);
stats.setInFreefall(freefall);
stats.setInFreefallFirstCheck(true);
SpinManager spinManager = null;
if (worldProvider instanceof WorldProviderSpaceStation && !stats.getPlatformControlled()) {
spinManager = ((WorldProviderSpaceStation) worldProvider).getSpinManager();
}
boolean doCentrifugal = spinManager != null;
if (freefall) {
this.pjumpticks = 0;
// Reverse effects of deceleration
p.motionX /= 0.91F;
p.motionZ /= 0.91F;
p.motionY /= 0.9800000190734863D;
if (spinManager != null) {
doCentrifugal = spinManager.updatePlayerForSpin(p, 1F);
}
// Do freefall motion
if (!p.capabilities.isCreativeMode) {
this.freefallMotion(p);
} else {
p.capabilities.isFlying = true;
// Half the normal acceleration in Creative mode
double dx = p.motionX - this.pPrevMotionX;
double dy = p.motionY - this.pPrevMotionY;
double dz = p.motionZ - this.pPrevMotionZ;
p.motionX -= dx / 2;
p.motionY -= dy / 2;
p.motionZ -= dz / 2;
if (p.motionX > 1.2F) {
p.motionX = 1.2F;
}
if (p.motionX < -1.2F) {
p.motionX = -1.2F;
}
if (p.motionY > 0.7F) {
p.motionY = 0.7F;
}
if (p.motionY < -0.7F) {
p.motionY = -0.7F;
}
if (p.motionZ > 1.2F) {
p.motionZ = 1.2F;
}
if (p.motionZ < -1.2F) {
p.motionZ = -1.2F;
}
}
// TODO: Think about endless drift?
// Player may run out of oxygen - that will kill the player eventually if can't get back to SS
// Could auto-kill + respawn the player if floats too far away (config option whether to lose items or not)
// But we want players to be able to enjoy the view of the spinning space station from the outside
// Arm and leg movements could start tumbling the player?
} else // Not freefall - within arm's length of something or jumping
{
double dy = p.motionY - this.pPrevMotionY;
// if (p.motionY != 0) p.motionY = this.pPrevMotionY;
if (p.movementInput.jump) {
if ((p.onGround || stats.isSsOnGroundLast()) && !p.capabilities.isCreativeMode) {
if (this.pjumpticks < 25)
this.pjumpticks++;
p.motionY -= dy;
} else {
p.motionY += 0.015D;
if (this.pjumpticks == 0) {
p.motionY -= dy;
}
}
} else if (this.pjumpticks > 0) {
p.motionY += 0.0145D * this.pjumpticks;
this.pjumpticks = 0;
} else if (p.movementInput.sneak) {
if (!p.onGround) {
p.motionY -= 0.015D;
}
this.pjumpticks = 0;
}
}
// Artificial gravity
if (doCentrifugal && !p.onGround) {
spinManager.applyCentrifugalForce(p);
}
this.pPrevMotionX = p.motionX;
this.pPrevMotionY = p.motionY;
this.pPrevMotionZ = p.motionZ;
}
use of micdoodle8.mods.galacticraft.core.dimension.SpinManager in project Galacticraft by micdoodle8.
the class FreefallHandler method testFreefall.
@SideOnly(Side.CLIENT)
private boolean testFreefall(EntityPlayerSP p, boolean flag) {
World world = p.worldObj;
WorldProvider worldProvider = world.provider;
if (!(worldProvider instanceof IZeroGDimension)) {
return false;
}
ZeroGravityEvent zeroGEvent = new ZeroGravityEvent.InFreefall(p);
MinecraftForge.EVENT_BUS.post(zeroGEvent);
if (zeroGEvent.isCanceled()) {
return false;
}
if (this.pjumpticks > 0 || (stats.isSsOnGroundLast() && p.movementInput.jump)) {
return false;
}
if (p.ridingEntity != null) {
Entity e = p.ridingEntity;
if (e instanceof EntitySpaceshipBase) {
return ((EntitySpaceshipBase) e).getLaunched();
}
if (e instanceof EntityLanderBase) {
return false;
}
// TODO: should check whether lander has landed (whatever that means)
// TODO: could check other ridden entities - every entity should have its own freefall check :(
}
// This is an "on the ground" check
if (!flag) {
return false;
} else {
float rY = p.rotationYaw % 360F;
double zreach = 0D;
double xreach = 0D;
if (rY < 80F || rY > 280F) {
zreach = 0.2D;
}
if (rY < 170F && rY > 10F) {
xreach = 0.2D;
}
if (rY < 260F && rY > 100F) {
zreach = -0.2D;
}
if (rY < 350F && rY > 190F) {
xreach = -0.2D;
}
AxisAlignedBB playerReach = p.getEntityBoundingBox().addCoord(xreach, 0, zreach);
boolean checkBlockWithinReach;
if (worldProvider instanceof WorldProviderSpaceStation) {
SpinManager spinManager = ((WorldProviderSpaceStation) worldProvider).getSpinManager();
checkBlockWithinReach = playerReach.maxX >= spinManager.ssBoundsMinX && playerReach.minX <= spinManager.ssBoundsMaxX && playerReach.maxY >= spinManager.ssBoundsMinY && playerReach.minY <= spinManager.ssBoundsMaxY && playerReach.maxZ >= spinManager.ssBoundsMinZ && playerReach.minZ <= spinManager.ssBoundsMaxZ;
// Player is somewhere within the space station boundaries
} else {
checkBlockWithinReach = true;
}
if (checkBlockWithinReach) {
// Check if the player's bounding box is in the same block coordinates as any non-vacuum block (including torches etc)
// If so, it's assumed the player has something close enough to grab onto, so is not in freefall
// Note: breatheable air here means the player is definitely not in freefall
int xm = MathHelper.floor_double(playerReach.minX);
int xx = MathHelper.floor_double(playerReach.maxX);
int ym = MathHelper.floor_double(playerReach.minY);
int yy = MathHelper.floor_double(playerReach.maxY);
int zm = MathHelper.floor_double(playerReach.minZ);
int zz = MathHelper.floor_double(playerReach.maxZ);
for (int x = xm; x <= xx; x++) {
for (int y = ym; y <= yy; y++) {
for (int z = zm; z <= zz; z++) {
// Blocks.air is hard vacuum - we want to check for that, here
Block b = world.getBlockState(new BlockPos(x, y, z)).getBlock();
if (Blocks.air != b && GCBlocks.brightAir != b) {
this.onWall = true;
return false;
}
}
}
}
}
}
/*
if (freefall)
{
//If that check didn't produce a result, see if the player is inside the walls
//TODO: could apply special weightless movement here like Coriolis force - the player is inside the walls, not touching them, and in a vacuum
int quadrant = 0;
double xd = p.posX - this.spinCentreX;
double zd = p.posZ - this.spinCentreZ;
if (xd<0)
{
if (xd<-Math.abs(zd))
{
quadrant = 2;
} else
quadrant = (zd<0) ? 3 : 1;
} else
if (xd>Math.abs(zd))
{
quadrant = 0;
} else
quadrant = (zd<0) ? 3 : 1;
int ymin = MathHelper.floor_double(p.boundingBox.minY)-1;
int ymax = MathHelper.floor_double(p.boundingBox.maxY);
int xmin, xmax, zmin, zmax;
switch (quadrant)
{
case 0:
xmin = MathHelper.floor_double(p.boundingBox.maxX);
xmax = this.ssBoundsMaxX - 1;
zmin = MathHelper.floor_double(p.boundingBox.minZ)-1;
zmax = MathHelper.floor_double(p.boundingBox.maxZ)+1;
break;
case 1:
xmin = MathHelper.floor_double(p.boundingBox.minX)-1;
xmax = MathHelper.floor_double(p.boundingBox.maxX)+1;
zmin = MathHelper.floor_double(p.boundingBox.maxZ);
zmax = this.ssBoundsMaxZ - 1;
break;
case 2:
zmin = MathHelper.floor_double(p.boundingBox.minZ)-1;
zmax = MathHelper.floor_double(p.boundingBox.maxZ)+1;
xmin = this.ssBoundsMinX;
xmax = MathHelper.floor_double(p.boundingBox.minX);
break;
case 3:
default:
xmin = MathHelper.floor_double(p.boundingBox.minX)-1;
xmax = MathHelper.floor_double(p.boundingBox.maxX)+1;
zmin = this.ssBoundsMinZ;
zmax = MathHelper.floor_double(p.boundingBox.minZ);
break;
}
//This block search could cost a lot of CPU (but client side) - maybe optimise later
BLOCKCHECK0:
for(int x = xmin; x <= xmax; x++)
for (int z = zmin; z <= zmax; z++)
for (int y = ymin; y <= ymax; y++)
if (Blocks.air != this.worldProvider.worldObj.getBlock(x, y, z))
{
freefall = false;
break BLOCKCHECK0;
}
}*/
this.onWall = false;
return true;
}
Aggregations