Forum > Serverside Modding
[C++] [WotLk] Real Stealth...
<< < (2/3) > >>
Kaev:
That sounds really awesome. Would love to see the outcome!
--- Quote from: "Scytheria23" ---This seems to work pretty well, but there are some bugs to iron out with line of sight, etc. I'm also not totally happy with the passive stealth which seems a little too powerful (e.g. you can stand still right in front of an npc without being detected). This should, hopefully, be a case of fine-tuning some of the spell variables.
--- End quote --- I don't know how they implemented the stealth mechanism, but i doubt that you can do that with some spell variables. Good thing: The server knows the orientation of the NPC, so you can calculate the area where the NPC could see the player. Bad thing: You probably have to mess with the whole line of sight and/or stealth detection system in your core.
EDIT: I thought 5 minutes about it and maybe it would be enough to implement a custom CanSeeOrDetect method, do the calculation if the player is in front of the NPC somewhere and return true. Not sure atm, but this should be the CanSeeOrDetect method that the NPCs are using: https://github.com/TrinityCore/TrinityC ... .cpp#L1940
EDIT2: There's even a CanDetectStealthOf method :) https://github.com/TrinityCore/TrinityC ... .cpp#L2068 But be careful, this is the only CanDetectStealthOf method in the whole project, which means you will change it for every single thing in the game. Example given: As a player, you'll only detect invisible NPCs infront of you too.
Scytheria23:
Another update. I'll get some vids online sometime soon to show how this is going...
Thanks to Kaev, for some very interesting ideas - these have totally reshaped my mechanism, but the new system is far more robust and works very nicely. I'll try to explain the main points:
(1) All players and NPCs now 'see' in an arc rather than having 360 vision. (2) The size of the arc is increased by having high intellect (e.g. perception). (3) The size of the arc is decreased, however, by an approaching unit's agility (e.g. stealth). (4) The distance a player/NPC can see is increased by intellect. (5) Thus, it is possible to follow any player/NPC (at a reasonable distance) without being seen regardless of any stealth ability. More perceptive units will spot you sooner, and you will need to move in a tighter zone to remain hidden. More agile units will be able to follow closer and in a wider zone. (6) Bulky armor and weapons improve resistance to physical damage and cause damage (of course) but reduce Agility. This effect can be mitigated by having a higher Strength. Armor and weapons in bags also count towards this effect. (7) The stealth ability is learnable (actually, talentable) and allows guaranteed invisibility when behind a unit's visual arc and a chance to be undetected when in front of it. (8) Lights emit stealth debuffs.
So, this is pretty much doing everything I wanted and without too much fiddling around. The only part of the Trinity Core modified (and heavily) is the CanDetectStealthOf function in object.cpp. This required a total rewriting, but remains compatible with the other things it handled. All I need to do next is somehow factor footsteps in to make a perfect system. Ideally, walking on things like tiles or metal plates should make noise and reduce all kinds of stealth. Not sure even where to begin on that, but something, somewhere knows when a unit walks on different textures to play different sounds or leave different footprints... clues welcomed.
Scy
Ascathos:
I'd love to see videos about this.
Scytheria23:
Due to my geographical location (e.g. China) where access to Youtube and similar sites is blocked, I'm going to have to hold up on providing videos until I get back to the UK for the summer. Meanwhile, in the spirit of sharing, I provide my code changes to object.cpp which replace the entire existing CanDetectStealthOf function. Don't poke at my coding style - I'm a mathematician, not a coder - this gets the job done.
If you choose to try out this system, you will need to make a few adjustments to suit your core because my own is heavily modified from Blizzlike parameters. My own project dispenses with levels entirely, attributes are in the range 0-200 only and stealth abilities award bonuses that only extend up to +100 stealth points. If, for example, you want a unit's level to factor into this or the level of the potential observer, you will need to figure that out yourself. If your stats are in the normal Blizzlike range, you'll need to play with the default values of v_intellect and o_agility and the bits of code that restrain them.
The below code does not do anything to create light emitters. I'm still working on that aspect, but am tinkering with the go type 30 (aura emitters) or a disused type (as Trinity Core already achieves things that way).
Anyway, use, abuse and enjoy.
--- Code: ---// Real Stealth
bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) const { float distance = GetExactDist(obj); float combatReach = 0.0f;
float v_intellect = 100.0f; float o_agility = 100.0f;
float viewarc = (float(M_PI) * 1.25); float radiusinner = 0.0f; float radiusmiddle = 10.0f; float radiusouter = 20.0f;
Unit const* v_unit = ToUnit(); Player const* v_player = ToPlayer(); Unit const* o_unit = obj->ToUnit(); Player const* o_player = obj->ToPlayer();
int32 sneakbonus = 100; float sneakscale = 1.0f;
// if object is not a player and has no stealth return true (visible at all times) // do this now to prevent running through the entire function for no good reason if (!(o_unit->GetTypeId() == TYPEID_PLAYER) && !(o_player) && !(obj->m_stealth.GetFlags())) return true;
if (v_unit) { combatReach = v_unit->GetCombatReach(); if ((v_unit->GetTypeId() == TYPEID_PLAYER) && (v_player)) v_intellect = v_player->GetStat(STAT_INTELLECT); }
if ((o_unit->GetTypeId() == TYPEID_PLAYER) && (o_player)) o_agility = o_player->GetStat(STAT_AGILITY); if (v_intellect < 1.0f) v_intellect = 1.0f; if (o_agility < 1.0f) o_agility = 1.0f; if (v_intellect > 200.0f) v_intellect = 200.0f; if (o_agility > 200.0f) o_agility = 200.0f;
viewarc = viewarc * (v_intellect / o_agility); if (viewarc > (float(M_PI) * 1.5f)) viewarc = (float(M_PI) * 1.5f); if (viewarc < (float(M_PI) / 2.0f)) viewarc = (float(M_PI) / 2.0f);
for (uint32 i = 0; i < TOTAL_STEALTH_TYPES; ++i) { if (!(obj->m_stealth.GetFlags() & (1 << i))) continue;
if (v_unit && v_unit->HasAuraTypeWithMiscvalue(SPELL_AURA_DETECT_STEALTH, i)) return true;
sneakbonus -= m_stealthDetect.GetValue(StealthType(i)); sneakbonus += obj->m_stealth.GetValue(StealthType(i)); }
if (sneakbonus < 0) sneakbonus = 0; if (sneakbonus > 100) sneakbonus = 100;
sneakscale = ((float(sneakbonus) / 100.f) * (o_agility / v_intellect));
radiusinner = combatReach; radiusmiddle = radiusinner + 15.0f - (5.0f * sneakscale); radiusouter = radiusmiddle * 2.0f;
if (radiusmiddle < radiusinner) radiusmiddle = radiusinner + 1.0f; if (radiusouter < radiusmiddle) radiusouter = radiusmiddle + 2.0f;
if (checkAlert) radiusinner += (radiusinner * 0.08f) + 1.5f; if (checkAlert) radiusmiddle += (radiusmiddle * 0.04f) + 1.0f; if (checkAlert) radiusouter += (radiusouter * 0.02f) + 0.5f;
// always detect things in combat reach if (distance < radiusinner) return true; // always detect things within the front middle arc if ((distance < radiusmiddle) && (HasInArc(viewarc, obj))) return true;
// always detect unstealthed things within the rear middle arc if ((distance < radiusmiddle) && !(HasInArc(viewarc, obj)) && !(obj->m_stealth.GetFlags())) return true;
// always detect unstealthed things within the front outer arc if ((distance < radiusouter) && (HasInArc(viewarc, obj)) && !(obj->m_stealth.GetFlags())) return true;
// otherwise thing is not detected return false; } --- End code ---
Scytheria23:
Just a quick point for anyone trying this - you will note that non-stealthed players become invisible to you when they are stood a certain distance behind you. This applies to enemies and allies alike. Essentially, they are beyond your visual arc. This is realistic (e.g. I can't see people standing behind me even if they are my friends), but possibly undesirable in a Blizzy environment (especially if you like mouse-wheeling out your view and panning around). You probably don't want half a raid group appearing to vanish just because they are stood behind you, so an additional condition will ne needed somewhere. In my project, where players can freely attack, kill and rob any other player, this effect is desired.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
|