mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 20:16:36 -04:00
Fix not dying from falling when landing on corner of a neighbouring block. Fixes #461 (Thanks goodlyay)
This commit is contained in:
parent
116680cd03
commit
55953c1118
@ -74,7 +74,7 @@ namespace MCGalaxy.Commands.Fun {
|
||||
for (; y <= lvl.Height; y++) {
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (above.IsInvalid) continue;
|
||||
if (Collide(lvl, above) != CollideType.Solid) continue;
|
||||
if (lvl.CollideType(above) != CollideType.Solid) continue;
|
||||
|
||||
int posY = (y + 1) * 32 - 6;
|
||||
BlockDefinition def = lvl.GetBlockDef(above);
|
||||
@ -85,15 +85,6 @@ namespace MCGalaxy.Commands.Fun {
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal static byte Collide(Level lvl, ExtBlock block) {
|
||||
BlockDefinition def = lvl.GetBlockDef(block);
|
||||
byte collide = def != null ? def.CollideType : CollideType.Solid;
|
||||
|
||||
if (def == null && !block.IsCustomType)
|
||||
return DefaultSet.Collide(Block.Convert(block.BlockID));
|
||||
return collide;
|
||||
}
|
||||
|
||||
public override void Help(Player p) {
|
||||
Player.Message(p, "%T/slap [name]");
|
||||
Player.Message(p, "%HSlaps [name], knocking them into the air");
|
||||
|
@ -51,12 +51,12 @@ namespace MCGalaxy.Commands.Misc {
|
||||
static int FindYAbove(Level lvl, ushort x, ushort y, ushort z) {
|
||||
for (; y < lvl.Height; y++) {
|
||||
ExtBlock block = lvl.GetBlock(x, y, z);
|
||||
if (!block.IsInvalid && CmdSlap.Collide(lvl, block) == CollideType.Solid) continue;
|
||||
if (!block.IsInvalid && lvl.CollideType(block) == CollideType.Solid) continue;
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (!above.IsInvalid && CmdSlap.Collide(lvl, above) == CollideType.Solid) continue;
|
||||
if (!above.IsInvalid && lvl.CollideType(above) == CollideType.Solid) continue;
|
||||
|
||||
ExtBlock below = lvl.GetBlock(x, (ushort)(y - 1), z);
|
||||
if (!below.IsInvalid && CmdSlap.Collide(lvl, below) == CollideType.Solid)
|
||||
if (!below.IsInvalid && lvl.CollideType(below) == CollideType.Solid)
|
||||
return y;
|
||||
}
|
||||
return -1;
|
||||
|
@ -54,12 +54,12 @@ namespace MCGalaxy.Commands.Misc {
|
||||
static int FindYBelow(Level lvl, ushort x, ushort y, ushort z) {
|
||||
for (; y > 0; y--) {
|
||||
ExtBlock block = lvl.GetBlock(x, y, z);
|
||||
if (!block.IsInvalid && CmdSlap.Collide(lvl, block) == CollideType.Solid) continue;
|
||||
if (!block.IsInvalid && lvl.CollideType(block) == CollideType.Solid) continue;
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (!above.IsInvalid && CmdSlap.Collide(lvl, above) == CollideType.Solid) continue;
|
||||
if (!above.IsInvalid && lvl.CollideType(above) == CollideType.Solid) continue;
|
||||
|
||||
ExtBlock below = lvl.GetBlock(x, (ushort)(y - 1), z);
|
||||
if (!below.IsInvalid && CmdSlap.Collide(lvl, below) == CollideType.Solid)
|
||||
if (!below.IsInvalid && lvl.CollideType(below) == CollideType.Solid)
|
||||
return y;
|
||||
}
|
||||
return -1;
|
||||
|
@ -457,6 +457,15 @@ namespace MCGalaxy {
|
||||
return block.BlockID != Block.custom_block ? Block.Name(block.BlockID).Capitalize() : block.ExtID.ToString();
|
||||
}
|
||||
|
||||
public byte CollideType(ExtBlock block) {
|
||||
BlockDefinition def = GetBlockDef(block);
|
||||
byte collide = def != null ? def.CollideType : MCGalaxy.Blocks.CollideType.Solid;
|
||||
|
||||
if (def == null && !block.IsCustomType)
|
||||
return DefaultSet.Collide(Block.Convert(block.BlockID));
|
||||
return collide;
|
||||
}
|
||||
|
||||
public bool LightPasses(ExtBlock block) {
|
||||
BlockDefinition def = GetBlockDef(block);
|
||||
if (def != null) return !def.BlocksLight || def.BlockDraw != DrawType.Opaque;
|
||||
|
@ -492,12 +492,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
public void UpdateBlockHandler(ExtBlock block) {
|
||||
bool nonSolid;
|
||||
if (GetBlockDef(block) == null) {
|
||||
nonSolid = Block.Walkthrough(Block.Convert(block.BlockID));
|
||||
} else {
|
||||
nonSolid = CustomBlockDefs[block.RawID].CollideType != CollideType.Solid;
|
||||
}
|
||||
bool nonSolid = CollideType(block) != MCGalaxy.Blocks.CollideType.Solid;
|
||||
|
||||
int i = block.Index;
|
||||
deleteHandlers[i] = BlockBehaviour.GetDeleteHandler(block, BlockProps);
|
||||
|
@ -590,6 +590,7 @@
|
||||
<Compile Include="Player\Player.Login.cs" />
|
||||
<Compile Include="Player\PlayerActions.cs" />
|
||||
<Compile Include="Player\PlayerInfo.cs" />
|
||||
<Compile Include="Player\PlayerPhysics.cs" />
|
||||
<Compile Include="Player\SpamChecker.cs" />
|
||||
<Compile Include="Player\TabList.cs" />
|
||||
<Compile Include="Database\Undo\UndoFormatCBin.cs" />
|
||||
|
@ -345,9 +345,10 @@ namespace MCGalaxy {
|
||||
void CheckBlocks(Position pos) {
|
||||
try {
|
||||
Vec3U16 P = (Vec3U16)pos.BlockCoords;
|
||||
if (level.Config.SurvivalDeath) CheckSurvival(P.X, P.Y, P.Z);
|
||||
AABB bb = ModelBB.OffsetPosition(Pos);
|
||||
if (level.Config.SurvivalDeath) CheckSurvival(P.X, P.Y, P.Z, bb);
|
||||
|
||||
CheckBlock();
|
||||
CheckBlock(bb);
|
||||
oldIndex = level.PosToInt(P.X, P.Y, P.Z);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex);
|
||||
@ -356,31 +357,9 @@ namespace MCGalaxy {
|
||||
|
||||
bool Moved() { return lastRot.RotY != Rot.RotY || lastRot.HeadX != Rot.HeadX; }
|
||||
|
||||
internal void CheckSurvival(ushort x, ushort y, ushort z) {
|
||||
byte bFeet = GetSurvivalBlock(x, (ushort)(y - 2), z);
|
||||
byte bBody = GetSurvivalBlock(x, (ushort)(y - 1), z);
|
||||
void CheckSurvival(ushort x, ushort y, ushort z, AABB bb) {
|
||||
byte bHead = GetSurvivalBlock(x, y, z);
|
||||
|
||||
if (level.PosToInt(x, y, z) != oldIndex || y != oldFallY) {
|
||||
bFeet = Block.Convert(bFeet);
|
||||
|
||||
if (bFeet == Block.air) {
|
||||
if (y < oldFallY)
|
||||
fallCount++;
|
||||
else if (y > oldFallY) // flying up, for example
|
||||
fallCount = 0;
|
||||
oldFallY = y;
|
||||
drownCount = 0;
|
||||
return;
|
||||
} else if (!(bFeet == Block.water || bFeet == Block.waterstill ||
|
||||
bFeet == Block.lava || bFeet == Block.lavastill)) {
|
||||
if (fallCount > level.Config.FallHeight)
|
||||
HandleDeath(ExtBlock.Air, null, false, true);
|
||||
fallCount = 0;
|
||||
drownCount = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (level.PosToInt(x, y, z) != oldIndex) PlayerPhysics.Fall(this, bb);
|
||||
|
||||
switch (Block.Convert(bHead)) {
|
||||
case Block.water:
|
||||
@ -412,8 +391,7 @@ namespace MCGalaxy {
|
||||
return level.GetTile(x, y, z);
|
||||
}
|
||||
|
||||
internal void CheckBlock() {
|
||||
AABB bb = ModelBB.OffsetPosition(Pos);
|
||||
void CheckBlock(AABB bb) {
|
||||
Vec3S32 min = bb.BlockMin, max = bb.BlockMax;
|
||||
bool hitWalkthrough = false;
|
||||
|
||||
|
63
MCGalaxy/Player/PlayerPhysics.cs
Normal file
63
MCGalaxy/Player/PlayerPhysics.cs
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using MCGalaxy.Maths;
|
||||
|
||||
namespace MCGalaxy.Blocks.Physics {
|
||||
|
||||
internal static class PlayerPhysics {
|
||||
|
||||
internal static void Fall(Player p, AABB bb) {
|
||||
bb.Min.Y -= 2; // test block below player feet
|
||||
Vec3S32 min = bb.BlockMin;
|
||||
if (min.Y == p.oldFallY) return;
|
||||
|
||||
Vec3S32 max = bb.BlockMax;
|
||||
bool allGas = true;
|
||||
|
||||
for (int z = min.Z; z <= max.Z; z++)
|
||||
for (int x = min.X; x <= max.X; x++)
|
||||
{
|
||||
ExtBlock block = GetSurvivalBlock(p, x, min.Y, z);
|
||||
byte collideType = p.level.CollideType(block);
|
||||
allGas = allGas && collideType == CollideType.WalkThrough;
|
||||
|
||||
if (collideType != CollideType.Solid) continue;
|
||||
if (p.fallCount > p.level.Config.FallHeight)
|
||||
p.HandleDeath(ExtBlock.Air, null, false, true);
|
||||
|
||||
p.fallCount = 0;
|
||||
p.drownCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!allGas) return;
|
||||
if (min.Y < p.oldFallY) p.fallCount++;
|
||||
else if (min.Y > p.oldFallY) p.fallCount = 0; // e.g. flying up
|
||||
|
||||
p.oldFallY = min.Y;
|
||||
p.drownCount = 0;
|
||||
}
|
||||
|
||||
static ExtBlock GetSurvivalBlock(Player p, int x, int y, int z) {
|
||||
if (y < 0) return (ExtBlock)Block.blackrock;
|
||||
if (y >= p.level.Height) return ExtBlock.Air;
|
||||
return p.level.GetBlock((ushort)x, (ushort)y, (ushort)z);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user