Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API] mob->AppearanceEffects improved functionality. #1821

Merged
merged 10 commits into from
Nov 27, 2021
58 changes: 47 additions & 11 deletions zone/mob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2838,8 +2838,44 @@ void Mob::SendStunAppearance()
safe_delete(outapp);
}

void Mob::SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target){
void Mob::SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target,
uint32 value1slot, uint32 value1ground, uint32 value2slot, uint32 value2ground, uint32 value3slot, uint32 value3ground,
uint32 value4slot, uint32 value4ground, uint32 value5slot, uint32 value5ground){
auto outapp = new EQApplicationPacket(OP_LevelAppearance, sizeof(LevelAppearance_Struct));

/* Location of the effect from value#slot, this is removed upon mob death/despawn.
0 = pelvis1
1 = pelvis2
2 = helm
3 = Offhand
4 = Mainhand
5 = left foot
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.
*/

//higher values can crash client
if (value1slot > 9) {
value1slot = 1;
}
if (value2slot > 9) {
value2slot = 1;
}
if (value2slot > 9) {
value2slot = 1;
}
if (value3slot > 9) {
value3slot = 1;
}
if (value4slot > 9) {
value4slot = 1;
}
if (value5slot > 9) {
value5slot = 1;
}

Kinglykrab marked this conversation as resolved.
Show resolved Hide resolved
LevelAppearance_Struct* la = (LevelAppearance_Struct*)outapp->pBuffer;
la->spawn_id = GetID();
la->parm1 = parm1;
Expand All @@ -2849,16 +2885,16 @@ void Mob::SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32
la->parm5 = parm5;
// Note that setting the b values to 0 will disable the related effect from the corresponding parameter.
// Setting the a value appears to have no affect at all.s
la->value1a = 1;
la->value1b = 1;
la->value2a = 1;
la->value2b = 1;
la->value3a = 1;
la->value3b = 1;
la->value4a = 1;
la->value4b = 1;
la->value5a = 1;
la->value5b = 1;
la->value1a = value1slot;
la->value1b = value1ground;
la->value2a = value2slot;
la->value2b = value2ground;
la->value3a = value3slot;
la->value3b = value3ground;
la->value4a = value4slot;
la->value4b = value4ground;
la->value5a = value5slot;
la->value5b = value5ground;
if(specific_target == nullptr) {
entity_list.QueueClients(this,outapp);
}
Expand Down
3 changes: 2 additions & 1 deletion zone/mob.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ class Mob : public Entity {
void ChangeSize(float in_size, bool bNoRestriction = false);
void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone);
void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0, float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, EQ::skills::SkillType skillInUse = EQ::skills::SkillArchery);
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target=nullptr);
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target=nullptr, uint32 value1slot = 1, uint32 value1ground = 1, uint32 value2slot = 1, uint32 value2ground = 1,
uint32 value3slot = 1, uint32 value3ground = 1, uint32 value4slot = 1, uint32 value4ground = 1, uint32 value5slot = 1, uint32 value5ground = 1);
void SendLevelAppearance();
void SendStunAppearance();
void SendTargetable(bool on, Client *specific_target = nullptr);
Expand Down
133 changes: 127 additions & 6 deletions zone/perl_mob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4701,32 +4701,151 @@ XS(XS_Mob_HasNPCSpecialAtk) {
XS(XS_Mob_SendAppearanceEffect); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_SendAppearanceEffect) {
dXSARGS;
if (items < 2 || items > 7)
Perl_croak(aTHX_ "Usage: Mob::SendAppearanceEffect(THIS, int32 param_1, [int32 param_2 = 0], [int32 param_3 = 0], [int32 param_4 = 0], [int32 param_5 = 0], [Client* single_client_to_send_to = null])"); // @categories Script Utility
if (items < 2 || items > 17)
Perl_croak(aTHX_ "Usage: Mob::SendAppearanceEffect(THIS, int32 effect1, [int32 effect2 = 0], [int32 effect3 = 0], [int32 effect4 = 0], [int32 effect5 = 0], [Client* single_client_to_send_to = null]), [uint32 slot1 = 1], [uint32 ground1 = 1], [uint32 slot2 = 1], [uint32 ground2 = 1], [uint32 slot3 = 1], [uint32 ground2 = 1], [uint32 slot4 = 1], [uint32 ground4 = 1], [uint32 slot5 = 1], [uint32 ground5 = 1]"); // @categories Script Utility
{
Mob *THIS;
int32 parm1 = (int32) SvIV(ST(1));
int32 parm2 = 0;
int32 parm3 = 0;
int32 parm4 = 0;
int32 parm5 = 0;
uint32 value1slot = 1;
uint32 value1ground = 1;
uint32 value2slot = 1;
uint32 value2ground = 1;
uint32 value3slot = 1;
uint32 value3ground = 1;
uint32 value4slot = 1;
uint32 value4ground = 1;
uint32 value5slot = 1;
uint32 value5ground = 1;
Client *client = nullptr;
bool nullclient = false;
VALIDATE_THIS_IS_MOB;
if (items > 2) { parm2 = (int32) SvIV(ST(2)); }
if (items > 3) { parm3 = (int32) SvIV(ST(3)); }
if (items > 4) { parm4 = (int32) SvIV(ST(4)); }
if (items > 5) { parm5 = (int32) SvIV(ST(5)); }
if (items > 6) {
if (sv_derived_from(ST(6), "Client")) {
IV tmp = SvIV((SV *) SvRV(ST(6)));
IV tmp = SvIV((SV *)SvRV(ST(6)));
client = INT2PTR(Client *, tmp);
} else
}
else {
nullclient = true;
}
if (client == nullptr) {
nullclient = true;
}
}
if (items > 7) { value1slot = (uint32)SvIV(ST(7)); }
if (items > 8) { value1ground = (uint32)SvIV(ST(8)); }
if (items > 9) { value2slot = (uint32)SvIV(ST(9)); }
if (items > 10) { value2ground = (uint32)SvIV(ST(10)); }
if (items > 11) { value3slot = (uint32)SvIV(ST(11)); }
if (items > 12) { value3ground = (uint32)SvIV(ST(12)); }
if (items > 13) { value4slot = (uint32)SvIV(ST(13)); }
if (items > 14) { value4ground = (uint32)SvIV(ST(14)); }
if (items > 15) { value5slot = (uint32)SvIV(ST(15)); }
if (items > 16) { value5ground = (uint32)SvIV(ST(16)); }

if (nullclient) {
THIS->SendAppearanceEffect(parm1, parm2, parm3, parm4, parm5, 0, value1slot, value1ground, value2slot, value2ground, value3slot, value3ground,
value4slot, value4ground, value5slot, value5ground);
}
else {
THIS->SendAppearanceEffect(parm1, parm2, parm3, parm4, parm5, client, value1slot, value1ground, value2slot, value2ground, value3slot, value3ground,
value4slot, value4ground, value5slot, value5ground);
}
}
XSRETURN_EMPTY;
}

XS(XS_Mob_SendAppearanceEffectActor); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_SendAppearanceEffectActor) {
dXSARGS;
if (items < 3 || items > 12)
Perl_croak(aTHX_ "Usage: Mob::SendAppearanceEffectActor(THIS, int32 effect1, uint32 slot1 = 0, [int32 effect2 = 0] [uint32 slot2 = 0], [int32 effect3 = 0] [uint32 slot3 = 0], [int32 effect4 = 0] [uint32 slot4 = 0], [int32 effect5 = 0], [uint32 slot5 = 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 = 0;
int32 parm3 = 0;
uint32 value3slot = 0;
int32 parm4 = 0;
uint32 value4slot = 0;
int32 parm5 = 0;
uint32 value5slot = 0;
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 (sv_derived_from(ST(11), "Client")) {
IV tmp = SvIV((SV *)SvRV(ST(11)));
client = INT2PTR(Client *, tmp);
}
else
Perl_croak(aTHX_ "client is not of type Client");
if (client == nullptr)
Perl_croak(aTHX_ "client is nullptr, avoiding crash.");
}

THIS->SendAppearanceEffect(parm1, parm2, parm3, parm4, parm5, client, value1slot, 0, value2slot, 0, value3slot, 0,
value4slot, 0, value5slot, 0);
}
XSRETURN_EMPTY;
}

XS(XS_Mob_SendAppearanceEffectGround); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_SendAppearanceEffectGround) {
dXSARGS;
if (items < 3 || items > 12)
Perl_croak(aTHX_ "Usage: Mob::SendAppearanceEffectActor(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
Kinglykrab marked this conversation as resolved.
Show resolved Hide resolved
{
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 (sv_derived_from(ST(6), "Client")) {
IV tmp = SvIV((SV *)SvRV(ST(11)));
client = INT2PTR(Client *, tmp);
}
else
Perl_croak(aTHX_ "client is not of type Client");
if (client == nullptr)
Perl_croak(aTHX_ "client is nullptr, avoiding crash.");
}

THIS->SendAppearanceEffect(parm1, parm2, parm3, parm4, parm5, client);
THIS->SendAppearanceEffect(parm1, parm2, parm3, parm4, parm5, client, value1slot, 1, value2slot, 1, value3slot, 1,
value4slot, 1, value5slot, 1);
}
XSRETURN_EMPTY;
}
Expand Down Expand Up @@ -6701,7 +6820,9 @@ XS(boot_Mob) {
newXSproto(strcpy(buf, "SeeImprovedHide"), XS_Mob_SeeImprovedHide, file, "$");
newXSproto(strcpy(buf, "SeeInvisible"), XS_Mob_SeeInvisible, file, "$");
newXSproto(strcpy(buf, "SeeInvisibleUndead"), XS_Mob_SeeInvisibleUndead, file, "$");
newXSproto(strcpy(buf, "SendAppearanceEffect"), XS_Mob_SendAppearanceEffect, file, "$$;$$$$");
newXSproto(strcpy(buf, "SendAppearanceEffect"), XS_Mob_SendAppearanceEffect, file, "$$;$$$$$$$$$$$$$$");
newXSproto(strcpy(buf, "SendAppearanceEffectActor"), XS_Mob_SendAppearanceEffectActor, file, "$$$;$$$$$$$$$");
newXSproto(strcpy(buf, "SendAppearanceEffectGround"), XS_Mob_SendAppearanceEffectGround, file, "$$$;$$$$$$$$$");
newXSproto(strcpy(buf, "SendIllusion"), XS_Mob_SendIllusion, file, "$$;$$$$$$$$$$$$");
newXSproto(strcpy(buf, "SendTo"), XS_Mob_SendTo, file, "$$$$");
newXSproto(strcpy(buf, "SendToFixZ"), XS_Mob_SendToFixZ, file, "$$$$");
Expand Down