Example #1
0
void
compute_opener_floors (void)
{
    size_t i;

    for (i = 0; i < opener_floor_nmemb;) {
        struct opener_floor *o = &opener_floor[i];
        if (fg (&o->p) == OPENER_FLOOR) {
            i++;
            continue;
        }
        remove_opener_floor (o);
    }

    for (i = 0; i < opener_floor_nmemb; i++) {
        struct opener_floor *o = &opener_floor[i];
        if (o->pressed && ! o->broken) {
            if (! o->noise) {
                alert_guards (&o->p);
                play_audio (&opener_floor_audio, &o->p, -1);
                o->noise = true;
            }
            open_door (o->p.l, o->event, o->priority, false);
        } else o->noise = false;
    }
}
Example #2
0
void
compute_loose_floor_release (struct loose_floor *l)
{
  if (l->resist-- > 0) {
    l->state = 0;
    return;
  }
  switch (l->i) {
  case 0: l->state = 1;
    alert_guards (&l->p);
    sample_random_loose_floor (l->p.room); l->i++; break;
  case 1: l->state = 0; l->i++; break;
  case 2: l->state = 2;
    sample_random_loose_floor (l->p.room); l->i++; break;
  case 3: l->state = 2; l->i++; break;
  case 4: l->state = 0; l->i++; break;
  case 5: l->state = 0; l->i++; break;
  case 6: l->state = 0; l->i++; break;
  case 7: l->state = 2;
    sample_random_loose_floor (l->p.room); l->i++; break;
  case 8: l->state = 2; l->i++; break;
  case 9: l->state = 2; l->i++; break;
  case 10:
    con (&l->p)->fg = NO_FLOOR;
    l->state = 2;
    l->i = 0;
    l->f.id = &l->f;
    l->action = FALL_LOOSE_FLOOR;
    l->resist = LOOSE_FLOOR_RESISTENCE;
    l->f.b = get_correct_falling_loose_floor_bitmap (l->f.b);
    break;
  }
}
Example #3
0
void
compute_loose_floor_shake (struct loose_floor *l)
{
  switch (l->i) {
  case 0: l->state = 1;
    alert_guards (&l->p);
    sample_random_loose_floor (l->p.room); l->i++; break;
  case 1: l->state = 0; l->i++; break;
  case 2: l->state = 2;
    sample_random_loose_floor (l->p.room); l->i++; break;
  case 3: l->state = 0;
    l->action = NO_LOOSE_FLOOR_ACTION; l->i = 0; break;
  }
}
Example #4
0
void
compute_closer_floors (void)
{
  size_t i;

  for (i = 0; i < closer_floor_nmemb; i++) {
    struct closer_floor *c = &closer_floor[i];
    if (c->pressed && ! c->unresponsive) {
      if (! c->noise) {
        alert_guards (&c->p);
        play_sample (closer_floor_sample, &c->p, -1);
        c->noise = true;
      }
      close_door (c->p.l, c->event);
    } else c->noise = false;
  }
}
Example #5
0
void
compute_opener_floors (void)
{
  size_t i;

  for (i = 0; i < opener_floor_nmemb; i++) {
    struct opener_floor *o = &opener_floor[i];
    if (o->p.room == -1) {
      /* remove_opener_floor (o); i--; */
      continue;
    }
    if (o->pressed || o->broken) {
      if (! o->noise) {
        alert_guards (&o->p);
        play_sample (opener_floor_sample, o->p.room);
        o->noise = true;
      }
      open_door (o->event);
    } else o->noise = false;
  }
}
Example #6
0
void
compute_doors (void)
{
  size_t i;

  for (i = 0; i < door_nmemb; i++) {
    struct door *d = &door[i];
    switch (d->action) {
    case OPEN_DOOR:
      if (d->i == 0 && d->wait == 0) d->action = CLOSE_DOOR;
      else if (d->i == 0 && d->wait > 0) {
        if (! d->noise) {
          play_sample (door_end_sample, &d->p, -1);
          d->noise = true;
        }

        d->wait--;
      }
      else if (d->i > 0) {
        if (d->i % 2 == 0) {
          if (d->i == DOOR_MAX_STEP - 1) alert_guards (&d->p);
          play_sample (door_open_sample, &d->p, -1);
        }
        d->i--;
        d->wait = DOOR_WAIT;
        register_changed_pos (&d->p, CHPOS_OPEN_DOOR);
      }
      break;
    case CLOSE_DOOR:
      if (d->i < DOOR_MAX_STEP) {
        if (d->wait++ % 4 == 0) {
          if (d->i == 0) alert_guards (&d->p);
          play_sample (door_close_sample, &d->p, -1);
          d->i++;
          d->noise = false;
          register_changed_pos (&d->p, CHPOS_CLOSE_DOOR);
        }
      } else if (d->i == DOOR_MAX_STEP) {
        play_sample (door_end_sample, &d->p, -1);
        d->action = NO_DOOR_ACTION;
        d->wait = DOOR_WAIT;
        d->noise = false;
      }
      break;
    case ABRUPTLY_CLOSE_DOOR:
      if (d->i < DOOR_MAX_STEP) {
        int r = 11 - (d->i % 12);
        d->i += r ? r : 12;
        register_changed_pos (&d->p, CHPOS_ABRUPTLY_CLOSE_DOOR);
        if (d->i >= DOOR_MAX_STEP) {
          d->i = DOOR_MAX_STEP;
          alert_guards (&d->p);
          play_sample (door_abruptly_close_sample, &d->p, -1);
        }
      } else {
        d->action = NO_DOOR_ACTION;
        d->wait = DOOR_WAIT;
        d->noise = false;
      }
      break;
    default:
      break;
    }
  }
}
Example #7
0
void
compute_loose_floor_fall (struct loose_floor *l)
{
  int speed = 3 * ++l->i;
  if (speed > 29) speed = 29;

  struct frame nf;
  struct frame_offset fo;
  fo.b = l->f.b;
  fo.dx = 0;
  fo.dy = speed;
  next_frame (&l->f, &nf, &fo);
  struct coord mbo_f, mbo_nf;
  struct pos fpmbo_f, nfpmbo_f, fpmbo_nf, nfpmbo_nf;
  enum confg fcmbo_f;
  fcmbo_f = survey (_mbo, posf, &l->f, &mbo_f, &fpmbo_f, &nfpmbo_f)->fg;
  survey (_mbo, posf, &nf, &mbo_nf, &fpmbo_nf, &nfpmbo_nf);

  struct pos p;

  /* hit kid */
  int i;
  for (i = 0; i < anima_nmemb; i++) {
    struct coord kmt, ambo_f, ambo_nf; struct pos np, kpmt;
    struct anim *a = &anima[i];
    if (is_anim_dead (&a->f)
        || a->immortal
        || a->loose_floor_immune)
      continue;
    survey (_mt, pos, &a->f, &kmt, &kpmt, &np);
    coord2room (&mbo_f, kpmt.room, &ambo_f);
    coord2room (&mbo_nf, kpmt.room, &ambo_nf);
    if (peq (&nfpmbo_f, &kpmt)
        && ambo_f.y <= kmt.y
        && ambo_nf.y >= kmt.y
        && ! a->hit_by_loose_floor
        && ! is_kid_hang_or_climb (&a->f)
        && ! is_kid_fall (&a->f)) {
      a->hit_by_loose_floor = true;
      a->splash = true;
      a->current_lives--;
      a->uncouch_slowly = true;
      /* ensure kid doesn't couch in thin air (might occur when hit
         while jumping, for example) */
      place_on_the_ground (&a->f, &a->f.c);
      play_sample (hit_wall_sample, kpmt.room);
      alert_guards (&kpmt);
      if (a->id == current_kid_id) {
        video_effect.color = get_flicker_blood_color ();
        start_video_effect (VIDEO_FLICKERING, SECS_TO_VCYCLES (0.1));
      }
      if (a->current_lives <= 0) {
        a->p = kpmt;
        anim_die_suddenly (a);
        a->death_reason = LOOSE_FLOOR_DEATH;
      }
      else if (a->type == KID) kid_couch (a);
    }
  }

  /* fall */
  if (is_strictly_traversable (&fpmbo_f)
      || peq (&fpmbo_f, &fpmbo_nf)) {
    /* the floor hit a rigid structure */
    if (is_rigid_con (&fpmbo_nf)) prel (&fpmbo_nf, &p, -1, 0);
    /* the floor continue to fall */
    else {
      l->f = nf;
      if (is_strictly_traversable (&fpmbo_nf)) l->p = fpmbo_nf;
      must_sort = true;
      return;
    }
    /* the floor hit the ground */
  } else {
    struct loose_floor *m;
    p = fpmbo_f;
    switch (fcmbo_f) {
    case LOOSE_FLOOR: /* loose floor isn't ground */
      m = loose_floor_at_pos (&fpmbo_f);
      if (m) m->p.room = -1;
      must_remove = true;
      l->f = nf;
      l->f.b = get_correct_falling_loose_floor_bitmap (dv_broken_floor);
      l->p = fpmbo_f;
      l->i = 0;
      con (&fpmbo_f)->fg = NO_FLOOR;
      must_sort = true;
      play_sample (broken_floor_sample, p.room);
      alert_guards (&p);
      return;
    case OPENER_FLOOR: break_opener_floor (&fpmbo_f); break;
    case CLOSER_FLOOR: break_closer_floor (&fpmbo_f); break;
    case SPIKES_FLOOR: break_spikes_floor (&fpmbo_f); break;
    case LEVEL_DOOR: break_level_door (&fpmbo_f); break;
    default: break;
    }
  }

  /* reach here only if the floor hit a rigid structure or the
     ground */
  if (con (&p)->fg != LEVEL_DOOR) con (&p)->fg = BROKEN_FLOOR;
  shake_loose_floor_row (&p);
  l->p.room = -1;
  must_remove = true;
  must_sort = true;
  play_sample (broken_floor_sample, p.room);
  alert_guards (&p);
}
Example #8
0
void m_death(struct monster *m)
{
    pob corpse;
    pml ml;
    int x;
    int y;
    int found = FALSE;
    m->hp = -1;

    if(los_p(Player.x, Player.y, m->x, m->y)) {
        putspot(m->x, m->y, getspot(m->x, m->y, FALSE));
        gain_experience(m->xpv);
        calc_melee();

        if(m->uniqueness != COMMON) {
            strcpy(Str1, m->monstring);
        }
        else {
            strcpy(Str1, "The ");
            strcat(Str1, m->monstring);
        }

        strcat(Str1, " is dead!");
        mprint(Str1);
    }

    m_dropstuff(m);

    /* Death */
    if(m->id == (ML10 + 0)) {
        mprint("Death lies sprawled out on the ground...");
        mprint("Death laughs ironically and gets back to his feet.");
        mprint("He gestures and another scythe appears in his hands.");

        switch(random_range(10)) {
        case 0:
            mprint("Death performs a little bow and goes back on guard.");

            break;
        case 1:
            mprint("\'A hit! A palpable hit!\' Death goes back on the attack.");

            break;
        case 2:
            mprint("\'Ah, if only it could be so simple!\' snickers Death.");

            break;
        case 3:
            mprint("\'This fool things he can slay death! What a jest!\' says Death.");

            break;
        case 4:
            mprint("\'You point is well taken.\' says Death, attacking again.");

            break;
        case 5:
            mprint("\'Oh, come now, stop delaying the inevitable.\' says Death.");

            break;
        case 6:
            mprint("\'Your destiny ends here with me.\' says Death, scythe raised.");

            break;
        case 7:
            mprint("\'I almost felt that.\' says Death, smiling.");

            break;
        case 8:
            mprint("\'Timeo Mortis?\' asks Death quizzically, \'Not me!\'");

            break;
        case 9:
            mprint("Death sighs theatrically. \'They never learn.\'");

            break;
        }

        strengthen_death(m);
    }
    else {
        Level->site[m->x][m->y].creature = NULL;

        if(random_range(2) || (m->uniqueness != COMMON)) {
            corpse = (pob)malloc(sizeof(objtype));
            make_corpse(corpse, m);
            drop_at(m->x, m->y, corpse);
        }

        plotspot(m->x, m->y, FALSE);

        switch(m->id) {
        case ML0 + 8: /* Hiscore NPC */
            switch(m->aux2) {
            case 0:
                mprint("You hear a faroff dirge. You feel a sense of triumph.");

                break;
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
                mprint("You hear a faroff sound like angels crying...");
                strcpy(Priest[1], nameprint());
                Priestbehavior[1] = 2933;

                break;
            case 7:
                mprint("A furtive figure dashes out of the shadows, takes a look at");
                mprint("the corpse, and runs away!");
                strcpy(Shadowlord, nameprint());
                Shadowlordbehavior = 2912;

                break;
            case 8:
                mprint("An aide-de-camp approaches, removes the corpse's insignia,");
                mprint("and departs.");
                strcpy(Commandant, nameprint());
                Commandantbehavior = 2912;

                break;
            case 9:
                mprint("An odd glow surrounds the corpse, and slowly fades.");
                strcpy(Archmage, nameprint());
                Archmagebehavior = 2933;

                break;
            case 10:
                mprint("A demon materializes, takes a quick look at the corpse,");
                mprint("and teleports away with a faint popping noise.");
                strcpy(Prime, nameprint());
                Primebehavior = 2932;

                break;
            case 11:
                mprint("A sports columnist rushes forward and takes a quick photo");
                mprint("of the corpse and rushes off muttering about a deadline.");
                strcpy(Champion, nameprint());
                Championbehavior = 2913;

                break;
            case 12:
                mprint("You hear a fanfare in the distance, and feel dismayed.");
                strcpy(Duke, nameprint());
                Dukebehavior = 2911;

                break;
            case 13:
                if(Player.alignment > 10) {
                    mprint("You feel smug.");
                }
                else if(Player.alignment < 10) {
                    mprint("You feel ashamed.");
                }

                strcpy(Chaoslord, nameprint());
                Chaoslordbehavior = 2912;

                break;
            case 14:
                if(Player.alignment < 10) {
                    mprint("You feel smug.");
                }
                else if(Player.alignment > 10) {
                    mprint("You feel ashamed.");
                }

                strcpy(Lawlord, nameprint());
                Lawlordbehavior = 2911;

                break;
            case 15:
                /*
                 * Just a tad complicated. Promote a new justiciar if
                 * an guards are left in the city, otherwise destroy
                 * the Order!
                 */
                Player.alignment -= 100;

                if(!gamestatusp(DESTROYED_ORDER)) {
                    mprint("In the distance you hear a trumpet. A Servent of Law");
                    mprint("materializes, sheds a tear, and leaves.");
                    strcpy(Justiciar, nameprint());
                    Justiciarbehavior = 2911;

                    /* Promote one of the city guards to be justiciar */
                    ml = City->mlist;

                    while(!found && (ml != NULL)) {
                        if((ml->m->id == (ML0 + 3)) && (ml->m->hp > 0)) {
                            found = 1;
                        }
                        else {
                            found = 0;
                        }

                        if(!found) {
                            ml = ml->next;
                        }
                    }

                    if(ml != NULL) {
                        mprint("A new justiciar has been promoted!");
                        x = ml->m->x;
                        y = ml->m->y;
                        ml->m->x = x;
                        ml->m->y = y;
                        ml->m->click = (Tick + 1) % 60;
                        m_status_reset(ml->m, AWAKE);
                        m_status_reset(ml->m, HOSTILE);
                    }

                    /* 
                     * Will cause order to be destroyed if no guards or justiciar
                     */
                    alert_guards();
                }
                else {
                    mprint("A Servant of Chaos materializes, grabs the corpse,");
                    mprint("snickers a bit, and vanishes.");
                }
            }
            
            break;
        case ML0 + 3: /* Guard */
            Player.alignment -= 10;
            
            if((Current_Environment == E_CITY)
               || (Current_Environment == E_VILLAGE)) {
                alert_guards();
            }
            
            break;
        case ML3 + 5: /* Goblin king */
            if(!gamestatusp(ATTACKED_ORACLE)) {
                mprint("You seem to hear a woman's voice from far off:");
                mprint("\'Well don! Come to me now...\'");
            }
            
            setgamestatus(COMPLETED_CAVES);
            
            break;
        case ML7 + 5: /* Great worm */
            if(!gamestatusp(ATTACKED_ORACLE)) {
                mprint("A female voice sounds from just behind your ear:");
                mprint("\'Well fought! I have some new advice for you...\'");
            }
            
            setgamestatus(COMPLETED_SEWERS);
            
            break;
        case ML10 + 1:
            setgamestatus(KILLED_EATER);
            
            break;
        case ML10 + 2:
            setgamestatus(KILLED_LAWBRINGER);
            
            break;
        case ML10 + 3:
            setgamestatus(KILLED_DRAGONLORD);
            
            break;
        case ML10 + 4:
            setgamestatus(COMPLETED_VOLCANO);
            
            if(!gamestatusp(ATTACKED_ORACLE)) {
                mprint("You feel a soft touch on your shoulder...");
                mprint("You turn around but there is no one there!");
                mprint("You turn back and see a not: \'See me soon.\'");
                mprint("The note vanishes in a burst of blue fire!");
            }
            
            break;
        case ML10 + 9: /* Elemental master */
            if(!gamestatusp(ATTACKED_ORACLE)) {
                mprint("Words appear before you, traced in blue flame!");
                mprint("\'Return to the Prime Plane via the Circle of Sorcerors...");
            }
            
            break;
        }
    }
    
    dodrawspot(m->x, m->y);
}
Example #9
0
void
compute_spikes_floors (void)
{
  size_t i, j;
  struct pos pm;

  for (i = 0; i < spikes_floor_nmemb; i++) {
    struct spikes_floor *s = &spikes_floor[i];

    if (s->inactive) continue;

    int state = s->state;

    switch (s->i) {
    case 0: if (should_spikes_raise (&s->p) || s->activate) {
        alert_guards (&s->p);
        play_sample (spikes_sample, &s->p, -1);
        s->i++;
        s->wait = 12;
        s->state = 1;
      } else if (s->state != 0) s->state = 0;
      break;
    case 1:
      s->i++;
      s->state = 2;
      break;
    case 2:
      s->i++;
      s->state = 3;
      break;
    case 3:
      s->i++;
      s->state = 4;
      break;
    case 4: if (! should_spikes_raise (&s->p)) {
        if (s->wait-- == 0) {
          s->i++;
          s->state = 3;
        } else s->state = 5;
      } else {
        s->state = 5;
      }
      break;
    case 5:
      s->i++;
      s->state = 2;
      break;
    case 6:
      s->i = 0;
      s->state = 1;
      s->activate = false;
      break;
    }

    if (state != s->state)
      register_changed_pos (&s->p, CHPOS_SPIKES);

    /* spike kid */
    for (j = 0; j < anima_nmemb; j++) {
      struct anim *a = &anima[j];
      if (is_kid_dead (&a->f)
          || a->immortal
          || a->spikes_immune) continue;
      survey (_m, pos, &a->f, NULL, &pm, NULL);
      if (peq (&pm, &s->p)
          && (((s->state >= 2 && s->state <= 4)
               && (is_kid_start_run (&a->f)
                   || is_kid_run (&a->f)
                   || is_kid_run_jump_running (&a->f)))
              || (is_kid_couch (&a->f) && a->fall && a->i < 3
                  && ! a->float_timer)
              || (is_kid_jump_landing (&a->f) && a->i <= 13)
              || is_kid_run_jump_landing (&a->f))) {
        a->p = s->p;
        anim_die_spiked (a);
      }
    }
  }
}
Example #10
0
void
compute_choppers (void)
{
  size_t i, j;

  for (i = 0; i < chopper_nmemb; i++) {
    struct chopper *c = &chopper[i];

    if (c->inactive) continue;

    switch (c->i) {
    case 0:
      if (! c->alert) c->alert = ! should_chomp (&c->p);
      if ((c->wait-- <= 0 && should_chomp (&c->p)
           && (anim_cycle % CHOPPER_WAIT) ==
           prandom_pos (&c->p, CHOPPER_WAIT - 1))
          || c->activate) {
        c->i++;
        register_changed_pos (&c->p, CHPOS_CHOPPER);
      }
      break;
    case 1: c->i++;
      if (c->alert) {
        alert_guards (&c->p);
        c->alert = false;
      }
      play_sample (chopper_sample, &c->p, -1);
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    case 2:
      c->i++;
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    case 3:
      c->i++;
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    case 4: c->i = 0; c->wait = CHOPPER_WAIT; c->activate = false;
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    }

    if (c->i != 1 && c->i != 2 ) continue;

    /* chomp kid */
    for (j = 0; j < anima_nmemb; j++) {
      struct anim *a = &anima[j];
      if (a->type == MOUSE
          || is_anim_fall (&a->f)
          || a->immortal
          || a->chopper_immune
          || (a->action == kid_walk && a->walk != -1))
        continue;
      struct pos pbf, pbb;
      survey (_bf, pos, &a->f, NULL, &pbf, NULL);
      survey (_bb, pos, &a->f, NULL, &pbb, NULL);
      pos2room (&pbf, c->p.room, &pbf);
      pos2room (&pbb, c->p.room, &pbb);
      if ((((pbf.room == c->p.room
             && pbf.floor == c->p.floor)
            || (pbb.room == c->p.room
                && pbb.floor == c->p.floor))
           && ((a->f.dir == LEFT && pbf.place < c->p.place
                && pbb.place >= c->p.place)
               || (a->f.dir == RIGHT && pbf.place >= c->p.place
                   && pbb.place < c->p.place)))
          && (! is_anim_dead (&a->f) || ! is_anim_chopped (&a->f))) {
        if (a->type != SKELETON) c->blood = true;
        a->splash = true;
        a->p = c->p;
        a->death_reason = CHOPPER_DEATH;
        if (a->id == current_kid_id) {
          mr.flicker = 2;
          mr.color = get_flicker_blood_color ();
        }
        if (a->type == SKELETON)
          play_sample (skeleton_sample, &c->p, -1);
        else play_sample (chopped_sample, &c->p, -1);
        anim_die_chopped (a);
      }
    }
  }
}