From 9539e22d8b5b1d58c7b6b54389675151d6b7c9d8 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Tue, 31 Dec 2013 17:38:02 +0000
Subject: [PATCH] [Change] Faction and combat ratings are now continuous.

---
 scripts/ai/tpl/escort.lua |  2 +-
 src/faction.c             | 81 +++++++++++++++++----------------------
 src/faction.h             |  8 ++--
 src/llua_faction.c        |  4 +-
 src/misn_lua.c            | 10 +++--
 src/pilot.c               |  6 +--
 src/player.c              | 24 ++++++------
 src/player.h              |  4 +-
 src/weapon.c              |  4 +-
 9 files changed, 67 insertions(+), 76 deletions(-)

diff --git a/scripts/ai/tpl/escort.lua b/scripts/ai/tpl/escort.lua
index 82f772c..4ac8ab4 100644
--- a/scripts/ai/tpl/escort.lua
+++ b/scripts/ai/tpl/escort.lua
@@ -26,7 +26,7 @@ function escort()
 
   dir = ai.face(target)
   dist = ai.dist(ai.pos(target))
-  bdist = ai.mindbrakedist()
+  bdist = ai.minbrakedist()
 
   -- Close enough.
   if ai.isstopped() and dist < 300 then
diff --git a/src/faction.c b/src/faction.c
index be325c9..c376181 100644
--- a/src/faction.c
+++ b/src/faction.c
@@ -21,7 +21,7 @@
 #define FACTION_DATA        "../dat/faction.xml" /**< Faction xml file. */
 #define FACTION_LOGO_PATH   "../gfx/logo/"       /**< Path to logo gfx. */
 
-#define PLAYER_ALLY   70 /**< Above this, player is considered ally. */
+#define PLAYER_ALLY   70. /**< Above this, player is considered ally. */
 
 /**
  * @struct Faction.
@@ -33,18 +33,18 @@ typedef struct Faction_ {
   char* longname;   /**< Long name. */
 
   /* Graphics. */
-  glTexture* logo_small; /**< Small logo. */
+  glTexture* logo_small;  /**< Small logo. */
 
   /* Enemies. */
-  int*  enemies;    /**< Enemies by ID of the faction. */
-  int   nenemies;   /**< Number of enemies. */
+  int*  enemies;          /**< Enemies by ID of the faction. */
+  int   nenemies;         /**< Number of enemies. */
 
   /* Allies. */
-  int*  allies;     /**< Allies by ID of the faction. */
-  int   nallies;    /**< Number of allies. */
+  int*  allies;           /**< Allies by ID of the faction. */
+  int   nallies;          /**< Number of allies. */
 
-  int player_def;   /**< Default player standing. */
-  int player;       /**< Standing with player - from -100 to 100. */
+  double player_def;      /**< Default player standing. */
+  double player;          /**< Standing with player - from -100 to 100. */
 } Faction;
 
 static Faction* faction_stack = NULL;   /**< Faction stack. */
@@ -136,14 +136,14 @@ glTexture* faction_logoSmall(int f) {
  *    @param faction Faction to sanitize.
  */
 static void faction_sanitizePlayer(Faction* faction) {
-  if(faction->player > 100)
-    faction->player = 100;
-  else if(faction->player < -100)
-    faction->player = -100;
+  if(faction->player > 100.)
+    faction->player = 100.;
+  else if(faction->player < -100.)
+    faction->player = -100.;
 }
 
 /**
- * @fn void faction_modPlayer(int f, int mod)
+ * @fn void faction_modPlayer(int f, double mod)
  *
  * @brief Modifies the players standing with a faction.
  *
@@ -153,7 +153,7 @@ static void faction_sanitizePlayer(Faction* faction) {
  *
  * @sa faction_modPlayerRaw
  */
-void faction_modPlayer(int f, int mod) {
+void faction_modPlayer(int f, double mod) {
   int i;
   Faction* faction, *ally, *enemy;
 
@@ -172,7 +172,7 @@ void faction_modPlayer(int f, int mod) {
   for(i = 0; i < faction->nallies; i++) {
     ally = &faction_stack[faction->allies[i]];
 
-    ally->player += RNG(0, (mod*3)/4);
+    ally->player += RNGF() * (mod*3/4);
     faction_sanitizePlayer(ally);
   }
 
@@ -180,13 +180,13 @@ void faction_modPlayer(int f, int mod) {
   for(i = 0; i < faction->nenemies; i++) {
     enemy = &faction_stack[faction->enemies[i]];
 
-    enemy->player -= MIN(1, RNG(0, (mod*3)/4));
+    enemy->player -= RNGF() * mod; /* Enemies are made faster. */
     faction_sanitizePlayer(enemy);
   }
 }
 
 /**
- * @fn void faction_modPlayerRaw(int f, int mod)
+ * @fn void faction_modPlayerRaw(int f, double mod)
  *
  * @brief Modifies the players standing without affecting others.
  *    @param f Faction whose standing to modify.
@@ -194,7 +194,7 @@ void faction_modPlayer(int f, int mod) {
  *
  * @sa faction_modPlayer
  */
-void faction_modPlayerRaw(int f, int mod) {
+void faction_modPlayerRaw(int f, double mod) {
   Faction* faction;
 
   if(!faction_isFaction(f)) {
@@ -209,13 +209,13 @@ void faction_modPlayerRaw(int f, int mod) {
 }
 
 /**
- * @fn int faction_getPlayer(int f)
+ * @fn double faction_getPlayer(int f)
  *
  * @brief Get the players standing with a faction.
  *    @param f Faction to get standing from.
  *    @return The standing the player has with the faction.
  */
-int faction_getPlayer(int f) {
+double faction_getPlayer(int f) {
   if(faction_isFaction(f)) {
     return faction_stack[f].player;
   } else {
@@ -241,35 +241,24 @@ glColour* faction_getColour(int f) {
 }
 
 /**
- * @fn char* faction_getStanding(int mod)
+ * @fn char* faction_getStanding(double mod)
  *
  * @brief Get the players standing in human readable form.
  *    @param mod Players standing.
  *    @return Human readable players standing.
  */
-static char* player_standings[] = {
-  "Hero",     /* 0 */
-  "Admired",
-  "Great",
-  "Good",
-  "Decent",
-  "Wanted",   /* 5 */
-  "Outlaw",
-  "Criminal",
-  "Enemy"
-};
 
-#define STANDING(m, i) if(mod >= m) return player_standings[i];
-char* faction_getStanding(int mod) {
-  STANDING( 90, 0);
-  STANDING( 70, 1);
-  STANDING( 50, 2);
-  STANDING( 30, 3);
-  STANDING( 0,  4);
-  STANDING(-15, 5);
-  STANDING(-30, 6);
-  STANDING(-50, 7);
-  return player_standings[8];
+#define STANDING(m, s) if(mod >= m) return s;
+char* faction_getStanding(double mod) {
+  STANDING( 90., "Here");
+  STANDING( 70., "Admired");
+  STANDING( 50., "Great");
+  STANDING( 30., "Good");
+  STANDING( 0.,  "Decent");
+  STANDING(-15., "Wanted");
+  STANDING(-30., "Outlaw");
+  STANDING(-50., "Criminal");
+  return "Enemy";
 
 }
 #undef STANDING
@@ -443,7 +432,7 @@ static Faction* faction_parse(xmlNodePtr parent) {
   do {
     /* Can be 0 or negative, so we have to take that into account. */
     if(xml_isNode(node, "player")) {
-      tmp->player_def = xml_getInt(node);
+      tmp->player_def = xml_getFloat(node);
       player = 1;
       continue;
     }
@@ -610,7 +599,7 @@ int pfaction_save(xmlTextWriterPtr writer) {
     xmlw_startElem(writer, "faction");
 
     xmlw_attr(writer, "name", "%s", faction_stack[i].name);
-    xmlw_str(writer, "%d", faction_stack[i].player);
+    xmlw_str(writer, "%f", faction_stack[i].player);
 
     xmlw_endElem(writer); /* Faction. */
   }
@@ -642,7 +631,7 @@ int pfaction_load(xmlNodePtr parent) {
             xmlr_attr(cur, "name", str);
             faction = faction_get(str);
             if(faction != -1) /* Faction is valid. */
-              faction_stack[faction].player = xml_getInt(cur);
+              faction_stack[faction].player = xml_getFloat(cur);
             free(str);
           }
       } while(xml_nextNode(cur));
diff --git a/src/faction.h b/src/faction.h
index 7af5bd9..ec3f874 100644
--- a/src/faction.h
+++ b/src/faction.h
@@ -11,10 +11,10 @@ char* faction_longname(int f);
 glTexture* faction_logoSmall(int f);
 
 /* Player stuff. */
-void faction_modPlayer(int f, int mod);
-void faction_modPlayerRaw(int f, int mod);
-int faction_getPlayer(int f);
-char* faction_getStanding(int mod);
+void faction_modPlayer(int f, double mod);
+void faction_modPlayerRaw(int f, double mod);
+double faction_getPlayer(int f);
+char* faction_getStanding(double mod);
 glColour* faction_getColour(int f);
 
 /* Works with only factions. */
diff --git a/src/llua_faction.c b/src/llua_faction.c
index 8d57dd7..ba4fe4c 100644
--- a/src/llua_faction.c
+++ b/src/llua_faction.c
@@ -302,7 +302,7 @@ static int factionL_areallies(lua_State* L) {
  */
 static int factionL_modplayer(lua_State* L) {
   LuaFaction* f;
-  int n;
+  double n;
   f = lua_tofaction(L, 1);
 
   if(lua_isnumber(L, 2)) n = lua_tonumber(L, 2);
@@ -324,7 +324,7 @@ static int factionL_modplayer(lua_State* L) {
  */
 static int factionL_modplayerraw(lua_State* L) {
   LuaFaction* f;
-  int n;
+  double n;
   f = lua_tofaction(L, 1);
 
   if(lua_isnumber(L, 2)) n = lua_tonumber(L, 2);
diff --git a/src/misn_lua.c b/src/misn_lua.c
index 6661c0b..70ef1b4 100644
--- a/src/misn_lua.c
+++ b/src/misn_lua.c
@@ -782,12 +782,13 @@ static int player_msg(lua_State* L) {
 
 static int player_modFaction(lua_State* L) {
   LLUA_MIN_ARGS(2);
-  int f, mod;
+  int f;
+  double mod;
 
   if(lua_isstring(L, 1)) f = faction_get(lua_tostring(L, 1));
   else LLUA_INVALID_PARAMETER();
 
-  if(lua_isnumber(L, 2)) mod = (int)lua_tonumber(L, 2);
+  if(lua_isnumber(L, 2)) mod = lua_tonumber(L, 2);
   else LLUA_INVALID_PARAMETER();
 
   faction_modPlayer(f, mod);
@@ -797,12 +798,13 @@ static int player_modFaction(lua_State* L) {
 
 static int player_modFactionRaw(lua_State* L) {
   LLUA_MIN_ARGS(2);
-  int f, mod;
+  int f;
+  double mod;
 
   if(lua_isstring(L, 1)) f = faction_get(lua_tostring(L,1));
   else LLUA_INVALID_PARAMETER();
 
-  if(lua_isnumber(L,2)) mod = (int) lua_tonumber(L,2);
+  if(lua_isnumber(L,2)) mod = lua_tonumber(L,2);
   else LLUA_INVALID_PARAMETER();
 
   faction_modPlayerRaw(f, mod);
diff --git a/src/pilot.c b/src/pilot.c
index e218983..d43bc36 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -38,7 +38,7 @@ int pilot_nstack = 0;       /**< Same. */
 static int pilot_mstack = 0; /** Memory allocated for pilot_stack. */
 
 extern Pilot* player;
-extern unsigned int player_crating; /**< Players combat rating. */
+extern double player_crating; /**< Players combat rating. */
 extern void player_abortAutonav(void);
 
 /* Stack of fleets. */
@@ -424,8 +424,8 @@ void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
       /* Adjust the combat rating based on pilot mass and ditto faction. */
       pshooter = pilot_get(shooter);
       if(pshooter->faction == FACTION_PLAYER) {
-        mod = (int)MAX(1, ceil(pow(p->ship->mass, 1./3.))-1.);
-        player_crating += MAX(1, mod);
+        mod = pow(p->ship->mass, 1./3.);
+        player_crating += 2*mod;
         faction_modPlayer(p->faction, -mod);
       }
     }
diff --git a/src/player.c b/src/player.c
index ed38483..2c6cd42 100644
--- a/src/player.c
+++ b/src/player.c
@@ -68,7 +68,7 @@ static int player_nstack    = 0;        /**< Number of ships player has. */
 
 /* Player global properties. */
 char* player_name = NULL;               /**< Player name. */
-int player_crating = 0;                 /**< Player combar rating. */
+double player_crating = 0;              /**< Player combar rating. */
 unsigned int player_flags = 0;          /**< Player flags. */
 
 /* Input.c */
@@ -325,7 +325,7 @@ static void player_newMake(void) {
             xmlr_float(tmp, "y", y);
           } while(xml_nextNode(tmp));
         }
-        xmlr_int(cur, "player_crating", player_crating);
+        xmlr_float(cur, "player_crating", player_crating);
         if(xml_isNode(cur, "date")) {
           tmp = cur->children;
           do {
@@ -698,14 +698,14 @@ static char* player_ratings[] = {
 };
 
 const char* player_rating(void) {
-  if(player_crating == 0)           return player_ratings[0];
-  else if(player_crating < 50)      return player_ratings[1];
-  else if(player_crating < 200)     return player_ratings[2];
-  else if(player_crating < 500)     return player_ratings[3];
-  else if(player_crating < 1000)    return player_ratings[4];
-  else if(player_crating < 2500)    return player_ratings[5];
-  else if(player_crating < 10000)   return player_ratings[6];
-  else                              return player_ratings[7];
+  if(player_crating == 0.)           return player_ratings[0];
+  else if(player_crating < 50.)      return player_ratings[1];
+  else if(player_crating < 200.)     return player_ratings[2];
+  else if(player_crating < 500.)     return player_ratings[3];
+  else if(player_crating < 1000.)    return player_ratings[4];
+  else if(player_crating < 2500.)    return player_ratings[5];
+  else if(player_crating < 10000.)   return player_ratings[6];
+  else                               return player_ratings[7];
 }
 
 /**
@@ -2141,7 +2141,7 @@ int player_save(xmlTextWriterPtr writer) {
   xmlw_startElem(writer, "player");
   xmlw_attr(writer, "name", player_name);
 
-  xmlw_elem(writer, "rating", "%d", player_crating);
+  xmlw_elem(writer, "rating", "%f", player_crating);
   xmlw_elem(writer, "scred", "%d", player->credits);
   xmlw_elem(writer, "time", "%d", ltime_get());
 
@@ -2245,7 +2245,7 @@ static int player_parse(xmlNodePtr parent) {
 
   do {
     /* Global stuff. */
-    xmlr_int(node, "rating", player_crating);
+    xmlr_float(node, "rating", player_crating);
     xmlr_int(node, "credits", player_credits);
     xmlr_long(node, "time", player_time);
     xmlr_str(node, "location", planet);
diff --git a/src/player.h b/src/player.h
index 2315a34..b0c5b99 100644
--- a/src/player.h
+++ b/src/player.h
@@ -22,10 +22,10 @@
 #define player_rmFlag(f)  if(player_isFlag(f)) (player_flags ^= f)  /**< Remove a player flag. */
 
 /* The player. */
-extern Pilot* pilot;                /**< The player. */
+extern Pilot* player;               /**< The player. */
 extern char* player_name;           /**< Player's name. */
 extern unsigned int player_flags;   /**< Player's flags. */
-extern int player_crating;          /**< Player's combat rating. */
+extern double player_crating;       /**< Player's combat rating. */
 
 /* Enums. */
 
diff --git a/src/weapon.c b/src/weapon.c
index 4094a9a..48111fa 100644
--- a/src/weapon.c
+++ b/src/weapon.c
@@ -601,7 +601,7 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer, Vec2* pos) {
       parent = pilot_get(w->parent);
       if((parent->faction == FACTION_PLAYER) &&
           (!pilot_isFlag(p, PILOT_HOSTILE) || (RNGF() < 0.5))) { /* 50% chance. */
-        faction_modPlayer(p->faction, -1); /* Slowly lower faction. */
+        faction_modPlayer(p->faction, -1.); /* Slowly lower faction. */
         pilot_setFlag(p, PILOT_HOSTILE);
       }
       ai_attacked(p, w->parent);
@@ -642,7 +642,7 @@ static void weapon_hitBeam(Weapon* w, Pilot* p, WeaponLayer layer,
       parent = pilot_get(w->parent);
       if((parent->faction == FACTION_PLAYER) &&
           (!pilot_isFlag(p, PILOT_HOSTILE) || (RNGF() < 0.5))) { /* 50% chance. */
-        faction_modPlayer(p->faction, -1); /* Slowly lower faction. */
+        faction_modPlayer(p->faction, -1.); /* Slowly lower faction. */
         pilot_setFlag(p, PILOT_HOSTILE);
       }
       ai_attacked(p, w->parent);