コード例 #1
0
void AI_SUPPORT_TOWER::CastSpellBookSpell( uint32 SpellBookPage, Unit *target )
{
	if( SpellBookPage != TOWER_INVALID_SPELL_INDEX )
	{
		uint64 target_guid = target->GetGUID();
		SetNextTarget( target_guid );

        SpellCastTargets targets( target_guid );
		SpellEntry *spellInfo = dbcSpell.LookupEntry( SpellBook[ SpellBookPage ].spell_id );
		if (spellInfo)
		{
			Spell *spell = SpellPool.PooledNew();
			spell->Init( m_Unit, spellInfo ,true, NULL);
			spell->forced_basepoints[0] = SpellBook[ SpellBookPage ].spell_effect_scale_fixed[ 0 ];
			if( SpellBook[ SpellBookPage ].spell_duration_fixed )
				spell->forced_duration = SpellBook[ SpellBookPage ].spell_duration_fixed;
//			m_Unit->ModUnsigned32Value( UNIT_FIELD_POWER1, m_Unit->GetUInt32Value( UNIT_FIELD_POWER1 ) * spellInfo->ManaCostPercentage );
			spell->prepare(&targets);
		}

		GlobalCoolDownFinished = TickNow + SpellBook[ SpellBookPage ].spell_global_cooldown;
		SpellInstances[ SpellBookPage ].cooldown_finished = TickNow + SpellBook[ SpellBookPage ].spell_cooldown;
		LastUsedSpellIndex  = SpellBookPage;
	}
}
コード例 #2
0
ファイル: SpellAuraHooks.cpp プロジェクト: Odiis/Descent-core
SPELL_EFFECT_OVERRIDE_RETURNS AH_48181( Aura *aur, bool apply, uint8 i )
{
    if( apply == false )
    {
        Unit *target = aur->GetTarget();
        ProcTriggerSpell *pts = target->HasProcSpell( 50091 );
        if( pts )
        {
            int32 dmg_received = pts->created_with_value;
            if( dmg_received > 0 )
            {
                Unit *caster = aur->GetUnitCaster();
                //cast the soul animation
                if( target && caster )
                    target->CastSpell( caster, 50091, false );
                //heal the owner
                if( caster )
                {
                    SpellEntry *spellInfo = dbcSpell.LookupEntry( 48210 );
                    Spell *spell = SpellPool.PooledNew( __FILE__, __LINE__ );
                    spell->Init( caster, spellInfo ,true, NULL);
                    SpellCastTargets targets2( caster->GetGUID() );
                    spell->forced_basepoints[0] = dmg_received;
//					spell->static_dmg[0] = dmg_received;	//some say demon armor should boost this
                    spell->prepare( &targets2 );
                }
            }
        }
        target->UnRegisterProcStruct( NULL, 50091 );
    }
    return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION;
}
コード例 #3
0
ファイル: Level2.cpp プロジェクト: AegisEmu/AegisEmu
bool ChatHandler::HandleKillCommand(const char *args, WorldSession *m_session)
{
	Unit * target = m_session->GetPlayer()->GetMapMgr()->GetUnit(m_session->GetPlayer()->GetSelection());
	if(target == 0)
	{
		RedSystemMessage(m_session, "A valid selection is required.");
		return true;
	}

	switch(target->GetTypeId())
	{
	case TYPEID_PLAYER:
		sGMLog.writefromsession(m_session, "used kill command on PLAYER %s", static_cast< Player* >( target )->GetName() );
		break;

	case TYPEID_UNIT:
		sGMLog.writefromsession( m_session, "used kill command on CREATURE %u [%s], sqlid %u%s", static_cast< Creature* >( target )->GetEntry(), static_cast< Creature* >( target )->GetCreatureInfo() ? static_cast< Creature* >( target )->GetCreatureInfo()->Name : "unknown", static_cast< Creature* >( target )->GetSQL_id(), m_session->GetPlayer()->InGroup() ? ", in group" : "" );
		break;
	}


	// If we're killing a player, send a message indicating a gm killed them.
	if(target->IsPlayer())
	{
		Player * plr = static_cast< Player* >(target);
		// cebernic: kill just is kill,don't use dealdamage for it
		// godcheat will not stop the killing,godcheat for DealDamage() only.
		//m_session->GetPlayer()->DealDamage(plr, plr->GetUInt32Value(UNIT_FIELD_HEALTH)*2,0,0,0);
		plr->SetUInt32Value(UNIT_FIELD_HEALTH, 0);
		plr->KillPlayer();
		BlueSystemMessageToPlr(plr, "%s killed you with a GM command.", m_session->GetPlayer()->GetName());
	}
	else
	{

		// Cast insta-kill.
		SpellEntry * se = dbcSpell.LookupEntry(5);
		if(se == 0) return false;

		SpellCastTargets targets(target->GetGUID());
		Spell * sp = SpellPool.PooledNew();
		sp->Init(m_session->GetPlayer(), se, true, 0);
		sp->prepare(&targets);

/*		SpellEntry * se = dbcSpell.LookupEntry(20479);
		if(se == 0) return false;

		SpellCastTargets targets(target->GetGUID());
		Spell * sp = new Spell(target, se, true, 0);
		sp->prepare(&targets);*/
	}

	return true;
}
コード例 #4
0
ファイル: Level2.cpp プロジェクト: Naqvamp/Sandbox
bool ChatHandler::HandleCastSelfCommand(const char* args, WorldSession *m_session)
{
	Unit *target = m_session->GetPlayer();
	//SystemMessage(m_session, "Auto-targeting self.");
	GreenSystemMessage(m_session, "Auto-targeting self.");
/*	Unit *target = getSelectedChar(m_session, false);
	if(!target)
		target = getSelectedCreature(m_session, false);
	if(!target)
	{
		RedSystemMessage(m_session, "Must select a char or creature.");
		return false;
	}
*/

	uint32 spellid = atol(args);
	SpellEntry *spellentry = dbcSpell.LookupEntry(spellid);
	if(!spellentry)
	{
		RedSystemMessage(m_session, "Invalid spell id!");
		return false;
	}

	Spell *sp = SpellPool.PooledNew();
	sp->Init(target, spellentry, false, NULL);
	if(!sp)
	{
		RedSystemMessage(m_session, "Spell failed creation!");
		SpellPool.PooledDelete( sp );
		return false;
	}

	BlueSystemMessage(m_session, "You have cast the spell %d on yourself.", spellid);
	SpellCastTargets targets;
	targets.m_unitTarget = target->GetGUID();
	sp->prepare(&targets);

/*	switch ( target->GetTypeId() )
	{
		case TYPEID_PLAYER:
			if ( m_session->GetPlayer() != target )
				sGMLog.writefromsession( m_session, "used castself with spell %d on PLAYER %s", spellid, static_cast< Player* >( target )->GetName() );
			break;
		case TYPEID_UNIT:
			sGMLog.writefromsession( m_session, "used castself with spell %d on CREATURE %u [%s], sqlid %u", spellid, static_cast< Creature* >( target )->GetEntry(), static_cast< Creature* >( target )->GetCreatureInfo() ? static_cast< Creature* >( target )->GetCreatureInfo()->Name : "unknown", static_cast< Creature* >( target )->GetSQL_id() );
			break;
	}
*/

	return true;
}
コード例 #5
0
	void OnDied(Unit *mKiller)
	{
		Unit *o = _unit->GetTopOwner();
		if( o->HasAuraWithNameHash( SPELL_HASH_FUNGAL_GROWTH, 0, AURA_SEARCH_PASSIVE ) )
		{
			SpellCastTargets targets( NULL );
			targets.m_targetMask = TARGET_FLAG_DEST_LOCATION;
			targets.m_destX = _unit->GetPositionX();
			targets.m_destY = _unit->GetPositionY();
			targets.m_destZ = _unit->GetPositionZ();
			SpellEntry *spellInfo = dbcSpell.LookupEntry( 94339 ); //Fungal Growth Visual
			Spell *spell = SpellPool.PooledNew( __FILE__, __LINE__ );
			spell->Init( o, spellInfo ,true, NULL);
			spell->prepare(&targets);
		}
	}
コード例 #6
0
void Tournament_Supervisor::Update(uint32 p_time)
{
/*	//method to pass commands to tournament via any supervizor
	debug_commands = m_Unit->GetUInt32Value( UNIT_FIELD_MAXHEALTH );

	//make him normal 
	m_Unit->SetUInt32Value( UNIT_FIELD_MAXHEALTH, SUPERVIZOR_MAX_HEALTH );*/

	//see if we need to turn anyone into a spectator

	//update spam will be filtered inside function
	UpdateTournaments( );

	//check for spectators and update their aura
	InrangeLoopExitAutoCallback AutoLock;
	for( InRangeSetRecProt::iterator itr = m_Unit->GetInRangeSetBegin( AutoLock ); itr != m_Unit->GetInRangeSetEnd(); ++itr)
	{
		if( !(*itr) || !(*itr)->IsInWorld() )
			continue;
		if( (*itr)->IsPlayer() )
		{
			if( IsPlayerSpectator( (Player*)(*itr) ) == false )
				continue;
		}
		else if( (*itr)->IsUnit() && (*itr)->GetUInt32Value( UNIT_FIELD_CREATEDBY ) )
		{
			Unit *Owner = m_Unit->GetMapMgr()->GetUnit( (*itr)->GetUInt32Value( UNIT_FIELD_CREATEDBY ) );
			if( Owner && Owner->IsPlayer() && IsPlayerSpectator( (Player*)(Owner) ) == false )
				continue;
			//what about totems that summon guardians ? Call GM ?
		}
		if( (*itr)->IsUnit() && ((Unit *)(*itr))->HasAura( SPECTATOR_AURA_ID, 0, AURA_SEARCH_NEGATIVE ) == false && IsUnitInsideAnyBattleRing( (*itr)->GetMapId(), (*itr)->GetPositionX(), (*itr)->GetPositionY() ) == true )
		{
			SpellEntry *spellInfo = dbcSpell.LookupEntry( SPECTATOR_AURA_ID );
			Spell *spell = SpellPool.PooledNew( __FILE__, __LINE__ );
			SpellCastTargets targets( (*itr)->GetGUID() );
			spell->Init((*itr), spellInfo ,true, NULL);
			spell->prepare(&targets);
		}
	}
}
コード例 #7
0
ファイル: Arenas.cpp プロジェクト: pfchrono/rs-ascent
void Arena::HookOnAreaTrigger(Player * plr, uint32 id)
{
	int32 buffslot = -1;

	ASSERT(plr != NULL);

	switch (id)
	{
		case 4536:
		case 4538:
		case 4696:
			buffslot = 0;
			break;
		case 4537:
		case 4539:
		case 4697:
			buffslot = 1;
			break;
	}

	if(buffslot >= 0)
	{
		if(m_buffs[buffslot] != NULL && m_buffs[buffslot]->IsInWorld())
		{
			/* apply the buff */
			SpellEntry * sp = dbcSpell.LookupEntry(m_buffs[buffslot]->GetInfo()->sound3);
			Spell * s = SpellPool.PooledNew();

			ASSERT(sp != NULL);
			ASSERT(s != NULL);

			s->Init(plr, sp, true, 0);
			SpellCastTargets targets(plr->GetGUID());
			s->prepare(&targets);

			/* despawn the gameobject (not delete!) */
			m_buffs[buffslot]->Despawn(BUFF_RESPAWN_TIME);
		}
	}
}
コード例 #8
0
ファイル: WarsongGulch.cpp プロジェクト: AegisEmu/AegisEmu
void WarsongGulch::HookFlagStand(Player * plr, GameObject * obj)
{
#ifdef ANTI_CHEAT
	if(!m_started)
	{
		Anticheat_Log->writefromsession(plr->GetSession(), "%s tryed to hook the flag in warsong gluch before battleground (ID %u) started.", plr->GetName(), this->m_id);
		SendChatMessage(CHAT_MSG_BG_EVENT_NEUTRAL, plr->GetGUID(), "%s will be removed from the game for cheating.", plr->GetName());
		// Remove player from battleground.
		this->RemovePlayer(plr, false);
		// Kick player from server.
		plr->Kick(6000);
		return;
	}
#endif
	if(m_flagHolders[plr->GetTeam()] || m_homeFlags[plr->GetTeam()] != obj)
	{
		// cheater!
		return;
	}

	map<uint32,uint32>::iterator itr = plr->m_forcedReactions.find(1059);
	if (itr != plr->m_forcedReactions.end()) {
		return;
	}

	SpellEntry * pSp = dbcSpell.LookupEntry(23333 + (plr->GetTeam() * 2));
	Spell * sp = SpellPool.PooledNew();
	sp->Init(plr, pSp, true, 0);
	SpellCastTargets targets(plr->GetGUID());
	sp->prepare(&targets);

	/* set the flag holder */
	m_flagHolders[plr->GetTeam()] = plr->GetLowGUID();
	if(m_homeFlags[plr->GetTeam()]->IsInWorld())
		m_homeFlags[plr->GetTeam()]->RemoveFromWorld(false);

	PlaySoundToAll(plr->GetTeam() ? SOUND_HORDE_CAPTURE : SOUND_ALLIANCE_CAPTURE);
	SetWorldState(plr->GetTeam() ? WSG_ALLIANCE_FLAG_CAPTURED : WSG_HORDE_FLAG_CAPTURED, 2);
}
コード例 #9
0
ファイル: SpellHandler.cpp プロジェクト: wow4all/wowtbc
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
	if(!_player->IsInWorld()) return;
	typedef std::list<Aura*> AuraList;
	
	Player* p_User = GetPlayer();
	sLog.outDetail("WORLD: got use Item packet, data length = %i",recvPacket.size());
	int8 tmp1,slot,tmp3;
	uint64 item_guid;
	uint8 cn;
	uint32 spellId = 0;

	recvPacket >> tmp1 >> slot >> tmp3 >> cn >> item_guid;
	Item* tmpItem = NULL;
	tmpItem = p_User->GetItemInterface()->GetInventoryItem(tmp1,slot);
	if (!tmpItem)
		tmpItem = p_User->GetItemInterface()->GetInventoryItem(slot);
	if (!tmpItem)
		return;
	ItemPrototype *itemProto = tmpItem->GetProto();
	if(!itemProto)
		return;

  if ( tmpItem->IsSoulbound() ){ // SouldBind item will be used after SouldBind()
    if(sScriptMgr.CallScriptedItem(tmpItem,_player))
		  return;
  }

	if(_player->getDeathState()==CORPSE)
                return;

        if(itemProto->Bonding == ITEM_BIND_ON_USE)
                tmpItem->SoulBind();

        if(sScriptMgr.CallScriptedItem(tmpItem,_player))
                return;
	
	if( itemProto->InventoryType != 0 && !_player->GetItemInterface()->IsEquipped(itemProto->ItemId) )//Equipable items cannot be used before they're equipped. Prevents exploits
                return;//Prevents exploits such as keeping an on-use trinket in your bag and using WPE to use it from your bag in mid-combat.

	if(itemProto->QuestId)
	{
		// Item Starter
		Quest *qst = QuestStorage.LookupEntry(itemProto->QuestId);
		if(!qst) 
			return;

		WorldPacket data;
		sQuestMgr.BuildQuestDetails(&data, qst, tmpItem, 0, language, _player);
		SendPacket(&data);
	}
	
  
    
    SpellCastTargets targets(recvPacket, _player->GetGUID());
	uint32 x;
	for(x = 0; x < 5; x++)
	{
		if(itemProto->Spells[x].Trigger == USE)
		{
			if(itemProto->Spells[x].Id)
			{
				spellId = itemProto->Spells[x].Id;

				// check for spell id
				SpellEntry *spellInfo = dbcSpell.LookupEntryForced( spellId );

				if ( !spellInfo || !sHookInterface.OnCastSpell( _player, spellInfo ) )
				{
					sLog.outError("WORLD: unknown spell id %i\n", spellId);
					return;
				}

				if (spellInfo->AuraInterruptFlags & AURA_INTERRUPT_ON_STAND_UP)
				{
					if (p_User->CombatStatus.IsInCombat() || p_User->IsMounted())
					{
						_player->GetItemInterface()->BuildInventoryChangeError(tmpItem,NULL,INV_ERR_CANT_DO_IN_COMBAT);
						return;
					}
					if(p_User->GetStandState()!=1)
						p_User->SetStandState(STANDSTATE_SIT);
					// loop through the auras and removing existing eating spells
				}else
				{ // cebernic: why not stand up
					if (!p_User->CombatStatus.IsInCombat() && !p_User->IsMounted())
					{
						if( p_User->GetStandState() )//not standing-> standup
						{
							p_User->SetStandState( STANDSTATE_STAND );//probably mobs also must standup
						}
					}
				}

				// cebernic: remove stealth on using item
				if (!(spellInfo->AuraInterruptFlags & ATTRIBUTESEX_NOT_BREAK_STEALTH))
				{
					if( p_User->IsStealth() )
						p_User->RemoveAllAuraType( SPELL_AURA_MOD_STEALTH );
				}

				if(itemProto->RequiredLevel)
				{
					if(_player->getLevel() < itemProto->RequiredLevel)
					{
						_player->GetItemInterface()->BuildInventoryChangeError(tmpItem,NULL,INV_ERR_ITEM_RANK_NOT_ENOUGH);
						return;
					}
				}

				if(itemProto->RequiredSkill)
				{
					if(!_player->_HasSkillLine(itemProto->RequiredSkill))
					{
						_player->GetItemInterface()->BuildInventoryChangeError(tmpItem,NULL,INV_ERR_ITEM_RANK_NOT_ENOUGH);
						return;
					}

					if(itemProto->RequiredSkillRank)
					{
						if(_player->_GetSkillLineCurrent(itemProto->RequiredSkill, false) < itemProto->RequiredSkillRank)
						{
							_player->GetItemInterface()->BuildInventoryChangeError(tmpItem,NULL,INV_ERR_ITEM_RANK_NOT_ENOUGH);
							return;
						}
					}
				}
				
				if( itemProto->AllowableClass && !(_player->getClassMask() & itemProto->AllowableClass) || itemProto->AllowableRace && !(_player->getRaceMask() & itemProto->AllowableRace) )
				{
					_player->GetItemInterface()->BuildInventoryChangeError(tmpItem,NULL,INV_ERR_YOU_CAN_NEVER_USE_THAT_ITEM);
					return;
				}		

				if( !_player->Cooldown_CanCast( itemProto, x ) )
				{
					_player->SendCastResult(spellInfo->Id, SPELL_FAILED_NOT_READY, cn, 0);
					return;
				}

				if(_player->m_currentSpell)
				{
					_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
					return;
				}

				if( itemProto->ForcedPetId >= 0 )
				{
					if( itemProto->ForcedPetId == 0 )
					{
						if( _player->GetGUID() != targets.m_unitTarget )
						{
							_player->SendCastResult(spellInfo->Id, SPELL_FAILED_BAD_TARGETS, cn, 0);
							return;
						}
					}
					else
					{
						if( !_player->GetSummon() || _player->GetSummon()->GetEntry() != (uint32)itemProto->ForcedPetId )
						{
							_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
							return;
						}
					}
				}

				Spell *spell = SpellPool.PooledNew();
				spell->Init(_player, spellInfo, false, NULL);
				uint8 result;
				spell->extra_cast_number=cn;
				spell->i_caster = tmpItem;
				//GetPlayer()->setCurrentSpell(spell);
				result = spell->prepare(&targets);
			}
		}
	}

}
コード例 #10
0
ファイル: SpellHandler.cpp プロジェクト: wow4all/wowtbc
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
	if(!_player->IsInWorld()) return;
	if(_player->getDeathState()==CORPSE)
		return;

	uint32 spellId;
	uint8 cn;

	recvPacket >> spellId >> cn;
	// check for spell id
	SpellEntry *spellInfo = dbcSpell.LookupEntryForced(spellId );

	if(!spellInfo || !sHookInterface.OnCastSpell(_player, spellInfo))
	{
		sLog.outError("WORLD: unknown spell id %i\n", spellId);
		return;
	}

/*  this is breaks capturing flags at arathi basin (marcelo)
	if (spellInfo->Attributes & ATTRIBUTES_NO_CAST)
	{
		sLog.outError("WORLD: attempt to cast spell %i, %s which has ATTRIBUTES_NO_CAST\n", spellId, spellInfo->Name);
		return;
	}*/

	sLog.outDetail("WORLD: got cast spell packet, spellId - %i (%s), data length = %i",
		spellId, spellInfo->Name, recvPacket.size());
	
	// Cheat Detection only if player and not from an item
	// this could f**k up things but meh it's needed ALOT of the newbs are using WPE now
	// WPE allows them to mod the outgoing packet and basicly choose what ever spell they want :(

	if( !GetPlayer()->HasSpell(spellId) || spellInfo->Attributes & ATTRIBUTES_PASSIVE )
	{
		sLog.outDetail("WORLD: Spell isn't casted because player \"%s\" is cheating", GetPlayer()->GetName());
		return;
	}

	if (GetPlayer()->GetOnMeleeSpell() != spellId)
	{
		//autoshot 75
		if((spellInfo->AttributesExB & FLAGS3_ACTIVATE_AUTO_SHOT) /*spellInfo->Attributes == 327698*/)	// auto shot..
		{
			//sLog.outString( "HandleSpellCast: Auto Shot-type spell cast (id %u, name %s)" , spellInfo->Id , spellInfo->Name );
			Item *weapon = GetPlayer()->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_RANGED);
			if(!weapon) 
				return;
			uint32 spellid;
			switch(weapon->GetProto()->SubClass)
			{
			case 2:			 // bows
			case 3:			 // guns
            case 18:		 // crossbow
				spellid = SPELL_RANGED_GENERAL;
				break;
			case 16:			// thrown
				spellid = SPELL_RANGED_THROW;
				break;
			case 19:			// wands
				spellid = SPELL_RANGED_WAND;
				break;
			default:
				spellid = 0;
				break;
			}
		   
			if(!spellid) 
				spellid = spellInfo->Id;
			
			if(!_player->m_onAutoShot)
			{
				_player->m_AutoShotTarget = _player->GetSelection();
				uint32 duration = _player->GetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME);
				SpellCastTargets targets(recvPacket,GetPlayer()->GetGUID());
				if(!targets.m_unitTarget)
				{
					sLog.outString( "Cancelling auto-shot cast because targets.m_unitTarget is null!" );
					return;
				}
				SpellEntry *sp = dbcSpell.LookupEntry(spellid);
			
				_player->m_AutoShotSpell = sp;
				_player->m_AutoShotDuration = duration;
				//This will fix fast clicks
				if(_player->m_AutoShotAttackTimer < 500)
					_player->m_AutoShotAttackTimer = 500;
				_player->m_onAutoShot = true;
			}

			return;
		}
		/*const char * name = sSpellStore.LookupString(spellInfo->Name);
		if(name)
			sChatHandler.SystemMessageToPlr(_player, "%sSpell Cast:%s %s %s[Group %u, family %u]", MSG_COLOR_LIGHTBLUE,
			MSG_COLOR_SUBWHITE, name, MSG_COLOR_YELLOW, spellInfo->SpellGroupType, spellInfo->SpellFamilyName);*/

        if(_player->m_currentSpell)
        {
			if( _player->m_currentSpell->getState() == SPELL_STATE_CASTING )
			{
				// cancel the existing channel spell, cast this one
				_player->m_currentSpell->cancel();
			}
			else
			{
				// send the error message
				_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
				return;
			}
        }

		SpellCastTargets targets(recvPacket,GetPlayer()->GetGUID());

		// some anticheat stuff
		if( spellInfo->self_cast_only )
		{
			if( targets.m_unitTarget && targets.m_unitTarget != _player->GetGUID() )
			{
				// send the error message
				_player->SendCastResult(spellInfo->Id, SPELL_FAILED_BAD_TARGETS, cn, 0);
				return;
			}
		}

		Spell *spell = SpellPool.PooledNew();
		spell->Init(GetPlayer(), spellInfo, false, NULL);
		spell->extra_cast_number=cn;
		spell->prepare(&targets);
	}
}
コード例 #11
0
ファイル: ArathiBasin.cpp プロジェクト: AscEmu/AscEmu_TBC
void ArathiBasin::HookOnAreaTrigger(Player * plr, uint32 id)
{
    uint32 spellid = 0;
    int32 buffslot = -1;
    switch (id)
    {
        case 3866:			// stables
            buffslot = AB_BUFF_STABLES;
            break;

        case 3867:			// farm
            buffslot = AB_BUFF_FARM;
            break;

        case 3870:			// blacksmith
            buffslot = AB_BUFF_BLACKSMITH;
            break;

        case 3869:			// mine
            buffslot = AB_BUFF_MINE;
            break;

        case 3868:			// lumbermill
            buffslot = AB_BUFF_LUMBERMILL;
            break;

        case 3948:			// alliance/horde exits
        case 3949:
        {
            RemovePlayer(plr, false);
            return;
        }break;

        default:
            Log.Error("ArathiBasin", "Encountered unhandled areatrigger id %u", id);
            return;
            break;
    }

    if (plr->isDead())		// dont apply to dead players... :P
        return;

    uint32 x = (uint32)buffslot;
    if (m_buffs[x] && m_buffs[x]->IsInWorld())
    {
        // apply the spell
        spellid = m_buffs[x]->GetInfo()->sound3;
        m_buffs[x]->RemoveFromWorld(false);

        // respawn it in buffrespawntime
        sEventMgr.AddEvent(this, &ArathiBasin::SpawnBuff, x, EVENT_AB_RESPAWN_BUFF, AB_BUFF_RESPAWN_TIME, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);

        // cast the spell on the player
        SpellEntry * sp = dbcSpell.LookupEntryForced(spellid);
        if (sp)
        {
            Spell * pSpell = SpellPool.PooledNew();
            pSpell->Init(plr, sp, true, NULL);
            SpellCastTargets targets(plr->GetGUID());
            pSpell->prepare(&targets);
        }
    }
}
コード例 #12
0
ファイル: Item.cpp プロジェクト: AegisEmu/AegisEmu
void Item::ApplyEnchantmentBonus( uint32 Slot, bool Apply )
{
	if( m_owner == NULL )
		return;

	EnchantmentMap::iterator itr = Enchantments.find( Slot );
	if( itr == Enchantments.end() )
		return;

	EnchantEntry* Entry = itr->second.Enchantment;
	uint32 RandomSuffixAmount = itr->second.RandomSuffix;

	if( itr->second.BonusApplied == Apply )
		return;

	itr->second.BonusApplied = Apply;

	if( Apply )
	{
		// Send the enchantment time update packet.
		SendEnchantTimeUpdate( itr->second.Slot, itr->second.Duration );
	}

	// Apply the visual on the player.
	uint32 ItemSlot = m_owner->GetItemInterface()->GetInventorySlotByGuid( GetGUID() ) * 16;
	uint32 VisibleBase = PLAYER_VISIBLE_ITEM_1_0 + ItemSlot;
	m_owner->SetUInt32Value( VisibleBase + 1 + Slot, Apply ? Entry->Id : 0 );

	// Another one of those for loop that where not indented properly god knows what will break
	// but i made it actually affect the code below it
	for( uint32 c = 0; c < 3; c++ )
	{
		if( Entry->type[c] )
		{
			// Depending on the enchantment type, take the appropriate course of action.
			switch( Entry->type[c] )
			{
			case 1:		 // Trigger spell on melee attack.
				{
					if( Apply && Entry->spell[c] != 0 )
					{
						// Create a proc trigger spell

						ProcTriggerSpell TS;
						TS.caster = m_owner->GetGUID();
						TS.origId = 0;
						TS.procFlags = PROC_ON_MELEE_ATTACK;
						TS.procCharges = 0;
						/* This needs to be modified based on the attack speed of the weapon.
						 * Secondly, need to assign some static chance for instant attacks (ss,
						 * gouge, etc.) */
						if( !Entry->min[c] && GetProto()->Class == 2 )
						{
							float speed = (float)GetProto()->Delay;
							/////// procChance calc ///////
							float ppm = 0;
							SpellEntry* sp = dbcSpell.LookupEntry( Entry->spell[c] );
							if( sp )
							{
								switch( sp->NameHash )
								{
								case SPELL_HASH_FROSTBRAND_ATTACK:
									ppm = 9;
									break;
								}
							}
							if( ppm != 0 )
							{
								float pcount = 60/ppm;
								float chance = (speed/10) / pcount;
								TS.procChance = (uint32)chance;
							}
							else
								TS.procChance = (uint32)( speed / 600.0f );
							///////////////////////////////
						}
						else
							TS.procChance = Entry->min[c];
						Log.Debug( "Enchant", "Setting procChance to %u%%.", TS.procChance );
						TS.deleted = false;
						TS.spellId = Entry->spell[c];
						TS.groupRelation = 0;
						TS.ProcType = 0;
						TS.LastTrigger = 0;
						m_owner->m_procSpells.push_back( TS );
					}
					else
					{
						// Remove the proctriggerspell
						uint32 SpellId;
						list< struct ProcTriggerSpell >::iterator itr/*, itr2*/;
						for( itr = m_owner->m_procSpells.begin(); itr != m_owner->m_procSpells.end(); )
						{
							SpellId = itr->spellId;
							/*itr2 = itr++;*/
							
							if( SpellId == Entry->spell[c] )
							{
								//m_owner->m_procSpells.erase(itr2);
								itr->deleted = true;
							}
							itr++;
						}
					}
				}break;

			case 2:		 // Mod damage done.
				{
					int32 val = Entry->min[c];
					if( RandomSuffixAmount )
						val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() );

					if( Apply )
						m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, val );
					else
						m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, -val );
					m_owner->CalcDamage();
				}break;

			case 3:		 // Cast spell (usually means apply aura)
				{
					if( Apply )
					{
						SpellCastTargets targets( m_owner->GetGUID() );
						SpellEntry* sp;
						Spell* spell;
						
						if( Entry->spell[c] != 0 )
						{
							sp = dbcSpell.LookupEntry( Entry->spell[c] );
							if( sp == NULL )
								continue;

							spell = SpellPool.PooledNew();
							spell->Init( m_owner, sp, true, 0 );
							spell->i_caster = this;
							spell->prepare( &targets );
						}
					}
					else
					{
						if( Entry->spell[c] != 0 )
								m_owner->RemoveAura( Entry->spell[c] );
					}

				}break;

			case 4:		 // Modify physical resistance
				{
					int32 val = Entry->min[c];
					if( RandomSuffixAmount )
						val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() );

					if( Apply )
					{
						m_owner->FlatResistanceModifierPos[Entry->spell[c]] += val;
					}
					else
					{
						m_owner->FlatResistanceModifierPos[Entry->spell[c]] -= val;
					}
					m_owner->CalcResistance( Entry->spell[c] );
				}break;

			case 5:	 //Modify rating ...order is PLAYER_FIELD_COMBAT_RATING_1 and above
				{
					//spellid is enum ITEM_STAT_TYPE
					//min=max is amount
					int32 val = Entry->min[c];
					if( RandomSuffixAmount )
						val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() );

					m_owner->ModifyBonuses( Entry->spell[c], val, Apply );
					m_owner->UpdateStats();
				}break;

			case 6:	 // Rockbiter weapon (increase damage per second... how the hell do you calc that)
				{
					if( Apply )
					{
						//m_owner->ModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, Entry->min[c]);
						//if i'm not wrong then we should apply DMPS formula for this. This will have somewhat a larger value 28->34
						int32 val = Entry->min[c];
						if( RandomSuffixAmount )
							val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() );

						int32 value = GetProto()->Delay * val / 1000;
						m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, value );
					}
					else
					{
						int32 val = Entry->min[c];
						if( RandomSuffixAmount )
							val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() );

						int32 value =- (int32)(GetProto()->Delay * val / 1000 );
						m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, value );
					}
					m_owner->CalcDamage();
				}break;

			default:
				{
					sLog.outError( "Unknown enchantment type: %u (%u)", Entry->type[c], Entry->Id );
				}break;
			}
		}
	}
}
コード例 #13
0
ファイル: WarsongGulch.cpp プロジェクト: AegisEmu/AegisEmu
void WarsongGulch::HookOnAreaTrigger(Player * plr, uint32 id)
{
	int32 buffslot = -1;
	switch(id)
	{
	case 3686:	  // Speed
		buffslot = 0;
		break;
	case 3687:	  // Speed (Horde)
		buffslot = 1;
		break;
	case 3706:	  // Restoration
		buffslot = 2;
		break;
	case 3708:	  // Restoration (Horde)
		buffslot = 3;
		break;
	case 3707:	  // Berserking
		buffslot = 4;
		break;
	case 3709:	  // Berserking (Horde)
		buffslot = 5;
		break;
	}

	if(buffslot >= 0)
	{
		if(m_buffs[buffslot] != 0 && m_buffs[buffslot]->IsInWorld())
		{
			/* apply the buff */
			SpellEntry * sp = dbcSpell.LookupEntry(m_buffs[buffslot]->GetInfo()->sound3);
			Spell * s = SpellPool.PooledNew();
			s->Init(plr, sp, true, 0);
			SpellCastTargets targets(plr->GetGUID());
			s->prepare(&targets);

			/* despawn the gameobject (not delete!) */
			m_buffs[buffslot]->Despawn(BUFF_RESPAWN_TIME);
		}
		return;
	}

	if(((id == 3646 && plr->GetTeam() == 0) || (id == 3647 && plr->GetTeam() == 1)) && (plr->m_bgHasFlag && m_flagHolders[plr->GetTeam()] == plr->GetLowGUID()))
	{
		if(m_flagHolders[plr->GetTeam() ? 0 : 1] != 0 || m_dropFlags[plr->GetTeam() ? 0 : 1]->IsInWorld())
		{
			/* can't cap while flag dropped */
			return;
		}

		/* remove the bool from the player so the flag doesn't drop */
		m_flagHolders[plr->GetTeam()] = 0;
		plr->m_bgHasFlag = 0;

		/* remove flag aura from player */
		plr->RemoveAura(23333+(plr->GetTeam() * 2));

		/* capture flag points */
		plr->m_bgScore.Misc1++;

		PlaySoundToAll( plr->GetTeam() ? SOUND_HORDE_SCORES : SOUND_ALLIANCE_SCORES );

		if( plr->GetTeam() == 1 )
			SendChatMessage( CHAT_MSG_BG_EVENT_HORDE, plr->GetGUID(), "%s captured the Alliance flag!", plr->GetName() );
		else
			SendChatMessage( CHAT_MSG_BG_EVENT_ALLIANCE, plr->GetGUID(), "%s captured the Horde flag!", plr->GetName() );

		SetWorldState( plr->GetTeam() ? WSG_ALLIANCE_FLAG_CAPTURED : WSG_HORDE_FLAG_CAPTURED, 1 );

		/* respawn the home flag */
		if( !m_homeFlags[plr->GetTeam()]->IsInWorld() )
			m_homeFlags[plr->GetTeam()]->PushToWorld(m_mapMgr);

		/* give each player on that team a bonus according to flagHonorTable */
		for(set<Player*>::iterator itr = m_players[plr->GetTeam()].begin(); itr != m_players[plr->GetTeam()].end(); ++itr)
		{
			(*itr)->m_bgScore.BonusHonor += flagHonorTable[m_lgroup];
			HonorHandler::AddHonorPointsToPlayer((*itr), flagHonorTable[m_lgroup]);
		}

		m_scores[plr->GetTeam()]++;
		if(m_scores[plr->GetTeam()] == 3)
		{
			/* victory! */
			m_ended = true;
			m_winningteam = plr->GetTeam() ? 1 : 0;
			m_nextPvPUpdateTime = 0;

			sEventMgr.RemoveEvents(this, EVENT_BATTLEGROUND_CLOSE);
			sEventMgr.AddEvent(((CBattleground*)this), &CBattleground::Close, EVENT_BATTLEGROUND_CLOSE, 120000, 1,0);

			m_mainLock.Acquire();
			/* add the marks of honor to all players */
			SpellEntry * winner_spell = dbcSpell.LookupEntry(24951);
			SpellEntry * loser_spell = dbcSpell.LookupEntry(24950);
			for(uint32 i = 0; i < 2; ++i)
			{
				for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
				{
					(*itr)->Root();
					if(i == m_winningteam)
					{
						int honor = winHonorTable[m_lgroup];
						if (m_isWeekend)
						{
							honor+= extraWinHonorTable[m_lgroup];
							honor+= extraCompleteHonorTable[m_lgroup];
						}
						(*itr)->m_bgScore.BonusHonor += honor;
						HonorHandler::AddHonorPointsToPlayer((*itr), honor);
						(*itr)->CastSpell((*itr), winner_spell, true);
					}
					else
					{
						if (m_isWeekend)
						{
							int honor = extraCompleteHonorTable[m_lgroup];
							(*itr)->m_bgScore.BonusHonor += honor;
							HonorHandler::AddHonorPointsToPlayer((*itr), honor);
						}
						(*itr)->CastSpell((*itr), loser_spell, true);
					}
				}
			}
			m_mainLock.Release();
		}

		/* increment the score world state */
		SetWorldState(plr->GetTeam() ? WSG_CURRENT_HORDE_SCORE : WSG_CURRENT_ALLIANCE_SCORE, m_scores[plr->GetTeam()]);

		UpdatePvPData();
	}
}
コード例 #14
0
ファイル: WarsongGulch.cpp プロジェクト: AegisEmu/AegisEmu
void WarsongGulch::HookFlagDrop(Player * plr, GameObject * obj)
{
	/* picking up a dropped flag */
	if(m_dropFlags[plr->GetTeam()] != obj)
	{
		/* are we returning it? */
		if( (obj->GetEntry() == 179785 && plr->GetTeam() == 0) ||
			(obj->GetEntry() == 179786 && plr->GetTeam() == 1) )
		{
			uint32 x = plr->GetTeam() ? 0 : 1;
			sEventMgr.RemoveEvents(this, EVENT_BATTLEGROUND_WSG_AUTO_RETURN_FLAG + plr->GetTeam());

			if( m_dropFlags[x]->IsInWorld() )
				m_dropFlags[x]->RemoveFromWorld(false);

			if(m_homeFlags[x]->IsInWorld() == false)
				m_homeFlags[x]->PushToWorld(m_mapMgr);

			plr->m_bgScore.Misc2++;
			UpdatePvPData();

			if( plr->GetTeam() == 1 )
				SendChatMessage( CHAT_MSG_BG_EVENT_HORDE, plr->GetGUID(), "The Horde flag was returned to its base by %s!", plr->GetName() );
			else
				SendChatMessage( CHAT_MSG_BG_EVENT_ALLIANCE, plr->GetGUID(), "The Alliance flag was returned to its base by %s!", plr->GetName() );

			SetWorldState(plr->GetTeam() ? WSG_ALLIANCE_FLAG_CAPTURED : WSG_HORDE_FLAG_CAPTURED, 1);
			PlaySoundToAll(plr->GetTeam() ? SOUND_HORDE_RETURNED : SOUND_ALLIANCE_RETURNED);
		}
		return;
	}

	map<uint32,uint32>::iterator itr = plr->m_forcedReactions.find(1059);
	if (itr != plr->m_forcedReactions.end()) {
		return;
	}

	if( plr->GetTeam() == 0 )
		sEventMgr.RemoveEvents(this, EVENT_BATTLEGROUND_WSG_AUTO_RETURN_FLAG);
	else
		sEventMgr.RemoveEvents(this, EVENT_BATTLEGROUND_WSG_AUTO_RETURN_FLAG + 1);

	if( m_dropFlags[plr->GetTeam()]->IsInWorld() )
		m_dropFlags[plr->GetTeam()]->RemoveFromWorld(false);

	m_flagHolders[plr->GetTeam()] = plr->GetLowGUID();
	plr->m_bgHasFlag = true;

	/* This is *really* strange. Even though the A9 create sent to the client is exactly the same as the first one, if
	 * you spawn and despawn it, then spawn it again it will not show. So we'll assign it a new guid, hopefully that
	 * will work.
	 * - Burlex
	 */
	m_dropFlags[plr->GetTeam()]->SetNewGuid(m_mapMgr->GenerateGameobjectGuid());
	
	SpellEntry * pSp = dbcSpell.LookupEntry(23333 + (plr->GetTeam() * 2));
	Spell * sp = SpellPool.PooledNew();
	sp->Init(plr, pSp, true, 0);
	SpellCastTargets targets(plr->GetGUID());
	sp->prepare(&targets);
	SetWorldState(plr->GetTeam() ? WSG_ALLIANCE_FLAG_CAPTURED : WSG_HORDE_FLAG_CAPTURED, 2);
}
コード例 #15
0
ファイル: EyeOfTheStorm.cpp プロジェクト: AegisEmu/AegisEmu
void EyeOfTheStorm::HookOnAreaTrigger(Player * plr, uint32 id)
{
	int32 tid = -1;
	int32 bonusid = -1;
	switch(id)
	{
	case 4476:			// BE Tower
		tid = EOTS_TOWER_BE;
		break;
	case 4568:			// BE Tower bonus
		bonusid = EOTS_TOWER_BE;
		break;
	case 4514:			// Fel Reaver Tower
		tid = EOTS_TOWER_FELREAVER;
		break;
	case 4569:			// Fel Reaver Tower bonus
		bonusid = EOTS_TOWER_FELREAVER;
		break;
	case 4518:			// Draenei Tower
		tid = EOTS_TOWER_DRAENEI;
		break;
	case 4571:			// Draenei Tower bonus
		bonusid = EOTS_TOWER_DRAENEI;
		break;
	case 4516:			// Mage Tower
		tid = EOTS_TOWER_MAGE;
		break;
	case 4570:			// Mage Tower bonus
		bonusid = EOTS_TOWER_MAGE;
		break;
	}

	if(bonusid > -1){
		uint32 spellid=0;
		uint32 x = (uint32)bonusid;
		if(EOTSm_buffs[x] && EOTSm_buffs[x]->IsInWorld())
		{
			spellid = EOTSm_buffs[x]->GetInfo()->sound3;
			SpellEntry * sp = dbcSpell.LookupEntryForced(spellid);
			if(sp)
			{
				Spell * pSpell = SpellPool.PooledNew();
				pSpell->Init(plr, sp, true, NULL);
				SpellCastTargets targets(plr->GetGUID());
				pSpell->prepare(&targets);
			}
			EOTSm_buffs[x]->Despawn(EOTS_BUFF_RESPAWN_TIME);
		}
	}


	if( tid < 0 )
		return;

#ifdef ANTI_CHEAT
	if(!m_started)
	{
		Anticheat_Log->writefromsession(plr->GetSession(), "%s tryed to hook the flag in eye of the storm before battleground (ID %u) started.", plr->GetName(), this->m_id);
		SendChatMessage(CHAT_MSG_BG_EVENT_NEUTRAL, plr->GetGUID(), "%s will be removed from the game for cheating.", plr->GetName());
		// Remove player from battleground.
		this->RemovePlayer(plr, false);
		// Kick	player from server.
		plr->Kick(6000);
		return;
	}
#endif
	uint32 spellid=0;
	uint32 x = (uint32)tid;
	if(EOTSm_buffs[x] && EOTSm_buffs[x]->IsInWorld())
	{
		spellid = EOTSm_buffs[x]->GetInfo()->sound3;
		SpellEntry * sp = dbcSpell.LookupEntryForced(spellid);
		if(sp)
		{
			Spell * pSpell = SpellPool.PooledNew();
			pSpell->Init(plr, sp, true, NULL);
			SpellCastTargets targets(plr->GetGUID());
			pSpell->prepare(&targets);
		}
		EOTSm_buffs[x]->Despawn(EOTS_BUFF_RESPAWN_TIME);
	}

	uint32 team = plr->GetTeam();
	if( plr->GetLowGUID() != m_flagHolder )
		return;

	int32 val;
	uint32 i;
	uint32 towers = 0;
	if( team == 0 )
		val = 100;
	else
		val = 0;

	if( m_CPStatus[tid] != val )
		return;			// not captured by our team

	for(i = 0; i < EOTS_TOWER_COUNT; ++i)
	{
		if(m_CPStatus[i] == val)
			towers++;
	}

	/*
	Points from flag captures

	* 1 towers controlled = 75 points
	* 2 towers controlled = 85 points
	* 3 towers controlled = 100 points
	* 4 towers controlled = 500 points 
	*/

	// 25 is guessed
	const static uint32 points[5] = { 25, 75, 85, 100, 500 };
	const char * msgs[2] = { "The Alliance have captured the flag.", "The Horde have captured the flag." };

	SendChatMessage( CHAT_MSG_BG_EVENT_ALLIANCE + team, 0, msgs[team] );
	GivePoints( team, points[towers] );

	m_standFlag->PushToWorld( m_mapMgr );
	m_flagHolder = 0;
	SetWorldState( 2757, 1 );

	plr->RemoveAura( EOTS_NETHERWING_FLAG_SPELL );
	plr->m_bgScore.Misc1++;
	UpdatePvPData();
}
コード例 #16
0
ファイル: AIAHealSupport.cpp プロジェクト: AegisEmu/AegisEmu
void AiAgentHealSupport::Update(uint32 p_time)
{
	_UpdateTimer(p_time);
	_UpdateMovement(p_time);

	if( !m_PetOwner )
		return; //oh noez, our master has abandoned us ! Where is te luv ?

	//we used this spell to create healbot. To avoid logout / login recreate we need to remove aura
	// lol, this will never work :(
	if( !m_Unit->isAlive() )
		m_PetOwner->RemoveAura( 36765 );

	if( m_Unit->GetMapMgr() != m_PetOwner->GetMapMgr() )
	{
		m_PetOwner->RemoveAura( 36765 );
		m_Unit->EventSummonPetExpire();
	}

	if( m_Unit->isCasting() )
		return; // we are already supporting someone ...get back later

	//we should be at same level at owner so we profit of fighting formulas same as owner
	if(	m_Unit->GetUInt32Value( UNIT_FIELD_LEVEL ) != m_PetOwner->GetUInt32Value( UNIT_FIELD_LEVEL ) )
	{
		m_Unit->SetUInt32Value( UNIT_FIELD_LEVEL, m_PetOwner->GetUInt32Value( UNIT_FIELD_LEVEL ) );
		DifficultyLevel = m_PetOwner->GetUInt32Value( UNIT_FIELD_LEVEL ) / 80.0f;
//printf("difficulty changed to %f \n",DifficultyLevel);
		//scale health and mana.when we level we max out our stats
		m_Unit->SetUInt32Value( UNIT_FIELD_MAXHEALTH , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_BASE_HEALTH ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
		m_Unit->SetUInt32Value( UNIT_FIELD_MAXPOWER1 , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_BASE_MANA ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
		m_Unit->SetUInt32Value( UNIT_FIELD_HEALTH , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_HEALTH ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
		m_Unit->SetUInt32Value( UNIT_FIELD_POWER1 , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_POWER1 ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
	}

	//if owner fights a long combat then we he desrvers to get lasy at the end ?
	if( m_PetOwner->CombatStatus.IsInCombat() )
		CombatDifficultyLevel += DIFFICULTY_UPDATE_SPEED;
	else CombatDifficultyLevel = 0;
	if( CombatDifficultyLevel > 1 )
		CombatDifficultyLevel = 1;

	uint32 Time_Now = getMSTime();

	std::list<healagentspell*>::iterator itr;
	SpellCastTargets targets( m_PetOwner->GetGUID() );
	healagentspell *m_castingSpell = NULL;
	Unit			*SpellTarget = m_PetOwner;

	//poor thing died. Res him. 
	//will never work
	if( !m_PetOwner->isAlive() && CheckCanCast( revive_spell.sp, SpellTarget ) )
	{
		m_castingSpell = &revive_spell;
//printf("master died, we are going to resurect him\n");
	}

	//if we are injusred we should try to survive it
	if ( m_castingSpell== NULL && m_Unit->GetUInt32Value( UNIT_FIELD_HEALTH ) < m_Unit->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
	{
//printf("we are injured, diff is %u \n",m_Unit->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) - m_Unit->GetUInt32Value( UNIT_FIELD_HEALTH ));
		if(	!Protect_self() ) //first we try to escape combat
		{
			m_castingSpell = PickSpellFromList( &m_healspells, m_Unit );
			SpellTarget = m_Unit;
		}
		else
		{
			m_castingSpell = &m_defend_self;
			SpellTarget = m_Unit;
		}
	}

	//select an augment spell if we have nothing better to do
	if( m_castingSpell== NULL && m_PetOwner->GetUInt32Value( UNIT_FIELD_HEALTH ) == m_PetOwner->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
	{
//printf("master is ok, we can try augment someone\n");
		m_castingSpell = PickSpellFromList( &m_AugmentSelf, m_Unit );
		//try augment owner ?
		if( !m_castingSpell )
		{
			m_castingSpell = PickSpellFromList( &m_AugmentTarget, m_PetOwner );
			SpellTarget = m_Unit;
		}
	}

	//master is injured, this should be most common case
	if( m_castingSpell==NULL && m_PetOwner->GetUInt32Value( UNIT_FIELD_HEALTH ) < m_PetOwner->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
	{
//printf("master is injured, will try to heal him\n");
		m_castingSpell = PickSpellFromList( &m_healspells , m_PetOwner);
		SpellTarget = m_PetOwner;
	}

	if( m_castingSpell )
	{
//printf("we have a spell to cast\n");

		SpellCastTime *sd = dbcSpellCastTime.LookupEntry( m_castingSpell->sp->CastingTimeIndex );

		//do not stop for instant casts
		if(GetCastTime(sd) != 0)
		{
			StopMovement(0);
//printf("spell is not instant so we are going to stop movement \n");
		}

		float distance = m_Unit->GetDistanceSq( SpellTarget );
		if(	distance <= m_castingSpell->sp->base_range_or_radius_sqr || m_castingSpell->sp->base_range_or_radius_sqr == 0 )
		{

//printf("we are in range and going to cast spell \n");
			m_AIState = STATE_CASTING;
			
			Spell *nspell = SpellPool.PooledNew();
			nspell->Init(m_Unit, m_castingSpell->sp, false, NULL);

#ifdef SPELL_EFF_PCT_SCALE_WITH_DIFFICULTY
			if( m_castingSpell->max_scale )
			{
				nspell->forced_basepoints[ 0 ] = (uint32)( m_castingSpell->max_scale * ( DifficultyLevel + CombatDifficultyLevel) );
				if( nspell->forced_basepoints[ 0 ] > m_castingSpell->max_scale * 2)
					nspell->forced_basepoints[ 0 ] = m_castingSpell->max_scale * 2;
			}
#endif

			targets.m_unitTarget = SpellTarget->GetGUID();
			nspell->prepare( &targets );

			CastSpell( m_Unit, m_castingSpell->sp, targets );

			SetSpellDuration( m_castingSpell );

			//mana regen is to big, he can cast forever, double mana usage maybe regulates this
			m_Unit->ModSignedInt32Value( UNIT_FIELD_POWER1, -m_castingSpell->sp->manaCost );

		}
		else // Target out of Range -> Run to it
		{
//printf("we are going to move closer \n");
			m_moveRun = true;
			_CalcDestinationAndMove( SpellTarget, sqrt( m_castingSpell->sp->base_range_or_radius_sqr ) );
		}
	}

// check if pets regenrate mana, If not then we should implement that too
	//if owner is mounted then we mount too. Speed is not set though
	if( m_PetOwner->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) && m_Unit->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) == 0 )
	{
		if( Owner_side == OWNER_SIDE_ALIANCE )
			m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, HELPER_MOUNT_A_DISPLAY );
		else
			m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, OWNER_SIDE_HORDE );
		m_moveSprint =  true;
	}
	else if( m_PetOwner->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) == 0 && m_Unit->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) != 0 )
	{
		m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, 0 );
		m_moveSprint = false;
	}

	//for fun : mimic master standstate. Note that this might give strange results
	if( m_PetOwner->GetStandState() != m_Unit->GetStandState() )
		m_Unit->SetStandState( m_PetOwner->GetStandState() );

	if( m_castingSpell == NULL )
	{
		if( First_noaction_stamp == 0 )
			First_noaction_stamp = Time_Now;

		float dist = m_Unit->CalcDistance( m_PetOwner );

//printf("we are far from owner, we should move closer , dist %f from %f \n",dist,(FollowDistance*FollowDistance));
		if ( dist > FollowDistance ) //if out of range
		{
			m_moveRun = true;

			if(dist > 20.0f)
				m_moveSprint = true;

			float delta_x = UnitToFollow->GetPositionX();
			float delta_y = UnitToFollow->GetPositionY();
			float d = 3;

			MoveTo(delta_x+(d*(cosf(m_fallowAngle+m_PetOwner->GetOrientation()))),
				delta_y+(d*(sinf(m_fallowAngle+m_PetOwner->GetOrientation()))),
				m_PetOwner->GetPositionZ(),m_PetOwner->GetOrientation());				
		}
	}
	else if(m_castingSpell != NULL )
		First_noaction_stamp = 0;

//if( First_noaction_stamp )printf("ms to say something %u and ms for say cooldown %u\n",First_noaction_stamp + BOREDOM_TIMER_TO_START_TRIGGERING - Time_Now,Boredom_cooldown - Time_Now );
	if( 
		First_noaction_stamp
		&& First_noaction_stamp + BOREDOM_TIMER_TO_START_TRIGGERING < Time_Now 
		&& Boredom_cooldown < Time_Now
		)
	{
		//some chance to say something
		if( Rand( 50 ) )
			m_Unit->SendChatMessage(CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, bored_texts[ RandomUInt( BOREDOM_TEXTCOUNT ) ]);
		else
			m_Unit->SetUInt32Value ( UNIT_NPC_EMOTESTATE, bored_emotes[ RandomUInt( BOREDOM_EMOTECOUNT ) ] );
		Boredom_cooldown = Time_Now + BOREDOM_TRIGGER_INTERVAL;
	}
}