From ce0bb15446041e982e0924acbb8334a62c7a5373 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Thu, 23 May 2013 00:30:20 +0100
Subject: [PATCH] [Add] First player faction stuff.

---
 dat/faction.xml |  16 ++++----
 src/faction.c   | 104 ++++++++++++++++++++++++++++++++++++++++--------
 src/faction.h   |   2 +
 3 files changed, 98 insertions(+), 24 deletions(-)

diff --git a/dat/faction.xml b/dat/faction.xml
index 883c1b3..94c7f04 100644
--- a/dat/faction.xml
+++ b/dat/faction.xml
@@ -1,18 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Factions>
-  <faction name = "Player">
- </faction>
   <faction name = "Independent">
+    <player>0</player>
   </faction>
   <faction name = "Merchant">
+    <player>0</player>
   </faction>
   <faction name = "Pirate">
+    <player>-20</player>
   </faction>
- <faction name = "Militia">
+  <faction name = "Militia">
+    <player>0</player>
  </faction>
  <faction name = "Empire">
+   <player>0</player>
  </faction>
  <faction name = "Collective">
+   <player>-100</player>
  </faction>
   <Alliances>
     <alliance name = "Neutral">
@@ -32,7 +36,7 @@
   </enemies>
   <enemies>
    <enemy type="faction">Collective</enemy>
-   <enemy type="faction">Player</enemy>
+   <enemy type="alliance">Empire United</enemy>
   </enemies>
   <enemies>
    <enemy type="alliance">Neutral</enemy>
@@ -42,9 +46,5 @@
    <enemy type="alliance">Empire United</enemy>
       <enemy type="faction">Pirate</enemy>
   </enemies>
-  <enemies>
-   <enemy type="faction">Pirate</enemy>
-      <enemy type="faction">Player</enemy>
-    </enemies>
   </Enemies>
 </Factions>
diff --git a/src/faction.c b/src/faction.c
index 6939e32..a45a098 100644
--- a/src/faction.c
+++ b/src/faction.c
@@ -16,6 +16,8 @@
 
 #define FACTION_DATA "../dat/faction.xml"
 
+#define PLAYER_ALLY   70 // Above this, player is considered ally.
+
 #define ALLIANCE_OFFSET 27182 // Special offset for alliances.
 
 typedef struct Faction_ {
@@ -25,6 +27,8 @@ typedef struct Faction_ {
   int   nenemies;
   int*  allies;
   int   nallies;
+
+  int player; // Standing with player - from -100 to 100.
 } Faction;
 
 static Faction* faction_stack = NULL;
@@ -97,6 +101,28 @@ int areEnemies(int a, int b) {
   
   if(a == b) return 0; // Luckily our factions aren't masochistic.
 
+  // Player handled seperately.
+  if(a == FACTION_PLAYER) {
+    if(faction_isFaction(b)) {
+      if(faction_stack[b].player < 0)
+        return 1;
+      else return 0;
+    } else {
+      DEBUG("areEnemies: %d is an invalid faction/alliance", b);
+      return 0;
+    }
+  }
+  if(b == FACTION_PLAYER) {
+    if(faction_isFaction(a)) {
+      if(faction_stack[a].player < 0)
+        return 1;
+      else return 0;
+    } else {
+      DEBUG("areEnemies: %d is an invalid faction/alliance", a);
+      return 0;
+    }
+  }
+
   // Handle a.
   if(faction_isFaction(a)) fa = &faction_stack[a];
   else {
@@ -128,13 +154,37 @@ int areEnemies(int a, int b) {
 // Return 1 if Faction a and b are allies.
 int areAllies(int a, int b) {
   Faction* fa, *fb;
-  int i = 0;
+  int i;
+
+  // We assume player becomes allies with high rating.
+  if(a == FACTION_PLAYER) {
+    if(faction_isFaction(b)) {
+      if(faction_stack[b].player > PLAYER_ALLY) return 1;
+      else return 0;
+    } else {
+      DEBUG("%d is an invalid faction/alliance", b);
+      return 0;
+    }
+  }
+  if(b == FACTION_PLAYER) {
+    if(faction_isFaction(a)) {
+      if(faction_stack[a].player > PLAYER_ALLY) return 1;
+      else return 0;
+    } else {
+      DEBUG("%d is an invalid faction/alliance", a);
+      return 0;
+    }
+  }
+
+  // D'aww. Player has no allies.
+  if((a == FACTION_PLAYER) || (b == FACTION_PLAYER))
+    return 0;
 
   // Handle a.
   if(faction_isFaction(a)) fa = &faction_stack[a];
   else {
     // b isn't valid.
-    DEBUG("areEnemies: %d is an invalid faction/alliance", a);
+    DEBUG("%d is an invalid faction/alliance", a);
     return 0;
   }
 
@@ -142,7 +192,7 @@ int areAllies(int a, int b) {
   if(faction_isFaction(b)) fb = &faction_stack[b];
   else {
     // b isn't valid.
-    DEBUG("areEnemies: %d is an invalid faction/alliance", b);
+    DEBUG("%d is an invalid faction/alliance", b);
     return 0;
   }
 
@@ -202,10 +252,27 @@ int faction_isFaction(int f) {
 
 // Parses a single faction, but does not set the allies/enemies.
 static Faction* faction_parse(xmlNodePtr parent) {
-  Faction* tmp = CALLOC_L(Faction);
+  xmlNodePtr node;
+  int player;
+  Faction* tmp;
+
+  tmp = CALLOC_L(Faction);
+
   tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
   if(tmp->name == NULL)
     WARN("Faction from "FACTION_DATA" has invalid or no name");
+
+  player = 0;
+  node = parent->xmlChildrenNode;
+  do {
+    if(xml_isNode(node, "player")) {
+      tmp->player = xml_getInt(node);
+      player = 1;
+    }
+  } while(xml_nextNode(node));
+
+  if(player == 0) DEBUG("Faction '%s' missing player tag", tmp->name);
+
   return tmp;
 }
 
@@ -351,7 +418,7 @@ int factions_load(void) {
   Faction* tmp = NULL;
 
   node = doc->xmlChildrenNode; // Faction node.
-  if(strcmp((char*)node->name, XML_FACTION_ID)) {
+  if(!xml_isNode(node, XML_FACTION_ID)) {
     ERR("Malformed "FACTION_DATA" file: missing root element '"XML_FACTION_ID"'");
     return -1;
   }
@@ -362,19 +429,24 @@ int factions_load(void) {
     return -1;
   }
 
+  // Player faction is hardcoded.
+  faction_stack = malloc(sizeof(Faction));
+  faction_stack[0].name     = strdup("Player");
+  faction_stack[0].nallies  = 0;
+  faction_stack[0].nenemies = 0;
+  nfactions++;
+
   do {
-    if(node->type == XML_NODE_START) {
-      if(strcmp((char*)node->name, XML_FACTION_TAG)==0) {
-        tmp = faction_parse(node);
-        faction_stack = realloc(faction_stack, sizeof(Faction)*(++nfactions));
-        memcpy(faction_stack+nfactions-1, tmp, sizeof(Faction));
-        free(tmp);
-      }
-      else if(strcmp((char*)node->name, XML_ALLIANCE_ID)==0)
-        alliance_parse(node);
-      else if(strcmp((char*)node->name, XML_ENEMIES_ID)==0)
-        enemies_parse(node);
+    if(xml_isNode(node, XML_FACTION_TAG)) {
+      tmp = faction_parse(node);
+      faction_stack = realloc(faction_stack, sizeof(Faction)*(++nfactions));
+      memcpy(faction_stack + nfactions - 1, tmp, sizeof(Faction));
+      free(tmp);
     }
+    else if(xml_isNode(node, XML_ALLIANCE_ID))
+      alliance_parse(node);
+    else if(xml_isNode(node, XML_ENEMIES_ID))
+      enemies_parse(node);
   } while((node = node->next));
 
   xmlFreeDoc(doc);
diff --git a/src/faction.h b/src/faction.h
index 7496cfe..7ad75d5 100644
--- a/src/faction.h
+++ b/src/faction.h
@@ -1,5 +1,7 @@
 #pragma once
 
+#define FACTION_PLAYER 0
+
 // Get stuff.
 int faction_get(const char* name);
 int faction_getAlliance(char* name);