Thread Tools Display Modes
06-14-15, 10:43 PM   #1
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
Detecting World PvP Zones

Someone has recently commented on my KillingBlow_Enhanced AddOn that it doesn't work in Ashran when PvP only mode (i.e. only report killing blows when in PvP zones) is enabled. To detect if the current zone is a PvP zone, I'm calling IsInInstance and checking if the instance type (second return value) is "pvp" or "arena".

Is there an easy way to detect whether the current zone is a World PvP zone? The World Battlefield API section didn't have any obvious solution to this.
  Reply With Quote
06-15-15, 03:42 AM   #2
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
Thanks, I'll use that approach.
  Reply With Quote
06-15-15, 06:15 AM   #3
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
I try to avoid to use SetMapToCurrentZone() as much as I can (so far I could totally avoid it) because it will interfere with the user watching another map. The alternative approach that works well is to use GetInstanceInfo()

Code:
local _,_,_,_,_,_,_,zone = GetInstanceInfo()
if zone==1191 then
	print("I am in Ashran")
elseif zone==732 then
	print("I am in Tol Barad")
end
This approach does NOT work in Wintergrasp though because when you are there you will get the 571 return which is the Northrend id both during Wintergrasp battle or between battles (when it is like any Northrend zone).
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill

Last edited by Banknorris : 06-15-15 at 06:20 AM.
  Reply With Quote
06-15-15, 08:03 AM   #4
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
That's a good idea. Using GetInstanceInfo, I can at least avoid calling SetMapToCurrentZone on every continent except Northrend.
  Reply With Quote
06-15-15, 09:03 AM   #5
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
Just for future reference:


When you enter a new continent/instance (including when you first log in), PLAYER_ENTERING_WORLD and ZONE_CHANGED_NEW_AREA are fired in that order. When PLAYER_ENTERING_WORLD fires, GetInstanceInfo returns the correct instance map ID but GetCurrentMapAreaID returns the area ID of the continent. When ZONE_CHANGED_NEW_AREA fires, GetCurrentMapAreaID returns the correct area ID (after you call SetMapToCurrentZone).

Last edited by Choonstertwo : 06-15-15 at 09:05 AM.
  Reply With Quote
06-15-15, 11:02 AM   #6
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Banknorris View Post
I try to avoid to use SetMapToCurrentZone() as much as I can (so far I could totally avoid it) because it will interfere with the user watching another map. The alternative approach that works well is to use GetInstanceInfo()

Code:
local _,_,_,_,_,_,_,zone = GetInstanceInfo()
if zone==1191 then
	print("I am in Ashran")
elseif zone==732 then
	print("I am in Tol Barad")
end
This approach does NOT work in Wintergrasp though because when you are there you will get the 571 return which is the Northrend id both during Wintergrasp battle or between battles (when it is like any Northrend zone).
You can use this to detect if the battle is active or not:

http://wowprogramming.com/docs/api/GetWorldPVPAreaInfo
  Reply With Quote
06-15-15, 01:30 PM   #7
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Presumably you can just use IsInActiveWorldPVP()

There's also GetZonePVPInfo()
  Reply With Quote
06-16-15, 10:06 AM   #8
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
I do something like this in "remgank" :

Lua Code:
  1. local _, instanceType = IsInInstance()
  2.         if REMGANK_ENABLE == false or instanceType == "arena" or instanceType == "pvp" or (instanceType == "none" and GetZonePVPInfo() == "combat") then
  3.             -- REMGANK_ENABLE == false Monitoring is disabled
  4.             -- arena is, obviously, an arena.
  5.             -- pvp is a battleground.
  6.             -- none with GetZonePVPInfo() == "combat" is an outdoor PvP zone like Wintergrasp.
  7.             self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  8.         else
  9.             -- If not in a pvp zone, register CLEU:
  10.             self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  11.         end
  12.         return
  13.     end

It seems to work for me ...
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
06-17-15, 06:18 AM   #9
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
Originally Posted by semlar View Post
Presumably you can just use IsInActiveWorldPVP()
Do you know whether that returns true only during an active battle or any time you're in a World PvP zone? Do you know which event to listen for to know when the return value changes? Unfortunately I don't think trial accounts have access to any world PvP zones, so I can't test it myself.

The default UI only seems to call it when you right click on a unit on the world map to determine whether or not you can report them as AFK.

WoW Programming doesn't have any documentation for it and Wowpedia doesn't have it listed at all.
  Reply With Quote
06-16-15, 01:53 PM   #10
p3lim
A Pyroguard Emberseer
 
p3lim's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 1,710
Originally Posted by Banknorris View Post
I try to avoid to use SetMapToCurrentZone() as much as I can (so far I could totally avoid it) because it will interfere with the user watching another map.
This method is safe:

Lua Code:
  1. local oldAreaID = GetCurrentMapAreaID()
  2. SetMapToCurrentZone()
  3.  
  4. -- store the current area ID
  5. local areaID = GetCurrentMapAreaID()
  6.  
  7. SetMapByID(oldAreaID)
  8.  
  9. -- do things
  Reply With Quote
06-16-15, 03:00 PM   #11
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by p3lim View Post
This method is safe:

Lua Code:
  1. local oldAreaID = GetCurrentMapAreaID()
  2. SetMapToCurrentZone()
  3.  
  4. -- store the current area ID
  5. local areaID = GetCurrentMapAreaID()
  6.  
  7. SetMapByID(oldAreaID)
  8.  
  9. -- do things
No it isn't, you don't take into account the previous map level. Also, changing the map resets its zoom (if you use the scroll wheel on the world map).

This would also set the map to the wrong zone if you're currently inside of a microdungeon.

There are other things to consider when changing the map, like how extremely cpu intensive addons like Routes and Gatherer would react.

The only safeish method for actively changing the current map is to unregister WORLD_MAP_UPDATE from every frame that's watching it, do your thing and swap the map back to what it previously was, then re-register the event to those frames.

I don't recommend anyone do that unless they fully comprehend how the map works.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Detecting World PvP Zones


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off