mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
[Features] Appearance Effects will now be sent to clients upon zone in. GM commands. (#1874)
* start * working * Update perl_mob.cpp * updates * Update perl_mob.cpp * illusion behavior * rework start * fix later * Update mob.cpp * rework * updates * Update mob.cpp * update * gm command updates * updates * Update CMakeLists.txt * [Features] Appearance Effects will now be sent to clients upon zone in. GM commands. remove debugs * [Features] Appearance Effects will now be sent to clients upon zone in. GM commands. perl fix * [Features] Appearance Effects will now be sent to clients upon zone in. GM commands. space fix * [Features] Appearance Effects will now be sent to clients upon zone in. GM commands. minor fix * Update CMakeLists.txt * [Features] Appearance Effects will now be sent to clients upon zone in. GM commands. cleaned up some inconsistency * [Features] Appearance Effects will now be sent to clients upon zone in. GM commands.
This commit is contained in:
parent
550485ba33
commit
8de410ebb7
@ -188,7 +188,7 @@
|
||||
#define MAX_SYMPATHETIC_PROCS 10 // Number of sympathetic procs a client can have (This is arbitrary)
|
||||
#define MAX_FOCUS_PROC_LIMIT_TIMERS 20 //Number of focus recast timers that can be going at same time (This is arbitrary)
|
||||
#define MAX_PROC_LIMIT_TIMERS 8 //Number of proc delay timers that can be going at same time, different proc types get their own timer array. (This is arbitrary)
|
||||
|
||||
#define MAX_APPEARANCE_EFFECTS 20 //Up to 20 Appearance Effects can be saved to a mobs appearance effect array, these will be sent to other clients when they enter a zone (This is arbitrary)
|
||||
|
||||
|
||||
const int Z_AGGRO=10;
|
||||
|
||||
@ -294,6 +294,7 @@ SET(gm_commands
|
||||
gm_commands/aggrozone.cpp
|
||||
gm_commands/ai.cpp
|
||||
gm_commands/appearance.cpp
|
||||
gm_commands/appearanceeffects.cpp
|
||||
gm_commands/attack.cpp
|
||||
gm_commands/augmentitem.cpp
|
||||
gm_commands/ban.cpp
|
||||
|
||||
@ -745,6 +745,8 @@ void Client::CompleteConnect()
|
||||
|
||||
entity_list.SendUntargetable(this);
|
||||
|
||||
entity_list.SendAppearanceEffects(this);
|
||||
|
||||
int x;
|
||||
for (x = EQ::textures::textureBegin; x <= EQ::textures::LastTexture; x++) {
|
||||
SendWearChange(x);
|
||||
|
||||
@ -120,6 +120,7 @@ int command_init(void)
|
||||
command_add("aggrozone", "[aggro] - Aggro every mob in the zone with X aggro. Default is 0. Not recommend if you're not invulnerable.", AccountStatus::GMAdmin, command_aggrozone) ||
|
||||
command_add("ai", "[factionid/spellslist/con/guard/roambox/stop/start] - Modify AI on NPC target", AccountStatus::GMAdmin, command_ai) ||
|
||||
command_add("appearance", "[type] [value] - Send an appearance packet for you or your target", AccountStatus::GMLeadAdmin, command_appearance) ||
|
||||
command_add("appearanceeffects", "- [view] [set] [remove] appearance effects.", AccountStatus::GMAdmin, command_appearanceeffects) ||
|
||||
command_add("apply_shared_memory", "[shared_memory_name] - Tells every zone and world to apply a specific shared memory segment by name.", AccountStatus::GMImpossible, command_apply_shared_memory) ||
|
||||
command_add("attack", "[targetname] - Make your NPC target attack targetname", AccountStatus::GMLeadAdmin, command_attack) ||
|
||||
command_add("augmentitem", "Force augments an item. Must have the augment item window open.", AccountStatus::GMImpossible, command_augmentitem) ||
|
||||
|
||||
@ -34,6 +34,7 @@ void command_aggro(Client *c, const Seperator *sep);
|
||||
void command_aggrozone(Client *c, const Seperator *sep);
|
||||
void command_ai(Client *c, const Seperator *sep);
|
||||
void command_appearance(Client *c, const Seperator *sep);
|
||||
void command_appearanceeffects(Client *c, const Seperator *sep);
|
||||
void command_apply_shared_memory(Client *c, const Seperator *sep);
|
||||
void command_attack(Client *c, const Seperator *sep);
|
||||
void command_augmentitem(Client *c, const Seperator *sep);
|
||||
|
||||
@ -4582,6 +4582,26 @@ void EntityList::SendUntargetable(Client *c)
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::SendAppearanceEffects(Client *c)
|
||||
{
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
auto it = mob_list.begin();
|
||||
while (it != mob_list.end()) {
|
||||
Mob *cur = it->second;
|
||||
|
||||
if (cur) {
|
||||
if (cur == c) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
cur->SendSavedAppearenceEffects(c);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::ZoneWho(Client *c, Who_All_Struct *Who)
|
||||
{
|
||||
// This is only called for SoF clients, as regular /who is now handled server-side for that client.
|
||||
|
||||
@ -380,6 +380,7 @@ public:
|
||||
void SendZoneAppearance(Client *c);
|
||||
void SendNimbusEffects(Client *c);
|
||||
void SendUntargetable(Client *c);
|
||||
void SendAppearanceEffects(Client *c);
|
||||
void DuelMessage(Mob* winner, Mob* loser, bool flee);
|
||||
void QuestJournalledSayClose(Mob *sender, float dist, const char* mobname, const char* message, Journal::Options &opts);
|
||||
void GroupMessage(uint32 gid, const char *from, const char *message);
|
||||
|
||||
44
zone/gm_commands/appearanceeffects.cpp
Normal file
44
zone/gm_commands/appearanceeffects.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_appearanceeffects(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) {
|
||||
c->Message(Chat::White, "Syntax: #appearanceeffects [subcommand].");
|
||||
c->Message(Chat::White, "[view] Display all appearance effects saved to your target. #appearanceffects view");
|
||||
c->Message(Chat::White, "[set] Set an appearance effects saved to your target. #appearanceffects set [app_effectid] [slotid]");
|
||||
c->Message(Chat::White, "[remove] Remove all appearance effects saved to your target. #appearanceffects remove");
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "view")) {
|
||||
Mob* m_target = c->GetTarget();
|
||||
if (m_target) {
|
||||
m_target->GetAppearenceEffects();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "set")) {
|
||||
int32 app_effectid = atof(sep->arg[2]);
|
||||
int32 slot = atoi(sep->arg[3]);
|
||||
|
||||
Mob* m_target = c->GetTarget();
|
||||
if (m_target) {
|
||||
m_target->SendAppearanceEffect(app_effectid, 0, 0, 0, 0, nullptr, slot, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
c->Message(Chat::White, "Appearance Effect ID %i for slot %i has been set.", app_effectid, slot);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "remove")) {
|
||||
Mob* m_target = c->GetTarget();
|
||||
if (m_target) {
|
||||
m_target->SendIllusionPacket(m_target->GetRace(), m_target->GetGender(), m_target->GetTexture(), m_target->GetHelmTexture(),
|
||||
m_target->GetHairColor(), m_target->GetBeardColor(), m_target->GetEyeColor1(), m_target->GetEyeColor2(),
|
||||
m_target->GetHairStyle(), m_target->GetLuclinFace(), m_target->GetBeard(), 0xFF,
|
||||
m_target->GetDrakkinHeritage(), m_target->GetDrakkinTattoo(), m_target->GetDrakkinDetails(), m_target->GetSize(), false);
|
||||
m_target->ClearAppearenceEffects();
|
||||
c->Message(Chat::White, "All Appearance Effects have been removed.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
86
zone/mob.cpp
86
zone/mob.cpp
@ -480,6 +480,11 @@ Mob::Mob(
|
||||
Vulnerability_Mod[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_APPEARANCE_EFFECTS; i++) {
|
||||
appearance_effects_id[i] = 0;
|
||||
appearance_effects_slot[i] = 0;
|
||||
}
|
||||
|
||||
emoteid = 0;
|
||||
endur_upkeep = false;
|
||||
degenerating_effects = false;
|
||||
@ -2385,7 +2390,8 @@ void Mob::SendIllusionPacket(
|
||||
uint32 in_drakkin_heritage,
|
||||
uint32 in_drakkin_tattoo,
|
||||
uint32 in_drakkin_details,
|
||||
float in_size
|
||||
float in_size,
|
||||
bool send_appearance_effects
|
||||
)
|
||||
{
|
||||
uint8 new_texture = in_texture;
|
||||
@ -2494,6 +2500,10 @@ void Mob::SendIllusionPacket(
|
||||
/* Refresh armor and tints after send illusion packet */
|
||||
SendArmorAppearance();
|
||||
|
||||
if (send_appearance_effects) {
|
||||
SendSavedAppearenceEffects(nullptr);
|
||||
}
|
||||
|
||||
LogSpells(
|
||||
"Illusion: Race [{}] Gender [{}] Texture [{}] HelmTexture [{}] HairColor [{}] BeardColor [{}] EyeColor1 [{}] EyeColor2 [{}] HairStyle [{}] Face [{}] DrakkinHeritage [{}] DrakkinTattoo [{}] DrakkinDetails [{}] Size [{}]",
|
||||
race,
|
||||
@ -2869,7 +2879,7 @@ void Mob::SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32
|
||||
6 = right foot
|
||||
9 = Face
|
||||
|
||||
value#ground = 1, will place the effect on ground, of corresponding slot is set to 0 effect is permanenant, if > 0 will fade if mob death/despawn.
|
||||
value#ground = 1, will place the effect on ground, this is permanenant
|
||||
*/
|
||||
|
||||
//higher values can crash client
|
||||
@ -2892,6 +2902,22 @@ void Mob::SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32
|
||||
value5slot = 1;
|
||||
}
|
||||
|
||||
if (!value1ground && parm1) {
|
||||
SetAppearenceEffects(value1slot, parm1);
|
||||
}
|
||||
if (!value2ground && parm2) {
|
||||
SetAppearenceEffects(value2slot, parm2);
|
||||
}
|
||||
if (!value3ground && parm3) {
|
||||
SetAppearenceEffects(value3slot, parm3);
|
||||
}
|
||||
if (!value4ground && parm4) {
|
||||
SetAppearenceEffects(value4slot, parm4);
|
||||
}
|
||||
if (!value5ground && parm5) {
|
||||
SetAppearenceEffects(value5slot, parm5);
|
||||
}
|
||||
|
||||
LevelAppearance_Struct* la = (LevelAppearance_Struct*)outapp->pBuffer;
|
||||
la->spawn_id = GetID();
|
||||
la->parm1 = parm1;
|
||||
@ -2920,6 +2946,62 @@ void Mob::SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Mob::SetAppearenceEffects(int32 slot, int32 value)
|
||||
{
|
||||
for (int i = 0; i < MAX_APPEARANCE_EFFECTS; i++) {
|
||||
if (!appearance_effects_id[i]) {
|
||||
appearance_effects_id[i] = value;
|
||||
appearance_effects_slot[i] = slot;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::GetAppearenceEffects()
|
||||
{
|
||||
//used with GM command
|
||||
if (!appearance_effects_id[0]) {
|
||||
Message(Chat::Red, "No Appearance Effects exist on this mob");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_APPEARANCE_EFFECTS; i++) {
|
||||
Message(Chat::Red, "ID: %i :: App Effect ID %i :: Slot %i", i, appearance_effects_id[i], appearance_effects_slot[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::ClearAppearenceEffects()
|
||||
{
|
||||
for (int i = 0; i < MAX_APPEARANCE_EFFECTS; i++) {
|
||||
appearance_effects_id[i] = 0;
|
||||
appearance_effects_slot[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::SendSavedAppearenceEffects(Client *receiver = nullptr)
|
||||
{
|
||||
if (!appearance_effects_id[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (appearance_effects_id[0]) {
|
||||
SendAppearanceEffect(appearance_effects_id[0], appearance_effects_id[1], appearance_effects_id[2], appearance_effects_id[3], appearance_effects_id[4], receiver,
|
||||
appearance_effects_slot[0], 0, appearance_effects_slot[1], 0, appearance_effects_slot[2], 0, appearance_effects_slot[3], 0, appearance_effects_slot[4], 0);
|
||||
}
|
||||
if (appearance_effects_id[5]) {
|
||||
SendAppearanceEffect(appearance_effects_id[5], appearance_effects_id[6], appearance_effects_id[7], appearance_effects_id[8], appearance_effects_id[9], receiver,
|
||||
appearance_effects_slot[5], 0, appearance_effects_slot[6], 0, appearance_effects_slot[7], 0, appearance_effects_slot[8], 0, appearance_effects_slot[9], 0);
|
||||
}
|
||||
if (appearance_effects_id[10]) {
|
||||
SendAppearanceEffect(appearance_effects_id[10], appearance_effects_id[11], appearance_effects_id[12], appearance_effects_id[13], appearance_effects_id[14], receiver,
|
||||
appearance_effects_slot[10], 0, appearance_effects_slot[11], 0, appearance_effects_slot[12], 0, appearance_effects_slot[13], 0, appearance_effects_slot[14], 0);
|
||||
}
|
||||
if (appearance_effects_id[15]) {
|
||||
SendAppearanceEffect(appearance_effects_id[15], appearance_effects_id[16], appearance_effects_id[17], appearance_effects_id[18], appearance_effects_id[19], receiver,
|
||||
appearance_effects_slot[15], 0, appearance_effects_slot[16], 0, appearance_effects_slot[17], 0, appearance_effects_slot[18], 0, appearance_effects_slot[19], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::SendTargetable(bool on, Client *specific_target) {
|
||||
auto outapp = new EQApplicationPacket(OP_Untargetable, sizeof(Untargetable_Struct));
|
||||
Untargetable_Struct *ut = (Untargetable_Struct*)outapp->pBuffer;
|
||||
|
||||
@ -425,6 +425,10 @@ public:
|
||||
inline bool HasEndurUpkeep() const { return endur_upkeep; }
|
||||
inline void SetEndurUpkeep(bool val) { endur_upkeep = val; }
|
||||
bool HasBuffWithSpellGroup(int spell_group);
|
||||
void SetAppearenceEffects(int32 slot, int32 value);
|
||||
void GetAppearenceEffects();
|
||||
void ClearAppearenceEffects();
|
||||
void SendSavedAppearenceEffects(Client *receiver);
|
||||
|
||||
//Basic Stats/Inventory
|
||||
virtual void SetLevel(uint8 in_level, bool command = false) { level = in_level; }
|
||||
@ -788,7 +792,7 @@ public:
|
||||
uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF,
|
||||
uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF,
|
||||
uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF,
|
||||
uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f);
|
||||
uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f, bool send_appearance_effects = true);
|
||||
bool RandomizeFeatures(bool send_illusion = true, bool set_variables = true);
|
||||
virtual void Stun(int duration);
|
||||
virtual void UnStun();
|
||||
@ -1508,6 +1512,9 @@ protected:
|
||||
Timer def_proclimit_timer[MAX_PROC_LIMIT_TIMERS]; //SPA 512
|
||||
int32 def_proclimit_spellid[MAX_PROC_LIMIT_TIMERS]; //SPA 512
|
||||
|
||||
int32 appearance_effects_id[MAX_APPEARANCE_EFFECTS];
|
||||
int32 appearance_effects_slot[MAX_APPEARANCE_EFFECTS];
|
||||
|
||||
Timer shield_timer;
|
||||
uint32 m_shield_target_id;
|
||||
uint32 m_shielder_id;
|
||||
|
||||
@ -4809,31 +4809,22 @@ XS(XS_Mob_SendAppearanceEffectActor) {
|
||||
XS(XS_Mob_SendAppearanceEffectGround); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_SendAppearanceEffectGround) {
|
||||
dXSARGS;
|
||||
if (items < 3 || items > 12)
|
||||
Perl_croak(aTHX_ "Usage: Mob::SendAppearanceEffectGround(THIS, int32 effect1, uint32 slot1 = 1, [int32 effect2 = 0], [uint32 slot2 = 1], [int32 effect3 = 0], [uint32 slot3 = 1], [int32 effect4 = 0], [uint32 slot4 = 1], [int32 effect5 = 0], [uint32 slot5 = 1], [Client* single_client_to_send_to = null])"); // @categories Script Utility
|
||||
if (items < 3 || items > 8)
|
||||
Perl_croak(aTHX_ "Usage: Mob::SendAppearanceEffectGround(THIS, int32 effect1, [int32 effect2 = 0], [int32 effect3 = 0], [int32 effect4 = 0], [int32 effect5 = 0], [Client* single_client_to_send_to = null])"); // @categories Script Utility
|
||||
{
|
||||
Mob *THIS;
|
||||
int32 parm1 = (int32)SvIV(ST(1));
|
||||
uint32 value1slot = (uint32)SvIV(ST(2));
|
||||
int32 parm2 = 0;
|
||||
uint32 value2slot = 1;
|
||||
int32 parm3 = 0;
|
||||
uint32 value3slot = 1;
|
||||
int32 parm4 = 0;
|
||||
uint32 value4slot = 1;
|
||||
int32 parm5 = 0;
|
||||
uint32 value5slot = 1;
|
||||
Client *client = nullptr;
|
||||
VALIDATE_THIS_IS_MOB;
|
||||
if (items > 3) { parm2 = (int32)SvIV(ST(3)); }
|
||||
if (items > 4) { value2slot = (uint32)SvIV(ST(4)); }
|
||||
if (items > 5) { parm3 = (int32)SvIV(ST(5)); }
|
||||
if (items > 6) { value3slot = (uint32)SvIV(ST(6)); }
|
||||
if (items > 7) { parm4 = (int32)SvIV(ST(7)); }
|
||||
if (items > 8) { value4slot = (uint32)SvIV(ST(8)); }
|
||||
if (items > 9) { parm5 = (int32)SvIV(ST(9)); }
|
||||
if (items > 10) { value5slot = (uint32)SvIV(ST(10)); }
|
||||
if (items > 11) {
|
||||
if (items > 3) { parm2 = (int32)SvIV(ST(2)); }
|
||||
if (items > 4) { parm3 = (int32)SvIV(ST(3)); }
|
||||
if (items > 5) { parm4 = (int32)SvIV(ST(4)); }
|
||||
if (items > 6) { parm5 = (int32)SvIV(ST(5)); }
|
||||
if (items > 7) {
|
||||
if (sv_derived_from(ST(6), "Client")) {
|
||||
IV tmp = SvIV((SV *)SvRV(ST(11)));
|
||||
client = INT2PTR(Client *, tmp);
|
||||
@ -4844,8 +4835,8 @@ XS(XS_Mob_SendAppearanceEffectGround) {
|
||||
Perl_croak(aTHX_ "client is nullptr, avoiding crash.");
|
||||
}
|
||||
|
||||
THIS->SendAppearanceEffect(parm1, parm2, parm3, parm4, parm5, client, value1slot, 1, value2slot, 1, value3slot, 1,
|
||||
value4slot, 1, value5slot, 1);
|
||||
THIS->SendAppearanceEffect(parm1, parm2, parm3, parm4, parm5, client, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@ -4858,10 +4849,11 @@ XS(XS_Mob_RemoveAllAppearanceEffects) {
|
||||
{
|
||||
Mob *THIS;
|
||||
VALIDATE_THIS_IS_MOB;
|
||||
THIS->SendIllusionPacket(THIS->GetRace(), THIS->GetGender(), THIS->GetTexture(), THIS->GetHelmTexture(),
|
||||
THIS->GetHairColor(), THIS->GetBeardColor(), THIS->GetEyeColor1(), THIS->GetEyeColor2(),
|
||||
THIS->GetHairStyle(), THIS->GetLuclinFace(), THIS->GetBeard(), 0xFF,
|
||||
THIS->GetDrakkinHeritage(), THIS->GetDrakkinTattoo(), THIS->GetDrakkinDetails(), THIS->GetSize());
|
||||
THIS->SendIllusionPacket(THIS->GetRace(), THIS->GetGender(), THIS->GetTexture(), THIS->GetHelmTexture(),
|
||||
THIS->GetHairColor(), THIS->GetBeardColor(), THIS->GetEyeColor1(), THIS->GetEyeColor2(),
|
||||
THIS->GetHairStyle(), THIS->GetLuclinFace(), THIS->GetBeard(), 0xFF,
|
||||
THIS->GetDrakkinHeritage(), THIS->GetDrakkinTattoo(), THIS->GetDrakkinDetails(), THIS->GetSize(), false);
|
||||
THIS->ClearAppearenceEffects();
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user