commit
457e93f1ed
@ -1 +1 @@
|
||||
Subproject commit c65b56767a5e59ca387a05be72ef18791baa9aed
|
||||
Subproject commit 944b0e95303a17200e52699c3bc7c349424be581
|
@ -2,15 +2,15 @@
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{3c30caed-20a3-4bd8-b12e-fdd1e13455e5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{59bfc075-705c-42cd-adf7-40cef1aed8e1}</UniqueIdentifier>
|
||||
<Extensions>.cpp</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{770573d2-b90d-43f4-ac1c-464ab10c46ec}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{407d7f02-df9e-485b-a95f-2f1dad08cbed}</UniqueIdentifier>
|
||||
<Extensions>.;.h</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Miscellaneous">
|
||||
<UniqueIdentifier>{1ac058bb-f217-4ac3-a14b-9c6ba021e030}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{293a01a6-81d1-4272-a7ff-310526bbc77f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -226,6 +226,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\Resources\resource_MCServer.h" />
|
||||
<ClInclude Include="..\src\Authenticator.h" />
|
||||
<ClInclude Include="..\src\BiomeDef.h" />
|
||||
<ClInclude Include="..\src\BlockArea.h" />
|
||||
<ClInclude Include="..\src\BlockID.h" />
|
||||
<ClInclude Include="..\src\BlockTracer.h" />
|
||||
@ -234,8 +235,6 @@
|
||||
<ClInclude Include="..\src\ChatColor.h" />
|
||||
<ClInclude Include="..\src\Chunk.h" />
|
||||
<ClInclude Include="..\src\ChunkDef.h" />
|
||||
<ClInclude Include="..\src\BiomeDef.h" />
|
||||
<ClInclude Include="..\src\BiomeDef.cpp" />
|
||||
<ClInclude Include="..\src\ChunkMap.h" />
|
||||
<ClInclude Include="..\src\ChunkSender.h" />
|
||||
<ClInclude Include="..\src\ClientHandle.h" />
|
||||
@ -374,7 +373,6 @@
|
||||
<ClInclude Include="..\src\Bindings\Plugin.h" />
|
||||
<ClInclude Include="..\src\Bindings\PluginLua.h" />
|
||||
<ClInclude Include="..\src\Bindings\PluginManager.h" />
|
||||
<ClInclude Include="..\src\Bindings\tolua_base.h" />
|
||||
<ClInclude Include="..\src\Bindings\WebPlugin.h" />
|
||||
<ClInclude Include="..\lib\inifile\iniFile.h" />
|
||||
<ClInclude Include="..\lib\md5\md5.h" />
|
||||
@ -618,6 +616,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\Authenticator.cpp" />
|
||||
<ClCompile Include="..\src\BiomeDef.cpp" />
|
||||
<ClCompile Include="..\src\BlockArea.cpp" />
|
||||
<ClCompile Include="..\src\BlockID.cpp" />
|
||||
<ClCompile Include="..\src\BoundingBox.cpp" />
|
||||
|
@ -10,73 +10,73 @@
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Mobs">
|
||||
<UniqueIdentifier>{813698c3-b2c1-4f3d-a89c-7ac6239fff97}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{46ffa881-c36b-41b0-85df-90e0f78c6285}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Entities">
|
||||
<UniqueIdentifier>{b120a538-d8b9-4576-8675-36cf01fd69fc}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{5eb3c155-b618-4232-92a5-52b3ae70ec96}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\UI">
|
||||
<UniqueIdentifier>{85037cf1-81a5-47c7-8c2e-899ea706b8e7}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{5f745788-b9aa-4dde-9763-cdfaddb3dfdf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Simulator">
|
||||
<UniqueIdentifier>{46c9cb22-7c7f-4589-b9b2-1fc79d2bdbdf}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{acb44271-df18-41b2-8a50-656a49c39d3c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\OSSupport">
|
||||
<UniqueIdentifier>{f12178cb-2ecb-4e48-9a8d-ba3e2e73cfbc}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{1091cb9f-3d9d-4ed5-9359-fc762be21759}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\OSSupport\Android Specific">
|
||||
<UniqueIdentifier>{488bc224-735f-405c-83de-870373cb52cb}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{c40bec86-f173-440a-b07e-bab15c8ce965}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Bindings">
|
||||
<UniqueIdentifier>{41c0d7c9-43b5-4d17-b50e-3c8ac3aa2905}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{4180990c-1257-4d07-9009-08535fedfbf8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\External">
|
||||
<UniqueIdentifier>{2c71a15a-8c65-4be7-bdfb-e083f4841c4a}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{ffc2297f-c790-4190-a56f-ac6a1f97a30c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\WorldStorage">
|
||||
<UniqueIdentifier>{2227f719-f0ac-444e-af14-230853017c45}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{011ff757-845a-4342-862e-44207ec46a94}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Generating">
|
||||
<UniqueIdentifier>{eb070b55-ba10-4bce-ba06-5d785a055e54}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7f7a0b8c-4ee6-4a3a-92d6-5ba242a565f3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Blocks">
|
||||
<UniqueIdentifier>{779dac55-c718-4fe1-8b67-547d431b9ebc}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{07157169-9da7-4998-9f00-4580641cf811}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Items">
|
||||
<UniqueIdentifier>{89847a5d-608a-4137-a766-1557276b4fcf}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{5b92b198-0a58-4399-9c8e-662bd5062b6c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Protocol">
|
||||
<UniqueIdentifier>{e159d08d-daec-46de-9b60-9f8e660da91d}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{16a88457-3862-4ff0-a591-a7160ea956f5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\SQLite">
|
||||
<UniqueIdentifier>{0278092b-abe5-4276-81cf-59e4079e5bc7}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{a3561ecf-a501-4c76-b176-1f214b7a5523}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\LuaExpat">
|
||||
<UniqueIdentifier>{e4879cf2-e769-4e1d-8905-0f6c40ee5bc1}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{a35eb320-d10b-4592-92ed-2d2f242dbed7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\BlockEntities">
|
||||
<UniqueIdentifier>{d641a9d4-f5dc-4808-bee6-194306505244}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{1c271d11-30ce-4aef-b8a9-7c8ee560d5d6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\HTTPServer">
|
||||
<UniqueIdentifier>{a1e39415-2aca-4779-a558-2567a9de304f}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{223bdf26-d107-498f-8c42-00c19ef80348}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Config files">
|
||||
<UniqueIdentifier>{eb5f3060-03ed-4548-8bde-340454d3d23a}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{99140e5f-0287-4601-ad28-bad2533d8876}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Plugins">
|
||||
<UniqueIdentifier>{7c681450-041a-4846-acf6-951c1f4e32a4}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{beb25b3b-31f3-468e-a721-6d0dc297e4b5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Plugins\Core">
|
||||
<UniqueIdentifier>{e961964c-9fb7-4513-89fa-05e0b760e0f1}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{f848f39d-680d-4f9c-8dcb-da9a0bb871f5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Plugins\ChatLog">
|
||||
<UniqueIdentifier>{70696c83-2307-43c6-8851-81aa3baa8523}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7c735e41-f3b2-4500-856b-54845f834eb2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Plugins\Debuggers">
|
||||
<UniqueIdentifier>{d3b692db-0684-4b89-9d38-2e5af12e9a6e}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{83d5aac9-2975-4334-9acc-b48e96a16b23}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Plugins\APIDump">
|
||||
<UniqueIdentifier>{6eee304c-f055-4758-a248-a125e1af7e73}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{e5167107-9cc8-4e03-b519-c3a13b9b7955}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -96,6 +96,9 @@
|
||||
<ClInclude Include="..\src\Authenticator.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\BiomeDef.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\BlockArea.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
@ -513,9 +516,6 @@
|
||||
<ClInclude Include="..\src\Bindings\PluginManager.h">
|
||||
<Filter>Source Files\Bindings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Bindings\tolua_base.h">
|
||||
<Filter>Source Files\Bindings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Bindings\WebPlugin.h">
|
||||
<Filter>Source Files\Bindings</Filter>
|
||||
</ClInclude>
|
||||
@ -1114,6 +1114,9 @@
|
||||
<ClCompile Include="..\src\Authenticator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\BiomeDef.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\BlockArea.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -169,9 +169,9 @@ void cPluginManager::InsertDefaultPlugins(cIniFile & a_SettingsIni)
|
||||
a_SettingsIni.AddKeyComment("Plugins", " Plugin=HookNotify");
|
||||
a_SettingsIni.AddKeyComment("Plugins", " Plugin=ChunkWorx");
|
||||
a_SettingsIni.AddKeyComment("Plugins", " Plugin=APIDump");
|
||||
a_SettingsIni.SetValue("Plugins", "Plugin", "Core");
|
||||
a_SettingsIni.SetValue("Plugins", "Plugin", "TransAPI");
|
||||
a_SettingsIni.SetValue("Plugins", "Plugin", "ChatLog");
|
||||
a_SettingsIni.AddValue("Plugins", "Plugin", "Core");
|
||||
a_SettingsIni.AddValue("Plugins", "Plugin", "TransAPI");
|
||||
a_SettingsIni.AddValue("Plugins", "Plugin", "ChatLog");
|
||||
}
|
||||
|
||||
|
||||
|
@ -767,6 +767,7 @@ public:
|
||||
g_BlockIsSolid[E_BLOCK_MELON_STEM] = false;
|
||||
g_BlockIsSolid[E_BLOCK_NETHER_PORTAL] = false;
|
||||
g_BlockIsSolid[E_BLOCK_PISTON_EXTENSION] = false;
|
||||
g_BlockIsSolid[E_BLOCK_POWERED_RAIL] = false;
|
||||
g_BlockIsSolid[E_BLOCK_RAIL] = false;
|
||||
g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_OFF] = false;
|
||||
g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_ON] = false;
|
||||
|
@ -321,7 +321,10 @@ void cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||
m_Health = 0;
|
||||
}
|
||||
|
||||
AddSpeed(a_TDI.Knockback * 2);
|
||||
if (IsMob() || IsPlayer()) // Knockback for only players and mobs
|
||||
{
|
||||
AddSpeed(a_TDI.Knockback * 2);
|
||||
}
|
||||
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_HURT);
|
||||
|
||||
@ -626,11 +629,6 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water.
|
||||
}
|
||||
else if (IsBlockRail(BlockBelow) && IsMinecart()) // Rails aren't solid, except for Minecarts
|
||||
{
|
||||
fallspeed = 0;
|
||||
m_bOnGround = true;
|
||||
}
|
||||
else if (BlockIn == E_BLOCK_COBWEB)
|
||||
{
|
||||
NextSpeed.y *= 0.05; // Reduce overall falling speed
|
||||
@ -645,41 +643,18 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsMinecart())
|
||||
// Friction
|
||||
if (NextSpeed.SqrLength() > 0.0004f)
|
||||
{
|
||||
if (!IsBlockRail(BlockBelow))
|
||||
NextSpeed.x *= 0.7f / (1 + a_Dt);
|
||||
if (fabs(NextSpeed.x) < 0.05)
|
||||
{
|
||||
// Friction if minecart is off track, otherwise, Minecart.cpp handles this
|
||||
if (NextSpeed.SqrLength() > 0.0004f)
|
||||
{
|
||||
NextSpeed.x *= 0.7f / (1 + a_Dt);
|
||||
if (fabs(NextSpeed.x) < 0.05)
|
||||
{
|
||||
NextSpeed.x = 0;
|
||||
}
|
||||
NextSpeed.z *= 0.7f / (1 + a_Dt);
|
||||
if (fabs(NextSpeed.z) < 0.05)
|
||||
{
|
||||
NextSpeed.z = 0;
|
||||
}
|
||||
}
|
||||
NextSpeed.x = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Friction for non-minecarts
|
||||
if (NextSpeed.SqrLength() > 0.0004f)
|
||||
NextSpeed.z *= 0.7f / (1 + a_Dt);
|
||||
if (fabs(NextSpeed.z) < 0.05)
|
||||
{
|
||||
NextSpeed.x *= 0.7f / (1 + a_Dt);
|
||||
if (fabs(NextSpeed.x) < 0.05)
|
||||
{
|
||||
NextSpeed.x = 0;
|
||||
}
|
||||
NextSpeed.z *= 0.7f / (1 + a_Dt);
|
||||
if (fabs(NextSpeed.z) < 0.05)
|
||||
{
|
||||
NextSpeed.z = 0;
|
||||
}
|
||||
NextSpeed.z = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1104,9 +1079,11 @@ void cEntity::AttachTo(cEntity * a_AttachTo)
|
||||
// Already attached to that entity, nothing to do here
|
||||
return;
|
||||
}
|
||||
|
||||
// Detach from any previous entity:
|
||||
Detach();
|
||||
if (m_AttachedTo != NULL)
|
||||
{
|
||||
// Detach from any previous entity:
|
||||
Detach();
|
||||
}
|
||||
|
||||
// Attach to the new entity:
|
||||
m_AttachedTo = a_AttachTo;
|
||||
|
@ -327,7 +327,7 @@ public:
|
||||
void AttachTo(cEntity * a_AttachTo);
|
||||
|
||||
/// Detaches from the currently attached entity, if any
|
||||
void Detach(void);
|
||||
virtual void Detach(void);
|
||||
|
||||
/// Makes sure head yaw is not over the specified range.
|
||||
void WrapHeadYaw();
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Minecart.cpp
|
||||
|
||||
// Implements the cMinecart class representing a minecart in the world
|
||||
// Handles physics when a minecart is on any type of rail (overrides simulator in Entity.cpp)
|
||||
// Indiana Jones!
|
||||
|
||||
#include "Globals.h"
|
||||
@ -10,6 +11,10 @@
|
||||
#include "../ClientHandle.h"
|
||||
#include "../Chunk.h"
|
||||
#include "Player.h"
|
||||
#include "../BoundingBox.h"
|
||||
|
||||
#define MAX_SPEED 8
|
||||
#define MAX_SPEED_NEGATIVE -MAX_SPEED
|
||||
|
||||
|
||||
|
||||
@ -18,11 +23,15 @@
|
||||
cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) :
|
||||
super(etMinecart, a_X, a_Y, a_Z, 0.98, 0.7),
|
||||
m_Payload(a_Payload),
|
||||
m_LastDamage(0)
|
||||
m_LastDamage(0),
|
||||
m_DetectorRailPosition(0, 0, 0),
|
||||
m_bIsOnDetectorRail(false)
|
||||
{
|
||||
SetMass(20.f);
|
||||
SetMaxHealth(6);
|
||||
SetHealth(6);
|
||||
SetWidth(1.2);
|
||||
SetHeight(0.9);
|
||||
}
|
||||
|
||||
|
||||
@ -53,6 +62,11 @@ void cMinecart::SpawnOn(cClientHandle & a_ClientHandle)
|
||||
|
||||
void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
if (IsDestroyed()) // Mainly to stop detector rails triggering again after minecart is dead
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int PosY = (int)floor(GetPosY());
|
||||
if ((PosY <= 0) || (PosY >= cChunkDef::Height))
|
||||
{
|
||||
@ -70,24 +84,361 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
// Inside an unloaded chunk, bail out all processing
|
||||
return;
|
||||
}
|
||||
BLOCKTYPE BelowType = Chunk->GetBlock(RelPosX, PosY - 1, RelPosZ);
|
||||
BLOCKTYPE InsideType = Chunk->GetBlock(RelPosX, PosY, RelPosZ);
|
||||
|
||||
if (IsBlockRail(BelowType))
|
||||
BLOCKTYPE InsideType;
|
||||
NIBBLETYPE InsideMeta;
|
||||
Chunk->GetBlockTypeMeta(RelPosX, PosY, RelPosZ, InsideType, InsideMeta);
|
||||
|
||||
if (!IsBlockRail(InsideType))
|
||||
{
|
||||
HandleRailPhysics(a_Dt, *Chunk);
|
||||
Chunk->GetBlockTypeMeta(RelPosX, PosY + 1, RelPosZ, InsideType, InsideMeta); // When an descending minecart hits a flat rail, it goes through the ground; check for this
|
||||
if (IsBlockRail(InsideType)) AddPosY(1); // Push cart upwards
|
||||
}
|
||||
|
||||
if (IsBlockRail(InsideType))
|
||||
{
|
||||
bool WasDetectorRail = false;
|
||||
SnapToRail(InsideMeta);
|
||||
|
||||
switch (InsideType)
|
||||
{
|
||||
case E_BLOCK_RAIL: HandleRailPhysics(InsideMeta, a_Dt); break;
|
||||
case E_BLOCK_ACTIVATOR_RAIL: break;
|
||||
case E_BLOCK_POWERED_RAIL: HandlePoweredRailPhysics(InsideMeta); break;
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
{
|
||||
HandleDetectorRailPhysics(InsideMeta, a_Dt);
|
||||
WasDetectorRail = true;
|
||||
break;
|
||||
}
|
||||
default: VERIFY(!"Unhandled rail type despite checking if block was rail!"); break;
|
||||
}
|
||||
|
||||
AddPosition(GetSpeed() * (a_Dt / 1000)); // Commit changes; as we use our own engine when on rails, this needs to be done, whereas it is normally in Entity.cpp
|
||||
|
||||
if (m_bIsOnDetectorRail && !WasDetectorRail)
|
||||
{
|
||||
m_World->SetBlock(m_DetectorRailPosition.x, m_DetectorRailPosition.y, m_DetectorRailPosition.z, E_BLOCK_DETECTOR_RAIL, m_World->GetBlockMeta(m_DetectorRailPosition) & 0x07);
|
||||
m_bIsOnDetectorRail = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsBlockRail(InsideType))
|
||||
// Not on rail, default physics
|
||||
SetPosY(floor(GetPosY()) + 0.35); // HandlePhysics overrides this if minecart can fall, else, it is to stop ground clipping minecart bottom when off-rail
|
||||
super::HandlePhysics(a_Dt, *Chunk);
|
||||
}
|
||||
|
||||
// Broadcast positioning changes to client
|
||||
BroadcastMovementUpdate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
|
||||
{
|
||||
/*
|
||||
NOTE: Please bear in mind that taking away from negatives make them even more negative,
|
||||
adding to negatives make them positive, etc.
|
||||
*/
|
||||
|
||||
switch (a_RailMeta)
|
||||
{
|
||||
case E_META_RAIL_ZM_ZP: // NORTHSOUTH
|
||||
{
|
||||
SetPosY(PosY + 1);
|
||||
HandleRailPhysics(a_Dt, *Chunk);
|
||||
SetRotation(270);
|
||||
SetPosY(floor(GetPosY()) + 0.55);
|
||||
SetSpeedY(0); // Don't move vertically as on ground
|
||||
SetSpeedX(0); // Correct diagonal movement from curved rails
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedZ() != 0) // Don't do anything if cart is stationary
|
||||
{
|
||||
if (GetSpeedZ() > 0)
|
||||
{
|
||||
// Going SOUTH, slow down
|
||||
AddSpeedZ(-0.1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Going NORTH, slow down
|
||||
AddSpeedZ(0.1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
case E_META_RAIL_XM_XP: // EASTWEST
|
||||
{
|
||||
super::HandlePhysics(a_Dt, *Chunk);
|
||||
BroadcastMovementUpdate();
|
||||
SetRotation(180);
|
||||
SetPosY(floor(GetPosY()) + 0.55);
|
||||
SetSpeedY(0);
|
||||
SetSpeedZ(0);
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedX() != 0)
|
||||
{
|
||||
if (GetSpeedX() > 0)
|
||||
{
|
||||
AddSpeedX(-0.1);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddSpeedX(0.1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH
|
||||
{
|
||||
SetRotation(270);
|
||||
SetSpeedX(0);
|
||||
|
||||
if (GetSpeedZ() >= 0)
|
||||
{
|
||||
// SpeedZ POSITIVE, going SOUTH
|
||||
if (GetSpeedZ() <= MAX_SPEED) // Speed limit
|
||||
{
|
||||
AddSpeedZ(0.5); // Speed up
|
||||
SetSpeedY(-GetSpeedZ()); // Downward movement is negative (0 minus positive numbers is negative)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// SpeedZ NEGATIVE, going NORTH
|
||||
AddSpeedZ(1); // Slow down
|
||||
SetSpeedY(-GetSpeedZ()); // Upward movement is positive (0 minus negative number is positive number)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH
|
||||
{
|
||||
SetRotation(270);
|
||||
SetSpeedX(0);
|
||||
|
||||
if (GetSpeedZ() > 0)
|
||||
{
|
||||
// SpeedZ POSITIVE, going SOUTH
|
||||
AddSpeedZ(-1); // Slow down
|
||||
SetSpeedY(GetSpeedZ()); // Upward movement positive
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetSpeedZ() >= MAX_SPEED_NEGATIVE) // Speed limit
|
||||
{
|
||||
// SpeedZ NEGATIVE, going NORTH
|
||||
AddSpeedZ(-0.5); // Speed up
|
||||
SetSpeedY(GetSpeedZ()); // Downward movement negative
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_ASCEND_XM: // ASCEND EAST
|
||||
{
|
||||
SetRotation(180);
|
||||
SetSpeedZ(0);
|
||||
|
||||
if (GetSpeedX() >= 0)
|
||||
{
|
||||
if (GetSpeedX() <= MAX_SPEED)
|
||||
{
|
||||
AddSpeedX(0.5);
|
||||
SetSpeedY(-GetSpeedX());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddSpeedX(1);
|
||||
SetSpeedY(-GetSpeedX());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_ASCEND_XP: // ASCEND WEST
|
||||
{
|
||||
SetRotation(180);
|
||||
SetSpeedZ(0);
|
||||
|
||||
if (GetSpeedX() > 0)
|
||||
{
|
||||
AddSpeedX(-1);
|
||||
SetSpeedY(GetSpeedX());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetSpeedX() >= MAX_SPEED_NEGATIVE)
|
||||
{
|
||||
AddSpeedX(-0.5);
|
||||
SetSpeedY(GetSpeedX());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_CURVED_ZM_XM: // Ends pointing NORTH and WEST
|
||||
{
|
||||
SetRotation(315); // Set correct rotation server side
|
||||
SetPosY(floor(GetPosY()) + 0.55); // Levitate dat cart
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedZ() > 0) // Cart moving south
|
||||
{
|
||||
int OldX = (int)floor(GetPosX());
|
||||
AddSpeedX(-GetSpeedZ() + 0.5); // See below
|
||||
AddPosX(-GetSpeedZ() * (a_Dt / 1000)); // Diagonally move southwest (which will make cart hit a southwest rail)
|
||||
// If we are already at southwest rail, set Z speed to zero as we can be moving so fast, MCS doesn't tick fast enough to active the handle for the rail...
|
||||
// ...and so we derail unexpectedly.
|
||||
if (GetPosX() <= OldX - 1) SetSpeedZ(0);
|
||||
}
|
||||
else if (GetSpeedX() > 0) // Cart moving east
|
||||
{
|
||||
int OldZ = (int)floor(GetPosZ());
|
||||
AddSpeedZ(-GetSpeedX() + 0.5);
|
||||
AddPosZ(-GetSpeedX() * (a_Dt / 1000)); // Diagonally move northeast
|
||||
if (GetPosZ() <= OldZ - 1) SetSpeedX(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_CURVED_ZM_XP: // Curved NORTH EAST
|
||||
{
|
||||
SetRotation(225);
|
||||
SetPosY(floor(GetPosY()) + 0.55);
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedZ() > 0)
|
||||
{
|
||||
int OldX = (int)floor(GetPosX());
|
||||
AddSpeedX(GetSpeedZ() - 0.5);
|
||||
AddPosX(GetSpeedZ() * (a_Dt / 1000));
|
||||
if (GetPosX() >= OldX + 1) SetSpeedZ(0);
|
||||
}
|
||||
else if (GetSpeedX() < 0)
|
||||
{
|
||||
int OldZ = (int)floor(GetPosZ());
|
||||
AddSpeedZ(GetSpeedX() + 0.5);
|
||||
AddPosZ(GetSpeedX() * (a_Dt / 1000));
|
||||
if (GetPosZ() <= OldZ - 1) SetSpeedX(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST
|
||||
{
|
||||
SetRotation(135);
|
||||
SetPosY(floor(GetPosY()) + 0.55);
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedZ() < 0)
|
||||
{
|
||||
int OldX = (int)floor(GetPosX());
|
||||
AddSpeedX(GetSpeedZ() + 0.5);
|
||||
AddPosX(GetSpeedZ() * (a_Dt / 1000));
|
||||
if (GetPosX() <= OldX - 1) SetSpeedZ(0);
|
||||
}
|
||||
else if (GetSpeedX() > 0)
|
||||
{
|
||||
int OldZ = (int)floor(GetPosZ());
|
||||
AddSpeedZ(GetSpeedX() - 0.5);
|
||||
AddPosZ(GetSpeedX() * (a_Dt / 1000));
|
||||
if (GetPosZ() >= OldZ + 1) SetSpeedX(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST
|
||||
{
|
||||
SetRotation(45);
|
||||
SetPosY(floor(GetPosY()) + 0.55);
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedZ() < 0)
|
||||
{
|
||||
int OldX = (int)floor(GetPosX());
|
||||
AddSpeedX(-GetSpeedZ() - 0.5);
|
||||
AddPosX(-GetSpeedZ() * (a_Dt / 1000));
|
||||
if (GetPosX() >= OldX + 1) SetSpeedZ(0);
|
||||
}
|
||||
else if (GetSpeedX() < 0)
|
||||
{
|
||||
int OldZ = (int)floor(GetPosZ());
|
||||
AddSpeedZ(-GetSpeedX() - 0.5);
|
||||
AddPosZ(-GetSpeedX() * (a_Dt / 1000));
|
||||
if (GetPosZ() >= OldZ + 1) SetSpeedX(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unhandled rail meta!"); // Dun dun DUN!
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
|
||||
{
|
||||
// Initialise to 'slow down' values
|
||||
int AccelDecelSpeed = -1;
|
||||
int AccelDecelNegSpeed = 1;
|
||||
|
||||
if ((a_RailMeta & 0x8) == 0x8)
|
||||
{
|
||||
// Rail powered - set variables to 'speed up' values
|
||||
AccelDecelSpeed = 1;
|
||||
AccelDecelNegSpeed = -1;
|
||||
}
|
||||
|
||||
switch (a_RailMeta & 0x07)
|
||||
{
|
||||
case E_META_RAIL_ZM_ZP: // NORTHSOUTH
|
||||
{
|
||||
SetRotation(270);
|
||||
SetPosY(floor(GetPosY()) + 0.55);
|
||||
SetSpeedY(0);
|
||||
SetSpeedX(0);
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedZ() != 0)
|
||||
{
|
||||
if (GetSpeedZ() > 0)
|
||||
{
|
||||
AddSpeedZ(AccelDecelNegSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddSpeedZ(AccelDecelSpeed);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_XM_XP: // EASTWEST
|
||||
{
|
||||
SetRotation(180);
|
||||
SetPosY(floor(GetPosY()) + 0.55);
|
||||
SetSpeedY(0);
|
||||
SetSpeedZ(0);
|
||||
|
||||
if (TestBlockCollision(a_RailMeta)) return;
|
||||
|
||||
if (GetSpeedX() != 0)
|
||||
{
|
||||
if (GetSpeedX() > 0)
|
||||
{
|
||||
AddSpeedX(AccelDecelSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddSpeedX(AccelDecelNegSpeed);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,260 +447,150 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
static const double MAX_SPEED = 8;
|
||||
static const double MAX_SPEED_NEGATIVE = (0 - MAX_SPEED);
|
||||
|
||||
void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk)
|
||||
void cMinecart::HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
|
||||
{
|
||||
|
||||
super::HandlePhysics(a_Dt, a_Chunk); // Main physics handling
|
||||
m_bIsOnDetectorRail = true;
|
||||
m_DetectorRailPosition = Vector3i((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()));
|
||||
|
||||
/*
|
||||
NOTE: Please bear in mind that taking away from negatives make them even more negative,
|
||||
adding to negatives make them positive, etc.
|
||||
*/
|
||||
|
||||
// Get block meta below the cart
|
||||
int RelPosX = (int)floor(GetPosX()) - a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int RelPosZ = (int)floor(GetPosZ()) - a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
NIBBLETYPE BelowMeta = a_Chunk.GetMeta(RelPosX, (int)floor(GetPosY() - 1), RelPosZ);
|
||||
double SpeedX = GetSpeedX(), SpeedY = GetSpeedY(), SpeedZ = GetSpeedZ(); // Get current speed
|
||||
|
||||
switch (BelowMeta)
|
||||
m_World->SetBlockMeta(m_DetectorRailPosition, a_RailMeta | 0x08);
|
||||
|
||||
HandleRailPhysics(a_RailMeta & 0x07, a_Dt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta)
|
||||
{
|
||||
switch (a_RailMeta)
|
||||
{
|
||||
case E_META_RAIL_ZM_ZP: // NORTHSOUTH
|
||||
case E_META_RAIL_ASCEND_XM:
|
||||
case E_META_RAIL_ASCEND_XP:
|
||||
case E_META_RAIL_XM_XP:
|
||||
{
|
||||
SetRotation(270);
|
||||
SpeedY = 0; // Don't move vertically as on ground
|
||||
SpeedX = 0; // Correct diagonal movement from curved rails
|
||||
|
||||
if (SpeedZ != 0) // Don't do anything if cart is stationary
|
||||
{
|
||||
if (SpeedZ > 0)
|
||||
{
|
||||
// Going SOUTH, slow down
|
||||
SpeedZ = SpeedZ - 0.1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Going NORTH, slow down
|
||||
SpeedZ = SpeedZ + 0.1;
|
||||
}
|
||||
}
|
||||
SetSpeedZ(0);
|
||||
SetPosZ(floor(GetPosZ()) + 0.5);
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_XM_XP: // EASTWEST
|
||||
case E_META_RAIL_ASCEND_ZM:
|
||||
case E_META_RAIL_ASCEND_ZP:
|
||||
case E_META_RAIL_ZM_ZP:
|
||||
{
|
||||
SetRotation(180);
|
||||
SpeedY = 0;
|
||||
SpeedZ = 0;
|
||||
|
||||
if (SpeedX != 0)
|
||||
{
|
||||
if (SpeedX > 0)
|
||||
{
|
||||
SpeedX = SpeedX - 0.1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeedX = SpeedX + 0.1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH
|
||||
{
|
||||
SetRotation(270);
|
||||
SetPosY(floor(GetPosY()) + 0.2); // It seems it doesn't work without levitation :/
|
||||
SpeedX = 0;
|
||||
|
||||
if (SpeedZ >= 0)
|
||||
{
|
||||
// SpeedZ POSITIVE, going SOUTH
|
||||
if (SpeedZ <= MAX_SPEED) // Speed limit
|
||||
{
|
||||
SpeedZ = SpeedZ + 0.5; // Speed up
|
||||
SpeedY = (0 - SpeedZ); // Downward movement is negative (0 minus positive numbers is negative)
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeedZ = MAX_SPEED; // Enforce speed limit
|
||||
SpeedY = (0 - SpeedZ);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// SpeedZ NEGATIVE, going NORTH
|
||||
SpeedZ = SpeedZ + 0.4; // Slow down
|
||||
SpeedY = (0 - SpeedZ); // Upward movement is positive (0 minus negative number is positive number)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH
|
||||
{
|
||||
SetRotation(270);
|
||||
SetPosY(floor(GetPosY()) + 0.2);
|
||||
SpeedX = 0;
|
||||
|
||||
if (SpeedZ > 0)
|
||||
{
|
||||
// SpeedZ POSITIVE, going SOUTH
|
||||
SpeedZ = SpeedZ - 0.4; // Slow down
|
||||
SpeedY = SpeedZ; // Upward movement positive
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SpeedZ >= MAX_SPEED_NEGATIVE) // Speed limit
|
||||
{
|
||||
// SpeedZ NEGATIVE, going NORTH
|
||||
SpeedZ = SpeedZ - 0.5; // Speed up
|
||||
SpeedY = SpeedZ; // Downward movement negative
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeedZ = MAX_SPEED_NEGATIVE; // Enforce speed limit
|
||||
SpeedY = SpeedZ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_ASCEND_XM: // ASCEND EAST
|
||||
{
|
||||
SetRotation(180);
|
||||
SetPosY(floor(GetPosY()) + 0.2);
|
||||
SpeedZ = 0;
|
||||
|
||||
if (SpeedX >= 0)
|
||||
{
|
||||
if (SpeedX <= MAX_SPEED)
|
||||
{
|
||||
SpeedX = SpeedX + 0.5;
|
||||
SpeedY = (0 - SpeedX);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeedX = MAX_SPEED;
|
||||
SpeedY = (0 - SpeedX);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeedX = SpeedX + 0.4;
|
||||
SpeedY = (0 - SpeedX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_ASCEND_XP: // ASCEND WEST
|
||||
{
|
||||
SetRotation(180);
|
||||
SetPosY(floor(GetPosY()) + 0.2);
|
||||
SpeedZ = 0;
|
||||
|
||||
if (SpeedX > 0)
|
||||
{
|
||||
SpeedX = SpeedX - 0.4;
|
||||
SpeedY = SpeedX;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SpeedX >= MAX_SPEED_NEGATIVE)
|
||||
{
|
||||
SpeedX = SpeedX - 0.5;
|
||||
SpeedY = SpeedX;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeedX = MAX_SPEED_NEGATIVE;
|
||||
SpeedY = SpeedX;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_CURVED_ZM_XM: // Ends pointing NORTH and WEST
|
||||
{
|
||||
SetRotation(315); // Set correct rotation server side
|
||||
SetPosY(floor(GetPosY()) + 0.2); // Levitate dat cart
|
||||
|
||||
if (SpeedZ > 0) // Cart moving south
|
||||
{
|
||||
SpeedX = (0 - SpeedZ); // Diagonally move southwest (which will make cart hit a southwest rail)
|
||||
}
|
||||
else if (SpeedX > 0) // Cart moving east
|
||||
{
|
||||
SpeedZ = (0 - SpeedX); // Diagonally move northeast
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_CURVED_ZM_XP: // Curved NORTH EAST
|
||||
{
|
||||
SetRotation(225);
|
||||
SetPosY(floor(GetPosY()) + 0.2);
|
||||
|
||||
if (SpeedZ > 0)
|
||||
{
|
||||
SpeedX = SpeedZ;
|
||||
}
|
||||
else if (SpeedX < 0)
|
||||
{
|
||||
SpeedZ = SpeedX;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST
|
||||
{
|
||||
SetRotation(135);
|
||||
SetPosY(floor(GetPosY()) + 0.2);
|
||||
|
||||
if (SpeedZ < 0)
|
||||
{
|
||||
SpeedX = SpeedZ;
|
||||
}
|
||||
else if (SpeedX > 0)
|
||||
{
|
||||
SpeedZ = SpeedX;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_META_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST
|
||||
{
|
||||
SetRotation(45);
|
||||
SetPosY(floor(GetPosY()) + 0.2);
|
||||
|
||||
if (SpeedZ < 0)
|
||||
{
|
||||
SpeedX = (0 - SpeedZ);
|
||||
}
|
||||
else if (SpeedX < 0)
|
||||
{
|
||||
SpeedZ = (0 - SpeedX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unhandled rail meta!"); // Dun dun DUN!
|
||||
SetSpeedX(0);
|
||||
SetPosX(floor(GetPosX()) + 0.5);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Set speed to speed variables
|
||||
SetSpeedX(SpeedX);
|
||||
SetSpeedY(SpeedY);
|
||||
SetSpeedZ(SpeedZ);
|
||||
}
|
||||
|
||||
|
||||
// Broadcast position to client
|
||||
BroadcastMovementUpdate();
|
||||
|
||||
|
||||
|
||||
bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
||||
{
|
||||
switch (a_RailMeta)
|
||||
{
|
||||
case E_META_RAIL_ZM_ZP:
|
||||
{
|
||||
if (GetSpeedZ() > 0)
|
||||
{
|
||||
BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)ceil(GetPosZ()));
|
||||
if (!IsBlockRail(Block) && g_BlockIsSolid[Block])
|
||||
{
|
||||
// We could try to detect a block in front based purely on coordinates, but xoft made a bounding box system - why not use? :P
|
||||
cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()), (int)floor(GetPosY()), (int)ceil(GetPosZ())), 0.5, 1);
|
||||
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
|
||||
|
||||
if (bbBlock.DoesIntersect(bbMinecart))
|
||||
{
|
||||
SetSpeed(0, 0, 0);
|
||||
SetPosZ(floor(GetPosZ()) + 0.4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) - 1);
|
||||
if (!IsBlockRail(Block) && g_BlockIsSolid[Block])
|
||||
{
|
||||
cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) - 1), 0.5, 1);
|
||||
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ() - 1), GetWidth() / 2, GetHeight());
|
||||
|
||||
if (bbBlock.DoesIntersect(bbMinecart))
|
||||
{
|
||||
SetSpeed(0, 0, 0);
|
||||
SetPosZ(floor(GetPosZ()) + 0.65);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_XM_XP:
|
||||
{
|
||||
if (GetSpeedX() > 0)
|
||||
{
|
||||
BLOCKTYPE Block = m_World->GetBlock((int)ceil(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()));
|
||||
if (!IsBlockRail(Block) && g_BlockIsSolid[Block])
|
||||
{
|
||||
cBoundingBox bbBlock(Vector3d((int)ceil(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())), 0.5, 1);
|
||||
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
|
||||
|
||||
if (bbBlock.DoesIntersect(bbMinecart))
|
||||
{
|
||||
SetSpeed(0, 0, 0);
|
||||
SetPosX(floor(GetPosX()) + 0.4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ()));
|
||||
if (!IsBlockRail(Block) && g_BlockIsSolid[Block])
|
||||
{
|
||||
cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ())), 0.5, 1);
|
||||
cBoundingBox bbMinecart(Vector3d(GetPosX() - 1, floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
|
||||
|
||||
if (bbBlock.DoesIntersect(bbMinecart))
|
||||
{
|
||||
SetSpeed(0, 0, 0);
|
||||
SetPosX(floor(GetPosX()) + 0.65);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_CURVED_ZM_XM:
|
||||
case E_META_RAIL_CURVED_ZM_XP:
|
||||
case E_META_RAIL_CURVED_ZP_XM:
|
||||
case E_META_RAIL_CURVED_ZP_XP:
|
||||
{
|
||||
BLOCKTYPE BlockXM = m_World->GetBlock((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ()));
|
||||
BLOCKTYPE BlockXP = m_World->GetBlock((int)floor(GetPosX()) + 1, (int)floor(GetPosY()), (int)floor(GetPosZ()));
|
||||
BLOCKTYPE BlockZM = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) + 1);
|
||||
BLOCKTYPE BlockZP = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) + 1);
|
||||
if (
|
||||
(!IsBlockRail(BlockXM) && g_BlockIsSolid[BlockXM]) ||
|
||||
(!IsBlockRail(BlockXP) && g_BlockIsSolid[BlockXP]) ||
|
||||
(!IsBlockRail(BlockZM) && g_BlockIsSolid[BlockZM]) ||
|
||||
(!IsBlockRail(BlockZP) && g_BlockIsSolid[BlockZP])
|
||||
)
|
||||
{
|
||||
SetSpeed(0, 0, 0);
|
||||
SetPosition((int)floor(GetPosX()) + 0.5, GetPosY(), (int)floor(GetPosZ()) + 0.5);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -358,6 +599,14 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
void cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
|
||||
{
|
||||
if (TDI.Attacker->IsPlayer() && ((cPlayer *)TDI.Attacker)->IsGameModeCreative())
|
||||
{
|
||||
Destroy();
|
||||
TDI.FinalDamage = GetMaxHealth(); // Instant hit for creative
|
||||
super::DoTakeDamage(TDI);
|
||||
return; // No drops for creative
|
||||
}
|
||||
|
||||
m_LastDamage = TDI.FinalDamage;
|
||||
super::DoTakeDamage(TDI);
|
||||
|
||||
@ -365,7 +614,7 @@ void cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
|
||||
|
||||
if (GetHealth() <= 0)
|
||||
{
|
||||
Destroy(true);
|
||||
Destroy();
|
||||
|
||||
cItems Drops;
|
||||
switch (m_Payload)
|
||||
@ -410,6 +659,18 @@ void cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
|
||||
|
||||
|
||||
|
||||
void cMinecart::Destroyed()
|
||||
{
|
||||
if (m_bIsOnDetectorRail)
|
||||
{
|
||||
m_World->SetBlock(m_DetectorRailPosition.x, m_DetectorRailPosition.y, m_DetectorRailPosition.z, E_BLOCK_DETECTOR_RAIL, m_World->GetBlockMeta(m_DetectorRailPosition) & 0x07);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cEmptyMinecart:
|
||||
|
||||
|
@ -51,17 +51,38 @@ public:
|
||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||
virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void DoTakeDamage(TakeDamageInfo & TDI) override;
|
||||
virtual void Destroyed() override;
|
||||
|
||||
int LastDamage(void) const { return m_LastDamage; }
|
||||
void HandleRailPhysics(float a_Dt, cChunk & a_Chunk);
|
||||
ePayload GetPayload(void) const { return m_Payload; }
|
||||
|
||||
protected:
|
||||
ePayload m_Payload;
|
||||
int m_LastDamage;
|
||||
Vector3i m_DetectorRailPosition;
|
||||
bool m_bIsOnDetectorRail;
|
||||
|
||||
cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z);
|
||||
|
||||
int m_LastDamage;
|
||||
/** Handles physics on normal rails
|
||||
For each tick, slow down on flat rails, speed up or slow down on ascending/descending rails (depending on direction), and turn on curved rails
|
||||
*/
|
||||
void HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt);
|
||||
|
||||
/** Handles powered rail physics
|
||||
Each tick, speed up or slow down cart, depending on metadata of rail (powered or not)
|
||||
*/
|
||||
void HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta);
|
||||
|
||||
/** Handles detector rail activation
|
||||
Activates detector rails when a minecart is on them. Calls HandleRailPhysics() for physics simulations
|
||||
*/
|
||||
void HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt);
|
||||
|
||||
/** Snaps a minecart to a rail's axis, resetting its speed */
|
||||
void SnapToRail(NIBBLETYPE a_RailMeta);
|
||||
/** Tests is a solid block is in front of a cart, and stops the cart (and returns true) if so; returns false if no obstruction*/
|
||||
bool TestBlockCollision(NIBBLETYPE a_RailMeta);
|
||||
|
||||
} ;
|
||||
|
||||
|
@ -1884,3 +1884,33 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::Detach()
|
||||
{
|
||||
super::Detach();
|
||||
int PosX = (int)floor(GetPosX());
|
||||
int PosY = (int)floor(GetPosY());
|
||||
int PosZ = (int)floor(GetPosZ());
|
||||
|
||||
// Search for a position within an area to teleport player after detachment
|
||||
// Position must be solid land, and occupied by a nonsolid block
|
||||
// If nothing found, player remains where they are
|
||||
for (int x = PosX - 2; x <= (PosX + 2); ++x)
|
||||
{
|
||||
for (int y = PosY; y <= (PosY + 3); ++y)
|
||||
{
|
||||
for (int z = PosZ - 2; z <= (PosZ + 2); ++z)
|
||||
{
|
||||
if (!g_BlockIsSolid[m_World->GetBlock(x, y, z)] && g_BlockIsSolid[m_World->GetBlock(x, y - 1, z)])
|
||||
{
|
||||
TeleportToCoords(x, y, z);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -350,6 +350,8 @@ public:
|
||||
virtual bool IsCrouched (void) const { return m_IsCrouched; }
|
||||
virtual bool IsSprinting(void) const { return m_IsSprinting; }
|
||||
virtual bool IsRclking (void) const { return IsEating(); }
|
||||
|
||||
virtual void Detach(void);
|
||||
|
||||
protected:
|
||||
typedef std::map< std::string, bool > PermissionMap;
|
||||
|
@ -69,7 +69,7 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu
|
||||
// Changeable sources
|
||||
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
|
||||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
||||
((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0x08) ||
|
||||
((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0) ||
|
||||
(((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) ||
|
||||
(((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0))
|
||||
)
|
||||
@ -505,8 +505,7 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
|
||||
// transferring power to other wires around.
|
||||
// However, self not directly powered anymore, so source must have been removed,
|
||||
// therefore, self must be set to meta zero
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, 0); // SetMeta & WakeUpSims doesn't seem to work here, so SetBlock
|
||||
return; // No need to process block power sets because self not powered
|
||||
}
|
||||
else
|
||||
@ -903,6 +902,7 @@ void cRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_BlockY, int a_B
|
||||
else
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0x0);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -965,6 +965,7 @@ void cRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_BlockY, int a_B
|
||||
else
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0x0);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user