- better leave() protection

- unit.race_name = "smurf"
This commit is contained in:
Enno Rehling 2009-07-07 15:31:12 +00:00
parent 4d79101a71
commit 0c61da36e0
12 changed files with 133 additions and 95 deletions

View file

@ -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) {

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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(

View file

@ -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);
}

View file

@ -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);
}

View file

@ -118,4 +118,3 @@ if orderfile==nil then
else
process(orderfile)
end