From b083979cb20ef3726c59a4d4dc9048e848e7827f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 19 Dec 2013 15:57:15 +0000 Subject: Fixed repeaters not updating power --- src/Simulator/RedstoneSimulator.cpp | 52 +++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index eb26d0ca3..92aeda29a 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -186,8 +186,32 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c } else { - ++itr; + itr++; + } + } + + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end();) + { + int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width; + int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width; + + BLOCKTYPE SourceBlockType; + if (!a_Chunk->UnboundedRelGetBlockType(RelX, itr->a_BlockPos.y, RelZ, SourceBlockType)) + { + continue; + } + + if ((SourceBlockType != E_BLOCK_REDSTONE_REPEATER_ON) && (SourceBlockType != E_BLOCK_REDSTONE_REPEATER_OFF)) + { + itr = m_RepeatersDelayList.erase(itr); + continue; + } + else if (itr->a_ElapsedTicks < itr->a_DelayTicks) + { + itr->a_ElapsedTicks++; } + + itr++; } for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;) @@ -564,9 +588,8 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int { NIBBLETYPE a_Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - // We do this so that the repeater can continually update block power status (without being affected by it's own block type, which would happen if the block powering code was in an IF statement) - bool IsOn = ((a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) ? true : false); - bool IsSelfPowered = IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3); + bool IsOn = ((a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) ? true : false); // Cache if repeater is on + bool IsSelfPowered = IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3); // Cache if repeater is pwoered if (IsSelfPowered && !IsOn) // Queue a power change if I am receiving power but not on { @@ -618,21 +641,19 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int } } - m_RepeatersDelayList.erase(itr); + // Removal of the data entry will be handled in SimChunk - we still want to continue trying to power blocks, even if our delay time has reached + // Otherwise, the power state of blocks in front won't update after we have powered on return; } else { m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); - m_RepeatersDelayList.erase(itr); + m_RepeatersDelayList.erase(itr); // We can remove off repeaters which don't need further updating return; } } - else - { - itr->a_ElapsedTicks++; - return; - } + + // Tick incrementing handled in SimChunk } } @@ -1271,6 +1292,15 @@ void cRedstoneSimulator::QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, in { if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { + if (ShouldPowerOn == itr->ShouldPowerOn) // We are queued already for the same thing, don't replace entry + { + return; + } + + // Already in here (normal to allow repeater to continue on powering and updating blocks in front) - just update info and quit + itr->a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; + itr->a_ElapsedTicks = 0; + itr->ShouldPowerOn = ShouldPowerOn; return; } } -- cgit v1.2.3 From 53ff372624e31028e61cdf72a82945fe935bb420 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 19 Dec 2013 15:57:35 +0000 Subject: Fixed dust from being placed on nonsolids --- src/Blocks/BlockRedstone.h | 2 +- src/Items/ItemRedstoneDust.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index 57bd91b46..1bd9995f2 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -20,7 +20,7 @@ public: virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]); + return ((a_RelY > 0) && g_BlockIsTorchPlaceable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]); } diff --git a/src/Items/ItemRedstoneDust.h b/src/Items/ItemRedstoneDust.h index b7860b187..38bf00ba6 100644 --- a/src/Items/ItemRedstoneDust.h +++ b/src/Items/ItemRedstoneDust.h @@ -27,6 +27,11 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { + if (!g_BlockIsTorchPlaceable[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) // Some solid blocks, such as cocoa beans, are not suitable for dust + { + return false; + } + a_BlockType = E_BLOCK_REDSTONE_WIRE; a_BlockMeta = 0; return true; -- cgit v1.2.3 From 53e8c067eabb7eb024c84bf0e2af9c81d30f2acd Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 19 Dec 2013 16:03:43 +0000 Subject: Fixed 1.7 arm swing animation --- src/ClientHandle.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 9565fc41f..de0a57a0a 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1065,7 +1065,29 @@ void cClientHandle::HandleAnimation(char a_Animation) // Plugin disagrees, bail out return; } - + + // Because the animation ID sent to servers by clients are different to those sent back, we need this + switch (a_Animation) + { + case 0: // No animation - wiki.vg doesn't say that client has something specific for it, so I suppose it will just become -1 + case 1: + case 2: + case 3: + { + a_Animation--; // Offset by -1 + break; + } + case 5: + case 6: + case 7: + { + a_Animation -= 2; // Offset by -2 + break; + } + default: // Anything else is the same + break; + } + m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, a_Animation, this); } -- cgit v1.2.3 From 03a8dfc4a8daf2ef3ea63b1fdf161018acbe12ce Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 19 Dec 2013 20:53:47 +0000 Subject: Fixed PlayerAbilities and creative --- src/ClientHandle.cpp | 6 +++--- src/Entities/Player.cpp | 18 ++++++++++++++++++ src/Protocol/Protocol17x.cpp | 13 +++---------- 3 files changed, 24 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index de0a57a0a..1e63e2ba1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -264,9 +264,6 @@ void cClientHandle::Authenticate(void) // Send experience m_Player->SendExperience(); - // Send gamemode (1.6.1 movementSpeed): - SendGameMode(m_Player->GetGameMode()); - m_Player->Initialize(World); m_State = csAuthenticated; @@ -489,6 +486,9 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel void cClientHandle::HandlePlayerAbilities(bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed) { + UNUSED(FlyingSpeed); // Ignore the client values for these + UNUSED(WalkingSpeed); + m_Player->SetCanFly(a_CanFly); m_Player->SetFlying(a_IsFlying); } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 7e7d77433..bb19bcce9 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1500,6 +1500,24 @@ bool cPlayer::LoadFromDisk() //SetExperience(root.get("experience", 0).asInt()); m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt(); + + if (m_GameMode == eGameMode_Creative) + { + m_CanFly = true; + } + else if (m_GameMode == eGameMode_NotSet) + { + cWorld * World = cRoot::Get()->GetWorld(GetLoadedWorldName()); + if (World == NULL) + { + World = cRoot::Get()->GetDefaultWorld(); + } + + if (World->GetGameMode() == eGameMode_Creative) + { + m_CanFly = true; + } + } m_Inventory.LoadFromJson(root["inventory"]); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index fff5311f6..161e81936 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -490,6 +490,7 @@ void cProtocol172::SendPlayerAbilities(void) if (m_Client->GetPlayer()->IsGameModeCreative()) { Flags |= 0x01; + Flags |= 0x08; // Godmode, used for creative } if (m_Client->GetPlayer()->IsFlying()) { @@ -499,7 +500,6 @@ void cProtocol172::SendPlayerAbilities(void) { Flags |= 0x04; } - // TODO: Other flags (god mode) Pkt.WriteByte(Flags); // TODO: Pkt.WriteFloat(m_Client->GetPlayer()->GetMaxFlyingSpeed()); Pkt.WriteFloat(0.05f); @@ -1291,23 +1291,16 @@ void cProtocol172::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed); - bool IsFlying, CanFly; + bool IsFlying = false, CanFly = false; if ((Flags & 2) != 0) { IsFlying = true; } - else - { - IsFlying = false; - } if ((Flags & 4) != 0) { CanFly = true; } - else - { - CanFly = false; - } + m_Client->HandlePlayerAbilities(CanFly, IsFlying, FlyingSpeed, WalkingSpeed); } -- cgit v1.2.3