Пример #1
0
/*! \brief Enemy initialisation
 *
 * This is the main enemy initialization routine.  This function sets up
 * the enemy types and then loads each one in.  It also calls a helper
 * function or two to complete the process.
 *
 * The encounter table consists of several 'sub-tables', grouped by
 * encounter number. Each row is one possible battle.
 * Fills in the cf[] array of enemies to load.
 *
 * \param   en Encounter number in the Encounter table.
 * \param   etid If =99, select a random row with that encounter number,
 *          otherwise select row etid.
 * \returns number of random encounter
 */
int select_encounter (int en, int etid)
{
   size_t i, p, j;
   int stop = 0, where = 0, entry = -1;

   while (!stop) {
      if (erows[where].tnum == en)
         stop = 1;
      else
         where++;
      if (where >= NUM_ETROWS) {
         sprintf (strbuf, _("There are no rows for encounter table #%d!"), en);
         program_death (strbuf);
      }
   }
   if (etid == 99) {
      i = rand () % 100 + 1;
      while (entry < 0) {
         if (i <= erows[where].per) {
            entry = where;
         } else
            where++;
         if (erows[where].tnum > en || where >= NUM_ETROWS)
            program_death (_("Couldn't select random encounter table row!"));
      }
   } else
      entry = where + etid;
   p = 0;
   for (j = 0; j < 5; j++) {
      if (erows[entry].idx[j] > 0) {
         cf[p] = erows[entry].idx[j] - 1;
         p++;
      }
   }
   num_enemies = p;
   /* adjust 'too hard' combat where player is alone and faced by >2 enemies */
   if (num_enemies > 2 && numchrs == 1 && erows[entry].lvl + 2 > party[pidx[0]].lvl
       && etid == 99)
      num_enemies = 2;
   if (num_enemies == 0)
      program_death (_("Empty encounter table row!"));
   return entry;
}
Пример #2
0
/*! \brief Read a command and parameter from a script
 *
 * This processes entity commands from the movement script.
 * This is from Verge1.
 *
 * Script commands are:
 * - U,R,D,L + param:  move up, right, down, left by param spaces
 * - W+param: wait param frames
 * - B: start script again
 * - X+param: move to x-coord param
 * - Y+param: move to y-coord param
 * - F+param: face direction param (0=S, 1=N, 2=W, 3=E)
 * - K: kill (remove) entity
 *
 * \param   target_entity Entity to process
 */
static void getcommand(t_entity target_entity)
{
    char s;

    /* PH FIXME: prevented from running off end of string */
    if (g_ent[target_entity].sidx < sizeof(g_ent[target_entity].script))
    {
        s = g_ent[target_entity].script[g_ent[target_entity].sidx++];
    }
    else
    {
        s = '\0';
    }
    switch (s)
    {
        case 'u':
        case 'U':
            g_ent[target_entity].cmd = COMMAND_MOVE_UP;
            parsems(target_entity);
            break;
        case 'd':
        case 'D':
            g_ent[target_entity].cmd = COMMAND_MOVE_DOWN;
            parsems(target_entity);
            break;
        case 'l':
        case 'L':
            g_ent[target_entity].cmd = COMMAND_MOVE_LEFT;
            parsems(target_entity);
            break;
        case 'r':
        case 'R':
            g_ent[target_entity].cmd = COMMAND_MOVE_RIGHT;
            parsems(target_entity);
            break;
        case 'w':
        case 'W':
            g_ent[target_entity].cmd = COMMAND_WAIT;
            parsems(target_entity);
            break;
        case '\0':
            g_ent[target_entity].cmd = COMMAND_FINISH_COMMANDS;
            g_ent[target_entity].movemode = MM_STAND;
            g_ent[target_entity].cmdnum = 0;
            g_ent[target_entity].sidx = 0;
            break;
        case 'b':
        case 'B':
            g_ent[target_entity].cmd = COMMAND_REPEAT;
            break;
        case 'x':
        case 'X':
            g_ent[target_entity].cmd = COMMAND_MOVETO_X;
            parsems(target_entity);
            break;
        case 'y':
        case 'Y':
            g_ent[target_entity].cmd = COMMAND_MOVETO_Y;
            parsems(target_entity);
            break;
        case 'f':
        case 'F':
            g_ent[target_entity].cmd = COMMAND_FACE;
            parsems(target_entity);
            break;
        case 'k':
        case 'K':
            /* PH add: command K makes the ent disappear */
            g_ent[target_entity].cmd = COMMAND_KILL;
            g_ent[target_entity].active = 0;
            break;
        default:
#ifdef DEBUGMODE
            if (debugging > 0)
            {
                sprintf(strbuf,
                        _("Invalid entity command (%c) at position %d for ent %d"), s,
                        g_ent[target_entity].sidx, target_entity);
                program_death(strbuf);
            }
#endif
            break;
    }
}
Пример #3
0
/*! \brief Load all enemies from disk
 *
 * Loads up enemies from the *.mon files and fills the enemies[] array.
 * \author PH
 * \date 2003????
 */
static void load_enemies (void)
{
   int i, tmp, lx, ly, p;
   FILE *edat;
   s_fighter *f;

   if (enemies != NULL) {
      /* Already done the loading */
      return;
   }
   enemy_pcx = load_datafile_object (PCX_DATAFILE, "ENEMY_PCX");
   if (enemy_pcx == NULL) {
      program_death (_("Could not load enemy sprites from datafile!"));
   }
   edat = fopen (kqres (DATA_DIR, "allstat.mon"), "r");
   if (!edat)
      program_death (_("Could not load 1st enemy datafile!"));
   enemies_n = 0;
   enemies_cap = 128;
   enemies = (s_fighter **) malloc (sizeof (s_fighter *) * enemies_cap);
   // Loop through for every monster in allstat.mon
   while (fscanf (edat, "%s", strbuf) != EOF) {
      if (enemies_n >= enemies_cap) {
         enemies_cap *= 2;
         enemies =
            (s_fighter **) realloc (enemies,
                                    sizeof (s_fighter *) * enemies_cap);
      }
      f = enemies[enemies_n++] = (s_fighter *) malloc (sizeof (s_fighter));
      memset (f, 0, sizeof (s_fighter));
      // Enemy name
      strncpy (f->name, strbuf, sizeof (f->name));
      // Index number (ignored; automatically generated)
      fscanf (edat, "%d", &tmp);
      // x-coord of image in datafile
      fscanf (edat, "%d", &tmp);
      lx = tmp;
      // y-coord of image in datafile
      fscanf (edat, "%d", &tmp);
      ly = tmp;
      // Image width
      fscanf (edat, "%d", &tmp);
      f->cw = tmp;
      // Image length (height)
      fscanf (edat, "%d", &tmp);
      f->cl = tmp;
      // Experience points earned
      fscanf (edat, "%d", &tmp);
      f->xp = tmp;
      // Gold received
      fscanf (edat, "%d", &tmp);
      f->gp = tmp;
      // Level
      fscanf (edat, "%d", &tmp);
      f->lvl = tmp;
      // Max HP
      fscanf (edat, "%d", &tmp);
      f->mhp = tmp;
      // Max MP
      fscanf (edat, "%d", &tmp);
      f->mmp = tmp;
      // Defeat Item Probability: chance of finding any items after defeat
      fscanf (edat, "%d", &tmp);
      f->dip = tmp;
      // Defeat Item Common: item found commonly of the time
      fscanf (edat, "%d", &tmp);
      f->defeat_item_common = tmp;
      // Defeat Item Rare: item found rarely
      fscanf (edat, "%d", &tmp);
      f->defeat_item_rare = tmp;
      // Steal Item Common: item found commonly from stealing
      fscanf (edat, "%d", &tmp);
      f->steal_item_common = tmp;
      // Steal Item Rare: item found rarely when stealing
      fscanf (edat, "%d", &tmp);
      f->steal_item_rare = tmp;
      // Enemy's strength (agility & vitality set to zero)
      fscanf (edat, "%d", &tmp);
      f->stats[A_STR] = tmp;
      f->stats[A_AGI] = 0;
      f->stats[A_VIT] = 0;
      // Intelligence & Sagacity (both the same)
      fscanf (edat, "%d", &tmp);
      f->stats[A_INT] = tmp;
      f->stats[A_SAG] = tmp;
      // Defense against: Speed, Spirit, Attack, Hit, Defence, Evade, Magic (in that order)
      for (p = 5; p < 13; p++) {
         fscanf (edat, "%d", &tmp);
         f->stats[p] = tmp;
      }
      // Bonus
      fscanf (edat, "%d", &tmp);
      f->bonus = tmp;
      f->bstat = 0;
      // Current weapon type
      fscanf (edat, "%d", &tmp);
      f->cwt = tmp;
      // Weapon elemental type
      fscanf (edat, "%d", &tmp);
      f->welem = tmp;
      // Undead Level (defense against Undead attacks)
      fscanf (edat, "%d", &tmp);
      f->unl = tmp;
      // Critical attacks
      fscanf (edat, "%d", &tmp);
      f->crit = tmp;
      // Temp Sag & Int for Imbued
      fscanf (edat, "%d", &tmp);
      f->imb_s = tmp;
      // Imbued stat type (Spd, Spi, Att, Hit, Def, Evd, Mag)
      fscanf (edat, "%d", &tmp);
      f->imb_a = tmp;
      f->img =
         create_sub_bitmap ((BITMAP *) enemy_pcx->dat, lx, ly, f->cw, f->cl);
      for (p = 0; p < 2; p++) {
         fscanf (edat, "%d", &tmp);
         f->imb[p] = tmp;
      }
   }
   fclose (edat);
   edat = fopen (kqres (DATA_DIR, "resabil.mon"), "r");
   if (!edat)
      program_death (_("Could not load 2nd enemy datafile!"));
   for (i = 0; i < enemies_n; i++) {
      f = enemies[i];
      fscanf (edat, "%s", strbuf);
      fscanf (edat, "%d", &tmp);
      for (p = 0; p < R_TOTAL_RES; p++) {
         fscanf (edat, "%d", &tmp);
         f->res[p] = tmp;
      }
      for (p = 0; p < 8; p++) {
         fscanf (edat, "%d", &tmp);
         f->ai[p] = tmp;
      }
      for (p = 0; p < 8; p++) {
         fscanf (edat, "%d", &tmp);
         f->aip[p] = tmp;
         f->atrack[p] = 0;
      }
      f->hp = f->mhp;
      f->mp = f->mmp;
      for (p = 0; p < 24; p++)
         f->sts[p] = 0;
      f->aux = 0;
      f->mrp = 100;
   }
   fclose (edat);
}