diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 9a6d3fde8..944d75f44 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -1497,7 +1497,7 @@ region_getname(const region * r) { int region_get_morale(const region * r) { - return r->land?r->land->morale:0; + return r->land?r->land->morale:-1; } void region_set_morale(region * r, int morale) diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 636e68389..07417f0ae 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -2088,6 +2088,50 @@ static void log_orders(const struct message * msg) } } +int +report_action(region * r, unit * actor, message * msg, int flags) +{ + int result = 0; + unit * u; + int view = flags&(ACTION_CANSEE|ACTION_CANNOTSEE); + + /* melden, 1x pro Partei */ + if (flags&ACTION_RESET) { + freset(actor->faction, FFL_SELECT); + for (u = r->units; u; u = u->next ) freset(u->faction, FFL_SELECT); + } + if (view) { + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FFL_SELECT) ) { + boolean show = u->faction == actor->faction; + fset(u->faction, FFL_SELECT); + if (view==ACTION_CANSEE) { + /* Bei Fernzaubern sieht nur die eigene Partei den Magier */ + show = show || (r==actor->region && cansee(u->faction, r, actor, 0)); + } else if (view==ACTION_CANNOTSEE) { + show = !show && !(r==actor->region && cansee(u->faction, r, actor, 0)); + } else { + /* the unliely (or lazy) case */ + show = true; + } + + if (show) { + r_addmessage(r, u->faction, msg); + } else { /* Partei des Magiers, sieht diesen immer */ + result = 1; + } + } + } + /* Ist niemand von der Partei des Magiers in der Region, dem Magier + * nochmal gesondert melden */ + if ((flags&ACTION_CANSEE) && !fval(actor->faction, FFL_SELECT)) { + add_message(&actor->faction->msgs, msg); + } + } + return result; +} + + void reports_init(void) { diff --git a/src/common/kernel/reports.h b/src/common/kernel/reports.h index 433e40043..3fc22dfb3 100644 --- a/src/common/kernel/reports.h +++ b/src/common/kernel/reports.h @@ -126,6 +126,11 @@ extern const char * report_kampfstatus(const struct unit * u, const struct local void report_building(const struct building * b, const char ** btype, const char ** billusion); void report_race(const struct unit * u, const char ** rcname, const char ** rcillusion); +#define ACTION_RESET 0x01 /* reset the one-time-flag FFL_SELECT (on first pass) */ +#define ACTION_CANSEE 0x02 /* to people who can see the actor */ +#define ACTION_CANNOTSEE 0x04 /* to people who can not see the actor */ +extern int report_action(struct region * r, struct unit * actor, struct message * msg, int flags); + extern size_t f_regionid(const struct region * r, const struct faction * f, char * buffer, size_t size); extern const char * combatstatus[]; diff --git a/src/common/kernel/spellid.h b/src/common/kernel/spellid.h index 4bb523bd7..ffdc411f0 100644 --- a/src/common/kernel/spellid.h +++ b/src/common/kernel/spellid.h @@ -35,9 +35,7 @@ enum { SPL_BERSERK, SPL_BLOODTHIRST, SPL_MAELSTROM, - SPL_BLESSEDHARVEST, - SPL_RAINDANCE, - SPL_TRANSFERAURA_DRUIDE, + SPL_TRANSFERAURA_DRUIDE = 27, SPL_TRANSFERAURA_BARDE, SPL_TRANSFERAURA_CHAOS, SPL_TRANSFERAURA_TRAUM, diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index ea11c441f..ccb458b73 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -1205,9 +1205,9 @@ item_modification(const unit *u, skill_t sk, int val) static int att_modification(const unit *u, skill_t sk) { - int bonus = 0, malus = 0; + double bonus = 0, malus = 0; attrib * a; - int result = 0; + double result = 0; static boolean init = false; static const curse_type * skillmod_ct, * gbdream_ct, * worse_ct; curse * c; @@ -1240,7 +1240,7 @@ att_modification(const unit *u, skill_t sk) while (a && a->type==&at_curse) { curse * c = (curse*)a->data.v; if (curse_active(c) && c->type==gbdream_ct) { - int mod = curse_geteffect(c); + double mod = curse_geteffect(c); unit * mage = c->magician; /* wir suchen jeweils den größten Bonus und den größten Malus */ if (mod>bonus) { @@ -1257,7 +1257,7 @@ att_modification(const unit *u, skill_t sk) } result = result + bonus + malus; - return result; + return (int)result; } int diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 3a4197146..f8e4169dc 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -380,9 +381,11 @@ break_curse(attrib **alist, int cast_level, double force, curse * c) /* ------------------------------------------------------------- */ /* Report a spell's effect to the units in the region. */ + static void report_effect(region * r, unit * mage, message * seen, message * unseen) { +#if 0 unit * u; /* melden, 1x pro Partei */ @@ -415,6 +418,12 @@ report_effect(region * r, unit * mage, message * seen, message * unseen) if (!fval(mage->faction, FFL_SELECT)) { add_message(&mage->faction->msgs, seen); } +#else + int err = report_action(r, mage, seen, ACTION_RESET|ACTION_CANSEE); + if (err) { + report_action(r, mage, seen, ACTION_CANNOTSEE); + } +#endif } /* ------------------------------------------------------------- */ @@ -1086,40 +1095,17 @@ sp_blessedharvest(castorder *co) unit *mage = co->magician.u; int cast_level = co->level; double power = co->force; - double effect; - int rule = rule_blessed_harvest(); + int duration = (int)power+1; /* Attribut auf Region. * Existiert schon ein curse, so wird dieser verstärkt * (Max(Dauer), Max(Stärke))*/ - if (rule==HARVEST_WORK) { - int duration = (int)power+1; - effect = 1; - create_curse(mage, &r->attribs, ct_find("blessedharvest"), power, duration, effect, 0); - } else if (rule==HARVEST_TAXES) { - int duration = (int)(power*2); - if (co->sp->id!=SPL_BLESSEDHARVEST) { - effect = (int)(100 * power); - create_curse(mage, &r->attribs, ct_find("blessedharvest"), power, duration, effect, 0); - } else { - int d; - region * rn[MAXDIRECTIONS]; - get_neighbours(r, rn); - effect = (int)(50 * power); - for (d=0;d!=MAXDIRECTIONS;++d) { - region * rx = rn[d]; - if (rx && rx->land) { - create_curse(mage, &rx->attribs, ct_find("blessedharvest"), power, duration, effect, 0); - } - } - create_curse(mage, &r->attribs, ct_find("blessedharvest"), power, duration, effect, 0); - } - } - { - message * seen = msg_message("harvest_effect", "mage", mage); - message * unseen = msg_message("harvest_effect", "mage", NULL); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); + + if (create_curse(mage, &r->attribs, ct_find("blessedharvest"), power, duration, 1.0, 0)) { + message * seen = msg_message("harvest_effect", "mage", mage); + message * unseen = msg_message("harvest_effect", "mage", NULL); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); } return cast_level; @@ -6869,20 +6855,6 @@ typedef struct spelldata { static spelldata spelldaten[] = { /* M_GWYRRD */ - { - SPL_BLESSEDHARVEST, "blessedharvest", NULL, NULL, NULL, - M_GWYRRD, - (FARCASTING | SPELLLEVEL | ONSHIPCAST | REGIONSPELL), - 5, 1, - { - { "aura", 1, SPC_LEVEL }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - (spell_f)sp_blessedharvest, NULL - }, { SPL_STONEGOLEM, "stonegolem", NULL, NULL, NULL, M_GWYRRD, (SPELLLEVEL), 4, 1, @@ -7937,20 +7909,6 @@ static spelldata spelldaten[] = }, (spell_f)sp_generous, NULL }, - { - SPL_RAINDANCE, "raindance", NULL, NULL, NULL, - M_CERDDOR, - (FARCASTING | SPELLLEVEL | ONSHIPCAST | REGIONSPELL), - 5, 3, - { - { "aura", 1, SPC_LEVEL }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - (spell_f)sp_blessedharvest, NULL - }, { SPL_SONG_OF_FEAR, "song_of_fear", NULL, NULL, NULL, M_CERDDOR, (COMBATSPELL | SPELLLEVEL), 5, 3, @@ -8933,6 +8891,7 @@ register_spells(void) register_regioncurse(); register_shipcurse(); register_buildingcurse(); + register_function((pf_generic)&sp_blessedharvest, "cast_blessedharvest"); register_function((pf_generic)&sp_wdwpyramid, "wdwpyramid"); register_function((pf_generic)&sp_summon_familiar, "cast_familiar"); } diff --git a/src/eressea/tolua/bind_message.c b/src/eressea/tolua/bind_message.c index b071e32b1..8dd37bd3e 100644 --- a/src/eressea/tolua/bind_message.c +++ b/src/eressea/tolua/bind_message.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -282,6 +283,18 @@ tolua_msg_send_region(lua_State * L) return 1; } +static int +tolua_msg_report_action(lua_State * L) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(L, 1, 0); + region * r = (region *)tolua_tousertype(L, 2, 0); + unit * u = (unit *)tolua_tousertype(L, 3, 0); + int flags = (int)tolua_tonumber(L, 4, 0); + int result = report_action(r, u, lmsg->msg, flags); + tolua_pushnumber(L, (lua_Number)result); + return 1; +} + static int tolua_msg_send_faction(lua_State * L) { @@ -314,6 +327,7 @@ tolua_message_open(lua_State* L) tolua_function(L, TOLUA_CAST "set_string", tolua_msg_set_string); tolua_function(L, TOLUA_CAST "send_faction", tolua_msg_send_faction); tolua_function(L, TOLUA_CAST "send_region", tolua_msg_send_region); + tolua_function(L, TOLUA_CAST "report_action", tolua_msg_report_action); tolua_function(L, TOLUA_CAST "create", tolua_msg_create); } diff --git a/src/eressea/tolua/bind_region.c b/src/eressea/tolua/bind_region.c index d56af95c8..fa5f26855 100644 --- a/src/eressea/tolua/bind_region.c +++ b/src/eressea/tolua/bind_region.c @@ -208,6 +208,23 @@ static int tolua_region_get_flag(lua_State* L) } static int tolua_region_get_adj(lua_State* L) +{ + region* r = (region*)tolua_tousertype(L, 1, 0); + region* rn[MAXDIRECTIONS]; + int d, idx; + get_neighbours(r, rn); + + lua_createtable(L, MAXDIRECTIONS, 0); + for (d=0,idx=0;d!=MAXDIRECTIONS;++d) { + if (rn[d]) { + tolua_pushusertype(L, rn[d], TOLUA_CAST "region"); + lua_rawseti(L, -2, ++idx); + } + } + return 1; +} + +static int tolua_region_get_next(lua_State* L) { region* self = (region*)tolua_tousertype(L, 1, 0); direction_t dir = (direction_t)tolua_tonumber(L, 2, 0); @@ -573,7 +590,8 @@ tolua_region_open(lua_State* L) tolua_function(L, TOLUA_CAST "set_resource", tolua_region_set_resource); tolua_function(L, TOLUA_CAST "get_flag", tolua_region_get_flag); tolua_function(L, TOLUA_CAST "set_flag", tolua_region_set_flag); - tolua_function(L, TOLUA_CAST "next", tolua_region_get_adj); + tolua_function(L, TOLUA_CAST "next", tolua_region_get_next); + tolua_variable(L, TOLUA_CAST "adj", tolua_region_get_adj, NULL); tolua_variable(L, TOLUA_CAST "terrain_name", &tolua_region_get_terrainname, &tolua_region_set_terrainname); tolua_variable(L, TOLUA_CAST "owner", &tolua_region_get_owner, &tolua_region_set_owner); diff --git a/src/eressea/tolua/bindings.c b/src/eressea/tolua/bindings.c index eb091114e..36ead747d 100644 --- a/src/eressea/tolua/bindings.c +++ b/src/eressea/tolua/bindings.c @@ -328,6 +328,46 @@ tolua_get_season(lua_State * L) return 1; } +static int +tolua_create_curse(lua_State * L) +{ + unit * u = (unit *)tolua_tousertype(L, 1, 0); + tolua_Error tolua_err; + attrib ** ap = NULL; + + if (tolua_isusertype(L, 2, TOLUA_CAST "unit", 0, &tolua_err)) { + unit * target = (unit *)tolua_tousertype(L, 1, 0); + if (target) ap = &target->attribs; + } else if (tolua_isusertype(L, 2, TOLUA_CAST "region", 0, &tolua_err)) { + region * target = (region *)tolua_tousertype(L, 1, 0); + if (target) ap = &target->attribs; + } else if (tolua_isusertype(L, 2, TOLUA_CAST "ship", 0, &tolua_err)) { + ship * target = (ship *)tolua_tousertype(L, 1, 0); + if (target) ap = &target->attribs; + } else if (tolua_isusertype(L, 2, TOLUA_CAST "building", 0, &tolua_err)) { + building * target = (building *)tolua_tousertype(L, 1, 0); + if (target) ap = &target->attribs; + } + if (ap) { + const char * cname = tolua_tostring(L, 3, 0); + const curse_type * ctype = ct_find(cname); + if (ctype) { + double vigour = tolua_tonumber(L, 4, 0); + int duration = (int)tolua_tonumber(L, 5, 0); + double effect = tolua_tonumber(L, 6, 0); + int men = (int)tolua_tonumber(L, 7, 0); /* optional */ + curse * c = create_curse(u, ap, ctype, vigour, duration, effect, men); + + if (c) { + tolua_pushboolean(L, true); + return 1; + } + } + } + tolua_pushboolean(L, false); + return 1; +} + static int tolua_learn_skill(lua_State * L) { @@ -970,6 +1010,7 @@ tolua_eressea_open(lua_State* L) tolua_function(L, TOLUA_CAST "update_owners", tolua_update_owners); tolua_function(L, TOLUA_CAST "learn_skill", tolua_learn_skill); + tolua_function(L, TOLUA_CAST "create_curse", tolua_create_curse); tolua_function(L, TOLUA_CAST "autoseed", tolua_autoseed); diff --git a/src/res/e3a.xml b/src/res/e3a.xml index f5a93efd8..0c640a2e5 100644 --- a/src/res/e3a.xml +++ b/src/res/e3a.xml @@ -28,6 +28,7 @@ + diff --git a/src/res/e3a/spells.xml b/src/res/e3a/spells.xml index 740060cd6..ac21a737c 100644 --- a/src/res/e3a/spells.xml +++ b/src/res/e3a/spells.xml @@ -278,6 +278,7 @@ + @@ -504,6 +505,7 @@ + diff --git a/src/res/eressea/spells.xml b/src/res/eressea/spells.xml index ad955dc4d..86b77ae2b 100644 --- a/src/res/eressea/spells.xml +++ b/src/res/eressea/spells.xml @@ -35,6 +35,12 @@ + + + + + + @@ -95,6 +101,11 @@ + + + + + diff --git a/src/scripts/e3a/rules.lua b/src/scripts/e3a/rules.lua index f87eee5eb..709065466 100644 --- a/src/scripts/e3a/rules.lua +++ b/src/scripts/e3a/rules.lua @@ -40,3 +40,39 @@ function building_taxes(b, blevel) end return 0.0 end + +-- the "raindance" spell +function raindance(r, mage, level, force) + if (create_curse(mage, r, "blessedharvest", force, force*2, 100 * force)) then + -- slightly crooked way of reporting an action to everyone in the region + local msg = message.create("raindance_effect") + msg:set_unit("mage", mage) + if (msg:report_action(r, mage, 3)) then + local msg2 = message.create("raindance_effect") + msg2:set_unit("mage", nil) + msg2:report_action(r, mage, 4) + end + end + return level +end + +-- the "blessed harvest" spell +function blessedharvest(r, mage, level, force) + if create_curse(mage, r, "blessedharvest", force, force*2, 50 * force) then + -- slightly crooked way of reporting an action to everyone in the region + local msg = message.create("harvest_effect") + msg:set_unit("mage", mage) + if (msg:report_action(r, mage, 3)) then + local msg2 = message.create("harvest_effect") + msg2:set_unit("mage", nil) + msg2:report_action(r, mage, 4) + end + for idx, rn in ipairs(r.adj) do + -- nur landregionen haben moral>=0 + if r.morale>=0 then + create_curse(mage, r, "blessedharvest", force, force*2, 50 * force) + end + end + end + return level +end diff --git a/src/scripts/spells.lua b/src/scripts/spells.lua index 9c3bd022d..fce0603b7 100644 --- a/src/scripts/spells.lua +++ b/src/scripts/spells.lua @@ -1,5 +1,5 @@ function creation_message(mage, type) - msg = message.create("item_create_spell") + local msg = message.create("item_create_spell") msg:set_unit("mage", mage) msg:set_int("number", 1) msg:set_resource("item", type) diff --git a/src/scripts/tests.lua b/src/scripts/tests.lua index c19ca5aea..8043d7cda 100644 --- a/src/scripts/tests.lua +++ b/src/scripts/tests.lua @@ -433,7 +433,7 @@ function test_taxes() local u = unit.create(f, r, 1) u:add_item("money", u.number * 10) u:clear_orders() - u:add_order("LERNE Wahrnehmung") + u:add_order("LERNE Holzfällen") -- do not work local b = building.create(r, "watch") b.size = 10 u.building = b @@ -652,7 +652,7 @@ mytests = { -- ["blessed"] = test_blessed -- foiled by peasantgrowth } fail = 0 -for k, v in pairs(mytests) do +for k, v in pairs(tests) do local status, err = pcall(v) if not status then fail = fail + 1