ef2gamesource/dlls/game/playerheuristics.cpp
Walter Julius Hennecke 5bbf27cabd Initial code commit ...
2012-12-30 17:37:54 +01:00

592 lines
13 KiB
C++

//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/playerheuristics.cpp $
// $Revision:: 14 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
#include "_pch_cpp.h"
#include "playerheuristics.h"
static fileHandle_t heuristicFile=NULL;
static str heuristicFileName=NULL;
PlayerHeuristics::PlayerHeuristics()
{
//Single Player Stats
shotsFired = 0;
shotsHit = 0;
numberOfDeaths = 0;
enemiesKilled = 0;
timeOnLevel = 0;
levelStartTime = 0;
levelEndTime = 0;
playerHealth = 0.0f;
lastLevel = "";
currentLevel = "";
shotsFiredInLevel = 0;
shotsHitInLevel = 0;
enemiesKilledInLevel = 0;
//Multiplayer Stats
ping = 0;
itemsPickedUp = 0;
specialEvents = 0;
//Skill Level
skillLevel = 0;
//Mission Objectives
numObjectives = 0;
numCompleteObjectives = 0;
numFailedObjectives = 0;
}
PlayerHeuristics::PlayerHeuristics( const PlayerHeuristics &pHeuristic )
{
//Single Player Stats
shotsFired = pHeuristic.shotsFired;
shotsHit = pHeuristic.shotsHit;
numberOfDeaths = pHeuristic.numberOfDeaths;
enemiesKilled = pHeuristic.enemiesKilled;
timeOnLevel = pHeuristic.timeOnLevel;
levelStartTime = pHeuristic.levelStartTime;
levelEndTime = pHeuristic.levelEndTime;
playerHealth = pHeuristic.playerHealth;
lastLevel = pHeuristic.lastLevel;
currentLevel = pHeuristic.currentLevel;
shotsFiredInLevel = pHeuristic.shotsFiredInLevel;
shotsHitInLevel = pHeuristic.shotsHitInLevel;
enemiesKilledInLevel = pHeuristic.enemiesKilledInLevel;
teammatesKilledInLevel = pHeuristic.teammatesKilledInLevel;
//Multiplayer Stats
ping = pHeuristic.ping;
itemsPickedUp = pHeuristic.itemsPickedUp;
specialEvents = pHeuristic.specialEvents;
//Skill Level
skillLevel = pHeuristic.skillLevel;
//Mission Objectives
numObjectives = pHeuristic.numObjectives;
numCompleteObjectives = pHeuristic.numCompleteObjectives;
numFailedObjectives = pHeuristic.numFailedObjectives;
}
PlayerHeuristics::~PlayerHeuristics()
{
}
void PlayerHeuristics::ShowHeuristics( const Player *player )
{
//Show Player Information in the console
levelEndTime = level.time;
timeOnLevel+= levelEndTime;
playerHealth = player->health;
ping = player->client->ping;
float accuracy = 0;
if ( shotsFired != 0 )
{
accuracy = (float)shotsHit / (float)shotsFired;
accuracy *= 100.0f;
}
gi.Printf( "\nPlayer Heuristics:\n");
gi.Printf( "Shots Fired: %d\n", shotsFired );
gi.Printf( "Shots Hit: %d\n", shotsHit );
gi.Printf( "Accuracy: %%%.2f\n", accuracy );
gi.Printf( "Number of Deaths: %d\n", numberOfDeaths );
gi.Printf( "Time On Level: %f\n", timeOnLevel );
gi.Printf( "Player Health: %d\n", playerHealth );
gi.Printf( "Ping: %d\n", ping );
gi.Printf( "Items Picked Up: %d\n", itemsPickedUp );
gi.Printf( "Special Events: %d\n", specialEvents );
gi.Printf( "Enemies Killed %d\n", enemiesKilled );
gi.Printf( "\n" );
gi.Printf( "Skill Level: %f\n", CalculateSkillLevel() );
gi.Printf( "\n" );
}
void PlayerHeuristics::SaveHeuristics( const Player *player )
{
str token;
str levelName;
Script script;
qboolean currentHeuristicsWritten;
PlayerHeuristics *pHeuristic;
//Precalculation for stats
levelEndTime = level.time;
timeOnLevel+= levelEndTime;
playerHealth = player->health;
ping = player->client->ping;
skillLevel = CalculateSkillLevel();
script.LoadFile( heuristicFileName );
OpenPlayerHeuristicFile();
if ( !heuristicFile )
{
script.Close();
return;
}
//Save off a copy of our current stats
pHeuristic = new PlayerHeuristics( *this );
currentHeuristicsWritten = false;
while( script.TokenAvailable( true ) )
{
token = script.GetToken(false);
//The reason we saved off our old stats, and are reading through
//is that in order to keep all the stats for all the other levels
//we need to read them all in and write them back out, just replacing
//the information we need for our current level
if ( !Q_stricmp( token.c_str(), "Level:" ) )
{
levelName = script.GetToken(false);
if ( Q_stricmp( levelName.c_str(), level.mapname.c_str() ) ) //Not Equal
{
script.UnGetToken();
ReadInHeuristicData(script, levelName);
}
else
{
//Restore Values
shotsFired = pHeuristic->shotsFired;
shotsHit = pHeuristic->shotsHit;
numberOfDeaths = pHeuristic->numberOfDeaths;
enemiesKilled = pHeuristic->enemiesKilled;
timeOnLevel = pHeuristic->timeOnLevel;
levelStartTime = pHeuristic->levelStartTime;
levelEndTime = pHeuristic->levelEndTime;
playerHealth = pHeuristic->playerHealth;
lastLevel = pHeuristic->lastLevel;
currentLevel = pHeuristic->currentLevel;
//Multiplayer Stats
ping = pHeuristic->ping;
itemsPickedUp = pHeuristic->itemsPickedUp;
specialEvents = pHeuristic->specialEvents;
//Skill Level
skillLevel = pHeuristic->skillLevel;
teammatesKilledInLevel = pHeuristic->teammatesKilledInLevel;
shotsFiredInLevel = pHeuristic->shotsFiredInLevel;
shotsHitInLevel = pHeuristic->shotsFiredInLevel;
numObjectives = pHeuristic->numObjectives;
numCompleteObjectives = pHeuristic->numCompleteObjectives;
numFailedObjectives = pHeuristic->numFailedObjectives;
currentHeuristicsWritten = true;
}
WriteOutHeuristicData(levelName);
}
}
if (!currentHeuristicsWritten)
{
currentHeuristicsWritten = true;
WriteOutHeuristicData(level.mapname);
}
ClosePlayerHeuristicFile();
}
void PlayerHeuristics::LoadHeuristics()
{
str token;
Script script;
CheckForHeuristicFile();
//Clear Heuristic Data Structure;
shotsFired = 0;
shotsHit = 0;
numberOfDeaths = 0;
enemiesKilled = 0;
timeOnLevel = 0;
levelStartTime = 0;
levelEndTime = 0;
playerHealth = 0;
ping = 0;
itemsPickedUp = 0;
specialEvents = 0;
//skillLevel = 0;
script.LoadFile( heuristicFileName );
ReadInHeuristicData(script, level.mapname);
//level.setSkill(skillLevel);
script.Close();
ClosePlayerHeuristicFile();
}
void PlayerHeuristics::ReadInHeuristicData( Script& script, str& levelName )
{
str token;
str precedingToken ;
//Fill Structure from File
while( script.TokenAvailable( true ) )
{
str heuristic;
str endSection;
token = script.GetToken( false );
if ( !Q_stricmp( token.c_str(), levelName.c_str() ) && ( precedingToken == "Level:" ) )
{
endSection = levelName + "_end";
while ( Q_stricmp( token.c_str(), endSection.c_str() ) )
{
token = script.GetToken( false );
if ( !Q_stricmp( token.c_str(), "ShotsFired:" ) )
{
heuristic = script.GetToken(false);
shotsFired = atol(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "ShotsHit:" ) )
{
heuristic = script.GetToken(false);
shotsHit = atol(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "NumberOfDeaths:" ) )
{
heuristic = script.GetToken(false);
numberOfDeaths = atol(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "EnemiesKilled:" ) )
{
heuristic = script.GetToken(false);
enemiesKilled = atol(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "TimeOnLevel:" ) )
{
heuristic = script.GetToken(false);
timeOnLevel = (float)atof(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "PlayerHealth:" ) )
{
heuristic = script.GetToken(false);
playerHealth = atoi(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "Ping:" ) )
{
heuristic = script.GetToken(false);
ping = atoi(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "ItemsPickedUp:" ) )
{
heuristic = script.GetToken(false);
itemsPickedUp = atoi(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "SpecialEvents:" ) )
{
heuristic = script.GetToken(false);
specialEvents = atoi(heuristic.c_str());
}
else if ( !Q_stricmp( token.c_str(), "SkillLevel:" ) )
{
heuristic = script.GetToken(false);
skillLevel = atof(heuristic.c_str());
}
}
return;
}
precedingToken = token ;
}
}
void PlayerHeuristics::WriteOutHeuristicData( const str &levelName )
{
str s;
str stat;
//Build File String
s = "Level: " + levelName + "\n";
stat = va("%l", shotsFired);
s+= "ShotsFired: " + stat + "\n";
stat = va("%l", shotsHit);
s+= "ShotsHit: " + stat + "\n";
stat = va("%l", numberOfDeaths);
s+= "NumberOfDeaths: " + stat + "\n";
stat = va("%l", enemiesKilled);
s+= "EnemiesKilled: " + stat + "\n";
stat = timeOnLevel;
s+= "TimeOnLevel: " + stat + "\n";
stat = playerHealth;
s+= "PlayerHealth: " + stat + "\n";
stat = ping;
s+= "Ping: " + stat + "\n";
stat = itemsPickedUp;
s+= "ItemsPickedUp: " + stat + "\n";
stat = specialEvents;
s+= "SpecialEvents: " + stat + "\n";
stat = skillLevel;
s+= "SkillLevel: " + stat + "\n";
s+= levelName + "_end";
s+= "\n\n";
gi.FS_Write( s, s.length(), heuristicFile );
gi.FS_Flush( heuristicFile );
}
void PlayerHeuristics::CreateInitialHeuristicFile()
{
//Clear Heuristic Data Structure;
shotsFired = 0;
shotsHit = 0;
numberOfDeaths = 0;
enemiesKilled = 0;
timeOnLevel = 0;
levelStartTime = 0;
levelEndTime = 0;
playerHealth = 0;
ping = 0;
itemsPickedUp = 0;
specialEvents = 0;
skillLevel = 0;
OpenPlayerHeuristicFile();
if ( !heuristicFile )
{
return;
}
WriteOutHeuristicData(level.mapname);
ClosePlayerHeuristicFile();
}
void PlayerHeuristics::OpenPlayerHeuristicFile()
{
if ( !heuristicFile )
{
heuristicFile = gi.FS_FOpenFileWrite( heuristicFileName.c_str() );
}
}
void PlayerHeuristics::ClosePlayerHeuristicFile()
{
if ( heuristicFile )
{
gi.FS_FCloseFile( heuristicFile );
heuristicFile = NULL;
}
}
void PlayerHeuristics::CheckForHeuristicFile()
{
str s,filename;
int filesize;
s = "heuristics";
filename = gi.GetArchiveFileName( NULL, s, "log", qtrue );
heuristicFileName = filename.c_str();
filesize = gi.FS_ReadFile( heuristicFileName.c_str(), NULL, true );
if ( filesize <= 0 ) //File Does Not Exsist
CreateInitialHeuristicFile();
}
float PlayerHeuristics::CalculateSkillLevel()
{
// Current Skill Level Formula
// (((Accuracy * 100) * .75 ) + (1 - (Deaths * .25))) / 10
// Returns a floating point number between 0 and 10
// I expect this function to change a lot during the course of development
// That is why it is written so verbosely.
float Accuracy;
float Deaths;
float SkillLevel;
Accuracy = (float)shotsHit / (float)shotsFired;
Deaths = numberOfDeaths;
SkillLevel = (((Accuracy * 100.0f) * .75f ) + (1.0f - (Deaths * .25f))) / 10.0f;
if (SkillLevel < 0.0f )
{
SkillLevel = 0.0f;
}
return SkillLevel;
}
//-----------------------------------------------------
//
// Name: ClearLevelStatistics
// Class: PlayerHeuristics
//
// Description: Clears the variables that are level specific.
//
// Parameters: None
//
// Returns: None
//-----------------------------------------------------
void PlayerHeuristics::ClearLevelStatistics(void)
{
shotsFiredInLevel = 0;
shotsHitInLevel = 0;
enemiesKilledInLevel = 0;
numCompleteObjectives = 0;
numObjectives = 0;
numFailedObjectives = 0;
teammatesKilledInLevel = 0;
}
void PlayerHeuristics::SetShotsFired( long int shots )
{
shotsFired = shots;
}
void PlayerHeuristics::IncrementShotsFired( void )
{
shotsFired++;
shotsFiredInLevel++;
}
void PlayerHeuristics::SetShotsHit( long int shots )
{
shotsHit = shots;
}
void PlayerHeuristics::IncrementShotsHit()
{
shotsHit++;
shotsHitInLevel++;
}
void PlayerHeuristics::SetNumberOfDeaths( long int deaths )
{
numberOfDeaths = deaths;
}
void PlayerHeuristics::IncrementNumberOfDeaths()
{
numberOfDeaths++;
}
void PlayerHeuristics::SetTimeOnLevel( float levelTime )
{
timeOnLevel = levelTime;
}
void PlayerHeuristics::SetPlayerHealth( int health )
{
playerHealth = health;
}
void PlayerHeuristics::SetPing( int ping_value )
{
ping = ping_value;
}
void PlayerHeuristics::SetItemsPickedUp( int items )
{
itemsPickedUp = items;
}
void PlayerHeuristics::IncrementItemsPickedUp()
{
itemsPickedUp++;
}
void PlayerHeuristics::SetSpecialEvents( int specialevent )
{
specialEvents = specialevent;
}
void PlayerHeuristics::IncrementSpecialEvents()
{
specialEvents++;
}
void PlayerHeuristics::UpdateShotsFired( void )
{
IncrementShotsFired();
}
void PlayerHeuristics::SetObjectives(int numMissionObjectives)
{
numObjectives = numMissionObjectives;
}
void PlayerHeuristics::IncrementCompleteObjectives()
{
numCompleteObjectives++;
}
void PlayerHeuristics::IncrementFailedObjectives()
{
numFailedObjectives++;
}
void PlayerHeuristics::IncrementEnemiesKilled(void)
{
enemiesKilled++;
enemiesKilledInLevel++;
}
void PlayerHeuristics::IncrementTeammatesKilled(void)
{
teammatesKilledInLevel++;
}