Browse Source

Fear and combat runspeed

Fix #88 - combat runspeed set (versus using movement loop speed previously set)
Fix #87 - fear pathing prototype
Image 4 years ago
parent
commit
eb7209f1c2

+ 44 - 1
EQ2/source/WorldServer/Entity.cpp

@@ -36,6 +36,7 @@ extern Classes classes;
 
 Entity::Entity(){
 	max_speed = 6;
+	base_speed = 0.0f;
 	last_x = -1;
 	last_y = -1;
 	last_z = -1;
@@ -67,6 +68,9 @@ Entity::Entity(){
 	MSpellEffects.SetName("Entity::MSpellEffects");
 	m_procList.clear();
 	control_effects.clear();
+	for (int i = 0; i < CONTROL_MAX_EFFECTS; i++)
+		control_effects[i] = NULL;
+
 	immunities.clear();
 
 	for(int i=0;i<45;i++){
@@ -1313,7 +1317,10 @@ float Entity::CalculateCastingSpeedMod() {
 }
 
 float Entity::GetSpeed() {
-	float ret = speed;
+	float ret = GetBaseSpeed();
+
+	if (EngagedInCombat())
+		ret = GetMaxSpeed();
 
 	if (IsStealthed() || IsInvis())
 		ret += stats[ITEM_STAT_STEALTHINVISSPEEDMOD];
@@ -1752,6 +1759,13 @@ void Entity::AddFearSpell(LuaSpell* spell){
 			GetZone()->LockAllSpells((Player*)this);
 	}
 
+	if (IsNPC())
+	{
+		this->ClearRunningLocations();
+		if (GetZone())
+			GetZone()->movementMgr->StopNavigation(this);
+	}
+
 	control_effects[CONTROL_EFFECT_TYPE_FEAR]->Add(spell);
 }
 
@@ -1767,6 +1781,14 @@ void Entity::RemoveFearSpell(LuaSpell* spell){
 		if (!IsMezzedOrStunned() && !IsStifled())
 			GetZone()->LockAllSpells((Player*)this);
 	}
+
+	if (IsNPC())
+	{
+		this->ClearRunningLocations();
+
+		if (GetZone())
+			GetZone()->movementMgr->StopNavigation(this);
+	}
 }
 
 void Entity::AddSnareSpell(LuaSpell* spell) {
@@ -1827,36 +1849,57 @@ float Entity::GetHighestSnare() {
 }
 
 bool Entity::IsSnared() {
+	if (control_effects.size() < 1 || !control_effects[CONTROL_EFFECT_TYPE_SNARE])
+		return false;
+
 	MutexList<LuaSpell*>* snare_list = control_effects[CONTROL_EFFECT_TYPE_SNARE];
 	return (!snare_list || snare_list->size(true) == 0) == false;
 }
 
 bool Entity::IsMezzed(){
+	if (control_effects.size() < 1 || !control_effects[CONTROL_EFFECT_TYPE_MEZ])
+		return false;
+
 	MutexList<LuaSpell*>* mez_spells = control_effects[CONTROL_EFFECT_TYPE_MEZ];
 	return  (!mez_spells || mez_spells->size(true) == 0 || IsMezImmune()) == false;
 }
 
 bool Entity::IsStifled(){
+	if (!control_effects[CONTROL_EFFECT_TYPE_STIFLE])
+		return false;
+
 	MutexList<LuaSpell*>* stifle_list = control_effects[CONTROL_EFFECT_TYPE_STIFLE];
 	return  (!stifle_list || stifle_list->size(true) == 0 || IsStifleImmune()) == false;
 }
 
 bool Entity::IsDazed(){
+	if (control_effects.size() < 1 || !control_effects[CONTROL_EFFECT_TYPE_DAZE])
+		return false;
+
 	MutexList<LuaSpell*>* daze_list = control_effects[CONTROL_EFFECT_TYPE_DAZE];
 	return  (!daze_list || daze_list->size(true) == 0 || IsDazeImmune()) == false;
 }
 
 bool Entity::IsStunned(){
+	if (!control_effects[CONTROL_EFFECT_TYPE_STUN])
+		return false;
+
 	MutexList<LuaSpell*>* stun_list = control_effects[CONTROL_EFFECT_TYPE_STUN];
 	return (!stun_list || stun_list->size(true) == 0 || IsStunImmune()) == false;
 }
 
 bool Entity::IsRooted(){
+	if (control_effects.size() < 1 || !control_effects[CONTROL_EFFECT_TYPE_ROOT])
+		return false;
+
 	MutexList<LuaSpell*>* root_list = control_effects[CONTROL_EFFECT_TYPE_ROOT];
 	return (!root_list || root_list->size(true) == 0 || IsRootImmune()) == false;
 }
 
 bool Entity::IsFeared(){
+	if (control_effects.size() < 1 || !control_effects[CONTROL_EFFECT_TYPE_FEAR])
+		return false;
+
 	MutexList<LuaSpell*>* fear_list = control_effects[CONTROL_EFFECT_TYPE_FEAR];
 	return (!fear_list || fear_list->size(true) == 0 || IsFearImmune()) == false;
 }

+ 4 - 2
EQ2/source/WorldServer/Entity.h

@@ -316,6 +316,7 @@ struct ThreatTransfer {
 #define CONTROL_EFFECT_TYPE_FLIGHT 12
 #define CONTROL_EFFECT_TYPE_GLIDE 13
 #define CONTROL_EFFECT_TYPE_SAFEFALL 14
+#define CONTROL_MAX_EFFECTS 15 // always +1 to highest control effect
 
 #define IMMUNITY_TYPE_MEZ 1
 #define IMMUNITY_TYPE_STIFLE 2
@@ -741,8 +742,8 @@ public:
 
 	float GetSpeed();
 	float GetAirSpeed();
-	float GetBaseSpeed() { return speed; }
-	void SetSpeed(float val) { speed = val; }
+	float GetBaseSpeed() { return base_speed; }
+	void SetSpeed(float val) { if (base_speed == 0.0f && val > 0.0f) base_speed = val;  speed = val; }
 	void SetSpeedMultiplier(float val) { speed_multiplier = val; }
 
 	void SetThreatTransfer(ThreatTransfer* transfer) { m_threatTransfer = transfer; }
@@ -871,6 +872,7 @@ private:
 	/// <param name='target'>Target of the proc</param>
 	bool CastProc(Proc* proc, int8 type, Spawn* target);
 
+	float base_speed;
 	float speed;
 	float speed_multiplier;
 

+ 1 - 1
EQ2/source/WorldServer/NPC_AI.cpp

@@ -59,7 +59,7 @@ void Brain::Think() {
 	Entity* target = GetMostHated();
 
 	// If mezzed, stunned or feared we can't do anything so skip
-	if (!m_body->IsMezzedOrStunned() || !m_body->IsFeared()) {
+	if (!m_body->IsMezzedOrStunned()) {
 		// Not mezzed or stunned
 
 		// Get the distance to the runback location

+ 25 - 1
EQ2/source/WorldServer/Spawn.cpp

@@ -2102,11 +2102,26 @@ void Spawn::ProcessMovement(bool isSpawnListLocked){
 	if (GetHP() <= 0 && !IsWidget())
 		return;
 
+	if (EngagedInCombat())
+	{
+		int locations = 0;
+		if (movement_locations && MMovementLocations)
+		{
+			MMovementLocations->readlock(__FUNCTION__, __LINE__);
+			locations = movement_locations->size();
+			MMovementLocations->releasereadlock(__FUNCTION__, __LINE__);
+		}
+		if (locations < 1 && GetZone() && ((Entity*)this)->IsFeared())
+		{
+			CalculateNewFearpoint();
+		}
+	}
+
 	MMovementLoop.lock();
 	Spawn* followTarget = GetZone()->GetSpawnByID(m_followTarget, isSpawnListLocked);
 	if (!followTarget && m_followTarget > 0)
 		m_followTarget = 0;
-	if (following && followTarget) {
+	if (following && followTarget && !((Entity*)this)->IsFeared()) {
 
 		// Need to clear m_followTarget before the zoneserver deletes it
 		if (followTarget->GetHP() <= 0) {
@@ -3026,3 +3041,12 @@ bool Spawn::CheckLoS(glm::vec3 myloc, glm::vec3 oloc)
 	return false;
 }
 
+void Spawn::CalculateNewFearpoint()
+{
+	if (GetZone() && GetZone()->pathing) {
+		auto Node = zone->pathing->GetRandomLocation(glm::vec3(GetX(), GetZ(), GetY()));
+		if (Node.x != 0.0f || Node.y != 0.0f || Node.z != 0.0f) {
+			AddRunningLocation(Node.x, Node.y, Node.z, GetSpeed(), 0, true, true, "", true);
+		}
+	}
+}

+ 1 - 0
EQ2/source/WorldServer/Spawn.h

@@ -971,6 +971,7 @@ public:
 	bool CheckLoS(Spawn* target);
 	bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc);
 
+	void CalculateNewFearpoint();
 
 	void StopMoving() {
 		if (movement_locations)