From 59e79dfef08dc328a3b3ece1fa67c547c2d893e6 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 29 Apr 2009 18:04:56 -0500 Subject: *let petattack command use provided guid instead of player selection. By thenecromancer --HG-- branch : trunk --- src/game/PetHandler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 456d68ed54d..6286ba40b74 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -107,8 +107,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) } // only place where pet can be player pet->clearUnitState(UNIT_STAT_FOLLOW); - uint64 selguid = _player->GetSelection(); - Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, selguid); + Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, guid2); if(!TargetUnit) return; -- cgit v1.2.3 From 98cda7714641d56bdb16bc01fbc3be6dd59c1be1 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 29 Apr 2009 18:10:00 -0500 Subject: *Cleanup InterruptNonMeleeSpells. Backported from TC2. Source: Mangos. --HG-- branch : trunk --- src/game/Unit.cpp | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 7b1ca779871..8d619f4922f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3485,40 +3485,16 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) { // generic spells are interrupted if they are not finished or delayed - Spell *spell = m_currentSpells[CURRENT_GENERIC_SPELL]; - if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id)) - { - m_currentSpells[CURRENT_GENERIC_SPELL] = NULL; - - if ( (spell->getState() != SPELL_STATE_FINISHED) && - (withDelayed || spell->getState() != SPELL_STATE_DELAYED) ) - spell->cancel(); - spell->SetReferencedFromCurrent(false); - } + if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id)) + InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed); - spell = m_currentSpells[CURRENT_AUTOREPEAT_SPELL]; // autorepeat spells are interrupted if they are not finished or delayed - if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id)) - { - m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL; - // send disable autorepeat packet in any case - if(GetTypeId()==TYPEID_PLAYER) - ((Player*)this)->SendAutoRepeatCancel(); - if ( (spell->getState() != SPELL_STATE_FINISHED) && - (withDelayed || spell->getState() != SPELL_STATE_DELAYED) ) - spell->cancel(); - spell->SetReferencedFromCurrent(false); - } + if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id)) + InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed); // channeled spells are interrupted if they are not finished, even if they are delayed - spell = m_currentSpells[CURRENT_CHANNELED_SPELL]; - if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id)) - { - m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL; - if (spell->getState() != SPELL_STATE_FINISHED) - spell->cancel(); - spell->SetReferencedFromCurrent(false); - } + if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id)) + InterruptSpell(CURRENT_CHANNELED_SPELL,true); } Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const -- cgit v1.2.3 From efd58033ea12f3380c2ff78ca1f7f0b6db368754 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 30 Apr 2009 09:58:34 -0500 Subject: *Use canattack to check if canattack in pethandler and combathandler --HG-- branch : trunk --- src/game/CombatHandler.cpp | 10 +--------- src/game/PetHandler.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/game/CombatHandler.cpp b/src/game/CombatHandler.cpp index fb212870822..f9fb4fd7ee0 100644 --- a/src/game/CombatHandler.cpp +++ b/src/game/CombatHandler.cpp @@ -50,7 +50,7 @@ void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data ) return; } - if(_player->IsFriendlyTo(pEnemy) || pEnemy->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) + if(!_player->canAttack(pEnemy)) { sLog.outError( "WORLD: Enemy %s %u is friendly",(IS_PLAYER_GUID(guid) ? "player" : "creature"),GUID_LOPART(guid)); @@ -59,14 +59,6 @@ void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data ) return; } - if(!pEnemy->isAlive()) - { - // client can generate swing to known dead target if autoswitch between autoshot and autohit is enabled in client options - // stop attack state at client - SendAttackStop(pEnemy); - return; - } - _player->Attack(pEnemy,true); } diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 6286ba40b74..932eb593ff8 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -105,19 +105,21 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) //TODO: Send proper error message to client return; } + // only place where pet can be player - pet->clearUnitState(UNIT_STAT_FOLLOW); Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, guid2); if(!TargetUnit) return; - // not let attack friendly units. - if(GetPlayer()->IsFriendlyTo(TargetUnit)) + if(!pet->canAttack(TargetUnit)) return; + // Not let attack through obstructions //if(!pet->IsWithinLOSInMap(TargetUnit)) // return; + pet->clearUnitState(UNIT_STAT_FOLLOW); + if(pet->GetTypeId() != TYPEID_PLAYER && ((Creature*)pet)->IsAIEnabled) { ((Creature*)pet)->AI()->AttackStart(TargetUnit); -- cgit v1.2.3 From a9f6f4481de5ae7db97bbfb6bfbb3f38e5627715 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 30 Apr 2009 09:59:16 -0500 Subject: *Do not allow client to interrupt instant spells. By thenecromancer --HG-- branch : trunk --- src/game/SpellHandler.cpp | 6 +----- src/game/Unit.cpp | 14 ++++++++------ src/game/Unit.h | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 3da05d37f3d..efa9c6feebd 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -339,12 +339,8 @@ void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket) uint32 spellId; recvPacket >> spellId; - //FIXME: hack, ignore unexpected client cancel Deadly Throw cast - if(spellId==26679) - return; - if(_player->IsNonMeleeSpellCasted(false)) - _player->InterruptNonMeleeSpells(false,spellId); + _player->InterruptNonMeleeSpells(false,spellId,false); } void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 8d619f4922f..1bda587f89e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3433,12 +3433,14 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell ) pSpell->SetReferencedFromCurrent(true); } -void Unit::InterruptSpell(uint32 spellType, bool withDelayed) +void Unit::InterruptSpell(uint32 spellType, bool withDelayed, bool withInstant) { assert(spellType < CURRENT_MAX_SPELL); Spell *spell = m_currentSpells[spellType]; - if(spell && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) ) + if(spell + && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) + && (withInstant || spell->GetCastTime() > 0)) { // for example, do not let self-stun aura interrupt itself if(!spell->IsInterruptable()) @@ -3482,19 +3484,19 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip return(false); } -void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) +void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id, bool withInstant) { // generic spells are interrupted if they are not finished or delayed if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id)) - InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed); + InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed,withInstant); // autorepeat spells are interrupted if they are not finished or delayed if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id)) - InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed); + InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed,withInstant); // channeled spells are interrupted if they are not finished, even if they are delayed if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id)) - InterruptSpell(CURRENT_CHANNELED_SPELL,true); + InterruptSpell(CURRENT_CHANNELED_SPELL,true,true); } Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const diff --git a/src/game/Unit.h b/src/game/Unit.h index 0179097de77..79fff7a7351 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1194,7 +1194,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SetCurrentCastedSpell(Spell * pSpell); virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } - void InterruptSpell(uint32 spellType, bool withDelayed = true); + void InterruptSpell(uint32 spellType, bool withDelayed = true, bool withInstant = true); // set withDelayed to true to account delayed spells as casted // delayed+channeled spells are always accounted as casted @@ -1203,7 +1203,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject // set withDelayed to true to interrupt delayed spells too // delayed+channeled spells are always interrupted - void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0); + void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0, bool withInstant = true); Spell* FindCurrentSpellBySpellId(uint32 spell_id) const; -- cgit v1.2.3 From 83758cb2e07be8c8dab9dffed0cbba760260f952 Mon Sep 17 00:00:00 2001 From: Chaz Brown Date: Thu, 30 Apr 2009 14:15:54 -0400 Subject: Prevent multiple bid attempts on the same item if BidsPerInterval set to a high number - patch submitted by Naicisum --HG-- branch : trunk --- src/game/AuctionHouseBot.cpp | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/game/AuctionHouseBot.cpp b/src/game/AuctionHouseBot.cpp index cb3244ee456..a212feb826d 100644 --- a/src/game/AuctionHouseBot.cpp +++ b/src/game/AuctionHouseBot.cpp @@ -503,14 +503,25 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World } } + uint32 bids = config->GetBidsPerInterval(); + for (uint32 count = 1;count <= bids;count++) + { + // Do we have anything to bid? If not, stop here. if(possibleBids.empty()) { + count = bids + 1; return; } // Choose random auction from possible auctions - uint32 auctionID = possibleBids[urand(0, possibleBids.size() - 1)]; + uint32 vectorPos = urand(0, possibleBids.size() - 1); + uint32 auctionID = possibleBids[vectorPos]; + + // Erase the auction from the vector to prevent bidding on item in next itteration. + vector::iterator iter = possibleBids.begin(); + advance(iter, vectorPos); + possibleBids.erase(iter); // from auctionhousehandler.cpp, creates auction pointer & player pointer AuctionEntry* auction = auctionHouse->GetAuction(auctionID); @@ -758,7 +769,7 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World auctionHouse->RemoveAuction(auction->Id); // Remove from database auction->DeleteFromDB(); - + } delete auction; } } @@ -781,33 +792,21 @@ void AuctionHouseBot() addNewAuctions(&_AHBplayer, &AllianceConfig); if (((_newrun - _lastrun_a) > (AllianceConfig.GetBiddingInterval() * 60)) && (AllianceConfig.GetBidsPerInterval() > 0)) { - uint32 bids = AllianceConfig.GetBidsPerInterval(); - for (uint32 count = 1;count <= bids;count++) - { - addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session); - _lastrun_a = _newrun; - } + addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session); + _lastrun_a = _newrun; } addNewAuctions(&_AHBplayer, &HordeConfig); if (((_newrun - _lastrun_h) > (HordeConfig.GetBiddingInterval() *60)) && (HordeConfig.GetBidsPerInterval() > 0)) { - uint32 bids = HordeConfig.GetBidsPerInterval(); - for (uint32 count = 1;count <= bids;count++) - { - addNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig, &_session); - _lastrun_h = _newrun; - } + addNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig, &_session); + _lastrun_h = _newrun; } } addNewAuctions(&_AHBplayer, &NeutralConfig); if (((_newrun - _lastrun_n) > (NeutralConfig.GetBiddingInterval() * 60)) && (NeutralConfig.GetBidsPerInterval() > 0)) { - uint32 bids = NeutralConfig.GetBidsPerInterval(); - for (uint32 count = 1;count <= bids;count++) - { - addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig, &_session); - _lastrun_n = _newrun; - } + addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig, &_session); + _lastrun_n = _newrun; } ObjectAccessor::Instance().RemoveObject(&_AHBplayer); } -- cgit v1.2.3 From eb9328e4dbd5e136728f90ae794da1066688953f Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 30 Apr 2009 16:13:57 -0500 Subject: *Fix the calculation of isInLine. --HG-- branch : trunk --- src/game/Object.cpp | 7 +++++++ src/game/Object.h | 1 + src/game/Unit.cpp | 7 +++---- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/game/Object.cpp b/src/game/Object.cpp index e7d07422c7a..fe3239e9d6b 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1153,6 +1153,13 @@ float WorldObject::GetDistance2d(float x, float y) const return ( dist > 0 ? dist : 0); } +float WorldObject::GetExactDistance2d(const float x, const float y) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + return sqrt((dx*dx) + (dy*dy)); +} + float WorldObject::GetDistance(const float x, const float y, const float z) const { float dx = GetPositionX() - x; diff --git a/src/game/Object.h b/src/game/Object.h index 3840337e437..328df30492a 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -438,6 +438,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object float GetDistanceSq(const float &x, const float &y, const float &z) const; float GetDistance2d(const WorldObject* obj) const; float GetDistance2d(const float x, const float y) const; + float GetExactDistance2d(const float x, const float y) const; float GetDistanceZ(const WorldObject* obj) const; bool IsInMap(const WorldObject* obj) const { return GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); } bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 1bda587f89e..756a1ac7d43 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3525,10 +3525,9 @@ bool Unit::isInBack(Unit const* target, float distance, float arc) const bool Unit::isInLine(Unit const* target, float distance) const { if(!HasInArc(M_PI, target) || !IsWithinDistInMap(target, distance)) return false; - float width = (GetObjectSize() / 2 + target->GetObjectSize()) / 2; - float angle = GetAngle(target); - angle -= GetOrientation(); - return abs(sin(angle)) * distance < width; + float width = GetObjectSize() + target->GetObjectSize() * 0.5f; + float angle = GetAngle(target) - GetOrientation(); + return abs(sin(angle)) * GetExactDistance2d(target->GetPositionX(), target->GetPositionY()) < width; } bool Unit::isInAccessiblePlaceFor(Creature const* c) const -- cgit v1.2.3