summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2013-11-07 19:47:47 +0100
committerHaru <haru@dotalux.com>2013-11-07 19:50:05 +0100
commit9f32aa958f86a228290c43544c8b9bbf3f1c2cc0 (patch)
treed757638ca65a475dbb05d0aec0b45e150072c494
parent75bbfdd137c0347155ad469d1c46f7f0a36a2579 (diff)
downloadhercules-9f32aa958f86a228290c43544c8b9bbf3f1c2cc0.tar.gz
hercules-9f32aa958f86a228290c43544c8b9bbf3f1c2cc0.tar.bz2
hercules-9f32aa958f86a228290c43544c8b9bbf3f1c2cc0.tar.xz
hercules-9f32aa958f86a228290c43544c8b9bbf3f1c2cc0.zip
Extended script constants to support NPC sprite IDs
- Added support for constants whose name begins with a number. - Follow-up to 124ab2a1cdb344f24170a4d91f7000ebabf39b40. - Replaced calls to setnpcdisplay with hardcoded numeric IDs to constants. - Thanks to Yommy. Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r--npc/custom/events/disguise.txt8
-rw-r--r--npc/events/gdevent_aru.txt14
-rw-r--r--npc/quests/newgears/2004_headgears.txt2
-rw-r--r--npc/quests/quests_rachel.txt6
-rw-r--r--npc/re/quests/quests_brasilis.txt2
-rw-r--r--npc/re/quests/quests_mora.txt4
-rw-r--r--src/map/script.c111
7 files changed, 94 insertions, 53 deletions
diff --git a/npc/custom/events/disguise.txt b/npc/custom/events/disguise.txt
index 1b46e9b16..a1d8c11c3 100644
--- a/npc/custom/events/disguise.txt
+++ b/npc/custom/events/disguise.txt
@@ -38,7 +38,7 @@ prontera,160,155,4 script Disguise Event 4_M_NFDEADMAN,{
setnpctimer 0; stopnpctimer;
announce "A GM has decided to turn the Disguise Event off. As a result no further prizes will be given.",bc_map | bc_blue;
deletepset 1;
- setnpcdisplay "Disguise Event",795;
+ setnpcdisplay "Disguise Event", 4_M_NFDEADMAN;
close;
}
set .EventON,1; set .Timer,1; setnpctimer 0; initnpctimer;
@@ -171,7 +171,7 @@ OnTimer10000:
OnTimer30000:
if (.Timer) end;
set .Change,0;
- setnpcdisplay "Disguise Event",795;
+ setnpcdisplay "Disguise Event", 4_M_NFDEADMAN;
npctalk "You took too long to guess what I was. Please wait 10 seconds while I disguise again.";
specialeffect 725;
set $MonsterName$,"";
@@ -230,13 +230,13 @@ iCorrect:
getitem .Prize,.PrizeAmt;
announce strcharinfo(0)+" is correct! I was disguised as: "+$MonsterName$+"",bc_map | bc_blue;
if (.RoundCount>=.Rounds) {
- setnpcdisplay "Disguise Event",795;
+ setnpcdisplay "Disguise Event", 4_M_NFDEADMAN;
set .RoundCount,0; set .Change,0; set .EventON,0;
setnpctimer 0; stopnpctimer;
npctalk "Thank you all for playing. That was the last round of the Disguise Event. Come play again later.";
end;
}
- setnpcdisplay "Disguise Event",795;
+ setnpcdisplay "Disguise Event", 4_M_NFDEADMAN;
set .Change,0;
setnpctimer 0;
end;
diff --git a/npc/events/gdevent_aru.txt b/npc/events/gdevent_aru.txt
index e0098bf9b..9f1a9617a 100644
--- a/npc/events/gdevent_aru.txt
+++ b/npc/events/gdevent_aru.txt
@@ -480,19 +480,19 @@ arug_que01,100,81,3 script Pierrot Pier#aru_gd 4_M_PIERROT,{
specialeffect EF_POISONHIT;
set .@sprchg_gd,rand(1,5);
if (.@sprchg_gd == 1) {
- setnpcdisplay "Pierrot Pier#aru_gd",950;
+ setnpcdisplay "Pierrot Pier#aru_gd", 4_GHOSTRING;
}
else if (.@sprchg_gd == 2) {
- setnpcdisplay "Pierrot Pier#aru_gd",715;
+ setnpcdisplay "Pierrot Pier#aru_gd", 4_M_PIERROT;
}
else if (.@sprchg_gd == 3) {
- setnpcdisplay "Pierrot Pier#aru_gd",714;
+ setnpcdisplay "Pierrot Pier#aru_gd", 4_F_06;
}
else if (.@sprchg_gd == 4) {
- setnpcdisplay "Pierrot Pier#aru_gd",785;
+ setnpcdisplay "Pierrot Pier#aru_gd", 4_M_UMDANCEKID2;
}
else {
- setnpcdisplay "Pierrot Pier#aru_gd",876;
+ setnpcdisplay "Pierrot Pier#aru_gd", 4_CAT;
}
if (checkweight(1201,1) == 0) {
mes "- Wait!! -";
@@ -506,7 +506,7 @@ arug_que01,100,81,3 script Pierrot Pier#aru_gd 4_M_PIERROT,{
if ($@gdeventv_a2 == 0) {
set .@que_2143,checkquest(2143,PLAYTIME);
if (.@que_2143 == -1) {
- setnpcdisplay "Pierrot Pier#aru_gd",715;
+ setnpcdisplay "Pierrot Pier#aru_gd", 4_M_PIERROT;
mes "A lonely clown is juggling.";
next;
mes "When looked at closely, the clown is just a puppet that looks like a human.";
@@ -845,7 +845,7 @@ arug_que01,100,81,3 script Pierrot Pier#aru_gd 4_M_PIERROT,{
}
else {
if ($@gdeventv_a2 == 0) {
- setnpcdisplay "Pierrot Pier#aru_gd",715;
+ setnpcdisplay "Pierrot Pier#aru_gd", 4_M_PIERROT;
mes "A lonely clown is juggling.";
next;
mes "When looked at closely, the clown is just a puppet that looks like a human.";
diff --git a/npc/quests/newgears/2004_headgears.txt b/npc/quests/newgears/2004_headgears.txt
index 1cfa2bc03..a6638d6a7 100644
--- a/npc/quests/newgears/2004_headgears.txt
+++ b/npc/quests/newgears/2004_headgears.txt
@@ -2034,7 +2034,7 @@ alde_alche,88,180,0 script Muscle Man#Alarm Mask 4_M_ALCHE_A,{
OnTimer4000:
specialeffect EF_FLASHER;
- setnpcdisplay "Muscle Man#Alarm Mask", 748;
+ setnpcdisplay "Muscle Man#Alarm Mask", 4_M_ALCHE_A;
disablenpc " #Alarm Mask Man1";
disablenpc " #Alarm Mask Man2";
disablenpc " #Alarm Mask Man3";
diff --git a/npc/quests/quests_rachel.txt b/npc/quests/quests_rachel.txt
index cf2e62dcb..fc96796bb 100644
--- a/npc/quests/quests_rachel.txt
+++ b/npc/quests/quests_rachel.txt
@@ -3131,7 +3131,7 @@ ice_dun02,120,105,3 script Man Stuck in Ice#cave 4_M_FROZEN1,5,5,{
mes "^3355FF*Pzzzzz*";
mes "*CRASH!*^000000";
next;
- setnpcdisplay "Man Stuck in Ice#cave",937;
+ setnpcdisplay "Man Stuck in Ice#cave", 4_M_ARUNA_NFM1;
emotion e_gasp;
mes "[Maheo]";
mes "Finally...!";
@@ -3193,7 +3193,7 @@ ice_dun02,120,105,3 script Man Stuck in Ice#cave 4_M_FROZEN1,5,5,{
getitem 7574,4; //Ice_Particle
close2;
cutin "",255;
- setnpcdisplay "Man Stuck in Ice#cave",924;
+ setnpcdisplay "Man Stuck in Ice#cave", 4_M_FROZEN1;
end;
}
@@ -7495,4 +7495,4 @@ OnTouch:
//= 2.7 Corrected overlaping warp coordinates. [L0ne_W0lf]
//= 2.8 Replaced effect numerics with constants. [L0ne_W0lf]
//= 2.9 Replaced effect numerics with constants. [Samuray22]
-//============================================================ \ No newline at end of file
+//============================================================
diff --git a/npc/re/quests/quests_brasilis.txt b/npc/re/quests/quests_brasilis.txt
index 306a19cdb..5276fafe5 100644
--- a/npc/re/quests/quests_brasilis.txt
+++ b/npc/re/quests/quests_brasilis.txt
@@ -814,7 +814,7 @@ brasilis,56,224,7 script Mage Paje#bra 4_M_BIBI,{
mes "[Mage Paje]";
mes "Abracadabra~";
specialeffect EF_POISONHIT,AREA,"Poring#bra";
- setarray .@display[0],800,876,909;
+ setarray .@display[0], 4_NFCOCK, 4_CAT, 4_PORING;
setnpcdisplay "Poring#bra",.@display[rand(3)];
if (brazil_gua != 5) close;
next;
diff --git a/npc/re/quests/quests_mora.txt b/npc/re/quests/quests_mora.txt
index 9acebd207..1d7e9bbd0 100644
--- a/npc/re/quests/quests_mora.txt
+++ b/npc/re/quests/quests_mora.txt
@@ -2461,14 +2461,14 @@ bif_fild01,132,338,3 script Lope#pa 4_M_FAIRYSOLDIER2,2,2,{
}
end;
OnEnable:
- setnpcdisplay "Lope#pa",999;
+ setnpcdisplay "Lope#pa", 4_M_MUT1;
end;
OnDisable:
disablenpc "Lope#pa";
initnpctimer;
end;
OnReset:
- setnpcdisplay "Lope#pa",461;
+ setnpcdisplay "Lope#pa", 4_M_FAIRYSOLDIER2;
enablenpc "Lope#pa";
end;
OnTimer2000:
diff --git a/src/map/script.c b/src/map/script.c
index 7a2f1f24b..b87020253 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -858,50 +858,87 @@ const char* parse_variable(const char* p) {
return p;
}
+/*
+ * Checks whether the gives string is a number literal
+ *
+ * Mainly necessary to differentiate between number literals and NPC name
+ * constants, since several of those start with a digit.
+ *
+ * All this does is to check if the string begins with an optional + or - sign,
+ * followed by a hexadecimal or decimal number literal literal and is NOT
+ * followed by a underscore or letter.
+ *
+ * @param p Pointer to the string to check
+ * @return Whether the string is a number literal
+ */
+bool is_number(const char *p) {
+ const char *np;
+ if (!p)
+ return false;
+ if (*p == '-' || *p == '+')
+ p++;
+ np = p;
+ if (*p == '0' && p[1] == 'x') {
+ p+=2;
+ np = p;
+ // Hexadecimal
+ while (ISXDIGIT(*np))
+ np++;
+ } else {
+ // Decimal
+ while (ISDIGIT(*np))
+ np++;
+ }
+ if (p != np && *np != '_' && !ISALPHA(*np)) // At least one digit, and next isn't a letter or _
+ return true;
+ return false;
+}
+
/*==========================================
* Analysis section
*------------------------------------------*/
-const char* parse_simpleexpr(const char *p)
-{
- long long i;
+const char* parse_simpleexpr(const char *p) {
+ int i;
p=script->skip_space(p);
if(*p==';' || *p==',')
disp_error_message("parse_simpleexpr: unexpected end of expression",p);
- if(*p=='('){
+ if(*p=='(') {
if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST )
++script->syntax.curly[i].count;
p=script->parse_subexpr(p+1,-1);
p=script->skip_space(p);
- if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST &&
- script->syntax.curly[i].flag == ARGLIST_UNDEFINED && --script->syntax.curly[i].count == 0
- ){
- if( *p == ',' ){
+ if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST
+ && script->syntax.curly[i].flag == ARGLIST_UNDEFINED && --script->syntax.curly[i].count == 0
+ ) {
+ if( *p == ',' ) {
script->syntax.curly[i].flag = ARGLIST_PAREN;
return p;
- } else
+ } else {
script->syntax.curly[i].flag = ARGLIST_NO_PAREN;
+ }
}
if( *p != ')' )
disp_error_message("parse_simpleexpr: unmatched ')'",p);
++p;
- } else if(ISDIGIT(*p) || ((*p=='-' || *p=='+') && ISDIGIT(p[1]))){
+ } else if(is_number(p)) {
char *np;
- while(*p == '0' && ISDIGIT(p[1])) p++;
- i=strtoll(p,&np,0);
- if( i < INT_MIN ) {
- i = INT_MIN;
+ long long lli;
+ while(*p == '0' && ISDIGIT(p[1])) p++; // Skip leading zeros, we don't support octal literals
+ lli=strtoll(p,&np,0);
+ if( lli < INT_MIN ) {
+ lli = INT_MIN;
script->disp_warning_message("parse_simpleexpr: underflow detected, capping value to INT_MIN",p);
- } else if( i > INT_MAX ) {
- i = INT_MAX;
+ } else if( lli > INT_MAX ) {
+ lli = INT_MAX;
script->disp_warning_message("parse_simpleexpr: overflow detected, capping value to INT_MAX",p);
}
- script->addi((int)i);
+ script->addi((int)lli); // Cast is safe, as it's already been checked for overflows
p=np;
- } else if(*p=='"'){
+ } else if(*p=='"') {
script->addc(C_STR);
p++;
- while( *p && *p != '"' ){
+ while( *p && *p != '"' ) {
if( (unsigned char)p[-1] <= 0x7e && *p == '\\' ) {
char buf[8];
size_t len = sv->skip_escaped_c(p) - p;
@@ -911,8 +948,9 @@ const char* parse_simpleexpr(const char *p)
p += len;
script->addb(*buf);
continue;
- } else if( *p == '\n' )
+ } else if( *p == '\n' ) {
disp_error_message("parse_simpleexpr: unexpected newline @ string",p);
+ }
script->addb(*p++);
}
if(!*p)
@@ -928,24 +966,24 @@ const char* parse_simpleexpr(const char *p)
disp_error_message("parse_simpleexpr: unexpected character",p);
l=script->add_word(p);
- if( script->str_data[l].type == C_FUNC || script->str_data[l].type == C_USERFUNC || script->str_data[l].type == C_USERFUNC_POS)
+ if( script->str_data[l].type == C_FUNC || script->str_data[l].type == C_USERFUNC || script->str_data[l].type == C_USERFUNC_POS) {
return script->parse_callfunc(p,1,0);
#ifdef SCRIPT_CALLFUNC_CHECK
- else {
+ } else {
const char* name = script->get_str(l);
if( strdb_get(script->userfunc_db,name) != NULL ) {
return script->parse_callfunc(p,1,1);
}
- }
#endif
+ }
- if( (pv = script->parse_variable(p)) )
- {// successfully processed a variable assignment
+ if( (pv = script->parse_variable(p)) ) {
+ // successfully processed a variable assignment
return pv;
}
p=script->skip_word(p);
- if( *p == '[' ){
+ if( *p == '[' ) {
// array(name[i] => getelementofarray(name,i) )
script->addl(script->buildin_getelementofarray_ref);
script->addc(C_ARG);
@@ -957,8 +995,9 @@ const char* parse_simpleexpr(const char *p)
disp_error_message("parse_simpleexpr: unmatched ']'",p);
++p;
script->addc(C_FUNC);
- }else
+ } else {
script->addl(l);
+ }
}
@@ -1229,8 +1268,16 @@ const char* parse_syntax(const char* p)
disp_error_message("parse_syntax: expect space ' '",p);
}
// check whether case label is integer or not
- v = strtol(p,&np,0);
- if(np == p) { //Check for constants
+ if(is_number(p)) {
+ //Numeric value
+ v = strtol(p,&np,0);
+ if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word
+ p++;
+ p = script->skip_word(p);
+ if(np != p)
+ disp_error_message("parse_syntax: 'case' label is not an integer",np);
+ } else {
+ //Check for constants
p2 = script->skip_word(p);
v = p2-p; // length of word at p2
memcpy(label,p,v);
@@ -1238,12 +1285,6 @@ const char* parse_syntax(const char* p)
if( !script->get_constant(label, &v) )
disp_error_message("parse_syntax: 'case' label is not an integer",p);
p = script->skip_word(p);
- } else { //Numeric value
- if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word
- p++;
- p = script->skip_word(p);
- if(np != p)
- disp_error_message("parse_syntax: 'case' label is not an integer",np);
}
p = script->skip_space(p);
if(*p != ':')