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.c443
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
}
/**