forked from github/server
smarter processing of MAKE TEMP.
the order gets its own keyword. parsing is hard - composite commands are an anti-pattern. this eliminates a lot of unnecessary mallocs for pushing/poping parser state.
This commit is contained in:
parent
41d42fa248
commit
c79dd33bfb
|
@ -2197,6 +2197,9 @@
|
|||
<string name="make">
|
||||
<text locale="de">MACHEN</text>
|
||||
</string>
|
||||
<string name="maketemp">
|
||||
<text locale="de">MACHE TEMP</text>
|
||||
</string>
|
||||
<string name="move">
|
||||
<text locale="de">NACH</text>
|
||||
</string>
|
||||
|
|
|
@ -1475,6 +1475,9 @@
|
|||
<string name="make">
|
||||
<text locale="en">MAKE</text>
|
||||
</string>
|
||||
<string name="maketemp">
|
||||
<text locale="de">MAKE TEMP</text>
|
||||
</string>
|
||||
<string name="move">
|
||||
<text locale="en">MOVE</text>
|
||||
</string>
|
||||
|
|
|
@ -1817,10 +1817,6 @@ int make_cmd(unit * u, struct order *ord)
|
|||
|
||||
p = findparam(s, u->faction->locale);
|
||||
|
||||
/* MACHE TEMP kann hier schon gar nicht auftauchen, weil diese nicht in
|
||||
* thisorder abgespeichert werden - und auf den ist getstrtoken() beim
|
||||
* aufruf von make geeicht */
|
||||
|
||||
if (p == P_ROAD) {
|
||||
plane *pl = rplane(r);
|
||||
if (pl && fval(pl, PFL_NOBUILD)) {
|
||||
|
@ -1905,12 +1901,15 @@ int make_cmd(unit * u, struct order *ord)
|
|||
else if (btype != NOBUILDING) {
|
||||
plane *pl = rplane(r);
|
||||
if (pl && fval(pl, PFL_NOBUILD)) {
|
||||
cmistake(u, ord, 94, MSG_PRODUCE);
|
||||
cmistake(u, ord, 275, MSG_PRODUCE);
|
||||
}
|
||||
else {
|
||||
else if (btype->construction) {
|
||||
int id = getid();
|
||||
build_building(u, btype, id, m, ord);
|
||||
}
|
||||
else {
|
||||
cmistake(u, ord, 275, MSG_PRODUCE);
|
||||
}
|
||||
}
|
||||
else if (itype != NULL) {
|
||||
create_item(u, itype, m);
|
||||
|
|
|
@ -1571,16 +1571,17 @@ message *msg_unitnotfound(const struct unit * mage, struct order * ord,
|
|||
{
|
||||
/* Einheit nicht gefunden */
|
||||
char tbuf[20];
|
||||
const char *uid;
|
||||
const char *uid = 0;
|
||||
|
||||
if (spobj->typ == SPP_UNIT) {
|
||||
uid = itoa36(spobj->data.i);
|
||||
}
|
||||
else {
|
||||
if (spobj->typ == SPP_TEMP) {
|
||||
sprintf(tbuf, "%s %s", LOC(mage->faction->locale,
|
||||
parameters[P_TEMP]), itoa36(spobj->data.i));
|
||||
uid = tbuf;
|
||||
}
|
||||
else if (spobj->typ == SPP_UNIT) {
|
||||
uid = itoa36(spobj->data.i);
|
||||
}
|
||||
assert(uid);
|
||||
return msg_message("unitnotfound_id",
|
||||
"unit region command id", mage, mage->region, ord, uid);
|
||||
}
|
||||
|
|
|
@ -359,6 +359,12 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
}
|
||||
sptr = s;
|
||||
kwd = get_keyword(parse_token(&sptr), lang);
|
||||
if (kwd == K_MAKE) {
|
||||
const char *s = parse_token(&sptr);
|
||||
if (isparam(s, lang, P_TEMP)) {
|
||||
kwd = K_MAKETEMP;
|
||||
}
|
||||
}
|
||||
if (kwd != NOKEYWORD) {
|
||||
while (isxspace(*(unsigned char *)sptr)) ++sptr;
|
||||
s = sptr;
|
||||
|
@ -380,7 +386,6 @@ bool is_repeated(const order * ord)
|
|||
{
|
||||
keyword_t kwd = ORD_KEYWORD(ord);
|
||||
const struct locale *lang = ORD_LOCALE(ord);
|
||||
const char * s;
|
||||
int result = 0;
|
||||
|
||||
switch (kwd) {
|
||||
|
@ -402,23 +407,10 @@ bool is_repeated(const order * ord)
|
|||
case K_BREED:
|
||||
case K_PIRACY:
|
||||
case K_PLANT:
|
||||
case K_MAKE:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case K_MAKE:
|
||||
/* Falls wir MACHE TEMP haben, ignorieren wir es. Alle anderen
|
||||
* Arten von MACHE zaehlen aber als neue defaults und werden
|
||||
* behandelt wie die anderen (deswegen kein break nach case
|
||||
* K_MAKE) - und in thisorder (der aktuelle 30-Tage Befehl)
|
||||
* abgespeichert). */
|
||||
parser_pushstate();
|
||||
init_tokens(ord); /* initialize token-parser */
|
||||
skip_token();
|
||||
s = getstrtoken();
|
||||
result = !isparam(s, lang, P_TEMP);
|
||||
parser_popstate();
|
||||
// TODO: push/popstate is slow, we can do better.
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
}
|
||||
|
@ -456,21 +448,10 @@ bool is_exclusive(const order * ord)
|
|||
case K_BREED:
|
||||
case K_PIRACY:
|
||||
case K_PLANT:
|
||||
case K_MAKE:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case K_MAKE:
|
||||
/* Falls wir MACHE TEMP haben, ignorieren wir es. Alle anderen
|
||||
* Arten von MACHE zaehlen aber als neue defaults und werden
|
||||
* behandelt wie die anderen (deswegen kein break nach case
|
||||
* K_MAKE) - und in thisorder (der aktuelle 30-Tage Befehl)
|
||||
* abgespeichert). */
|
||||
parser_pushstate();
|
||||
init_tokens(ord); /* initialize token-parser */
|
||||
skip_token();
|
||||
result = !isparam(getstrtoken(), lang, P_TEMP);
|
||||
parser_popstate();
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
}
|
||||
|
@ -511,20 +492,9 @@ bool is_long(const order * ord)
|
|||
case K_BREED:
|
||||
case K_PIRACY:
|
||||
case K_PLANT:
|
||||
case K_MAKE:
|
||||
return true;
|
||||
|
||||
case K_MAKE:
|
||||
/* Falls wir MACHE TEMP haben, ignorieren wir es. Alle anderen
|
||||
* Arten von MACHE zaehlen aber als neue defaults und werden
|
||||
* behandelt wie die anderen (deswegen kein break nach case
|
||||
* K_MAKE) - und in thisorder (der aktuelle 30-Tage Befehl)
|
||||
* abgespeichert). */
|
||||
parser_pushstate();
|
||||
init_tokens(ord); /* initialize token-parser */
|
||||
skip_token();
|
||||
result = !isparam(getstrtoken(), lang, P_TEMP);
|
||||
parser_popstate();
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
|
|
104
src/laws.c
104
src/laws.c
|
@ -3594,71 +3594,67 @@ void new_units(void)
|
|||
|
||||
while (*ordp) {
|
||||
order *makeord = *ordp;
|
||||
if (getkeyword(makeord) == K_MAKE) {
|
||||
init_tokens(makeord);
|
||||
skip_token();
|
||||
if (isparam(getstrtoken(), u->faction->locale, P_TEMP)) {
|
||||
const char *token;
|
||||
char *name = NULL;
|
||||
int alias;
|
||||
ship *sh;
|
||||
order **newordersp;
|
||||
int err = checkunitnumber(u->faction, 1);
|
||||
if (getkeyword(makeord) == K_MAKETEMP) {
|
||||
const char *token;
|
||||
char *name = NULL;
|
||||
int alias;
|
||||
ship *sh;
|
||||
order **newordersp;
|
||||
int err = checkunitnumber(u->faction, 1);
|
||||
|
||||
if (err) {
|
||||
if (err == 1) {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, makeord,
|
||||
"too_many_units_in_alliance",
|
||||
"allowed", maxunits(u->faction)));
|
||||
}
|
||||
else {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, makeord,
|
||||
"too_many_units_in_faction",
|
||||
"allowed", maxunits(u->faction)));
|
||||
}
|
||||
ordp = &makeord->next;
|
||||
|
||||
while (*ordp) {
|
||||
order *ord = *ordp;
|
||||
if (getkeyword(ord) == K_END)
|
||||
break;
|
||||
*ordp = ord->next;
|
||||
ord->next = NULL;
|
||||
free_order(ord);
|
||||
}
|
||||
continue;
|
||||
if (err) {
|
||||
if (err == 1) {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, makeord,
|
||||
"too_many_units_in_alliance",
|
||||
"allowed", maxunits(u->faction)));
|
||||
}
|
||||
alias = getid();
|
||||
|
||||
token = getstrtoken();
|
||||
if (token && token[0]) {
|
||||
name = _strdup(token);
|
||||
else {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, makeord,
|
||||
"too_many_units_in_faction",
|
||||
"allowed", maxunits(u->faction)));
|
||||
}
|
||||
u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u);
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
fset(u2, UFL_ISNEW);
|
||||
|
||||
a_add(&u2->attribs, a_new(&at_alias))->data.i = alias;
|
||||
sh = leftship(u);
|
||||
if (sh) {
|
||||
set_leftship(u2, sh);
|
||||
}
|
||||
setstatus(u2, u->status);
|
||||
|
||||
ordp = &makeord->next;
|
||||
newordersp = &u2->orders;
|
||||
|
||||
while (*ordp) {
|
||||
order *ord = *ordp;
|
||||
if (getkeyword(ord) == K_END)
|
||||
break;
|
||||
*ordp = ord->next;
|
||||
ord->next = NULL;
|
||||
*newordersp = ord;
|
||||
newordersp = &ord->next;
|
||||
free_order(ord);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
alias = getid();
|
||||
|
||||
token = getstrtoken();
|
||||
if (token && token[0]) {
|
||||
name = _strdup(token);
|
||||
}
|
||||
u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u);
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
fset(u2, UFL_ISNEW);
|
||||
|
||||
a_add(&u2->attribs, a_new(&at_alias))->data.i = alias;
|
||||
sh = leftship(u);
|
||||
if (sh) {
|
||||
set_leftship(u2, sh);
|
||||
}
|
||||
setstatus(u2, u->status);
|
||||
|
||||
ordp = &makeord->next;
|
||||
newordersp = &u2->orders;
|
||||
while (*ordp) {
|
||||
order *ord = *ordp;
|
||||
if (getkeyword(ord) == K_END)
|
||||
break;
|
||||
*ordp = ord->next;
|
||||
ord->next = NULL;
|
||||
*newordersp = ord;
|
||||
newordersp = &ord->next;
|
||||
}
|
||||
}
|
||||
if (*ordp == makeord)
|
||||
|
|
1304
src/study.c
1304
src/study.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue