Browse Source

LUAFunctions CanSeeInvis(spawn,target) SetSeeInvis(spawn,1/0) SetSeeHide(spawn,1/0)

Query required to enable see invisibility spell: update spells set is_active=1 where id=210013;
Image 1 year ago
parent
commit
a25166ad8d

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

@@ -83,6 +83,9 @@ Entity::Entity(){
 	}
 
 	MCommandMutex.SetName("Entity::MCommandMutex");
+	hasSeeInvisSpell = false;
+	hasSeeHideSpell = false;
+
 }
 
 Entity::~Entity(){
@@ -1728,7 +1731,17 @@ bool Entity::IsStealthed(){
 }
 
 bool Entity::CanSeeInvis(Entity* target) {
-	return true;
+	if (!target)
+		return true;
+
+	if (!target->IsStealthed() && !target->IsInvis())
+		return true;
+	if (target->IsStealthed() && HasSeeHideSpell())
+		return true;
+	else if (target->IsInvis() && HasSeeInvisSpell())
+		return true;
+
+	return false;
 }
 
 bool Entity::IsInvis(){

+ 9 - 0
EQ2/source/WorldServer/Entity.h

@@ -839,6 +839,12 @@ public:
 	set<int32> HatedBy;
 
 	Mutex	MCommandMutex;
+
+	bool HasSeeInvisSpell() { return hasSeeInvisSpell; }
+	void SetSeeInvisSpell(bool val) { hasSeeInvisSpell = val; }
+
+	bool HasSeeHideSpell() { return hasSeeHideSpell; }
+	void SetSeeHideSpell(bool val) { hasSeeHideSpell = val; }
 protected:
 	bool	in_combat;
 
@@ -895,6 +901,9 @@ private:
 	ThreatTransfer* m_threatTransfer;
 
 	GroupMemberInfo* group_member_info;
+
+	bool hasSeeInvisSpell;
+	bool hasSeeHideSpell;
 };
 
 #endif

+ 60 - 0
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -9327,3 +9327,63 @@ int EQ2Emu_lua_AddSpawnProximity(lua_State* state) {
 		spawn->AddLUASpawnProximity(spawn_value, (Spawn::SpawnProximityType)spawn_type, distance, in_range_function, leaving_range_function);
 	return 0;
 }
+
+int EQ2Emu_lua_CanSeeInvis(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Spawn* spawn = lua_interface->GetSpawn(state);
+	Spawn* target = lua_interface->GetSpawn(state, 2);
+	if (spawn && target)
+	{
+		if (spawn->IsPlayer() && target->IsEntity())
+		{
+			lua_interface->SetBooleanValue(state, ((Player*)spawn)->CanSeeInvis((Entity*)target));
+			return 1;
+		}
+		else if (spawn->IsEntity() && target->IsEntity())
+		{
+			lua_interface->SetBooleanValue(state, ((Entity*)spawn)->CanSeeInvis((Entity*)target));
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int EQ2Emu_lua_SetSeeInvis(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Spawn* spawn = lua_interface->GetSpawn(state);
+	bool val = (lua_interface->GetInt8Value(state, 2) == 1);
+	if (spawn && spawn->IsEntity())
+	{
+		((Entity*)spawn)->SetSeeInvisSpell(val);
+		if (spawn->IsPlayer())
+		{
+			Client* client = spawn->GetZone()->GetClientBySpawn((Player*)spawn);
+			if (client)
+				((Player*)spawn)->GetZone()->SendAllSpawnsForInvisChange(client);
+		}
+	}
+
+	return 0;
+}
+
+int EQ2Emu_lua_SetSeeHide(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Spawn* spawn = lua_interface->GetSpawn(state);
+	bool val = (lua_interface->GetInt8Value(state, 2) == 1);
+	if (spawn && spawn->IsEntity())
+	{
+		((Entity*)spawn)->SetSeeHideSpell(val);
+		if (spawn->IsPlayer())
+		{
+			Client* client = spawn->GetZone()->GetClientBySpawn((Player*)spawn);
+			if (client)
+				((Player*)spawn)->GetZone()->SendAllSpawnsForInvisChange(client);
+		}
+	}
+
+	return 0;
+}

+ 4 - 0
EQ2/source/WorldServer/LuaFunctions.h

@@ -421,4 +421,8 @@ int EQ2Emu_lua_SetZoneExpansionFlag(lua_State* state);
 int EQ2Emu_lua_GetZoneExpansionFlag(lua_State* state);
 
 int EQ2Emu_lua_AddSpawnProximity(lua_State* state);
+
+int EQ2Emu_lua_CanSeeInvis(lua_State* state);
+int EQ2Emu_lua_SetSeeInvis(lua_State* state);
+int EQ2Emu_lua_SetSeeHide(lua_State* state);
 #endif

+ 4 - 0
EQ2/source/WorldServer/LuaInterface.cpp

@@ -1024,6 +1024,10 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
 	lua_register(state, "GetZoneExpansionFlag", EQ2Emu_lua_GetZoneExpansionFlag);
 
 	lua_register(state, "AddSpawnProximity", EQ2Emu_lua_AddSpawnProximity);
+
+	lua_register(state, "CanSeeInvis", EQ2Emu_lua_CanSeeInvis);
+	lua_register(state, "SetSeeInvis", EQ2Emu_lua_SetSeeInvis);
+	lua_register(state, "SetSeeHide", EQ2Emu_lua_SetSeeHide);
 }
 
 void LuaInterface::LogError(const char* error, ...)  {

+ 4 - 0
EQ2/source/WorldServer/Player.cpp

@@ -5644,6 +5644,10 @@ bool Player::CanSeeInvis(Entity* target)
 {
 	if (!target->IsStealthed() && !target->IsInvis())
 		return true;
+	if (target->IsStealthed() && HasSeeHideSpell())
+		return true;
+	else if (target->IsInvis() && HasSeeInvisSpell())
+		return true;
 
 	sint32 radius = rule_manager.GetGlobalRule(R_PVP, InvisPlayerDiscoveryRange)->GetSInt32();
 

+ 19 - 5
EQ2/source/WorldServer/zoneserver.cpp

@@ -851,7 +851,7 @@ bool ZoneServer::CheckNPCAttacks(NPC* npc, Spawn* victim, Client* client){
 		return true;
 
 	if (client) {
-		if (client->IsConnected() && client->GetPlayer()->GetFactions()->ShouldAttack(npc->GetFactionID()) && npc->AttackAllowed((Entity*)victim, false)) {
+		if (client->IsConnected() && npc->CanSeeInvis(client->GetPlayer()) && client->GetPlayer()->GetFactions()->ShouldAttack(npc->GetFactionID()) && npc->AttackAllowed((Entity*)victim, false)) {
 			if (!npc->EngagedInCombat() && client->GetPlayer()->GetArrowColor(npc->GetLevel()) != ARROW_COLOR_GRAY) {
 				AggroVictim(npc, victim, client);
 			}
@@ -3967,13 +3967,13 @@ void ZoneServer::SendQuestUpdates(Client* client, Spawn* spawn){
 	}
 }
 
-void ZoneServer::SendAllSpawnsForLevelChange(Client* client){
+void ZoneServer::SendAllSpawnsForLevelChange(Client* client) {
 	Spawn* spawn = 0;
-	if(spawn_range_map.count(client) > 0) {
+	if (spawn_range_map.count(client) > 0) {
 		MutexMap<int32, float >::iterator itr = spawn_range_map.Get(client)->begin();
-		while(itr.Next()) {
+		while (itr.Next()) {
 			spawn = GetSpawnByID(itr->first);
-			if(spawn && client->GetPlayer()->WasSentSpawn(spawn->GetID()) && !client->GetPlayer()->WasSpawnRemoved(spawn)) {
+			if (spawn && client->GetPlayer()->WasSentSpawn(spawn->GetID()) && !client->GetPlayer()->WasSpawnRemoved(spawn)) {
 				SendSpawnChanges(spawn, client, false, true);
 				// Attempt to slow down the packet spam sent to the client
 				Sleep(5);
@@ -3982,6 +3982,20 @@ void ZoneServer::SendAllSpawnsForLevelChange(Client* client){
 	}
 }
 
+
+void ZoneServer::SendAllSpawnsForInvisChange(Client* client) {
+	Spawn* spawn = 0;
+	if (spawn_range_map.count(client) > 0) {
+		MutexMap<int32, float >::iterator itr = spawn_range_map.Get(client)->begin();
+		while (itr.Next()) {
+			spawn = GetSpawnByID(itr->first);
+			if (spawn && spawn->IsEntity() && (((Entity*)spawn)->IsInvis() || ((Entity*)spawn)->IsStealthed()) && client->GetPlayer()->WasSentSpawn(spawn->GetID()) && !client->GetPlayer()->WasSpawnRemoved(spawn)) {
+				SendSpawnChanges(spawn, client, true, true);
+			}
+		}
+	}
+}
+
 void ZoneServer::StartZoneSpawnsForLevelThread(Client* client){
 	if(zoneShuttingDown)
 		return;

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

@@ -327,6 +327,7 @@ public:
 	
 	void	ReloadClientQuests();
 	void	SendAllSpawnsForLevelChange(Client* client);
+	void	SendAllSpawnsForInvisChange(Client* client);
 	
 	void	AddLocationGrid(LocationGrid* grid);
 	void	RemoveLocationGrids();

+ 2 - 2
server/Spells/Mage/SeeInvisibility.lua

@@ -8,10 +8,9 @@
 
 function cast(Caster, Target)
     -- code to cast the spell
-    Say(Caster, "Whoops! Guess this is not implemented yet!")
-
 -- Info from spell_display_effects (remove from script when done)
 -- Grants See Invisibility to target
+	SetSeeInvis(Target, 1)
 
 end
 
@@ -21,5 +20,6 @@ end
 
 function remove(Caster, Target)
     -- code to remove the spell
+	SetSeeInvis(Target, 0)
 end