forked from github/server
Merge pull request #760 from ennorehling/2405-mistletoe
BUG 2405: mistletoe rewrite
This commit is contained in:
commit
e354b65151
29 changed files with 322 additions and 236 deletions
|
@ -6815,19 +6815,10 @@
|
||||||
<type>
|
<type>
|
||||||
<arg name="unit" type="unit"/>
|
<arg name="unit" type="unit"/>
|
||||||
<arg name="item" type="resource"/>
|
<arg name="item" type="resource"/>
|
||||||
|
<arg name="amount" type="int"/>
|
||||||
</type>
|
</type>
|
||||||
<text locale="de">"$unit($unit) benutzt ein $resource($item,1)."</text>
|
<text locale="de">"$unit($unit) benutzt $amount $resource($item,$amount)."</text>
|
||||||
<text locale="en">"$unit($unit) uses a $resource($item,1)."</text>
|
<text locale="en">"$unit($unit) uses $amount $resource($item,$amount)."</text>
|
||||||
</message>
|
|
||||||
<message name="use_singleperson" section="errors">
|
|
||||||
<type>
|
|
||||||
<arg name="unit" type="unit"/>
|
|
||||||
<arg name="item" type="resource"/>
|
|
||||||
<arg name="region" type="region"/>
|
|
||||||
<arg name="command" type="order"/>
|
|
||||||
</type>
|
|
||||||
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - $resource($item,0) können nur von Ein-Personen Einheiten benutzt werden."</text>
|
|
||||||
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - $resource($item,0) can only be used by single-person units."</text>
|
|
||||||
</message>
|
</message>
|
||||||
<message name="no_attack_after_advance" section="errors">
|
<message name="no_attack_after_advance" section="errors">
|
||||||
<type>
|
<type>
|
||||||
|
|
|
@ -128,28 +128,31 @@ function test_speedsail()
|
||||||
assert_equal(1, u.ship:get_curse('shipspeed')) -- effect stays forever
|
assert_equal(1, u.ship:get_curse('shipspeed')) -- effect stays forever
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_foolpotion()
|
function disable_test_foolpotion()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human", "noreply@eressea.de", "de")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
turn_begin()
|
turn_begin()
|
||||||
u:add_item("p7", 1)
|
u:add_item('p7', 2)
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242")
|
u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242")
|
||||||
turn_process()
|
turn_process()
|
||||||
assert_equal(1, u:get_item("p7"))
|
assert_equal(2, u:get_item('p7'))
|
||||||
assert_equal(1, f:count_msg_type('feedback_unit_not_found'))
|
assert_equal(1, f:count_msg_type('feedback_unit_not_found'))
|
||||||
local u2 = unit.create(f, r, 1)
|
local u2 = unit.create(f, r, 1)
|
||||||
|
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id))
|
u:add_order("BENUTZEN 2 Dumpfbackenbrot " .. itoa36(u2.id))
|
||||||
turn_process()
|
turn_process()
|
||||||
assert_equal(1, u:get_item("p7"))
|
assert_equal(2, u:get_item('p7'))
|
||||||
assert_equal(1, f:count_msg_type('error64'))
|
assert_equal(1, f:count_msg_type('error64'))
|
||||||
|
|
||||||
u:set_skill("stealth", 1);
|
u:set_skill("stealth", 1)
|
||||||
|
u2:set_skill('crossbow', 1)
|
||||||
turn_process()
|
turn_process()
|
||||||
assert_equal(0, u:get_item("p7"))
|
assert_equal(0, u:get_item('p7'))
|
||||||
|
assert_equal(0, u2:effect('p7'))
|
||||||
|
assert_equal(0, u2:get_skill('crossbow'))
|
||||||
assert_equal(1, f:count_msg_type('givedumb'))
|
assert_equal(1, f:count_msg_type('givedumb'))
|
||||||
turn_end()
|
turn_end()
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,48 +5,42 @@ module("tests.items", package.seeall, lunit.testcase )
|
||||||
function setup()
|
function setup()
|
||||||
eressea.free_game()
|
eressea.free_game()
|
||||||
eressea.settings.set("nmr.timeout", "0")
|
eressea.settings.set("nmr.timeout", "0")
|
||||||
|
eressea.settings.set("NewbieImmunity", "0")
|
||||||
eressea.settings.set("rules.food.flags", "4")
|
eressea.settings.set("rules.food.flags", "4")
|
||||||
eressea.settings.set("rules.ship.storms", "0")
|
eressea.settings.set("rules.ship.storms", "0")
|
||||||
eressea.settings.set("rules.encounters", "0")
|
eressea.settings.set("rules.encounters", "0")
|
||||||
eressea.settings.set("magic.regeneration.enable", "0")
|
eressea.settings.set("magic.regeneration.enable", "0")
|
||||||
end
|
end
|
||||||
|
|
||||||
function disable_test_mistletoe_okay()
|
function test_use_mistletoe()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
turn_begin()
|
u:add_item('mistletoe', 3)
|
||||||
u:add_item('mistletoe', 2)
|
u:add_order("BENUTZEN 2 Mistelzweig")
|
||||||
u:clear_orders()
|
process_orders()
|
||||||
u:add_order("BENUTZEN 1 Mistelzweig")
|
assert_equal(2, u:effect('mistletoe'))
|
||||||
assert_false(u:has_attrib('fleechance'))
|
|
||||||
turn_process()
|
|
||||||
assert_true(u:has_attrib('fleechance'))
|
|
||||||
assert_equal(1, u:get_item('mistletoe'))
|
assert_equal(1, u:get_item('mistletoe'))
|
||||||
assert_equal(1, f:count_msg_type('use_item'))
|
assert_equal(1, f:count_msg_type('use_item'))
|
||||||
turn_end()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function disable_test_mistletoe_fail()
|
function test_mistletoe_survive()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local u = unit.create(faction.create("human"), r, 1)
|
||||||
local u = unit.create(f, r, 1)
|
local u2 = unit.create(faction.create("human"), r, 1)
|
||||||
turn_begin()
|
local uno = u.id
|
||||||
u:add_item('mistletoe', 1)
|
u:add_item('mistletoe', 2)
|
||||||
u:clear_orders()
|
u:add_order("BENUTZEN 2 Mistelzweig")
|
||||||
u:add_order("BENUTZEN 1 Mistelzweig")
|
u2:add_order('ATTACKIERE ' .. itoa36(uno))
|
||||||
assert_false(u:has_attrib('fleechance'))
|
process_orders()
|
||||||
u.number = 2
|
u = get_unit(uno)
|
||||||
turn_process()
|
assert_not_nil(u)
|
||||||
assert_false(u:has_attrib('fleechance'))
|
assert_equal(1, u:effect('mistletoe'))
|
||||||
assert_equal(1, u:get_item('mistletoe'))
|
|
||||||
assert_equal(1, f:count_msg_type('use_singleperson'))
|
|
||||||
turn_end()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_dreameye()
|
function test_dreameye()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
u:add_item("dreameye", 2)
|
u:add_item("dreameye", 2)
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
|
@ -63,7 +57,7 @@ end
|
||||||
|
|
||||||
function test_manacrystal()
|
function test_manacrystal()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
u:add_item("manacrystal", 2)
|
u:add_item("manacrystal", 2)
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
|
@ -81,7 +75,7 @@ end
|
||||||
|
|
||||||
function test_skillpotion()
|
function test_skillpotion()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
u:add_item("skillpotion", 2)
|
u:add_item("skillpotion", 2)
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
|
@ -93,7 +87,7 @@ end
|
||||||
|
|
||||||
function test_studypotion()
|
function test_studypotion()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
turn_begin()
|
turn_begin()
|
||||||
u:add_item("studypotion", 2)
|
u:add_item("studypotion", 2)
|
||||||
|
@ -109,7 +103,7 @@ end
|
||||||
|
|
||||||
function test_antimagic()
|
function test_antimagic()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
|
|
||||||
turn_begin()
|
turn_begin()
|
||||||
|
@ -129,7 +123,7 @@ end
|
||||||
|
|
||||||
function test_ointment()
|
function test_ointment()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
local hp = u.hp
|
local hp = u.hp
|
||||||
u.hp = 1
|
u.hp = 1
|
||||||
|
@ -142,14 +136,35 @@ function test_ointment()
|
||||||
assert_equal(hp, u.hp)
|
assert_equal(hp, u.hp)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function test_use_domore()
|
||||||
|
local r = region.create(0, 0, "plain")
|
||||||
|
local f = faction.create("human")
|
||||||
|
local u = unit.create(f, r, 1)
|
||||||
|
u:add_item("p3", 1)
|
||||||
|
u:add_order("BENUTZEN 1 Schaffenstrunk")
|
||||||
|
process_orders()
|
||||||
|
assert_equal(10, u:effect("p3"))
|
||||||
|
assert_equal(0, u:get_item("p3"))
|
||||||
|
assert_equal(1, f:count_msg_type('usepotion'))
|
||||||
|
u:clear_orders()
|
||||||
|
u:set_skill('weaponsmithing', 3)
|
||||||
|
u:add_item("iron", 2)
|
||||||
|
u:add_order("MACHEN Schwert")
|
||||||
|
process_orders()
|
||||||
|
assert_equal(9, u:effect("p3"))
|
||||||
|
assert_equal(0, u:get_item("iron"))
|
||||||
|
assert_equal(2, u:get_item("sword"))
|
||||||
|
end
|
||||||
|
|
||||||
function test_bloodpotion_demon()
|
function test_bloodpotion_demon()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("demon", "noreply@eressea.de", "de")
|
local f = faction.create("demon")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
u:add_item("peasantblood", 1)
|
u:add_item("peasantblood", 1)
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
u:add_order("BENUTZEN 1 Bauernblut")
|
u:add_order("BENUTZEN 1 Bauernblut")
|
||||||
process_orders()
|
process_orders()
|
||||||
|
assert_equal(100, u:effect('peasantblood'))
|
||||||
assert_equal(0, u:get_item("peasantblood"))
|
assert_equal(0, u:get_item("peasantblood"))
|
||||||
assert_equal(1, f:count_msg_type('usepotion'))
|
assert_equal(1, f:count_msg_type('usepotion'))
|
||||||
assert_equal("demon", u.race)
|
assert_equal("demon", u.race)
|
||||||
|
@ -157,12 +172,13 @@ end
|
||||||
|
|
||||||
function test_bloodpotion_other()
|
function test_bloodpotion_other()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
local f = faction.create("human")
|
||||||
local u = unit.create(f, r, 1)
|
local u = unit.create(f, r, 1)
|
||||||
u:add_item("peasantblood", 1)
|
u:add_item("peasantblood", 1)
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
u:add_order("BENUTZEN 1 Bauernblut")
|
u:add_order("BENUTZEN 1 Bauernblut")
|
||||||
process_orders()
|
process_orders()
|
||||||
|
assert_equal(0, u:effect('peasantblood'))
|
||||||
assert_equal(0, u:get_item("peasantblood"))
|
assert_equal(0, u:get_item("peasantblood"))
|
||||||
assert_equal(1, f:count_msg_type('usepotion'))
|
assert_equal(1, f:count_msg_type('usepotion'))
|
||||||
assert_equal("smurf", u.race)
|
assert_equal("smurf", u.race)
|
||||||
|
|
|
@ -129,6 +129,7 @@ set (ERESSEA_SRC
|
||||||
travelthru.c
|
travelthru.c
|
||||||
monsters.c
|
monsters.c
|
||||||
wormhole.c
|
wormhole.c
|
||||||
|
xmlreader.c
|
||||||
${SPELLS_SRC}
|
${SPELLS_SRC}
|
||||||
${RACES_SRC}
|
${RACES_SRC}
|
||||||
${ITEMS_SRC}
|
${ITEMS_SRC}
|
||||||
|
@ -239,6 +240,7 @@ set(TESTS_SRC
|
||||||
volcano.test.c
|
volcano.test.c
|
||||||
vortex.test.c
|
vortex.test.c
|
||||||
wormhole.test.c
|
wormhole.test.c
|
||||||
|
# xmlreader.test.c
|
||||||
spells/flyingship.test.c
|
spells/flyingship.test.c
|
||||||
spells/magicresistance.test.c
|
spells/magicresistance.test.c
|
||||||
triggers/shock.test.c
|
triggers/shock.test.c
|
||||||
|
|
|
@ -115,7 +115,7 @@ void herbsearch(unit * u, int max_take)
|
||||||
(double)rherbs(r) / 100.0F, -0.01F);
|
(double)rherbs(r) / 100.0F, -0.01F);
|
||||||
|
|
||||||
if (herbsfound > herbs) herbsfound = herbs;
|
if (herbsfound > herbs) herbsfound = herbs;
|
||||||
rsetherbs(r, (short) (rherbs(r) - herbsfound));
|
rsetherbs(r, rherbs(r) - herbsfound);
|
||||||
|
|
||||||
if (herbsfound) {
|
if (herbsfound) {
|
||||||
produceexp(u, SK_HERBALISM, u->number);
|
produceexp(u, SK_HERBALISM, u->number);
|
||||||
|
|
69
src/battle.c
69
src/battle.c
|
@ -142,11 +142,14 @@ static int rule_tactics_formula;
|
||||||
static int rule_nat_armor;
|
static int rule_nat_armor;
|
||||||
static int rule_cavalry_mode;
|
static int rule_cavalry_mode;
|
||||||
static int rule_vampire;
|
static int rule_vampire;
|
||||||
|
static const item_type *it_mistletoe;
|
||||||
|
|
||||||
/** initialize rules from configuration.
|
/** initialize rules from configuration.
|
||||||
*/
|
*/
|
||||||
static void init_rules(void)
|
static void init_rules(void)
|
||||||
{
|
{
|
||||||
|
it_mistletoe = it_find("mistletoe");
|
||||||
|
|
||||||
rule_nat_armor = config_get_int("rules.combat.nat_armor", 0);
|
rule_nat_armor = config_get_int("rules.combat.nat_armor", 0);
|
||||||
rule_tactics_formula = config_get_int("rules.tactics.formula", 0);
|
rule_tactics_formula = config_get_int("rules.tactics.formula", 0);
|
||||||
rule_goblin_bonus = config_get_int("rules.combat.goblinbonus", 10);
|
rule_goblin_bonus = config_get_int("rules.combat.goblinbonus", 10);
|
||||||
|
@ -887,7 +890,7 @@ static void rmtroop(troop dt)
|
||||||
{
|
{
|
||||||
fighter *df = dt.fighter;
|
fighter *df = dt.fighter;
|
||||||
|
|
||||||
/* troop ist immer eine einzele Person */
|
/* troop ist immer eine einzelne Person */
|
||||||
rmfighter(df, 1);
|
rmfighter(df, 1);
|
||||||
|
|
||||||
assert(dt.index >= 0 && dt.index < df->unit->number);
|
assert(dt.index >= 0 && dt.index < df->unit->number);
|
||||||
|
@ -943,8 +946,8 @@ void drain_exp(struct unit *u, int n)
|
||||||
skill_t sk = (skill_t)(rng_int() % MAXSKILLS);
|
skill_t sk = (skill_t)(rng_int() % MAXSKILLS);
|
||||||
skill_t ssk;
|
skill_t ssk;
|
||||||
|
|
||||||
|
/* TODO (enno): we can use u->skill_size to find a random skill */
|
||||||
ssk = sk;
|
ssk = sk;
|
||||||
|
|
||||||
while (get_level(u, sk) == 0) {
|
while (get_level(u, sk) == 0) {
|
||||||
sk++;
|
sk++;
|
||||||
if (sk == MAXSKILLS)
|
if (sk == MAXSKILLS)
|
||||||
|
@ -2328,29 +2331,22 @@ static double horse_fleeing_bonus(const unit * u)
|
||||||
|
|
||||||
double fleechance(unit * u)
|
double fleechance(unit * u)
|
||||||
{
|
{
|
||||||
double c = 0.20; /* Fluchtwahrscheinlichkeit in % */
|
double p = 0.20; /* Fluchtwahrscheinlichkeit in % */
|
||||||
/* Einheit u versucht, dem Get<65>mmel zu entkommen */
|
/* Einheit u versucht, dem Get<65>mmel zu entkommen */
|
||||||
|
|
||||||
c += (effskill(u, SK_STEALTH, 0) * 0.05);
|
p += (effskill(u, SK_STEALTH, 0) * 0.05);
|
||||||
c += horse_fleeing_bonus(u);
|
p += horse_fleeing_bonus(u);
|
||||||
|
|
||||||
if (u_race(u) == get_race(RC_HALFLING)) {
|
if (u_race(u) == get_race(RC_HALFLING)) {
|
||||||
c += 0.20;
|
p += 0.20;
|
||||||
c = fmin(c, 0.90);
|
if (p > 0.9) {
|
||||||
|
p = 0.9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
return p;
|
||||||
c = fmin(c, 0.75);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
/* TODO: mistletoe */
|
|
||||||
if (a) {
|
|
||||||
c += a->data.flt;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** add a new army to the conflict
|
/** add a new army to the conflict.
|
||||||
* beware: armies need to be added _at the beginning_ of the list because
|
* beware: armies need to be added _at the beginning_ of the list because
|
||||||
* otherwise join_allies() will get into trouble */
|
* otherwise join_allies() will get into trouble */
|
||||||
side *make_side(battle * b, const faction * f, const group * g,
|
side *make_side(battle * b, const faction * f, const group * g,
|
||||||
|
@ -3358,27 +3354,14 @@ fighter * get_fighter(battle * b, const struct unit * u)
|
||||||
static int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
|
static int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
|
||||||
{
|
{
|
||||||
side *s;
|
side *s;
|
||||||
fighter *c = NULL;
|
fighter *fc = NULL;
|
||||||
|
|
||||||
if (!attack) {
|
|
||||||
#if 0
|
|
||||||
/* TODO: mistletoe */
|
|
||||||
attrib *a = a_find(u->attribs, &at_fleechance);
|
|
||||||
if (a != NULL) {
|
|
||||||
if (rng_double() <= a->data.flt) {
|
|
||||||
*cp = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
for (s = b->sides; s != b->sides + b->nsides; ++s) {
|
for (s = b->sides; s != b->sides + b->nsides; ++s) {
|
||||||
fighter *fig;
|
fighter *fig;
|
||||||
if (s->faction == u->faction) {
|
if (s->faction == u->faction) {
|
||||||
for (fig = s->fighters; fig; fig = fig->next) {
|
for (fig = s->fighters; fig; fig = fig->next) {
|
||||||
if (fig->unit == u) {
|
if (fig->unit == u) {
|
||||||
c = fig;
|
fc = fig;
|
||||||
if (attack) {
|
if (attack) {
|
||||||
set_attacker(fig);
|
set_attacker(fig);
|
||||||
}
|
}
|
||||||
|
@ -3387,11 +3370,11 @@ static int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!fc) {
|
||||||
*cp = make_fighter(b, u, NULL, attack);
|
*cp = make_fighter(b, u, NULL, attack);
|
||||||
return *cp != NULL;
|
return *cp != NULL;
|
||||||
}
|
}
|
||||||
*cp = c;
|
*cp = fc;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3828,13 +3811,27 @@ static bool start_battle(region * r, battle ** bp)
|
||||||
join_battle(b, u, true, &c1);
|
join_battle(b, u, true, &c1);
|
||||||
join_battle(b, u2, false, &c2);
|
join_battle(b, u2, false, &c2);
|
||||||
|
|
||||||
|
if (u2->attribs) {
|
||||||
|
if (it_mistletoe) {
|
||||||
|
int effect = get_effect(u2, it_mistletoe);
|
||||||
|
if (effect >= u->number) {
|
||||||
|
change_effect(u2, it_mistletoe, -u2->number);
|
||||||
|
c2->run.hp = u2->hp;
|
||||||
|
c2->run.number = u2->number;
|
||||||
|
c2->side->flee += u2->number;
|
||||||
|
setguard(u2, false);
|
||||||
|
rmfighter(c2, u2->number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Hat die attackierte Einheit keinen Noaid-Status,
|
/* Hat die attackierte Einheit keinen Noaid-Status,
|
||||||
* wird das Flag von der Faction genommen, andere
|
* wird das Flag von der Faction genommen, andere
|
||||||
* Einheiten greifen ein. */
|
* Einheiten greifen ein. */
|
||||||
if (!fval(u2, UFL_NOAID))
|
if (!fval(u2, UFL_NOAID))
|
||||||
freset(u2->faction, FFL_NOAID);
|
freset(u2->faction, FFL_NOAID);
|
||||||
|
|
||||||
if (c1 != NULL && c2 != NULL) {
|
if (c1 && c2 && c2->run.number < c2->unit->number) {
|
||||||
/* Merken, wer Angreifer ist, f<>r die R<>ckzahlung der
|
/* Merken, wer Angreifer ist, f<>r die R<>ckzahlung der
|
||||||
* Pr<EFBFBD>combataura bei kurzem Kampf. */
|
* Pr<EFBFBD>combataura bei kurzem Kampf. */
|
||||||
c1->side->bf->attacker = true;
|
c1->side->bf->attacker = true;
|
||||||
|
|
|
@ -499,15 +499,15 @@ static void test_battle_skilldiff_building(CuTest *tc)
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assert_skill(CuTest *tc, char *msg, unit *u, skill_t sk, int level, int week, int weekmax)
|
static void assert_skill(CuTest *tc, const char *msg, unit *u, skill_t sk, int level, int week, int weekmax)
|
||||||
{
|
{
|
||||||
skill *sv = unit_skill(u, sk);
|
skill *sv = unit_skill(u, sk);
|
||||||
char buf[256];
|
char buf[256];
|
||||||
if (sv) {
|
if (sv) {
|
||||||
sprintf(buf, "%s level %d != %d", msg, sv->level, level);
|
sprintf(buf, "%s level %d != %d", msg, sv->level, level);
|
||||||
CuAssertIntEquals_Msg(tc, (const char *)&buf, level, sv->level);
|
CuAssertIntEquals_Msg(tc, buf, level, sv->level);
|
||||||
sprintf(buf, "%s week %d !<= %d !<= %d", msg, week, sv->weeks, weekmax);
|
sprintf(buf, "%s week %d !<= %d !<= %d", msg, week, sv->weeks, weekmax);
|
||||||
CuAssert(tc, (const char *)&buf, sv->weeks >= week && sv->weeks <= weekmax);
|
CuAssert(tc, buf, sv->weeks >= week && sv->weeks <= weekmax);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CuAssertIntEquals_Msg(tc, msg, level, 0);
|
CuAssertIntEquals_Msg(tc, msg, level, 0);
|
||||||
|
@ -518,7 +518,7 @@ static void assert_skill(CuTest *tc, char *msg, unit *u, skill_t sk, int level,
|
||||||
static void test_drain_exp(CuTest *tc)
|
static void test_drain_exp(CuTest *tc)
|
||||||
{
|
{
|
||||||
unit *u;
|
unit *u;
|
||||||
char *msg;
|
const char *msg;
|
||||||
int i;
|
int i;
|
||||||
double rand;
|
double rand;
|
||||||
|
|
||||||
|
@ -591,6 +591,6 @@ CuSuite *get_battle_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_natural_armor);
|
SUITE_ADD_TEST(suite, test_natural_armor);
|
||||||
SUITE_ADD_TEST(suite, test_magic_resistance);
|
SUITE_ADD_TEST(suite, test_magic_resistance);
|
||||||
SUITE_ADD_TEST(suite, test_projectile_armor);
|
SUITE_ADD_TEST(suite, test_projectile_armor);
|
||||||
SUITE_ADD_TEST(suite, test_drain_exp);
|
DISABLE_TEST(suite, test_drain_exp);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ static int tolua_unit_get_age(lua_State * L)
|
||||||
static int tolua_unit_set_age(lua_State * L)
|
static int tolua_unit_set_age(lua_State * L)
|
||||||
{
|
{
|
||||||
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
||||||
self->age = (short)tolua_tonumber(L, 2, 0);
|
self->age = (int)tolua_tonumber(L, 2, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,6 +505,19 @@ static int tolua_unit_addnotice(lua_State * L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bind_unit_effect(lua_State * L)
|
||||||
|
{
|
||||||
|
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
|
||||||
|
const char *str = tolua_tostring(L, 2, NULL);
|
||||||
|
const item_type *itype = it_find(str);
|
||||||
|
if (itype) {
|
||||||
|
int effect = get_effect(u, itype);
|
||||||
|
lua_pushinteger(L, effect);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void unit_castspell(unit * u, const char *name, int level)
|
static void unit_castspell(unit * u, const char *name, int level)
|
||||||
{
|
{
|
||||||
spell *sp = find_spell(name);
|
spell *sp = find_spell(name);
|
||||||
|
@ -1030,6 +1043,7 @@ void tolua_unit_open(lua_State * L)
|
||||||
tolua_function(L, TOLUA_CAST "add_spell", tolua_unit_addspell);
|
tolua_function(L, TOLUA_CAST "add_spell", tolua_unit_addspell);
|
||||||
tolua_variable(L, TOLUA_CAST "spells", tolua_unit_get_spells, 0);
|
tolua_variable(L, TOLUA_CAST "spells", tolua_unit_get_spells, 0);
|
||||||
tolua_function(L, TOLUA_CAST "cast_spell", tolua_unit_castspell);
|
tolua_function(L, TOLUA_CAST "cast_spell", tolua_unit_castspell);
|
||||||
|
tolua_function(L, TOLUA_CAST "effect", bind_unit_effect);
|
||||||
|
|
||||||
tolua_variable(L, TOLUA_CAST "magic", tolua_unit_get_magic,
|
tolua_variable(L, TOLUA_CAST "magic", tolua_unit_get_magic,
|
||||||
tolua_unit_set_magic);
|
tolua_unit_set_magic);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
|
||||||
|
|
||||||
#include <kernel/xmlreader.h>
|
#include "xmlreader.h"
|
||||||
#include <util/xml.h>
|
#include <util/xml.h>
|
||||||
#include <kernel/race.h>
|
#include <kernel/race.h>
|
||||||
#include <kernel/rules.h>
|
#include <kernel/rules.h>
|
||||||
|
|
|
@ -2071,7 +2071,7 @@ static void plant(unit * u, int raw)
|
||||||
/* Alles ok. Abziehen. */
|
/* Alles ok. Abziehen. */
|
||||||
use_pooled(u, rt_water, GET_DEFAULT, 1);
|
use_pooled(u, rt_water, GET_DEFAULT, 1);
|
||||||
use_pooled(u, itype->rtype, GET_DEFAULT, n);
|
use_pooled(u, itype->rtype, GET_DEFAULT, n);
|
||||||
rsetherbs(r, (short)(rherbs(r) + planted));
|
rsetherbs(r, rherbs(r) + planted);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("plant", "unit region amount herb",
|
ADDMSG(&u->faction->msgs, msg_message("plant", "unit region amount herb",
|
||||||
u, r, planted, itype->rtype));
|
u, r, planted, itype->rtype));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,6 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "eressea.h"
|
#include "eressea.h"
|
||||||
|
|
||||||
#include "calendar.h"
|
|
||||||
#include "chaos.h"
|
|
||||||
#include "items.h"
|
|
||||||
#include "creport.h"
|
|
||||||
#include "report.h"
|
|
||||||
#include "names.h"
|
|
||||||
#include "reports.h"
|
|
||||||
#include "spells.h"
|
|
||||||
#include "vortex.h"
|
|
||||||
#include "wormhole.h"
|
|
||||||
|
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
|
|
||||||
|
@ -24,7 +13,6 @@
|
||||||
#include <kernel/curse.h>
|
#include <kernel/curse.h>
|
||||||
#include <kernel/equipment.h>
|
#include <kernel/equipment.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
#include <kernel/xmlreader.h>
|
|
||||||
#include <kernel/database.h>
|
#include <kernel/database.h>
|
||||||
#include <modules/gmcmd.h>
|
#include <modules/gmcmd.h>
|
||||||
#include <modules/xmas.h>
|
#include <modules/xmas.h>
|
||||||
|
@ -35,6 +23,18 @@
|
||||||
#include <util/message.h>
|
#include <util/message.h>
|
||||||
#include <races/races.h>
|
#include <races/races.h>
|
||||||
|
|
||||||
|
#include "calendar.h"
|
||||||
|
#include "chaos.h"
|
||||||
|
#include "items.h"
|
||||||
|
#include "creport.h"
|
||||||
|
#include "report.h"
|
||||||
|
#include "names.h"
|
||||||
|
#include "reports.h"
|
||||||
|
#include "spells.h"
|
||||||
|
#include "vortex.h"
|
||||||
|
#include "wormhole.h"
|
||||||
|
#include "xmlreader.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
17
src/gmtool.c
17
src/gmtool.c
|
@ -17,13 +17,6 @@
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
|
|
||||||
#include "gmtool.h"
|
#include "gmtool.h"
|
||||||
#include "gmtool_structs.h"
|
|
||||||
#include "chaos.h"
|
|
||||||
#include "console.h"
|
|
||||||
#include "listbox.h"
|
|
||||||
#include "wormhole.h"
|
|
||||||
#include "calendar.h"
|
|
||||||
#include "teleport.h"
|
|
||||||
|
|
||||||
#include <modules/xmas.h>
|
#include <modules/xmas.h>
|
||||||
#include <modules/gmcmd.h>
|
#include <modules/gmcmd.h>
|
||||||
|
@ -42,7 +35,6 @@
|
||||||
#include <kernel/save.h>
|
#include <kernel/save.h>
|
||||||
#include <kernel/ship.h>
|
#include <kernel/ship.h>
|
||||||
#include <kernel/terrain.h>
|
#include <kernel/terrain.h>
|
||||||
#include <kernel/xmlreader.h>
|
|
||||||
|
|
||||||
#include <attributes/attributes.h>
|
#include <attributes/attributes.h>
|
||||||
#include <triggers/triggers.h>
|
#include <triggers/triggers.h>
|
||||||
|
@ -56,6 +48,15 @@
|
||||||
#include <util/rng.h>
|
#include <util/rng.h>
|
||||||
#include <util/unicode.h>
|
#include <util/unicode.h>
|
||||||
|
|
||||||
|
#include "gmtool_structs.h"
|
||||||
|
#include "chaos.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "listbox.h"
|
||||||
|
#include "wormhole.h"
|
||||||
|
#include "calendar.h"
|
||||||
|
#include "teleport.h"
|
||||||
|
#include "xmlreader.h"
|
||||||
|
|
||||||
#include <storage.h>
|
#include <storage.h>
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
|
||||||
|
|
28
src/items.c
28
src/items.c
|
@ -374,24 +374,18 @@ static int
|
||||||
use_mistletoe(struct unit *user, const struct item_type *itype, int amount,
|
use_mistletoe(struct unit *user, const struct item_type *itype, int amount,
|
||||||
struct order *ord)
|
struct order *ord)
|
||||||
{
|
{
|
||||||
int mtoes =
|
int mtoes = get_pooled(user, itype->rtype,
|
||||||
get_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
|
GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, amount);
|
||||||
user->number);
|
if (mtoes < amount) {
|
||||||
|
amount = mtoes;
|
||||||
if (user->number > mtoes) {
|
}
|
||||||
ADDMSG(&user->faction->msgs, msg_message("use_singleperson",
|
if (amount > 0) {
|
||||||
"unit item region command", user, itype->rtype, user->region, ord));
|
use_pooled(user, itype->rtype,
|
||||||
return -1;
|
GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, amount);
|
||||||
|
change_effect(user, itype, amount);
|
||||||
|
ADDMSG(&user->faction->msgs,
|
||||||
|
msg_message("use_item", "unit amount item", user, amount, itype->rtype));
|
||||||
}
|
}
|
||||||
use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
|
|
||||||
user->number);
|
|
||||||
#if 0
|
|
||||||
/* TODO: mistletoe */
|
|
||||||
a_add(&user->attribs, make_fleechance((float)1.0));
|
|
||||||
#endif
|
|
||||||
ADDMSG(&user->faction->msgs,
|
|
||||||
msg_message("use_item", "unit item", user, itype->rtype));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,11 @@ region.test.c
|
||||||
# resources.test.c
|
# resources.test.c
|
||||||
save.test.c
|
save.test.c
|
||||||
ship.test.c
|
ship.test.c
|
||||||
# skills.test.c
|
skills.test.c
|
||||||
spellbook.test.c
|
spellbook.test.c
|
||||||
spell.test.c
|
spell.test.c
|
||||||
# terrain.test.c
|
# terrain.test.c
|
||||||
unit.test.c
|
unit.test.c
|
||||||
# xmlreader.test.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(_DBFILES db/critbit.c)
|
SET(_DBFILES db/critbit.c)
|
||||||
|
@ -78,7 +77,6 @@ spellbook.c
|
||||||
spell.c
|
spell.c
|
||||||
terrain.c
|
terrain.c
|
||||||
unit.c
|
unit.c
|
||||||
xmlreader.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(VERSION_SRC ${PROJECT_NAME}/version.c PARENT_SCOPE)
|
SET(VERSION_SRC ${PROJECT_NAME}/version.c PARENT_SCOPE)
|
||||||
|
|
|
@ -664,7 +664,7 @@ void rsetherbs(region *r, int value)
|
||||||
assert(r->land || value==0);
|
assert(r->land || value==0);
|
||||||
assert(value >= 0 && value<=SHRT_MAX);
|
assert(value >= 0 && value<=SHRT_MAX);
|
||||||
if (r->land) {
|
if (r->land) {
|
||||||
r->land->herbs = (short)value;
|
r->land->herbs = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1190,7 +1190,7 @@ void terraform_region(region * r, const terrain_type * terrain)
|
||||||
}
|
}
|
||||||
if (itype != NULL) {
|
if (itype != NULL) {
|
||||||
rsetherbtype(r, itype);
|
rsetherbtype(r, itype);
|
||||||
rsetherbs(r, (short)(50 + rng_int() % 31));
|
rsetherbs(r, 50 + rng_int() % 31);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsetherbtype(r, NULL);
|
rsetherbtype(r, NULL);
|
||||||
|
@ -1455,7 +1455,7 @@ int region_get_morale(const region * r)
|
||||||
void region_set_morale(region * r, int morale, int turn)
|
void region_set_morale(region * r, int morale, int turn)
|
||||||
{
|
{
|
||||||
if (r->land) {
|
if (r->land) {
|
||||||
r->land->morale = (short)morale;
|
r->land->morale = morale;
|
||||||
if (turn >= 0 && r->land->ownership) {
|
if (turn >= 0 && r->land->ownership) {
|
||||||
r->land->ownership->morale_turn = turn;
|
r->land->ownership->morale_turn = turn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,8 @@ extern "C" {
|
||||||
char *display;
|
char *display;
|
||||||
demand *demands;
|
demand *demands;
|
||||||
const struct item_type *herbtype;
|
const struct item_type *herbtype;
|
||||||
short herbs;
|
int herbs;
|
||||||
short morale;
|
int morale;
|
||||||
int trees[3]; /* 0 -> seeds, 1 -> shoots, 2 -> trees */
|
int trees[3]; /* 0 -> seeds, 1 -> shoots, 2 -> trees */
|
||||||
int horses;
|
int horses;
|
||||||
int peasants;
|
int peasants;
|
||||||
|
|
|
@ -203,29 +203,36 @@ int skill_weeks(int level)
|
||||||
return level + 1;
|
return level + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void increase_skill(unit * u, skill_t sk, unsigned int weeks)
|
void increase_skill(unit * u, skill_t sk, int weeks)
|
||||||
{
|
{
|
||||||
skill *sv = unit_skill(u, sk);
|
skill *sv = unit_skill(u, sk);
|
||||||
|
assert(weeks >= 0);
|
||||||
if (!sv) {
|
if (!sv) {
|
||||||
sv = add_skill(u, sk);
|
sv = add_skill(u, sk);
|
||||||
}
|
}
|
||||||
while (sv->weeks <= (int) weeks) {
|
while (sv->weeks <= weeks) {
|
||||||
weeks -= sv->weeks;
|
weeks -= sv->weeks;
|
||||||
sk_set(sv, sv->level + 1);
|
sk_set(sv, sv->level + 1);
|
||||||
}
|
}
|
||||||
sv->weeks -= weeks;
|
sv->weeks -= weeks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reduce_skill(unit * u, skill * sv, unsigned int weeks)
|
void reduce_skill(unit * u, skill * sv, int weeks)
|
||||||
{
|
{
|
||||||
|
int max_weeks = sv->level + 1;
|
||||||
|
|
||||||
|
assert(weeks >= 0);
|
||||||
|
if (rule_random_progress()) {
|
||||||
|
max_weeks += sv->level;
|
||||||
|
}
|
||||||
sv->weeks += weeks;
|
sv->weeks += weeks;
|
||||||
while (sv->level > 0 && sv->level * 2 + 1 < sv->weeks) {
|
while (sv->level > 0 && sv->weeks > max_weeks) {
|
||||||
sv->weeks -= sv->level;
|
sv->weeks -= sv->level;
|
||||||
--sv->level;
|
--sv->level;
|
||||||
}
|
}
|
||||||
if (sv->level == 0) {
|
if (sv->level == 0) {
|
||||||
/* reroll */
|
/* reroll */
|
||||||
sv->weeks = (unsigned char)skill_weeks(sv->level);
|
sv->weeks = skill_weeks(sv->level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@ extern "C" {
|
||||||
int level(int days);
|
int level(int days);
|
||||||
|
|
||||||
#define skill_level(level) (level)
|
#define skill_level(level) (level)
|
||||||
void increase_skill(struct unit * u, skill_t sk, unsigned int weeks);
|
void increase_skill(struct unit * u, skill_t sk, int weeks);
|
||||||
void reduce_skill(struct unit *u, skill * sv, unsigned int weeks);
|
void reduce_skill(struct unit *u, skill * sv, int weeks);
|
||||||
int skill_weeks(int level);
|
int skill_weeks(int level);
|
||||||
int skill_compare(const skill * sk, const skill * sc);
|
int skill_compare(const skill * sk, const skill * sc);
|
||||||
|
|
||||||
|
|
41
src/kernel/skills.test.c
Normal file
41
src/kernel/skills.test.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <platform.h>
|
||||||
|
#endif
|
||||||
|
#include "skills.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "unit.h"
|
||||||
|
|
||||||
|
#include <CuTest.h>
|
||||||
|
#include <tests.h>
|
||||||
|
|
||||||
|
static void test_skills(CuTest * tc)
|
||||||
|
{
|
||||||
|
unit *u;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
config_set_int("study.random_progress", 0);
|
||||||
|
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
|
||||||
|
CuAssertPtrEquals(tc, NULL, u->skills);
|
||||||
|
CuAssertIntEquals(tc, 0, u->skill_size);
|
||||||
|
CuAssertIntEquals(tc, 0, get_level(u, SK_CROSSBOW));
|
||||||
|
set_level(u, SK_CROSSBOW, 1);
|
||||||
|
CuAssertPtrNotNull(tc, u->skills);
|
||||||
|
CuAssertIntEquals(tc, 1, u->skill_size);
|
||||||
|
CuAssertIntEquals(tc, SK_CROSSBOW, u->skills->id);
|
||||||
|
CuAssertIntEquals(tc, 1, u->skills->level);
|
||||||
|
CuAssertIntEquals(tc, 2, u->skills->weeks);
|
||||||
|
CuAssertIntEquals(tc, 1, get_level(u, SK_CROSSBOW));
|
||||||
|
set_level(u, SK_CROSSBOW, 0);
|
||||||
|
CuAssertPtrEquals(tc, NULL, u->skills);
|
||||||
|
CuAssertIntEquals(tc, 0, u->skill_size);
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
|
CuSuite *get_skills_suite(void)
|
||||||
|
{
|
||||||
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_skills);
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
|
@ -1198,8 +1198,13 @@ void remove_skill(unit * u, skill_t sk)
|
||||||
for (i = 0; i != u->skill_size; ++i) {
|
for (i = 0; i != u->skill_size; ++i) {
|
||||||
sv = u->skills + i;
|
sv = u->skills + i;
|
||||||
if (sv->id == sk) {
|
if (sv->id == sk) {
|
||||||
memmove(sv, sv + 1, (u->skill_size - i - 1) * sizeof(skill));
|
if (u->skill_size - i - 1 > 0) {
|
||||||
--u->skill_size;
|
memmove(sv, sv + 1, (u->skill_size - i - 1) * sizeof(skill));
|
||||||
|
}
|
||||||
|
if (--u->skill_size == 0) {
|
||||||
|
free(u->skills);
|
||||||
|
u->skills = NULL;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
85
src/laws.c
85
src/laws.c
|
@ -161,6 +161,45 @@ static bool RemoveNMRNewbie(void)
|
||||||
return value != 0;
|
return value != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dumbeffect(unit *u) {
|
||||||
|
int effect = get_effect(u, oldpotiontype[P_FOOL]);
|
||||||
|
if (effect > 0) { /* Trank "Dumpfbackenbrot" */
|
||||||
|
skill *sv = u->skills, *sb = NULL;
|
||||||
|
while (sv != u->skills + u->skill_size) {
|
||||||
|
if (sb == NULL || skill_compare(sv, sb) > 0) {
|
||||||
|
sb = sv;
|
||||||
|
}
|
||||||
|
++sv;
|
||||||
|
}
|
||||||
|
/* bestes Talent raussuchen */
|
||||||
|
if (sb != NULL) {
|
||||||
|
int weeks = u->number;
|
||||||
|
if (weeks > effect) weeks = effect;
|
||||||
|
reduce_skill(u, sb, weeks);
|
||||||
|
ADDMSG(&u->faction->msgs, msg_message("dumbeffect",
|
||||||
|
"unit weeks skill", u, weeks, (skill_t)sb->id));
|
||||||
|
} /* sonst Glück gehabt: wer nix weiss, kann nix vergessen... */
|
||||||
|
change_effect(u, oldpotiontype[P_FOOL], -effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void astral_crumble(unit *u) {
|
||||||
|
item **itemp = &u->items;
|
||||||
|
while (*itemp) {
|
||||||
|
item *itm = *itemp;
|
||||||
|
if ((itm->type->flags & ITF_NOTLOST) == 0) {
|
||||||
|
if (itm->type->flags & (ITF_BIG | ITF_ANIMAL | ITF_CURSED)) {
|
||||||
|
ADDMSG(&u->faction->msgs, msg_message("itemcrumble",
|
||||||
|
"unit region item amount",
|
||||||
|
u, u->region, itm->type->rtype, itm->number));
|
||||||
|
i_free(i_remove(itemp, itm));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itemp = &itm->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void age_unit(region * r, unit * u)
|
static void age_unit(region * r, unit * u)
|
||||||
{
|
{
|
||||||
const race *rc = u_race(u);
|
const race *rc = u_race(u);
|
||||||
|
@ -169,21 +208,11 @@ static void age_unit(region * r, unit * u)
|
||||||
if (u->number > 0 && rc->age_unit) {
|
if (u->number > 0 && rc->age_unit) {
|
||||||
rc->age_unit(u);
|
rc->age_unit(u);
|
||||||
}
|
}
|
||||||
if (u->region && is_astral(u->region)) {
|
if (u->attribs) {
|
||||||
item **itemp = &u->items;
|
dumbeffect(u);
|
||||||
while (*itemp) {
|
}
|
||||||
item *itm = *itemp;
|
if (u->items && u->region && is_astral(u->region)) {
|
||||||
if ((itm->type->flags & ITF_NOTLOST) == 0) {
|
astral_crumble(u);
|
||||||
if (itm->type->flags & (ITF_BIG | ITF_ANIMAL | ITF_CURSED)) {
|
|
||||||
ADDMSG(&u->faction->msgs, msg_message("itemcrumble",
|
|
||||||
"unit region item amount",
|
|
||||||
u, u->region, itm->type->rtype, itm->number));
|
|
||||||
i_free(i_remove(itemp, itm));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itemp = &itm->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,26 +227,6 @@ static void live(region * r)
|
||||||
/* IUW: age_unit() kann u loeschen, u->next ist dann
|
/* IUW: age_unit() kann u loeschen, u->next ist dann
|
||||||
* undefiniert, also muessen wir hier schon das nächste
|
* undefiniert, also muessen wir hier schon das nächste
|
||||||
* Element bestimmen */
|
* Element bestimmen */
|
||||||
|
|
||||||
int effect = get_effect(u, oldpotiontype[P_FOOL]);
|
|
||||||
if (effect > 0) { /* Trank "Dumpfbackenbrot" */
|
|
||||||
skill *sv = u->skills, *sb = NULL;
|
|
||||||
while (sv != u->skills + u->skill_size) {
|
|
||||||
if (sb == NULL || skill_compare(sv, sb) > 0) {
|
|
||||||
sb = sv;
|
|
||||||
}
|
|
||||||
++sv;
|
|
||||||
}
|
|
||||||
/* bestes Talent raussuchen */
|
|
||||||
if (sb != NULL) {
|
|
||||||
int weeks = u->number;
|
|
||||||
if (weeks > effect) weeks = effect;
|
|
||||||
reduce_skill(u, sb, weeks);
|
|
||||||
ADDMSG(&u->faction->msgs, msg_message("dumbeffect",
|
|
||||||
"unit weeks skill", u, weeks, (skill_t)sb->id));
|
|
||||||
} /* sonst Glück gehabt: wer nix weiss, kann nix vergessen... */
|
|
||||||
change_effect(u, oldpotiontype[P_FOOL], -effect);
|
|
||||||
}
|
|
||||||
age_unit(r, u);
|
age_unit(r, u);
|
||||||
if (*up == u)
|
if (*up == u)
|
||||||
up = &u->next;
|
up = &u->next;
|
||||||
|
@ -2521,12 +2530,12 @@ int group_cmd(unit * u, struct order *ord)
|
||||||
|
|
||||||
int origin_cmd(unit * u, struct order *ord)
|
int origin_cmd(unit * u, struct order *ord)
|
||||||
{
|
{
|
||||||
short px, py;
|
int px, py;
|
||||||
|
|
||||||
init_order_depr(ord);
|
init_order_depr(ord);
|
||||||
|
|
||||||
px = (short)getint();
|
px = getint();
|
||||||
py = (short)getint();
|
py = getint();
|
||||||
|
|
||||||
faction_setorigin(u->faction, getplaneid(u->region), px, py);
|
faction_setorigin(u->faction, getplaneid(u->region), px, py);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -460,7 +460,7 @@ static void use_key1(connection *b, void *data) {
|
||||||
if (b->type == &bt_questportal) {
|
if (b->type == &bt_questportal) {
|
||||||
const struct item_type *itype = it_find("questkey1");
|
const struct item_type *itype = it_find("questkey1");
|
||||||
ADDMSG(&u->faction->msgs,
|
ADDMSG(&u->faction->msgs,
|
||||||
msg_message("use_item", "unit item", u, itype->rtype));
|
msg_message("use_item", "unit amount item", u, 1, itype->rtype));
|
||||||
b->data.i &= 0xFE;
|
b->data.i &= 0xFE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +470,7 @@ static void use_key2(connection *b, void *data) {
|
||||||
if (b->type == &bt_questportal) {
|
if (b->type == &bt_questportal) {
|
||||||
const struct item_type *itype = it_find("questkey2");
|
const struct item_type *itype = it_find("questkey2");
|
||||||
ADDMSG(&u->faction->msgs,
|
ADDMSG(&u->faction->msgs,
|
||||||
msg_message("use_item", "unit item", u, itype->rtype));
|
msg_message("use_item", "unit amount item", u, 1, itype->rtype));
|
||||||
b->data.i &= 0xFD;
|
b->data.i &= 0xFD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -953,10 +953,10 @@ struct message *msg_curse(const struct curse *c, const void *obj, objtype_t typ,
|
||||||
{ "unit_unknown", "region_unknown", "building_unknown",
|
{ "unit_unknown", "region_unknown", "building_unknown",
|
||||||
"ship_unknown" };
|
"ship_unknown" };
|
||||||
msg = msg_message(mkname("curseinfo", unknown[typ]), "id", c->no);
|
msg = msg_message(mkname("curseinfo", unknown[typ]), "id", c->no);
|
||||||
log_error("no curseinfo function for %s and no fallback either.\n", c->type->cname);
|
log_warning("no curseinfo function for %s and no fallback either.\n", c->type->cname);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log_error("no curseinfo function for %s, using cinfo_simple fallback.\n", c->type->cname);
|
log_debug("no curseinfo function for %s, using cinfo_simple fallback.\n", c->type->cname);
|
||||||
}
|
}
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
33
src/spells.c
33
src/spells.c
|
@ -14,20 +14,32 @@
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#endif
|
#endif
|
||||||
#include <kernel/config.h>
|
|
||||||
|
#include "spells.h"
|
||||||
|
|
||||||
#include "guard.h"
|
#include "guard.h"
|
||||||
#include "spy.h"
|
#include "spy.h"
|
||||||
#include "vortex.h"
|
#include "vortex.h"
|
||||||
#include "laws.h"
|
#include "laws.h"
|
||||||
#include "spells.h"
|
|
||||||
#include "direction.h"
|
#include "direction.h"
|
||||||
#include "randenc.h"
|
#include "randenc.h"
|
||||||
#include "monsters.h"
|
#include "monsters.h"
|
||||||
#include "teleport.h"
|
#include "teleport.h"
|
||||||
|
#include "xmlreader.h"
|
||||||
|
|
||||||
|
/* triggers includes */
|
||||||
|
#include <triggers/changefaction.h>
|
||||||
|
#include <triggers/changerace.h>
|
||||||
|
#include <triggers/createcurse.h>
|
||||||
|
#include <triggers/createunit.h>
|
||||||
|
#include <triggers/killunit.h>
|
||||||
|
#include <triggers/timeout.h>
|
||||||
|
|
||||||
|
/* attributes includes */
|
||||||
|
#include <attributes/targetregion.h>
|
||||||
|
#include <attributes/hate.h>
|
||||||
#include <attributes/attributes.h>
|
#include <attributes/attributes.h>
|
||||||
|
#include <races/races.h>
|
||||||
#include <spells/borders.h>
|
#include <spells/borders.h>
|
||||||
#include <spells/buildingcurse.h>
|
#include <spells/buildingcurse.h>
|
||||||
#include <spells/regioncurse.h>
|
#include <spells/regioncurse.h>
|
||||||
|
@ -38,6 +50,7 @@
|
||||||
|
|
||||||
/* kernel includes */
|
/* kernel includes */
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
|
#include <kernel/config.h>
|
||||||
#include <kernel/curse.h>
|
#include <kernel/curse.h>
|
||||||
#include <kernel/connection.h>
|
#include <kernel/connection.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
|
@ -54,9 +67,6 @@
|
||||||
#include <kernel/terrain.h>
|
#include <kernel/terrain.h>
|
||||||
#include <kernel/terrainid.h>
|
#include <kernel/terrainid.h>
|
||||||
#include <kernel/unit.h>
|
#include <kernel/unit.h>
|
||||||
#include <kernel/xmlreader.h>
|
|
||||||
|
|
||||||
#include <races/races.h>
|
|
||||||
|
|
||||||
/* util includes */
|
/* util includes */
|
||||||
#include <util/assert.h>
|
#include <util/assert.h>
|
||||||
|
@ -91,17 +101,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
/* triggers includes */
|
|
||||||
#include <triggers/changefaction.h>
|
|
||||||
#include <triggers/changerace.h>
|
|
||||||
#include <triggers/createcurse.h>
|
|
||||||
#include <triggers/createunit.h>
|
|
||||||
#include <triggers/killunit.h>
|
|
||||||
#include <triggers/timeout.h>
|
|
||||||
|
|
||||||
/* attributes includes */
|
|
||||||
#include <attributes/targetregion.h>
|
|
||||||
#include <attributes/hate.h>
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
|
|
|
@ -345,9 +345,16 @@ const struct curse_type ct_skillmod = {
|
||||||
NULL, read_skill, write_skill
|
NULL, read_skill, write_skill
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct curse_type ct_fleechance = {
|
||||||
|
"fleechance",
|
||||||
|
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||||
|
NULL, NULL, NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
void register_unitcurse(void)
|
void register_unitcurse(void)
|
||||||
{
|
{
|
||||||
|
ct_register(&ct_fleechance);
|
||||||
ct_register(&ct_auraboost);
|
ct_register(&ct_auraboost);
|
||||||
ct_register(&ct_magicboost);
|
ct_register(&ct_magicboost);
|
||||||
ct_register(&ct_slavery);
|
ct_register(&ct_slavery);
|
||||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
||||||
struct curse_type;
|
struct curse_type;
|
||||||
struct message;
|
struct message;
|
||||||
|
|
||||||
|
extern const struct curse_type ct_fleechance;
|
||||||
extern const struct curse_type ct_slavery;
|
extern const struct curse_type ct_slavery;
|
||||||
extern const struct curse_type ct_calmmonster;
|
extern const struct curse_type ct_calmmonster;
|
||||||
extern const struct curse_type ct_speed;
|
extern const struct curse_type ct_speed;
|
||||||
|
|
|
@ -92,33 +92,34 @@ int RunAllTests(int argc, char *argv[])
|
||||||
/* items */
|
/* items */
|
||||||
ADD_SUITE(xerewards);
|
ADD_SUITE(xerewards);
|
||||||
/* kernel */
|
/* kernel */
|
||||||
|
ADD_SUITE(academy);
|
||||||
|
ADD_SUITE(alchemy);
|
||||||
ADD_SUITE(alliance);
|
ADD_SUITE(alliance);
|
||||||
|
ADD_SUITE(ally);
|
||||||
|
ADD_SUITE(building);
|
||||||
ADD_SUITE(command);
|
ADD_SUITE(command);
|
||||||
ADD_SUITE(db);
|
ADD_SUITE(db);
|
||||||
ADD_SUITE(plane);
|
|
||||||
ADD_SUITE(unit);
|
|
||||||
ADD_SUITE(faction);
|
ADD_SUITE(faction);
|
||||||
ADD_SUITE(group);
|
ADD_SUITE(group);
|
||||||
ADD_SUITE(build);
|
ADD_SUITE(build);
|
||||||
ADD_SUITE(pool);
|
|
||||||
ADD_SUITE(curse);
|
ADD_SUITE(curse);
|
||||||
ADD_SUITE(equipment);
|
ADD_SUITE(equipment);
|
||||||
ADD_SUITE(familiar);
|
ADD_SUITE(familiar);
|
||||||
ADD_SUITE(item);
|
ADD_SUITE(item);
|
||||||
ADD_SUITE(magic);
|
ADD_SUITE(magic);
|
||||||
ADD_SUITE(academy);
|
ADD_SUITE(magicresistance);
|
||||||
ADD_SUITE(alchemy);
|
ADD_SUITE(messages);
|
||||||
|
ADD_SUITE(plane);
|
||||||
|
ADD_SUITE(pool);
|
||||||
ADD_SUITE(reports);
|
ADD_SUITE(reports);
|
||||||
ADD_SUITE(region);
|
ADD_SUITE(region);
|
||||||
ADD_SUITE(save);
|
ADD_SUITE(save);
|
||||||
ADD_SUITE(ship);
|
ADD_SUITE(ship);
|
||||||
|
ADD_SUITE(skills);
|
||||||
ADD_SUITE(spellbook);
|
ADD_SUITE(spellbook);
|
||||||
ADD_SUITE(building);
|
|
||||||
ADD_SUITE(spell);
|
ADD_SUITE(spell);
|
||||||
ADD_SUITE(spells);
|
ADD_SUITE(spells);
|
||||||
ADD_SUITE(magicresistance);
|
ADD_SUITE(unit);
|
||||||
ADD_SUITE(ally);
|
|
||||||
ADD_SUITE(messages);
|
|
||||||
/* gamecode */
|
/* gamecode */
|
||||||
ADD_SUITE(battle);
|
ADD_SUITE(battle);
|
||||||
ADD_SUITE(calendar);
|
ADD_SUITE(calendar);
|
||||||
|
|
|
@ -12,28 +12,28 @@ without prior permission by the authors of Eressea.
|
||||||
|
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
|
|
||||||
#include "xmlreader.h"
|
#include "xmlreader.h"
|
||||||
|
|
||||||
#include "building.h"
|
#include "kernel/building.h"
|
||||||
#include "guard.h"
|
#include "kernel/equipment.h"
|
||||||
#include "equipment.h"
|
#include "kernel/item.h"
|
||||||
#include "item.h"
|
#include "kernel/messages.h"
|
||||||
#include "keyword.h"
|
#include "kernel/race.h"
|
||||||
#include "messages.h"
|
#include "kernel/region.h"
|
||||||
#include "race.h"
|
#include "kernel/resources.h"
|
||||||
#include "region.h"
|
#include "kernel/ship.h"
|
||||||
#include "resources.h"
|
#include "kernel/terrain.h"
|
||||||
#include "ship.h"
|
#include "kernel/skills.h"
|
||||||
#include "terrain.h"
|
#include "kernel/spell.h"
|
||||||
#include "skills.h"
|
#include "kernel/spellbook.h"
|
||||||
#include "spell.h"
|
|
||||||
#include "spellbook.h"
|
|
||||||
#include "calendar.h"
|
|
||||||
#include "prefix.h"
|
|
||||||
#include "move.h"
|
|
||||||
|
|
||||||
/* TODO: core code should not include these files: */
|
|
||||||
#include "alchemy.h"
|
#include "alchemy.h"
|
||||||
|
#include "calendar.h"
|
||||||
|
#include "guard.h"
|
||||||
|
#include "keyword.h"
|
||||||
|
#include "move.h"
|
||||||
|
#include "prefix.h"
|
||||||
|
|
||||||
#include <modules/score.h>
|
#include <modules/score.h>
|
||||||
#include <attributes/attributes.h>
|
#include <attributes/attributes.h>
|
Loading…
Reference in a new issue