DEBUG_LOG("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str());
+ // If player is an enemy of the current player, give warning
+ if (player->GetTeam() != GetPlayer()->GetTeam())
+ if (player->IsInWorld())
+ {
+ player->GetSession()->SendNotification("You have been invited to join an enemy guild.");
+ sWorld.SendServerMessage(SERVER_MSG_STRING, "By joining an enemy guild, you will be a traitor. You will lose your reputation with your people.", player);
+ }
+
player->SetGuildIdInvited(GetPlayer()->GetGuildId());
// Put record into guildlog
guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0);
-205,6 +213,10 @@ void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0);
guild->BroadcastEvent(GE_JOINED, player->GetGUID(), 1, player->GetName(), "", "");
+
+ // If player was an enemy to the current player, change to a traitor
+ if (player->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(guild->GetLeader()))
+ player->changeFactionToOpposite(player->getRace());
}
+/**
+ * Gets the opposite race of the given race
+ *
+ * @param race the race to get the opposite of
+ * @returns the opposite race
+ *
+ */
+uint8 Player::getOppositeRace(uint8 race)
+{
+ switch(race)
+ {
+ case RACE_HUMAN : return RACE_ORC;
+ case RACE_ORC : return RACE_HUMAN;
+ case RACE_DWARF : return RACE_UNDEAD_PLAYER;
+ case RACE_UNDEAD_PLAYER : return RACE_DWARF;
+ case RACE_NIGHTELF : return RACE_TAUREN;
+ case RACE_TAUREN : return RACE_NIGHTELF;
+ case RACE_GNOME : return RACE_TROLL;
+ case RACE_TROLL : return RACE_GNOME;
+ case RACE_DRAENEI : return RACE_BLOODELF;
+ case RACE_BLOODELF : return RACE_DRAENEI;
+ }
+
+ sLog.outError("Race %u not found", uint32(race));
+ return RACE_HUMAN;
+}
+
+/**
+ * Changes the player's faction and notifies
+ *
+ * @param race the race of the player
+ *
+ */
+void Player::changeFactionToOpposite(uint8 race)
+{
+ uint8 raceto;
+
+ // determine which race to use as a base
+ if (IsTraitor())
+ raceto = race;
+ else
+ raceto = getOppositeRace(race);
+
+ // set reputation to base defaults for current race
+ m_reputationMgr.SetBaseDefaults();
+
+ // change race faction and team
+ m_faction = getFactionForRace( raceto );
+ setFactionForRace( race );
+
+ // set reputation to base defaults for new race faction
+ m_reputationMgr.SetBaseDefaults();
+
+ // send reputation to client to allow it properly work without a relogin
+ m_reputationMgr.SendInitialReputations();
+ m_reputationMgr.SendStates();
+
+ // add team languages
+ // although client doesn't allow them to be used
+ if(!IsInWorld())
+ {
+ addSpell(668, true, true, true, false);
+ addSpell(669, true, true, true, false);
+ }
+ else
+ {
+ learnSpell(668, true);
+ learnSpell(669, true);
+ }
+
+ DEBUG_LOG("PLAYER changed to opposite (Class: %u Race: %u)", uint32(getClass()), uint32(raceto));
+
+ // build message to let everyone know
+ std::string strmessage = GetName();
+ if (IsTraitor())
+ strmessage += " is a traitor and switched to the ";
+ else
+ strmessage += " is a double traitor and switched back to the ";
+
+ if (GetTeam() == ALLIANCE)
+ strmessage += "Alliance";
+ else
+ strmessage += "Horde";
+ strmessage += "!";
+
+ // send messages to all players and current player
+ sWorld.SendServerMessage(SERVER_MSG_STRING, strmessage.c_str());
+ sWorld.SendServerMessage(SERVER_MSG_STRING, "You are a traitor! Your reputation has been lost with your people.", this);
+}
+
void Player::setFactionForRace(uint8 race)
{
- m_team = TeamForRace(race);
- setFaction( getFactionForRace(race) );
+ uint8 temprace;
+ temprace = race;
+
+ // Does the faction match for the given race; IsTraitor
+ if ( (m_faction != 0) && (m_faction != getFactionForRace(race)) )
+ {
+ temprace = getOppositeRace(race);
+ }
+
+ m_team = TeamForRace(temprace);
+ m_faction = getFactionForRace(temprace);
+ setFaction( m_faction );
}
//Need to call it to initialize m_team (m_team can be calculated from race)
//Other way is to saves m_team into characters table.
+ m_faction = fields[65].GetUInt32();
setFactionForRace(getRace());
SetCharm(NULL);
+/**
+ * This method is called to set the defaults for the originally visible, at peace,
+ * at war, or invisible for the current race.
+ *
+ */
+void ReputationMgr::SetBaseDefaults()
+{
+ for(unsigned int i = 1; i < sFactionStore.GetNumRows(); i++)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(i);
+
+ if( factionEntry && (factionEntry->reputationListID >= 0))
+ {
+ FactionState* faction = &m_factions[factionEntry->reputationListID];
+ uint32 defaultFlags = GetDefaultStateFlags(factionEntry);
+
+ // if faction matches any flags then update
+ // this resets the default standings to 0, should be better way for this
+ if( (defaultFlags & FACTION_FLAG_VISIBLE) ||
+ (defaultFlags & FACTION_FLAG_INVISIBLE_FORCED) ||
+ (defaultFlags & FACTION_FLAG_AT_WAR) ||
+ (defaultFlags & FACTION_FLAG_PEACE_FORCED) )
+ {
+ if (faction->Standing != 0)
+ {
+ faction->Standing = 0;
+ faction->Changed = true;
+ }
+
+ if (faction->Flags != defaultFlags)
+ {
+ faction->Flags = defaultFlags;
+ faction->Changed = true;
+ }
+ }
+ }
+ }
+}
+
bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental)
{
SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID);
diff --git a/src/game/ReputationMgr.h b/src/game/ReputationMgr.h
index 37d4312..1235dec 100644
--- a/src/game/ReputationMgr.h
+++ b/src/game/ReputationMgr.h
-87,9 +87,41 @@ class ReputationMgr
return repItr != m_factions.end() ? &repItr->second : NULL;
}
+ /**
+ * Gets the FactionEntry from the faction_id and returns the reputation for it.
+ *
+ * @param faction_id the id number of the faction to be returned.
+ *
+ */
int32 GetReputation(uint32 faction_id) const;
int32 GetReputation(FactionEntry const* factionEntry) const;
+ /**
+ * Gets the FactionEntry from the faction_id and returns the base reputation for it.
+ *
+ * @param faction_id the id number of the faction to be returned.
+ * @returns the base reputation.
+ *
+ */
+ int32 GetBaseReputation(uint32 faction_id) const;
int32 GetBaseReputation(FactionEntry const* factionEntry) const;
+ /**
+ * Gets the FactionEntry from the faction_id and returns the difference
+ * of the opposite race's reputation for it.
+ *
+ * @param faction_id the id number of the faction to be returned.
+ * @returns the difference between the opposing races reputation.
+ *
+ */
+ int32 GetBaseReputationDifference(uint32 faction_id) const;
+ /**
+ * Gets the current race's difference of reputation of the
+ * factionEntry and the opposite race's reputation.
+ *
+ * @param factionEntry the faction to be returned.
+ * @returns the difference between the opposing races reputation.
+ *
+ */
+ int32 GetBaseReputationDifference(FactionEntry const* factionEntry) const;
+ void SetBaseDefaults();
+
public: // senders
void SendInitialReputations();
void SendForceReactions();
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 3bc6524..e092646 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
-3031,13 +3031,13 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
{
// players are a bit difficult since the dbc has seldomly an horde modelid
// so we add hacks here to set the right model
- if (Player::TeamForRace(target->getRace()) == ALLIANCE)
+ if (((Player*)target)->GetTeam() == ALLIANCE)
modelid = ssEntry->modelID_A;
else // 3.2.3 only the moonkin form has this information
modelid = ssEntry->modelID_H;
// no model found, if player is horde we look here for our hardcoded modelids
- if (!modelid && Player::TeamForRace(target->getRace()) == HORDE)
+ if (!modelid && ((Player*)target)->GetTeam() == HORDE)
{