/*----------------------------------------------------------------------------*
 | This file is part of DEU (Doom Editing Utilities), created by the DEU team:|
 | Raphael Quinet, Brendon Wyber, Ted Vessenes and others.  See README.1ST or |
 | the "about" dialog box for full credits.                                   |
 |                                                                            |
 | DEU is an open project: if you think that you can contribute, please join  |
 | the DEU team.  You will be credited for any code (or ideas) included in    |
 | the next version of the program.                                           |
 |                                                                            |
 | If you want to make any modifications and re-distribute them on your own,  |
 | you must follow the conditions of the DEU license.  Read the file LICENSE  |
 | in this directory or README.1ST in the top directory.  If do not have a    |
 | copy of these files, you can request them from any member of the DEU team, |
 | or by mail: Raphael Quinet, Rue des Martyrs 9, B-4550 Nandrin (Belgium).   |
 |                                                                            |
 | This program comes with absolutely no warranty.  Use it at your own risks! |
 *----------------------------------------------------------------------------*

 M_STATS.C - Compute statistics for a map (difficulty rating, etc.)

*/

/* the includes */
#include "deu.h"
#include "d_main.h"
#include "w_things.h"
#include "w_struct.h"
#include "w_levels.h"
#include "m_stats.h"

/*
   Adds the weighted value to the specified array under certain skills
*/
static void AddToSkillArray(Int16 val, Int32 array[5], UInt16 when, float weight[5])
{
  Bool present[5] = {FALSE, FALSE, FALSE, FALSE, FALSE};
  int  i;

  /* Ignore net-only objects */
  if (when & 0x10)
    return;

  if (when & 0x01)
    present[0] = present[1] = TRUE;
  if (when & 0x02)
    present[2] = TRUE;
  if (when & 0x04)
    present[3] = present[4] = TRUE;

  for (i = 0; i < 5; i++)
    if (present[i])
      array[i] += val * weight[i];
}



/*
   Computes the DEU WAD Rating for each skill level on the specified level
*/
void ComputeDifficulty(LevelPtr level, Int16 skill[5])
{
  Int32  PHealth[5], PDamage[5], MHealth[5], MDamage[5];
  float  AmmoInc[5] = {2.0, 1.0, 1.0, 1.0, 2.0};
  float  DmgeInc[5] = { .5, 1.0, 1.0, 1.0, 4.0};
  float  FlatWgt[5] = {1.0, 1.0, 1.0, 1.0, 1.0};
  UInt16 props;
  UInt16 t;
  TPtr   tptr;

  if (DoomVersion >= 0x10)
    {
      AmmoInc[0] = 1.5;
      DmgeInc[4] = 2.0;
    }

  for (t = 0; t < 5; t++)
    {
      PHealth[t] = GetThingHealth(THING_PLAYER1);
      PDamage[t] = GetThingDamage(THING_PLAYER1) * AmmoInc[t];
    }

  for (t = 0, tptr = level->things; t < level->num_things; t++, tptr++)
    {
      props = GetThingProperties(tptr->type);
      /* If it doesn't affect you, ignore it */
      if (props & TP_KILL)
        {
          AddToSkillArray(GetThingHealth(tptr->type), MDamage, tptr->when,
                     DmgeInc);
          AddToSkillArray(GetThingDamage(tptr->type), MHealth, tptr->when,
                     FlatWgt);
        }
      else if (props & TP_PICK)
        {
          if (props & (TP_WAMMO | TP_WEAPON))
            AddToSkillArray(GetThingDamage(tptr->type), PDamage, tptr->when,
                       AmmoInc);
          else
            AddToSkillArray(GetThingDamage(tptr->type), PHealth, tptr->when,
                       FlatWgt);
        }
    }

  /* Cover face, wave hands, say magic words... */
  for (t = 0; t < 5; t++)
    skill[t] = 100*MDamage[t] / PHealth[t] + 100*MHealth[t] / PDamage[t];

  /*! The values of 100 are very very very very very uncertain */
}

/* end of file */
