Skip to content

[3.3.5] Get zone/area IDs from vmap data in the liquid update#19840

Merged
Shauren merged 4 commits into
TrinityCore:3.3.5from
Treeston:3.3.5-cachezoneareaids
Jun 7, 2017
Merged

[3.3.5] Get zone/area IDs from vmap data in the liquid update#19840
Shauren merged 4 commits into
TrinityCore:3.3.5from
Treeston:3.3.5-cachezoneareaids

Conversation

@Treeston

@Treeston Treeston commented Jun 2, 2017

Copy link
Copy Markdown
Contributor

Right now, every call to GetZoneId/GetAreaId (which seem innocuous enough) actually invokes a full vmaps lookup to find the zone/area id of the object. This is kind of bad.

However, as discussed in #19056, we already do liquid state updates on every server tick for everything, and that's a vmap lookup. And that vmap lookup gives us the zone/area data, we just don't use it.

And even that is kind of stupid, because why are we doing liquid updates every tick if it liquid data is static? Instead, we now do liquid update whenever the WorldObject's position changes.

Then we save it on the WorldObject, and use that info to turn GetZoneId and GetAreaId into simple member accesses.

@Treeston Treeston requested review from Shauren and r00ty-tc June 2, 2017 17:35
@Treeston Treeston changed the title Get zone/area IDs from vmap data in the liquid update [3.3.5] Get zone/area IDs from vmap data in the liquid update Jun 2, 2017
Comment thread src/server/game/Entities/Unit/Unit.cpp Outdated
if (area->zone)
m_zoneId = area->zone;

/*if (GetTypeId() == TYPEID_PLAYER)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads-up, enable this block if you're reproing to get me some useful info (also, give me a .gps).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about a timer to be able to know how much it takes?

virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const=0;
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0;
// get both area + liquid data in a single vmap lookup
virtual void getAreaAndLiquidData(unsigned int mapId, float x, float y, float z, uint8 reqLiquidType,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactor this to output all of these parameters into a structure

void WorldObject::AddToWorld()
{
Object::AddToWorld();
GetMap()->GetZoneAndAreaId(m_zoneId, m_areaId, GetPositionX(), GetPositionY(), GetPositionZ());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not GetBaseMap()?

// transports
Transport* m_transport;

// zone/area ID updated in Unit::Update (only Units can move)

@Shauren Shauren Jun 2, 2017

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False. GameObjects and DynamicObjects can move when on transport. (and on master AreaTriggers, always)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, should we do the call in their ::Update too? Or are transports always their own area?

Comment thread src/server/game/Entities/Unit/Unit.cpp Outdated
void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z)
void Unit::UpdatePositionData()
{
PositionFullVMapData data;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FullTerrainStatus (naming - matters here because you are returning GridMap data if on flat/nowmo terrain)

@nawuko

nawuko commented Jun 2, 2017

Copy link
Copy Markdown
Contributor

It's somewhat unrealated to this PR, but since you are currently working on it this could an intressting issue to solve: #19761. I did not look into this issue at all, so i'm not sure if zone/area id is even the root cause here.

@Treeston

Treeston commented Jun 2, 2017

Copy link
Copy Markdown
Contributor Author

That'd be an issue with base gridmap/vmap data, @nawuko. Not something this PR will (or aims to) address.

@nawuko

nawuko commented Jun 2, 2017

Copy link
Copy Markdown
Contributor

okay, just wanted to be sure its not a problem in the lookup logic. Thanks for looking into that 👍

@Treeston

Treeston commented Jun 2, 2017

Copy link
Copy Markdown
Contributor Author

I honestly can't say whether it is, @nawuko - though it seems unlikely.

data.liquidInfo.type = info.hitModel->GetLiquidType();
if (!reqLiquidType || (GetLiquidFlagsPtr(data.liquidInfo.type) & reqLiquidType))
if (info.hitInstance->GetLiquidLevel(pos, info, data.liquidInfo.level))
data.hasLiquid = true;

@Shauren Shauren Jun 2, 2017

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good place to use Optional

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would make it inconsistent with other vmap methods though.

@Shauren Shauren Jun 6, 2017

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use it. (Optional)

@Treeston

Treeston commented Jun 3, 2017

Copy link
Copy Markdown
Contributor Author

@Shauren it is my understanding that any movement of a worldobject while it's added to a map should go through one of the methods calling ->Relocate in Map - is this correct?

@Treeston Treeston requested a review from Shauren June 4, 2017 21:37
data.liquidInfo.type = info.hitModel->GetLiquidType();
if (!reqLiquidType || (GetLiquidFlagsPtr(data.liquidInfo.type) & reqLiquidType))
if (info.hitInstance->GetLiquidLevel(pos, info, data.liquidInfo.level))
data.hasLiquid = true;

@Shauren Shauren Jun 6, 2017

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use it. (Optional)


bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const override;
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const override;
virtual void getAreaAndLiquidData(unsigned int mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const override;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

virtual keyword not needed

#define VMAP_INVALID_HEIGHT -100000.0f // for check
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case

struct TC_COMMON_API AreaAndLiquidData

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*_API macro is only needed when your struct/class has methods implemented in .cpp file

// transports
Transport* m_transport;

virtual void _ProcessPositionDataChanged(PositionFullTerrainStatus const& data);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't prefix method names with _

Comment thread src/server/game/Entities/Unit/Unit.cpp Outdated
{
WorldObject::_ProcessPositionDataChanged(data);

/*if (GetTypeId() == TYPEID_PLAYER)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove debug commented out code

Comment thread src/server/game/Maps/Map.h Outdated

struct PositionFullTerrainStatus
{
bool hasFullAreaInfo;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls, Optional (no has*** members)

Comment thread src/server/game/Maps/Map.cpp Outdated

// area lookup
AreaTableEntry const* areaEntry = nullptr;
if (vmapData.hasAreaInfo && !(z + 2.0f > mapHeight && mapHeight > vmapData.floorZ))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dont bring out the negation before (), especially when you have conditions you can easily change (> to <=)

Comment thread src/server/game/Maps/Map.cpp Outdated
data.areaInfo.groupId = vmapData.areaInfo.groupId;
data.areaInfo.mogpFlags = vmapData.areaInfo.flags;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 newlines

Comment thread src/server/game/Maps/Map.cpp Outdated
return result;
}

void Map::getFullTerrainStatusForPosition(float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType) const

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

method name? make it start with uppercase (you can leave the one in vmapmanager as-is)

Comment thread src/server/game/Entities/Unit/Unit.h Outdated

void DisableSpline();

void _ProcessPositionDataChanged(PositionFullTerrainStatus const& data) override;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't prefix method names with _

… liquid info in a single vmap lookup

- Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
- Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
- Clean up liquid state handling on Unit and Player since I'm at it (fixes and closes TrinityCore#16489)
@Treeston Treeston force-pushed the 3.3.5-cachezoneareaids branch from 78ced7b to ed93010 Compare June 7, 2017 01:03
@Treeston

Treeston commented Jun 7, 2017

Copy link
Copy Markdown
Contributor Author

Travis build fail is due to outdated boost (it has 1.55, we require 1.59).

Removing in place construction (.emplace, the Boost 1.56 feature we need) would be a pretty significant performance impact, which I'm not overly willing to accept at this point in a core vmap call.

@Treeston Treeston requested a review from Shauren June 7, 2017 01:34
@ariel-

ariel- commented Jun 7, 2017

Copy link
Copy Markdown
Contributor

Ref boost::optional move semantics, not the first time this happens:
4c27203#diff-1bfb148491dedaab3a6311bec32f7e7eR172.

Is the performance hit that bad? IIRC POD types were just copied instead moved, you can still use boost::in_place to perform an in-place initialization

@Shauren

Shauren commented Jun 7, 2017

Copy link
Copy Markdown
Member

We use boost::in_place everywhere in packets on master branch (you just need a no-arg constructor, or just no constructors at all)

Comment thread src/server/game/Maps/Map.h Outdated

struct PositionFullTerrainStatus
{
typedef VMAP::AreaAndLiquidData::AreaInfo AreaInfo;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is convenient but don't do this. Don't make all users of Map class also include VMapManager

@Treeston Treeston requested a review from Shauren June 7, 2017 11:41
@Shauren

Shauren commented Jun 7, 2017

Copy link
Copy Markdown
Member

response.SuccessInfo = boost::in_place();

This is the zero-overhead pattern that is used in master branch for building packets - assigning boost::in_place() no-arg version is the same as calling .emplace() with no args
after that you just assign each field (obviously they cant be const in that case)

Treeston added 2 commits June 7, 2017 21:47
…it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.
@Shauren Shauren merged commit f6c8497 into TrinityCore:3.3.5 Jun 7, 2017
@Treeston Treeston deleted the 3.3.5-cachezoneareaids branch July 10, 2017 21:02
Jildor added a commit to Jildor/TrinityCore that referenced this pull request Jul 19, 2017
Jildor added a commit to Jildor/TrinityCore that referenced this pull request Jul 19, 2017
Jildor added a commit to Jildor/TrinityCore that referenced this pull request Jul 19, 2017
Jildor added a commit to Jildor/TrinityCore that referenced this pull request Jul 22, 2017
Carbenium pushed a commit to Carbenium/TrinityCore that referenced this pull request Jun 24, 2020
…yCore#19840)

* Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup
* Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
* Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
* Clean up liquid state handling on Unit and Player
* Hand floor's Z coord up through GetFullTerrainStatusForPosition, use it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.

Closes TrinityCore#16489

(cherry picked from commit f6c8497)
Carbenium pushed a commit to Carbenium/TrinityCore that referenced this pull request Jun 25, 2020
…yCore#19840)

* Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup
* Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
* Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
* Clean up liquid state handling on Unit and Player
* Hand floor's Z coord up through GetFullTerrainStatusForPosition, use it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.

Closes TrinityCore#16489

(cherry picked from commit f6c8497)
Carbenium pushed a commit to Carbenium/TrinityCore that referenced this pull request Jun 25, 2020
…yCore#19840)

* Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup
* Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
* Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
* Clean up liquid state handling on Unit and Player
* Hand floor's Z coord up through GetFullTerrainStatusForPosition, use it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.

Closes TrinityCore#16489

(cherry picked from commit f6c8497)
Shauren pushed a commit to Carbenium/TrinityCore that referenced this pull request Jul 16, 2020
…yCore#19840)

* Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup
* Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
* Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
* Clean up liquid state handling on Unit and Player
* Hand floor's Z coord up through GetFullTerrainStatusForPosition, use it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.

Closes TrinityCore#16489

(cherry picked from commit f6c8497)
Shauren pushed a commit to Carbenium/TrinityCore that referenced this pull request Jul 16, 2020
…yCore#19840)

* Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup
* Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
* Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
* Clean up liquid state handling on Unit and Player
* Hand floor's Z coord up through GetFullTerrainStatusForPosition, use it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.

Closes TrinityCore#16489

(cherry picked from commit f6c8497)
Shauren pushed a commit to Carbenium/TrinityCore that referenced this pull request Jul 16, 2020
…yCore#19840)

* Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup
* Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
* Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
* Clean up liquid state handling on Unit and Player
* Hand floor's Z coord up through GetFullTerrainStatusForPosition, use it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.

Closes TrinityCore#16489

(cherry picked from commit f6c8497)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants