diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 2392686f7..dd6c8634b 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -2772,7 +2772,7 @@ aftermath(battle * b) /* must leave ships or buildings, or a stealthy hobbit * can hold castles indefinitely */ if (!fval(r->terrain, SEA_REGION)) { - leave(du->region, du); + leave(du, true); /* even region owners have to flee */ } #ifndef SIMPLE_ESCAPE if (df->run.region) { diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index d63962782..41969935b 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -924,9 +924,10 @@ build_building(unit * u, const building_type * btype, int want, order * ord) fset(b, BLD_MAINTAINED); /* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */ - leave(r, u); - u->building = b; - fset(u, UFL_OWNER); + if (leave(u, false)) { + u->building = b; + fset(u, UFL_OWNER); + } #ifdef WDW_PYRAMID if(b->type == bt_find("pyramid") && u->faction->alliance != NULL) { @@ -1041,11 +1042,12 @@ create_ship(region * r, unit * u, const struct ship_type * newtype, int want, or sh = new_ship(newtype, u->faction->locale, r); - leave(r, u); - if (fval(u->race, RCF_CANSAIL)) { - u->ship = sh; + if (leave(u, false)) { + if (fval(u->race, RCF_CANSAIL)) { + u->ship = sh; + fset(u, UFL_OWNER); + } } - fset(u, UFL_OWNER); new_order = create_order(K_MAKE, u->faction->locale, "%s %i", LOC(u->faction->locale, parameters[P_SHIP]), sh->no); replace_order(&u->orders, ord, new_order); free_order(new_order); @@ -1141,7 +1143,7 @@ leave_cmd(unit * u, struct order * ord) if (!slipthru(r, u, u->building)) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "entrance_besieged", "building", u->building)); } else { - leave(r, u); + leave(u, true); } return 0; } @@ -1199,13 +1201,14 @@ enter_ship(unit * u, struct order * ord, int id, boolean report) } } - leave(u->region, u); - u->ship = sh; + if (leave(u, false)) { + u->ship = sh; - if (shipowner(sh) == NULL) { - fset(u, UFL_OWNER); + if (shipowner(sh) == NULL) { + fset(u, UFL_OWNER); + } + fset(u, UFL_ENTER); } - fset(u, UFL_ENTER); return true; } @@ -1246,12 +1249,13 @@ enter_building(unit * u, order * ord, int id, boolean report) return false; } - leave(r, u); - u->building = b; - if (buildingowner(r, b) == 0) { - fset(u, UFL_OWNER); + if (leave(u, false)) { + u->building = b; + if (buildingowner(r, b) == 0) { + fset(u, UFL_OWNER); + } + fset(u, UFL_ENTER); } - fset(u, UFL_ENTER); return true; } diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index 955b8526d..8962fa6d8 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -526,7 +526,7 @@ remove_building(building ** blist, building * b) handle_event(b->attribs, "destroy", b); for (u=b->region->units; u; u=u->next) { - if (u->building == b) leave(b->region, u); + if (u->building == b) leave(u, true); } b->size = 0; diff --git a/src/common/kernel/move.c b/src/common/kernel/move.c index c3593390d..ba3bb6c55 100644 --- a/src/common/kernel/move.c +++ b/src/common/kernel/move.c @@ -1997,12 +1997,8 @@ travel(unit * u, region_list ** routep) /* a few pre-checks that need not be done for each step: */ if (!fval(r->terrain, SEA_REGION)) { ship * sh = u->ship; - static int rule_leave = -1; - if (rule_leave<0) { - rule_leave = get_param_int(global.parameters, "rules.move.owner_leave", 0); - } - if (rule_leave && u->building && u==buildingowner(u->region, u->building)) { + if (!can_leave(u)) { cmistake(u, u->thisorder, 150, MSG_MOVE); return; } diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 6f199b7d7..719be4778 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -336,7 +336,7 @@ remove_unit(unit ** ulist, unit * u) } if (u->number) set_number(u, 0); - leave(u->region, u); + leave(u, true); u->region = NULL; uunhash(u); @@ -820,12 +820,36 @@ leave_building(unit * u) } } -void -leave(struct region * r, unit * u) +boolean +can_leave(unit * u) { + static int rule_leave = -1; + + if (!u->building) { + return true; + } + if (rule_leave<0) { + rule_leave = get_param_int(global.parameters, "rules.move.owner_leave", 0); + } + if (rule_leave && u->building && u==buildingowner(u->region, u->building)) { + building * b = largestbuilding(u->region, &is_tax_building, false); + if (b==u->building) { + return false; + } + } + return true; +} + +boolean +leave(unit * u, boolean force) +{ + + if (!force) { + if (!can_leave(u)) return true; + } if (u->building) leave_building(u); else if (u->ship) leave_ship(u); - unused(r); + return true; } const struct race * @@ -867,7 +891,7 @@ move_unit(unit * u, region * r, unit ** ulist) if (u->region) { setguard(u, GUARD_NONE); fset(u, UFL_MOVED); - if (u->ship || u->building) leave(u->region, u); + if (u->ship || u->building) leave(u, true); translist(&u->region->units, ulist, u); } else { addlist(ulist, u); @@ -881,7 +905,7 @@ move_unit(unit * u, region * r, unit ** ulist) /* if (maxhp>0) u->hp = u->hp * unit_max_hp(u) / maxhp; */ } -/* ist mist, aber wegen nicht skalierender attirbute notwendig: */ +/* ist mist, aber wegen nicht skalierender attribute notwendig: */ #include "alchemy.h" void diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 7d613097d..f2967b243 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -184,7 +184,9 @@ extern int resolve_unit(variant data, void * address); extern void write_unit_reference(const struct unit * u, struct storage * store); extern variant read_unit_reference(struct storage * store); -extern void leave(struct region * r, struct unit * u); +extern boolean leave(struct unit * u, boolean force); +extern boolean can_leave(struct unit * u); + extern void leave_ship(unit * u); extern void leave_building(unit * u); diff --git a/src/common/modules/xecmd.c b/src/common/modules/xecmd.c index 3d19e70f3..d70123992 100644 --- a/src/common/modules/xecmd.c +++ b/src/common/modules/xecmd.c @@ -67,20 +67,20 @@ xe_givepotion(unit *u, struct order *ord) static void xe_giveballon(unit *u, struct order *ord) { - unit *u2 = getunitg(u->region, u->faction); - ship *sh; + unit *u2 = getunitg(u->region, u->faction); + ship *sh; - if(!u2) { + if (!u2) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); - return; - } + return; + } - sh = new_ship(st_find("balloon"), u2->faction->locale, u2->region); - sh->size = 5; + sh = new_ship(st_find("balloon"), u2->faction->locale, u2->region); + sh->size = 5; ship_setname(sh, "Xontormia-Ballon"); - leave(u2->region, u2); - u2->ship = sh; - fset(u2, UFL_OWNER); + leave(u2, false); + u2->ship = sh; + fset(u2, UFL_OWNER); } int diff --git a/src/common/spells/combatspells.c b/src/common/spells/combatspells.c index 3c164d171..8d00c11d2 100644 --- a/src/common/spells/combatspells.c +++ b/src/common/spells/combatspells.c @@ -1288,7 +1288,7 @@ sp_denyattack(fighter * fi, int level, double power, spell * sp) /* Fliehende Einheiten verlassen auf jeden Fall Gebäude und Schiffe. */ if (!fval(r->terrain, SEA_REGION)) { - leave(r, mage); + leave(mage, false); } /* und bewachen nicht */ setguard(mage, GUARD_NONE); diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index fcf639fe2..f0156db49 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -4821,8 +4821,9 @@ sp_icastle(castorder *co) data->time = 2+(rng_int()%(int)(power)+1)*(rng_int()%(int)(power)+1); if (mage->region == r) { - leave(r, mage); - mage->building = b; + if (leave(mage, false)) { + mage->building = b; + } } ADDMSG(&mage->faction->msgs, msg_message( diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp index 2230839ed..17078b955 100644 --- a/src/eressea/lua/unit.cpp +++ b/src/eressea/lua/unit.cpp @@ -330,7 +330,7 @@ unit_getregion(const unit * u) static void unit_setship(unit * u, ship * s) { - leave(u->region, u); + leave(u, true); if (u->region!=s->region) { move_unit(u, s->region, NULL); } @@ -346,7 +346,7 @@ unit_getship(const unit * u) static void unit_setbuilding(unit * u, building * b) { - leave(u->region, u); + leave(u, true); if (u->region!=b->region) { move_unit(u, b->region, NULL); } diff --git a/src/eressea/tolua/bind_unit.c b/src/eressea/tolua/bind_unit.c index c246e69ec..2d655fbcc 100644 --- a/src/eressea/tolua/bind_unit.c +++ b/src/eressea/tolua/bind_unit.c @@ -539,7 +539,7 @@ tolua_unit_removespell(lua_State* L) } static int -tolua_unit_setracename(lua_State* L) +tolua_unit_set_racename(lua_State* L) { unit* self = (unit*)tolua_tousertype(L, 1, 0); const char * str = tolua_tostring(L, 2, 0); @@ -548,6 +548,18 @@ tolua_unit_setracename(lua_State* L) return 0; } +static int +tolua_unit_get_racename(lua_State* L) +{ + unit* self = (unit*)tolua_tousertype(L, 1, 0); + attrib * a = a_find(self->attribs, &at_racename); + if (a) { + tolua_pushstring(L, get_racename(a)); + return 1; + } + return 0; +} + static int tolua_unit_setskill(lua_State* L) { @@ -627,7 +639,7 @@ static int tolua_unit_get_building(lua_State* L) static void unit_setbuilding(unit * u, building * b) { - leave(u->region, u); + leave(u, true); if (u->region!=b->region) { move_unit(u, b->region, NULL); } @@ -651,7 +663,7 @@ static int tolua_unit_get_ship(lua_State* L) static void unit_setship(unit * u, ship * s) { - leave(u->region, u); + leave(u, true); if (u->region!=s->region) { move_unit(u, s->region, NULL); } @@ -905,71 +917,71 @@ tolua_unit_open(lua_State * L) tolua_cclass(L, "event", "event", "", NULL); tolua_beginmodule(L, "event"); { - tolua_function(L, "get_type", tolua_event_gettype); - tolua_function(L, "get", tolua_event_get); + tolua_function(L, "get_type", &tolua_event_gettype); + tolua_function(L, "get", &tolua_event_get); } tolua_endmodule(L); tolua_cclass(L, "unit", "unit", "", NULL); tolua_beginmodule(L, "unit"); { - tolua_function(L, "__tostring", tolua_unit_tostring); - tolua_function(L, "create", tolua_unit_create); + tolua_function(L, "__tostring", &tolua_unit_tostring); + tolua_function(L, "create", &tolua_unit_create); - tolua_variable(L, "name", tolua_unit_get_name, tolua_unit_set_name); - tolua_variable(L, "faction", tolua_unit_get_faction, tolua_unit_set_faction); - tolua_variable(L, "id", tolua_unit_get_id, tolua_unit_set_id); - tolua_variable(L, "info", tolua_unit_get_info, tolua_unit_set_info); - tolua_variable(L, "hp", tolua_unit_get_hp, tolua_unit_set_hp); - tolua_variable(L, "status", tolua_unit_get_status, tolua_unit_set_status); - tolua_variable(L, "familiar", tolua_unit_get_familiar, tolua_unit_set_familiar); + tolua_variable(L, "name", &tolua_unit_get_name, tolua_unit_set_name); + tolua_variable(L, "faction", &tolua_unit_get_faction, tolua_unit_set_faction); + tolua_variable(L, "id", &tolua_unit_get_id, tolua_unit_set_id); + tolua_variable(L, "info", &tolua_unit_get_info, tolua_unit_set_info); + tolua_variable(L, "hp", &tolua_unit_get_hp, tolua_unit_set_hp); + tolua_variable(L, "status", &tolua_unit_get_status, tolua_unit_set_status); + tolua_variable(L, "familiar", &tolua_unit_get_familiar, tolua_unit_set_familiar); - tolua_variable(L, "weight", tolua_unit_get_weight, 0); - tolua_variable(L, "capacity", tolua_unit_get_capacity, 0); + tolua_variable(L, "weight", &tolua_unit_get_weight, 0); + tolua_variable(L, "capacity", &tolua_unit_get_capacity, 0); - tolua_function(L, "add_order", tolua_unit_add_order); - tolua_function(L, "clear_orders", tolua_unit_clear_orders); - tolua_variable(L, "orders", tolua_unit_get_orders, 0); + tolua_function(L, "add_order", &tolua_unit_add_order); + tolua_function(L, "clear_orders", &tolua_unit_clear_orders); + tolua_variable(L, "orders", &tolua_unit_get_orders, 0); // key-attributes for named flags: - tolua_function(L, "set_flag", tolua_unit_set_flag); - tolua_function(L, "get_flag", tolua_unit_get_flag); - tolua_variable(L, "flags", tolua_unit_get_flags, tolua_unit_set_flags); - tolua_variable(L, "age", tolua_unit_get_age, tolua_unit_set_age); + tolua_function(L, "set_flag", &tolua_unit_set_flag); + tolua_function(L, "get_flag", &tolua_unit_get_flag); + tolua_variable(L, "flags", &tolua_unit_get_flags, tolua_unit_set_flags); + tolua_variable(L, "age", &tolua_unit_get_age, tolua_unit_set_age); // items: - tolua_function(L, "get_item", tolua_unit_get_item); - tolua_function(L, "add_item", tolua_unit_add_item); - tolua_variable(L, "items", tolua_unit_get_items, 0); - tolua_function(L, "get_pooled", tolua_unit_get_pooled); - tolua_function(L, "use_pooled", tolua_unit_use_pooled); + tolua_function(L, "get_item", &tolua_unit_get_item); + tolua_function(L, "add_item", &tolua_unit_add_item); + tolua_variable(L, "items", &tolua_unit_get_items, 0); + tolua_function(L, "get_pooled", &tolua_unit_get_pooled); + tolua_function(L, "use_pooled", &tolua_unit_use_pooled); // skills: - tolua_function(L, "get_skill", tolua_unit_getskill); - tolua_function(L, "eff_skill", tolua_unit_effskill); - tolua_function(L, "set_skill", tolua_unit_setskill); + tolua_function(L, "get_skill", &tolua_unit_getskill); + tolua_function(L, "eff_skill", &tolua_unit_effskill); + tolua_function(L, "set_skill", &tolua_unit_setskill); - tolua_function(L, "add_notice", tolua_unit_addnotice); + tolua_function(L, "add_notice", &tolua_unit_addnotice); // npc logic: - tolua_function(L, "add_handler", tolua_unit_addhandler); + tolua_function(L, "add_handler", &tolua_unit_addhandler); - tolua_function(L, "set_racename", tolua_unit_setracename); - tolua_function(L, "add_spell", tolua_unit_addspell); - tolua_function(L, "remove_spell", tolua_unit_removespell); - tolua_function(L, "cast_spell", tolua_unit_castspell); + tolua_variable(L, "race_name", &tolua_unit_get_racename, &tolua_unit_set_racename); + tolua_function(L, "add_spell", &tolua_unit_addspell); + tolua_function(L, "remove_spell", &tolua_unit_removespell); + tolua_function(L, "cast_spell", &tolua_unit_castspell); - tolua_variable(L, "magic", tolua_unit_get_magic, tolua_unit_set_magic); - tolua_variable(L, "aura", tolua_unit_get_aura, tolua_unit_set_aura); - tolua_variable(L, "building", tolua_unit_get_building, tolua_unit_set_building); - tolua_variable(L, "ship", tolua_unit_get_ship, tolua_unit_set_ship); - tolua_variable(L, "region", tolua_unit_get_region, tolua_unit_set_region); - tolua_variable(L, "spells", tolua_unit_get_spells, 0); - tolua_variable(L, "number", tolua_unit_get_number, tolua_unit_set_number); - tolua_variable(L, "race", tolua_unit_get_race, tolua_unit_set_race); - tolua_variable(L, "hp_max", tolua_unit_get_hpmax, 0); + tolua_variable(L, "magic", &tolua_unit_get_magic, tolua_unit_set_magic); + tolua_variable(L, "aura", &tolua_unit_get_aura, tolua_unit_set_aura); + tolua_variable(L, "building", &tolua_unit_get_building, tolua_unit_set_building); + tolua_variable(L, "ship", &tolua_unit_get_ship, tolua_unit_set_ship); + tolua_variable(L, "region", &tolua_unit_get_region, tolua_unit_set_region); + tolua_variable(L, "spells", &tolua_unit_get_spells, 0); + tolua_variable(L, "number", &tolua_unit_get_number, tolua_unit_set_number); + tolua_variable(L, "race", &tolua_unit_get_race, tolua_unit_set_race); + tolua_variable(L, "hp_max", &tolua_unit_get_hpmax, 0); - tolua_variable(L, "objects", tolua_unit_get_objects, 0); + tolua_variable(L, "objects", &tolua_unit_get_objects, 0); } tolua_endmodule(L); } diff --git a/src/scripts/run-e3a.lua b/src/scripts/run-e3a.lua index 682ab420e..dab91dc0b 100644 --- a/src/scripts/run-e3a.lua +++ b/src/scripts/run-e3a.lua @@ -118,4 +118,3 @@ if orderfile==nil then else process(orderfile) end -