Exemplo n.º 1
0
static order *monster_move(region * r, unit * u)
{
    direction_t d = NODIRECTION;

    if (monster_is_waiting(u)) {
        return NULL;
    }
    switch (old_race(u_race(u))) {
    case RC_FIREDRAGON:
    case RC_DRAGON:
    case RC_WYRM:
        d = richest_neighbour(r, u->faction, 1);
        break;
    case RC_TREEMAN:
        d = treeman_neighbour(r);
        break;
    default:
        d = random_neighbour(r, u);
        break;
    }

    /* falls kein geld gefunden wird, zufaellig verreisen, aber nicht in
     * den ozean */

    if (d == NODIRECTION)
        return NULL;

    reduce_weight(u);
    return create_order(K_MOVE, u->faction->locale, "%s",
        LOC(u->faction->locale, directions[d]));
}
Exemplo n.º 2
0
static order *monster_attack(unit * u, const unit * target)
{
    assert(u->region == target->region);
    assert(u->faction != target->faction);
    if (!cansee(u->faction, u->region, target, 0))
        return NULL;
    if (monster_is_waiting(u))
        return NULL;

    return create_order(K_ATTACK, u->faction->locale, "%i", target->no);
}
Exemplo n.º 3
0
void monster_kills_peasants(unit * u)
{
    if (!monster_is_waiting(u)) {
        if (u_race(u)->flags & RCF_SCAREPEASANTS) {
            scared_by_monster(u);
        }
        if (u_race(u)->flags & RCF_KILLPEASANTS) {
            eaten_by_monster(u);
        }
        if (u_race(u)->flags & RCF_ABSORBPEASANTS) {
            absorbed_by_monster(u);
        }
    }
}
Exemplo n.º 4
0
static order *make_movement_order(unit * u, const region * target, int moves,
    bool(*allowed) (const region *, const region *))
{
    region *r = u->region;
    region **plan;
    int bytes, position = 0;
    char zOrder[128], *bufp = zOrder;
    size_t size = sizeof(zOrder) - 1;

    if (monster_is_waiting(u))
        return NULL;

    plan = path_find(r, target, DRAGON_RANGE * 5, allowed);
    if (plan == NULL)
        return NULL;

    bytes =
        (int)strlcpy(bufp,
        (const char *)LOC(u->faction->locale, keyword(K_MOVE)), size);
    if (wrptr(&bufp, &size, bytes) != 0)
        WARN_STATIC_BUFFER();

    while (position != moves && plan[position + 1]) {
        region *prev = plan[position];
        region *next = plan[++position];
        direction_t dir = reldirection(prev, next);
        assert(dir != NODIRECTION && dir != D_SPECIAL);
        if (size > 1) {
            *bufp++ = ' ';
            --size;
        }
        bytes =
            (int)strlcpy(bufp,
            (const char *)LOC(u->faction->locale, directions[dir]), size);
        if (wrptr(&bufp, &size, bytes) != 0)
            WARN_STATIC_BUFFER();
    }

    *bufp = 0;
    return parse_order(zOrder, u->faction->locale);
}
Exemplo n.º 5
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();
}