Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement WorldObject::IsInBetween() to work as intented. #3146

Merged
merged 1 commit into from Sep 23, 2011
Merged

Reimplement WorldObject::IsInBetween() to work as intented. #3146

merged 1 commit into from Sep 23, 2011

Conversation

Havenard
Copy link
Contributor

Reimplement WorldObject::IsInBetween() to work as intented.

The current algorithm is nonsense and broken, and most likely always fail to determine if the object is between obj1 and obj2 line of sight.

Closes #2163 and #1329 and makes heroic modes of Sindragosa possible. yay!

@Havenard
Copy link
Contributor Author

Trust me, I have years of experience in Garry's Mod with algorithms envolving LoS checks for all kind of systems like auto-aim turrets, "heat"-seeking missiles and stuff like that. This functions is totally broken and a big hacky shit. Mine is clean, linear, makes sense, and most importantly it works.

Currently Sindragosa is only possible because the Frost Bomb NPC is level 1 and always fail to hit the players with the explosions. If they were level 83 as they should you would see that the Ice Tomb pretty much never protect the players at all, and its not survivable in heroic mode.

@Anonimo17
Copy link

I trust you, I'm not a developer nor a mathematician, but the previous code made more sense.
Do you mind explaining yours line per line (if you have time)?

@megamage
Copy link

The old code was written by me for Sindragosa. It creates a belt-shape zone. This new patch creates a cone-shape zone. The difference is that in belt zone you need to hide right behind the ice block, while in cone zone you can hide from a long distance.

I do not know how it works in offical server. But for cone-shape zone there may be a problem. Suppose the ice block is right at the foot of Sindragosa. Then dist = 0, and all players are safe no matter where you stand. Should that be the case?

@megamage
Copy link

@kapoeira
The crash should be caused by NULL obj. Yes I agree that a check should be added. If a function is supposed to be used in script it better has more checks. Many scripters pass NULL pointers without checking.

@Havenard
Copy link
Contributor Author

Well megamage I'm sorry to say its not working in none of this cases. Sometimes it protects you from distance, and sometimes when you are right behind it you die anyway. Once I set size = 16.0f for Sindragosa to try to workaround this problem, but even with this absurd range the players were dieing sometimes. The function just doesn't work at all.

@Havenard
Copy link
Contributor Author

@Anonimo17 http://i55.tinypic.com/k32kb9.png

First it do a simple check to determine if the rock can be between both objects by checking the distances. They must be more distant from each other then any one of them is distant from the rock, otherwhise the tree objects may be aligned but not necessarily putting obj1 and obj2 out of sight.

Being it true, it get the distance from the first object, the angle from the second object, and calculate a third point in the equation that should be within the radius "size" of the rock. Being it true the objects are aligned, combined with the first condition it means obj1 and obj2 are out of line of sight.

The image shows how it works. I draw with obj1 being the explosion, but the order doesn't really metter.

@megamage
Copy link

@Havenard
Thank you for the figure. It can be seen that as the distance between dragon and tomb decreases, the area of safe zone increases. If the dragon is within the tomb, i.e., dist is about 0, all players are covered by the safe zone. Should it work in that way?

@Havenard
Copy link
Contributor Author

If the bomb explode inside the Ice Tomb radius? It still depends on the side and distance it explodes. I beleave it can provide up to "almost" 180º protection, or as long as your distance from the Ice Tomb is lower then your distance from the explosion.

If it explode exactly at distance 0 from the Ice Tomb then I guess everybody would die.

But notice the explosion doesn't occur from the dragon, its an invisible trigger NPC where the bomb lands that explodes.

http://www.wowhead.com/npc=37186

@Warpten
Copy link
Member

Warpten commented Sep 21, 2011

Anyways, i think this case is quite ... extreme, and should almost never occur, considering the width of sindragosa's lair.

@Havenard
Copy link
Contributor Author

Yeah, if the players go to the stairs during the air phase as the boss strategy suggest, then a Frost Bomb will never land inside the Ice Tombs radius. If a player freeze in the middle of the room then you are already doing the boss wrong and will probably get wiped.

@megamage
Copy link

@Havenard
If dist == 0,
GetExactDist2dSq(obj1->GetPositionX() + cos(angle) * dist, obj1->GetPositionY() + sin(angle) * dist)
== GetExactDist2dSq(obj1->GetPositionX(), obj1->GetPositionY())
== 0
(size * size) >= 0 will always be true.
So everyone will be protected instead of being killed.
Also, I doubt in official server they allow you to create a 180 degree protection. I thought you always need to hide right behind the ice tomb.
But I have never been to offical server so maybe I am wrong.

@WarHead
Copy link

WarHead commented Sep 21, 2011

it's not needed (on the offi) to be direct in one line of the explosion behind the tomb. it's enough if something of the tomb is between the explosion point and the player.

@megamage: it's impossible (on the offi) that the distance between the explosion and the tomb is zero.

@Havenard
Copy link
Contributor Author

@megamage do you realise that the chance to this distance be exactly 0.00000f is nearly impossible? I mean practically impossible, you may try for decades and never get it to happen. I don't know what kind of defect you are trying to point here, the current IsInBetween() just don't work at all and you come with this silly discussion.

And if the player or the explosion somehow got inside the stone or at distance 0.0f from the center, what is the problem not to die? They are out line of sight after all, aren't they?

@megamage
Copy link

@WarHead @Havenard
dist == 0 is just an extreme case. It will cover all players as long as dist is within about the ice tomb size. Because you know where the frost bomb falls, it may not be difficult to create some ice tombs near that point and cover all players.

But if the official server works in that way, I do not have any problems.

And Havenard, I am not trying to discuss if the current function works or not.

@Havenard
Copy link
Contributor Author

Eh.. nope, you don't know where they are going to fall. And the tombs can't move. Even if you use a cheat you may move your player but the tomb won't follow. You cant try to circle a group of players either because they all would freeze and the boss would reset. It works just right and I cant see a single situation where it is exploitable or even behave weird.

@Havenard
Copy link
Contributor Author

@megamage I wrote this simulator do help everyone test how it behaves in a variety of situations. It showed that in fact you were right when you said everybody would survive if it explode near the center of the tomb, yet I don't think this is a problem.

It also simulates the old function and show how it is broken.

http://www.swfcabin.com/open/1316644094

And this is why the old function fails: http://i56.tinypic.com/98ww1s.gif

@DeltaPower
Copy link

As you can see here, the closer the ice tomb placed to X or Y axis, the more deadly zone appears behind ice tombs:
http://i54.tinypic.com/xnc96v.jpg
(red zone states safe)

If you stand X=0.0000001 and the ice tomb center is at X= - 0.0000001 (let's say Sapphi is at X=0), then
min(obj1X, obj2X) will be X=0
Because of Line 1530 of Megamage's code:
if (GetPositionX() < std::min(obj1->GetPositionX(), obj2->GetPositionX())
you will die, altough you were behind the ice tomb.
The difference is as small as cannot be visually stated, the only thing can be done is try to create the ice tomb at exactly the same distance from both axes to minimize deadly zone behind them.
The more serious problem is that if coord check fails, function returns false without even checking gameobject size.

I noticed this error more than a year ago, but could not find solution, Thanks Havenard!

@megamage
Copy link

@Havenard @DeltaPower
Thank you for the nice flash and figures. I just watched a video and read the strategy. Sindragosa's spells are now very different from two years ago... Now she casts 4 ice bombs to random locations. I remember she used to only cast one exactly at the center of the hall. So I think Havenard's patch is correct.

QAston added a commit that referenced this pull request Sep 23, 2011
Reimplement WorldObject::IsInBetween() to work as intented.
@QAston QAston merged commit 71bbbaa into TrinityCore:master Sep 23, 2011
asido pushed a commit to asido/TrinityCore that referenced this pull request Mar 12, 2012
Reimplement WorldObject::IsInBetween() to work as intented.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[NPC] Sindragosa
7 participants