Merge remote branch 'origin/master' into 330

This commit is contained in:
tomrus88 2010-03-24 08:33:12 +03:00
commit 292f6189ea
50 changed files with 363 additions and 318 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` (
`required_9375_01_characters_character_glyphs` bit(1) default NULL
`required_9611_01_characters` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
--
@ -466,7 +466,8 @@ CREATE TABLE `character_equipmentsets` (
`item17` int(11) NOT NULL default '0',
`item18` int(11) NOT NULL default '0',
PRIMARY KEY (`setguid`),
UNIQUE KEY `idx_set` (`guid`,`setguid`,`setindex`)
UNIQUE KEY `idx_set` (`guid`,`setguid`,`setindex`),
INDEX `Idx_setindex` (`setindex`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@ -898,7 +899,9 @@ CREATE TABLE `corpse` (
`instance` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`guid`),
KEY `idx_type` (`corpse_type`),
KEY `instance` (`instance`)
KEY `instance` (`instance`),
INDEX `Idx_player`(`player`),
INDEX `Idx_time`(`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Death System';
--
@ -978,7 +981,8 @@ CREATE TABLE `group_member` (
`memberGuid` int(11) unsigned NOT NULL,
`assistant` tinyint(1) unsigned NOT NULL,
`subgroup` smallint(6) unsigned NOT NULL,
PRIMARY KEY (`groupId`,`memberGuid`)
PRIMARY KEY (`groupId`,`memberGuid`),
INDEX `Idx_memberGuid`(`memberGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Groups';
--
@ -1036,7 +1040,9 @@ CREATE TABLE `guild_bank_eventlog` (
`DestTabId` tinyint(1) unsigned NOT NULL default '0' COMMENT 'Destination Tab Id',
`TimeStamp` bigint(20) unsigned NOT NULL default '0' COMMENT 'Event UNIX time',
PRIMARY KEY (`guildid`,`LogGuid`,`TabId`),
KEY `guildid_key` (`guildid`)
KEY `guildid_key` (`guildid`),
INDEX `Idx_PlayerGuid`(`PlayerGuid`),
INDEX `Idx_LogGuid`(`LogGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@ -1060,7 +1066,8 @@ CREATE TABLE `guild_bank_item` (
`item_guid` int(11) unsigned NOT NULL default '0',
`item_entry` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`guildid`,`tabid`,`slotid`),
KEY `guildid_key` (`guildid`)
KEY `guildid_key` (`guildid`),
INDEX `Idx_item_guid`(`item_guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@ -1133,7 +1140,10 @@ CREATE TABLE `guild_eventlog` (
`PlayerGuid2` int(11) NOT NULL COMMENT 'Player 2',
`NewRank` tinyint(2) NOT NULL COMMENT 'New rank(in case promotion/demotion)',
`TimeStamp` bigint(20) NOT NULL COMMENT 'Event UNIX time',
PRIMARY KEY (`guildid`, `LogGuid`)
PRIMARY KEY (`guildid`, `LogGuid`),
INDEX `Idx_PlayerGuid1`(`PlayerGuid1`),
INDEX `Idx_PlayerGuid2`(`PlayerGuid2`),
INDEX `Idx_LogGuid`(`LogGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'Guild Eventlog';
--
@ -1195,7 +1205,8 @@ CREATE TABLE `guild_rank` (
`rname` varchar(255) NOT NULL default '',
`rights` int(3) unsigned NOT NULL default '0',
`BankMoneyPerDay` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`guildid`,`rid`)
PRIMARY KEY (`guildid`,`rid`),
INDEX `Idx_rid`(`rid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System';
--
@ -1453,7 +1464,9 @@ CREATE TABLE `petition_sign` (
`playerguid` int(11) unsigned NOT NULL default '0',
`player_account` int(11) unsigned NOT NULL default '0',
`type` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`petitionguid`,`playerguid`)
PRIMARY KEY (`petitionguid`,`playerguid`),
INDEX `Idx_playerguid`(`playerguid`),
INDEX `Idx_ownerguid`(`ownerguid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System';
--

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
`required_9539_01_mangos_spell_bonus_data` bit(1) default NULL
`required_9590_01_mangos_db_script_string` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -1098,7 +1098,8 @@ CREATE TABLE `creature_template` (
`faction_A` smallint(5) unsigned NOT NULL default '0',
`faction_H` smallint(5) unsigned NOT NULL default '0',
`npcflag` int(10) unsigned NOT NULL default '0',
`speed` float NOT NULL default '1',
`speed_walk` float NOT NULL default '1' COMMENT 'Result of 2.5/2.5, most common value',
`speed_run` float NOT NULL default '1.14286' COMMENT 'Result of 8.0/7.0, most common value',
`scale` float NOT NULL default '1',
`rank` tinyint(3) unsigned NOT NULL default '0',
`mindmg` float NOT NULL default '0',
@ -1165,7 +1166,7 @@ CREATE TABLE `creature_template` (
LOCK TABLES `creature_template` WRITE;
/*!40000 ALTER TABLE `creature_template` DISABLE KEYS */;
INSERT INTO `creature_template` VALUES
(1,0,0,0,0,0,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,0,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,1,2000,2200,8,4096,0,0,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1.0,1.0,0,0,0,0,0,0,0,0,1,0,0,0x82,'');
(1,0,0,0,0,0,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,0,1,1,64,64,0,0,5,35,35,0,0.91,1.14286,1,0,2,3,0,10,1,2000,2200,8,4096,0,0,0,0,0,0,1,2,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1,1,0,0,0,0,0,0,0,0,1,0,0,130,'');
/*!40000 ALTER TABLE `creature_template` ENABLE KEYS */;
UNLOCK TABLES;
@ -1200,7 +1201,7 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `db_script_string`;
CREATE TABLE `db_script_string` (
`entry` mediumint(8) unsigned NOT NULL default '0',
`entry` int(11) unsigned NOT NULL default '0',
`content_default` text NOT NULL,
`content_loc1` text,
`content_loc2` text,
@ -1972,22 +1973,22 @@ CREATE TABLE gossip_menu_option (
LOCK TABLES `gossip_menu_option` WRITE;
/*!40000 ALTER TABLE `gossip_menu_option` DISABLE KEYS */;
INSERT INTO gossip_menu_option VALUES
(0,0,0,'GOSSIP_OPTION_QUESTGIVER',2,2,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,1,1,'GOSSIP_OPTION_VENDOR',3,128,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,2,2,'GOSSIP_OPTION_TAXIVENDOR',4,8192,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,3,3,'GOSSIP_OPTION_TRAINER',5,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,4,4,'GOSSIP_OPTION_SPIRITHEALER',6,16384,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,5,4,'GOSSIP_OPTION_SPIRITGUIDE',7,32768,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,6,5,'GOSSIP_OPTION_INNKEEPER',8,65536,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,7,6,'GOSSIP_OPTION_BANKER',9,131072,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,8,7,'GOSSIP_OPTION_PETITIONER',10,262144,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,9,8,'GOSSIP_OPTION_TABARDDESIGNER',11,524288,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,10,9,'GOSSIP_OPTION_BATTLEFIELD',12,1048576,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,11,6,'GOSSIP_OPTION_AUCTIONEER',13,2097152,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,12,0,'GOSSIP_OPTION_STABLEPET',14,4194304,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,13,1,'GOSSIP_OPTION_ARMORER',15,4096,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,14,2,'GOSSIP_OPTION_UNLEARNTALENTS',16,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,15,2,'GOSSIP_OPTION_UNLEARNPETSKILLS',17,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0);
(0, 0,0,'GOSSIP_OPTION_QUESTGIVER', 2,0x000002,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 1,1,'GOSSIP_OPTION_VENDOR', 3,0x000080,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 2,2,'GOSSIP_OPTION_TAXIVENDOR', 4,0x002000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 3,3,'GOSSIP_OPTION_TRAINER', 5,0x000010,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 4,4,'GOSSIP_OPTION_SPIRITHEALER', 6,0x004000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 5,4,'GOSSIP_OPTION_SPIRITGUIDE', 7,0x008000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 6,5,'GOSSIP_OPTION_INNKEEPER', 8,0x010000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 7,6,'GOSSIP_OPTION_BANKER', 9,0x020000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 8,7,'GOSSIP_OPTION_PETITIONER', 10,0x040000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0, 9,8,'GOSSIP_OPTION_TABARDDESIGNER', 11,0x080000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,10,9,'GOSSIP_OPTION_BATTLEFIELD', 12,0x100000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,11,6,'GOSSIP_OPTION_AUCTIONEER', 13,0x200000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,12,0,'GOSSIP_OPTION_STABLEPET', 14,0x400000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,13,1,'GOSSIP_OPTION_ARMORER', 15,0x001000,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,14,2,'GOSSIP_OPTION_UNLEARNTALENTS', 16,0x000010,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0),
(0,15,2,'GOSSIP_OPTION_UNLEARNPETSKILLS',17,0x000010,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0);
/*!40000 ALTER TABLE `gossip_menu_option` ENABLE KEYS */;
UNLOCK TABLES;

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_9539_01_mangos_spell_bonus_data required_9589_01_mangos_creature_template bit;
ALTER TABLE creature_template ADD COLUMN speed_run float NOT NULL default '1.14286' COMMENT 'Result of 8.0/7.0, most common value' AFTER speed;
ALTER TABLE creature_template CHANGE COLUMN speed speed_walk float NOT NULL default '1' COMMENT 'Result of 2.5/2.5, most common value';

View file

@ -0,0 +1,3 @@
ALTER TABLE db_version CHANGE COLUMN required_9589_01_mangos_creature_template required_9590_01_mangos_db_script_string bit;
ALTER TABLE `db_script_string` CHANGE `entry` `entry` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0';

View file

@ -0,0 +1,15 @@
ALTER TABLE character_db_version CHANGE COLUMN required_9375_01_characters_character_glyphs required_9611_01_characters bit;
ALTER TABLE `group_member` ADD INDEX `Idx_memberGuid`(`memberGuid`);
ALTER TABLE `guild_eventlog` ADD INDEX `Idx_PlayerGuid1`(`PlayerGuid1`);
ALTER TABLE `guild_eventlog` ADD INDEX `Idx_PlayerGuid2`(`PlayerGuid2`);
ALTER TABLE `guild_bank_eventlog` ADD INDEX `Idx_PlayerGuid`(`PlayerGuid`);
ALTER TABLE `petition_sign` ADD INDEX `Idx_playerguid`(`playerguid`);
ALTER TABLE `petition_sign` ADD INDEX `Idx_ownerguid`(`ownerguid`);
ALTER TABLE `guild_eventlog` ADD INDEX `Idx_LogGuid`(`LogGuid`);
ALTER TABLE `guild_bank_eventlog` ADD INDEX `Idx_LogGuid`(`LogGuid`);
ALTER TABLE `guild_bank_item` ADD INDEX `Idx_item_guid`(`item_guid`);
ALTER TABLE `corpse` ADD INDEX `Idx_player`(`player`);
ALTER TABLE `corpse` ADD INDEX `Idx_time`(`time`);
ALTER TABLE `guild_rank` ADD INDEX `Idx_rid`(`rid`);
ALTER TABLE `character_equipmentsets` ADD INDEX `Idx_setindex` (`setindex`);

View file

@ -87,6 +87,9 @@ pkgdata_DATA = \
9526_01_mangos_spell_proc_event.sql \
9528_01_mangos_spell_bonus_data.sql \
9539_01_mangos_spell_bonus_data.sql \
9589_01_mangos_creature_template.sql \
9590_01_mangos_db_script_string.sql \
9611_01_characters.sql \
README
## Additional files to include when running 'make dist'
@ -154,4 +157,7 @@ EXTRA_DIST = \
9526_01_mangos_spell_proc_event.sql \
9528_01_mangos_spell_bonus_data.sql \
9539_01_mangos_spell_bonus_data.sql \
9589_01_mangos_creature_template.sql \
9590_01_mangos_db_script_string.sql \
9611_01_characters.sql \
README

View file

@ -29,6 +29,7 @@
#include "SpellMgr.h"
#include "ArenaTeam.h"
#include "ProgressBar.h"
#include "Mail.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
#include "Language.h"
@ -331,6 +332,9 @@ bool AchievementCriteriaRequirement::Meets(uint32 criteria_id, Player const* sou
if (!source->IsInWorld())
return false;
Map* map = source->GetMap();
// BattleGroundMap-class is instanceable, but no InstanceMap-class
if (map->IsBattleGroundOrArena())
return false;
if (!map->Instanceable())
{
sLog.outErrorDb("Achievement system call ACHIEVEMENT_CRITERIA_REQUIRE_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-instance map %u",
@ -1826,9 +1830,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
}
}
uint32 itemTextId = sObjectMgr.CreateItemText( text );
MailDraft draft(subject, itemTextId);
MailDraft draft(subject, text);
if(item)
{

View file

@ -47,9 +47,8 @@ AggressorAI::MoveInLineOfSight(Unit *u)
if( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return;
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() &&
( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) &&
u->isInAccessablePlaceFor(m_creature))
if (m_creature->CanInitiateAttack() && u->isTargetableForAttack() &&
m_creature->IsHostileTo(u) && u->isInAccessablePlaceFor(m_creature))
{
float attackRadius = m_creature->GetAttackDistance(u);
if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u) )

View file

@ -26,6 +26,7 @@
#include "Player.h"
#include "UpdateMask.h"
#include "AuctionHouseMgr.h"
#include "Mail.h"
#include "Util.h"
//please DO NOT use iterator++, because it is slower than ++iterator!!!

View file

@ -33,6 +33,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Mail.h"
#include "Policies/SingletonImp.h"
@ -134,9 +135,6 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction )
msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() );
//prepare mail data... :
uint32 itemTextId = sObjectMgr.CreateItemText( msgAuctionWonBody.str() );
// set owner to bidder (to prevent delete item with sender char deleting)
// owner in `data` will set at mail receive and item extracting
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
@ -152,7 +150,7 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction )
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
// will delete item or place to receiver mail list
MailDraft(msgAuctionWonSubject.str(), itemTextId)
MailDraft(msgAuctionWonSubject.str(), msgAuctionWonBody.str())
.AddItem(pItem)
.SendMailTo(MailReceiver(bidder,auction->bidder), auction, MAIL_CHECK_MASK_AUCTION);
}
@ -189,9 +187,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry * auction )
sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
uint32 itemTextId = sObjectMgr.CreateItemText( msgAuctionSalePendingBody.str() );
MailDraft(msgAuctionSalePendingSubject.str(), itemTextId)
MailDraft(msgAuctionSalePendingSubject.str(), msgAuctionSalePendingBody.str())
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_AUCTION);
}
}
@ -222,8 +218,6 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
uint32 itemTextId = sObjectMgr.CreateItemText( auctionSuccessfulBody.str() );
uint32 profit = auction->bid + auction->deposit - auctionCut;
if (owner)
@ -235,7 +229,7 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
owner->GetSession()->SendAuctionOwnerNotification( auction );
}
MailDraft(msgAuctionSuccessfulSubject.str(), itemTextId)
MailDraft(msgAuctionSuccessfulSubject.str(), auctionSuccessfulBody.str())
.AddMoney(profit)
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_AUCTION, HOUR);
}

View file

@ -29,6 +29,7 @@
#include "Group.h"
#include "ObjectGuid.h"
#include "ObjectMgr.h"
#include "Mail.h"
#include "WorldPacket.h"
#include "Util.h"
#include "Formulas.h"
@ -208,7 +209,6 @@ void BattleGround::BroadcastWorker(Do& _do)
BattleGround::BattleGround()
{
m_TypeID = BattleGroundTypeId(0);
m_InstanceID = 0;
m_Status = STATUS_NONE;
m_ClientInstanceID = 0;
m_EndTime = 0;
@ -226,7 +226,6 @@ BattleGround::BattleGround()
m_LevelMin = 0;
m_LevelMax = 0;
m_InBGFreeSlotQueue = false;
m_SetDeleteThis = false;
m_MaxPlayersPerTeam = 0;
m_MaxPlayers = 0;
@ -297,6 +296,7 @@ BattleGround::~BattleGround()
}
sBattleGroundMgr.RemoveBattleGround(GetInstanceID(), GetTypeID());
sBattleGroundMgr.DeleteClientVisibleInstanceId(GetTypeID(), GetBracketId(), GetClientInstanceID());
// unload map
// map can be null at bg destruction
@ -325,7 +325,8 @@ void BattleGround::Update(uint32 diff)
// ]]
// BattleGround Template instance cannot be updated, because it would be deleted
if (!GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE))
m_SetDeleteThis = true;
delete this;
return;
}
@ -965,7 +966,7 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName());
uint32 itemTextId = sObjectMgr.CreateItemText( textBuf );
MailDraft(subject, itemTextId)
MailDraft(subject, textBuf)
.AddItem(markItem)
.SendMailTo(plr, MailSender(MAIL_CREATURE, bmEntry));
}
@ -1326,10 +1327,9 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
{
// set to be able to re-add if needed
m_InBGFreeSlotQueue = false;
// uncomment this code when battlegrounds will work like instances
for (BGFreeSlotQueueType::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)
{
if ((*itr)->GetInstanceID() == m_InstanceID)
if ((*itr)->GetInstanceID() == GetInstanceID())
{
sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].erase(itr);
return;
@ -1840,4 +1840,4 @@ void BattleGround::SetBracket( PvPDifficultyEntry const* bracketEntry )
{
m_BracketId = bracketEntry->GetBracketId();
SetLevelRange(bracketEntry->minLevel,bracketEntry->maxLevel);
}
}

View file

@ -21,6 +21,7 @@
#include "Common.h"
#include "SharedDefines.h"
#include "Map.h"
// magic event-numbers
#define BG_EVENT_NONE 255
@ -298,7 +299,9 @@ class BattleGround
char const* GetName() const { return m_Name; }
BattleGroundTypeId GetTypeID() const { return m_TypeID; }
BattleGroundBracketId GetBracketId() const { return m_BracketId; }
uint32 GetInstanceID() const { return m_InstanceID; }
// the instanceId check is also used to determine a bg-template
// that's why the m_map hack is here..
uint32 GetInstanceID() { return m_Map?GetBgMap()->GetInstanceId():0; }
BattleGroundStatus GetStatus() const { return m_Status; }
uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
uint32 GetStartTime() const { return m_StartTime; }
@ -323,7 +326,6 @@ class BattleGround
void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
//here we can count minlevel and maxlevel for players
void SetBracket(PvPDifficultyEntry const* bracketEntry);
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
void SetStatus(BattleGroundStatus Status) { m_Status = Status; }
void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
void SetStartTime(uint32 Time) { m_StartTime = Time; }
@ -514,8 +516,6 @@ class BattleGround
uint32 GetOtherTeam(uint32 teamId){ return (teamId) ? ((teamId == ALLIANCE) ? HORDE : ALLIANCE) : 0; }
bool IsPlayerInBattleGround(uint64 guid);
void SetDeleteThis() {m_SetDeleteThis = true;}
/* virtual score-array - get's used in bg-subclasses */
int32 m_TeamScores[BG_TEAMS_COUNT];
@ -562,7 +562,6 @@ class BattleGround
private:
/* Battleground */
BattleGroundTypeId m_TypeID;
uint32 m_InstanceID; //BattleGround Instance's GUID!
BattleGroundStatus m_Status;
uint32 m_ClientInstanceID; //the instance-id which is sent to the client and without any other internal use
uint32 m_StartTime;
@ -571,7 +570,6 @@ class BattleGround
BattleGroundBracketId m_BracketId;
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
bool m_IsArena;
uint8 m_Winner; // 0=alliance, 1=horde, 2=none
int32 m_StartDelayTime;

View file

@ -1138,55 +1138,21 @@ BattleGroundMgr::~BattleGroundMgr()
void BattleGroundMgr::DeleteAllBattleGrounds()
{
// will also delete template bgs:
for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
{
for(BattleGroundSet::iterator itr = m_BattleGrounds[i].begin(); itr != m_BattleGrounds[i].end();)
{
BattleGround * bg = itr->second;
m_BattleGrounds[i].erase(itr++);
if (!m_ClientBattleGroundIds[i][bg->GetBracketId()].empty())
m_ClientBattleGroundIds[i][bg->GetBracketId()].erase(bg->GetClientInstanceID());
itr++;
delete bg;
}
}
// destroy template battlegrounds that listed only in queues (other already terminated)
for(uint32 bgTypeId = 0; bgTypeId < MAX_BATTLEGROUND_TYPE_ID; ++bgTypeId)
{
// ~BattleGround call unregistring BG from queue
while(!BGFreeSlotQueue[bgTypeId].empty())
delete BGFreeSlotQueue[bgTypeId].front();
}
}
// used to update running battlegrounds, and delete finished ones
void BattleGroundMgr::Update(uint32 diff)
{
BattleGroundSet::iterator itr, next;
for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
{
itr = m_BattleGrounds[i].begin();
// skip updating battleground template
if (itr != m_BattleGrounds[i].end())
++itr;
for(; itr != m_BattleGrounds[i].end(); itr = next)
{
next = itr;
++next;
itr->second->Update(diff);
// use the SetDeleteThis variable
// direct deletion caused crashes
if (itr->second->m_SetDeleteThis)
{
BattleGround * bg = itr->second;
m_BattleGrounds[i].erase(itr);
if (!m_ClientBattleGroundIds[i][bg->GetBracketId()].empty())
m_ClientBattleGroundIds[i][bg->GetBracketId()].erase(bg->GetClientInstanceID());
delete bg;
}
}
}
// update scheduled queues
if (!m_QueueUpdateScheduler.empty())
{
@ -1576,8 +1542,9 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
return 0;
}
// generate a new instance id
bg->SetInstanceID(sMapMgr.GenerateInstanceId()); // set instance id
// will also set m_bgMap, instanceid
sMapMgr.CreateBgMap(bg->GetMapId(), bg);
bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, bracketEntry->GetBracketId()));
// reset the new bg (set status to status_wait_queue from status_none)
@ -1617,7 +1584,6 @@ uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsA
bg->SetMapId(MapID);
bg->SetTypeID(bgTypeId);
bg->SetInstanceID(0);
bg->SetArenaorBGType(IsArena);
bg->SetMinPlayersPerTeam(MinPlayersPerTeam);
bg->SetMaxPlayersPerTeam(MaxPlayersPerTeam);

View file

@ -211,6 +211,11 @@ class BattleGroundMgr
void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id);
void DeleteClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint32 clientInstanceID)
{
if (!m_ClientBattleGroundIds[bgTypeId][bracket_id].empty())
m_ClientBattleGroundIds[bgTypeId][bracket_id].erase(clientInstanceID);
}
void CreateInitialBattleGrounds();
void DeleteAllBattleGrounds();

View file

@ -263,9 +263,10 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
SetSpeedRate(MOVE_WALK, cinfo->speed);
SetSpeedRate(MOVE_RUN, cinfo->speed);
SetSpeedRate(MOVE_SWIM, cinfo->speed);
SetSpeedRate(MOVE_WALK, cinfo->speed_walk);
SetSpeedRate(MOVE_RUN, cinfo->speed_run);
SetSpeedRate(MOVE_SWIM, 1.0f); // using 1.0 rate
SetSpeedRate(MOVE_FLIGHT, 1.0f); // using 1.0 rate
SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale);
@ -1633,6 +1634,20 @@ bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /
return true;
}
bool Creature::CanInitiateAttack()
{
if (hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
return false;
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
return false;
if (isPassiveToHostile())
return false;
return true;
}
void Creature::SaveRespawnTime()
{
if(isPet() || !m_DBTableGuid)

View file

@ -81,7 +81,8 @@ struct CreatureInfo
uint32 faction_A;
uint32 faction_H;
uint32 npcflag;
float speed;
float speed_walk;
float speed_run;
float scale;
uint32 rank;
float mindmg;
@ -555,6 +556,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; }
bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const;
bool CanInitiateAttack();
MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }

View file

@ -875,6 +875,13 @@ void CreatureEventAI::JustDied(Unit* killer)
{
Reset();
if (m_creature->isGuard())
{
//Send Zone Under Attack message to the LocalDefense and WorldDefense Channels
if (Player* pKiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
m_creature->SendZoneUnderAttackMessage(pKiller);
}
if (bEmptyList)
return;
@ -1022,7 +1029,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
if (m_creature->isCivilian() || m_creature->IsNeutralToAll())
return;
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && who->isTargetableForAttack() &&
if (m_creature->CanInitiateAttack() && who->isTargetableForAttack() &&
m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature))
{
if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)

View file

@ -837,6 +837,51 @@ uint32 const* GetTalentTabPages(uint32 cls)
return sTalentTabPages[cls];
}
bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta)
{
if (mapid != atEntry->mapid)
return false;
if (atEntry->radius > 0)
{
// if we have radius check it
float dist2 = (x-atEntry->x)*(x-atEntry->x) + (y-atEntry->y)*(y-atEntry->y) + (z-atEntry->z)*(z-atEntry->z);
if(dist2 > (atEntry->radius + delta)*(atEntry->radius + delta))
return false;
}
else
{
// we have only extent
// rotate the players position instead of rotating the whole cube, that way we can make a simplified
// is-in-cube check and we have to calculate only one point instead of 4
// 2PI = 360°, keep in mind that ingame orientation is counter-clockwise
double rotation = 2*M_PI-atEntry->box_orientation;
double sinVal = sin(rotation);
double cosVal = cos(rotation);
float playerBoxDistX = x - atEntry->x;
float playerBoxDistY = y - atEntry->y;
float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY*sinVal);
float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX*sinVal);
// box edges are parallel to coordiante axis, so we can treat every dimension independently :D
float dz = z - atEntry->z;
float dx = rotPlayerX - atEntry->x;
float dy = rotPlayerY - atEntry->y;
if( (fabs(dx) > atEntry->box_x/2 + delta) ||
(fabs(dy) > atEntry->box_y/2 + delta) ||
(fabs(dz) > atEntry->box_z/2 + delta) )
{
return false;
}
}
return true;
}
// script support functions
MANGOS_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; }
MANGOS_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore() { return &sSpellStore; }

View file

@ -63,6 +63,8 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta = 0.0f);
PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id);

View file

@ -25,7 +25,6 @@
#include "ProgressBar.h"
#include "Policies/SingletonImp.h"
#include "Player.h"
#include "ObjectGuid.h"
INSTANTIATE_SINGLETON_1(GMTicketMgr);

View file

@ -75,7 +75,7 @@ static void CorpsesErase(bool bones,uint32 delay)
{
///- Get the list of eligible corpses/bones to be removed
//No SQL injection (uint32 and enum)
CharacterDatabase.AsyncPQuery(&CorpsesEraseCallBack, bones, "SELECT guid,position_x,position_y,map,player FROM corpse WHERE UNIX_TIMESTAMP()-time > '%u' AND corpse_type %s '0'", delay, (bones ? "=" : "<>"));
CharacterDatabase.AsyncPQuery(&CorpsesEraseCallBack, bones, "SELECT guid,position_x,position_y,map,player FROM corpse WHERE time < (UNIX_TIMESTAMP()+'%u') AND corpse_type %s '0'", delay, (bones ? "=" : "<>"));
}
/// not thread guarded variant for call from other thread

View file

@ -147,7 +147,7 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target)
return;
//Check targets for not_selectable unit flag and remove
if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE))
return;
// Evade target

View file

@ -711,7 +711,7 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI,
Roll::PlayerVote::iterator itr = roll->playerVote.find(playerGUID.GetRawValue());
// this condition means that player joins to the party after roll begins
if (itr == roll->playerVote.end())
return false;
return true; // result used for need iterator ++, so avoid for end of list
if (roll->getLoot())
if (roll->getLoot()->items.empty())
@ -1246,12 +1246,15 @@ void Group::_setLeader(const uint64 &guid)
void Group::_removeRolls(const uint64 &guid)
{
for (Rolls::iterator it = RollId.begin(); it < RollId.end(); )
for (Rolls::iterator it = RollId.begin(); it != RollId.end(); )
{
Roll* roll = *it;
Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid);
if(itr2 == roll->playerVote.end())
{
++it;
continue;
}
if (itr2->second == GREED || itr2->second == DISENCHANT)
--roll->totalGreed;
@ -1641,11 +1644,8 @@ InstanceGroupBind* Group::GetBoundInstance(Player* player)
return NULL;
}
InstanceGroupBind* Group::GetBoundInstance(Map* aMap)
InstanceGroupBind* Group::GetBoundInstance(Map* aMap, Difficulty difficulty)
{
// Currently spawn numbering not different from map difficulty
Difficulty difficulty = GetDifficulty(aMap->IsRaid());
// some instances only have one difficulty
MapDifficulty const* mapDiff = GetMapDifficultyData(aMap->GetId(),difficulty);
if(!mapDiff)

View file

@ -328,7 +328,7 @@ class MANGOS_DLL_SPEC Group
InstanceGroupBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false);
void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false);
InstanceGroupBind* GetBoundInstance(Player* player);
InstanceGroupBind* GetBoundInstance(Map* aMap);
InstanceGroupBind* GetBoundInstance(Map* aMap, Difficulty difficulty);
BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; }
protected:

View file

@ -41,9 +41,7 @@ Guild::Guild()
m_BorderColor = 0;
m_BackgroundColor = 0;
m_CreatedYear = 0;
m_CreatedMonth = 0;
m_CreatedDay = 0;
m_CreatedDate = time(0);
m_GuildBankMoney = 0;
m_PurchasedTabs = 0;
@ -224,21 +222,13 @@ bool Guild::LoadGuildFromDB(QueryResult *guildDataResult)
m_BackgroundColor = fields[7].GetUInt32();
GINFO = fields[8].GetCppString();
MOTD = fields[9].GetCppString();
time_t time = fields[10].GetUInt64();
m_CreatedDate = fields[10].GetUInt64();
m_GuildBankMoney = fields[11].GetUInt64();
m_PurchasedTabs = fields[12].GetUInt32();
if (m_PurchasedTabs > GUILD_BANK_MAX_TABS)
m_PurchasedTabs = GUILD_BANK_MAX_TABS;
if (time > 0)
{
tm local = *(localtime(&time)); // dereference and assign
m_CreatedDay = local.tm_mday;
m_CreatedMonth = local.tm_mon + 1;
m_CreatedYear = local.tm_year + 1900;
}
return true;
}

View file

@ -301,9 +301,7 @@ class Guild
std::string const& GetMOTD() const { return MOTD; }
std::string const& GetGINFO() const { return GINFO; }
uint32 GetCreatedYear() const { return m_CreatedYear; }
uint32 GetCreatedMonth() const { return m_CreatedMonth; }
uint32 GetCreatedDay() const { return m_CreatedDay; }
time_t GetCreatedDate() const { return m_CreatedDate; }
uint32 GetEmblemStyle() const { return m_EmblemStyle; }
uint32 GetEmblemColor() const { return m_EmblemColor; }
@ -437,9 +435,7 @@ class Guild
uint64 m_LeaderGuid;
std::string MOTD;
std::string GINFO;
uint32 m_CreatedYear;
uint32 m_CreatedMonth;
uint32 m_CreatedDay;
time_t m_CreatedDate;
uint32 m_EmblemStyle;
uint32 m_EmblemColor;

View file

@ -226,13 +226,11 @@ void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/)
return;
}
WorldPacket data(SMSG_GUILD_INFO, (5*4 + guild->GetName().size() + 1));
WorldPacket data(SMSG_GUILD_INFO, (guild->GetName().size() + 4 + 4 + 4));
data << guild->GetName();
data << guild->GetCreatedDay();
data << guild->GetCreatedMonth();
data << guild->GetCreatedYear();
data << guild->GetMemberSize();
data << guild->GetMemberSize();
data << uint32(secsToTimeBitFields(guild->GetCreatedDate())); // 3.x (prev. day + month + year)
data << uint32(guild->GetMemberSize()); // amount of chars
data << uint32(guild->GetMemberSize()); // amount of accounts (TODO: implement)
SendPacket(&data);
}

View file

@ -31,6 +31,7 @@
#include "Language.h"
#include "CellImpl.h"
#include "InstanceSaveMgr.h"
#include "Mail.h"
#include "Util.h"
#ifdef _DEBUG_VMAPS
#include "VMapFactory.h"
@ -1978,9 +1979,7 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
// from console show not existed sender
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
uint32 itemTextId = !text.empty() ? sObjectMgr.CreateItemText( text ) : 0;
MailDraft(subject, itemTextId)
MailDraft(subject, text)
.SendMailTo(MailReceiver(target,GUID_LOPART(target_guid)),sender);
std::string nameLink = playerLink(target_name);

View file

@ -44,6 +44,7 @@
#include "SkillExtraItems.h"
#include "SystemConfig.h"
#include "Config/ConfigEnv.h"
#include "Mail.h"
#include "Util.h"
#include "ItemEnchantmentMgr.h"
#include "BattleGroundMgr.h"
@ -6297,10 +6298,8 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
// from console show not existed sender
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
uint32 itemTextId = !text.empty() ? sObjectMgr.CreateItemText( text ) : 0;
// fill mail
MailDraft draft(subject, itemTextId);
MailDraft draft(subject, text);
for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
{
@ -6357,9 +6356,7 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
// from console show not existed sender
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
uint32 itemTextId = !text.empty() ? sObjectMgr.CreateItemText( text ) : 0;
MailDraft(subject, itemTextId)
MailDraft(subject, text)
.AddMoney(money)
.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);

View file

@ -907,6 +907,19 @@ MailReceiver::MailReceiver( Player* receiver,uint32 receiver_lowguid ) : m_recei
{
ASSERT(!receiver || receiver->GetGUIDLow() == receiver_lowguid);
}
/**
* Creates a new MailDraft object using subject and contect texts.
*
* @param subject The subject of the mail.
* @param itemText The text of the body of the mail.
*/
MailDraft::MailDraft( std::string subject, std::string text ) : m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject),
m_bodyId(!text.empty() ? sObjectMgr.CreateItemText(text) : 0), m_money(0), m_COD(0)
{
}
/**
* Adds an item to the MailDraft.
*

View file

@ -109,15 +109,15 @@ enum MailAuctionAnswers
class MailSender
{
public: // Constructors
/**
* Creates a new MailSender object.
*
* @param messageType the type of the mail.
* @param sender_guidlow_or_entry The lower part of the GUID of the player sending
* this mail, or the Entry of the non-player object.
* @param stationery The stationary associated with this MailSender.
*
*/
/**
* Creates a new MailSender object.
*
* @param messageType the type of the mail.
* @param sender_guidlow_or_entry The lower part of the GUID of the player sending
* this mail, or the Entry of the non-player object.
* @param stationery The stationary associated with this MailSender.
*
*/
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_NORMAL)
: m_messageType(messageType), m_senderId(sender_guidlow_or_entry), m_stationery(stationery)
{
@ -170,30 +170,37 @@ class MailReceiver
*/
class MailDraft
{
/**
* Holds a Map of GUIDs of items and pointers to the items.
*/
typedef std::map<uint32, Item*> MailItemMap;
/**
* Holds a Map of GUIDs of items and pointers to the items.
*/
typedef std::map<uint32, Item*> MailItemMap;
public: // Constructors
/**
* Creates a new MailDraft object.
*
* @param mailTemplateId The ID of the Template to be used.
* @param a boolean specifying whether the mail needs items or not.
*
*/
/**
* Creates a new MailDraft object using mail template id.
*
* @param mailTemplateId The ID of the Template to be used.
* @param a boolean specifying whether the mail needs items or not.
*
*/
explicit MailDraft(uint16 mailTemplateId, bool need_items = true)
: m_mailTemplateId(mailTemplateId), m_mailTemplateItemsNeed(need_items), m_bodyId(0), m_money(0), m_COD(0)
{}
/**
* Creates a new MailDraft object.
* Creates a new MailDraft object using subject text and content text id.
*
* @param subject The subject of the mail.
* @param itemTextId The id of the body of the mail.
*/
MailDraft(std::string subject, uint32 itemTextId = 0)
: m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_bodyId(itemTextId), m_money(0), m_COD(0) {}
/**
* Creates a new MailDraft object using subject and contect texts.
*
* @param subject The subject of the mail.
* @param itemText The text of the body of the mail.
*/
MailDraft(std::string subject, std::string text);
public: // Accessors
/// Returns the template ID used for this MailDraft.
uint16 GetMailTemplateId() const { return m_mailTemplateId; }

View file

@ -39,6 +39,7 @@
#include "MapInstanced.h"
#include "InstanceSaveMgr.h"
#include "VMapFactory.h"
#include "BattleGroundMgr.h"
GridState* si_GridStates[MAX_GRID_STATE];
@ -2450,7 +2451,7 @@ bool InstanceMap::Add(Player *player)
if(pGroup)
{
// solo saves should be reset when entering a group
InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this);
InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this,GetDifficulty());
if(playerBind)
{
sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
@ -2527,6 +2528,13 @@ void InstanceMap::Update(const uint32& t_diff)
i_data->Update(t_diff);
}
void BattleGroundMap::Update(const uint32& diff)
{
Map::Update(diff);
GetBG()->Update(diff);
}
void InstanceMap::Remove(Player *player, bool remove)
{
sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());

View file

@ -576,6 +576,7 @@ class MANGOS_DLL_SPEC BattleGroundMap : public Map
BattleGroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode);
~BattleGroundMap();
void Update(const uint32&);
bool Add(Player *);
void Remove(Player *, bool);
bool CanEnter(Player* player);

View file

@ -104,11 +104,8 @@ void MapInstanced::UnloadAll(bool pForce)
Map::UnloadAll(pForce);
}
/*
- return the right instance for the object, based on its InstanceId
- create the instance if it's not created already
- the player is not actually added to the instance (only in InstanceMap::Add)
*/
/// returns a new or existing Instance
/// in case of battlegrounds it will only return an existing map, those maps are created by bg-system
Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
{
if(GetId() != mapId || !player)
@ -119,13 +116,11 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
if(IsBattleGroundOrArena())
{
// instantiate or find existing bg map for player
// the instance id is set in battlegroundid
// find existing bg map for player
NewInstanceId = player->GetBattleGroundId();
ASSERT(NewInstanceId);
map = _FindMap(NewInstanceId);
if(!map)
map = CreateBattleGroundMap(NewInstanceId, player->GetBattleGround());
ASSERT(map);
}
else
{
@ -139,7 +134,7 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
InstanceGroupBind *groupBind = NULL;
Group *group = player->GetGroup();
// use the player's difficulty setting (it may not be the same as the group's)
if(group && (groupBind = group->GetBoundInstance(this)))
if(group && (groupBind = group->GetBoundInstance(this,player->GetDifficulty(IsRaid()))))
pSave = groupBind->save;
}

View file

@ -58,11 +58,11 @@ class MANGOS_DLL_DECL MapInstanced : public Map
InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; }
virtual void InitVisibilityDistance();
BattleGroundMap* CreateBattleGroundMap(uint32 InstanceId, BattleGround* bg);
private:
InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty);
BattleGroundMap* CreateBattleGroundMap(uint32 InstanceId, BattleGround* bg);
InstancedMaps m_InstancedMaps;

View file

@ -138,6 +138,13 @@ Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
return m;
}
Map* MapManager::CreateBgMap(uint32 mapid, BattleGround* bg)
{
Map *m = _createBaseMap(mapid);
((MapInstanced*)m)->CreateBattleGroundMap(sMapMgr.GenerateInstanceId(), bg);
return m;
}
Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) const
{
Map *map = _findMap(mapid);

View file

@ -27,6 +27,7 @@
#include "GridStates.h"
class Transport;
class BattleGround;
class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockable<MapManager, ACE_Thread_Mutex> >
{
@ -38,6 +39,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
public:
Map* CreateMap(uint32, const WorldObject* obj);
Map* CreateBgMap(uint32 mapid, BattleGround* bg);
Map const* CreateBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_createBaseMap(id); }
Map* FindMap(uint32 mapid, uint32 instanceId = 0) const;

View file

@ -696,92 +696,43 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
return;
}
if (GetPlayer()->GetMapId() != atEntry->mapid)
{
sLog.outDebug("Player '%s' (GUID: %u) too far (trigger map: %u player map: %u), ignore Area Trigger ID: %u", GetPlayer()->GetName(), atEntry->mapid, GetPlayer()->GetMapId(), GetPlayer()->GetGUIDLow(), Trigger_ID);
return;
}
// delta is safe radius
const float delta = 5.0f;
// check if player in the range of areatrigger
Player* pl = GetPlayer();
if (atEntry->radius > 0)
if (!IsPointInAreaTriggerZone(atEntry, pl->GetMapId(), pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), delta))
{
// if we have radius check it
float dist = pl->GetDistance(atEntry->x, atEntry->y, atEntry->z);
if(dist > atEntry->radius + delta)
{
sLog.outDebug("Player '%s' (GUID: %u) too far (radius: %f distance: %f), ignore Area Trigger ID: %u",
pl->GetName(), pl->GetGUIDLow(), atEntry->radius, dist, Trigger_ID);
return;
}
}
else
{
// we have only extent
// rotate the players position instead of rotating the whole cube, that way we can make a simplified
// is-in-cube check and we have to calculate only one point instead of 4
// 2PI = 360°, keep in mind that ingame orientation is counter-clockwise
double rotation = 2*M_PI-atEntry->box_orientation;
double sinVal = sin(rotation);
double cosVal = cos(rotation);
float playerBoxDistX = pl->GetPositionX() - atEntry->x;
float playerBoxDistY = pl->GetPositionY() - atEntry->y;
float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY*sinVal);
float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX*sinVal);
// box edges are parallel to coordiante axis, so we can treat every dimension independently :D
float dz = pl->GetPositionZ() - atEntry->z;
float dx = rotPlayerX - atEntry->x;
float dy = rotPlayerY - atEntry->y;
if( (fabs(dx) > atEntry->box_x/2 + delta) ||
(fabs(dy) > atEntry->box_y/2 + delta) ||
(fabs(dz) > atEntry->box_z/2 + delta) )
{
sLog.outDebug("Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %f 1/2 box Z: %f rotatedPlayerX: %f rotatedPlayerY: %f dZ:%f), ignore Area Trigger ID: %u",
pl->GetName(), pl->GetGUIDLow(), atEntry->box_x/2, atEntry->box_y/2, atEntry->box_z/2, rotPlayerX, rotPlayerY, dz, Trigger_ID);
return;
}
sLog.outDebug("Player '%s' (GUID: %u) too far, ignore Area Trigger ID: %u", pl->GetName(), pl->GetGUIDLow(), Trigger_ID);
return;
}
if(Script->scriptAreaTrigger(GetPlayer(), atEntry))
if(Script->scriptAreaTrigger(pl, atEntry))
return;
uint32 quest_id = sObjectMgr.GetQuestForAreaTrigger( Trigger_ID );
if( quest_id && GetPlayer()->isAlive() && GetPlayer()->IsActiveQuest(quest_id) )
if( quest_id && pl->isAlive() && pl->IsActiveQuest(quest_id) )
{
Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id);
if( pQuest )
{
if(GetPlayer()->GetQuestStatus(quest_id) == QUEST_STATUS_INCOMPLETE)
GetPlayer()->AreaExploredOrEventHappens( quest_id );
if(pl->GetQuestStatus(quest_id) == QUEST_STATUS_INCOMPLETE)
pl->AreaExploredOrEventHappens( quest_id );
}
}
if(sObjectMgr.IsTavernAreaTrigger(Trigger_ID))
// enter to tavern, not overwrite city rest
if(sObjectMgr.IsTavernAreaTrigger(Trigger_ID) && pl->GetRestType() != REST_TYPE_IN_CITY)
{
// set resting flag we are in the inn
GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
GetPlayer()->InnEnter(time(NULL), atEntry->mapid, atEntry->x, atEntry->y, atEntry->z);
GetPlayer()->SetRestType(REST_TYPE_IN_TAVERN);
if(sWorld.IsFFAPvPRealm())
GetPlayer()->SetFFAPvP(false);
pl->SetRestType(REST_TYPE_IN_TAVERN, Trigger_ID);
return;
}
if(GetPlayer()->InBattleGround())
if(pl->InBattleGround())
{
BattleGround* bg = GetPlayer()->GetBattleGround();
if(bg)
bg->HandleAreaTrigger(GetPlayer(), Trigger_ID);
if (BattleGround* bg = pl->GetBattleGround())
bg->HandleAreaTrigger(pl, Trigger_ID);
return;
}

View file

@ -44,6 +44,7 @@
#include "Util.h"
#include "WaypointManager.h"
#include "GossipDef.h"
#include "Mail.h"
#include <limits>

View file

@ -31,7 +31,6 @@
#include "ItemPrototype.h"
#include "NPCHandler.h"
#include "Database/DatabaseEnv.h"
#include "Mail.h"
#include "Map.h"
#include "ObjectAccessor.h"
#include "ObjectGuid.h"

View file

@ -60,6 +60,7 @@
#include "Spell.h"
#include "SocialMgr.h"
#include "AchievementMgr.h"
#include "Mail.h"
#include <cmath>
@ -431,10 +432,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
////////////////////Rest System/////////////////////
time_inn_enter=0;
inn_pos_mapid=0;
inn_pos_x=0;
inn_pos_y=0;
inn_pos_z=0;
inn_trigger_id=0;
m_rest_bonus=0;
rest_type=REST_TYPE_NO;
////////////////////Rest System/////////////////////
@ -1246,7 +1244,7 @@ void Player::Update( uint32 p_time )
if (time_inn >= 10) //freeze update
{
float bubble = 0.125f*sWorld.getConfig(CONFIG_FLOAT_RATE_REST_INGAME);
//speed collect rest bonus (section/in hour)
//speed collect rest bonus (section/in hour)
SetRestBonus( float(GetRestBonus()+ time_inn*(GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble ));
UpdateInnerTime(time(NULL));
}
@ -4130,8 +4128,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE PlayerGuid2 = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid);
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid);
CharacterDatabase.CommitTransaction();
@ -6487,38 +6484,19 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
}
if(zone->flags & AREA_FLAG_CAPITAL) // in capital city
{
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
SetRestType(REST_TYPE_IN_CITY);
InnEnter(time(0),GetMapId(),0,0,0);
if(sWorld.IsFFAPvPRealm())
SetFFAPvP(false);
}
else // anywhere else
{
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) // but resting (walk from city or maybe in tavern or leave tavern recently)
if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) // but resting (walk from city or maybe in tavern or leave tavern recently)
{
if(GetRestType()==REST_TYPE_IN_TAVERN) // has been in tavern. Is still in?
if (GetRestType()==REST_TYPE_IN_TAVERN) // has been in tavern. Is still in?
{
if(GetMapId()!=GetInnPosMapId() || sqrt((GetPositionX()-GetInnPosX())*(GetPositionX()-GetInnPosX())+(GetPositionY()-GetInnPosY())*(GetPositionY()-GetInnPosY())+(GetPositionZ()-GetInnPosZ())*(GetPositionZ()-GetInnPosZ()))>40)
{
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(inn_trigger_id);
if (!at || !IsPointInAreaTriggerZone(at, GetMapId(), GetPositionX(), GetPositionY(), GetPositionY()))
SetRestType(REST_TYPE_NO);
if(sWorld.IsFFAPvPRealm())
SetFFAPvP(true);
}
}
else // not in tavern (leave city then)
{
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
SetRestType(REST_TYPE_NO);
// Set player to FFA PVP when not in rested environment.
if(sWorld.IsFFAPvPRealm())
SetFFAPvP(true);
}
}
}
@ -19384,9 +19362,9 @@ void Player::SendAurasForTarget(Unit *target)
else
data << uint8(aura->GetStackAmount());
if(!(auraFlags & AFLAG_NOT_CASTER))
if(!(auraFlags & AFLAG_NOT_CASTER)) // packed GUID of caster
{
data << uint8(0); // packed GUID of someone (caster?)
data.appendPackGUID(aura->GetCasterGUID());
}
if(auraFlags & AFLAG_DURATION) // include aura duration
@ -21753,3 +21731,27 @@ Object* Player::GetObjectByTypeMask(ObjectGuid guid, TypeMask typemask)
return NULL;
}
void Player::SetRestType( RestType n_r_type, uint32 areaTriggerId /*= 0*/)
{
rest_type = n_r_type;
if (rest_type == REST_TYPE_NO)
{
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
// Set player to FFA PVP when not in rested environment.
if(sWorld.IsFFAPvPRealm())
SetFFAPvP(true);
}
else
{
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
inn_trigger_id = areaTriggerId;
time_inn_enter = time(NULL);
if(sWorld.IsFFAPvPRealm())
SetFFAPvP(false);
}
}

View file

@ -1103,25 +1103,11 @@ class MANGOS_DLL_SPEC Player : public Unit
void setDeathState(DeathState s); // overwrite Unit::setDeathState
void InnEnter (time_t time, uint32 mapid, float x, float y, float z)
{
inn_pos_mapid = mapid;
inn_pos_x = x;
inn_pos_y = y;
inn_pos_z = z;
time_inn_enter = time;
}
float GetRestBonus() const { return m_rest_bonus; }
void SetRestBonus(float rest_bonus_new);
RestType GetRestType() const { return rest_type; }
void SetRestType(RestType n_r_type) { rest_type = n_r_type; }
uint32 GetInnPosMapId() const { return inn_pos_mapid; }
float GetInnPosX() const { return inn_pos_x; }
float GetInnPosY() const { return inn_pos_y; }
float GetInnPosZ() const { return inn_pos_z; }
void SetRestType(RestType n_r_type, uint32 areaTriggerId = 0);
time_t GetTimeInnEnter() const { return time_inn_enter; }
void UpdateInnerTime (time_t time) { time_inn_enter = time; }
@ -2476,10 +2462,7 @@ class MANGOS_DLL_SPEC Player : public Unit
////////////////////Rest System/////////////////////
time_t time_inn_enter;
uint32 inn_pos_mapid;
float inn_pos_x;
float inn_pos_y;
float inn_pos_z;
uint32 inn_trigger_id;
float m_rest_bonus;
RestType rest_type;
////////////////////Rest System/////////////////////

View file

@ -1249,7 +1249,7 @@ void Aura::SendAuraUpdate(bool remove)
if(!(auraFlags & AFLAG_NOT_CASTER))
{
data << uint8(0); // pguid
data.appendPackGUID(GetCasterGUID());
}
if(auraFlags & AFLAG_DURATION)

View file

@ -3379,6 +3379,7 @@ void Spell::EffectEnergize(SpellEffectIndex eff_idx)
case 31930: // Judgements of the Wise
case 48542: // Revitalize (mana restore case)
case 63375: // Improved Stormstrike
case 68082: // Glyph of Seal of Command
damage = damage * unitTarget->GetCreateMana() / 100;
break;
default:
@ -3863,6 +3864,7 @@ void Spell::DoSummon(SpellEffectIndex eff_idx)
m_caster->GetClosePoint(x, y, z, spawnCreature->GetObjectSize());
spawnCreature->Relocate(x, y, z, -m_caster->GetOrientation());
spawnCreature->SetSummonPoint(x, y, z, -m_caster->GetOrientation());
if (!spawnCreature->IsPositionValid())
{
@ -4280,6 +4282,7 @@ void Spell::DoSummonGuardian(SpellEffectIndex eff_idx, uint32 forceFaction)
m_caster->GetClosePoint(px, py, pz,spawnCreature->GetObjectSize());
spawnCreature->Relocate(px, py, pz, m_caster->GetOrientation());
spawnCreature->SetSummonPoint(px, py, pz, m_caster->GetOrientation());
if (!spawnCreature->IsPositionValid())
{
@ -6372,6 +6375,7 @@ void Spell::DoSummonTotem(SpellEffectIndex eff_idx, uint8 slot_dbc)
z = m_caster->GetPositionZ();
pTotem->Relocate(x, y, z, m_caster->GetOrientation());
pTotem->SetSummonPoint(x, y, z, m_caster->GetOrientation());
if (slot < MAX_TOTEM_SLOT)
m_caster->_AddTotem(TotemSlot(slot),pTotem);
@ -6876,6 +6880,7 @@ void Spell::DoSummonCritter(SpellEffectIndex eff_idx, uint32 forceFaction)
m_caster->GetClosePoint(x, y, z, critter->GetObjectSize());
critter->Relocate(x, y, z, m_caster->GetOrientation());
critter->SetSummonPoint(x, y, z, m_caster->GetOrientation());
if(!critter->IsPositionValid())
{

View file

@ -50,12 +50,13 @@
#include "MovementGenerator.h"
#include <math.h>
#include <varargs.h>
float baseMoveSpeed[MAX_MOVE_TYPE] =
{
2.5f, // MOVE_WALK
7.0f, // MOVE_RUN
1.25f, // MOVE_RUN_BACK
2.5f, // MOVE_RUN_BACK
4.722222f, // MOVE_SWIM
4.5f, // MOVE_SWIM_BACK
3.141594f, // MOVE_TURN_RATE
@ -343,8 +344,12 @@ bool Unit::haveOffhandWeapon() const
return false;
}
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineType type, SplineFlags flags, uint32 Time, Player* player)
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineType type, SplineFlags flags, uint32 Time, Player* player, ...)
{
va_list vargs;
va_start(vargs,player);
float moveTime = (float)Time;
WorldPacket data( SMSG_MONSTER_MOVE, (41 + GetPackGUID().size()) );
@ -359,30 +364,36 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineTy
case SPLINETYPE_NORMAL: // normal packet
break;
case SPLINETYPE_STOP: // stop packet (raw pos?)
va_end(vargs);
SendMessageToSet( &data, true );
return;
case SPLINETYPE_FACINGSPOT: // facing spot, not used currently
data << float(0);
data << float(0);
data << float(0);
{
data << float(va_arg(vargs,float));
data << float(va_arg(vargs,float));
data << float(va_arg(vargs,float));
break;
}
case SPLINETYPE_FACINGTARGET:
data << uint64(m_InteractionObject); // set in SetFacingToObject()
data << uint64(va_arg(vargs,uint64));
break;
case SPLINETYPE_FACINGANGLE: // not used currently
data << float(0); // facing angle
data << float(va_arg(vargs,float)); // facing angle
break;
}
data << uint32(flags);
if(flags & SPLINEFLAG_WALKMODE)
moveTime *= 1.05f;
// enable me if things goes wrong or looks ugly, it is however an old hack
// if(flags & SPLINEFLAG_WALKMODE)
// moveTime *= 1.05f;
data << uint32(moveTime); // Time in between points
data << uint32(1); // 1 single waypoint
data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
va_end(vargs);
if(player)
player->GetSession()->SendPacket(&data);
else
@ -3514,12 +3525,10 @@ void Unit::SetFacingToObject(WorldObject* pObject)
if (!IsStopped())
return;
m_InteractionObject = pObject->GetGUID();
// TODO: figure out under what conditions creature will move towards object instead of facing it where it currently is.
SetOrientation(GetAngle(pObject));
SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), SPLINETYPE_FACINGTARGET, ((Creature*)this)->GetSplineFlags(), 0);
SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), SPLINETYPE_FACINGTARGET, ((Creature*)this)->GetSplineFlags(), 0, NULL, pObject->GetGUID());
}
bool Unit::isInAccessablePlaceFor(Creature const* c) const
@ -10288,6 +10297,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
if (creatureNotInCombat)
{
// should probably be removed for the attacked (+ it's party/group) only, not global
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
if (((Creature*)this)->AI())
@ -11185,11 +11195,13 @@ bool Unit::SelectHostileTarget()
// No taunt aura or taunt aura caster is dead standart target selection
target = m_ThreatManager.getHostileTarget();
if(target)
if (target)
{
if(!hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
if (!hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
{
SetInFront(target);
((Creature*)this)->AI()->AttackStart(target);
((Creature*)this)->AI()->AttackStart(target);
}
return true;
}

View file

@ -545,8 +545,8 @@ enum UnitFlags
UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP
UNIT_FLAG_UNK_6 = 0x00000040,
UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
UNIT_FLAG_OOC_NOT_ATTACKABLE = 0x00000100, // 2.0.8 - (OOC Out Of Combat) Can not be attacked when not in combat. Removed if unit for some reason enter combat.
UNIT_FLAG_UNK_9 = 0x00000200, // 3.0.3 - makes you unable to attack everything
UNIT_FLAG_OOC_NOT_ATTACKABLE = 0x00000100, // 2.0.8 - (OOC Out Of Combat) Can not be attacked when not in combat. Removed if unit for some reason enter combat (flag probably removed for the attacked and it's party/group only)
UNIT_FLAG_PASSIVE = 0x00000200, // 3.0.3 - makes you unable to attack everything. Almost identical to our "civilian"-term. Will ignore it's surroundings and not engage in combat unless "called upon" or engaged by another unit.
UNIT_FLAG_LOOTING = 0x00000400, // loot animation
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8
UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
@ -1342,6 +1342,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage);
bool isTargetableForAttack(bool inversAlive = false) const;
bool isPassiveToHostile() { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); }
virtual bool IsInWater() const;
virtual bool IsUnderWater() const;
bool isInAccessablePlaceFor(Creature const* c) const;
@ -1374,7 +1376,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void MonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0);
// recommend use MonsterMove/MonsterMoveWithSpeed for most case that correctly work with movegens
void SendMonsterMove(float x, float y, float z, SplineType type, SplineFlags flags, uint32 Time, Player* player = NULL);
void SendMonsterMove(float x, float y, float z, SplineType type, SplineFlags flags, uint32 Time, Player* player = NULL, ...);
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, SplineFlags flags);
void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
@ -1850,8 +1852,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
uint32 m_regenTimer;
uint32 m_lastManaUseTimer;
uint64 m_InteractionObject;
private:
void CleanupDeletedAuras();

View file

@ -29,6 +29,8 @@ void MaNGOSsoapRunnable::run()
struct soap soap;
int m, s;
soap_init(&soap);
soap_set_imode(&soap, SOAP_C_UTFSTRING);
soap_set_omode(&soap, SOAP_C_UTFSTRING);
m = soap_bind(&soap, m_host.c_str(), m_port, 100);
// check every 3 seconds if world ended

View file

@ -25,8 +25,8 @@ extern DatabasePostgre WorldDatabase;
extern DatabaseMysql WorldDatabase;
#endif
const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis";
const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii";
const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis";
const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii";
const char CreatureDataAddonInfofmt[]="iiiiiis";
const char CreatureModelfmt[]="iffbi";
const char CreatureInfoAddonInfofmt[]="iiiiiis";

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9585"
#define REVISION_NR "9612"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_9375_01_characters_character_glyphs"
#define REVISION_DB_MANGOS "required_9539_01_mangos_spell_bonus_data"
#define REVISION_DB_CHARACTERS "required_9611_01_characters"
#define REVISION_DB_MANGOS "required_9590_01_mangos_db_script_string"
#define REVISION_DB_REALMD "required_9010_01_realmd_realmlist"
#endif // __REVISION_SQL_H__