- 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 /* must leave ships or buildings, or a stealthy hobbit
* can hold castles indefinitely */ * can hold castles indefinitely */
if (!fval(r->terrain, SEA_REGION)) { if (!fval(r->terrain, SEA_REGION)) {
leave(du->region, du); leave(du, true); /* even region owners have to flee */
} }
#ifndef SIMPLE_ESCAPE #ifndef SIMPLE_ESCAPE
if (df->run.region) { 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); fset(b, BLD_MAINTAINED);
/* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */ /* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */
leave(r, u); if (leave(u, false)) {
u->building = b; u->building = b;
fset(u, UFL_OWNER); fset(u, UFL_OWNER);
}
#ifdef WDW_PYRAMID #ifdef WDW_PYRAMID
if(b->type == bt_find("pyramid") && u->faction->alliance != NULL) { 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); sh = new_ship(newtype, u->faction->locale, r);
leave(r, u); if (leave(u, false)) {
if (fval(u->race, RCF_CANSAIL)) { if (fval(u->race, RCF_CANSAIL)) {
u->ship = sh; 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); 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); replace_order(&u->orders, ord, new_order);
free_order(new_order); free_order(new_order);
@ -1141,7 +1143,7 @@ leave_cmd(unit * u, struct order * ord)
if (!slipthru(r, u, u->building)) { if (!slipthru(r, u, u->building)) {
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "entrance_besieged", "building", u->building)); ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "entrance_besieged", "building", u->building));
} else { } else {
leave(r, u); leave(u, true);
} }
return 0; return 0;
} }
@ -1199,13 +1201,14 @@ enter_ship(unit * u, struct order * ord, int id, boolean report)
} }
} }
leave(u->region, u); if (leave(u, false)) {
u->ship = sh; u->ship = sh;
if (shipowner(sh) == NULL) { if (shipowner(sh) == NULL) {
fset(u, UFL_OWNER); fset(u, UFL_OWNER);
}
fset(u, UFL_ENTER);
} }
fset(u, UFL_ENTER);
return true; return true;
} }
@ -1246,12 +1249,13 @@ enter_building(unit * u, order * ord, int id, boolean report)
return false; return false;
} }
leave(r, u); if (leave(u, false)) {
u->building = b; u->building = b;
if (buildingowner(r, b) == 0) { if (buildingowner(r, b) == 0) {
fset(u, UFL_OWNER); fset(u, UFL_OWNER);
}
fset(u, UFL_ENTER);
} }
fset(u, UFL_ENTER);
return true; return true;
} }

View file

@ -526,7 +526,7 @@ remove_building(building ** blist, building * b)
handle_event(b->attribs, "destroy", b); handle_event(b->attribs, "destroy", b);
for (u=b->region->units; u; u=u->next) { 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; 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: */ /* a few pre-checks that need not be done for each step: */
if (!fval(r->terrain, SEA_REGION)) { if (!fval(r->terrain, SEA_REGION)) {
ship * sh = u->ship; ship * sh = u->ship;
static int rule_leave = -1;
if (rule_leave<0) { if (!can_leave(u)) {
rule_leave = get_param_int(global.parameters, "rules.move.owner_leave", 0);
}
if (rule_leave && u->building && u==buildingowner(u->region, u->building)) {
cmistake(u, u->thisorder, 150, MSG_MOVE); cmistake(u, u->thisorder, 150, MSG_MOVE);
return; return;
} }

View file

@ -336,7 +336,7 @@ remove_unit(unit ** ulist, unit * u)
} }
if (u->number) set_number(u, 0); if (u->number) set_number(u, 0);
leave(u->region, u); leave(u, true);
u->region = NULL; u->region = NULL;
uunhash(u); uunhash(u);
@ -820,12 +820,36 @@ leave_building(unit * u)
} }
} }
void boolean
leave(struct region * r, unit * u) 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); if (u->building) leave_building(u);
else if (u->ship) leave_ship(u); else if (u->ship) leave_ship(u);
unused(r); return true;
} }
const struct race * const struct race *
@ -867,7 +891,7 @@ move_unit(unit * u, region * r, unit ** ulist)
if (u->region) { if (u->region) {
setguard(u, GUARD_NONE); setguard(u, GUARD_NONE);
fset(u, UFL_MOVED); 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); translist(&u->region->units, ulist, u);
} else { } else {
addlist(ulist, u); 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; */ /* 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" #include "alchemy.h"
void 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 void write_unit_reference(const struct unit * u, struct storage * store);
extern variant read_unit_reference(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_ship(unit * u);
extern void leave_building(unit * u); extern void leave_building(unit * u);

View file

@ -67,20 +67,20 @@ xe_givepotion(unit *u, struct order *ord)
static void static void
xe_giveballon(unit *u, struct order *ord) xe_giveballon(unit *u, struct order *ord)
{ {
unit *u2 = getunitg(u->region, u->faction); unit *u2 = getunitg(u->region, u->faction);
ship *sh; ship *sh;
if(!u2) { if (!u2) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); 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 = new_ship(st_find("balloon"), u2->faction->locale, u2->region);
sh->size = 5; sh->size = 5;
ship_setname(sh, "Xontormia-Ballon"); ship_setname(sh, "Xontormia-Ballon");
leave(u2->region, u2); leave(u2, false);
u2->ship = sh; u2->ship = sh;
fset(u2, UFL_OWNER); fset(u2, UFL_OWNER);
} }
int 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. */ /* Fliehende Einheiten verlassen auf jeden Fall Gebäude und Schiffe. */
if (!fval(r->terrain, SEA_REGION)) { if (!fval(r->terrain, SEA_REGION)) {
leave(r, mage); leave(mage, false);
} }
/* und bewachen nicht */ /* und bewachen nicht */
setguard(mage, GUARD_NONE); 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); data->time = 2+(rng_int()%(int)(power)+1)*(rng_int()%(int)(power)+1);
if (mage->region == r) { if (mage->region == r) {
leave(r, mage); if (leave(mage, false)) {
mage->building = b; mage->building = b;
}
} }
ADDMSG(&mage->faction->msgs, msg_message( ADDMSG(&mage->faction->msgs, msg_message(

View file

@ -330,7 +330,7 @@ unit_getregion(const unit * u)
static void static void
unit_setship(unit * u, ship * s) unit_setship(unit * u, ship * s)
{ {
leave(u->region, u); leave(u, true);
if (u->region!=s->region) { if (u->region!=s->region) {
move_unit(u, s->region, NULL); move_unit(u, s->region, NULL);
} }
@ -346,7 +346,7 @@ unit_getship(const unit * u)
static void static void
unit_setbuilding(unit * u, building * b) unit_setbuilding(unit * u, building * b)
{ {
leave(u->region, u); leave(u, true);
if (u->region!=b->region) { if (u->region!=b->region) {
move_unit(u, b->region, NULL); move_unit(u, b->region, NULL);
} }

View file

@ -539,7 +539,7 @@ tolua_unit_removespell(lua_State* L)
} }
static int static int
tolua_unit_setracename(lua_State* L) tolua_unit_set_racename(lua_State* L)
{ {
unit* self = (unit*)tolua_tousertype(L, 1, 0); unit* self = (unit*)tolua_tousertype(L, 1, 0);
const char * str = tolua_tostring(L, 2, 0); const char * str = tolua_tostring(L, 2, 0);
@ -548,6 +548,18 @@ tolua_unit_setracename(lua_State* L)
return 0; 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 static int
tolua_unit_setskill(lua_State* L) tolua_unit_setskill(lua_State* L)
{ {
@ -627,7 +639,7 @@ static int tolua_unit_get_building(lua_State* L)
static void static void
unit_setbuilding(unit * u, building * b) unit_setbuilding(unit * u, building * b)
{ {
leave(u->region, u); leave(u, true);
if (u->region!=b->region) { if (u->region!=b->region) {
move_unit(u, b->region, NULL); move_unit(u, b->region, NULL);
} }
@ -651,7 +663,7 @@ static int tolua_unit_get_ship(lua_State* L)
static void static void
unit_setship(unit * u, ship * s) unit_setship(unit * u, ship * s)
{ {
leave(u->region, u); leave(u, true);
if (u->region!=s->region) { if (u->region!=s->region) {
move_unit(u, s->region, NULL); move_unit(u, s->region, NULL);
} }
@ -905,71 +917,71 @@ tolua_unit_open(lua_State * L)
tolua_cclass(L, "event", "event", "", NULL); tolua_cclass(L, "event", "event", "", NULL);
tolua_beginmodule(L, "event"); tolua_beginmodule(L, "event");
{ {
tolua_function(L, "get_type", tolua_event_gettype); tolua_function(L, "get_type", &tolua_event_gettype);
tolua_function(L, "get", tolua_event_get); tolua_function(L, "get", &tolua_event_get);
} }
tolua_endmodule(L); tolua_endmodule(L);
tolua_cclass(L, "unit", "unit", "", NULL); tolua_cclass(L, "unit", "unit", "", NULL);
tolua_beginmodule(L, "unit"); tolua_beginmodule(L, "unit");
{ {
tolua_function(L, "__tostring", tolua_unit_tostring); tolua_function(L, "__tostring", &tolua_unit_tostring);
tolua_function(L, "create", tolua_unit_create); tolua_function(L, "create", &tolua_unit_create);
tolua_variable(L, "name", tolua_unit_get_name, tolua_unit_set_name); 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, "faction", &tolua_unit_get_faction, tolua_unit_set_faction);
tolua_variable(L, "id", tolua_unit_get_id, tolua_unit_set_id); 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, "info", &tolua_unit_get_info, tolua_unit_set_info);
tolua_variable(L, "hp", tolua_unit_get_hp, tolua_unit_set_hp); 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, "status", &tolua_unit_get_status, tolua_unit_set_status);
tolua_variable(L, "familiar", tolua_unit_get_familiar, tolua_unit_set_familiar); tolua_variable(L, "familiar", &tolua_unit_get_familiar, tolua_unit_set_familiar);
tolua_variable(L, "weight", tolua_unit_get_weight, 0); tolua_variable(L, "weight", &tolua_unit_get_weight, 0);
tolua_variable(L, "capacity", tolua_unit_get_capacity, 0); tolua_variable(L, "capacity", &tolua_unit_get_capacity, 0);
tolua_function(L, "add_order", tolua_unit_add_order); tolua_function(L, "add_order", &tolua_unit_add_order);
tolua_function(L, "clear_orders", tolua_unit_clear_orders); tolua_function(L, "clear_orders", &tolua_unit_clear_orders);
tolua_variable(L, "orders", tolua_unit_get_orders, 0); tolua_variable(L, "orders", &tolua_unit_get_orders, 0);
// key-attributes for named flags: // key-attributes for named flags:
tolua_function(L, "set_flag", tolua_unit_set_flag); tolua_function(L, "set_flag", &tolua_unit_set_flag);
tolua_function(L, "get_flag", tolua_unit_get_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, "flags", &tolua_unit_get_flags, tolua_unit_set_flags);
tolua_variable(L, "age", tolua_unit_get_age, tolua_unit_set_age); tolua_variable(L, "age", &tolua_unit_get_age, tolua_unit_set_age);
// items: // items:
tolua_function(L, "get_item", tolua_unit_get_item); tolua_function(L, "get_item", &tolua_unit_get_item);
tolua_function(L, "add_item", tolua_unit_add_item); tolua_function(L, "add_item", &tolua_unit_add_item);
tolua_variable(L, "items", tolua_unit_get_items, 0); tolua_variable(L, "items", &tolua_unit_get_items, 0);
tolua_function(L, "get_pooled", tolua_unit_get_pooled); tolua_function(L, "get_pooled", &tolua_unit_get_pooled);
tolua_function(L, "use_pooled", tolua_unit_use_pooled); tolua_function(L, "use_pooled", &tolua_unit_use_pooled);
// skills: // skills:
tolua_function(L, "get_skill", tolua_unit_getskill); tolua_function(L, "get_skill", &tolua_unit_getskill);
tolua_function(L, "eff_skill", tolua_unit_effskill); tolua_function(L, "eff_skill", &tolua_unit_effskill);
tolua_function(L, "set_skill", tolua_unit_setskill); 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: // 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_variable(L, "race_name", &tolua_unit_get_racename, &tolua_unit_set_racename);
tolua_function(L, "add_spell", tolua_unit_addspell); tolua_function(L, "add_spell", &tolua_unit_addspell);
tolua_function(L, "remove_spell", tolua_unit_removespell); tolua_function(L, "remove_spell", &tolua_unit_removespell);
tolua_function(L, "cast_spell", tolua_unit_castspell); tolua_function(L, "cast_spell", &tolua_unit_castspell);
tolua_variable(L, "magic", tolua_unit_get_magic, tolua_unit_set_magic); 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, "aura", &tolua_unit_get_aura, tolua_unit_set_aura);
tolua_variable(L, "building", tolua_unit_get_building, tolua_unit_set_building); 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, "ship", &tolua_unit_get_ship, tolua_unit_set_ship);
tolua_variable(L, "region", tolua_unit_get_region, tolua_unit_set_region); tolua_variable(L, "region", &tolua_unit_get_region, tolua_unit_set_region);
tolua_variable(L, "spells", tolua_unit_get_spells, 0); tolua_variable(L, "spells", &tolua_unit_get_spells, 0);
tolua_variable(L, "number", tolua_unit_get_number, tolua_unit_set_number); 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, "race", &tolua_unit_get_race, tolua_unit_set_race);
tolua_variable(L, "hp_max", tolua_unit_get_hpmax, 0); 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); tolua_endmodule(L);
} }

View file

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