aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorSubv <s.v.h21@hotmail.com>2012-10-16 21:55:01 -0500
committerSubv <s.v.h21@hotmail.com>2012-10-16 21:55:01 -0500
commit705873091b470a5d0cd361bd7f295ec724141df2 (patch)
tree2b557293395baaf88d66a1fbac55b3919569c0fc /src/server/game
parentb49891e348c01ae7f240ef07c05e09bc361f4c58 (diff)
parent27f091806a6f52f406837d188dd4171019bfa59b (diff)
Merge branch 'master' of https://github.com/TrinityCore/TrinityCore into 4.3.4
Conflicts: src/server/game/Entities/Player/Player.cpp src/server/game/Handlers/TicketHandler.cpp src/server/game/Tickets/TicketMgr.cpp src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Entities/Player/Player.cpp180
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--[-rwxr-xr-x]src/server/game/Handlers/TicketHandler.cpp42
-rw-r--r--src/server/game/Spells/SpellMgr.cpp44
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.h6
-rw-r--r--[-rwxr-xr-x]src/server/game/Tickets/TicketMgr.cpp66
-rwxr-xr-xsrc/server/game/Tickets/TicketMgr.h5
7 files changed, 130 insertions, 215 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0582a879d5f..036062393fb 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -9170,7 +9170,6 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
{
// data depends on zoneid/mapid...
Battleground* bg = GetBattleground();
- uint16 NumberOfFields = 0;
uint32 mapid = GetMapId();
OutdoorPvP* pvp = sOutdoorPvPMgr->GetOutdoorPvPToZoneId(zoneid);
InstanceScript* instance = GetInstanceScript();
@@ -9178,91 +9177,12 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
sLog->outDebug(LOG_FILTER_NETWORKIO, "Sending SMSG_INIT_WORLD_STATES to Map: %u, Zone: %u", mapid, zoneid);
- // may be exist better way to do this...
- switch (zoneid)
- {
- case 0:
- case 1:
- case 4:
- case 8:
- case 10:
- case 11:
- case 12:
- case 36:
- case 38:
- case 40:
- case 41:
- case 51:
- case 267:
- case 1519:
- case 1537:
- case 2257:
- case 2918:
- NumberOfFields = 8;
- break;
- case 1377:
- NumberOfFields = 15;
- break;
- case 2597:
- NumberOfFields = 83;
- break;
- case 3277:
- NumberOfFields = 18;
- break;
- case 3358:
- case 3820:
- NumberOfFields = 40;
- break;
- case 3483:
- NumberOfFields = 27;
- break;
- case 3518:
- NumberOfFields = 39;
- break;
- case 3519:
- NumberOfFields = 38;
- break;
- case 3521:
- NumberOfFields = 37;
- break;
- case 3698:
- case 3702:
- case 3968:
- case 4378:
- case 3703:
- NumberOfFields = 11;
- break;
- case 4384:
- NumberOfFields = 30;
- break;
- case 4710:
- NumberOfFields = 28;
- break;
- case 4812: // Icecrown Citadel
- case 4100: // The Culling of Stratholme
- NumberOfFields = 13;
- break;
- case 4987: // The Ruby Sanctum
- NumberOfFields = 3;
- break;
- case 4273: // Ulduar
- NumberOfFields = 10;
- break;
- case 4197: // Wintergrasp
- /// Use the max here, and fill with zeros if missing.
- NumberOfFields = 10 + WG_MAX_OBJ + WG_MAX_WORKSHOP;
- break;
- default:
- NumberOfFields = 12;
- break;
- }
-
- WorldPacket data(SMSG_INIT_WORLD_STATES, (4+4+4+2+(NumberOfFields*8)));
+ WorldPacket data(SMSG_INIT_WORLD_STATES, (4+4+4+2+(12*8)));
data << uint32(mapid); // mapid
data << uint32(zoneid); // zone id
data << uint32(areaid); // area id, new 2.1.0
size_t countPos = data.wpos();
- data << uint16(NumberOfFields); // count of uint64 blocks
+ data << uint16(0); // count of uint64 blocks
data << uint32(0x8d8) << uint32(0x0); // 1
data << uint32(0x8d7) << uint32(0x0); // 2
data << uint32(0x8d6) << uint32(0x0); // 3
@@ -9806,8 +9726,6 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
bf->FillInitialWorldStates(data);
break;
}
- else
- data.put<uint16>(countPos, 12);
// No break here, intended.
default:
data << uint32(0x914) << uint32(0x0); // 7
@@ -9816,6 +9734,10 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
data << uint32(0x915) << uint32(0x0); // 10
break;
}
+
+ uint16 length = (data.wpos() - countPos) / 8;
+ data.put<uint16>(countPos, length);
+
GetSession()->SendPacket(&data);
SendBGWeekendWorldStates();
SendBattlefieldWorldStates();
@@ -15001,24 +14923,6 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
if (questGiver && quest->GetQuestStartScript() != 0)
GetMap()->ScriptsStart(sQuestStartScripts, quest->GetQuestStartScript(), questGiver, this);
- // Some spells applied at quest activation
- SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id, true);
- if (saBounds.first != saBounds.second)
- {
- uint32 zone, area;
- GetZoneAndAreaId(zone, area);
-
- for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
- if (itr->second->autocast && itr->second->IsFitToRequirements(this, zone, area))
- if (!HasAura(itr->second->spellId))
- CastSpell(this, itr->second->spellId, true);
- }
-
- PhaseUpdateData phaseUdateData;
- phaseUdateData.AddQuestUpdate(quest_id);
-
- phaseMgr.NotifyConditionChanged(phaseUdateData);
-
UpdateForQuestWorldObjects();
}
@@ -15187,11 +15091,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
m_RewardedQuests.insert(quest_id);
m_RewardedQuestsSave[quest_id] = true;
- PhaseUpdateData phaseUdateData;
- phaseUdateData.AddQuestUpdate(quest_id);
-
- phaseMgr.NotifyConditionChanged(phaseUdateData);
-
// StoreNewItem, mail reward, etc. save data directly to the database
// to prevent exploitable data desynchronisation we save the quest status to the database too
// (to prevent rewarding this quest another time while rewards were already given out)
@@ -15212,33 +15111,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId());
- uint32 zone = 0;
- uint32 area = 0;
-
- // remove auras from spells with quest reward state limitations
- SpellAreaForQuestMapBounds saEndBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(quest_id);
- if (saEndBounds.first != saEndBounds.second)
- {
- GetZoneAndAreaId(zone, area);
-
- for (SpellAreaForAreaMap::const_iterator itr = saEndBounds.first; itr != saEndBounds.second; ++itr)
- if (!itr->second->IsFitToRequirements(this, zone, area))
- RemoveAurasDueToSpell(itr->second->spellId);
- }
-
- // Some spells applied at quest reward
- SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id, false);
- if (saBounds.first != saBounds.second)
- {
- if (!zone || !area)
- GetZoneAndAreaId(zone, area);
-
- for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
- if (itr->second->autocast && itr->second->IsFitToRequirements(this, zone, area))
- if (!HasAura(itr->second->spellId))
- CastSpell(this, itr->second->spellId, true);
- }
-
//lets remove flag for delayed teleports
SetCanDelayTeleport(false);
}
@@ -15786,6 +15658,30 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
phaseMgr.NotifyConditionChanged(phaseUdateData);
+ uint32 zone = 0, area = 0;
+
+ SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id);
+ if (saBounds.first != saBounds.second)
+ {
+ GetZoneAndAreaId(zone, area);
+
+ for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ if (itr->second->autocast && itr->second->IsFitToRequirements(this, zone, area))
+ if (!HasAura(itr->second->spellId))
+ CastSpell(this, itr->second->spellId, true);
+ }
+
+ saBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(quest_id);
+ if (saBounds.first != saBounds.second)
+ {
+ if (!zone || !area)
+ GetZoneAndAreaId(zone, area);
+
+ for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ if (!itr->second->IsFitToRequirements(this, zone, area))
+ RemoveAurasDueToSpell(itr->second->spellId);
+ }
+
UpdateForQuestWorldObjects();
}
@@ -23866,21 +23762,15 @@ bool Player::CanUseBattlegroundObject()
// TODO : some spells gives player ForceReaction to one faction (ReputationMgr::ApplyForceReaction)
// maybe gameobject code should handle that ForceReaction usage
// BUG: sometimes when player clicks on flag in AB - client won't send gameobject_use, only gameobject_report_use packet
- return (//InBattleground() && // in battleground - not need, check in other cases
- //!IsMounted() && - not correct, player is dismounted when he clicks on flag
- //player cannot use object when he is invulnerable (immune)
- !isTotalImmune() && // not totally immune
- //i'm not sure if these two are correct, because invisible players should get visible when they click on flag
- !HasStealthAura() && // not stealthed
- !HasInvisibilityAura() && // not invisible
- !HasAura(SPELL_RECENTLY_DROPPED_FLAG) && // can't pickup
- isAlive() // live player
-);
+ // Note: Mount, stealth and invisibility will be removed when used
+ return (!isTotalImmune() && // Damage immune
+ !HasAura(SPELL_RECENTLY_DROPPED_FLAG) && // Still has recently held flag debuff
+ isAlive()); // Alive
}
bool Player::CanCaptureTowerPoint()
{
- return (!HasStealthAura() && // not stealthed
+ return (!HasStealthAura() && // not stealthed
!HasInvisibilityAura() && // not invisible
isAlive() // live player
);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 651dad2aeea..01207b6bf2f 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -6345,7 +6345,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (GetTypeId() != TYPEID_PLAYER)
{
beaconTarget = triggeredByAura->GetBase()->GetCaster();
- if (beaconTarget == this || !(beaconTarget->GetAura(53563, victim->GetGUID())))
+ if (!beaconTarget || beaconTarget == this || !(beaconTarget->GetAura(53563, victim->GetGUID())))
return false;
basepoints0 = int32(damage);
triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654;
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index e5618420ac5..5213dff2f56 100755..100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -16,6 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "zlib.h"
#include "Language.h"
#include "WorldPacket.h"
#include "Common.h"
@@ -26,7 +27,7 @@
#include "WorldSession.h"
#include "Util.h"
-void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recvData)
+void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
{
// Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable)
if (sTicketMgr->GetStatus() == GMTICKET_QUEUE_STATUS_DISABLED)
@@ -43,6 +44,45 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recvData)
if (!sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
{
GmTicket* ticket = new GmTicket(GetPlayer(), recvData);
+
+ uint32 count;
+ std::list<uint32> times;
+ uint32 decompressedSize;
+ std::string chatLog;
+
+ recvData >> count;
+
+ for (uint32 i = 0; i < count; i++)
+ {
+ uint32 time;
+ recvData >> time;
+ times.push_back(time);
+ }
+
+ recvData >> decompressedSize;
+
+ if (count && decompressedSize && decompressedSize < 0xFFFF)
+ {
+ uint32 pos = recvData.rpos();
+ ByteBuffer dest;
+ dest.resize(decompressedSize);
+
+ uLongf realSize = decompressedSize;
+ if (uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recvData.contents() + pos), recvData.size() - pos) == Z_OK)
+ {
+ dest >> chatLog;
+ ticket->SetChatLog(times, chatLog);
+ }
+ else
+ {
+ sLog->outError(LOG_FILTER_NETWORKIO, "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
+ recvData.rfinish();
+ return;
+ }
+
+ recvData.rfinish(); // Will still have compressed data in buffer.
+ }
+
sTicketMgr->AddTicket(ticket);
sTicketMgr->UpdateLastChange();
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index eb5c26a1c71..7fb518271cf 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -1061,12 +1061,9 @@ SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds(uint32 spell_id) const
return SpellAreaMapBounds(mSpellAreaMap.lower_bound(spell_id), mSpellAreaMap.upper_bound(spell_id));
}
-SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const
+SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds(uint32 quest_id) const
{
- if (active)
- return SpellAreaForQuestMapBounds(mSpellAreaForActiveQuestMap.lower_bound(quest_id), mSpellAreaForActiveQuestMap.upper_bound(quest_id));
- else
- return SpellAreaForQuestMapBounds(mSpellAreaForQuestMap.lower_bound(quest_id), mSpellAreaForQuestMap.upper_bound(quest_id));
+ return SpellAreaForQuestMapBounds(mSpellAreaForQuestMap.lower_bound(quest_id), mSpellAreaForQuestMap.upper_bound(quest_id));
}
SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const
@@ -1099,11 +1096,11 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
return false;
if (questStart) // not in expected required quest state
- if (!player || ((!questStartCanActive || !player->IsActiveQuest(questStart)) && !player->GetQuestRewardStatus(questStart)))
+ if (!player || (((1 << player->GetQuestStatus(questStart)) & questStartStatus) == 0))
return false;
if (questEnd) // not in expected forbidden quest state
- if (!player || player->GetQuestRewardStatus(questEnd))
+ if (!player || (((1 << player->GetQuestStatus(questEnd)) & questEndStatus) == 0))
return false;
if (auraSpell) // not have expected aura
@@ -2433,12 +2430,11 @@ void SpellMgr::LoadSpellAreas()
mSpellAreaMap.clear(); // need for reload case
mSpellAreaForQuestMap.clear();
- mSpellAreaForActiveQuestMap.clear();
mSpellAreaForQuestEndMap.clear();
mSpellAreaForAuraMap.clear();
- // 0 1 2 3 4 5 6 7 8
- QueryResult result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_active, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
+ // 0 1 2 3 4 5 6 7 8 9
+ QueryResult result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_status, quest_end_status, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
if (!result)
{
@@ -2457,12 +2453,13 @@ void SpellMgr::LoadSpellAreas()
spellArea.spellId = spell;
spellArea.areaId = fields[1].GetUInt32();
spellArea.questStart = fields[2].GetUInt32();
- spellArea.questStartCanActive = fields[3].GetBool();
- spellArea.questEnd = fields[4].GetUInt32();
- spellArea.auraSpell = fields[5].GetInt32();
- spellArea.raceMask = fields[6].GetUInt32();
- spellArea.gender = Gender(fields[7].GetUInt8());
- spellArea.autocast = fields[8].GetBool();
+ spellArea.questStartStatus = fields[3].GetUInt32();
+ spellArea.questEndStatus = fields[4].GetUInt32();
+ spellArea.questEnd = fields[5].GetUInt32();
+ spellArea.auraSpell = fields[6].GetInt32();
+ spellArea.raceMask = fields[7].GetUInt32();
+ spellArea.gender = Gender(fields[8].GetUInt8());
+ spellArea.autocast = fields[9].GetBool();
if (SpellInfo const* spellInfo = GetSpellInfo(spell))
{
@@ -2494,7 +2491,7 @@ void SpellMgr::LoadSpellAreas()
continue;
// duplicate by requirements
- ok =false;
+ ok = false;
break;
}
@@ -2524,12 +2521,6 @@ void SpellMgr::LoadSpellAreas()
sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_area` have wrong end quest (%u) requirement", spell, spellArea.questEnd);
continue;
}
-
- if (spellArea.questEnd == spellArea.questStart && !spellArea.questStartCanActive)
- {
- sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_area` have quest (%u) requirement for start and end in same time", spell, spellArea.questEnd);
- continue;
- }
}
if (spellArea.auraSpell)
@@ -2605,12 +2596,7 @@ void SpellMgr::LoadSpellAreas()
// for search at quest start/reward
if (spellArea.questStart)
- {
- if (spellArea.questStartCanActive)
- mSpellAreaForActiveQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
- else
- mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
- }
+ mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
// for search at quest start/reward
if (spellArea.questEnd)
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 9646bc9dabf..cec9d4650f5 100755
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -495,7 +495,8 @@ struct SpellArea
int32 auraSpell; // spell aura must be applied for spell apply)if possitive) and it must not be applied in other case
uint32 raceMask; // can be applied only to races
Gender gender; // can be applied only to gender
- bool questStartCanActive; // if true then quest start can be active (not only rewarded)
+ uint32 questStartStatus; // QuestStatus that quest_start must have in order to keep the spell
+ uint32 questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped)
bool autocast; // if true then auto applied at area enter, in other case just allowed to cast
// helpers
@@ -681,7 +682,7 @@ class SpellMgr
// Spell area
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const;
- SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const;
+ SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id) const;
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const;
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const;
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds(uint32 area_id) const;
@@ -740,7 +741,6 @@ class SpellMgr
EnchantCustomAttribute mEnchantCustomAttr;
SpellAreaMap mSpellAreaMap;
SpellAreaForQuestMap mSpellAreaForQuestMap;
- SpellAreaForQuestMap mSpellAreaForActiveQuestMap;
SpellAreaForQuestMap mSpellAreaForQuestEndMap;
SpellAreaForAuraMap mSpellAreaForAuraMap;
SpellAreaForAreaMap mSpellAreaForAreaMap;
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index 220d348fba2..334ed676660 100755..100644
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -31,7 +31,7 @@ inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; }
// GM ticket
GmTicket::GmTicket() { }
-GmTicket::GmTicket(Player* player, WorldPacket& recvData) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED)
+GmTicket::GmTicket(Player* player, WorldPacket& recvData) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _haveTicket(false)
{
_id = sTicketMgr->GenerateTicketId();
_playerName = player->GetName();
@@ -47,29 +47,16 @@ GmTicket::GmTicket(Player* player, WorldPacket& recvData) : _createTime(time(NUL
recvData >> _message;
uint32 needResponse;
recvData >> needResponse;
- _needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default)
- uint8 unk1;
- recvData >> unk1; // Requests further GM interaction on a ticket to which a GM has already responded
-
- recvData.rfinish();
- /*
- recvData >> count; // text lines
- for (int i = 0; i < count; i++)
- recvData >> uint32();
-
- if (something)
- recvData >> uint32();
- else
- compressed uint32 + string;
- */
+ _needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default)
+ recvData >> _haveTicket; // Requests further GM interaction on a ticket to which a GM has already responded. Basically means "has a new ticket"
}
GmTicket::~GmTicket() { }
bool GmTicket::LoadFromDB(Field* fields)
{
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- // ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ // ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket
uint8 index = 0;
_id = fields[ index].GetUInt32();
_playerGuid = MAKE_NEW_GUID(fields[++index].GetUInt32(), 0, HIGHGUID_PLAYER);
@@ -84,9 +71,11 @@ bool GmTicket::LoadFromDB(Field* fields)
_closedBy = fields[++index].GetInt32();
_assignedTo = MAKE_NEW_GUID(fields[++index].GetUInt32(), 0, HIGHGUID_PLAYER);
_comment = fields[++index].GetString();
+ _response = fields[++index].GetString();
_completed = fields[++index].GetBool();
_escalatedStatus = GMTicketEscalationStatus(fields[++index].GetUInt8());
_viewed = fields[++index].GetBool();
+ _haveTicket = fields[++index].GetBool();
return true;
}
@@ -109,9 +98,11 @@ void GmTicket::SaveToDB(SQLTransaction& trans) const
stmt->setInt32 (++index, GUID_LOPART(_closedBy));
stmt->setUInt32(++index, GUID_LOPART(_assignedTo));
stmt->setString(++index, _comment);
+ stmt->setString(++index, _response);
stmt->setBool (++index, _completed);
stmt->setUInt8 (++index, uint8(_escalatedStatus));
stmt->setBool (++index, _viewed);
+ stmt->setBool (++index, _haveTicket);
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
@@ -125,6 +116,10 @@ void GmTicket::DeleteFromDB()
void GmTicket::WritePacket(WorldPacket& data) const
{
+ data << uint32(GMTICKET_STATUS_HASTEXT);
+ data << uint32(_id);
+ data << _message;
+ data << uint8(_haveTicket);
data << GetAge(_lastModifiedTime);
if (GmTicket* ticket = sTicketMgr->GetOldestOpenTicket())
data << GetAge(ticket->GetLastModifiedTime());
@@ -223,6 +218,20 @@ void GmTicket::TeleportTo(Player* player) const
player->TeleportTo(_mapId, _posX, _posY, _posZ, 0.0f, 0);
}
+void GmTicket::SetChatLog(std::list<uint32> time, std::string const& log)
+{
+ std::stringstream ss(log);
+ std::stringstream newss;
+ std::string line;
+ while (std::getline(ss, line))
+ {
+ newss << secsToTimeString(time.front()) << ": " << line << "\n";
+ time.pop_front();
+ }
+
+ _chatLog = newss.str();
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
// Ticket manager
TicketMgr::TicketMgr() : _status(true), _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), _lastChange(time(NULL)) { }
@@ -365,27 +374,12 @@ void TicketMgr::ShowEscalatedList(ChatHandler& handler) const
void TicketMgr::SendTicket(WorldSession* session, GmTicket* ticket) const
{
- uint32 status = GMTICKET_STATUS_DEFAULT;
- std::string message;
- if (ticket)
- {
- message = ticket->GetMessage();
- status = GMTICKET_STATUS_HASTEXT;
- }
-
- WorldPacket data(SMSG_GMTICKET_GETTICKET, (4 + (ticket ? 4 + message.length() + 1 + 4 + 4 + 4 + 1 + 1 : 0)));
- data << uint32(status); // standard 0x0A, 0x06 if text present
+ WorldPacket data(SMSG_GMTICKET_GETTICKET, (ticket ? (4 + 4 + 1 + 4 + 4 + 4 + 1 + 1) : 4));
if (ticket)
- {
- data << uint32(ticket->GetId()); // ticketID
- data << message.c_str(); // ticket text
- data << uint8(0x7); // ticket category; why is this hardcoded? does it make a diff re: client?
-
- // we've got the easy stuff done by now.
- // Now we need to go through the client logic for displaying various levels of ticket load
ticket->WritePacket(data);
- }
+ else
+ data << uint32(GMTICKET_STATUS_DEFAULT);
session->SendPacket(&data);
}
diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h
index f8a5c527fae..63837e39452 100755
--- a/src/server/game/Tickets/TicketMgr.h
+++ b/src/server/game/Tickets/TicketMgr.h
@@ -142,6 +142,9 @@ public:
std::string FormatMessageString(ChatHandler& handler, bool detailed = false) const;
std::string FormatMessageString(ChatHandler& handler, const char* szClosedName, const char* szAssignedToName, const char* szUnassignedName, const char* szDeletedName) const;
+ void SetChatLog(std::list<uint32> time, std::string const& log);
+ std::string GetChatLog() const { return _chatLog; }
+
private:
uint32 _id;
uint64 _playerGuid;
@@ -160,7 +163,9 @@ private:
GMTicketEscalationStatus _escalatedStatus;
bool _viewed;
bool _needResponse; // TODO: find out the use of this, and then store it in DB
+ bool _haveTicket;
std::string _response;
+ std::string _chatLog; // No need to store in db, will be refreshed every session client side
};
typedef std::map<uint32, GmTicket*> GmTicketList;