Esempio n. 1
0
/* does end of month actions */
void passmonth(char &clearformess,char canseethings)
{
   short oldlaw[LAWNUM];
   memmove(oldlaw,law,sizeof(short)*LAWNUM);
   int l, v, p;

   //TIME ADVANCE
   day=1;
   month++;
   if(month==13)
   {
      month=1;
      year++;
   }

   switch(endgamestate)
   {
   case ENDGAME_NONE:
      if(publicmood(-1)>60)
      {
         endgamestate=ENDGAME_CCS_APPEARANCE;
         attitude[VIEW_CONSERVATIVECRIMESQUAD]=0;
      }
      break;
   case ENDGAME_CCS_APPEARANCE:
      if(publicmood(-1)>80)
         endgamestate=ENDGAME_CCS_ATTACKS;
      break;
   case ENDGAME_CCS_ATTACKS:
      if(publicmood(-1)>90)
         endgamestate=ENDGAME_CCS_SIEGES;
      break;
   case ENDGAME_CCS_SIEGES:
   case ENDGAME_CCS_DEFEATED:
      //if(publicmood(-1)>85&&presparty!=LIBERAL_PARTY)
      //   endgamestate=ENDGAME_MARTIALLAW;
      break;
   }

   //CLEAR RENT EXEMPTIONS
   for(l=0;l<len(location);l++) location[l]->newrental=0;

   //YOUR PAPER AND PUBLIC OPINION AND STUFF
   vector<int> nploc;
   for(l=0;l<len(location);l++)
   {
      if((location[l]->compound_walls & COMPOUND_PRINTINGPRESS)&&
         !location[l]->siege.siege&&
          location[l]->renting!=RENTING_CCS) nploc.push_back(l);
   }

   // Check for game over
   endcheck(END_DEAD);
   dispersalcheck(clearformess);

   int guardianpower=0;
   if(len(nploc)&&!disbanding)
   {
      //DO SPECIAL EDITIONS
      int loottypeindex=choosespecialedition(clearformess);

      if(loottypeindex!=-1)
      {
         guardianpower+=10*len(nploc);
         printnews(loottypeindex,len(nploc));

         if(loottype[loottypeindex]->get_idname()=="LOOT_INTHQDISK"|| //For special edition xml file? -XML
            loottype[loottypeindex]->get_idname()=="LOOT_SECRETDOCUMENTS")
         {
            for(int l=0;l<len(nploc);l++)
               criminalizepool(LAWFLAG_TREASON,-1,nploc[l]);
         }
      }
   }

   int libpower[VIEWNUM]={0};

   //STORIES STALE EVEN IF NOT PRINTED
   for(v=0;v<VIEWNUM;v++)public_interest[v]/=2;

   int conspower=200-attitude[VIEW_AMRADIO]-attitude[VIEW_CABLENEWS];

   //HAVING SLEEPERS
   for(int pl=len(pool)-1;pl>0;pl--)
      if(pool[pl]->alive&&(pool[pl]->flag & CREATUREFLAG_SLEEPER))
         sleepereffect(*pool[pl],clearformess,canseethings,libpower);

   //Manage graffiti
   for(int l=0;l<len(location);l++) // Check each location
   {
      for(int c=len(location[l]->changes)-1;c>=0;c--) // Each change to the map
      {
         if(location[l]->changes[c].flag==SITEBLOCK_GRAFFITI||
            location[l]->changes[c].flag==SITEBLOCK_GRAFFITI_CCS||
            location[l]->changes[c].flag==SITEBLOCK_GRAFFITI_OTHER) // Find changes that refer specifically to graffiti
         {
            int power=0,align=0;

            if(location[l]->changes[c].flag==SITEBLOCK_GRAFFITI) align=1;
            if(location[l]->changes[c].flag==SITEBLOCK_GRAFFITI_CCS) align=-1;

            //Purge graffiti from more secure sites (or from non-secure
            //sites about once every five years), but these will
            //influence people more for the current month
            if(securityable(location[l]->type))
            {
               location[l]->changes.erase(location[l]->changes.begin()+c);
               power=5;
            }
            else
            {
               if(location[l]->renting==RENTING_CCS)
                  location[l]->changes[c].flag=SITEBLOCK_GRAFFITI_CCS; // Convert to CCS tags
               else if(location[l]->renting==RENTING_PERMANENT)
                  location[l]->changes[c].flag=SITEBLOCK_GRAFFITI; // Convert to LCS tags
               else
               {
                  power=1;
                  if(!LCSrandom(10))
                     location[l]->changes[c].flag=SITEBLOCK_GRAFFITI_OTHER; // Convert to other tags
                  if(!LCSrandom(10)&&endgamestate<ENDGAME_CCS_DEFEATED&&endgamestate>0)
                     location[l]->changes[c].flag=SITEBLOCK_GRAFFITI_CCS; // Convert to CCS tags
                  if(!LCSrandom(30))
                     location[l]->changes.erase(location[l]->changes.begin()+c); // Clean up
               }
            }
            if(align==1)
            {
               background_liberal_influence[VIEW_LIBERALCRIMESQUAD]+=power;
               background_liberal_influence[VIEW_CONSERVATIVECRIMESQUAD]+=power;
            }
            else if(align==-1)
            {
               background_liberal_influence[VIEW_LIBERALCRIMESQUAD]-=power;
               background_liberal_influence[VIEW_CONSERVATIVECRIMESQUAD]-=power;
            }
         }
      }
   }

   int mediabalance=0;
   int issuebalance[VIEWNUM-5];
   //int stimulus=0;
   //double cost=0;
   //double tax=0;

   //PUBLIC OPINION NATURAL MOVES
   for(v=0;v<VIEWNUM;v++)
   {
      // Liberal essays add their power to the effect of sleepers
      libpower[v]+=background_liberal_influence[v];
      background_liberal_influence[v]=static_cast<short>(background_liberal_influence[v]*0.66);

      if(v==VIEW_LIBERALCRIMESQUADPOS) continue;
      if(v==VIEW_LIBERALCRIMESQUAD) continue;
      //if(v==VIEW_POLITICALVIOLENCE)
      //{
      //   change_public_opinion(VIEW_POLITICALVIOLENCE,-1,0);
      //   continue;
      //}
      if(v==VIEW_CONSERVATIVECRIMESQUAD) continue;
      if(v!=VIEW_AMRADIO&&v!=VIEW_CABLENEWS)
      {
         issuebalance[v] = libpower[v] - conspower;
         mediabalance += issuebalance[v];

         // Heavy randomization -- balance of power just biases the roll
         int roll = issuebalance[v] + LCSrandom(400)-200;

         // If +/-50 to either side, that side wins the tug-of-war
         if(roll < -50)
            change_public_opinion(v,-1,0);
         else if(roll > 50)
            change_public_opinion(v,1,0);
         else // Else random movement
            change_public_opinion(v,LCSrandom(2)*2-1,0);
      }

      // AM Radio and Cable News popularity slowly shift to reflect public
      // opinion over time -- if left unchecked, their subtle influence
      // on society will become a self-perpetuating Conservative nightmare!
      else if(v==VIEW_AMRADIO||v==VIEW_CABLENEWS)
      {
         if(publicmood(-1)<attitude[v])change_public_opinion(v,-1);
         else change_public_opinion(v,1);
      }
   }

   // Temporary Stalinizing Code (TODO: Implement the Stalinist Comrade Squad for changing public opinion, then remove this)
   if(stalinmode) for(int v=0;v<VIEWNUM-3;v++)
   {
      if(stalinview(v,false)) { if((attitude[v]+=3)>100) attitude[v]=100; }
      else { if(--attitude[v]<0) attitude[v]=0; }
   }
   // End Temporary Stalinizing Code (TODO: Implement the Stalinist Comrade Squad for changing public opinion, then remove this)

   // Seduction monthly experience stipends for those liberals
   // who have been getting it on with their love slaves/masters
   // in the background
   for(int s=0;s<len(pool);s++)
   {
      pool[s]->train(SKILL_SEDUCTION,loveslaves(*pool[s])*5);
      if(pool[s]->flag & CREATUREFLAG_LOVESLAVE)
         pool[s]->train(SKILL_SEDUCTION,5);
   }

   /*******************************************************
   *                 INTELLIGENCE REPORT                  *
   *     ONLY IF SHOWMECHANICS OR SHOWWAIT IS DEFINED     *
   *        EYES ONLY - LCS PROPERTY - TOP SECRET         *
   *******************************************************/
   #if defined(SHOWMECHANICS) || defined(SHOWWAIT)
   if(canseethings)
   {
      music.play(MUSIC_ELECTIONS);
      erase();
      set_color(COLOR_WHITE,COLOR_BLACK,1);
      mvaddstr(0,23,"LCS MONTHLY INTELLIGENCE REPORT");
      mvaddstr(2,27,"CURRENT POLITICAL TRENDS");
      int numviews=(endgamestate>=ENDGAME_CCS_DEFEATED||newscherrybusted<2)?VIEWNUM-1:VIEWNUM;
      for(int v=-1-stalinmode,y=4,x=0,pip;v<numviews;v++)
      {
         if((y-4)*2>=numviews+1+stalinmode) y=4,x=40;
         for(pip=2;pip>=-2;pip--)
         {
            set_alignment_color(pip,true);
            if(pip==2) mvaddchar(y,x+22,'\x11');
            addstr("ÄÄÄ");
            if(pip==-2) addchar('\x10');
         }
         if(v>=0) pip=14-(attitude[v]*14)/100;
         else pip=14-(publicmood(v)*14)/100;
         set_alignment_color((14-pip)/3-2,true);
         mvaddstr(y,x,getview(v,false));
         mvaddchar(y++,x+23+pip,'O');
      }
      set_color(COLOR_GREEN,COLOR_BLACK,1);
      mvaddstr(23,0,"Elite Liberal ");
      set_color(COLOR_WHITE,COLOR_BLACK,0);
      addstr("-  ");
      set_color(COLOR_CYAN,COLOR_BLACK,1);
      addstr("Liberal  ");
      set_color(COLOR_WHITE,COLOR_BLACK,0);
      addstr("-  ");
      set_color(COLOR_YELLOW,COLOR_BLACK,1);
      addstr("moderate  ");
      set_color(COLOR_WHITE,COLOR_BLACK,0);
      addstr("-  ");
      set_color(COLOR_MAGENTA,COLOR_BLACK,1);
      addstr("Conservative  ");
      set_color(COLOR_WHITE,COLOR_BLACK,0);
      addstr("-  ");
      set_color(COLOR_RED,COLOR_BLACK,1);
      addstr("Arch-Conservative");
      set_color(COLOR_WHITE,COLOR_BLACK,0);
      mvaddstr(24,0,"Press any key to reflect on these poll numbers.");
      clearformess=1;

      getkey();
   }
   #endif
   /*******************************************************
   *                                                      *
   *               END INTELLIGENCE REPORT                *
   *                                                      *
   *******************************************************/

   //ELECTIONS
   if(month==11){elections(clearformess,canseethings);clearformess=1;}

   //SUPREME COURT
   if(month==6){supremecourt(clearformess,canseethings);clearformess=1;}

   //CONGRESS
   congress(clearformess,canseethings);clearformess=1;

   //DID YOU WIN?
   if(wincheck())
   {
      liberalagenda(1);
      savehighscore(END_WON);
      reset(savefile_name);
      viewhighscores();
      end_game();
   }

   //CONTROL LONG DISBANDS
   if(disbanding&&year-disbandtime>=50)
   {
      music.play(MUSIC_DEFEAT);
      set_color(COLOR_WHITE,COLOR_BLACK,1);

      erase();
      move(12,10);
      addstr("The Liberal Crime Squad is now just a memory.", gamelog);
      gamelog.newline();

      getkey();

      set_color(COLOR_WHITE,COLOR_BLACK,0);
      erase();
      move(12,12);
      addstr("The last LCS members have all been hunted down.", gamelog);
      gamelog.newline();

      getkey();

      set_color(COLOR_BLACK,COLOR_BLACK,1);
      erase();
      move(12,14);
      addstr("They will never see the utopia they dreamed of...", gamelog);
      gamelog.newline();
      gamelog.nextMessage();

      getkey();

      savehighscore(END_DISBANDLOSS);
      reset(savefile_name);
      viewhighscores();
      end_game();
   }

   //UPDATE THE WORLD IN CASE THE LAWS HAVE CHANGED
   updateworld_laws(law,oldlaw);

   //THE SYSTEM!
   for(p=len(pool)-1;p>=0;p--)
   {
      if(disbanding) break;

      if(!pool[p]->alive) continue;
      if(pool[p]->flag & CREATUREFLAG_SLEEPER) continue;
      if(pool[p]->location==-1) continue;

      if(location[pool[p]->location]->type==SITE_GOVERNMENT_POLICESTATION)
      {
         if(clearformess) erase();
         else makedelimiter();

         if(pool[p]->flag & CREATUREFLAG_MISSING)
         {
            set_color(COLOR_MAGENTA,COLOR_BLACK,1);
            move(8,1);
            addstr("Cops re-polluted ", gamelog);
            addstr(pool[p]->name, gamelog);
            addstr("'s mind with Conservatism!", gamelog);
            gamelog.nextMessage();

            getkey();

            removesquadinfo(*pool[p]);
            delete_and_remove(pool,p);
            continue;
         }
         else if(pool[p]->flag & CREATUREFLAG_ILLEGALALIEN && law[LAW_IMMIGRATION]!=2)
         {
            set_color(COLOR_MAGENTA,COLOR_BLACK,1);
            move(8,1);
            addstr(pool[p]->name, gamelog);
            addstr(" has been shipped out to the INS to face ", gamelog);
            if(law[LAW_IMMIGRATION]==-2 && law[LAW_DEATHPENALTY]==-2)
               addstr("execution.", gamelog);
            else addstr("deportation.", gamelog);
            gamelog.newline();

            getkey();

            removesquadinfo(*pool[p]);
            delete_and_remove(pool,p);
            continue;
         }
         else
         {
            //TRY TO GET RACKETEERING CHARGE
            int copstrength=100;
            if(law[LAW_POLICEBEHAVIOR]==-2) copstrength=200;
            if(law[LAW_POLICEBEHAVIOR]==-1) copstrength=150;
            if(law[LAW_POLICEBEHAVIOR]==1) copstrength=75;
            if(law[LAW_POLICEBEHAVIOR]==2) copstrength=50;

            copstrength=(copstrength*pool[p]->heat)/4;
            if(copstrength>200)copstrength=200;

            //Confession check
            if(LCSrandom(copstrength)>pool[p]->juice  +  pool[p]->get_attribute(ATTRIBUTE_HEART,true)*5  -
                                      pool[p]->get_attribute(ATTRIBUTE_WISDOM,true)*5  +  pool[p]->get_skill(SKILL_PSYCHOLOGY)*5
                                      /*+ pool[p]->get_skill(SKILL_SURVIVAL)*5*/  &&  pool[p]->hireid!=-1)
            {
               int nullify=0;
               int p2=getpoolcreature(pool[p]->hireid);

               if(pool[p2]->alive && (pool[p2]->location==-1 || location[pool[p2]->location]->type!=SITE_GOVERNMENT_PRISON))
               {  //Charge the boss with racketeering!
                  criminalize(*pool[p2],LAWFLAG_RACKETEERING);
                  //Rack up testimonies against the boss in court!
                  pool[p2]->confessions++;
               }
               if(!nullify)
               {  //Issue a raid on this guy's base!
                  if(pool[p]->base>=0)location[pool[p]->base]->heat+=300;

                  set_color(COLOR_WHITE,COLOR_BLACK,1);
                  move(8,1);
                  addstr(pool[p]->name, gamelog);
                  addstr(" has broken under the pressure and ratted you out!", gamelog);
                  gamelog.newline();

                  getkey();

                  set_color(COLOR_WHITE,COLOR_BLACK,1);
                  move(9,1);
                  addstr("The traitor will testify in court, and safehouses may be compromised.", gamelog);
                  gamelog.nextMessage();

                  getkey();

                  removesquadinfo(*pool[p]);

                  delete_and_remove(pool,p);
                  continue; //no trial for this person; skip to next person
               }
               //else continue to trial
            }

            set_color(COLOR_WHITE,COLOR_BLACK,1);
            move(8,1);
            addstr(pool[p]->name, gamelog);
            addstr(" is moved to the courthouse for trial.", gamelog);
            gamelog.nextMessage();

            getkey();

            pool[p]->location=find_courthouse(*pool[p]);
            Armor prisoner(*armortype[getarmortype("ARMOR_PRISONER")]);
            pool[p]->give_armor(prisoner,NULL);
         }
      }
      else if(location[pool[p]->location]->type==SITE_GOVERNMENT_COURTHOUSE)
      { trial(*pool[p]); clearformess=1; }
      else if(location[pool[p]->location]->type==SITE_GOVERNMENT_PRISON)
         if(prison(*pool[p])) clearformess=1;
   }

   //NUKE EXECUTION VICTIMS
   for(p=len(pool)-1;p>=0;p--)
   {
      if(pool[p]->location==-1) continue;

      if(location[pool[p]->location]->type==SITE_GOVERNMENT_PRISON&&!pool[p]->alive)
      {
         removesquadinfo(*pool[p]);
         pool[p]->die();
         pool[p]->location=-1;
      }
   }

   //MUST DO AN END OF GAME CHECK HERE BECAUSE OF EXECUTIONS
   endcheck(END_EXECUTED);

   //DISPERSAL CHECK
   dispersalcheck(clearformess);

   //FUND REPORTS
   if(canseethings)fundreport(clearformess);
   ledger.resetMonthlyAmounts();
   if(clearformess) erase();

   //HEAL CLINIC PEOPLE
   for(p=0;p<len(pool);p++)
   {
      if(disbanding) break;
      if(!(pool[p]->alive)) continue;

      if(pool[p]->clinic>0)
      {
         pool[p]->clinic--;

         for(int w=0;w<BODYPARTNUM;w++)
         {
            if((pool[p]->wound[w]&WOUND_NASTYOFF)||(pool[p]->wound[w]&WOUND_CLEANOFF))
               pool[p]->wound[w]=(char)WOUND_CLEANOFF;
            else pool[p]->wound[w]=0;
         }

         int healthdamage = 0;

         if(pool[p]->special[SPECIALWOUND_RIGHTLUNG]!=1)
         {
            pool[p]->special[SPECIALWOUND_RIGHTLUNG]=1;
            if(LCSrandom(2)) healthdamage++;
         }
         if(pool[p]->special[SPECIALWOUND_LEFTLUNG]!=1)
         {
            pool[p]->special[SPECIALWOUND_LEFTLUNG]=1;
            if(LCSrandom(2)) healthdamage++;
         }
         if(pool[p]->special[SPECIALWOUND_HEART]!=1)
         {
            pool[p]->special[SPECIALWOUND_HEART]=1;
            if(LCSrandom(3)) healthdamage++;
         }
         pool[p]->special[SPECIALWOUND_LIVER]=1;
         pool[p]->special[SPECIALWOUND_STOMACH]=1;
         pool[p]->special[SPECIALWOUND_RIGHTKIDNEY]=1;
         pool[p]->special[SPECIALWOUND_LEFTKIDNEY]=1;
         pool[p]->special[SPECIALWOUND_SPLEEN]=1;
         pool[p]->special[SPECIALWOUND_RIBS]=RIBNUM;

         if(!pool[p]->special[SPECIALWOUND_NECK])
            pool[p]->special[SPECIALWOUND_NECK]=2;
         if(!pool[p]->special[SPECIALWOUND_UPPERSPINE])
            pool[p]->special[SPECIALWOUND_UPPERSPINE]=2;
         if(!pool[p]->special[SPECIALWOUND_LOWERSPINE])
            pool[p]->special[SPECIALWOUND_LOWERSPINE]=2;

         // Inflict permanent health damage
         pool[p]->set_attribute(ATTRIBUTE_HEALTH,pool[p]->get_attribute(ATTRIBUTE_HEALTH,0)-healthdamage);
         if(pool[p]->get_attribute(ATTRIBUTE_HEALTH,0)<=0)
            pool[p]->set_attribute(ATTRIBUTE_HEALTH,1);

         if(pool[p]->blood<=20&&pool[p]->clinic<=2)pool[p]->blood=50;
         if(pool[p]->blood<=50&&pool[p]->clinic<=1)pool[p]->blood=75;

         // If at clinic and in critical condition, transfer to university hospital
         if(pool[p]->clinic > 2 &&
            pool[p]->location > -1 &&
            location[pool[p]->location]->type==SITE_HOSPITAL_CLINIC)
         {
            int hospital=find_hospital(*pool[p]);
            if(hospital!=-1)
            {
               pool[p]->location=hospital;
               set_color(COLOR_WHITE,COLOR_BLACK,1);
               move(8,1);
               addstr(pool[p]->name, gamelog);
               addstr(" has been transferred to ", gamelog);
               addstr(location[hospital]->name, gamelog);
               addstr(".", gamelog);
               gamelog.nextMessage();

               getkey();
            }
         }

         // End treatment
         if(pool[p]->clinic==0)
         {
            pool[p]->blood=100;
            if(clearformess) erase();
            else makedelimiter();

            set_color(COLOR_WHITE,COLOR_BLACK,1);
            move(8,1);
            addstr(pool[p]->name, gamelog);
            addstr(" has left ", gamelog);
            addstr(location[pool[p]->location]->name, gamelog);
            addstr(".", gamelog);
            gamelog.nextMessage();

            int hs=find_homeless_shelter(*pool[p]);
            if(hs==-1) hs=0; //TODO: Error unable to find location

            if(location[pool[p]->base]->siege.siege||
               location[pool[p]->base]->renting==RENTING_NOCONTROL)
               pool[p]->base=hs;

            pool[p]->location=pool[p]->base;

            getkey();
         }
      }
   }
}
/* full screen character sheet */
void printliberalstats(Creature &cr)
{
   set_color(COLOR_WHITE,COLOR_BLACK,0);

   char num[20],str[200];

   // Add name
   move(2,0);
   addstr("Name: ");
   set_color(COLOR_WHITE,COLOR_BLACK,1);
   addstr(cr.name);
   set_color(COLOR_WHITE,COLOR_BLACK,0);
   if(strcmp(cr.propername,cr.name)!=0)
   {
      //The names do not match, print real name as well
      addstr(" (");
      addstr(cr.propername);
      addstr(")");
   }
   addstr(", ");
   gettitle(str,cr);
   addstr(str);
   addstr(" (");
   getrecruitcreature(str,cr.type);
   addstr(str);
   addstr(")");
   move(3,0);



   // Add birthdate
   addstr("Born ");
   switch(cr.birthday_month)
   {
   case 1:addstr("January");break;
   case 2:addstr("February");break;
   case 3:addstr("March");break;
   case 4:addstr("April");break;
   case 5:addstr("May");break;
   case 6:addstr("June");break;
   case 7:addstr("July");break;
   case 8:addstr("August");break;
   case 9:addstr("September");break;
   case 10:addstr("October");break;
   case 11:addstr("November");break;
   case 12:addstr("December");break;
   }
   addstr(" ");
   itoa(cr.birthday_day,num,10);
   addstr(num);
   addstr(", ");
   if(cr.birthday_month < month ||
      (cr.birthday_month == month && cr.birthday_day <= day))
   {
      itoa(year-cr.age,num,10);
   }
   else
   {
      itoa(year-1-cr.age,num,10);
   }
   addstr(num);
   // Add age
   addstr(" (Age ");
   itoa(cr.age,num,10);
   addstr(num);
   addstr(", ");
   // Add Liberal gender
   if(cr.gender_liberal == GENDER_FEMALE)
      addstr("Female");
   else if(cr.gender_liberal == GENDER_MALE)
      addstr("Male");
   else
      addstr("Androgynous");
   // Note if there's some conflict with Conservative society's perceptions
   //if(cr.gender_liberal != cr.gender_conservative)
   //   addstr("*");
   addstr(")");

   move(3,46);
   statebrokenlaws(cr);
   set_color(COLOR_WHITE,COLOR_BLACK,0);

   // Add juice
   move(10,16);
   addstr("Juice: ");
   itoa(cr.juice,num,10);
   addstr(num);
   if(cr.juice<1000)
   {
      move(11,16);addstr("Next:  ");
      if(cr.juice<0)addstr("0");
      else if(cr.juice<10)addstr("10");
      else if(cr.juice<50)addstr("50");
      else if(cr.juice<100)addstr("100");
      else if(cr.juice<200)addstr("200");
      else if(cr.juice<500)addstr("500");
      else addstr("1000");
   }
   // Add attributes
   move(5,0);addstr("Heart: ");
   itoa(cr.get_attribute(ATTRIBUTE_HEART,true),num,10);
   addstr(num);
   move(6,0);addstr("Intelligence: ");
   itoa(cr.get_attribute(ATTRIBUTE_INTELLIGENCE,true),num,10);
   addstr(num);
   move(7,0);addstr("Wisdom: ");
   itoa(cr.get_attribute(ATTRIBUTE_WISDOM,true),num,10);
   addstr(num);
   move(8,0);addstr("Health: ");
   itoa(cr.get_attribute(ATTRIBUTE_HEALTH,true),num,10);
   addstr(num);
   move(9,0);addstr("Agility: ");
   itoa(cr.get_attribute(ATTRIBUTE_AGILITY,true),num,10);
   addstr(num);
   move(10,0);addstr("Strength: ");
   itoa(cr.get_attribute(ATTRIBUTE_STRENGTH,true),num,10);
   addstr(num);
   move(11,0);addstr("Charisma: ");
   itoa(cr.get_attribute(ATTRIBUTE_CHARISMA,true),num,10);
   addstr(num);

   // Add highest skills
   char used[SKILLNUM];
   memset(used,0,sizeof(char)*SKILLNUM);

   int skills_max=16;
   char printed=1;

   move(5,28);
   addstr("SKILL");
   move(5,43);
   addstr("NOW   MAX");
   for(int skills_shown=0;skills_shown<skills_max&&printed;skills_shown++)
   {
      printed=0;

      int max=0;
      long maxs=-1;
      for(int s=0;s<SKILLNUM;s++)
      {
         if((cr.get_skill(s)*10000+cr.get_skill_ip(s))>max && !used[s])
         {
            max=(cr.get_skill(s)*10000+cr.get_skill_ip(s));
            maxs=s;
         }
      }

      if(maxs!=-1)
      {
         used[maxs]=1;
         printed=1;

         // Maxed skills are green
         if(cr.skill_cap(maxs,true)!=0 && cr.get_skill(maxs)>=cr.skill_cap(maxs,true))set_color(COLOR_CYAN,COLOR_BLACK,1);
         // About to level up skills are white
         else if(cr.get_skill_ip(maxs)>=100+(10*cr.get_skill(maxs))&&
            cr.get_skill(maxs)<cr.skill_cap(maxs,true))set_color(COLOR_WHITE,COLOR_BLACK,1);
         // <1 skills are dark gray
         else if(cr.get_skill(maxs)<1)set_color(COLOR_BLACK,COLOR_BLACK,1);
         // >=1 skills are light gray
         else set_color(COLOR_WHITE,COLOR_BLACK,0);

         move(6+skills_shown,28);
         strcpy(str,Skill::get_name(maxs).c_str());
         strcat(str,": ");
         addstr(str);
         move(6+skills_shown,42);
         sprintf(num,"%2d.",cr.get_skill(maxs));
         addstr(num);
         if(cr.get_skill_ip(maxs)<100+(10*cr.get_skill(maxs)))
         {
            if ((cr.get_skill_ip(maxs)*100)/(100+(10*cr.get_skill(maxs)))!=0)
            {
               itoa((cr.get_skill_ip(maxs)*100)/(100+(10*cr.get_skill(maxs))),num,10);
               if ((cr.get_skill_ip(maxs)*100)/(100+(10*cr.get_skill(maxs)))<10)
               {
                  addstr("0");
               }
               addstr(num);
            }
            else addstr("00");
         }
         else
         {
            addstr("99+");
         }

         if(cr.skill_cap(maxs,true)==0 || cr.get_skill(maxs)<cr.skill_cap(maxs,true))
            set_color(COLOR_BLACK,COLOR_BLACK,1);
         move(6+skills_shown,48);
         sprintf(str,"%2d.00",cr.skill_cap(maxs,true));
         addstr(str);
      }
   }

   set_color(COLOR_WHITE,COLOR_BLACK,0);

   // Add weapon
   move(13,0);
   addstr("Weapon: ");
   addstr(cr.get_weapon_string(0).c_str());

   // Add clothing
   move(14,0);
   addstr("Clothes: ");
   addstr(cr.get_armor_string(true).c_str());


   // Add vehicle
   move(15,0);
   addstr("Car: ");
   long v=-1;
   if(showcarprefs==1)v=id_getcar(cr.pref_carid);
   else v=id_getcar(cr.carid);
   if(v!=-1&&showcarprefs!=-1)
   {
      strcpy(str,vehicle[v]->shortname().c_str());
      char d;
      if(showcarprefs==1)d=cr.pref_is_driver;
      else d=cr.is_driver;
      if(d)strcat(str,"-D");
   }
   else
   {
      int legok=2;
      if((cr.wound[BODYPART_LEG_RIGHT] & WOUND_NASTYOFF)||
         (cr.wound[BODYPART_LEG_RIGHT] & WOUND_CLEANOFF))legok--;
      if((cr.wound[BODYPART_LEG_LEFT] & WOUND_NASTYOFF)||
         (cr.wound[BODYPART_LEG_LEFT] & WOUND_CLEANOFF))legok--;
      if(cr.flag & CREATUREFLAG_WHEELCHAIR)strcpy(str,"Wheelchair");
      else if(legok>=1)strcpy(str,"On Foot");
      else strcpy(str,"On \"Foot\"");
   }
   addstr(str);

   // Add recruit stats
   if(cr.flag!=CREATUREFLAG_BRAINWASHED)
   {
      move(18,0);
      itoa(maxsubordinates(cr)-subordinatesleft(cr),num,10);
      addstr(num);
      addstr(" Recruits / ");
      itoa(maxsubordinates(cr),num,10);
      addstr(num);
      addstr(" Max");
   }
   else
   {
      move(18,0);
      addstr("Enlightened ");
      addstr("Can't Recruit");
   }
   // Any meetings with potential recruits scheduled?
   int recruiting = scheduledmeetings(cr);
   if(recruiting)
   {
      move(18,55);
      itoa(recruiting,num,10);
      addstr("Scheduled Meetings: ");
      addstr(num);
   }
   // Add seduction stats
   move(19,0); 
   int lovers = loveslaves(cr);
   if(cr.flag & CREATUREFLAG_LOVESLAVE)
      lovers++;
   if(lovers)
   {
      itoa(lovers,num,10);
      addstr(num);
      addstr(" Romantic Interest");
      if(lovers>1)addstr("s");
   }
   // Any dates with potential love interests scheduled?
   int wooing = scheduleddates(cr);
   if(wooing)
   {
      move(19,55);
      itoa(wooing,num,10);
      addstr("Scheduled Dates:    ");
      addstr(num);
   }

   // Add wound status
   for(int w=0;w<BODYPARTNUM;w++)
   {
      if(cr.wound[w] & WOUND_BLEEDING)set_color(COLOR_RED,COLOR_BLACK,1);
      else set_color(COLOR_WHITE,COLOR_BLACK,0);

      move(5+w,55);
      switch(w)
      {
      case BODYPART_HEAD:addstr("Head:");break;
      case BODYPART_BODY:addstr("Body:");break;
      case BODYPART_ARM_RIGHT:addstr("Right Arm:");break;
      case BODYPART_ARM_LEFT:addstr("Left Arm:");break;
      case BODYPART_LEG_RIGHT:addstr("Right Leg:");break;
      case BODYPART_LEG_LEFT:addstr("Left Leg:");break;
      }

      move(5+w,66);
      if(cr.wound[w] & WOUND_NASTYOFF)addstr("Ripped off");
      else if(cr.wound[w] & WOUND_CLEANOFF)addstr("Severed");
      else
      {
         int sum=0;

         if(cr.wound[w] & WOUND_SHOT)sum++;
         if(cr.wound[w] & WOUND_CUT)sum++;
         if(cr.wound[w] & WOUND_BRUISED)sum++;
         if(cr.wound[w] & WOUND_BURNED)sum++;
         if(cr.wound[w] & WOUND_TORN)sum++;

         if(sum==0)
         {
            set_color(COLOR_GREEN,COLOR_BLACK,1);
            if(cr.animalgloss==ANIMALGLOSS_ANIMAL)
               addstr("Animal");
            else
               addstr("Liberal");
         }

         if(cr.wound[w] & WOUND_SHOT){addstr("Shot");sum--;if(sum>0)addstr(",");}
         if(cr.wound[w] & WOUND_BRUISED){addstr("Bruised");sum--;if(sum>0)addstr(",");}
         if(cr.wound[w] & WOUND_CUT){addstr("Cut");sum--;if(sum>0)addstr(",");}
         if(cr.wound[w] & WOUND_TORN){addstr("Torn");sum--;if(sum>0)addstr(",");}
         if(cr.wound[w] & WOUND_BURNED){addstr("Burned");sum--;if(sum>0)addstr(",");}
      }
   }
   set_color(COLOR_WHITE,COLOR_BLACK,0);

   //SPECIAL WOUNDS
   set_color(COLOR_RED,COLOR_BLACK,0);

   int y=12;
   int x=55;
   if(cr.special[SPECIALWOUND_HEART]!=1)
   {
      move(y++,x);
      addstr("Heart Punctured");
   }
   if(cr.special[SPECIALWOUND_RIGHTLUNG]!=1)
   {
      move(y++,x);
      addstr("R. Lung Collapsed");
   }
   if(cr.special[SPECIALWOUND_LEFTLUNG]!=1)
   {
      move(y++,x);
      addstr("L. Lung Collapsed");
   }
   if(cr.special[SPECIALWOUND_NECK]!=1)
   {
      move(y++,x);
      addstr("Broken Neck");
   }
   if(cr.special[SPECIALWOUND_UPPERSPINE]!=1)
   {
      move(y++,x);
      addstr("Broken Up Spine");
   }
   if(cr.special[SPECIALWOUND_LOWERSPINE]!=1)
   {
      move(y++,x);
      addstr("Broken Lw Spine");
   }
   if(cr.special[SPECIALWOUND_RIGHTEYE]!=1)
   {
      move(y++,x);
      addstr("No Right Eye");
   }
   if(cr.special[SPECIALWOUND_LEFTEYE]!=1)
   {
      move(y++,x);
      addstr("No Left Eye");
   }
   if(cr.special[SPECIALWOUND_NOSE]!=1)
   {
      move(y++,x);
      addstr("No Nose");
   }
   if(cr.special[SPECIALWOUND_TONGUE]!=1)
   {
      move(y++,x);
      addstr("No Tongue");
   }
   if(cr.special[SPECIALWOUND_TEETH]!=TOOTHNUM)
   {
      move(y++,x);
      if(cr.special[SPECIALWOUND_TEETH]==0)addstr("No Teeth");
      else if(cr.special[SPECIALWOUND_TEETH]==TOOTHNUM-1)addstr("Missing a Tooth");
      else if(cr.special[SPECIALWOUND_TEETH]<TOOTHNUM)addstr("Missing Teeth");
   }
   if(cr.special[SPECIALWOUND_LIVER]!=1)
   {
      move(y++,x);
      addstr("Liver Damaged");
   }
   if(cr.special[SPECIALWOUND_RIGHTKIDNEY]!=1)
   {
      move(y++,x);
      addstr("R. Kidney Damaged");
   }
   if(cr.special[SPECIALWOUND_LEFTKIDNEY]!=1)
   {
      move(y++,x);
      addstr("L. Kidney Damaged");
   }
   if(cr.special[SPECIALWOUND_STOMACH]!=1)
   {
      move(y++,x);
      addstr("Stomach Injured");
   }
   if(cr.special[SPECIALWOUND_SPLEEN]!=1)
   {
      move(y++,x);
      addstr("Busted Spleen");
   }
   if(cr.special[SPECIALWOUND_RIBS]!=RIBNUM)
   {
      move(y++,x);
      if(cr.special[SPECIALWOUND_RIBS]==0)addstr("All Ribs Broken");
      else if(cr.special[SPECIALWOUND_RIBS]==RIBNUM-1)addstr("Broken Rib");
      else if(cr.special[SPECIALWOUND_RIBS]<RIBNUM)addstr("Broken Ribs");
   }

   set_color(COLOR_WHITE,COLOR_BLACK,0);
}