forked from github/server
Merge branch 'develop' of github.com:ennorehling/eressea into develop
This commit is contained in:
commit
0eb030194c
2
clibs
2
clibs
|
@ -1 +1 @@
|
|||
Subproject commit 9b6e34959f77d7ca3a4ce3826cb487487f557441
|
||||
Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871
|
|
@ -868,21 +868,6 @@
|
|||
</type>
|
||||
</message>
|
||||
|
||||
<message name="sink_lost_msg" section="events">
|
||||
<type>
|
||||
<arg name="dead" type="int"/>
|
||||
<arg name="region" type="region"/>
|
||||
<arg name="unit" type="unit"/>
|
||||
</type>
|
||||
</message>
|
||||
|
||||
<message name="sink_saved_msg" section="events">
|
||||
<type>
|
||||
<arg name="region" type="region"/>
|
||||
<arg name="unit" type="unit"/>
|
||||
</type>
|
||||
</message>
|
||||
|
||||
<message name="sink_msg" section="events">
|
||||
<type>
|
||||
<arg name="ship" type="ship"/>
|
||||
|
|
|
@ -1773,7 +1773,7 @@ msgid "storm"
|
|||
msgstr "\"Die $ship($ship) wird in $region($region) von Stürmen abgetrieben$if($sink,\" und sinkt\",\"\").\""
|
||||
|
||||
msgid "nr_insectwinter"
|
||||
msgstr "Es ist Winter, und Insekten können nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren."
|
||||
msgstr "Insekten können wegen des Winterwetters in der kommenden Woche nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren."
|
||||
|
||||
msgid "spellfail_nomonsters"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Dieser Zauber kann nicht auf Monster gezaubert werden.\""
|
||||
|
@ -2121,7 +2121,7 @@ msgid "missing_components"
|
|||
msgstr "\"$unit($unit) hat nicht genügend Komponenten um $spell($spell) auf Stufe $int($level) zu zaubern.\""
|
||||
|
||||
msgid "seduce_effect_1"
|
||||
msgstr "\"$unit($unit) verfiel dem Glücksspiel und hat fast sein ganzes Hab und gut verspielt.\""
|
||||
msgstr "\"$unit($unit) verfiel dem Glücksspiel und hat fast sein ganzes Hab und Gut verspielt.\""
|
||||
|
||||
msgid "xmastree_effect"
|
||||
msgstr "\"In der Region erstrahlen des Nachts bunte Lichter, Gloeckchen klingeln und frohes Kindergelaechter klingt durch den Wald.\""
|
||||
|
@ -2303,9 +2303,6 @@ msgstr "\"$unit($mage) erleidet durch den Tod seines Vertrauten einen Schock.\""
|
|||
msgid "error269"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Hier kann man nicht zaubern.\""
|
||||
|
||||
msgid "sink_saved_msg"
|
||||
msgstr "\"$unit($unit) überlebt unbeschadet und rettet sich nach $region($region).\""
|
||||
|
||||
msgid "race_noregroup"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - $race($race,0) können nicht neu gruppiert werden.\""
|
||||
|
||||
|
@ -2654,9 +2651,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit kan
|
|||
msgid "analyse_building_noage"
|
||||
msgstr "\"$unit($mage) fand heraus, dass auf $building($building) der Zauber '$curse($curse)' liegt, dessen Kraft ausreicht, um noch Jahrhunderte bestehen zu bleiben.\""
|
||||
|
||||
msgid "sink_lost_msg"
|
||||
msgstr "\"$int($amount) Personen von $unit($unit) ertrinken.$if($isnull($region),\"\",\" Die Einheit rettet sich nach $region($region).\")\""
|
||||
|
||||
msgid "error130"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIEGEBIET [1-5].\""
|
||||
|
||||
|
@ -2733,7 +2727,7 @@ msgid "volcanostartsmoke"
|
|||
msgstr "\"Aus dem Vulkankrater von $region($region) steigt plötzlich Rauch.\""
|
||||
|
||||
msgid "nr_insectfall"
|
||||
msgstr "Es ist Spätherbst, und diese Woche ist die letzte vor dem Winter, in der Insekten rekrutieren können."
|
||||
msgstr "Es ist Spätherbst, und die kommende Woche ist die letzte vor dem Winter, in der Insekten rekrutieren können."
|
||||
|
||||
msgid "error296"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Hier werden niemals Bäume wachsen.\""
|
||||
|
|
|
@ -2303,9 +2303,6 @@ msgstr "\"$unit($mage) receives a shock when his familiar dies.\""
|
|||
msgid "error269"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - You cannot cast spells here.\""
|
||||
|
||||
msgid "sink_saved_msg"
|
||||
msgstr "\"$unit($unit) survives unscathed and makes it to $region($region).\""
|
||||
|
||||
msgid "race_noregroup"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot be regrouped.\""
|
||||
|
||||
|
@ -2654,9 +2651,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit cannot
|
|||
msgid "analyse_building_noage"
|
||||
msgstr "\"$unit($mage) discovers that $building($building) is charmed with '$curse($curse)', which will last for centuries.\""
|
||||
|
||||
msgid "sink_lost_msg"
|
||||
msgstr "\"$int($amount) people of $unit($unit) drown.$if($isnull($region),\"\",\" The unit makes it to $region($region).\")\""
|
||||
|
||||
msgid "error130"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIC SPHERE [1-5].\""
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
local self = {}
|
||||
|
||||
local function equip_first(u)
|
||||
equip_newunits(u)
|
||||
name = 'seed_' .. u.race
|
||||
equip_unit(u, name, 255)
|
||||
end
|
||||
|
|
|
@ -99,8 +99,6 @@ function self.update()
|
|||
r:set_resource("tree", trees * 1.1)
|
||||
msg:send_region(r)
|
||||
end
|
||||
if clear then
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
|
|
|
@ -338,45 +338,6 @@ function test_message()
|
|||
return msg
|
||||
end
|
||||
|
||||
function test_events()
|
||||
local fail = 1
|
||||
local function msg_handler(u, evt)
|
||||
str = evt:get(0)
|
||||
u2 = evt:get(1)
|
||||
assert(u2~=nil)
|
||||
assert(str=="Du Elf stinken")
|
||||
message_unit(u, u2, "thanks unit, i got your message: " .. str)
|
||||
message_faction(u, u2.faction, "thanks faction, i got your message: " .. str)
|
||||
message_region(u, "thanks region, i got your message: " .. str)
|
||||
fail = 0
|
||||
end
|
||||
|
||||
plain = region.create(0, 0, "plain")
|
||||
skill = 8
|
||||
|
||||
f = create_faction('elf')
|
||||
f.age = 20
|
||||
|
||||
u = unit.create(f, plain)
|
||||
u.number = 1
|
||||
u:add_item("money", u.number*100)
|
||||
u:clear_orders()
|
||||
u:add_order("NUMMER PARTEI test")
|
||||
u:add_handler("message", msg_handler)
|
||||
msg = "BOTSCHAFT EINHEIT " .. itoa36(u.id) .. " Du~Elf~stinken"
|
||||
f = create_faction('elf')
|
||||
f.age = 20
|
||||
|
||||
u = unit.create(f, plain)
|
||||
u.number = 1
|
||||
u:add_item("money", u.number*100)
|
||||
u:clear_orders()
|
||||
u:add_order("NUMMER PARTEI eviL")
|
||||
u:add_order(msg)
|
||||
process_orders()
|
||||
assert(fail==0)
|
||||
end
|
||||
|
||||
function test_renumber_ship()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = create_faction('human')
|
||||
|
|
|
@ -30,6 +30,26 @@ function test_first_troll()
|
|||
assert_equal(2, u:eff_skill('perception'))
|
||||
end
|
||||
|
||||
function test_first_human()
|
||||
local f = faction.create('human')
|
||||
local r = region.create(0, 0, "plain")
|
||||
local u = unit.create(f, r, 1)
|
||||
u:equip('first_unit')
|
||||
assert_not_nil(u.building)
|
||||
assert_equal('castle', u.building.type)
|
||||
assert_equal(10, u.building.size)
|
||||
end
|
||||
|
||||
function test_first_aquarian()
|
||||
local f = faction.create('aquarian')
|
||||
local r = region.create(0, 0, "plain")
|
||||
local u = unit.create(f, r, 1)
|
||||
u:equip('first_unit')
|
||||
assert_not_nil(u.ship)
|
||||
assert_equal('boat', u.ship.type)
|
||||
assert_equal(1, u:get_skill('sailing'))
|
||||
end
|
||||
|
||||
function test_seed_unit()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create('human')
|
||||
|
@ -53,3 +73,4 @@ function test_seed_elf()
|
|||
assert_equal('castle', u.building.type)
|
||||
assert_equal(10, u.building.size)
|
||||
end
|
||||
|
||||
|
|
|
@ -517,3 +517,16 @@ function test_buy_sell()
|
|||
assert_equal(4, u:get_item(item))
|
||||
assert_not_equal(0, u:get_item('money'))
|
||||
end
|
||||
|
||||
function test_seaserpent_attack()
|
||||
local r = region.create(0, 0, 'ocean')
|
||||
local sh = ship.create(r, 'boat')
|
||||
local us = unit.create(get_monsters(), r, 1, 'seaserpent')
|
||||
local u = unit.create(faction.create('human', 'enno@example.com'), r, 20, 'human')
|
||||
u.ship = sh
|
||||
us:clear_orders()
|
||||
us:add_order('ATTACKIERE ' .. itoa36(u.id))
|
||||
us:set_skill('unarmed', 10)
|
||||
process_orders()
|
||||
write_reports()
|
||||
end
|
||||
|
|
|
@ -93,11 +93,11 @@ end
|
|||
function test_lighthouse()
|
||||
eressea.free_game()
|
||||
local r = region.create(0, 0, "mountain")
|
||||
local f = faction.create("human", "noreply@eressea.de", "de")
|
||||
local f = faction.create("human", "human@example.com")
|
||||
region.create(1, 0, "mountain")
|
||||
region.create(2, 0, "ocean")
|
||||
region.create(0, 1, "firewall")
|
||||
region.create(3, 0, "mountain")
|
||||
region.create(3, 0, "ocean")
|
||||
region.create(4, 0, "plain")
|
||||
local u = unit.create(f, r, 1)
|
||||
local b = building.create(r, "lighthouse")
|
||||
|
@ -110,7 +110,7 @@ function test_lighthouse()
|
|||
|
||||
init_reports()
|
||||
write_report(f)
|
||||
assert_true(find_in_report(f, " %(1,0%) %(vom Turm erblickt%)"))
|
||||
assert_false(find_in_report(f, " %(1,0%) %(vom Turm erblickt%)"))
|
||||
assert_true(find_in_report(f, " %(2,0%) %(vom Turm erblickt%)"))
|
||||
assert_true(find_in_report(f, " %(3,0%) %(vom Turm erblickt%)"))
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "move.h"
|
||||
#include "skill.h"
|
||||
#include "study.h"
|
||||
#include "spy.h"
|
||||
|
||||
#include <spells/buildingcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
@ -2787,10 +2788,12 @@ static void aftermath(battle * b)
|
|||
ship *sh = *sp;
|
||||
freset(sh, SF_DAMAGED);
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
sink_ship(sh);
|
||||
remove_ship(sp, sh);
|
||||
}
|
||||
if (*sp == sh)
|
||||
else {
|
||||
sp = &sh->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -455,48 +455,6 @@ int fctr_handle(struct trigger *tp, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void fctr_init(trigger * t)
|
||||
{
|
||||
t->data.v = calloc(sizeof(fctr_data), 1);
|
||||
}
|
||||
|
||||
static void fctr_done(trigger * t)
|
||||
{
|
||||
fctr_data *fd = (fctr_data *)t->data.v;
|
||||
lua_State *L = (lua_State *)global.vm_state;
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, fd->fhandle);
|
||||
free(fd);
|
||||
}
|
||||
|
||||
static struct trigger_type tt_lua = {
|
||||
"lua_event",
|
||||
fctr_init,
|
||||
fctr_done,
|
||||
fctr_handle
|
||||
};
|
||||
|
||||
static trigger *trigger_lua(struct unit *u, int handle)
|
||||
{
|
||||
trigger *t = t_new(&tt_lua);
|
||||
fctr_data *td = (fctr_data *)t->data.v;
|
||||
td->target = u;
|
||||
td->fhandle = handle;
|
||||
return t;
|
||||
}
|
||||
|
||||
static int tolua_unit_addhandler(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
||||
const char *ename = tolua_tostring(L, 2, 0);
|
||||
int handle;
|
||||
|
||||
lua_pushvalue(L, 3);
|
||||
handle = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
add_trigger(&self->attribs, ename, trigger_lua(self, handle));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_unit_addnotice(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
||||
|
@ -909,8 +867,8 @@ static int tolua_unit_create(lua_State * L)
|
|||
faction *f = (faction *)tolua_tousertype(L, 1, 0);
|
||||
region *r = (region *)tolua_tousertype(L, 2, 0);
|
||||
unit *u;
|
||||
const char *rcname = tolua_tostring(L, 4, NULL);
|
||||
int num = (int)tolua_tonumber(L, 3, 1);
|
||||
const char *rcname = tolua_tostring(L, 4, NULL);
|
||||
const race *rc;
|
||||
|
||||
assert(f && r);
|
||||
|
@ -1046,9 +1004,6 @@ void tolua_unit_open(lua_State * L)
|
|||
|
||||
tolua_function(L, TOLUA_CAST "add_notice", tolua_unit_addnotice);
|
||||
|
||||
/* npc logic: */
|
||||
tolua_function(L, TOLUA_CAST "add_handler", tolua_unit_addhandler);
|
||||
|
||||
tolua_variable(L, TOLUA_CAST "race_name", tolua_unit_get_racename,
|
||||
tolua_unit_set_racename);
|
||||
tolua_function(L, TOLUA_CAST "add_spell", tolua_unit_addspell);
|
||||
|
|
20
src/chaos.c
20
src/chaos.c
|
@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "chaos.h"
|
||||
#include "monsters.h"
|
||||
#include "move.h"
|
||||
#include "spy.h"
|
||||
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/faction.h>
|
||||
|
@ -144,19 +145,20 @@ static void chaos(region * r)
|
|||
break;
|
||||
}
|
||||
if (dir != MAXDIRECTIONS) {
|
||||
ship *sh = r->ships;
|
||||
ship **slist = &r->ships;
|
||||
unit **up;
|
||||
|
||||
while (sh) {
|
||||
ship *nsh = sh->next;
|
||||
double dmg =
|
||||
config_get_flt("rules.ship.damage.atlantis",
|
||||
0.50);
|
||||
damage_ship(sh, dmg);
|
||||
while (*slist) {
|
||||
ship *sh = *slist;
|
||||
|
||||
damage_ship(sh, 0.5);
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
sink_ship(sh);
|
||||
remove_ship(slist, sh);
|
||||
}
|
||||
else {
|
||||
slist = &sh->next;
|
||||
}
|
||||
sh = nsh;
|
||||
}
|
||||
|
||||
for (up = &r->units; *up;) {
|
||||
|
|
|
@ -22,8 +22,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct region;
|
||||
|
||||
void chaos_update(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1529,6 +1529,7 @@ static void report_itemtype(FILE *F, faction *f, const item_type *itype) {
|
|||
fprintf(F, "\"%s\"\n", translate(ch, LOC(f->locale, ch)));
|
||||
m++;
|
||||
}
|
||||
assert(!m->rtype);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
153
src/economy.c
153
src/economy.c
|
@ -426,6 +426,59 @@ static int recruit_cost(const faction * f, const race * rc)
|
|||
return -1;
|
||||
}
|
||||
|
||||
message *can_recruit(unit *u, const race *rc, order *ord, int now)
|
||||
{
|
||||
region *r = u->region;
|
||||
|
||||
/* this is a very special case because the recruiting unit may be empty
|
||||
* at this point and we have to look at the creating unit instead. This
|
||||
* is done in cansee, which is called indirectly by is_guarded(). */
|
||||
if (is_guarded(r, u)) {
|
||||
return msg_error(u, ord, 70);
|
||||
}
|
||||
|
||||
if (rc == get_race(RC_INSECT)) {
|
||||
gamedate date;
|
||||
get_gamedate(now, &date);
|
||||
if (date.season == SEASON_WINTER && r->terrain != newterrain(T_DESERT)) {
|
||||
bool usepotion = false;
|
||||
unit *u2;
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (fval(u2, UFL_WARMTH)) {
|
||||
usepotion = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!usepotion) {
|
||||
return msg_error(u, ord, 98);
|
||||
}
|
||||
}
|
||||
/* in Gletschern, Eisbergen gar nicht rekrutieren */
|
||||
if (r_insectstalled(r)) {
|
||||
return msg_error(u, ord, 97);
|
||||
}
|
||||
}
|
||||
if (is_cursed(r->attribs, &ct_riotzone)) {
|
||||
/* Die Region befindet sich in Aufruhr */
|
||||
return msg_error(u, ord, 237);
|
||||
}
|
||||
|
||||
if (rc && !playerrace(rc)) {
|
||||
return msg_error(u, ord, 139);
|
||||
}
|
||||
|
||||
if (fval(u, UFL_HERO)) {
|
||||
return msg_feedback(u, ord, "error_herorecruit", "");
|
||||
}
|
||||
if (has_skill(u, SK_MAGIC)) {
|
||||
/* error158;de;{unit} in {region}: '{command}' - Magier arbeiten
|
||||
* grunds<EFBFBD>tzlich nur alleine! */
|
||||
return msg_error(u, ord, 158);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
||||
{
|
||||
region *r = u->region;
|
||||
|
@ -434,6 +487,7 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
|||
const faction *f = u->faction;
|
||||
const struct race *rc = u_race(u);
|
||||
int n;
|
||||
message *msg;
|
||||
|
||||
init_order_depr(ord);
|
||||
n = getint();
|
||||
|
@ -456,6 +510,7 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recruitcost < 0) {
|
||||
rc = u_race(u);
|
||||
recruitcost = recruit_cost(f, rc);
|
||||
|
@ -463,95 +518,46 @@ static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
|||
recruitcost = INT_MAX;
|
||||
}
|
||||
}
|
||||
assert(rc);
|
||||
u_setrace(u, rc);
|
||||
|
||||
/* this is a very special case because the recruiting unit may be empty
|
||||
* at this point and we have to look at the creating unit instead. This
|
||||
* is done in cansee, which is called indirectly by is_guarded(). */
|
||||
if (is_guarded(r, u)) {
|
||||
cmistake(u, ord, 70, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == get_race(RC_INSECT)) {
|
||||
gamedate date;
|
||||
get_gamedate(turn, &date);
|
||||
if (date.season == 0 && r->terrain != newterrain(T_DESERT)) {
|
||||
bool usepotion = false;
|
||||
unit *u2;
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next)
|
||||
if (fval(u2, UFL_WARMTH)) {
|
||||
usepotion = true;
|
||||
break;
|
||||
}
|
||||
if (!usepotion)
|
||||
{
|
||||
cmistake(u, ord, 98, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* in Gletschern, Eisbergen gar nicht rekrutieren */
|
||||
if (r_insectstalled(r)) {
|
||||
cmistake(u, ord, 97, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (is_cursed(r->attribs, &ct_riotzone)) {
|
||||
/* Die Region befindet sich in Aufruhr */
|
||||
cmistake(u, ord, 237, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (recruitcost) {
|
||||
if (recruitcost > 0) {
|
||||
int pool;
|
||||
plane *pl = getplane(r);
|
||||
if (pl && fval(pl, PFL_NORECRUITS)) {
|
||||
|
||||
if (pl && (pl->flags & PFL_NORECRUITS)) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_pflnorecruit", ""));
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT,
|
||||
recruitcost) < recruitcost) {
|
||||
pool = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, recruitcost * n);
|
||||
if (pool < recruitcost) {
|
||||
cmistake(u, ord, 142, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
pool /= recruitcost;
|
||||
if (n > pool) n = pool;
|
||||
}
|
||||
if (!playerrace(rc)) {
|
||||
cmistake(u, ord, 139, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fval(u, UFL_HERO)) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_herorecruit", ""));
|
||||
return;
|
||||
}
|
||||
if (has_skill(u, SK_MAGIC)) {
|
||||
/* error158;de;{unit} in {region}: '{command}' - Magier arbeiten
|
||||
* grunds<EFBFBD>tzlich nur alleine! */
|
||||
cmistake(u, ord, 158, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
if (has_skill(u, SK_ALCHEMY)
|
||||
&& count_skill(u->faction, SK_ALCHEMY) + n >
|
||||
skill_limit(u->faction, SK_ALCHEMY)) {
|
||||
cmistake(u, ord, 156, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
if (recruitcost > 0) {
|
||||
int pooled =
|
||||
get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, recruitcost * n);
|
||||
int pr = pooled / recruitcost;
|
||||
if (n > pr) n = pr;
|
||||
}
|
||||
|
||||
u->wants = n;
|
||||
|
||||
if (!n) {
|
||||
cmistake(u, ord, 142, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
if (has_skill(u, SK_ALCHEMY)) {
|
||||
if (count_skill(u->faction, SK_ALCHEMY) + n > skill_limit(u->faction, SK_ALCHEMY)) {
|
||||
cmistake(u, ord, 156, MSG_EVENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(rc);
|
||||
msg = can_recruit(u, rc, ord, turn);
|
||||
if (msg) {
|
||||
add_message(&u->faction->msgs, msg);
|
||||
msg_release(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
u_setrace(u, rc);
|
||||
u->wants = n;
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->qty = n;
|
||||
o->unit = u;
|
||||
|
@ -1252,7 +1258,6 @@ static void create_potion(unit * u, const item_type * itype, int want)
|
|||
/* something missing from the list of materials */
|
||||
ADDMSG(&u->faction->msgs, msg_materials_required(u, u->thisorder,
|
||||
itype->construction, want));
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
i_change(&u->items, itype, built);
|
||||
|
|
|
@ -44,6 +44,7 @@ extern "C" {
|
|||
#define MAXNEWBIES 5
|
||||
|
||||
struct unit;
|
||||
struct race;
|
||||
struct region;
|
||||
struct faction;
|
||||
struct order;
|
||||
|
@ -94,6 +95,7 @@ extern "C" {
|
|||
void steal_cmd(struct unit * u, struct order *ord, struct econ_request ** stealorders);
|
||||
void expandstealing(struct region * r, struct econ_request * stealorders);
|
||||
|
||||
struct message *can_recruit(struct unit *u, const struct race *rc, struct order *ord, int now);
|
||||
void add_recruits(struct unit * u, int number, int wanted);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -480,6 +480,35 @@ static void test_recruit(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_recruit_insect(CuTest *tc) {
|
||||
unit *u;
|
||||
faction *f;
|
||||
message * msg;
|
||||
|
||||
test_setup();
|
||||
test_create_calendar();
|
||||
f = test_create_faction(test_create_race("insect"));
|
||||
u = test_create_unit(f, test_create_region(0, 0, NULL));
|
||||
u->thisorder = create_order(K_RECRUIT, f->locale, "%d", 1);
|
||||
|
||||
msg = can_recruit(u, f->race, u->thisorder, 1083); /* Autumn */
|
||||
CuAssertPtrEquals(tc, NULL, msg);
|
||||
|
||||
msg = can_recruit(u, f->race, u->thisorder, 1084); /* Insects, Winter */
|
||||
CuAssertPtrNotNull(tc, msg);
|
||||
msg_release(msg);
|
||||
|
||||
u->flags |= UFL_WARMTH;
|
||||
msg = can_recruit(u, f->race, u->thisorder, 1084); /* Insects, potion, Winter */
|
||||
CuAssertPtrEquals(tc, NULL, msg);
|
||||
|
||||
u->flags = 0;
|
||||
msg = can_recruit(u, NULL, u->thisorder, 1084); /* Other races, Winter */
|
||||
CuAssertPtrEquals(tc, NULL, msg);
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_income(CuTest *tc)
|
||||
{
|
||||
race *rc;
|
||||
|
@ -764,6 +793,7 @@ CuSuite *get_economy_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_trade_insect);
|
||||
SUITE_ADD_TEST(suite, test_maintain_buildings);
|
||||
SUITE_ADD_TEST(suite, test_recruit);
|
||||
SUITE_ADD_TEST(suite, test_recruit_insect);
|
||||
SUITE_ADD_TEST(suite, test_loot);
|
||||
SUITE_ADD_TEST(suite, test_expand_production);
|
||||
return suite;
|
||||
|
|
|
@ -625,6 +625,7 @@ static void handle_requirement(parseinfo *pi, const XML_Char *el, const XML_Char
|
|||
|
||||
assert(nreqs < MAX_REQUIREMENTS);
|
||||
req = reqs + nreqs;
|
||||
req->number = 1;
|
||||
for (i = 0; attr[i]; i += 2) {
|
||||
if (xml_strcmp(attr[i], "type") == 0) {
|
||||
req->rtype = rt_get_or_create(attr[i + 1]);
|
||||
|
|
29
src/gmtool.c
29
src/gmtool.c
|
@ -530,16 +530,31 @@ static void statusline(WINDOW * win, const char *str)
|
|||
}
|
||||
|
||||
static void reset_region(region *r) {
|
||||
unit **up = &r->units;
|
||||
bool players = false;
|
||||
|
||||
r->flags = 0;
|
||||
a_removeall(&r->attribs, NULL);
|
||||
while (r->units) {
|
||||
remove_unit(&r->units, r->units);
|
||||
while (*up) {
|
||||
unit *u = *up;
|
||||
if (is_monsters(u->faction)) {
|
||||
remove_unit(up, u);
|
||||
}
|
||||
else {
|
||||
players = true;
|
||||
up = &u->next;
|
||||
}
|
||||
}
|
||||
while (r->ships) {
|
||||
remove_ship(&r->ships, r->ships);
|
||||
}
|
||||
while (r->buildings) {
|
||||
remove_building(&r->buildings, r->buildings);
|
||||
if (!players) {
|
||||
while (r->ships) {
|
||||
remove_ship(&r->ships, r->ships);
|
||||
}
|
||||
while (r->buildings) {
|
||||
remove_building(&r->buildings, r->buildings);
|
||||
}
|
||||
if (r->land) {
|
||||
init_region(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -895,7 +895,9 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
|
|||
}
|
||||
fset(b, BLD_EXPANDED);
|
||||
|
||||
update_lighthouse(b);
|
||||
if (is_lighthouse(btype)) {
|
||||
update_lighthouse(b);
|
||||
}
|
||||
|
||||
return built;
|
||||
}
|
||||
|
|
|
@ -377,7 +377,9 @@ building *new_building(const struct building_type * btype, region * r,
|
|||
bptr = &(*bptr)->next;
|
||||
*bptr = b;
|
||||
|
||||
update_lighthouse(b);
|
||||
if (is_lighthouse(b->type)) {
|
||||
update_lighthouse(b);
|
||||
}
|
||||
bname = LOC(lang, btype->_name);
|
||||
if (!bname) {
|
||||
bname = LOC(lang, parameters[P_GEBAEUDE]);
|
||||
|
@ -399,6 +401,7 @@ static building *deleted_buildings;
|
|||
void remove_building(building ** blist, building * b)
|
||||
{
|
||||
unit *u;
|
||||
region *r = b->region;
|
||||
static const struct building_type *bt_caravan, *bt_dam, *bt_tunnel;
|
||||
static int btypes;
|
||||
|
||||
|
@ -410,18 +413,19 @@ void remove_building(building ** blist, building * b)
|
|||
bt_tunnel = bt_find("tunnel");
|
||||
}
|
||||
handle_event(b->attribs, "destroy", b);
|
||||
for (u = b->region->units; u; u = u->next) {
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->building == b) leave(u, true);
|
||||
}
|
||||
|
||||
if (is_lighthouse(b->type)) {
|
||||
remove_lighthouse(b);
|
||||
}
|
||||
b->size = 0;
|
||||
update_lighthouse(b);
|
||||
bunhash(b);
|
||||
|
||||
/* Falls Karawanserei, Damm oder Tunnel einst<73>rzen, wird die schon
|
||||
* gebaute Strasse zur Haelfte vernichtet */
|
||||
if (b->type == bt_caravan || b->type == bt_dam || b->type == bt_tunnel) {
|
||||
region *r = b->region;
|
||||
int d;
|
||||
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||
direction_t dir = (direction_t)d;
|
||||
|
|
|
@ -1048,6 +1048,43 @@ int fix_demand(region * rd) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void init_region(region *r)
|
||||
{
|
||||
static int changed;
|
||||
static const terrain_type *t_plain;
|
||||
const terrain_type * terrain = r->terrain;
|
||||
int horses = 0, trees = 0;
|
||||
if (terrain_changed(&changed)) {
|
||||
t_plain = get_terrain(terrainnames[T_PLAIN]);
|
||||
}
|
||||
if (terrain->size>0) {
|
||||
horses = rng_int() % (terrain->size / 50);
|
||||
trees = terrain->size * (30 + rng_int() % 40) / 1000;
|
||||
}
|
||||
if (t_plain && terrain == t_plain) {
|
||||
rsethorses(r, horses);
|
||||
if (chance(0.4)) {
|
||||
rsettrees(r, 2, trees);
|
||||
}
|
||||
}
|
||||
else if (trees>0 && chance(0.2)) {
|
||||
rsettrees(r, 2, trees);
|
||||
}
|
||||
else {
|
||||
rsettrees(r, 2, 0);
|
||||
}
|
||||
rsettrees(r, 1, rtrees(r, 2) / 4);
|
||||
rsettrees(r, 0, rtrees(r, 2) / 8);
|
||||
|
||||
if (!fval(r, RF_CHAOTIC)) {
|
||||
int peasants;
|
||||
peasants = (region_maxworkers(r) * (20 + dice(6, 10))) / 100;
|
||||
rsetpeasants(r, MAX(100, peasants));
|
||||
rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL,
|
||||
INT_MAX) + 1) + rng_int() % 5));
|
||||
}
|
||||
}
|
||||
|
||||
void terraform_region(region * r, const terrain_type * terrain)
|
||||
{
|
||||
/* Resourcen, die nicht mehr vorkommen können, löschen */
|
||||
|
@ -1195,40 +1232,8 @@ void terraform_region(region * r, const terrain_type * terrain)
|
|||
else
|
||||
freset(r, RF_MALLORN);
|
||||
}
|
||||
}
|
||||
|
||||
if (oldterrain == NULL || terrain->size != oldterrain->size) {
|
||||
static int changed;
|
||||
static const terrain_type *t_plain;
|
||||
int horses = 0, trees = 0;
|
||||
if (terrain_changed(&changed)) {
|
||||
t_plain = get_terrain(terrainnames[T_PLAIN]);
|
||||
}
|
||||
if (terrain->size>0) {
|
||||
horses = rng_int() % (terrain->size / 50);
|
||||
trees = terrain->size * (30 + rng_int() % 40) / 1000;
|
||||
}
|
||||
if (t_plain && terrain == t_plain) {
|
||||
rsethorses(r, horses);
|
||||
if (chance(0.4)) {
|
||||
rsettrees(r, 2, trees);
|
||||
}
|
||||
}
|
||||
else if (trees>0 && chance(0.2)) {
|
||||
rsettrees(r, 2, trees);
|
||||
}
|
||||
else {
|
||||
rsettrees(r, 2, 0);
|
||||
}
|
||||
rsettrees(r, 1, rtrees(r, 2) / 4);
|
||||
rsettrees(r, 0, rtrees(r, 2) / 8);
|
||||
|
||||
if (!fval(r, RF_CHAOTIC)) {
|
||||
int peasants;
|
||||
peasants = (region_maxworkers(r) * (20 + dice(6, 10))) / 100;
|
||||
rsetpeasants(r, MAX(100, peasants));
|
||||
rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL,
|
||||
INT_MAX) + 1) + rng_int() % 5));
|
||||
if (oldterrain == NULL || terrain->size != oldterrain->size) {
|
||||
init_region(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,6 +228,7 @@ extern "C" {
|
|||
struct region *new_region(int x, int y, struct plane *pl, int uid);
|
||||
void remove_region(region ** rlist, region * r);
|
||||
void terraform_region(struct region *r, const struct terrain_type *terrain);
|
||||
void init_region(struct region *r);
|
||||
bool pnormalize(int *x, int *y, const struct plane *pl);
|
||||
|
||||
extern const int delta_x[MAXDIRECTIONS];
|
||||
|
|
|
@ -1493,7 +1493,9 @@ int read_game(gamedata *data)
|
|||
if (r->flags & RF_LIGHTHOUSE) {
|
||||
building *b;
|
||||
for (b = r->buildings; b; b = b->next) {
|
||||
update_lighthouse(b);
|
||||
if (is_lighthouse(b->type)) {
|
||||
update_lighthouse(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,9 +124,9 @@ extern "C" {
|
|||
extern void write_ship_reference(const struct ship *sh,
|
||||
struct storage *store);
|
||||
|
||||
extern void remove_ship(struct ship **slist, struct ship *s);
|
||||
extern void free_ship(struct ship *s);
|
||||
extern void free_ships(void);
|
||||
void remove_ship(struct ship **slist, struct ship *s);
|
||||
void free_ship(struct ship *s);
|
||||
void free_ships(void);
|
||||
|
||||
const char *ship_getname(const struct ship *sh);
|
||||
void ship_setname(struct ship *self, const char *name);
|
||||
|
|
12
src/laws.c
12
src/laws.c
|
@ -2058,17 +2058,6 @@ int mail_cmd(unit * u, struct order *ord)
|
|||
break;
|
||||
}
|
||||
else {
|
||||
attrib *a = a_find(u2->attribs, &at_eventhandler);
|
||||
if (a != NULL) {
|
||||
event_arg args[3];
|
||||
args[0].data.v = (void *)s;
|
||||
args[0].type = "string";
|
||||
args[1].data.v = (void *)u;
|
||||
args[1].type = "unit";
|
||||
args[2].type = NULL;
|
||||
handle_event(a, "message", args);
|
||||
}
|
||||
|
||||
mailunit(r, u, n, ord, s);
|
||||
}
|
||||
return 0;
|
||||
|
@ -2590,6 +2579,7 @@ void sinkships(struct region * r)
|
|||
}
|
||||
}
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
sink_ship(sh);
|
||||
remove_ship(shp, sh);
|
||||
}
|
||||
if (*shp == sh)
|
||||
|
|
140
src/lighthouse.c
140
src/lighthouse.c
|
@ -19,72 +19,94 @@ attrib_type at_lighthouse = {
|
|||
/* Rest ist NULL; tempor<6F>res, nicht alterndes Attribut */
|
||||
};
|
||||
|
||||
bool is_lighthouse(const building_type *btype)
|
||||
{
|
||||
return is_building_type(btype, "lighthouse");
|
||||
}
|
||||
|
||||
/* update_lighthouse: call this function whenever the size of a lighthouse changes
|
||||
* it adds temporary markers to the surrounding regions.
|
||||
* The existence of markers says nothing about the quality of the observer in
|
||||
* the lighthouse, for this may change more frequently.
|
||||
*/
|
||||
* it adds temporary markers to the surrounding regions.
|
||||
* The existence of markers says nothing about the quality of the observer in
|
||||
* the lighthouse, since this may change more frequently.
|
||||
*/
|
||||
void update_lighthouse(building * lh)
|
||||
{
|
||||
if (is_building_type(lh->type, "lighthouse")) {
|
||||
region *r = lh->region;
|
||||
region *r = lh->region;
|
||||
assert(is_lighthouse(lh->type));
|
||||
|
||||
r->flags |= RF_LIGHTHOUSE;
|
||||
if (lh->size > 0) {
|
||||
int d = (int)log10(lh->size) + 1;
|
||||
int x;
|
||||
for (x = -d; x <= d; ++x) {
|
||||
int y;
|
||||
for (y = -d; y <= d; ++y) {
|
||||
attrib *a;
|
||||
region *r2;
|
||||
int px = r->x + x, py = r->y + y;
|
||||
r->flags |= RF_LIGHTHOUSE;
|
||||
if (lh->size >= 10) {
|
||||
int d = lighthouse_range(lh);
|
||||
int x;
|
||||
for (x = -d; x <= d; ++x) {
|
||||
int y;
|
||||
for (y = -d; y <= d; ++y) {
|
||||
attrib *a;
|
||||
region *r2;
|
||||
int px = r->x + x, py = r->y + y;
|
||||
|
||||
pnormalize(&px, &py, rplane(r));
|
||||
r2 = findregion(px, py);
|
||||
if (!r2 || !fval(r2->terrain, SEA_REGION))
|
||||
continue;
|
||||
if (distance(r, r2) > d)
|
||||
continue;
|
||||
a = a_find(r2->attribs, &at_lighthouse);
|
||||
while (a && a->type == &at_lighthouse) {
|
||||
building *b = (building *)a->data.v;
|
||||
if (b == lh)
|
||||
break;
|
||||
a = a->next;
|
||||
}
|
||||
if (!a) {
|
||||
a = a_add(&r2->attribs, a_new(&at_lighthouse));
|
||||
a->data.v = (void *)lh;
|
||||
}
|
||||
pnormalize(&px, &py, rplane(r));
|
||||
r2 = findregion(px, py);
|
||||
if (!r2 || !fval(r2->terrain, SEA_REGION))
|
||||
continue;
|
||||
if (distance(r, r2) > d)
|
||||
continue;
|
||||
a = a_find(r2->attribs, &at_lighthouse);
|
||||
while (a && a->type == &at_lighthouse) {
|
||||
building *b = (building *)a->data.v;
|
||||
if (b == lh)
|
||||
break;
|
||||
a = a->next;
|
||||
}
|
||||
if (!a) {
|
||||
a = a_add(&r2->attribs, a_new(&at_lighthouse));
|
||||
a->data.v = (void *)lh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int lighthouse_range(const building * b, const faction * f, const unit *u)
|
||||
{
|
||||
if (fval(b, BLD_MAINTAINED) && b->size >= 10) {
|
||||
int maxd = (int)log10(b->size) + 1;
|
||||
void remove_lighthouse(const building *lh) {
|
||||
building *b;
|
||||
region * r = lh->region;
|
||||
|
||||
if (u && skill_enabled(SK_PERCEPTION)) {
|
||||
r->flags &= ~RF_LIGHTHOUSE;
|
||||
for (b = r->buildings; b; b = b->next) {
|
||||
if (b != lh && is_lighthouse(b->type)) {
|
||||
update_lighthouse(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int lighthouse_range(const building * b)
|
||||
{
|
||||
if (b->size >= 10 && (b->flags & BLD_MAINTAINED)) {
|
||||
return (int)log10(b->size) + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lighthouse_view_distance(const building * b, const unit *u)
|
||||
{
|
||||
if (b->size >= 10 && (b->flags & BLD_MAINTAINED)) {
|
||||
int maxd = lighthouse_range(b);
|
||||
|
||||
if (maxd > 0 && u && skill_enabled(SK_PERCEPTION)) {
|
||||
int sk = effskill(u, SK_PERCEPTION, 0) / 3;
|
||||
assert(u->building == b);
|
||||
assert(u->faction == f);
|
||||
if (maxd > sk) maxd = sk;
|
||||
}
|
||||
/* E3A rule: no perception req'd */
|
||||
return maxd;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool check_leuchtturm(region * r, faction * f)
|
||||
bool lighthouse_guarded(const region * r)
|
||||
{
|
||||
attrib *a;
|
||||
|
||||
if (!fval(r->terrain, SEA_REGION)) {
|
||||
if (!r->attribs || !(r->terrain->flags & SEA_REGION)) {
|
||||
return false;
|
||||
}
|
||||
for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse;
|
||||
|
@ -92,37 +114,11 @@ bool check_leuchtturm(region * r, faction * f)
|
|||
building *b = (building *)a->data.v;
|
||||
|
||||
assert(is_building_type(b->type, "lighthouse"));
|
||||
if (fval(b, BLD_MAINTAINED) && b->size >= 10) {
|
||||
if ((b->flags & BLD_MAINTAINED) && b->size >= 10) {
|
||||
int maxd = (int)log10(b->size) + 1;
|
||||
|
||||
if (skill_enabled(SK_PERCEPTION) && f) {
|
||||
region *r2 = b->region;
|
||||
unit *u;
|
||||
int c = 0;
|
||||
int d = 0;
|
||||
|
||||
for (u = r2->units; u; u = u->next) {
|
||||
if (u->building == b) {
|
||||
c += u->number;
|
||||
if (c > buildingcapacity(b))
|
||||
break;
|
||||
if (u->faction == f) {
|
||||
if (!d)
|
||||
d = distance(r, r2);
|
||||
if (maxd < d)
|
||||
break;
|
||||
if (effskill(u, SK_PERCEPTION, 0) >= d * 3)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (c)
|
||||
break; /* first unit that's no longer in the house ends the search */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* E3A rule: no perception req'd */
|
||||
return true;
|
||||
}
|
||||
int d = distance(r, b->region);
|
||||
assert(maxd >= d);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,15 +29,18 @@ extern "C" {
|
|||
struct faction;
|
||||
struct region;
|
||||
struct building;
|
||||
struct building_type;
|
||||
struct unit;
|
||||
struct attrib;
|
||||
|
||||
extern struct attrib_type at_lighthouse;
|
||||
/* leuchtturm */
|
||||
bool check_leuchtturm(struct region *r, struct faction *f);
|
||||
bool is_lighthouse(const struct building_type *btype);
|
||||
bool lighthouse_guarded(const struct region *r);
|
||||
void update_lighthouse(struct building *b);
|
||||
int lighthouse_range(const struct building *b, const struct faction *f,
|
||||
const struct unit *u);
|
||||
void remove_lighthouse(const struct building *lh);
|
||||
int lighthouse_range(const struct building *b);
|
||||
int lighthouse_view_distance(const struct building *b, const struct unit *u);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -26,35 +26,39 @@ static void test_lighthouse_range(CuTest * tc)
|
|||
u1 = test_create_unit(test_create_faction(NULL), r);
|
||||
u2 = test_create_unit(test_create_faction(NULL), r);
|
||||
b = test_create_building(r, test_create_buildingtype("lighthouse"));
|
||||
CuAssertIntEquals(tc, 0, lighthouse_range(b, NULL, NULL));
|
||||
CuAssertIntEquals(tc, 0, lighthouse_range(b, u1->faction, NULL));
|
||||
CuAssertIntEquals(tc, 0, lighthouse_range(b));
|
||||
b->size = 9;
|
||||
CuAssertIntEquals(tc, 0, lighthouse_range(b));
|
||||
b->size = 10;
|
||||
CuAssertIntEquals(tc, 0, lighthouse_range(b, NULL, NULL));
|
||||
CuAssertIntEquals(tc, 0, lighthouse_range(b));
|
||||
b->flags |= BLD_MAINTAINED;
|
||||
CuAssertIntEquals(tc, 2, lighthouse_range(b));
|
||||
u1->building = b;
|
||||
u2->building = b;
|
||||
u1->number = 10;
|
||||
set_level(u1, SK_PERCEPTION, 3);
|
||||
set_level(u2, SK_PERCEPTION, 3);
|
||||
CuAssertIntEquals(tc, 0, lighthouse_range(b, NULL, NULL));
|
||||
b->flags |= BLD_MAINTAINED;
|
||||
CuAssertIntEquals(tc, 1, lighthouse_range(b, u1->faction, u1));
|
||||
|
||||
CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u1));
|
||||
set_level(u1, SK_PERCEPTION, 6);
|
||||
CuAssertIntEquals(tc, 2, lighthouse_range(b, u1->faction, u1));
|
||||
/* lighthouse_range does not check inside_building */
|
||||
CuAssertIntEquals(tc, 1, lighthouse_range(b, u2->faction, u2));
|
||||
CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u2));
|
||||
CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, u1));
|
||||
b->size = 100;
|
||||
update_lighthouse(b);
|
||||
CuAssertIntEquals(tc, 3, lighthouse_range(b, NULL, NULL));
|
||||
CuAssertIntEquals(tc, 2, lighthouse_range(b, u1->faction, u1));
|
||||
CuAssertIntEquals(tc, 3, lighthouse_range(b));
|
||||
CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, u1));
|
||||
set_level(u1, SK_PERCEPTION, 9);
|
||||
CuAssertIntEquals(tc, 3, lighthouse_range(b, u1->faction, u1));
|
||||
CuAssertIntEquals(tc, 1, lighthouse_range(b, u2->faction, u2));
|
||||
CuAssertIntEquals(tc, 3, lighthouse_view_distance(b, u1));
|
||||
CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u2));
|
||||
b->size = 99;
|
||||
CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, u1));
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_lighthouse_update(CuTest * tc)
|
||||
{
|
||||
region *r1, *r2, *r3;
|
||||
region *r1, *r2, *r3, *r4;
|
||||
building *b;
|
||||
const struct terrain_type *t_ocean, *t_plain;
|
||||
|
||||
|
@ -64,20 +68,23 @@ static void test_lighthouse_update(CuTest * tc)
|
|||
r1 = test_create_region(0, 0, t_plain);
|
||||
r2 = test_create_region(1, 0, t_ocean);
|
||||
r3 = test_create_region(2, 0, t_ocean);
|
||||
r4 = test_create_region(0, 1, t_plain);
|
||||
b = test_create_building(r1, test_create_buildingtype("lighthouse"));
|
||||
b->flags |= BLD_MAINTAINED;
|
||||
CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE);
|
||||
CuAssertPtrEquals(tc, NULL, r1->attribs);
|
||||
CuAssertPtrEquals(tc, NULL, r2->attribs);
|
||||
CuAssertPtrEquals(tc, NULL, r3->attribs);
|
||||
CuAssertPtrEquals(tc, NULL, r4->attribs);
|
||||
|
||||
r1->flags = 0;
|
||||
b->size = 1;
|
||||
b->size = 9; /* minimum size for any effect is 10 */
|
||||
update_lighthouse(b);
|
||||
CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE);
|
||||
CuAssertPtrNotNull(tc, r2->attribs);
|
||||
CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r2->attribs->type);
|
||||
CuAssertPtrEquals(tc, NULL, r1->attribs);
|
||||
CuAssertPtrEquals(tc, NULL, r2->attribs);
|
||||
CuAssertPtrEquals(tc, NULL, r3->attribs);
|
||||
CuAssertPtrEquals(tc, NULL, r4->attribs);
|
||||
|
||||
a_removeall(&r2->attribs, NULL);
|
||||
r1->flags = 0;
|
||||
|
@ -88,6 +95,39 @@ static void test_lighthouse_update(CuTest * tc)
|
|||
CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r2->attribs->type);
|
||||
CuAssertPtrNotNull(tc, r3->attribs);
|
||||
CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r3->attribs->type);
|
||||
CuAssertPtrEquals(tc, NULL, r4->attribs);
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_lighthouse_guard(CuTest * tc) {
|
||||
region *r1, *r2, *r3, *r4;
|
||||
building *b;
|
||||
const struct terrain_type *t_ocean, *t_plain;
|
||||
|
||||
test_setup();
|
||||
t_ocean = test_create_terrain("ocean", SEA_REGION);
|
||||
t_plain = test_create_terrain("plain", LAND_REGION);
|
||||
r1 = test_create_region(0, 0, t_plain);
|
||||
r2 = test_create_region(1, 0, t_ocean);
|
||||
r3 = test_create_region(2, 0, t_ocean);
|
||||
r4 = test_create_region(0, 1, t_plain);
|
||||
b = test_create_building(r1, test_create_buildingtype("lighthouse"));
|
||||
b->flags |= BLD_MAINTAINED;
|
||||
b->size = 10;
|
||||
CuAssertIntEquals(tc, 2, lighthouse_range(b));
|
||||
update_lighthouse(b);
|
||||
CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE);
|
||||
CuAssertPtrEquals(tc, NULL, r1->attribs);
|
||||
CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r2->attribs->type);
|
||||
CuAssertPtrEquals(tc, (void *)&at_lighthouse, (void *)r3->attribs->type);
|
||||
CuAssertPtrEquals(tc, NULL, r4->attribs);
|
||||
CuAssertIntEquals(tc, false, lighthouse_guarded(r1));
|
||||
CuAssertIntEquals(tc, true, lighthouse_guarded(r2));
|
||||
CuAssertIntEquals(tc, true, lighthouse_guarded(r3));
|
||||
CuAssertIntEquals(tc, false, lighthouse_guarded(r4));
|
||||
b->size = 1; /* size can go down in destroy_cmd */
|
||||
CuAssertIntEquals(tc, false, lighthouse_guarded(r2));
|
||||
CuAssertIntEquals(tc, false, lighthouse_guarded(r3));
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
|
@ -96,5 +136,6 @@ CuSuite *get_lighthouse_suite(void)
|
|||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_lighthouse_range);
|
||||
SUITE_ADD_TEST(suite, test_lighthouse_update);
|
||||
SUITE_ADD_TEST(suite, test_lighthouse_guard);
|
||||
return suite;
|
||||
}
|
||||
|
|
13
src/move.c
13
src/move.c
|
@ -47,6 +47,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "laws.h"
|
||||
#include "reports.h"
|
||||
#include "study.h"
|
||||
#include "spy.h"
|
||||
#include "alchemy.h"
|
||||
#include "travelthru.h"
|
||||
#include "vortex.h"
|
||||
|
@ -541,6 +542,7 @@ static ship *do_maelstrom(region * r, unit * u)
|
|||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
||||
"region ship damage sink", r, sh, damage, 1));
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -882,12 +884,14 @@ static void drifting_ships(region * r)
|
|||
}
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
msg_to_ship_inmates(sh, &firstu, &lastu, msg_message("shipsink", "ship", sh));
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
sink_ship(sh);
|
||||
remove_ship(shp, sh);
|
||||
}
|
||||
}
|
||||
|
||||
if (*shp == sh)
|
||||
if (*shp == sh) {
|
||||
shp = &sh->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1779,7 +1783,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
|
||||
/* storms should be the first thing we do. */
|
||||
stormchance = stormyness / shipspeed(sh, u);
|
||||
if (check_leuchtturm(next_point, NULL)) {
|
||||
if (lighthouse_guarded(next_point)) {
|
||||
if (lighthouse_div > 0) {
|
||||
stormchance /= lighthouse_div;
|
||||
}
|
||||
|
@ -1867,7 +1871,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
if (reason == SA_NO_INSECT) {
|
||||
ADDMSG(&f->msgs, msg_message("detectforbidden", "unit region", u, sh->region));
|
||||
}
|
||||
else if (check_leuchtturm(current_point, NULL)) {
|
||||
else if (lighthouse_guarded(current_point)) {
|
||||
ADDMSG(&f->msgs, msg_message("sailnolandingstorm", "ship region", sh, next_point));
|
||||
}
|
||||
else {
|
||||
|
@ -1926,6 +1930,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
if (sh->region) {
|
||||
ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh));
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = NULL;
|
||||
|
|
|
@ -287,6 +287,9 @@ void setup_drift (struct drift_fixture *fix) {
|
|||
u_set_ship(fix->u, fix->sh = test_create_ship(fix->u->region, fix->st_boat));
|
||||
assert(fix->sh);
|
||||
|
||||
mt_create_va(mt_new("sink_msg", NULL),
|
||||
"ship:ship", "region:region", MT_NEW_END);
|
||||
|
||||
mt_create_va(mt_new("ship_drift", NULL),
|
||||
"ship:ship", "dir:int", MT_NEW_END);
|
||||
mt_create_va(mt_new("shipsink", NULL),
|
||||
|
|
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "economy.h"
|
||||
#include "monsters.h"
|
||||
#include "move.h"
|
||||
#include "spy.h"
|
||||
#include "study.h"
|
||||
#include "volcano.h"
|
||||
|
||||
|
@ -295,6 +296,7 @@ static void move_iceberg(region * r)
|
|||
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des",
|
||||
"ship", sh));
|
||||
}
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
else if (u != NULL) {
|
||||
|
@ -421,6 +423,7 @@ static void godcurse(void)
|
|||
ADDMSG(&uo->faction->msgs,
|
||||
msg_message("godcurse_destroy_ship", "ship", sh));
|
||||
}
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = shn;
|
||||
|
|
|
@ -2191,6 +2191,7 @@ report_plaintext(const char *filename, report_context * ctx,
|
|||
if (wrptr(&bufp, &size, bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
assert(!rm->rtype);
|
||||
}
|
||||
*bufp = 0;
|
||||
centre(out, buf, true);
|
||||
|
|
|
@ -1353,6 +1353,13 @@ static void add_seen_nb(faction *f, region *r, seen_mode mode) {
|
|||
update_interval(f, last);
|
||||
}
|
||||
|
||||
static void add_seen_lighthouse(region *r, faction *f)
|
||||
{
|
||||
if (r->terrain->flags & SEA_REGION) {
|
||||
add_seen_nb(f, r, seen_lighthouse);
|
||||
}
|
||||
}
|
||||
|
||||
/** mark all regions seen by the lighthouse.
|
||||
*/
|
||||
static void prepare_lighthouse_ql(faction *f, selist *rlist) {
|
||||
|
@ -1361,9 +1368,7 @@ static void prepare_lighthouse_ql(faction *f, selist *rlist) {
|
|||
|
||||
for (ql = rlist, qi = 0; ql; selist_advance(&ql, &qi, 1)) {
|
||||
region *rl = (region *)selist_get(ql, qi);
|
||||
if (!fval(rl->terrain, FORBIDDEN_REGION)) {
|
||||
add_seen_nb(f, rl, seen_lighthouse);
|
||||
}
|
||||
add_seen_lighthouse(rl, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1382,9 +1387,7 @@ static void prepare_lighthouse(faction *f, region *r, int range)
|
|||
assert(n > 0 && n <= 64);
|
||||
for (i = 0; i != n; ++i) {
|
||||
region *rl = result[i];
|
||||
if (!fval(rl->terrain, FORBIDDEN_REGION)) {
|
||||
add_seen_nb(f, rl, seen_lighthouse);
|
||||
}
|
||||
add_seen_lighthouse(rl, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1514,24 +1517,23 @@ static void cb_add_seen(region *r, unit *u, void *cbdata) {
|
|||
}
|
||||
}
|
||||
|
||||
void report_warnings(faction *f, const gamedate *date)
|
||||
void report_warnings(faction *f, int now)
|
||||
{
|
||||
if (f->age < NewbieImmunity()) {
|
||||
ADDMSG(&f->msgs, msg_message("newbieimmunity", "turns",
|
||||
NewbieImmunity() - f->age));
|
||||
}
|
||||
|
||||
if (date) {
|
||||
if (f->race == get_race(RC_INSECT)) {
|
||||
if (date->season == 0) {
|
||||
ADDMSG(&f->msgs, msg_message("nr_insectwinter", ""));
|
||||
}
|
||||
else {
|
||||
gamedate next;
|
||||
get_gamedate(date->turn + 1, &next);
|
||||
if (next.season == 0) {
|
||||
ADDMSG(&f->msgs, msg_message("nr_insectfall", ""));
|
||||
}
|
||||
if (f->race == get_race(RC_INSECT)) {
|
||||
gamedate date;
|
||||
get_gamedate(now + 1, &date);
|
||||
|
||||
if (date.season == SEASON_WINTER) {
|
||||
ADDMSG(&f->msgs, msg_message("nr_insectwinter", ""));
|
||||
}
|
||||
else if (date.season == SEASON_AUTUMN) {
|
||||
if (get_gamedate(now + 2 + 2, &date)->season == SEASON_WINTER) {
|
||||
ADDMSG(&f->msgs, msg_message("nr_insectfall", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1549,11 +1551,9 @@ void prepare_report(report_context *ctx, faction *f)
|
|||
static bool rule_region_owners;
|
||||
static bool rule_lighthouse_units;
|
||||
const struct building_type *bt_lighthouse = bt_find("lighthouse");
|
||||
gamedate now;
|
||||
|
||||
/* Insekten-Winter-Warnung */
|
||||
get_gamedate(turn, &now);
|
||||
report_warnings(f, &now);
|
||||
report_warnings(f, turn);
|
||||
|
||||
if (bt_lighthouse && config_changed(&config)) {
|
||||
rule_region_owners = config_token("rules.region_owner_pay_building", bt_lighthouse->_name);
|
||||
|
@ -1592,8 +1592,8 @@ void prepare_report(report_context *ctx, faction *f)
|
|||
if (rule_region_owners && f == region_get_owner(r)) {
|
||||
for (b = rbuildings(r); b; b = b->next) {
|
||||
if (b && b->type == bt_lighthouse) {
|
||||
/* region owners get maximm range */
|
||||
int lhr = lighthouse_range(b, NULL, NULL);
|
||||
/* region owners get maximum range */
|
||||
int lhr = lighthouse_view_distance(b, NULL);
|
||||
if (lhr > range) range = lhr;
|
||||
}
|
||||
}
|
||||
|
@ -1610,7 +1610,7 @@ void prepare_report(report_context *ctx, faction *f)
|
|||
*/
|
||||
if (!fval(r, RF_LIGHTHOUSE)) {
|
||||
/* it's enough to add the region once, and if there are
|
||||
* no lighthouses, there is no need to look at more units */
|
||||
* no lighthouses here, there is no need to look at more units */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1630,10 +1630,10 @@ void prepare_report(report_context *ctx, faction *f)
|
|||
/* unit is one of ours, and inside the current lighthouse */
|
||||
if (br == 0) {
|
||||
/* lazy-calculate the range */
|
||||
br = lighthouse_range(u->building, f, u);
|
||||
}
|
||||
if (br > range) {
|
||||
range = br;
|
||||
br = lighthouse_view_distance(b, u);
|
||||
if (br > range) {
|
||||
range = br;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2446,8 +2446,10 @@ bool visible_unit(const unit *u, const faction *f, int stealthmod, seen_mode mod
|
|||
return true;
|
||||
}
|
||||
else {
|
||||
if (stealthmod > INT_MIN && (mode == seen_lighthouse || mode >= seen_unit)) {
|
||||
return cansee(f, u->region, u, stealthmod);
|
||||
if (stealthmod > INT_MIN && mode >= seen_lighthouse) {
|
||||
if (mode != seen_travel || u->building || u->ship || is_guard(u)) {
|
||||
return cansee(f, u->region, u, stealthmod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -115,7 +115,7 @@ extern "C" {
|
|||
int size, const struct faction *viewer, bool see_unit);
|
||||
int report_items(const struct unit *u, struct item *result, int size,
|
||||
const struct unit *owner, const struct faction *viewer);
|
||||
void report_warnings(struct faction *f, const struct gamedate *date);
|
||||
void report_warnings(struct faction *f, int now);
|
||||
void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length);
|
||||
void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang);
|
||||
void report_item(const struct unit *owner, const struct item *i,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <platform.h>
|
||||
#include "reports.h"
|
||||
|
||||
#include "kernel/calendar.h"
|
||||
#include "guard.h"
|
||||
#include "keyword.h"
|
||||
#include "lighthouse.h"
|
||||
#include "laws.h"
|
||||
|
@ -10,28 +10,29 @@
|
|||
#include "spy.h"
|
||||
#include "travelthru.h"
|
||||
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/config.h>
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/item.h>
|
||||
#include <kernel/race.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/ship.h>
|
||||
#include <kernel/terrain.h>
|
||||
#include <kernel/unit.h>
|
||||
#include <kernel/spell.h>
|
||||
#include <kernel/spellbook.h>
|
||||
#include <kernel/terrain.h>
|
||||
#include "kernel/ally.h"
|
||||
#include "kernel/calendar.h"
|
||||
#include "kernel/config.h"
|
||||
#include "kernel/building.h"
|
||||
#include "kernel/faction.h"
|
||||
#include "kernel/item.h"
|
||||
#include "kernel/race.h"
|
||||
#include "kernel/region.h"
|
||||
#include "kernel/ship.h"
|
||||
#include "kernel/terrain.h"
|
||||
#include "kernel/unit.h"
|
||||
#include "kernel/spell.h"
|
||||
#include "kernel/spellbook.h"
|
||||
#include "kernel/terrain.h"
|
||||
|
||||
#include <util/attrib.h>
|
||||
#include <util/language.h>
|
||||
#include <util/lists.h>
|
||||
#include <util/message.h>
|
||||
#include "util/attrib.h"
|
||||
#include "util/language.h"
|
||||
#include "util/lists.h"
|
||||
#include "util/message.h"
|
||||
|
||||
#include <attributes/attributes.h>
|
||||
#include <attributes/key.h>
|
||||
#include <attributes/otherfaction.h>
|
||||
#include "attributes/attributes.h"
|
||||
#include "attributes/key.h"
|
||||
#include "attributes/otherfaction.h"
|
||||
|
||||
#include <selist.h>
|
||||
#include <stream.h>
|
||||
|
@ -495,7 +496,7 @@ void test_prepare_lighthouse_capacity(CuTest *tc) {
|
|||
u1->number = 4;
|
||||
u1->building = b;
|
||||
set_level(u1, SK_PERCEPTION, 3);
|
||||
CuAssertIntEquals(tc, 1, lighthouse_range(b, u1->faction, u1));
|
||||
CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u1));
|
||||
CuAssertPtrEquals(tc, b, inside_building(u1));
|
||||
u2 = test_create_unit(f, r1);
|
||||
u2->building = b;
|
||||
|
@ -530,7 +531,7 @@ void test_prepare_lighthouse_capacity(CuTest *tc) {
|
|||
static void test_prepare_lighthouse(CuTest *tc) {
|
||||
report_context ctx;
|
||||
faction *f;
|
||||
region *r1, *r2, *r3;
|
||||
region *r1, *r2, *r3, *r4;
|
||||
unit *u;
|
||||
building *b;
|
||||
building_type *btype;
|
||||
|
@ -543,6 +544,7 @@ static void test_prepare_lighthouse(CuTest *tc) {
|
|||
r1 = test_create_region(0, 0, t_plain);
|
||||
r2 = test_create_region(1, 0, t_ocean);
|
||||
r3 = test_create_region(2, 0, t_ocean);
|
||||
r4 = test_create_region(0, 1, t_plain);
|
||||
btype = test_create_buildingtype("lighthouse");
|
||||
b = test_create_building(r1, btype);
|
||||
b->flags |= BLD_MAINTAINED;
|
||||
|
@ -557,6 +559,7 @@ static void test_prepare_lighthouse(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
|
||||
CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode);
|
||||
CuAssertIntEquals(tc, seen_neighbour, r3->seen.mode);
|
||||
CuAssertIntEquals(tc, seen_neighbour, r4->seen.mode);
|
||||
finish_reports(&ctx);
|
||||
test_teardown();
|
||||
}
|
||||
|
@ -595,7 +598,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc)
|
|||
u = test_create_unit(test_create_faction(NULL), r1);
|
||||
u->building = b;
|
||||
region_set_owner(b->region, f, 0);
|
||||
CuAssertIntEquals(tc, 2, lighthouse_range(b, NULL, NULL));
|
||||
CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, NULL));
|
||||
prepare_report(&ctx, f);
|
||||
CuAssertPtrEquals(tc, r1, ctx.first);
|
||||
CuAssertPtrEquals(tc, NULL, ctx.last);
|
||||
|
@ -786,19 +789,29 @@ static void test_insect_warnings(CuTest *tc) {
|
|||
faction *f;
|
||||
gamedate gd;
|
||||
|
||||
/* OBS: in unit tests, get_gamedate always returns season = 0 */
|
||||
test_setup();
|
||||
test_create_calendar();
|
||||
test_inject_messagetypes();
|
||||
f = test_create_faction(test_create_race("insect"));
|
||||
|
||||
gd.turn = 0;
|
||||
gd.season = 3;
|
||||
report_warnings(f, &gd);
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectfall"));
|
||||
|
||||
gd.season = 0;
|
||||
report_warnings(f, &gd);
|
||||
CuAssertIntEquals(tc, SEASON_AUTUMN, get_gamedate(1083, &gd)->season);
|
||||
report_warnings(f, gd.turn);
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "nr_insectfall"));
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectwinter"));
|
||||
test_clear_messages(f);
|
||||
|
||||
CuAssertIntEquals(tc, SEASON_AUTUMN, get_gamedate(1082, &gd)->season);
|
||||
report_warnings(f, gd.turn);
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectfall"));
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "nr_insectwinter"));
|
||||
test_clear_messages(f);
|
||||
|
||||
CuAssertIntEquals(tc, SEASON_WINTER, get_gamedate(1084, &gd)->season);
|
||||
report_warnings(f, gd.turn);
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "nr_insectfall"));
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "nr_insectwinter"));
|
||||
test_clear_messages(f);
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
|
@ -807,16 +820,16 @@ static void test_newbie_warning(CuTest *tc) {
|
|||
|
||||
test_setup();
|
||||
test_inject_messagetypes();
|
||||
f = test_create_faction(test_create_race("insect"));
|
||||
f = test_create_faction(NULL);
|
||||
config_set_int("NewbieImmunity", 3);
|
||||
|
||||
f->age = 2;
|
||||
report_warnings(f, NULL);
|
||||
report_warnings(f, 0);
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "newbieimmunity"));
|
||||
test_clear_messages(f);
|
||||
|
||||
f->age = 3;
|
||||
report_warnings(f, NULL);
|
||||
report_warnings(f, 0);
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "newbieimmunity"));
|
||||
test_clear_messages(f);
|
||||
|
||||
|
@ -824,38 +837,61 @@ static void test_newbie_warning(CuTest *tc) {
|
|||
}
|
||||
|
||||
static void test_visible_unit(CuTest *tc) {
|
||||
unit *u2;
|
||||
unit *u;
|
||||
faction *f;
|
||||
ship *sh;
|
||||
building *b;
|
||||
race *rc;
|
||||
|
||||
test_setup();
|
||||
f = test_create_faction(NULL);
|
||||
u2 = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
||||
sh = test_create_ship(u2->region, NULL);
|
||||
rc = test_create_race("smurf");
|
||||
rc->flags |= RCF_UNARMEDGUARD;
|
||||
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
|
||||
|
||||
CuAssertTrue(tc, cansee(f, u2->region, u2, 0));
|
||||
CuAssertTrue(tc, visible_unit(u2, f, 0, seen_unit));
|
||||
CuAssertTrue(tc, visible_unit(u2, f, 0, seen_spell));
|
||||
CuAssertTrue(tc, visible_unit(u2, f, 0, seen_battle));
|
||||
CuAssertTrue(tc, !visible_unit(u2, f, 0, seen_travel));
|
||||
CuAssertTrue(tc, !visible_unit(u2, f, 0, seen_none));
|
||||
CuAssertTrue(tc, !visible_unit(u2, f, 0, seen_neighbour));
|
||||
CuAssertTrue(tc, cansee(f, u->region, u, 0));
|
||||
CuAssertTrue(tc, visible_unit(u, f, 0, seen_unit));
|
||||
CuAssertTrue(tc, visible_unit(u, f, 0, seen_spell));
|
||||
CuAssertTrue(tc, visible_unit(u, f, 0, seen_battle));
|
||||
CuAssertTrue(tc, !visible_unit(u, f, 0, seen_travel));
|
||||
CuAssertTrue(tc, !visible_unit(u, f, 0, seen_none));
|
||||
CuAssertTrue(tc, !visible_unit(u, f, 0, seen_neighbour));
|
||||
|
||||
CuAssertTrue(tc, visible_unit(u2, f, 0, seen_lighthouse));
|
||||
CuAssertTrue(tc, !visible_unit(u2, f, -2, seen_lighthouse));
|
||||
u2->ship = sh;
|
||||
CuAssertTrue(tc, visible_unit(u2, f, -2, seen_lighthouse));
|
||||
u2->ship = NULL;
|
||||
CuAssertTrue(tc, visible_unit(u, f, 0, seen_lighthouse));
|
||||
CuAssertTrue(tc, !visible_unit(u, f, -2, seen_lighthouse));
|
||||
|
||||
set_level(u2, SK_STEALTH, 1);
|
||||
CuAssertTrue(tc, !cansee(f, u2->region, u2, 0));
|
||||
CuAssertTrue(tc, cansee(f, u2->region, u2, 1));
|
||||
u->ship = sh = test_create_ship(u->region, NULL);
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel));
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse));
|
||||
u->ship = NULL;
|
||||
|
||||
u2->ship = sh;
|
||||
CuAssertTrue(tc, visible_unit(u2, f, -2, seen_lighthouse));
|
||||
u2->ship = NULL;
|
||||
CuAssertTrue(tc, visible_unit(u2, f, 1, seen_spell));
|
||||
CuAssertTrue(tc, visible_unit(u2, f, 1, seen_battle));
|
||||
setguard(u, true);
|
||||
CuAssertTrue(tc, is_guard(u));
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel));
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse));
|
||||
setguard(u, false);
|
||||
|
||||
u->building = b = test_create_building(u->region, NULL);
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel));
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse));
|
||||
u->building = NULL;
|
||||
|
||||
set_level(u, SK_STEALTH, 1);
|
||||
CuAssertTrue(tc, !cansee(f, u->region, u, 0));
|
||||
CuAssertTrue(tc, cansee(f, u->region, u, 1));
|
||||
|
||||
u->ship = sh;
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse));
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel));
|
||||
u->ship = NULL;
|
||||
|
||||
u->building = b;
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_lighthouse));
|
||||
CuAssertTrue(tc, visible_unit(u, f, -2, seen_travel));
|
||||
u->building = NULL;
|
||||
|
||||
CuAssertTrue(tc, visible_unit(u, f, 1, seen_spell));
|
||||
CuAssertTrue(tc, visible_unit(u, f, 1, seen_battle));
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
|
40
src/spells.c
40
src/spells.c
|
@ -4072,7 +4072,7 @@ static int sp_pump(castorder * co)
|
|||
* Betoert eine Einheit, so das sie ihm den groe<EFBFBD>ten Teil ihres Bargelds
|
||||
* und 50% ihres Besitzes schenkt. Sie behaelt jedoch immer soviel, wie
|
||||
* sie zum ueberleben braucht. Wirkt gegen Magieresistenz.
|
||||
* MIN(Stufe*1000$, u->money - maintenace)
|
||||
* MIN(Stufe*1000$, u->money - maintenance)
|
||||
* Von jedem Item wird 50% abgerundet ermittelt und uebergeben. Dazu
|
||||
* kommt Itemzahl%2 mit 50% chance
|
||||
*
|
||||
|
@ -4083,15 +4083,16 @@ static int sp_seduce(castorder * co)
|
|||
{
|
||||
const resource_type *rsilver = get_resourcetype(R_SILVER);
|
||||
unit *target;
|
||||
item **itmp, *items = 0;
|
||||
unit *mage = co->magician.u;
|
||||
item **itmp, *items = NULL;
|
||||
unit *u, *mage = co->magician.u;
|
||||
spellparameter *pa = co->par;
|
||||
int cast_level = co->level;
|
||||
double force = co->force;
|
||||
|
||||
/* wenn kein Ziel gefunden, Zauber abbrechen */
|
||||
if (pa->param[0]->flag == TARGET_NOTFOUND)
|
||||
if (pa->param[0]->flag == TARGET_NOTFOUND) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
target = pa->param[0]->data.u; /* Zieleinheit */
|
||||
|
||||
|
@ -4101,6 +4102,15 @@ static int sp_seduce(castorder * co)
|
|||
return 0;
|
||||
}
|
||||
|
||||
u = mage;
|
||||
if (mage->region != target->region) {
|
||||
for (u = target->region->units; u; u = u->next) {
|
||||
if (u->faction == mage->faction) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Erfolgsmeldung */
|
||||
|
||||
itmp = &target->items;
|
||||
|
@ -4113,28 +4123,30 @@ static int sp_seduce(castorder * co)
|
|||
if (loot < 0) loot = 0;
|
||||
}
|
||||
else {
|
||||
loot = itm->number / 2;
|
||||
if (itm->number % 2) {
|
||||
loot += rng_int() % 2;
|
||||
}
|
||||
loot = (itm->number + 1) / 2;
|
||||
if (loot > 0) {
|
||||
int floot = (int)(5 * force);
|
||||
if (loot > floot) loot = floot;
|
||||
}
|
||||
}
|
||||
if (loot > 0) {
|
||||
i_change(&mage->items, itm->type, loot);
|
||||
i_change(&items, itm->type, loot);
|
||||
if (u) {
|
||||
i_change(&u->items, itm->type, loot);
|
||||
i_change(&items, itm->type, loot);
|
||||
}
|
||||
i_change(itmp, itm->type, -loot);
|
||||
}
|
||||
if (*itmp == itm)
|
||||
if (*itmp == itm) {
|
||||
itmp = &itm->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (items) {
|
||||
ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items",
|
||||
mage, target, items));
|
||||
i_freeall(&items);
|
||||
if (u) {
|
||||
ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items",
|
||||
u, target, items));
|
||||
i_freeall(&items);
|
||||
}
|
||||
ADDMSG(&target->faction->msgs, msg_message("seduce_effect_1", "unit",
|
||||
target));
|
||||
}
|
||||
|
|
96
src/spy.c
96
src/spy.c
|
@ -392,19 +392,16 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff)
|
|||
return 1; /* success */
|
||||
}
|
||||
|
||||
static void sink_ship(region * r, ship * sh, unit * saboteur)
|
||||
void sink_ship(ship * sh)
|
||||
{
|
||||
unit **ui, *u;
|
||||
region *safety = r;
|
||||
int i;
|
||||
direction_t d;
|
||||
double probability = 0.0;
|
||||
unit *u;
|
||||
region *r;
|
||||
message *sink_msg = NULL;
|
||||
faction *f;
|
||||
|
||||
assert(r);
|
||||
assert(sh);
|
||||
assert(saboteur);
|
||||
assert(sh && sh->region);
|
||||
r = sh->region;
|
||||
|
||||
for (f = NULL, u = r->units; u; u = u->next) {
|
||||
/* slight optimization to avoid dereferencing u->faction each time */
|
||||
if (f != u->faction) {
|
||||
|
@ -413,76 +410,27 @@ static void sink_ship(region * r, ship * sh, unit * saboteur)
|
|||
}
|
||||
}
|
||||
|
||||
/* figure out what a unit's chances of survival are: */
|
||||
if (!(r->terrain->flags & SEA_REGION)) {
|
||||
probability = CANAL_SWIMMER_CHANCE;
|
||||
}
|
||||
else {
|
||||
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||
region *rn = rconnect(r, d);
|
||||
if (rn && !(rn->terrain->flags & SEA_REGION) && !move_blocked(NULL, r, rn)) {
|
||||
safety = rn;
|
||||
probability = OCEAN_SWIMMER_CHANCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ui = &r->units; *ui;) {
|
||||
for (f = NULL, u = r->units; u; u = u->next) {
|
||||
/* inform this faction about the sinking ship: */
|
||||
u = *ui;
|
||||
if (!(u->faction->flags & FFL_SELECT)) {
|
||||
fset(u->faction, FFL_SELECT);
|
||||
if (sink_msg == NULL) {
|
||||
sink_msg = msg_message("sink_msg", "ship region", sh, r);
|
||||
}
|
||||
add_message(&f->msgs, sink_msg);
|
||||
}
|
||||
|
||||
if (u->ship == sh) {
|
||||
int dead = 0;
|
||||
message *msg;
|
||||
|
||||
/* if this fails, I misunderstood something: */
|
||||
for (i = 0; i != u->number; ++i)
|
||||
if (chance(probability))
|
||||
++dead;
|
||||
|
||||
if (dead != u->number) {
|
||||
/* she will live. but her items get stripped */
|
||||
if (dead > 0) {
|
||||
msg =
|
||||
msg_message("sink_lost_msg", "dead region unit", dead, safety, u);
|
||||
}
|
||||
else {
|
||||
msg = msg_message("sink_saved_msg", "region unit", safety, u);
|
||||
}
|
||||
leave_ship(u);
|
||||
if (r != safety) {
|
||||
setguard(u, false);
|
||||
}
|
||||
while (u->items) {
|
||||
i_remove(&u->items, u->items);
|
||||
}
|
||||
move_unit(u, safety, NULL);
|
||||
}
|
||||
else {
|
||||
msg = msg_message("sink_lost_msg", "dead region unit", dead, (region *)NULL, u);
|
||||
}
|
||||
add_message(&u->faction->msgs, msg);
|
||||
msg_release(msg);
|
||||
if (dead == u->number) {
|
||||
if (remove_unit(ui, u) == 0) {
|
||||
/* ui is already pointing at u->next */
|
||||
continue;
|
||||
if (f != u->faction) {
|
||||
f = u->faction;
|
||||
if (!(f->flags & FFL_SELECT)) {
|
||||
f->flags |= FFL_SELECT;
|
||||
if (sink_msg == NULL) {
|
||||
sink_msg = msg_message("sink_msg", "ship region", sh, r);
|
||||
}
|
||||
add_message(&f->msgs, sink_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
ui = &u->next;
|
||||
else if (f != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sink_msg)
|
||||
if (sink_msg) {
|
||||
msg_release(sink_msg);
|
||||
/* finally, get rid of the ship */
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
}
|
||||
|
||||
int sabotage_cmd(unit * u, struct order *ord)
|
||||
|
@ -514,7 +462,9 @@ int sabotage_cmd(unit * u, struct order *ord)
|
|||
effskill(u, SK_SPY, 0) - top_skill(u->region, u2->faction, sh, SK_PERCEPTION);
|
||||
}
|
||||
if (try_destruction(u, u2, sh, skdiff)) {
|
||||
sink_ship(u->region, sh, u);
|
||||
sink_ship(sh);
|
||||
/* finally, get rid of the ship */
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -27,6 +27,7 @@ extern "C" {
|
|||
struct strlist;
|
||||
struct order;
|
||||
struct faction;
|
||||
struct ship;
|
||||
|
||||
int setstealth_cmd(struct unit *u, struct order *ord);
|
||||
int spy_cmd(struct unit *u, struct order *ord);
|
||||
|
@ -34,10 +35,7 @@ extern "C" {
|
|||
void spy_message(int spy, const struct unit *u,
|
||||
const struct unit *target);
|
||||
void set_factionstealth(struct unit * u, struct faction * f);
|
||||
|
||||
|
||||
#define OCEAN_SWIMMER_CHANCE 0.1
|
||||
#define CANAL_SWIMMER_CHANCE 0.9
|
||||
void sink_ship(struct ship * sh);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -55,10 +55,6 @@ static void setup_spy(spy_fixture *fix) {
|
|||
"ship:ship", MT_NEW_END);
|
||||
mt_create_va(mt_new("sink_msg", NULL),
|
||||
"ship:ship", "region:region", MT_NEW_END);
|
||||
mt_create_va(mt_new("sink_lost_msg", NULL),
|
||||
"unit:unit", "region:region", "dead:int", MT_NEW_END);
|
||||
mt_create_va(mt_new("sink_saved_msg", NULL),
|
||||
"unit:unit", "region:region", MT_NEW_END);
|
||||
|
||||
if (fix) {
|
||||
fix->r = test_create_region(0, 0, NULL);
|
||||
|
@ -112,6 +108,7 @@ static void test_sabotage_self(CuTest *tc) {
|
|||
unit *u;
|
||||
region *r;
|
||||
order *ord;
|
||||
message *msg;
|
||||
|
||||
test_setup();
|
||||
setup_spy(NULL);
|
||||
|
@ -119,17 +116,49 @@ static void test_sabotage_self(CuTest *tc) {
|
|||
assert(r);
|
||||
u = test_create_unit(test_create_faction(NULL), r);
|
||||
assert(u && u->faction && u->region == r);
|
||||
u->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||
u->ship = test_create_ship(r, NULL);
|
||||
assert(u->ship);
|
||||
ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
|
||||
assert(ord);
|
||||
CuAssertIntEquals(tc, 0, sabotage_cmd(u, ord));
|
||||
CuAssertPtrEquals(tc, 0, r->ships);
|
||||
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "sink_msg"));
|
||||
CuAssertPtrEquals(tc, NULL, r->ships);
|
||||
CuAssertPtrNotNull(tc, msg = test_find_messagetype(u->faction->msgs, "sink_msg"));
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u->faction->msgs, "sink_msg", msg));
|
||||
free_order(ord);
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_sink_ship(CuTest *tc) {
|
||||
ship *sh;
|
||||
unit *u1, *u2, *u3;
|
||||
region *r;
|
||||
message *msg;
|
||||
|
||||
test_setup();
|
||||
setup_spy(NULL);
|
||||
r = test_create_ocean(0, 0);
|
||||
u1 = test_create_unit(test_create_faction(NULL), r);
|
||||
u2 = test_create_unit(u1->faction, r);
|
||||
u3 = test_create_unit(test_create_faction(NULL), r);
|
||||
u1->ship = u2->ship = u3->ship = sh = test_create_ship(r, NULL);
|
||||
|
||||
sink_ship(sh);
|
||||
CuAssertPtrEquals(tc, r, sh->region);
|
||||
CuAssertPtrEquals(tc, sh, r->ships);
|
||||
CuAssertPtrNotNull(tc, msg = test_find_messagetype(u1->faction->msgs, "sink_msg"));
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u1->faction->msgs, "sink_msg", msg));
|
||||
CuAssertPtrNotNull(tc, msg = test_find_messagetype(u3->faction->msgs, "sink_msg"));
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u3->faction->msgs, "sink_msg", msg));
|
||||
|
||||
remove_ship(&r->ships, sh);
|
||||
CuAssertPtrEquals(tc, NULL, sh->region);
|
||||
CuAssertPtrEquals(tc, NULL, r->ships);
|
||||
CuAssertPtrEquals(tc, NULL, u1->ship);
|
||||
CuAssertPtrEquals(tc, NULL, u2->ship);
|
||||
CuAssertPtrEquals(tc, NULL, u3->ship);
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_sabotage_other_fail(CuTest *tc) {
|
||||
unit *u, *u2;
|
||||
|
@ -145,7 +174,7 @@ static void test_sabotage_other_fail(CuTest *tc) {
|
|||
u = test_create_unit(test_create_faction(NULL), r);
|
||||
u2 = test_create_unit(test_create_faction(NULL), r);
|
||||
assert(u && u2);
|
||||
u2->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||
u2->ship = test_create_ship(r, NULL);
|
||||
assert(u2->ship);
|
||||
u->ship = u2->ship;
|
||||
ship_update_owner(u->ship);
|
||||
|
@ -167,7 +196,7 @@ static void test_setstealth_cmd(CuTest *tc) {
|
|||
const struct locale *lang;
|
||||
|
||||
test_setup();
|
||||
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
||||
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
|
||||
lang = u->faction->locale;
|
||||
u->flags = UFL_ANON_FACTION | UFL_SIEGE;
|
||||
u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s",
|
||||
|
@ -191,7 +220,7 @@ static void test_setstealth_demon(CuTest *tc) {
|
|||
test_setup();
|
||||
lang = test_create_locale();
|
||||
rc = test_create_race("demon");
|
||||
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
|
||||
u = test_create_unit(test_create_faction(rc), test_create_plain(0, 0));
|
||||
rc = test_create_race("dwarf");
|
||||
init_races(lang);
|
||||
u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc));
|
||||
|
@ -208,7 +237,7 @@ static void test_setstealth_demon_bad(CuTest *tc) {
|
|||
test_setup();
|
||||
lang = test_create_locale();
|
||||
rc = test_create_race("demon");
|
||||
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
|
||||
u = test_create_unit(test_create_faction(rc), test_create_plain(0, 0));
|
||||
|
||||
rc = test_create_race("smurf");
|
||||
rc->flags &= ~RCF_PLAYABLE;
|
||||
|
@ -232,7 +261,7 @@ static void test_sabotage_other_success(CuTest *tc) {
|
|||
u = test_create_unit(test_create_faction(NULL), r);
|
||||
u2 = test_create_unit(test_create_faction(NULL), r);
|
||||
assert(u && u2);
|
||||
u2->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||
u2->ship = test_create_ship(r, NULL);
|
||||
assert(u2->ship);
|
||||
u->ship = u2->ship;
|
||||
ship_update_owner(u->ship);
|
||||
|
@ -251,6 +280,7 @@ CuSuite *get_spy_suite(void)
|
|||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_simple_spy_message);
|
||||
SUITE_ADD_TEST(suite, test_all_spy_message);
|
||||
SUITE_ADD_TEST(suite, test_sink_ship);
|
||||
SUITE_ADD_TEST(suite, test_sabotage_self);
|
||||
SUITE_ADD_TEST(suite, test_setstealth_cmd);
|
||||
SUITE_ADD_TEST(suite, test_setstealth_demon);
|
||||
|
|
15
src/tests.c
15
src/tests.c
|
@ -260,6 +260,21 @@ static void test_reset(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void test_create_calendar(void) {
|
||||
config_set_int("game.start", 184);
|
||||
months_per_year = 9;
|
||||
month_season = malloc(sizeof(int) * months_per_year);
|
||||
month_season[0] = SEASON_SUMMER;
|
||||
month_season[1] = SEASON_AUTUMN;
|
||||
month_season[2] = SEASON_AUTUMN;
|
||||
month_season[3] = SEASON_WINTER;
|
||||
month_season[4] = SEASON_WINTER;
|
||||
month_season[5] = SEASON_WINTER;
|
||||
month_season[6] = SEASON_SPRING;
|
||||
month_season[7] = SEASON_SPRING;
|
||||
month_season[8] = SEASON_SUMMER;
|
||||
}
|
||||
|
||||
void test_inject_messagetypes(void)
|
||||
{
|
||||
message_handle_missing(MESSAGE_MISSING_REPLACE);
|
||||
|
|
|
@ -40,6 +40,7 @@ extern "C" {
|
|||
struct log_t * test_log_start(int flags, struct strlist **slist);
|
||||
void test_log_stop(struct log_t *log, struct strlist *slist);
|
||||
|
||||
void test_create_calendar(void);
|
||||
struct locale * test_create_locale(void);
|
||||
struct terrain_type * test_create_terrain(const char * name, int flags);
|
||||
struct race *test_create_race(const char *name);
|
||||
|
|
|
@ -54,11 +54,11 @@ assert_grep_count reports/$CRFILE '^EINHEIT' 2
|
|||
assert_grep_count reports/$CRFILE '^GEGENSTAENDE' 2
|
||||
|
||||
assert_grep_count reports/185-heg.cr '185;Runde' 1
|
||||
assert_grep_count reports/185-heg.cr ';Baeume' 4
|
||||
assert_grep_count reports/185-heg.cr '"B.ume";type' 4
|
||||
assert_grep_count reports/185-heg.cr '"Pferde";type' 6
|
||||
assert_grep_count reports/185-heg.nr 'erblickt' 6
|
||||
assert_grep_count reports/185-heg.cr '"lighthouse";visibility' 6
|
||||
assert_grep_count reports/185-heg.cr ';Baeume' 2
|
||||
assert_grep_count reports/185-heg.cr '"B.ume";type' 2
|
||||
assert_grep_count reports/185-heg.cr '"Pferde";type' 2
|
||||
assert_grep_count reports/185-heg.nr 'erblickt' 2
|
||||
assert_grep_count reports/185-heg.cr '"lighthouse";visibility' 2
|
||||
assert_grep_count reports/185-heg.cr '"neighbour";visibility' 11
|
||||
assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2
|
||||
assert_grep_count reports/185-6rLo.cr '^REGION' 13
|
||||
|
|
|
@ -19,7 +19,7 @@ done
|
|||
#set -e
|
||||
cd $ROOT/tests
|
||||
setup
|
||||
#cleanup
|
||||
cleanup
|
||||
VALGRIND=`which valgrind`
|
||||
TESTS=../Debug/eressea/test_eressea
|
||||
SERVER=../Debug/eressea/eressea
|
||||
|
|
Loading…
Reference in New Issue