示例#1
0
void
apply_guard_mode (struct anim *g, enum gm gm)
{
    if (! is_guard (g)) return;
    switch (gm) {
    case ORIGINAL_GM:
        g->type = g->original_type;
        break;
    case GUARD_GM:
        g->type = GUARD;
        break;
    case FAT_GUARD_GM:
        g->type = FAT_GUARD;
        break;
    case VIZIER_GM:
        g->type = VIZIER;
        break;
    case SKELETON_GM:
        g->type = SKELETON;
        break;
    case SHADOW_GM:
        g->type = SHADOW;
        break;
    }
}
示例#2
0
void
draw_guard_frame (ALLEGRO_BITMAP *bitmap, struct anim *g, enum vm vm)
{
    struct coord c;

    if (! is_guard (g)) return;
    if (g->invisible) return;

    struct frame f = g->f;
    struct frame_offset xf = g->xf;

    f.b = apply_guard_palette (f.b, g->type, g->style, vm);
    xf.b = apply_guard_palette (xf.b, g->type, g->style, vm);

    draw_xframe (bitmap, &f, &xf);
    draw_frame (bitmap, &f);

    if (g->splash && g->type != SKELETON) {
        ALLEGRO_BITMAP *splash = (g->type == SHADOW) ? v_kid_splash : guard_splash;
        palette pal = get_guard_palette (g->style, vm);
        splash = apply_palette (splash, pal);
        if (hgc) splash = apply_palette (splash, hgc_palette);
        draw_bitmapc (splash, bitmap, splash_coord (&g->f, &c), g->f.flip);
    }
}
示例#3
0
void
draw_guard_lives (ALLEGRO_BITMAP *bitmap, struct anim *g, enum vm vm)
{
    if (g->dont_draw_lives) return;
    if (g->current_lives <= 0) return;

    int current_lives = (g->current_lives > 10)
                        ? 10 : g->current_lives;

    int i;
    struct coord c;
    struct rect r;
    new_rect (&r, room_view, ORIGINAL_WIDTH - 7 * current_lives,
              ORIGINAL_HEIGHT - 8, 7 * current_lives,
              ORIGINAL_HEIGHT - 1);

    ALLEGRO_COLOR bg_color;

    switch (vm) {
    case CGA:
        bg_color = C_LIVES_RECT_COLOR;
        break;
    case EGA:
        bg_color = E_LIVES_RECT_COLOR;
        break;
    case VGA:
        bg_color = V_LIVES_RECT_COLOR;
        break;
    }

    draw_filled_rect (bitmap, &r, bg_color);

    ALLEGRO_BITMAP *life = guard_life;
    palette pal = NULL;

    if ((g->type == SHADOW && g->style == 0)
            || g->type == KID) {
        pal = get_shadow_life_palette (vm);
        life = apply_palette (life, pal);
    } else if (g->type == SKELETON && g->style == 0)
        life = apply_palette (life, skeleton_life_palette);
    else if (is_guard (g)) {
        pal = get_guard_palette (g->style, vm);
        life = apply_palette (life, pal);
    }

    if (hgc) life = apply_palette (life, hgc_palette);

    for (i = 0; i < current_lives; i++)
        draw_bitmapc (life, bitmap, guard_life_coord (i, &c), 0);
}
示例#4
0
文件: fight.c 项目: oitofelix/mininim
void
alert_guards (struct pos *p)
{
  int i;
  for (i = 0; i < anima_nmemb; i++) {
    struct anim *g = &anima[i];
    if (is_guard (g) && is_pos_on_back (g, p)
        && g->current_lives > 0 && g->enemy_id == -1
        && abs (anim_cycle - g->alert_cycle) > 24) {
      invert_frame_dir (&g->f, &g->f);
      g->alert_cycle = anim_cycle;
    }
  }
}
示例#5
0
文件: build.c 项目: Xolgrim/server
static void destroy_road(unit * u, int nmax, struct order *ord)
{
    char token[128];
    const char *s = gettoken(token, sizeof(token));
    direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION;
    if (d == NODIRECTION) {
        /* Die Richtung wurde nicht erkannt */
        cmistake(u, ord, 71, MSG_PRODUCE);
    }
    else {
        unit *u2;
        region *r = u->region;
        short road, n = (short)nmax;

        if (nmax > SHRT_MAX) {
            n = SHRT_MAX;
        }
        else if (nmax < 0) {
            n = 0;
        }

        for (u2 = r->units; u2; u2 = u2->next) {
            if (u2->faction != u->faction && is_guard(u2, GUARD_TAX)
                && cansee(u2->faction, u->region, u, 0)
                && !alliedunit(u, u2->faction, HELP_GUARD)) {
                cmistake(u, ord, 70, MSG_EVENT);
                return;
            }
        }

        road = rroad(r, d);
        n = _min(n, road);
        if (n != 0) {
            region *r2 = rconnect(r, d);
            int willdo = eff_skill(u, SK_ROAD_BUILDING, r) * u->number;
            willdo = _min(willdo, n);
            if (willdo == 0) {
                /* TODO: error message */
            }
            if (willdo > SHRT_MAX)
                road = 0;
            else
                road = road - (short)willdo;
            rsetroad(r, d, road);
            ADDMSG(&u->faction->msgs, msg_message("destroy_road",
                "unit from to", u, r, r2));
        }
    }
}
示例#6
0
static bool is_guardian_u(const unit * guard, unit * u)
{
    if (guard->faction == u->faction)
        return false;
    if (is_guard(guard) == 0)
        return false;
    if (alliedunit(guard, u->faction, HELP_GUARD))
        return false;
    if (ucontact(guard, u))
        return false;
    if (!cansee(guard->faction, u->region, u, 0))
        return false;
    if (!(u_race(guard)->flags & RCF_FLY) && u_race(u)->flags & RCF_FLY)
        return false;

    return true;
}
示例#7
0
static order *get_money_for_dragon(region * r, unit * udragon, int wanted)
{
    int n;
    bool attacks = attack_chance > 0.0;

    /* falls genug geld in der region ist, treiben wir steuern ein. */
    if (rmoney(r) >= wanted) {
        /* 5% chance, dass der drache aus einer laune raus attackiert */
        if (!attacks || chance(1.0 - u_race(udragon)->aggression)) {
            /* Drachen haben in E3 und E4 keine Einnahmen. Neuer Befehl Pluendern erstmal nur fuer Monster?*/
            return create_order(K_LOOT, default_locale, NULL);
        }
    }

    /* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an
     * und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */
    n = 0;
    if (attacks && is_guard(udragon, GUARD_TAX)) {
        unit *u;
        for (u = r->units; u; u = u->next) {
            if (u->faction != udragon->faction && cansee(udragon->faction, r, u, 0) && !in_safe_building(u, udragon)) {
                int m = get_money(u);
                if (m != 0) {
                    order *ord = monster_attack(udragon, u);
                    if (ord) {
                        addlist(&udragon->orders, ord);
                        n += m;
                    }
                }
            }
        }
    }

    /* falls die einnahmen erreicht werden, bleibt das monster noch eine */
    /* runde hier. */
    if (n + rmoney(r) >= wanted) {
        return create_order(K_LOOT, default_locale, NULL);
    }

    /* wenn wir NULL zurueckliefern, macht der drache was anderes, z.b. weggehen */
    return NULL;
}
示例#8
0
文件: fight.c 项目: oitofelix/mininim
void
fight_hit (struct anim *k, struct anim *ke)
{
  if (k->immortal || k->sword_immune) return;
  if (k->current_lives <= 0) return;
  if (is_anim_fall (&k->f) || is_kid_stairs (&k->f))
    return;

  place_on_the_ground (&k->f, &k->f.c);
  k->xf.b = NULL;

  if (! is_in_fight_mode (k)) k->current_lives = 0;
  else k->current_lives--;

  if (! is_guard (ke))
    upgrade_skill (&ke->skill, &k->skill, k->total_lives);

  int d = (k->f.dir == LEFT) ? +1 : -1;
  struct pos pb;
  survey (_m, pos, &k->f, NULL, &k->p, NULL);
  prel (&k->p, &pb, 0, d);

  if (k->current_lives <= 0 && ! is_strictly_traversable (&pb)) {
    k->current_lives = 0;
    k->death_reason = FIGHT_DEATH;
    ke->alert_cycle = anim_cycle;
    anim_die (k);
  } else anim_sword_hit (k);

  if (is_in_fight_mode (k)) {
    backoff_from_range (ke, k, ATTACK_RANGE - 20, true, false);
    get_in_range (ke, k, ATTACK_RANGE - 10, false, false);
  }

  k->splash = true;

  if (k->id == current_kid_id) {
    mr.flicker = 2;
    mr.color = get_flicker_blood_color ();
    play_audio (&harm_audio, NULL, k->id);
  } else play_audio (&guard_hit_audio, NULL, k->id);
}
示例#9
0
void plan_monsters(faction * f)
{
    region *r;
    
    assert(f);
    attack_chance = get_param_flt(global.parameters, "rules.monsters.attack_chance", 0.4);
    f->lastorders = turn;

    for (r = regions; r; r = r->next) {
        unit *u;
        bool attacking = false;

        for (u = r->units; u; u = u->next) {
            attrib *ta;
            order *long_order = NULL;

            /* Ab hier nur noch Befehle für NPC-Einheiten. */
            if (!is_monsters(u->faction))
                continue;

            /* Befehle müssen jede Runde neu gegeben werden: */
            free_orders(&u->orders);
            if (skill_enabled(SK_PERCEPTION)) {
                /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */
                /* TODO: this only works for playerrace */
                produceexp(u, SK_PERCEPTION, u->number);
            }

            if (!attacking) {
                if (chance(attack_chance)) attacking = true;
            }
            if (u->status > ST_BEHIND) {
                setstatus(u, ST_FIGHT);
                /* all monsters fight */
            }
            if (attacking && (!r->land || is_guard(u, GUARD_TAX))) {
                monster_attacks(u);
            }
            /* units with a plan to kill get ATTACK orders: */
            ta = a_find(u->attribs, &at_hate);
            if (ta && !monster_is_waiting(u)) {
                unit *tu = (unit *)ta->data.v;
                if (tu && tu->region == r) {
                    order * ord = monster_attack(u, tu);
                    if (ord) {
                        addlist(&u->orders, ord);
                    }
                }
                else if (tu) {
                    tu = findunitg(ta->data.i, NULL);
                    if (tu != NULL) {
                        long_order = make_movement_order(u, tu->region, 2, allowed_walk);
                    }
                }
                else
                    a_remove(&u->attribs, ta);
            }

            /* All monsters guard the region: */
            if (!monster_is_waiting(u) && r->land) {
                addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL));
            }

            /* Einheiten mit Bewegungsplan kriegen ein NACH: */
            if (long_order == NULL) {
                attrib *ta = a_find(u->attribs, &at_targetregion);
                if (ta) {
                    if (u->region == (region *)ta->data.v) {
                        a_remove(&u->attribs, ta);
                    }
                }
                else if (u_race(u)->flags & RCF_MOVERANDOM) {
                    if (rng_int() % 100 < MOVECHANCE || check_overpopulated(u)) {
                        long_order = monster_move(r, u);
                    }
                }
            }

            if (long_order == NULL && unit_can_study(u)) {
                /* Einheiten, die Waffenlosen Kampf lernen könnten, lernen es um
                 * zu bewachen: */
                if (u_race(u)->bonus[SK_WEAPONLESS] != -99) {
                    if (effskill(u, SK_WEAPONLESS, 0) < 1) {
                        long_order =
                            create_order(K_STUDY, f->locale, "'%s'",
                            skillname(SK_WEAPONLESS, f->locale));
                    }
                }
            }

            if (long_order == NULL) {
                /* Ab hier noch nicht generalisierte Spezialbehandlungen. */

                if (!u->orders) {
                    handle_event(u->attribs, "ai_move", u);
                }

                switch (old_race(u_race(u))) {
                case RC_SEASERPENT:
                    long_order = create_order(K_PIRACY, f->locale, NULL);
                    break;
#ifdef TODO_ALP
                case RC_ALP:
                    long_order = monster_seeks_target(r, u);
                    break;
#endif
                case RC_FIREDRAGON:
                case RC_DRAGON:
                case RC_WYRM:
                    long_order = plan_dragon(u);
                    break;
                default:
                    if (u_race(u)->flags & RCF_LEARN) {
                        long_order = monster_learn(u);
                    }
                    break;
                }
            }
            if (long_order) {
                addlist(&u->orders, long_order);
            }
        }
    }
    pathfinder_cleanup();
}