diff --git a/sql/characters.sql b/sql/characters.sql index 2fcab08d6..698006470 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -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'; -- diff --git a/sql/mangos.sql b/sql/mangos.sql index 3ca31e14b..1ff76fc19 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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; diff --git a/sql/updates/9589_01_mangos_creature_template.sql b/sql/updates/9589_01_mangos_creature_template.sql new file mode 100644 index 000000000..9f45918e3 --- /dev/null +++ b/sql/updates/9589_01_mangos_creature_template.sql @@ -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'; diff --git a/sql/updates/9590_01_mangos_db_script_string.sql b/sql/updates/9590_01_mangos_db_script_string.sql new file mode 100644 index 000000000..f649300d4 --- /dev/null +++ b/sql/updates/9590_01_mangos_db_script_string.sql @@ -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'; diff --git a/sql/updates/9611_01_characters.sql b/sql/updates/9611_01_characters.sql new file mode 100644 index 000000000..94e97c3df --- /dev/null +++ b/sql/updates/9611_01_characters.sql @@ -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`); \ No newline at end of file diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index b4ecd65fa..792c2e2a1 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -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 diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index d682be5ed..5a61c4e93 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -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) { diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 4ab9a7ab2..b6a5e356d 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -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) ) diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index 4e3d61734..d68b54f8a 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -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!!! diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index 4f26b1394..f8a975192 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -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); } diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 7bc403df5..b9561045b 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -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); -} \ No newline at end of file +} diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index da7523ac8..bdf7c1304 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -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; diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 85ed0fbd2..338853cb4 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -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); diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 73352f669..b16e80115 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -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(); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 2ab304e0b..cd4123c73 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -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) diff --git a/src/game/Creature.h b/src/game/Creature.h index dfbcb771d..0ffd48d4d 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -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; } diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index d036e9909..ae0a67446 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -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) diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 6154967e2..0a8d0ee39 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -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 const* GetSoundEntriesStore() { return &sSoundEntriesStore; } MANGOS_DLL_SPEC DBCStorage const* GetSpellStore() { return &sSpellStore; } diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index b82d34382..e9cf95674 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -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); diff --git a/src/game/GMTicketMgr.cpp b/src/game/GMTicketMgr.cpp index 8166f290a..c76962f64 100644 --- a/src/game/GMTicketMgr.cpp +++ b/src/game/GMTicketMgr.cpp @@ -25,7 +25,6 @@ #include "ProgressBar.h" #include "Policies/SingletonImp.h" #include "Player.h" -#include "ObjectGuid.h" INSTANTIATE_SINGLETON_1(GMTicketMgr); diff --git a/src/game/GlobalEvents.cpp b/src/game/GlobalEvents.cpp index 7226364fb..910c68f2b 100644 --- a/src/game/GlobalEvents.cpp +++ b/src/game/GlobalEvents.cpp @@ -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 diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 252e4330e..10f6daf1b 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -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 diff --git a/src/game/Group.cpp b/src/game/Group.cpp index c794bb8ce..961b82a6d 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -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) diff --git a/src/game/Group.h b/src/game/Group.h index 504358b25..397363e3a 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -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: diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index a709db5ad..d447d5e57 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -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; } diff --git a/src/game/Guild.h b/src/game/Guild.h index f3d4184b9..06dd96772 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -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; diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp index caba6462c..8b4d450bc 100644 --- a/src/game/GuildHandler.cpp +++ b/src/game/GuildHandler.cpp @@ -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); } diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 69022ce56..cf3537543 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -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); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 91400aede..103b08a27 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -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); diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp index bd9fbc207..aaee87cb5 100644 --- a/src/game/Mail.cpp +++ b/src/game/Mail.cpp @@ -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. * diff --git a/src/game/Mail.h b/src/game/Mail.h index df45eddc4..c29b46451 100644 --- a/src/game/Mail.h +++ b/src/game/Mail.h @@ -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 MailItemMap; + /** + * Holds a Map of GUIDs of items and pointers to the items. + */ + typedef std::map 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; } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index a1e5a846a..5c2b74c27 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -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()); diff --git a/src/game/Map.h b/src/game/Map.h index bd6c0c952..b22cad16f 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -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); diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index 46263e2be..7e59bfd36 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -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; } diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h index d9a8c66b7..df2bb9834 100644 --- a/src/game/MapInstanced.h +++ b/src/game/MapInstanced.h @@ -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; diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index e3b37cdda..261d7a05b 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -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); diff --git a/src/game/MapManager.h b/src/game/MapManager.h index e9046d2b5..a72e30185 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -27,6 +27,7 @@ #include "GridStates.h" class Transport; +class BattleGround; class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton > { @@ -38,6 +39,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton(this)->_createBaseMap(id); } Map* FindMap(uint32 mapid, uint32 instanceId = 0) const; diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 786b12834..76b0282e1 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -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; } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index b6997b746..f863a4cff 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -44,6 +44,7 @@ #include "Util.h" #include "WaypointManager.h" #include "GossipDef.h" +#include "Mail.h" #include diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 8df515bc4..0cd054708 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -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" diff --git a/src/game/Player.cpp b/src/game/Player.cpp index b30e39ed9..e83b26fa0 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -60,6 +60,7 @@ #include "Spell.h" #include "SocialMgr.h" #include "AchievementMgr.h" +#include "Mail.h" #include @@ -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); + } +} \ No newline at end of file diff --git a/src/game/Player.h b/src/game/Player.h index e1bd8a22c..3f4515362 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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///////////////////// diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 18b4af6d2..3ee1892b5 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -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) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 9c7d8f88b..6db4481ab 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -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()) { diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b82df238b..5484b61f3 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -50,12 +50,13 @@ #include "MovementGenerator.h" #include +#include 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; } diff --git a/src/game/Unit.h b/src/game/Unit.h index 45dcdfb55..9aae2cb7f 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -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(); diff --git a/src/mangosd/MaNGOSsoap.cpp b/src/mangosd/MaNGOSsoap.cpp index fe358d28d..09ee0ed07 100644 --- a/src/mangosd/MaNGOSsoap.cpp +++ b/src/mangosd/MaNGOSsoap.cpp @@ -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 diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index a7e978531..9f8e32a7c 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -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"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4d15b819b..ad132966a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9585" + #define REVISION_NR "9612" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 82c8a6bfb..d76a2e8d2 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -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__