Exemple #1
0
/**
 ** GM: TAKE <unit> <int> <itemtype>
 ** requires: permission-key "gmtake"
 **/
static void gm_take(const void *tnext, struct unit *u, struct order *ord)
{
  unit *to = findunit(getid());
  int num = getint();
  const item_type *itype = finditemtype(getstrtoken(), u->faction->locale);

  if (to == NULL || rplane(to->region) != rplane(u->region)) {
    /* unknown or in another plane */
    ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found",
        ""));
  } else if (itype == NULL || i_get(to->items, itype) == 0) {
    /* unknown or not enough */
    mistake(u, ord, "invalid item or item not found.");
  } else {
    /* checking permissions */
    attrib *permissions = a_find(u->faction->attribs, &at_permissions);
    if (!permissions || !has_permission(permissions, atoi36("gmtake"))) {
      mistake(u, ord, "permission denied.");
    } else {
      int i = i_get(to->items, itype);
      if (i < num)
        num = i;
      if (num) {
        i_change(&to->items, itype, -num);
        i_change(&u->items, itype, num);
      }
    }
  }
}
Exemple #2
0
static void test_tax_cmd(CuTest *tc) {
    order *ord;
    faction *f;
    region *r;
    unit *u;
    item_type *sword, *silver;
    request *taxorders = 0;


    test_cleanup();
    config_set("taxing.perlevel", "20");
    test_create_world();
    f = test_create_faction(NULL);
    r = findregion(0, 0);
    assert(r && f);
    u = test_create_unit(f, r);

    ord = create_order(K_TAX, f->locale, "");
    assert(ord);

    tax_cmd(u, ord, &taxorders);
    CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error48"));
    test_clear_messages(u->faction);

    silver = get_resourcetype(R_SILVER)->itype;

    sword = it_get_or_create(rt_get_or_create("sword"));
    new_weapontype(sword, 0, 0.0, NULL, 0, 0, 0, SK_MELEE, 1);
    i_change(&u->items, sword, 1);
    set_level(u, SK_MELEE, 1);

    tax_cmd(u, ord, &taxorders);
    CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_no_tax_skill"));
    test_clear_messages(u->faction);

    set_level(u, SK_TAXING, 1);
    tax_cmd(u, ord, &taxorders);
    CuAssertPtrEquals(tc, 0, test_find_messagetype(u->faction->msgs, "error_no_tax_skill"));
    CuAssertPtrNotNull(tc, taxorders);

    rsetmoney(r, 11);
    expandtax(r, taxorders);
    CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "income"));
    /* taxing is in multiples of 10 */
    CuAssertIntEquals(tc, 10, i_get(u->items, silver));
    test_clear_messages(u->faction);
    i_change(&u->items, silver, -i_get(u->items, silver));

    rsetmoney(r, 1000);
    taxorders = 0;
    tax_cmd(u, ord, &taxorders);
    expandtax(r, taxorders);
    CuAssertIntEquals(tc, 20, i_get(u->items, silver));
    test_clear_messages(u->faction);

    free_order(ord);
    test_cleanup();
}
Exemple #3
0
static int
use_museumexitticket(unit * u, const struct item_type *itype, int amount,
order * ord)
{
    attrib *a;
    region *r;
    unit *warden = findunit(atoi36("mwar"));
    int unit_cookie;

    unused_arg(amount);

    /* Prüfen ob in Eingangshalle */
    if (u->region->x != 9525 || u->region->y != 9525) {
        cmistake(u, ord, 266, MSG_MAGIC);
        return 0;
    }

    a = a_find(u->attribs, &at_museumexit);
    assert(a);
    r = findregion(a->data.sa[0], a->data.sa[1]);
    assert(r);
    a_remove(&u->attribs, a);
    /* Übergebene Gegenstände zurückgeben */

    a = a_find(u->attribs, &at_museumgivebackcookie);
    if (a) {
        unit_cookie = a->data.i;
        a_remove(&u->attribs, a);

        for (a = a_find(warden->attribs, &at_museumgiveback);
            a && a->type == &at_museumgiveback; a = a->next) {
            if (((museumgiveback *)(a->data.v))->cookie == unit_cookie)
                break;
        }
        if (a && a->type == &at_museumgiveback) {
            museumgiveback *gb = (museumgiveback *)(a->data.v);
            item *it;

            for (it = gb->items; it; it = it->next) {
                i_change(&u->items, it->type, it->number);
            }
            ADDMSG(&u->faction->msgs, msg_message("museumgiveback",
                "region unit sender items", r, u, warden, gb->items));
            a_remove(&warden->attribs, a);
        }
    }

    /* Benutzer zurück teleportieren */
    move_unit(u, r, NULL);

    /* Exitticket abziehen */
    i_change(&u->items, itype, -1);

    return 0;
}
Exemple #4
0
static void test_fishing_feeds_2_people(CuTest * tc)
{
    const resource_type *rtype;
    region *r;
    faction *f;
    unit *u;
    ship *sh;
    
    test_cleanup();
    test_create_world();
    r = findregion(-1, 0);
    CuAssertStrEquals(tc, "ocean", r->terrain->_name);    /* test_create_world needs coverage */
    f = test_create_faction(rc_find("human"));
    u = test_create_unit(f, r);
    sh = new_ship(st_find("boat"), r, 0);
    u_set_ship(u, sh);
    rtype = get_resourcetype(R_SILVER);
    i_change(&u->items, rtype->itype, 42);
    
    scale_number(u, 1);
    sh->flags |= SF_FISHING;
    get_food(r);
    CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype));

    scale_number(u, 2);
    sh->flags |= SF_FISHING;
    get_food(r);
    CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype));

    scale_number(u, 3);
    sh->flags |= SF_FISHING;
    get_food(r);
    CuAssertIntEquals(tc, 32, i_get(u->items, rtype->itype));
}
Exemple #5
0
static int
use_speedsail(struct unit *u, const struct item_type *itype, int amount,
struct order *ord)
{
    struct plane *p = rplane(u->region);
    unused_arg(amount);
    unused_arg(itype);
    if (p != NULL) {
        ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "use_realworld_only", ""));
    }
    else {
        if (u->ship) {
            attrib *a = a_find(u->ship->attribs, &at_speedup);
            if (a == NULL) {
                a = a_add(&u->ship->attribs, a_new(&at_speedup));
                a->data.sa[0] = 50;     /* speed */
                a->data.sa[1] = 50;     /* decay */
                ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit", u));
                /* Ticket abziehen */
                i_change(&u->items, itype, -1);
                return 0;
            }
            else {
                cmistake(u, ord, 211, MSG_EVENT);
            }
        }
        else {
            cmistake(u, ord, 144, MSG_EVENT);
        }
    }
    return EUNUSABLE;
}
Exemple #6
0
static void rotting_herbs(void)
{
    region *r;
    int rule_rot = config_get_int("rules.economy.herbrot", HERBROTCHANCE);
    if (rule_rot == 0) return;

    for (r = regions; r; r = r->next) {
        unit *u;
        for (u = r->units; u; u = u->next) {
            const struct item_type *it_bag = it_find("magicherbbag");
            item **itmp = &u->items;
            int rot_chance = rule_rot;

            if (it_bag && *i_find(itmp, it_bag)) {
                rot_chance = (rot_chance * 2) / 5;
            }
            while (*itmp) {
                item *itm = *itmp;
                int n = itm->number;
                double k = n * rot_chance / 100.0;
                if (fval(itm->type, ITF_HERB)) {
                    double nv = normalvariate(k, k / 4);
                    int inv = (int)nv;
                    int delta = _min(n, inv);
                    if (!i_change(itmp, itm->type, -delta)) {
                        continue;
                    }
                }
                itmp = &itm->next;
            }
        }
    }
}
Exemple #7
0
unit *addplayer(region * r, faction * f)
{
    unit *u;
    const char * name;

    assert(r->land);
    if (rpeasants(r) < PEASANT_MIN) {
        rsetpeasants(r, PEASANT_MIN + rng_int() % (PEASANT_MAX - PEASANT_MIN));
    }

    assert(f->units == NULL);
    faction_setorigin(f, 0, r->x, r->y);
    u = create_unit(r, f, 1, f->race, 0, NULL, NULL);
    u->thisorder = default_order(f->locale);
    unit_addorder(u, copy_order(u->thisorder));
    name = config_get("rules.equip_first");
    if (!equip_unit(u, name ? name : "first_unit")) {
        /* give every unit enough money to survive the first turn */
        i_change(&u->items, get_resourcetype(R_SILVER)->itype, maintenance_cost(u));
    }
    u->hp = unit_max_hp(u) * u->number;
    fset(u, UFL_ISNEW);
    if (f->race == get_race(RC_DAEMON)) {
        race_t urc;
        const race *rc;
        do {
            urc = (race_t)(rng_int() % MAXRACES);
            rc = get_race(urc);
        } while (rc == NULL || urc == RC_DAEMON || !playerrace(rc));
        u->irace = rc;
    }
    f->lastorders = 0;
    return u;
}
Exemple #8
0
static void test_dragon_attacks_the_rich(CuTest * tc)
{
    faction *f, *f2;
    region *r;
    unit *u, *m;
    const item_type *i_silver;

    init_language();
    create_monsters(&f, &f2, &r, &u, &m);

    guard(m, GUARD_TAX);
    set_level(m, SK_WEAPONLESS, 10);

    rsetmoney(r, 1);
    rsetmoney(findregion(1, 0), 0);
    i_silver = it_find("money");
    assert(i_silver);
    i_change(&u->items, i_silver, 5000);

    config_set("rules.monsters.attack_chance", "0.00001");

    plan_monsters(f2);

    CuAssertPtrNotNull(tc, find_order("ATTACKIERE 1", m));
    CuAssertPtrNotNull(tc, find_order("PLUENDERE", m));
    test_cleanup();
}
Exemple #9
0
void test_upkeep_from_pool(CuTest * tc)
{
    region *r;
    unit *u1, *u2;
    const item_type *i_silver;

    test_cleanup();
    test_create_world();

    i_silver = it_find("money");
    assert(i_silver);
    r = findregion(0, 0);
    u1 = test_create_unit(test_create_faction(test_create_race("human")), r);
	assert(u1);
    u2 = test_create_unit(u1->faction, r);
    assert(r && u1 && u2);

    set_param(&global.parameters, "rules.food.flags", "0");
    i_change(&u1->items, i_silver, 30);
    get_food(r);
    CuAssertIntEquals(tc, 10, i_get(u1->items, i_silver));
    CuAssertIntEquals(tc, 0, fval(u1, UFL_HUNGER));
    CuAssertIntEquals(tc, 0, fval(u2, UFL_HUNGER));
    get_food(r);
    CuAssertIntEquals(tc, 0, i_get(u1->items, i_silver));
    CuAssertIntEquals(tc, 0, fval(u1, UFL_HUNGER));
    CuAssertIntEquals(tc, UFL_HUNGER, fval(u2, UFL_HUNGER));

    test_cleanup();
}
Exemple #10
0
void test_upkeep_default(CuTest * tc)
{
    region *r;
    unit *u1, *u2;
    faction *f1, *f2;
    const item_type *i_silver;

    test_cleanup();
    test_create_world();

    i_silver = it_find("money");
    assert(i_silver);
    r = findregion(0, 0);
    f1 = test_create_faction(test_create_race("human"));
    f2 = test_create_faction(test_create_race("human"));
    assert(f1 && f2);
    u1 = test_create_unit(f1, r);
    u2 = test_create_unit(f2, r);
    assert(r && u1 && u2);

    set_param(&global.parameters, "rules.food.flags", "0");
    i_change(&u1->items, i_silver, 20);
    get_food(r);
    // since u1 and u2 are not allied, u1 should not help u2 with upkeep
    CuAssertIntEquals(tc, 10, i_get(u1->items, i_silver));
    CuAssertIntEquals(tc, 0, fval(u1, UFL_HUNGER));
    CuAssertIntEquals(tc, UFL_HUNGER, fval(u2, UFL_HUNGER));

    test_cleanup();
}
Exemple #11
0
static void test_all_spy_message(CuTest *tc) {
    spy_fixture fix;

    setup_spy(&fix);

    enable_skill(SK_MAGIC, true);
    set_level(fix.victim, SK_MINING, 2);
    set_level(fix.victim, SK_MAGIC, 2);
    create_mage(fix.victim, M_DRAIG);
    set_factionstealth(fix.victim, fix.spy->faction);

    item_type *itype;
    itype = it_get_or_create(rt_get_or_create("sword"));
    new_weapontype(itype, 0, 0.0, NULL, 0, 0, 0, SK_MELEE, 2);
    i_change(&fix.victim->items, itype, 1);

    spy_message(99, fix.spy, fix.victim);

    CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport"));
    CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_mage"));
    CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_skills"));
    CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_faction"));
    CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_items"));

    test_cleanup();
}
Exemple #12
0
static void gm_create(const void *tnext, struct unit *u, struct order *ord)
{
  int i;
  attrib *permissions = a_find(u->faction->attribs, &at_permissions);
  if (permissions)
    permissions = (attrib *) permissions->data.v;
  if (!permissions)
    return;
  i = getint();

  if (i > 0) {
    const char *iname = getstrtoken();
    const item_type *itype = finditemtype(iname, u->faction->locale);
    if (itype == NULL) {
      mistake(u, ord, "unknown item.");
    } else {
      attrib *a = a_find(permissions, &at_gmcreate);

      while (a && a->type == &at_gmcreate && a->data.v != (void *)itype)
        a = a->next;
      if (a)
        i_change(&u->items, itype, i);
      else
        mistake(u, ord, "your faction cannot create this item.");
    }
  }
}
Exemple #13
0
static void test_dragon_attacks_the_rich(CuTest * tc)
{
    faction *f, *f2;
    unit *u, *m;
    const item_type *i_silver;

    create_monsters(&f, &f2, &u, &m);
    init_resources();

    setguard(m, true);
    set_level(m, SK_WEAPONLESS, 10);

    rsetmoney(findregion(0, 0), 1);
    rsetmoney(findregion(1, 0), 0);
    i_silver = it_find("money");
    assert(i_silver);
    i_change(&u->items, i_silver, 5000);

    config_set("rules.monsters.attack_chance", "0.00001");

    plan_monsters(f2);

    CuAssertPtrNotNull(tc, find_order("attack 1", m));
    CuAssertPtrNotNull(tc, find_order("loot", m));
    test_cleanup();
}
Exemple #14
0
static int
use_museumticket(unit * u, const struct item_type *itype, int amount,
order * ord)
{
    attrib *a;
    region *r = u->region;
    plane *pl = rplane(r);

    unused_arg(amount);

    /* Pruefen ob in normaler Plane und nur eine Person */
    if (pl != get_homeplane()) {
        cmistake(u, ord, 265, MSG_MAGIC);
        return 0;
    }
    if (u->number != 1) {
        cmistake(u, ord, 267, MSG_MAGIC);
        return 0;
    }
    if (has_horses(u)) {
        cmistake(u, ord, 272, MSG_MAGIC);
        return 0;
    }

    /* In diesem Attribut merken wir uns, wohin die Einheit zurückgesetzt
     * wird, wenn sie das Museum verläßt. */

    a = a_add(&u->attribs, a_new(&at_museumexit));
    a->data.sa[0] = (short)r->x;
    a->data.sa[1] = (short)r->y;

    /* Benutzer in die Halle teleportieren */
    move_unit(u, findregion(9525, 9525), NULL);

    /* Ticket abziehen */
    i_change(&u->items, itype, -1);

    /* Benutzer ein Exitticket geben */
    i_change(&u->items, itype, 1);

    return 0;
}
Exemple #15
0
void warden_add_give(unit * src, unit * u, const item_type * itype, int n)
{
    attrib *aw = a_find(u->attribs, &at_warden);
    museumgiveback *gb = NULL;
    museumgivebackcookie *gbc;
    attrib *a;

    /* has the giver a cookie corresponding to the warden */
    for (a = a_find(src->attribs, &at_museumgivebackcookie);
        a && a->type == &at_museumgivebackcookie; a = a->next) {
        if (((museumgivebackcookie *)(a->data.v))->warden_no == u->no)
            break;
    }

    /* if not give it one */
    if (a == NULL || a->type != &at_museumgivebackcookie) {
        a = a_add(&src->attribs, a_new(&at_museumgivebackcookie));
        gbc = (museumgivebackcookie *)a->data.v;
        gbc->warden_no = u->no;
        gbc->cookie = aw->data.i;
        assert(aw->data.i < INT_MAX);
        aw->data.i++;
    }
    else {
        gbc = (museumgivebackcookie *)(a->data.v);
    }

    /* now we search for the warden's corresponding item list */
    for (a = a_find(u->attribs, &at_museumgiveback);
        a && a->type == &at_museumgiveback; a = a->next) {
        gb = (museumgiveback *)a->data.v;
        if (gb->cookie == gbc->cookie) {
            break;
        }
    }

    /* if there's none, give it one */
    if (!gb) {
        a = a_add(&u->attribs, a_new(&at_museumgiveback));
        gb = (museumgiveback *)a->data.v;
        gb->cookie = gbc->cookie;
    }

    /* now register the items */
    i_change(&gb->items, itype, n);

    /* done */

    /* this has a caveat: If the src-unit is destroyed while inside
     * the museum, the corresponding itemlist of the warden will never
     * be removed. to circumvent that in a generic way will be extremly
     * difficult. */
}
Exemple #16
0
static int giveitem_handle(trigger * t, void *data)
{
    /* call an event handler on giveitem.
     * data.v -> ( variant event, int timer )
     */
    giveitem_data *td = (giveitem_data *)t->data.v;
    if (td->u && td->u->number) {
        i_change(&td->u->items, td->itype, td->number);
    }
    else {
        log_error("could not perform giveitem::handle()\n");
    }
    UNUSED_ARG(data);
    return 0;
}
Exemple #17
0
int tolua_faction_add_item(lua_State * L)
{
    faction *self = (faction *)tolua_tousertype(L, 1, 0);
    const char *iname = tolua_tostring(L, 2, 0);
    int number = (int)tolua_tonumber(L, 3, 0);
    int result = -1;

    if (iname != NULL) {
        const resource_type *rtype = rt_find(iname);
        if (rtype && rtype->itype) {
            item *i = i_change(&self->items, rtype->itype, number);
            result = i ? i->number : 0;
        }                           /* if (itype!=NULL) */
    }
    lua_pushnumber(L, result);
    return 1;
}
Exemple #18
0
static void guardian_faction(plane * pl, int id)
{
    region *r;
    faction *f = findfaction(id);

    if (!f) {
        f = calloc(1, sizeof(faction));
        f->banner = _strdup("Sie dienen dem großen Wyrm");
        f->passw = _strdup(itoa36(rng_int()));
        set_email(&f->email, "*****@*****.**");
        f->name = _strdup("Igjarjuks Kundschafter");
        f->race = get_race(RC_ILLUSION);
        f->age = turn;
        f->locale = get_locale("de");
        f->options =
            want(O_COMPRESS) | want(O_REPORT) | want(O_COMPUTER) | want(O_ADRESSEN) |
            want(O_DEBUG);

        f->no = id;
        addlist(&factions, f);
        fhash(f);
    }
    if (f->race != get_race(RC_ILLUSION)) {
        assert(!"guardian id vergeben");
        exit(0);
    }
    f->lastorders = turn;
    f->alive = true;
    for (r = regions; r; r = r->next)
        if (getplane(r) == pl && rterrain(r) != T_FIREWALL) {
            unit *u;
            freset(r, RF_ENCOUNTER);
            for (u = r->units; u; u = u->next) {
                if (u->faction == f)
                    break;
            }
            if (u)
                continue;
            u = create_unit(r, f, 1, get_race(RC_GOBLIN), 0, NULL, NULL);
            set_string(&u->name, "Igjarjuks Auge");
            i_change(&u->items, it_find("roi"), 1);
            set_order(&u->thisorder, NULL);
            fset(u, UFL_ANON_FACTION);
            set_money(u, 1000);
        }
}
Exemple #19
0
static void test_give(CuTest * tc) {
    struct give env = { 0 };

    test_setup_ex(tc);
    env.f2 = env.f1 = test_create_faction(NULL);
    setup_give(&env);

    i_change(&env.src->items, env.itype, 10);
    CuAssertIntEquals(tc, 0, give_item(10, env.itype, env.src, env.dst, NULL));
    CuAssertIntEquals(tc, 0, i_get(env.src->items, env.itype));
    CuAssertIntEquals(tc, 10, i_get(env.dst->items, env.itype));

    CuAssertIntEquals(tc, -1, give_item(10, env.itype, env.src, env.dst, NULL));
    CuAssertIntEquals(tc, 0, i_get(env.src->items, env.itype));
    CuAssertIntEquals(tc, 10, i_get(env.dst->items, env.itype));
    test_teardown();
}
Exemple #20
0
static void give_special_items(unit *u, item **items) {
    item **iter = items;
    while (*iter) {
        item *itm = *iter;
        if (itm->number > 0 && itm->type->flags & ITF_NOTLOST) {
            i_change(&u->items, itm->type, itm->number);
            *iter = itm->next;
            if (iter == items) {
                *items = *iter;
            }
            i_free(itm);
        }
        else {
            iter = &itm->next;
        }
    }
}
Exemple #21
0
static void test_give_herbs(CuTest * tc) {
    struct give env = { 0 };
    struct order *ord;

    test_setup_ex(tc);
    env.f2 = env.f1 = test_create_faction(NULL);
    setup_give(&env);
    i_change(&env.src->items, env.itype, 10);

    ord = create_order(K_GIVE, env.f1->locale, "%s %s", itoa36(env.dst->no), LOC(env.f1->locale, parameters[P_HERBS]));
    assert(ord);

    give_cmd(env.src, ord);
    CuAssertIntEquals(tc, 0, i_get(env.src->items, env.itype));
    CuAssertIntEquals(tc, 10, i_get(env.dst->items, env.itype));
    free_order(ord);
    test_teardown();
}
Exemple #22
0
static void eaten_by_monster(unit * u)
{
    /* adjustment for smaller worlds */
    static double multi = 0.0;
    int n = 0;
    int horse = -1;
    const resource_type *rhorse = get_resourcetype(R_HORSE);
    if (multi == 0.0) {
        multi = RESOURCE_QUANTITY * newterrain(T_PLAIN)->size / 10000.0;
    }

    switch (old_race(u_race(u))) {
    case RC_FIREDRAGON:
        n = rng_int() % 80 * u->number;
        break;
    case RC_DRAGON:
        n = rng_int() % 200 * u->number;
        break;
    case RC_WYRM:
        n = rng_int() % 500 * u->number;
        break;
    default:
        n = rng_int() % (u->number / 20 + 1);
        horse = 0;
    }
    horse = horse ? i_get(u->items, rhorse->itype) : 0;

    n = (int)(n * multi);
    if (n > 0) {
        n = lovar(n);
        n = _min(rpeasants(u->region), n);

        if (n > 0) {
            deathcounts(u->region, n);
            rsetpeasants(u->region, rpeasants(u->region) - n);
            ADDMSG(&u->region->msgs, msg_message("eatpeasants", "unit amount", u, n));
        }
    }
    if (horse > 0) {
        i_change(&u->items, rhorse->itype, -horse);
        ADDMSG(&u->region->msgs, msg_message("eathorse", "unit amount", u, horse));
    }
}
Exemple #23
0
static void test_give_invalid_target(CuTest *tc) {
    /* bug https://bugs.eressea.de/view.php?id=1685 */
    struct give env = { 0 };
    order *ord;

    test_setup_ex(tc);
    env.f1 = test_create_faction(NULL);
    env.f2 = 0;
    setup_give(&env);

    i_change(&env.src->items, env.itype, 10);
    ord = create_order(K_GIVE, env.f1->locale, "## KRAUT");
    assert(ord);

    give_cmd(env.src, ord);
    CuAssertIntEquals(tc, 10, i_get(env.src->items, env.itype));
    CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_unit_not_found"));
    free_order(ord);
    test_teardown();
}
Exemple #24
0
void herbsearch(region * r, unit * u, int max)
{
  int herbsfound;
  const item_type *whichherb;

  if (eff_skill(u, SK_HERBALISM, r) == 0) {
    cmistake(u, u->thisorder, 59, MSG_PRODUCE);
    return;
  }

  if (is_guarded(r, u, GUARD_PRODUCE)) {
    cmistake(u, u->thisorder, 70, MSG_EVENT);
    return;
  }

  whichherb = rherbtype(r);
  if (whichherb == NULL) {
    cmistake(u, u->thisorder, 108, MSG_PRODUCE);
    return;
  }

  if (max)
    max = _min(max, rherbs(r));
  else
    max = rherbs(r);
  herbsfound = ntimespprob(eff_skill(u, SK_HERBALISM, r) * u->number,
    (double)rherbs(r) / 100.0F, -0.01F);
  herbsfound = _min(herbsfound, max);
  rsetherbs(r, rherbs(r) - herbsfound);

  if (herbsfound) {
    produceexp(u, SK_HERBALISM, u->number);
    i_change(&u->items, whichherb, herbsfound);
    ADDMSG(&u->faction->msgs, msg_message("herbfound",
        "unit region amount herb", u, r, herbsfound, whichherb->rtype));
  } else {
    ADDMSG(&u->faction->msgs, msg_message("researchherb_none",
        "unit region", u, u->region));
  }
}
Exemple #25
0
void do_markets(void)
{
    quicklist *traders = 0;
    unit *markets[MAX_MARKETS];
    region *r;
    for (r = regions; r; r = r->next) {
        if (r->land) {
            faction *f = region_get_owner(r);
            const struct race *rc = f ? f->race : NULL;
            int p = rpeasants(r);
            int numlux = rc_luxury_trade(rc), numherbs = rc_herb_trade(rc);
            numlux = (p + numlux - MIN_PEASANTS) / numlux;
            numherbs = (p + numherbs - MIN_PEASANTS) / numherbs;
            if (numlux > 0 || numherbs > 0) {
                int d, nmarkets = 0;
                const item_type *lux = r_luxury(r);
                const item_type *herb = r->land->herbtype;

                nmarkets += get_markets(r, markets + nmarkets, MAX_MARKETS - nmarkets);
                for (d = 0; d != MAXDIRECTIONS; ++d) {
                    region *r2 = rconnect(r, d);
                    if (r2 && r2->buildings) {
                        nmarkets +=
                            get_markets(r2, markets + nmarkets, MAX_MARKETS - nmarkets);
                    }
                }
                if (nmarkets) {
                    while (lux && numlux--) {
                        int n = rng_int() % nmarkets;
                        unit *u = markets[n];
                        item *items;
                        attrib *a = a_find(u->attribs, &at_market);
                        if (a == NULL) {
                            a = a_add(&u->attribs, a_new(&at_market));
                            ql_push(&traders, u);
                        }
                        items = (item *)a->data.v;
                        i_change(&items, lux, 1);
                        a->data.v = items;
                        /* give 1 luxury */
                    }
                    while (herb && numherbs--) {
                        int n = rng_int() % nmarkets;
                        unit *u = markets[n];
                        item *items;
                        attrib *a = a_find(u->attribs, &at_market);
                        if (a == NULL) {
                            a = a_add(&u->attribs, a_new(&at_market));
                            ql_push(&traders, u);
                        }
                        items = (item *)a->data.v;
                        i_change(&items, herb, 1);
                        a->data.v = items;
                        /* give 1 herb */
                    }
                }
            }
        }
    }

    if (traders) {
        quicklist *qliter = traders;
        int qli = 0;
        for (qli = 0; qliter; ql_advance(&qliter, &qli, 1)) {
            unit *u = (unit *)ql_get(qliter, qli);
            attrib *a = a_find(u->attribs, &at_market);
            item *items = (item *)a->data.v;

            a->data.v = NULL;
            while (items) {
                item *itm = items;
                items = itm->next;

                if (itm->number) {
                    ADDMSG(&u->faction->msgs, msg_message("buyamount",
                        "unit amount resource", u, itm->number, itm->type->rtype));
                    itm->next = NULL;
                    i_add(&u->items, itm);
                }
                else {
                    i_free(itm);
                }
            }

            a_remove(&u->attribs, a);
        }
        ql_free(traders);
    }
}
Exemple #26
0
int sp_undeadhero(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    region *r = b->region;
    selist *fgs, *ql;
    int qi, n, undead = 0;
    message *msg;
    int force = (int)get_force(power, 0);
    double c = 0.50 + 0.02 * power;

    /* Liste aus allen Kaempfern */
    fgs = select_fighters(b, fi->side, FS_ENEMY | FS_HELP, select_hero, NULL);
    scramble_fighters(fgs);

    for (qi = 0, ql = fgs; ql && force>0; selist_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)selist_get(ql, qi);
        unit *du = df->unit;
        int j = 0;

        /* Wieviele Untote koennen wir aus dieser Einheit wecken? */
        for (n = df->alive + df->run.number; force>0 && n != du->number; n++) {
            if (chance(c)) {
                ++j;
                --force;
            }
        }

        if (j > 0) {
            item **ilist;
            unit *u =
                create_unit(r, mage->faction, 0, get_race(RC_UNDEAD), 0, unit_getname(du),
                du);

            /* new units gets some stats from old unit */

            unit_setinfo(u, unit_getinfo(du));
            unit_setstatus(u, du->status);
            setguard(u, false);
            for (ilist = &du->items; *ilist;) {
                item *itm = *ilist;
                int loot = itm->number * j / du->number;
                if (loot != itm->number) {
                    int split = itm->number * j % du->number;
                    if (split > 0 && (rng_int() % du->number) < split) {
                        ++loot;
                    }
                }
                i_change(&u->items, itm->type, loot);
                i_change(ilist, itm->type, -loot);
                if (*ilist == itm) {
                    ilist = &itm->next;
                }
            }

            /* inherit stealth from magician */
            if (mage->flags & UFL_ANON_FACTION) {
                u->flags |= UFL_ANON_FACTION;
            }

            /* transfer dead people to new unit, set hitpoints to those of old unit */
            transfermen(du, u, j);
            u->hp = u->number * unit_max_hp(du);
            assert(j <= df->side->casualties);
            df->side->casualties -= j;
            df->side->dead -= j;

            /* counting total number of undead */
            undead += j;
        }
    }
    selist_free(fgs);

    if (level > undead) {
        level = undead;
    }
    if (undead == 0) {
        msg =
            msg_message("summonundead_effect_0", "mage region", mage, mage->region);
    }
    else {
        msg =
            msg_message("summonundead_effect_1", "mage region amount", mage,
            mage->region, undead);
    }

    message_all(b, msg);
    msg_release(msg);
    return level;
}
Exemple #27
0
static int
damage_unit(unit * u, const char *dam, bool physical, bool magic)
{
  int *hp = malloc(u->number * sizeof(int));
  int h;
  int i, dead = 0, hp_rem = 0, heiltrank;
  double magres = magic_resistance(u);

  assert(u->number);
  if (fval(u_race(u), RCF_ILLUSIONARY) || u_race(u) == get_race(RC_SPELL)) {
    return 0;
  }

  h = u->hp / u->number;
  /* HP verteilen */
  for (i = 0; i < u->number; i++)
    hp[i] = h;
  h = u->hp - (u->number * h);
  for (i = 0; i < h; i++)
    hp[i]++;

  /* Schaden */
  for (i = 0; i < u->number; i++) {
    int damage = dice_rand(dam);
    if (magic)
      damage = (int)(damage * (1.0 - magres));
    if (physical)
      damage -= nb_armor(u, i);
    hp[i] -= damage;
  }

  /* Auswirkungen */
  for (i = 0; i < u->number; i++) {
    if (hp[i] <= 0) {
      heiltrank = 0;

      /* Sieben Leben */
      if (old_race(u_race(u)) == RC_CAT && (chance(1.0 / 7))) {
        hp[i] = u->hp / u->number;
        hp_rem += hp[i];
        continue;
      }

      /* Heiltrank */
      if (oldpotiontype[P_HEAL]) {
        if (get_effect(u, oldpotiontype[P_HEAL]) > 0) {
          change_effect(u, oldpotiontype[P_HEAL], -1);
          heiltrank = 1;
        } else if (i_get(u->items, oldpotiontype[P_HEAL]->itype) > 0) {
          i_change(&u->items, oldpotiontype[P_HEAL]->itype, -1);
          change_effect(u, oldpotiontype[P_HEAL], 3);
          heiltrank = 1;
        }
        if (heiltrank && (chance(0.50))) {
          hp[i] = u->hp / u->number;
          hp_rem += hp[i];
          continue;
        }
      }
      dead++;
    } else {
      hp_rem += hp[i];
    }
  }

  scale_number(u, u->number - dead);
  u->hp = hp_rem;

  free(hp);

  return dead;
}
Exemple #28
0
/* Rosthauch */
int sp_combatrosthauch(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    battle *b = fi->side->battle;
    selist *ql, *fgs;
    int force = lovar(power * 15);
    int qi, k = 0;

    if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1,
        SELECT_ADVANCE | SELECT_FIND)) {
        message *msg = msg_message("rust_effect_0", "mage", fi->unit);
        message_all(b, msg);
        msg_release(msg);
        return 0;
    }

    fgs = select_fighters(b, fi->side, FS_ENEMY, select_armed, NULL);
    scramble_fighters(fgs);

    for (qi = 0, ql = fgs; force>0 && ql; selist_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)selist_get(ql, qi);
        int w;

        for (w = 0; df->weapons[w].type != NULL; ++w) {
            weapon *wp = df->weapons;
            if (df->unit->items && force > 0) {
                item ** itp = i_find(&df->unit->items, wp->type->itype);
                if (*itp) {
                    item *it = *itp;
                    requirement *mat = wp->type->itype->construction->materials;
                    int n = force;
                    if (it->number < n) n = it->number;

                    while (mat && mat->number > 0) {
                        if (mat->rtype == get_resourcetype(R_IRON)) {
                            int p;
                            force -= n;
                            k += n;
                            i_change(itp, wp->type->itype, -n);
                            for (p = 0; n && p != df->unit->number; ++p) {
                                if (df->person[p].melee == wp) {
                                    df->person[p].melee = NULL;
                                    --n;
                                }
                            }
                            for (p = 0; n && p != df->unit->number; ++p) {
                                if (df->person[p].missile == wp) {
                                    df->person[p].missile = NULL;
                                    --n;
                                }
                            }
                            break;
                        }
                        mat++;
                    }
                }
            }
        }
    }
    selist_free(fgs);

    if (k == 0) {
        /* keine Waffen mehr da, die zerstoert werden koennten */
        message *msg = msg_message("rust_effect_1", "mage", fi->unit);
        message_all(b, msg);
        msg_release(msg);
        fi->magic = 0;              /* kaempft nichtmagisch weiter */
        level = 0;
    }
    else {
        message *msg = msg_message("rust_effect_2", "mage", fi->unit);
        message_all(b, msg);
        msg_release(msg);
    }
    return level;
}
Exemple #29
0
/** give all items to friends or peasants.
 * this function returns 0 on success, or 1 if there are items that
 * could not be destroyed.
 */
int gift_items(unit * u, int flags)
{
  region *r = u->region;
  item **itm_p = &u->items;
  int retval = 0;
  int rule = rule_give();

  assert(u->region);
  assert(u->faction);

  if ((u->faction->flags & FFL_QUIT) == 0 || (rule & GIVE_ONDEATH) == 0) {
    if ((rule & GIVE_ALLITEMS) == 0 && (flags & GIFT_FRIENDS))
      flags -= GIFT_FRIENDS;
    if ((rule & GIVE_PEASANTS) == 0 && (flags & GIFT_PEASANTS))
      flags -= GIFT_PEASANTS;
    if ((rule & GIVE_SELF) == 0 && (flags & GIFT_SELF))
      flags -= GIFT_SELF;
  }

  if (u->items == NULL || fval(u_race(u), RCF_ILLUSIONARY))
    return 0;
  if ((u_race(u)->ec_flags & GIVEITEM) == 0)
    return 0;

  /* at first, I should try giving my crap to my own units in this region */
  if (u->faction && (u->faction->flags & FFL_QUIT) == 0 && (flags & GIFT_SELF)) {
    unit *u2, *u3 = NULL;
    for (u2 = r->units; u2; u2 = u2->next) {
      if (u2 != u && u2->faction == u->faction && u2->number > 0) {
        /* some units won't take stuff: */
        if (u_race(u2)->ec_flags & GETITEM) {
          /* we don't like to gift it to units that won't give it back */
          if (u_race(u2)->ec_flags & GIVEITEM) {
            i_merge(&u2->items, &u->items);
            u->items = NULL;
            break;
          } else {
            u3 = u2;
          }
        }
      }
    }
    if (u->items && u3) {
      /* if nobody else takes it, we give it to a unit that has issues */
      i_merge(&u3->items, &u->items);
      u->items = NULL;
    }
    if (u->items == NULL)
      return 0;
  }

  /* if I have friends, I'll try to give my stuff to them */
  if (u->faction && (flags & GIFT_FRIENDS)) {
    int number = 0;
    buddy *friends = get_friends(u, &number);

    while (friends) {
      struct buddy *nf = friends;
      unit *u2 = nf->unit;
      item *itm = u->items;
      while (itm != NULL) {
        const item_type *itype = itm->type;
        item *itn = itm->next;
        int n = itm->number;
        n = n * nf->number / number;
        if (n > 0) {
          i_change(&u->items, itype, -n);
          i_change(&u2->items, itype, n);
        }
        itm = itn;
      }
      number -= nf->number;
      friends = nf->next;
      free(nf);
    }
    if (u->items == NULL)
      return 0;
  }

  /* last, but not least, give money and horses to peasants */
  while (*itm_p) {
    item *itm = *itm_p;

    if (flags & GIFT_PEASANTS) {
      if (!fval(u->region->terrain, SEA_REGION)) {
        if (itm->type == olditemtype[I_HORSE]) {
          rsethorses(r, rhorses(r) + itm->number);
          itm->number = 0;
        } else if (itm->type == i_silver) {
          rsetmoney(r, rmoney(r) + itm->number);
          itm->number = 0;
        }
      }
    }
    if (itm->number > 0 && (itm->type->flags & ITF_NOTLOST)) {
      itm_p = &itm->next;
      retval = -1;
    } else {
      i_remove(itm_p, itm);
      i_free(itm);
    }
  }
  return retval;
}
Exemple #30
0
/** 
 * see https://bugs.eressea.de/view.php?id=2234
 */
static void test_maintain_buildings(CuTest *tc) {
    region *r;
    building *b;
    building_type *btype;
    unit *u;
    faction *f;
    maintenance *req;
    item_type *itype;

    test_cleanup();
    btype = test_create_buildingtype("Hort");
    btype->maxsize = 10;
    r = test_create_region(0, 0, 0);
    f = test_create_faction(0);
    u = test_create_unit(f, r);
    b = test_create_building(r, btype);
    itype = test_create_itemtype("money");
    b->size = btype->maxsize;
    u_set_building(u, b);

    // this building has no upkeep, it just works:
    b->flags = 0;
    maintain_buildings(r);
    CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED));
    CuAssertPtrEquals(tc, 0, f->msgs);
    CuAssertPtrEquals(tc, 0, r->msgs);

    req = calloc(2, sizeof(maintenance));
    req[0].number = 100;
    req[0].rtype = itype->rtype;
    btype->maintenance = req;

    // we cannot afford to pay:
    b->flags = 0;
    maintain_buildings(r);
    CuAssertIntEquals(tc, 0, fval(b, BLD_MAINTAINED));
    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "maintenancefail"));
    CuAssertPtrNotNull(tc, test_find_messagetype(r->msgs, "maintenance_nowork"));
    test_clear_messagelist(&f->msgs);
    test_clear_messagelist(&r->msgs);
    
    // we can afford to pay:
    i_change(&u->items, itype, 100);
    b->flags = 0;
    maintain_buildings(r);
    CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED));
    CuAssertIntEquals(tc, 0, i_get(u->items, itype));
    CuAssertPtrEquals(tc, 0, r->msgs);
    CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "maintenance_nowork"));
    CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "maintenance"));
    test_clear_messagelist(&f->msgs);

    // this building has no owner, it doesn't work:
    u_set_building(u, NULL);
    b->flags = 0;
    maintain_buildings(r);
    CuAssertIntEquals(tc, 0, fval(b, BLD_MAINTAINED));
    CuAssertPtrEquals(tc, 0, f->msgs);
    CuAssertPtrNotNull(tc, test_find_messagetype(r->msgs, "maintenance_noowner"));
    test_clear_messagelist(&r->msgs);

    test_cleanup();
}