Index: src/framework/Platform/Define.h =================================================================== --- src/framework/Platform/Define.h (revision 4656) +++ src/framework/Platform/Define.h (working copy) @@ -31,6 +31,7 @@ #define MANGOS_IMPORT __cdecl #define MANGOS_SCRIPT_EXT ".dll" #define MANGOS_SCRIPT_NAME "MaNGOSScript" +#define MANGOS_TIER_SCRIPT_NAME "Script" #define SIGQUIT 3 #else #define MANGOS_LIBRARY_HANDLE void* Index: src/game/AuctionHouse.cpp =================================================================== --- src/game/AuctionHouse.cpp (revision 4656) +++ src/game/AuctionHouse.cpp (working copy) @@ -228,6 +228,10 @@ if (!item || !bid || !etime) return; //check for cheaters + //DM Aleajecta + SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); + return; + Creature *pCreature = ObjectAccessor::Instance().GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { @@ -347,7 +351,7 @@ AuctionEntry *auction = mAuctions->GetAuction(auctionId); Player *pl = GetPlayer(); - if ((auction) && (auction->owner != pl->GetGUIDLow())) + if ((auction) /*&& (auction->owner != pl->GetGUIDLow())*/) { if (price < (auction->bid + objmgr.GetAuctionOutBid(auction->bid))) { @@ -372,6 +376,8 @@ else { // mail to last bidder and return money + //SendAuctionOutbiddedMail( auction , price ); + //pl->ModifyMoney(((int32) price) * -1); SendAuctionOutbiddedMail( auction , price ); pl->ModifyMoney( -int32(price) ); } @@ -380,13 +386,21 @@ { pl->ModifyMoney( -int32(price) ); } - auction->bidder = pl->GetGUIDLow(); - auction->bid = price; + //auction->bidder = pl->GetGUIDLow(); + //auction->bid = price; // after this update we should save player's money ... - sDatabase.PExecute("UPDATE `auctionhouse` SET `buyguid` = '%u',`lastbid` = '%u' WHERE `id` = '%u'", auction->bidder, auction->bid, auction->Id); - - SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0 ); + //sDatabase.PExecute("UPDATE `auctionhouse` SET `buyguid` = '%u',`lastbid` = '%u' WHERE `id` = '%u'", auction->bidder, auction->bid, auction->Id); + uint16 dest; + ItemPrototype const *pProto = objmgr.GetItemPrototype( auction->item_template ); + + if( pl->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, auction->item_template, pProto->Stackable, false ) == EQUIP_ERR_OK ) + { + pl->StoreNewItem( dest, auction->item_template, pProto->Stackable, true, Item::GenerateItemRandomPropertyId(auction->item_template)); + SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0 ); + } + else + SendAuctionCommandResult(auction->Id, AUCTION_INTERNAL_ERROR, AUCTION_OK); } else { Index: src/game/Chat.cpp =================================================================== --- src/game/Chat.cpp (revision 4656) +++ src/game/Chat.cpp (working copy) @@ -379,7 +379,7 @@ { "setvalue", SEC_ADMINISTRATOR, &ChatHandler::HandleSetValue, "", NULL }, { "getvalue", SEC_ADMINISTRATOR, &ChatHandler::HandleGetValue, "", NULL }, { "Mod32Value", SEC_ADMINISTRATOR, &ChatHandler::HandleMod32Value, "", NULL }, - + { "fillauction", SEC_ADMINISTRATOR, &ChatHandler::HandleFillAuctionHouse, "", NULL }, { NULL, 0, NULL, "", NULL } }; Index: src/game/Chat.h =================================================================== --- src/game/Chat.h (revision 4656) +++ src/game/Chat.h (working copy) @@ -322,6 +322,7 @@ bool HandleRemoveQuest(const char * args); bool HandleSaveAllCommand(const char* args); bool HandleGetItemState(const char * args); + bool HandleFillAuctionHouse(const char * args); Player* getSelectedPlayer(); Creature* getSelectedCreature(); Index: src/game/Creature.cpp =================================================================== --- src/game/Creature.cpp (revision 4656) +++ src/game/Creature.cpp (working copy) @@ -36,6 +36,7 @@ #include "SpellAuras.h" #include "WaypointMovementGenerator.h" #include "InstanceData.h" +#include "spell.h" // apply implementation of the singletons #include "Policies/SingletonImp.h" @@ -55,10 +56,9 @@ for(int i =0; i<4; ++i) m_spells[i] = 0; - m_CreatureSpellCooldowns.clear(); m_CreatureCategoryCooldowns.clear(); m_GlobalCooldown = 0; - + m_creatureSpellBook = NULL; m_AlreadyCallAssistence = false; } @@ -304,7 +304,7 @@ addvalue = uint32(Spirit * 0.80 * HealthIncreaseRate); } else - addvalue = maxValue/3; + addvalue = maxValue/150; ModifyHealth(addvalue); } @@ -1649,10 +1649,9 @@ { if( !m_AlreadyCallAssistence && getVictim() ) { - CastSpell(this,SPELL_ID_AGGRO, true, NULL, NULL, getVictim()->GetGUID()); + //CastSpell(this,SPELL_ID_AGGRO, true, NULL, NULL, getVictim()->GetGUID()); } } - void Creature::SaveRespawnTime() { if(isPet()) @@ -1764,14 +1763,37 @@ if(!spellInfo) return; - uint32 cooldown = spellInfo->CategoryRecoveryTime > spellInfo->RecoveryTime ? spellInfo->CategoryRecoveryTime : spellInfo->RecoveryTime; + uint32 cooldown = 0; + + if(m_creatureSpellBook) + { + CreatureSpellInfoMap::iterator _info = m_creatureSpellBook->info.begin(); + for(;_info != m_creatureSpellBook->info.end(); ++_info) + { + if( _info->second.id == spellid ) + { + cooldown = _info->second.recoveryTime; + break; + } + } + } + + if(!cooldown) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); + if(!spellInfo) + return; + + cooldown = spellInfo->CategoryRecoveryTime > spellInfo->RecoveryTime ? spellInfo->CategoryRecoveryTime : spellInfo->RecoveryTime; + } + if(cooldown) _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/1000); if(spellInfo->Category) _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL)); - m_GlobalCooldown = 1500; + m_GlobalCooldown = 1500; // We Should Add A Rate, so we Control a little, Strenght Of Spell Casting } bool Creature::HasCategoryCooldown(uint32 spell_id) const @@ -1784,10 +1806,13 @@ return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / 1000)) > time(NULL)); } -bool Creature::HasSpellCooldown(uint32 spell_id) const +bool Creature::HasSpellCooldown(uint32 spell_id,uint32 addTime) const { + if(!spell_id) + return m_GlobalCooldown > 0; + CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id); - return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || m_GlobalCooldown > 0 || HasCategoryCooldown(spell_id); + return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)+addTime) || m_GlobalCooldown > 0 || HasCategoryCooldown(spell_id); } bool Creature::IsInEvadeMode() const @@ -1803,3 +1828,158 @@ break; return i < CREATURE_MAX_SPELLS; //broke before end of iteration of known spells } + +void Creature::LoadSpellInfo() +{ + if(m_creatureSpellBook) + delete m_creatureSpellBook; + + QueryResult* _result = sDatabase.PQuery("SELECT * FROM creature_spellbook WHERE entry=%u",GetEntry()); + if(_result) + { + Field *_spellInfo = _result->Fetch(); + char* _spellId = NULL; + + m_creatureSpellBook = new CreatureSpellBook(); + //spellId, recoveryTime, unknow1, buffDuration, cost, rangeMin, rangeMax + for(uint8 itr = CREATURE_SPELL_MIN; itr < CREATURE_SPELL_MAX; ++itr) + { + const char* rawSpellInfo = _spellInfo[itr+1].GetString(); + _spellId = strtok((char*)rawSpellInfo, " "); + if( _spellId ) + { + uint32 spellId = m_creatureSpellBook->info[itr].id = atoi(_spellId); + + char* _recoveryTime = strtok(NULL, " "); + if(_recoveryTime) + m_creatureSpellBook->info[itr].recoveryTime = atoi(_recoveryTime); + char* _castingTime = strtok(NULL, " "); + if(_castingTime) + m_creatureSpellBook->info[itr].unknow1 = atoi(_castingTime); + char* _buffDuration = strtok(NULL, " "); + if(_buffDuration) + m_creatureSpellBook->info[itr].buffDuration = atoi(_buffDuration); + char* _cost = strtok(NULL, " "); + if(_cost) + m_creatureSpellBook->info[itr].cost = atoi(_cost); + char* _rangeMin = strtok(NULL, " "); + if(_rangeMin) + m_creatureSpellBook->info[itr].range[0] = atof(_rangeMin); + char* _rangeMax = strtok(NULL, " "); + if(_rangeMax) + m_creatureSpellBook->info[itr].range[1] = atof(_rangeMax); + } + } + delete _result; + + SpellEntry const* dbcSpell; + SpellRangeEntry const *dbcRange; + SpellDurationEntry const * dbcDuration; + SpellCastTimesEntry const *dbcCastTime; + + CreatureSpellInfoMap::iterator itr = m_creatureSpellBook->info.begin(); + if(itr == m_creatureSpellBook->info.end()) + return; + + for(; itr != m_creatureSpellBook->info.end(); ++itr) + { + dbcSpell = GetSpellStore()->LookupEntry(itr->second.id); + if( !dbcSpell ) + continue; + dbcRange = GetSpellRangeStore()->LookupEntry(dbcSpell->rangeIndex); + dbcDuration = GetSpellDurationStore()->LookupEntry(dbcSpell->DurationIndex); + dbcCastTime = GetCastTimesStore()->LookupEntry(dbcSpell->CastingTimeIndex); + + for (int j=0; j<3; j++) + { + //Spell targets self + if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF ) + itr->second.targets |= 1 << (SELECT_TARGET_SELF-1); + + //Spell targets a single enemy + if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE || + dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY ) + itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1); + + //Spell targets AoE at enemy + if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA || + dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || + dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED ) + itr->second.targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1); + + //Spell targets an enemy + if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE || + dbcSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY || + dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA || + dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || + dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED ) + itr->second.targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1); + + //Spell targets a single friend(or self) + if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF || + dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND || + dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ) + itr->second.targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1); + + //Spell targets aoe friends + if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER || + dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ) + itr->second.targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1); + + //Spell targets any friend(or self) + if ( dbcSpell->EffectImplicitTargetA[j] == TARGET_SELF || + dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND || + dbcSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY || + dbcSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER || + dbcSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ) + itr->second.targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1); + + //Make sure that this spell includes a damage effect + if ( dbcSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || + dbcSpell->Effect[j] == SPELL_EFFECT_INSTAKILL || + dbcSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE || + dbcSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ) + itr->second.effects |= 1 << (SELECT_EFFECT_DAMAGE-1); + + //Make sure that this spell includes a healing effect + if ( dbcSpell->Effect[j] == SPELL_EFFECT_HEAL || + dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH || + dbcSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL ) + itr->second.effects |= 1 << (SELECT_EFFECT_HEALING-1); + + //Make sure that this spell applies an aura + if( dbcSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA ) + itr->second.effects |= 1 << (SELECT_EFFECT_AURA-1); + + // Buff Duration + if( dbcDuration && itr->second.buffDuration < dbcDuration->Duration[j] )//DBC Info Not Good + itr->second.buffDuration = dbcDuration->Duration[j]; + } + + //We use powerCost from SQL on missing DBC value + if( dbcSpell->manaCost ) + { + itr->second.usingDBC = true; + itr->second.cost = dbcSpell->manaCost; + } + + //CoolDown + if( !itr->second.recoveryTime && dbcSpell->RecoveryTime ) + itr->second.recoveryTime = dbcSpell->RecoveryTime; + + if(dbcRange) + { + //Range Min + if( !itr->second.range[0] ) + itr->second.range[0] = dbcRange->minRange; + //Range Max + if( !itr->second.range[1] )//DBC Info Not Good + itr->second.range[1] = dbcRange->maxRange; + } + + //Casttime + if(dbcCastTime && dbcCastTime->CastTime) + itr->second.isDelayed = true; + } + } +} Index: src/game/Creature.h =================================================================== --- src/game/Creature.h (revision 4656) +++ src/game/Creature.h (working copy) @@ -269,6 +269,116 @@ uint32 modelid_other_gender; }; +enum CreatureSpellSelectTarget +{ + SELECT_TARGET_DONTCARE = 0, //All target types allowed + + SELECT_TARGET_SELF, //Only Self casting + + SELECT_TARGET_SINGLE_ENEMY, //Only Single Enemy + SELECT_TARGET_AOE_ENEMY, //Only AoE Enemy + SELECT_TARGET_ANY_ENEMY, //AoE or Single Enemy + + SELECT_TARGET_SINGLE_FRIEND, //Only Single Friend + SELECT_TARGET_AOE_FRIEND, //Only AoE Friend + SELECT_TARGET_ANY_FRIEND, //AoE or Single Friend +}; + +enum CreatureSpellSelectEffect +{ + SELECT_EFFECT_DONTCARE = 0, //All spell effects allowed + SELECT_EFFECT_DAMAGE, //Spell does damage + SELECT_EFFECT_HEALING, //Spell does healing + SELECT_EFFECT_AURA, //Spell applies an aura +}; +enum CreatureSpellIndex +{ + CREATURE_SPELL_MIN, + CREATURE_SPELL_ATTACK_1 = 0, //Normal Attack + CREATURE_SPELL_ATTACK_2, + CREATURE_SPELL_ATTACK_3, + CREATURE_SPELL_ATTACK_4, + CREATURE_SPELL_ATTACK_5, + CREATURE_SPELL_ATTACK_MAX, + CREATURE_SPELL_SPEED_1 = 5, //When target Run Away + CREATURE_SPELL_SPEED_2, + CREATURE_SPELL_SPEED_MAX, + CREATURE_SPELL_STUNT_1 = 7, + CREATURE_SPELL_STUNT_2, //When target Run Closer + CREATURE_SPELL_STUNT_MAX, + CREATURE_SPELL_HEALING_1 = 9, //When Less Life Or Friend Target + CREATURE_SPELL_HEALING_2, + CREATURE_SPELL_HEALING_MAX, + CREATURE_SPELL_BUFF_1 = 11, //When Begin of the fight Or Friend Target + CREATURE_SPELL_BUFF_2, + CREATURE_SPELL_BUFF_MAX, + CREATURE_SPELL_INTERRUPT_1 = 13, //Select When Target is Casting Channeling Spell + CREATURE_SPELL_INTERRUPT_MAX, + CREATURE_SPELL_MAX = 14 +}; +struct CreatureSpellInfo +{ + CreatureSpellInfo() : id(NULL), recoveryTime(0), + unknow1(0),buffDuration(0),cost(0), + targets(0), usingDBC(false) + { + range[0] = 0.0f; + range[1] = 0.0f; + } + + uint8 targets,effects; + uint32 id,recoveryTime,unknow1,buffDuration,cost; + float range[2]; + bool usingDBC, isDelayed; +}; +typedef std::map CreatureSpellInfoMap; +struct CreatureSpellBook +{ + CreatureSpellBook() : entry(0) { info.clear(); } + uint32 entry; + CreatureSpellInfoMap info; + + bool hasHealing() + { + CreatureSpellInfoMap::iterator spellItr; + for(uint8 i = CREATURE_SPELL_HEALING_1; i < CREATURE_SPELL_HEALING_MAX; ++i) + { + spellItr = info.find(i); + if( spellItr != info.end() && spellItr->second.id) + return true; + } + return false; + } + bool hasSpeed() + { + CreatureSpellInfoMap::iterator spellItr; + for(uint8 i = CREATURE_SPELL_SPEED_1; i < CREATURE_SPELL_SPEED_MAX; ++i) + { + spellItr = info.find(i); + if( spellItr != info.end() && spellItr->second.id) + return true; + } + return false; + } + bool hasInterrupt() + { + CreatureSpellInfoMap::iterator spellItr; + for(uint8 i = CREATURE_SPELL_INTERRUPT_1; i < CREATURE_SPELL_INTERRUPT_MAX; ++i) + { + spellItr = info.find(i); + if( spellItr != info.end() && spellItr->second.id) + return true; + } + return false; + } +}; + + +struct Assistance +{ + uint8 helperCount; + bool gaveLove; +} enum InhabitTypeValues { INHAVIT_GROUND = 1, @@ -362,7 +472,7 @@ void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time); void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time); void AddCreatureSpellCooldown(uint32 spellid); - bool HasSpellCooldown(uint32 spell_id) const; + bool HasSpellCooldown(uint32 spell_id = 0, uint32 addTime = 0) const; bool HasCategoryCooldown(uint32 spell_id) const; bool HasSpell(uint32 spellID) const; @@ -463,9 +573,9 @@ SpellEntry const *reachWithSpellCure(Unit *pVictim); uint32 m_spells[CREATURE_MAX_SPELLS]; + uint32 m_GlobalCooldown; CreatureSpellCooldowns m_CreatureSpellCooldowns; CreatureSpellCooldowns m_CreatureCategoryCooldowns; - uint32 m_GlobalCooldown; float GetAttackDistance(Unit *pl) const; @@ -505,7 +615,8 @@ else return m_charmInfo->GetCharmSpell(pos)->spellId; } - + CreatureSpellBook *m_creatureSpellBook; + void LoadSpellInfo(); protected: // vendor items typedef std::vector CreatureItems; Index: src/game/DestinationHolderImp.h =================================================================== --- src/game/DestinationHolderImp.h (revision 4656) +++ src/game/DestinationHolderImp.h (working copy) @@ -89,15 +89,27 @@ float dx = i_destX - i_fromX; float dy = i_destY - i_fromY; float dz = i_destZ - i_fromZ; - double dist = ::sqrt((dx*dx) + (dy*dy) + (dz*dz)); + + double dist = ::sqrt((dx*dx) + (dy*dy) /*+ (dz*dz)*/); // i think client don't see speed like that but allways 2d, since you go faster on surface with 80 degree as example double speed = traveller.Speed(); if(speed<=0) speed = 2.5f; speed *= 0.001f; // speed is in seconds so convert from second to millisecond i_totalTravelTime = static_cast( dist/speed + 0.5 ); + /*if ( (dz > 0.50 || dz < -0.50) && i_totalTravelTime > 50) + { + float newDist = 50*dist/i_totalTravelTime; + i_destX = (traveller.GetPositionX() + newDist) * cos( traveller.GetTraveller().GetAngle(i_destX,i_destY) ); + i_destY = (traveller.GetPositionY() + newDist) * sin( traveller.GetTraveller().GetAngle(i_destX,i_destY) ); + traveller.GetTraveller().UpdateGroundPositionZ( i_destX,i_destY,i_destZ ); + i_totalTravelTime = 50; + }*/ + i_timeStarted = getMSTime(); i_timeElapsed = 0; - if(sendMove) traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime); + if(sendMove) + traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime); + return i_totalTravelTime; } Index: src/game/GridNotifiers.h =================================================================== --- src/game/GridNotifiers.h (revision 4656) +++ src/game/GridNotifiers.h (working copy) @@ -623,10 +623,10 @@ return false; // only from same creature faction - if(u->getFaction() != i_funit->getFaction() ) + if( u->getFaction() != i_funit->getFaction() ) return false; - if(!u->IsWithinLOSInMap(i_enemy) ) + if( !u->IsWithinLOSInMap(i_enemy) ) return false; return true; Index: src/game/GridNotifiersImpl.h =================================================================== --- src/game/GridNotifiersImpl.h (revision 4656) +++ src/game/GridNotifiersImpl.h (working copy) @@ -70,32 +70,32 @@ pl->UpdateVisibilityOf(c); // Creature AI reaction - if(!c->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) - { + /*if(!c->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) + {*/ if( c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode() ) c->AI()->MoveInLineOfSight(pl); - } + /*}*/ } inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2) { - if(!c1->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) - { + /*if(!c1->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) + {*/ if( c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode() ) c1->AI()->MoveInLineOfSight(c2); - } + /*}*/ - if(!c2->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) - { + /*if(!c2->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) + {*/ if( c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode() ) c2->AI()->MoveInLineOfSight(c1); - } + /*}*/ } inline void MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m) { - if(!i_player.isAlive() || i_player.isInFlight()) + if(!i_player.isAlive() /*|| i_player.isInFlight()*/) return; for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) @@ -111,7 +111,7 @@ return; for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) - if( iter->getSource()->isAlive() && !iter->getSource()->isInFlight()) + if( iter->getSource()->isAlive() /*&& !iter->getSource()->isInFlight()*/) PlayerCreatureRelocationWorker(iter->getSource(), &i_creature); } @@ -129,7 +129,7 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) { - if(!target->isAlive() || target->isInFlight() ) + if(!target->isAlive() /*|| target->isInFlight()*/ ) return; if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isTotem()) Index: src/game/Level3.cpp =================================================================== --- src/game/Level3.cpp (revision 4656) +++ src/game/Level3.cpp (working copy) @@ -4195,6 +4195,133 @@ return true; } +bool ChatHandler::HandleFillAuctionHouse(const char * args) +{ + Player *player = m_session->GetPlayer(); + if (!player) + return true; + + uint32 itemId = 1; + uint32 counter = 1; + uint32 startbid = 1; + bool craftedItem = false; + Item *item = NULL; + + PSendSysMessage("Starting Fill GM AuctionHouse"); + + for(itemId; itemId < 45000; itemId++) + { + craftedItem = false; + startbid = 1; + + if( (float)itemId / 999.0f > counter) + { + PSendSysMessage( "%u Items to go...", (45000 - itemId) ); + counter += 1; + } + + ItemPrototype const *itemProto = objmgr.GetItemPrototype(itemId); + if( itemProto && itemProto->Quality && itemProto->Class != 12 && itemProto->Class != 10) + { + for(uint32 spellId = 1; spellId < sSpellStore.GetNumRows(); spellId++) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(spellInfo) + { + for(uint8 ii=0; ii < 3; ii++) + { + if( spellInfo->Effect[ii] == 24 && spellInfo->EffectItemType[ii] == itemId ) + { + craftedItem = true; + break; + } + } + } + if(craftedItem) + break; + } + + if( craftedItem ) + continue; + + switch( itemProto->Quality ) + { + case 1: + { + if(!itemProto->BuyPrice) + { + startbid += itemProto->ItemLevel * itemProto->ItemLevel * 2 * itemProto->Class == 6 ? 1 : itemProto->Stackable + itemProto->BuyPrice; + } + else + { + startbid += itemProto->Stackable/itemProto->BuyCount * itemProto->BuyPrice; + } + }break; + case 2: + { + if(!itemProto->BuyPrice) + { + startbid += itemProto->ItemLevel * itemProto->ItemLevel * 500 * itemProto->Class == 6 ? 1 : itemProto->Stackable + itemProto->BuyPrice; + } + else + { + startbid += itemProto->Stackable/itemProto->BuyCount * itemProto->BuyPrice; + } + }break; + case 3: + { + startbid += (itemProto->ItemLevel * itemProto->ItemLevel * 1500 * itemProto->Class == 6 ? 1 : itemProto->Stackable) + itemProto->BuyPrice; + }break; + case 4: + { + startbid += (itemProto->ItemLevel * itemProto->ItemLevel * 4500 * itemProto->Class == 6 ? 1 : itemProto->Stackable) + itemProto->BuyPrice; + }break; + case 5: + { + startbid += (itemProto->ItemLevel * itemProto->ItemLevel * 18500 * itemProto->Class == 6 ? 1 : itemProto->Stackable) + itemProto->BuyPrice; + }break; + case 6: + { + startbid += (itemProto->ItemLevel * itemProto->ItemLevel * 35500 * itemProto->Class == 6 ? 1 : itemProto->Stackable) + itemProto->BuyPrice; + } + } + + item = player->CreateItem( itemId, itemProto->Stackable); + + if(!item) + continue; + + AuctionHouseObject *mAuctions = objmgr.GetAuctionsMap( 7 ); + AuctionEntry *AH = new AuctionEntry; + + AH->Id = objmgr.GenerateAuctionID(); + AH->auctioneer = 15677; + AH->item_guid = item->GetGUIDLow(); + AH->item_template = item->GetEntry(); + AH->owner = player->GetGUID(); + AH->startbid = startbid; + AH->bidder = 0; + AH->bid = 0; + AH->buyout = 0; + time_t base = ((time_t)(3600 * sWorld.getRate(RATE_AUCTION_TIME))) + time(NULL); + AH->time = base; + AH->deposit = 0; + AH->location = 7; + + mAuctions->AddAuction(AH); + objmgr.AddAItem(item); + + sDatabase.BeginTransaction(); + item->SaveToDB(); // recursive and not have transaction guard into self + sDatabase.PExecute("INSERT INTO `auctionhouse` (`id`,`auctioneerguid`,`itemguid`,`item_template`,`itemowner`,`buyoutprice`,`time`,`buyguid`,`lastbid`,`startbid`,`deposit`,`location`) " + "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u')", + AH->Id, AH->auctioneer, AH->item_guid, AH->item_template, AH->owner, AH->buyout, (uint64)AH->time, AH->bidder, AH->bid, AH->startbid, AH->deposit, AH->location); + sDatabase.CommitTransaction(); + } + } + PSendSysMessage("Complete AuctionHouse Fill"); + return true; +} bool ChatHandler::HandleMovegensCommand(const char *args) { Unit* unit = getSelectedUnit(); Index: src/game/MotionMaster.cpp =================================================================== --- src/game/MotionMaster.cpp (revision 4656) +++ src/game/MotionMaster.cpp (working copy) @@ -67,7 +67,7 @@ void MotionMaster::UpdateMotion(const uint32 &diff) { - if(i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED)) + if(i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) ) return; assert( !empty() ); if (!top()->Update(*i_owner, diff)) @@ -88,7 +88,6 @@ assert( !empty() ); if (reset) top()->Reset(*i_owner); } - void MotionMaster::MovementExpired(bool reset) { @@ -135,6 +134,7 @@ void MotionMaster::Mutate(MovementGenerator *m) { // HomeMovement is not that important, delete it if meanwhile a new comes + //Don't agree we should manage she return HOME with that original MV, GS if (!empty() && top()->GetMovementGeneratorType() == HOME_MOTION_TYPE) MovementExpired(false); m->Initialize(*i_owner); Index: src/game/Object.cpp =================================================================== --- src/game/Object.cpp (revision 4656) +++ src/game/Object.cpp (working copy) @@ -920,7 +920,9 @@ } // angle to face `obj` to `this` - float angle = rand_norm()*2*M_PI; + srand(getMSTime()); + float angle = rand_norm()*M_PI; + srand(getMSTime()); float new_dist = rand_norm()*distance; rand_x = x + new_dist * cos(angle); @@ -1180,10 +1182,9 @@ void WorldObject::GetNearPoint2D(float &x, float &y, float distance2d, float absAngle ) const { - x = GetPositionX() + (GetObjectSize() + distance2d) * cos(absAngle); - y = GetPositionY() + (GetObjectSize() + distance2d) * sin(absAngle); + x = GetPositionX() + (GetObjectSize() + (distance2d-(distance2d/100.0f))) * cos(absAngle); + y = GetPositionY() + (GetObjectSize() + (distance2d-(distance2d/100.0f))) * sin(absAngle); } - void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float distance2d, float absAngle ) const { float size = searcher ? searcher->GetObjectSize() : 0; Index: src/game/Object.h =================================================================== --- src/game/Object.h (revision 4656) +++ src/game/Object.h (working copy) @@ -279,11 +279,11 @@ void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const { // angle to face `obj` to `this` using distance includes size of `obj` - GetNearPoint(obj,x,y,z,distance2d,GetAngle( obj )); + GetNearPoint(obj,x,y,z,distance2d, GetAngle( obj )); } const float GetObjectSize() const { - return ( m_valuesCount > UNIT_FIELD_BOUNDINGRADIUS ) ? m_floatValues[UNIT_FIELD_BOUNDINGRADIUS] : 0.39f; + return ( m_valuesCount > UNIT_FIELD_BOUNDINGRADIUS ) ? m_floatValues[UNIT_FIELD_BOUNDINGRADIUS]*2 : 0.39f*2; } bool IsPositionValid() const; void UpdateGroundPositionZ(float x, float y, float &z) const; Index: src/game/ObjectMgr.cpp =================================================================== --- src/game/ObjectMgr.cpp (revision 4656) +++ src/game/ObjectMgr.cpp (working copy) @@ -579,7 +579,6 @@ { return sEquipmentStorage.LookupEntry(entry); } - void ObjectMgr::LoadEquipmentTemplates() { sEquipmentStorage.Load(); @@ -587,7 +586,13 @@ sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount ); sLog.outString(); } +/*void ObjectMgr::LoadCreatureSpellBook() +{ + sCreatureSpellBookStorage.Load(); + sLog.outString( ">> Loaded %u Creature Spells Books from template", sCreatureSpellBookStorage.RecordCount ); + sLog.outString(); +}*/ CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid) { return sCreatureModelStorage.LookupEntry(modelid); Index: src/game/ObjectMgr.h =================================================================== --- src/game/ObjectMgr.h (revision 4656) +++ src/game/ObjectMgr.h (working copy) @@ -44,6 +44,7 @@ extern SQLStorage sCreatureStorage; extern SQLStorage sCreatureDataAddonStorage; +//extern SQLStorage sCreatureRawSpellBookStorage; extern SQLStorage sCreatureInfoAddonStorage; extern SQLStorage sCreatureModelStorage; extern SQLStorage sEquipmentStorage; @@ -72,7 +73,6 @@ float z; float o; }; - typedef std::multimap ScriptMap; typedef std::map ScriptMapMap; extern ScriptMapMap sQuestEndScripts; @@ -265,15 +265,16 @@ void RemoveArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.erase( arenateam ); } CreatureInfo const *GetCreatureTemplate( uint32 id ); + CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid ); CreatureModelInfo const* GetCreatureModelRandomGender(uint32 display_id); uint32 ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data); EquipmentInfo const *GetEquipmentInfo( uint32 entry ); + static CreatureDataAddon const *GetCreatureAddon( uint32 lowguid ) { return sCreatureDataAddonStorage.LookupEntry(lowguid); } - static CreatureDataAddon const *GetCreatureTemplateAddon( uint32 entry ) { return sCreatureInfoAddonStorage.LookupEntry(entry); @@ -451,6 +452,7 @@ void LoadCreatureAddons(); void LoadCreatureModelInfo(); void LoadEquipmentTemplates(); + void LoadCreatureSpellBook(); void LoadGameObjectLocales(); void LoadGameobjects(); void LoadGameobjectRespawnTimes(); @@ -817,6 +819,6 @@ typedef HM_NAMESPACE::hash_map SpellProcEventMap; SpellProcEventMap mSpellProcEventMap; }; - +//SQLStorage const* GetCreaturesSpellsBooks() {return &sCreatureSpellBookStorage;} #define objmgr MaNGOS::Singleton::Instance() #endif Index: src/game/Player.cpp =================================================================== --- src/game/Player.cpp (revision 4656) +++ src/game/Player.cpp (working copy) @@ -420,7 +420,7 @@ SetUInt32Value( PLAYER_FIELD_TODAY_CONTRIBUTION, 0 ); SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 ); - SetUInt32Value( UNIT_FIELD_LEVEL, 1 ); //set level = 1 for created characters + SetUInt32Value( UNIT_FIELD_LEVEL, 60 ); //set level = 1 for created characters // Played time m_Last_tick = time(NULL); @@ -452,6 +452,67 @@ } } + + //DM Aleajecta + learnSpell(2575); //Mining Rank-1 + switch (class_) + { + case CLASS_WARRIOR: + learnSpell(71); //Defensive Stance + learnSpell(2458); //Berserker Stance + learnSpell(750); //Plate + AddItemSet(189); + break; + case CLASS_PALADIN: + learnSpell(7328); //Redemption + learnSpell(750); //Plate + AddItemSet(188); + break; + case CLASS_HUNTER: + learnSpell(1515); //Tame Beast + learnSpell(883); //Call Pet + learnSpell(2461); //Dismiss Pet + learnSpell(5149); //Beast Training + learnSpell(982); //Revive Pet + learnSpell(6991); //Feed Pet + learnSpell(8737); //Mail + AddItemSet(186); + break; + case CLASS_ROGUE: + learnSpell(2842); //Poison + AddItemSet(184); + break; + case CLASS_PRIEST: + AddItemSet(182); + break; + case CLASS_SHAMAN: + learnSpell(8737); //Mail + AddItemSet(5175,false); //Earth Totem + AddItemSet(5176,false); //Fire Totem + AddItemSet(5177,false); //Water Totem + AddItemSet(5178,false); //Air Totem + AddItemSet(187); + break; + case CLASS_MAGE: + AddItemSet(181); + break; + case CLASS_WARLOCK: + learnSpell(688); //Summon Imp + learnSpell(697); //Summon Voidwalker + learnSpell(691); //Summon FelHunter + learnSpell(712); //Summon Succubus + learnSpell(1122); //Summon Inferno + AddItemSet(183); + break; + case CLASS_DRUID: + learnSpell(768); //Cat Form + learnSpell(5487); //Bear Form + learnSpell(6795); //Growl + learnSpell(6807); //Maul + learnSpell(9634); //Dire Bear Form + AddItemSet(185); + break; + } skill_itr = info->skill.begin(); for (; skill_itr!=info->skill.end(); ) @@ -483,9 +544,9 @@ UpdateBlockPercentage(); + Item *pItem; uint16 dest; uint8 msg; - Item *pItem; for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++) { titem_id = item_id_itr->item_id; @@ -556,6 +617,69 @@ return true; } +void Player::AddItemSet(const uint16 itemSetEntry, bool itemSet) +{ + Item *pItem; + uint16 dest; + uint8 msg; + + if(itemSet) + { + QueryResult *result = sDatabase.PQuery("SELECT `entry` FROM `item_template` WHERE `itemset` = %u",itemSetEntry); + + if(!result) + return; + do + { + Field *fields = result->Fetch(); + uint32 itemId = fields[0].GetUInt32(); + + if(itemId) + { + pItem = CreateItem( itemId, 1); + if( pItem ) + { + msg = CanEquipItem( NULL_SLOT, dest, pItem, false ); + if( msg == EQUIP_ERR_OK ) + EquipItem( dest, pItem, true); + else + { + // store in main bag to simplify second pass + msg = CanStoreItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, dest, pItem, false ); + if( msg == EQUIP_ERR_OK ) + StoreItem( dest, pItem, true); + else + delete pItem; + } + } + } + + }while( result->NextRow() ); + delete result; + } + else + { + if(itemSetEntry) + { + pItem = CreateItem( itemSetEntry, 1); + if( pItem ) + { + msg = CanEquipItem( NULL_SLOT, dest, pItem, false ); + if( msg == EQUIP_ERR_OK ) + EquipItem( dest, pItem, true); + else + { + // store in main bag to simplify second pass + msg = CanStoreItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, dest, pItem, false ); + if( msg == EQUIP_ERR_OK ) + StoreItem( dest, pItem, true); + else + delete pItem; + } + } + } + } +} void Player::StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue) { uint32 BreathRegen = (uint32)-1; @@ -1847,6 +1971,7 @@ for(AuraList::const_iterator i = mModHealthRegenFlat.begin(); i != mModHealthRegenFlat.end(); ++i) addvalue += (*i)->GetModifier()->m_amount; + addvalue /= 10; if(addvalue < 0) addvalue = 0; @@ -3771,6 +3896,45 @@ void Player::CleanupChannels() { + //Constant CTF System, To be Excuse On Player Logout Only.. Not on Server Crash. + for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ++iter) + { + if(iter->second->GetSpellProto()->Id == 23335) + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2338); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,HORDE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1545); //Special World Flag for Ally + data2 << uint32(-1); + sWorld.SendGlobalMessage(&data2,NULL,ALLIANCE); + + RemoveAura(iter); + _SaveAuras(); + CastSpell(this,23336,true); + break; + } + if(iter->second->GetSpellProto()->Id == 23333) + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2339); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,ALLIANCE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1546); //Special World Flag for Horde + data2 << uint32(-1); + sWorld.SendGlobalMessage(&data2,NULL,HORDE); + + RemoveAura(iter); + _SaveAuras(); + CastSpell(this,23334,true); + break; + } + } + for(JoinedChannelsList::iterator i = m_channels.begin(), next; i != m_channels.end(); i = next) { next = i; ++next; @@ -3868,7 +4032,7 @@ void Player::UpdateDefense() { - if(UpdateSkill(SKILL_DEFENSE)) + if( irand(0,100) < 10 && UpdateSkill(SKILL_DEFENSE) ) { // update dependent from defense skill part BlockChanceWithoutMods = 5 + (GetDefenseSkillValue() - getLevel()*5)*0.04); UpdateBlockPercentage(); @@ -4286,7 +4450,7 @@ // For skinning and Mining chance decrease with level. 1-74 - no decrease, 75-149 - 2 times, 225-299 - 8 times switch (SkillId) { - case SKILL_HERBALISM: + //case SKILL_HERBALISM: DM Aleajecta case SKILL_LOCKPICKING: case SKILL_JEWELCRAFTING: return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator); @@ -4296,10 +4460,11 @@ else return UpdateSkillPro(SkillId, (SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator) >> (SkillValue/sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)) ); case SKILL_MINING: + case SKILL_HERBALISM: //DM Aleajecta if (sWorld.getConfig(CONFIG_SKILL_CHANCE_MINING_STEPS)==0) - return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator); + return false;//DM Aleajecta UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator); else - return UpdateSkillPro(SkillId, (SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator) >> (SkillValue/sWorld.getConfig(CONFIG_SKILL_CHANCE_MINING_STEPS)) ); + return false; UpdateSkillPro(SkillId, (SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator) >> (SkillValue/sWorld.getConfig(CONFIG_SKILL_CHANCE_MINING_STEPS)) ); } return false; } @@ -5357,7 +5522,52 @@ SetUInt32Value(PLAYER_FIELD_KILLS, kills_today << 16); } } +void Player::giveHonorXpMoney(int32 honorValue, int32 xpValue, int32 moneyValue, bool allGroup) +{ + if(allGroup) + { + Group *pGroup = GetGroup(); + if(pGroup) + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + if(honorValue != 0) + itr->getSource()->RewardHonor(NULL,1,honorValue); + + if(xpValue != 0) + { + itr->getSource()->GiveXP(xpValue,NULL); + if(Pet* pet = itr->getSource()->GetPet()) + { + pet->GivePetXP(xpValue/2); + } + } + if(moneyValue != 0) + itr->getSource()->SetMoney( itr->getSource()->GetMoney() + moneyValue ); + + } + } + } + else + { + if(honorValue != 0) + RewardHonor(NULL,1,honorValue); + + if(xpValue != 0) + { + GiveXP(xpValue,NULL); + + if(Pet* pet = GetPet()) + { + pet->GivePetXP(xpValue/2); + } + } + + if(moneyValue != 0) + SetMoney( GetMoney() + moneyValue ); + } +} ///Calculate the amount of honor gained based on the victim ///and the size of the group for which the honor is divided ///An exact honor value can also be given (overriding the calcs) @@ -15495,3 +15705,17 @@ m_DailyQuestChanged = false; m_lastDailyQuestTime = 0; } + +void Player::SummonGuardian(uint32 entry, uint32 duration) +{ + float x = GetPositionX(); + float y = GetPositionY(); + float z = GetPositionZ()+0.1; + + Creature* creature = SummonCreature(entry, x, y, z, GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,duration); + if(creature) + { + creature->AIM_Initialize(); + creature->AI()->MoveInLineOfSight((Unit*)this); + } +} Index: src/game/Player.h =================================================================== --- src/game/Player.h (revision 4656) +++ src/game/Player.h (working copy) @@ -790,7 +790,7 @@ void TeleportTo(uint32 mapid, float x, float y, float z, float orientation, bool outofrange = true, bool ignore_transport = true, bool is_gm_command = false); bool Create ( uint32 guidlow, WorldPacket &data ); - + void AddItemSet(const uint16 itemSetEntry, bool itemSet = true); void Update( uint32 time ); void BuildEnumData( QueryResult * result, WorldPacket * p_data ); @@ -1030,6 +1030,7 @@ void SetDailyQuestStatus( uint32 quest_id ); void ResetDailyQuestStatus(); + void SummonGuardian(uint32 entry, uint32 duration); uint32 GetReqKillOrCastCurrentCount(uint32 quest_id, uint32 entry); void AdjustQuestReqItemCount( Quest const* pQuest ); @@ -1464,6 +1465,7 @@ /*********************************************************/ void UpdateArenaFields(); void UpdateHonorFields(bool force = false); + void giveHonorXpMoney(int32 honorValue, int32 xpValue = 0, int32 moneyValue = 0, bool allGroup = false); bool RewardHonor(Unit *pVictim, uint32 groupsize, float honor = -1); uint32 GetHonorPoints() { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); } uint32 GetArenaPoints() { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); } Index: src/game/ScriptCalls.cpp =================================================================== --- src/game/ScriptCalls.cpp (revision 4656) +++ src/game/ScriptCalls.cpp (working copy) @@ -41,8 +41,18 @@ { ScriptsSet testScript=new _ScriptSet; - std::string name = strlen(libName) ? libName : MANGOS_SCRIPT_NAME; + std::string name; + name = strlen(libName) ? libName : MANGOS_TIER_SCRIPT_NAME; name += MANGOS_SCRIPT_EXT; + + const char* TierScriptName = name.c_str(); + + if( !fopen( TierScriptName, "r") ) //Tier Script Not Present Taking Default MaNGOSScript.dll + { + printf("Error loading TIER Scripts Library %s !\n",name.c_str()); + name = strlen(libName) ? libName : MANGOS_SCRIPT_NAME; + name += MANGOS_SCRIPT_EXT; + } testScript->hScriptsLib=MANGOS_LOAD_LIBRARY(name.c_str()); Index: src/game/Spell.cpp =================================================================== --- src/game/Spell.cpp (revision 4656) +++ src/game/Spell.cpp (working copy) @@ -264,6 +264,38 @@ m_autoRepeat = true; casttime = GetCastTime(sCastTimesStore.LookupEntry(m_spellInfo->CastingTimeIndex)); + + //DM Aleajecta + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + uint16 skillId; + for(uint8 i = 0; i < 3; ++i) + { + + if( m_spellInfo->Effect[i] == SPELL_EFFECT_SKILL ) + { + skillId = m_spellInfo->EffectMiscValue[i]; + switch(skillId) + { + case SKILL_FIRST_AID: + case SKILL_BLACKSMITHING: + case SKILL_LEATHERWORKING: + case SKILL_ALCHEMY: + case SKILL_HERBALISM: + case SKILL_COOKING: + case SKILL_MINING: + case SKILL_ENGINERING: + case SKILL_TAILORING: + case SKILL_ENCHANTING: + case SKILL_SKINNING: + case SKILL_LOCKPICKING: + case SKILL_JEWELCRAFTING: + case LOCKTYPE_PICKLOCK: + casttime += irand( 35000,47000) - ( ((Player*)m_caster)->GetSkillValue(LOCKTYPE_PICKLOCK ? SKILL_LOCKPICKING : skillId)*10 ); + } + } + } + } if(Player* modOwner = m_caster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_CASTING_TIME, casttime); @@ -965,6 +997,7 @@ { m_caster->SetCurrentCastedSpell( this ); m_selfContainer = &(m_caster->m_currentSpells[GetCurrentContainer()]); + SendSpellStart(); } } @@ -1461,6 +1494,9 @@ void Spell::SendSpellCooldown() { + if( m_caster->GetTypeId() == TYPEID_UNIT && !((Creature*)m_caster)->isPet() ) + ((Creature*)m_caster)->AddCreatureSpellCooldown(m_spellInfo->Id); + if(m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -1614,9 +1650,11 @@ } // check if the player caster has moved before the spell finished - if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && - (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && - (m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !((Player*)m_caster)->HasMovementFlags(MOVEMENTFLAG_FALLING)) ) + if( m_timer != 0 + && ( m_castPositionX != m_caster->GetPositionX() + || m_castPositionY != m_caster->GetPositionY() + || m_castPositionZ != m_caster->GetPositionZ() ) + && ( m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || ( m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->HasMovementFlags(MOVEMENTFLAG_FALLING))) ) { // always cancel for channeled spells if( m_spellState == SPELL_STATE_CASTING ) @@ -2048,6 +2086,7 @@ { if(time == 0) { + m_timer = 0; //reset Channeling Timer, Should not be there, in place Must Check with State , but have to Be sure Deleyed and CASTING are never together. m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,0); m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL,0); } @@ -2314,8 +2353,9 @@ if(target) { // Not allow casting on flying player - if (target->isInFlight()) - return SPELL_FAILED_BAD_TARGETS; + //DM Aleajecta + //if (target->isInFlight()) + //return SPELL_FAILED_BAD_TARGETS; if(VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target)) return SPELL_FAILED_LINE_OF_SIGHT; Index: src/game/Spell.h =================================================================== --- src/game/Spell.h (revision 4656) +++ src/game/Spell.h (working copy) @@ -562,7 +562,7 @@ void SetAutoRepeat(bool rep) { m_autoRepeat = rep; } void ReSetTimer() { m_timer = casttime<0?0:casttime; } bool IsMeleeSpell() const { return m_meleeSpell; } - bool IsChanneledSpell() const { return m_spellInfo->ChannelInterruptFlags != 0; } + bool IsChanneledSpell() const { return (m_spellInfo->CastingTimeIndex > 1 && m_spellInfo->CastingTimeIndex != 191) || m_spellInfo->ChannelInterruptFlags; } bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; } bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->School != 0) && !(m_spellInfo->Attributes == 327680 && m_spellInfo->AttributesEx2 ==0); } @@ -573,7 +573,8 @@ uint64 GetDelayMoment() const { return m_delayMoment; } CurrentSpellTypes GetCurrentContainer(); - + + uint32 GetTimer() { return m_timer; } Unit* GetCaster() { return m_caster; } Unit* GetOriginalCaster() { return m_originalCaster; } Index: src/game/SpellAuras.cpp =================================================================== --- src/game/SpellAuras.cpp (revision 4656) +++ src/game/SpellAuras.cpp (working copy) @@ -455,6 +455,9 @@ } if(caster && m_target->isAlive() && m_target->HasFlag(UNIT_FIELD_FLAGS,(UNIT_STAT_FLEEING<<16))) { + if( caster->GetGUID() == m_target->GetGUID() && caster->getVictim() && caster->getVictim()->isAlive() ) + caster = caster->getVictim(); + int q = rand() % 80; if(q == 8) m_fearMoveAngle += (float)(urand(45, 90)); else if(q == 23) m_fearMoveAngle -= (float)(urand(45, 90)); @@ -2045,8 +2048,11 @@ { //FIX ME: we need Mutate to now not existed FleeMovementGenerator (see Aura::Update hack code) // at this moment Idle instead - m_target->GetMotionMaster()->MovementExpired(false); - m_target->GetMotionMaster()->Idle(); + + //Fear should Stack is Movement. , It will break MV targeted System if not after fear is removed, GS + //Fear Remove Will destroy Friendly Target AI system Have if working as actual. Need to Fix that, GS + //m_target->GetMotionMaster()->MovementExpired(false); + //m_target->GetMotionMaster()->Idle(); // what is this for ? (doesn't work anyway) /*WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9); @@ -2063,7 +2069,7 @@ // only at real remove aura if(Real) { - m_target->GetMotionMaster()->MovementExpired(false); + /*m_target->GetMotionMaster()->MovementExpired(false); if(m_target->GetTypeId() != TYPEID_PLAYER) { @@ -2077,7 +2083,7 @@ Unit* caster = GetCaster(); if(caster && caster != m_target->getVictim()) ((Creature*)m_target)->AI()->AttackStart(caster); - } + }*/ // what is this for ? (doesn't work anyway) /*WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9); @@ -2651,49 +2657,6 @@ void Aura::HandleAuraModEffectImmunity(bool apply, bool Real) { - if(!apply) - { - if(m_target->GetTypeId() == TYPEID_PLAYER) - { - if(((Player*)m_target)->InBattleGround()) - { - BattleGround *bg = sBattleGroundMgr.GetBattleGround(((Player*)m_target)->GetBattleGroundId()); - if(bg) - { - switch(bg->GetTypeID()) - { - case BATTLEGROUND_AV: - { - break; - } - case BATTLEGROUND_WS: - { - if(((BattleGroundWS*)bg)->IsHordeFlagPickedup()) - // Warsong Flag, horde - if(GetSpellProto()->Id == 23333) - // Horde Flag Drop - ((BattleGroundWS*)bg)->EventPlayerDroppedFlag(((Player*)m_target)); - if(((BattleGroundWS*)bg)->IsAllianceFlagPickedup()) - // Silverwing Flag, alliance - if(GetSpellProto()->Id == 23335) - // Alliance Flag Drop - ((BattleGroundWS*)bg)->EventPlayerDroppedFlag(((Player*)m_target)); - break; - } - case BATTLEGROUND_AB: - { - break; - } - case BATTLEGROUND_EY: - { - break; - } - } - } - } - } - } - m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply); } Index: src/game/SpellEffects.cpp =================================================================== --- src/game/SpellEffects.cpp (revision 4656) +++ src/game/SpellEffects.cpp (working copy) @@ -53,6 +53,7 @@ #include "BattleGroundWS.h" #include "VMapFactory.h" #include "Language.h" +#include "TargetedMovementGenerator.h" pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -1306,6 +1307,16 @@ void Spell::EffectSendEvent(uint32 i) { + /* switch( EffectMiscValue[i] ) + { + case 8505: // Alliance & Horde Flag, PickUP + + case 8506: //Alliance Flag, Drop + + case 8507: //Horde Flag, Drop + + }*/ + if (m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->InBattleGround()) { BattleGround* bg = sBattleGroundMgr.GetBattleGround(((Player *)m_caster)->GetBattleGroundId()); @@ -2923,6 +2934,8 @@ if(pGameObj->GetGoType() != GAMEOBJECT_TYPE_FLAGDROP) // make dropped flag clickable for other players (not set owner guid (created by) for this)... m_caster->AddGameObject(pGameObj); + else + pGameObj->SaveToDB(); // Save CTF Flag To DB on Dropped. MapManager::Instance().GetMap(pGameObj->GetMapId(), pGameObj)->Add(pGameObj); } @@ -2934,11 +2947,17 @@ switch(m_spellInfo->Id) { // Keep in top, because core use it for npc aggro other npc + + //Why put that here, try be Blizzlike, it can't im pretty sure blizzard will not slow down all they process for that spell + // for sure we don't have the same spellSystsme as blizz so.. i think should be gone from here, serve no purpose + // a simple Function to call the command by script if we need should be much more then sufissent and save a lot of cpu and mem. case SPELL_ID_AGGRO: { if( !m_caster || m_caster->GetTypeId() != TYPEID_UNIT || !m_caster->getVictim() ) return; + // Should be == to diff from Home Location to Location, with a maximun of 50 like. + //So we can bring her too far away from original location float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTEMCE_RADIUS); if(radius > 0) { @@ -2958,16 +2977,23 @@ CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); } + std::list::iterator firstTarget = assistList.begin(); + if( firstTarget != assistList.end() ) + { + if( m_caster->getVictim() && m_caster->getVictim()->GetTypeId() == TYPEID_PLAYER) + m_caster->getVictim()->SetUInt64Value(UNIT_FIELD_TARGET,0); + m_caster->GetMotionMaster()->Mutate(new TargetedMovementGenerator( *(*firstTarget),2.0f,0,true )); + } - for(std::list::iterator iter = assistList.begin(); iter != assistList.end(); ++iter) + /*for(std::list::iterator iter = assistList.begin(); iter != assistList.end(); ++iter) { ((Creature*)m_caster)->SetNoCallAssistence(true); (*iter)->SetNoCallAssistence(true); if((*iter)->AI()) (*iter)->AI()->AttackStart(m_caster->getVictim()); - } + }*/ + } - return; } Index: src/game/SpellHandler.cpp =================================================================== --- src/game/SpellHandler.cpp (revision 4656) +++ src/game/SpellHandler.cpp (working copy) @@ -30,6 +30,9 @@ #include "MapManager.h" #include "ScriptCalls.h" +typedef std::pair spellEffectPair; +typedef std::multimap< spellEffectPair, Aura*> AuraMap; + void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { // TODO: add targets.read() check @@ -218,7 +221,7 @@ uint64 guid; uint32 spellId = OPEN_CHEST; - const GameObjectInfo *info; + const GameObjectInfo *goInfo; recv_data >> guid; @@ -266,10 +269,10 @@ //Sitting: Wooden bench, chairs enzz case GAMEOBJECT_TYPE_CHAIR: //7 - info = obj->GetGOInfo(); - if(info) + goInfo = obj->GetGOInfo(); + if(goInfo) { - spellId = info->sound0; + spellId = goInfo->sound0; //guid=GetPlayer()->GetGUID(); _player->TeleportTo(obj->GetMapId(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),false,false); @@ -283,30 +286,30 @@ //big gun, its a spell/aura case GAMEOBJECT_TYPE_GOOBER: //10 - info = obj->GetGOInfo(); - spellId = info ? info->sound10 : 0; + goInfo = obj->GetGOInfo(); + spellId = goInfo ? goInfo->sound10 : 0; break; case GAMEOBJECT_TYPE_SPELLCASTER: //22 obj->SetUInt32Value(GAMEOBJECT_FLAGS,2); - info = obj->GetGOInfo(); - if(info) + goInfo = obj->GetGOInfo(); + if(goInfo) { - spellId = info->sound0; + spellId = goInfo->sound0; if (spellId == 0) - spellId = info->sound3; + spellId = goInfo->sound3; //guid=_player->GetGUID(); } break; case GAMEOBJECT_TYPE_CAMERA: //13 - info = obj->GetGOInfo(); - if(info) + goInfo = obj->GetGOInfo(); + if(goInfo) { - uint32 cinematic_id = info->sound1; + uint32 cinematic_id = goInfo->sound1; if(cinematic_id) { WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); @@ -382,7 +385,7 @@ { Unit* caster = obj->GetOwner(); - info = obj->GetGOInfo(); + goInfo = obj->GetGOInfo(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; @@ -394,7 +397,7 @@ obj->AddUse(GetPlayer()); // must 2 group members use GO, or only 1 when it is meeting stone summon - if(obj->GetUniqueUseCount() < (info->sound0 == 2 ? 1 : 2)) + if(obj->GetUniqueUseCount() < (goInfo->sound0 == 2 ? 1 : 2)) return; // in case summoning ritual caster is GO creator @@ -403,7 +406,7 @@ if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) return; - spellId = info->sound1; + spellId = goInfo->sound1; // finish spell caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); @@ -417,7 +420,7 @@ } case GAMEOBJECT_TYPE_MEETINGSTONE: //23 { - info = obj->GetGOInfo(); + goInfo = obj->GetGOInfo(); Player* targetPlayer = ObjectAccessor::Instance().FindPlayer(((Player*)spellCaster)->GetSelection()); @@ -427,10 +430,10 @@ //required lvl checks! uint8 level = _player->getLevel(); - if (level < info->sound0 || level > info->sound1) + if (level < goInfo->sound0 || level > goInfo->sound1) return; level = targetPlayer->getLevel(); - if (level < info->sound0 || level > info->sound1) + if (level < goInfo->sound0 || level > goInfo->sound1) return; spellId = 23598; @@ -439,132 +442,211 @@ } case GAMEOBJECT_TYPE_FLAGSTAND: // 24 - if(_player->InBattleGround() && // in battleground - !_player->IsMounted() && // not mounted - !_player->HasStealthAura() && // not stealthed - !_player->HasInvisibilityAura()) // not invisible - { - BattleGround *bg = sBattleGroundMgr.GetBattleGround(_player->GetBattleGroundId()); - if(!bg) - return; - // BG flag click - // AB: - // 15001 - // 15002 - // 15003 - // 15004 - // 15005 - // WSG: - // 179830 - Silverwing Flag - // 179831 - Warsong Flag - // EotS: - // 184141 - Netherstorm Flag - info = obj->GetGOInfo(); - if(info) + goInfo = obj->GetGOInfo(); + if( goInfo && !_player->IsMounted() && !_player->HasStealthAura() && !_player->HasInvisibilityAura() ) + { + if( goInfo->sound1 == 23333 ) // Horde Flag { - switch(info->id) + if( _player->GetTeam() == ALLIANCE ) + { + obj->SetRespawnTime(8000000); + objmgr.SaveGORespawnTime(obj->GetGUIDLow(), 0, 8000000); + //obj->Delete(); + obj->SetLootState(GO_LOOTED); + spellId = goInfo->sound1; + + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2339); + data << uint32(2); + sWorld.SendGlobalMessage(&data,NULL,ALLIANCE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1546); //Special World Flag for Ally + data2 << uint32(1); + sWorld.SendGlobalMessage(&data2,NULL,HORDE); + + WorldPacket data3(SMSG_PLAY_SOUND,4); + data3 << uint32(8212); //Sound Of Looser ;) + sWorld.SendGlobalMessage(&data3); + } + else { - case 179830: - // check if it's correct bg - if(bg->GetTypeID() != BATTLEGROUND_WS) - return; - // check if flag dropped - if(((BattleGroundWS*)bg)->GetFlagState(ALLIANCE) != BG_WS_FLAG_STATE_ON_BASE) - return; - // check if it's correct flag - if(((BattleGroundWS*)bg)->m_bgobjects[BG_WS_OBJECT_A_FLAG] != obj->GetGUID()) - return; - // check player team - if(_player->GetTeam() == ALLIANCE) - return; - spellId = 23335; // Silverwing Flag - break; - case 179831: - // check if it's correct bg - if(bg->GetTypeID() != BATTLEGROUND_WS) - return; - // check if flag dropped - if(((BattleGroundWS*)bg)->GetFlagState(HORDE) != BG_WS_FLAG_STATE_ON_BASE) - return; - // check if it's correct flag - if(((BattleGroundWS*)bg)->m_bgobjects[BG_WS_OBJECT_H_FLAG] != obj->GetGUID()) - return; - // check player team - if(_player->GetTeam() == HORDE) - return; - spellId = 23333; // Warsong Flag - break; - case 184141: - // check if it's correct bg - if(bg->GetTypeID() != BATTLEGROUND_EY) - return; - spellId = 34976; // Netherstorm Flag - break; + spellId = 0; + for(AuraMap::iterator iter = _player->m_Auras.begin(); iter != _player->m_Auras.end(); ++iter) + { + if(iter->second->GetSpellProto()->Id == 23335) + { + _player->RemoveAura(iter); + + //Reward + _player->giveHonorXpMoney(4,25,50000,false); + _player->giveHonorXpMoney(3,25,50000,true); + _player->SummonGuardian(50200,60000); + + WorldPacket data(SMSG_PLAY_SOUND,4); + data << uint32(8213); //Sound Of Winner ;) + sWorld.SendGlobalMessage(&data); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(2338); + data2 << uint32(1); + sWorld.SendGlobalMessage(&data2,NULL,HORDE); + + GameObject *flagObj = HashMapHolder::Find( MAKE_GUID(1,HIGHGUID_GAMEOBJECT) ); + if(flagObj) + { + flagObj->SetRespawnTime(0); + objmgr.SaveGORespawnTime(flagObj->GetGUIDLow(), 0, 0); + } + } + } } } + + if( goInfo->sound1 == 23335 ) //Ally Flag + { + if( _player->GetTeam() == HORDE ) //Ally Flag is Taken + { + obj->SetRespawnTime(8000000); + objmgr.SaveGORespawnTime(obj->GetGUIDLow(), 0, 8000000); + //obj->Delete(); + obj->SetLootState(GO_LOOTED); + spellId = goInfo->sound1; + + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2338); + data << uint32(2); + sWorld.SendGlobalMessage(&data,NULL,HORDE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1545); //Special World Flag for Ally + data2 << uint32(1); + sWorld.SendGlobalMessage(&data2,NULL,ALLIANCE); + + WorldPacket data3(SMSG_PLAY_SOUND,4); + data3 << uint32(8212); //Sound Of Looser ;) + sWorld.SendGlobalMessage(&data3); + } + else + { + spellId = 0; + + for(AuraMap::iterator iter = _player->m_Auras.begin(); iter != _player->m_Auras.end(); ++iter) + { + if(iter->second->GetSpellProto()->Id == 23333) + { + _player->RemoveAura(iter); + //Reward + _player->giveHonorXpMoney(4,25,50000,false); + _player->giveHonorXpMoney(3,25,50000,true); + _player->SummonGuardian(50201,60000); + + WorldPacket data(SMSG_PLAY_SOUND,4); + data << uint32(8173); //Sound Of Winner ;) + sWorld.SendGlobalMessage(&data); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(2339); + data2 << uint32(1); + sWorld.SendGlobalMessage(&data2,NULL,ALLIANCE); + + GameObject *flagObj = HashMapHolder::Find( MAKE_GUID(2,HIGHGUID_GAMEOBJECT) ); + if(flagObj) + { + flagObj->SetRespawnTime(0); + objmgr.SaveGORespawnTime(flagObj->GetGUIDLow(), 0, 0); + } + } + } + } + } } break; case GAMEOBJECT_TYPE_FLAGDROP: // 26 - if(_player->InBattleGround() && // in battleground - !_player->IsMounted() && // not mounted - !_player->HasStealthAura() && // not stealthed - !_player->HasInvisibilityAura()) // not invisible + goInfo = obj->GetGOInfo(); + if( goInfo && !_player->IsMounted() && !_player->HasStealthAura() && !_player->HasInvisibilityAura() ) { - BattleGround *bg = sBattleGroundMgr.GetBattleGround(_player->GetBattleGroundId()); - if(!bg) - return; - // BG flag dropped - // WSG: - // 179785 - Silverwing Flag - // 179786 - Warsong Flag - // EotS: - // 184142 - Netherstorm Flag - info = obj->GetGOInfo(); - if(info) + spellId = goInfo->sound2; + + if( spellId == 23333 ) //Horde Flag Drop { - switch(info->id) + if( _player->GetTeam() == HORDE ) { - case 179785: // Silverwing Flag - // check if it's correct bg - if(bg->GetTypeID() != BATTLEGROUND_WS) - return; - // check if flag dropped - if(((BattleGroundWS*)bg)->GetFlagState(ALLIANCE) != BG_WS_FLAG_STATE_ON_GROUND) - return; - obj->Delete(); - if(_player->GetTeam() == ALLIANCE) - { - ((BattleGroundWS*)bg)->EventPlayerReturnedFlag(_player); - return; - } - else - { - _player->CastSpell(_player, 23335, true); - return; - } - break; - case 179786: // Warsong Flag - // check if it's correct bg - if(bg->GetTypeID() != BATTLEGROUND_WS) - return; - // check if flag dropped - if(((BattleGroundWS*)bg)->GetFlagState(HORDE) != BG_WS_FLAG_STATE_ON_GROUND) - return; - obj->Delete(); - if(_player->GetTeam() == HORDE) - { - ((BattleGroundWS*)bg)->EventPlayerReturnedFlag(_player); - return; - } - else - { - _player->CastSpell(_player, 23333, true); - return; - } - break; + GameObject *flagObj = HashMapHolder::Find( MAKE_GUID(2,HIGHGUID_GAMEOBJECT) ); + if( flagObj ) + { + flagObj->SetRespawnTime(0); + objmgr.SaveGORespawnTime(flagObj->GetGUIDLow(), 0, 0); + + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2338); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,HORDE); + + WorldPacket data2(SMSG_PLAY_SOUND,4); + data2 << uint32(8192); //Sound Of Returned Flag + sWorld.SendGlobalMessage(&data2); + } + spellId = 0; } + else + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2339); + data << uint32(2); + sWorld.SendGlobalMessage(&data,NULL,ALLIANCE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1546); //Special World Flag for Ally + data2 << uint32(1); + sWorld.SendGlobalMessage(&data2,NULL,HORDE); + + WorldPacket data3(SMSG_PLAY_SOUND,4); + data3 << uint32(8212); //Flag Horde Pickup + sWorld.SendGlobalMessage(&data3); + } } + if(spellId == 23335 ) + { + if( _player->GetTeam() == ALLIANCE ) //Flag Return Ally + { + GameObject *flagObj = HashMapHolder::Find( MAKE_GUID(1,HIGHGUID_GAMEOBJECT) ); + if(flagObj) + { + flagObj->SetRespawnTime(0); + objmgr.SaveGORespawnTime(flagObj->GetGUIDLow(), 0, 0); + + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2339); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,ALLIANCE); + + WorldPacket data2(SMSG_PLAY_SOUND,4); + data2 << uint32(8192); //Sound Of Returned Flag + sWorld.SendGlobalMessage(&data2); + } + spellId = 0; + } + else //Horde Retake Flag Ally + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2338); + data << uint32(2); + sWorld.SendGlobalMessage(&data,NULL,HORDE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1545); //Special World Flag for Ally + data2 << uint32(1); + sWorld.SendGlobalMessage(&data2,NULL,ALLIANCE); + + WorldPacket data3(SMSG_PLAY_SOUND,4); + data3 << uint32(8174); //Flag Ally Pickup + sWorld.SendGlobalMessage(&data3); + } + } + obj->SetLootState(GO_LOOTED); obj->Delete(); + obj->DeleteFromDB(); } break; default: @@ -572,7 +654,8 @@ break; } - if (!spellId) return; + if( !spellId ) + return; SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId ); if(!spellInfo) @@ -686,6 +769,36 @@ return; bg->RemovePlayerFromResurrectQueue(_player->GetGUID()); } + // Warsong Flag, horde + if( spellId == 23333 ) + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2339); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,ALLIANCE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1546); //Special World Flag for Horde + data2 << uint32(-1); + sWorld.SendGlobalMessage(&data2,NULL,HORDE); + + _player->CastSpell(_player,23334,true); + } + // Silverwing Flag, alliance + if( spellId == 23335 ) + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2338); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,HORDE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1545); //Special World Flag for Alliance + data2 << uint32(-1); + sWorld.SendGlobalMessage(&data2,NULL,ALLIANCE); + + _player->CastSpell(_player,23336,true); + } } void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket) Index: src/game/TargetedMovementGenerator.cpp =================================================================== --- src/game/TargetedMovementGenerator.cpp (revision 4656) +++ src/game/TargetedMovementGenerator.cpp (working copy) @@ -22,6 +22,7 @@ #include "Creature.h" #include "MapManager.h" #include "DestinationHolderImp.h" +#include "Spell.h" #define SMALL_ALPHA 0.05f @@ -50,26 +51,37 @@ return; // prevent redundant micro-movement for pets, other followers. - if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset)) + if( i_angle && i_target->IsWithinDistInMap( &owner,i_offset+owner.GetObjectSize() ) ) return; float x, y, z; - if(!i_offset) + if(!i_offset && !i_angle) //Normal Attack Range Selected, 0.5 Default Contact Offset { // to nearest contact position i_target->GetContactPoint( &owner, x, y, z ); + //i_target->GetContactPoint( &owner, x, y, z ); } - else + else if(!i_angle) //We Ask Solution with a i_offset from target + random angle to it. { // to at i_offset distance from target and i_angle from target facing + i_target->GetContactPoint( &owner, x, y, z ,i_offset); + //i_target->GetRandomPoint( x, y, z, i_offset, x, y, z ); + //i_target->GetContactPoint( &owner, x, y, z , i_offset); + //i_target->GetClosePoint(x,y,z,0.0f,i_angle); + //i_target->GetRandomPoint( x, y, z, i_offset, x, y, z ); + } + else //Angle And Offset Allready Set. + { + // to at i_offset distance from target and i_angle from target facing + //owner.GetContactPoint( i_target.getTarget(), x, y, z ,-i_offset); i_target->GetClosePoint(x,y,z,owner.GetObjectSize() + i_offset,i_angle); } - + //We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize - float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE; - if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize ) - return; + //if( sqrt(i_target->GetDistanceSq(x,y,z)) + i_destinationHolder.GetDestinationDiff(x,y,z) <= i_offset+float(irand(2,4)/5) ) + // return; Traveller traveller(owner); + owner.SetInFront(i_target.getTarget()); i_destinationHolder.SetDestination(traveller, x, y, z); owner.addUnitState(UNIT_STAT_CHASE); } @@ -101,14 +113,21 @@ } if( !&owner || !owner.isAlive() || !&i_target ) return true; - if( owner.hasUnitState(UNIT_STAT_ROOT) || owner.hasUnitState(UNIT_STAT_STUNDED) || owner.hasUnitState(UNIT_STAT_FLEEING)) + if( owner.hasUnitState(UNIT_STAT_ROOT) || owner.hasUnitState(UNIT_STAT_STUNDED) || owner.hasUnitState(UNIT_STAT_FLEEING) || owner.HasSpellChannelActiveTimer()) return true; if( !owner.isInCombat() && !owner.hasUnitState(UNIT_STAT_FOLLOW) ) { //owner.AIM_Initialize(); This case must be the one, when a creature aggroed you. By Initalized a new AI, we prevented to Ai::_stopAttack() to be executed properly. return true; } - + + //To Debug why sometime Mangos screw: UNIT_FIELD_TARGET + if( owner.getVictim() && i_target.getTarget() && owner.GetUInt64Value(UNIT_FIELD_TARGET) != i_target.getTarget()->GetGUID() ) + { + owner.GetUInt64Value(UNIT_FIELD_TARGET); + //Just hope is not into the back Stack... + } + // prevent crash after creature killed pet if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget()) return true; @@ -127,29 +146,33 @@ if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false)) { // put targeted movement generators on a higher priority - if (owner.GetObjectSize()) - i_destinationHolder.ResetUpdate(50); + //if (owner.GetObjectSize()) + //i_destinationHolder.ResetUpdate(300); - float dist = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE; + //float dist = i_target.isValid() ? i_target->GetObjectSize() : 0.38f + owner.GetObjectSize() + CONTACT_DISTANCE + (i_offset/2); // try to counter precision differences - if( i_destinationHolder.GetDistanceFromDestSq(*i_target.getTarget()) > dist * dist + 0.8) + float _difference = sqrt(i_destinationHolder.GetDistanceFromDestSq(*i_target.getTarget())) - (i_offset+i_target->GetObjectSize()+(CONTACT_DISTANCE*2)) > owner.GetObjectSize(); + if( sqrt(i_destinationHolder.GetDistanceFromDestSq(*i_target.getTarget())) - (i_offset+i_target->GetObjectSize()+(CONTACT_DISTANCE*2)) > owner.GetObjectSize()+(owner.GetObjectSize()/10) ) { - owner.SetInFront(i_target.getTarget()); // Set new Angle For Map:: + owner.SetInFront(i_target.getTarget()); // Set new Angle For Map _setTargetLocation(owner); //Calculate New Dest and Send data To Player } // Update the Angle of the target only for Map::, no need to send packet for player - else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) ) - owner.SetInFront(i_target.getTarget()); + // i_angle represente a pet like movement + //else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) ) + //owner.SetInFront(i_target.getTarget()); + + //Angle update should be alone and at about 70ms timing. if( !owner.IsStopped() && i_destinationHolder.HasArrived()) { - //Angle update will take place into owner.StopMoving() + owner.StopMoving(); owner.SetInFront(i_target.getTarget()); - - owner.StopMoving(); - if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW)) - owner.Attack(i_target.getTarget()); + //if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW)) + //owner.Attack(i_target.getTarget()); + if(i_forceExpireAtDest) + return false; } } return true; @@ -161,7 +184,18 @@ { return i_target.getTarget(); } - +template +float +TargetedMovementGenerator::GetOffSet() const +{ + return i_offset; +} +template +void +TargetedMovementGenerator::SetOffSet(float newOffSet) +{ + i_offset = *new float(newOffSet); +} template void TargetedMovementGenerator::_setTargetLocation(Player &); template void TargetedMovementGenerator::_setTargetLocation(Creature &); template void TargetedMovementGenerator::Initialize(Player &); @@ -172,3 +206,7 @@ template bool TargetedMovementGenerator::Update(Creature &, const uint32 &); template Unit* TargetedMovementGenerator::GetTarget() const; template Unit* TargetedMovementGenerator::GetTarget() const; +template float TargetedMovementGenerator::GetOffSet() const; +template float TargetedMovementGenerator::GetOffSet() const; +template void TargetedMovementGenerator::SetOffSet(float newOffSet); +template void TargetedMovementGenerator::SetOffSet(float newOffSet); \ No newline at end of file Index: src/game/TargetedMovementGenerator.h =================================================================== --- src/game/TargetedMovementGenerator.h (revision 4656) +++ src/game/TargetedMovementGenerator.h (working copy) @@ -41,8 +41,8 @@ TargetedMovementGenerator(Unit &target) : TargetedMovementGeneratorBase(target), i_offset(0), i_angle(0) {} - TargetedMovementGenerator(Unit &target, float offset, float angle) - : TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle) {} + TargetedMovementGenerator(Unit &target, float offset, float angle, bool forceExpireAtDest = false) + : TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle),i_forceExpireAtDest(forceExpireAtDest) {} ~TargetedMovementGenerator() {} void Initialize(T &); @@ -51,7 +51,9 @@ MovementGeneratorType GetMovementGeneratorType() { return TARGETED_MOTION_TYPE; } Unit* GetTarget() const; - + float GetOffSet() const; + void SetOffSet(float newOffSet); + bool GetDestination(float &x, float &y, float &z) { if(!i_destinationHolder.HasDestination()) return false; @@ -61,9 +63,10 @@ private: void _setTargetLocation(T &); - + float i_offset; float i_angle; + bool i_forceExpireAtDest; DestinationHolder< Traveller > i_destinationHolder; }; #endif Index: src/game/Transports.cpp =================================================================== --- src/game/Transports.cpp (revision 4656) +++ src/game/Transports.cpp (working copy) @@ -468,6 +468,7 @@ void Transport::Update(uint32 p_time) { + return; if (m_WayPoints.size() <= 1) return; Index: src/game/Traveller.h =================================================================== --- src/game/Traveller.h (revision 4656) +++ src/game/Traveller.h (working copy) @@ -47,6 +47,7 @@ inline float GetPositionX() const { return i_traveller.GetPositionX(); } inline float GetPositionY() const { return i_traveller.GetPositionY(); } inline float GetPositionZ() const { return i_traveller.GetPositionZ(); } + inline float GetOrientation() const { return i_traveller.GetOrientation(); } inline T& GetTraveller(void) { return i_traveller; } float Speed(void) { assert(false); return 0.0f; } Index: src/game/Unit.cpp =================================================================== --- src/game/Unit.cpp (revision 4656) +++ src/game/Unit.cpp (working copy) @@ -131,6 +131,7 @@ for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) m_currentSpells[i] = NULL; + m_hasHealer = false; m_addDmgOnce = 0; m_TotemSlot[0] = m_TotemSlot[1] = m_TotemSlot[2] = m_TotemSlot[3] = 0; m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0; @@ -301,17 +302,16 @@ SendMonsterMove(x,y,z,0,run,transitTime); } -void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time) +void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time, bool tryFlag512) { WorldPacket data( SMSG_MONSTER_MOVE, (41 + GetPackGUID().size()) ); data.append(GetPackGUID()); - // Point A, starting location data << GetPositionX() << GetPositionY() << GetPositionZ(); // unknown field - unrelated to orientation // seems to increment about 1000 for every 1.7 seconds // for now, we'll just use mstime - data << getMSTime(); + data << getMSTime()/* + ((Time / 1000) * 140)*/; //Simulate 140 allways Ping data << uint8(type); // unknown switch(type) @@ -329,7 +329,10 @@ break; } - data << uint32(Run ? 0x00000100 : 0x00000000); // flags (0x100 - running, 0x200 - taxi) + if(tryFlag512) + data << uint32(0x11111111); + else + data << uint32(Run ? 0x00000100 : 0x00000000); // flags (0x100 - running, 0x200 - taxi) /* Flags: 512: Floating, moving without walking/running */ @@ -345,7 +348,7 @@ if (GetTypeId() == TYPEID_PLAYER) m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); else - m_attackTimer[type] = uint32(BASE_ATTACK_TIME * m_modAttackSpeedPct[type]); + m_attackTimer[type] = uint32( ((Creature*)this)->GetCreatureInfo()->baseattacktime * m_modAttackSpeedPct[BASE_ATTACK]); } bool Unit::canReachWithAttack(Unit *pVictim) const @@ -382,6 +385,10 @@ return (!m_modAuras[auraType].empty()); } +bool Unit::HasSpellChannelActiveTimer() +{ + return m_currentSpells[CURRENT_CHANNELED_SPELL] ? m_currentSpells[CURRENT_CHANNELED_SPELL]->GetTimer() > 0 : false; +} /* Called by DealDamage for auras that have a chance to be dispelled on damage taken. */ void Unit::RemoveSpellbyDamageTaken(uint32 auraType, uint32 damage) { @@ -549,6 +556,41 @@ } } + //CTF Constant System + for(AuraMap::iterator iter = pVictim->m_Auras.begin(); iter != pVictim->m_Auras.end(); ++iter) + { + if(iter->second->GetSpellProto()->Id == 23335) + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2339); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,HORDE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1545); //Special World Flag for Alliance + data2 << uint32(-1); + sWorld.SendGlobalMessage(&data2,NULL,ALLIANCE); + + pVictim->CastSpell(this,23336,true); + break; + } + if(iter->second->GetSpellProto()->Id == 23333) + { + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4); + data << uint32(2339); + data << uint32(1); + sWorld.SendGlobalMessage(&data,NULL,ALLIANCE); + + WorldPacket data2(SMSG_UPDATE_WORLD_STATE, 4+4); + data2 << uint32(1546); //Special World Flag for HORDE + data2 << uint32(-1); + sWorld.SendGlobalMessage(&data2,NULL,HORDE); + + pVictim->CastSpell(this,23334,true); + break; + } + } + DEBUG_LOG("DealDamage: victim just died"); DEBUG_LOG("DealDamageAttackStop"); @@ -630,6 +672,9 @@ ((Creature*)pVictim)->AI()->JustDied(this); } + + m_hasHealer = false; + //judge if GainXP, Pet kill like player kill,kill pet not like PvP bool PvP = false; Player *player = NULL; @@ -863,7 +908,7 @@ if (damagetype != NODAMAGE) { - if(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL] && pVictim->GetTypeId() == TYPEID_PLAYER && damage) + if(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL] /*&& pVictim->GetTypeId() == TYPEID_PLAYER*/ && damage) { if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_CASTING) { @@ -2028,7 +2073,7 @@ } } - if (pVictim->GetTypeId() == TYPEID_PLAYER && *damage) + if (/*pVictim->GetTypeId() == TYPEID_PLAYER &&*/ *damage) { for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) { @@ -4728,19 +4773,21 @@ //Set our target SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); + SetInFront(victim); addUnitState(UNIT_STAT_ATTACKING); SetInCombat(); m_attacking = victim; m_attacking->_addAttacker(this); - if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI()) - ((Creature*)m_attacking)->AI()->AttackedBy(this); + //if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI()) + //((Creature*)m_attacking)->AI()->AttackedBy(this); //Heu.. don't understand why we need that??? - if( GetTypeId()==TYPEID_UNIT && !(((Creature*)this)->isPet() || isCharmed()) ) + /*if( GetTypeId()==TYPEID_UNIT && !(((Creature*)this)->isPet() || isCharmed()) ) { ((Creature*)this)->CallAssistence(); - } + }*/ + //if(!isAttackReady(BASE_ATTACK)) //resetAttackTimer(BASE_ATTACK); @@ -6312,19 +6359,17 @@ if(target) { - SetInFront(target); ((Creature*)this)->AI()->AttackStart(target); return true; } // no target but something prevent go to evade mode + // !isInCombat(), Do EnterEvade Only if inCombat(), no need after + // HasAuraType(SPELL_AURA_MOD_TAUNT), Cause EnterEvadeTake Place here : Unit::TauntFadeOut(Unit *taunter) if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_TAUNT) || !CanFreeMove() ) return false; - // last case when creature don't must go to evade mode: - // it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list - // for example at owner command to pet attack some far away creature - // Note: creature not have targeted movement generator but have attacker in this case + // this, is waiting the Attacker to come to aggro range, no yet Threat Created from Attacker, GS if( GetMotionMaster()->empty() || GetMotionMaster()->top()->GetMovementGeneratorType() != TARGETED_MOTION_TYPE ) { for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr) Index: src/game/Unit.h =================================================================== --- src/game/Unit.h (revision 4656) +++ src/game/Unit.h (working copy) @@ -904,7 +904,9 @@ { return m_Auras.find(spellEffectPair(spellId, effIndex)) != m_Auras.end(); } bool virtual HasSpell(uint32 /*spellID*/) const { return false; } + bool HasSpellChannelActiveTimer(); + bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); } bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); } bool isFeared() const { return HasAuraType(SPELL_AURA_MOD_FEAR); } @@ -934,7 +936,7 @@ void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchools DamageType, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount); void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchools DamageType,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false); - void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time); + void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time, bool tryFlag512 = false); virtual void MoveOutOfRange(Player &) { }; @@ -1018,6 +1020,7 @@ void InterruptNonMeleeSpells(bool withDelayed); Spell* m_currentSpells[CURRENT_MAX_SPELL]; + bool m_hasHealer; uint32 m_addDmgOnce; uint64 m_TotemSlot[4]; uint64 m_ObjectSlot[4]; Index: src/game/World.cpp =================================================================== --- src/game/World.cpp (revision 4656) +++ src/game/World.cpp (working copy) @@ -674,7 +674,7 @@ m_timers[WUPDATE_OBJECTS].SetInterval(0); m_timers[WUPDATE_SESSIONS].SetInterval(0); m_timers[WUPDATE_WEATHERS].SetInterval(1000); - m_timers[WUPDATE_AUCTIONS].SetInterval(60000); //set auction update interval to 1 minute + m_timers[WUPDATE_AUCTIONS].SetInterval(60*60000); //set auction update interval to 1 minute m_timers[WUPDATE_UPTIME].SetInterval(10*60000); //Update "uptime" table every 10 minutes m_timers[WUPDATE_CORPSES].SetInterval(20*60000); //erase corpses every 20 minutes @@ -766,63 +766,7 @@ if (m_timers[WUPDATE_AUCTIONS].Passed()) { m_timers[WUPDATE_AUCTIONS].Reset(); - - ///- Update mails (return old mails with item, or delete them) - //(tested... works on win) - if (++mail_timer > mail_timer_expires) - { - mail_timer = 0; - objmgr.ReturnOrDeleteOldMails(true); - } - - AuctionHouseObject* AuctionMap; - for (int i = 0; i < 3; i++) - { - switch (i) - { - case 0: - AuctionMap = objmgr.GetAuctionsMap( 6 );//horde - break; - case 1: - AuctionMap = objmgr.GetAuctionsMap( 2 );//alliance - break; - case 2: - AuctionMap = objmgr.GetAuctionsMap( 7 );//neutral - break; - } - - ///- Handle expired auctions - AuctionHouseObject::AuctionEntryMap::iterator itr,next; - for (itr = AuctionMap->GetAuctionsBegin(); itr != AuctionMap->GetAuctionsEnd();itr = next) - { - next = itr; - ++next; - if (m_gameTime > (itr->second->time)) - { - ///- Either cancel the auction if there was no bidder - if (itr->second->bidder == 0) - { - objmgr.SendAuctionExpiredMail( itr->second ); - } - ///- Or perform the transaction - else - { - //we should send an "item sold" message if the seller is online - //we send the item to the winner - //we send the money to the seller - objmgr.SendAuctionSuccessfulMail( itr->second ); - objmgr.SendAuctionWonMail( itr->second ); - } - - ///- In any case clear the auction - //No SQL injection (Id is integer) - sDatabase.PExecute("DELETE FROM `auctionhouse` WHERE `id` = '%u'",itr->second->Id); - objmgr.RemoveAItem(itr->second->item_guid); - delete itr->second; - AuctionMap->RemoveAuction(itr->first); - } - } - } + sDatabase.PExecute("UPDATE `auctionhouse` SET `time`=%u",(time(NULL)+(3600*24))); } ///
  • Handle session updates when the timer has passed Index: src/mangosd/Master.cpp =================================================================== --- src/mangosd/Master.cpp (revision 4656) +++ src/mangosd/Master.cpp (working copy) @@ -33,7 +33,7 @@ #include "Policies/SingletonImp.h" #include "SystemConfig.h" #include "Config/ConfigEnv.h" -#include "Database/DatabaseEnv.h" + #include "CliRunnable.h" #include "RASocket.h" #include "ScriptCalls.h" @@ -269,7 +269,6 @@ return; } - /// Initialize connection to the databases bool Master::_StartDB() { Index: src/mangosd/Master.h =================================================================== --- src/mangosd/Master.h (revision 4656) +++ src/mangosd/Master.h (working copy) @@ -25,6 +25,7 @@ #include "Common.h" #include "Policies/Singleton.h" +#include "Database/DatabaseEnv.h" /// Start the server class Master @@ -33,7 +34,6 @@ Master(); ~Master(); void Run(); - private: bool _StartDB(); Index: src/shared/Database/DatabaseEnv.h =================================================================== --- src/shared/Database/DatabaseEnv.h (revision 4656) +++ src/shared/Database/DatabaseEnv.h (working copy) @@ -39,6 +39,7 @@ #include "Database/Database.h" #include "Database/DatabaseMysql.h" #include "Database/DatabaseSqlite.h" + extern DatabaseMysql sDatabase; extern DatabaseMysql loginDatabase; #endif Index: src/shared/Database/DBCStores.cpp =================================================================== --- src/shared/Database/DBCStores.cpp (revision 4656) +++ src/shared/Database/DBCStores.cpp (working copy) @@ -796,3 +796,19 @@ // script support functions MANGOS_DLL_SPEC DBCStorage const* GetSpellStore() { return &sSpellStore; } MANGOS_DLL_SPEC DBCStorage const* GetSpellRangeStore() { return &sSpellRangeStore; } +MANGOS_DLL_SPEC DBCStorage const* GetSpellDurationStore() { return &sSpellDurationStore; } +MANGOS_DLL_SPEC DBCStorage const* GetCastTimesStore() { return &sCastTimesStore; } +//AI Improuvement +/*MANGOS_DLL_SPEC void GetCreatureSpellBook(uint32 entry, char** spellInfo) +{ + QueryResult *result = sDatabase.PQuery("SELECT * FROM `creature_SpellBook` WHERE `entry`=%u",entry); + if(result) // wrong data found + { + Field *fields = result->Fetch(); + spellInfo = new char*[14]; + for(uint8 itr = 1; itr < 15; ++itr) + spellInfo[itr] = new char[] = ((char*)fields[1].GetString()); + + delete result; + } +}*/ Index: src/shared/Database/DBCStores.h =================================================================== --- src/shared/Database/DBCStores.h (revision 4656) +++ src/shared/Database/DBCStores.h (working copy) @@ -199,6 +199,8 @@ void LoadDBCStores(std::string dataPath); // script support functions -MANGOS_DLL_SPEC DBCStorage const* GetSpellStore() ; -MANGOS_DLL_SPEC DBCStorage const* GetSpellRangeStore() ; +MANGOS_DLL_SPEC DBCStorage const* GetSpellStore(); +MANGOS_DLL_SPEC DBCStorage const* GetSpellRangeStore(); +MANGOS_DLL_SPEC DBCStorage const* GetSpellDurationStore(); +MANGOS_DLL_SPEC DBCStorage const* GetCastTimesStore(); #endif Index: src/shared/Database/QueryResult.h =================================================================== --- src/shared/Database/QueryResult.h (revision 4656) +++ src/shared/Database/QueryResult.h (working copy) @@ -19,7 +19,7 @@ #if !defined(QUERYRESULT_H) #define QUERYRESULT_H -class QueryResult +class MANGOS_DLL_SPEC QueryResult { public: QueryResult(uint64 rowCount, uint32 fieldCount) Index: src/shared/Database/SQLStorage.cpp =================================================================== --- src/shared/Database/SQLStorage.cpp (revision 4656) +++ src/shared/Database/SQLStorage.cpp (working copy) @@ -28,6 +28,7 @@ const char CreatureInfofmt[]="iiiiissiiiiiiiiiififfiiiiiiiiiiiffiiliiiiiiiiiiiiiiiisiillis"; const char CreatureDataAddonInfofmt[]="iiiiiiiiiii"; +//const char CreatureSpellBookInfofmt[]="issssssssssssss"; const char CreatureModelfmt[]="iffii"; const char CreatureInfoAddonInfofmt[]="iiiiiiiiiii"; const char EquipmentInfofmt[]="iiiiiiiiii"; @@ -38,6 +39,7 @@ SQLStorage sCreatureStorage(CreatureInfofmt,"entry","creature_template"); SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon"); +//SQLStorage sCreatureSpellBookStorage(CreatureSpellBookInfofmt,"entry","creature_spellbook"); SQLStorage sCreatureModelStorage(CreatureModelfmt,"modelid","creature_model_info"); SQLStorage sCreatureInfoAddonStorage(CreatureInfoAddonInfofmt,"entry","creature_template_addon"); SQLStorage sEquipmentStorage(EquipmentInfofmt,"entry","creature_equip_template"); @@ -181,4 +183,4 @@ pIndex =newIndex; MaxEntry=maxi; data=_data; -} +} \ No newline at end of file Index: src/shared/Database/SQLStorage.h =================================================================== --- src/shared/Database/SQLStorage.h (revision 4656) +++ src/shared/Database/SQLStorage.h (working copy) @@ -25,7 +25,6 @@ class SQLStorage { public: - SQLStorage(const char*fmt,const char * _entry_field,const char * sqlname) { format=fmt; @@ -65,4 +64,4 @@ const char *entry_field; //bool HasString; }; -#endif +#endif \ No newline at end of file Index: src/shared/Util.h =================================================================== --- src/shared/Util.h (revision 4656) +++ src/shared/Util.h (working copy) @@ -34,6 +34,7 @@ /* Return a random number in the range min..max; (max-min) must be smaller than 32768. * Note: Not reentrant - if two threads call this simultaneously, they will likely * get the same random number. */ +MANGOS_DLL_SPEC extern int32 irand(int32 min, int32 max); /* Return a random number in the range min..max; (max-min) must be smaller than 32768. @@ -50,11 +51,13 @@ /* Return a random number in the range 0 .. RAND32_MAX. * Note: Not reentrant - if two threads call this simultaneously, they will likely * get the same random number. */ +MANGOS_DLL_SPEC extern int32 rand32(void); /* Return a random double from 0.0 to 1.0 (exclusive). Floats support only 7 valid decimal digits. * A double supports up to 15 valid decimal digits and is used internaly (RAND32_MAX has 10 digits). * With an FPU, there is usually no difference in performance between float and double. */ +MANGOS_DLL_SPEC inline double rand_norm(void) { return double(rand32()) / double(RAND32_MAX+1); Index: win/VC80/mangosd.vcproj =================================================================== --- win/VC80/mangosd.vcproj (revision 4656) +++ win/VC80/mangosd.vcproj (working copy) @@ -1,7 +1,7 @@