public void Update(EntityPosition_ stateplayerposition, Controls move, float dt, BoolRef soundnow, Vector3Ref push, float modelheight) { if (game.stopPlayerMove) { movedz = 0; game.stopPlayerMove = false; } // No air control if (!isplayeronground) { acceleration.acceleration1 = 0.99f; acceleration.acceleration2 = 0.2f; acceleration.acceleration3 = 70; } // Trampoline { int blockunderplayer = game.BlockUnderPlayer(); if (blockunderplayer != -1 && blockunderplayer == game.d_Data.BlockIdTrampoline() && (!isplayeronground) && !game.controls.shiftkeydown) { game.controls.wantsjump = true; jumpstartacceleration = 20.666f * constGravity; } } // Slippery walk on ice and when swimming { int blockunderplayer = game.BlockUnderPlayer(); if ((blockunderplayer != -1 && game.d_Data.IsSlipperyWalk()[blockunderplayer]) || game.SwimmingBody()) { acceleration.acceleration1 = 0.99f; acceleration.acceleration2 = 0.2f; acceleration.acceleration3 = 70; } } soundnow.value = false; Vector3Ref diff1ref = new Vector3Ref(); VectorTool.ToVectorInFixedSystem (move.movedx * movespeednow * dt, 0, move.movedy * movespeednow * dt, stateplayerposition.rotx, stateplayerposition.roty, diff1ref); Vector3Ref diff1 = new Vector3Ref(); diff1.X = diff1ref.X; diff1.Y = diff1ref.Y; diff1.Z = diff1ref.Z; if (MiscCi.Vec3Length(push.X, push.Y, push.Z) > 0.01f) { push.Normalize(); push.X *= 5; push.Y *= 5; push.Z *= 5; } diff1.X += push.X * dt; diff1.Y += push.Y * dt; diff1.Z += push.Z * dt; bool loaded = false; int cx = game.platform.FloatToInt(game.player.position.x / Game.chunksize); int cy = game.platform.FloatToInt(game.player.position.z / Game.chunksize); int cz = game.platform.FloatToInt(game.player.position.y / Game.chunksize); if (game.map.IsValidChunkPos(cx, cy, cz)) { if (game.map.chunks[MapUtilCi.Index3d(cx, cy, cz, game.map.MapSizeX / Game.chunksize, game.map.MapSizeY / Game.chunksize)] != null) { loaded = true; } } else { loaded = true; } if ((!(move.freemove)) && loaded) { if (!game.SwimmingBody()) { movedz += -constGravity;//gravity } else { movedz += -constGravity * constWaterGravityMultiplier; //more gravity because it's slippery. } } game.movedz = movedz; if (constEnableAcceleration) { curspeed.X *= acceleration.acceleration1; curspeed.Y *= acceleration.acceleration1; curspeed.Z *= acceleration.acceleration1; curspeed.X = MakeCloserToZero(curspeed.X, acceleration.acceleration2 * dt); curspeed.Y = MakeCloserToZero(curspeed.Y, acceleration.acceleration2 * dt); curspeed.Z = MakeCloserToZero(curspeed.Z, acceleration.acceleration2 * dt); diff1.Y += move.moveup ? 2 * movespeednow * dt : 0; diff1.Y -= move.movedown ? 2 * movespeednow * dt : 0; curspeed.X += diff1.X * acceleration.acceleration3 * dt; curspeed.Y += diff1.Y * acceleration.acceleration3 * dt; curspeed.Z += diff1.Z * acceleration.acceleration3 * dt; if (curspeed.Length() > movespeednow) { curspeed.Normalize(); curspeed.X *= movespeednow; curspeed.Y *= movespeednow; curspeed.Z *= movespeednow; } } else { if (MiscCi.Vec3Length(diff1.X, diff1.Y, diff1.Z) > 0) { diff1.Normalize(); } curspeed.X = diff1.X * movespeednow; curspeed.Y = diff1.Y * movespeednow; curspeed.Z = diff1.Z * movespeednow; } Vector3Ref newposition = Vector3Ref.Create(0, 0, 0); if (!(move.freemove)) { newposition.X = stateplayerposition.x + curspeed.X; newposition.Y = stateplayerposition.y + curspeed.Y; newposition.Z = stateplayerposition.z + curspeed.Z; if (!game.SwimmingBody()) { newposition.Y = stateplayerposition.y; } // Fast move when looking at the ground float diffx = newposition.X - stateplayerposition.x; float diffy = newposition.Y - stateplayerposition.y; float diffz = newposition.Z - stateplayerposition.z; float difflength = MiscCi.Vec3Length(diffx, diffy, diffz); if (difflength > 0) { diffx /= difflength; diffy /= difflength; diffz /= difflength; diffx *= curspeed.Length(); diffy *= curspeed.Length(); diffz *= curspeed.Length(); } newposition.X = stateplayerposition.x + diffx * dt; newposition.Y = stateplayerposition.y + diffy * dt; newposition.Z = stateplayerposition.z + diffz * dt; } else { newposition.X = stateplayerposition.x + (curspeed.X) * dt; newposition.Y = stateplayerposition.y + (curspeed.Y) * dt; newposition.Z = stateplayerposition.z + (curspeed.Z) * dt; } newposition.Y += movedz * dt; Vector3Ref previousposition = Vector3Ref.Create(stateplayerposition.x, stateplayerposition.y, stateplayerposition.z); if (!move.noclip) { float[] v = WallSlide( Vec3.FromValues(stateplayerposition.x, stateplayerposition.y, stateplayerposition.z), Vec3.FromValues(newposition.X, newposition.Y, newposition.Z), modelheight); stateplayerposition.x = v[0]; stateplayerposition.y = v[1]; stateplayerposition.z = v[2]; } else { stateplayerposition.x = newposition.X; stateplayerposition.y = newposition.Y; stateplayerposition.z = newposition.Z; } if (!(move.freemove)) { if ((isplayeronground) || game.SwimmingBody()) { jumpacceleration = 0; movedz = 0; } if ((move.wantsjump || move.wantsjumphalf) && (((jumpacceleration == 0 && isplayeronground) || game.SwimmingBody()) && loaded) && (!game.SwimmingEyes())) { jumpacceleration = move.wantsjumphalf ? jumpstartaccelerationhalf : jumpstartacceleration; soundnow.value = true; } if (jumpacceleration > 0) { isplayeronground = false; jumpacceleration = jumpacceleration / 2; } //if (!this.reachedceiling) { movedz += jumpacceleration * constJump; } } else { isplayeronground = true; } game.isplayeronground = isplayeronground; }
internal Vector3Ref GrenadeBounce(Game game, Vector3Ref oldposition, Vector3Ref newposition, Vector3Ref velocity, float dt) { bool ismoving = velocity.Length() > 100 * dt; float modelheight = walldistance; oldposition.Y += walldistance; newposition.Y += walldistance; //Math.Floor() is needed because casting negative values to integer is not floor. Vector3IntRef oldpositioni = Vector3IntRef.Create(game.MathFloor(oldposition.X), game.MathFloor(oldposition.Z), game.MathFloor(oldposition.Y)); float playerpositionX = newposition.X; float playerpositionY = newposition.Y; float playerpositionZ = newposition.Z; //left { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z + walldistance; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.Z - oldposition.Z > 0) { if (!newempty) { velocity.Z = -velocity.Z; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Z = oldposition.Z - newposition.Z; } } } //front { float qnewpositionX = newposition.X + walldistance; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.X - oldposition.X > 0) { if (!newempty) { velocity.X = -velocity.X; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.X = oldposition.X - newposition.X; } } } //top { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y - walldistance; float qnewpositionZ = newposition.Z; int x = game.MathFloor(qnewpositionX); int y = game.MathFloor(qnewpositionZ); int z = game.MathFloor(qnewpositionY); float a_ = walldistance; bool newfull = (!game.IsTileEmptyForPhysics(x, y, z)) || (qnewpositionX - game.MathFloor(qnewpositionX) <= a_ && (!game.IsTileEmptyForPhysics(x - 1, y, z)) && (game.IsTileEmptyForPhysics(x - 1, y, z + 1))) || (qnewpositionX - game.MathFloor(qnewpositionX) >= (1 - a_) && (!game.IsTileEmptyForPhysics(x + 1, y, z)) && (game.IsTileEmptyForPhysics(x + 1, y, z + 1))) || (qnewpositionZ - game.MathFloor(qnewpositionZ) <= a_ && (!game.IsTileEmptyForPhysics(x, y - 1, z)) && (game.IsTileEmptyForPhysics(x, y - 1, z + 1))) || (qnewpositionZ - game.MathFloor(qnewpositionZ) >= (1 - a_) && (!game.IsTileEmptyForPhysics(x, y + 1, z)) && (game.IsTileEmptyForPhysics(x, y + 1, z + 1))); if (newposition.Y - oldposition.Y < 0) { if (newfull) { velocity.Y = -velocity.Y; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Y = oldposition.Y - newposition.Y; } } } //right { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z - walldistance; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.Z - oldposition.Z < 0) { if (!newempty) { velocity.Z = -velocity.Z; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Z = oldposition.Z - newposition.Z; } } } //back { float qnewpositionX = newposition.X - walldistance; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.X - oldposition.X < 0) { if (!newempty) { velocity.X = -velocity.X; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.X = oldposition.X - newposition.X; } } } //bottom { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y + modelheight; float qnewpositionZ = newposition.Z; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)); if (newposition.Y - oldposition.Y > 0) { if (!newempty) { velocity.Y = -velocity.Y; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Y = oldposition.Y - newposition.Y; } } } //ok: playerpositionY -= walldistance; return Vector3Ref.Create(playerpositionX, playerpositionY, playerpositionZ); }
internal Vector3Ref GrenadeBounce(Game game, Vector3Ref oldposition, Vector3Ref newposition, Vector3Ref velocity, float dt) { bool ismoving = velocity.Length() > 100 * dt; float modelheight = walldistance; oldposition.Y += walldistance; newposition.Y += walldistance; //Math.Floor() is needed because casting negative values to integer is not floor. Vector3IntRef oldpositioni = Vector3IntRef.Create(game.MathFloor(oldposition.X), game.MathFloor(oldposition.Z), game.MathFloor(oldposition.Y)); float playerpositionX = newposition.X; float playerpositionY = newposition.Y; float playerpositionZ = newposition.Z; //left { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z + walldistance; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.Z - oldposition.Z > 0) { if (!newempty) { velocity.Z = -velocity.Z; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Z = oldposition.Z - newposition.Z; } } } //front { float qnewpositionX = newposition.X + walldistance; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.X - oldposition.X > 0) { if (!newempty) { velocity.X = -velocity.X; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.X = oldposition.X - newposition.X; } } } //top { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y - walldistance; float qnewpositionZ = newposition.Z; int x = game.MathFloor(qnewpositionX); int y = game.MathFloor(qnewpositionZ); int z = game.MathFloor(qnewpositionY); float a_ = walldistance; bool newfull = (!game.IsTileEmptyForPhysics(x, y, z)) || (qnewpositionX - game.MathFloor(qnewpositionX) <= a_ && (!game.IsTileEmptyForPhysics(x - 1, y, z)) && (game.IsTileEmptyForPhysics(x - 1, y, z + 1))) || (qnewpositionX - game.MathFloor(qnewpositionX) >= (1 - a_) && (!game.IsTileEmptyForPhysics(x + 1, y, z)) && (game.IsTileEmptyForPhysics(x + 1, y, z + 1))) || (qnewpositionZ - game.MathFloor(qnewpositionZ) <= a_ && (!game.IsTileEmptyForPhysics(x, y - 1, z)) && (game.IsTileEmptyForPhysics(x, y - 1, z + 1))) || (qnewpositionZ - game.MathFloor(qnewpositionZ) >= (1 - a_) && (!game.IsTileEmptyForPhysics(x, y + 1, z)) && (game.IsTileEmptyForPhysics(x, y + 1, z + 1))); if (newposition.Y - oldposition.Y < 0) { if (newfull) { velocity.Y = -velocity.Y; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Y = oldposition.Y - newposition.Y; } } } //right { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z - walldistance; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.Z - oldposition.Z < 0) { if (!newempty) { velocity.Z = -velocity.Z; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Z = oldposition.Z - newposition.Z; } } } //back { float qnewpositionX = newposition.X - walldistance; float qnewpositionY = newposition.Y; float qnewpositionZ = newposition.Z; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)) && game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY) + 1); if (newposition.X - oldposition.X < 0) { if (!newempty) { velocity.X = -velocity.X; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.X = oldposition.X - newposition.X; } } } //bottom { float qnewpositionX = newposition.X; float qnewpositionY = newposition.Y + modelheight; float qnewpositionZ = newposition.Z; bool newempty = game.IsTileEmptyForPhysics(game.MathFloor(qnewpositionX), game.MathFloor(qnewpositionZ), game.MathFloor(qnewpositionY)); if (newposition.Y - oldposition.Y > 0) { if (!newempty) { velocity.Y = -velocity.Y; velocity.X *= bouncespeedmultiply; velocity.Y *= bouncespeedmultiply; velocity.Z *= bouncespeedmultiply; if (ismoving) { game.AudioPlayAt("grenadebounce.ogg", newposition.X, newposition.Y, newposition.Z); } //playerposition.Y = oldposition.Y - newposition.Y; } } } //ok: playerpositionY -= walldistance; return(Vector3Ref.Create(playerpositionX, playerpositionY, playerpositionZ)); }
internal void DrawPlayers(Game game, float dt) { game.totaltimeMilliseconds = game.platform.TimeMillisecondsFromStart(); for (int i = 0; i < game.entitiesCount; i++) { if (game.entities[i] == null) { continue; } if (game.entities[i].drawModel == null) { continue; } Entity p_ = game.entities[i]; if (i == game.LocalPlayerId && (!game.ENABLE_TPP_VIEW)) { continue; } if ((p_.networkPosition != null) && (!p_.networkPosition.PositionLoaded)) { continue; } if (!game.d_FrustumCulling.SphereInFrustum(p_.position.x, p_.position.y, p_.position.z, 3)) { continue; } if (p_.drawModel.CurrentTexture == -1) { continue; } int cx = game.platform.FloatToInt(p_.position.x) / Game.chunksize; int cy = game.platform.FloatToInt(p_.position.z) / Game.chunksize; int cz = game.platform.FloatToInt(p_.position.y) / Game.chunksize; if (game.map.IsValidChunkPos(cx, cy, cz)) { if (!game.map.IsChunkRendered(cx, cy, cz)) { continue; } } float shadow = (one * game.GetLight(game.platform.FloatToInt(p_.position.x), game.platform.FloatToInt(p_.position.z), game.platform.FloatToInt(p_.position.y))) / Game.maxlight; if (p_.playerDrawInfo == null) { p_.playerDrawInfo = new PlayerDrawInfo(); } p_.playerDrawInfo.anim.light = shadow; float FeetPosX = p_.position.x; float FeetPosY = p_.position.y; float FeetPosZ = p_.position.z; AnimationHint animHint = game.entities[i].playerDrawInfo.AnimationHint_; float playerspeed_; if (i == game.LocalPlayerId) { if (game.player.playerDrawInfo == null) { game.player.playerDrawInfo = new PlayerDrawInfo(); } Vector3Ref playerspeed = Vector3Ref.Create(game.playervelocity.X / 60, game.playervelocity.Y / 60, game.playervelocity.Z / 60); float playerspeedf = playerspeed.Length() * (one * 15 / 10); game.player.playerDrawInfo.moves = playerspeedf != 0; playerspeed_ = playerspeedf; } else { playerspeed_ = (game.Length(p_.playerDrawInfo.velocityX, p_.playerDrawInfo.velocityY, p_.playerDrawInfo.velocityZ) / dt) * (one * 4 / 100); } { if (p_.drawModel.renderer == null) { p_.drawModel.renderer = new AnimatedModelRenderer(); byte[] data = game.GetFile(p_.drawModel.Model_); int dataLength = game.GetFileLength(p_.drawModel.Model_); if (data != null) { string dataString = game.platform.StringFromUtf8ByteArray(data, dataLength); AnimatedModel model = AnimatedModelSerializer.Deserialize(game.platform, dataString); p_.drawModel.renderer.Start(game, model); } } game.GLPushMatrix(); game.GLTranslate(FeetPosX, FeetPosY, FeetPosZ); //game.GLRotate(PlayerInterpolate.RadToDeg(p_.position.rotx), 1, 0, 0); game.GLRotate(PlayerInterpolate.RadToDeg(-p_.position.roty + Game.GetPi()), 0, 1, 0); //game.GLRotate(PlayerInterpolate.RadToDeg(p_.position.rotz), 0, 0, 1); game.platform.BindTexture2d(game.entities[i].drawModel.CurrentTexture); p_.drawModel.renderer.Render(dt, PlayerInterpolate.RadToDeg(p_.position.rotx + Game.GetPi()), true, p_.playerDrawInfo.moves, shadow); game.GLPopMatrix(); } } }