diff options
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 443 |
1 files changed, 292 insertions, 151 deletions
diff --git a/src/map/script.c b/src/map/script.c index d5cf58946..e7a0175c7 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -4,60 +4,59 @@ #define HERCULES_CORE -#include "../config/core.h" // RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL +#include "config/core.h" // RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL #include "script.h" +#include "map/atcommand.h" +#include "map/battle.h" +#include "map/battleground.h" +#include "map/channel.h" +#include "map/chat.h" +#include "map/chrif.h" +#include "map/clif.h" +#include "map/elemental.h" +#include "map/guild.h" +#include "map/homunculus.h" +#include "map/instance.h" +#include "map/intif.h" +#include "map/itemdb.h" +#include "map/log.h" +#include "map/mail.h" +#include "map/map.h" +#include "map/mapreg.h" +#include "map/mercenary.h" +#include "map/mob.h" +#include "map/npc.h" +#include "map/party.h" +#include "map/path.h" +#include "map/pc.h" +#include "map/pet.h" +#include "map/pet.h" +#include "map/quest.h" +#include "map/skill.h" +#include "map/status.h" +#include "map/status.h" +#include "map/storage.h" +#include "map/unit.h" +#include "common/cbasetypes.h" +#include "common/malloc.h" +#include "common/md5calc.h" +#include "common/mmo.h" // NEW_CARTS +#include "common/nullpo.h" +#include "common/random.h" +#include "common/showmsg.h" +#include "common/socket.h" // usage: getcharip +#include "common/strlib.h" +#include "common/sysinfo.h" +#include "common/timer.h" +#include "common/utils.h" +#include "common/HPM.h" + #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> - -#include "atcommand.h" -#include "battle.h" -#include "battleground.h" -#include "channel.h" -#include "chat.h" -#include "chrif.h" -#include "clif.h" -#include "elemental.h" -#include "guild.h" -#include "homunculus.h" -#include "instance.h" -#include "intif.h" -#include "itemdb.h" -#include "log.h" -#include "mail.h" -#include "map.h" -#include "mapreg.h" -#include "mercenary.h" -#include "mob.h" -#include "npc.h" -#include "party.h" -#include "path.h" -#include "pc.h" -#include "pet.h" -#include "pet.h" -#include "quest.h" -#include "skill.h" -#include "status.h" -#include "status.h" -#include "storage.h" -#include "unit.h" -#include "../common/cbasetypes.h" -#include "../common/malloc.h" -#include "../common/md5calc.h" -#include "../common/mmo.h" // NEW_CARTS -#include "../common/nullpo.h" -#include "../common/random.h" -#include "../common/showmsg.h" -#include "../common/socket.h" // usage: getcharip -#include "../common/strlib.h" -#include "../common/sysinfo.h" -#include "../common/timer.h" -#include "../common/utils.h" -#include "../common/HPM.h" - #ifndef WIN32 #include <sys/time.h> #endif @@ -406,7 +405,7 @@ unsigned int calc_hash_ci(const char* p) { /// Looks up string using the provided id. const char* script_get_str(int id) { - Assert( id >= LABEL_START && id < script->str_size ); + Assert_retr(NULL, id >= LABEL_START && id < script->str_size); return script->str_buf+script->str_data[id].str; } @@ -462,7 +461,7 @@ const char *script_casecheck_add_str_sub(struct casecheck_data *ccd, const char int i; for (i = ccd->str_hash[h]; ; i = ccd->str_data[i].next) { const char *s = NULL; - Assert( i >= 0 && i < ccd->str_size ); + Assert_retb(i >= 0 && i < ccd->str_size); s = ccd->str_buf+ccd->str_data[i].str; if (strcasecmp(s,p) == 0) { return s; // string already in list @@ -1295,7 +1294,8 @@ const char* parse_simpleexpr(const char *p) const char *line_start = start_point; const char *line_end = start_point; struct script_string_buf *lbuf = &script->lang_export_line_buf; - size_t line_length; + struct script_string_buf *ubuf = &script->lang_export_unescaped_buf; + size_t line_length, cursor; while( line_start > script->parser_current_src ) { if( *line_start != '\n' ) @@ -1319,6 +1319,13 @@ const char* parse_simpleexpr(const char *p) normalize_name(lbuf->ptr, "\r\n\t "); } + for(cursor = 0; cursor < sbuf->pos; cursor++) { + if( sbuf->ptr[cursor] == '"' ) + script_string_buf_addb(ubuf, '\\'); + script_string_buf_addb(ubuf, sbuf->ptr[cursor]); + } + script_string_buf_addb(ubuf, 0); + fprintf(script->lang_export_fp, "#: %s\n" "# %s\n" "msgctxt \"%s\"\n" @@ -1327,10 +1334,11 @@ const char* parse_simpleexpr(const char *p) script->parser_current_file ? script->parser_current_file : "Unknown File", lbuf->ptr, script->parser_current_npc_name ? script->parser_current_npc_name : "Unknown NPC", - sbuf->ptr + ubuf->ptr ); lbuf->pos = 0; + ubuf->pos = 0; } sbuf->pos = 0; @@ -2427,9 +2435,11 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o script->syntax.translation_db = strdb_get(script->translation_db, script->parser_current_npc_name); } - script->buf=(unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char)); + if( !script->buf ) { + script->buf = (unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char)); + script->size = SCRIPT_BLOCK_SIZE; + } script->pos=0; - script->size=SCRIPT_BLOCK_SIZE; script->parse_nextline(true, NULL); // who called parse_script is responsible for clearing the database after using it, but just in case... lets clear it here @@ -2443,10 +2453,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o if( script->error_report ) script->error(src,file,line,script->error_msg,script->error_pos); aFree( script->error_msg ); - aFree( script->buf ); script->pos = 0; - script->size = 0; - script->buf = NULL; for(i=LABEL_START;i<script->str_num;i++) if(script->str_data[i].type == C_NOP) script->str_data[i].type = C_NAME; for(i=0; i<size; i++) @@ -2468,10 +2475,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o {// does not require brackets around the script if( *p == '\0' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) ) {// empty script and can return NULL - aFree( script->buf ); script->pos = 0; - script->size = 0; - script->buf = NULL; #ifdef ENABLE_CASE_CHECK script->local_casecheck.clear(); script->parser_current_src = NULL; @@ -2491,10 +2495,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o p = script->skip_space(p+1); if( *p == '}' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) ) {// empty script and can return NULL - aFree( script->buf ); script->pos = 0; - script->size = 0; - script->buf = NULL; #ifdef ENABLE_CASE_CHECK script->local_casecheck.clear(); script->parser_current_src = NULL; @@ -2543,10 +2544,6 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o script->addc(C_NOP); - // trim code to size - script->size = script->pos; - RECREATE(script->buf,unsigned char,script->pos); - // default unknown references to variables for (i = LABEL_START; i < script->str_num; i++) { if (script->str_data[i].type == C_NOP) { @@ -2611,8 +2608,9 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o #endif CREATE(code,struct script_code,1); - code->script_buf = script->buf; - code->script_size = script->size; + code->script_buf = (unsigned char *)aMalloc(script->pos*sizeof(unsigned char)); + memcpy(code->script_buf, script->buf, script->pos); + code->script_size = script->pos; code->local.vars = NULL; code->local.arrays = NULL; #ifdef ENABLE_CASE_CHECK @@ -3397,15 +3395,13 @@ void script_free_code(struct script_code* code) { nullpo_retv(code); - if( code->instances ) + if (code->instances) script->stop_instances(code); - else { - script->free_vars(code->local.vars); - if( code->local.arrays ) - code->local.arrays->destroy(code->local.arrays,script->array_free_db); - } - aFree( code->script_buf ); - aFree( code ); + script->free_vars(code->local.vars); + if (code->local.arrays) + code->local.arrays->destroy(code->local.arrays,script->array_free_db); + aFree(code->script_buf); + aFree(code); } /// Creates a new script state. @@ -4682,6 +4678,9 @@ void script_load_translations(void) { int i, size; uint32 total = 0; uint8 lang_id = 0, k; + + if (map->minimal) // No translations in minimal mode + return; script->translation_db = strdb_alloc(DB_OPT_DUP_KEY, NAME_LENGTH*2+1); @@ -4815,6 +4814,7 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) { continue; if( strncasecmp(line,"msgctxt \"", 9) == 0 ) { + msgctxt[0] = '\0'; for(i = 9; i < len - 2; i++) { if( line[i] == '\\' && line[i+1] == '"' ) { msgctxt[cursor] = '"'; @@ -4826,6 +4826,7 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) { } msgctxt[cursor] = '\0'; } else if ( strncasecmp(line, "msgid \"", 7) == 0 ) { + msgid.pos = 0; for(i = 7; i < len - 2; i++) { if( line[i] == '\\' && line[i+1] == '"' ) { script_string_buf_addb(&msgid, '"'); @@ -4835,6 +4836,7 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) { } script_string_buf_addb(&msgid,0); } else if ( len > 9 && line[9] != '"' && strncasecmp(line, "msgstr \"",8) == 0 ) { + msgstr.pos = 0; for(i = 8; i < len - 2; i++) { if( line[i] == '\\' && line[i+1] == '"' ) { script_string_buf_addb(&msgstr, '"'); @@ -4886,7 +4888,6 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) { st->translations++; st->len += inner_len; } - msgctxt[0] = '\0'; msgid.pos = msgstr.pos = 0; translations++; @@ -4967,6 +4968,13 @@ int script_translation_db_destroyer(DBKey key, DBData *data, va_list ap) { * **/ void script_parser_clean_leftovers(void) { + + if( script->buf ) + aFree(script->buf); + + script->buf = NULL; + script->size = 0; + if( script->translation_db ) { script->translation_db->destroy(script->translation_db,script->translation_db_destroyer); script->translation_db = NULL; @@ -4979,6 +4987,7 @@ void script_parser_clean_leftovers(void) { script_string_buf_destroy(&script->parse_simpleexpr_str); script_string_buf_destroy(&script->lang_export_line_buf); + script_string_buf_destroy(&script->lang_export_unescaped_buf); } /** @@ -5672,6 +5681,13 @@ BUILDIN(getarg) /// return; /// return <value>; BUILDIN(return) { + st->state = RETFUNC; + + if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp-1].type != C_RETINFO ) { + // Incorrect usage of return outside the scope of a function or subroutine. + return true; // No need for further processing, running script is about to be aborted. + } + if( script_hasdata(st,2) ) {// return value struct script_data* data; @@ -5685,16 +5701,19 @@ BUILDIN(return) { script->get_val(st, data);// current scope, convert to value if( data->ref && data->ref->vars == st->stack->stack_data[st->stack->defsp-1].u.ri->scope.vars ) data->ref = NULL; // Reference to the parent scope, remove reference pointer - } else if( name[0] == '.' && !data->ref ) { - // script variable without a reference set, link to current script - data->ref = (struct reg_db *)aCalloc(sizeof(struct reg_db), 1); - script->add_pending_ref(st, data->ref); - data->ref->vars = st->script->local.vars; - if( !st->script->local.arrays ) - st->script->local.arrays = idb_alloc(DB_OPT_BASE); - data->ref->arrays = st->script->local.arrays; - } else if ( name[0] == '.' /* && data->ref != NULL */ ) { - data->ref = NULL; // Reference to the parent scope's script, remove reference pointer. + } else if( name[0] == '.' ) { + // npc variable + if( !data->ref ) { + // npc variable without a reference set, link to current script + data->ref = (struct reg_db *)aCalloc(sizeof(struct reg_db), 1); + script->add_pending_ref(st, data->ref); + data->ref->vars = st->script->local.vars; + if( !st->script->local.arrays ) + st->script->local.arrays = idb_alloc(DB_OPT_BASE); + data->ref->arrays = st->script->local.arrays; + } else if( data->ref->vars == st->stack->stack_data[st->stack->defsp-1].u.ri->script->local.vars ) { + data->ref = NULL; // Reference to the parent scope's script, remove reference pointer. + } } } } @@ -5702,7 +5721,7 @@ BUILDIN(return) { {// no return value script_pushnil(st); } - st->state = RETFUNC; + return true; } @@ -5744,6 +5763,7 @@ BUILDIN(warp) { int ret; int x,y; + int warp_clean = 1; const char* str; TBL_PC* sd; @@ -5755,6 +5775,11 @@ BUILDIN(warp) x = script_getnum(st,3); y = script_getnum(st,4); + if (script_hasdata(st, 5)) { + warp_clean = script_getnum(st, 5); + } + + sd->state.warp_clean = warp_clean; if(strcmp(str,"Random")==0) ret = pc->randomwarp(sd,CLR_TELEPORT); else if(strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0) @@ -7424,7 +7449,7 @@ void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, b {// delete associated pet intif->delete_petdata(MakeDWord(inv->card[1], inv->card[2])); } - pc->delitem(sd, idx, delamount, 0, 0, LOG_TYPE_SCRIPT); + pc->delitem(sd, idx, delamount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT); } amount[0]-= delamount; @@ -8085,6 +8110,23 @@ BUILDIN(strnpcinfo) { return true; } +/** + * charid2rid: Returns the RID associated to the given character ID + */ +BUILDIN(charid2rid) +{ + int cid = script_getnum(st, 2); + TBL_PC *sd = map->charid2sd(cid); + + if (sd == NULL) { + script_pushint(st, 0); + return true; + } + + script_pushint(st, sd->status.account_id); + return true; +} + /*========================================== * GetEquipID(Pos); Pos: 1-SCRIPT_EQUIP_TABLE_SIZE *------------------------------------------*/ @@ -8455,10 +8497,10 @@ BUILDIN(successrefitem) sd->status.inventory[i].refine += up; sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); - pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below + pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); // status calc will happen in pc->equipitem() below clif->refine(sd->fd,0,i,sd->status.inventory[i].refine); - clif->delitem(sd,i,1,3); + clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE); //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]); @@ -8504,10 +8546,10 @@ BUILDIN(failedrefitem) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { sd->status.inventory[i].refine = 0; - pc->unequipitem(sd,i,3); //recalculate bonus + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //recalculate bonus clif->refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); clif->misceffect(&sd->bl,2); // display failure effect } @@ -8538,12 +8580,12 @@ BUILDIN(downrefitem) //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]); - pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below + pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); // status calc will happen in pc->equipitem() below sd->status.inventory[i].refine -= down; sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); clif->refine(sd->fd,2,i,sd->status.inventory[i].refine); - clif->delitem(sd,i,1,3); + clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE); //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]); @@ -8572,8 +8614,8 @@ BUILDIN(delequip) if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { - pc->unequipitem(sd,i,3); //recalculate bonus - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //recalculate bonus + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); return true; } @@ -8829,7 +8871,7 @@ BUILDIN(autobonus3) { BUILDIN(skill) { int id; int level; - int flag = 1; + int flag = SKILL_GRANT_TEMPORARY; TBL_PC* sd; sd = script->rid2sd(st); @@ -8857,7 +8899,7 @@ BUILDIN(skill) { BUILDIN(addtoskill) { int id; int level; - int flag = 2; + int flag = SKILL_GRANT_TEMPSTACK; TBL_PC* sd; sd = script->rid2sd(st); @@ -9702,8 +9744,7 @@ BUILDIN(monster) if (script_hasdata(st, 10)) { ai = script_getnum(st, 10); - if (ai > 4) - { + if (ai > AI_FLORA) { ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_); return false; } @@ -9807,7 +9848,7 @@ BUILDIN(areamonster) { if (script_hasdata(st, 12)) { ai = script_getnum(st, 12); - if (ai > 4) { + if (ai > AI_FLORA) { ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_); return false; } @@ -10977,7 +11018,7 @@ BUILDIN(homunculus_mutate) if (m_class == HT_EVO && m_id == HT_S && sd->hd->homunculus.level >= 99 && i != INDEX_NOT_FOUND && - !pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_SCRIPT) ) { + !pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT) ) { sd->hd->homunculus.vaporize = HOM_ST_REST; // Remove morph state. homun->call(sd); // Respawn homunculus. homun->mutate(sd->hd, homun_id); @@ -11158,26 +11199,24 @@ BUILDIN(resetstatus) /*========================================== * script command resetskill *------------------------------------------*/ -BUILDIN(resetskill) -{ +BUILDIN(resetskill) { TBL_PC *sd; sd=script->rid2sd(st); if( sd == NULL ) return false; - pc->resetskill(sd,1); + pc->resetskill(sd, PCRESETSKILL_RESYNC); return true; } /*========================================== * Counts total amount of skill points. *------------------------------------------*/ -BUILDIN(skillpointcount) -{ +BUILDIN(skillpointcount) { TBL_PC *sd; sd=script->rid2sd(st); if( sd == NULL ) return false; - script_pushint(st,sd->status.skill_point + pc->resetskill(sd,2)); + script_pushint(st,sd->status.skill_point + pc->resetskill(sd, PCRESETSKILL_RECOUNT)); return true; } @@ -11219,10 +11258,10 @@ static TBL_PC *prepareChangeSex(struct script_state* st) if (sd == NULL) return NULL; - pc->resetskill(sd, 4); + pc->resetskill(sd, PCRESETSKILL_CHSEX); // to avoid any problem with equipment and invalid sex, equipment is unequiped. for (i=0; i<EQI_MAX; i++) - if (sd->equip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], 3); + if (sd->equip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); return sd; } @@ -11234,7 +11273,7 @@ BUILDIN(changesex) TBL_PC *sd = prepareChangeSex(st); if (sd == NULL) return false; - chrif->changesex(sd); + chrif->changesex(sd, true); return true; } @@ -11246,12 +11285,7 @@ BUILDIN(changecharsex) TBL_PC *sd = prepareChangeSex(st); if (sd == NULL) return false; - if (sd->status.sex == 99) - sd->status.sex = 0; - sd->status.sex = sd->status.sex ? 0 : 1; - chrif->save(sd, 0); - if (sd->fd) - clif->authfail_fd(sd->fd, 15); + chrif->changesex(sd, false); return true; } @@ -12280,7 +12314,7 @@ BUILDIN(successremovecards) for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) item_tmp.card[j]=sd->status.inventory[i].card[j]; - pc->delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_MATERIALCHANGE, LOG_TYPE_SCRIPT); if ((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { //chk if can be spawn in inventory otherwise put on floor clif->additem(sd,0,0,flag); @@ -12342,7 +12376,7 @@ BUILDIN(failedremovecards) if (cardflag == 1) { if (typefail == 0 || typefail == 2) { // destroy the item - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); } else if (typefail == 1) { // destroy the card int flag, j; @@ -12360,7 +12394,7 @@ BUILDIN(failedremovecards) for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) item_tmp.card[j]=sd->status.inventory[i].card[j]; - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { clif->additem(sd,0,0,flag); @@ -13054,7 +13088,7 @@ BUILDIN(clearitem) if(sd==NULL) return true; for (i=0; i<MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount) { - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_SCRIPT); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT); } } return true; @@ -13483,7 +13517,7 @@ BUILDIN(nude) if( sd->equip_index[ i ] >= 0 ) { if( !calcflag ) calcflag = 1; - pc->unequipitem( sd , sd->equip_index[ i ] , 2); + pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE); } } @@ -13830,7 +13864,7 @@ BUILDIN(npcstop) { if( nd ) { unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit - unit->stop_walking(&nd->bl,1|4); + unit->stop_walking(&nd->bl, STOPWALKING_FLAG_FIXPOS|STOPWALKING_FLAG_NEXTCELL); } return true; @@ -14240,11 +14274,6 @@ BUILDIN(isnight) { return true; } -BUILDIN(isday) { - script_pushint(st,(map->night_flag == 0)); - return true; -} - /*================================================ * Check how many items/cards in the list are * equipped - used for 2/15's cards patch [celest] @@ -14460,7 +14489,7 @@ BUILDIN(unequip) if (sd != NULL && num >= 1 && num <= ARRAYLENGTH(script->equip)) { int i = pc->checkequip(sd,script->equip[num-1]); if (i >= 0) - pc->unequipitem(sd,i,1|2); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } return true; } @@ -15466,8 +15495,26 @@ BUILDIN(compare) return true; } -// [zBuffer] List of mathematics commands ---> -BUILDIN(sqrt) +BUILDIN(strcmp) +{ + const char *str1 = script_getstr(st,2); + const char *str2 = script_getstr(st,3); + script_pushint(st,strcmp(str1, str2)); + return true; +} + +// List of mathematics commands ---> + +BUILDIN(log10) +{ + double i, a; + i = script_getnum(st,2); + a = log10(i); + script_pushint(st,(int)a); + return true; +} + +BUILDIN(sqrt) //[zBuffer] { double i, a; i = script_getnum(st,2); @@ -15476,7 +15523,7 @@ BUILDIN(sqrt) return true; } -BUILDIN(pow) +BUILDIN(pow) //[zBuffer] { double i, a, b; a = script_getnum(st,2); @@ -15486,7 +15533,7 @@ BUILDIN(pow) return true; } -BUILDIN(distance) +BUILDIN(distance) //[zBuffer] { int x0, y0, x1, y1; @@ -15499,7 +15546,7 @@ BUILDIN(distance) return true; } -// <--- [zBuffer] List of mathematics commands +// <--- List of mathematics commands BUILDIN(min) { @@ -16432,7 +16479,7 @@ BUILDIN(unitstop) { if( bl != NULL ) { unit->bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit unit->stop_attack(bl); - unit->stop_walking(bl,4); + unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL); if( bl->type == BL_MOB ) ((TBL_MOB*)bl)->target_id = 0; } @@ -17136,18 +17183,27 @@ BUILDIN(changequest) { BUILDIN(questactive) { struct map_session_data *sd = script->rid2sd(st); - int quest_progress = 0; + int qid, i; - if (sd == NULL) + if (sd == NULL) { + ShowError("questactive: no player attached!"); return false; + } + + qid = script_getnum(st, 2); + + ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == qid ); + + if( i >= sd->avail_quests ) { + script_pushint(st, 0); + return true; + } - if (quest->check(sd, script_getnum(st, 2), HAVEQUEST) == Q_ACTIVE) + if(sd->quest_log[i].state == Q_ACTIVE) script_pushint(st, 1); else script_pushint(st, 0); - script_pushint(st, quest_progress); - return true; } @@ -17251,7 +17307,9 @@ BUILDIN(waitingroom2bg) { return true; } + Assert_retr(false, cd->users < MAX_CHAT_USERS); n = cd->users; // This is always < MAX_CHAT_USERS + for (i = 0; i < n && i < MAX_BG_MEMBERS; i++) { struct map_session_data *sd = cd->usersd[i]; if (sd != NULL && bg->team_join(bg_id, sd)) @@ -17356,7 +17414,7 @@ BUILDIN(bg_monster_set_team) { md->bg_id = bg_id; mob_stop_attack(md); - mob_stop_walking(md, 0); + mob_stop_walking(md, STOPWALKING_FLAG_NONE); md->target_id = md->attacked_id = 0; clif->charnameack(0, &md->bl); @@ -18158,7 +18216,7 @@ BUILDIN(setcashmount) if ((sd = script->rid2sd(st)) == NULL) return true; if (pc_hasmount(sd)) { - clif->msgtable(sd->fd, 0X78b); + clif->msgtable(sd, MSG_REINS_CANT_USE_MOUNTED); script_pushint(st,0);//can't mount with one of these } else { if (sd->sc.data[SC_ALL_RIDING]) @@ -19617,6 +19675,48 @@ BUILDIN(channelmes) return true; } + +/** By Cydh +Display script message +showscript "<message>"{,<GID>}; +*/ +BUILDIN(showscript) { + struct block_list *bl = NULL; + const char *msg = script_getstr(st, 2); + int id = 0; + + if (script_hasdata(st, 3)) { + id = script_getnum(st, 3); + bl = map->id2bl(id); + } + else { + bl = st->rid ? map->id2bl(st->rid) : map->id2bl(st->oid); + } + + if (!bl) { + ShowError("buildin_showscript: Script not attached. (id=%d, rid=%d, oid=%d)\n", id, st->rid, st->oid); + script_pushint(st, 0); + return false; + } + + clif->ShowScript(bl, msg); + + script_pushint(st, 1); + + return true; +} + +BUILDIN(mergeitem) +{ + struct map_session_data *sd = script->rid2sd(st); + + if (sd == NULL) + return true; + + clif->openmergeitem(sd->fd, sd); + + return true; +} /** place holder for the translation macro **/ BUILDIN(_) { return true; @@ -19761,7 +19861,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(jobchange,"i?"), BUILDIN_DEF(jobname,"i"), BUILDIN_DEF(input,"r??"), - BUILDIN_DEF(warp,"sii"), + BUILDIN_DEF(warp,"sii?"), BUILDIN_DEF(areawarp,"siiiisii??"), BUILDIN_DEF(warpchar,"siii"), // [LuzZza] BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X] @@ -19807,6 +19907,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(getguildmember,"i?"), BUILDIN_DEF(strcharinfo,"i"), BUILDIN_DEF(strnpcinfo,"i"), + BUILDIN_DEF(charid2rid,"i"), BUILDIN_DEF(getequipid,"i"), BUILDIN_DEF(getequipname,"i"), BUILDIN_DEF(getbrokenid,"i"), // [Valaris] @@ -19997,7 +20098,6 @@ void script_parse_builtin(void) { BUILDIN_DEF(logmes,"s"), //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus] BUILDIN_DEF(summon,"si??"), // summons a slave monster [Celest] BUILDIN_DEF(isnight,""), // check whether it is night time [Celest] - BUILDIN_DEF_DEPRECATED(isday,""), // check whether it is day time [Celest] // DEPRECATED 2015-01-21 [Haru] BUILDIN_DEF(isequipped,"i*"), // check whether another item/card has been equipped [Celest] BUILDIN_DEF(isequippedcnt,"i*"), // check how many items/cards are being equipped [Celest] BUILDIN_DEF(cardscnt,"i*"), // check how many items/cards are being equipped in the same arm [Lupus] @@ -20040,14 +20140,16 @@ void script_parse_builtin(void) { BUILDIN_DEF(countstr,"ss?"), BUILDIN_DEF(setnpcdisplay,"sv??"), BUILDIN_DEF(compare,"ss"), // Lordalfa - To bring strstr to scripting Engine. + BUILDIN_DEF(strcmp,"ss"), BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item - // [zBuffer] List of mathematics commands ---> - BUILDIN_DEF(sqrt,"i"), - BUILDIN_DEF(pow,"ii"), - BUILDIN_DEF(distance,"iiii"), - // <--- [zBuffer] List of mathematics commands + // List of mathematics commands ---> + BUILDIN_DEF(log10,"i"), + BUILDIN_DEF(sqrt,"i"), //[zBuffer] + BUILDIN_DEF(pow,"ii"), //[zBuffer] + BUILDIN_DEF(distance,"iiii"), //[zBuffer] + // <--- List of mathematics commands BUILDIN_DEF(min, "i*"), BUILDIN_DEF(max, "i*"), BUILDIN_DEF(md5,"s"), @@ -20175,7 +20277,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(makerune,"i"), BUILDIN_DEF(hascashmount,""),//[Ind] BUILDIN_DEF(setcashmount,""),//[Ind] - BUILDIN_DEF(checkre,"i"), + BUILDIN_DEF_DEPRECATED(checkre,"i"), // Deprecated 2015-05-08 [Haru] /** * rAthena and beyond! **/ @@ -20252,6 +20354,8 @@ void script_parse_builtin(void) { BUILDIN_DEF(shopcount, "i"), BUILDIN_DEF(channelmes, "ss"), + BUILDIN_DEF(showscript, "s?"), + BUILDIN_DEF(mergeitem,""), BUILDIN_DEF(_,"s"), }; int i, len = ARRAYLENGTH(BUILDIN); @@ -20357,6 +20461,43 @@ void script_hardcoded_constants(void) { script->set_constant("BG_AREA",BG_AREA,false); script->set_constant("BG_AREA_WOS",BG_AREA_WOS,false); script->set_constant("BG_QUEUE",BG_QUEUE,false); + + /* Renewal */ +#ifdef RENEWAL + script->set_constant("RENEWAL", 1, false); +#else + script->set_constant("RENEWAL", 0, false); +#endif +#ifdef RENEWAL_CAST + script->set_constant("RENEWAL_CAST", 1, false); +#else + script->set_constant("RENEWAL_CAST", 0, false); +#endif +#ifdef RENEWAL_DROP + script->set_constant("RENEWAL_DROP", 1, false); +#else + script->set_constant("RENEWAL_DROP", 0, false); +#endif +#ifdef RENEWAL_EXP + script->set_constant("RENEWAL_EXP", 1, false); +#else + script->set_constant("RENEWAL_EXP", 0, false); +#endif +#ifdef RENEWAL_LVDMG + script->set_constant("RENEWAL_LVDMG", 1, false); +#else + script->set_constant("RENEWAL_LVDMG", 0, false); +#endif +#ifdef RENEWAL_EDP + script->set_constant("RENEWAL_EDP", 1, false); +#else + script->set_constant("RENEWAL_EDP", 0, false); +#endif +#ifdef RENEWAL_ASPD + script->set_constant("RENEWAL_ASPD", 1, false); +#else + script->set_constant("RENEWAL_ASPD", 0, false); +#endif } /** |