[Rule] Classic Invite Requires Target (#3878)

* [Rule] Classic Invite Requires Target

Default is false, when enabled, group invites will require a hard target to invite.

`/invite charname` will no longer function when enabled.

* Updates including raid errors

* String Suggestion
This commit is contained in:
Fryguy 2024-01-07 12:12:57 -05:00 committed by GitHub
parent c08200188f
commit dfa349492c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 35 deletions

View File

@ -218,6 +218,7 @@ RULE_BOOL(Character, ItemExtraSkillDamageCalcAsPercent, false, "If enabled, appl
RULE_BOOL(Character, UseForageCommonFood, true, "If enabled, use the common foods specified in the code.") RULE_BOOL(Character, UseForageCommonFood, true, "If enabled, use the common foods specified in the code.")
RULE_INT(Character, ClearXTargetDelay, 10, "Seconds between uses of the #clearxtargets command (Set to 0 to disable)") RULE_INT(Character, ClearXTargetDelay, 10, "Seconds between uses of the #clearxtargets command (Set to 0 to disable)")
RULE_BOOL(Character, PreventMountsFromZoning, false, "Enable to prevent mounts from zoning - Prior to December 15, 2004 this is enabled.") RULE_BOOL(Character, PreventMountsFromZoning, false, "Enable to prevent mounts from zoning - Prior to December 15, 2004 this is enabled.")
RULE_BOOL(Character, GroupInvitesRequireTarget, false, "Enable to require players to have invitee on target (Disables /invite name) - Classic Style")
RULE_CATEGORY_END() RULE_CATEGORY_END()
RULE_CATEGORY(Mercs) RULE_CATEGORY(Mercs)

View File

@ -7322,63 +7322,80 @@ void Client::Handle_OP_GroupInvite2(const EQApplicationPacket *app)
GroupInvite_Struct* gis = (GroupInvite_Struct*)app->pBuffer; GroupInvite_Struct* gis = (GroupInvite_Struct*)app->pBuffer;
Mob *Invitee = entity_list.GetMob(gis->invitee_name); Mob* invitee = nullptr;
if (Invitee == this) if (RuleB(Character, GroupInvitesRequireTarget)) {
{ // We can only invite the current target.
invitee = GetTarget();
} else {
invitee = entity_list.GetMob(gis->invitee_name);
}
if (invitee == this) {
MessageString(Chat::LightGray, GROUP_INVITEE_SELF); MessageString(Chat::LightGray, GROUP_INVITEE_SELF);
return; return;
} }
if (Invitee) if (invitee) {
{ if (invitee->IsClient()) {
if (Invitee->IsClient()) if (invitee->CastToClient()->MercOnlyOrNoGroup() && !invitee->IsRaidGrouped()) {
{ if (app->GetOpcode() == OP_GroupInvite2) {
if (Invitee->CastToClient()->MercOnlyOrNoGroup() && !Invitee->IsRaidGrouped())
{
if (app->GetOpcode() == OP_GroupInvite2)
{
//Make a new packet using all the same information but make sure it's a fixed GroupInvite opcode so we //Make a new packet using all the same information but make sure it's a fixed GroupInvite opcode so we
//Don't have to deal with GroupFollow2 crap. //Don't have to deal with GroupFollow2 crap.
auto outapp = auto outapp =
new EQApplicationPacket(OP_GroupInvite, sizeof(GroupInvite_Struct)); new EQApplicationPacket(OP_GroupInvite, sizeof(GroupInvite_Struct));
memcpy(outapp->pBuffer, app->pBuffer, outapp->size); memcpy(outapp->pBuffer, app->pBuffer, outapp->size);
Invitee->CastToClient()->QueuePacket(outapp); invitee->CastToClient()->QueuePacket(outapp);
safe_delete(outapp); safe_delete(outapp);
return; return;
} } else {
else
{
//The correct opcode, no reason to bother wasting time reconstructing the packet //The correct opcode, no reason to bother wasting time reconstructing the packet
Invitee->CastToClient()->QueuePacket(app); invitee->CastToClient()->QueuePacket(app);
} }
} } else if (invitee->IsRaidGrouped()) {
else { Raid* inviter_raid = GetRaid();
Raid* invitee_raid = invitee->CastToClient()->GetRaid();
bool leader = false;
if (invitee_raid) {
leader = invitee_raid->IsGroupLeader(invitee->GetName());
}
if (inviter_raid != invitee_raid || leader) {
MessageString(Chat::Default, ALREADY_IN_GRP_RAID, invitee->GetCleanName());
} else {
MessageString(Chat::Default, TARGET_ALREADY_IN_GROUP, invitee->GetCleanName());
}
return;
} else {
if (RuleB(Character, OnInviteReceiveAlreadyinGroupMessage)) { if (RuleB(Character, OnInviteReceiveAlreadyinGroupMessage)) {
if (!Invitee->CastToClient()->MercOnlyOrNoGroup()) { if (!invitee->CastToClient()->MercOnlyOrNoGroup()) {
Message(Chat::LightGray, "%s is already in another group.", Invitee->GetCleanName()); MessageString(Chat::Default, TARGET_ALREADY_IN_GROUP, invitee->GetCleanName());
} }
} }
} }
} } else if (invitee->IsBot()) {
else if (Invitee->IsBot()) {
Client* inviter = entity_list.GetClientByName(gis->inviter_name); Client* inviter = entity_list.GetClientByName(gis->inviter_name);
if (inviter && inviter->IsRaidGrouped() && !Invitee->HasRaid()) { if (inviter && inviter->IsRaidGrouped() && !invitee->HasRaid()) {
Bot::ProcessRaidInvite(Invitee->CastToBot(), inviter, true); Bot::ProcessRaidInvite(invitee->CastToBot(), inviter, true);
} } else if (!invitee->HasRaid()) {
else if (!Invitee->HasRaid()) { Bot::ProcessBotGroupInvite(this, std::string(invitee->GetName()));
Bot::ProcessBotGroupInvite(this, std::string(Invitee->GetName()));
} else { } else {
MessageString(Chat::LightGray, ALREADY_IN_RAID, Invitee->GetCleanName()); MessageString(Chat::LightGray, ALREADY_IN_RAID, invitee->GetCleanName());
} }
} }
} } else {
else if (RuleB(Character, GroupInvitesRequireTarget)) {
{ Message(Chat::White, "You must target a player first to invite to join your group.");
auto pack = new ServerPacket(ServerOP_GroupInvite, sizeof(GroupInvite_Struct)); } else {
memcpy(pack->pBuffer, gis, sizeof(GroupInvite_Struct)); auto pack = new ServerPacket(ServerOP_GroupInvite, sizeof(GroupInvite_Struct));
worldserver.SendPacket(pack); memcpy(pack->pBuffer, gis, sizeof(GroupInvite_Struct));
safe_delete(pack); worldserver.SendPacket(pack);
safe_delete(pack);
}
} }
return; return;
} }

View File

@ -373,6 +373,7 @@
#define ALREADY_IN_YOUR_RAID 5077 //%1 is already in your raid. #define ALREADY_IN_YOUR_RAID 5077 //%1 is already in your raid.
#define NOT_IN_YOUR_RAID 5082 //%1 is not in your raid. #define NOT_IN_YOUR_RAID 5082 //%1 is not in your raid.
#define GAIN_RAIDEXP 5085 //You gained raid experience! #define GAIN_RAIDEXP 5085 //You gained raid experience!
#define ALREADY_IN_GRP_RAID 5088 //% 1 rejects your invite because they are in a raid and you are not in theirs, or they are a raid group leader
#define DUNGEON_SEALED 5141 //The gateway to the dungeon is sealed off to you. Perhaps you would be able to enter if you needed to adventure there. #define DUNGEON_SEALED 5141 //The gateway to the dungeon is sealed off to you. Perhaps you would be able to enter if you needed to adventure there.
#define ADVENTURE_COMPLETE 5147 //You received %1 points for successfully completing the adventure. #define ADVENTURE_COMPLETE 5147 //You received %1 points for successfully completing the adventure.
#define SUCCOR_FAIL 5169 //The portal collapes before you can escape! #define SUCCOR_FAIL 5169 //The portal collapes before you can escape!