forked from github/server
Merge pull request #725 from ennorehling/develop
Bugfixes for 3.14 release
This commit is contained in:
commit
5f518ae4f0
|
@ -27,7 +27,7 @@
|
||||||
"rules.reserve.twophase": true,
|
"rules.reserve.twophase": true,
|
||||||
"rules.give.max_men": -1,
|
"rules.give.max_men": -1,
|
||||||
"rules.check_overload": false,
|
"rules.check_overload": false,
|
||||||
"rules.limit.faction": 3000,
|
"rules.limit.faction": 2500,
|
||||||
"rules.maxskills.magic": 5,
|
"rules.maxskills.magic": 5,
|
||||||
"rules.guard.base_stop_prob": 0.30,
|
"rules.guard.base_stop_prob": 0.30,
|
||||||
"rules.guard.skill_stop_prob": 0.05,
|
"rules.guard.skill_stop_prob": 0.05,
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
"rules.economy.herbrot": 0,
|
"rules.economy.herbrot": 0,
|
||||||
"rules.region_owner_pay_building": "market harbour lighthouse",
|
"rules.region_owner_pay_building": "market harbour lighthouse",
|
||||||
"rules.dwarf_castles": true,
|
"rules.dwarf_castles": true,
|
||||||
"rules.limit.faction": 500,
|
"rules.limit.faction": 250,
|
||||||
"rules.grow.formula": 1,
|
"rules.grow.formula": 1,
|
||||||
"rules.tactics.formula": 1,
|
"rules.tactics.formula": 1,
|
||||||
"rules.help.mask": "fight guard money give",
|
"rules.help.mask": "fight guard money give",
|
||||||
|
|
|
@ -4990,12 +4990,12 @@
|
||||||
<string name="sacrifice_strength">
|
<string name="sacrifice_strength">
|
||||||
<text locale="de">Mit Hilfe dieses Zaubers kann der Magier einen Teil
|
<text locale="de">Mit Hilfe dieses Zaubers kann der Magier einen Teil
|
||||||
seiner magischen Kraft permanent auf einen anderen Magier übertragen.
|
seiner magischen Kraft permanent auf einen anderen Magier übertragen.
|
||||||
Auf einen Tybied-Magier kann er die Hälfte der eingesetzten Kraft
|
Auf einen Magier des selben Magiegebietes kann er die Hälfte der
|
||||||
übertragen, auf einen Magier eines anderen Gebietes ein Drittel.</text>
|
eingesetzten Kraft übertragen, auf andere Magier ein Drittel.</text>
|
||||||
<text locale="en">This spell allows the magician to transfer part of
|
<text locale="en">This spell allows the magician to transfer part of
|
||||||
his magical powers to another magician. Tybied magicians will receive
|
his magical powers to another magician. Magicians of the seam school
|
||||||
half the power invested, magicians of another school will receive one
|
will receive half the power invested, magicians of other schoolsreceive
|
||||||
third.</text>
|
receive one third.</text>
|
||||||
</string>
|
</string>
|
||||||
<string name="eternal_walls">
|
<string name="eternal_walls">
|
||||||
<text locale="de">Mit dieser Formel bindet der Magier auf ewig die
|
<text locale="de">Mit dieser Formel bindet der Magier auf ewig die
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
if not config.autoseed then return nil end
|
if not config.autoseed or config.autoseed==0 then return nil end
|
||||||
local autoseed = {}
|
local autoseed = {}
|
||||||
|
|
||||||
-- minimum required resources in the 7-hex neighborhood:
|
-- minimum required resources in the 7-hex neighborhood:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- Muschelplateau
|
-- Muschelplateau
|
||||||
|
|
||||||
if not config.embassy then return nil end
|
if not config.embassy or config.embassy==0 then return nil end
|
||||||
|
|
||||||
local embassy = {}
|
local embassy = {}
|
||||||
local home = nil
|
local home = nil
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- DEPRECATED
|
-- DEPRECATED
|
||||||
if not config.eternath then return nil end
|
if not config.eternath or config.eternath==0 then return nil end
|
||||||
-- implements parts of a quest in E2
|
-- implements parts of a quest in E2
|
||||||
-- this module is deprecated, because it puts functions in the global environment for at_building_action
|
-- this module is deprecated, because it puts functions in the global environment for at_building_action
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
local modules = {}
|
||||||
|
|
||||||
|
function add_module(pkg)
|
||||||
|
table.insert(modules, pkg)
|
||||||
|
end
|
||||||
|
|
||||||
|
local pkg = {}
|
||||||
|
|
||||||
|
function pkg.init()
|
||||||
|
for k, v in ipairs(modules) do
|
||||||
|
if v.init then v.init() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function pkg.update()
|
||||||
|
for k, v in ipairs(modules) do
|
||||||
|
if v.update then v.update() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return pkg
|
|
@ -1,4 +1,4 @@
|
||||||
if not config.ponnuki then return nil end
|
if not config.ponnuki or config.ponnuki==0 then return nil end
|
||||||
local ponnuki = {}
|
local ponnuki = {}
|
||||||
|
|
||||||
local directions = { "NW", "NO", "O", "SO", "SW", "W" }
|
local directions = { "NW", "NO", "O", "SO", "SW", "W" }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- DEPRECATED
|
-- DEPRECATED
|
||||||
if not config.wedding then return nil end
|
if not config.wedding or config.wedding==0 then return nil end
|
||||||
|
|
||||||
-- this script contains the action functions for the two portals
|
-- this script contains the action functions for the two portals
|
||||||
-- used on the jadee/wildente wedding island. the two _action functions
|
-- used on the jadee/wildente wedding island. the two _action functions
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
if not config.xmas then return nil end
|
if not config.xmas or config.xmas==0 then return nil end
|
||||||
|
|
||||||
local gifts = {
|
local gifts = {
|
||||||
e2 = {
|
e2 = {
|
||||||
|
|
|
@ -11,6 +11,23 @@ function setup()
|
||||||
eressea.settings.set("rules.encounters", "0")
|
eressea.settings.set("rules.encounters", "0")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function test_bug_2361_forget_magic()
|
||||||
|
-- https://bugs.eressea.de/view.php?id=2361
|
||||||
|
-- familiars cannot forget magic
|
||||||
|
local r = region.create(0, 0, "plain")
|
||||||
|
local f = faction.create("human")
|
||||||
|
local u = unit.create(f, r, 1)
|
||||||
|
u:clear_orders()
|
||||||
|
u:add_order("VERGESSE Magie")
|
||||||
|
u:set_skill('magic', 5)
|
||||||
|
u.race = 'unicorn'
|
||||||
|
process_orders()
|
||||||
|
assert_equal(5, u:get_skill('magic'))
|
||||||
|
u.race = 'human'
|
||||||
|
process_orders()
|
||||||
|
assert_equal(0, u:get_skill('magic'))
|
||||||
|
end
|
||||||
|
|
||||||
function test_mine_bonus()
|
function test_mine_bonus()
|
||||||
local r = region.create(0, 0, "mountain")
|
local r = region.create(0, 0, "mountain")
|
||||||
r:set_resource("iron", 100)
|
r:set_resource("iron", 100)
|
||||||
|
|
|
@ -254,7 +254,7 @@ cr_output_curses(struct stream *out, const faction * viewer, const void *obj, ob
|
||||||
}
|
}
|
||||||
|
|
||||||
while (a) {
|
while (a) {
|
||||||
if (fval(a->type, ATF_CURSE)) {
|
if (a->type == &at_curse) {
|
||||||
curse *c = (curse *)a->data.v;
|
curse *c = (curse *)a->data.v;
|
||||||
message *msg;
|
message *msg;
|
||||||
|
|
||||||
|
|
|
@ -661,7 +661,12 @@ static int forget_cmd(unit * u, order * ord)
|
||||||
init_order(ord);
|
init_order(ord);
|
||||||
s = gettoken(token, sizeof(token));
|
s = gettoken(token, sizeof(token));
|
||||||
|
|
||||||
if ((sk = get_skill(s, u->faction->locale)) != NOSKILL) {
|
sk = get_skill(s, u->faction->locale);
|
||||||
|
if (sk != NOSKILL) {
|
||||||
|
if (sk == SK_MAGIC && (u_race(u)->flags & RCF_FAMILIAR)) {
|
||||||
|
/* some races cannot forget their innate magical abilities */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
ADDMSG(&u->faction->msgs, msg_message("forget", "unit skill", u, sk));
|
ADDMSG(&u->faction->msgs, msg_message("forget", "unit skill", u, sk));
|
||||||
set_level(u, sk, 0);
|
set_level(u, sk, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,17 @@
|
||||||
#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>
|
||||||
|
|
||||||
|
@ -25,16 +36,6 @@
|
||||||
#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 "wormhole.h"
|
|
||||||
|
|
||||||
void game_done(void)
|
void game_done(void)
|
||||||
{
|
{
|
||||||
#ifdef CLEANUP_CODE
|
#ifdef CLEANUP_CODE
|
||||||
|
@ -53,6 +54,7 @@ void game_done(void)
|
||||||
calendar_cleanup();
|
calendar_cleanup();
|
||||||
free_functions();
|
free_functions();
|
||||||
free_config();
|
free_config();
|
||||||
|
free_special_directions();
|
||||||
free_locales();
|
free_locales();
|
||||||
kernel_done();
|
kernel_done();
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ struct order *ord)
|
||||||
while (*ap && force > 0) {
|
while (*ap && force > 0) {
|
||||||
curse *c;
|
curse *c;
|
||||||
attrib *a = *ap;
|
attrib *a = *ap;
|
||||||
if (!(a->type->flags & ATF_CURSE)) {
|
if (a->type != &at_curse) {
|
||||||
do {
|
do {
|
||||||
ap = &(*ap)->next;
|
ap = &(*ap)->next;
|
||||||
} while (*ap && a->type == (*ap)->type);
|
} while (*ap && a->type == (*ap)->type);
|
||||||
|
|
|
@ -273,8 +273,7 @@ attrib_type at_curse = {
|
||||||
curse_age,
|
curse_age,
|
||||||
curse_write,
|
curse_write,
|
||||||
curse_read,
|
curse_read,
|
||||||
NULL,
|
NULL
|
||||||
ATF_CURSE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
@ -363,7 +362,7 @@ void ct_checknames(void) {
|
||||||
static bool cmp_curse(const attrib * a, const void *data)
|
static bool cmp_curse(const attrib * a, const void *data)
|
||||||
{
|
{
|
||||||
const curse *c = (const curse *)data;
|
const curse *c = (const curse *)data;
|
||||||
if (a->type->flags & ATF_CURSE) {
|
if (a->type == &at_curse) {
|
||||||
if (!data || c == (curse *)a->data.v)
|
if (!data || c == (curse *)a->data.v)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -375,7 +374,7 @@ curse *get_curse(attrib * ap, const curse_type * ctype)
|
||||||
attrib *a = ap;
|
attrib *a = ap;
|
||||||
if (!ctype) return NULL;
|
if (!ctype) return NULL;
|
||||||
while (a) {
|
while (a) {
|
||||||
if (a->type->flags & ATF_CURSE) {
|
if (a->type == &at_curse) {
|
||||||
const attrib_type *at = a->type;
|
const attrib_type *at = a->type;
|
||||||
while (a && a->type == at) {
|
while (a && a->type == at) {
|
||||||
curse *c = (curse *)a->data.v;
|
curse *c = (curse *)a->data.v;
|
||||||
|
@ -710,7 +709,7 @@ bool is_cursed_with(const attrib * ap, const curse * c)
|
||||||
const attrib *a = ap;
|
const attrib *a = ap;
|
||||||
|
|
||||||
while (a) {
|
while (a) {
|
||||||
if ((a->type->flags & ATF_CURSE) && (c == (const curse *)a->data.v)) {
|
if ((a->type == &at_curse) && (c == (const curse *)a->data.v)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
a = a->next;
|
a = a->next;
|
||||||
|
|
|
@ -311,9 +311,6 @@ extern "C" {
|
||||||
#define get_curseeffect(a, ctype) \
|
#define get_curseeffect(a, ctype) \
|
||||||
curse_geteffect(get_curse(a, ctype))
|
curse_geteffect(get_curse(a, ctype))
|
||||||
|
|
||||||
/* eressea-defined attribute-type flags */
|
|
||||||
#define ATF_CURSE ATF_USER_DEFINED
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -745,11 +745,17 @@ int rtrees(const region * r, int ageclass)
|
||||||
|
|
||||||
int rsettrees(const region * r, int ageclass, int value)
|
int rsettrees(const region * r, int ageclass, int value)
|
||||||
{
|
{
|
||||||
if (!r->land)
|
if (!r->land) {
|
||||||
assert(value == 0);
|
assert(value == 0);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
assert(value >= 0);
|
assert(value >= 0);
|
||||||
return r->land->trees[ageclass] = value;
|
if (value <= MAXTREES) {
|
||||||
|
return r->land->trees[ageclass] = value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r->land->trees[ageclass] = MAXTREES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
#define MAXLUXURIES 16 /* there must be no more than MAXLUXURIES kinds of luxury goods in any game */
|
#define MAXLUXURIES 16 /* there must be no more than MAXLUXURIES kinds of luxury goods in any game */
|
||||||
#define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */
|
#define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */
|
||||||
|
#define MAXTREES 100 * 1000 * 1000 /* bug 2360: some players are crazy */
|
||||||
|
|
||||||
/* FAST_CONNECT: regions are directly connected to neighbours, saves doing
|
/* FAST_CONNECT: regions are directly connected to neighbours, saves doing
|
||||||
a hash-access each time a neighbour is needed, 6 extra pointers per hex */
|
a hash-access each time a neighbour is needed, 6 extra pointers per hex */
|
||||||
|
|
|
@ -78,10 +78,29 @@ static void test_region_getset_resource(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_trees(CuTest *tc) {
|
||||||
|
region *r;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
r = test_create_region(0, 0, NULL);
|
||||||
|
rsettrees(r, 0, 1000);
|
||||||
|
rsettrees(r, 1, 2000);
|
||||||
|
rsettrees(r, 2, 3000);
|
||||||
|
CuAssertIntEquals(tc, 1000, rtrees(r, 0));
|
||||||
|
CuAssertIntEquals(tc, 2000, rtrees(r, 1));
|
||||||
|
CuAssertIntEquals(tc, 3000, rtrees(r, 2));
|
||||||
|
rsettrees(r, 0, MAXTREES);
|
||||||
|
CuAssertIntEquals(tc, MAXTREES, rtrees(r, 0));
|
||||||
|
rsettrees(r, 0, MAXTREES+100);
|
||||||
|
CuAssertIntEquals(tc, MAXTREES, rtrees(r, 0));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_region_suite(void)
|
CuSuite *get_region_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_terraform);
|
SUITE_ADD_TEST(suite, test_terraform);
|
||||||
|
SUITE_ADD_TEST(suite, test_trees);
|
||||||
SUITE_ADD_TEST(suite, test_region_getset_resource);
|
SUITE_ADD_TEST(suite, test_region_getset_resource);
|
||||||
SUITE_ADD_TEST(suite, test_region_get_owner);
|
SUITE_ADD_TEST(suite, test_region_get_owner);
|
||||||
return suite;
|
return suite;
|
||||||
|
|
|
@ -329,8 +329,9 @@ sc_mage *get_mage(const unit * u)
|
||||||
{
|
{
|
||||||
if (has_skill(u, SK_MAGIC)) {
|
if (has_skill(u, SK_MAGIC)) {
|
||||||
attrib *a = a_find(u->attribs, &at_mage);
|
attrib *a = a_find(u->attribs, &at_mage);
|
||||||
if (a)
|
if (a) {
|
||||||
return a->data.v;
|
return (sc_mage *)a->data.v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (sc_mage *)NULL;
|
return (sc_mage *)NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -568,7 +568,7 @@ nr_curses_i(struct stream *out, int indent, const faction *viewer, objtype_t typ
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
message *msg = 0;
|
message *msg = 0;
|
||||||
|
|
||||||
if (fval(a->type, ATF_CURSE)) {
|
if (a->type == &at_curse) {
|
||||||
curse *c = (curse *)a->data.v;
|
curse *c = (curse *)a->data.v;
|
||||||
|
|
||||||
self = curse_cansee(c, viewer, typ, obj, self);
|
self = curse_cansee(c, viewer, typ, obj, self);
|
||||||
|
|
52
src/spells.c
52
src/spells.c
|
@ -144,7 +144,7 @@ static void magicanalyse_region(region * r, unit * mage, double force)
|
||||||
double probability;
|
double probability;
|
||||||
int mon;
|
int mon;
|
||||||
|
|
||||||
if (!fval(a->type, ATF_CURSE))
|
if (a->type != &at_curse)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* ist der curse schwaecher als der Analysezauber, so ergibt sich
|
/* ist der curse schwaecher als der Analysezauber, so ergibt sich
|
||||||
|
@ -184,7 +184,7 @@ static void magicanalyse_unit(unit * u, unit * mage, double force)
|
||||||
curse *c;
|
curse *c;
|
||||||
double probability;
|
double probability;
|
||||||
int mon;
|
int mon;
|
||||||
if (!fval(a->type, ATF_CURSE))
|
if (a->type != &at_curse)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c = (curse *)a->data.v;
|
c = (curse *)a->data.v;
|
||||||
|
@ -225,7 +225,7 @@ static void magicanalyse_building(building * b, unit * mage, double force)
|
||||||
double probability;
|
double probability;
|
||||||
int mon;
|
int mon;
|
||||||
|
|
||||||
if (!fval(a->type, ATF_CURSE))
|
if (a->type != &at_curse)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c = (curse *)a->data.v;
|
c = (curse *)a->data.v;
|
||||||
|
@ -266,7 +266,7 @@ static void magicanalyse_ship(ship * sh, unit * mage, double force)
|
||||||
curse *c;
|
curse *c;
|
||||||
double probability;
|
double probability;
|
||||||
int mon;
|
int mon;
|
||||||
if (!fval(a->type, ATF_CURSE))
|
if (a->type != &at_curse)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c = (curse *)a->data.v;
|
c = (curse *)a->data.v;
|
||||||
|
@ -308,7 +308,7 @@ static int break_curse(attrib ** alist, int cast_level, double force, curse * c)
|
||||||
while (*ap && force > 0) {
|
while (*ap && force > 0) {
|
||||||
curse *c1;
|
curse *c1;
|
||||||
attrib *a = *ap;
|
attrib *a = *ap;
|
||||||
if (!fval(a->type, ATF_CURSE)) {
|
if (a->type != &at_curse) {
|
||||||
do {
|
do {
|
||||||
ap = &(*ap)->next;
|
ap = &(*ap)->next;
|
||||||
} while (*ap && a->type == (*ap)->type);
|
} while (*ap && a->type == (*ap)->type);
|
||||||
|
@ -2970,7 +2970,7 @@ static int sp_deathcloud(castorder * co)
|
||||||
unit *u;
|
unit *u;
|
||||||
|
|
||||||
while (a) {
|
while (a) {
|
||||||
if ((a->type->flags & ATF_CURSE)) {
|
if (a->type == &at_curse) {
|
||||||
curse *c = a->data.v;
|
curse *c = a->data.v;
|
||||||
if (c->type == &ct_deathcloud) {
|
if (c->type == &ct_deathcloud) {
|
||||||
report_failure(mage, co->order);
|
report_failure(mage, co->order);
|
||||||
|
@ -3116,46 +3116,6 @@ static int sp_summonshadowlords(castorder * co)
|
||||||
return cast_level;
|
return cast_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool chaosgate_valid(const connection * b)
|
|
||||||
{
|
|
||||||
const attrib *a = a_find(b->from->attribs, &at_direction);
|
|
||||||
if (!a)
|
|
||||||
a = a_find(b->to->attribs, &at_direction);
|
|
||||||
if (!a)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct region *chaosgate_move(const connection * b, struct unit *u,
|
|
||||||
struct region *from, struct region *to, bool routing)
|
|
||||||
{
|
|
||||||
UNUSED_ARG(from);
|
|
||||||
UNUSED_ARG(b);
|
|
||||||
if (!routing) {
|
|
||||||
int maxhp = u->hp / 4;
|
|
||||||
if (maxhp < u->number)
|
|
||||||
maxhp = u->number;
|
|
||||||
u->hp = maxhp;
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
}
|
|
||||||
|
|
||||||
border_type bt_chaosgate = {
|
|
||||||
"chaosgate", VAR_NONE,
|
|
||||||
b_transparent, /* transparent */
|
|
||||||
NULL, /* init */
|
|
||||||
NULL, /* destroy */
|
|
||||||
NULL, /* read */
|
|
||||||
NULL, /* write */
|
|
||||||
b_blocknone, /* block */
|
|
||||||
NULL, /* name */
|
|
||||||
b_rinvisible, /* rvisible */
|
|
||||||
b_finvisible, /* fvisible */
|
|
||||||
b_uinvisible, /* uvisible */
|
|
||||||
chaosgate_valid,
|
|
||||||
chaosgate_move
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Name: Chaossog
|
/* Name: Chaossog
|
||||||
* Stufe: 14
|
* Stufe: 14
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
|
||||||
#include "borders.h"
|
#include "borders.h"
|
||||||
|
#include "vortex.h"
|
||||||
|
|
||||||
#include <kernel/connection.h>
|
#include <kernel/connection.h>
|
||||||
#include <kernel/curse.h>
|
#include <kernel/curse.h>
|
||||||
|
@ -28,46 +29,15 @@ typedef struct wallcurse {
|
||||||
connection *wall;
|
connection *wall;
|
||||||
} wallcurse;
|
} wallcurse;
|
||||||
|
|
||||||
static void cw_init(attrib * a)
|
static int cw_read_depr(attrib * a, void *target, gamedata *data)
|
||||||
{
|
|
||||||
curse *c;
|
|
||||||
curse_init(a);
|
|
||||||
c = (curse *)a->data.v;
|
|
||||||
c->data.v = calloc(sizeof(wallcurse), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cw_write(const attrib * a, const void *target, storage * store)
|
|
||||||
{
|
|
||||||
connection *b = ((wallcurse *)((curse *)a->data.v)->data.v)->wall;
|
|
||||||
curse_write(a, target, store);
|
|
||||||
WRITE_INT(store, b->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct bresolve {
|
|
||||||
int id;
|
|
||||||
curse *self;
|
|
||||||
} bresolve;
|
|
||||||
|
|
||||||
static int resolve_buddy(variant data, void *addr);
|
|
||||||
|
|
||||||
static int cw_read(attrib * a, void *target, gamedata *data)
|
|
||||||
{
|
{
|
||||||
storage *store = data->store;
|
storage *store = data->store;
|
||||||
bresolve *br = calloc(sizeof(bresolve), 1);
|
|
||||||
curse *c = (curse *)a->data.v;
|
|
||||||
wallcurse *wc = (wallcurse *)c->data.v;
|
|
||||||
variant var;
|
|
||||||
|
|
||||||
|
curse_init(a);
|
||||||
curse_read(a, store, target);
|
curse_read(a, store, target);
|
||||||
br->self = c;
|
curse_done(a);
|
||||||
READ_INT(store, &br->id);
|
READ_INT(store, NULL);
|
||||||
|
return AT_READ_DEPR;
|
||||||
var.i = br->id;
|
|
||||||
ur_add(var, &wc->wall, resolve_borderid);
|
|
||||||
|
|
||||||
var.v = br;
|
|
||||||
ur_add(var, &wc->buddy, resolve_buddy);
|
|
||||||
return AT_READ_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
@ -105,61 +75,6 @@ const curse_type ct_firewall = {
|
||||||
wall_vigour /* change_vigour */
|
wall_vigour /* change_vigour */
|
||||||
};
|
};
|
||||||
|
|
||||||
static attrib_type at_cursewall = {
|
|
||||||
"cursewall",
|
|
||||||
cw_init,
|
|
||||||
curse_done,
|
|
||||||
curse_age,
|
|
||||||
cw_write,
|
|
||||||
cw_read,
|
|
||||||
NULL,
|
|
||||||
ATF_CURSE
|
|
||||||
};
|
|
||||||
|
|
||||||
static int resolve_buddy(variant data, void *addr)
|
|
||||||
{
|
|
||||||
curse *result = NULL;
|
|
||||||
bresolve *br = (bresolve *)data.v;
|
|
||||||
connection *b;
|
|
||||||
|
|
||||||
assert(br->id > 0);
|
|
||||||
b = find_border(br->id);
|
|
||||||
|
|
||||||
if (b && b->from && b->to) {
|
|
||||||
attrib *a = a_find(b->from->attribs, &at_cursewall);
|
|
||||||
while (a && a->data.v != br->self) {
|
|
||||||
curse *c = (curse *)a->data.v;
|
|
||||||
wallcurse *wc = (wallcurse *)c->data.v;
|
|
||||||
if (wc->wall->id == br->id)
|
|
||||||
break;
|
|
||||||
a = a->next;
|
|
||||||
}
|
|
||||||
if (!a || a->type != &at_cursewall) {
|
|
||||||
a = a_find(b->to->attribs, &at_cursewall);
|
|
||||||
while (a && a->type == &at_cursewall && a->data.v != br->self) {
|
|
||||||
curse *c = (curse *)a->data.v;
|
|
||||||
wallcurse *wc = (wallcurse *)c->data.v;
|
|
||||||
if (wc->wall->id == br->id)
|
|
||||||
break;
|
|
||||||
a = a->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (a && a->type == &at_cursewall) {
|
|
||||||
curse *c = (curse *)a->data.v;
|
|
||||||
free(br);
|
|
||||||
result = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* fail, object does not exist (but if you're still loading then
|
|
||||||
* you may want to try again later) */
|
|
||||||
*(curse **)addr = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*(curse **)addr = result;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wall_init(connection * b)
|
static void wall_init(connection * b)
|
||||||
{
|
{
|
||||||
wall_data *fd = (wall_data *)calloc(sizeof(wall_data), 1);
|
wall_data *fd = (wall_data *)calloc(sizeof(wall_data), 1);
|
||||||
|
@ -284,10 +199,50 @@ border_type bt_wisps = { /* only here for reading old data */
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool chaosgate_valid(const connection * b)
|
||||||
|
{
|
||||||
|
const attrib *a = a_find(b->from->attribs, &at_direction);
|
||||||
|
if (!a)
|
||||||
|
a = a_find(b->to->attribs, &at_direction);
|
||||||
|
if (!a)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct region *chaosgate_move(const connection * b, struct unit *u,
|
||||||
|
struct region *from, struct region *to, bool routing)
|
||||||
|
{
|
||||||
|
UNUSED_ARG(from);
|
||||||
|
UNUSED_ARG(b);
|
||||||
|
if (!routing) {
|
||||||
|
int maxhp = u->hp / 4;
|
||||||
|
if (maxhp < u->number)
|
||||||
|
maxhp = u->number;
|
||||||
|
u->hp = maxhp;
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
border_type bt_chaosgate = {
|
||||||
|
"chaosgate", VAR_NONE,
|
||||||
|
b_transparent, /* transparent */
|
||||||
|
NULL, /* init */
|
||||||
|
NULL, /* destroy */
|
||||||
|
NULL, /* read */
|
||||||
|
NULL, /* write */
|
||||||
|
b_blocknone, /* block */
|
||||||
|
NULL, /* name */
|
||||||
|
b_rinvisible, /* rvisible */
|
||||||
|
b_finvisible, /* fvisible */
|
||||||
|
b_uinvisible, /* uvisible */
|
||||||
|
chaosgate_valid,
|
||||||
|
chaosgate_move
|
||||||
|
};
|
||||||
|
|
||||||
void register_borders(void)
|
void register_borders(void)
|
||||||
{
|
{
|
||||||
border_convert_cb = &convert_firewall_timeouts;
|
border_convert_cb = &convert_firewall_timeouts;
|
||||||
at_register(&at_cursewall);
|
at_deprecate("cursewall", cw_read_depr);
|
||||||
|
|
||||||
register_bordertype(&bt_firewall);
|
register_bordertype(&bt_firewall);
|
||||||
register_bordertype(&bt_wisps);
|
register_bordertype(&bt_wisps);
|
||||||
|
|
|
@ -15,6 +15,7 @@ extern "C" {
|
||||||
**/
|
**/
|
||||||
extern struct border_type bt_chaosgate;
|
extern struct border_type bt_chaosgate;
|
||||||
extern struct border_type bt_firewall;
|
extern struct border_type bt_firewall;
|
||||||
|
extern const struct curse_type ct_firewall;
|
||||||
|
|
||||||
typedef struct wall_data {
|
typedef struct wall_data {
|
||||||
struct unit *mage;
|
struct unit *mage;
|
||||||
|
@ -23,7 +24,6 @@ extern "C" {
|
||||||
int countdown;
|
int countdown;
|
||||||
} wall_data;
|
} wall_data;
|
||||||
|
|
||||||
extern const struct curse_type ct_firewall;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
#include "calendar.h"
|
#include "calendar.h"
|
||||||
|
#include "vortex.h"
|
||||||
|
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include <kernel/alliance.h>
|
#include <kernel/alliance.h>
|
||||||
|
@ -209,6 +210,7 @@ static void test_reset(void) {
|
||||||
default_locale = 0;
|
default_locale = 0;
|
||||||
calendar_cleanup();
|
calendar_cleanup();
|
||||||
close_orders();
|
close_orders();
|
||||||
|
free_special_directions();
|
||||||
free_locales();
|
free_locales();
|
||||||
free_spells();
|
free_spells();
|
||||||
free_buildingtypes();
|
free_buildingtypes();
|
||||||
|
|
10
src/vortex.c
10
src/vortex.c
|
@ -26,6 +26,16 @@ typedef struct dir_lookup {
|
||||||
|
|
||||||
static dir_lookup *dir_name_lookup;
|
static dir_lookup *dir_name_lookup;
|
||||||
|
|
||||||
|
void free_special_directions(void)
|
||||||
|
{
|
||||||
|
while (dir_name_lookup) {
|
||||||
|
dir_lookup *dl = dir_name_lookup;
|
||||||
|
dir_name_lookup = dl->next;
|
||||||
|
free(dl->name);
|
||||||
|
free(dl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void register_special_direction(struct locale *lang, const char *name)
|
void register_special_direction(struct locale *lang, const char *name)
|
||||||
{
|
{
|
||||||
const char *token = locale_string(lang, name, false);
|
const char *token = locale_string(lang, name, false);
|
||||||
|
|
|
@ -26,6 +26,8 @@ extern "C" {
|
||||||
struct region *find_special_direction(const struct region *r,
|
struct region *find_special_direction(const struct region *r,
|
||||||
const char *token);
|
const char *token);
|
||||||
void register_special_direction(struct locale *lang, const char *name);
|
void register_special_direction(struct locale *lang, const char *name);
|
||||||
|
void free_special_directions(void);
|
||||||
|
|
||||||
struct spec_direction *special_direction(const struct region * from,
|
struct spec_direction *special_direction(const struct region * from,
|
||||||
const struct region * to);
|
const struct region * to);
|
||||||
struct attrib *create_special_direction(struct region *r, struct region *rt,
|
struct attrib *create_special_direction(struct region *r, struct region *rt,
|
||||||
|
|
Loading…
Reference in New Issue