special cases, not callbacks, for money and horses.

This commit is contained in:
Enno Rehling 2017-03-03 19:17:20 +01:00
parent af28da365d
commit d976ee6f67
9 changed files with 57 additions and 71 deletions

View file

@ -70,9 +70,7 @@
</resource> </resource>
<resource name="elvenhorse"> <resource name="elvenhorse">
<item weight="5000" notlost="yes" big="yes" score="6000" capacity="7000" animal="yes"> <item weight="5000" notlost="yes" big="yes" score="6000" capacity="7000" animal="yes"/>
<function name="give" value="givehorses"/>
</item>
</resource> </resource>
<resource name="dolphin"> <resource name="dolphin">

View file

@ -1,7 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<resource name="horse" limited="yes"> <resource name="horse" limited="yes">
<item big="yes" weight="5000" score="10" capacity="7000" animal="yes"> <item big="yes" weight="5000" score="10" capacity="7000" animal="yes">
<construction skill="training" minskill="1"/> <construction skill="training" minskill="1" />
<function name="give" value="givehorses"/>
</item> </item>
</resource> </resource>

View file

@ -62,13 +62,12 @@
</resource> </resource>
<resource name="charger"> <resource name="charger">
<item big="yes" weight="5000" score="10" capacity="7000" animal="yes"> <item big="yes" weight="5000" score="20" capacity="7000" animal="yes">
<construction skill="training" minskill="4"> <construction skill="training" minskill="4">
<requirement type="money" quantity="200"/> <requirement type="money" quantity="200"/>
<requirement type="iron" quantity="1"/> <requirement type="iron" quantity="1"/>
<requirement type="horse" quantity="1"/> <requirement type="horse" quantity="1"/>
</construction> </construction>
<function name="give" value="givehorses"/>
</item> </item>
</resource> </resource>

View file

@ -1035,14 +1035,14 @@ function test_give_horses()
local u = unit.create(f, r, 1) local u = unit.create(f, r, 1)
r:set_resource("horse", 0) r:set_resource("horse", 0)
u:add_item("horse", 20) u:add_item("horse", 21)
u:add_item("dolphin", 10) u:add_item("dolphin", 10)
u:add_order("GIB 0 10 PFERD") u:add_order("GIB 0 7 PFERD")
u:add_order("GIB 0 5 DELPHIN") u:add_order("GIB 0 5 DELPHIN")
process_orders() process_orders()
assert_equal(10, r:get_resource("horse")) assert_equal(7, r:get_resource("horse"))
assert_equal(5, u:get_item("dolphin")) assert_equal(5, u:get_item("dolphin"))
assert_equal(10, u:get_item("horse")) assert_equal(14, u:get_item("horse"))
end end
function test_give_silver() function test_give_silver()

View file

@ -19,6 +19,7 @@
/* kernel includes */ /* kernel includes */
#include <kernel/ally.h> #include <kernel/ally.h>
#include <kernel/build.h>
#include <kernel/curse.h> #include <kernel/curse.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/item.h> #include <kernel/item.h>
@ -147,17 +148,45 @@ int give_quota(const unit * src, const unit * dst, const item_type * type,
return n; return n;
} }
static int
give_horses(unit * s, unit * d, const item_type * itype, int n,
struct order *ord)
{
if (d == NULL) {
region *r = s->region;
if (r->land) {
rsethorses(r, rhorses(r) + n);
}
return 0;
}
return -1; /* use the mechanism */
}
static int
give_money(unit * s, unit * d, const item_type * itype, int n,
struct order *ord)
{
if (d == NULL) {
region *r = s->region;
if (r->land) {
rsetmoney(r, rmoney(r) + n);
}
return 0;
}
return -1; /* use the mechanism */
}
int int
give_item(int want, const item_type * itype, unit * src, unit * dest, give_item(int want, const item_type * itype, unit * src, unit * dest,
struct order *ord) struct order *ord)
{ {
short error = 0; short error = 0;
int n, r; int n, delta;
assert(itype != NULL); assert(itype != NULL);
n = get_pooled(src, item2resource(itype), GET_SLACK | GET_POOLED_SLACK, want); n = get_pooled(src, item2resource(itype), GET_SLACK | GET_POOLED_SLACK, want);
n = MIN(want, n); n = MIN(want, n);
r = n; delta = n;
if (dest && src->faction != dest->faction if (dest && src->faction != dest->faction
&& src->faction->age < GiveRestriction()) { && src->faction->age < GiveRestriction()) {
if (ord != NULL) { if (ord != NULL) {
@ -178,18 +207,19 @@ struct order *ord)
else if (itype->flags & ITF_CURSED) { else if (itype->flags & ITF_CURSED) {
error = 25; error = 25;
} }
else if (itype->give == NULL || itype->give(src, dest, itype, n, ord) != 0) { else {
int use = use_pooled(src, item2resource(itype), GET_SLACK, n); int use = use_pooled(src, item2resource(itype), GET_SLACK, n);
if (use < n) if (use < n)
use += use +=
use_pooled(src, item2resource(itype), GET_POOLED_SLACK, use_pooled(src, item2resource(itype), GET_POOLED_SLACK,
n - use); n - use);
if (dest) { if (dest) {
r = give_quota(src, dest, itype, n); delta = give_quota(src, dest, itype, n);
i_change(&dest->items, itype, r); i_change(&dest->items, itype, delta);
#ifdef RESERVE_GIVE #ifdef RESERVE_GIVE
#ifdef RESERVE_DONATIONS #ifdef RESERVE_DONATIONS
change_reservation(dest, itype, r); change_reservation(dest, itype, delta);
#else #else
if (src->faction == dest->faction) { if (src->faction == dest->faction) {
change_reservation(dest, item2resource(itype), r); change_reservation(dest, item2resource(itype), r);
@ -199,14 +229,25 @@ struct order *ord)
#if MUSEUM_MODULE && defined(TODO) #if MUSEUM_MODULE && defined(TODO)
/* TODO: use a trigger for the museum warden! */ /* TODO: use a trigger for the museum warden! */
if (a_find(dest->attribs, &at_warden)) { if (a_find(dest->attribs, &at_warden)) {
warden_add_give(src, dest, itype, r); warden_add_give(src, dest, itype, delta);
} }
#endif #endif
handle_event(dest->attribs, "receive", src); handle_event(dest->attribs, "receive", src);
} }
else {
/* return horses to the region */
if (itype->construction && itype->flags & ITF_ANIMAL) {
if (itype->construction->skill == SK_HORSE_TRAINING) {
give_horses(src, dest, itype, n, ord);
}
}
else if (itype->rtype == get_resourcetype(R_SILVER)) {
give_money(src, dest, itype, n, ord);
}
}
handle_event(src->attribs, "give", dest); handle_event(src->attribs, "give", dest);
} }
add_give(src, dest, n, r, item2resource(itype), ord, error); add_give(src, dest, n, delta, item2resource(itype), ord, error);
if (error) if (error)
return -1; return -1;
return 0; return 0;

View file

@ -565,46 +565,6 @@ item *i_new(const item_type * itype, int size)
#include "region.h" #include "region.h"
static int
give_horses(unit * s, unit * d, const item_type * itype, int n,
struct order *ord)
{
if (d == NULL) {
int use = use_pooled(s, item2resource(itype), GET_SLACK, n);
region *r = s->region;
if (use < n) {
use +=
use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK,
n - use);
}
if (r->land) {
rsethorses(r, rhorses(r) + use);
}
return 0;
}
return -1; /* use the mechanism */
}
static int
give_money(unit * s, unit * d, const item_type * itype, int n,
struct order *ord)
{
if (d == NULL) {
int use = use_pooled(s, item2resource(itype), GET_SLACK, n);
region *r = s->region;
if (use < n) {
use +=
use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK,
n - use);
}
if (r->land) {
rsetmoney(r, rmoney(r) + use);
}
return 0;
}
return -1; /* use the mechanism */
}
#define R_MINOTHER R_SILVER #define R_MINOTHER R_SILVER
#define R_MINHERB R_PLAIN_1 #define R_MINHERB R_PLAIN_1
#define R_MINPOTION R_FAST #define R_MINPOTION R_FAST
@ -755,7 +715,6 @@ void init_resources(void)
rtype->flags |= RTF_ITEM | RTF_POOLED; rtype->flags |= RTF_ITEM | RTF_POOLED;
rtype->uchange = res_changeitem; rtype->uchange = res_changeitem;
rtype->itype = it_get_or_create(rtype); rtype->itype = it_get_or_create(rtype);
rtype->itype->give = give_money;
rtype = rt_get_or_create(resourcenames[R_PERMAURA]); rtype = rt_get_or_create(resourcenames[R_PERMAURA]);
rtype->uchange = res_changepermaura; rtype->uchange = res_changepermaura;
@ -1055,6 +1014,4 @@ void register_resources(void)
register_function((pf_generic)res_changepermaura, "changepermaura"); register_function((pf_generic)res_changepermaura, "changepermaura");
register_function((pf_generic)res_changehp, "changehp"); register_function((pf_generic)res_changehp, "changehp");
register_function((pf_generic)res_changeaura, "changeaura"); register_function((pf_generic)res_changeaura, "changeaura");
register_item_give(give_horses, "givehorses");
} }

View file

@ -128,8 +128,6 @@ extern "C" {
/* --- functions --- */ /* --- functions --- */
bool(*canuse) (const struct unit * user, bool(*canuse) (const struct unit * user,
const struct item_type * itype); const struct item_type * itype);
int(*give) (struct unit * src, struct unit * dest,
const struct item_type * itm, int number, struct order * ord);
int score; int score;
} item_type; } item_type;

View file

@ -162,7 +162,6 @@ static void test_core_resources(CuTest *tc) {
CuAssertPtrNotNull(tc, rtype = rt_find("money")); CuAssertPtrNotNull(tc, rtype = rt_find("money"));
CuAssertPtrNotNull(tc, rtype->itype); CuAssertPtrNotNull(tc, rtype->itype);
CuAssertPtrNotNull(tc, rtype->uchange); CuAssertPtrNotNull(tc, rtype->uchange);
CuAssertPtrNotNull(tc, rtype->itype->give);
CuAssertPtrNotNull(tc, rtype = rt_find("peasant")); CuAssertPtrNotNull(tc, rtype = rt_find("peasant"));
CuAssertPtrEquals(tc, 0, rtype->itype); CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrNotNull(tc, rtype = rt_find("person")); CuAssertPtrNotNull(tc, rtype = rt_find("person"));

View file

@ -873,12 +873,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype)
continue; continue;
} }
assert(propValue != NULL); assert(propValue != NULL);
if (strcmp((const char *)propValue, "give") == 0) { if (strcmp((const char *)propValue, "canuse") == 0) {
itype->give =
(int(*)(struct unit *, struct unit *, const struct item_type *, int,
struct order *))fun;
}
else if (strcmp((const char *)propValue, "canuse") == 0) {
itype->canuse = itype->canuse =
(bool(*)(const struct unit *, const struct item_type *))fun; (bool(*)(const struct unit *, const struct item_type *))fun;
} }