diff --git a/zone/client.cpp b/zone/client.cpp index 17e730008..62b27ba4f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -10488,25 +10488,41 @@ void Client::MovePCDynamicZone(const std::string& zone_name, int zone_version, b MovePCDynamicZone(zone_id, zone_version, msg_if_invalid); } -void Client::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clipping) { +void Client::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls, bool calculate_speed) { BuffFadeByEffect(SE_Levitate); if (CheckLosFN(target_x, target_y, target_z, 6.0f) || ignore_los) { - auto outapp_fling = new EQApplicationPacket(OP_Fling, sizeof(fling_struct)); - fling_struct* flingTo = (fling_struct*)outapp_fling->pBuffer; - if(clipping) - flingTo->collision = 0; - else - flingTo->collision = -1; + auto p = new EQApplicationPacket(OP_Fling, sizeof(fling_struct)); + auto* f = (fling_struct*) p->pBuffer; - flingTo->travel_time = -1; - flingTo->unk3 = 1; - flingTo->disable_fall_damage = 1; - flingTo->speed_z = value; - flingTo->new_y = target_y; - flingTo->new_x = target_x; - flingTo->new_z = target_z; - outapp_fling->priority = 6; - FastQueuePacket(&outapp_fling); + if (!calculate_speed) { + f->speed_z = value; + } else { + auto speed = 1.0f; + const auto distance = CalculateDistance(target_x, target_y, target_z); + + auto z_diff = target_z - GetZ(); + if (z_diff != 0.0f) { + speed += std::abs(z_diff) / 12.0f; + } + + speed += distance / 200.0f; + + speed++; + + speed = std::abs(speed); + + f->speed_z = speed; + } + + f->collision = clip_through_walls ? 0 : -1; + f->travel_time = -1; + f->unk3 = 1; + f->disable_fall_damage = 1; + f->new_y = target_y; + f->new_x = target_x; + f->new_z = target_z; + p->priority = 6; + FastQueuePacket(&p); } } diff --git a/zone/client.h b/zone/client.h index b82af9bfd..f2c68238c 100644 --- a/zone/client.h +++ b/zone/client.h @@ -836,7 +836,7 @@ public: uint8 GetCharMaxLevelFromQGlobal(); uint8 GetCharMaxLevelFromBucket(); - void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los = false, bool clipping = false); + void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los = false, bool clip_through_walls = false, bool calculate_speed = false); inline bool IsStanding() const {return (playeraction == 0);} inline bool IsSitting() const {return (playeraction == 1);} diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 5e525cabd..7590e54d9 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -2103,6 +2103,21 @@ void Lua_Client::CreateTaskDynamicZone(int task_id, luabind::object dz_table) { self->CreateTaskDynamicZone(task_id, dz); } +void Lua_Client::Fling(float target_x, float target_y, float target_z) { + Lua_Safe_Call_Void(); + self->Fling(0, target_x, target_y, target_z, false, false, true); +} + +void Lua_Client::Fling(float target_x, float target_y, float target_z, bool ignore_los) { + Lua_Safe_Call_Void(); + self->Fling(0, target_x, target_y, target_z, ignore_los, false, true); +} + +void Lua_Client::Fling(float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) { + Lua_Safe_Call_Void(); + self->Fling(0, target_x, target_y, target_z, ignore_los, clip_through_walls, true); +} + void Lua_Client::Fling(float value, float target_x, float target_y, float target_z) { Lua_Safe_Call_Void(); self->Fling(value, target_x, target_y, target_z); @@ -2113,9 +2128,9 @@ void Lua_Client::Fling(float value, float target_x, float target_y, float target self->Fling(value, target_x, target_y, target_z, ignore_los); } -void Lua_Client::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clipping) { +void Lua_Client::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) { Lua_Safe_Call_Void(); - self->Fling(value, target_x, target_y, target_z, ignore_los, clipping); + self->Fling(value, target_x, target_y, target_z, ignore_los, clip_through_walls); } double Lua_Client::GetAAEXPModifier(uint32 zone_id) { @@ -3049,6 +3064,9 @@ luabind::scope lua_register_client() { .def("FindMemmedSpellBySlot", (uint16(Lua_Client::*)(int))&Lua_Client::FindMemmedSpellBySlot) .def("FindMemmedSpellBySpellID", (int(Lua_Client::*)(uint16))&Lua_Client::FindMemmedSpellBySpellID) .def("FindSpellBookSlotBySpellID", (int(Lua_Client::*)(int))&Lua_Client::FindSpellBookSlotBySpellID) + .def("Fling", (void(Lua_Client::*)(float,float,float))&Lua_Client::Fling) + .def("Fling", (void(Lua_Client::*)(float,float,float,bool))&Lua_Client::Fling) + .def("Fling", (void(Lua_Client::*)(float,float,float,bool,bool))&Lua_Client::Fling) .def("Fling", (void(Lua_Client::*)(float,float,float,float))&Lua_Client::Fling) .def("Fling", (void(Lua_Client::*)(float,float,float,float,bool))&Lua_Client::Fling) .def("Fling", (void(Lua_Client::*)(float,float,float,float,bool,bool))&Lua_Client::Fling) diff --git a/zone/lua_client.h b/zone/lua_client.h index d34213a2d..105b405bd 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -557,9 +557,12 @@ public: void MovePCDynamicZone(std::string zone_name, int zone_version); void MovePCDynamicZone(std::string zone_name, int zone_version, bool msg_if_invalid); void CreateTaskDynamicZone(int task_id, luabind::object dz_table); + void Fling(float target_x, float target_y, float target_z); + void Fling(float target_x, float target_y, float target_z, bool ignore_los); + void Fling(float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls); void Fling(float value, float target_x, float target_y, float target_z); void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los); - void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clipping); + void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls); }; #endif diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index c518f4cbb..44df9f09c 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1931,6 +1931,21 @@ void Perl_Client_MovePCDynamicZone(Client* self, perl::scalar zone, int zone_ver self->MovePCDynamicZone(zone_id, zone_version, msg_if_invalid); } +void Perl_Client_Fling(Client* self, float target_x, float target_y, float target_z) +{ + self->Fling(0, target_x, target_y, target_z, false, false, true); +} + +void Perl_Client_Fling(Client* self, float target_x, float target_y, float target_z, bool ignore_los) +{ + self->Fling(0, target_x, target_y, target_z, ignore_los, false, true); +} + +void Perl_Client_Fling(Client* self, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) +{ + self->Fling(0, target_x, target_y, target_z, ignore_los, clip_through_walls, true); +} + void Perl_Client_Fling(Client* self, float value, float target_x, float target_y, float target_z) { self->Fling(value, target_x, target_y, target_z); @@ -1941,9 +1956,9 @@ void Perl_Client_Fling(Client* self, float value, float target_x, float target_y self->Fling(value, target_x, target_y, target_z, ignore_los); } -void Perl_Client_Fling(Client* self, float value, float target_x, float target_y, float target_z, bool ignore_los, bool clipping) +void Perl_Client_Fling(Client* self, float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) { - self->Fling(value, target_x, target_y, target_z, ignore_los, clipping); + self->Fling(value, target_x, target_y, target_z, ignore_los, clip_through_walls); } bool Perl_Client_HasDisciplineLearned(Client* self, uint16 spell_id) @@ -2914,6 +2929,9 @@ void perl_register_client() package.add("FindEmptyMemSlot", &Perl_Client_FindEmptyMemSlot); package.add("FindMemmedSpellBySlot", &Perl_Client_FindMemmedSpellBySlot); package.add("FindMemmedSpellBySpellID", &Perl_Client_FindMemmedSpellBySpellID); + package.add("Fling", (void(*)(Client*, float, float, float))&Perl_Client_Fling); + package.add("Fling", (void(*)(Client*, float, float, float, bool))&Perl_Client_Fling); + package.add("Fling", (void(*)(Client*, float, float, float, bool, bool))&Perl_Client_Fling); package.add("Fling", (void(*)(Client*, float, float, float, float))&Perl_Client_Fling); package.add("Fling", (void(*)(Client*, float, float, float, float, bool))&Perl_Client_Fling); package.add("Fling", (void(*)(Client*, float, float, float, float, bool, bool))&Perl_Client_Fling);