not sure what have i done

while reading pbmm sources :)
This commit is contained in:
jeefo 2014-08-05 21:04:43 +04:00
commit 5e73326033
8 changed files with 206 additions and 130 deletions

View file

@ -55,7 +55,10 @@ extern int g_mapType;
extern int g_numWaypoints; extern int g_numWaypoints;
extern int g_gameVersion; extern int g_gameVersion;
extern int g_fakeArgc; extern int g_fakeArgc;
extern int g_killHistory;
extern int g_highestDamageCT;
extern int g_highestDamageT;
extern int g_highestKills;
extern int g_normalWeaponPrefs[NUM_WEAPONS]; extern int g_normalWeaponPrefs[NUM_WEAPONS];
extern int g_rusherWeaponPrefs[NUM_WEAPONS]; extern int g_rusherWeaponPrefs[NUM_WEAPONS];

View file

@ -26,7 +26,7 @@
#include <../include/resource.h> #include <../include/resource.h>
// generated by update tool -- do not edit -- // generated by update tool -- do not edit --
#define PRODUCT_BUILD_TOOL 3846 #define PRODUCT_BUILD_TOOL 3850
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION PRODUCT_VERSION_DWORD, PRODUCT_BUILD_TOOL FILEVERSION PRODUCT_VERSION_DWORD, PRODUCT_BUILD_TOOL

View file

@ -2982,7 +2982,7 @@ void Bot::ChooseAimDirection (void)
TraceLine (pev->origin, dest, true, GetEntity (), &tr); TraceLine (pev->origin, dest, true, GetEntity (), &tr);
if (tr.flFraction > 0.8 || tr.pHit != g_worldEdict) if (tr.flFraction > 0.8 || tr.pHit != g_worldEdict)
m_lookAt = dest; m_lookAt = dest + pev->view_ofs;
} }
} }
else else
@ -2993,7 +2993,7 @@ void Bot::ChooseAimDirection (void)
TraceLine (pev->origin, dest, true, GetEntity (), &tr); TraceLine (pev->origin, dest, true, GetEntity (), &tr);
if (tr.flFraction > 0.8 || tr.pHit != g_worldEdict) if (tr.flFraction > 0.8 || tr.pHit != g_worldEdict)
m_lookAt = dest; m_lookAt = dest + pev->view_ofs;
} }
} }
} }
@ -5656,6 +5656,7 @@ void Bot::TakeDamage (edict_t *inflictor, int damage, int armor, int bits)
m_actualReactionTime = 0.0; m_actualReactionTime = 0.0;
m_seeEnemyTime = GetWorldTime(); m_seeEnemyTime = GetWorldTime();
m_enemy = inflictor; m_enemy = inflictor;
m_lastEnemy = m_enemy; m_lastEnemy = m_enemy;
m_lastEnemyOrigin = m_enemy->v.origin; m_lastEnemyOrigin = m_enemy->v.origin;
m_enemyOrigin = m_enemy->v.origin; m_enemyOrigin = m_enemy->v.origin;
@ -5691,6 +5692,8 @@ void Bot::TakeDamage (edict_t *inflictor, int damage, int armor, int bits)
// FIXME - Bot doesn't necessary sees this enemy // FIXME - Bot doesn't necessary sees this enemy
m_seeEnemyTime = GetWorldTime (); m_seeEnemyTime = GetWorldTime ();
} }
if (yb_csdm_mode.GetInt () == 0)
CollectExperienceData (inflictor, armor + damage); CollectExperienceData (inflictor, armor + damage);
} }
} }
@ -5801,7 +5804,7 @@ void Bot::CollectExperienceData (edict_t *attacker, int damage)
int attackerTeam = GetTeam (attacker); int attackerTeam = GetTeam (attacker);
int victimTeam = GetTeam (GetEntity ()); int victimTeam = GetTeam (GetEntity ());
if (attackerTeam == victimTeam) if (attackerTeam == victimTeam )
return; return;
// if these are bots also remember damage to rank destination of the bot // if these are bots also remember damage to rank destination of the bot
@ -5841,6 +5844,9 @@ void Bot::CollectExperienceData (edict_t *attacker, int damage)
if (value > MAX_DAMAGE_VALUE) if (value > MAX_DAMAGE_VALUE)
value = MAX_DAMAGE_VALUE; value = MAX_DAMAGE_VALUE;
if (value > g_highestDamageT)
g_highestDamageT = value;
(g_experienceData + (victimIndex * g_numWaypoints) + attackerIndex)->team0Damage = static_cast <unsigned short> (value); (g_experienceData + (victimIndex * g_numWaypoints) + attackerIndex)->team0Damage = static_cast <unsigned short> (value);
} }
else else
@ -5851,6 +5857,9 @@ void Bot::CollectExperienceData (edict_t *attacker, int damage)
if (value > MAX_DAMAGE_VALUE) if (value > MAX_DAMAGE_VALUE)
value = MAX_DAMAGE_VALUE; value = MAX_DAMAGE_VALUE;
if (value > g_highestDamageCT)
g_highestDamageCT = value;
(g_experienceData + (victimIndex * g_numWaypoints) + attackerIndex)->team1Damage = static_cast <unsigned short> (value); (g_experienceData + (victimIndex * g_numWaypoints) + attackerIndex)->team1Damage = static_cast <unsigned short> (value);
} }
} }

View file

@ -953,7 +953,7 @@ int BotManager::GetHumansJoinedTeam (void)
{ {
Client *cl = &g_clients[i]; Client *cl = &g_clients[i];
if ((cl->flags & (CF_USED | CF_ALIVE)) && m_bots[i] == NULL && cl->team != TEAM_SPEC && !(cl->ent->v.flags & FL_FAKECLIENT)) if ((cl->flags & (CF_USED | CF_ALIVE)) && m_bots[i] == NULL && cl->team != TEAM_SPEC && !(cl->ent->v.flags & FL_FAKECLIENT) && cl->ent->v.movetype != MOVETYPE_FLY)
count++; count++;
} }
return count; return count;

View file

@ -57,7 +57,10 @@ int g_fakeArgc = 0;
int g_gameVersion = CSV_STEAM; int g_gameVersion = CSV_STEAM;
int g_numWaypoints = 0; int g_numWaypoints = 0;
int g_mapType = 0; int g_mapType = 0;
int g_killHistory = 0;
int g_highestDamageCT = 1;
int g_highestDamageT = 1;
int g_highestKills = 1;
short g_modelIndexLaser = 0; short g_modelIndexLaser = 0;
short g_modelIndexArrow = 0; short g_modelIndexArrow = 0;

View file

@ -1029,131 +1029,161 @@ void PriorityQueue::HeapSiftUp (void)
} }
} }
float gfunctionKillsDistT (int thisIndex, int parent, int skillOffset)
int gfunctionKillsDistT (int currentIndex, int parentIndex)
{ {
// least kills and number of nodes to goal for a team // least kills and number of nodes to goal for a team
float cost = (g_experienceData + (thisIndex * g_numWaypoints) + thisIndex)->team0Damage + g_killHistory; int cost = (g_experienceData + (currentIndex * g_numWaypoints) + currentIndex)->team0Damage + g_highestDamageT;
Path *current = g_waypoint->GetPath (currentIndex);
Path *parent = g_waypoint->GetPath (parentIndex);
for (int i = 0; i < MAX_PATH_INDEX; i++) for (int i = 0; i < MAX_PATH_INDEX; i++)
{ {
int neighbour = g_waypoint->GetPath (thisIndex)->index[i]; int neighbour = current->index[i];
if (neighbour != -1) if (neighbour != -1)
cost += (g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team0Damage; cost += (g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team0Damage * 0.3;
} }
float pathDistance = static_cast <float> (g_waypoint->GetPathDistance (parent, thisIndex));
if (g_waypoint->GetPath (thisIndex)->flags & FLAG_CROUCH) if (current->flags & FLAG_CROUCH)
cost += pathDistance * 2; cost *= 2;
return pathDistance + (cost * (yb_danger_factor.GetFloat () * 2 / skillOffset)); if (parentIndex < 0 || parentIndex > g_numWaypoints || parentIndex == currentIndex)
return cost * ((yb_danger_factor.GetInt () * 20 / (2 * g_highestDamageT)));
return g_waypoint->GetPathDistance (parentIndex, currentIndex) + (cost * 10 * yb_danger_factor.GetInt ());
} }
float gfunctionKillsT (int thisIndex, int parent, int skillOffset)
{
// least kills to goal for a team
float cost = (g_experienceData + (thisIndex * g_numWaypoints) + thisIndex)->team0Damage; int gfunctionKillsDistCT (int currentIndex, int parentIndex)
for (int i = 0; i < MAX_PATH_INDEX; i++)
{
int neighbour = g_waypoint->GetPath (thisIndex)->index[i];
if (neighbour != -1)
cost += (g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team0Damage;
}
float pathDistance = static_cast <float> (g_waypoint->GetPathDistance (parent, thisIndex));
if (g_waypoint->GetPath (thisIndex)->flags & FLAG_CROUCH)
cost += pathDistance * 3;
return pathDistance + (cost * (yb_danger_factor.GetFloat () * 2 / skillOffset));
}
float gfunctionKillsDistCT (int thisIndex, int parent, int skillOffset)
{ {
// least kills and number of nodes to goal for a team // least kills and number of nodes to goal for a team
float cost = (g_experienceData + (thisIndex * g_numWaypoints) + thisIndex)->team1Damage + g_killHistory; int cost = (g_experienceData + (currentIndex * g_numWaypoints) + currentIndex)->team1Damage + g_highestDamageCT;
Path *current = g_waypoint->GetPath (currentIndex);
Path *parent = g_waypoint->GetPath (parentIndex);
for (int i = 0; i < MAX_PATH_INDEX; i++) for (int i = 0; i < MAX_PATH_INDEX; i++)
{ {
int neighbour = g_waypoint->GetPath (thisIndex)->index[i]; int neighbour = current->index[i];
if (neighbour != -1) if (neighbour != -1)
cost += (g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team1Damage; cost += static_cast <int> ((g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team1Damage * 0.3);
} }
float pathDistance = static_cast <float> (g_waypoint->GetPathDistance (parent, thisIndex));
if (g_waypoint->GetPath (thisIndex)->flags & FLAG_CROUCH) if (current->flags & FLAG_CROUCH)
cost += pathDistance * 2; cost *= 2;
return pathDistance + (cost * (yb_danger_factor.GetFloat () * 2 / skillOffset)); if (parentIndex < 0 || parentIndex > g_numWaypoints || parentIndex == currentIndex)
return cost * ((yb_danger_factor.GetInt () * 20 / (2 * g_highestDamageCT)));
return g_waypoint->GetPathDistance (parentIndex, currentIndex) + (cost * 10 * yb_danger_factor.GetInt ());
} }
float gfunctionKillsCT (int thisIndex, int parent, int skillOffset) int gfunctionKillsDistCTWithHostage (int currentIndex, int parentIndex)
{
// least kills and number of nodes to goal for a team
Path *current = g_waypoint->GetPath (currentIndex);
if (current->flags & FLAG_NOHOSTAGE)
return 65536;
else if (current->flags & (FLAG_CROUCH | FLAG_LADDER))
return gfunctionKillsDistCT (currentIndex, parentIndex) * 500;
return gfunctionKillsDistCT (currentIndex, parentIndex);
}
int gfunctionKillsT (int currentIndex, int parentIndex)
{ {
// least kills to goal for a team // least kills to goal for a team
float cost = (g_experienceData + (thisIndex * g_numWaypoints) + thisIndex)->team1Damage; int cost = (g_experienceData + (currentIndex * g_numWaypoints) + currentIndex)->team0Damage;
Path *current = g_waypoint->GetPath (currentIndex);
for (int i = 0; i < MAX_PATH_INDEX; i++) for (int i = 0; i < MAX_PATH_INDEX; i++)
{ {
int neighbour = g_waypoint->GetPath (thisIndex)->index[i]; int neighbour = current->index[i];
if (neighbour != -1) if (neighbour != -1)
cost += (g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team1Damage; cost += (g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team0Damage * 0.3;
} }
float pathDistance = static_cast <float> (g_waypoint->GetPathDistance (parent, thisIndex));
if (g_waypoint->GetPath (thisIndex)->flags & FLAG_CROUCH) if (current->flags & FLAG_CROUCH)
cost += pathDistance * 3; cost *= 2;
return pathDistance + (cost * (yb_danger_factor.GetFloat () * 2 / skillOffset)); return cost * 10 * yb_danger_factor.GetInt ();
} }
float gfunctionKillsDistCTNoHostage (int thisIndex, int parent, int skillOffset) int gfunctionKillsCT (int currentIndex, int parentIndex)
{ {
if (g_waypoint->GetPath (thisIndex)->flags & FLAG_NOHOSTAGE) // least kills to goal for a team
return 65355;
else if (g_waypoint->GetPath (thisIndex)->flags & (FLAG_CROUCH | FLAG_LADDER))
return gfunctionKillsDistCT (thisIndex, parent, skillOffset) * 500;
return gfunctionKillsDistCT (thisIndex, parent, skillOffset); int cost = (g_experienceData + (currentIndex * g_numWaypoints) + currentIndex)->team1Damage;
Path *current = g_waypoint->GetPath (currentIndex);
for (int i = 0; i < MAX_PATH_INDEX; i++)
{
int neighbour = current->index[i];
if (neighbour != -1)
cost += (g_experienceData + (neighbour * g_numWaypoints) + neighbour)->team1Damage * 0.3;
}
if (current->flags & FLAG_CROUCH)
cost *= 2;
return cost * 10 * yb_danger_factor.GetInt ();
} }
float gfunctionKillsCTNoHostage (int thisIndex, int parent, int skillOffset) int gfunctionKillsCTWithHostage (int currentIndex, int parentIndex)
{ {
if (g_waypoint->GetPath (thisIndex)->flags & FLAG_NOHOSTAGE) // least kills to goal for a team
return 65355;
else if (g_waypoint->GetPath (thisIndex)->flags & (FLAG_CROUCH | FLAG_LADDER))
return gfunctionKillsCT (thisIndex, parent, skillOffset) * 500;
return gfunctionKillsCT (thisIndex, parent, skillOffset); Path *current = g_waypoint->GetPath (currentIndex);
if (current->flags & FLAG_NOHOSTAGE)
return 65536;
else if (current->flags & (FLAG_CROUCH | FLAG_LADDER))
return gfunctionKillsDistCT (currentIndex, parentIndex) * 500;
return gfunctionKillsCT (currentIndex, parentIndex);
} }
float hfunctionPathDist (int startIndex, int goalIndex, int) int hfunctionSquareDist (int startIndex, int goalIndex)
{ {
// using square heuristic // square distance heuristic
Path *goal = g_waypoint->GetPath (goalIndex);
Path *start = g_waypoint->GetPath (startIndex); Path *start = g_waypoint->GetPath (startIndex);
Path *goal = g_waypoint->GetPath (goalIndex);
float deltaX = fabsf (goal->origin.x - start->origin.x); float deltaX = fabsf (goal->origin.x - start->origin.x);
float deltaY = fabsf (goal->origin.y - start->origin.y); float deltaY = fabsf (goal->origin.y - start->origin.y);
float deltaZ = fabsf (goal->origin.z - start->origin.z); float deltaZ = fabsf (goal->origin.z - start->origin.z);
return deltaX + deltaY + deltaZ; return static_cast <int> (deltaX + deltaY + deltaZ);
} }
float hfunctionNumberNodes (int startIndex, int goalIndex, int unused) int hfunctionSquareDistWithHostage (int startIndex, int goalIndex)
{ {
return hfunctionPathDist (startIndex, goalIndex, unused) / 128 * g_killHistory; // square distance heuristic with hostages
if (g_waypoint->GetPath (startIndex)->flags & FLAG_NOHOSTAGE)
return 65536;
return hfunctionSquareDist (startIndex, goalIndex);
} }
float hfunctionNone (int startIndex, int goalIndex, int unused) int hfunctionNone (int startIndex, int goalIndex)
{ {
return hfunctionPathDist (startIndex, goalIndex, unused) / (128 * 100); return hfunctionSquareDist (startIndex, goalIndex) / (128 * 10);
} }
void Bot::FindPath (int srcIndex, int destIndex, unsigned char pathType) void Bot::FindPath (int srcIndex, int destIndex, unsigned char pathType)
@ -1182,10 +1212,9 @@ void Bot::FindPath (int srcIndex, int destIndex, unsigned char pathType)
struct AStar_t struct AStar_t
{ {
double g; int g;
double f; int f;
short parentIndex; short parentIndex;
AStarState_t state; AStarState_t state;
} astar[MAX_WAYPOINTS]; } astar[MAX_WAYPOINTS];
@ -1199,52 +1228,64 @@ void Bot::FindPath (int srcIndex, int destIndex, unsigned char pathType)
astar[i].state = NEW; astar[i].state = NEW;
} }
float (*gcalc) (int, int, int) = NULL; int (*gcalc) (int, int) = NULL;
float (*hcalc) (int, int, int) = NULL; int (*hcalc) (int, int) = NULL;
int skillOffset = 1; switch (pathType)
{
if (pathType == 0) case 0:
if ((g_mapType & MAP_CS) && HasHostage ())
{ {
if (GetTeam (GetEntity ()) == TEAM_TF)
gcalc = hfunctionNone; gcalc = hfunctionNone;
else if (HasHostage ()) hcalc = hfunctionSquareDistWithHostage;
gcalc = hfunctionNone;
else
gcalc = hfunctionNone;
hcalc = hfunctionNumberNodes;
skillOffset = m_skill / 25;
} }
else if (pathType == 1) else
{ {
gcalc = hfunctionNone;
hcalc = hfunctionSquareDist;
}
break;
case 1:
if (GetTeam (GetEntity ()) == TEAM_TF) if (GetTeam (GetEntity ()) == TEAM_TF)
{
gcalc = gfunctionKillsDistT; gcalc = gfunctionKillsDistT;
else if (HasHostage ()) hcalc = hfunctionSquareDist;
gcalc = gfunctionKillsDistCTNoHostage;
else
gcalc = gfunctionKillsDistCT;
hcalc = hfunctionNumberNodes;
skillOffset = m_skill / 25;
} }
else if (pathType == 2) else if ((g_mapType & MAP_CS) && HasHostage ())
{ {
if (GetTeam (GetEntity ()) == TEAM_TF) gcalc = gfunctionKillsDistCTWithHostage;
gcalc = gfunctionKillsT; hcalc = hfunctionSquareDistWithHostage;
else if (HasHostage ())
gcalc = gfunctionKillsCTNoHostage;
else
gcalc = gfunctionKillsCT;
hcalc = hfunctionNone;
skillOffset = m_skill / 20;
} }
else
{
gcalc = gfunctionKillsDistCT;
hcalc = hfunctionSquareDist;
}
break;
case 2:
if (GetTeam (GetEntity ()) == TEAM_TF)
{
gcalc = gfunctionKillsT;
hcalc = hfunctionNone;
}
else if ((g_mapType & MAP_CS) && HasHostage ())
{
gcalc = gfunctionKillsDistCTWithHostage;
hcalc = hfunctionNone;
}
else
{
gcalc = gfunctionKillsCT;
hcalc = hfunctionNone;
}
break;
}
// put start node into open list // put start node into open list
astar[srcIndex].g = gcalc (srcIndex, -1, skillOffset); astar[srcIndex].g = gcalc (srcIndex, -1);
astar[srcIndex].f = astar[srcIndex].g + hcalc (srcIndex, destIndex, skillOffset); astar[srcIndex].f = astar[srcIndex].g + hcalc (srcIndex, destIndex);
astar[srcIndex].state = OPEN; astar[srcIndex].state = OPEN;
openList.Insert (srcIndex, astar[srcIndex].g); openList.Insert (srcIndex, astar[srcIndex].g);
@ -1285,26 +1326,26 @@ void Bot::FindPath (int srcIndex, int destIndex, unsigned char pathType)
// now expand the current node // now expand the current node
for (int i = 0; i < MAX_PATH_INDEX; i++) for (int i = 0; i < MAX_PATH_INDEX; i++)
{ {
int iCurChild = g_waypoint->GetPath (currentIndex)->index[i]; int currentChild = g_waypoint->GetPath (currentIndex)->index[i];
if (iCurChild == -1) if (currentChild == -1)
continue; continue;
// calculate the F value as F = G + H // calculate the F value as F = G + H
float g = astar[currentIndex].g + gcalc (iCurChild, currentIndex, skillOffset); int g = astar[currentIndex].g + gcalc (currentChild, currentIndex);
float h = hcalc (srcIndex, destIndex, skillOffset); int h = hcalc (srcIndex, destIndex);
float f = g + h; int f = g + h;
if ((astar[iCurChild].state == NEW) || (astar[iCurChild].f > f)) if (astar[currentChild].state == NEW || astar[currentChild].f > f)
{ {
// put the current child into open list // put the current child into open list
astar[iCurChild].parentIndex = currentIndex; astar[currentChild].parentIndex = currentIndex;
astar[iCurChild].state = OPEN; astar[currentChild].state = OPEN;
astar[iCurChild].g = g; astar[currentChild].g = g;
astar[iCurChild].f = f; astar[currentChild].f = f;
openList.Insert (iCurChild, g); openList.Insert (currentChild, g);
} }
} }
} }
@ -1656,7 +1697,7 @@ int Bot::FindDefendWaypoint (Vector origin)
else else
experience = exp->team1Damage; experience = exp->team1Damage;
experience = (experience * 100) / MAX_DAMAGE_VALUE; experience = (experience * 100) / (GetTeam (GetEntity ()) == TEAM_TF ? g_highestDamageT : g_highestDamageCT);
minDistance[i] = (experience * 100) / 8192; minDistance[i] = (experience * 100) / 8192;
minDistance[i] += experience; minDistance[i] += experience;
} }
@ -1910,28 +1951,25 @@ bool Bot::HeadTowardWaypoint (void)
int kills = 0; int kills = 0;
if (GetTeam (GetEntity ()) == TEAM_TF) if (GetTeam (GetEntity ()) == TEAM_TF)
kills = (g_experienceData + (waypoint * g_numWaypoints) + waypoint)->team0Damage; kills = (g_experienceData + (waypoint * g_numWaypoints) + waypoint)->team0Damage / g_highestDamageT;
else else
kills = (g_experienceData + (waypoint * g_numWaypoints) + waypoint)->team1Damage; kills = (g_experienceData + (waypoint * g_numWaypoints) + waypoint)->team1Damage / g_highestDamageCT;
// if damage done higher than one // if damage done higher than one
if (kills > 1 && g_timeRoundMid > GetWorldTime () && g_killHistory > 0) if (kills > 0.15f && g_timeRoundMid > GetWorldTime ())
{ {
kills = (kills * 100) / g_killHistory;
kills /= 100;
switch (m_personality) switch (m_personality)
{ {
case PERSONALITY_NORMAL: case PERSONALITY_NORMAL:
kills /= 2; kills *= 0.33f;
break; break;
default: default:
kills /= 1.2; kills *= 0.5f;
break; break;
} }
if (m_baseAgressionLevel < static_cast <float> (kills) && (m_skill < 98 || GetTeam (GetEntity ()) == TEAM_CF)) if (m_baseAgressionLevel < static_cast <float> (kills) && GetTaskId () != TASK_MOVETOPOSITION && HasPrimaryWeapon ())
{ {
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + (m_fearLevel * (g_timeRoundMid - GetWorldTime ()) * 0.5), true); // push camp task on to stack StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + (m_fearLevel * (g_timeRoundMid - GetWorldTime ()) * 0.5), true); // push camp task on to stack

View file

@ -637,7 +637,7 @@ void UpdateGlobalExperienceData (void)
// this function called after each end of the round to update knowledge about most dangerous waypoints for each team. // this function called after each end of the round to update knowledge about most dangerous waypoints for each team.
// no waypoints, no experience used or waypoints edited or being edited? // no waypoints, no experience used or waypoints edited or being edited?
if ((g_numWaypoints < 1) || g_waypointsChanged) if (g_numWaypoints < 1 || g_waypointsChanged)
return; // no action return; // no action
unsigned short maxDamage; // maximum damage unsigned short maxDamage; // maximum damage
@ -726,16 +726,30 @@ void UpdateGlobalExperienceData (void)
} }
} }
} }
g_killHistory++; g_highestKills++;
if (g_killHistory == MAX_KILL_HISTORY) int clip = g_highestDamageT - static_cast <int> (MAX_DAMAGE_VALUE * 0.5);
if (clip < 1)
clip = 1;
g_highestDamageT = clip;
clip = (int) g_highestDamageCT - static_cast <int> (MAX_DAMAGE_VALUE * 0.5);
if (clip < 1)
clip = 1;
g_highestDamageCT = clip;
if (g_highestKills == MAX_KILL_HISTORY)
{ {
for (int i = 0; i < g_numWaypoints; i++) for (int i = 0; i < g_numWaypoints; i++)
{ {
(g_experienceData + (i * g_numWaypoints) + i)->team0Damage /= static_cast <unsigned short> (GetMaxClients () * 0.5); (g_experienceData + (i * g_numWaypoints) + i)->team0Damage /= static_cast <unsigned short> (GetMaxClients () * 0.5);
(g_experienceData + (i * g_numWaypoints) + i)->team1Damage /= static_cast <unsigned short> (GetMaxClients () * 0.5); (g_experienceData + (i * g_numWaypoints) + i)->team1Damage /= static_cast <unsigned short> (GetMaxClients () * 0.5);
} }
g_killHistory = 1; g_highestKills = 1;
} }
} }

View file

@ -897,6 +897,9 @@ void Waypoint::InitExperienceTab (void)
g_experienceData = new Experience[g_numWaypoints * g_numWaypoints]; g_experienceData = new Experience[g_numWaypoints * g_numWaypoints];
g_highestDamageCT = 1;
g_highestDamageT = 1;
// initialize table by hand to correct values, and NOT zero it out // initialize table by hand to correct values, and NOT zero it out
for (i = 0; i < g_numWaypoints; i++) for (i = 0; i < g_numWaypoints; i++)
{ {
@ -934,6 +937,12 @@ void Waypoint::InitExperienceTab (void)
{ {
(g_experienceData + (i * g_numWaypoints) + j)->team0Damage = (unsigned short) ((experienceLoad + (i * g_numWaypoints) + j)->team0Damage); (g_experienceData + (i * g_numWaypoints) + j)->team0Damage = (unsigned short) ((experienceLoad + (i * g_numWaypoints) + j)->team0Damage);
(g_experienceData + (i * g_numWaypoints) + j)->team1Damage = (unsigned short) ((experienceLoad + (i * g_numWaypoints) + j)->team1Damage); (g_experienceData + (i * g_numWaypoints) + j)->team1Damage = (unsigned short) ((experienceLoad + (i * g_numWaypoints) + j)->team1Damage);
if ((g_experienceData + (i * g_numWaypoints) + j)->team0Damage > g_highestDamageT)
g_highestDamageT = (g_experienceData + (i * g_numWaypoints) + j)->team0Damage;
if ((g_experienceData + (i * g_numWaypoints) + j)->team1Damage > g_highestDamageCT)
g_highestDamageCT = (g_experienceData + (i * g_numWaypoints) + j)->team1Damage;
} }
else else
{ {
@ -1168,7 +1177,7 @@ bool Waypoint::Load (void)
InitTypes (); InitTypes ();
g_waypointsChanged = false; g_waypointsChanged = false;
g_killHistory = 0; g_highestKills = 1;
m_pathDisplayTime = 0.0; m_pathDisplayTime = 0.0;
m_arrowDisplayTime = 0.0; m_arrowDisplayTime = 0.0;
@ -1244,7 +1253,7 @@ bool Waypoint::Reachable (Bot *bot, int index)
{ {
// this function return wether bot able to reach index waypoint or not, depending on several factors. // this function return wether bot able to reach index waypoint or not, depending on several factors.
if (index < 0 || index >= g_numWaypoints) if (bot == NULL || index < 0 || index >= g_numWaypoints)
return false; return false;
Vector src = bot->pev->origin; Vector src = bot->pev->origin;