diff --git a/ClassicalSharp/Entities/LocalPlayer.cs b/ClassicalSharp/Entities/LocalPlayer.cs index 11b873585..e20816b56 100644 --- a/ClassicalSharp/Entities/LocalPlayer.cs +++ b/ClassicalSharp/Entities/LocalPlayer.cs @@ -29,6 +29,7 @@ namespace ClassicalSharp.Entities { internal SoundComponent sound; internal LocalInterpComponent interp; internal TiltComponent tilt; + bool warnedRespawn, warnedFly, warnedNoclip; public LocalPlayer(Game game) : base(game) { DisplayName = game.Username; @@ -39,7 +40,7 @@ namespace ClassicalSharp.Entities { physics = new PhysicsComponent(game, this); sound = new SoundComponent(game, this); interp = new LocalInterpComponent(game, this); - tilt = new TiltComponent(game); + tilt = new TiltComponent(game); physics.hacks = Hacks; physics.collisions = collisions; } @@ -141,10 +142,10 @@ namespace ClassicalSharp.Entities { Hacks.SpeedMultiplier = Options.GetFloat(OptionsKey.Speed, 0.1f, 50, 10); Hacks.PushbackPlacing = Options.GetBool(OptionsKey.PushbackPlacing, false); Hacks.NoclipSlide = Options.GetBool(OptionsKey.NoclipSlide, false); - Hacks.WOMStyleHacks = Options.GetBool(OptionsKey.WOMStyleHacks, false); - Hacks.FullBlockStep = Options.GetBool(OptionsKey.FullBlockStep, false); + Hacks.WOMStyleHacks = Options.GetBool(OptionsKey.WOMStyleHacks, false); + Hacks.FullBlockStep = Options.GetBool(OptionsKey.FullBlockStep, false); physics.userJumpVel = Options.GetFloat(OptionsKey.JumpVelocity, 0.0f, 52.0f, 0.42f); - physics.jumpVel = physics.userJumpVel; + physics.jumpVel = physics.userJumpVel; } void IGameComponent.Ready(Game game) { } @@ -154,6 +155,9 @@ namespace ClassicalSharp.Entities { void IGameComponent.OnNewMap(Game game) { Velocity = Vector3.Zero; OldVelocity = Vector3.Zero; + warnedRespawn = false; + warnedFly = false; + warnedNoclip = false; } void IGameComponent.Reset(Game game) { @@ -166,7 +170,7 @@ namespace ClassicalSharp.Entities { static Predicate touchesAnySolid = IsSolidCollide; - static bool IsSolidCollide(BlockID b) { return BlockInfo.Collide[b] == CollideType.Solid; } + static bool IsSolidCollide(BlockID b) { return BlockInfo.Collide[b] == CollideType.Solid; } void DoRespawn() { if (!game.World.HasBlocks) return; Vector3 spawn = Spawn; @@ -199,21 +203,55 @@ namespace ClassicalSharp.Entities { onGround = TouchesAny(bb, touchesAnySolid); } - public bool HandlesKey(Key key) { - if (key == game.Mapping(KeyBind.Respawn) && Hacks.CanRespawn) { + void HandleRespawn() { + if (Hacks.CanRespawn) { DoRespawn(); - } else if (key == game.Mapping(KeyBind.SetSpawn) && Hacks.CanRespawn) { - Spawn = Position; - Spawn.X = Utils.Floor(Spawn.X) + 0.5f; - Spawn.Z = Utils.Floor(Spawn.Z) + 0.5f; + } else if (!warnedRespawn) { + warnedRespawn = true; + game.Chat.Add("&cRespawning is disabled in this map"); + } + } + + void HandleSetSpawn() { + if (Hacks.CanRespawn) { + Spawn.X = Utils.Floor(Position.X) + 0.5f; + Spawn.Y = Position.Y; + Spawn.Z = Utils.Floor(Position.Z) + 0.5f; SpawnRotY = RotY; SpawnHeadX = HeadX; - DoRespawn(); - } else if (key == game.Mapping(KeyBind.Fly) && Hacks.CanFly && Hacks.Enabled) { + } + HandleRespawn(); + } + + void HandleFly() { + if (Hacks.CanFly && Hacks.Enabled) { Hacks.Flying = !Hacks.Flying; - } else if (key == game.Mapping(KeyBind.NoClip) && Hacks.CanNoclip && Hacks.Enabled && !Hacks.WOMStyleHacks) { + } else if (!warnedFly) { + warnedFly = true; + game.Chat.Add("&cFlying is disabled in this map"); + } + } + + void HandleNoClip() { + if (Hacks.CanNoclip && Hacks.Enabled) { + if (Hacks.WOMStyleHacks) return; // don't handle this here if (Hacks.Noclip) Velocity.Y = 0; Hacks.Noclip = !Hacks.Noclip; + } else if (!warnedNoclip) { + warnedNoclip = true; + game.Chat.Add("&cNoclip is disabled in this map"); + } + } + + public bool HandlesKey(Key key) { + if (key == game.Mapping(KeyBind.Respawn)) { + HandleRespawn(); + } else if (key == game.Mapping(KeyBind.SetSpawn)) { + HandleSetSpawn(); + } else if (key == game.Mapping(KeyBind.Fly)) { + HandleFly(); + } else if (key == game.Mapping(KeyBind.NoClip)) { + HandleNoClip(); } else if (key == game.Mapping(KeyBind.Jump) && !onGround && !(Hacks.Flying || Hacks.Noclip)) { int maxJumps = Hacks.CanDoubleJump && Hacks.WOMStyleHacks ? 2 : 0; maxJumps = Math.Max(maxJumps, Hacks.MaxJumps - 1); diff --git a/src/Entity.c b/src/Entity.c index b5d20401d..43ca1dbad 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -875,9 +875,14 @@ static void LocalPlayer_Reset(void) { } static void LocalPlayer_OnNewMap(void) { + struct LocalPlayer* p = &LocalPlayer_Instance; Vector3 zero = Vector3_Zero; - LocalPlayer_Instance.Base.Velocity = zero; - LocalPlayer_Instance.OldVelocity = zero; + p->Base.Velocity = zero; + p->OldVelocity = zero; + + p->_WarnedRespawn = false; + p->_WarnedFly = false; + p->_WarnedNoclip = false; } void LocalPlayer_MakeComponent(struct IGameComponent* comp) { @@ -941,25 +946,63 @@ static void LocalPlayer_DoRespawn(void) { p->Base.OnGround = Entity_TouchesAny(&bb, LocalPlayer_IsSolidCollide); } +static void LocalPlayer_HandleRespawn(void) { + struct LocalPlayer* p = &LocalPlayer_Instance; + if (p->Hacks.CanRespawn) { + LocalPlayer_DoRespawn(); + } else if (!p->_WarnedRespawn) { + p->_WarnedRespawn = true; + Chat_AddRaw("&cRespawning is disabled in this map"); + } +} + +static void LocalPlayer_HandleSetSpawn(void) { + struct LocalPlayer* p = &LocalPlayer_Instance; + if (p->Hacks.CanRespawn) { + p->Spawn.X = Math_Floor(p->Base.Position.X) + 0.5f; + p->Spawn.Y = p->Base.Position.Y; + p->Spawn.Z = Math_Floor(p->Base.Position.Z) + 0.5f; + p->SpawnRotY = p->Base.RotY; + p->SpawnHeadX = p->Base.HeadX; + } + LocalPlayer_HandleRespawn(); +} + +static void LocalPlayer_HandleFly(void) { + struct LocalPlayer* p = &LocalPlayer_Instance; + if (p->Hacks.CanFly && p->Hacks.Enabled) { + p->Hacks.Flying = !p->Hacks.Flying; + } else if(!p->_WarnedFly) { + p->_WarnedFly = true; + Chat_AddRaw("&cFlying is disabled in this map"); + } +} + +static void LocalPlayer_HandleNoClip(void) { + struct LocalPlayer* p = &LocalPlayer_Instance; + if (p->Hacks.CanNoclip && p->Hacks.Enabled) { + if (p->Hacks.WOMStyleHacks) return; /* don't handle this here */ + if (p->Hacks.Noclip) p->Base.Velocity.Y = 0; + p->Hacks.Noclip = !p->Hacks.Noclip; + } else if (!p->_WarnedNoclip) { + p->_WarnedNoclip = true; + Chat_AddRaw("&cNoclip is disabled in this map"); + } +} + bool LocalPlayer_HandlesKey(Int32 key) { struct LocalPlayer* p = &LocalPlayer_Instance; struct HacksComp* hacks = &p->Hacks; struct PhysicsComp* physics = &p->Physics; - if (key == KeyBind_Get(KeyBind_Respawn) && hacks->CanRespawn) { - LocalPlayer_DoRespawn(); - } else if (key == KeyBind_Get(KeyBind_SetSpawn) && hacks->CanRespawn) { - p->Spawn = p->Base.Position; - p->Spawn.X = Math_Floor(p->Spawn.X) + 0.5f; - p->Spawn.Z = Math_Floor(p->Spawn.Z) + 0.5f; - p->SpawnRotY = p->Base.RotY; - p->SpawnHeadX = p->Base.HeadX; - LocalPlayer_DoRespawn(); - } else if (key == KeyBind_Get(KeyBind_Fly) && hacks->CanFly && hacks->Enabled) { - hacks->Flying = !hacks->Flying; - } else if (key == KeyBind_Get(KeyBind_NoClip) && hacks->CanNoclip && hacks->Enabled && !hacks->WOMStyleHacks) { - if (hacks->Noclip) p->Base.Velocity.Y = 0; - hacks->Noclip = !hacks->Noclip; + if (key == KeyBind_Get(KeyBind_Respawn)) { + LocalPlayer_HandleRespawn(); + } else if (key == KeyBind_Get(KeyBind_SetSpawn)) { + LocalPlayer_HandleSetSpawn(); + } else if (key == KeyBind_Get(KeyBind_Fly)) { + LocalPlayer_HandleFly(); + } else if (key == KeyBind_Get(KeyBind_NoClip)) { + LocalPlayer_HandleNoClip(); } else if (key == KeyBind_Get(KeyBind_Jump) && !p->Base.OnGround && !(hacks->Flying || hacks->Noclip)) { Int32 maxJumps = hacks->CanDoubleJump && hacks->WOMStyleHacks ? 2 : 0; maxJumps = max(maxJumps, hacks->MaxJumps - 1); diff --git a/src/Entity.h b/src/Entity.h index 98ace2d9a..036252d56 100644 --- a/src/Entity.h +++ b/src/Entity.h @@ -153,6 +153,7 @@ struct LocalPlayer { struct InterpComp Interp; struct CollisionsComp Collisions; struct PhysicsComp Physics; + bool _WarnedRespawn, _WarnedFly, _WarnedNoclip; }; struct LocalPlayer LocalPlayer_Instance; diff --git a/src/Platform.c b/src/Platform.c index ff573cfcd..713fca09d 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -507,18 +507,12 @@ ReturnCode File_Length(void* file, UInt32* length) { *#########################################################################################################################*/ #if CC_BUILD_WIN void Thread_Sleep(UInt32 milliseconds) { Sleep(milliseconds); } -DWORD WINAPI Thread_StartCallback(LPVOID lpParam) { - Thread_StartFunc* func = (Thread_StartFunc*)lpParam; +DWORD WINAPI Thread_StartCallback(void* param) { + Thread_StartFunc* func = (Thread_StartFunc*)param; (*func)(); return 0; } -static void Thread_FreeHandle(void* handle) { - if (!CloseHandle((HANDLE)handle)) { - ErrorHandler_Fail2(GetLastError(), "Freeing thread handle"); - } -} - void* Thread_Start(Thread_StartFunc* func, bool detach) { DWORD threadID; void* handle = CreateThread(NULL, 0, Thread_StartCallback, func, 0, &threadID); @@ -526,13 +520,19 @@ void* Thread_Start(Thread_StartFunc* func, bool detach) { ErrorHandler_Fail2(GetLastError(), "Creating thread"); } - if (detach) Thread_FreeHandle(handle); + if (detach) Thread_Detach(handle); return handle; } +void Thread_Detach(void* handle) { + if (!CloseHandle((HANDLE)handle)) { + ErrorHandler_Fail2(GetLastError(), "Freeing thread handle"); + } +} + void Thread_Join(void* handle) { WaitForSingleObject((HANDLE)handle, INFINITE); - Thread_FreeHandle(handle); + Thread_Detach(handle); } CRITICAL_SECTION mutexList[3]; Int32 mutexIndex; @@ -584,15 +584,19 @@ void* Thread_Start(Thread_StartFunc* func, bool detach) { int result = pthread_create(ptr, NULL, Thread_StartCallback, func); ErrorHandler_CheckOrFail(result, "Creating thread"); - if (detach) { - result = pthread_detach(*ptr); - ErrorHandler_CheckOrFail(result, "Detaching thread"); - } + if (detach) Thread_Detach(ptr); threadIndex++; return ptr; } +void Thread_Detach(void* handle) { + pthread_t* ptr = handle; + int result = pthread_detach(*ptr); + ErrorHandler_CheckOrFail(result, "Detaching thread"); +} + void Thread_Join(void* handle) { - int result = pthread_join(*((pthread_t*)handle), NULL); + pthread_t* ptr = handle; + int result = pthread_join(*ptr, NULL); ErrorHandler_CheckOrFail(result, "Joining thread"); } diff --git a/src/Platform.h b/src/Platform.h index 09b1f5d70..e3effeea8 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -72,6 +72,7 @@ ReturnCode File_Length(void* file, UInt32* length); void Thread_Sleep(UInt32 milliseconds); typedef void Thread_StartFunc(void); void* Thread_Start(Thread_StartFunc* func, bool detach); +void Thread_Detach(void* handle); void Thread_Join(void* handle); void* Mutex_Create(void);