⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interface.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:

#include "StdAfx.h"

// only enable with COLLISION define.
#ifdef COLLISION
#define LOS_CHECKS 1
//#define LOS_ONLY_IN_INSTANCE 1
#endif

#ifdef WIN32
#define HACKY_CRASH_FIXES 1		// SEH stuff
#endif

AIInterface::AIInterface()
{
	m_waypoints=NULL;
	m_canMove = true;
	m_destinationX = m_destinationY = m_destinationZ = 0;
	m_nextPosX = m_nextPosY = m_nextPosZ = 0;
	UnitToFollow = NULL;
	FollowDistance = 0.0f;
	m_fallowAngle = float(M_PI/2);
	m_timeToMove = 0;
	m_timeMoved = 0;
	m_moveTimer = 0;
	m_WayPointsShowing = false;
	m_WayPointsShowBackwards = false;
	m_currentWaypoint = 0;
	m_moveBackward = false;
	m_moveType = 0;
	m_move = false;
	m_moveSprint = false;
	m_move = false;
	m_MONSTERState = STOPPED;
	m_canCallForHelp = false;
	m_hasCalledForHelp = false;
	m_fleeTimer = 0;
	m_FleeDuration = 0;
	m_canFlee = false;
	m_hasFleed = false;
	m_canRangedAttack = false;
	m_FleeHealth = m_CallForHelpHealth = 0.0f;
	m_AIState = STATE_IDLE;

	m_updateAssist = false;
	m_updateTargets = false;
	m_updateAssistTimer = 1;
	m_updateTargetsTimer = TARGET_UPDATE_INTERVAL;

	m_nextSpell = NULL;
	m_nextTarget = NULL;
	totemspell = NULL;
	m_Unit = NULL;
	m_PetOwner = NULL;
	m_aiCurrentAgent = AGENT_NULL;
	m_Speed = 0.0f;
	m_Speed = 0.0f;
	UnitToFear = NULL;
	firstLeaveCombat = true;
	m_outOfCombatRange = 2500;

	tauntedBy = NULL;
	isTaunted = false;
	soullinkedWith = NULL;
	isSoulLinked = false;
	m_AllowedToEnterCombat = true;
	m_totalMoveTime = 0;
	m_lastFollowX = m_lastFollowY = 0;
	m_FearTimer = 0;
	m_WanderTimer = 0;
	m_totemspelltime = 0;
	m_totemspelltimer = 0;
	m_formationFollowAngle = 0.0f;
	m_formationFollowDistance = 0.0f;
	m_formationLinkTarget = 0;
	m_formationLinkSqlId = 0;
	m_currentHighestThreat = 0;

	disable_combat = false;

	disable_melee = false;
	disable_ranged = false;
	disable_spell = false;

	disable_targeting = false;

	next_spell_time = 0;
	waiting_for_cooldown = false;
	UnitToFollow_backup = NULL;
	m_isGuard = false;
	m_is_in_instance=false;
	skip_reset_hp=false;
}

void AIInterface::Init(Unit *un, AIType at, MovementType mt)
{
	ASSERT(at != AITYPE_PET);

	m_AIType = at;
	m_MovementType = mt;

	m_AIState = STATE_IDLE;
	m_MovementState = MOVEMENTSTATE_STOP;

	m_Unit = un;

	m_walkSpeed = m_Unit->m_walkSpeed*0.001f;//move distance per ms time 
	m_Speed = m_Unit->m_Speed*0.001f;//move distance per ms time 
	m_Speed = m_Unit->m_Speed * 0.001f;
	/*if(!m_DefaultMeleeSpell)
	{
		m_DefaultMeleeSpell = new AI_Spell;
		m_DefaultMeleeSpell->entryId = 0;
		m_DefaultMeleeSpell->spellType = 0;
		m_DefaultMeleeSpell->agent = AGENT_MELEE;
		m_DefaultSpell = m_DefaultMeleeSpell;
	}*/
	m_sourceX = un->GetPositionX();
	m_sourceY = un->GetPositionY();
	m_sourceZ = un->GetPositionZ();
	m_guardTimer = getMSTime();
}

AIInterface::~AIInterface()
{
	for(list<AI_Spell*>::iterator itr = m_SKILLS.begin(); itr != m_SKILLS.end(); ++itr)
		if((*itr)->custom_pointer)
			delete (*itr);
}

void AIInterface::Init(Unit *un, AIType at, MovementType mt, Unit *owner)
{
	ASSERT(at == AITYPE_PET || at == AITYPE_TOTEM);

	m_AIType = at;
	m_MovementType = mt;

	m_AIState = STATE_IDLE;
	m_MovementState = MOVEMENTSTATE_STOP;

	m_Unit = un;
	m_PetOwner = owner;

	m_walkSpeed = m_Unit->m_walkSpeed*0.001f;//move distance per ms time 
	m_Speed = m_Unit->m_Speed*0.001f;//move/ms
	m_Speed = m_Unit->m_Speed*0.001f;
	m_sourceX = un->GetPositionX();
	m_sourceY = un->GetPositionY();
	m_sourceZ = un->GetPositionZ();
}

void AIInterface::HandleEvent(uint32 event, Unit* pUnit, uint32 misc1)
{
	if( m_Unit == NULL ) return;
	
	if(m_AIState != STATE_EVADE)
	{
		switch(event)
		{
		case EVENT_ENTERCOMBAT:
			{
				if( pUnit == NULL ) return;

				/* send the message */
				if( m_Unit->GetTypeId() == TYPEID_UNIT )
				{
					if( static_cast< MONSTER* >( m_Unit )->has_combat_text )
						objmgr.HandleMonsterSayEvent( static_cast< MONSTER* >( m_Unit ), MONSTER_SAY_EVENT_ENTER_COMBAT );

					CALL_SCRIPT_EVENT(m_Unit, OnCombatStart)(pUnit);

					if( static_cast< MONSTER* >( m_Unit )->m_spawn && ( static_cast< MONSTER* >( m_Unit )->m_spawn->channel_target_go || static_cast< MONSTER* >( m_Unit )->m_spawn->channel_target_MONSTER))
					{
						m_Unit->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
						m_Unit->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, 0);
					}
				}
				
				// Stop the emote
				m_Unit->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
				m_returnX = m_Unit->GetPositionX();
				m_returnY = m_Unit->GetPositionY();
				m_returnZ = m_Unit->GetPositionZ();

				m_move = true; // to the target

				// dismount if mounted
				m_Unit->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);

				if(m_AIState != STATE_ATTACKING)
					StopMovement(0);

				m_AIState = STATE_ATTACKING;
				firstLeaveCombat = true;
				if(pUnit && pUnit->GetInstanceID() == m_Unit->GetInstanceID())
				{
					m_Unit->SetUInt64Value(UNIT_FIELD_TARGET, pUnit->GetGUID());
				}
				if(m_Unit->GetMapMgr()->GetMapInfo() && m_Unit->GetMapMgr()->GetMapInfo()->type == INSTANCE_RAID)
				{
					if(m_Unit->GetTypeId() == TYPEID_UNIT)
					{
						if(static_cast<MONSTER*>(m_Unit)->GetMONSTERName() && static_cast<MONSTER*>(m_Unit)->GetMONSTERName()->Rank == 3)
						{
							 m_Unit->GetMapMgr()->AddCombatInProgress(m_Unit->GetGUID());
						}
					}
				}
			}break;
		case EVENT_LEAVECOMBAT:
			{
				if( pUnit == NULL ) return;
				
				if( pUnit->IsMONSTER() )
					pUnit->RemoveNegativeAuras();
				//cancel SKILLS that we are casting. Should remove bug where MONSTERs cast a spell after they died
//				CancelSpellCast();
				// restart emote
				if(m_Unit->GetTypeId() == TYPEID_UNIT)
				{
					if( static_cast< MONSTER* >( m_Unit )->has_combat_text )
					objmgr.HandleMonsterSayEvent( static_cast< MONSTER* >( m_Unit ), MONSTER_SAY_EVENT_ON_COMBAT_STOP );

					if(static_cast<MONSTER*>(m_Unit)->original_emotestate)
						m_Unit->SetUInt32Value(UNIT_NPC_EMOTESTATE, static_cast< MONSTER* >( m_Unit )->original_emotestate);
					
					if(static_cast<MONSTER*>(m_Unit)->m_spawn && (static_cast< MONSTER* >( m_Unit )->m_spawn->channel_target_go || static_cast< MONSTER* >( m_Unit )->m_spawn->channel_target_MONSTER ) )
					{
						if(static_cast<MONSTER*>(m_Unit)->m_spawn->channel_target_go)
							sEventMgr.AddEvent( static_cast< MONSTER* >( m_Unit ), &MONSTER::ChannelLinkUpGO, static_cast< MONSTER* >( m_Unit )->m_spawn->channel_target_go, EVENT_MONSTER_CHANNEL_LINKUP, 1000, 5, 0 );

						if(static_cast<MONSTER*>(m_Unit)->m_spawn->channel_target_MONSTER)
							sEventMgr.AddEvent( static_cast< MONSTER* >( m_Unit ), &MONSTER::ChannelLinkUpMONSTER, static_cast< MONSTER* >( m_Unit )->m_spawn->channel_target_MONSTER, EVENT_MONSTER_CHANNEL_LINKUP, 1000, 5, 0 );
					}
				}

				//reset ProcCount
				//ResetProcCounts();
				m_move = true;
				m_aiTargets.clear();			
				m_fleeTimer = 0;
				m_hasFleed = false;
				m_hasCalledForHelp = false;
				m_nextSpell = NULL;
				SetNextTarget(NULL);
				m_Unit->CombatStatus.Vanished();

				if(m_AIType == AITYPE_PET)
				{
					m_AIState = STATE_FOLLOWING;
					UnitToFollow = m_PetOwner;
					FollowDistance = 3.0f;
					m_lastFollowX = m_lastFollowY = 0;
					if(m_Unit->IsPet())
					{
						((Pet*)m_Unit)->SetPetAction(PET_ACTION_FOLLOW);
						if( m_Unit->GetEntry() == 416 && m_Unit->isAlive() && m_Unit->IsInWorld() )
						{
							((Pet*)m_Unit)->HandleAutoCastEvent(AUTOCAST_EVENT_LEAVE_COMBAT);
						}
					}
					HandleEvent(EVENT_FOLLOWOWNER, 0, 0);
				}
				else
				{
					m_AIState = STATE_EVADE;

					Unit* SavedFollow = UnitToFollow;
					UnitToFollow = NULL;
					FollowDistance = 0.0f;
					m_lastFollowX = m_lastFollowY = 0;

					if(m_Unit->isAlive())
					{
						if(m_returnX != 0.0f && m_returnY != 0.0f && m_returnZ != 0.0f)
							MoveTo(m_returnX,m_returnY,m_returnZ,m_Unit->GetOrientation());
						else
						{
							MoveTo(m_Unit->GetSpawnX(),m_Unit->GetSpawnY(),m_Unit->GetSpawnZ(),m_Unit->GetSpawnO());
							m_returnX=m_Unit->GetSpawnX();
							m_returnY=m_Unit->GetSpawnY();
							m_returnZ=m_Unit->GetSpawnZ();
						}

						MONSTER *aiowner = static_cast<MONSTER*>(m_Unit);
						//clear tagger.
						aiowner->Tagged = false;
						aiowner->TaggerGuid = 0;
						aiowner->SetUInt32Value(UNIT_DYNAMIC_FLAGS,aiowner->GetUInt32Value(UNIT_DYNAMIC_FLAGS) & ~(U_DYN_FLAG_TAGGED_BY_OTHER |U_DYN_FLAG_LOOTABLE));
						aiowner->m_lootMethod = -1;
					}
					CALL_SCRIPT_EVENT(m_Unit, OnCombatStop)(SavedFollow);
				}

				if(m_Unit->GetMapMgr()->GetMapInfo() && m_Unit->GetMapMgr()->GetMapInfo()->type == INSTANCE_RAID)
				{
					if(m_Unit->GetTypeId() == TYPEID_UNIT)
					{
						if(static_cast<MONSTER*>(m_Unit)->GetMONSTERName() && static_cast<MONSTER*>(m_Unit)->GetMONSTERName()->Rank == 3)
						{
							  m_Unit->GetMapMgr()->RemoveCombatInProgress(m_Unit->GetGUID());
						}
					}
				}

				// Remount if mounted
				if(m_Unit->GetTypeId() == TYPEID_UNIT)
				{
					if( static_cast< MONSTER* >( m_Unit )->proto )
						m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, static_cast< MONSTER* >( m_Unit )->proto->MountedDisplayID );
				}
			}break;
		case EVENT_DAMAGETAKEN:
			{
				if( pUnit == NULL ) return;

				if( static_cast< MONSTER* >( m_Unit )->has_combat_text )
				objmgr.HandleMonsterSayEvent( static_cast< MONSTER* >( m_Unit ), MONSTER_SAY_EVENT_ON_DAMAGE_TAKEN );

				CALL_SCRIPT_EVENT(m_Unit, OnDamageTaken)(pUnit, float(misc1));
				if(!modThreatByPtr(pUnit, misc1))
				{
					m_aiTargets.insert(TargetMap::value_type(pUnit, misc1));
				}
				m_Unit->CombatStatus.OnDamageDealt(pUnit);
			}break;
		case EVENT_FOLLOWOWNER:
			{
				m_AIState = STATE_FOLLOWING;
				if(m_Unit->IsPet())
					((Pet*)m_Unit)->SetPetAction(PET_ACTION_FOLLOW);
				UnitToFollow = m_PetOwner;
				m_lastFollowX = m_lastFollowY = 0;
				FollowDistance = 4.0f;

				m_aiTargets.clear();
				m_fleeTimer = 0;
				m_hasFleed = false;
				m_hasCalledForHelp = false;
				m_nextSpell = NULL;
				SetNextTarget(NULL);
				m_move = true;
			}break;

		case EVENT_FEAR:
			{
				if( pUnit == NULL ) return;

				m_FearTimer = 0;
				SetUnitToFear(pUnit);

				CALL_SCRIPT_EVENT(m_Unit, OnFear)(pUnit, 0);
				m_AIState = STATE_FEAR;
				StopMovement(1);

				UnitToFollow_backup = UnitToFollow;
				UnitToFollow = NULL;
				m_lastFollowX = m_lastFollowY = 0;
				FollowDistance_backup = FollowDistance;
				FollowDistance = 0.0f;

				m_aiTargets.clear(); // we'll get a new target after we are unfeared
				m_fleeTimer = 0;
				m_hasFleed = false;
				m_hasCalledForHelp = false;

				// update speed
				m_move = true;
				getMoveFlags();

				SetNextSpell(NULL);
				SetNextTarget(NULL);
			}break;

		case EVENT_UNFEAR:
			{
				UnitToFollow = UnitToFollow_backup;
				FollowDistance = FollowDistance_backup;
				m_AIState = STATE_IDLE; // we need this to prevent permanent fear, wander, and other problems

				SetUnitToFear(NULL);
				StopMovement(1);
			}break;

		case EVENT_WANDER:
			{
				if( pUnit == NULL ) return;

				m_WanderTimer = 0;

				//CALL_SCRIPT_EVENT(m_Unit, OnWander)(pUnit, 0); FIXME
				m_AIState = STATE_WANDER;
				StopMovement(1);

				UnitToFollow_backup = UnitToFollow;
				UnitToFollow = NULL;
				m_lastFollowX = m_lastFollowY = 0;
				FollowDistance_backup = FollowDistance;
				FollowDistance = 0.0f;

				m_aiTargets.clear(); // we'll get a new target after we are unwandered
				m_fleeTimer = 0;
				m_hasFleed = false;
				m_hasCalledForHelp = false;

				// update speed
				m_move = true;
				getMoveFlags();

				SetNextSpell(NULL);
				SetNextTarget(NULL);
			}break;

		case EVENT_UNWANDER:
			{
				UnitToFollow = UnitToFollow_backup;
				FollowDistance = FollowDistance_backup;
				m_AIState = STATE_IDLE; // we need this to prevent permanent fear, wander, and other problems

				StopMovement(1);
			}break;

		default:
			{
			}break;
		}
	}

	//Should be able to do this stuff even when evading
	switch(event)
	{
		case EVENT_UNITDIED:
		{
			if( pUnit == NULL ) return;

			if( static_cast< MONSTER* >( m_Unit )->has_combat_text )
			objmgr.HandleMonsterSayEvent( static_cast< MONSTER* >( m_Unit ), MONSTER_SAY_EVENT_ON_DIED );

			CALL_SCRIPT_EVENT(m_Unit, OnDied)(pUnit);
			m_AIState = STATE_IDLE;

			StopMovement(0);
			m_aiTargets.clear();
			UnitToFollow = NULL;
			m_lastFollowX = m_lastFollowY = 0;
			UnitToFear = NULL;
			FollowDistance = 0.0f;
			m_fleeTimer = 0;
			m_hasFleed = false;
			m_hasCalledForHelp = false;
			m_nextSpell = NULL;

			SetNextTarget(NULL);
			//reset ProcCount
			//ResetProcCounts();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -