forked from github/server
new implementation blessedharvest and raindance (in lua)
lots of lua interfacing for spells. region.adj (Lua) is kewl.
This commit is contained in:
parent
c175a8dcea
commit
bc3612935b
15 changed files with 200 additions and 71 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <kernel/curse.h>
|
||||
#include <kernel/spellid.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/reports.h>
|
||||
#include <kernel/item.h>
|
||||
#include <kernel/karma.h>
|
||||
#include <kernel/magic.h>
|
||||
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <kernel/faction.h>
|
||||
#include <kernel/item.h>
|
||||
#include <kernel/message.h>
|
||||
#include <kernel/reports.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
<xi:include href="e3a/calendar.xml"/>
|
||||
<xi:include href="e3a/items.xml" />
|
||||
<xi:include href="e3a/strings.xml"/>
|
||||
<xi:include href="e3a/messages.xml"/>
|
||||
<xi:include href="e3a/races.xml"/>
|
||||
<xi:include href="e3a/buildings.xml"/>
|
||||
<xi:include href="e3a/equipment.xml"/>
|
||||
|
|
|
@ -278,6 +278,7 @@
|
|||
<!-- new gwyrrd -->
|
||||
<spell name="blessedharvest" type="gwyrrd" rank="5" level="3" index="25" ship="true" far="true" variable="true">
|
||||
<!-- Segen der Erde -->
|
||||
<function name="cast" value="lua_castspell"/>
|
||||
<resource name="aura" amount="1" cost="level"/>
|
||||
</spell>
|
||||
<spell name="earn_silver#gwyrrd" type="gwyrrd" ship="true" variable="true" rank="5" level="1" index="159">
|
||||
|
@ -504,6 +505,7 @@
|
|||
</spell>
|
||||
<spell name="raindance" type="common" rank="5" level="2" index="26" ship="true" far="true" variable="true">
|
||||
<!-- Regentanz -->
|
||||
<function name="cast" value="lua_castspell"/>
|
||||
<resource name="aura" amount="1" cost="level"/>
|
||||
</spell>
|
||||
<spell name="irongolem" type="common" rank="4" level="2" index="33" variable="true">
|
||||
|
|
|
@ -35,6 +35,12 @@
|
|||
</spell>
|
||||
|
||||
<!-- gwyrrd spells -->
|
||||
<spell name="blessedharvest" type="gwyrrd" rank="5" level="1" index="25" ship="true" far="true" variable="true">
|
||||
<!-- Segen der Erde -->
|
||||
<function name="cast" value="cast_blessedharvest"/>
|
||||
<resource name="aura" amount="1" cost="level"/>
|
||||
</spell>
|
||||
|
||||
<spell name="create_roi" type="gwyrrd" ship="true" rank="5" level="6" index="129">
|
||||
<function name="cast" value="lua_castspell"/>
|
||||
<resource name="aura" amount="50" cost="fixed"/>
|
||||
|
@ -95,6 +101,11 @@
|
|||
</spell>
|
||||
|
||||
<!-- cerddor spells -->
|
||||
<spell name="raindance" type="cerddor" rank="5" level="3" index="26" ship="true" far="true" variable="true">
|
||||
<!-- Segen der Erde -->
|
||||
<function name="cast" value="cast_blessedharvest"/>
|
||||
<resource name="aura" amount="1" cost="level"/>
|
||||
</spell>
|
||||
<spell name="create_roi" type="cerddor" ship="true" rank="5" level="6" index="132">
|
||||
<function name="cast" value="lua_castspell"/>
|
||||
<resource name="aura" amount="50" cost="fixed"/>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue