- Joined
- Feb 16, 2007
- Messages
- 71
- Reaction score
- 0
OK guys i changed a few things with stealth, it is now working pretty good. And i added the option to keep the old system in the ini. It is now possible to stealth arround an instance, i added collision detection (just distance in between mob and player), and fixed something to do with the size of the objects (before getdistance would only give the distance of the mob 4 feet infront of it, with this it is more accurate). Also added level detection, if a mob is 5 levels or more above the player he will be automaticly detected. I published this over at project mangos, let me know what you guys think. Once i have it down perfectly going to add some fixes to sap, gauge and garote.
well here goes :
added changes in mangosconf.ini :
Modified function in unit.cpp :
modified function in world.cpp
Added the fallowing variable in world.cpp in under void World::SetInitialWorldSettings() (under the raterate section)
Added the fallowing under world.h under enum Rates
Well these are the main changes, let me know if you want the cpp, ?h and ini files i ll make them availble easier than edtting the whle thing by hand.
Well let me know what you guys think, be back later.
well here goes :
added changes in mangosconf.ini :
Code:
#************************* NEW*****************
#Stealth probability rate
# default = 1, 0 = probability 0 of being seen by mob
RATE_STEALTH=0
#***********************************************
Modified function in unit.cpp :
Code:
bool Unit::isVisibleFor(Unit* u, bool detect)
{
// Visible units, always are visible for all pjs
if (m_Visibility == VISIBILITY_ON)
return true;
// GMs are visible for higher gms (or players are visible for gms)
if (u->GetTypeId() == TYPEID_PLAYER && ((Player *)u)->isGameMaster())
return (GetTypeId() == TYPEID_PLAYER && ((Player *)this)->GetSession()->GetSecurity() <= ((Player *)u)->GetSession()->GetSecurity());
// non faction visibility non-breakable for non-GMs
if (m_Visibility == VISIBILITY_OFF)
return false;
// Units far than MAX_DIST_INVISIBLE, that are not gms and are stealth, are not visibles too
if (!this->IsWithinDist(u,MAX_DIST_INVISIBLE_UNIT))
return false;
// Stealth not hostile units, not visibles (except Player-with-Player case)
if (!u->IsHostileTo(this))
{
// player autodetect other player with stealth only if he in same group or raid or same team (raid/team case dependent from conf setting)
if(GetTypeId()==TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER)
{
if(((Player*)this)->IsGroupVisibleFor(((Player*)u)))
return true;
// else apply same rules as for hostile case (detecting check)
}
else
return true;
}
// if in non-detect mode then invisible for unit
if(!detect)
return false;
bool IsVisible = true;
bool notInFront = u->isInFront(this, MAX_DIST_INVISIBLE_UNIT * MAX_DIST_INVISIBLE_UNIT) ? 0 : 1;
float Distance = sqrt(GetDistanceSq(u));
float prob = 0;
int32 x = u->getLevel() + (u->m_detectStealth / 5) - (m_stealthvalue / 5) + 59;
//Code not needed anymore, but still commented to show progression and future needs
/*
float PlayerPositionX = converter(((Player*)this)->GetPositionX());
float PlayerPositionY = converter(((Player*)this)->GetPositionY());
float PlayerPositionZ = converter(((Player*)this)->GetPositionZ());
float MobPositiontest = converter(((Player*)this)->GetPositionX()- sqrt(GetDistanceSq(u)));// test
float MobPositionX = converter(((Player*)this)->GetPositionX()+ sqrt(GetDistanceSq(u)));
float MobPositionY = converter(((Player*)this)->GetPositionY()+ sqrt(GetDistanceSq(u)));
float MobPositionZ = converter(((Player*)this)->GetPositionZ()+ sqrt(GetDistanceSq(u)));
//INITIALISE COLLISION VARIABLES
float collisionX = 0;
float collisionY = 0;
float collisionZ = 0;
//detecting if there is a collision or user is very close to a mob student1
//the constant 2.3 is used to fix the issue with getdistance not being very exact, currently it does not center at the mob, 4 feet infront of it right now
collisionX = converter(PlayerPositionX - MobPositionX);
collisionY = converter(PlayerPositionY - MobPositionY);
collisionZ = converter(PlayerPositionZ - MobPositionZ);
//Shows values onscreen //student1
cout << "PlayerPositionY: " << PlayerPositionY << "\n";
cout << "MobPositionY: " << MobPositionY << "\n";
cout << "PlayerPositionX: " << PlayerPositionX << "\n";
cout << "MobPositionX: " << MobPositionX << "\n";
cout << "PlayerPositionZ: " << PlayerPositionZ << "\n";
cout << "MobPositionZ: " << MobPositionZ << "\n";
*/
//Simple printscreen to show distance from mobs in console. Student1
cout << "Stealth activated: Distance from mobs: " << GetDistanceSq(u) << "\n";
/*
cout << "collisions x " << collisionX << "\n";
cout << "collision y " << collisionY << "\n";
cout << "collision Z " << collisionZ << "\n";
*/
//cout << "mob level " << u->getLevel() << "/n";
//cout << "player level " << ((Player*)this)->getLevel() << "/n" ;
//This verifies if the player is on top of the mob, if he is he is detected, therefore collision detection :) student1
//if (collisionX <= 1 && collisionY <= 1 && collisionZ <= 1 )
//if (collisionX<=0.01 && collisionY<=0.01 && collisionZ<=0.01)//student1
if (GetDistanceSq(u)<0.20)//student1
{
IsVisible = true; // removes invisibility student1
//return fuction is visible = true
return IsVisible && ( Distance <= MAX_DIST_INVISIBLE_UNIT * MAX_DIST_INVISIBLE_UNIT) ;
}
//If mob is 5 levels or more above player then player is detected automaticly. Student1
if (u->getLevel() >= ((Player*)this)->getLevel()+ 5)
{
IsVisible = true; // removes invisibility student1
return IsVisible && ( Distance <= MAX_DIST_INVISIBLE_UNIT * MAX_DIST_INVISIBLE_UNIT) ;
}
//If variable RATE_STEALTH in config == 0 we do not use the old detection, easier to stealth arround
if (sWorld.getRate(RATE_STEALTH)==0) //student1
IsVisible = false; // remains visible student1
else {
// Function for detection (can be improved)
// Take into account that this function is executed every x secs, so prob must be low for right working
if (x<0) x = 0;
float AverageDist = 1 - 0.11016949*x + 0.00301637*x*x; //at this distance, the detector has to be a 15% prob of detect
if (AverageDist < 1) AverageDist = 1;
if (Distance > AverageDist)
//prob between 10% and 0%
prob = (AverageDist-200+9*Distance)/(AverageDist-20);
else
prob = 75 - (60/AverageDist)*Distance; //prob between 15% and 75% (75% max prob)
if (notInFront)
prob = prob/100;
if (prob < 0.1)
prob = 0.1; //min prob of detect is 0.1
if (rand_chance() > prob)
IsVisible = false;
else
IsVisible = true;
}
return IsVisible && ( Distance <= MAX_DIST_INVISIBLE_UNIT * MAX_DIST_INVISIBLE_UNIT) ;
}
Code:
float WorldObject::GetDistanceSq(const WorldObject* obj) const
{
float dx = GetPositionX() - obj->GetPositionX();
float dy = GetPositionY() - obj->GetPositionY();
float dz = GetPositionZ() - obj->GetPositionZ();
float sizefactor = GetObjectSize() + obj->GetObjectSize() - 2.28; //size factor is too big student1
if (sizefactor <= 0) sizefactor = 1; //makes sures values are not negative for too little objects student1
float dist = sqrt((dx*dx) + (dy*dy) + (dz*dz)) - sizefactor;
return ( dist > 0 ? dist * dist : 0);
}
Added the fallowing variable in world.cpp in under void World::SetInitialWorldSettings() (under the raterate section)
Code:
//Added mangos.ini rate_stealth, this variable controls probability of stealth detection
rate_values[RATE_STEALTH] = sConfig.GetFloatDefault("RATE_STEALTH", 1);
Code:
//Stealth prob initialisation
RATE_STEALTH,
Well these are the main changes, let me know if you want the cpp, ?h and ini files i ll make them availble easier than edtting the whle thing by hand.
Well let me know what you guys think, be back later.