summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/script.c')
-rw-r--r--src/map/script.c234
1 files changed, 172 insertions, 62 deletions
diff --git a/src/map/script.c b/src/map/script.c
index f842b614a..dec4a3f89 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -483,7 +483,14 @@ static void script_reportdata(struct script_data* data)
break;
case C_STR:
case C_CONSTSTR:// string
- ShowDebug("Data: string value=\"%s\"\n", data->u.str);
+ if( data->u.str )
+ {
+ ShowDebug("Data: string value=\"%s\"\n", data->u.str);
+ }
+ else
+ {
+ ShowDebug("Data: string value=NULL\n");
+ }
break;
case C_NAME:// reference
if( reference_tovariable(data) )
@@ -1253,7 +1260,9 @@ const char* parse_curly_close(const char* p)
set_label(l,script_pos, p);
linkdb_final(&syntax.curly[pos].case_label); // free the list of case label
syntax.curly_count--;
- return p+1;
+ // if, for , while の閉じ判定
+ p = parse_syntax_close(p + 1);
+ return p;
} else {
disp_error_message("parse_curly_close: unexpected string",p);
return p + 1;
@@ -1341,10 +1350,8 @@ const char* parse_syntax(const char* p)
v = p2-p; // length of word at p2
memcpy(label,p,v);
label[v]='\0';
- v = search_str(label);
- if (v < 0 || str_data[v].type != C_INT)
+ if( !script_get_constant(label, &v) )
disp_error_message("parse_syntax: 'case' label not integer",p);
- v = str_data[v].val;
p = skip_word(p);
} else { //Numeric value
if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word
@@ -1916,6 +1923,40 @@ static void add_buildin_func(void)
}
}
+/// Retrieves the value of a constant.
+bool script_get_constant(const char* name, int* value)
+{
+ int n = search_str(name);
+
+ if( n == -1 || str_data[n].type != C_INT )
+ {// not found or not a constant
+ return false;
+ }
+ value[0] = str_data[n].val;
+
+ return true;
+}
+
+/// Creates new constant or parameter with given value.
+void script_set_constant(const char* name, int value, bool isparameter)
+{
+ int n = add_str(name);
+
+ if( str_data[n].type == C_NOP )
+ {// new
+ str_data[n].type = isparameter ? C_PARAM : C_INT;
+ str_data[n].val = value;
+ }
+ else if( str_data[n].type == C_PARAM || str_data[n].type == C_INT )
+ {// existing parameter or constant
+ ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%d, new value=%d).\n", ( str_data[n].type == C_PARAM ) ? "parameter" : "constant", name, str_data[n].val, value);
+ }
+ else
+ {// existing name
+ ShowError("script_set_constant: Invalid name for %s '%s' (already defined as %s).\n", isparameter ? "parameter" : "constant", name, script_op2name(str_data[n].type));
+ }
+}
+
/*==========================================
* 定数データベースの読み込み
*------------------------------------------*/
@@ -1923,7 +1964,7 @@ static void read_constdb(void)
{
FILE *fp;
char line[1024],name[1024],val[1024];
- int n,type;
+ int type;
sprintf(line, "%s/const.txt", db_path);
fp=fopen(line, "r");
@@ -1938,12 +1979,7 @@ static void read_constdb(void)
type=0;
if(sscanf(line,"%[A-Za-z0-9_],%[-0-9xXA-Fa-f],%d",name,val,&type)>=2 ||
sscanf(line,"%[A-Za-z0-9_] %[-0-9xXA-Fa-f] %d",name,val,&type)>=2){
- n=add_str(name);
- if(type==0)
- str_data[n].type=C_INT;
- else
- str_data[n].type=C_PARAM;
- str_data[n].val= (int)strtol(val,NULL,0);
+ script_set_constant(name, (int)strtol(val, NULL, 0), (bool)type);
}
}
fclose(fp);
@@ -5336,6 +5372,7 @@ BUILDIN_FUNC(countitem)
{
int nameid, i;
int count = 0;
+ struct item_data* id = NULL;
struct script_data* data;
TBL_PC* sd = script_rid2sd(st);
@@ -5345,24 +5382,26 @@ BUILDIN_FUNC(countitem)
}
data = script_getdata(st,2);
- get_val(st,data);
- if( data_isstring(data) ) {
- const char* name = conv_str(st,data);
- struct item_data* item_data;
- if((item_data = itemdb_searchname(name)) != NULL)
- nameid = item_data->nameid;
- else
- nameid = 0;
- } else
- nameid = conv_num(st,data);
+ get_val(st, data); // convert into value in case of a variable
- if (nameid < 500) {
- ShowError("wrong item ID : countitem(%i)\n", nameid);
- script_reportsrc(st);
+ if( data_isstring(data) )
+ {// item name
+ id = itemdb_searchname(conv_str(st, data));
+ }
+ else
+ {// item id
+ id = itemdb_exists(conv_num(st, data));
+ }
+
+ if( id == NULL )
+ {
+ ShowError("buildin_countitem: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was
script_pushint(st,0);
return 1;
}
+ nameid = id->nameid;
+
for(i = 0; i < MAX_INVENTORY; i++)
if(sd->status.inventory[i].nameid == nameid)
count += sd->status.inventory[i].amount;
@@ -5379,7 +5418,8 @@ BUILDIN_FUNC(countitem2)
{
int nameid, iden, ref, attr, c1, c2, c3, c4;
int count = 0;
- int i;
+ int i;
+ struct item_data* id = NULL;
struct script_data* data;
TBL_PC* sd = script_rid2sd(st);
@@ -5387,19 +5427,27 @@ BUILDIN_FUNC(countitem2)
script_pushint(st,0);
return 0;
}
-
+
data = script_getdata(st,2);
- get_val(st,data);
- if( data_isstring(data) ) {
- const char* name = conv_str(st,data);
- struct item_data* item_data;
- if((item_data = itemdb_searchname(name)) != NULL)
- nameid = item_data->nameid;
- else
- nameid = 0;
- } else
- nameid = conv_num(st,data);
-
+ get_val(st, data); // convert into value in case of a variable
+
+ if( data_isstring(data) )
+ {// item name
+ id = itemdb_searchname(conv_str(st, data));
+ }
+ else
+ {// item id
+ id = itemdb_exists(conv_num(st, data));
+ }
+
+ if( id == NULL )
+ {
+ ShowError("buildin_countitem2: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was
+ script_pushint(st,0);
+ return 1;
+ }
+
+ nameid = id->nameid;
iden = script_getnum(st,3);
ref = script_getnum(st,4);
attr = script_getnum(st,5);
@@ -5407,13 +5455,7 @@ BUILDIN_FUNC(countitem2)
c2 = (short)script_getnum(st,7);
c3 = (short)script_getnum(st,8);
c4 = (short)script_getnum(st,9);
-
- if (nameid < 500) {
- ShowError("wrong item ID : countitem2(%i)\n", nameid);
- script_pushint(st,0);
- return 1;
- }
-
+
for(i = 0; i < MAX_INVENTORY; i++)
if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] != NULL &&
sd->status.inventory[i].amount > 0 && sd->status.inventory[i].nameid == nameid &&
@@ -5652,7 +5694,7 @@ BUILDIN_FUNC(getitem2)
if (item_data == NULL)
return -1;
if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR){
- if(ref > 10) ref = 10;
+ if(ref > MAX_REFINE) ref = MAX_REFINE;
}
else if(item_data->type==IT_PETEGG) {
iden = 1;
@@ -9089,6 +9131,11 @@ BUILDIN_FUNC(birthpet)
if( sd == NULL )
return 0;
+ if( sd->status.pet_id )
+ {// do not send egg list, when you already have a pet
+ return 0;
+ }
+
clif_sendegg(sd);
return 0;
}
@@ -9745,7 +9792,7 @@ BUILDIN_FUNC(pvpon)
return 0; // nothing to do
map[m].flag.pvp = 1;
- clif_send0199(m,1);
+ clif_map_property_mapall(m, MAPPROPERTY_FREEPVPZONE);
if(battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris]
return 0;
@@ -9790,7 +9837,7 @@ BUILDIN_FUNC(pvpoff)
return 0; //fixed Lupus
map[m].flag.pvp = 0;
- clif_send0199(m,0);
+ clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
if(battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris]
return 0;
@@ -9808,7 +9855,7 @@ BUILDIN_FUNC(gvgon)
m = map_mapname2mapid(str);
if(m >= 0 && !map[m].flag.gvg) {
map[m].flag.gvg = 1;
- clif_send0199(m,3);
+ clif_map_property_mapall(m, MAPPROPERTY_AGITZONE);
}
return 0;
@@ -9822,7 +9869,7 @@ BUILDIN_FUNC(gvgoff)
m = map_mapname2mapid(str);
if(m >= 0 && map[m].flag.gvg) {
map[m].flag.gvg = 0;
- clif_send0199(m,0);
+ clif_map_property_mapall(m, MAPPROPERTY_NOTHING);
}
return 0;
@@ -11773,17 +11820,17 @@ BUILDIN_FUNC(message)
BUILDIN_FUNC(npctalk)
{
const char* str;
- char message[255];
+ char name[NAME_LENGTH], message[256];
struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid);
str = script_getstr(st,2);
- if(nd) {
- memcpy(message, nd->name, NAME_LENGTH);
- strtok(message, "#"); // discard extra name identifier if present
- strcat(message, " : ");
- strncat(message, str, 254); //Prevent overflow possibility. [Skotlex]
- clif_message(&(nd->bl), message);
+ if(nd)
+ {
+ safestrncpy(name, nd->name, sizeof(name));
+ strtok(name, "#"); // discard extra name identifier if present
+ safesnprintf(message, sizeof(message), "%s : %s", name, str);
+ clif_message(&nd->bl, message);
}
return 0;
@@ -12357,9 +12404,20 @@ BUILDIN_FUNC(autoequip)
struct item_data *item_data;
nameid=script_getnum(st,2);
flag=script_getnum(st,3);
- if(nameid>=500 && (item_data = itemdb_exists(nameid)) != NULL){
- item_data->flag.autoequip = flag>0?1:0;
+
+ if( ( item_data = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowError("buildin_autoequip: Invalid item '%d'.\n", nameid);
+ return 1;
+ }
+
+ if( !itemdb_isequip2(item_data) )
+ {
+ ShowError("buildin_autoequip: Item '%d' cannot be equipped.\n", nameid);
+ return 1;
}
+
+ item_data->flag.autoequip = flag>0?1:0;
return 0;
}
@@ -14635,9 +14693,6 @@ static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap)
if( md->class_ != mobid )
return 0;
- if( md->ud.skilltimer != INVALID_TIMER ) // Cancel the casting skill.
- unit_skillcastcancel(bl,0);
-
// 0:self, 1:target, 2:master, default:random
switch( target )
{
@@ -14650,6 +14705,9 @@ static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap)
if( !tbl )
return 0;
+ if( md->ud.skilltimer != INVALID_TIMER ) // Cancel the casting skill.
+ unit_skillcastcancel(bl,0);
+
if( skill_get_casttype(skillid) == CAST_GROUND )
unit_skilluse_pos2(&md->bl, tbl->x, tbl->y, skillid, skilllv, casttime, cancel);
else
@@ -14756,6 +14814,56 @@ BUILDIN_FUNC(pushpc)
return 0;
}
+
+/// Invokes buying store preparation window
+/// buyingstore <slots>;
+BUILDIN_FUNC(buyingstore)
+{
+ struct map_session_data* sd;
+
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ return 0;
+ }
+
+ buyingstore_setup(sd, script_getnum(st,2));
+ return 0;
+}
+
+
+/// Invokes search store info window
+/// searchstores <uses>,<effect>;
+BUILDIN_FUNC(searchstores)
+{
+ unsigned short effect;
+ unsigned int uses;
+ struct map_session_data* sd;
+
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ return 0;
+ }
+
+ uses = script_getnum(st,2);
+ effect = script_getnum(st,3);
+
+ if( !uses )
+ {
+ ShowError("buildin_searchstores: Amount of uses cannot be zero.\n");
+ return 1;
+ }
+
+ if( effect > 1 )
+ {
+ ShowError("buildin_searchstores: Invalid effect id %hu, specified.\n", effect);
+ return 1;
+ }
+
+ searchstore_open(sd, uses, effect);
+ return 0;
+}
+
+
// declarations that were supposed to be exported from npc_chat.c
#ifdef PCRE_SUPPORT
BUILDIN_FUNC(defpattern);
@@ -15117,6 +15225,8 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(areamobuseskill,"siiiiviiiii"),
BUILDIN_DEF(progressbar,"si"),
BUILDIN_DEF(pushpc,"ii"),
+ BUILDIN_DEF(buyingstore,"i"),
+ BUILDIN_DEF(searchstores,"ii"),
// WoE SE
BUILDIN_DEF(agitstart2,""),
BUILDIN_DEF(agitend2,""),