diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-02-07 01:49:28 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-02-07 01:49:28 +0000 |
commit | 8e8f16147f2fd1b06ffd596a32beaa7d26fc32aa (patch) | |
tree | 8c40b5d049b3bd9e823fea6ad44be9127e1bffef | |
parent | d32e2b4c2c8f40f9acd6b88a45729010d758b118 (diff) | |
download | hercules-8e8f16147f2fd1b06ffd596a32beaa7d26fc32aa.tar.gz hercules-8e8f16147f2fd1b06ffd596a32beaa7d26fc32aa.tar.bz2 hercules-8e8f16147f2fd1b06ffd596a32beaa7d26fc32aa.tar.xz hercules-8e8f16147f2fd1b06ffd596a32beaa7d26fc32aa.zip |
Cleaned up the script engine's get_val() function
- changed the long if-spaghetti into a compact switch statement
- changed its behavior so that it exits if !sd and it requires one
- upon exiting, it will now ensure that meaningful values get returned (the old code would return random memory / crash)
- removed many !sd checks since they are done at the beginning now
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9812 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r-- | Changelog-Trunk.txt | 7 | ||||
-rw-r--r-- | src/map/script.c | 152 |
2 files changed, 76 insertions, 83 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index d882cd00f..fb30b9cb0 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,13 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2007/02/06 + * Cleaned up the script engine's get_val() function [ultramage] + - changed the long if-spaghetti into a compact switch statement + - changed its behavior so that it exits if !sd and it requires one + - upon exiting, it will now ensure that meaningful values get returned + (the old code had no qualms about returning random junk from memory + for integer queries, and crashing for string queries) + - removed many !sd checks since they are done at the beginning now * Fixed #lvup having the gm level check backwards. * Fixed the stormgust freeze counter going up even if the attack is blocked/cancelled. diff --git a/src/map/script.c b/src/map/script.c index b5cc1d55d..c1eec1a43 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -1886,95 +1886,81 @@ struct map_session_data *script_rid2sd(struct script_state *st) /*========================================== - * 変数の読み取り - *------------------------------------------ - */ -int get_val(struct script_state*st,struct script_data* data) + * Retrieves the value of a script variable + *------------------------------------------*/ +int get_val(struct script_state* st, struct script_data* data) { - struct map_session_data *sd=NULL; - if(data->type==C_NAME){ - char *name=str_buf+str_data[data->u.num&0x00ffffff].str; - char prefix=*name; - char postfix=name[strlen(name)-1]; - - if(not_server_variable(prefix)){ - if((sd=script_rid2sd(st))==NULL) - ShowError("get_val error name?:%s\n",name); - } - if(postfix=='$'){ - - data->type=C_CONSTSTR; - if( prefix=='@'){ - if(sd) - data->u.str = pc_readregstr(sd,data->u.num); - }else if(prefix=='$'){ - data->u.str = (char *)idb_get(mapregstr_db,data->u.num); - }else if(prefix=='#'){ - if( name[1]=='#'){ - if(sd) - data->u.str = pc_readaccountreg2str(sd,name); - }else{ - if(sd) - data->u.str = pc_readaccountregstr(sd,name); - } - }else if(prefix=='.') { - struct linkdb_node **n; - if( data->ref ) { - n = data->ref; - } else if( name[1] == '@' ) { - n = st->stack->var_function; - } else { - n = &st->script->script_vars; - } - data->u.str = linkdb_search(n, (void*)data->u.num ); - }else{ - if(sd) - data->u.str = pc_readglobalreg_str(sd,name); - } // [zBuffer] - /*else{ - ShowWarning("script: get_val: illegal scope string variable.\n"); - data->u.str = "!!ERROR!!"; - }*/ - if( data->u.str == NULL ) - data->u.str =""; + struct map_session_data* sd = NULL; + char *name, prefix, postfix; + + if(data->type != C_NAME) return 0; - }else{ + name = str_buf + str_data[data->u.num&0x00ffffff].str; + prefix = name[0]; postfix = name[strlen(name)-1]; - data->type=C_INT; - if(str_data[data->u.num&0x00ffffff].type==C_INT){ - data->u.num = str_data[data->u.num&0x00ffffff].val; - }else if(str_data[data->u.num&0x00ffffff].type==C_PARAM){ - if(sd) - data->u.num = pc_readparam(sd,str_data[data->u.num&0x00ffffff].val); - }else if(prefix=='@'){ - if(sd) - data->u.num = pc_readreg(sd,data->u.num); - }else if(prefix=='$'){ - data->u.num = (int)idb_get(mapreg_db,data->u.num); - }else if(prefix=='#'){ - if( name[1]=='#'){ - if(sd) - data->u.num = pc_readaccountreg2(sd,name); - }else{ - if(sd) - data->u.num = pc_readaccountreg(sd,name); - } - }else if(prefix=='.'){ - struct linkdb_node **n; - if( data->ref ) { - n = data->ref; - } else if( name[1] == '@' ) { - n = st->stack->var_function; - } else { - n = &st->script->script_vars; - } - data->u.num = (int)linkdb_search(n, (void*)data->u.num); - }else{ - if(sd) - data->u.num = pc_readglobalreg(sd,name); + if(not_server_variable(prefix)) { + sd = script_rid2sd(st); + if (!sd) { // needs player attached + // throw error, load some meaningful default values and return + ShowError("get_val error, cannot access player variable '%s'\n", name); + if (postfix == '$') { data->type = C_CONSTSTR; data->u.str = ""; } else { data->type = C_INT; data->u.num = 0; } + return 0; + } + } + + if(postfix == '$') { // string variable + + data->type = C_CONSTSTR; + + switch (prefix) { + case '@': + data->u.str = pc_readregstr(sd, data->u.num); break; + case '$': + data->u.str = (char *)idb_get(mapregstr_db,data->u.num); break; + case '#': + data->u.str = (name[1] == '#') ? pc_readaccountreg2str(sd, name) : pc_readaccountregstr(sd, name); break; + case '.': { + struct linkdb_node** n; + n = (data->ref) ? data->ref : (name[1] == '@') ? st->stack->var_function : &st->script->script_vars; + data->u.str = linkdb_search(n, (void*)data->u.num); + } + break; + default: + data->u.str = pc_readglobalreg_str(sd, name); break; + } + + if( data->u.str == NULL ) + data->u.str = ""; + + } else { // integer variable + + data->type = C_INT; + + if(str_data[data->u.num&0x00ffffff].type == C_INT) { + data->u.num = str_data[data->u.num&0x00ffffff].val; + } else if(str_data[data->u.num&0x00ffffff].type == C_PARAM) { + data->u.num = pc_readparam(sd, str_data[data->u.num&0x00ffffff].val); + } + else + switch (prefix) { + case '@': + data->u.num = pc_readreg(sd, data->u.num); break; + case '$': + data->u.num = (int)idb_get(mapreg_db, data->u.num); break; + case '#': + data->u.num = (name[1] == '#') ? pc_readaccountreg2(sd, name) : pc_readaccountreg(sd, name); break; + case '.': { + struct linkdb_node** n; + n = (data->ref) ? data->ref : (name[1] == '@') ? st->stack->var_function : &st->script->script_vars; + data->u.num = (int)linkdb_search(n, (void*)data->u.num); } + break; + default: + data->u.num = pc_readglobalreg(sd, name); break; } + } + return 0; } /*========================================== |