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.c7315
1 files changed, 5918 insertions, 1397 deletions
diff --git a/src/map/script.c b/src/map/script.c
index 48c377d24..841e21169 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2016 Hercules Dev Team
+ * Copyright (C) 2012-2018 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -29,7 +29,9 @@
#include "map/channel.h"
#include "map/chat.h"
#include "map/chrif.h"
+#include "map/clan.h"
#include "map/clif.h"
+#include "map/date.h"
#include "map/elemental.h"
#include "map/guild.h"
#include "map/homunculus.h"
@@ -41,6 +43,7 @@
#include "map/map.h"
#include "map/mapreg.h"
#include "map/mercenary.h"
+#include "map/messages.h"
#include "map/mob.h"
#include "map/npc.h"
#include "map/party.h"
@@ -54,6 +57,7 @@
#include "map/status.h"
#include "map/storage.h"
#include "map/unit.h"
+#include "map/achievement.h"
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/db.h"
@@ -80,7 +84,7 @@
#include <sys/time.h>
#endif
-struct script_interface script_s;
+static struct script_interface script_s;
struct script_interface *script;
static inline int GETVALUE(const struct script_buf *buf, int i) __attribute__((nonnull (1)));
@@ -100,7 +104,8 @@ static inline void SETVALUE(struct script_buf *buf, int i, int n)
VECTOR_INDEX(*buf, i+2) = GetByte(n, 2);
}
-const char* script_op2name(int op) {
+const char *script_op2name(int op)
+{
#define RETURN_OP_NAME(type) case type: return #type
switch( op ) {
RETURN_OP_NAME(C_NOP);
@@ -136,6 +141,7 @@ const char* script_op2name(int op) {
RETURN_OP_NAME(C_ADD);
RETURN_OP_NAME(C_SUB);
RETURN_OP_NAME(C_MUL);
+ RETURN_OP_NAME(C_POW);
RETURN_OP_NAME(C_DIV);
RETURN_OP_NAME(C_MOD);
RETURN_OP_NAME(C_NEG);
@@ -158,7 +164,7 @@ const char* script_op2name(int op) {
}
#ifdef SCRIPT_DEBUG_DUMP_STACK
-static void script_dump_stack(struct script_state* st)
+static void script_dump_stack(struct script_state *st)
{
int i;
nullpo_retv(st);
@@ -201,7 +207,8 @@ static void script_dump_stack(struct script_state* st)
#endif
/// Reports on the console the src of a script error.
-void script_reportsrc(struct script_state *st) {
+static void script_reportsrc(struct script_state *st)
+{
struct block_list* bl;
nullpo_retv(st);
@@ -232,7 +239,7 @@ void script_reportsrc(struct script_state *st) {
}
/// Reports on the console information about the script data.
-void script_reportdata(struct script_data* data)
+static void script_reportdata(struct script_data *data)
{
if( data == NULL )
return;
@@ -274,7 +281,7 @@ void script_reportdata(struct script_data* data)
}
/// Reports on the console information about the current built-in function.
-void script_reportfunc(struct script_state* st)
+static void script_reportfunc(struct script_state *st)
{
int params, id;
struct script_data* data;
@@ -309,8 +316,9 @@ void script_reportfunc(struct script_state* st)
/*==========================================
* Output error message
*------------------------------------------*/
-static void disp_error_message2(const char *mes,const char *pos,int report) __attribute__((nonnull (1))) analyzer_noreturn;
-static void disp_error_message2(const char *mes,const char *pos,int report) {
+static void disp_error_message2(const char *mes, const char *pos, int report) __attribute__((nonnull (1))) analyzer_noreturn;
+static void disp_error_message2(const char *mes, const char *pos, int report)
+{
script->error_msg = aStrdup(mes);
script->error_pos = pos;
script->error_report = report;
@@ -318,12 +326,13 @@ static void disp_error_message2(const char *mes,const char *pos,int report) {
}
#define disp_error_message(mes,pos) (disp_error_message2((mes),(pos),1))
-void disp_warning_message(const char *mes, const char *pos) {
+static void disp_warning_message(const char *mes, const char *pos)
+{
script->warning(script->parser_current_src,script->parser_current_file,script->parser_current_line,mes,pos);
}
/// Checks event parameter validity
-void check_event(struct script_state *st, const char *evt)
+static void check_event(struct script_state *st, const char *evt)
{
if( evt && evt[0] && !stristr(evt, "::On") )
{
@@ -335,7 +344,8 @@ void check_event(struct script_state *st, const char *evt)
/*==========================================
* Hashes the input string
*------------------------------------------*/
-unsigned int calc_hash(const char* p) {
+static unsigned int calc_hash(const char *p)
+{
unsigned int h;
nullpo_ret(p);
@@ -370,7 +380,8 @@ unsigned int calc_hash(const char* p) {
/*==========================================
* Hashes the input string in a case insensitive way
*------------------------------------------*/
-unsigned int calc_hash_ci(const char* p) {
+static unsigned int calc_hash_ci(const char *p)
+{
unsigned int h = 0;
#ifdef ENABLE_CASE_CHECK
@@ -409,14 +420,14 @@ unsigned int calc_hash_ci(const char* p) {
*------------------------------------------*/
/// Looks up string using the provided id.
-const char* script_get_str(int id)
+static const char *script_get_str(int id)
{
Assert_retr(NULL, id >= LABEL_START && id < script->str_size);
return script->str_buf+script->str_data[id].str;
}
/// Returns the uid of the string, or -1.
-int script_search_str(const char* p)
+static int script_search_str(const char *p)
{
int i;
@@ -429,7 +440,7 @@ int script_search_str(const char* p)
return -1;
}
-void script_casecheck_clear_sub(struct casecheck_data *ccd)
+static void script_casecheck_clear_sub(struct casecheck_data *ccd)
{
#ifdef ENABLE_CASE_CHECK
nullpo_retv(ccd);
@@ -449,15 +460,17 @@ void script_casecheck_clear_sub(struct casecheck_data *ccd)
#endif // ENABLE_CASE_CHECK
}
-void script_global_casecheck_clear(void) {
+static void script_global_casecheck_clear(void)
+{
script_casecheck_clear_sub(&script->global_casecheck);
}
-void script_local_casecheck_clear(void) {
+static void script_local_casecheck_clear(void)
+{
script_casecheck_clear_sub(&script->local_casecheck);
}
-const char *script_casecheck_add_str_sub(struct casecheck_data *ccd, const char *p)
+static const char *script_casecheck_add_str_sub(struct casecheck_data *ccd, const char *p)
{
#ifdef ENABLE_CASE_CHECK
int len;
@@ -514,17 +527,19 @@ const char *script_casecheck_add_str_sub(struct casecheck_data *ccd, const char
return NULL;
}
-const char *script_global_casecheck_add_str(const char *p) {
+static const char *script_global_casecheck_add_str(const char *p)
+{
return script_casecheck_add_str_sub(&script->global_casecheck, p);
}
-const char *script_local_casecheck_add_str(const char *p) {
+static const char *script_local_casecheck_add_str(const char *p)
+{
return script_casecheck_add_str_sub(&script->local_casecheck, p);
}
/// Stores a copy of the string and returns its id.
/// If an identical string is already present, returns its id instead.
-int script_add_str(const char* p)
+static int script_add_str(const char *p)
{
int len, h = script->calc_hash(p);
#ifdef ENABLE_CASE_CHECK
@@ -598,12 +613,24 @@ int script_add_str(const char* p)
return script->str_num++;
}
+static int script_add_variable(const char *varname)
+{
+ int key = script->search_str(varname);
+
+ if (key < 0) {
+ key = script->add_str(varname);
+ script->str_data[key].type = C_NAME;
+ }
+
+ return key;
+}
+
/**
* Appends 1 byte to the script buffer.
*
* @param a The byte to append.
*/
-void add_scriptb(int a)
+static void add_scriptb(int a)
{
VECTOR_ENSURE(script->buf, 1, SCRIPT_BLOCK_SIZE);
VECTOR_PUSH(script->buf, (uint8)a);
@@ -618,7 +645,7 @@ void add_scriptb(int a)
*
* @param a The value to append.
*/
-void add_scriptc(int a)
+static void add_scriptc(int a)
{
while( a >= 0x40 )
{
@@ -638,7 +665,7 @@ void add_scriptc(int a)
*
* @param a The value to append.
*/
-void add_scripti(int a)
+static void add_scripti(int a)
{
while( a >= 0x40 )
{
@@ -653,7 +680,7 @@ void add_scripti(int a)
*
* @param l The id of the script->str_data entry (Maximum up to 16M)
*/
-void add_scriptl(int l)
+static void add_scriptl(int l)
{
int backpatch = script->str_data[l].backpatch;
@@ -691,7 +718,7 @@ void add_scriptl(int l)
/*==========================================
* Resolve the label
*------------------------------------------*/
-void set_label(int l,int pos, const char* script_pos)
+static void set_label(int l, int pos, const char *script_pos)
{
int i;
@@ -715,7 +742,7 @@ void set_label(int l,int pos, const char* script_pos)
}
/// Skips spaces and/or comments.
-const char* script_skip_space(const char* p)
+static const char *script_skip_space(const char *p)
{
if( p == NULL )
return NULL;
@@ -754,7 +781,7 @@ const char* script_skip_space(const char* p)
/// Skips a word.
/// A word consists of undercores and/or alphanumeric characters,
/// and valid variable prefixes/postfixes.
-const char* skip_word(const char* p)
+static const char *skip_word(const char *p)
{
nullpo_retr(NULL, p);
// prefix
@@ -783,7 +810,8 @@ const char* skip_word(const char* p)
/// Adds a word to script->str_data.
/// @see skip_word
/// @see script->add_str
-int add_word(const char* p) {
+static int add_word(const char *p)
+{
size_t len;
int i;
@@ -809,8 +837,7 @@ int add_word(const char* p) {
/// Parses a function call.
/// The argument list can have parenthesis or not.
/// The number of arguments is checked.
-static
-const char* parse_callfunc(const char* p, int require_paren, int is_custom)
+static const char *parse_callfunc(const char *p, int require_paren, int is_custom)
{
const char *p2;
char *arg = NULL;
@@ -941,7 +968,7 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom)
/// Processes end of logical script line.
/// @param first When true, only fix up scheduling data is initialized
/// @param p Script position for error reporting in set_label
-void parse_nextline(bool first, const char* p)
+static void parse_nextline(bool first, const char *p)
{
if( !first )
{
@@ -959,7 +986,7 @@ void parse_nextline(bool first, const char* p)
* Pushes a variable into stack, processing its array index if needed.
* @see parse_variable
*/
-void parse_variable_sub_push(int word, const char *p2)
+static void parse_variable_sub_push(int word, const char *p2)
{
if( p2 ) {
const char* p3 = NULL;
@@ -990,7 +1017,7 @@ void parse_variable_sub_push(int word, const char *p2)
/// Parse a variable assignment using the direct equals operator
/// @param p script position where the function should run from
/// @return NULL if not a variable assignment, the new position otherwise
-const char* parse_variable(const char* p)
+static const char *parse_variable(const char *p)
{
int word;
c_op type = C_NOP;
@@ -1035,6 +1062,7 @@ const char* parse_variable(const char* p)
|| ( p[0] == '|' && p[1] == '=' && (type = C_OR, true) ) // |=
|| ( p[0] == '&' && p[1] == '=' && (type = C_AND, true) ) // &=
|| ( p[0] == '*' && p[1] == '=' && (type = C_MUL, true) ) // *=
+ || ( p[0] == '*' && p[1] == '*' && p[2] == '=' && (type = C_POW, true) ) // **=
|| ( p[0] == '/' && p[1] == '=' && (type = C_DIV, true) ) // /=
|| ( p[0] == '%' && p[1] == '=' && (type = C_MOD, true) ) // %=
|| ( p[0] == '+' && p[1] == '+' && (type = C_ADD_POST, true) ) // post ++
@@ -1058,6 +1086,7 @@ const char* parse_variable(const char* p)
case C_L_SHIFT: // <<=
case C_R_SHIFT: // >>=
+ case C_POW: // **=
p = script->skip_space( &p[3] );
break;
@@ -1144,7 +1173,8 @@ const char* parse_variable(const char* p)
* @param p Pointer to the string to check
* @return Whether the string is a number literal
*/
-bool is_number(const char *p) {
+static bool is_number(const char *p)
+{
const char *np;
if (!p)
return false;
@@ -1175,7 +1205,7 @@ bool is_number(const char *p) {
* @param str The string to insert.
* @return the string position in the script string list.
*/
-int script_string_dup(char *str)
+static int script_string_dup(char *str)
{
int len;
int pos = script->string_list_pos;
@@ -1197,7 +1227,7 @@ int script_string_dup(char *str)
/*==========================================
* Analysis section
*------------------------------------------*/
-const char *parse_simpleexpr(const char *p)
+static const char *parse_simpleexpr(const char *p)
{
p=script->skip_space(p);
@@ -1215,7 +1245,7 @@ const char *parse_simpleexpr(const char *p)
}
}
-const char *parse_simpleexpr_paren(const char *p)
+static const char *parse_simpleexpr_paren(const char *p)
{
int i = script->syntax.curly_count - 1;
nullpo_retr(NULL, p);
@@ -1242,7 +1272,7 @@ const char *parse_simpleexpr_paren(const char *p)
return p + 1;
}
-const char *parse_simpleexpr_number(const char *p)
+static const char *parse_simpleexpr_number(const char *p)
{
char *np = NULL;
long long lli;
@@ -1264,7 +1294,7 @@ const char *parse_simpleexpr_number(const char *p)
return np;
}
-const char *parse_simpleexpr_string(const char *p)
+static const char *parse_simpleexpr_string(const char *p)
{
const char *start_point = p;
@@ -1305,7 +1335,7 @@ const char *parse_simpleexpr_string(const char *p)
return p;
}
-const char *parse_simpleexpr_name(const char *p)
+static const char *parse_simpleexpr_name(const char *p)
{
int l;
const char *pv = NULL;
@@ -1348,6 +1378,11 @@ const char *parse_simpleexpr_name(const char *p)
disp_error_message("parse_simpleexpr: unmatched ']'", p);
++p;
script->addc(C_FUNC);
+ } else if (script->str_data[l].type == C_INT) {
+ script->addc(C_NAME);
+ script->addb(l);
+ script->addb(l >> 8);
+ script->addb(l >> 16);
} else {
script->addl(l);
}
@@ -1355,7 +1390,7 @@ const char *parse_simpleexpr_name(const char *p)
return p;
}
-void script_add_translatable_string(const struct script_string_buf *string, const char *start_point)
+static void script_add_translatable_string(const struct script_string_buf *string, const char *start_point)
{
struct string_translation *st = NULL;
@@ -1395,7 +1430,7 @@ void script_add_translatable_string(const struct script_string_buf *string, cons
/*==========================================
* Analysis of the expression
*------------------------------------------*/
-const char* script_parse_subexpr(const char* p,int limit)
+static const char *script_parse_subexpr(const char *p, int limit)
{
int op,opl,len;
@@ -1422,8 +1457,9 @@ const char* script_parse_subexpr(const char* p,int limit)
p=script->skip_space(p);
while((
(op=C_OP3, opl=0, len=1,*p=='?') // ?:
- || (op=C_ADD, opl=9, len=1,*p=='+') // +
- || (op=C_SUB, opl=9, len=1,*p=='-') // -
+ || (op=C_ADD, opl=9, len=1,*p=='+' && p[1]!='+') // +
+ || (op=C_SUB, opl=9, len=1,*p=='-' && p[1]!='-') // -
+ || (op=C_POW, opl=11,len=2,*p=='*' && p[1]=='*') // **
|| (op=C_MUL, opl=10,len=1,*p=='*') // *
|| (op=C_DIV, opl=10,len=1,*p=='/') // /
|| (op=C_MOD, opl=10,len=1,*p=='%') // %
@@ -1463,7 +1499,7 @@ const char* script_parse_subexpr(const char* p,int limit)
/*==========================================
* Evaluation of the expression
*------------------------------------------*/
-const char* parse_expr(const char *p)
+static const char *parse_expr(const char *p)
{
nullpo_retr(NULL, p);
switch(*p) {
@@ -1478,7 +1514,7 @@ const char* parse_expr(const char *p)
/*==========================================
* Analysis of the line
*------------------------------------------*/
-const char* parse_line(const char* p)
+static const char *parse_line(const char *p)
{
const char* p2;
@@ -1541,7 +1577,7 @@ const char* parse_line(const char* p)
}
// { ... } Closing process
-const char* parse_curly_close(const char* p)
+static const char *parse_curly_close(const char *p)
{
nullpo_retr(NULL, p);
if(script->syntax.curly_count <= 0) {
@@ -1600,7 +1636,7 @@ const char* parse_curly_close(const char* p)
// Syntax-related processing
// break, case, continue, default, do, for, function,
// if, switch, while ? will handle this internally.
-const char* parse_syntax(const char* p)
+static const char *parse_syntax(const char *p)
{
const char *p2 = script->skip_word(p);
@@ -2030,7 +2066,8 @@ const char* parse_syntax(const char* p)
return NULL;
}
-const char* parse_syntax_close(const char *p) {
+static const char *parse_syntax_close(const char *p)
+{
// If (...) for (...) hoge (); as to make sure closed closed once again
int flag;
@@ -2044,7 +2081,7 @@ const char* parse_syntax_close(const char *p) {
// Close judgment if, for, while, of do
// flag == 1 : closed
// flag == 0 : not closed
-const char* parse_syntax_close_sub(const char* p,int* flag)
+static const char *parse_syntax_close_sub(const char *p, int *flag)
{
char label[256];
int pos = script->syntax.curly_count - 1;
@@ -2217,7 +2254,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
}
/// Retrieves the value of a constant.
-bool script_get_constant(const char* name, int* value)
+static bool script_get_constant(const char *name, int *value)
{
int n = script->search_str(name);
@@ -2235,11 +2272,11 @@ bool script_get_constant(const char* name, int* value)
}
/// Creates new constant or parameter with given value.
-void script_set_constant(const char *name, int value, bool is_parameter, bool is_deprecated)
+static void script_set_constant(const char *name, int value, bool is_parameter, bool is_deprecated)
{
int n = script->add_str(name);
- if( script->str_data[n].type == C_NOP ) {// new
+ if (script->str_data[n].type == C_NOP) {
script->str_data[n].type = is_parameter ? C_PARAM : C_INT;
script->str_data[n].val = value;
script->str_data[n].deprecated = is_deprecated ? 1 : 0;
@@ -2250,7 +2287,7 @@ void script_set_constant(const char *name, int value, bool is_parameter, bool is
}
}
/* adds data to a existent constant in the database, inserted normally via parse */
-void script_set_constant2(const char *name, int value, bool is_parameter, bool is_deprecated)
+static void script_set_constant2(const char *name, int value, bool is_parameter, bool is_deprecated)
{
int n = script->add_str(name);
@@ -2283,7 +2320,7 @@ void script_set_constant2(const char *name, int value, bool is_parameter, bool i
/**
* Loads the constants database from constants.conf
*/
-void read_constdb(void)
+static void read_constdb(bool reload)
{
struct config_t constants_conf;
char filepath[256];
@@ -2291,7 +2328,7 @@ void read_constdb(void)
struct config_setting_t *t;
int i = 0;
- snprintf(filepath, 256, "%s/constants.conf", map->db_path);
+ safesnprintf(filepath, 256, "%s/constants.conf", map->db_path);
if (!libconfig->load_file(&constants_conf, filepath))
return;
@@ -2302,7 +2339,6 @@ void read_constdb(void)
}
while ((t = libconfig->setting_get_elem(cdb, i++))) {
- bool is_parameter = false;
bool is_deprecated = false;
int value = 0;
const char *name = config_setting_name(t);
@@ -2333,10 +2369,6 @@ void read_constdb(void)
continue;
}
value = i32;
- if (libconfig->setting_lookup_bool(t, "Parameter", &i32)) {
- if (i32 != 0)
- is_parameter = true;
- }
if (libconfig->setting_lookup_bool(t, "Deprecated", &i32)) {
if (i32 != 0)
is_deprecated = true;
@@ -2344,9 +2376,13 @@ void read_constdb(void)
} else {
value = libconfig->setting_get_int(t);
}
- if (is_parameter)
- ShowWarning("read_constdb: Defining parameters in the constants configuration is deprecated and will no longer be possible in a future version. Parameters should be defined in source. (parameter = '%s')\n", name);
- script->set_constant(name, value, is_parameter, is_deprecated);
+
+ if (reload) {
+ int n = script->add_str(name);
+ script->str_data[n].type = C_NOP; // ensures it will be overwritten
+ }
+
+ script->set_constant(name, value, false, is_deprecated);
}
script->constdb_comment(NULL);
libconfig->destroy(&constants_conf);
@@ -2359,12 +2395,12 @@ void read_constdb(void)
*
* @param comment The comment to set (NULL to unset)
*/
-void script_constdb_comment(const char *comment)
+static void script_constdb_comment(const char *comment)
{
(void)comment;
}
-void script_load_parameters(void)
+static void script_load_parameters(void)
{
int i = 0;
struct {
@@ -2384,6 +2420,7 @@ void script_load_parameters(void)
{"SkillPoint", SP_SKILLPOINT},
{"Class", SP_CLASS},
{"Zeny", SP_ZENY},
+ {"BankVault", SP_BANKVAULT},
{"Sex", SP_SEX},
{"NextBaseExp", SP_NEXTBASEEXP},
{"NextJobExp", SP_NEXTJOBEXP},
@@ -2418,7 +2455,7 @@ void script_load_parameters(void)
/*==========================================
* Display emplacement line of script
*------------------------------------------*/
-const char* script_print_line(StringBuf* buf, const char* p, const char* mark, int line)
+static const char *script_print_line(StringBuf *buf, const char *p, const char *mark, int line)
{
int i, mark_pos = 0, tabstop = TAB_SIZE;
if( p == NULL || !p[0] ) return NULL;
@@ -2457,7 +2494,8 @@ const char* script_print_line(StringBuf* buf, const char* p, const char* mark, i
#undef update_tabstop
#define CONTEXTLINES 3
-void script_errorwarning_sub(StringBuf *buf, const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos) {
+static void script_errorwarning_sub(StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos)
+{
// Find the line where the error occurred
int j;
int line = start_line;
@@ -2493,7 +2531,8 @@ void script_errorwarning_sub(StringBuf *buf, const char* src, const char* file,
}
#undef CONTEXTLINES
-void script_error(const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos) {
+static void script_error(const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos)
+{
StringBuf buf;
StrBuf->Init(&buf);
@@ -2505,7 +2544,8 @@ void script_error(const char* src, const char* file, int start_line, const char*
StrBuf->Destroy(&buf);
}
-void script_warning(const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos) {
+static void script_warning(const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos)
+{
StringBuf buf;
StrBuf->Init(&buf);
@@ -2519,7 +2559,8 @@ void script_warning(const char* src, const char* file, int start_line, const cha
/*==========================================
* Analysis of the script
*------------------------------------------*/
-struct script_code* parse_script(const char *src,const char *file,int line,int options, int *retval) {
+static struct script_code *parse_script(const char *src, const char *file, int line, int options, int *retval)
+{
const char *p,*tmpp;
int i;
struct script_code* code = NULL;
@@ -2733,7 +2774,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
/// Returns the player attached to this script, identified by the rid.
/// If there is no player attached, the script is terminated.
-struct map_session_data *script_rid2sd(struct script_state *st)
+static struct map_session_data *script_rid2sd(struct script_state *st)
{
struct map_session_data *sd;
nullpo_retr(NULL, st);
@@ -2746,7 +2787,7 @@ struct map_session_data *script_rid2sd(struct script_state *st)
return sd;
}
-struct map_session_data *script_id2sd(struct script_state *st, int account_id)
+static struct map_session_data *script_id2sd(struct script_state *st, int account_id)
{
struct map_session_data *sd;
if ((sd = map->id2sd(account_id)) == NULL) {
@@ -2757,7 +2798,7 @@ struct map_session_data *script_id2sd(struct script_state *st, int account_id)
return sd;
}
-struct map_session_data *script_charid2sd(struct script_state *st, int char_id)
+static struct map_session_data *script_charid2sd(struct script_state *st, int char_id)
{
struct map_session_data *sd;
if ((sd = map->charid2sd(char_id)) == NULL) {
@@ -2768,7 +2809,7 @@ struct map_session_data *script_charid2sd(struct script_state *st, int char_id)
return sd;
}
-struct map_session_data *script_nick2sd(struct script_state *st, const char *name)
+static struct map_session_data *script_nick2sd(struct script_state *st, const char *name)
{
struct map_session_data *sd;
if ((sd = map->nick2sd(name)) == NULL) {
@@ -2779,14 +2820,25 @@ struct map_session_data *script_nick2sd(struct script_state *st, const char *nam
return sd;
}
-char *get_val_npcscope_str(struct script_state* st, struct reg_db *n, struct script_data* data) {
+static char *get_val_npcscope_str(struct script_state *st, struct reg_db *n, struct script_data *data)
+{
if (n)
return (char*)i64db_get(n->vars, reference_getuid(data));
else
return NULL;
}
-char *get_val_instance_str(struct script_state* st, const char* name, struct script_data* data) {
+static char *get_val_pc_ref_str(struct script_state *st, struct reg_db *n, struct script_data *data)
+{
+ struct script_reg_str *p = NULL;
+ nullpo_retr(NULL, n);
+
+ p = i64db_get(n->vars, reference_getuid(data));
+ return p ? p->value : NULL;
+}
+
+static char *get_val_instance_str(struct script_state *st, const char *name, struct script_data *data)
+{
nullpo_retr(NULL, st);
if (st->instance_id >= 0) {
return (char*)i64db_get(instance->list[st->instance_id].regs.vars, reference_getuid(data));
@@ -2796,14 +2848,25 @@ char *get_val_instance_str(struct script_state* st, const char* name, struct scr
}
}
-int get_val_npcscope_num(struct script_state* st, struct reg_db *n, struct script_data* data) {
+static int get_val_npcscope_num(struct script_state *st, struct reg_db *n, struct script_data *data)
+{
if (n)
return (int)i64db_iget(n->vars, reference_getuid(data));
else
return 0;
}
-int get_val_instance_num(struct script_state* st, const char* name, struct script_data* data) {
+static int get_val_pc_ref_num(struct script_state *st, struct reg_db *n, struct script_data *data)
+{
+ struct script_reg_num *p = NULL;
+ nullpo_retr(0, n);
+
+ p = i64db_get(n->vars, reference_getuid(data));
+ return p ? p->value : 0;
+}
+
+static int get_val_instance_num(struct script_state *st, const char *name, struct script_data *data)
+{
if (st->instance_id >= 0)
return (int)i64db_iget(instance->list[st->instance_id].regs.vars, reference_getuid(data));
else {
@@ -2819,7 +2882,8 @@ int get_val_instance_num(struct script_state* st, const char* name, struct scrip
* @param data[in,out] variable/constant.
* @return pointer to data, for convenience.
*/
-struct script_data *get_val(struct script_state* st, struct script_data* data) {
+static struct script_data *get_val(struct script_state *st, struct script_data *data)
+{
const char* name;
char prefix;
char postfix;
@@ -2839,8 +2903,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
return data;
}
- //##TODO use reference_tovariable(data) when it's confirmed that it works [FlavioJS]
- if (!reference_toconstant(data) && not_server_variable(prefix) && reference_getref(data) == NULL) {
+ if (((reference_tovariable(data) && not_server_variable(prefix)) || reference_toparam(data)) && reference_getref(data) == NULL) {
sd = script->rid2sd(st);
if (sd == NULL) {// needs player attached
if (postfix == '$') {// string variable
@@ -2873,7 +2936,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
break;
case '#':
if (data->ref) {
- str = script->get_val_ref_str(st, data->ref, data);
+ str = script->get_val_pc_ref_str(st, data->ref, data);
} else if (name[1] == '#') {
str = pc_readaccountreg2str(sd, data->u.num);// global
} else {
@@ -2894,7 +2957,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
break;
default:
if (data->ref) {
- str = script->get_val_ref_str(st, data->ref, data);
+ str = script->get_val_pc_ref_str(st, data->ref, data);
} else {
str = pc_readglobalreg_str(sd, data->u.num);
}
@@ -2932,7 +2995,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
break;
case '#':
if (data->ref) {
- data->u.num = script->get_val_ref_num(st, data->ref, data);
+ data->u.num = script->get_val_pc_ref_num(st, data->ref, data);
} else if (name[1] == '#') {
data->u.num = pc_readaccountreg2(sd, data->u.num);// global
} else {
@@ -2953,7 +3016,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
break;
default:
if (data->ref) {
- data->u.num = script->get_val_ref_num(st, data->ref, data);
+ data->u.num = script->get_val_pc_ref_num(st, data->ref, data);
} else {
data->u.num = pc_readglobalreg(sd, data->u.num);
}
@@ -2976,7 +3039,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
* @param ref[in] the container to look up the reference into.
* @return the retrieved value of the reference.
*/
-const void *get_val2(struct script_state *st, int64 uid, struct reg_db *ref)
+static const void *get_val2(struct script_state *st, int64 uid, struct reg_db *ref)
{
struct script_data* data;
nullpo_retr(NULL, st);
@@ -2985,6 +3048,10 @@ const void *get_val2(struct script_state *st, int64 uid, struct reg_db *ref)
script->get_val(st, data);
if (data->type == C_INT) // u.num is int32 because it comes from script->get_val
return (const void *)h64BPTRSIZE((int32)data->u.num);
+ else if (data_isreference(data) && reference_toconstant(data))
+ return (const void *)h64BPTRSIZE((int32)reference_getconstant(data));
+ else if (data_isreference(data) && reference_toparam(data))
+ return (const void *)h64BPTRSIZE((int32)reference_getparamtype(data));
else
return (const void *)h64BPTRSIZE(data->u.str);
}
@@ -2992,7 +3059,8 @@ const void *get_val2(struct script_state *st, int64 uid, struct reg_db *ref)
* Because, currently, array members with key 0 are indifferenciable from normal variables, we should ensure its actually in
* Will be gone as soon as undefined var feature is implemented
**/
-void script_array_ensure_zero(struct script_state *st, struct map_session_data *sd, int64 uid, struct reg_db *ref) {
+static void script_array_ensure_zero(struct script_state *st, struct map_session_data *sd, int64 uid, struct reg_db *ref)
+{
const char *name = script->get_str(script_getvarid(uid));
struct reg_db *src = NULL;
bool insert = false;
@@ -3039,7 +3107,8 @@ void script_array_ensure_zero(struct script_state *st, struct map_session_data *
/**
* Returns array size by ID
**/
-unsigned int script_array_size(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) {
+static unsigned int script_array_size(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref)
+{
struct script_array *sa = NULL;
struct reg_db *src = script->array_src(st, sd, name, ref);
@@ -3051,7 +3120,8 @@ unsigned int script_array_size(struct script_state *st, struct map_session_data
/**
* Returns array's highest key (for that awful getarraysize implementation that doesn't really gets the array size)
**/
-unsigned int script_array_highest_key(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) {
+static unsigned int script_array_highest_key(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref)
+{
struct script_array *sa = NULL;
struct reg_db *src = script->array_src(st, sd, name, ref);
@@ -3072,7 +3142,7 @@ unsigned int script_array_highest_key(struct script_state *st, struct map_sessio
}
return 0;
}
-int script_free_array_db(union DBKey key, struct DBData *data, va_list ap)
+static int script_free_array_db(union DBKey key, struct DBData *data, va_list ap)
{
struct script_array *sa = DB->data2ptr(data);
aFree(sa->members);
@@ -3082,7 +3152,8 @@ int script_free_array_db(union DBKey key, struct DBData *data, va_list ap)
/**
* Clears script_array and removes it from script->array_db
**/
-void script_array_delete(struct reg_db *src, struct script_array *sa) {
+static void script_array_delete(struct reg_db *src, struct script_array *sa)
+{
nullpo_retv(src);
nullpo_retv(sa);
aFree(sa->members);
@@ -3094,7 +3165,8 @@ void script_array_delete(struct reg_db *src, struct script_array *sa) {
*
* @param idx the index of the member in script_array struct list, not of the actual array member
**/
-void script_array_remove_member(struct reg_db *src, struct script_array *sa, unsigned int idx) {
+static void script_array_remove_member(struct reg_db *src, struct script_array *sa, unsigned int idx)
+{
unsigned int i, cursor;
nullpo_retv(sa);
@@ -3121,7 +3193,8 @@ void script_array_remove_member(struct reg_db *src, struct script_array *sa, uns
*
* @param idx the index of the array member being inserted
**/
-void script_array_add_member(struct script_array *sa, unsigned int idx) {
+static void script_array_add_member(struct script_array *sa, unsigned int idx)
+{
nullpo_retv(sa);
RECREATE(sa->members, unsigned int, ++sa->size);
sa->members[sa->size - 1] = idx;
@@ -3130,7 +3203,8 @@ void script_array_add_member(struct script_array *sa, unsigned int idx) {
* Obtains the source of the array database for this type and scenario
* Initializes such database when not yet initialized.
**/
-struct reg_db *script_array_src(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) {
+static struct reg_db *script_array_src(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref)
+{
struct reg_db *src = NULL;
nullpo_retr(NULL, name);
@@ -3181,7 +3255,8 @@ struct reg_db *script_array_src(struct script_state *st, struct map_session_data
* @param num[in] Variable ID
* @param empty[in] Whether the modified member is empty (needs to be removed)
**/
-void script_array_update(struct reg_db *src, int64 num, bool empty) {
+static void script_array_update(struct reg_db *src, int64 num, bool empty)
+{
struct script_array *sa = NULL;
int id = script_getvarid(num);
unsigned int index = script_getvaridx(num);
@@ -3222,7 +3297,7 @@ void script_array_update(struct reg_db *src, int64 num, bool empty) {
}
}
-void set_reg_npcscope_str(struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str)
+static void set_reg_npcscope_str(struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str)
{
if (n)
{
@@ -3239,7 +3314,33 @@ void set_reg_npcscope_str(struct script_state* st, struct reg_db *n, int64 num,
}
}
-void set_reg_npcscope_num(struct script_state* st, struct reg_db *n, int64 num, const char* name, int val)
+static void set_reg_pc_ref_str(struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str)
+{
+ struct DBIterator *iter = db_iterator(map->pc_db);
+
+ for (struct map_session_data *sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter)) {
+ if (sd != NULL && n == &sd->regs) {
+ pc->setregistry_str(sd, num, str);
+ break;
+ }
+ }
+ dbi_destroy(iter);
+}
+
+static void set_reg_pc_ref_num(struct script_state *st, struct reg_db *n, int64 num, const char *name, int val)
+{
+ struct DBIterator *iter = db_iterator(map->pc_db);
+
+ for (struct map_session_data *sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter)) {
+ if (sd != NULL && n == &sd->regs) {
+ pc->setregistry(sd, num, val);
+ break;
+ }
+ }
+ dbi_destroy(iter);
+}
+
+static void set_reg_npcscope_num(struct script_state *st, struct reg_db *n, int64 num, const char *name, int val)
{
if (n) {
if (val != 0) {
@@ -3254,7 +3355,7 @@ void set_reg_npcscope_num(struct script_state* st, struct reg_db *n, int64 num,
}
}
-void set_reg_instance_str(struct script_state* st, int64 num, const char* name, const char *str)
+static void set_reg_instance_str(struct script_state *st, int64 num, const char *name, const char *str)
{
nullpo_retv(st);
if (st->instance_id >= 0) {
@@ -3273,7 +3374,7 @@ void set_reg_instance_str(struct script_state* st, int64 num, const char* name,
}
}
-void set_reg_instance_num(struct script_state* st, int64 num, const char* name, int val)
+static void set_reg_instance_num(struct script_state *st, int64 num, const char *name, int val)
{
nullpo_retv(st);
if (st->instance_id >= 0) {
@@ -3306,12 +3407,25 @@ void set_reg_instance_num(struct script_state* st, int64 num, const char* name,
*
* TODO: return values are screwed up, have been for some time (reaad: years), e.g. some functions return 1 failure and success.
*------------------------------------------*/
-int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref)
+static int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref)
{
char prefix;
nullpo_ret(name);
prefix = name[0];
+ if (script->str_data[script_getvarid(num)].type != C_NAME && script->str_data[script_getvarid(num)].type != C_PARAM) {
+ ShowError("script:set_reg: not a variable! '%s'\n", name);
+
+ // to avoid this don't do script->add_str(") without setting its type.
+ // either use script->add_variable() or manually set the type
+
+ if (st) {
+ script->reportsrc(st);
+ st->state = END;
+ }
+ return 0;
+ }
+
if (strlen(name) > SCRIPT_VARNAME_LENGTH) {
ShowError("script:set_reg: variable name too long. '%s'\n", name);
if (st) {
@@ -3337,7 +3451,7 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
return 1;
case '#':
if (ref) {
- script->set_reg_ref_str(st, ref, num, name, str);
+ script->set_reg_pc_ref_str(st, ref, num, name, str);
} else if (name[1] == '#') {
pc_setaccountreg2str(sd, num, str);
} else {
@@ -3358,7 +3472,7 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
return 1;
default:
if (ref) {
- script->set_reg_ref_str(st, ref, num, name, str);
+ script->set_reg_pc_ref_str(st, ref, num, name, str);
} else {
pc_setglobalreg_str(sd, num, str);
}
@@ -3399,7 +3513,7 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
return 1;
case '#':
if (ref) {
- script->set_reg_ref_num(st, ref, num, name, val);
+ script->set_reg_pc_ref_num(st, ref, num, name, val);
} else if (name[1] == '#') {
pc_setaccountreg2(sd, num, val);
} else {
@@ -3420,7 +3534,7 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
return 1;
default:
if (ref) {
- script->set_reg_ref_num(st, ref, num, name, val);
+ script->set_reg_pc_ref_num(st, ref, num, name, val);
} else {
pc_setglobalreg(sd, num, val);
}
@@ -3429,18 +3543,32 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
}
}
-int set_var(struct map_session_data *sd, char *name, void *val)
+static int set_var(struct map_session_data *sd, char *name, void *val)
{
- return script->set_reg(NULL, sd, reference_uid(script->add_str(name),0), name, val, NULL);
+ int key = script->add_variable(name);
+
+ if (script->str_data[key].type != C_NAME) {
+ ShowError("script:setd_sub: `%s` is already used by something that is not a variable.\n", name);
+ return -1;
+ }
+
+ return script->set_reg(NULL, sd, reference_uid(key, 0), name, val, NULL);
}
-void setd_sub(struct script_state *st, struct map_session_data *sd, const char *varname, int elem, const void *value, struct reg_db *ref)
+static void setd_sub(struct script_state *st, struct map_session_data *sd, const char *varname, int elem, const void *value, struct reg_db *ref)
{
- script->set_reg(st, sd, reference_uid(script->add_str(varname),elem), varname, value, ref);
+ int key = script->add_variable(varname);
+
+ if (script->str_data[key].type != C_NAME) {
+ ShowError("script:setd_sub: `%s` is already used by something that is not a variable.\n", varname);
+ return;
+ }
+
+ script->set_reg(st, sd, reference_uid(key, elem), varname, value, ref);
}
/// Converts the data to a string
-const char *conv_str(struct script_state *st, struct script_data* data)
+static const char *conv_str(struct script_state *st, struct script_data *data)
{
script->get_val(st, data);
if (data_isstring(data)) {
@@ -3474,7 +3602,7 @@ const char *conv_str(struct script_state *st, struct script_data* data)
}
/// Converts the data to an int
-int conv_num(struct script_state *st, struct script_data *data)
+static int conv_num(struct script_state *st, struct script_data *data)
{
long num;
@@ -3532,7 +3660,8 @@ int conv_num(struct script_state *st, struct script_data *data)
//
/// Increases the size of the stack
-void stack_expand(struct script_stack* stack) {
+static void stack_expand(struct script_stack *stack)
+{
nullpo_retv(stack);
stack->sp_max += 64;
stack->stack_data = (struct script_data*)aRealloc(stack->stack_data,
@@ -3542,7 +3671,8 @@ void stack_expand(struct script_stack* stack) {
}
/// Pushes a value into the stack (with reference)
-struct script_data* push_val(struct script_stack* stack, enum c_op type, int64 val, struct reg_db *ref) {
+static struct script_data *push_val(struct script_stack *stack, enum c_op type, int64 val, struct reg_db *ref)
+{
nullpo_retr(NULL, stack);
if( stack->sp >= stack->sp_max )
script->stack_expand(stack);
@@ -3554,7 +3684,7 @@ struct script_data* push_val(struct script_stack* stack, enum c_op type, int64 v
}
/// Pushes a string into the stack
-struct script_data *push_str(struct script_stack *stack, char *str)
+static struct script_data *push_str(struct script_stack *stack, char *str)
{
nullpo_retr(NULL, stack);
if( stack->sp >= stack->sp_max )
@@ -3567,7 +3697,7 @@ struct script_data *push_str(struct script_stack *stack, char *str)
}
/// Pushes a constant string into the stack
-struct script_data *push_conststr(struct script_stack *stack, const char *str)
+static struct script_data *push_conststr(struct script_stack *stack, const char *str)
{
nullpo_retr(NULL, stack);
if( stack->sp >= stack->sp_max )
@@ -3580,7 +3710,8 @@ struct script_data *push_conststr(struct script_stack *stack, const char *str)
}
/// Pushes a retinfo into the stack
-struct script_data* push_retinfo(struct script_stack* stack, struct script_retinfo* ri, struct reg_db *ref) {
+static struct script_data *push_retinfo(struct script_stack *stack, struct script_retinfo *ri, struct reg_db *ref)
+{
nullpo_retr(NULL, stack);
if( stack->sp >= stack->sp_max )
script->stack_expand(stack);
@@ -3592,7 +3723,8 @@ struct script_data* push_retinfo(struct script_stack* stack, struct script_retin
}
/// Pushes a copy of the target position into the stack
-struct script_data* push_copy(struct script_stack* stack, int pos) {
+static struct script_data *push_copy(struct script_stack *stack, int pos)
+{
nullpo_retr(NULL, stack);
switch( stack->stack_data[pos].type ) {
case C_CONSTSTR:
@@ -3617,7 +3749,8 @@ struct script_data* push_copy(struct script_stack* stack, int pos) {
/// Removes the values in indexes [start,end[ from the stack.
/// Adjusts all stack pointers.
-void pop_stack(struct script_state* st, int start, int end) {
+static void pop_stack(struct script_state *st, int start, int end)
+{
struct script_stack* stack;
struct script_data* data;
int i;
@@ -3689,7 +3822,7 @@ void pop_stack(struct script_state* st, int start, int end) {
/*==========================================
* Release script dependent variable, dependent variable of function
*------------------------------------------*/
-void script_free_vars(struct DBMap *var_storage)
+static void script_free_vars(struct DBMap *var_storage)
{
if( var_storage ) {
// destroy the storage construct containing the variables
@@ -3697,7 +3830,7 @@ void script_free_vars(struct DBMap *var_storage)
}
}
-void script_free_code(struct script_code* code)
+static void script_free_code(struct script_code *code)
{
nullpo_retv(code);
@@ -3717,7 +3850,8 @@ void script_free_code(struct script_code* code)
/// @param rid Who is running the script (attached player)
/// @param oid Where the code is being run (npc 'object')
/// @return Script state
-struct script_state* script_alloc_state(struct script_code* rootscript, int pos, int rid, int oid) {
+static struct script_state *script_alloc_state(struct script_code *rootscript, int pos, int rid, int oid)
+{
struct script_state* st;
st = ers_alloc(script->st_ers, struct script_state);
@@ -3759,7 +3893,8 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
/// Frees a script state.
///
/// @param st Script state
-void script_free_state(struct script_state* st) {
+static void script_free_state(struct script_state *st)
+{
nullpo_retv(st);
if( idb_exists(script->st_db,st->id) ) {
struct map_session_data *sd = st->rid ? map->id2sd(st->rid) : NULL;
@@ -3821,7 +3956,8 @@ void script_free_state(struct script_state* st) {
* @param st[in] Script state.
* @param ref[in] Reference to be added.
*/
-void script_add_pending_ref(struct script_state *st, struct reg_db *ref) {
+static void script_add_pending_ref(struct script_state *st, struct reg_db *ref)
+{
nullpo_retv(st);
RECREATE(st->pending_refs, struct reg_db*, ++st->pending_ref_count);
st->pending_refs[st->pending_ref_count-1] = ref;
@@ -3833,7 +3969,7 @@ void script_add_pending_ref(struct script_state *st, struct reg_db *ref) {
/*==========================================
* Read command
*------------------------------------------*/
-c_op get_com(const struct script_buf *scriptbuf, int *pos)
+static c_op get_com(const struct script_buf *scriptbuf, int *pos)
{
int i = 0, j = 0;
@@ -3850,7 +3986,7 @@ c_op get_com(const struct script_buf *scriptbuf, int *pos)
/*==========================================
* Income figures
*------------------------------------------*/
-int get_num(const struct script_buf *scriptbuf, int *pos)
+static int get_num(const struct script_buf *scriptbuf, int *pos)
{
int i,j;
i=0; j=0;
@@ -3863,7 +3999,7 @@ int get_num(const struct script_buf *scriptbuf, int *pos)
/// Ternary operators
/// test ? if_true : if_false
-void op_3(struct script_state* st, int op)
+static void op_3(struct script_state *st, int op)
{
struct script_data* data;
int flag = 0;
@@ -3900,7 +4036,7 @@ void op_3(struct script_state* st, int op)
/// s1 RE_EQ s2 -> i
/// s1 RE_NE s2 -> i
/// s1 ADD s2 -> s
-void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
+static void op_2str(struct script_state *st, int op, const char *s1, const char *s2)
{
int a = 0;
@@ -3963,10 +4099,10 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
int i;
for (i = 0; i < offsetcount; i++) {
libpcre->get_substring(s1, offsets, offsetcount, i, &pcre_match);
- mapreg->setregstr(reference_uid(script->add_str("$@regexmatch$"), i), pcre_match);
+ mapreg->setregstr(reference_uid(script->add_variable("$@regexmatch$"), i), pcre_match);
libpcre->free_substring(pcre_match);
}
- mapreg->setreg(script->add_str("$@regexmatchcount"), i);
+ mapreg->setreg(script->add_variable("$@regexmatchcount"), i);
a = offsetcount;
} else { // C_RE_NE
a = (offsetcount == 0);
@@ -3997,7 +4133,7 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
/// Binary number operators
/// i OP i -> i
-void op_2num(struct script_state* st, int op, int i1, int i2)
+static void op_2num(struct script_state *st, int op, int i1, int i2)
{
int ret;
int64 ret64;
@@ -4036,6 +4172,7 @@ void op_2num(struct script_state* st, int op, int i1, int i2)
case C_ADD: ret = i1 + i2; ret64 = (int64)i1 + i2; break;
case C_SUB: ret = i1 - i2; ret64 = (int64)i1 - i2; break;
case C_MUL: ret = i1 * i2; ret64 = (int64)i1 * i2; break;
+ case C_POW: ret = (int)pow((double)i1, (double)i2); ret64 = (int64)pow((double)i1, (double)i2); break;
default:
ShowError("script:op_2num: unexpected number operator %s i1=%d i2=%d\n", script->op2name(op), i1, i2);
script->reportsrc(st);
@@ -4056,7 +4193,7 @@ void op_2num(struct script_state* st, int op, int i1, int i2)
}
/// Binary operators
-void op_2(struct script_state *st, int op)
+static void op_2(struct script_state *st, int op)
{
struct script_data* left, leftref;
struct script_data* right;
@@ -4130,7 +4267,7 @@ void op_2(struct script_state *st, int op)
/// NEG i -> i
/// NOT i -> i
/// LNOT i -> i
-void op_1(struct script_state* st, int op)
+static void op_1(struct script_state *st, int op)
{
struct script_data* data;
int i1;
@@ -4168,7 +4305,7 @@ void op_1(struct script_state* st, int op)
///
/// @param st Script state whose stack arguments should be inspected.
/// @param func Built-in function for which the arguments are intended.
-bool script_check_buildin_argtype(struct script_state* st, int func)
+static bool script_check_buildin_argtype(struct script_state *st, int func)
{
int idx, invalid = 0;
char* sf;
@@ -4254,7 +4391,7 @@ bool script_check_buildin_argtype(struct script_state* st, int func)
/// Executes a buildin command.
/// Stack: C_NAME(<command>) C_ARG <arg0> <arg1> ... <argN>
-int run_func(struct script_state *st)
+static int run_func(struct script_state *st)
{
struct script_data* data;
int i,start_sp,end_sp,func;
@@ -4347,7 +4484,8 @@ int run_func(struct script_state *st)
/*==========================================
* script execution
*------------------------------------------*/
-void run_script(struct script_code *rootscript, int pos, int rid, int oid) {
+static void run_script(struct script_code *rootscript, int pos, int rid, int oid)
+{
struct script_state *st;
if( rootscript == NULL || pos < 0 )
@@ -4361,7 +4499,7 @@ void run_script(struct script_code *rootscript, int pos, int rid, int oid) {
script->run_main(st);
}
-void script_stop_instances(struct script_code *code)
+static void script_stop_instances(struct script_code *code)
{
struct DBIterator *iter;
struct script_state* st;
@@ -4383,7 +4521,8 @@ void script_stop_instances(struct script_code *code)
/*==========================================
* Timer function for sleep
*------------------------------------------*/
-int run_script_timer(int tid, int64 tick, int id, intptr_t data) {
+static int run_script_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct script_state *st = idb_get(script->st_db,(int)data);
if( st ) {
struct map_session_data *sd = map->id2sd(st->rid);
@@ -4404,7 +4543,8 @@ int run_script_timer(int tid, int64 tick, int id, intptr_t data) {
///
/// @param st Script state to detach.
/// @param dequeue_event Whether to schedule any queued events, when there was no previous script.
-void script_detach_state(struct script_state* st, bool dequeue_event) {
+static void script_detach_state(struct script_state *st, bool dequeue_event)
+{
struct map_session_data* sd;
nullpo_retv(st);
@@ -4438,7 +4578,8 @@ void script_detach_state(struct script_state* st, bool dequeue_event) {
/// Attaches script state to possibly attached character and backups it's previous script, if any.
///
/// @param st Script state to attach.
-void script_attach_state(struct script_state* st) {
+static void script_attach_state(struct script_state *st)
+{
struct map_session_data* sd;
nullpo_retv(st);
@@ -4470,7 +4611,8 @@ void script_attach_state(struct script_state* st) {
/*==========================================
* The main part of the script execution
*------------------------------------------*/
-void run_script_main(struct script_state *st) {
+static void run_script_main(struct script_state *st)
+{
int cmdcount = script->config.check_cmdcount;
int gotocount = script->config.check_gotocount;
struct map_session_data *sd;
@@ -4573,6 +4715,7 @@ void run_script_main(struct script_state *st) {
case C_ADD:
case C_SUB:
case C_MUL:
+ case C_POW:
case C_DIV:
case C_MOD:
case C_EQ:
@@ -4659,7 +4802,7 @@ void run_script_main(struct script_state *st) {
*
* @retval false in case of error.
*/
-bool script_config_read(const char *filename, bool imported)
+static bool script_config_read(const char *filename, bool imported)
{
struct config_t config;
struct config_setting_t * setting = NULL;
@@ -4706,7 +4849,7 @@ bool script_config_read(const char *filename, bool imported)
/**
* @see DBApply
*/
-int db_script_free_code_sub(union DBKey key, struct DBData *data, va_list ap)
+static int db_script_free_code_sub(union DBKey key, struct DBData *data, va_list ap)
{
struct script_code *code = DB->data2ptr(data);
if (code)
@@ -4714,7 +4857,7 @@ int db_script_free_code_sub(union DBKey key, struct DBData *data, va_list ap)
return 0;
}
-void script_run_autobonus(const char *autobonus, int id, int pos)
+static void script_run_autobonus(const char *autobonus, int id, int pos)
{
struct script_code *scriptroot = (struct script_code *)strdb_get(script->autobonus_db, autobonus);
@@ -4724,7 +4867,7 @@ void script_run_autobonus(const char *autobonus, int id, int pos)
}
}
-void script_add_autobonus(const char *autobonus)
+static void script_add_autobonus(const char *autobonus)
{
if( strdb_get(script->autobonus_db, autobonus) == NULL ) {
struct script_code *scriptroot = script->parse(autobonus, "autobonus", 0, 0, NULL);
@@ -4735,13 +4878,19 @@ void script_add_autobonus(const char *autobonus)
}
/// resets a temporary character array variable to given value
-void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value) {
+static void script_cleararray_pc(struct map_session_data *sd, const char *varname, void *value)
+{
struct script_array *sa = NULL;
struct reg_db *src = NULL;
unsigned int i, *list = NULL, size = 0;
int key;
- key = script->add_str(varname);
+ key = script->add_variable(varname);
+
+ if (script->str_data[key].type != C_NAME) {
+ ShowError("script:cleararray_pc: `%s` is already used by something that is not a variable.\n", varname);
+ return;
+ }
if( !(src = script->array_src(NULL,sd,varname,NULL) ) )
return;
@@ -4762,15 +4911,21 @@ void script_cleararray_pc(struct map_session_data* sd, const char* varname, void
/// sets a temporary character array variable element idx to given value
/// @param refcache Pointer to an int variable, which keeps a copy of the reference to varname and must be initialized to 0. Can be NULL if only one element is set.
-void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache) {
+static void script_setarray_pc(struct map_session_data *sd, const char *varname, uint32 idx, void *value, int *refcache)
+{
int key;
- if( idx >= SCRIPT_MAX_ARRAYSIZE ) {
+ if (idx > SCRIPT_MAX_ARRAYSIZE) {
ShowError("script_setarray_pc: Variable '%s' has invalid index '%u' (char_id=%d).\n", varname, idx, sd->status.char_id);
return;
}
- key = ( refcache && refcache[0] ) ? refcache[0] : script->add_str(varname);
+ key = ( refcache && refcache[0] ) ? refcache[0] : script->add_variable(varname);
+
+ if (script->str_data[key].type != C_NAME) {
+ ShowError("script:setarray_pc: `%s` is already used by something that is not a variable.\n", varname);
+ return;
+ }
script->set_reg(NULL,sd,reference_uid(key, idx),varname,value,NULL);
@@ -4782,7 +4937,7 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32
/**
* Clears persistent variables from memory
**/
-int script_reg_destroy(union DBKey key, struct DBData *data, va_list ap)
+static int script_reg_destroy(union DBKey key, struct DBData *data, va_list ap)
{
struct script_reg_state *src;
@@ -4807,7 +4962,8 @@ int script_reg_destroy(union DBKey key, struct DBData *data, va_list ap)
/**
* Clears a single persistent variable
**/
-void script_reg_destroy_single(struct map_session_data *sd, int64 reg, struct script_reg_state *data) {
+static void script_reg_destroy_single(struct map_session_data *sd, int64 reg, struct script_reg_state *data)
+{
nullpo_retv(sd);
nullpo_retv(data);
i64db_remove(sd->regs.vars, reg);
@@ -4823,21 +4979,23 @@ void script_reg_destroy_single(struct map_session_data *sd, int64 reg, struct sc
ers_free(pc->num_reg_ers,(struct script_reg_num*)data);
}
}
-unsigned int *script_array_cpy_list(struct script_array *sa) {
+static unsigned int *script_array_cpy_list(struct script_array *sa)
+{
nullpo_retr(NULL, sa);
if( sa->size > script->generic_ui_array_size )
script->generic_ui_array_expand(sa->size);
memcpy(script->generic_ui_array, sa->members, sizeof(unsigned int)*sa->size);
return script->generic_ui_array;
}
-void script_generic_ui_array_expand (unsigned int plus) {
+static void script_generic_ui_array_expand(unsigned int plus)
+{
script->generic_ui_array_size += plus + 100;
RECREATE(script->generic_ui_array, unsigned int, script->generic_ui_array_size);
}
/*==========================================
* Destructor
*------------------------------------------*/
-void do_final_script(void)
+static void do_final_script(void)
{
int i;
struct DBIterator *iter;
@@ -4917,6 +5075,8 @@ void do_final_script(void)
aFree(script->str_buf);
for( i = 0; i < atcommand->binding_count; i++ ) {
+ aFree(atcommand->binding[i]->at_groups);
+ aFree(atcommand->binding[i]->char_groups);
aFree(atcommand->binding[i]);
}
@@ -4970,7 +5130,8 @@ void do_final_script(void)
/**
*
**/
-uint8 script_add_language(const char *name) {
+static uint8 script_add_language(const char *name)
+{
uint8 lang_id = script->max_lang_id;
nullpo_ret(name);
@@ -4982,7 +5143,8 @@ uint8 script_add_language(const char *name) {
/**
* Goes thru db/translations.conf file
**/
-void script_load_translations(void) {
+static void script_load_translations(void)
+{
struct config_t translations_conf;
const char *config_filename = "db/translations.conf"; // FIXME hardcoded name
struct config_setting_t *translations = NULL;
@@ -5066,7 +5228,7 @@ void script_load_translations(void) {
* @param file The filename.
* @return The corresponding translation name.
*/
-const char *script_get_translation_file_name(const char *file)
+static const char *script_get_translation_file_name(const char *file)
{
const char *basename = NULL, *last_dot = NULL;
@@ -5110,7 +5272,7 @@ const char *script_get_translation_file_name(const char *file)
* @return success state
* @retval true if a new string was added.
*/
-bool script_load_translation_addstring(const char *file, uint8 lang_id, const char *msgctxt, const struct script_string_buf *msgid, const struct script_string_buf *msgstr)
+static bool script_load_translation_addstring(const char *file, uint8 lang_id, const char *msgctxt, const struct script_string_buf *msgid, const struct script_string_buf *msgstr)
{
nullpo_retr(false, file);
nullpo_retr(false, msgctxt);
@@ -5178,7 +5340,7 @@ bool script_load_translation_addstring(const char *file, uint8 lang_id, const ch
* @param lang_id The language identifier.
* @return The amount of strings loaded.
*/
-int script_load_translation(const char *file, uint8 lang_id)
+static int script_load_translation(const char *file, uint8 lang_id)
{
int translations = 0;
char line[1024];
@@ -5318,7 +5480,8 @@ int script_load_translation(const char *file, uint8 lang_id)
/**
*
**/
-void script_clear_translations(bool reload) {
+static void script_clear_translations(bool reload)
+{
uint32 i;
if( script->string_list )
@@ -5352,7 +5515,7 @@ void script_clear_translations(bool reload) {
/**
*
**/
-int script_translation_db_destroyer(union DBKey key, struct DBData *data, va_list ap)
+static int script_translation_db_destroyer(union DBKey key, struct DBData *data, va_list ap)
{
struct DBMap *string_db = DB->data2ptr(data);
@@ -5373,7 +5536,7 @@ int script_translation_db_destroyer(union DBKey key, struct DBData *data, va_lis
/**
*
**/
-void script_parser_clean_leftovers(void)
+static void script_parser_clean_leftovers(void)
{
VECTOR_CLEAR(script->buf);
@@ -5388,7 +5551,8 @@ void script_parser_clean_leftovers(void)
/**
* Performs cleanup after all parsing is processed
**/
-int script_parse_cleanup_timer(int tid, int64 tick, int id, intptr_t data) {
+static int script_parse_cleanup_timer(int tid, int64 tick, int id, intptr_t data)
+{
script->parser_clean_leftovers();
script->parse_cleanup_timer_id = INVALID_TIMER;
@@ -5399,7 +5563,8 @@ int script_parse_cleanup_timer(int tid, int64 tick, int id, intptr_t data) {
/*==========================================
* Initialization
*------------------------------------------*/
-void do_init_script(bool minimal) {
+static void do_init_script(bool minimal)
+{
script->parse_cleanup_timer_id = INVALID_TIMER;
VECTOR_INIT(script->parse_simpleexpr_strbuf);
@@ -5418,7 +5583,7 @@ void do_init_script(bool minimal) {
VECTOR_INIT(script->hqi);
script->parse_builtin();
- script->read_constdb();
+ script->read_constdb(false);
script->load_parameters();
script->hardcoded_constants();
@@ -5429,7 +5594,7 @@ void do_init_script(bool minimal) {
script->load_translations();
}
-int script_reload(void)
+static int script_reload(void)
{
int i;
struct DBIterator *iter;
@@ -5451,6 +5616,8 @@ int script_reload(void)
script->label_count = 0;
for( i = 0; i < atcommand->binding_count; i++ ) {
+ aFree(atcommand->binding[i]->at_groups);
+ aFree(atcommand->binding[i]->char_groups);
aFree(atcommand->binding[i]);
}
@@ -5468,16 +5635,18 @@ int script_reload(void)
script->parse_cleanup_timer_id = INVALID_TIMER;
}
- mapreg->reload();
-
+ script->read_constdb(true);
itemdb->name_constants();
+ clan->set_constants();
+ mapreg->reload();
sysinfo->vcsrevision_reload();
return 0;
}
/* returns name of current function being run, from within the stack [Ind/Hercules] */
-const char *script_getfuncname(struct script_state *st) {
+static const char *script_getfuncname(struct script_state *st)
+{
struct script_data *data;
nullpo_retr(NULL, st);
@@ -5501,7 +5670,7 @@ const char *script_getfuncname(struct script_state *st) {
* already initialized)
* @retval false if an error occurs.
*/
-bool script_sprintf(struct script_state *st, int start, struct StringBuf *out)
+static bool script_sprintf_helper(struct script_state *st, int start, struct StringBuf *out)
{
const char *format = NULL;
const char *p = NULL, *np = NULL;
@@ -5554,7 +5723,7 @@ bool script_sprintf(struct script_state *st, int start, struct StringBuf *out)
}
// placeholder = "%n" ; (ignored)
if (*np == 'n') {
- ShowWarning("script_sprintf: Format %%n not supported! Skipping...\n");
+ ShowWarning("script_sprintf_helper: Format %%n not supported! Skipping...\n");
script->reportsrc(st);
lastarg = nextarg;
p = np + 1;
@@ -5726,13 +5895,17 @@ bool script_sprintf(struct script_state *st, int start, struct StringBuf *out)
/// If a dialog doesn't exist yet, one is created.
///
/// mes "<message>";
-BUILDIN(mes)
+static BUILDIN(mes)
{
struct map_session_data *sd = script->rid2sd(st);
+
if (sd == NULL)
return true;
- clif->scriptmes(sd, st->oid, script_getstr(st, 2));
+ if (script_hasdata(st, 2))
+ clif->scriptmes(sd, st->oid, script_getstr(st, 2));
+ else
+ clif->scriptmes(sd, st->oid, "");
return true;
}
@@ -5747,7 +5920,7 @@ BUILDIN(mes)
* mes "<message>";
* @endcode
*/
-BUILDIN(mesf)
+static BUILDIN(mesf)
{
struct map_session_data *sd = script->rid2sd(st);
struct StringBuf buf;
@@ -5757,7 +5930,7 @@ BUILDIN(mesf)
StrBuf->Init(&buf);
- if (!script_sprintf(st, 2, &buf)) {
+ if (!script->sprintf_helper(st, 2, &buf)) {
StrBuf->Destroy(&buf);
return false;
}
@@ -5772,7 +5945,7 @@ BUILDIN(mesf)
/// The dialog text is cleared and the script continues when the button is pressed.
///
/// next;
-BUILDIN(next)
+static BUILDIN(next)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -5789,7 +5962,7 @@ BUILDIN(next)
/// The dialog is closed when the button is pressed.
///
/// close;
-BUILDIN(close)
+static BUILDIN(close)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -5804,7 +5977,7 @@ BUILDIN(close)
/// The dialog is closed and the script continues when the button is pressed.
///
/// close2;
-BUILDIN(close2)
+static BUILDIN(close2)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -5824,7 +5997,7 @@ BUILDIN(close2)
/// Counts the number of valid and total number of options in 'str'
/// If max_count > 0 the counting stops when that valid option is reached
/// total is incremented for each option (NULL is supported)
-int menu_countoptions(const char* str, int max_count, int* total)
+static int menu_countoptions(const char *str, int max_count, int *total)
{
int count = 0;
int bogus_total;
@@ -5874,7 +6047,7 @@ int menu_countoptions(const char* str, int max_count, int* total)
/// NOTE: the client closes the npc dialog when cancel is pressed
///
/// menu "<option_text>",<target_label>{,"<option_text>",<target_label>,...};
-BUILDIN(menu)
+static BUILDIN(menu)
{
int i;
const char* text;
@@ -5926,11 +6099,11 @@ BUILDIN(menu)
sd->state.menu_or_input = 1;
/* menus beyond this length crash the client (see bugreport:6402) */
- if( StrBuf->Length(&buf) >= 2047 ) {
+ if( StrBuf->Length(&buf) >= MAX_MENU_LENGTH - 1 ) {
struct npc_data * nd = map->id2nd(st->oid);
char* menu;
- CREATE(menu, char, 2048);
- safestrncpy(menu, StrBuf->Value(&buf), 2047);
+ CREATE(menu, char, MAX_MENU_LENGTH);
+ safestrncpy(menu, StrBuf->Value(&buf), MAX_MENU_LENGTH - 1);
ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StrBuf->Length(&buf));
clif->scriptmenu(sd, st->oid, menu);
aFree(menu);
@@ -5939,13 +6112,13 @@ BUILDIN(menu)
StrBuf->Destroy(&buf);
- if( sd->npc_menu >= 0xff )
+ if( sd->npc_menu >= MAX_MENU_OPTIONS )
{// client supports only up to 254 entries; 0 is not used and 255 is reserved for cancel; excess entries are displayed but cause 'uint8' overflow
- ShowWarning("buildin_menu: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
+ ShowWarning("buildin_menu: Too many options specified (current=%d, max=%d).\n", sd->npc_menu, MAX_MENU_OPTIONS - 1);
script->reportsrc(st);
}
}
- else if( sd->npc_menu == 0xff )
+ else if( sd->npc_menu == MAX_MENU_OPTIONS )
{// Cancel was pressed
sd->state.menu_or_input = 0;
st->state = END;
@@ -5983,7 +6156,7 @@ BUILDIN(menu)
st->state = END;
return false;
}
- pc->setreg(sd, script->add_str("@menu"), menu);
+ pc->setreg(sd, script->add_variable("@menu"), menu);
st->pos = script_getnum(st, i + 1);
st->state = GOTO;
}
@@ -5996,7 +6169,7 @@ BUILDIN(menu)
/// select(<option_text>{,<option_text>,...}) -> <selected_option>
///
/// @see menu
-BUILDIN(select)
+static BUILDIN(select)
{
int i;
const char* text;
@@ -6027,11 +6200,11 @@ BUILDIN(select)
sd->state.menu_or_input = 1;
/* menus beyond this length crash the client (see bugreport:6402) */
- if( StrBuf->Length(&buf) >= 2047 ) {
+ if( StrBuf->Length(&buf) >= MAX_MENU_LENGTH - 1 ) {
struct npc_data * nd = map->id2nd(st->oid);
char* menu;
- CREATE(menu, char, 2048);
- safestrncpy(menu, StrBuf->Value(&buf), 2047);
+ CREATE(menu, char, MAX_MENU_LENGTH);
+ safestrncpy(menu, StrBuf->Value(&buf), MAX_MENU_LENGTH - 1);
ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StrBuf->Length(&buf));
clif->scriptmenu(sd, st->oid, menu);
aFree(menu);
@@ -6039,107 +6212,31 @@ BUILDIN(select)
clif->scriptmenu(sd, st->oid, StrBuf->Value(&buf));
StrBuf->Destroy(&buf);
- if( sd->npc_menu >= 0xff ) {
- ShowWarning("buildin_select: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
+ if( sd->npc_menu >= MAX_MENU_OPTIONS ) {
+ ShowWarning("buildin_select: Too many options specified (current=%d, max=%d).\n", sd->npc_menu, MAX_MENU_OPTIONS - 1);
script->reportsrc(st);
}
- } else if( sd->npc_menu == 0xff ) {// Cancel was pressed
+ } else if(sd->npc_menu == MAX_MENU_OPTIONS) { // Cancel was pressed
sd->state.menu_or_input = 0;
- st->state = END;
- } else {// return selected option
- int menu = 0;
-
- sd->state.menu_or_input = 0;
- for( i = 2; i <= script_lastdata(st); ++i ) {
- text = script_getstr(st, i);
- sd->npc_menu -= script->menu_countoptions(text, sd->npc_menu, &menu);
- if( sd->npc_menu <= 0 )
- break;// entry found
- }
- pc->setreg(sd, script->add_str("@menu"), menu);
- script_pushint(st, menu);
- st->state = RUN;
- }
- return true;
-}
-
-/// Displays a menu with options and returns the selected option.
-/// Behaves like 'menu' without the target labels, except when cancel is
-/// pressed.
-/// When cancel is pressed, the script continues and 255 is returned.
-///
-/// prompt(<option_text>{,<option_text>,...}) -> <selected_option>
-///
-/// @see menu
-BUILDIN(prompt)
-{
- int i;
- const char *text;
- struct map_session_data *sd = script->rid2sd(st);
- if (sd == NULL)
- return true;
-#ifdef SECURE_NPCTIMEOUT
- sd->npc_idle_type = NPCT_MENU;
-#endif
-
- if( sd->state.menu_or_input == 0 )
- {
- struct StringBuf buf;
-
- StrBuf->Init(&buf);
- sd->npc_menu = 0;
- for( i = 2; i <= script_lastdata(st); ++i )
- {
- text = script_getstr(st, i);
- if( sd->npc_menu > 0 )
- StrBuf->AppendStr(&buf, ":");
- StrBuf->AppendStr(&buf, text);
- sd->npc_menu += script->menu_countoptions(text, 0, NULL);
- }
-
- st->state = RERUNLINE;
- sd->state.menu_or_input = 1;
-
- /* menus beyond this length crash the client (see bugreport:6402) */
- if( StrBuf->Length(&buf) >= 2047 ) {
- struct npc_data * nd = map->id2nd(st->oid);
- char* menu;
- CREATE(menu, char, 2048);
- safestrncpy(menu, StrBuf->Value(&buf), 2047);
- ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StrBuf->Length(&buf));
- clif->scriptmenu(sd, st->oid, menu);
- aFree(menu);
- } else
- clif->scriptmenu(sd, st->oid, StrBuf->Value(&buf));
- StrBuf->Destroy(&buf);
-
- if( sd->npc_menu >= 0xff )
- {
- ShowWarning("buildin_prompt: Too many options specified (current=%d, max=254).\n", sd->npc_menu);
- script->reportsrc(st);
+ if (strncmp(get_buildin_name(st), "prompt", 6) == 0) {
+ pc->setreg(sd, script->add_variable("@menu"), MAX_MENU_OPTIONS);
+ script_pushint(st, MAX_MENU_OPTIONS); // XXX: we should really be pushing -1 instead
+ st->state = RUN;
+ } else {
+ st->state = END;
}
- }
- else if( sd->npc_menu == 0xff )
- {// Cancel was pressed
- sd->state.menu_or_input = 0;
- pc->setreg(sd, script->add_str("@menu"), 0xff);
- script_pushint(st, 0xff);
- st->state = RUN;
- }
- else
- {// return selected option
+ } else {// return selected option
int menu = 0;
sd->state.menu_or_input = 0;
- for( i = 2; i <= script_lastdata(st); ++i )
- {
+ for( i = 2; i <= script_lastdata(st); ++i ) {
text = script_getstr(st, i);
sd->npc_menu -= script->menu_countoptions(text, sd->npc_menu, &menu);
if( sd->npc_menu <= 0 )
break;// entry found
}
- pc->setreg(sd, script->add_str("@menu"), menu);
+ pc->setreg(sd, script->add_variable("@menu"), menu); // TODO: throw a deprecation warning for scripts using @menu
script_pushint(st, menu);
st->state = RUN;
}
@@ -6153,7 +6250,7 @@ BUILDIN(prompt)
/// Jumps to the target script label.
///
/// goto <label>;
-BUILDIN(goto)
+static BUILDIN(goto)
{
if( !data_islabel(script_getdata(st,2)) )
{
@@ -6171,7 +6268,7 @@ BUILDIN(goto)
/*==========================================
* user-defined function call
*------------------------------------------*/
-BUILDIN(callfunc)
+static BUILDIN(callfunc)
{
int i, j;
struct script_retinfo* ri;
@@ -6231,7 +6328,7 @@ BUILDIN(callfunc)
/*==========================================
* subroutine call
*------------------------------------------*/
-BUILDIN(callsub)
+static BUILDIN(callsub)
{
int i,j;
struct script_retinfo* ri;
@@ -6284,7 +6381,7 @@ BUILDIN(callsub)
/// If the argument doesn't exist
///
/// getarg(<index>{,<default_value>}) -> <value>
-BUILDIN(getarg)
+static BUILDIN(getarg)
{
struct script_retinfo* ri;
int idx;
@@ -6318,7 +6415,8 @@ BUILDIN(getarg)
///
/// return;
/// return <value>;
-BUILDIN(return) {
+static BUILDIN(return)
+{
st->state = RETFUNC;
if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp-1].type != C_RETINFO ) {
@@ -6368,7 +6466,7 @@ BUILDIN(return) {
/// If <min> is greater than <max>, their numbers are switched.
/// rand(<range>) -> <int>
/// rand(<min>,<max>) -> <int>
-BUILDIN(rand)
+static BUILDIN(rand)
{
int range;
int min;
@@ -6397,7 +6495,7 @@ BUILDIN(rand)
/*==========================================
* Warp sd to str,x,y or Random or SavePoint/Save
*------------------------------------------*/
-BUILDIN(warp)
+static BUILDIN(warp)
{
int ret;
int x,y;
@@ -6433,7 +6531,7 @@ BUILDIN(warp)
/*==========================================
* Warp a specified area
*------------------------------------------*/
-int buildin_areawarp_sub(struct block_list *bl, va_list ap)
+static int buildin_areawarp_sub(struct block_list *bl, va_list ap)
{
int x2,y2,x3,y3;
unsigned int index;
@@ -6474,7 +6572,7 @@ int buildin_areawarp_sub(struct block_list *bl, va_list ap)
}
return 0;
}
-BUILDIN(areawarp)
+static BUILDIN(areawarp)
{
int16 m, x0,y0,x1,y1, x2,y2,x3=0,y3=0;
unsigned int index;
@@ -6516,7 +6614,7 @@ BUILDIN(areawarp)
/*==========================================
* areapercentheal <map>,<x1>,<y1>,<x2>,<y2>,<hp>,<sp>
*------------------------------------------*/
-int buildin_areapercentheal_sub(struct block_list *bl, va_list ap)
+static int buildin_areapercentheal_sub(struct block_list *bl, va_list ap)
{
int hp = va_arg(ap, int);
int sp = va_arg(ap, int);
@@ -6530,7 +6628,8 @@ int buildin_areapercentheal_sub(struct block_list *bl, va_list ap)
return 0;
}
-BUILDIN(areapercentheal) {
+static BUILDIN(areapercentheal)
+{
int hp,sp,m;
const char *mapname;
int x0,y0,x1,y1;
@@ -6556,7 +6655,8 @@ BUILDIN(areapercentheal) {
* another player npc-session.
* Using: warpchar "mapname",x,y,Char_ID;
*------------------------------------------*/
-BUILDIN(warpchar) {
+static BUILDIN(warpchar)
+{
int x,y,a;
const char *str;
struct map_session_data *sd;
@@ -6581,11 +6681,12 @@ BUILDIN(warpchar) {
return true;
}
/*==========================================
- * Warpparty - [Fredzilla] [Paradox924X]
- * Syntax: warpparty "to_mapname",x,y,Party_ID,{"from_mapname"};
+ * Warpparty - [Fredzilla] [Paradox924X] [Jedzkie] [Dastgir]
+ * Syntax: warpparty("<to_mapname>", <x>, <y>, <party_id>, "<from_mapname>", <include_leader>)
* If 'from_mapname' is specified, only the party members on that map will be warped
+ * If 'include_leader' option is set to false, the leader will be warped too.
*------------------------------------------*/
-BUILDIN(warpparty)
+static BUILDIN(warpparty)
{
struct map_session_data *sd = NULL;
struct map_session_data *pl_sd;
@@ -6593,78 +6694,84 @@ BUILDIN(warpparty)
int type;
int map_index;
int i;
+ bool include_leader = true;
- const char* str = script_getstr(st,2);
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- int p_id = script_getnum(st,5);
+ const char* str = script_getstr(st, 2);
+ int x = script_getnum(st, 3);
+ int y = script_getnum(st, 4);
+ int p_id = script_getnum(st, 5);
const char* str2 = NULL;
- if ( script_hasdata(st,6) )
- str2 = script_getstr(st,6);
+
+ if (script_hasdata(st, 6))
+ str2 = script_getstr(st, 6);
+ if (script_hasdata(st, 7))
+ include_leader = script_getnum(st, 7);
p = party->search(p_id);
- if(!p)
+
+ if (p == NULL)
return true;
- type = ( strcmp(str,"Random")==0 ) ? 0
- : ( strcmp(str,"SavePointAll")==0 ) ? 1
- : ( strcmp(str,"SavePoint")==0 ) ? 2
- : ( strcmp(str,"Leader")==0 ) ? 3
+ type = (strcmp(str, "Random") == 0) ? 0
+ : (strcmp(str, "SavePointAll") == 0) ? 1
+ : (strcmp(str, "SavePoint") == 0) ? 2
+ : (strcmp(str, "Leader") == 0) ? 3
: 4;
- switch (type)
- {
- case 3:
- for(i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++);
- if (i == MAX_PARTY || !p->data[i].sd) //Leader not found / not online
- return true;
- pl_sd = p->data[i].sd;
- map_index = pl_sd->mapindex;
- x = pl_sd->bl.x;
- y = pl_sd->bl.y;
- break;
- case 4:
- map_index = script->mapindexname2id(st,str);
- break;
- case 2:
- //"SavePoint" uses save point of the currently attached player
- if (( sd = script->rid2sd(st) ) == NULL )
- return true;
- /* Fall through */
- default:
- map_index = 0;
- break;
+ switch (type) {
+ case 3:
+ ARR_FIND(0, MAX_PARTY, i, p->party.member[i].leader);
+ if (i == MAX_PARTY || !p->data[i].sd) // Leader not found / not online
+ return true;
+ pl_sd = p->data[i].sd;
+ map_index = pl_sd->mapindex;
+ x = pl_sd->bl.x;
+ y = pl_sd->bl.y;
+ break;
+ case 4:
+ map_index = script->mapindexname2id(st, str);
+ break;
+ case 2:
+ // "SavePoint" uses save point of the currently attached player
+ if ((sd = script->rid2sd(st)) == NULL)
+ return true;
+ /* Fall through */
+ default:
+ map_index = 0;
+ break;
}
for (i = 0; i < MAX_PARTY; i++) {
- if( !(pl_sd = p->data[i].sd) || pl_sd->status.party_id != p_id )
+ if (!(pl_sd = p->data[i].sd) || pl_sd->status.party_id != p_id)
continue;
- if( str2 && strcmp(str2, map->list[pl_sd->bl.m].name) != 0 )
+ if (str2 && strcmp(str2, map->list[pl_sd->bl.m].name) != 0)
continue;
- if( pc_isdead(pl_sd) )
+ if (pc_isdead(pl_sd))
continue;
- switch( type )
- {
- case 0: // Random
- if(!map->list[pl_sd->bl.m].flag.nowarp)
- pc->randomwarp(pl_sd,CLR_TELEPORT);
- break;
- case 1: // SavePointAll
- if(!map->list[pl_sd->bl.m].flag.noreturn)
- pc->setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT);
- break;
- case 2: // SavePoint
- if(!map->list[pl_sd->bl.m].flag.noreturn)
- pc->setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- break;
- case 3: // Leader
- case 4: // m,x,y
- if(!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp)
- pc->setpos(pl_sd,map_index,x,y,CLR_TELEPORT);
- break;
+ if (include_leader == false && p->party.member[i].leader)
+ continue;
+
+ switch( type ) {
+ case 0: // Random
+ if (!map->list[pl_sd->bl.m].flag.nowarp)
+ pc->randomwarp(pl_sd, CLR_TELEPORT);
+ break;
+ case 1: // SavePointAll
+ if (!map->list[pl_sd->bl.m].flag.noreturn)
+ pc->setpos(pl_sd, pl_sd->status.save_point.map, pl_sd->status.save_point.x, pl_sd->status.save_point.y, CLR_TELEPORT);
+ break;
+ case 2: // SavePoint
+ if (!map->list[pl_sd->bl.m].flag.noreturn)
+ pc->setpos(pl_sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
+ break;
+ case 3: // Leader
+ case 4: // m,x,y
+ if (!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp)
+ pc->setpos(pl_sd, map_index, x, y, CLR_TELEPORT);
+ break;
}
}
@@ -6674,7 +6781,7 @@ BUILDIN(warpparty)
* Warpguild - [Fredzilla]
* Syntax: warpguild "mapname",x,y,Guild_ID,{"from_mapname"};
*------------------------------------------*/
-BUILDIN(warpguild)
+static BUILDIN(warpguild)
{
struct map_session_data *sd = NULL;
struct guild* g;
@@ -6739,7 +6846,7 @@ BUILDIN(warpguild)
/*==========================================
* Force Heal a player (hp and sp)
*------------------------------------------*/
-BUILDIN(heal)
+static BUILDIN(heal)
{
int hp,sp;
struct map_session_data *sd = script->rid2sd(st);
@@ -6748,13 +6855,13 @@ BUILDIN(heal)
hp=script_getnum(st,2);
sp=script_getnum(st,3);
- status->heal(&sd->bl, hp, sp, 1);
+ status->heal(&sd->bl, hp, sp, STATUS_HEAL_FORCED);
return true;
}
/*==========================================
* Heal a player by item (get vit bonus etc)
*------------------------------------------*/
-BUILDIN(itemheal)
+static BUILDIN(itemheal)
{
struct map_session_data *sd;
int hp,sp;
@@ -6777,7 +6884,7 @@ BUILDIN(itemheal)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(percentheal)
+static BUILDIN(percentheal)
{
int hp,sp;
struct map_session_data *sd;
@@ -6808,7 +6915,7 @@ BUILDIN(percentheal)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(jobchange)
+static BUILDIN(jobchange)
{
int class, upper=-1;
@@ -6830,7 +6937,7 @@ BUILDIN(jobchange)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(jobname)
+static BUILDIN(jobname)
{
int class = script_getnum(st,2);
script_pushconststr(st, pc->job_name(class));
@@ -6844,7 +6951,7 @@ BUILDIN(jobname)
/// shorter than 'min' and 0 otherwise.
///
/// input(<var>{,<min>{,<max>}}) -> <int>
-BUILDIN(input)
+static BUILDIN(input)
{
struct script_data* data;
int64 uid;
@@ -6897,13 +7004,13 @@ BUILDIN(input)
}
// declare the copyarray method here for future reference
-BUILDIN(copyarray);
+static BUILDIN(copyarray);
/// Sets the value of a variable.
/// The value is converted to the type of the variable.
///
/// set(<variable>,<value>) -> <variable>
-BUILDIN(__setr)
+static BUILDIN(__setr)
{
struct map_session_data *sd = NULL;
struct script_data* data;
@@ -6911,6 +7018,7 @@ BUILDIN(__setr)
int64 num;
const char* name;
char prefix;
+ struct reg_db *ref;
data = script_getdata(st,2);
//datavalue = script_getdata(st,3);
@@ -6923,11 +7031,11 @@ BUILDIN(__setr)
num = reference_getuid(data);
name = reference_getname(data);
+ ref = reference_getref(data);
prefix = *name;
if (not_server_variable(prefix)) {
- sd = script->rid2sd(st);
- if (sd == NULL) {
+ if (ref == NULL && (sd = script->rid2sd(st)) == NULL) {
ShowError("script:set: no player attached for player variable '%s'\n", name);
return true;
}
@@ -6975,9 +7083,9 @@ BUILDIN(__setr)
}
if (is_string_variable(name))
- script->set_reg(st, sd, num, name, script_getstr(st, 3), script_getref(st, 2));
+ script->set_reg(st, sd, num, name, script_getstr(st, 3), ref);
else
- script->set_reg(st, sd, num, name, (const void *)h64BPTRSIZE(script_getnum(st, 3)), script_getref(st, 2));
+ script->set_reg(st, sd, num, name, (const void *)h64BPTRSIZE(script_getnum(st, 3)), ref);
return true;
}
@@ -6990,7 +7098,7 @@ BUILDIN(__setr)
/// ex: setarray arr[1],1,2,3;
///
/// setarray <array variable>,<value1>{,<value2>...};
-BUILDIN(setarray)
+static BUILDIN(setarray)
{
struct script_data* data;
const char* name;
@@ -7040,7 +7148,7 @@ BUILDIN(setarray)
/// ex: cleararray arr[0],0,1;
///
/// cleararray <array variable>,<value>,<count>;
-BUILDIN(cleararray)
+static BUILDIN(cleararray)
{
struct script_data* data;
const char* name;
@@ -7088,7 +7196,7 @@ BUILDIN(cleararray)
/// ex: copyarray arr[0],arr[2],2;
///
/// copyarray <destination array variable>,<source array variable>,<count>;
-BUILDIN(copyarray)
+static BUILDIN(copyarray)
{
struct script_data* data1;
struct script_data* data2;
@@ -7175,7 +7283,7 @@ BUILDIN(copyarray)
/// ex: getarraysize(arr[3])
///
/// getarraysize(<array variable>) -> <int>
-BUILDIN(getarraysize)
+static BUILDIN(getarraysize)
{
struct script_data* data;
@@ -7192,17 +7300,33 @@ BUILDIN(getarraysize)
script_pushint(st, script->array_highest_key(st,st->rid ? script->rid2sd(st) : NULL,reference_getname(data),reference_getref(data)));
return true;
}
-int script_array_index_cmp(const void *a, const void *b)
+static int script_array_index_cmp(const void *a, const void *b)
{
return (*(const unsigned int *)a - *(const unsigned int *)b); // FIXME: Is the unsigned difference really intended here?
}
+static BUILDIN(getarrayindex)
+{
+ struct script_data *data = script_getdata(st, 2);
+
+ if (!data_isreference(data) || reference_toconstant(data))
+ {
+ ShowError("script:getarrayindex: not a variable\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;// not a variable
+ }
+
+ script_pushint(st, reference_getindex(data));
+ return true;
+}
+
/// Deletes count or all the elements in an array, from the starting index.
/// ex: deletearray arr[4],2;
///
/// deletearray <array variable>;
/// deletearray <array variable>,<count>;
-BUILDIN(deletearray)
+static BUILDIN(deletearray)
{
struct script_data* data;
const char* name;
@@ -7316,7 +7440,7 @@ BUILDIN(deletearray)
/// Equivalent to var[index].
///
/// getelementofarray(<array variable>,<index>) -> <variable reference>
-BUILDIN(getelementofarray)
+static BUILDIN(getelementofarray)
{
struct script_data* data;
int32 id;
@@ -7335,7 +7459,7 @@ BUILDIN(getelementofarray)
id = reference_getid(data);
i = script_getnum(st, 3);
- if (i < 0 || i >= SCRIPT_MAX_ARRAYSIZE) {
+ if (i < 0 || i > SCRIPT_MAX_ARRAYSIZE) {
ShowWarning("script:getelementofarray: index out of range (%"PRId64")\n", i);
script->reportdata(data);
script_pushnil(st);
@@ -7354,7 +7478,7 @@ BUILDIN(getelementofarray)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(setlook)
+static BUILDIN(setlook)
{
int type,val;
struct map_session_data *sd;
@@ -7371,7 +7495,7 @@ BUILDIN(setlook)
return true;
}
-BUILDIN(changelook)
+static BUILDIN(changelook)
{ // As setlook but only client side
int type,val;
struct map_session_data *sd;
@@ -7391,7 +7515,7 @@ BUILDIN(changelook)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(cutin)
+static BUILDIN(cutin)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -7404,7 +7528,7 @@ BUILDIN(cutin)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(viewpoint)
+static BUILDIN(viewpoint)
{
int type,x,y,id,color;
struct map_session_data *sd;
@@ -7427,8 +7551,8 @@ BUILDIN(viewpoint)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(countitem) {
- int nameid, i;
+static BUILDIN(countitem)
+{
int count = 0;
struct item_data* id = NULL;
@@ -7450,11 +7574,12 @@ BUILDIN(countitem) {
return false;
}
- nameid = id->nameid;
+ int nameid = id->nameid;
- for(i = 0; i < MAX_INVENTORY; i++)
- if(sd->status.inventory[i].nameid == nameid)
+ for (int i = 0; i < sd->status.inventorySize; i++) {
+ if (sd->status.inventory[i].nameid == nameid)
count += sd->status.inventory[i].amount;
+ }
script_pushint(st,count);
return true;
@@ -7464,10 +7589,10 @@ BUILDIN(countitem) {
* countitem2(nameID,Identified,Refine,Attribute,Card0,Card1,Card2,Card3) [Lupus]
* returns number of items that meet the conditions
*------------------------------------------*/
-BUILDIN(countitem2) {
+static BUILDIN(countitem2)
+{
int nameid, iden, ref, attr, c1, c2, c3, c4;
int count = 0;
- int i;
struct item_data* id = NULL;
struct map_session_data *sd = script->rid2sd(st);
@@ -7492,12 +7617,12 @@ BUILDIN(countitem2) {
iden = script_getnum(st,3);
ref = script_getnum(st,4);
attr = script_getnum(st,5);
- c1 = (short)script_getnum(st,6);
- c2 = (short)script_getnum(st,7);
- c3 = (short)script_getnum(st,8);
- c4 = (short)script_getnum(st,9);
+ c1 = script_getnum(st,6);
+ c2 = script_getnum(st,7);
+ c3 = script_getnum(st,8);
+ c4 = script_getnum(st,9);
- for(i = 0; i < MAX_INVENTORY; i++)
+ for (int i = 0; i < sd->status.inventorySize; 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 &&
sd->status.inventory[i].identify == iden && sd->status.inventory[i].refine == ref &&
@@ -7518,7 +7643,7 @@ BUILDIN(countitem2) {
* 0 : fail
* 1 : success (npc side only)
*------------------------------------------*/
-BUILDIN(checkweight)
+static BUILDIN(checkweight)
{
int slots, amount2=0;
unsigned int weight=0, i, nbargs;
@@ -7600,7 +7725,7 @@ BUILDIN(checkweight)
return true;
}
-BUILDIN(checkweight2)
+static BUILDIN(checkweight2)
{
//variable sub checkweight
int i=0, amount2=0, slots=0, weight=0;
@@ -7704,7 +7829,8 @@ BUILDIN(checkweight2)
* getitembound <item id>,<amount>,<type>{,<account ID>};
* getitembound "<item id>",<amount>,<type>{,<account ID>};
*------------------------------------------*/
-BUILDIN(getitem) {
+static BUILDIN(getitem)
+{
int nameid,amount,get_count,i,flag = 0, offset = 0;
struct item it;
struct map_session_data *sd;
@@ -7778,7 +7904,7 @@ BUILDIN(getitem) {
if ((flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT))) {
clif->additem(sd, 0, 0, flag);
if( pc->candrop(sd,&it) )
- map->addflooritem(&sd->bl, &it, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
+ map->addflooritem(&sd->bl, &it, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
}
}
}
@@ -7789,7 +7915,7 @@ BUILDIN(getitem) {
/*==========================================
*
*------------------------------------------*/
-BUILDIN(getitem2)
+static BUILDIN(getitem2)
{
int nameid,amount,flag = 0, offset = 0;
int iden,ref,attr,c1,c2,c3,c4, bound = 0;
@@ -7827,10 +7953,10 @@ BUILDIN(getitem2)
iden=script_getnum(st,4);
ref=script_getnum(st,5);
attr=script_getnum(st,6);
- c1=(short)script_getnum(st,7);
- c2=(short)script_getnum(st,8);
- c3=(short)script_getnum(st,9);
- c4=(short)script_getnum(st,10);
+ c1 = script_getnum(st,7);
+ c2 = script_getnum(st,8);
+ c3 = script_getnum(st,9);
+ c4 = script_getnum(st,10);
if (bound && (itemdb_type(nameid) == IT_PETEGG || itemdb_type(nameid) == IT_PETARMOR)) {
ShowError("script_getitembound2: can't bind a pet egg/armor! Type=%d\n",bound);
@@ -7869,10 +7995,10 @@ BUILDIN(getitem2)
item_tmp.refine=ref;
item_tmp.attribute=attr;
item_tmp.bound=(unsigned char)bound;
- item_tmp.card[0]=(short)c1;
- item_tmp.card[1]=(short)c2;
- item_tmp.card[2]=(short)c3;
- item_tmp.card[3]=(short)c4;
+ item_tmp.card[0] = c1;
+ item_tmp.card[1] = c2;
+ item_tmp.card[2] = c3;
+ item_tmp.card[3] = c4;
//Check if it's stackable.
if (!itemdb->isstackable(nameid))
@@ -7886,7 +8012,7 @@ BUILDIN(getitem2)
if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
clif->additem(sd, 0, 0, flag);
if( pc->candrop(sd,&item_tmp) )
- map->addflooritem(&sd->bl, &item_tmp, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
+ map->addflooritem(&sd->bl, &item_tmp, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
}
}
}
@@ -7899,7 +8025,8 @@ BUILDIN(getitem2)
* rentitem <item id>,<seconds>
* rentitem "<item name>",<seconds>
*------------------------------------------*/
-BUILDIN(rentitem) {
+static BUILDIN(rentitem)
+{
struct map_session_data *sd;
struct item it;
int seconds;
@@ -7947,7 +8074,8 @@ BUILDIN(rentitem) {
* Returned Qty is always 1, only works on equip-able
* equipment
*------------------------------------------*/
-BUILDIN(getnameditem) {
+static BUILDIN(getnameditem)
+{
int nameid;
struct item item_tmp;
struct map_session_data *sd, *tsd;
@@ -8006,7 +8134,8 @@ BUILDIN(getnameditem) {
* gets a random item ID from an item group [Skotlex]
* groupranditem group_num
*------------------------------------------*/
-BUILDIN(grouprandomitem) {
+static BUILDIN(grouprandomitem)
+{
struct item_data *data;
int nameid;
@@ -8036,7 +8165,7 @@ BUILDIN(grouprandomitem) {
/*==========================================
*
*------------------------------------------*/
-BUILDIN(makeitem)
+static BUILDIN(makeitem)
{
int nameid,amount;
int x,y,m;
@@ -8079,15 +8208,15 @@ BUILDIN(makeitem)
item_tmp.nameid = nameid;
item_tmp.identify=1;
- map->addflooritem(NULL, &item_tmp, amount, m, x, y, 0, 0, 0, 0);
+ map->addflooritem(NULL, &item_tmp, amount, m, x, y, 0, 0, 0, 0, false);
return true;
}
/*==========================================
-* makeitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,{"<map name>",<X>,<Y>,<range>};
-*------------------------------------------*/
-BUILDIN(makeitem2)
+ * makeitem2 <item id>, <amount>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>, {"<map name>", <X>, <Y>, <range>};
+ *------------------------------------------*/
+static BUILDIN(makeitem2)
{
struct map_session_data *sd = NULL;
struct item_data *i_data;
@@ -8136,7 +8265,7 @@ BUILDIN(makeitem2)
map->search_freecell(NULL, m, &x, &y, -1, -1, 1);
} else {
range = (script_hasdata(st, 14) ? cap_value(script_getnum(st, 14), 1, battle_config.area_size) : 3);
- map->search_freecell(&sd->bl, sd->bl.m, &x, &y, range, range, 0); // Locate spot next to player.
+ map->search_freecell(&sd->bl, sd->bl.m, &x, &y, range, range, 0); // Locate spot next to player.
}
}
@@ -8158,12 +8287,12 @@ BUILDIN(makeitem2)
item_tmp.identify = script_getnum(st, 4);
item_tmp.refine = cap_value(script_getnum(st, 5), 0, MAX_REFINE);
item_tmp.attribute = script_getnum(st, 6);
- item_tmp.card[0] = (short)script_getnum(st, 7);
- item_tmp.card[1] = (short)script_getnum(st, 8);
- item_tmp.card[2] = (short)script_getnum(st, 9);
- item_tmp.card[3] = (short)script_getnum(st, 10);
+ item_tmp.card[0] = script_getnum(st, 7);
+ item_tmp.card[1] = script_getnum(st, 8);
+ item_tmp.card[2] = script_getnum(st, 9);
+ item_tmp.card[3] = script_getnum(st, 10);
- map->addflooritem(NULL, &item_tmp, amount, m, x, y, 0, 0, 0, 0);
+ map->addflooritem(NULL, &item_tmp, amount, m, x, y, 0, 0, 0, 0, false);
return true;
}
@@ -8171,7 +8300,7 @@ BUILDIN(makeitem2)
/// Counts / deletes the current item given by idx.
/// Used by buildin_delitem_search
/// Relies on all input data being already fully valid.
-void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, bool delete_items)
+static void buildin_delitem_delete(struct map_session_data *sd, int idx, int *amount, bool delete_items)
{
int delamount;
struct item* inv;
@@ -8199,7 +8328,7 @@ void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, b
/// Relies on all input data being already fully valid.
/// @param exact_match will also match item attributes and cards, not just name id
/// @return true when all items could be deleted, false when there were not enough items to delete
-bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool exact_match)
+static bool buildin_delitem_search(struct map_session_data *sd, struct item *it, bool exact_match)
{
bool delete_items = false;
int i, amount;
@@ -8308,7 +8437,7 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e
///
/// delitem <item id>,<amount>{,<account id>}
/// delitem "<item name>",<amount>{,<account id>}
-BUILDIN(delitem)
+static BUILDIN(delitem)
{
struct map_session_data *sd;
struct item it;
@@ -8365,7 +8494,7 @@ BUILDIN(delitem)
///
/// delitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
/// delitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
-BUILDIN(delitem2)
+static BUILDIN(delitem2)
{
struct map_session_data *sd;
struct item it;
@@ -8406,10 +8535,10 @@ BUILDIN(delitem2)
it.identify=script_getnum(st,4);
it.refine=script_getnum(st,5);
it.attribute=script_getnum(st,6);
- it.card[0]=(short)script_getnum(st,7);
- it.card[1]=(short)script_getnum(st,8);
- it.card[2]=(short)script_getnum(st,9);
- it.card[3]=(short)script_getnum(st,10);
+ it.card[0] = script_getnum(st, 7);
+ it.card[1] = script_getnum(st, 8);
+ it.card[2] = script_getnum(st, 9);
+ it.card[3] = script_getnum(st, 10);
if( it.amount <= 0 )
return true;// nothing to do
@@ -8428,7 +8557,7 @@ BUILDIN(delitem2)
/*==========================================
* Enables/Disables use of items while in an NPC [Skotlex]
*------------------------------------------*/
-BUILDIN(enableitemuse)
+static BUILDIN(enableitemuse)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd != NULL)
@@ -8436,7 +8565,7 @@ BUILDIN(enableitemuse)
return true;
}
-BUILDIN(disableitemuse)
+static BUILDIN(disableitemuse)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd != NULL)
@@ -8448,23 +8577,71 @@ BUILDIN(disableitemuse)
* return the basic stats of sd
* chk pc->readparam for available type
*------------------------------------------*/
-BUILDIN(readparam) {
+static BUILDIN(readparam)
+{
int type;
struct map_session_data *sd;
+ struct script_data *data = script_getdata(st, 2);
- type=script_getnum(st,2);
- if (script_hasdata(st,3))
- sd = script->nick2sd(st, script_getstr(st,3));
- else
- sd=script->rid2sd(st);
+ if (reference_toparam(data)) {
+ type = reference_getparamtype(data);
+ } else {
+ type = script->conv_num(st, data);
+ }
+
+ if (script_hasdata(st, 3)) {
+ if (script_isstringtype(st, 3)) {
+ sd = script->nick2sd(st, script_getstr(st, 3));
+ } else {
+ sd = script->id2sd(st, script_getnum(st, 3));
+ }
+ } else {
+ sd = script->rid2sd(st);
+ }
if (sd == NULL) {
- script_pushint(st,-1);
+ script_pushint(st, -1);
return true;
}
- script_pushint(st,pc->readparam(sd,type));
+ script_pushint(st, pc->readparam(sd, type));
+ return true;
+}
+
+static BUILDIN(setparam)
+{
+ int type;
+ struct map_session_data *sd;
+ struct script_data *data = script_getdata(st, 2);
+ int val = script_getnum(st, 3);
+
+ if (data_isreference(data) && reference_toparam(data)) {
+ type = reference_getparamtype(data);
+ } else {
+ type = script->conv_num(st, data);
+ }
+
+ if (script_hasdata(st, 4)) {
+ if (script_isstringtype(st, 4)) {
+ sd = script->nick2sd(st, script_getstr(st, 4));
+ } else {
+ sd = script->id2sd(st, script_getnum(st, 4));
+ }
+ } else {
+ sd = script->rid2sd(st);
+ }
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ return true;
+ }
+
+ if (pc->setparam(sd, type, val) == 0) {
+ script_pushint(st, 0);
+ return false;
+ }
+
+ script_pushint(st, 1);
return true;
}
@@ -8476,62 +8653,67 @@ BUILDIN(readparam) {
* 2 : guild_id
* 3 : account_id
* 4 : bg_id
+ * 5 : clan_id
*------------------------------------------*/
-BUILDIN(getcharid) {
- int num;
+static BUILDIN(getcharid)
+{
+ int num = script_getnum(st, 2);
struct map_session_data *sd;
- num = script_getnum(st,2);
- if( script_hasdata(st,3) )
- sd=map->nick2sd(script_getstr(st,3));
+ if (script_hasdata(st, 3))
+ sd = map->nick2sd(script_getstr(st, 3));
else
- sd=script->rid2sd(st);
+ sd = script->rid2sd(st);
- if(sd==NULL) {
- script_pushint(st,0); //return 0, according docs
+ if (sd == NULL) {
+ script_pushint(st, 0); //return 0, according docs
return true;
}
- switch( num ) {
- case 0: script_pushint(st,sd->status.char_id); break;
- case 1: script_pushint(st,sd->status.party_id); break;
- case 2: script_pushint(st,sd->status.guild_id); break;
- case 3: script_pushint(st,sd->status.account_id); break;
- case 4: script_pushint(st,sd->bg_id); break;
- default:
- ShowError("buildin_getcharid: invalid parameter (%d).\n", num);
- script_pushint(st,0);
- break;
+ switch (num) {
+ case 0:
+ script_pushint(st, sd->status.char_id);
+ break;
+ case 1:
+ script_pushint(st, sd->status.party_id);
+ break;
+ case 2:
+ script_pushint(st, sd->status.guild_id);
+ break;
+ case 3:
+ script_pushint(st, sd->status.account_id);
+ break;
+ case 4:
+ script_pushint(st, sd->bg_id);
+ break;
+ case 5:
+ script_pushint(st, sd->status.clan_id);
+ break;
+ default:
+ ShowError("buildin_getcharid: invalid parameter (%d).\n", num);
+ script_pushint(st, 0);
+ break;
}
return true;
}
+
/*==========================================
* returns the GID of an NPC
*------------------------------------------*/
-BUILDIN(getnpcid)
+static BUILDIN(getnpcid)
{
- int num = script_getnum(st,2);
- struct npc_data* nd = NULL;
-
- if( script_hasdata(st,3) )
- {// unique npc name
- if( ( nd = npc->name2id(script_getstr(st,3)) ) == NULL )
- {
- ShowError("buildin_getnpcid: No such NPC '%s'.\n", script_getstr(st,3));
- script_pushint(st,0);
- return false;
+ if (script_hasdata(st, 2)) {
+ if (script_isinttype(st, 2)) {
+ // Deprecate old form - getnpcid(<type>{, <"npc name">})
+ ShowWarning("buildin_getnpcid: Use of type is deprecated. Format - getnpcid({<\"npc name\">})\n");
+ script_pushint(st, 0);
+ } else {
+ struct npc_data *nd = npc->name2id(script_getstr(st, 2));
+ script_pushint(st, (nd != NULL) ? nd->bl.id : 0);
}
- }
-
- switch (num) {
- case 0:
- script_pushint(st,nd ? nd->bl.id : st->oid);
- break;
- default:
- ShowError("buildin_getnpcid: invalid parameter (%d).\n", num);
- script_pushint(st,0);
- return false;
+ } else {
+ script_pushint(st, st->oid);
}
return true;
@@ -8541,7 +8723,7 @@ BUILDIN(getnpcid)
* Return the name of the party_id
* null if not found
*------------------------------------------*/
-BUILDIN(getpartyname)
+static BUILDIN(getpartyname)
{
int party_id;
struct party_data* p;
@@ -8567,7 +8749,7 @@ BUILDIN(getpartyname)
* 1 : char_id des membres
* 2 : account_id des membres
*------------------------------------------*/
-BUILDIN(getpartymember)
+static BUILDIN(getpartymember)
{
struct party_data *p;
int j=0,type=0;
@@ -8583,19 +8765,19 @@ BUILDIN(getpartymember)
if(p->party.member[i].account_id) {
switch (type) {
case 2:
- mapreg->setreg(reference_uid(script->add_str("$@partymemberaid"), j),p->party.member[i].account_id);
+ mapreg->setreg(reference_uid(script->add_variable("$@partymemberaid"), j),p->party.member[i].account_id);
break;
case 1:
- mapreg->setreg(reference_uid(script->add_str("$@partymembercid"), j),p->party.member[i].char_id);
+ mapreg->setreg(reference_uid(script->add_variable("$@partymembercid"), j),p->party.member[i].char_id);
break;
default:
- mapreg->setregstr(reference_uid(script->add_str("$@partymembername$"), j),p->party.member[i].name);
+ mapreg->setregstr(reference_uid(script->add_variable("$@partymembername$"), j),p->party.member[i].name);
}
j++;
}
}
}
- mapreg->setreg(script->add_str("$@partymembercount"),j);
+ mapreg->setreg(script->add_variable("$@partymembercount"),j);
return true;
}
@@ -8604,7 +8786,7 @@ BUILDIN(getpartymember)
* Retrieves party leader. if flag is specified,
* return some of the leader data. Otherwise, return name.
*------------------------------------------*/
-BUILDIN(getpartyleader)
+static BUILDIN(getpartyleader)
{
int party_id, type = 0, i=0;
struct party_data *p;
@@ -8641,7 +8823,7 @@ BUILDIN(getpartyleader)
* Return the name of the @guild_id
* null if not found
*------------------------------------------*/
-BUILDIN(getguildname)
+static BUILDIN(getguildname)
{
int guild_id;
struct guild* g;
@@ -8663,7 +8845,7 @@ BUILDIN(getguildname)
* Return the name of the guild master of @guild_id
* null if not found
*------------------------------------------*/
-BUILDIN(getguildmaster)
+static BUILDIN(getguildmaster)
{
int guild_id;
struct guild* g;
@@ -8681,7 +8863,7 @@ BUILDIN(getguildmaster)
return true;
}
-BUILDIN(getguildmasterid)
+static BUILDIN(getguildmasterid)
{
int guild_id;
struct guild* g;
@@ -8708,7 +8890,7 @@ BUILDIN(getguildmasterid)
* 1 : character ID
* 2 : account ID
*------------------------------------------*/
-BUILDIN(getguildmember)
+static BUILDIN(getguildmember)
{
struct guild *g = NULL;
int j = 0;
@@ -8725,20 +8907,20 @@ BUILDIN(getguildmember)
if ( g->member[i].account_id ) {
switch (type) {
case 2:
- mapreg->setreg(reference_uid(script->add_str("$@guildmemberaid"), j),g->member[i].account_id);
+ mapreg->setreg(reference_uid(script->add_variable("$@guildmemberaid"), j),g->member[i].account_id);
break;
case 1:
- mapreg->setreg(reference_uid(script->add_str("$@guildmembercid"), j), g->member[i].char_id);
+ mapreg->setreg(reference_uid(script->add_variable("$@guildmembercid"), j), g->member[i].char_id);
break;
default:
- mapreg->setregstr(reference_uid(script->add_str("$@guildmembername$"), j), g->member[i].name);
+ mapreg->setregstr(reference_uid(script->add_variable("$@guildmembername$"), j), g->member[i].name);
break;
}
j++;
}
}
}
- mapreg->setreg(script->add_str("$@guildmembercount"), j);
+ mapreg->setreg(script->add_variable("$@guildmembercount"), j);
return true;
}
@@ -8749,10 +8931,12 @@ BUILDIN(getguildmember)
* 1 : party_name or ""
* 2 : guild_name or ""
* 3 : map_name
+ * 4 : clan_name or ""
* - : ""
*------------------------------------------*/
-BUILDIN(strcharinfo)
+static BUILDIN(strcharinfo)
{
+ struct clan *c;
struct guild* g;
struct party_data* p;
struct map_session_data *sd;
@@ -8792,6 +8976,13 @@ BUILDIN(strcharinfo)
case 3:
script_pushconststr(st, map->list[sd->bl.m].name);
break;
+ case 4:
+ if ((c = sd->clan) != NULL) {
+ script_pushstrcopy(st, c->name);
+ } else {
+ script_pushconststr(st, "");
+ }
+ break;
default:
ShowWarning("script:strcharinfo: unknown parameter.\n");
script_pushconststr(st, "");
@@ -8809,7 +9000,7 @@ BUILDIN(strcharinfo)
* 3 : ::str
* 4 : map name
*------------------------------------------*/
-BUILDIN(strnpcinfo)
+static BUILDIN(strnpcinfo)
{
char *buf,*name=NULL;
struct npc_data *nd;
@@ -8866,7 +9057,7 @@ BUILDIN(strnpcinfo)
/**
* charid2rid: Returns the RID associated to the given character ID
*/
-BUILDIN(charid2rid)
+static BUILDIN(charid2rid)
{
int cid = script_getnum(st, 2);
struct map_session_data *sd = map->charid2sd(cid);
@@ -8883,7 +9074,7 @@ BUILDIN(charid2rid)
/*==========================================
* GetEquipID(Pos); Pos: 1-SCRIPT_EQUIP_TABLE_SIZE
*------------------------------------------*/
-BUILDIN(getequipid)
+static BUILDIN(getequipid)
{
int i, num;
struct item_data* item;
@@ -8919,7 +9110,7 @@ BUILDIN(getequipid)
* Get the equipement name at pos
* return item jname or ""
*------------------------------------------*/
-BUILDIN(getequipname)
+static BUILDIN(getequipname)
{
int i, num;
struct item_data* item;
@@ -8954,15 +9145,17 @@ BUILDIN(getequipname)
/*==========================================
* getbrokenid [Valaris]
*------------------------------------------*/
-BUILDIN(getbrokenid)
+static BUILDIN(getbrokenid)
{
- int i,num,id=0,brokencounter=0;
+ int num,id=0,brokencounter=0;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
num=script_getnum(st,2);
- for(i=0; i<MAX_INVENTORY; i++) {
+ for (int i = 0; i < sd->status.inventorySize; i++) {
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if ((sd->status.inventory[i].attribute & ATTR_BROKEN) != 0) {
brokencounter++;
if(num==brokencounter) {
@@ -8980,14 +9173,16 @@ BUILDIN(getbrokenid)
/*==========================================
* getbrokencount
*------------------------------------------*/
-BUILDIN(getbrokencount)
+static BUILDIN(getbrokencount)
{
int i, counter = 0;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
- for (i = 0; i < MAX_INVENTORY; i++) {
+ for (i = 0; i < sd->status.inventorySize; i++) {
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if ((sd->status.inventory[i].attribute & ATTR_BROKEN) != 0)
counter++;
}
@@ -9000,22 +9195,23 @@ BUILDIN(getbrokencount)
/*==========================================
* repair [Valaris]
*------------------------------------------*/
-BUILDIN(repair)
+static BUILDIN(repair)
{
- int i,num;
int repaircounter=0;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
- num=script_getnum(st,2);
- for(i=0; i<MAX_INVENTORY; i++) {
+ int num = script_getnum(st, 2);
+ for(int i = 0; i < sd->status.inventorySize; i++) {
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if ((sd->status.inventory[i].attribute & ATTR_BROKEN) != 0) {
repaircounter++;
if(num==repaircounter) {
sd->status.inventory[i].attribute |= ATTR_BROKEN;
sd->status.inventory[i].attribute ^= ATTR_BROKEN;
- clif->equiplist(sd);
+ clif->equipList(sd);
clif->produce_effect(sd, 0, sd->status.inventory[i].nameid);
clif->misceffect(&sd->bl, 3);
break;
@@ -9029,15 +9225,17 @@ BUILDIN(repair)
/*==========================================
* repairall
*------------------------------------------*/
-BUILDIN(repairall)
+static BUILDIN(repairall)
{
- int i, repaircounter = 0;
+ int repaircounter = 0;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
- for(i = 0; i < MAX_INVENTORY; i++)
+ for (int i = 0; i < sd->status.inventorySize; i++)
{
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if (sd->status.inventory[i].nameid && (sd->status.inventory[i].attribute & ATTR_BROKEN) != 0)
{
sd->status.inventory[i].attribute |= ATTR_BROKEN;
@@ -9050,7 +9248,7 @@ BUILDIN(repairall)
if(repaircounter)
{
clif->misceffect(&sd->bl, 3);
- clif->equiplist(sd);
+ clif->equipList(sd);
}
return true;
@@ -9059,7 +9257,7 @@ BUILDIN(repairall)
/*==========================================
* Chk if player have something equiped at pos
*------------------------------------------*/
-BUILDIN(getequipisequiped)
+static BUILDIN(getequipisequiped)
{
int i = -1,num;
struct map_session_data *sd;
@@ -9086,7 +9284,7 @@ BUILDIN(getequipisequiped)
* 1 : true
* 0 : false
*------------------------------------------*/
-BUILDIN(getequipisenableref)
+static BUILDIN(getequipisenableref)
{
int i = -1,num;
struct map_session_data *sd;
@@ -9106,13 +9304,42 @@ BUILDIN(getequipisenableref)
return true;
}
+/**
+ * Checks if the equipped item allows options.
+ * *getequipisenableopt(<equipment_index>);
+ *
+ * @param equipment_index as the inventory index of the equipment.
+ * @return 1 on enabled 0 on disabled.
+ */
+static BUILDIN(getequipisenableopt)
+{
+ int i = -1, index = script_getnum(st, 2);
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
+ ShowError("buildin_getequipisenableopt: player is not attached!");
+ return false;
+ }
+
+ if (index > 0 && index <= ARRAYLENGTH(script->equip))
+ i = pc->checkequip(sd, script->equip[index - 1]);
+
+ if (i >=0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_options && !sd->status.inventory[i].expire_time)
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
+
+ return true;
+}
+
/*==========================================
* Chk if the item equiped at pos is identify (huh ?)
* return (npc)
* 1 : true
* 0 : false
*------------------------------------------*/
-BUILDIN(getequipisidentify)
+static BUILDIN(getequipisidentify)
{
int i = -1,num;
struct map_session_data *sd;
@@ -9138,7 +9365,7 @@ BUILDIN(getequipisidentify)
* x : refine amount
* 0 : false (not refined)
*------------------------------------------*/
-BUILDIN(getequiprefinerycnt)
+static BUILDIN(getequiprefinerycnt)
{
int i = -1,num;
struct map_session_data *sd;
@@ -9165,7 +9392,7 @@ BUILDIN(getequiprefinerycnt)
* x : weapon level
* 0 : false
*------------------------------------------*/
-BUILDIN(getequipweaponlv)
+static BUILDIN(getequipweaponlv)
{
int i = -1,num;
struct map_session_data *sd;
@@ -9191,21 +9418,34 @@ BUILDIN(getequipweaponlv)
* x : refine chance
* 0 : false (max refine level or unequip..)
*------------------------------------------*/
-BUILDIN(getequippercentrefinery) {
- int i = -1,num;
+static BUILDIN(getequippercentrefinery)
+{
+ int i = -1, num;
struct map_session_data *sd;
+ int type = 0;
+
+ num = script_getnum(st, 2);
+ type = (script_hasdata(st, 3)) ? script_getnum(st, 3) : REFINE_CHANCE_TYPE_NORMAL;
- num = script_getnum(st,2);
sd = script->rid2sd(st);
- if( sd == NULL )
+ if (sd == NULL)
return true;
+ if (type < REFINE_CHANCE_TYPE_NORMAL || type >= REFINE_CHANCE_TYPE_MAX) {
+ ShowError("buildin_getequippercentrefinery: Invalid type (%d) provided!\n", type);
+ script_pushint(st, 0);
+ return false;
+ }
+
+
if (num > 0 && num <= ARRAYLENGTH(script->equip))
- i=pc->checkequip(sd,script->equip[num-1]);
- if(i >= 0 && sd->status.inventory[i].nameid && sd->status.inventory[i].refine < MAX_REFINE)
- script_pushint(st,status->get_refine_chance(itemdb_wlv(sd->status.inventory[i].nameid), (int)sd->status.inventory[i].refine));
+ i = pc->checkequip(sd, script->equip[num - 1]);
+
+ if (i >= 0 && sd->status.inventory[i].nameid != 0 && sd->status.inventory[i].refine < MAX_REFINE)
+ script_pushint(st,
+ status->get_refine_chance(itemdb_wlv(sd->status.inventory[i].nameid), (int) sd->status.inventory[i].refine, (enum refine_chance_type) type));
else
- script_pushint(st,0);
+ script_pushint(st, 0);
return true;
}
@@ -9213,7 +9453,7 @@ BUILDIN(getequippercentrefinery) {
/*==========================================
* Refine +1 item at pos and log and display refine
*------------------------------------------*/
-BUILDIN(successrefitem)
+static BUILDIN(successrefitem)
{
int i = -1 , num, up = 1;
struct map_session_data *sd;
@@ -9250,6 +9490,11 @@ BUILDIN(successrefitem)
clif->additem(sd,i,1,0);
pc->equipitem(sd,i,ep);
clif->misceffect(&sd->bl,3);
+
+ achievement->validate_refine(sd, i, true); // Achievements [Smokexyz/Hercules]
+
+ /* The following check is exclusive to characters (possibly only whitesmiths)
+ * that create equipments and refine them to level 10. */
if(sd->status.inventory[i].refine == 10 &&
sd->status.inventory[i].card[0] == CARD0_FORGE &&
sd->status.char_id == (int)MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])
@@ -9274,7 +9519,7 @@ BUILDIN(successrefitem)
/*==========================================
* Show a failed Refine +1 attempt
*------------------------------------------*/
-BUILDIN(failedrefitem)
+static BUILDIN(failedrefitem)
{
int i=-1,num;
struct map_session_data *sd;
@@ -9287,6 +9532,9 @@ BUILDIN(failedrefitem)
if (num > 0 && num <= ARRAYLENGTH(script->equip))
i=pc->checkequip(sd,script->equip[num-1]);
if(i >= 0) {
+ // Call before changing refine to 0.
+ achievement->validate_refine(sd, i, false);
+
sd->status.inventory[i].refine = 0;
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
@@ -9302,7 +9550,7 @@ BUILDIN(failedrefitem)
/*==========================================
* Downgrades an Equipment Part by -1 . [Masao]
*------------------------------------------*/
-BUILDIN(downrefitem)
+static BUILDIN(downrefitem)
{
int i = -1, num, down = 1;
struct map_session_data *sd;
@@ -9334,6 +9582,9 @@ BUILDIN(downrefitem)
clif->additem(sd,i,1,0);
pc->equipitem(sd,i,ep);
+
+ achievement->validate_refine(sd, i, false); // Achievements [Smokexyz/Hercules]
+
clif->misceffect(&sd->bl,2);
}
@@ -9343,7 +9594,7 @@ BUILDIN(downrefitem)
/*==========================================
* Delete the item equipped at pos.
*------------------------------------------*/
-BUILDIN(delequip)
+static BUILDIN(delequip)
{
int i=-1,num;
struct map_session_data *sd;
@@ -9371,7 +9622,8 @@ BUILDIN(delequip)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(statusup) {
+static BUILDIN(statusup)
+{
int type;
struct map_session_data *sd;
@@ -9387,7 +9639,7 @@ BUILDIN(statusup) {
/*==========================================
*
*------------------------------------------*/
-BUILDIN(statusup2)
+static BUILDIN(statusup2)
{
int type,val;
struct map_session_data *sd;
@@ -9403,6 +9655,25 @@ BUILDIN(statusup2)
return true;
}
+
+/*==========================================
+* Returns the number of stat points needed to change the specified stat by val.
+* needed_status_point(<type>,<val>{,<char id>}); [secretdataz]
+*------------------------------------------*/
+static BUILDIN(needed_status_point)
+{
+ int type = script_getnum(st, 2);
+ int val = script_getnum(st, 3);;
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd == NULL)
+ script_pushint(st, 0);
+ else
+ script_pushint(st, pc->need_status_point(sd, type, val));
+
+ return true;
+}
+
/// See 'doc/item_bonus.txt'
///
/// bonus <bonus type>,<val1>;
@@ -9410,7 +9681,8 @@ BUILDIN(statusup2)
/// bonus3 <bonus type>,<val1>,<val2>,<val3>;
/// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>;
/// bonus5 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5>;
-BUILDIN(bonus) {
+static BUILDIN(bonus)
+{
int type;
int val1;
int val2 = 0;
@@ -9492,7 +9764,7 @@ BUILDIN(bonus) {
return true;
}
-BUILDIN(autobonus)
+static BUILDIN(autobonus)
{
unsigned int dur;
short rate;
@@ -9527,7 +9799,7 @@ BUILDIN(autobonus)
return true;
}
-BUILDIN(autobonus2)
+static BUILDIN(autobonus2)
{
unsigned int dur;
short rate;
@@ -9562,7 +9834,7 @@ BUILDIN(autobonus2)
return true;
}
-BUILDIN(autobonus3)
+static BUILDIN(autobonus3)
{
unsigned int dur;
short rate,atk_type;
@@ -9605,7 +9877,8 @@ BUILDIN(autobonus3)
/// skill <skill id>,<level>
/// skill "<skill name>",<level>,<flag>
/// skill "<skill name>",<level>
-BUILDIN(skill) {
+static BUILDIN(skill)
+{
int id;
int level;
int flag = SKILL_GRANT_TEMPORARY;
@@ -9631,7 +9904,8 @@ BUILDIN(skill) {
/// addtoskill "<skill name>",<amount>
///
/// @see skill
-BUILDIN(addtoskill) {
+static BUILDIN(addtoskill)
+{
int id;
int level;
int flag = SKILL_GRANT_TEMPSTACK;
@@ -9652,7 +9926,8 @@ BUILDIN(addtoskill) {
///
/// guildskill <skill id>,<amount>;
/// guildskill "<skill name>",<amount>;
-BUILDIN(guildskill) {
+static BUILDIN(guildskill)
+{
int skill_id, id, max_points;
int level;
@@ -9691,7 +9966,7 @@ BUILDIN(guildskill) {
///
/// getskilllv(<skill id>) -> <level>
/// getskilllv("<skill name>") -> <level>
-BUILDIN(getskilllv)
+static BUILDIN(getskilllv)
{
int id;
struct map_session_data *sd = script->rid2sd(st);
@@ -9708,7 +9983,8 @@ BUILDIN(getskilllv)
///
/// getgdskilllv(<guild id>,<skill id>) -> <level>
/// getgdskilllv(<guild id>,"<skill name>") -> <level>
-BUILDIN(getgdskilllv) {
+static BUILDIN(getgdskilllv)
+{
int guild_id;
uint16 skill_id;
struct guild* g;
@@ -9729,7 +10005,7 @@ BUILDIN(getgdskilllv) {
/// before allowing the basic actions.
///
/// basicskillcheck() -> <bool>
-BUILDIN(basicskillcheck)
+static BUILDIN(basicskillcheck)
{
script_pushint(st, battle_config.basic_skill_check);
return true;
@@ -9738,7 +10014,7 @@ BUILDIN(basicskillcheck)
/// Returns the GM level of the player.
///
/// getgmlevel() -> <level>
-BUILDIN(getgmlevel)
+static BUILDIN(getgmlevel)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -9752,7 +10028,8 @@ BUILDIN(getgmlevel)
/// set the group ID of the player.
/// setgroupid(<new group id>{,"<character name>"|<account id>})
/// return 1 on success, 0 if failed.
-BUILDIN(setgroupid) {
+static BUILDIN(setgroupid)
+{
struct map_session_data* sd = NULL;
int new_group = script_getnum(st, 2);
@@ -9775,21 +10052,31 @@ BUILDIN(setgroupid) {
/// Returns the group ID of the player.
///
-/// getgroupid() -> <int>
-BUILDIN(getgroupid)
+/// getgroupid({<account id>}) -> <int>
+static BUILDIN(getgroupid)
{
- struct map_session_data *sd = script->rid2sd(st);
- if (sd == NULL)
+ struct map_session_data *sd = NULL;
+
+ if (script_hasdata(st, 2)) {
+ sd = map->id2sd(script_getnum(st, 2));
+ } else {
+ sd = script->rid2sd(st);
+ }
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
return true; // no player attached, report source
- script_pushint(st, pc_get_group_id(sd));
+ }
+ script_pushint(st, pc_get_group_id(sd));
return true;
}
/// Terminates the execution of this script instance.
///
/// end
-BUILDIN(end) {
+static BUILDIN(end)
+{
st->state = END;
/* are we stopping inside a function? */
@@ -9809,10 +10096,16 @@ BUILDIN(end) {
/// Checks if the player has that effect state (option).
///
/// checkoption(<option>) -> <bool>
-BUILDIN(checkoption)
+static BUILDIN(checkoption)
{
int option;
- struct map_session_data *sd = script->rid2sd(st);
+ struct map_session_data *sd;
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = script->rid2sd(st);
+
if (sd == NULL)
return true;// no player attached, report source
@@ -9828,10 +10121,16 @@ BUILDIN(checkoption)
/// Checks if the player is in that body state (opt1).
///
/// checkoption1(<opt1>) -> <bool>
-BUILDIN(checkoption1)
+static BUILDIN(checkoption1)
{
int opt1;
- struct map_session_data *sd = script->rid2sd(st);
+ struct map_session_data *sd;
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = script->rid2sd(st);
+
if (sd == NULL)
return true;// no player attached, report source
@@ -9847,10 +10146,16 @@ BUILDIN(checkoption1)
/// Checks if the player has that health state (opt2).
///
/// checkoption2(<opt2>) -> <bool>
-BUILDIN(checkoption2)
+static BUILDIN(checkoption2)
{
int opt2;
- struct map_session_data *sd = script->rid2sd(st);
+ struct map_session_data *sd;
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = script->rid2sd(st);
+
if (sd == NULL)
return true;// no player attached, report source
@@ -9870,11 +10175,17 @@ BUILDIN(checkoption2)
///
/// setoption <option>,<flag>;
/// setoption <option>;
-BUILDIN(setoption)
+static BUILDIN(setoption)
{
int option;
int flag = 1;
- struct map_session_data *sd = script->rid2sd(st);
+ struct map_session_data *sd;
+
+ if (script_hasdata(st, 4))
+ sd = map->id2sd(script_getnum(st, 4));
+ else
+ sd = script->rid2sd(st);
+
if (sd == NULL)
return true;// no player attached, report source
@@ -9903,7 +10214,7 @@ BUILDIN(setoption)
/// checkcart() -> <bool>
///
/// @author Valaris
-BUILDIN(checkcart)
+static BUILDIN(checkcart)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -9928,7 +10239,7 @@ BUILDIN(checkcart)
///
/// setcart <type>;
/// setcart;
-BUILDIN(setcart)
+static BUILDIN(setcart)
{
int type = 1;
struct map_session_data *sd = script->rid2sd(st);
@@ -9947,7 +10258,7 @@ BUILDIN(setcart)
/// checkfalcon() -> <bool>
///
/// @author Valaris
-BUILDIN(checkfalcon)
+static BUILDIN(checkfalcon)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -9966,7 +10277,7 @@ BUILDIN(checkfalcon)
///
/// setfalcon <flag>;
/// setfalcon;
-BUILDIN(setfalcon)
+static BUILDIN(setfalcon)
{
bool flag = true;
struct map_session_data *sd = script->rid2sd(st);
@@ -10003,7 +10314,7 @@ enum setmount_type {
* The exact returned values are the same used as flag in setmount, except for
* dragons, where SETMOUNT_TYPE_DRAGON is returned, regardless of color.
*/
-BUILDIN(checkmount)
+static BUILDIN(checkmount)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -10046,7 +10357,7 @@ BUILDIN(checkmount)
* auto-detected. As a result of this, there is no need to specify a flag at
* all, unless it is a dragon color other than green.
*/
-BUILDIN(setmount)
+static BUILDIN(setmount)
{
int flag = SETMOUNT_TYPE_AUTODETECT;
struct map_session_data *sd = script->rid2sd(st);
@@ -10111,7 +10422,7 @@ BUILDIN(setmount)
///
/// checkwug() -> <bool>
///
-BUILDIN(checkwug)
+static BUILDIN(checkwug)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -10129,7 +10440,8 @@ BUILDIN(checkwug)
///
/// save "<map name>",<x>,<y>
/// savepoint "<map name>",<x>,<y>
-BUILDIN(savepoint) {
+static BUILDIN(savepoint)
+{
int x;
int y;
short mapid;
@@ -10151,7 +10463,9 @@ BUILDIN(savepoint) {
/*==========================================
* GetTimeTick(0: System Tick, 1: Time Second Tick)
*------------------------------------------*/
-BUILDIN(gettimetick) { /* Asgard Version */
+/* Asgard Version */
+static BUILDIN(gettimetick)
+{
int type;
time_t clock;
struct tm *t;
@@ -10184,7 +10498,9 @@ BUILDIN(gettimetick) { /* Asgard Version */
* 4: WeekDay 5: MonthDay 6: Month
* 7: Year
*------------------------------------------*/
-BUILDIN(gettime) { /* Asgard Version */
+/* Asgard Version */
+static BUILDIN(gettime)
+{
int type;
time_t clock;
struct tm *t;
@@ -10229,7 +10545,7 @@ BUILDIN(gettime) { /* Asgard Version */
/*==========================================
* GetTimeStr("TimeFMT", Length);
*------------------------------------------*/
-BUILDIN(gettimestr)
+static BUILDIN(gettimestr)
{
char *tmpstr;
const char *fmtstr;
@@ -10250,17 +10566,25 @@ BUILDIN(gettimestr)
/*==========================================
* Open player storage
*------------------------------------------*/
-BUILDIN(openstorage)
+static BUILDIN(openstorage)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
- return true;
+ return false;
+
+ if (sd->storage.received == false) {
+ script_pushint(st, 0);
+ ShowWarning("buildin_openstorage: Storage data for AID %d has not been loaded.\n", sd->bl.id);
+ return false;
+ }
storage->open(sd);
+
+ script_pushint(st, 1); // success flag.
return true;
}
-BUILDIN(guildopenstorage)
+static BUILDIN(guildopenstorage)
{
int ret;
struct map_session_data *sd = script->rid2sd(st);
@@ -10277,7 +10601,7 @@ BUILDIN(guildopenstorage)
*------------------------------------------*/
/// itemskill <skill id>,<level>{,flag
/// itemskill "<skill name>",<level>{,flag
-BUILDIN(itemskill)
+static BUILDIN(itemskill)
{
int id;
int lv;
@@ -10302,7 +10626,7 @@ BUILDIN(itemskill)
/*==========================================
* Attempt to create an item
*------------------------------------------*/
-BUILDIN(produce)
+static BUILDIN(produce)
{
int trigger;
struct map_session_data *sd = script->rid2sd(st);
@@ -10316,7 +10640,7 @@ BUILDIN(produce)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(cooking)
+static BUILDIN(cooking)
{
int trigger;
struct map_session_data *sd = script->rid2sd(st);
@@ -10330,7 +10654,7 @@ BUILDIN(cooking)
/*==========================================
* Create a pet
*------------------------------------------*/
-BUILDIN(makepet)
+static BUILDIN(makepet)
{
struct map_session_data *sd;
int id,pet_id;
@@ -10348,7 +10672,7 @@ BUILDIN(makepet)
sd->catch_target_class = pet->db[pet_id].class_;
intif->create_pet(sd->status.account_id, sd->status.char_id,
(short)pet->db[pet_id].class_, (short)mob->db(pet->db[pet_id].class_)->lv,
- (short)pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate,
+ pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate,
100, 0, 1, pet->db[pet_id].jname);
}
@@ -10357,7 +10681,7 @@ BUILDIN(makepet)
/*==========================================
* Give player exp base,job * quest_exp_rate/100
*------------------------------------------*/
-BUILDIN(getexp)
+static BUILDIN(getexp)
{
int base=0,job=0;
struct map_session_data *sd = script->rid2sd(st);
@@ -10381,7 +10705,7 @@ BUILDIN(getexp)
/*==========================================
* Gain guild exp [Celest]
*------------------------------------------*/
-BUILDIN(guildgetexp)
+static BUILDIN(guildgetexp)
{
int exp;
struct map_session_data *sd = script->rid2sd(st);
@@ -10400,7 +10724,7 @@ BUILDIN(guildgetexp)
/*==========================================
* Changes the guild master of a guild [Skotlex]
*------------------------------------------*/
-BUILDIN(guildchangegm)
+static BUILDIN(guildchangegm)
{
struct map_session_data *sd;
int guild_id;
@@ -10413,7 +10737,7 @@ BUILDIN(guildchangegm)
if (sd == NULL)
script_pushint(st,0);
else
- script_pushint(st,guild->gm_change(guild_id, sd));
+ script_pushint(st, guild->gm_change(guild_id, sd->status.char_id));
return true;
}
@@ -10426,7 +10750,7 @@ BUILDIN(guildchangegm)
* @amount : nb to spawn
* @event : event to attach to mob
*------------------------------------------*/
-BUILDIN(monster)
+static BUILDIN(monster)
{
const char *mapn = script_getstr(st,2);
int x = script_getnum(st,3);
@@ -10498,7 +10822,7 @@ BUILDIN(monster)
/*==========================================
* Request List of Monster Drops
*------------------------------------------*/
-BUILDIN(getmobdrops)
+static BUILDIN(getmobdrops)
{
int class_ = script_getnum(st,2);
int i, j = 0;
@@ -10519,13 +10843,13 @@ BUILDIN(getmobdrops)
if( itemdb->exists(monster->dropitem[i].nameid) == NULL )
continue;
- mapreg->setreg(reference_uid(script->add_str("$@MobDrop_item"), j), monster->dropitem[i].nameid);
- mapreg->setreg(reference_uid(script->add_str("$@MobDrop_rate"), j), monster->dropitem[i].p);
+ mapreg->setreg(reference_uid(script->add_variable("$@MobDrop_item"), j), monster->dropitem[i].nameid);
+ mapreg->setreg(reference_uid(script->add_variable("$@MobDrop_rate"), j), monster->dropitem[i].p);
j++;
}
- mapreg->setreg(script->add_str("$@MobDrop_count"), j);
+ mapreg->setreg(script->add_variable("$@MobDrop_count"), j);
script_pushint(st, 1);
return true;
@@ -10533,7 +10857,8 @@ BUILDIN(getmobdrops)
/*==========================================
* Same as monster but randomize location in x0,x1,y0,y1 area
*------------------------------------------*/
-BUILDIN(areamonster) {
+static BUILDIN(areamonster)
+{
const char *mapn = script_getstr(st,2);
int x0 = script_getnum(st,3);
int y0 = script_getnum(st,4);
@@ -10596,7 +10921,7 @@ BUILDIN(areamonster) {
/*==========================================
* KillMonster subcheck, verify if mob to kill ain't got an even to handle, could be force kill by allflag
*------------------------------------------*/
-int buildin_killmonster_sub_strip(struct block_list *bl, va_list ap)
+static int buildin_killmonster_sub_strip(struct block_list *bl, va_list ap)
{
//same fix but with killmonster instead - stripping events from mobs.
struct mob_data *md = NULL;
@@ -10619,7 +10944,7 @@ int buildin_killmonster_sub_strip(struct block_list *bl, va_list ap)
md->state.npc_killmonster = 0;
return 0;
}
-int buildin_killmonster_sub(struct block_list *bl, va_list ap)
+static int buildin_killmonster_sub(struct block_list *bl, va_list ap)
{
struct mob_data *md = NULL;
char *event = va_arg(ap,char *);
@@ -10638,7 +10963,8 @@ int buildin_killmonster_sub(struct block_list *bl, va_list ap)
}
return 0;
}
-BUILDIN(killmonster) {
+static BUILDIN(killmonster)
+{
const char *mapname,*event;
int16 m,allflag=0;
mapname=script_getstr(st,2);
@@ -10667,7 +10993,7 @@ BUILDIN(killmonster) {
return true;
}
-int buildin_killmonsterall_sub_strip(struct block_list *bl,va_list ap)
+static int buildin_killmonsterall_sub_strip(struct block_list *bl, va_list ap)
{ //Strips the event from the mob if it's killed the old method.
struct mob_data *md;
@@ -10679,12 +11005,13 @@ int buildin_killmonsterall_sub_strip(struct block_list *bl,va_list ap)
status_kill(bl);
return 0;
}
-int buildin_killmonsterall_sub(struct block_list *bl,va_list ap)
+static int buildin_killmonsterall_sub(struct block_list *bl, va_list ap)
{
status_kill(bl);
return 0;
}
-BUILDIN(killmonsterall) {
+static BUILDIN(killmonsterall)
+{
const char *mapname;
int16 m;
mapname=script_getstr(st,2);
@@ -10710,7 +11037,8 @@ BUILDIN(killmonsterall) {
* Creates a clone of a player.
* clone map, x, y, event, char_id, master_id, mode, flag, duration
*------------------------------------------*/
-BUILDIN(clone) {
+static BUILDIN(clone)
+{
struct map_session_data *sd, *msd = NULL;
int char_id, master_id = 0, x, y, flag = 0, m;
uint32 mode = 0;
@@ -10758,7 +11086,7 @@ BUILDIN(clone) {
}
/*==========================================
*------------------------------------------*/
-BUILDIN(doevent)
+static BUILDIN(doevent)
{
const char* event = script_getstr(st,2);
struct map_session_data* sd;
@@ -10774,7 +11102,7 @@ BUILDIN(doevent)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(donpcevent)
+static BUILDIN(donpcevent)
{
const char* event = script_getstr(st,2);
script->check_event(st, event);
@@ -10789,7 +11117,7 @@ BUILDIN(donpcevent)
/*==========================================
*------------------------------------------*/
-BUILDIN(addtimer)
+static BUILDIN(addtimer)
{
int tick = script_getnum(st, 2);
const char* event = script_getstr(st, 3);
@@ -10818,7 +11146,7 @@ BUILDIN(addtimer)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(deltimer)
+static BUILDIN(deltimer)
{
const char *event;
struct map_session_data *sd;
@@ -10839,7 +11167,7 @@ BUILDIN(deltimer)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(addtimercount)
+static BUILDIN(addtimercount)
{
const char *event;
int tick;
@@ -10861,9 +11189,232 @@ BUILDIN(addtimercount)
return true;
}
+enum gettimer_mode {
+ GETTIMER_COUNT = 0,
+ GETTIMER_TICK_NEXT = 1,
+ GETTIMER_TICK_LAST = 2,
+};
+
+static BUILDIN(gettimer)
+{
+ struct map_session_data *sd;
+ const struct TimerData *td;
+ int i;
+ int tick;
+ const char *event = NULL;
+ int val = 0;
+ bool first = true;
+ short mode = script_getnum(st, 2);
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = script->rid2sd(st);
+
+ if (script_hasdata(st, 4)) {
+ event = script_getstr(st, 4);
+ script->check_event(st, event);
+ }
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
+ return true;
+ }
+
+ switch (mode) {
+ case GETTIMER_COUNT:
+ // get number of timers
+ for (i = 0; i < MAX_EVENTTIMER; i++) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ if (event != NULL) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+
+ if (strcmp((char *)(td->data), event) == 0) {
+ val++;
+ }
+ } else {
+ val++;
+ }
+ }
+ }
+ break;
+ case GETTIMER_TICK_NEXT:
+ // get the number of tick before the next timer runs
+ for (i = 0; i < MAX_EVENTTIMER; i++) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+ tick = max(0, DIFF_TICK32(td->tick, timer->gettick()));
+
+ if (event != NULL) {
+ if ((first == true || tick < val) && strcmp((char *)(td->data), event) == 0) {
+ val = tick;
+ first = false;
+ }
+ } else if (first == true || tick < val) {
+ val = tick;
+ first = false;
+ }
+ }
+ }
+ break;
+ case GETTIMER_TICK_LAST:
+ // get the number of ticks before the last timer runs
+ for (i = MAX_EVENTTIMER - 1; i >= 0; i--) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+ tick = max(0, DIFF_TICK32(td->tick, timer->gettick()));
+
+ if (event != NULL) {
+ if (strcmp((char *)(td->data), event) == 0) {
+ val = max(val, tick);
+ }
+ } else {
+ val = max(val, tick);
+ }
+ }
+ }
+ break;
+ }
+
+ script_pushint(st, val);
+ return true;
+}
+
+static int buildin_getunits_sub(struct block_list *bl, va_list ap)
+{
+ struct script_state *st = va_arg(ap, struct script_state *);
+ struct map_session_data *sd = va_arg(ap, struct map_session_data *);
+ int32 id = va_arg(ap, int32);
+ uint32 start = va_arg(ap, uint32);
+ uint32 *count = va_arg(ap, uint32 *);
+ uint32 limit = va_arg(ap, uint32);
+ const char *name = va_arg(ap, const char *);
+ struct reg_db *ref = va_arg(ap, struct reg_db *);
+ enum bl_type type = va_arg(ap, enum bl_type);
+ uint32 index = start + *count;
+
+ if ((bl->type & type) == 0) {
+ return 0; // type mismatch => skip
+ }
+
+ if (index >= SCRIPT_MAX_ARRAYSIZE || *count >= limit) {
+ return -1;
+ }
+
+ script->set_reg(st, sd, reference_uid(id, index), name,
+ (const void *)h64BPTRSIZE(bl->id), ref);
+
+ (*count)++;
+ return 1;
+}
+
+static int buildin_getunits_sub_pc(struct map_session_data *sd, va_list ap)
+{
+ return buildin_getunits_sub(&sd->bl, ap);
+}
+
+static int buildin_getunits_sub_mob(struct mob_data *md, va_list ap)
+{
+ return buildin_getunits_sub(&md->bl, ap);
+}
+
+static int buildin_getunits_sub_npc(struct npc_data *nd, va_list ap)
+{
+ return buildin_getunits_sub(&nd->bl, ap);
+}
+
+static BUILDIN(getunits)
+{
+ const char *name;
+ int32 id;
+ uint32 start;
+ struct reg_db *ref;
+ enum bl_type type = script_getnum(st, 2);
+ struct script_data *data = script_getdata(st, 3);
+ uint32 count = 0;
+ uint32 limit = script_getnum(st, 4);
+ struct map_session_data *sd = NULL;
+
+ if (!data_isreference(data) || reference_toconstant(data)) {
+ ShowError("script:getunits: second argument must be a variable\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;
+ }
+
+ id = reference_getid(data);
+ start = reference_getindex(data);
+ name = reference_getname(data);
+ ref = reference_getref(data);
+
+ if (not_server_variable(*name)) {
+ sd = script->rid2sd(st);
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ return true; // player variable but no player attached
+ }
+ }
+
+ if (is_string_variable(name)) {
+ ShowError("script:getunits: second argument must be an integer variable\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;
+ }
+
+ if (limit < 1 || limit > SCRIPT_MAX_ARRAYSIZE) {
+ limit = SCRIPT_MAX_ARRAYSIZE;
+ }
+
+ if (script_hasdata(st, 5)) {
+ const char *mapname = script_getstr(st, 5);
+ int16 m = map->mapname2mapid(mapname);
+
+ if (script_hasdata(st, 9)) {
+ int16 x1 = script_getnum(st, 6);
+ int16 y1 = script_getnum(st, 7);
+ int16 x2 = script_getnum(st, 8);
+ int16 y2 = script_getnum(st, 9);
+
+ map->forcountinarea(buildin_getunits_sub, m, x1, y1, x2, y2, limit, type,
+ st, sd, id, start, &count, limit, name, ref, type);
+ } else {
+ map->forcountinmap(buildin_getunits_sub, m, limit, type,
+ st, sd, id, start, &count, limit, name, ref, type);
+ }
+ } else {
+ // for faster lookup we try to reduce the scope of the search if possible
+ switch (type) {
+ case BL_PC:
+ map->foreachpc(buildin_getunits_sub_pc,
+ st, sd, id, start, &count, limit, name, ref, type);
+ break;
+ case BL_MOB:
+ map->foreachmob(buildin_getunits_sub_mob,
+ st, sd, id, start, &count, limit, name, ref, type);
+ break;
+ case BL_NPC:
+ map->foreachnpc(buildin_getunits_sub_npc,
+ st, sd, id, start, &count, limit, name, ref, type);
+ break;
+ default:
+ // fallback to global lookup (slowest option)
+ map->foreachiddb(buildin_getunits_sub,
+ st, sd, id, start, &count, limit, name, ref, type);
+ }
+ }
+
+ script_pushint(st, count);
+ return true;
+}
+
/*==========================================
*------------------------------------------*/
-BUILDIN(initnpctimer)
+static BUILDIN(initnpctimer)
{
struct npc_data *nd;
int flag = 0;
@@ -10908,7 +11459,7 @@ BUILDIN(initnpctimer)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(startnpctimer)
+static BUILDIN(startnpctimer)
{
struct npc_data *nd;
int flag = 0;
@@ -10951,7 +11502,8 @@ BUILDIN(startnpctimer)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(stopnpctimer) {
+static BUILDIN(stopnpctimer)
+{
struct npc_data *nd;
int flag = 0;
@@ -10989,7 +11541,7 @@ BUILDIN(stopnpctimer) {
}
/*==========================================
*------------------------------------------*/
-BUILDIN(getnpctimer)
+static BUILDIN(getnpctimer)
{
struct npc_data *nd;
struct map_session_data *sd;
@@ -11027,7 +11579,7 @@ BUILDIN(getnpctimer)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(setnpctimer)
+static BUILDIN(setnpctimer)
{
int tick;
struct npc_data *nd;
@@ -11052,7 +11604,7 @@ BUILDIN(setnpctimer)
/*==========================================
* attaches the player rid to the timer [Celest]
*------------------------------------------*/
-BUILDIN(attachnpctimer)
+static BUILDIN(attachnpctimer)
{
struct map_session_data *sd;
struct npc_data *nd = map->id2nd(st->oid);
@@ -11081,7 +11633,8 @@ BUILDIN(attachnpctimer)
/*==========================================
* detaches a player rid from the timer [Celest]
*------------------------------------------*/
-BUILDIN(detachnpctimer) {
+static BUILDIN(detachnpctimer)
+{
struct npc_data *nd;
if( script_hasdata(st,2) )
@@ -11105,7 +11658,8 @@ BUILDIN(detachnpctimer) {
* it checks if there is a player attached to the current script. [Skotlex]
* If no, returns 0, if yes, returns the account_id of the attached player.
*------------------------------------------*/
-BUILDIN(playerattached) {
+static BUILDIN(playerattached)
+{
if(st->rid == 0 || map->id2sd(st->rid) == NULL)
script_pushint(st,0);
else
@@ -11115,7 +11669,7 @@ BUILDIN(playerattached) {
/*==========================================
*------------------------------------------*/
-BUILDIN(announce)
+static BUILDIN(announce)
{
const char *mes = script_getstr(st,2);
int flag = script_getnum(st,3);
@@ -11163,7 +11717,7 @@ BUILDIN(announce)
}
/*==========================================
*------------------------------------------*/
-int buildin_announce_sub(struct block_list *bl, va_list ap)
+static int buildin_announce_sub(struct block_list *bl, va_list ap)
{
const char *mes = va_arg(ap, const char *);
int len = va_arg(ap, int);
@@ -11182,7 +11736,7 @@ int buildin_announce_sub(struct block_list *bl, va_list ap)
/* Runs item effect on attached character.
* itemeffect <item id>;
* itemeffect "<item name>"; */
-BUILDIN(itemeffect)
+static BUILDIN(itemeffect)
{
struct npc_data *nd;
struct item_data *item_data;
@@ -11215,7 +11769,7 @@ BUILDIN(itemeffect)
return true;
}
-BUILDIN(mapannounce)
+static BUILDIN(mapannounce)
{
const char *mapname = script_getstr(st,2);
const char *mes = script_getstr(st,3);
@@ -11238,7 +11792,7 @@ BUILDIN(mapannounce)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(areaannounce)
+static BUILDIN(areaannounce)
{
const char *mapname = script_getstr(st,2);
int x0 = script_getnum(st,3);
@@ -11266,7 +11820,8 @@ BUILDIN(areaannounce)
/*==========================================
*------------------------------------------*/
-BUILDIN(getusers) {
+static BUILDIN(getusers)
+{
int flag, val = 0;
struct map_session_data* sd;
struct block_list* bl = NULL;
@@ -11302,7 +11857,7 @@ BUILDIN(getusers) {
/*==========================================
* Works like @WHO - displays all online users names in window
*------------------------------------------*/
-BUILDIN(getusersname)
+static BUILDIN(getusersname)
{
struct map_session_data *sd;
const struct map_session_data *pl_sd;
@@ -11331,7 +11886,7 @@ BUILDIN(getusersname)
/*==========================================
* getmapguildusers("mapname",guild ID) Returns the number guild members present on a map [Reddozen]
*------------------------------------------*/
-BUILDIN(getmapguildusers)
+static BUILDIN(getmapguildusers)
{
const char *str;
int16 m;
@@ -11359,7 +11914,8 @@ BUILDIN(getmapguildusers)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(getmapusers) {
+static BUILDIN(getmapusers)
+{
const char *str;
int16 m;
str=script_getstr(st,2);
@@ -11372,7 +11928,7 @@ BUILDIN(getmapusers) {
}
/*==========================================
*------------------------------------------*/
-int buildin_getareausers_sub(struct block_list *bl,va_list ap)
+static int buildin_getareausers_sub(struct block_list *bl, va_list ap)
{
int *users=va_arg(ap,int *);
nullpo_ret(users);
@@ -11380,7 +11936,7 @@ int buildin_getareausers_sub(struct block_list *bl,va_list ap)
return 0;
}
-BUILDIN(getareausers)
+static BUILDIN(getareausers)
{
int16 m = -1, x0, y0, x1, y1;
int users = 0;
@@ -11440,7 +11996,7 @@ BUILDIN(getareausers)
/*==========================================
*------------------------------------------*/
-int buildin_getareadropitem_sub(struct block_list *bl, va_list ap)
+static int buildin_getareadropitem_sub(struct block_list *bl, va_list ap)
{
int item = va_arg(ap, int);
int *amount = va_arg(ap, int *);
@@ -11456,7 +12012,8 @@ int buildin_getareadropitem_sub(struct block_list *bl, va_list ap)
return 0;
}
-BUILDIN(getareadropitem) {
+static BUILDIN(getareadropitem)
+{
const char *str;
int16 m,x0,y0,x1,y1;
int item,amount=0;
@@ -11488,7 +12045,7 @@ BUILDIN(getareadropitem) {
}
/*==========================================
*------------------------------------------*/
-BUILDIN(enablenpc)
+static BUILDIN(enablenpc)
{
const char *str;
str=script_getstr(st,2);
@@ -11497,7 +12054,7 @@ BUILDIN(enablenpc)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(disablenpc)
+static BUILDIN(disablenpc)
{
const char *str;
str=script_getstr(st,2);
@@ -11507,7 +12064,7 @@ BUILDIN(disablenpc)
/*==========================================
*------------------------------------------*/
-BUILDIN(hideoffnpc)
+static BUILDIN(hideoffnpc)
{
const char *str;
str=script_getstr(st,2);
@@ -11516,7 +12073,7 @@ BUILDIN(hideoffnpc)
}
/*==========================================
*------------------------------------------*/
-BUILDIN(hideonnpc)
+static BUILDIN(hideonnpc)
{
const char *str;
str=script_getstr(st,2);
@@ -11531,7 +12088,7 @@ BUILDIN(hideonnpc)
* sc_start4 <effect_id>,<duration>,<val1>,<val2>,<val3>,<val4>{,<rate,<flag>,{<unit_id>}};
* <flag>: @see enum scstart_flag
*/
-BUILDIN(sc_start)
+static BUILDIN(sc_start)
{
struct npc_data *nd = map->id2nd(st->oid);
struct block_list* bl;
@@ -11599,7 +12156,8 @@ BUILDIN(sc_start)
/// Ends one or all status effects on the target unit or on the attached player.
///
/// sc_end <effect_id>{,<unit_id>};
-BUILDIN(sc_end) {
+static BUILDIN(sc_end)
+{
struct block_list* bl;
int type;
@@ -11634,7 +12192,9 @@ BUILDIN(sc_end) {
}
//This should help status_change_end force disabling the SC in case it has no limit.
- sce->val1 = sce->val2 = sce->val3 = sce->val4 = 0;
+ if (type != SC_BERSERK)
+ sce->val1 = 0; // SC_BERSERK requires skill_lv that's stored in sce->val1 when being removed [KirieZ]
+ sce->val2 = sce->val3 = sce->val4 = 0;
status_change_end(bl, (sc_type)type, INVALID_TIMER);
}
else
@@ -11646,7 +12206,8 @@ BUILDIN(sc_end) {
/*==========================================
* @FIXME atm will return reduced tick, 0 immune, 1 no tick
*------------------------------------------*/
-BUILDIN(getscrate) {
+static BUILDIN(getscrate)
+{
struct block_list *bl;
int type,rate;
@@ -11667,7 +12228,7 @@ BUILDIN(getscrate) {
/*==========================================
* getstatus <type>{, <info>};
*------------------------------------------*/
-BUILDIN(getstatus)
+static BUILDIN(getstatus)
{
int id, type;
struct map_session_data* sd = script->rid2sd(st);
@@ -11698,14 +12259,16 @@ BUILDIN(getstatus)
case 3: script_pushint(st, sd->sc.data[id]->val3); break;
case 4: script_pushint(st, sd->sc.data[id]->val4); break;
case 5:
- {
- const struct TimerData *td = timer->get(sd->sc.data[id]->timer);
+ if (sd->sc.data[id]->infinite_duration) {
+ script_pushint(st, INFINITE_DURATION);
+ } else {
+ const struct TimerData *td = timer->get(sd->sc.data[id]->timer);
- if (td != NULL) {
- // return the amount of time remaining
- script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values
+ if (td != NULL) {
+ // return the amount of time remaining
+ script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values
+ }
}
- }
break;
default: script_pushint(st, 1); break;
}
@@ -11716,17 +12279,26 @@ BUILDIN(getstatus)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(debugmes)
+static BUILDIN(debugmes)
{
- const char *str;
- str=script_getstr(st,2);
- ShowDebug("script debug : %d %d : %s\n",st->rid,st->oid,str);
+ struct StringBuf buf;
+ StrBuf->Init(&buf);
+
+ if (!script->sprintf_helper(st, 2, &buf)) {
+ StrBuf->Destroy(&buf);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ ShowDebug("script debug : %d %d : %s\n", st->rid, st->oid, StrBuf->Value(&buf));
+ StrBuf->Destroy(&buf);
+ script_pushint(st, 1);
return true;
}
/*==========================================
*------------------------------------------*/
-BUILDIN(catchpet)
+static BUILDIN(catchpet)
{
int pet_id;
struct map_session_data *sd;
@@ -11743,7 +12315,7 @@ BUILDIN(catchpet)
/*==========================================
* [orn]
*------------------------------------------*/
-BUILDIN(homunculus_evolution)
+static BUILDIN(homunculus_evolution)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -11763,7 +12335,7 @@ BUILDIN(homunculus_evolution)
* Checks for vaporized morph state
* and deletes ITEMID_STRANGE_EMBRYO.
*------------------------------------------*/
-BUILDIN(homunculus_mutate)
+static BUILDIN(homunculus_mutate)
{
bool success = false;
struct map_session_data *sd = script->rid2sd(st);
@@ -11777,7 +12349,7 @@ BUILDIN(homunculus_mutate)
if (script_hasdata(st,2))
homun_id = script_getnum(st,2);
else
- homun_id = 6048 + (rnd() % 4);
+ homun_id = HOMID_EIRA + (rnd() % 4);
m_class = homun->class2type(sd->hd->homunculus.class_);
m_id = homun->class2type(homun_id);
@@ -11804,7 +12376,7 @@ BUILDIN(homunculus_mutate)
* Puts homunculus into morph state
* and gives ITEMID_STRANGE_EMBRYO.
*------------------------------------------*/
-BUILDIN(homunculus_morphembryo)
+static BUILDIN(homunculus_morphembryo)
{
bool success = false;
struct map_session_data *sd = script->rid2sd(st);
@@ -11847,7 +12419,7 @@ BUILDIN(homunculus_morphembryo)
* 1 = Homunculus is vaporized (rest)
* 2 = Homunculus is in morph state
*------------------------------------------*/
-BUILDIN(homunculus_checkcall)
+static BUILDIN(homunculus_checkcall)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL || sd->hd == NULL)
@@ -11859,7 +12431,7 @@ BUILDIN(homunculus_checkcall)
}
// [Zephyrus]
-BUILDIN(homunculus_shuffle)
+static BUILDIN(homunculus_shuffle)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -11872,7 +12444,7 @@ BUILDIN(homunculus_shuffle)
}
//These two functions bring the eA MAPID_* class functionality to scripts.
-BUILDIN(eaclass)
+static BUILDIN(eaclass)
{
int class;
if (script_hasdata(st,2)) {
@@ -11887,7 +12459,7 @@ BUILDIN(eaclass)
return true;
}
-BUILDIN(roclass)
+static BUILDIN(roclass)
{
int job = script_getnum(st,2);
int sex;
@@ -11907,7 +12479,7 @@ BUILDIN(roclass)
/*==========================================
* Tells client to open a hatching window, used for pet incubator
*------------------------------------------*/
-BUILDIN(birthpet)
+static BUILDIN(birthpet)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -11930,7 +12502,7 @@ BUILDIN(birthpet)
* 3 : don't reset skill, blvl=1
* 4 : jlvl=0
*------------------------------------------*/
-BUILDIN(resetlvl)
+static BUILDIN(resetlvl)
{
int type=script_getnum(st,2);
struct map_session_data *sd = script->rid2sd(st);
@@ -11943,7 +12515,7 @@ BUILDIN(resetlvl)
/*==========================================
* Reset a player status point
*------------------------------------------*/
-BUILDIN(resetstatus)
+static BUILDIN(resetstatus)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -11955,7 +12527,7 @@ BUILDIN(resetstatus)
/*==========================================
* script command resetskill
*------------------------------------------*/
-BUILDIN(resetskill)
+static BUILDIN(resetskill)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -11967,7 +12539,7 @@ BUILDIN(resetskill)
/*==========================================
* Counts total amount of skill points.
*------------------------------------------*/
-BUILDIN(skillpointcount)
+static BUILDIN(skillpointcount)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -11979,7 +12551,7 @@ BUILDIN(skillpointcount)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(changebase)
+static BUILDIN(changebase)
{
struct map_session_data *sd = NULL;
int vclass;
@@ -12025,7 +12597,7 @@ static struct map_session_data *prepareChangeSex(struct script_state *st)
/*==========================================
* Unequip all item and request for a changesex to char-serv
*------------------------------------------*/
-BUILDIN(changesex)
+static BUILDIN(changesex)
{
struct map_session_data *sd = prepareChangeSex(st);
if (sd == NULL)
@@ -12037,7 +12609,7 @@ BUILDIN(changesex)
/*==========================================
* Unequip all items and change character sex [4144]
*------------------------------------------*/
-BUILDIN(changecharsex)
+static BUILDIN(changecharsex)
{
struct map_session_data *sd = prepareChangeSex(st);
if (sd == NULL)
@@ -12049,7 +12621,7 @@ BUILDIN(changecharsex)
/*==========================================
* Works like 'announce' but outputs in the common chat window
*------------------------------------------*/
-BUILDIN(globalmes)
+static BUILDIN(globalmes)
{
const char *name=NULL,*mes;
@@ -12077,7 +12649,7 @@ BUILDIN(globalmes)
/// Creates a waiting room (chat room) for this npc.
///
/// waitingroom "<title>",<limit>{,"<event>"{,<trigger>{,<zeny>{,<minlvl>{,<maxlvl>}}}}};
-BUILDIN(waitingroom)
+static BUILDIN(waitingroom)
{
struct npc_data* nd;
const char* title = script_getstr(st, 2);
@@ -12101,7 +12673,8 @@ BUILDIN(waitingroom)
///
/// delwaitingroom "<npc_name>";
/// delwaitingroom;
-BUILDIN(delwaitingroom) {
+static BUILDIN(delwaitingroom)
+{
struct npc_data* nd;
if( script_hasdata(st,2) )
nd = npc->name2id(script_getstr(st, 2));
@@ -12116,7 +12689,8 @@ BUILDIN(delwaitingroom) {
///
/// kickwaitingroomall "<npc_name>";
/// kickwaitingroomall;
-BUILDIN(waitingroomkickall) {
+static BUILDIN(waitingroomkickall)
+{
struct npc_data* nd;
struct chat_data* cd;
@@ -12134,7 +12708,8 @@ BUILDIN(waitingroomkickall) {
///
/// enablewaitingroomevent "<npc_name>";
/// enablewaitingroomevent;
-BUILDIN(enablewaitingroomevent) {
+static BUILDIN(enablewaitingroomevent)
+{
struct npc_data* nd;
struct chat_data* cd;
@@ -12152,7 +12727,8 @@ BUILDIN(enablewaitingroomevent) {
///
/// disablewaitingroomevent "<npc_name>";
/// disablewaitingroomevent;
-BUILDIN(disablewaitingroomevent) {
+static BUILDIN(disablewaitingroomevent)
+{
struct npc_data *nd;
struct chat_data *cd;
@@ -12184,7 +12760,7 @@ BUILDIN(disablewaitingroomevent) {
///
/// getwaitingroomstate(<type>,"<npc_name>") -> <info>
/// getwaitingroomstate(<type>) -> <info>
-BUILDIN(getwaitingroomstate)
+static BUILDIN(getwaitingroomstate)
{
const struct npc_data *nd;
const struct chat_data *cd;
@@ -12207,7 +12783,7 @@ BUILDIN(getwaitingroomstate)
for (i = 0; i < cd->users; i++) {
struct map_session_data *sd = cd->usersd[i];
nullpo_retr(false, sd);
- mapreg->setreg(reference_uid(script->add_str("$@chatmembers"), i), sd->bl.id);
+ mapreg->setreg(reference_uid(script->add_variable("$@chatmembers"), i), sd->bl.id);
}
script_pushint(st, cd->users);
break;
@@ -12240,7 +12816,7 @@ BUILDIN(getwaitingroomstate)
///
/// warpwaitingpc "<map name>",<x>,<y>,<number of players>;
/// warpwaitingpc "<map name>",<x>,<y>;
-BUILDIN(warpwaitingpc)
+static BUILDIN(warpwaitingpc)
{
int x, y, i, n;
const char* map_name;
@@ -12277,7 +12853,7 @@ BUILDIN(warpwaitingpc)
pc->payzeny(sd, cd->zeny, LOG_TYPE_NPC, NULL);
}
- mapreg->setreg(reference_uid(script->add_str("$@warpwaitingpc"), i), sd->bl.id);
+ mapreg->setreg(reference_uid(script->add_variable("$@warpwaitingpc"), i), sd->bl.id);
if( strcmp(map_name,"Random") == 0 )
pc->randomwarp(sd,CLR_TELEPORT);
@@ -12286,7 +12862,7 @@ BUILDIN(warpwaitingpc)
else
pc->setpos(sd, script->mapindexname2id(st,map_name), x, y, CLR_OUTSIGHT);
}
- mapreg->setreg(script->add_str("$@warpwaitingpcnum"), i);
+ mapreg->setreg(script->add_variable("$@warpwaitingpcnum"), i);
return true;
}
@@ -12297,7 +12873,8 @@ BUILDIN(warpwaitingpc)
/// Detaches a character from a script.
///
/// @param st Script state to detach the character from.
-void script_detach_rid(struct script_state* st) {
+static void script_detach_rid(struct script_state *st)
+{
if(st->rid) {
script->detach_state(st, false);
st->rid = 0;
@@ -12307,7 +12884,8 @@ void script_detach_rid(struct script_state* st) {
/*==========================================
* Attach sd char id to script and detach current one if any
*------------------------------------------*/
-BUILDIN(attachrid) {
+static BUILDIN(attachrid)
+{
int rid = script_getnum(st,2);
if (map->id2sd(rid) != NULL) {
@@ -12323,7 +12901,7 @@ BUILDIN(attachrid) {
/*==========================================
* Detach script to rid
*------------------------------------------*/
-BUILDIN(detachrid)
+static BUILDIN(detachrid)
{
script->detach_rid(st);
return true;
@@ -12331,7 +12909,7 @@ BUILDIN(detachrid)
/*==========================================
* Chk if account connected, (and charid from account if specified)
*------------------------------------------*/
-BUILDIN(isloggedin)
+static BUILDIN(isloggedin)
{
struct map_session_data *sd = map->id2sd(script_getnum(st,2));
if (script_hasdata(st,3) && sd != NULL
@@ -12344,7 +12922,8 @@ BUILDIN(isloggedin)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(setmapflagnosave) {
+static BUILDIN(setmapflagnosave)
+{
int16 m,x,y;
unsigned short map_index;
const char *str,*str2;
@@ -12366,7 +12945,77 @@ BUILDIN(setmapflagnosave) {
return true;
}
-BUILDIN(getmapflag)
+enum mapinfo_info {
+ MAPINFO_NAME,
+ MAPINFO_ID,
+ MAPINFO_SIZE_X,
+ MAPINFO_SIZE_Y,
+ MAPINFO_ZONE
+};
+
+static BUILDIN(getmapinfo)
+{
+ enum mapinfo_info mode = script_getnum(st, 2);
+ int16 m = -1;
+
+ if (script_hasdata(st, 3)) {
+ if (script_isstringtype(st, 3)) {
+ const char *str = script_getstr(st, 3);
+ m = map->mapindex2mapid(strdb_iget(mapindex->db, str));
+ } else {
+ m = script_getnum(st, 3);
+ }
+ } else {
+ struct block_list *bl = NULL;
+
+ if (st->oid) {
+ bl = map->id2bl(st->oid);
+ } else if (st->rid) {
+ bl = map->id2bl(st->rid);
+ }
+
+ if (bl == NULL) {
+ ShowError("script:getmapinfo: map not supplied and NPC/PC not attached!\n");
+ script_pushint(st, -3);
+ return false;
+ }
+
+ m = bl->m;
+ }
+
+ if (m < 0) {
+ // here we don't throw an error, so the command can be used
+ // to detect whether or not a map exists
+ script_pushint(st, -1);
+ return true;
+ }
+
+ switch (mode) {
+ case MAPINFO_NAME:
+ script_pushconststr(st, map->list[m].name);
+ break;
+ case MAPINFO_ID:
+ script_pushint(st, m);
+ break;
+ case MAPINFO_SIZE_X:
+ script_pushint(st, map->list[m].xs);
+ break;
+ case MAPINFO_SIZE_Y:
+ script_pushint(st, map->list[m].ys);
+ break;
+ case MAPINFO_ZONE:
+ script_pushstrcopy(st, map->list[m].zone->name);
+ break;
+ default:
+ ShowError("script:getmapinfo: unknown option in second argument (%u).\n", mode);
+ script_pushint(st, -2);
+ return false;
+ }
+
+ return true;
+}
+
+static BUILDIN(getmapflag)
{
int16 m,i;
const char *str;
@@ -12428,14 +13077,17 @@ BUILDIN(getmapflag)
case MF_RESET: script_pushint(st,map->list[m].flag.reset); break;
case MF_NOTOMB: script_pushint(st,map->list[m].flag.notomb); break;
case MF_NOCASHSHOP: script_pushint(st,map->list[m].flag.nocashshop); break;
- case MF_NOVIEWID: script_pushint(st,map->list[m].flag.noviewid); break;
+ case MF_NOAUTOLOOT: script_pushint(st, map->list[m].flag.noautoloot); break;
+ case MF_NOVIEWID: script_pushint(st, map->list[m].flag.noviewid); break;
+ case MF_PAIRSHIP_STARTABLE: script_pushint(st, map->list[m].flag.pairship_startable); break;
+ case MF_PAIRSHIP_ENDABLE: script_pushint(st, map->list[m].flag.pairship_endable); break;
}
}
return true;
}
/* pvp timer handling */
-int script_mapflag_pvp_sub(struct block_list *bl, va_list ap)
+static int script_mapflag_pvp_sub(struct block_list *bl, va_list ap)
{
struct map_session_data *sd = NULL;
@@ -12444,7 +13096,8 @@ int script_mapflag_pvp_sub(struct block_list *bl, va_list ap)
sd = BL_UCAST(BL_PC, bl);
if (sd->pvp_timer == INVALID_TIMER) {
- sd->pvp_timer = timer->add(timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0);
+ if (!map->list[sd->bl.m].flag.pvp_nocalcrank)
+ sd->pvp_timer = timer->add(timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0);
sd->pvp_rank = 0;
sd->pvp_lastusers = 0;
sd->pvp_point = 5;
@@ -12456,7 +13109,8 @@ int script_mapflag_pvp_sub(struct block_list *bl, va_list ap)
return 0;
}
-BUILDIN(setmapflag) {
+static BUILDIN(setmapflag)
+{
int16 m,i;
const char *str, *val2 = NULL;
int val=0;
@@ -12495,6 +13149,7 @@ BUILDIN(setmapflag) {
case MF_PVP_NOGUILD: map->list[m].flag.pvp_noguild = 1; break;
case MF_GVG: {
struct block_list bl;
+ memset(&bl, 0, sizeof(bl));
map->list[m].flag.gvg = 1;
clif->map_property_mapall(m, MAPPROPERTY_AGITZONE);
bl.type = BL_NUL;
@@ -12552,14 +13207,18 @@ BUILDIN(setmapflag) {
case MF_RESET: map->list[m].flag.reset = 1; break;
case MF_NOTOMB: map->list[m].flag.notomb = 1; break;
case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 1; break;
+ case MF_NOAUTOLOOT: map->list[m].flag.noautoloot = 1; break;
case MF_NOVIEWID: map->list[m].flag.noviewid = (val <= 0) ? EQP_NONE : val; break;
+ case MF_PAIRSHIP_STARTABLE: map->list[m].flag.pairship_startable = 1; break;
+ case MF_PAIRSHIP_ENDABLE: map->list[m].flag.pairship_endable = 1; break;
}
}
return true;
}
-BUILDIN(removemapflag) {
+static BUILDIN(removemapflag)
+{
int16 m,i;
const char *str;
@@ -12577,6 +13236,7 @@ BUILDIN(removemapflag) {
case MF_NOZENYPENALTY: map->list[m].flag.nozenypenalty = 0; break;
case MF_PVP: {
struct block_list bl;
+ memset(&bl, 0, sizeof(bl));
bl.type = BL_NUL;
bl.m = m;
map->list[m].flag.pvp = 0;
@@ -12588,6 +13248,7 @@ BUILDIN(removemapflag) {
case MF_PVP_NOGUILD: map->list[m].flag.pvp_noguild = 0; break;
case MF_GVG: {
struct block_list bl;
+ memset(&bl, 0, sizeof(bl));
bl.type = BL_NUL;
bl.m = m;
map->list[m].flag.gvg = 0;
@@ -12639,6 +13300,7 @@ BUILDIN(removemapflag) {
case MF_RESET: map->list[m].flag.reset = 0; break;
case MF_NOTOMB: map->list[m].flag.notomb = 0; break;
case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 0; break;
+ case MF_NOAUTOLOOT: map->list[m].flag.noautoloot = 0; break;
case MF_NOVIEWID: map->list[m].flag.noviewid = EQP_NONE; break;
}
}
@@ -12646,7 +13308,7 @@ BUILDIN(removemapflag) {
return true;
}
-BUILDIN(pvpon)
+static BUILDIN(pvpon)
{
int16 m;
const char *str;
@@ -12654,6 +13316,7 @@ BUILDIN(pvpon)
struct s_mapiterator* iter;
struct block_list bl;
+ memset(&bl, 0, sizeof(bl));
str = script_getstr(st,2);
m = map->mapname2mapid(str);
if( m < 0 || map->list[m].flag.pvp )
@@ -12679,7 +13342,8 @@ BUILDIN(pvpon)
if( sd->bl.m != m || sd->pvp_timer != INVALID_TIMER )
continue; // not applicable
- sd->pvp_timer = timer->add(timer->gettick()+200,pc->calc_pvprank_timer,sd->bl.id,0);
+ if (!map->list[m].flag.pvp_nocalcrank)
+ sd->pvp_timer = timer->add(timer->gettick()+200,pc->calc_pvprank_timer,sd->bl.id,0);
sd->pvp_rank = 0;
sd->pvp_lastusers = 0;
sd->pvp_point = 5;
@@ -12691,7 +13355,7 @@ BUILDIN(pvpon)
return true;
}
-int buildin_pvpoff_sub(struct block_list *bl, va_list ap)
+static int buildin_pvpoff_sub(struct block_list *bl, va_list ap)
{
struct map_session_data *sd = NULL;
@@ -12707,11 +13371,13 @@ int buildin_pvpoff_sub(struct block_list *bl, va_list ap)
return 0;
}
-BUILDIN(pvpoff) {
+static BUILDIN(pvpoff)
+{
int16 m;
const char *str;
struct block_list bl;
+ memset(&bl, 0, sizeof(bl));
str=script_getstr(st,2);
m = map->mapname2mapid(str);
if(m < 0 || !map->list[m].flag.pvp)
@@ -12731,7 +13397,8 @@ BUILDIN(pvpoff) {
return true;
}
-BUILDIN(gvgon) {
+static BUILDIN(gvgon)
+{
int16 m;
const char *str;
@@ -12740,6 +13407,7 @@ BUILDIN(gvgon) {
if(m >= 0 && !map->list[m].flag.gvg) {
struct block_list bl;
+ memset(&bl, 0, sizeof(bl));
if( !strdb_exists(map->zone_db,MAP_ZONE_GVG_NAME) ) {
ShowError("buildin_gvgon: zone_db missing '%s'\n",MAP_ZONE_GVG_NAME);
return true;
@@ -12755,7 +13423,8 @@ BUILDIN(gvgon) {
return true;
}
-BUILDIN(gvgoff) {
+static BUILDIN(gvgoff)
+{
int16 m;
const char *str;
@@ -12763,6 +13432,7 @@ BUILDIN(gvgoff) {
m = map->mapname2mapid(str);
if(m >= 0 && map->list[m].flag.gvg) {
struct block_list bl;
+ memset(&bl, 0, sizeof(bl));
map->zone_change2(m, map->list[m].prev_zone);
map->list[m].flag.gvg = 0;
clif->map_property_mapall(m, MAPPROPERTY_NOTHING);
@@ -12778,7 +13448,8 @@ BUILDIN(gvgoff) {
* emotion emotion#, <target: 0 - NPC, 1 - PC>, <NPC/PC name>
*------------------------------------------*/
//Optional second parameter added by [Skotlex]
-BUILDIN(emotion) {
+static BUILDIN(emotion)
+{
int type;
int player=0;
@@ -12807,7 +13478,7 @@ BUILDIN(emotion) {
return true;
}
-int buildin_maprespawnguildid_sub_pc(struct map_session_data* sd, va_list ap)
+static int buildin_maprespawnguildid_sub_pc(struct map_session_data *sd, va_list ap)
{
int16 m=va_arg(ap,int);
int g_id=va_arg(ap,int);
@@ -12824,7 +13495,7 @@ int buildin_maprespawnguildid_sub_pc(struct map_session_data* sd, va_list ap)
return 1;
}
-int buildin_maprespawnguildid_sub_mob(struct block_list *bl, va_list ap)
+static int buildin_maprespawnguildid_sub_mob(struct block_list *bl, va_list ap)
{
struct mob_data *md = NULL;
@@ -12838,7 +13509,8 @@ int buildin_maprespawnguildid_sub_mob(struct block_list *bl, va_list ap)
return 0;
}
-BUILDIN(maprespawnguildid) {
+static BUILDIN(maprespawnguildid)
+{
const char *mapname=script_getstr(st,2);
int g_id=script_getnum(st,3);
int flag=script_getnum(st,4);
@@ -12855,28 +13527,32 @@ BUILDIN(maprespawnguildid) {
return true;
}
-BUILDIN(agitstart) {
+static BUILDIN(agitstart)
+{
if(map->agit_flag==1) return true; // Agit already Start.
map->agit_flag=1;
guild->agit_start();
return true;
}
-BUILDIN(agitend) {
+static BUILDIN(agitend)
+{
if(map->agit_flag==0) return true; // Agit already End.
map->agit_flag=0;
guild->agit_end();
return true;
}
-BUILDIN(agitstart2) {
+static BUILDIN(agitstart2)
+{
if(map->agit2_flag==1) return true; // Agit2 already Start.
map->agit2_flag=1;
guild->agit2_start();
return true;
}
-BUILDIN(agitend2) {
+static BUILDIN(agitend2)
+{
if(map->agit2_flag==0) return true; // Agit2 already End.
map->agit2_flag=0;
guild->agit2_end();
@@ -12886,7 +13562,8 @@ BUILDIN(agitend2) {
/*==========================================
* Returns whether woe is on or off.
*------------------------------------------*/
-BUILDIN(agitcheck) {
+static BUILDIN(agitcheck)
+{
script_pushint(st,map->agit_flag);
return true;
}
@@ -12894,7 +13571,8 @@ BUILDIN(agitcheck) {
/*==========================================
* Returns whether woese is on or off.
*------------------------------------------*/
-BUILDIN(agitcheck2) {
+static BUILDIN(agitcheck2)
+{
script_pushint(st,map->agit2_flag);
return true;
}
@@ -12902,7 +13580,7 @@ BUILDIN(agitcheck2) {
/// Sets the guild_id of this npc.
///
/// flagemblem <guild_id>;
-BUILDIN(flagemblem)
+static BUILDIN(flagemblem)
{
struct npc_data *nd;
int g_id = script_getnum(st,2);
@@ -12927,7 +13605,7 @@ BUILDIN(flagemblem)
return true;
}
-BUILDIN(getcastlename)
+static BUILDIN(getcastlename)
{
const char* mapname = mapindex->getmapname(script_getstr(st,2),NULL);
struct guild_castle* gc = guild->mapname2gc(mapname);
@@ -12936,7 +13614,7 @@ BUILDIN(getcastlename)
return true;
}
-BUILDIN(getcastledata)
+static BUILDIN(getcastledata)
{
const char *mapname = mapindex->getmapname(script_getstr(st,2),NULL);
int index = script_getnum(st,3);
@@ -12979,7 +13657,7 @@ BUILDIN(getcastledata)
return true;
}
-BUILDIN(setcastledata)
+static BUILDIN(setcastledata)
{
const char *mapname = mapindex->getmapname(script_getstr(st,2),NULL);
int index = script_getnum(st,3);
@@ -13002,7 +13680,7 @@ BUILDIN(setcastledata)
/* =====================================================================
* ---------------------------------------------------------------------*/
-BUILDIN(requestguildinfo)
+static BUILDIN(requestguildinfo)
{
int guild_id=script_getnum(st,2);
const char *event=NULL;
@@ -13019,7 +13697,7 @@ BUILDIN(requestguildinfo)
/// Returns the number of cards that have been compounded onto the specified equipped item.
/// getequipcardcnt(<equipment slot>);
-BUILDIN(getequipcardcnt)
+static BUILDIN(getequipcardcnt)
{
int i=-1,j,num;
struct map_session_data *sd;
@@ -13056,149 +13734,115 @@ BUILDIN(getequipcardcnt)
/// Removes all cards from the item found in the specified equipment slot of the invoking character,
/// and give them to the character. If any cards were removed in this manner, it will also show a success effect.
-/// successremovecards <slot>;
-BUILDIN(successremovecards)
+/// successremovecards(<slot>);
+static BUILDIN(successremovecards)
{
- int i=-1,c,cardflag=0;
+ int i = -1, c, cardflag = 0;
struct map_session_data *sd = script->rid2sd(st);
- int num = script_getnum(st,2);
+ int num = script_getnum(st, 2);
if (sd == NULL)
return true;
if (num > 0 && num <= ARRAYLENGTH(script->equip))
- i=pc->checkequip(sd,script->equip[num-1]);
+ i = pc->checkequip(sd,script->equip[num - 1]);
- if (i < 0 || !sd->inventory_data[i]) {
+ if (i < 0 || sd->inventory_data[i] == NULL)
return true;
- }
- if(itemdb_isspecial(sd->status.inventory[i].card[0]))
+ if (itemdb_isspecial(sd->status.inventory[i].card[0]))
return true;
- for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) {
- if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) {// extract this card from the item
+ for (c = sd->inventory_data[i]->slot - 1; c >= 0; --c) {
+ if (sd->status.inventory[i].card[c] > 0 && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD) {
int flag;
struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
+
+ memset(&item_tmp, 0, sizeof(item_tmp));
+
cardflag = 1;
- item_tmp.nameid = sd->status.inventory[i].card[c];
+ item_tmp.nameid = sd->status.inventory[i].card[c];
item_tmp.identify = 1;
+ sd->status.inventory[i].card[c] = 0;
- if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
- // get back the cart in inventory
- clif->additem(sd,0,0,flag);
- map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
+ if ((flag = pc->additem(sd, &item_tmp, 1, LOG_TYPE_SCRIPT))) {
+ clif->additem(sd, 0, 0, flag);
+ map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
}
}
}
if (cardflag == 1) {
- //if card was remove replace item with no card
- int flag, j;
- struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
-
- item_tmp.nameid = sd->status.inventory[i].nameid;
- item_tmp.identify = 1;
- item_tmp.refine = sd->status.inventory[i].refine;
- item_tmp.attribute = sd->status.inventory[i].attribute;
- item_tmp.expire_time = sd->status.inventory[i].expire_time;
- item_tmp.bound = sd->status.inventory[i].bound;
-
- 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, 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);
- map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
- }
-
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE);
+ clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE);
+ clif->additem(sd, i, 1, 0);
+ pc->equipitem(sd, i, sd->status.inventory[i].equip);
clif->misceffect(&sd->bl,3);
}
return true;
}
/// Removes all cards from the item found in the specified equipment slot of the invoking character.
-/// failedremovecards <slot>, <type>;
+/// failedremovecards(<slot>, <type>);
/// <type>=0 : will destroy both the item and the cards.
/// <type>=1 : will keep the item, but destroy the cards.
/// <type>=2 : will keep the cards, but destroy the item.
-/// <type>=? : will just display the failure effect.
-BUILDIN(failedremovecards)
+/// <type>=3 : will just display the failure effect.
+static BUILDIN(failedremovecards)
{
- int i=-1,c,cardflag=0;
+ int i = -1, c, cardflag = 0;
+ int num = script_getnum(st, 2);
+ int typefail = script_getnum(st, 3);
struct map_session_data *sd = script->rid2sd(st);
- int num = script_getnum(st,2);
- int typefail = script_getnum(st,3);
if (sd == NULL)
return true;
if (num > 0 && num <= ARRAYLENGTH(script->equip))
- i=pc->checkequip(sd,script->equip[num-1]);
+ i = pc->checkequip(sd, script->equip[num - 1]);
- if (i < 0 || !sd->inventory_data[i])
+ if (i < 0 || sd->inventory_data[i] == NULL)
return true;
- if(itemdb_isspecial(sd->status.inventory[i].card[0]))
+ if (itemdb_isspecial(sd->status.inventory[i].card[0]))
return true;
- for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) {
- if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) {
+ for (c = sd->inventory_data[i]->slot - 1; c >= 0; --c) {
+ if (sd->status.inventory[i].card[c] > 0 && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD) {
cardflag = 1;
- if(typefail == 2) {// add cards to inventory, clear
+ sd->status.inventory[i].card[c] = 0;
+
+ if (typefail == 2) { // add cards to inventory, clear
int flag;
struct item item_tmp;
- memset(&item_tmp,0,sizeof(item_tmp));
+ memset(&item_tmp, 0, sizeof(item_tmp));
- item_tmp.nameid = sd->status.inventory[i].card[c];
+ item_tmp.nameid = sd->status.inventory[i].card[c];
item_tmp.identify = 1;
- if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
- clif->additem(sd,0,0,flag);
- map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
+ if ((flag = pc->additem(sd, &item_tmp, 1, LOG_TYPE_SCRIPT))) {
+ clif->additem(sd, 0, 0, flag);
+ map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
}
}
}
}
if (cardflag == 1) {
- if (typefail == 0 || typefail == 2) {
- // destroy the item
+ if (typefail == 0 || typefail == 2) { // destroy the item
pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT);
} else if (typefail == 1) {
- // destroy the card
- int flag, j;
- struct item item_tmp;
-
- memset(&item_tmp,0,sizeof(item_tmp));
-
- item_tmp.nameid = sd->status.inventory[i].nameid;
- item_tmp.identify = 1;
- item_tmp.refine = sd->status.inventory[i].refine;
- item_tmp.attribute = sd->status.inventory[i].attribute;
- item_tmp.expire_time = sd->status.inventory[i].expire_time;
- item_tmp.bound = sd->status.inventory[i].bound;
-
- 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, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT);
-
- if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
- clif->additem(sd,0,0,flag);
- map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
- }
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE);
+ clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE);
+ clif->additem(sd, i, 1, 0);
+ pc->equipitem(sd, i, sd->status.inventory[i].equip);
}
- clif->misceffect(&sd->bl,2);
}
+ clif->misceffect(&sd->bl, 2);
return true;
}
@@ -13209,7 +13853,8 @@ BUILDIN(failedremovecards)
* improved by [Lance]
* ================================================================*/
// Added by RoVeRT
-BUILDIN(mapwarp) {
+static BUILDIN(mapwarp)
+{
int x,y,m,check_val=0,check_ID=0,i=0;
struct guild *g = NULL;
struct party_data *p = NULL;
@@ -13262,7 +13907,7 @@ BUILDIN(mapwarp) {
}
// Added by RoVeRT
-int buildin_mobcount_sub(struct block_list *bl, va_list ap)
+static int buildin_mobcount_sub(struct block_list *bl, va_list ap)
{
char *event = va_arg(ap,char *);
const struct mob_data *md = NULL;
@@ -13277,7 +13922,8 @@ int buildin_mobcount_sub(struct block_list *bl, va_list ap)
}
// Added by RoVeRT
-BUILDIN(mobcount) {
+static BUILDIN(mobcount)
+{
const char *mapname,*event;
int16 m;
mapname=script_getstr(st,2);
@@ -13310,7 +13956,8 @@ BUILDIN(mobcount) {
return true;
}
-BUILDIN(marriage) {
+static BUILDIN(marriage)
+{
const char *partner=script_getstr(st,2);
struct map_session_data *sd = script->rid2sd(st);
struct map_session_data *p_sd = script->nick2sd(st, partner);
@@ -13322,7 +13969,7 @@ BUILDIN(marriage) {
script_pushint(st,1);
return true;
}
-BUILDIN(wedding_effect)
+static BUILDIN(wedding_effect)
{
struct map_session_data *sd = script->rid2sd(st);
struct block_list *bl;
@@ -13334,7 +13981,7 @@ BUILDIN(wedding_effect)
clif->wedding_effect(bl);
return true;
}
-BUILDIN(divorce)
+static BUILDIN(divorce)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL || pc->divorce(sd) < 0) {
@@ -13345,7 +13992,8 @@ BUILDIN(divorce)
return true;
}
-BUILDIN(ispartneron) {
+static BUILDIN(ispartneron)
+{
struct map_session_data *sd = script->rid2sd(st);
if (sd==NULL || !pc->ismarried(sd)
@@ -13358,7 +14006,7 @@ BUILDIN(ispartneron) {
return true;
}
-BUILDIN(getpartnerid)
+static BUILDIN(getpartnerid)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -13368,7 +14016,7 @@ BUILDIN(getpartnerid)
return true;
}
-BUILDIN(getchildid)
+static BUILDIN(getchildid)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -13378,7 +14026,7 @@ BUILDIN(getchildid)
return true;
}
-BUILDIN(getmotherid)
+static BUILDIN(getmotherid)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -13388,7 +14036,8 @@ BUILDIN(getmotherid)
return true;
}
-BUILDIN(getfatherid) {
+static BUILDIN(getfatherid)
+{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
@@ -13397,7 +14046,7 @@ BUILDIN(getfatherid) {
return true;
}
-BUILDIN(warppartner)
+static BUILDIN(warppartner)
{
int x,y;
unsigned short map_index;
@@ -13427,7 +14076,7 @@ BUILDIN(warppartner)
/*================================================
* Script for Displaying MOB Information [Valaris]
*------------------------------------------------*/
-BUILDIN(strmobinfo)
+static BUILDIN(strmobinfo)
{
int num=script_getnum(st,2);
@@ -13461,7 +14110,8 @@ BUILDIN(strmobinfo)
* Summon guardians [Valaris]
* guardian("<map name>",<x>,<y>,"<name to show>",<mob id>{,"<event label>"}{,<guardian index>}) -> <id>
*------------------------------------------*/
-BUILDIN(guardian) {
+static BUILDIN(guardian)
+{
int class_ = 0, x = 0, y = 0, guardian = 0;
const char *str, *mapname, *evt="";
bool has_index = false;
@@ -13502,7 +14152,8 @@ BUILDIN(guardian) {
/*==========================================
* Invisible Walls [Zephyrus]
*------------------------------------------*/
-BUILDIN(setwall) {
+static BUILDIN(setwall)
+{
const char *mapname, *name;
int x, y, m, size, dir;
bool shootable;
@@ -13521,9 +14172,15 @@ BUILDIN(setwall) {
map->iwall_set(m, x, y, size, dir, shootable, name);
return true;
}
-BUILDIN(delwall) {
+
+static BUILDIN(delwall)
+{
const char *name = script_getstr(st,2);
- map->iwall_remove(name);
+
+ if (!map->iwall_remove(name)) {
+ ShowWarning("buildin_delwall: Non-existent '%s' provided.\n", name);
+ return false;
+ }
return true;
}
@@ -13535,7 +14192,8 @@ BUILDIN(delwall) {
/// 1 - maximum hp
/// 2 - current hp
///
-BUILDIN(guardianinfo) {
+static BUILDIN(guardianinfo)
+{
const char* mapname = mapindex->getmapname(script_getstr(st,2),NULL);
int id = script_getnum(st,3);
int type = script_getnum(st,4);
@@ -13567,7 +14225,8 @@ BUILDIN(guardianinfo) {
/*==========================================
* Get the item name by item_id or null
*------------------------------------------*/
-BUILDIN(getitemname) {
+static BUILDIN(getitemname)
+{
int item_id=0;
struct item_data *i_data;
char *item_name;
@@ -13595,7 +14254,7 @@ BUILDIN(getitemname) {
/*==========================================
* Returns number of slots an item has. [Skotlex]
*------------------------------------------*/
-BUILDIN(getitemslots)
+static BUILDIN(getitemslots)
{
int item_id;
struct item_data *i_data;
@@ -13611,88 +14270,353 @@ BUILDIN(getitemslots)
return true;
}
-// TODO: add matk here if needed/once we get rid of RENEWAL
+// TODO: add matk here if needed
/*==========================================
* Returns some values of an item [Lupus]
* Price, Weight, etc...
- * getiteminfo(itemID,n), where n
- * 0 value_buy;
- * 1 value_sell;
- * 2 type;
- * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc..
- * if = 0, then monsters don't drop it at all (rare or a quest item)
- * if = -1, then this item is sold in NPC shops only
- * 4 sex;
- * 5 equip;
- * 6 weight;
- * 7 atk;
- * 8 def;
- * 9 range;
- * 10 slot;
- * 11 look;
- * 12 elv;
- * 13 wlv;
- * 14 view id
*------------------------------------------*/
-BUILDIN(getiteminfo)
+static BUILDIN(getiteminfo)
{
- int item_id,n;
- struct item_data *i_data;
+ int item_id = script_getnum(st, 2);
+ int n = script_getnum(st, 3);
+ struct item_data *it = itemdb->exists(item_id);
- item_id = script_getnum(st,2);
- n = script_getnum(st,3);
- i_data = itemdb->exists(item_id);
+ if (it == NULL) {
+ script_pushint(st, -1);
+ return true;
+ }
- if (i_data && n>=0 && n<=14) {
- int *item_arr = (int*)&i_data->value_buy;
- script_pushint(st,item_arr[n]);
- } else {
+ switch (n) {
+ case ITEMINFO_BUYPRICE:
+ script_pushint(st, it->value_buy);
+ break;
+ case ITEMINFO_SELLPRICE:
+ script_pushint(st, it->value_sell);
+ break;
+ case ITEMINFO_TYPE:
+ script_pushint(st, it->type);
+ break;
+ case ITEMINFO_MAXCHANCE:
+ script_pushint(st, it->maxchance);
+ break;
+ case ITEMINFO_SEX:
+ script_pushint(st, it->sex);
+ break;
+ case ITEMINFO_LOC:
+ script_pushint(st, it->equip);
+ break;
+ case ITEMINFO_WEIGHT:
+ script_pushint(st, it->weight);
+ break;
+ case ITEMINFO_ATK:
+ script_pushint(st, it->atk);
+ break;
+ case ITEMINFO_DEF:
+ script_pushint(st, it->def);
+ break;
+ case ITEMINFO_RANGE:
+ script_pushint(st, it->range);
+ break;
+ case ITEMINFO_SLOTS:
+ script_pushint(st, it->slot);
+ break;
+ case ITEMINFO_SUBTYPE:
+ script_pushint(st, it->subtype);
+ break;
+ case ITEMINFO_ELV:
+ script_pushint(st, it->elv);
+ break;
+ case ITEMINFO_WLV:
+ script_pushint(st, it->wlv);
+ break;
+ case ITEMINFO_VIEWID:
+ script_pushint(st, it->view_id);
+ break;
+ case ITEMINFO_MATK:
+ script_pushint(st, it->matk);
+ break;
+ case ITEMINFO_VIEWSPRITE:
+ script_pushint(st, it->view_sprite);
+ break;
+ case ITEMINFO_TRADE:
+ script_pushint(st, it->flag.trade_restriction);
+ break;
+ default:
+ ShowError("buildin_getiteminfo: Invalid item type %d.\n", n);
script_pushint(st,-1);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Returns the value of the current equipment being parsed using static variables -
+ * current_equip_item_index and current_equip_option_index.
+ * !!Designed to be used with item_options.conf only!!
+ * *getequippedoptioninfo(<info_type>);
+ *
+ * @param (int) Types -
+ * IT_OPT_INDEX ID of the item option.
+ * IT_OPT_VALUE Amount of the bonus to be added.
+ * @return value of the type or -1.
+ */
+static BUILDIN(getequippedoptioninfo)
+{
+ int val = 0, type = script_getnum(st, 2);
+ struct map_session_data *sd = NULL;
+
+ if ((sd = script->rid2sd(st)) == NULL || status->current_equip_item_index == -1 || status->current_equip_option_index == -1
+ || !sd->status.inventory[status->current_equip_item_index].option[status->current_equip_option_index].index) {
+ script_pushint(st, -1);
+ return false;
+ }
+
+ switch (type) {
+ case IT_OPT_INDEX:
+ val = sd->status.inventory[status->current_equip_item_index].option[status->current_equip_option_index].index;
+ break;
+ case IT_OPT_VALUE:
+ val = sd->status.inventory[status->current_equip_item_index].option[status->current_equip_option_index].value;
+ break;
+ default:
+ ShowError("buildin_getequippedoptioninfo: Invalid option data type %d (Max %d).\n", type, IT_OPT_MAX-1);
+ script_pushint(st, -1);
+ return false;
+ }
+
+ script_pushint(st, val);
+
+ return true;
+}
+
+/**
+ * Gets the option information of an equipment.
+ * *getequipoption(<equip_index>,<slot>,<type>);
+ *
+ * @param equip_index as the Index of the Equipment.
+ * @param slot as the slot# of the Item Option (1 to MAX_ITEM_OPTIONS)
+ * @param type IT_OPT_INDEX or IT_OPT_VALUE.
+ * @return (int) value or -1 on failure.
+ */
+static BUILDIN(getequipoption)
+{
+ int val = 0, equip_index = script_getnum(st, 2);
+ int slot = script_getnum(st, 3);
+ int opt_type = script_getnum(st, 4);
+ int i = -1;
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
+ ShowError("buildin_getequipoption: Player not attached!\n");
+ return false;
+ }
+
+ if (slot <= 0 || slot > MAX_ITEM_OPTIONS) {
+ script_pushint(st, -1);
+ ShowError("buildin_getequipoption: Invalid option slot %d (Min: 1, Max: %d) provided.\n", slot, MAX_ITEM_OPTIONS);
+ return false;
+ }
+
+ if (equip_index > 0 && equip_index <= ARRAYLENGTH(script->equip)) {
+ if ((i = pc->checkequip(sd, script->equip[equip_index - 1])) == -1) {
+ ShowError("buildin_getequipoption: No equipment is equipped in the given index %d.\n", equip_index);
+ script_pushint(st, -1);
+ return false;
+ }
+ } else {
+ ShowError("buildin_getequipoption: Invalid equipment index %d provided.\n", equip_index);
+ script_pushint(st, 0);
+ return false;
}
+
+ if (sd->status.inventory[i].nameid != 0) {
+ switch (opt_type) {
+ case IT_OPT_INDEX:
+ val = sd->status.inventory[i].option[slot-1].index;
+ break;
+ case IT_OPT_VALUE:
+ val = sd->status.inventory[i].option[slot-1].value;
+ break;
+ default:
+ ShowError("buildin_getequipoption: Invalid option data type %d provided.\n", opt_type);
+ script_pushint(st, -1);
+ break;
+ }
+ }
+
+ script_pushint(st, val);
+
return true;
}
+/**
+ * Set an equipment's option value.
+ * *setequipoption(<equip_index>,<slot>,<opt_index>,<value>);
+ *
+ * @param equip_index as the inventory index of the equipment.
+ * @param slot as the slot of the item option (1 to MAX_ITEM_OPTIONS)
+ * @param opt_index as the index of the option available as "Id" in db/item_options.conf.
+ * @param value as the value of the option type.
+ * For IT_OPT_INDEX see "Name" in item_options.conf
+ * For IT_OPT_VALUE, the value of the script bonus.
+ * @return 0 on failure, 1 on success.
+ */
+static BUILDIN(setequipoption)
+{
+ int equip_index = script_getnum(st, 2);
+ int slot = script_getnum(st, 3);
+ int opt_index = script_getnum(st, 4);
+ int value = script_getnum(st, 5);
+ int i = -1;
+
+ struct map_session_data *sd = script->rid2sd(st);
+ struct itemdb_option *ito = NULL;
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipoption: Player not attached!\n");
+ return false;
+ }
+
+ if (slot <= 0 || slot > MAX_ITEM_OPTIONS) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipoption: Invalid option index %d (Min: 1, Max: %d) provided.\n", slot, MAX_ITEM_OPTIONS);
+ return false;
+ }
+
+ if (equip_index > 0 && equip_index <= ARRAYLENGTH(script->equip)) {
+ if ((i = pc->checkequip(sd, script->equip[equip_index - 1])) == -1) {
+ ShowError("buildin_setequipoption: No equipment is equipped in the given index %d.\n", equip_index);
+ script_pushint(st, 0);
+ return false;
+ }
+ } else {
+ ShowError("buildin_setequipoption: Invalid equipment index %d provided.\n", equip_index);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (sd->status.inventory[i].nameid != 0) {
+ if (opt_index == 0) {
+ // Remove the option
+ sd->status.inventory[i].option[slot-1].index = 0;
+ sd->status.inventory[i].option[slot-1].value = 0;
+ } else {
+ if ((ito = itemdb->option_exists(opt_index)) == NULL) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipotion: Option index %d does not exist!\n", opt_index);
+ return false;
+ } else if (value < -INT16_MAX || value > INT16_MAX) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipotion: Option value %d exceeds maximum limit (%d to %d) for type!\n", value, -INT16_MAX, INT16_MAX);
+ return false;
+ }
+ /* Add Option Index */
+ sd->status.inventory[i].option[slot-1].index = ito->index;
+ /* Add Option Value */
+ sd->status.inventory[i].option[slot-1].value = value;
+ }
+
+ /* Unequip and simulate deletion of the item. */
+ 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); // notify client of a refine.
+ clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE); // notify client to simulate item deletion.
+ /* Log deletion of the item. */
+ logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]);
+ /* Equip and simulate addition of the item. */
+ clif->additem(sd, i, 1, 0); // notify client to simulate item addition.
+ /* Log addition of the item. */
+ logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i], sd->inventory_data[i]);
+ pc->equipitem(sd, i, sd->status.inventory[i].equip); // force equip the item at the original position.
+ clif->misceffect(&sd->bl, 2); // show effect
+ }
+
+ script_pushint(st, 1);
+
+ return true;
+
+}
+
/*==========================================
* Set some values of an item [Lupus]
* Price, Weight, etc...
- * setiteminfo(itemID,n,Value), where n
- * 0 value_buy;
- * 1 value_sell;
- * 2 type;
- * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc..
- * if = 0, then monsters don't drop it at all (rare or a quest item)
- * if = -1, then this item is sold in NPC shops only
- * 4 sex;
- * 5 equip;
- * 6 weight;
- * 7 atk;
- * 8 def;
- * 9 range;
- * 10 slot;
- * 11 look;
- * 12 elv;
- * 13 wlv;
- * 14 view id
- * Returns Value or -1 if the wrong field's been set
*------------------------------------------*/
-BUILDIN(setiteminfo)
+static BUILDIN(setiteminfo)
{
- int item_id,n,value;
- struct item_data *i_data;
+ // TODO: Validate data in a similar way as during database load
+ int item_id = script_getnum(st, 2);
+ int n = script_getnum(st, 3);
+ int value = script_getnum(st,4);
+ struct item_data *it = itemdb->exists(item_id);
- item_id = script_getnum(st,2);
- n = script_getnum(st,3);
- value = script_getnum(st,4);
- i_data = itemdb->exists(item_id);
+ if (it == NULL) {
+ script_pushint(st, -1);
+ return true;
+ }
- if (i_data && n>=0 && n<=14) {
- int *item_arr = (int*)&i_data->value_buy;
- item_arr[n] = value;
- script_pushint(st,value);
- } else {
+ switch (n) {
+ case ITEMINFO_BUYPRICE:
+ it->value_buy = value;
+ break;
+ case ITEMINFO_SELLPRICE:
+ it->value_sell = value;
+ break;
+ case ITEMINFO_TYPE:
+ it->type = value;
+ break;
+ case ITEMINFO_MAXCHANCE:
+ it->maxchance = value;
+ break;
+ case ITEMINFO_SEX:
+ it->sex = value;
+ break;
+ case ITEMINFO_LOC:
+ it->equip = value;
+ break;
+ case ITEMINFO_WEIGHT:
+ it->weight = value;
+ break;
+ case ITEMINFO_ATK:
+ it->atk = value;
+ break;
+ case ITEMINFO_DEF:
+ it->def = value;
+ break;
+ case ITEMINFO_RANGE:
+ it->range = value;
+ break;
+ case ITEMINFO_SLOTS:
+ it->slot = value;
+ break;
+ case ITEMINFO_SUBTYPE:
+ it->subtype = value;
+ break;
+ case ITEMINFO_ELV:
+ it->elv = value;
+ break;
+ case ITEMINFO_WLV:
+ it->wlv = value;
+ break;
+ case ITEMINFO_VIEWID:
+ it->view_id = value;
+ break;
+ case ITEMINFO_MATK:
+ it->matk = value;
+ break;
+ case ITEMINFO_VIEWSPRITE:
+ it->view_sprite = value;
+ break;
+ case ITEMINFO_TRADE:
+ it->flag.trade_restriction = value;
+ break;
+ default:
+ ShowError("buildin_setiteminfo: invalid type %d.\n", n);
script_pushint(st,-1);
+ return false;
}
+ script_pushint(st,value);
return true;
}
@@ -13708,7 +14632,7 @@ BUILDIN(setiteminfo)
* Useful for such quests as "Sign this refined item with players name" etc
* Hat[0] +4 -> Player's Hat[0] +4
*------------------------------------------*/
-BUILDIN(getequipcardid)
+static BUILDIN(getequipcardid)
{
int i=-1,num,slot;
struct map_session_data *sd;
@@ -13733,7 +14657,7 @@ BUILDIN(getequipcardid)
/*==========================================
* petskillbonus [Valaris] //Rewritten by [Skotlex]
*------------------------------------------*/
-BUILDIN(petskillbonus)
+static BUILDIN(petskillbonus)
{
struct pet_data *pd;
@@ -13770,7 +14694,7 @@ BUILDIN(petskillbonus)
/*==========================================
* pet looting [Valaris] //Rewritten by [Skotlex]
*------------------------------------------*/
-BUILDIN(petloot)
+static BUILDIN(petloot)
{
int max;
struct pet_data *pd;
@@ -13810,93 +14734,108 @@ BUILDIN(petloot)
* @inventorylist_card(0..3), @inventorylist_expire
* @inventorylist_count = scalar
*------------------------------------------*/
-BUILDIN(getinventorylist)
+static BUILDIN(getinventorylist)
{
struct map_session_data *sd = script->rid2sd(st);
- char card_var[NAME_LENGTH];
+ char card_var[SCRIPT_VARNAME_LENGTH];
- int i,j=0,k;
+ int j=0,k;
if(!sd) return true;
- for(i=0;i<MAX_INVENTORY;i++) {
+ for (int i = 0;i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0) {
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid);
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_id"), j),sd->status.inventory[i].nameid);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_amount"), j),sd->status.inventory[i].amount);
if(sd->status.inventory[i].equip) {
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_equip"), j),pc->equippoint(sd,i));
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_equip"), j),pc->equippoint(sd,i));
} else {
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_equip"), j),0);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_equip"), j),0);
}
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_refine"), j),sd->status.inventory[i].refine);
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_identify"), j),sd->status.inventory[i].identify);
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_attribute"), j),sd->status.inventory[i].attribute);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_refine"), j),sd->status.inventory[i].refine);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_identify"), j),sd->status.inventory[i].identify);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_attribute"), j),sd->status.inventory[i].attribute);
for (k = 0; k < MAX_SLOTS; k++) {
sprintf(card_var, "@inventorylist_card%d",k+1);
- pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.inventory[i].card[k]);
+ pc->setreg(sd,reference_uid(script->add_variable(card_var), j),sd->status.inventory[i].card[k]);
+ }
+ for (k = 0; k < MAX_ITEM_OPTIONS; k++) {
+ sprintf(card_var, "@inventorylist_opt_id%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_variable(card_var), j), sd->status.inventory[i].option[k].index);
+ sprintf(card_var, "@inventorylist_opt_val%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_variable(card_var), j), sd->status.inventory[i].option[k].value);
+ sprintf(card_var, "@inventorylist_opt_param%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_variable(card_var), j), sd->status.inventory[i].option[k].param);
}
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
- pc->setreg(sd,reference_uid(script->add_str("@inventorylist_bound"), j),sd->status.inventory[i].bound);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
+ pc->setreg(sd,reference_uid(script->add_variable("@inventorylist_bound"), j),sd->status.inventory[i].bound);
j++;
}
}
- pc->setreg(sd,script->add_str("@inventorylist_count"),j);
+ pc->setreg(sd,script->add_variable("@inventorylist_count"),j);
return true;
}
-BUILDIN(getcartinventorylist)
+static BUILDIN(getcartinventorylist)
{
struct map_session_data *sd = script->rid2sd(st);
- char card_var[26];
+ char card_var[SCRIPT_VARNAME_LENGTH];
int i,j=0,k;
if(!sd) return true;
for(i=0;i<MAX_CART;i++) {
if(sd->status.cart[i].nameid > 0 && sd->status.cart[i].amount > 0) {
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_id"), j),sd->status.cart[i].nameid);
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_amount"), j),sd->status.cart[i].amount);
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_equip"), j),sd->status.cart[i].equip);
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_refine"), j),sd->status.cart[i].refine);
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_identify"), j),sd->status.cart[i].identify);
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_attribute"), j),sd->status.cart[i].attribute);
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_id"), j),sd->status.cart[i].nameid);
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_amount"), j),sd->status.cart[i].amount);
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_equip"), j),sd->status.cart[i].equip);
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_refine"), j),sd->status.cart[i].refine);
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_identify"), j),sd->status.cart[i].identify);
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_attribute"), j),sd->status.cart[i].attribute);
for (k = 0; k < MAX_SLOTS; k++) {
sprintf(card_var, "@cartinventorylist_card%d",k+1);
- pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.cart[i].card[k]);
+ pc->setreg(sd,reference_uid(script->add_variable(card_var), j),sd->status.cart[i].card[k]);
}
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_expire"), j),sd->status.cart[i].expire_time);
- pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_bound"), j),sd->status.cart[i].bound);
+ for (k = 0; k < MAX_ITEM_OPTIONS; k++) {
+ sprintf(card_var, "@cartinventorylist_opt_id%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_variable(card_var), j), sd->status.cart[i].option[k].index);
+ sprintf(card_var, "@cartinventorylist_opt_val%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_variable(card_var), j), sd->status.cart[i].option[k].value);
+ sprintf(card_var, "@cartinventorylist_opt_param%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_variable(card_var), j), sd->status.cart[i].option[k].param);
+ }
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_expire"), j),sd->status.cart[i].expire_time);
+ pc->setreg(sd,reference_uid(script->add_variable("@cartinventorylist_bound"), j),sd->status.cart[i].bound);
j++;
}
}
- pc->setreg(sd,script->add_str("@cartinventorylist_count"),j);
+ pc->setreg(sd,script->add_variable("@cartinventorylist_count"),j);
return true;
}
-BUILDIN(getskilllist)
+static BUILDIN(getskilllist)
{
struct map_session_data *sd = script->rid2sd(st);
int i,j=0;
if (sd == NULL)
return true;
- for(i=0;i<MAX_SKILL;i++) {
+ for (i = 0; i < MAX_SKILL_DB; i++) {
if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0) {
- pc->setreg(sd,reference_uid(script->add_str("@skilllist_id"), j),sd->status.skill[i].id);
- pc->setreg(sd,reference_uid(script->add_str("@skilllist_lv"), j),sd->status.skill[i].lv);
- pc->setreg(sd,reference_uid(script->add_str("@skilllist_flag"), j),sd->status.skill[i].flag);
+ pc->setreg(sd,reference_uid(script->add_variable("@skilllist_id"), j),sd->status.skill[i].id);
+ pc->setreg(sd,reference_uid(script->add_variable("@skilllist_lv"), j),sd->status.skill[i].lv);
+ pc->setreg(sd,reference_uid(script->add_variable("@skilllist_flag"), j),sd->status.skill[i].flag);
j++;
}
}
- pc->setreg(sd,script->add_str("@skilllist_count"),j);
+ pc->setreg(sd,script->add_variable("@skilllist_count"),j);
return true;
}
-BUILDIN(clearitem)
+static BUILDIN(clearitem)
{
struct map_session_data *sd = script->rid2sd(st);
- int i;
if (sd == NULL)
return true;
- for (i=0; i<MAX_INVENTORY; i++) {
+ for (int i = 0; i < sd->status.inventorySize; i++) {
if (sd->status.inventory[i].amount) {
pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT);
}
@@ -13907,7 +14846,7 @@ BUILDIN(clearitem)
/*==========================================
* Disguise Player (returns Mob/NPC ID if success, 0 on fail)
*------------------------------------------*/
-BUILDIN(disguise)
+static BUILDIN(disguise)
{
int id;
struct map_session_data *sd = script->rid2sd(st);
@@ -13928,7 +14867,7 @@ BUILDIN(disguise)
/*==========================================
* Undisguise Player (returns 1 if success, 0 on fail)
*------------------------------------------*/
-BUILDIN(undisguise)
+static BUILDIN(undisguise)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -13947,7 +14886,7 @@ BUILDIN(undisguise)
* Transform a bl to another class,
* @type unused
*------------------------------------------*/
-BUILDIN(classchange)
+static BUILDIN(classchange)
{
int class, type, target;
struct block_list *bl = map->id2bl(st->oid);
@@ -13973,7 +14912,7 @@ BUILDIN(classchange)
/*==========================================
* Display an effect
*------------------------------------------*/
-BUILDIN(misceffect)
+static BUILDIN(misceffect)
{
int type;
@@ -13992,7 +14931,7 @@ BUILDIN(misceffect)
/*==========================================
* Play a BGM on a single client [Rikter/Yommy]
*------------------------------------------*/
-BUILDIN(playbgm)
+static BUILDIN(playbgm)
{
struct map_session_data* sd = script->rid2sd(st);
@@ -14005,7 +14944,7 @@ BUILDIN(playbgm)
return true;
}
-int playbgm_sub(struct block_list* bl,va_list ap)
+static int playbgm_sub(struct block_list *bl, va_list ap)
{
const char* name = va_arg(ap,const char*);
@@ -14014,7 +14953,7 @@ int playbgm_sub(struct block_list* bl,va_list ap)
return 0;
}
-int playbgm_foreachpc_sub(struct map_session_data* sd, va_list args)
+static int playbgm_foreachpc_sub(struct map_session_data *sd, va_list args)
{
const char* name = va_arg(args, const char*);
@@ -14026,7 +14965,8 @@ int playbgm_foreachpc_sub(struct map_session_data* sd, va_list args)
/*==========================================
* Play a BGM on multiple client [Rikter/Yommy]
*------------------------------------------*/
-BUILDIN(playbgmall) {
+static BUILDIN(playbgmall)
+{
const char* name;
name = script_getstr(st,2);
@@ -14068,7 +15008,7 @@ BUILDIN(playbgmall) {
/*==========================================
* Play a .wav sound for sd
*------------------------------------------*/
-BUILDIN(soundeffect)
+static BUILDIN(soundeffect)
{
struct map_session_data *sd = script->rid2sd(st);
const char* name = script_getstr(st,2);
@@ -14080,7 +15020,7 @@ BUILDIN(soundeffect)
return true;
}
-int soundeffect_sub(struct block_list *bl, va_list ap)
+static int soundeffect_sub(struct block_list *bl, va_list ap)
{
struct map_session_data *sd = NULL;
char *name = va_arg(ap, char *);
@@ -14099,7 +15039,8 @@ int soundeffect_sub(struct block_list *bl, va_list ap)
* Play a sound effect (.wav) on multiple clients
* soundeffectall "<filepath>",<type>{,"<map name>"}{,<x0>,<y0>,<x1>,<y1>};
*------------------------------------------*/
-BUILDIN(soundeffectall) {
+static BUILDIN(soundeffectall)
+{
struct block_list* bl;
const char* name;
int type;
@@ -14150,7 +15091,7 @@ BUILDIN(soundeffectall) {
/*==========================================
* pet status recovery [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
-BUILDIN(petrecovery)
+static BUILDIN(petrecovery)
{
struct pet_data *pd;
struct map_session_data *sd = script->rid2sd(st);
@@ -14179,7 +15120,7 @@ BUILDIN(petrecovery)
*------------------------------------------*/
/// petskillattack <skill id>,<level>,<div>,<rate>,<bonusrate>
/// petskillattack "<skill name>",<level>,<div>,<rate>,<bonusrate>
-BUILDIN(petskillattack)
+static BUILDIN(petskillattack)
{
struct pet_data *pd;
struct map_session_data *sd = script->rid2sd(st);
@@ -14205,7 +15146,7 @@ BUILDIN(petskillattack)
*------------------------------------------*/
/// petskillsupport <skill id>,<level>,<delay>,<hp>,<sp>
/// petskillsupport "<skill name>",<level>,<delay>,<hp>,<sp>
-BUILDIN(petskillsupport)
+static BUILDIN(petskillsupport)
{
struct pet_data *pd;
struct map_session_data *sd = script->rid2sd(st);
@@ -14244,7 +15185,7 @@ BUILDIN(petskillsupport)
*------------------------------------------*/
/// skilleffect <skill id>,<level>
/// skilleffect "<skill name>",<level>
-BUILDIN(skilleffect)
+static BUILDIN(skilleffect)
{
struct map_session_data *sd;
@@ -14272,7 +15213,8 @@ BUILDIN(skilleffect)
*------------------------------------------*/
/// npcskilleffect <skill id>,<level>,<x>,<y>
/// npcskilleffect "<skill name>",<level>,<x>,<y>
-BUILDIN(npcskilleffect) {
+static BUILDIN(npcskilleffect)
+{
struct block_list *bl= map->id2bl(st->oid);
uint16 skill_id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) );
@@ -14289,26 +15231,43 @@ BUILDIN(npcskilleffect) {
/*==========================================
* Special effects [Valaris]
*------------------------------------------*/
-BUILDIN(specialeffect) {
+static BUILDIN(specialeffect)
+{
struct block_list *bl = NULL;
- int type = script_getnum(st,2);
- enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA;
+ int type = script_getnum(st, 2);
+ enum send_target target = AREA;
- if (script_hasdata(st,4)) {
- struct npc_data *nd = npc->name2id(script_getstr(st,4));
- if (nd != NULL)
- bl = &nd->bl;
+ if (script_hasdata(st, 3)) {
+ target = script_getnum(st, 3);
+ }
+
+ if (script_hasdata(st, 4)) {
+ if (script_isstringtype(st, 4)) {
+ struct npc_data *nd = npc->name2id(script_getstr(st, 4));
+ if (nd != NULL) {
+ bl = &nd->bl;
+ }
+ } else {
+ bl = map->id2bl(script_getnum(st, 4));
+ }
} else {
bl = map->id2bl(st->oid);
}
- if (bl == NULL)
+ if (bl == NULL) {
return true;
+ }
if (target == SELF) {
- struct map_session_data *sd = script->rid2sd(st);
- if (sd != NULL)
+ struct map_session_data *sd;
+ if (script_hasdata(st, 5)) {
+ sd = map->id2sd(script_getnum(st, 5));
+ } else {
+ sd = script->rid2sd(st);
+ }
+ if (sd != NULL) {
clif->specialeffect_single(bl, type, sd->fd);
+ }
} else {
clif->specialeffect(bl, type, target);
}
@@ -14316,7 +15275,8 @@ BUILDIN(specialeffect) {
return true;
}
-BUILDIN(specialeffect2) {
+static BUILDIN(specialeffect2)
+{
struct map_session_data *sd;
int type = script_getnum(st,2);
enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA;
@@ -14332,10 +15292,54 @@ BUILDIN(specialeffect2) {
return true;
}
+static BUILDIN(removespecialeffect)
+{
+ struct block_list *bl = NULL;
+ int type = script_getnum(st, 2);
+ enum send_target target = AREA;
+
+ if (script_hasdata(st, 3)) {
+ target = script_getnum(st, 3);
+ }
+
+ if (script_hasdata(st, 4)) {
+ if (script_isstringtype(st, 4)) {
+ struct npc_data *nd = npc->name2id(script_getstr(st, 4));
+ if (nd != NULL) {
+ bl = &nd->bl;
+ }
+ } else {
+ bl = map->id2bl(script_getnum(st, 4));
+ }
+ } else {
+ bl = map->id2bl(st->oid);
+ }
+
+ if (bl == NULL) {
+ return true;
+ }
+
+ if (target == SELF) {
+ struct map_session_data *sd;
+ if (script_hasdata(st, 5)) {
+ sd = map->id2sd(script_getnum(st, 5));
+ } else {
+ sd = script->rid2sd(st);
+ }
+ if (sd != NULL) {
+ clif->removeSpecialEffect_single(bl, type, &sd->bl);
+ }
+ } else {
+ clif->removeSpecialEffect(bl, type, target);
+ }
+
+ return true;
+}
+
/*==========================================
* Nude [Valaris]
*------------------------------------------*/
-BUILDIN(nude)
+static BUILDIN(nude)
{
struct map_session_data *sd = script->rid2sd(st);
int i, calcflag = 0;
@@ -14360,7 +15364,7 @@ BUILDIN(nude)
/*==========================================
* gmcommand [MouseJstr]
*------------------------------------------*/
-BUILDIN(atcommand)
+static BUILDIN(atcommand)
{
struct map_session_data *sd, *dummy_sd = NULL;
int fd;
@@ -14402,7 +15406,7 @@ BUILDIN(atcommand)
* dispbottom "<message>"{,<color>};
* @endcode
*/
-BUILDIN(dispbottom)
+static BUILDIN(dispbottom)
{
struct map_session_data *sd = script->rid2sd(st);
const char *message = script_getstr(st,2);
@@ -14424,28 +15428,68 @@ BUILDIN(dispbottom)
* All The Players Full Recovery
* (HP/SP full restore and resurrect if need)
*------------------------------------------*/
-BUILDIN(recovery)
+static int buildin_recovery_sub(struct map_session_data *sd)
{
- struct map_session_data *sd;
- struct s_mapiterator* iter;
+ nullpo_retr(0, sd);
- iter = mapit_getallusers();
- for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) {
- if(pc_isdead(sd))
- status->revive(&sd->bl, 100, 100);
- else
- status_percent_heal(&sd->bl, 100, 100);
- clif->message(sd->fd,msg_sd(sd,880)); // "You have been recovered!"
+ if (pc_isdead(sd)) {
+ status->revive(&sd->bl, 100, 100);
+ } else {
+ status_percent_heal(&sd->bl, 100, 100);
+ }
+
+ return 0;
+}
+
+static int buildin_recovery_pc_sub(struct map_session_data *sd, va_list ap)
+{
+ return script->buildin_recovery_sub(sd);
+}
+
+static int buildin_recovery_bl_sub(struct block_list *bl, va_list ap)
+{
+ return script->buildin_recovery_sub(BL_CAST(BL_PC, bl));
+}
+
+static BUILDIN(recovery)
+{
+ if (script_hasdata(st, 2)) {
+ if (script_isstringtype(st, 2)) {
+ int16 m = map->mapname2mapid(script_getstr(st, 2));
+
+ if (m == -1) {
+ ShowWarning("script:recovery: invalid map!\n");
+ return false;
+ }
+
+ if (script_hasdata(st, 6)) {
+ int16 x1 = script_getnum(st, 3);
+ int16 y1 = script_getnum(st, 4);
+ int16 x2 = script_getnum(st, 5);
+ int16 y2 = script_getnum(st, 6);
+ map->foreachinarea(script->buildin_recovery_bl_sub, m, x1, y1, x2, y2, BL_PC);
+ } else {
+ map->foreachinmap(script->buildin_recovery_bl_sub, m, BL_PC);
+ }
+ } else {
+ struct map_session_data *sd = script->id2sd(st, script_getnum(st, 2));
+
+ if (sd != NULL) {
+ script->buildin_recovery_sub(sd);
+ }
+ }
+ } else {
+ map->foreachpc(script->buildin_recovery_pc_sub);
}
- mapit->free(iter);
return true;
}
+
/*==========================================
* Get your pet info: getpetinfo(n)
* n -> 0:pet_id 1:pet_class 2:pet_name
* 3:friendly 4:hungry, 5: rename flag.
*------------------------------------------*/
-BUILDIN(getpetinfo)
+static BUILDIN(getpetinfo)
{
struct map_session_data *sd = script->rid2sd(st);
struct pet_data *pd;
@@ -14479,7 +15523,7 @@ BUILDIN(getpetinfo)
* 3:friendly 4:hungry, 5: rename flag.
* 6: level
*------------------------------------------*/
-BUILDIN(gethominfo)
+static BUILDIN(gethominfo)
{
struct map_session_data *sd = script->rid2sd(st);
int type = script_getnum(st,2);
@@ -14509,7 +15553,7 @@ BUILDIN(gethominfo)
/// Retrieves information about character's mercenary
/// getmercinfo <type>[,<char id>];
-BUILDIN(getmercinfo)
+static BUILDIN(getmercinfo)
{
int type;
struct map_session_data* sd;
@@ -14560,21 +15604,20 @@ BUILDIN(getmercinfo)
* selected card or not.
* checkequipedcard(4001);
*------------------------------------------*/
-BUILDIN(checkequipedcard)
+static BUILDIN(checkequipedcard)
{
- int n,i,c=0;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
- c = script_getnum(st,2);
+ int c = script_getnum(st,2);
- for( i=0; i<MAX_INVENTORY; i++) {
+ for (int i = 0; i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]) {
if (itemdb_isspecial(sd->status.inventory[i].card[0]))
continue;
- for(n=0;n<sd->inventory_data[i]->slot;n++) {
+ for (int n = 0; n < sd->inventory_data[i]->slot; n++) {
if(sd->status.inventory[i].card[n]==c) {
script_pushint(st,1);
return true;
@@ -14587,7 +15630,7 @@ BUILDIN(checkequipedcard)
return true;
}
-BUILDIN(__jump_zero)
+static BUILDIN(__jump_zero)
{
int sel;
sel=script_getnum(st,2);
@@ -14609,7 +15652,7 @@ BUILDIN(__jump_zero)
/*==========================================
* movenpc [MouseJstr]
*------------------------------------------*/
-BUILDIN(movenpc)
+static BUILDIN(movenpc)
{
struct npc_data *nd = NULL;
const char *npc_name;
@@ -14631,7 +15674,7 @@ BUILDIN(movenpc)
/*==========================================
* message [MouseJstr]
*------------------------------------------*/
-BUILDIN(message)
+static BUILDIN(message)
{
const char *message;
struct map_session_data *sd = NULL;
@@ -14650,14 +15693,38 @@ BUILDIN(message)
return true;
}
+static BUILDIN(servicemessage)
+{
+ struct map_session_data *sd = NULL;
+
+ if (script_hasdata(st, 4)) {
+ if (script_isstringtype(st, 4))
+ sd = script->nick2sd(st, script_getstr(st, 4));
+ else
+ sd = script->id2sd(st, script_getnum(st, 4));
+ } else {
+ sd = script->rid2sd(st);
+ }
+
+ if (sd == NULL)
+ return true;
+
+ const char *message = script_getstr(st, 2);
+ const int color = script_getnum(st, 3);
+ clif->serviceMessageColor(sd, color, message);
+
+ return true;
+}
+
/*==========================================
* npctalk (sends message to surrounding area)
- * usage: npctalk "<message>"{,"<npc name>"};
+ * usage: npctalk("<message>"{, "<npc name>"{, <show_name>}});
*------------------------------------------*/
-BUILDIN(npctalk)
+static BUILDIN(npctalk)
{
struct npc_data* nd;
const char *str = script_getstr(st,2);
+ bool show_name = true;
if (script_hasdata(st, 3)) {
nd = npc->name2id(script_getstr(st, 3));
@@ -14665,19 +15732,28 @@ BUILDIN(npctalk)
nd = map->id2nd(st->oid);
}
+ if (script_hasdata(st, 4)) {
+ show_name = (script_getnum(st, 4) != 0) ? true : false;
+ }
+
if (nd != NULL) {
char name[NAME_LENGTH], message[256];
safestrncpy(name, nd->name, sizeof(name));
strtok(name, "#"); // discard extra name identifier if present
- safesnprintf(message, sizeof(message), "%s : %s", name, str);
- clif->disp_overhead(&nd->bl, message);
+ if (show_name) {
+ safesnprintf(message, sizeof(message), "%s : %s", name, str);
+ } else {
+ safesnprintf(message, sizeof(message), "%s", str);
+ }
+ clif->disp_overhead(&nd->bl, message, AREA_CHAT_WOC, NULL);
}
return true;
}
// change npc walkspeed [Valaris]
-BUILDIN(npcspeed) {
+static BUILDIN(npcspeed)
+{
struct npc_data* nd;
int speed;
@@ -14693,7 +15769,7 @@ BUILDIN(npcspeed) {
return true;
}
// make an npc walk to a position [Valaris]
-BUILDIN(npcwalkto)
+static BUILDIN(npcwalkto)
{
struct npc_data *nd = map->id2nd(st->oid);
int x=0,y=0;
@@ -14714,7 +15790,7 @@ BUILDIN(npcwalkto)
return true;
}
// stop an npc's movement [Valaris]
-BUILDIN(npcstop)
+static BUILDIN(npcstop)
{
struct npc_data *nd = map->id2nd(st->oid);
@@ -14727,7 +15803,7 @@ BUILDIN(npcstop)
}
// set click npc distance [4144]
-BUILDIN(setnpcdistance)
+static BUILDIN(setnpcdistance)
{
struct npc_data *nd = map->id2nd(st->oid);
if (nd == NULL)
@@ -14739,7 +15815,7 @@ BUILDIN(setnpcdistance)
}
// return current npc direction [4144]
-BUILDIN(getnpcdir)
+static BUILDIN(getnpcdir)
{
const struct npc_data *nd = NULL;
@@ -14765,7 +15841,7 @@ BUILDIN(getnpcdir)
}
// set npc direction [4144]
-BUILDIN(setnpcdir)
+static BUILDIN(setnpcdir)
{
int newdir;
struct npc_data *nd = NULL;
@@ -14799,7 +15875,7 @@ BUILDIN(setnpcdir)
}
// return npc class [4144]
-BUILDIN(getnpcclass)
+static BUILDIN(getnpcclass)
{
const struct npc_data *nd = NULL;
@@ -14827,7 +15903,7 @@ BUILDIN(getnpcclass)
/*==========================================
* getlook char info. getlook(arg)
*------------------------------------------*/
-BUILDIN(getlook)
+static BUILDIN(getlook)
{
int type,val = -1;
struct map_session_data *sd = script->rid2sd(st);
@@ -14837,15 +15913,15 @@ BUILDIN(getlook)
type=script_getnum(st,2);
switch(type) {
case LOOK_HAIR: val = sd->status.hair; break; //1
- case LOOK_WEAPON: val = sd->status.weapon; break; //2
- case LOOK_HEAD_BOTTOM: val = sd->status.head_bottom; break; //3
- case LOOK_HEAD_TOP: val = sd->status.head_top; break; //4
- case LOOK_HEAD_MID: val = sd->status.head_mid; break; //5
+ case LOOK_WEAPON: val = sd->status.look.weapon; break; //2
+ case LOOK_HEAD_BOTTOM: val = sd->status.look.head_bottom; break; //3
+ case LOOK_HEAD_TOP: val = sd->status.look.head_top; break; //4
+ case LOOK_HEAD_MID: val = sd->status.look.head_mid; break; //5
case LOOK_HAIR_COLOR: val = sd->status.hair_color; break; //6
case LOOK_CLOTHES_COLOR: val = sd->status.clothes_color; break; //7
- case LOOK_SHIELD: val = sd->status.shield; break; //8
+ case LOOK_SHIELD: val = sd->status.look.shield; break; //8
case LOOK_SHOES: break; //9
- case LOOK_ROBE: val = sd->status.robe; break; //12
+ case LOOK_ROBE: val = sd->status.look.robe; break; //12
case LOOK_BODY2: val=sd->status.body; break; //13
}
@@ -14856,7 +15932,7 @@ BUILDIN(getlook)
/*==========================================
* get char save point. argument: 0- map name, 1- x, 2- y
*------------------------------------------*/
-BUILDIN(getsavepoint)
+static BUILDIN(getsavepoint)
{
int type;
struct map_session_data *sd = script->rid2sd(st);
@@ -14899,7 +15975,7 @@ BUILDIN(getsavepoint)
* 0 - success
* -1 - some error, MapName$,MapX,MapY contains unknown value.
*------------------------------------------*/
-BUILDIN(getmapxy)
+static BUILDIN(getmapxy)
{
struct block_list *bl = NULL;
struct map_session_data *sd = NULL;
@@ -15095,23 +16171,42 @@ BUILDIN(getmapxy)
return true;
}
+enum logmes_type {
+ LOGMES_NPC,
+ LOGMES_ATCOMMAND
+};
+
/*==========================================
- * Allows player to write NPC logs (i.e. Bank NPC, etc) [Lupus]
+ * Allows player to write logs (i.e. Bank NPC, etc) [Lupus]
*------------------------------------------*/
-BUILDIN(logmes)
+static BUILDIN(logmes)
{
- const char *str;
+ const char *str = script_getstr(st, 2);
struct map_session_data *sd = script->rid2sd(st);
+ enum logmes_type type = LOGMES_NPC;
+ nullpo_retr(false, sd);
- if (sd == NULL)
- return true;
+ if (script_hasdata(st, 3)) {
+ type = script_getnum(st, 3);
+ }
+
+ switch (type) {
+ case LOGMES_ATCOMMAND:
+ logs->atcommand(sd, str);
+ break;
+ case LOGMES_NPC:
+ logs->npc(sd, str);
+ break;
+ default:
+ ShowError("script:logmes: Unknown log type!\n");
+ st->state = END;
+ return false;
+ }
- str = script_getstr(st,2);
- logs->npc(sd,str);
return true;
}
-BUILDIN(summon)
+static BUILDIN(summon)
{
int class_, timeout=0;
const char *str,*event="";
@@ -15149,7 +16244,8 @@ BUILDIN(summon)
/*==========================================
* Checks whether it is daytime/nighttime
*------------------------------------------*/
-BUILDIN(isnight) {
+static BUILDIN(isnight)
+{
script_pushint(st,(map->night_flag == 1));
return true;
}
@@ -15158,7 +16254,7 @@ BUILDIN(isnight) {
* Check how many items/cards in the list are
* equipped - used for 2/15's cards patch [celest]
*------------------------------------------------*/
-BUILDIN(isequippedcnt)
+static BUILDIN(isequippedcnt)
{
int i, j, k, id = 1;
int ret = 0;
@@ -15207,7 +16303,7 @@ BUILDIN(isequippedcnt)
* -- Items checked cannot be reused in another
* card set to prevent exploits
*------------------------------------------------*/
-BUILDIN(isequipped)
+static BUILDIN(isequipped)
{
int i, j, k, id = 1;
int index, flag;
@@ -15287,7 +16383,7 @@ BUILDIN(isequipped)
* Check how many given inserted cards in the CURRENT
* weapon - used for 2/15's cards patch [Lupus]
*------------------------------------------------*/
-BUILDIN(cardscnt)
+static BUILDIN(cardscnt)
{
int i, k, id = 1;
int ret = 0;
@@ -15329,7 +16425,7 @@ BUILDIN(cardscnt)
* Returns the refined number of the current item, or an
* item with inventory index specified
*-------------------------------------------------------*/
-BUILDIN(getrefine)
+static BUILDIN(getrefine)
{
struct map_session_data *sd = script->rid2sd(st);
@@ -15346,11 +16442,13 @@ BUILDIN(getrefine)
/*=======================================================
* Day/Night controls
*-------------------------------------------------------*/
-BUILDIN(night) {
+static BUILDIN(night)
+{
if (map->night_flag != 1) pc->map_night_timer(pc->night_timer_tid, 0, 0, 1);
return true;
}
-BUILDIN(day) {
+static BUILDIN(day)
+{
if (map->night_flag != 0) pc->map_day_timer(pc->day_timer_tid, 0, 0, 1);
return true;
}
@@ -15358,7 +16456,7 @@ BUILDIN(day) {
//=======================================================
// Unequip [Spectre]
//-------------------------------------------------------
-BUILDIN(unequip)
+static BUILDIN(unequip)
{
size_t num;
struct map_session_data *sd;
@@ -15373,7 +16471,7 @@ BUILDIN(unequip)
return true;
}
-BUILDIN(equip)
+static BUILDIN(equip)
{
int nameid=0,i;
struct item_data *item_data;
@@ -15384,17 +16482,17 @@ BUILDIN(equip)
nameid=script_getnum(st,2);
if((item_data = itemdb->exists(nameid)) == NULL)
{
- ShowError("wrong item ID : equipitem(%i)\n",nameid);
+ ShowError("wrong item ID : equipitem(%d)\n",nameid);
return false;
}
- ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid && sd->status.inventory[i].equip == 0 );
- if( i < MAX_INVENTORY )
- pc->equipitem(sd,i,item_data->equip);
+ ARR_FIND(0, sd->status.inventorySize, i, sd->status.inventory[i].nameid == nameid && sd->status.inventory[i].equip == 0);
+ if (i < sd->status.inventorySize)
+ pc->equipitem(sd, i, item_data->equip);
return true;
}
-BUILDIN(autoequip)
+static BUILDIN(autoequip)
{
int nameid, flag;
struct item_data *item_data;
@@ -15421,7 +16519,7 @@ BUILDIN(autoequip)
* Equip2
* equip2 <item id>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>;
*-------------------------------------------------------*/
-BUILDIN(equip2)
+static BUILDIN(equip2)
{
int i,nameid,ref,attr,c0,c1,c2,c3;
struct item_data *item_data;
@@ -15440,33 +16538,33 @@ BUILDIN(equip2)
return false;
}
- ref = script_getnum(st,3);
- attr = script_getnum(st,4);
- c0 = (short)script_getnum(st,5);
- c1 = (short)script_getnum(st,6);
- c2 = (short)script_getnum(st,7);
- c3 = (short)script_getnum(st,8);
+ ref = script_getnum(st, 3);
+ attr = script_getnum(st, 4);
+ c0 = script_getnum(st, 5);
+ c1 = script_getnum(st, 6);
+ c2 = script_getnum(st, 7);
+ c3 = script_getnum(st, 8);
- ARR_FIND( 0, MAX_INVENTORY, i,( sd->status.inventory[i].equip == 0 &&
+ ARR_FIND(0, sd->status.inventorySize, i, (sd->status.inventory[i].equip == 0 &&
sd->status.inventory[i].nameid == nameid &&
sd->status.inventory[i].refine == ref &&
sd->status.inventory[i].attribute == attr &&
sd->status.inventory[i].card[0] == c0 &&
sd->status.inventory[i].card[1] == c1 &&
sd->status.inventory[i].card[2] == c2 &&
- sd->status.inventory[i].card[3] == c3 ) );
+ sd->status.inventory[i].card[3] == c3));
- if( i < MAX_INVENTORY ) {
+ if (i < sd->status.inventorySize) {
script_pushint(st,1);
pc->equipitem(sd,i,item_data->equip);
- }
- else
+ } else {
script_pushint(st,0);
+ }
return true;
}
-BUILDIN(setbattleflag)
+static BUILDIN(setbattleflag)
{
const char *flag, *value;
@@ -15481,7 +16579,7 @@ BUILDIN(setbattleflag)
return true;
}
-BUILDIN(getbattleflag)
+static BUILDIN(getbattleflag)
{
const char *flag;
int value;
@@ -15503,7 +16601,7 @@ BUILDIN(getbattleflag)
//=======================================================
// strlen [Valaris]
//-------------------------------------------------------
-BUILDIN(getstrlen)
+static BUILDIN(getstrlen)
{
const char *str = script_getstr(st,2);
@@ -15516,7 +16614,7 @@ BUILDIN(getstrlen)
//=======================================================
// isalpha [Valaris]
//-------------------------------------------------------
-BUILDIN(charisalpha)
+static BUILDIN(charisalpha)
{
const char *str=script_getstr(st,2);
int pos=script_getnum(st,3);
@@ -15530,7 +16628,7 @@ BUILDIN(charisalpha)
//=======================================================
// charisupper <str>, <index>
//-------------------------------------------------------
-BUILDIN(charisupper)
+static BUILDIN(charisupper)
{
const char *str = script_getstr(st,2);
int pos = script_getnum(st,3);
@@ -15544,7 +16642,7 @@ BUILDIN(charisupper)
//=======================================================
// charislower <str>, <index>
//-------------------------------------------------------
-BUILDIN(charislower)
+static BUILDIN(charislower)
{
const char *str = script_getstr(st,2);
int pos = script_getnum(st,3);
@@ -15558,7 +16656,8 @@ BUILDIN(charislower)
//=======================================================
// charat <str>, <index>
//-------------------------------------------------------
-BUILDIN(charat) {
+static BUILDIN(charat)
+{
const char *str = script_getstr(st,2);
int pos = script_getnum(st,3);
@@ -15573,9 +16672,141 @@ BUILDIN(charat) {
}
//=======================================================
+// isstr <argument>
+//
+// returns type:
+// 0 - int
+// 1 - string
+// 2 - other
+//-------------------------------------------------------
+static BUILDIN(isstr)
+{
+ if (script_isinttype(st, 2)) {
+ script_pushint(st, 0);
+ } else if (script_isstringtype(st, 2)) {
+ script_pushint(st, 1);
+ } else {
+ script_pushint(st, 2);
+ }
+ return true;
+}
+
+enum datatype {
+ DATATYPE_NIL = 1 << 7, // we don't start at 1, to leave room for primitives
+ DATATYPE_STR = 1 << 8,
+ DATATYPE_INT = 1 << 9,
+ DATATYPE_CONST = 1 << 10,
+ DATATYPE_PARAM = 1 << 11,
+ DATATYPE_VAR = 1 << 12,
+ DATATYPE_LABEL = 1 << 13,
+};
+
+static BUILDIN(getdatatype)
+{
+ int type;
+
+ if (script_hasdata(st, 2)) {
+ struct script_data *data = script_getdata(st, 2);
+
+ if (data_isstring(data)) {
+ type = DATATYPE_STR;
+ if (data->type == C_CONSTSTR) {
+ type |= DATATYPE_CONST;
+ }
+ } else if (data_isint(data)) {
+ type = DATATYPE_INT;
+ } else if (data_islabel(data)) {
+ type = DATATYPE_LABEL;
+ } else if (data_isreference(data)) {
+ if (reference_toconstant(data)) {
+ type = DATATYPE_CONST | DATATYPE_INT;
+ } else if (reference_toparam(data)) {
+ type = DATATYPE_PARAM | DATATYPE_INT;
+ } else if (reference_tovariable(data)) {
+ type = DATATYPE_VAR;
+ if (is_string_variable(reference_getname(data))) {
+ type |= DATATYPE_STR;
+ } else {
+ type |= DATATYPE_INT;
+ }
+ } else {
+ ShowError("script:getdatatype: Unknown reference type!\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;
+ }
+ } else {
+ type = data->type; // fallback to primitive type if unknown
+ }
+ } else {
+ type = DATATYPE_NIL; // nothing was passed
+ }
+
+ script_pushint(st, type);
+ return true;
+}
+
+static BUILDIN(data_to_string)
+{
+ if (script_hasdata(st, 2)) {
+ struct script_data *data = script_getdata(st, 2);
+
+ if (data_isstring(data)) {
+ script_pushcopy(st, 2);
+ } else if (data_isint(data)) {
+ char *str = NULL;
+
+ CREATE(str, char, 20);
+ safesnprintf(str, 20, "%"PRId64"", data->u.num);
+ script_pushstr(st, str);
+ } else if (data_islabel(data)) {
+ const char *str = "";
+
+ // XXX: because all we have is the label pos we can't be sure which
+ // one is the correct label if more than one has the same pos.
+ // We might want to store both the pos and str_data index in
+ // data->u.num, similar to how C_NAME stores both the array
+ // index and str_data index in u.num with bitmasking. This
+ // would also avoid the awkward for() loops as we could
+ // directly access the string with script->get_str().
+
+ if (st->oid) {
+ struct npc_data *nd = map->id2nd(st->oid);
+
+ for (int i = 0; i < nd->u.scr.label_list_num; ++i) {
+ if (nd->u.scr.label_list[i].pos == data->u.num) {
+ str = nd->u.scr.label_list[i].name;
+ break;
+ }
+ }
+ } else {
+ for (int i = LABEL_START; script->str_data[i].next != 0; i = script->str_data[i].next) {
+ if (script->str_data[i].label == data->u.num) {
+ str = script->get_str(i);
+ break;
+ }
+ }
+ }
+
+ script_pushconststr(st, str);
+ } else if (data_isreference(data)) {
+ script_pushstrcopy(st, reference_getname(data));
+ } else {
+ ShowWarning("script:data_to_string: unknown data type!\n");
+ script->reportdata(data);
+ script_pushconststr(st, "");
+ }
+ } else {
+ script_pushconststr(st, ""); // NIL
+ }
+
+ return true;
+}
+
+//=======================================================
// chr <int>
//-------------------------------------------------------
-BUILDIN(chr)
+static BUILDIN(chr)
{
char output[2];
output[0] = script_getnum(st, 2);
@@ -15588,7 +16819,7 @@ BUILDIN(chr)
//=======================================================
// ord <chr>
//-------------------------------------------------------
-BUILDIN(ord)
+static BUILDIN(ord)
{
const char *chr = script_getstr(st, 2);
script_pushint(st, *chr);
@@ -15598,7 +16829,7 @@ BUILDIN(ord)
//=======================================================
// setchar <string>, <char>, <index>
//-------------------------------------------------------
-BUILDIN(setchar)
+static BUILDIN(setchar)
{
const char *str = script_getstr(st,2);
const char *c = script_getstr(st,3);
@@ -15615,7 +16846,7 @@ BUILDIN(setchar)
//=======================================================
// insertchar <string>, <char>, <index>
//-------------------------------------------------------
-BUILDIN(insertchar)
+static BUILDIN(insertchar)
{
const char *str = script_getstr(st,2);
const char *c = script_getstr(st,3);
@@ -15642,7 +16873,7 @@ BUILDIN(insertchar)
//=======================================================
// delchar <string>, <index>
//-------------------------------------------------------
-BUILDIN(delchar)
+static BUILDIN(delchar)
{
const char *str = script_getstr(st,2);
int index = script_getnum(st,3);
@@ -15668,7 +16899,7 @@ BUILDIN(delchar)
//=======================================================
// strtoupper <str>
//-------------------------------------------------------
-BUILDIN(strtoupper)
+static BUILDIN(strtoupper)
{
const char *str = script_getstr(st,2);
char *output = aStrdup(str);
@@ -15686,7 +16917,7 @@ BUILDIN(strtoupper)
//=======================================================
// strtolower <str>
//-------------------------------------------------------
-BUILDIN(strtolower)
+static BUILDIN(strtolower)
{
const char *str = script_getstr(st,2);
char *output = aStrdup(str);
@@ -15704,7 +16935,7 @@ BUILDIN(strtolower)
//=======================================================
// substr <str>, <start>, <end>
//-------------------------------------------------------
-BUILDIN(substr)
+static BUILDIN(substr)
{
const char *str = script_getstr(st,2);
char *output;
@@ -15730,7 +16961,7 @@ BUILDIN(substr)
// explode <dest_string_array>, <str>, <delimiter>
// Note: delimiter is limited to 1 char
//-------------------------------------------------------
-BUILDIN(explode)
+static BUILDIN(explode)
{
struct script_data* data = script_getdata(st, 2);
const char *str = script_getstr(st,3);
@@ -15795,7 +17026,7 @@ BUILDIN(explode)
// implode <string_array>
// implode <string_array>, <glue>
//-------------------------------------------------------
-BUILDIN(implode)
+static BUILDIN(implode)
{
struct script_data* data = script_getdata(st, 2);
const char *name;
@@ -15887,12 +17118,12 @@ BUILDIN(implode)
// Implements C sprintf, except format %n. The resulting string is
// returned, instead of being saved in variable by reference.
//-------------------------------------------------------
-BUILDIN(sprintf)
+static BUILDIN(sprintf)
{
struct StringBuf buf;
StrBuf->Init(&buf);
- if (!script_sprintf(st, 2, &buf)) {
+ if (!script->sprintf_helper(st, 2, &buf)) {
StrBuf->Destroy(&buf);
script_pushconststr(st, "");
return false;
@@ -15908,7 +17139,8 @@ BUILDIN(sprintf)
// sscanf(<str>, <format>, ...);
// Implements C sscanf.
//-------------------------------------------------------
-BUILDIN(sscanf) {
+static BUILDIN(sscanf)
+{
unsigned int argc, arg = 0;
struct script_data* data;
struct map_session_data* sd = NULL;
@@ -16021,7 +17253,8 @@ BUILDIN(sscanf) {
// Implements PHP style strpos. Adapted from code from
// http://www.daniweb.com/code/snippet313.html, Dave Sinkula
//-------------------------------------------------------
-BUILDIN(strpos) {
+static BUILDIN(strpos)
+{
const char *haystack = script_getstr(st,2);
const char *needle = script_getstr(st,3);
int i;
@@ -16065,7 +17298,7 @@ BUILDIN(strpos) {
// instances as specified in <count>. By default will be case
// sensitive.
//---------------------------------------------------------------
-BUILDIN(replacestr)
+static BUILDIN(replacestr)
{
const char *input = script_getstr(st, 2);
const char *find = script_getstr(st, 3);
@@ -16148,7 +17381,7 @@ BUILDIN(replacestr)
// Note: Counts the number of times <search> occurs in
// <input>. By default will be case sensitive.
//--------------------------------------------------------
-BUILDIN(countstr)
+static BUILDIN(countstr)
{
const char *input = script_getstr(st, 2);
const char *find = script_getstr(st, 3);
@@ -16205,7 +17438,8 @@ BUILDIN(countstr)
/// setnpcdisplay("<npc name>", "<new display name>", <new class id>) -> <int>
/// setnpcdisplay("<npc name>", "<new display name>") -> <int>
/// setnpcdisplay("<npc name>", <new class id>) -> <int>
-BUILDIN(setnpcdisplay) {
+static BUILDIN(setnpcdisplay)
+{
const char* name;
const char* newname = NULL;
int class_ = -1, size = -1;
@@ -16251,14 +17485,16 @@ BUILDIN(setnpcdisplay) {
return true;
}
-BUILDIN(atoi) {
+static BUILDIN(atoi)
+{
const char *value;
value = script_getstr(st,2);
script_pushint(st,atoi(value));
return true;
}
-BUILDIN(axtoi) {
+static BUILDIN(axtoi)
+{
const char *hex = script_getstr(st,2);
long value = strtol(hex, NULL, 16);
#if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN
@@ -16268,7 +17504,8 @@ BUILDIN(axtoi) {
return true;
}
-BUILDIN(strtol) {
+static BUILDIN(strtol)
+{
const char *string = script_getstr(st, 2);
int base = script_getnum(st, 3);
long value = strtol(string, NULL, base);
@@ -16280,7 +17517,7 @@ BUILDIN(strtol) {
}
// case-insensitive substring search [lordalfa]
-BUILDIN(compare)
+static BUILDIN(compare)
{
const char *message;
const char *cmpstring;
@@ -16290,7 +17527,7 @@ BUILDIN(compare)
return true;
}
-BUILDIN(strcmp)
+static BUILDIN(strcmp)
{
const char *str1 = script_getstr(st,2);
const char *str2 = script_getstr(st,3);
@@ -16300,7 +17537,7 @@ BUILDIN(strcmp)
// List of mathematics commands --->
-BUILDIN(log10)
+static BUILDIN(log10)
{
double i, a;
i = script_getnum(st,2);
@@ -16309,7 +17546,7 @@ BUILDIN(log10)
return true;
}
-BUILDIN(sqrt) //[zBuffer]
+static BUILDIN(sqrt) //[zBuffer]
{
double i, a;
i = script_getnum(st,2);
@@ -16322,7 +17559,7 @@ BUILDIN(sqrt) //[zBuffer]
return true;
}
-BUILDIN(pow) //[zBuffer]
+static BUILDIN(pow) //[zBuffer]
{
double i, a, b;
a = script_getnum(st,2);
@@ -16332,7 +17569,7 @@ BUILDIN(pow) //[zBuffer]
return true;
}
-BUILDIN(distance) //[zBuffer]
+static BUILDIN(distance) //[zBuffer]
{
int x0, y0, x1, y1;
@@ -16347,7 +17584,7 @@ BUILDIN(distance) //[zBuffer]
// <--- List of mathematics commands
-BUILDIN(min)
+static BUILDIN(min)
{
int i, min;
@@ -16362,7 +17599,7 @@ BUILDIN(min)
return true;
}
-BUILDIN(max)
+static BUILDIN(max)
{
int i, max;
@@ -16377,7 +17614,7 @@ BUILDIN(max)
return true;
}
-BUILDIN(md5)
+static BUILDIN(md5)
{
const char *tmpstr;
char *md5str;
@@ -16389,10 +17626,11 @@ BUILDIN(md5)
return true;
}
-BUILDIN(swap)
+static BUILDIN(swap)
{
struct map_session_data *sd = NULL;
struct script_data *data1, *data2;
+ struct reg_db *ref1, *ref2;
const char *varname1, *varname2;
int64 uid1, uid2;
@@ -16433,6 +17671,8 @@ BUILDIN(swap)
uid1 = reference_getuid(data1);
uid2 = reference_getuid(data2);
+ ref1 = reference_getref(data1);
+ ref2 = reference_getref(data2);
if (is_string_variable(varname1)) {
const char *value1, *value2;
@@ -16441,8 +17681,8 @@ BUILDIN(swap)
value2 = script_getstr(st,3);
if (strcmpi(value1, value2)) {
- script->set_reg(st, sd, uid1, varname1, value2, script_getref(st,3));
- script->set_reg(st, sd, uid2, varname2, value1, script_getref(st,2));
+ script->set_reg(st, sd, uid1, varname1, value2, ref1);
+ script->set_reg(st, sd, uid2, varname2, value1, ref2);
}
}
else {
@@ -16452,8 +17692,8 @@ BUILDIN(swap)
value2 = script_getnum(st,3);
if (value1 != value2) {
- script->set_reg(st, sd, uid1, varname1, (const void *)h64BPTRSIZE(value2), script_getref(st,3));
- script->set_reg(st, sd, uid2, varname2, (const void *)h64BPTRSIZE(value1), script_getref(st,2));
+ script->set_reg(st, sd, uid1, varname1, (const void *)h64BPTRSIZE(value2), ref1);
+ script->set_reg(st, sd, uid2, varname2, (const void *)h64BPTRSIZE(value1), ref2);
}
}
return true;
@@ -16461,7 +17701,7 @@ BUILDIN(swap)
// [zBuffer] List of dynamic var commands --->
-BUILDIN(setd)
+static BUILDIN(setd)
{
struct map_session_data *sd = NULL;
char varname[100];
@@ -16491,7 +17731,7 @@ BUILDIN(setd)
return true;
}
-int buildin_query_sql_sub(struct script_state *st, struct Sql *handle)
+static int buildin_query_sql_sub(struct script_state *st, struct Sql *handle)
{
int i, j;
struct map_session_data *sd = NULL;
@@ -16573,11 +17813,13 @@ int buildin_query_sql_sub(struct script_state *st, struct Sql *handle)
return true;
}
-BUILDIN(query_sql) {
+static BUILDIN(query_sql)
+{
return script->buildin_query_sql_sub(st, map->mysql_handle);
}
-BUILDIN(query_logsql) {
+static BUILDIN(query_logsql)
+{
if( !logs->config.sql_logs ) {// logs->mysql_handle == NULL
ShowWarning("buildin_query_logsql: SQL logs are disabled, query '%s' will not be executed.\n", script_getstr(st,2));
script_pushint(st,-1);
@@ -16587,7 +17829,7 @@ BUILDIN(query_logsql) {
}
//Allows escaping of a given string.
-BUILDIN(escape_sql)
+static BUILDIN(escape_sql)
{
const char *str;
char *esc_str;
@@ -16601,25 +17843,37 @@ BUILDIN(escape_sql)
return true;
}
-BUILDIN(getd) {
+static BUILDIN(getd)
+{
char varname[100];
const char *buffer;
int elem;
+ int id;
buffer = script_getstr(st, 2);
if (sscanf(buffer, "%99[^[][%d]", varname, &elem) < 2)
elem = 0;
+ id = script->add_variable(varname);
+
+ if (script->str_data[id].type != C_NAME && // variable
+ script->str_data[id].type != C_PARAM && // param
+ script->str_data[id].type != C_INT) { // constant
+ ShowError("script:getd: `%s` is already used by something that is not a variable.\n", varname);
+ st->state = END;
+ return false;
+ }
+
// Push the 'pointer' so it's more flexible [Lance]
- script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem),NULL);
+ script->push_val(st->stack, C_NAME, reference_uid(id, elem),NULL);
return true;
}
// <--- [zBuffer] List of dynamic var commands
// Pet stat [Lance]
-BUILDIN(petstat)
+static BUILDIN(petstat)
{
struct pet_data *pd;
int flag = script_getnum(st,2);
@@ -16645,7 +17899,7 @@ BUILDIN(petstat)
return true;
}
-BUILDIN(callshop)
+static BUILDIN(callshop)
{
struct npc_data *nd;
const char *shopname;
@@ -16685,7 +17939,7 @@ BUILDIN(callshop)
return true;
}
-BUILDIN(npcshopitem)
+static BUILDIN(npcshopitem)
{
const char* npcname = script_getstr(st, 2);
struct npc_data* nd = npc->name2id(npcname);
@@ -16714,7 +17968,7 @@ BUILDIN(npcshopitem)
return true;
}
-BUILDIN(npcshopadditem)
+static BUILDIN(npcshopadditem)
{
const char* npcname = script_getstr(st,2);
struct npc_data* nd = npc->name2id(npcname);
@@ -16743,7 +17997,7 @@ BUILDIN(npcshopadditem)
return true;
}
-BUILDIN(npcshopdelitem)
+static BUILDIN(npcshopdelitem)
{
const char* npcname = script_getstr(st,2);
struct npc_data* nd = npc->name2id(npcname);
@@ -16779,7 +18033,8 @@ BUILDIN(npcshopdelitem)
}
//Sets a script to attach to a shop npc.
-BUILDIN(npcshopattach) {
+static BUILDIN(npcshopattach)
+{
const char* npcname = script_getstr(st,2);
struct npc_data* nd = npc->name2id(npcname);
int flag = 1;
@@ -16811,7 +18066,7 @@ BUILDIN(npcshopattach) {
* 1 - Equip script
* 2 - Unequip script
*------------------------------------------*/
-BUILDIN(setitemscript)
+static BUILDIN(setitemscript)
{
int item_id,n=0;
const char *new_bonus_script;
@@ -16857,7 +18112,8 @@ BUILDIN(setitemscript)
* is updated to the new rate. Rate must be in the range [1:10000]
* Returns 1 if succeeded (added/updated a mob drop)
*-------------------------------------------------------*/
-BUILDIN(addmonsterdrop) {
+static BUILDIN(addmonsterdrop)
+{
struct mob_db *monster;
int item_id, rate, i, c = MAX_MOB_DROP;
@@ -16917,7 +18173,8 @@ BUILDIN(addmonsterdrop) {
*
* Returns 1 if succeeded (deleted a mob drop)
*-------------------------------------------------------*/
-BUILDIN(delmonsterdrop) {
+static BUILDIN(delmonsterdrop)
+{
struct mob_db *monster;
int item_id, i;
@@ -16959,7 +18216,7 @@ BUILDIN(delmonsterdrop) {
* Name, Level, race, size, etc...
* getmonsterinfo(monsterID,queryIndex);
*------------------------------------------*/
-BUILDIN(getmonsterinfo)
+static BUILDIN(getmonsterinfo)
{
struct mob_db *monster;
int mob_id;
@@ -17003,7 +18260,7 @@ BUILDIN(getmonsterinfo)
return true;
}
-BUILDIN(checkvending) // check vending [Nab4]
+static BUILDIN(checkvending) // check vending [Nab4]
{
struct map_session_data *sd = NULL;
@@ -17021,7 +18278,8 @@ BUILDIN(checkvending) // check vending [Nab4]
}
// check chatting [Marka]
-BUILDIN(checkchatting) {
+static BUILDIN(checkchatting)
+{
struct map_session_data *sd = NULL;
if (script_hasdata(st,2))
@@ -17037,7 +18295,8 @@ BUILDIN(checkchatting) {
return true;
}
-BUILDIN(checkidle) {
+static BUILDIN(checkidle)
+{
struct map_session_data *sd = NULL;
if (script_hasdata(st, 2))
@@ -17053,7 +18312,7 @@ BUILDIN(checkidle) {
return true;
}
-BUILDIN(searchitem)
+static BUILDIN(searchitem)
{
struct script_data* data = script_getdata(st, 2);
const char *itemname = script_getstr(st,3);
@@ -17116,7 +18375,7 @@ BUILDIN(searchitem)
}
// [zBuffer] List of player cont commands --->
-BUILDIN(rid2name)
+static BUILDIN(rid2name)
{
struct block_list *bl = NULL;
int rid = script_getnum(st,2);
@@ -17140,7 +18399,8 @@ BUILDIN(rid2name)
return true;
}
-BUILDIN(pcblockmove) {
+static BUILDIN(pcblockmove)
+{
int id, flag;
struct map_session_data *sd = NULL;
@@ -17152,13 +18412,92 @@ BUILDIN(pcblockmove) {
else
sd = script->rid2sd(st);
- if (sd != NULL)
- sd->state.blockedmove = flag > 0;
+ if (!sd)
+ return true;
+
+ if (flag)
+ sd->block_action.move = 1;
+ else
+ sd->block_action.move = 0;
+
+ return true;
+}
+
+static BUILDIN(setpcblock)
+{
+ struct map_session_data *sd = script->rid2sd(st);
+ enum pcblock_action_flag type = script_getnum(st, 2);
+ int state = (script_getnum(st, 3) > 0) ? 1 : 0;
+
+ if (sd == NULL)
+ return true;
+
+ if ((type & PCBLOCK_MOVE) != 0)
+ sd->block_action.move = state;
+
+ if ((type & PCBLOCK_ATTACK) != 0)
+ sd->block_action.attack = state;
+
+ if ((type & PCBLOCK_SKILL) != 0)
+ sd->block_action.skill = state;
+
+ if ((type & PCBLOCK_USEITEM) != 0)
+ sd->block_action.useitem = state;
+
+ if ((type & PCBLOCK_CHAT) != 0)
+ sd->block_action.chat = state;
+
+ if ((type & PCBLOCK_IMMUNE) != 0)
+ sd->block_action.immune = state;
+
+ if ((type & PCBLOCK_SITSTAND) != 0)
+ sd->block_action.sitstand = state;
+
+ if ((type & PCBLOCK_COMMANDS) != 0)
+ sd->block_action.commands = state;
+
+ return true;
+}
+
+static BUILDIN(checkpcblock)
+{
+ struct map_session_data *sd = script->rid2sd(st);
+ int retval = PCBLOCK_NONE;
+ if (sd == NULL) {
+ script_pushint(st, PCBLOCK_NONE);
+ return true;
+ }
+
+ if (sd->block_action.move != 0)
+ retval |= PCBLOCK_MOVE;
+
+ if (sd->block_action.attack != 0)
+ retval |= PCBLOCK_ATTACK;
+
+ if (sd->block_action.skill != 0)
+ retval |= PCBLOCK_SKILL;
+
+ if (sd->block_action.useitem != 0)
+ retval |= PCBLOCK_USEITEM;
+
+ if (sd->block_action.chat != 0)
+ retval |= PCBLOCK_CHAT;
+
+ if (sd->block_action.immune != 0)
+ retval |= PCBLOCK_IMMUNE;
+
+ if (sd->block_action.sitstand != 0)
+ retval |= PCBLOCK_SITSTAND;
+
+ if (sd->block_action.commands != 0)
+ retval |= PCBLOCK_COMMANDS;
+
+ script_pushint(st, retval);
return true;
}
-BUILDIN(pcfollow)
+static BUILDIN(pcfollow)
{
int id, targetid;
struct map_session_data *sd = NULL;
@@ -17177,7 +18516,7 @@ BUILDIN(pcfollow)
return true;
}
-BUILDIN(pcstopfollow)
+static BUILDIN(pcstopfollow)
{
int id;
struct map_session_data *sd = NULL;
@@ -17198,7 +18537,8 @@ BUILDIN(pcstopfollow)
// [zBuffer] List of mob control commands --->
//## TODO always return if the request/whatever was successfull [FlavioJS]
-BUILDIN(getunittype) {
+static BUILDIN(getunittype)
+{
struct block_list* bl;
int value;
@@ -17225,12 +18565,1647 @@ BUILDIN(getunittype) {
return true;
}
+/**
+ * Sets real-time unit data for a game object.
+ * Setunitdata <GUID>,<DataType>,<Val1>{,<Val2>,<Val3>}
+ * @param1 GUID GID of the unit.
+ * @param2 DataType Type of Data to be set for the unit.
+ * @param3 Value#1 Value to be passed as change in data.
+ * @param4 Value#2 Optional int value to be passed for certain data types.
+ * @param5 Value#3 Optional int value to be passed for certain data types.
+ * @return 1 on success, 0 on failure.
+ */
+static BUILDIN(setunitdata)
+{
+ struct block_list *bl = NULL;
+ const char *mapname = NULL, *udtype = NULL;
+ int type = 0, val = 0, val2 = 0, val3 = 0;
+ struct map_session_data *tsd = NULL;
+
+ bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_setunitdata: Error in finding object with given GID %d!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ type = script_getnum(st, 3);
+
+ /* type bounds */
+ if (type < UDT_SIZE || type >= UDT_MAX) { // Note: UDT_TYPE is not valid here
+ ShowError("buildin_setunitdata: Invalid unit data type %d provided.\n", type);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ /* Mandatory Argument 3 */
+ if (type == UDT_MAPIDXY) {
+ if (!script_isstringtype(st, 4)) {
+ ShowError("buildin_setunitdata: Invalid data type for argument #3.\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ mapname = script_getstr(st, 4);
+ } else {
+ if (script_isstringtype(st, 4)) {
+ ShowError("buildin_setunitdata: Invalid data type for argument #3.\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ val = script_getnum(st, 4);
+ }
+/* checks if value is out of bounds. */
+#define setunitdata_check_bounds(arg, min, max) \
+ do { \
+ if (script_getnum(st, (arg)) < (min) || script_getnum(st, (arg)) > (max)) { \
+ ShowError("buildin_setunitdata: Invalid value %d for argument #%d. (min: %d, max: %d)\n", script_getnum(st, (arg)), (arg)-1, (min), (max)); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+/* checks if value is out of bounds. */
+#define setunitdata_check_min(arg, min) \
+ do { \
+ if (script_getnum(st, (arg)) < (min)) { \
+ ShowError("buildin_setunitdata: Invalid value %d for argument #%d. (min: %d)\n", script_getnum(st, (arg)), (arg)-1, (min)); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+/* checks if the argument doesn't exist, if required.
+ * also checks if the argument exists, if not required. */
+#define setunitdata_assert_arg(arg, required) \
+ do { \
+ if (required && !script_hasdata(st, (arg))) { \
+ ShowError("buildin_setunitdata: Type %d reqires argument #%d.\n", type, (arg)-1); \
+ script_pushint(st, 0); \
+ return false; \
+ } else if (!required && script_hasdata(st, arg)) { \
+ ShowError("buildin_setunitdata: Argument %d is not required for type %d.\n", (arg)-1, type); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while (0);
+/* checks if the data is an integer. */
+#define setunitdata_check_int(arg) \
+ do { \
+ setunitdata_assert_arg((arg), true); \
+ if (script_isstringtype(st, (arg))) { \
+ ShowError("buildin_setunitdata: Argument #%d expects integer, string given.\n", (arg)-1); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+/* checks if the data is a string. */
+#define setunitdata_check_string(arg) \
+ do { \
+ setunitdata_assert_arg((arg), true); \
+ if (script_isinttype(st, (arg))) { \
+ ShowError("buildin_setunitdata: Argument #%d expects string, integer given.\n", (arg)-1); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+
+ if (type != UDT_MAPIDXY && type != UDT_WALKTOXY) {
+ setunitdata_assert_arg(5, false);
+ setunitdata_assert_arg(6, false);
+ }
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ setunitdata_check_bounds(4, SZ_SMALL, SZ_BIG);
+ break;
+ case UDT_LEVEL:
+ case UDT_HP:
+ case UDT_MAXHP:
+ case UDT_SP:
+ case UDT_MAXSP:
+ case UDT_CLASS:
+ case UDT_HEADBOTTOM:
+ case UDT_HEADMIDDLE:
+ case UDT_HEADTOP:
+ case UDT_CLOTHCOLOR:
+ case UDT_SHIELD:
+ case UDT_WEAPON:
+ case UDT_INTIMACY:
+ case UDT_LIFETIME:
+ case UDT_MERC_KILLCOUNT:
+ case UDT_ROBE:
+ case UDT_BODY2:
+ setunitdata_check_min(4, 0);
+ break;
+ case UDT_MASTERAID:
+ setunitdata_check_min(4, 0);
+ tsd = map->id2sd(val);
+ if (tsd == NULL) {
+ ShowWarning("buildin_setunitdata: Account ID %d not found for master change!\n",val);
+ script_pushint(st, 0);
+ return false;
+ }
+ break;
+ case UDT_MASTERCID:
+ setunitdata_check_min(4, 0);
+ tsd = map->charid2sd(val);
+ if (tsd == NULL) {
+ ShowWarning("buildin_setunitdata: Character ID %d not found for master change!\n",val);
+ script_pushint(st, 0);
+ return false;
+ }
+ break;
+ case UDT_MAPIDXY:
+ if ((val = map->mapname2mapid(mapname)) == -1) {
+ ShowError("buildin_setunitdata: Non-existent map %s provided.\n", mapname);
+ return false;
+ }
+ setunitdata_check_int(5);
+ setunitdata_check_int(6);
+ setunitdata_check_bounds(5, 0, MAX_MAP_SIZE/2);
+ setunitdata_check_bounds(6, 0, MAX_MAP_SIZE/2);
+ val2 = script_getnum(st, 5);
+ val3 = script_getnum(st, 6);
+ break;
+ case UDT_WALKTOXY:
+ setunitdata_assert_arg(6, false);
+ setunitdata_check_int(5);
+ val2 = script_getnum(st, 5);
+ setunitdata_check_bounds(4, 0, MAX_MAP_SIZE/2);
+ setunitdata_check_bounds(5, 0, MAX_MAP_SIZE/2);
+ break;
+ case UDT_SPEED:
+ setunitdata_check_bounds(4, 0, MAX_WALK_SPEED);
+ break;
+ case UDT_MODE:
+ setunitdata_check_bounds(4, MD_NONE, MD_MASK);
+ break;
+ case UDT_AI:
+ setunitdata_check_bounds(4, AI_NONE, AI_MAX-1);
+ break;
+ case UDT_SCOPTION:
+ setunitdata_check_bounds(4, OPTION_NOTHING, OPTION_COSTUME);
+ break;
+ case UDT_SEX:
+ setunitdata_check_bounds(4, SEX_FEMALE, SEX_MALE);
+ break;
+ case UDT_HAIRSTYLE:
+ setunitdata_check_bounds(4, 0, battle->bc->max_hair_style);
+ break;
+ case UDT_HAIRCOLOR:
+ setunitdata_check_bounds(4, 0, battle->bc->max_hair_color);
+ break;
+ case UDT_LOOKDIR:
+ setunitdata_check_bounds(4, 0, 7);
+ break;
+ case UDT_CANMOVETICK:
+ setunitdata_check_min(4, 0);
+ break;
+ case UDT_STR:
+ case UDT_AGI:
+ case UDT_VIT:
+ case UDT_INT:
+ case UDT_DEX:
+ case UDT_LUK:
+ case UDT_STATPOINT:
+ case UDT_ATKRANGE:
+ case UDT_ATKMIN:
+ case UDT_ATKMAX:
+ case UDT_MATKMIN:
+ case UDT_MATKMAX:
+ case UDT_AMOTION:
+ case UDT_ADELAY:
+ case UDT_DMOTION:
+ setunitdata_check_bounds(4, 0, USHRT_MAX);
+ break;
+ case UDT_DEF:
+ case UDT_MDEF:
+ case UDT_HIT:
+ case UDT_FLEE:
+ case UDT_PDODGE:
+ case UDT_CRIT:
+ setunitdata_check_bounds(4, 0, SHRT_MAX);
+ break;
+ case UDT_HUNGER:
+ setunitdata_check_bounds(4, 0, 99);
+ break;
+ case UDT_RACE:
+ case UDT_ELETYPE:
+ case UDT_ELELEVEL:
+ setunitdata_check_bounds(4, 0, CHAR_MAX);
+ break;
+ default:
+ break;
+ }
+
+#undef setunitdata_check_bounds
+#undef setunitdata_assert_arg
+#undef setunitdata_check_int
+#undef setunitdata_check_string
+
+ /* Set the values */
+ switch (bl->type) {
+ case BL_MOB:
+ {
+ struct mob_data *md = BL_UCAST(BL_MOB, bl);
+ nullpo_retr(false, md);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ md->status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ md->level = val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ clif->charnameack(0, &md->bl);
+ break;
+ case UDT_MAXHP:
+ md->status.max_hp = (unsigned int) val;
+ clif->charnameack(0, &md->bl);
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXSP:
+ md->status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERAID:
+ md->master_id = val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ md->status.speed = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_MODE:
+ md->status.mode = (enum e_mode) val;
+ break;
+ case UDT_AI:
+ md->special_state.ai = (enum ai) val;
+ break;
+ case UDT_SCOPTION:
+ md->sc.option = (unsigned int) val;
+ break;
+ case UDT_SEX:
+ md->vd->sex = (char) val;
+ break;
+ case UDT_CLASS:
+ mob->class_change(md, val);
+ break;
+ case UDT_HAIRSTYLE:
+ clif->changelook(bl, LOOK_HAIR, val);
+ break;
+ case UDT_HAIRCOLOR:
+ clif->changelook(bl, LOOK_HAIR_COLOR, val);
+ break;
+ case UDT_HEADBOTTOM:
+ clif->changelook(bl, LOOK_HEAD_BOTTOM, val);
+ break;
+ case UDT_HEADMIDDLE:
+ clif->changelook(bl, LOOK_HEAD_MID, val);
+ break;
+ case UDT_HEADTOP:
+ clif->changelook(bl, LOOK_HEAD_TOP, val);
+ break;
+ case UDT_CLOTHCOLOR:
+ clif->changelook(bl, LOOK_CLOTHES_COLOR, val);
+ break;
+ case UDT_SHIELD:
+ clif->changelook(bl, LOOK_SHIELD, val);
+ break;
+ case UDT_WEAPON:
+ clif->changelook(bl, LOOK_WEAPON, val);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (uint8) val);
+ break;
+ case UDT_CANMOVETICK:
+ md->ud.canmove_tick = val;
+ break;
+ case UDT_STR:
+ md->status.str = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_AGI:
+ md->status.agi = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_VIT:
+ md->status.vit = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_INT:
+ md->status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_DEX:
+ md->status.dex = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_LUK:
+ md->status.luk = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_ATKRANGE:
+ md->status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ md->status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ md->status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ md->status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ md->status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ md->status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ md->status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ md->status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ md->status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ md->status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ md->status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ md->status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ md->status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ md->status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ md->status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ md->status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ md->status.dmotion = (unsigned short) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for mob unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_HOM:
+ {
+ struct homun_data *hd = BL_UCAST(BL_HOM, bl);
+
+ nullpo_retr(false, hd);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ hd->base_status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ hd->homunculus.level = (short) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXHP:
+ hd->homunculus.max_hp = val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXSP:
+ hd->homunculus.max_sp = val;
+ break;
+ case UDT_MASTERCID:
+ hd->homunculus.char_id = val;
+ hd->master = tsd;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ hd->base_status.speed = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ hd->ud.canmove_tick = val;
+ break;
+ case UDT_STR:
+ hd->base_status.str = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_AGI:
+ hd->base_status.agi = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_VIT:
+ hd->base_status.vit = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_INT:
+ hd->base_status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_DEX:
+ hd->base_status.dex = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_LUK:
+ hd->base_status.luk = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_ATKRANGE:
+ hd->base_status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ hd->base_status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ hd->base_status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ hd->base_status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ hd->base_status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ hd->base_status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ hd->base_status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ hd->base_status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ hd->base_status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ hd->base_status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ hd->base_status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ hd->base_status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ hd->base_status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ hd->base_status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ hd->base_status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ hd->base_status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ hd->base_status.dmotion = (unsigned short) val;
+ break;
+ case UDT_HUNGER:
+ hd->homunculus.hunger = (short) val;
+ clif->send_homdata(hd->master, SP_HUNGRY, hd->homunculus.hunger);
+ break;
+ case UDT_INTIMACY:
+ homun->add_intimacy(hd, (unsigned int) val);
+ clif->send_homdata(hd->master, SP_INTIMATE, hd->homunculus.intimacy / 100);
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for homunculus unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ clif->send_homdata(hd->master, SP_ACK, 0); // send homun data
+ }
+ break;
+ case BL_PET:
+ {
+ struct pet_data *pd = BL_UCAST(BL_PET, bl);
+
+ nullpo_retr(false, pd);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ pd->status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ pd->pet.level = (short) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXHP:
+ pd->status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXSP:
+ pd->status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERAID:
+ pd->pet.account_id = val;
+ pd->msd = tsd;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ pd->status.speed = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ pd->ud.canmove_tick = val;
+ break;
+ case UDT_STR:
+ pd->status.str = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_AGI:
+ pd->status.agi = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_VIT:
+ pd->status.vit = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_INT:
+ pd->status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_DEX:
+ pd->status.dex = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_LUK:
+ pd->status.luk = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_ATKRANGE:
+ pd->status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ pd->status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ pd->status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ pd->status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ pd->status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ pd->status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ pd->status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ pd->status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ pd->status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ pd->status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ pd->status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ pd->status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ pd->status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ pd->status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ pd->status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ pd->status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ pd->status.dmotion = (unsigned short) val;
+ break;
+ case UDT_INTIMACY:
+ pet->set_intimate(pd, val);
+ clif->send_petdata(pd->msd, pd, 1, pd->pet.intimate);
+ break;
+ case UDT_HUNGER:
+ pd->pet.hungry = (short) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for pet unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ clif->send_petstatus(pd->msd); // send pet data
+ }
+ break;
+ case BL_MER:
+ {
+ struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
+
+ nullpo_retr(false, mc);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ mc->base_status.size = (unsigned char) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXHP:
+ mc->base_status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXSP:
+ mc->base_status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERCID:
+ mc->mercenary.char_id = val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ mc->base_status.size = (unsigned char) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ mc->ud.canmove_tick = val;
+ break;
+ case UDT_STR:
+ mc->base_status.str = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_AGI:
+ mc->base_status.agi = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_VIT:
+ mc->base_status.vit = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_INT:
+ mc->base_status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_DEX:
+ mc->base_status.dex = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_LUK:
+ mc->base_status.luk = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_ATKRANGE:
+ mc->base_status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ mc->base_status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ mc->base_status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ mc->base_status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ mc->base_status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ mc->base_status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ mc->base_status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ mc->base_status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ mc->base_status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ mc->base_status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ mc->base_status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ mc->base_status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ mc->base_status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ mc->base_status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ mc->base_status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ mc->base_status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ mc->base_status.dmotion = (unsigned short) val;
+ break;
+ case UDT_MERC_KILLCOUNT:
+ mc->mercenary.kill_count = (unsigned int) val;
+ break;
+ case UDT_LIFETIME:
+ mc->mercenary.life_time = (unsigned int) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for mercenary unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ clif->mercenary_info(map->charid2sd(mc->mercenary.char_id));
+ clif->mercenary_skillblock(map->charid2sd(mc->mercenary.char_id));
+ }
+ break;
+ case BL_ELEM:
+ {
+ struct elemental_data *ed = BL_UCAST(BL_ELEM, bl);
+
+ nullpo_retr(false, ed);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ ed->base_status.size = (unsigned char) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXHP:
+ ed->base_status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXSP:
+ ed->base_status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERCID:
+ ed->elemental.char_id = val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ ed->base_status.speed = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ ed->ud.canmove_tick = val;
+ break;
+ case UDT_STR:
+ ed->base_status.str = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_AGI:
+ ed->base_status.agi = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_VIT:
+ ed->base_status.vit = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_INT:
+ ed->base_status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_DEX:
+ ed->base_status.dex = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_LUK:
+ ed->base_status.luk = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_ATKRANGE:
+ ed->base_status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ ed->base_status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ ed->base_status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ ed->base_status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ ed->base_status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ ed->base_status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ ed->base_status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ ed->base_status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ ed->base_status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ ed->base_status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ ed->base_status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ ed->base_status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ ed->base_status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ ed->base_status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ ed->base_status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ ed->base_status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ ed->base_status.dmotion = (unsigned short) val;
+ break;
+ case UDT_LIFETIME:
+ ed->elemental.life_time = val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for elemental unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ clif->elemental_info(ed->master);
+ }
+ break;
+ case BL_NPC:
+ {
+ struct npc_data *nd = BL_UCAST(BL_NPC, bl);
+
+ nullpo_retr(false, nd);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ nd->status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ nd->level = (unsigned short) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXHP:
+ nd->status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
+ break;
+ case UDT_MAXSP:
+ nd->status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_CLASS:
+ npc->setclass(nd, (short) val);
+ break;
+ case UDT_SPEED:
+ nd->speed = (short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_STR:
+ nd->status.str = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_AGI:
+ nd->status.agi = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_VIT:
+ nd->status.vit = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_INT:
+ nd->status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_DEX:
+ nd->status.dex = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_LUK:
+ nd->status.luk = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_STATPOINT:
+ nd->stat_point = (unsigned short) val;
+ break;
+ case UDT_ATKRANGE:
+ nd->status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ nd->status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ nd->status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ nd->status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ nd->status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ nd->status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ nd->status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ nd->status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ nd->status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ nd->status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ nd->status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ nd->status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ nd->status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ nd->status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ nd->status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ nd->status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ nd->status.dmotion = (unsigned short) val;
+ break;
+ case UDT_SEX:
+ nd->vd.sex = (char)val;
+ npc->refresh(nd);
+ break;
+ case UDT_HAIRSTYLE:
+ clif->changelook(bl, LOOK_HAIR, val);
+ break;
+ case UDT_HAIRCOLOR:
+ clif->changelook(bl, LOOK_HAIR_COLOR, val);
+ break;
+ case UDT_HEADBOTTOM:
+ clif->changelook(bl, LOOK_HEAD_BOTTOM, val);
+ break;
+ case UDT_HEADMIDDLE:
+ clif->changelook(bl, LOOK_HEAD_MID, val);
+ break;
+ case UDT_HEADTOP:
+ clif->changelook(bl, LOOK_HEAD_TOP, val);
+ break;
+ case UDT_CLOTHCOLOR:
+ clif->changelook(bl, LOOK_CLOTHES_COLOR, val);
+ break;
+ case UDT_SHIELD:
+ clif->changelook(bl, LOOK_SHIELD, val);
+ break;
+ case UDT_WEAPON:
+ clif->changelook(bl, LOOK_WEAPON, val);
+ break;
+ case UDT_ROBE:
+ clif->changelook(bl, LOOK_ROBE, val);
+ break;
+ case UDT_BODY2:
+ clif->changelook(bl, LOOK_BODY2, val);
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for NPC unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ default:
+ ShowError("buildin_setunitdata: Unknown object!\n");
+ script_pushint(st, 0);
+ return false;
+ } // end of bl->type switch
+
+ script_pushint(st, 1);
+ return true;
+}
+
+/**
+ * Retrieves real-time data for a game object.
+ * Getunitdata <GUID>,<DataType>{,<Variable>}
+ * @param1 GUID Game object unique Id.
+ * @param2 DataType Type of Data to be set for the unit.
+ * @param3 Variable array reference to store data into. (used for UDT_MAPIDXY)
+ * @return 0 on failure, <value> on success
+ */
+static BUILDIN(getunitdata)
+{
+ struct block_list *bl;
+ const char *udtype = NULL;
+ const struct map_session_data *sd = NULL;
+ int type = 0;
+ char* name = NULL;
+ struct script_data *data = script_hasdata(st,4)?script_getdata(st, 4):NULL;
+
+ bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_getunitdata: Error in finding object with given GID %d!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ type = script_getnum(st, 3);
+
+ /* Type check */
+ if (type < UDT_TYPE || type >= UDT_MAX) {
+ ShowError("buildin_getunitdata: Invalid unit data type %d provided.\n", type);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ /* Argument checks */
+ if (type == UDT_MAPIDXY) {
+ if (data == NULL || !data_isreference(data)) {
+ ShowWarning("buildin_getunitdata: Error in argument 3. Please provide a reference variable to store values in.\n");
+ script_pushint(st, 0);
+ return false;
+ }
+
+ name = reference_getname(data);
+
+ if (not_server_variable(*name)) {
+ sd = script->rid2sd(st);
+ if (sd == NULL) {
+ ShowWarning("buildin_getunitdata: Player not attached! Cannot use player variable %s.\n",name);
+ script_pushint(st, 0);
+ return true;// no player attached
+ }
+ }
+ }
+
+#define getunitdata_sub(idx__,var__) script->setd_sub(st,NULL,name,(idx__),(void *)h64BPTRSIZE((int)(var__)),data->ref);
+
+ switch (bl->type) {
+ case BL_MOB:
+ {
+ const struct mob_data *md = BL_UCAST(BL_MOB, bl);
+
+ nullpo_retr(false, md);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_MOB); break;
+ case UDT_SIZE: script_pushint(st, md->status.size); break;
+ case UDT_LEVEL: script_pushint(st, md->level); break;
+ case UDT_HP: script_pushint(st, md->status.hp); break;
+ case UDT_MAXHP: script_pushint(st, md->status.max_hp); break;
+ case UDT_SP: script_pushint(st, md->status.sp); break;
+ case UDT_MAXSP: script_pushint(st, md->status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, md->bl.m);
+ getunitdata_sub(1, md->bl.x);
+ getunitdata_sub(2, md->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, md->status.speed); break;
+ case UDT_MODE: script_pushint(st, md->status.mode); break;
+ case UDT_AI: script_pushint(st, md->special_state.ai); break;
+ case UDT_SCOPTION: script_pushint(st, md->sc.option); break;
+ case UDT_SEX: script_pushint(st, md->vd->sex); break;
+ case UDT_CLASS: script_pushint(st, md->vd->class); break;
+ case UDT_HAIRSTYLE: script_pushint(st, md->vd->hair_style); break;
+ case UDT_HAIRCOLOR: script_pushint(st, md->vd->hair_color); break;
+ case UDT_HEADBOTTOM: script_pushint(st, md->vd->head_bottom); break;
+ case UDT_HEADMIDDLE: script_pushint(st, md->vd->head_mid); break;
+ case UDT_HEADTOP: script_pushint(st, md->vd->head_top); break;
+ case UDT_CLOTHCOLOR: script_pushint(st, md->vd->cloth_color); break;
+ case UDT_SHIELD: script_pushint(st, md->vd->shield); break;
+ case UDT_WEAPON: script_pushint(st, md->vd->weapon); break;
+ case UDT_LOOKDIR: script_pushint(st, md->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, md->ud.canmove_tick); break;
+ case UDT_STR: script_pushint(st, md->status.str); break;
+ case UDT_AGI: script_pushint(st, md->status.agi); break;
+ case UDT_VIT: script_pushint(st, md->status.vit); break;
+ case UDT_INT: script_pushint(st, md->status.int_); break;
+ case UDT_DEX: script_pushint(st, md->status.dex); break;
+ case UDT_LUK: script_pushint(st, md->status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, md->status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, md->status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, md->status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, md->status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, md->status.matk_max); break;
+ case UDT_DEF: script_pushint(st, md->status.def); break;
+ case UDT_MDEF: script_pushint(st, md->status.mdef); break;
+ case UDT_HIT: script_pushint(st, md->status.hit); break;
+ case UDT_FLEE: script_pushint(st, md->status.flee); break;
+ case UDT_PDODGE: script_pushint(st, md->status.flee2); break;
+ case UDT_CRIT: script_pushint(st, md->status.cri); break;
+ case UDT_RACE: script_pushint(st, md->status.race); break;
+ case UDT_ELETYPE: script_pushint(st, md->status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, md->status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, md->status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, md->status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, md->status.dmotion); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Mob unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_HOM:
+ {
+ const struct homun_data *hd = BL_UCAST(BL_HOM, bl);
+
+ nullpo_retr(false, hd);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_HOM); break;
+ case UDT_SIZE: script_pushint(st, hd->base_status.size); break;
+ case UDT_LEVEL: script_pushint(st, hd->homunculus.level); break;
+ case UDT_HP: script_pushint(st, hd->base_status.hp); break;
+ case UDT_MAXHP: script_pushint(st, hd->base_status.max_hp); break;
+ case UDT_SP: script_pushint(st, hd->base_status.sp); break;
+ case UDT_MAXSP: script_pushint(st, hd->base_status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, hd->bl.m);
+ getunitdata_sub(1, hd->bl.x);
+ getunitdata_sub(2, hd->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, hd->base_status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, hd->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, hd->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, hd->base_status.mode); break;
+ case UDT_STR: script_pushint(st, hd->base_status.str); break;
+ case UDT_AGI: script_pushint(st, hd->base_status.agi); break;
+ case UDT_VIT: script_pushint(st, hd->base_status.vit); break;
+ case UDT_INT: script_pushint(st, hd->base_status.int_); break;
+ case UDT_DEX: script_pushint(st, hd->base_status.dex); break;
+ case UDT_LUK: script_pushint(st, hd->base_status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, hd->base_status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, hd->base_status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, hd->base_status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, hd->base_status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, hd->base_status.matk_max); break;
+ case UDT_DEF: script_pushint(st, hd->base_status.def); break;
+ case UDT_MDEF: script_pushint(st, hd->base_status.mdef); break;
+ case UDT_HIT: script_pushint(st, hd->base_status.hit); break;
+ case UDT_FLEE: script_pushint(st, hd->base_status.flee); break;
+ case UDT_PDODGE: script_pushint(st, hd->base_status.flee2); break;
+ case UDT_CRIT: script_pushint(st, hd->base_status.cri); break;
+ case UDT_RACE: script_pushint(st, hd->base_status.race); break;
+ case UDT_ELETYPE: script_pushint(st, hd->base_status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, hd->base_status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, hd->base_status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, hd->base_status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, hd->base_status.dmotion); break;
+ case UDT_MASTERCID: script_pushint(st, hd->homunculus.char_id); break;
+ case UDT_HUNGER: script_pushint(st, hd->homunculus.hunger); break;
+ case UDT_INTIMACY: script_pushint(st, hd->homunculus.intimacy); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Homunculus unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_PET:
+ {
+ const struct pet_data *pd = BL_UCAST(BL_PET, bl);
+
+ nullpo_retr(false, pd);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_PET); break;
+ case UDT_SIZE: script_pushint(st, pd->status.size); break;
+ case UDT_LEVEL: script_pushint(st, pd->pet.level); break;
+ case UDT_HP: script_pushint(st, pd->status.hp); break;
+ case UDT_MAXHP: script_pushint(st, pd->status.max_hp); break;
+ case UDT_SP: script_pushint(st, pd->status.sp); break;
+ case UDT_MAXSP: script_pushint(st, pd->status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, pd->bl.m);
+ getunitdata_sub(1, pd->bl.x);
+ getunitdata_sub(2, pd->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, pd->status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, pd->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, pd->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, pd->status.mode); break;
+ case UDT_STR: script_pushint(st, pd->status.str); break;
+ case UDT_AGI: script_pushint(st, pd->status.agi); break;
+ case UDT_VIT: script_pushint(st, pd->status.vit); break;
+ case UDT_INT: script_pushint(st, pd->status.int_); break;
+ case UDT_DEX: script_pushint(st, pd->status.dex); break;
+ case UDT_LUK: script_pushint(st, pd->status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, pd->status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, pd->status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, pd->status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, pd->status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, pd->status.matk_max); break;
+ case UDT_DEF: script_pushint(st, pd->status.def); break;
+ case UDT_MDEF: script_pushint(st, pd->status.mdef); break;
+ case UDT_HIT: script_pushint(st, pd->status.hit); break;
+ case UDT_FLEE: script_pushint(st, pd->status.flee); break;
+ case UDT_PDODGE: script_pushint(st, pd->status.flee2); break;
+ case UDT_CRIT: script_pushint(st, pd->status.cri); break;
+ case UDT_RACE: script_pushint(st, pd->status.race); break;
+ case UDT_ELETYPE: script_pushint(st, pd->status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, pd->status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, pd->status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, pd->status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, pd->status.dmotion); break;
+ case UDT_MASTERAID: script_pushint(st, pd->pet.account_id); break;
+ case UDT_HUNGER: script_pushint(st, pd->pet.hungry); break;
+ case UDT_INTIMACY: script_pushint(st, pd->pet.intimate); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Pet unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_MER:
+ {
+ const struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
+
+ nullpo_retr(false, mc);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_MER); break;
+ case UDT_SIZE: script_pushint(st, mc->base_status.size); break;
+ case UDT_HP: script_pushint(st, mc->base_status.hp); break;
+ case UDT_MAXHP: script_pushint(st, mc->base_status.max_hp); break;
+ case UDT_SP: script_pushint(st, mc->base_status.sp); break;
+ case UDT_MAXSP: script_pushint(st, mc->base_status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, mc->bl.m);
+ getunitdata_sub(1, mc->bl.x);
+ getunitdata_sub(2, mc->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, mc->base_status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, mc->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, mc->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, mc->base_status.mode); break;
+ case UDT_STR: script_pushint(st, mc->base_status.str); break;
+ case UDT_AGI: script_pushint(st, mc->base_status.agi); break;
+ case UDT_VIT: script_pushint(st, mc->base_status.vit); break;
+ case UDT_INT: script_pushint(st, mc->base_status.int_); break;
+ case UDT_DEX: script_pushint(st, mc->base_status.dex); break;
+ case UDT_LUK: script_pushint(st, mc->base_status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, mc->base_status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, mc->base_status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, mc->base_status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, mc->base_status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, mc->base_status.matk_max); break;
+ case UDT_DEF: script_pushint(st, mc->base_status.def); break;
+ case UDT_MDEF: script_pushint(st, mc->base_status.mdef); break;
+ case UDT_HIT: script_pushint(st, mc->base_status.hit); break;
+ case UDT_FLEE: script_pushint(st, mc->base_status.flee); break;
+ case UDT_PDODGE: script_pushint(st, mc->base_status.flee2); break;
+ case UDT_CRIT: script_pushint(st, mc->base_status.cri); break;
+ case UDT_RACE: script_pushint(st, mc->base_status.race); break;
+ case UDT_ELETYPE: script_pushint(st, mc->base_status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, mc->base_status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, mc->base_status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, mc->base_status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, mc->base_status.dmotion); break;
+ case UDT_MASTERCID: script_pushint(st, mc->mercenary.char_id); break;
+ case UDT_MERC_KILLCOUNT: script_pushint(st, mc->mercenary.kill_count); break;
+ case UDT_LIFETIME: script_pushint(st, mc->mercenary.life_time); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Mercenary unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_ELEM:
+ {
+ const struct elemental_data *ed = BL_UCAST(BL_ELEM, bl);
+
+ nullpo_retr(false, ed);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_ELEM); break;
+ case UDT_SIZE: script_pushint(st, ed->base_status.size); break;
+ case UDT_HP: script_pushint(st, ed->base_status.hp); break;
+ case UDT_MAXHP: script_pushint(st, ed->base_status.max_hp); break;
+ case UDT_SP: script_pushint(st, ed->base_status.sp); break;
+ case UDT_MAXSP: script_pushint(st, ed->base_status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, ed->bl.m);
+ getunitdata_sub(1, ed->bl.x);
+ getunitdata_sub(2, ed->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, ed->base_status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, ed->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, ed->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, ed->base_status.mode); break;
+ case UDT_STR: script_pushint(st, ed->base_status.str); break;
+ case UDT_AGI: script_pushint(st, ed->base_status.agi); break;
+ case UDT_VIT: script_pushint(st, ed->base_status.vit); break;
+ case UDT_INT: script_pushint(st, ed->base_status.int_); break;
+ case UDT_DEX: script_pushint(st, ed->base_status.dex); break;
+ case UDT_LUK: script_pushint(st, ed->base_status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, ed->base_status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, ed->base_status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, ed->base_status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, ed->base_status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, ed->base_status.matk_max); break;
+ case UDT_DEF: script_pushint(st, ed->base_status.def); break;
+ case UDT_MDEF: script_pushint(st, ed->base_status.mdef); break;
+ case UDT_HIT: script_pushint(st, ed->base_status.hit); break;
+ case UDT_FLEE: script_pushint(st, ed->base_status.flee); break;
+ case UDT_PDODGE: script_pushint(st, ed->base_status.flee2); break;
+ case UDT_CRIT: script_pushint(st, ed->base_status.cri); break;
+ case UDT_RACE: script_pushint(st, ed->base_status.race); break;
+ case UDT_ELETYPE: script_pushint(st, ed->base_status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, ed->base_status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, ed->base_status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, ed->base_status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, ed->base_status.dmotion); break;
+ case UDT_MASTERCID: script_pushint(st, ed->elemental.char_id); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Elemental unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_NPC:
+ {
+ const struct npc_data *nd = BL_UCAST(BL_NPC, bl);
+
+ nullpo_retr(false, nd);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_NPC); break;
+ case UDT_SIZE: script_pushint(st, nd->status.size); break;
+ case UDT_HP: script_pushint(st, nd->status.hp); break;
+ case UDT_MAXHP: script_pushint(st, nd->status.max_hp); break;
+ case UDT_SP: script_pushint(st, nd->status.sp); break;
+ case UDT_MAXSP: script_pushint(st, nd->status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, bl->m);
+ getunitdata_sub(1, bl->x);
+ getunitdata_sub(2, bl->y);
+ break;
+ case UDT_SPEED: script_pushint(st, nd->status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, nd->ud->dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, nd->ud->canmove_tick); break;
+ case UDT_MODE: script_pushint(st, nd->status.mode); break;
+ case UDT_STR: script_pushint(st, nd->status.str); break;
+ case UDT_AGI: script_pushint(st, nd->status.agi); break;
+ case UDT_VIT: script_pushint(st, nd->status.vit); break;
+ case UDT_INT: script_pushint(st, nd->status.int_); break;
+ case UDT_DEX: script_pushint(st, nd->status.dex); break;
+ case UDT_LUK: script_pushint(st, nd->status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, nd->status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, nd->status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, nd->status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, nd->status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, nd->status.matk_max); break;
+ case UDT_DEF: script_pushint(st, nd->status.def); break;
+ case UDT_MDEF: script_pushint(st, nd->status.mdef); break;
+ case UDT_HIT: script_pushint(st, nd->status.hit); break;
+ case UDT_FLEE: script_pushint(st, nd->status.flee); break;
+ case UDT_PDODGE: script_pushint(st, nd->status.flee2); break;
+ case UDT_CRIT: script_pushint(st, nd->status.cri); break;
+ case UDT_RACE: script_pushint(st, nd->status.race); break;
+ case UDT_ELETYPE: script_pushint(st, nd->status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, nd->status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, nd->status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, nd->status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, nd->status.dmotion); break;
+ case UDT_SEX: script_pushint(st, nd->vd.sex); break;
+ case UDT_CLASS: script_pushint(st, nd->vd.class); break;
+ case UDT_HAIRSTYLE: script_pushint(st, nd->vd.hair_style); break;
+ case UDT_HAIRCOLOR: script_pushint(st, nd->vd.hair_color); break;
+ case UDT_HEADBOTTOM: script_pushint(st, nd->vd.head_bottom); break;
+ case UDT_HEADMIDDLE: script_pushint(st, nd->vd.head_mid); break;
+ case UDT_HEADTOP: script_pushint(st, nd->vd.head_top); break;
+ case UDT_CLOTHCOLOR: script_pushint(st, nd->vd.cloth_color); break;
+ case UDT_SHIELD: script_pushint(st, nd->vd.shield); break;
+ case UDT_WEAPON: script_pushint(st, nd->vd.weapon); break;
+ case UDT_ROBE: script_pushint(st, nd->vd.robe); break;
+ case UDT_BODY2: script_pushint(st, nd->vd.body_style); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for NPC unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ default:
+ ShowError("buildin_getunitdata: Unknown object!\n");
+ script_pushint(st, 0);
+ return false;
+ } // end of bl->type switch
+
+#undef getunitdata_sub
+
+ return true;
+}
+
+/**
+ * Gets the name of a Unit.
+ * Supported types are [MOB|HOM|PET|NPC].
+ * MER and ELEM don't support custom names.
+ *
+ * @command getunitname <GUID>;
+ * @param GUID Game Object Unique ID.
+ * @return boolean or Name of the game object.
+ */
+static BUILDIN(getunitname)
+{
+ const struct block_list* bl = NULL;
+
+ bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_getunitname: Error in finding object with given game ID %d!\n", script_getnum(st, 2));
+ script_pushconststr(st, "Unknown");
+ return false;
+ }
+
+ script_pushstrcopy(st, status->get_name(bl));
+
+ return true;
+}
+
+/**
+ * Changes the name of a bl.
+ * Supported types are [MOB|HOM|PET].
+ * For NPC see 'setnpcdisplay', MER and ELEM don't support custom names.
+ *
+ * @command setunitname <GUID>,<name>;
+ * @param GUID Game object unique ID.
+ * @param Name as string.
+ * @return boolean.
+ */
+static BUILDIN(setunitname)
+{
+ struct block_list* bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_setunitname: Game object with ID %d was not found!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ switch (bl->type) {
+ case BL_MOB:
+ {
+ struct mob_data *md = BL_UCAST(BL_MOB, bl);
+ if (md == NULL) {
+ ShowWarning("buildin_setunitname: Error in finding object BL_MOB!\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ safestrncpy(md->name, script_getstr(st, 3), NAME_LENGTH);
+ }
+ break;
+ case BL_HOM:
+ {
+ struct homun_data *hd = BL_UCAST(BL_HOM, bl);
+ if (hd == NULL) {
+ ShowWarning("buildin_setunitname: Error in finding object BL_HOM!\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ safestrncpy(hd->homunculus.name, script_getstr(st, 3), NAME_LENGTH);
+ }
+ break;
+ case BL_PET:
+ {
+ struct pet_data *pd = BL_UCAST(BL_PET, bl);
+ if (pd == NULL) {
+ ShowWarning("buildin_setunitname: Error in finding object BL_PET!\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ safestrncpy(pd->pet.name, script_getstr(st, 3), NAME_LENGTH);
+ }
+ break;
+ default:
+ script_pushint(st, 0);
+ ShowWarning("buildin_setunitname: Unknown object type!\n");
+ return false;
+ }
+
+ script_pushint(st, 1);
+ clif->charnameack(0, bl); // Send update to client.
+
+ return true;
+}
+
/// Makes the unit walk to target position or target id
/// Returns if it was successfull
///
/// unitwalk(<unit_id>,<x>,<y>) -> <bool>
/// unitwalk(<unit_id>,<target_id>) -> <bool>
-BUILDIN(unitwalk) {
+static BUILDIN(unitwalk)
+{
struct block_list* bl;
bl = map->id2bl(script_getnum(st,2));
@@ -17257,7 +20232,7 @@ BUILDIN(unitwalk) {
/// Kills the unit
///
/// unitkill <unit_id>;
-BUILDIN(unitkill)
+static BUILDIN(unitkill)
{
struct block_list* bl = map->id2bl(script_getnum(st,2));
if( bl != NULL )
@@ -17270,7 +20245,8 @@ BUILDIN(unitkill)
/// Returns if it was successfull
///
/// unitwarp(<unit_id>,"<map name>",<x>,<y>) -> <bool>
-BUILDIN(unitwarp) {
+static BUILDIN(unitwarp)
+{
int unit_id;
int mapid;
short x;
@@ -17310,7 +20286,8 @@ BUILDIN(unitwarp) {
///
/// unitattack(<unit_id>,"<target name>"{,<action type>}) -> <bool>
/// unitattack(<unit_id>,<target_id>{,<action type>}) -> <bool>
-BUILDIN(unitattack) {
+static BUILDIN(unitattack)
+{
struct block_list* unit_bl;
struct block_list* target_bl = NULL;
int actiontype = 0;
@@ -17364,7 +20341,8 @@ BUILDIN(unitattack) {
/// Makes the unit stop attacking and moving
///
/// unitstop <unit_id>;
-BUILDIN(unitstop) {
+static BUILDIN(unitstop)
+{
int unit_id;
struct block_list* bl;
@@ -17384,15 +20362,30 @@ BUILDIN(unitstop) {
/// Makes the unit say the message
///
-/// unittalk <unit_id>,"<message>";
-BUILDIN(unittalk) {
+/// unittalk(<unit_id>,"<message>"{, show_name{, <send_target>{, <target_id>}}});
+static BUILDIN(unittalk)
+{
int unit_id;
const char* message;
- struct block_list* bl;
+ struct block_list *bl, *target_bl = NULL;
+ bool show_name = true;
+ enum send_target target = AREA_CHAT_WOC;
unit_id = script_getnum(st,2);
message = script_getstr(st, 3);
+ if (script_hasdata(st, 4)) {
+ show_name = (script_getnum(st, 4) != 0) ? true : false;
+ }
+
+ if (script_hasdata(st, 5)) {
+ target = script_getnum(st, 5);
+ }
+
+ if (script_hasdata(st, 6)) {
+ target_bl = map->id2bl(script_getnum(st, 6));
+ }
+
bl = map->id2bl(unit_id);
if( bl != NULL ) {
struct StringBuf sbuf;
@@ -17401,8 +20394,17 @@ BUILDIN(unittalk) {
safestrncpy(blname, clif->get_bl_name(bl), sizeof(blname));
if(bl->type == BL_NPC)
strtok(blname, "#");
- StrBuf->Printf(&sbuf, "%s : %s", blname, message);
- clif->disp_overhead(bl, StrBuf->Value(&sbuf));
+ if (show_name) {
+ StrBuf->Printf(&sbuf, "%s : %s", blname, message);
+ } else {
+ StrBuf->Printf(&sbuf, "%s", message);
+ }
+
+ if (bl->type == BL_PC && target == SELF && (target_bl == NULL || bl == target_bl)) {
+ clif->notify_playerchat(bl, StrBuf->Value(&sbuf));
+ } else {
+ clif->disp_overhead(bl, StrBuf->Value(&sbuf), target, target_bl);
+ }
StrBuf->Destroy(&sbuf);
}
@@ -17414,7 +20416,8 @@ BUILDIN(unittalk) {
/// unitemote <unit_id>,<emotion>;
///
/// @see e_* in const.txt
-BUILDIN(unitemote) {
+static BUILDIN(unitemote)
+{
int unit_id;
int emotion;
struct block_list* bl;
@@ -17432,7 +20435,8 @@ BUILDIN(unitemote) {
///
/// unitskilluseid <unit_id>,<skill_id>,<skill_lv>{,<target_id>};
/// unitskilluseid <unit_id>,"<skill name>",<skill_lv>{,<target_id>};
-BUILDIN(unitskilluseid) {
+static BUILDIN(unitskilluseid)
+{
int unit_id;
uint16 skill_id;
uint16 skill_lv;
@@ -17465,7 +20469,8 @@ BUILDIN(unitskilluseid) {
///
/// unitskillusepos <unit_id>,<skill_id>,<skill_lv>,<target_x>,<target_y>;
/// unitskillusepos <unit_id>,"<skill name>",<skill_lv>,<target_x>,<target_y>;
-BUILDIN(unitskillusepos) {
+static BUILDIN(unitskillusepos)
+{
int unit_id;
uint16 skill_id;
uint16 skill_lv;
@@ -17501,7 +20506,7 @@ BUILDIN(unitskillusepos) {
/// Pauses the execution of the script, detaching the player
///
/// sleep <mili seconds>;
-BUILDIN(sleep)
+static BUILDIN(sleep)
{
int ticks;
@@ -17530,7 +20535,8 @@ BUILDIN(sleep)
/// Returns if a player is still attached
///
/// sleep2(<mili secconds>) -> <bool>
-BUILDIN(sleep2) {
+static BUILDIN(sleep2)
+{
int ticks;
ticks = script_getnum(st,2);
@@ -17554,7 +20560,7 @@ BUILDIN(sleep2) {
/// Awakes all the sleep timers of the target npc
///
/// awake "<npc name>";
-BUILDIN(awake)
+static BUILDIN(awake)
{
struct DBIterator *iter;
struct script_state *tst;
@@ -17597,7 +20603,7 @@ BUILDIN(awake)
/// Returns 0 if an error occurs.
///
/// getvariableofnpc(<variable>, "<npc name>") -> <reference>
-BUILDIN(getvariableofnpc)
+static BUILDIN(getvariableofnpc)
{
struct script_data* data;
const char* name;
@@ -17639,7 +20645,7 @@ BUILDIN(getvariableofnpc)
return true;
}
-BUILDIN(getvariableofpc)
+static BUILDIN(getvariableofpc)
{
const char* name;
struct script_data* data = script_getdata(st, 2);
@@ -17657,7 +20663,6 @@ BUILDIN(getvariableofpc)
switch (*name)
{
- case '#':
case '$':
case '.':
case '\'':
@@ -17682,7 +20687,7 @@ BUILDIN(getvariableofpc)
}
if (!sd->regs.vars)
- sd->regs.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
+ sd->regs.vars = i64db_alloc(DB_OPT_BASE);
script->push_val(st->stack, C_NAME, reference_getuid(data), &sd->regs);
return true;
@@ -17694,7 +20699,8 @@ BUILDIN(getvariableofpc)
/// warpportal <source x>,<source y>,"<target map>",<target x>,<target y>;
///
/// @author blackhole89
-BUILDIN(warpportal) {
+static BUILDIN(warpportal)
+{
int spx;
int spy;
unsigned short map_index;
@@ -17731,7 +20737,7 @@ BUILDIN(warpportal) {
return true;
}
-BUILDIN(openmail)
+static BUILDIN(openmail)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -17742,7 +20748,7 @@ BUILDIN(openmail)
return true;
}
-BUILDIN(openauction)
+static BUILDIN(openauction)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -17758,7 +20764,8 @@ BUILDIN(openauction)
/// checkcell("<map name>",<x>,<y>,<type>) -> <bool>
///
/// @see cell_chk* constants in const.txt for the types
-BUILDIN(checkcell) {
+static BUILDIN(checkcell)
+{
int16 m = map->mapname2mapid(script_getstr(st,2));
int16 x = script_getnum(st,3);
int16 y = script_getnum(st,4);
@@ -17779,7 +20786,8 @@ BUILDIN(checkcell) {
/// setcell "<map name>",<x1>,<y1>,<x2>,<y2>,<type>,<flag>;
///
/// @see cell_* constants in const.txt for the types
-BUILDIN(setcell) {
+static BUILDIN(setcell)
+{
int16 m = map->mapname2mapid(script_getstr(st,2));
int16 x1 = script_getnum(st,3);
int16 y1 = script_getnum(st,4);
@@ -17808,7 +20816,7 @@ BUILDIN(setcell) {
/*==========================================
* Mercenary Commands
*------------------------------------------*/
-BUILDIN(mercenary_create)
+static BUILDIN(mercenary_create)
{
struct map_session_data *sd;
int class_, contract_time;
@@ -17826,7 +20834,8 @@ BUILDIN(mercenary_create)
return true;
}
-BUILDIN(mercenary_heal) {
+static BUILDIN(mercenary_heal)
+{
struct map_session_data *sd = script->rid2sd(st);
int hp, sp;
@@ -17835,11 +20844,12 @@ BUILDIN(mercenary_heal) {
hp = script_getnum(st,2);
sp = script_getnum(st,3);
- status->heal(&sd->md->bl, hp, sp, 0);
+ status->heal(&sd->md->bl, hp, sp, STATUS_HEAL_DEFAULT);
return true;
}
-BUILDIN(mercenary_sc_start) {
+static BUILDIN(mercenary_sc_start)
+{
struct map_session_data *sd = script->rid2sd(st);
enum sc_type type;
int tick, val1;
@@ -17855,7 +20865,8 @@ BUILDIN(mercenary_sc_start) {
return true;
}
-BUILDIN(mercenary_get_calls) {
+static BUILDIN(mercenary_get_calls)
+{
struct map_session_data *sd = script->rid2sd(st);
int guild_id;
@@ -17881,7 +20892,8 @@ BUILDIN(mercenary_get_calls) {
return true;
}
-BUILDIN(mercenary_set_calls) {
+static BUILDIN(mercenary_set_calls)
+{
struct map_session_data *sd = script->rid2sd(st);
int guild_id, value, *calls;
@@ -17911,7 +20923,8 @@ BUILDIN(mercenary_set_calls) {
return true;
}
-BUILDIN(mercenary_get_faith) {
+static BUILDIN(mercenary_get_faith)
+{
struct map_session_data *sd = script->rid2sd(st);
int guild_id;
@@ -17937,7 +20950,8 @@ BUILDIN(mercenary_get_faith) {
return true;
}
-BUILDIN(mercenary_set_faith) {
+static BUILDIN(mercenary_set_faith)
+{
struct map_session_data *sd = script->rid2sd(st);
int guild_id, value, *calls;
@@ -17972,7 +20986,7 @@ BUILDIN(mercenary_set_faith) {
/*------------------------------------------
* Book Reading
*------------------------------------------*/
-BUILDIN(readbook)
+static BUILDIN(readbook)
{
struct map_session_data *sd;
int book_id, page;
@@ -17991,89 +21005,215 @@ BUILDIN(readbook)
* Questlog script commands *
****************************/
-BUILDIN(questinfo)
+static BUILDIN(questinfo)
{
struct npc_data *nd = map->id2nd(st->oid);
- int quest_id, icon;
- struct questinfo qi;
+ struct questinfo qi = { 0 };
+ int icon = script_getnum(st, 2);
- if( nd == NULL || nd->bl.m == -1 )
+ if (nd == NULL)
return true;
- quest_id = script_getnum(st, 2);
- icon = script_getnum(st, 3);
-
- #if PACKETVER >= 20120410
- if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7)
- icon = 9999; // Default to nothing if icon id is invalid.
- #else
- if(icon < 0 || icon > 7)
- icon = 0;
- else
- icon = icon + 1;
- #endif
+ if (nd->bl.m == -1) {
+ ShowWarning("buildin_questinfo: questinfo cannot be set for an npc with no valid map.\n");
+ return false;
+ }
- qi.quest_id = quest_id;
- qi.icon = (unsigned char)icon;
qi.nd = nd;
-
- if (script_hasdata(st, 4)) {
- int color = script_getnum(st, 4);
+ qi.icon = quest->questinfo_validate_icon(icon);
+ if (script_hasdata(st, 3)) {
+ int color = script_getnum(st, 3);
if (color < 0 || color > 3) {
- ShowWarning("buildin_questinfo: invalid color '%d', changing to 0\n",color);
+ ShowWarning("buildin_questinfo: invalid color '%d', defaulting to 0.\n", color);
script->reportfunc(st);
color = 0;
}
qi.color = (unsigned char)color;
}
- qi.hasJob = false;
+ map->add_questinfo(nd->bl.m, &qi);
+ return true;
+}
- if (script_hasdata(st, 5)) {
- int job = script_getnum(st, 5);
+static BUILDIN(setquestinfo)
+{
+ struct npc_data *nd = map->id2nd(st->oid);
+ struct questinfo *qi = NULL;
+ uint32 type = script_getnum(st, 2);
- if (!pc->db_checkid(job)) {
- ShowError("buildin_questinfo: Nonexistant Job Class.\n");
- } else {
- qi.hasJob = true;
- qi.job = (unsigned short)job;
+ if (nd == NULL)
+ return true;
+
+ if (nd->bl.m == -1) {
+ ShowWarning("buildin_setquestinfo: questinfo cannot be set for an npc with no valid map.\n");
+ return false;
+ }
+
+ qi = &VECTOR_LAST(map->list[nd->bl.m].qi_data);
+ if (qi == NULL) {
+ ShowWarning("buildin_setquestinfo: no valide questinfo data has been found for this npc.\n");
+ return false;
+ }
+ if (qi->nd != nd) {
+ ShowWarning("buildin_setquestinfo: invalid usage, setquestinfo must be used only after questinfo.\n");
+ return false;
+ }
+ switch (type) {
+ case QINFO_JOB:
+ {
+ int jobid = script_getnum(st, 3);
+ if (!pc->db_checkid(jobid)) {
+ ShowWarning("buildin_setquestinfo: invalid job id given (%d).\n", jobid);
+ return false;
+ }
+ qi->hasJob = true;
+ qi->job = jobid;
+ break;
+ }
+ case QINFO_SEX:
+ {
+ int sex = script_getnum(st, 3);
+ if (sex != SEX_MALE && sex != SEX_FEMALE) {
+ ShowWarning("buildin_setquestinfo: unsupported sex has been given (%d).\n", sex);
+ return false;
+ }
+ qi->sex_enabled = true;
+ qi->sex = sex;
+ break;
+ }
+ case QINFO_BASE_LEVEL:
+ {
+ int min = script_getnum(st, 3);
+ int max = script_getnum(st, 4);
+ if (min > max) {
+ ShowWarning("buildin_setquestinfo: minimal level (%d) is bigger than the maximal level (%d).\n", min, max);
+ return false;
+ }
+ qi->base_level.min = min;
+ qi->base_level.max = max;
+ break;
+ }
+ case QINFO_JOB_LEVEL:
+ {
+ int min = script_getnum(st, 3);
+ int max = script_getnum(st, 4);
+ if (min > max) {
+ ShowWarning("buildin_setquestinfo: minimal level (%d) is bigger than the maximal level (%d).\n", min, max);
+ return false;
}
+ qi->job_level.min = min;
+ qi->job_level.max = max;
+ break;
}
+ case QINFO_ITEM:
+ {
+ struct questinfo_itemreq item = { 0 };
- map->add_questinfo(nd->bl.m,&qi);
+ item.nameid = script_getnum(st, 3);
+ item.min = script_hasdata(st, 4) ? script_getnum(st, 4) : 0;
+ item.max = script_hasdata(st, 5) ? script_getnum(st, 5) : 0;
+ if (itemdb->exists(item.nameid) == NULL) {
+ ShowWarning("buildin_setquestinfo: non existing item (%d) have been given.\n", item.nameid);
+ return false;
+ }
+ if (item.min > item.max) {
+ ShowWarning("buildin_setquestinfo: minimal amount (%d) is bigger than the maximal amount (%d).\n", item.min, item.max);
+ return false;
+ }
+ if (item.min < 0 || item.min > MAX_AMOUNT) {
+ ShowWarning("buildin_setquestinfo: given amount (%d) must be bigger than or equal to 0 and smaller than %d.\n", item.min, MAX_AMOUNT + 1);
+ return false;
+ }
+ if (item.max < 0 || item.max > MAX_AMOUNT) {
+ ShowWarning("buildin_setquestinfo: given amount (%d) must be bigger than or equal to 0 and smaller than %d.\n", item.max, MAX_AMOUNT + 1);
+ return false;
+ }
+ if (VECTOR_LENGTH(qi->items) == 0)
+ VECTOR_INIT(qi->items);
+ VECTOR_ENSURE(qi->items, 1, 1);
+ VECTOR_PUSH(qi->items, item);
+ break;
+ }
+ case QINFO_HOMUN_LEVEL:
+ {
+ int min = script_getnum(st, 3);
+ if (min > battle_config.hom_max_level && min > battle_config.hom_S_max_level) {
+ ShowWarning("buildin_setquestinfo: minimum homunculus level given (%d) is bigger than the max possible level.\n", min);
+ return false;
+ }
+ qi->homunculus.level = min;
+ break;
+ }
+ case QINFO_HOMUN_TYPE:
+ {
+ int hom_type = script_getnum(st, 3);
+ if (hom_type < HT_REG || hom_type > HT_S) {
+ ShowWarning("buildin_setquestinfo: invalid homunculus type (%d).\n", hom_type);
+ return false;
+ }
+ qi->homunculus_type = hom_type;
+ break;
+ }
+ case QINFO_QUEST:
+ {
+ struct questinfo_qreq quest_req = { 0 };
+ struct quest_db *quest_data = NULL;
+
+ quest_req.id = script_getnum(st, 3);
+ quest_req.state = script_getnum(st, 4);
+
+ quest_data = quest->db(quest_req.id);
+ if (quest_data == &quest->dummy) {
+ ShowWarning("buildin_setquestinfo: invalid quest given (%d).\n", quest_req.id);
+ return false;
+ }
+ if (quest_req.state < Q_INACTIVE || quest_req.state > Q_COMPLETE) {
+ ShowWarning("buildin_setquestinfo: invalid quest state given (%d).\n", quest_req.state);
+ return false;
+ }
+
+ if (VECTOR_LENGTH(qi->quest_requirement) == 0)
+ VECTOR_INIT(qi->quest_requirement);
+ VECTOR_ENSURE(qi->quest_requirement, 1, 1);
+ VECTOR_PUSH(qi->quest_requirement, quest_req);
+ break;
+ }
+ case QINFO_MERCENARY_CLASS:
+ {
+ int mer_class = script_getnum(st, 3);
+
+ if (!mercenary->class(mer_class)) {
+ ShowWarning("buildin_setquestinfo: invalid mercenary class given (%d).\n", mer_class);
+ return false;
+ }
+ qi->mercenary_class = mer_class;
+ break;
+ }
+ default:
+ ShowWarning("buildin_setquestinfo: invalid type given (%u).\n", type);
+ return false;
+ }
return true;
}
-BUILDIN(setquest)
+static BUILDIN(setquest)
{
- unsigned short i;
int quest_id;
+ unsigned int time_limit;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
quest_id = script_getnum(st, 2);
+ time_limit = script_hasdata(st, 3) ? script_getnum(st, 3) : 0;
- quest->add(sd, quest_id);
-
- // If questinfo is set, remove quest bubble once quest is set.
- for(i = 0; i < map->list[sd->bl.m].qi_count; i++) {
- struct questinfo *qi = &map->list[sd->bl.m].qi_data[i];
- if( qi->quest_id == quest_id ) {
-#if PACKETVER >= 20120410
- clif->quest_show_event(sd, &qi->nd->bl, 9999, 0);
-#else
- clif->quest_show_event(sd, &qi->nd->bl, 0, 0);
-#endif
- }
- }
-
+ quest->add(sd, quest_id, time_limit);
return true;
}
-BUILDIN(erasequest)
+static BUILDIN(erasequest)
{
struct map_session_data *sd = script->rid2sd(st);
@@ -18096,7 +21236,7 @@ BUILDIN(erasequest)
return true;
}
-BUILDIN(completequest)
+static BUILDIN(completequest)
{
struct map_session_data *sd = script->rid2sd(st);
@@ -18119,7 +21259,7 @@ BUILDIN(completequest)
return true;
}
-BUILDIN(changequest)
+static BUILDIN(changequest)
{
struct map_session_data *sd = script->rid2sd(st);
@@ -18130,7 +21270,7 @@ BUILDIN(changequest)
return true;
}
-BUILDIN(questactive)
+static BUILDIN(questactive)
{
struct map_session_data *sd = script->rid2sd(st);
int qid, i;
@@ -18156,7 +21296,7 @@ BUILDIN(questactive)
return true;
}
-BUILDIN(questprogress)
+static BUILDIN(questprogress)
{
struct map_session_data *sd = script->rid2sd(st);
enum quest_check_type type = HAVEQUEST;
@@ -18184,7 +21324,7 @@ BUILDIN(questprogress)
return true;
}
-BUILDIN(showevent)
+static BUILDIN(showevent)
{
struct map_session_data *sd = script->rid2sd(st);
struct npc_data *nd = map->id2nd(st->oid);
@@ -18203,24 +21343,89 @@ BUILDIN(showevent)
}
}
- #if PACKETVER >= 20120410
- if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7)
- icon = 9999; // Default to nothing if icon id is invalid.
- #else
- if(icon < 0 || icon > 7)
- icon = 0;
- else
- icon = icon + 1;
- #endif
+ icon = quest->questinfo_validate_icon(icon);
clif->quest_show_event(sd, &nd->bl, icon, color);
return true;
}
/*==========================================
+ * Achievement System [Smokexyz/Hercules]
+ *-----------------------------------------*/
+/**
+ * Validates an objective index for the given achievement.
+ * Can be used for any achievement type.
+ * @command achievement_progress(<ach_id>,<obj_idx>,<progress>,<incremental?>{,<char_id>});
+ * @param aid - achievement ID
+ * @param obj_idx - achievement objective index.
+ * @param progress - objective progress towards goal.
+ * @Param incremental - (boolean) true to add the progress towards the goal,
+ * false to use the progress only as a comparand.
+ * @param account_id - (optional) character ID to perform on.
+ * @return true on success, false on failure.
+ * @push 1 on success, 0 on failure.
+ */
+static BUILDIN(achievement_progress)
+{
+ struct map_session_data *sd = script->rid2sd(st);
+ int aid = script_getnum(st, 2);
+ int obj_idx = script_getnum(st, 3);
+ int progress = script_getnum(st, 4);
+ int incremental = script_getnum(st, 5);
+ int account_id = script_hasdata(st, 6) ? script_getnum(st, 6) : 0;
+ const struct achievement_data *ad = NULL;
+
+ if ((ad = achievement->get(aid)) == NULL) {
+ ShowError("buildin_achievement_progress: Invalid achievement ID %d received.\n", aid);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (obj_idx <= 0 || obj_idx > VECTOR_LENGTH(ad->objective)) {
+ ShowError("buildin_achievement_progress: Invalid objective index %d received. (min: %d, max: %d)\n", obj_idx, 0, VECTOR_LENGTH(ad->objective));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ obj_idx--; // convert to array index.
+
+ if (progress <= 0 || progress > VECTOR_INDEX(ad->objective, obj_idx).goal) {
+ ShowError("buildin_achievement_progress: Progress exceeds goal limit for achievement id %d.\n", aid);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (incremental < 0 || incremental > 1) {
+ ShowError("buildin_achievement_progress: Argument 4 expects boolean (0/1). provided value: %d\n", incremental);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (script_hasdata(st, 6)) {
+ if (account_id <= 0) {
+ ShowError("buildin_achievement_progress: Invalid Account id %d provided.\n", account_id);
+ script_pushint(st, 0);
+ return false;
+ } else if ((sd = map->id2sd(account_id)) == NULL) {
+ ShowError("buildin_achievement_progress: Account with id %d was not found.\n", account_id);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+
+ if (achievement->validate(sd, aid, obj_idx, progress, incremental ? true : false))
+ script_pushint(st, progress);
+ else
+ script_pushint(st, 0);
+
+ return true;
+}
+
+/*==========================================
* BattleGround System
*------------------------------------------*/
-BUILDIN(waitingroom2bg) {
+static BUILDIN(waitingroom2bg)
+{
struct npc_data *nd;
struct chat_data *cd;
const char *map_name, *ev = "", *dev = "";
@@ -18264,17 +21469,18 @@ BUILDIN(waitingroom2bg) {
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))
- mapreg->setreg(reference_uid(script->add_str("$@arenamembers"), i), sd->bl.id);
+ mapreg->setreg(reference_uid(script->add_variable("$@arenamembers"), i), sd->bl.id);
else
- mapreg->setreg(reference_uid(script->add_str("$@arenamembers"), i), 0);
+ mapreg->setreg(reference_uid(script->add_variable("$@arenamembers"), i), 0);
}
- mapreg->setreg(script->add_str("$@arenamembersnum"), i);
+ mapreg->setreg(script->add_variable("$@arenamembersnum"), i);
script_pushint(st,bg_id);
return true;
}
-BUILDIN(waitingroom2bg_single) {
+static BUILDIN(waitingroom2bg_single)
+{
const char* map_name;
struct npc_data *nd;
struct chat_data *cd;
@@ -18307,7 +21513,7 @@ BUILDIN(waitingroom2bg_single) {
return true;
}
-BUILDIN(bg_team_setxy)
+static BUILDIN(bg_team_setxy)
{
struct battleground_data *bgd;
int bg_id;
@@ -18321,7 +21527,7 @@ BUILDIN(bg_team_setxy)
return true;
}
-BUILDIN(bg_warp)
+static BUILDIN(bg_warp)
{
int x, y, map_index, bg_id;
const char* map_name;
@@ -18336,7 +21542,7 @@ BUILDIN(bg_warp)
return true;
}
-BUILDIN(bg_monster)
+static BUILDIN(bg_monster)
{
int class_ = 0, x = 0, y = 0, bg_id = 0;
const char *str, *mapname, *evt="";
@@ -18353,7 +21559,7 @@ BUILDIN(bg_monster)
return true;
}
-BUILDIN(bg_monster_set_team)
+static BUILDIN(bg_monster_set_team)
{
int id = script_getnum(st,2),
bg_id = script_getnum(st,3);
@@ -18372,7 +21578,7 @@ BUILDIN(bg_monster_set_team)
return true;
}
-BUILDIN(bg_leave)
+static BUILDIN(bg_leave)
{
struct map_session_data *sd = script->rid2sd(st);
if( sd == NULL || !sd->bg_id )
@@ -18382,14 +21588,14 @@ BUILDIN(bg_leave)
return true;
}
-BUILDIN(bg_destroy)
+static BUILDIN(bg_destroy)
{
int bg_id = script_getnum(st,2);
bg->team_delete(bg_id);
return true;
}
-BUILDIN(bg_getareausers)
+static BUILDIN(bg_getareausers)
{
const char *str;
int16 m, x0, y0, x1, y1;
@@ -18423,7 +21629,7 @@ BUILDIN(bg_getareausers)
return true;
}
-BUILDIN(bg_updatescore)
+static BUILDIN(bg_updatescore)
{
const char *str;
int16 m;
@@ -18439,7 +21645,7 @@ BUILDIN(bg_updatescore)
return true;
}
-BUILDIN(bg_get_data)
+static BUILDIN(bg_get_data)
{
struct battleground_data *bgd;
int bg_id = script_getnum(st,2),
@@ -18466,11 +21672,12 @@ BUILDIN(bg_get_data)
* Instancing Script Commands
*------------------------------------------*/
-BUILDIN(instance_create)
+static BUILDIN(instance_create)
{
const char *name;
int owner_id, res;
int type = IOT_PARTY;
+ struct map_session_data *sd = map->id2sd(st->rid);
name = script_getstr(st, 2);
owner_id = script_getnum(st, 3);
@@ -18483,27 +21690,48 @@ BUILDIN(instance_create)
}
res = instance->create(owner_id, name, (enum instance_owner_type) type);
- if( res == -4 ) { // Already exists
- script_pushint(st, -1);
- return true;
- } else if( res < 0 ) {
+ if (sd != NULL) {
+ switch (res) {
+ case -4: // Already exists
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_DUPLICATE, name);
+ break;
+ case -3: // No free instances
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_EXIST, name);
+ break;
+ case -2: // Invalid type
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_RIGHT, name);
+ break;
+ case -1: // Unknown
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_UNKNOWN, name);
+ break;
+ default:
+ if (res < 0)
+ ShowError("buildin_instance_create: failed to unknown reason [%d].\n", res);
+ }
+ } else {
const char *err;
- switch(res) {
- case -3: err = "No free instances"; break;
- case -2: err = "Invalid party ID"; break;
- case -1: err = "Invalid type"; break;
- default: err = "Unknown"; break;
+ switch (res) {
+ case -3:
+ err = "No free instances";
+ break;
+ case -2:
+ err = "Invalid party ID";
+ break;
+ case -1:
+ err = "Invalid type";
+ break;
+ default:
+ err = "Unknown";
+ break;
}
- ShowError("buildin_instance_create: %s [%d].\n", err, res);
- script_pushint(st, -2);
- return true;
+ if (res < 0)
+ ShowError("buildin_instance_create: %s [%d].\n", err, res);
}
-
script_pushint(st, res);
return true;
}
-BUILDIN(instance_destroy)
+static BUILDIN(instance_destroy)
{
int instance_id = -1;
@@ -18522,7 +21750,7 @@ BUILDIN(instance_destroy)
return true;
}
-BUILDIN(instance_attachmap)
+static BUILDIN(instance_attachmap)
{
const char *map_name = NULL;
int16 m;
@@ -18546,7 +21774,8 @@ BUILDIN(instance_attachmap)
return true;
}
-BUILDIN(instance_detachmap) {
+static BUILDIN(instance_detachmap)
+{
const char *str;
int16 m;
int instance_id = -1;
@@ -18567,7 +21796,7 @@ BUILDIN(instance_detachmap) {
return true;
}
-BUILDIN(instance_attach)
+static BUILDIN(instance_attach)
{
int instance_id = script_getnum(st, 2);
@@ -18578,12 +21807,13 @@ BUILDIN(instance_attach)
return true;
}
-BUILDIN(instance_id) {
+static BUILDIN(instance_id)
+{
script_pushint(st, st->instance_id);
return true;
}
-BUILDIN(instance_set_timeout)
+static BUILDIN(instance_set_timeout)
{
int progress_timeout, idle_timeout;
int instance_id = -1;
@@ -18603,7 +21833,7 @@ BUILDIN(instance_set_timeout)
return true;
}
-BUILDIN(instance_init)
+static BUILDIN(instance_init)
{
int instance_id = script_getnum(st, 2);
@@ -18621,7 +21851,7 @@ BUILDIN(instance_init)
return true;
}
-BUILDIN(instance_announce)
+static BUILDIN(instance_announce)
{
int instance_id = script_getnum(st,2);
const char *mes = script_getstr(st,3);
@@ -18652,7 +21882,7 @@ BUILDIN(instance_announce)
return true;
}
-BUILDIN(instance_npcname)
+static BUILDIN(instance_npcname)
{
const char *str;
int instance_id = -1;
@@ -18677,82 +21907,100 @@ BUILDIN(instance_npcname)
return true;
}
-BUILDIN(has_instance)
+static BUILDIN(has_instance)
{
struct map_session_data *sd;
const char *str;
int16 m;
int instance_id = -1;
+ int i = 0, j = 0;
bool type = strcmp(script->getfuncname(st),"has_instance2") == 0 ? true : false;
str = script_getstr(st, 2);
- if( (m = map->mapname2mapid(str)) < 0 ) {
- if( type )
+ if ((m = map->mapname2mapid(str)) < 0) {
+ if (type) {
script_pushint(st, -1);
- else
+ } else {
script_pushconststr(st, "");
+ }
return true;
}
- if( script_hasdata(st, 3) )
+ if (script_hasdata(st, 3))
instance_id = script_getnum(st, 3);
- else if( st->instance_id >= 0 )
+ else if (st->instance_id >= 0)
instance_id = st->instance_id;
- else if( (sd = script->rid2sd(st)) != NULL ) {
+ else if ((sd = script->rid2sd(st)) != NULL) {
struct party_data *p;
- int i = 0, j = 0;
- if( sd->instances ) {
- for( i = 0; i < sd->instances; i++ ) {
- if( sd->instance[i] >= 0 ) {
+ if (sd->instances) {
+ for (i = 0; i < sd->instances; i++) {
+ if (sd->instance[i] >= 0) {
ARR_FIND(0, instance->list[sd->instance[i]].num_map, j, map->list[instance->list[sd->instance[i]].map[j]].instance_src_map == m);
- if( j != instance->list[sd->instance[i]].num_map )
+ if (j != instance->list[sd->instance[i]].num_map)
break;
}
}
- if( i != sd->instances )
+ if (i != sd->instances) {
instance_id = sd->instance[i];
+ }
}
if (instance_id == -1 && sd->status.party_id && (p = party->search(sd->status.party_id)) != NULL && p->instances) {
- for( i = 0; i < p->instances; i++ ) {
- if( p->instance[i] >= 0 ) {
+ for (i = 0; i < p->instances; i++) {
+ if (p->instance[i] >= 0) {
ARR_FIND(0, instance->list[p->instance[i]].num_map, j, map->list[instance->list[p->instance[i]].map[j]].instance_src_map == m);
- if( j != instance->list[p->instance[i]].num_map )
+ if (j != instance->list[p->instance[i]].num_map)
break;
}
}
- if( i != p->instances )
+ if (i != p->instances) {
instance_id = p->instance[i];
+ }
}
- if( instance_id == -1 && sd->guild && sd->guild->instances ) {
- for( i = 0; i < sd->guild->instances; i++ ) {
- if( sd->guild->instance[i] >= 0 ) {
+ if (instance_id == -1 && sd->guild && sd->guild->instances) {
+ for (i = 0; i < sd->guild->instances; i++) {
+ if (sd->guild->instance[i] >= 0) {
ARR_FIND(0, instance->list[sd->guild->instance[i]].num_map, j, map->list[instance->list[sd->guild->instance[i]].map[j]].instance_src_map == m);
- if( j != instance->list[sd->guild->instance[i]].num_map )
+ if (j != instance->list[sd->guild->instance[i]].num_map)
break;
}
}
- if( i != sd->guild->instances )
+ if (i != sd->guild->instances)
instance_id = sd->guild->instance[i];
}
}
- if( !instance->valid(instance_id) || (m = instance->map2imap(m, instance_id)) < 0 ) {
- if( type )
+ if (instance_id == -1) {
+ for (i = 0; i < instance->instances; i++) {
+ if (instance->list[i].state != INSTANCE_FREE && instance->list[i].owner_type == IOT_NONE && instance->list[i].num_map > 0) {
+ ARR_FIND(0, instance->list[i].num_map, j, map->list[instance->list[i].map[j]].instance_src_map == m);
+ if (j != instance->list[i].num_map)
+ break;
+ }
+ }
+ if (i != instance->instances) {
+ instance_id = instance->list[i].id;
+ }
+ }
+
+ if (!instance->valid(instance_id) || (m = instance->map2imap(m, instance_id)) < 0) {
+ if (type) {
script_pushint(st, -1);
- else
+ } else {
script_pushconststr(st, "");
+ }
return true;
}
- if( type )
+ if (type) {
script_pushint(st, instance_id);
- else
+ } else {
script_pushconststr(st, map->list[m].name);
+ }
return true;
}
-int buildin_instance_warpall_sub(struct block_list *bl, va_list ap)
+static int buildin_instance_warpall_sub(struct block_list *bl, va_list ap)
{
struct map_session_data *sd = NULL;
int map_index = va_arg(ap,int);
@@ -18768,7 +22016,7 @@ int buildin_instance_warpall_sub(struct block_list *bl, va_list ap)
return 0;
}
-BUILDIN(instance_warpall)
+static BUILDIN(instance_warpall)
{
int16 m;
int instance_id = -1;
@@ -18807,7 +22055,7 @@ BUILDIN(instance_warpall)
* Example: instance_check_party (getcharid(1){,amount}{,min}{,max});
* Example 2: instance_check_party (getcharid(1),1,1,99);
*------------------------------------------*/
-BUILDIN(instance_check_party)
+static BUILDIN(instance_check_party)
{
int amount, min, max, i, party_id, c = 0;
struct party_data *p = NULL;
@@ -18866,7 +22114,7 @@ BUILDIN(instance_check_party)
* Example: instance_check_guild (getcharid(2){,amount}{,min}{,max});
* Example 2: instance_check_guild (getcharid(2),1,1,99);
*------------------------------------------*/
-BUILDIN(instance_check_guild)
+static BUILDIN(instance_check_guild)
{
int amount, min, max, i, guild_id, c = 0;
struct guild *g = NULL;
@@ -18918,7 +22166,7 @@ BUILDIN(instance_check_guild)
/*==========================================
* Custom Fonts
*------------------------------------------*/
-BUILDIN(setfont)
+static BUILDIN(setfont)
{
struct map_session_data *sd = script->rid2sd(st);
int font = script_getnum(st,2);
@@ -18934,7 +22182,7 @@ BUILDIN(setfont)
return true;
}
-int buildin_mobuseskill_sub(struct block_list *bl, va_list ap)
+static int buildin_mobuseskill_sub(struct block_list *bl, va_list ap)
{
struct mob_data *md = NULL;
struct block_list *tbl;
@@ -18981,7 +22229,7 @@ int buildin_mobuseskill_sub(struct block_list *bl, va_list ap)
/*==========================================
* areamobuseskill "Map Name",<x>,<y>,<range>,<Mob ID>,"Skill Name"/<Skill ID>,<Skill Lv>,<Cast Time>,<Cancelable>,<Emotion>,<Target Type>;
*------------------------------------------*/
-BUILDIN(areamobuseskill)
+static BUILDIN(areamobuseskill)
{
struct block_list center;
int16 m;
@@ -19011,7 +22259,7 @@ BUILDIN(areamobuseskill)
return true;
}
-BUILDIN(progressbar)
+static BUILDIN(progressbar)
{
struct map_session_data * sd = script->rid2sd(st);
const char * color;
@@ -19032,8 +22280,30 @@ BUILDIN(progressbar)
clif->progressbar(sd, (unsigned int)strtoul(color, (char **)NULL, 0), second);
return true;
}
+static BUILDIN(progressbar_unit)
+{
+ const char *color = script_getstr(st, 2);
+ uint32 second = script_getnum(st, 3);
+
+ if (script_hasdata(st, 4)) {
+ struct block_list *bl = map->id2bl(script_getnum(st, 4));
-BUILDIN(pushpc)
+ if (bl == NULL) {
+ ShowWarning("buildin_progressbar_unit: Error in finding object with given GID %d!\n", script_getnum(st, 4));
+ return true;
+ }
+ clif->progressbar_unit(bl, (unsigned int)strtoul(color, (char **)NULL, 0), second);
+ } else {
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd == NULL)
+ return false;
+
+ clif->progressbar_unit(&sd->bl, (unsigned int)strtoul(color, (char **)NULL, 0), second);
+ }
+ return true;
+}
+static BUILDIN(pushpc)
{
uint8 dir;
int cells, dx, dy;
@@ -19073,7 +22343,7 @@ BUILDIN(pushpc)
/// Invokes buying store preparation window
/// buyingstore <slots>;
-BUILDIN(buyingstore)
+static BUILDIN(buyingstore)
{
struct map_session_data* sd;
@@ -19087,7 +22357,7 @@ BUILDIN(buyingstore)
/// Invokes search store info window
/// searchstores <uses>,<effect>;
-BUILDIN(searchstores)
+static BUILDIN(searchstores)
{
unsigned short effect;
unsigned int uses;
@@ -19118,7 +22388,7 @@ BUILDIN(searchstores)
}
/// Displays a number as large digital clock.
/// showdigit <value>[,<type>];
-BUILDIN(showdigit)
+static BUILDIN(showdigit)
{
unsigned int type = 0;
int value;
@@ -19148,7 +22418,7 @@ BUILDIN(showdigit)
/**
* Rune Knight
**/
-BUILDIN(makerune)
+static BUILDIN(makerune)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -19161,15 +22431,19 @@ BUILDIN(makerune)
/**
* hascashmount() returns 1 if mounting a cash mount or 0 otherwise
**/
-BUILDIN(hascashmount)
+static BUILDIN(hascashmount)
{
struct map_session_data *sd = script->rid2sd(st);
+
if (sd == NULL)
return true;
- if( sd->sc.data[SC_ALL_RIDING] )
- script_pushint(st,1);
- else
- script_pushint(st,0);
+
+ if (sd->sc.data[SC_ALL_RIDING]) {
+ script_pushint(st, 1);
+ } else {
+ script_pushint(st, 0);
+ }
+
return true;
}
@@ -19180,21 +22454,27 @@ BUILDIN(hascashmount)
* - Will fail if the player is already riding a standard mount e.g. dragon, peco, wug, mado, etc.
* - Will unmount the player is he is already mounting a cash mount
**/
-BUILDIN(setcashmount)
+static BUILDIN(setcashmount)
{
struct map_session_data *sd = script->rid2sd(st);
+
if (sd == NULL)
return true;
+
if (pc_hasmount(sd)) {
- clif->msgtable(sd, MSG_REINS_CANT_USE_MOUNTED);
- script_pushint(st,0);//can't mount with one of these
+#if PACKETVER >= 20110531
+ clif->msgtable(sd, MSG_FAIELD_RIDING_OVERLAPPED);
+#endif
+ script_pushint(st, 0); // Can't mount with one of these
} else {
- if (sd->sc.data[SC_ALL_RIDING])
+ if (sd->sc.data[SC_ALL_RIDING]) {
status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER);
- else
- sc_start(NULL, &sd->bl, SC_ALL_RIDING, 100, 25, INFINITE_DURATION);
- script_pushint(st,1);//in both cases, return 1.
+ } else {
+ sc_start(NULL, &sd->bl, SC_ALL_RIDING, 100, battle_config.boarding_halter_speed, INFINITE_DURATION);
+ }
+ script_pushint(st, 1); // In both cases, return 1.
}
+
return true;
}
@@ -19202,7 +22482,7 @@ BUILDIN(setcashmount)
* Retrieves quantity of arguments provided to callfunc/callsub.
* getargcount() -> amount of arguments received in a function
**/
-BUILDIN(getargcount)
+static BUILDIN(getargcount)
{
struct script_retinfo* ri;
@@ -19221,7 +22501,7 @@ BUILDIN(getargcount)
/**
* getcharip(<account ID>/<character ID>/<character name>)
**/
-BUILDIN(getcharip)
+static BUILDIN(getcharip)
{
struct map_session_data* sd = NULL;
@@ -19256,25 +22536,59 @@ BUILDIN(getcharip)
return true;
}
+enum function_type {
+ FUNCTION_IS_NONE = 0,
+ FUNCTION_IS_COMMAND,
+ FUNCTION_IS_GLOBAL,
+ FUNCTION_IS_LOCAL,
+ FUNCTION_IS_LABEL,
+};
+
/**
- * is_function(<function name>) -> 1 if function exists, 0 otherwise
+ * is_function(<function name>)
**/
-BUILDIN(is_function)
+static BUILDIN(is_function)
{
- const char* str = script_getstr(st,2);
+ const char *str = script_getstr(st, 2);
+ enum function_type type = FUNCTION_IS_NONE;
- if( strdb_exists(script->userfunc_db, str) )
- script_pushint(st,1);
- else
- script_pushint(st,0);
+ // TODO: add support for exported functions (#2142)
+ if (strdb_exists(script->userfunc_db, str)) {
+ type = FUNCTION_IS_GLOBAL;
+ } else {
+ int n = script->search_str(str);
+
+ if (n >= 0) {
+ switch (script->str_data[n].type) {
+ case C_FUNC:
+ type = FUNCTION_IS_COMMAND;
+ break;
+ case C_USERFUNC:
+ case C_USERFUNC_POS:
+ type = FUNCTION_IS_LOCAL;
+ break;
+ case C_POS:
+ type = FUNCTION_IS_LABEL;
+ break;
+ case C_NAME:
+ if (script->str_data[n].label >= 0) {
+ // WTF... ?
+ // for some reason local functions can have type C_NAME
+ type = FUNCTION_IS_LOCAL;
+ }
+ }
+ }
+ }
+
+ script_pushint(st, type);
return true;
}
/**
* freeloop(<toggle>) -> toggles this script instance's looping-check ability
**/
-BUILDIN(freeloop)
+static BUILDIN(freeloop)
{
if( script_getnum(st,2) )
st->freeloop = 1;
@@ -19286,7 +22600,7 @@ BUILDIN(freeloop)
return true;
}
-BUILDIN(sit)
+static BUILDIN(sit)
{
struct map_session_data *sd = NULL;
@@ -19307,7 +22621,7 @@ BUILDIN(sit)
return true;
}
-BUILDIN(stand)
+static BUILDIN(stand)
{
struct map_session_data *sd = NULL;
@@ -19328,7 +22642,7 @@ BUILDIN(stand)
return true;
}
-BUILDIN(issit)
+static BUILDIN(issit)
{
struct map_session_data *sd = NULL;
@@ -19347,10 +22661,47 @@ BUILDIN(issit)
return true;
}
+static BUILDIN(add_group_command)
+{
+ AtCommandInfo *acmd_d;
+ struct atcmd_binding_data *bcmd_d;
+ GroupSettings *group;
+ int group_index;
+ const char *atcmd = script_getstr(st, 2);
+ int group_id = script_getnum(st, 3);
+ bool self_perm = (script_getnum(st, 4) == 1);
+ bool char_perm = (script_getnum(st, 5) == 1);
+
+ if (!pcg->exists(group_id)) {
+ ShowWarning("script:add_group_command: group does not exist: %i\n", group_id);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ group = pcg->id2group(group_id);
+ group_index = pcg->get_idx(group);
+
+ if ((bcmd_d = atcommand->get_bind_byname(atcmd)) != NULL) {
+ bcmd_d->at_groups[group_index] = self_perm;
+ bcmd_d->char_groups[group_index] = char_perm;
+ script_pushint(st, 1);
+ return true;
+ } else if ((acmd_d = atcommand->get_info_byname(atcmd)) != NULL) {
+ acmd_d->at_groups[group_index] = self_perm;
+ acmd_d->char_groups[group_index] = char_perm;
+ script_pushint(st, 1);
+ return true;
+ }
+
+ ShowWarning("script:add_group_command: command does not exist: %s\n", atcmd);
+ script_pushint(st, 0);
+ return false;
+}
+
/**
* @commands (script based)
**/
-BUILDIN(bindatcmd)
+static BUILDIN(bindatcmd)
{
const char* atcmd;
const char* eventName;
@@ -19396,12 +22747,14 @@ BUILDIN(bindatcmd)
atcommand->binding[i]->group_lv = group_lv;
atcommand->binding[i]->group_lv_char = group_lv_char;
atcommand->binding[i]->log = log;
+ CREATE(atcommand->binding[i]->at_groups, char, db_size(pcg->db));
+ CREATE(atcommand->binding[i]->char_groups, char, db_size(pcg->db));
}
return true;
}
-BUILDIN(unbindatcmd)
+static BUILDIN(unbindatcmd)
{
const char* atcmd;
int i = 0;
@@ -19419,6 +22772,8 @@ BUILDIN(unbindatcmd)
ARR_FIND(0, atcommand->binding_count, i, strcmp(atcommand->binding[i]->command, atcmd) == 0);
if( i < atcommand->binding_count ) {
int cursor = 0;
+ aFree(atcommand->binding[i]->at_groups);
+ aFree(atcommand->binding[i]->char_groups);
aFree(atcommand->binding[i]);
atcommand->binding[i] = NULL;
/* compact the list now that we freed a slot somewhere */
@@ -19443,7 +22798,7 @@ BUILDIN(unbindatcmd)
return true;
}
-BUILDIN(useatcmd)
+static BUILDIN(useatcmd)
{
struct map_session_data *sd, *dummy_sd = NULL;
int fd;
@@ -19481,8 +22836,69 @@ BUILDIN(useatcmd)
return true;
}
+static BUILDIN(has_permission)
+{
+ struct map_session_data *sd;
+ enum e_pc_permission perm;
+
+ if (script_hasdata(st, 3)) {
+ sd = map->id2sd(script_getnum(st, 3));
+ } else {
+ sd = script->rid2sd(st);
+ }
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (script_isstringtype(st, 2)) {
+ // to check for plugin permissions
+ int i = 0, j = -1;
+ const char *name = script_getstr(st, 2);
+ for (; i < pcg->permission_count; ++i) {
+ if (strcmp(pcg->permissions[i].name, name) == 0) {
+ j = i;
+ break;
+ }
+ }
+ if (j < 0) {
+ ShowError("script:has_permission: unknown permission: %s\n", name);
+ script_pushint(st, 0);
+ return false;
+ }
+ script_pushint(st, pc_has_permission(sd, pcg->permissions[j].permission));
+ return true;
+ }
+
+ // to ckeck for built-in permission
+ perm = script_getnum(st, 2);
+ script_pushint(st, pc_has_permission(sd, perm));
+ return true;
+}
+
+static BUILDIN(can_use_command)
+{
+ struct map_session_data *sd;
+ const char *cmd = script_getstr(st, 2);
+
+ if (script_hasdata(st, 3)) {
+ sd = map->id2sd(script_getnum(st, 3));
+ } else {
+ sd = script->rid2sd(st);
+ }
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ return false;
+ }
+
+ script_pushint(st, pc->can_use_command(sd, cmd));
+ return true;
+}
+
/* getrandgroupitem <container_item_id>,<quantity> */
-BUILDIN(getrandgroupitem)
+static BUILDIN(getrandgroupitem)
{
struct item_data *data = NULL;
struct map_session_data *sd = NULL;
@@ -19523,7 +22939,7 @@ BUILDIN(getrandgroupitem)
if ((flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT))) {
clif->additem(sd, 0, 0, flag);
if( pc->candrop(sd,&it) )
- map->addflooritem(&sd->bl, &it, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
+ map->addflooritem(&sd->bl, &it, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
}
}
}
@@ -19536,14 +22952,14 @@ BUILDIN(getrandgroupitem)
/* cleanmap <map_name>;
* cleanarea <map_name>, <x0>, <y0>, <x1>, <y1>; */
-int script_cleanfloor_sub(struct block_list *bl, va_list ap)
+static int script_cleanfloor_sub(struct block_list *bl, va_list ap)
{
map->clearflooritem(bl);
return 0;
}
-BUILDIN(cleanmap)
+static BUILDIN(cleanmap)
{
const char *mapname = script_getstr(st, 2);
int16 m = map->mapname2mapid(mapname);
@@ -19572,7 +22988,7 @@ BUILDIN(cleanmap)
/* Cast a skill on the attached player.
* npcskill <skill id>, <skill lvl>, <stat point>, <NPC level>;
* npcskill "<skill name>", <skill lvl>, <stat point>, <NPC level>; */
-BUILDIN(npcskill)
+static BUILDIN(npcskill)
{
struct npc_data *nd;
uint16 skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2);
@@ -19618,7 +23034,7 @@ BUILDIN(npcskill)
/* Turns a player into a monster and grants SC attribute effect. [malufett/Hercules]
* montransform <monster name/id>, <duration>, <sc type>, <val1>, <val2>, <val3>, <val4>; */
-BUILDIN(montransform)
+static BUILDIN(montransform)
{
int tick;
enum sc_type type;
@@ -19702,7 +23118,7 @@ BUILDIN(montransform)
*
* @return The queue, or NULL if it doesn't exist.
*/
-struct script_queue *script_hqueue_get(int idx)
+static struct script_queue *script_hqueue_get(int idx)
{
if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid)
return NULL;
@@ -19714,7 +23130,7 @@ struct script_queue *script_hqueue_get(int idx)
*
* @return The index of the created queue.
*/
-int script_hqueue_create(void)
+static int script_hqueue_create(void)
{
struct script_queue *queue = NULL;
int i;
@@ -19741,7 +23157,7 @@ int script_hqueue_create(void)
* .@queue_id = queue();
* @endcode
*/
-BUILDIN(queue)
+static BUILDIN(queue)
{
script_pushint(st,script->queue_create());
return true;
@@ -19756,7 +23172,7 @@ BUILDIN(queue)
* .@size = queuesize(<queue id>);
* \endcode
*/
-BUILDIN(queuesize)
+static BUILDIN(queuesize)
{
int idx = script_getnum(st, 2);
@@ -19778,7 +23194,7 @@ BUILDIN(queuesize)
* @retval false if the queue is invalid or the entry is already in the queue.
* @retval true in case of success.
*/
-bool script_hqueue_add(int idx, int var)
+static bool script_hqueue_add(int idx, int var)
{
int i;
struct map_session_data *sd = NULL;
@@ -19816,7 +23232,7 @@ bool script_hqueue_add(int idx, int var)
* .@size = queuesize(.@queue_id);
* @endcode
*/
-BUILDIN(queueadd)
+static BUILDIN(queueadd)
{
int idx = script_getnum(st, 2);
int var = script_getnum(st, 3);
@@ -19837,7 +23253,7 @@ BUILDIN(queueadd)
* @retval true if the entry was removed.
* @retval false if the entry wasn't in queue.
*/
-bool script_hqueue_remove(int idx, int var)
+static bool script_hqueue_remove(int idx, int var)
{
int i;
struct map_session_data *sd = NULL;
@@ -19874,7 +23290,7 @@ bool script_hqueue_remove(int idx, int var)
* queueremove(.@queue_id, .@value);
* @endcode
*/
-BUILDIN(queueremove)
+static BUILDIN(queueremove)
{
int idx = script_getnum(st, 2);
int var = script_getnum(st, 3);
@@ -19890,7 +23306,7 @@ BUILDIN(queueremove)
/**
* Script command queueopt: Modifies the options of a queue.
*
- * When the option value isn't provided, the option is removed.
+ * When the <event label> isn't provided, the option is removed.
*
* Returns 1 (true) on success, 0 (false) on failure.
*
@@ -19900,13 +23316,13 @@ BUILDIN(queueremove)
* - QUEUEOPT_MAPCHANGE
*
* When the QUEUEOPT_MAPCHANGE event is triggered, it sets a temporary
- * character variable \c @Queue_Destination_Map$ with the destination map name.
+ * character variable @Queue_Destination_Map$ with the destination map name.
*
* @code{.herc}
- * queueopt(.@queue_id, optionType, <optional val>);
+ * queueopt(.@queue_id, optionType{, <event label>});
* @endcode
*/
-BUILDIN(queueopt)
+static BUILDIN(queueopt)
{
int idx = script_getnum(st, 2);
int var = script_getnum(st, 3);
@@ -19956,7 +23372,7 @@ BUILDIN(queueopt)
* @retval true if the queue was correctly deleted.
* @retval false if the queue didn't exist.
*/
-bool script_hqueue_del(int idx)
+static bool script_hqueue_del(int idx)
{
if (!script->queue_clear(idx))
return false;
@@ -19975,7 +23391,7 @@ bool script_hqueue_del(int idx)
* queuedel(.@queue_id);
* @endcode
*/
-BUILDIN(queuedel)
+static BUILDIN(queuedel)
{
int idx = script_getnum(st, 2);
@@ -19995,7 +23411,7 @@ BUILDIN(queuedel)
* @retval true if the queue was correctly cleared.
* @retval false if the queue didn't exist.
*/
-bool script_hqueue_clear(int idx)
+static bool script_hqueue_clear(int idx)
{
struct script_queue *queue = NULL;
@@ -20032,7 +23448,7 @@ bool script_hqueue_clear(int idx)
* .@id = queueiterator(.@queue_id);
* @endcode
*/
-BUILDIN(queueiterator)
+static BUILDIN(queueiterator)
{
int qid = script_getnum(st, 2);
struct script_queue *queue = NULL;
@@ -20075,7 +23491,7 @@ BUILDIN(queueiterator)
* }
* @endcode
*/
-BUILDIN(qiget)
+static BUILDIN(qiget)
{
int idx = script_getnum(st, 2);
struct script_queue_iterator *it = NULL;
@@ -20109,7 +23525,7 @@ BUILDIN(qiget)
* }
* @endcode
*/
-BUILDIN(qicheck)
+static BUILDIN(qicheck)
{
int idx = script_getnum(st, 2);
struct script_queue_iterator *it = NULL;
@@ -20140,7 +23556,7 @@ BUILDIN(qicheck)
* qiclear(.@iter);
* @endcode
*/
-BUILDIN(qiclear)
+static BUILDIN(qiclear)
{
int idx = script_getnum(st, 2);
struct script_queue_iterator *it = NULL;
@@ -20165,7 +23581,8 @@ BUILDIN(qiclear)
* packageitem({<optional container_item_id>})
* when no item id is provided it tries to assume it comes from the current item id being processed (if any)
**/
-BUILDIN(packageitem) {
+static BUILDIN(packageitem)
+{
struct item_data *data = NULL;
struct map_session_data *sd = NULL;
int nameid;
@@ -20199,7 +23616,8 @@ BUILDIN(packageitem) {
/* New Battlegrounds Stuff */
/* bg_team_create(map_name,respawn_x,respawn_y) */
/* returns created team id or -1 when fails */
-BUILDIN(bg_create_team) {
+static BUILDIN(bg_create_team)
+{
const char *map_name, *ev = "", *dev = "";//ev and dev will be dropped.
int x, y, map_index = 0, bg_id;
@@ -20226,7 +23644,8 @@ BUILDIN(bg_create_team) {
/* bg_join_team(team_id{,optional account id}) */
/* when account id is not present it tries to autodetect from the attached player (if any) */
/* returns 0 when successful, 1 otherwise */
-BUILDIN(bg_join_team) {
+static BUILDIN(bg_join_team)
+{
struct map_session_data *sd;
int team_id = script_getnum(st, 2);
@@ -20252,9 +23671,9 @@ BUILDIN(bg_join_team) {
* 3 - Party Bound
* 4 - Character Bound
*------------------------------------------*/
-BUILDIN(countbound)
+static BUILDIN(countbound)
{
- int i, type, j=0, k=0;
+ int type, j=0, k=0;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
@@ -20262,12 +23681,12 @@ BUILDIN(countbound)
type = script_hasdata(st,2)?script_getnum(st,2):0;
- for(i=0;i<MAX_INVENTORY;i++) {
+ for (int i = 0; i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid > 0 && (
(!type && sd->status.inventory[i].bound > 0) ||
(type && sd->status.inventory[i].bound == type)
)) {
- pc->setreg(sd,reference_uid(script->add_str("@bound_items"), k),sd->status.inventory[i].nameid);
+ pc->setreg(sd,reference_uid(script->add_variable("@bound_items"), k),sd->status.inventory[i].nameid);
k++;
j += sd->status.inventory[i].amount;
}
@@ -20287,7 +23706,7 @@ BUILDIN(countbound)
* 3 - Party Bound
* 4 - Character Bound
*------------------------------------------*/
-BUILDIN(checkbound)
+static BUILDIN(checkbound)
{
int i, nameid = script_getnum(st,2);
int bound_type = 0;
@@ -20308,27 +23727,28 @@ BUILDIN(checkbound)
ShowError("script_checkbound: Not a valid bind type! Type=%d\n", bound_type);
}
- ARR_FIND( 0, MAX_INVENTORY, i, (sd->status.inventory[i].nameid == nameid &&
+ ARR_FIND(0, sd->status.inventorySize, i, (sd->status.inventory[i].nameid == nameid &&
( sd->status.inventory[i].refine == (script_hasdata(st,4)? script_getnum(st,4) : sd->status.inventory[i].refine) ) &&
( sd->status.inventory[i].attribute == (script_hasdata(st,5)? script_getnum(st,5) : sd->status.inventory[i].attribute) ) &&
( sd->status.inventory[i].card[0] == (script_hasdata(st,6)? script_getnum(st,6) : sd->status.inventory[i].card[0]) ) &&
( sd->status.inventory[i].card[1] == (script_hasdata(st,7)? script_getnum(st,7) : sd->status.inventory[i].card[1]) ) &&
( sd->status.inventory[i].card[2] == (script_hasdata(st,8)? script_getnum(st,8) : sd->status.inventory[i].card[2]) ) &&
( sd->status.inventory[i].card[3] == (script_hasdata(st,9)? script_getnum(st,9) : sd->status.inventory[i].card[3]) ) &&
- ((sd->status.inventory[i].bound > 0 && !bound_type) || sd->status.inventory[i].bound == bound_type )) );
+ ((sd->status.inventory[i].bound > 0 && !bound_type) || sd->status.inventory[i].bound == bound_type)));
- if( i < MAX_INVENTORY ){
+ if (i < sd->status.inventorySize) {
script_pushint(st, sd->status.inventory[i].bound);
return true;
- } else
+ } else {
script_pushint(st,0);
+ }
return true;
}
/* bg_match_over( arena_name {, optional canceled } ) */
/* returns 0 when successful, 1 otherwise */
-BUILDIN(bg_match_over)
+static BUILDIN(bg_match_over)
{
bool canceled = script_hasdata(st,3) ? true : false;
struct bg_arena *arena = bg->name2arena(script_getstr(st, 2));
@@ -20342,7 +23762,7 @@ BUILDIN(bg_match_over)
return true;
}
-BUILDIN(instance_mapname)
+static BUILDIN(instance_mapname)
{
const char *map_name;
int m;
@@ -20367,7 +23787,7 @@ BUILDIN(instance_mapname)
/* modify an instances' reload-spawn point */
/* instance_set_respawn <map_name>,<x>,<y>{,<instance_id>} */
/* returns 1 when successful, 0 otherwise. */
-BUILDIN(instance_set_respawn)
+static BUILDIN(instance_set_respawn)
{
const char *map_name;
short instance_id = -1;
@@ -20415,7 +23835,7 @@ BUILDIN(instance_set_respawn)
*
* @return 1 on success, 0 otherwise.
**/
-BUILDIN(openshop)
+static BUILDIN(openshop)
{
struct npc_data *nd;
struct map_session_data *sd;
@@ -20452,12 +23872,13 @@ BUILDIN(openshop)
* adds <Item_ID> (or modifies if present) to shop
* if price not provided (or -1) uses the item's value_sell
**/
-BUILDIN(sellitem)
+static BUILDIN(sellitem)
{
struct npc_data *nd;
struct item_data *it;
int i = 0, id = script_getnum(st,2);
int value = 0;
+ int value2 = 0;
int qty = 0;
if( !(nd = map->id2nd(st->oid)) ) {
@@ -20468,17 +23889,43 @@ BUILDIN(sellitem)
return false;
}
- value = script_hasdata(st,3) ? script_getnum(st, 3) : it->value_buy;
- if( value == -1 )
- value = it->value_buy;
-
- if( !nd->u.scr.shop )
- npc->trader_update(nd->src_id?nd->src_id:nd->bl.id);
- else {/* no need to run this if its empty */
- for( i = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == id )
- break;
+ if (!nd->u.scr.shop) {
+ npc->trader_update(nd->src_id ? nd->src_id : nd->bl.id);
+ if (nd->u.scr.shop->type == NST_BARTER) {
+ if (!script_hasdata(st, 5)) {
+ ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n");
+ return false;
+ }
+ value = script_getnum(st, 4);
+ value2 = script_getnum(st, 5);
}
+ } else {/* no need to run this if its empty */
+ if (nd->u.scr.shop->type == NST_BARTER) {
+ if (!script_hasdata(st, 5)) {
+ ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n");
+ return false;
+ }
+ value = script_getnum(st, 4);
+ value2 = script_getnum(st, 5);
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ const struct npc_item_list *const item = &nd->u.scr.shop->item[i];
+ if (item->nameid == id && item->value == value && item->value2 == value2) {
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == id) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (nd->u.scr.shop->type != NST_BARTER) {
+ value = script_hasdata(st,3) ? script_getnum(st, 3) : it->value_buy;
+ if( value == -1 )
+ value = it->value_buy;
}
if( nd->u.scr.shop->type == NST_MARKET ) {
@@ -20493,19 +23940,29 @@ BUILDIN(sellitem)
it->name, id, value, (int)(value*0.75), it->value_sell, (int)(it->value_sell*1.24), nd->exname, nd->path);
}
- if( i != nd->u.scr.shop->items ) {
+ if (nd->u.scr.shop->type == NST_BARTER) {
+ qty = script_getnum(st, 3);
+ if (qty < -1 || value <= 0 || value2 <= 0) {
+ ShowError("buildin_sellitem: invalid parameters for barter-type shop!\n");
+ return false;
+ }
+ }
+
+ if (i != nd->u.scr.shop->items) {
nd->u.scr.shop->item[i].value = value;
nd->u.scr.shop->item[i].qty = qty;
- if( nd->u.scr.shop->type == NST_MARKET ) /* has been manually updated, make it reflect on sql */
- npc->market_tosql(nd,i);
+ if (nd->u.scr.shop->type == NST_MARKET) /* has been manually updated, make it reflect on sql */
+ npc->market_tosql(nd, i);
+ else if (nd->u.scr.shop->type == NST_BARTER) /* has been manually updated, make it reflect on sql */
+ npc->barter_tosql(nd, i);
} else {
- for( i = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == 0 )
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == 0)
break;
}
- if( i == nd->u.scr.shop->items ) {
- if( nd->u.scr.shop->items == USHRT_MAX ) {
+ if (i == nd->u.scr.shop->items) {
+ if (nd->u.scr.shop->items == USHRT_MAX) {
ShowWarning("buildin_sellitem: Can't add %s (%s/%s), shop list is full!\n", it->name, nd->exname, nd->path);
return false;
}
@@ -20515,6 +23972,7 @@ BUILDIN(sellitem)
nd->u.scr.shop->item[i].nameid = it->nameid;
nd->u.scr.shop->item[i].value = value;
+ nd->u.scr.shop->item[i].value2 = value2;
nd->u.scr.shop->item[i].qty = qty;
}
@@ -20528,38 +23986,58 @@ BUILDIN(sellitem)
*
* @return 1 on success, 0 otherwise
**/
-BUILDIN(stopselling)
+static BUILDIN(stopselling)
{
struct npc_data *nd;
- int i, id = script_getnum(st,2);
+ int i, id = script_getnum(st, 2);
- if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) {
+ if (!(nd = map->id2nd(st->oid)) || !nd->u.scr.shop) {
ShowWarning("buildin_stopselling: trying to run without a proper NPC!\n");
return false;
}
- for( i = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == id )
- break;
+ if (nd->u.scr.shop->type == NST_BARTER) {
+ if (!script_hasdata(st, 4)) {
+ ShowError("buildin_stopselling: called with wrong number of arguments\n");
+ return false;
+ }
+ const int id2 = script_getnum(st, 3);
+ const int amount2 = script_getnum(st, 4);
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ const struct npc_item_list *const item = &nd->u.scr.shop->item[i];
+ if (item->nameid == id && item->value == id2 && item->value2 == amount2) {
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == id) {
+ break;
+ }
+ }
}
- if( i != nd->u.scr.shop->items ) {
+ if (i != nd->u.scr.shop->items) {
int cursor;
- if( nd->u.scr.shop->type == NST_MARKET )
- npc->market_delfromsql(nd,i);
+ if (nd->u.scr.shop->type == NST_MARKET)
+ npc->market_delfromsql(nd, i);
+ if (nd->u.scr.shop->type == NST_BARTER)
+ npc->barter_delfromsql(nd, i);
nd->u.scr.shop->item[i].nameid = 0;
nd->u.scr.shop->item[i].value = 0;
+ nd->u.scr.shop->item[i].value2 = 0;
nd->u.scr.shop->item[i].qty = 0;
- for( i = 0, cursor = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == 0 )
+ for (i = 0, cursor = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == 0)
continue;
- if( cursor != i ) {
+ if (cursor != i) {
nd->u.scr.shop->item[cursor].nameid = nd->u.scr.shop->item[i].nameid;
nd->u.scr.shop->item[cursor].value = nd->u.scr.shop->item[i].value;
+ nd->u.scr.shop->item[cursor].value2 = nd->u.scr.shop->item[i].value2;
nd->u.scr.shop->item[cursor].qty = nd->u.scr.shop->item[i].qty;
}
@@ -20579,7 +24057,7 @@ BUILDIN(stopselling)
* updates currently-attached player shop currency
**/
/* setcurrency(<Val1>,{<Val2>}) */
-BUILDIN(setcurrency)
+static BUILDIN(setcurrency)
{
int val1 = script_getnum(st,2),
val2 = script_hasdata(st, 3) ? script_getnum(st,3) : 0;
@@ -20603,7 +24081,7 @@ BUILDIN(setcurrency)
* check enum npc_shop_types for list
* cleans shop list on use
**/
-BUILDIN(tradertype)
+static BUILDIN(tradertype)
{
int type = script_getnum(st, 2);
struct npc_data *nd;
@@ -20625,7 +24103,8 @@ BUILDIN(tradertype)
nd->u.scr.shop->item[i].value = 0;
nd->u.scr.shop->item[i].qty = 0;
}
- npc->market_delfromsql(nd,USHRT_MAX);
+ npc->market_delfromsql(nd, INT_MAX);
+ npc->barter_delfromsql(nd, INT_MAX);
}
#if PACKETVER < 20131223
@@ -20634,6 +24113,12 @@ BUILDIN(tradertype)
script->reportsrc(st);
}
#endif
+#if PACKETVER_ZERO_NUM < 20181226
+ if (type == NST_BARTER) {
+ ShowWarning("buildin_tradertype: NST_BARTER is only available with PACKETVER_ZERO_NUM 20181226 or newer!\n");
+ script->reportsrc(st);
+ }
+#endif
if( nd->u.scr.shop )
nd->u.scr.shop->type = type;
@@ -20646,7 +24131,7 @@ BUILDIN(tradertype)
*
* signs the transaction can proceed
**/
-BUILDIN(purchaseok)
+static BUILDIN(purchaseok)
{
struct npc_data *nd;
@@ -20665,7 +24150,7 @@ BUILDIN(purchaseok)
*
* @return number of available items in the script's attached shop
**/
-BUILDIN(shopcount)
+static BUILDIN(shopcount)
{
struct npc_data *nd;
int id = script_getnum(st, 2);
@@ -20677,8 +24162,8 @@ BUILDIN(shopcount)
} else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) {
ShowWarning("buildin_shopcount(%d): trying to use without any items!\n",id);
return false;
- } else if ( nd->u.scr.shop->type != NST_MARKET ) {
- ShowWarning("buildin_shopcount(%d): trying to use on a non-NST_MARKET shop!\n",id);
+ } else if (nd->u.scr.shop->type != NST_MARKET && nd->u.scr.shop->type != NST_BARTER) {
+ ShowWarning("buildin_shopcount(%d): trying to use on a non-NST_MARKET and non-NST_BARTER shop!\n",id);
return false;
}
@@ -20703,9 +24188,9 @@ BUILDIN(shopcount)
* Sends a message through the specified chat channel.
*
*/
-BUILDIN(channelmes)
+static BUILDIN(channelmes)
{
- struct map_session_data *sd = script->rid2sd(st);
+ struct map_session_data *sd = map->id2sd(st->rid);
const char *channelname = script_getstr(st, 2);
struct channel_data *chan = channel->search(channelname, sd);
@@ -20720,11 +24205,62 @@ BUILDIN(channelmes)
return true;
}
+static BUILDIN(addchannelhandler)
+{
+ int i;
+ struct map_session_data *sd = map->id2sd(st->rid);
+ const char *channelname = script_getstr(st, 2);
+ const char *eventname = script_getstr(st, 3);
+ struct channel_data *chan = channel->search(channelname, sd);
+
+ if (!chan) {
+ script_pushint(st, 0);
+ return true;
+ }
+
+ ARR_FIND(0, MAX_EVENTQUEUE, i, chan->handlers[i][0] == '\0');
+
+ if (i < MAX_EVENTQUEUE) {
+ safestrncpy(chan->handlers[i], eventname, EVENT_NAME_LENGTH); //Event enqueued.
+ script_pushint(st, 1);
+ return true;
+ }
+
+ ShowWarning("script:addchannelhandler: too many handlers for channel %s.\n", channelname);
+ script_pushint(st, 0);
+ return true;
+}
+
+static BUILDIN(removechannelhandler)
+{
+ int i;
+ struct map_session_data *sd = map->id2sd(st->rid);
+ const char *channelname = script_getstr(st, 2);
+ const char *eventname = script_getstr(st, 3);
+ struct channel_data *chan = channel->search(channelname, sd);
+
+ if (!chan) {
+ script_pushint(st, 0);
+ return true;
+ }
+
+ for (i = 0; i < MAX_EVENTQUEUE; i++) {
+ if (strcmp(chan->handlers[i], eventname) == 0) {
+ chan->handlers[i][0] = '\0';
+ script_pushint(st, 1);
+ return true;
+ }
+ }
+
+ script_pushint(st, 0);
+ return true;
+}
+
/** By Cydh
-Display script message
-showscript "<message>"{,<GID>};
-*/
-BUILDIN(showscript)
+ * Display script message
+ * showscript "<message>"{, <GID>};
+ */
+static BUILDIN(showscript)
{
struct block_list *bl = NULL;
const char *msg = script_getstr(st, 2);
@@ -20751,7 +24287,7 @@ BUILDIN(showscript)
return true;
}
-BUILDIN(mergeitem)
+static BUILDIN(mergeitem)
{
struct map_session_data *sd = script->rid2sd(st);
@@ -20763,8 +24299,102 @@ BUILDIN(mergeitem)
return true;
}
+// getcalendartime(<day of month>, <day of week>{, <hour>{, <minute>}});
+// Returns the UNIX Timestamp of next ocurrency of given time
+static BUILDIN(getcalendartime)
+{
+ struct tm info = { 0 };
+ int day_of_month = script_hasdata(st, 4) ? script_getnum(st, 4) : -1;
+ int day_of_week = script_hasdata(st, 5) ? script_getnum(st, 5) : -1;
+ int year = date_get_year();
+ int month = date_get_month();
+ int day = date_get_day();
+ int cur_hour = date_get_hour();
+ int cur_min = date_get_min();
+ int hour = script_getnum(st, 2);
+ int minute = script_getnum(st, 3);
+
+ info.tm_sec = 0;
+ info.tm_min = minute;
+ info.tm_hour = hour;
+ info.tm_mday = day;
+ info.tm_mon = month - 1;
+ info.tm_year = year - 1900;
+
+ if (day_of_month > -1 && day_of_week > -1) {
+ ShowError("script:getcalendartime: You must only specify a day_of_week or a day_of_month, not both\n");
+ script_pushint(st, -1);
+ return false;
+ }
+ if (day_of_month > -1 && (day_of_month < 1 || day_of_month > 31)) {
+ ShowError("script:getcalendartime: Day of Month in invalid range. Must be between 1 and 31.\n");
+ script_pushint(st, -1);
+ return false;
+ }
+ if (day_of_week > -1 && (day_of_week < 0 || day_of_week > 6)) {
+ ShowError("script:getcalendartime: Day of Week in invalid range. Must be between 0 and 6.\n");
+ script_pushint(st, -1);
+ return false;
+ }
+ if (hour > -1 && (hour > 23)) {
+ ShowError("script:getcalendartime: Hour in invalid range. Must be between 0 and 23.\n");
+ script_pushint(st, -1);
+ return false;
+ }
+ if (minute > -1 && (minute > 59)) {
+ ShowError("script:getcalendartime: Minute in invalid range. Must be between 0 and 59.\n");
+ script_pushint(st, -1);
+ return false;
+ }
+ if (hour == -1 || minute == -1) {
+ ShowError("script:getcalendartime: Minutes and Hours are required\n");
+ script_pushint(st, -1);
+ return false;
+ }
+
+ if (day_of_month > -1) {
+ if (day_of_month < day) { // Next Month
+ info.tm_mon++;
+ } else if (day_of_month == day) { // Today
+ if (hour < cur_hour || (hour == cur_hour && minute < cur_min)) { // But past time, next month
+ info.tm_mon++;
+ }
+ }
+
+ // Loops until month has finding a month that has day_of_month
+ do {
+ time_t t;
+ struct tm *lt;
+ info.tm_mday = day_of_month;
+ t = mktime(&info);
+ lt = localtime(&t);
+ info = *lt;
+ } while (info.tm_mday != day_of_month);
+ } else if (day_of_week > -1) {
+ int cur_wday = date_get_dayofweek();
+
+ if (day_of_week > cur_wday) { // This week
+ info.tm_mday += (day_of_week - cur_wday);
+ } else if (day_of_week == cur_wday) { // Today
+ if (hour < cur_hour || (hour == cur_hour && minute <= cur_min)) {
+ info.tm_mday += 7; // Next week
+ }
+ } else if (day_of_week < cur_wday) { // Next week
+ info.tm_mday += (7 - cur_wday + day_of_week);
+ }
+ } else if (day_of_week == -1 && day_of_month == -1) { // Next occurence of hour/min
+ if (hour < cur_hour || (hour == cur_hour && minute < cur_min)) {
+ info.tm_mday++;
+ }
+ }
+
+ script_pushint(st, mktime(&info));
+
+ return true;
+}
+
/** place holder for the translation macro **/
-BUILDIN(_)
+static BUILDIN(_)
{
return true;
}
@@ -20775,7 +24405,51 @@ BUILDIN(activatepset);
BUILDIN(deactivatepset);
BUILDIN(deletepset);
-BUILDIN(pcre_match)
+enum dressroom_mode {
+ DRESSROOM_CLOSE = 0,
+ DRESSROOM_OPEN = 1
+};
+
+/**
+ * dressroom({<enum dressroom_mode>});
+ */
+static BUILDIN(dressroom)
+{
+#if PACKETVER >= 20150513
+ struct map_session_data *sd = script->rid2sd(st);
+ enum dressroom_mode mode = DRESSROOM_OPEN;
+
+ if (sd == NULL) {
+ return false;
+ }
+
+ if (script_hasdata(st, 2)) {
+ mode = script_getnum(st, 2);
+ }
+
+ switch (mode) {
+ case DRESSROOM_OPEN:
+ clif->dressroom_open(sd, 1);
+ break;
+ case DRESSROOM_CLOSE:
+ clif->dressroom_open(sd, 0);
+ break;
+ default:
+ ShowWarning("script:dressroom: unknown mode (%u).\n", mode);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ script_pushint(st, 1);
+ return true;
+#else
+ ShowError("The dressing room works only with packet version >= 20150513");
+ script_pushint(st, 0);
+ return false;
+#endif
+}
+
+static BUILDIN(pcre_match)
{
const char *input = script_getstr(st, 2);
const char *regex = script_getstr(st, 3);
@@ -20787,7 +24461,7 @@ BUILDIN(pcre_match)
/**
* navigateto("<map>"{,<x>,<y>,<flag>,<hide_window>,<monster_id>,<char_id>});
*/
-BUILDIN(navigateto)
+static BUILDIN(navigateto)
{
#if PACKETVER >= 20111010
struct map_session_data* sd;
@@ -20826,6 +24500,494 @@ BUILDIN(navigateto)
#endif
}
+static bool rodex_sendmail_sub(struct script_state *st, struct rodex_message *msg)
+{
+ const char *sender_name, *title, *body;
+
+ if (strcmp(script->getfuncname(st), "rodex_sendmail_acc") == 0 || strcmp(script->getfuncname(st), "rodex_sendmail_acc2") == 0)
+ msg->receiver_accountid = script_getnum(st, 2);
+ else
+ msg->receiver_id = script_getnum(st, 2);
+
+ sender_name = script_getstr(st, 3);
+ if (strlen(sender_name) >= NAME_LENGTH) {
+ ShowError("script:rodex_sendmail: Sender name must not be bigger than %d!\n", NAME_LENGTH - 1);
+ return false;
+ }
+ safestrncpy(msg->sender_name, sender_name, NAME_LENGTH);
+
+ title = script_getstr(st, 4);
+ if (strlen(title) >= RODEX_TITLE_LENGTH) {
+ ShowError("script:rodex_sendmail: Mail Title must not be bigger than %d!\n", RODEX_TITLE_LENGTH - 1);
+ return false;
+ }
+ safestrncpy(msg->title, title, RODEX_TITLE_LENGTH);
+
+ body = script_getstr(st, 5);
+ if (strlen(body) >= MAIL_BODY_LENGTH) {
+ ShowError("script:rodex_sendmail: Mail Message must not be bigger than %d!\n", RODEX_BODY_LENGTH - 1);
+ return false;
+ }
+ safestrncpy(msg->body, body, MAIL_BODY_LENGTH);
+
+ if (script_hasdata(st, 6)) {
+ msg->zeny = script_getnum(st, 6);
+ if (msg->zeny < 0 || msg->zeny > MAX_ZENY) {
+ ShowError("script:rodex_sendmail: Invalid Zeny value %"PRId64"!\n", msg->zeny);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static BUILDIN(rodex_sendmail)
+{
+ struct rodex_message msg = { 0 };
+ int item_count = 0, i = 0, param = 7;
+
+ // Common parameters - sender/message/zeny
+ if (rodex_sendmail_sub(st, &msg) == false)
+ return false;
+
+ // Item list
+ while (i < RODEX_MAX_ITEM && script_hasdata(st, param)) {
+ struct item_data *idata;
+
+ if (!script_hasdata(st, param + 1)) {
+ ShowError("script:rodex_sendmail: Missing Item %d amount!\n", (i + 1));
+ return false;
+ }
+
+ ++item_count;
+ if (data_isstring(script_getdata(st, param)) == false) {
+ int itemid = script_getnum(st, param);
+
+ if (itemdb->exists(itemid) == false) {
+ ShowError("script:rodex_sendmail: Unknown item ID %d.\n", itemid);
+ return false;
+ }
+
+ idata = itemdb->search(itemid);
+ }
+ else {
+ ShowError("script:rodex_sendmail: Item %d must be passed as Number.\n", (i + 1));
+ return false;
+ }
+
+ msg.items[i].item.nameid = idata->nameid;
+ msg.items[i].item.amount = script_getnum(st, (param + 1));
+ msg.items[i].item.identify = 1;
+
+ ++i;
+ param += 2;
+ }
+ msg.items_count = item_count;
+
+ msg.type = MAIL_TYPE_NPC;
+ if (msg.zeny > 0)
+ msg.type |= MAIL_TYPE_ZENY;
+ if (msg.items_count > 0)
+ msg.type |= MAIL_TYPE_ITEM;
+ msg.send_date = (int)time(NULL);
+ msg.expire_date = (int)time(NULL) + RODEX_EXPIRE;
+
+ intif->rodex_sendmail(&msg);
+
+ return true;
+}
+
+static BUILDIN(rodex_sendmail2)
+{
+ struct rodex_message msg = { 0 };
+ int item_count = 0, i = 0, param = 7;
+
+ // Common parameters - sender/message/zeny
+ if (rodex_sendmail_sub(st, &msg) == false)
+ return false;
+
+ // Item list
+ while (i < RODEX_MAX_ITEM && script_hasdata(st, param)) {
+ struct item_data *idata;
+ int j;
+
+ // Tests
+ if (!script_hasdata(st, param + 1)) {
+ ShowError("script:rodex_sendmail: Missing Item %d amount!\n", (i + 1));
+ return false;
+ }
+ if (!script_hasdata(st, param + 2)) {
+ ShowError("script:rodex_sendmail: Missing Item %d refine!\n", (i + 1));
+ return false;
+ }
+ if (!script_hasdata(st, param + 3)) {
+ ShowError("script:rodex_sendmail: Missing Item %d attribute!\n", (i + 1));
+ return false;
+ }
+ for (j = 0; j < MAX_SLOTS; ++j) {
+ if (!script_hasdata(st, param + 4 + j)) {
+ ShowError("script:rodex_sendmail: Missing Item %d card %d!\n", (i + 1), j);
+ return false;
+ }
+ }
+
+ // Set data to message
+ ++item_count;
+ if (data_isstring(script_getdata(st, param)) == false) {
+ int itemid = script_getnum(st, param);
+
+ if (itemdb->exists(itemid) == false) {
+ ShowError("script:rodex_sendmail: Unknown item ID %d.\n", itemid);
+ return false;
+ }
+
+ idata = itemdb->search(itemid);
+ } else {
+ ShowError("script:rodex_sendmail: Item %d must be passed as Number.\n", (i + 1));
+ return false;
+ }
+
+ msg.items[i].item.nameid = idata->nameid;
+ msg.items[i].item.amount = script_getnum(st, (param + 1));
+ msg.items[i].item.refine = script_getnum(st, (param + 2));
+ msg.items[i].item.attribute = script_getnum(st, (param + 3));
+ msg.items[i].item.identify = 1;
+
+ for (j = 0; j < MAX_SLOTS; ++j) {
+ msg.items[i].item.card[j] = script_getnum(st, param + 4 + j);
+ }
+
+ ++i;
+ param += 4 + MAX_SLOTS;
+ }
+ msg.items_count = item_count;
+
+ msg.type = MAIL_TYPE_NPC;
+ if (msg.zeny > 0)
+ msg.type |= MAIL_TYPE_ZENY;
+ if (msg.items_count > 0)
+ msg.type |= MAIL_TYPE_ITEM;
+ msg.send_date = (int)time(NULL);
+ msg.expire_date = (int)time(NULL) + RODEX_EXPIRE;
+
+ intif->rodex_sendmail(&msg);
+
+ return true;
+}
+
+/**
+ * Clan System: Add a player to a clan
+ */
+static BUILDIN(clan_join)
+{
+ struct map_session_data *sd = NULL;
+ int clan_id = script_getnum(st, 2);
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = map->id2sd(st->rid);
+
+ if (sd == NULL) {
+ script_pushint(st, false);
+ return false;
+ }
+
+ if (clan->join(sd, clan_id))
+ script_pushint(st, true);
+ else
+ script_pushint(st, false);
+
+ return true;
+}
+
+/**
+ * Clan System: Remove a player from clan
+ */
+static BUILDIN(clan_leave)
+{
+ struct map_session_data *sd = NULL;
+
+ if (script_hasdata(st, 2))
+ sd = map->id2sd(script_getnum(st, 2));
+ else
+ sd = map->id2sd(st->rid);
+
+ if (sd == NULL) {
+ script_pushint(st, false);
+ return false;
+ }
+
+ if (clan->leave(sd, false))
+ script_pushint(st, true);
+ else
+ script_pushint(st, false);
+
+ return true;
+}
+
+/**
+ * Clan System: Show clan emblem next to npc name
+ */
+static BUILDIN(clan_master)
+{
+ struct npc_data *nd = map->id2nd(st->oid);
+ int clan_id = script_getnum(st, 2);
+
+ if (nd == NULL) {
+ script_pushint(st, false);
+ return false;
+ } else if (clan_id <= 0) {
+ script_pushint(st, false);
+ ShowError("buildin_clan_master: Received Invalid Clan ID %d\n", clan_id);
+ return false;
+ } else if (clan->search(clan_id) == NULL) {
+ script_pushint(st, false);
+ ShowError("buildin_clan_master: Received Id of a nonexistent Clan. Id: %d\n", clan_id);
+ return false;
+ }
+
+ nd->clan_id = clan_id;
+ clif->sc_load(&nd->bl, nd->bl.id, AREA, status->dbs->IconChangeTable[SC_CLAN_INFO], 0, clan_id, 0);
+
+ script_pushint(st, true);
+ return true;
+}
+
+static BUILDIN(airship_respond)
+{
+ struct map_session_data *sd = map->id2sd(st->rid);
+ int32 flag = script_getnum(st, 2);
+
+ if (sd == NULL)
+ return false;
+
+ if (flag < P_AIRSHIP_NONE || flag > P_AIRSHIP_ITEM_INVALID) {
+ ShowWarning("buildin_airship_respond: invalid flag %d has been given.", flag);
+ return false;
+ }
+
+ clif->PrivateAirshipResponse(sd, flag);
+ return true;
+}
+
+/**
+ * hateffect(EffectID, Enable_State)
+ */
+static BUILDIN(hateffect)
+{
+#if PACKETVER >= 20150422
+ struct map_session_data *sd = script_rid2sd(st);
+ int effectId, enabled = 0;
+ int i;
+
+ if (sd == NULL)
+ return false;
+
+ effectId = script_getnum(st, 2);
+ enabled = script_getnum(st, 3);
+
+ for (i = 0; i < VECTOR_LENGTH(sd->hatEffectId); ++i) {
+ if (VECTOR_INDEX(sd->hatEffectId, i) == effectId) {
+ if (enabled == 1) { // Already Enabled
+ return true;
+ } else { // Remove
+ VECTOR_ERASE(sd->hatEffectId, i);
+ clif->hat_effect_single(&sd->bl, effectId, enabled);
+ return true;
+ }
+ }
+ }
+
+ VECTOR_ENSURE(sd->hatEffectId, 1, 1);
+ VECTOR_PUSH(sd->hatEffectId, effectId);
+
+ clif->hat_effect_single(&sd->bl, effectId, enabled);
+#endif
+ return true;
+}
+
+static BUILDIN(openstylist)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+
+ if (sd == NULL)
+ return false;
+
+#if PACKETVER >= 20150128
+ clif->open_ui(sd, CZ_STYLIST_UI);
+#endif
+ return true;
+}
+
+static BUILDIN(msgtable)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+
+ const enum clif_messages msgId = script_getnum(st, 2);
+ if (script_hasdata(st, 3)) {
+ clif->msgtable_color(sd, msgId, script_getnum(st, 3));
+ } else {
+ clif->msgtable(sd, msgId);
+ }
+
+ return true;
+}
+
+static BUILDIN(msgtable2)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+
+ const enum clif_messages msgId = script_getnum(st, 2);
+ if (script_isstringtype(st, 3)) {
+ const char *value = script_getstr(st, 3);
+ if (script_hasdata(st, 4)) {
+ clif->msgtable_str_color(sd, msgId, value, script_getnum(st, 4));
+ } else {
+ clif->msgtable_str(sd, msgId, value);
+ }
+ } else {
+ const int value = script_getnum(st, 3);
+ clif->msgtable_num(sd, msgId, value);
+ }
+
+ return true;
+}
+
+// show/hide camera info
+static BUILDIN(camerainfo)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+
+ clif->camera_showWindow(sd);
+ return true;
+}
+
+// allow change some camera parameters
+static BUILDIN(changecamera)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+
+ enum send_target target = SELF;
+ if (script_hasdata(st, 5)) {
+ target = script_getnum(st, 5);
+ }
+ clif->camera_change(sd, (float)script_getnum(st, 2), (float)script_getnum(st, 3), (float)script_getnum(st, 4), target);
+ return true;
+}
+
+// update preview window to given item
+static BUILDIN(itempreview)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+ clif->item_preview(sd, script_getnum(st, 2));
+ return true;
+}
+
+// insert or remove card into equipped item
+static BUILDIN(enchantitem)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+ const int pos = script_getnum(st, 2);
+ if ((pos < EQI_ACC_L || pos > EQI_HAND_R) && pos != EQI_AMMO) {
+ ShowError("Wrong equip position: %d\n", pos);
+ script->reportfunc(st);
+ script->reportsrc(st);
+ script_pushint(st, false);
+ return true;
+ }
+ const int cardId = script_getnum(st, 4);
+ struct item_data *it = itemdb->exists(cardId);
+ if (it == NULL || it->type != IT_CARD) {
+ ShowError("Item id is not card or not exists: %d\n", cardId);
+ script->reportfunc(st);
+ script->reportsrc(st);
+ script_pushint(st, false);
+ return true;
+ }
+ const int n = sd->equip_index[pos];
+ if (n < 0) {
+ ShowError("Item in equipment slot %d is not equipped\n", pos);
+ script->reportfunc(st);
+ script->reportsrc(st);
+ script_pushint(st, false);
+ return true;
+ }
+ const int cardSlot = script_getnum(st, 3);
+ if (cardSlot < 0 || cardSlot >= MAX_SLOTS) {
+ ShowError("Wrong card slot %d. Must be in range 0-3.\n", cardSlot);
+ script->reportfunc(st);
+ script->reportsrc(st);
+ script_pushint(st, false);
+ return true;
+ }
+ const bool res = clif->enchant_equipment(sd, pc->equip_pos[pos], cardSlot, cardId);
+ if (res) {
+ logs->pick_pc(sd, LOG_TYPE_CARD, -1, &sd->status.inventory[n],sd->inventory_data[n]);
+ sd->status.inventory[n].card[cardSlot] = cardId;
+ logs->pick_pc(sd, LOG_TYPE_CARD, 1, &sd->status.inventory[n],sd->inventory_data[n]);
+ status_calc_pc(sd, SCO_NONE);
+ }
+ script_pushint(st, res);
+ return true;
+}
+
+// send ack to inventory expand request
+static BUILDIN(expandInventoryAck)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+ int itemId = 0;
+ if (script_hasdata(st, 3)) {
+ itemId = script_getnum(st, 3);
+ }
+ clif->inventoryExpandAck(sd, script_getnum(st, 2), itemId);
+ return true;
+}
+
+// send final ack to inventory expand request
+static BUILDIN(expandInventoryResult)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+ clif->inventoryExpandResult(sd, script_getnum(st, 2));
+ return true;
+}
+
+// adjust player inventory size to given value positive or negative
+static BUILDIN(expandInventory)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+ script_pushint(st, pc->expandInventory(sd, script_getnum(st, 2)));
+ return true;
+}
+
+// return current player inventory size
+static BUILDIN(getInventorySize)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ if (sd == NULL)
+ return false;
+ script_pushint(st, sd->status.inventorySize);
+ return true;
+}
+
/**
* Adds a built-in script function.
*
@@ -20834,7 +24996,7 @@ BUILDIN(navigateto)
* (i.e. a plugin overriding a built-in function)
* @return Whether the function was successfully added.
*/
-bool script_add_builtin(const struct script_function *buildin, bool override)
+static bool script_add_builtin(const struct script_function *buildin, bool override)
{
int n = 0, offset = 0;
size_t slen;
@@ -20916,7 +25078,7 @@ bool script_add_builtin(const struct script_function *buildin, bool override)
return true;
}
-bool script_hp_add(char *name, char *args, bool (*func)(struct script_state *st), bool isDeprecated)
+static bool script_hp_add(char *name, char *args, bool (*func)(struct script_state *st), bool isDeprecated)
{
struct script_function buildin;
buildin.name = name;
@@ -20926,7 +25088,7 @@ bool script_hp_add(char *name, char *args, bool (*func)(struct script_state *st)
return script->add_builtin(&buildin, true);
}
-void script_run_use_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull (1)));
+static void script_run_use_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull (1)));
/**
* Run use script for item.
@@ -20935,7 +25097,7 @@ void script_run_use_script(struct map_session_data *sd, struct item_data *data,
* @param n item index in inventory. Must be correct and checked before.
* @param oid npc id. Can be also 0 or fake npc id.
*/
-void script_run_use_script(struct map_session_data *sd, struct item_data *data, int oid)
+static void script_run_use_script(struct map_session_data *sd, struct item_data *data, int oid)
{
nullpo_retv(data);
script->current_item_id = data->nameid;
@@ -20943,7 +25105,7 @@ void script_run_use_script(struct map_session_data *sd, struct item_data *data,
script->current_item_id = 0;
}
-void script_run_item_equip_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull (1, 2)));
+static void script_run_item_equip_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull (1, 2)));
/**
* Run item equip script for item.
@@ -20952,14 +25114,14 @@ void script_run_item_equip_script(struct map_session_data *sd, struct item_data
* @param data equipped item data. Must be correct and checked before.
* @param oid npc id. Can be also 0 or fake npc id.
*/
-void script_run_item_equip_script(struct map_session_data *sd, struct item_data *data, int oid)
+static void script_run_item_equip_script(struct map_session_data *sd, struct item_data *data, int oid)
{
script->current_item_id = data->nameid;
script->run(data->equip_script, 0, sd->bl.id, oid);
script->current_item_id = 0;
}
-void script_run_item_unequip_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull (1, 2)));
+static void script_run_item_unequip_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull (1, 2)));
/**
* Run item unequip script for item.
@@ -20968,7 +25130,7 @@ void script_run_item_unequip_script(struct map_session_data *sd, struct item_dat
* @param data unequipped item data. Must be correct and checked before.
* @param oid npc id. Can be also 0 or fake npc id.
*/
-void script_run_item_unequip_script(struct map_session_data *sd, struct item_data *data, int oid)
+static void script_run_item_unequip_script(struct map_session_data *sd, struct item_data *data, int oid)
{
script->current_item_id = data->nameid;
script->run(data->unequip_script, 0, sd->bl.id, oid);
@@ -20979,21 +25141,22 @@ void script_run_item_unequip_script(struct map_session_data *sd, struct item_dat
#define BUILDIN_DEF2(x,x2,args) { buildin_ ## x , x2 , args, false }
#define BUILDIN_DEF_DEPRECATED(x,args) { buildin_ ## x , #x , args, true }
#define BUILDIN_DEF2_DEPRECATED(x,x2,args) { buildin_ ## x , x2 , args, true }
-void script_parse_builtin(void) {
+static void script_parse_builtin(void)
+{
struct script_function BUILDIN[] = {
/* Commands for internal use by the script engine */
BUILDIN_DEF(__jump_zero,"il"),
BUILDIN_DEF(__setr,"rv?"),
// NPC interaction
- BUILDIN_DEF(mes,"s"),
- BUILDIN_DEF(mesf,"s*"),
+ BUILDIN_DEF(mes, "?"),
+ BUILDIN_DEF(mesf, "s*"),
BUILDIN_DEF(next,""),
BUILDIN_DEF(close,""),
BUILDIN_DEF(close2,""),
BUILDIN_DEF(menu,"sl*"),
BUILDIN_DEF(select,"s*"), //for future jA script compatibility
- BUILDIN_DEF(prompt,"s*"),
+ BUILDIN_DEF2(select, "prompt", "s*"),
//
BUILDIN_DEF(goto,"l"),
BUILDIN_DEF(callsub,"l*"),
@@ -21006,7 +25169,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(warp,"sii?"),
BUILDIN_DEF(areawarp,"siiiisii??"),
BUILDIN_DEF(warpchar,"siii"), // [LuzZza]
- BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X]
+ BUILDIN_DEF(warpparty,"siii??"), // [Fredzilla] [Paradox924X] [Jedzkie] [Dastgir]
BUILDIN_DEF(warpguild,"siii?"), // [Fredzilla]
BUILDIN_DEF(setlook,"ii"),
BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it
@@ -21015,6 +25178,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(cleararray,"rvi"),
BUILDIN_DEF(copyarray,"rri"),
BUILDIN_DEF(getarraysize,"r"),
+ BUILDIN_DEF(getarrayindex,"r"),
BUILDIN_DEF(deletearray,"r?"),
BUILDIN_DEF(getelementofarray,"ri"),
BUILDIN_DEF(getitem,"vi?"),
@@ -21039,8 +25203,9 @@ void script_parse_builtin(void) {
BUILDIN_DEF(checkweight,"vi*"),
BUILDIN_DEF(checkweight2,"rr"),
BUILDIN_DEF(readparam,"i?"),
+ BUILDIN_DEF(setparam,"ii?"),
BUILDIN_DEF(getcharid,"i?"),
- BUILDIN_DEF(getnpcid,"i?"),
+ BUILDIN_DEF(getnpcid, "?"),
BUILDIN_DEF(getpartyname,"i"),
BUILDIN_DEF(getpartymember,"i?"),
BUILDIN_DEF(getpartyleader,"i?"),
@@ -21062,12 +25227,13 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getequipisidentify,"i"),
BUILDIN_DEF(getequiprefinerycnt,"i"),
BUILDIN_DEF(getequipweaponlv,"i"),
- BUILDIN_DEF(getequippercentrefinery,"i"),
+ BUILDIN_DEF(getequippercentrefinery,"i?"),
BUILDIN_DEF(successrefitem,"i?"),
BUILDIN_DEF(failedrefitem,"i"),
BUILDIN_DEF(downrefitem,"i?"),
BUILDIN_DEF(statusup,"i"),
BUILDIN_DEF(statusup2,"ii"),
+ BUILDIN_DEF(needed_status_point,"ii?"),
BUILDIN_DEF(bonus,"iv"),
BUILDIN_DEF2(bonus,"bonus2","ivi"),
BUILDIN_DEF2(bonus,"bonus3","ivii"),
@@ -21084,10 +25250,10 @@ void script_parse_builtin(void) {
BUILDIN_DEF(basicskillcheck,""),
BUILDIN_DEF(getgmlevel,""),
BUILDIN_DEF(setgroupid, "i?"),
- BUILDIN_DEF(getgroupid,""),
+ BUILDIN_DEF(getgroupid,"?"),
BUILDIN_DEF(end,""),
- BUILDIN_DEF(checkoption,"i"),
- BUILDIN_DEF(setoption,"i?"),
+ BUILDIN_DEF(checkoption,"i?"),
+ BUILDIN_DEF(setoption,"i??"),
BUILDIN_DEF(setcart,"?"),
BUILDIN_DEF(checkcart,""),
BUILDIN_DEF(setfalcon,"?"),
@@ -21115,6 +25281,8 @@ void script_parse_builtin(void) {
BUILDIN_DEF(addtimer,"is?"),
BUILDIN_DEF(deltimer,"s?"),
BUILDIN_DEF(addtimercount,"si?"),
+ BUILDIN_DEF(gettimer,"i??"),
+ BUILDIN_DEF(getunits,"iri?????"),
BUILDIN_DEF(initnpctimer,"??"),
BUILDIN_DEF(stopnpctimer,"??"),
BUILDIN_DEF(startnpctimer,"??"),
@@ -21141,7 +25309,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(sc_end,"i?"),
BUILDIN_DEF(getstatus, "i?"),
BUILDIN_DEF(getscrate,"ii?"),
- BUILDIN_DEF(debugmes,"v"),
+ BUILDIN_DEF(debugmes,"v*"),
BUILDIN_DEF2(catchpet,"pet","i"),
BUILDIN_DEF2(birthpet,"bpet",""),
BUILDIN_DEF(resetlvl,"i"),
@@ -21163,6 +25331,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(isloggedin,"i?"),
BUILDIN_DEF(setmapflagnosave,"ssii"),
BUILDIN_DEF(getmapflag,"si"),
+ BUILDIN_DEF(getmapinfo,"i?"),
BUILDIN_DEF(setmapflag,"si?"),
BUILDIN_DEF(removemapflag,"si"),
BUILDIN_DEF(pvpon,"s"),
@@ -21200,7 +25369,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getskilllist,""),
BUILDIN_DEF(clearitem,""),
BUILDIN_DEF(classchange,"ii?"),
- BUILDIN_DEF(misceffect,"i"),
+ BUILDIN_DEF_DEPRECATED(misceffect,"i"),
BUILDIN_DEF(playbgm,"s"),
BUILDIN_DEF(playbgmall,"s?????"),
BUILDIN_DEF(soundeffect,"si"),
@@ -21215,15 +25384,17 @@ void script_parse_builtin(void) {
BUILDIN_DEF(petskillsupport,"viiii"), // [Skotlex]
BUILDIN_DEF(skilleffect,"vi"), // skill effect [Celest]
BUILDIN_DEF(npcskilleffect,"viii"), // npc skill effect [Valaris]
- BUILDIN_DEF(specialeffect,"i??"), // npc skill effect [Valaris]
- BUILDIN_DEF(specialeffect2,"i??"), // skill effect on players[Valaris]
+ BUILDIN_DEF(specialeffect,"i???"), // npc skill effect [Valaris]
+ BUILDIN_DEF(removespecialeffect,"i???"),
+ BUILDIN_DEF_DEPRECATED(specialeffect2,"i??"), // skill effect on players[Valaris]
BUILDIN_DEF(nude,""), // nude command [Valaris]
BUILDIN_DEF(mapwarp,"ssii??"), // Added by RoVeRT
BUILDIN_DEF(atcommand,"s"), // [MouseJstr]
BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr]
BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr]
BUILDIN_DEF(message,"vs"), // [MouseJstr]
- BUILDIN_DEF(npctalk,"s?"), // [Valaris]
+ BUILDIN_DEF(servicemessage, "si?"),
+ BUILDIN_DEF(npctalk,"s??"), // [Valaris][Murilo BiO]
BUILDIN_DEF(mobcount,"ss"),
BUILDIN_DEF(getlook,"i"),
BUILDIN_DEF(getsavepoint,"i"),
@@ -21235,11 +25406,11 @@ void script_parse_builtin(void) {
BUILDIN_DEF(setnpcdir,"*"), // [4144]
BUILDIN_DEF(getnpcclass,"?"), // [4144]
BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus]
- BUILDIN_DEF(checkoption1,"i"),
- BUILDIN_DEF(checkoption2,"i"),
+ BUILDIN_DEF(checkoption1,"i?"),
+ BUILDIN_DEF(checkoption2,"i?"),
BUILDIN_DEF(guildgetexp,"i"),
BUILDIN_DEF(guildchangegm,"is"),
- BUILDIN_DEF(logmes,"s"), //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus]
+ 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(isequipped,"i*"), // check whether another item/card has been equipped [Celest]
@@ -21252,10 +25423,11 @@ void script_parse_builtin(void) {
BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr]
BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr]
BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr]
+ BUILDIN_DEF(dressroom,"?"),
BUILDIN_DEF(pcre_match,"ss"),
BUILDIN_DEF(dispbottom,"s?"), //added from jA [Lupus]
BUILDIN_DEF(getusersname,""),
- BUILDIN_DEF(recovery,""),
+ BUILDIN_DEF(recovery,"?????"),
BUILDIN_DEF(getpetinfo,"i"),
BUILDIN_DEF(gethominfo,"i"),
BUILDIN_DEF(getmercinfo,"i?"),
@@ -21265,6 +25437,10 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris]
BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris]
BUILDIN_DEF(charat,"si"),
+ BUILDIN_DEF(isstr,"v"),
+ BUILDIN_DEF(getdatatype, "?"),
+ BUILDIN_DEF(data_to_string, "?"),
+ BUILDIN_DEF2(getd, "string_to_data", "?"),
BUILDIN_DEF(chr,"i"),
BUILDIN_DEF(ord,"s"),
BUILDIN_DEF(setchar,"ssi"),
@@ -21288,10 +25464,14 @@ void script_parse_builtin(void) {
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
+ BUILDIN_DEF(getequippedoptioninfo, "i"),
+ BUILDIN_DEF(getequipoption, "iii"),
+ BUILDIN_DEF(setequipoption, "iiii"),
+ BUILDIN_DEF(getequipisenableopt, "i"),
// List of mathematics commands --->
BUILDIN_DEF(log10,"i"),
BUILDIN_DEF(sqrt,"i"), //[zBuffer]
- BUILDIN_DEF(pow,"ii"), //[zBuffer]
+ BUILDIN_DEF_DEPRECATED(pow,"ii"), //[zBuffer]
BUILDIN_DEF(distance,"iiii"), //[zBuffer]
// <--- List of mathematics commands
BUILDIN_DEF(min, "i*"),
@@ -21329,16 +25509,23 @@ void script_parse_builtin(void) {
BUILDIN_DEF(rid2name,"i"),
BUILDIN_DEF(pcfollow,"ii"),
BUILDIN_DEF(pcstopfollow,"i"),
- BUILDIN_DEF(pcblockmove,"ii"),
+ BUILDIN_DEF_DEPRECATED(pcblockmove,"ii"), // Deprecated 2018-05-04
+ BUILDIN_DEF(setpcblock, "ii"),
+ BUILDIN_DEF(checkpcblock, ""),
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
BUILDIN_DEF(getunittype,"i"),
+ /* Unit Data */
+ BUILDIN_DEF(setunitdata,"iiv??"),
+ BUILDIN_DEF(getunitdata,"ii?"),
+ BUILDIN_DEF(getunitname,"i"),
+ BUILDIN_DEF(setunitname,"is"),
BUILDIN_DEF(unitwalk,"ii?"),
BUILDIN_DEF(unitkill,"i"),
BUILDIN_DEF(unitwarp,"isii"),
BUILDIN_DEF(unitattack,"iv?"),
BUILDIN_DEF(unitstop,"i"),
- BUILDIN_DEF(unittalk,"is"),
+ BUILDIN_DEF(unittalk,"is???"),
BUILDIN_DEF(unitemote,"ii"),
BUILDIN_DEF(unitskilluseid,"ivi?"), // originally by Qamera [Celest]
BUILDIN_DEF(unitskillusepos,"iviii"), // [Celest]
@@ -21377,14 +25564,19 @@ void script_parse_builtin(void) {
BUILDIN_DEF(setfont,"i"),
BUILDIN_DEF(areamobuseskill,"siiiiviiiii"),
BUILDIN_DEF(progressbar,"si"),
+ BUILDIN_DEF(progressbar_unit,"si?"),
BUILDIN_DEF(pushpc,"ii"),
BUILDIN_DEF(buyingstore,"i"),
BUILDIN_DEF(searchstores,"ii"),
BUILDIN_DEF(showdigit,"i?"),
+ BUILDIN_DEF(msgtable, "i?"),
+ BUILDIN_DEF(msgtable2, "iv?"),
// WoE SE
BUILDIN_DEF(agitstart2,""),
BUILDIN_DEF(agitend2,""),
BUILDIN_DEF(agitcheck2,""),
+ // Achievements [Smokexyz/Hercules]
+ BUILDIN_DEF(achievement_progress, "iiii?"),
// BattleGround
BUILDIN_DEF(waitingroom2bg,"siiss?"),
BUILDIN_DEF(waitingroom2bg_single,"isiis"),
@@ -21443,7 +25635,10 @@ void script_parse_builtin(void) {
**/
BUILDIN_DEF(bindatcmd, "ss???"),
BUILDIN_DEF(unbindatcmd, "s"),
- BUILDIN_DEF(useatcmd, "s"),
+ BUILDIN_DEF_DEPRECATED(useatcmd, "s"),
+ BUILDIN_DEF(has_permission, "v?"),
+ BUILDIN_DEF(can_use_command, "s?"),
+ BUILDIN_DEF(add_group_command, "siii"),
/**
* Item bound [Xantara] [Akinari] [Mhalicot/Hercules]
@@ -21454,8 +25649,9 @@ void script_parse_builtin(void) {
BUILDIN_DEF(checkbound, "i???????"),
//Quest Log System [Inkfish]
- BUILDIN_DEF(questinfo, "ii??"),
- BUILDIN_DEF(setquest, "i"),
+ BUILDIN_DEF(questinfo, "i?"),
+ BUILDIN_DEF(setquestinfo, "i???"),
+ BUILDIN_DEF(setquest, "i?"),
BUILDIN_DEF(erasequest, "i?"),
BUILDIN_DEF(completequest, "i?"),
BUILDIN_DEF(questprogress, "i?"),
@@ -21492,8 +25688,8 @@ void script_parse_builtin(void) {
/* New Shop Support */
BUILDIN_DEF(openshop,"?"),
- BUILDIN_DEF(sellitem,"i??"),
- BUILDIN_DEF(stopselling,"i"),
+ BUILDIN_DEF(sellitem,"i???"),
+ BUILDIN_DEF(stopselling,"i??"),
BUILDIN_DEF(setcurrency,"i?"),
BUILDIN_DEF(tradertype,"i"),
BUILDIN_DEF(purchaseok,""),
@@ -21502,11 +25698,41 @@ void script_parse_builtin(void) {
/* Navigation */
BUILDIN_DEF(navigateto, "s??????"),
+ /* Clan System */
+ BUILDIN_DEF(clan_join,"i?"),
+ BUILDIN_DEF(clan_leave,"?"),
+ BUILDIN_DEF(clan_master,"i"),
+
BUILDIN_DEF(channelmes, "ss"),
+ BUILDIN_DEF(addchannelhandler, "ss"),
+ BUILDIN_DEF(removechannelhandler, "ss"),
BUILDIN_DEF(showscript, "s?"),
BUILDIN_DEF(mergeitem,""),
+ BUILDIN_DEF(getcalendartime, "ii??"),
+
+ // -- RoDEX
+ BUILDIN_DEF(rodex_sendmail, "isss???????????"),
+ BUILDIN_DEF2(rodex_sendmail, "rodex_sendmail_acc", "isss???????????"),
+ BUILDIN_DEF(rodex_sendmail2, "isss?????????????????????????????????????????"),
+ BUILDIN_DEF2(rodex_sendmail2, "rodex_sendmail_acc2", "isss?????????????????????????????????????????"),
+ BUILDIN_DEF(airship_respond, "i"),
+ BUILDIN_DEF(openstylist,""),
BUILDIN_DEF(_,"s"),
BUILDIN_DEF2(_, "_$", "s"),
+
+ // -- HatEffect
+ BUILDIN_DEF(hateffect, "ii"),
+
+ // camera
+ BUILDIN_DEF(camerainfo, ""),
+ BUILDIN_DEF(changecamera, "iii?"),
+
+ BUILDIN_DEF(itempreview, "i"),
+ BUILDIN_DEF(enchantitem, "iii"),
+ BUILDIN_DEF(expandInventoryAck, "i?"),
+ BUILDIN_DEF(expandInventoryResult, "i"),
+ BUILDIN_DEF(expandInventory, "i"),
+ BUILDIN_DEF(getInventorySize, ""),
};
int i, len = ARRAYLENGTH(BUILDIN);
RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
@@ -21518,7 +25744,7 @@ void script_parse_builtin(void) {
#undef BUILDIN_DEF
#undef BUILDIN_DEF2
-void script_label_add(int key, int pos)
+static void script_label_add(int key, int pos)
{
int idx = script->label_count;
@@ -21535,7 +25761,7 @@ void script_label_add(int key, int pos)
/**
* Sets source-end constants for scripts to play with
**/
-void script_hardcoded_constants(void)
+static void script_hardcoded_constants(void)
{
script->constdb_comment("Boolean");
script->set_constant("true", 1, false, false);
@@ -21546,12 +25772,16 @@ void script_hardcoded_constants(void)
script->set_constant("MAX_LEVEL",MAX_LEVEL,false, false);
script->set_constant("MAX_STORAGE",MAX_STORAGE,false, false);
script->set_constant("MAX_GUILD_STORAGE",MAX_GUILD_STORAGE,false, false);
- script->set_constant("MAX_CART",MAX_INVENTORY,false, false);
+ script->set_constant("MAX_CART", MAX_CART, false, false);
script->set_constant("MAX_INVENTORY",MAX_INVENTORY,false, false);
+ script->set_constant("FIXED_INVENTORY_SIZE", FIXED_INVENTORY_SIZE, false, false);
script->set_constant("MAX_ZENY",MAX_ZENY,false, false);
+ script->set_constant("MAX_BANK_ZENY", MAX_BANK_ZENY, false, false);
script->set_constant("MAX_BG_MEMBERS",MAX_BG_MEMBERS,false, false);
script->set_constant("MAX_CHAT_USERS",MAX_CHAT_USERS,false, false);
script->set_constant("MAX_REFINE",MAX_REFINE,false, false);
+ script->set_constant("MAX_MENU_OPTIONS", MAX_MENU_OPTIONS, false, false);
+ script->set_constant("MAX_MENU_LENGTH", MAX_MENU_LENGTH, false, false);
script->constdb_comment("status options");
script->set_constant("Option_Nothing",OPTION_NOTHING,false, false);
@@ -21578,6 +25808,7 @@ void script_hardcoded_constants(void)
script->set_constant("Option_Dragon5",OPTION_DRAGON5,false, false);
script->set_constant("Option_Hanbok",OPTION_HANBOK,false, false);
script->set_constant("Option_Oktoberfest",OPTION_OKTOBERFEST,false, false);
+ script->set_constant("Option_Summer2", OPTION_SUMMER2, false, false);
script->constdb_comment("status option compounds");
script->set_constant("Option_Dragon",OPTION_DRAGON,false, false);
@@ -21655,6 +25886,23 @@ void script_hardcoded_constants(void)
script->set_constant("EQP_SHADOW_SHOES", EQP_SHADOW_SHOES, false, false);
script->set_constant("EQP_SHADOW_ACC_R", EQP_SHADOW_ACC_R, false, false);
script->set_constant("EQP_SHADOW_ACC_L", EQP_SHADOW_ACC_L, false, false);
+ // Synonyms and combined values
+ script->set_constant("EQP_WEAPON", EQP_WEAPON, false, false);
+ script->set_constant("EQP_SHIELD", EQP_SHIELD, false, false);
+ script->set_constant("EQP_ARMS", EQP_ARMS, false, false);
+ script->set_constant("EQP_HELM", EQP_HELM, false, false);
+ script->set_constant("EQP_ACC", EQP_ACC, false, false);
+ script->set_constant("EQP_COSTUME", EQP_COSTUME, false, false);
+ script->set_constant("EQP_SHADOW_ACC", EQP_SHADOW_ACC, false, false);
+ script->set_constant("EQP_SHADOW_ARMS", EQP_SHADOW_ARMS, false, false);
+
+ script->constdb_comment("Item Option Types");
+ script->set_constant("IT_OPT_INDEX", IT_OPT_INDEX, false, false);
+ script->set_constant("IT_OPT_VALUE", IT_OPT_VALUE, false, false);
+ script->set_constant("IT_OPT_PARAM", IT_OPT_PARAM, false, false);
+
+ script->constdb_comment("Maximum Item Options");
+ script->set_constant("MAX_ITEM_OPTIONS", MAX_ITEM_OPTIONS, false, false);
script->constdb_comment("Navigation constants, use with *navigateto*");
script->set_constant("NAV_NONE", NAV_NONE, false, false);
@@ -21666,6 +25914,269 @@ void script_hardcoded_constants(void)
script->set_constant("NAV_KAFRA_AND_SCROLL", NAV_KAFRA_AND_SCROLL, false, false);
script->set_constant("NAV_ALL", NAV_ALL, false, false);
+ script->constdb_comment("BL types");
+ script->set_constant("BL_PC",BL_PC,false, false);
+ script->set_constant("BL_MOB",BL_MOB,false, false);
+ script->set_constant("BL_PET",BL_PET,false, false);
+ script->set_constant("BL_HOM",BL_HOM,false, false);
+ script->set_constant("BL_MER",BL_MER,false, false);
+ script->set_constant("BL_ITEM",BL_ITEM,false, false);
+ script->set_constant("BL_SKILL",BL_SKILL,false, false);
+ script->set_constant("BL_NPC",BL_NPC,false, false);
+ script->set_constant("BL_CHAT",BL_CHAT,false, false);
+ script->set_constant("BL_ELEM",BL_ELEM,false, false);
+ script->set_constant("BL_CHAR",BL_CHAR,false, false);
+ script->set_constant("BL_ALL",BL_ALL,false, false);
+
+ script->constdb_comment("Refine Chance Types");
+ script->set_constant("REFINE_CHANCE_TYPE_NORMAL", REFINE_CHANCE_TYPE_NORMAL, false, false);
+ script->set_constant("REFINE_CHANCE_TYPE_ENRICHED", REFINE_CHANCE_TYPE_ENRICHED, false, false);
+ script->set_constant("REFINE_CHANCE_TYPE_E_NORMAL", REFINE_CHANCE_TYPE_E_NORMAL, false, false);
+ script->set_constant("REFINE_CHANCE_TYPE_E_ENRICHED", REFINE_CHANCE_TYPE_E_ENRICHED, false, false);
+
+ script->constdb_comment("Player permissions");
+ script->set_constant("PERM_TRADE", PC_PERM_TRADE, false, false);
+ script->set_constant("PERM_PARTY", PC_PERM_PARTY, false, false);
+ script->set_constant("PERM_ALL_SKILL", PC_PERM_ALL_SKILL, false, false);
+ script->set_constant("PERM_USE_ALL_EQUIPMENT", PC_PERM_USE_ALL_EQUIPMENT, false, false);
+ script->set_constant("PERM_SKILL_UNCONDITIONAL", PC_PERM_SKILL_UNCONDITIONAL, false, false);
+ script->set_constant("PERM_JOIN_ALL_CHAT", PC_PERM_JOIN_ALL_CHAT, false, false);
+ script->set_constant("PERM_NO_CHAT_KICK", PC_PERM_NO_CHAT_KICK, false, false);
+ script->set_constant("PERM_HIDE_SESSION", PC_PERM_HIDE_SESSION, false, false);
+ script->set_constant("PERM_RECEIVE_HACK_INFO", PC_PERM_RECEIVE_HACK_INFO, false, false);
+ script->set_constant("PERM_WARP_ANYWHERE", PC_PERM_WARP_ANYWHERE, false, false);
+ script->set_constant("PERM_VIEW_HPMETER", PC_PERM_VIEW_HPMETER, false, false);
+ script->set_constant("PERM_VIEW_EQUIPMENT", PC_PERM_VIEW_EQUIPMENT, false, false);
+ script->set_constant("PERM_USE_CHECK", PC_PERM_USE_CHECK, false, false);
+ script->set_constant("PERM_USE_CHANGEMAPTYPE", PC_PERM_USE_CHANGEMAPTYPE, false, false);
+ script->set_constant("PERM_USE_ALL_COMMANDS", PC_PERM_USE_ALL_COMMANDS, false, false);
+ script->set_constant("PERM_RECEIVE_REQUESTS", PC_PERM_RECEIVE_REQUESTS, false, false);
+ script->set_constant("PERM_SHOW_BOSS", PC_PERM_SHOW_BOSS, false, false);
+ script->set_constant("PERM_DISABLE_PVM", PC_PERM_DISABLE_PVM, false, false);
+ script->set_constant("PERM_DISABLE_PVP", PC_PERM_DISABLE_PVP, false, false);
+ script->set_constant("PERM_DISABLE_CMD_DEAD", PC_PERM_DISABLE_CMD_DEAD, false, false);
+ script->set_constant("PERM_HCHSYS_ADMIN", PC_PERM_HCHSYS_ADMIN, false, false);
+ script->set_constant("PERM_TRADE_BOUND", PC_PERM_TRADE_BOUND, false, false);
+ script->set_constant("PERM_DISABLE_PICK_UP", PC_PERM_DISABLE_PICK_UP, false, false);
+ script->set_constant("PERM_DISABLE_STORE", PC_PERM_DISABLE_STORE, false, false);
+ script->set_constant("PERM_DISABLE_EXP", PC_PERM_DISABLE_EXP, false, false);
+ script->set_constant("PERM_DISABLE_SKILL_USAGE", PC_PERM_DISABLE_SKILL_USAGE, false, false);
+
+ script->constdb_comment("Data types");
+ script->set_constant("DATATYPE_NIL", DATATYPE_NIL, false, false);
+ script->set_constant("DATATYPE_STR", DATATYPE_STR, false, false);
+ script->set_constant("DATATYPE_INT", DATATYPE_INT, false, false);
+ script->set_constant("DATATYPE_CONST", DATATYPE_CONST, false, false);
+ script->set_constant("DATATYPE_PARAM", DATATYPE_PARAM, false, false);
+ script->set_constant("DATATYPE_VAR", DATATYPE_VAR, false, false);
+ script->set_constant("DATATYPE_LABEL", DATATYPE_LABEL, false, false);
+
+ script->constdb_comment("Logmes types");
+ script->set_constant("LOGMES_NPC", LOGMES_NPC, false, false);
+ script->set_constant("LOGMES_ATCOMMAND", LOGMES_ATCOMMAND, false, false);
+
+ script->constdb_comment("Item Subtypes (Weapon types)");
+ script->set_constant("W_FIST", W_FIST, false, false);
+ script->set_constant("W_DAGGER", W_DAGGER, false, false);
+ script->set_constant("W_1HSWORD", W_1HSWORD, false, false);
+ script->set_constant("W_2HSWORD", W_2HSWORD, false, false);
+ script->set_constant("W_1HSPEAR", W_1HSPEAR, false, false);
+ script->set_constant("W_2HSPEAR", W_2HSPEAR, false, false);
+ script->set_constant("W_1HAXE", W_1HAXE, false, false);
+ script->set_constant("W_2HAXE", W_2HAXE, false, false);
+ script->set_constant("W_MACE", W_MACE, false, false);
+ script->set_constant("W_2HMACE", W_2HMACE, false, false);
+ script->set_constant("W_STAFF", W_STAFF, false, false);
+ script->set_constant("W_BOW", W_BOW, false, false);
+ script->set_constant("W_KNUCKLE", W_KNUCKLE, false, false);
+ script->set_constant("W_MUSICAL", W_MUSICAL, false, false);
+ script->set_constant("W_WHIP", W_WHIP, false, false);
+ script->set_constant("W_BOOK", W_BOOK, false, false);
+ script->set_constant("W_KATAR", W_KATAR, false, false);
+ script->set_constant("W_REVOLVER", W_REVOLVER, false, false);
+ script->set_constant("W_RIFLE", W_RIFLE, false, false);
+ script->set_constant("W_GATLING", W_GATLING, false, false);
+ script->set_constant("W_SHOTGUN", W_SHOTGUN, false, false);
+ script->set_constant("W_GRENADE", W_GRENADE, false, false);
+ script->set_constant("W_HUUMA", W_HUUMA, false, false);
+ script->set_constant("W_2HSTAFF", W_2HSTAFF, false, false);
+
+ script->constdb_comment("Item Subtypes (Ammunition types)");
+ script->set_constant("A_ARROW", A_ARROW, false, false);
+ script->set_constant("A_DAGGER", A_DAGGER, false, false);
+ script->set_constant("A_BULLET", A_BULLET, false, false);
+ script->set_constant("A_SHELL", A_SHELL, false, false);
+ script->set_constant("A_GRENADE", A_GRENADE, false, false);
+ script->set_constant("A_SHURIKEN", A_SHURIKEN, false, false);
+ script->set_constant("A_KUNAI", A_KUNAI, false, false);
+ script->set_constant("A_CANNONBALL", A_CANNONBALL, false, false);
+ script->set_constant("A_THROWWEAPON", A_THROWWEAPON, false, false);
+
+ script->constdb_comment("Item Upper Masks");
+ script->set_constant("ITEMUPPER_NONE", ITEMUPPER_NONE, false, false);
+ script->set_constant("ITEMUPPER_NORMAL", ITEMUPPER_NORMAL, false, false);
+ script->set_constant("ITEMUPPER_UPPER", ITEMUPPER_UPPER, false, false);
+ script->set_constant("ITEMUPPER_BABY", ITEMUPPER_BABY, false, false);
+ script->set_constant("ITEMUPPER_THIRD", ITEMUPPER_THIRD, false, false);
+ script->set_constant("ITEMUPPER_THIRDUPPER", ITEMUPPER_THIRDUPPER, false, false);
+ script->set_constant("ITEMUPPER_THIRDBABY", ITEMUPPER_THIRDBABY, false, false);
+ script->set_constant("ITEMUPPER_ALL", ITEMUPPER_ALL, false, false);
+
+ script->constdb_comment("dressroom modes");
+ script->set_constant("DRESSROOM_OPEN", DRESSROOM_OPEN, false, false);
+ script->set_constant("DRESSROOM_CLOSE", DRESSROOM_CLOSE, false, false);
+
+ script->constdb_comment("getmapinfo options");
+ script->set_constant("MAPINFO_NAME", MAPINFO_NAME, false, false);
+ script->set_constant("MAPINFO_ID", MAPINFO_ID, false, false);
+ script->set_constant("MAPINFO_SIZE_X", MAPINFO_SIZE_X, false, false);
+ script->set_constant("MAPINFO_SIZE_Y", MAPINFO_SIZE_Y, false, false);
+ script->set_constant("MAPINFO_ZONE", MAPINFO_ZONE, false, false);
+
+ script->constdb_comment("set/getiteminfo options");
+ script->set_constant("ITEMINFO_BUYPRICE", ITEMINFO_BUYPRICE, false, false);
+ script->set_constant("ITEMINFO_SELLPRICE", ITEMINFO_SELLPRICE, false, false);
+ script->set_constant("ITEMINFO_TYPE", ITEMINFO_TYPE, false, false);
+ script->set_constant("ITEMINFO_MAXCHANCE", ITEMINFO_MAXCHANCE, false, false);
+ script->set_constant("ITEMINFO_SEX", ITEMINFO_SEX, false, false);
+ script->set_constant("ITEMINFO_LOC", ITEMINFO_LOC, false, false);
+ script->set_constant("ITEMINFO_WEIGHT", ITEMINFO_WEIGHT, false, false);
+ script->set_constant("ITEMINFO_ATK", ITEMINFO_ATK, false, false);
+ script->set_constant("ITEMINFO_DEF", ITEMINFO_DEF, false, false);
+ script->set_constant("ITEMINFO_RANGE", ITEMINFO_RANGE, false, false);
+ script->set_constant("ITEMINFO_SLOTS", ITEMINFO_SLOTS, false, false);
+ script->set_constant("ITEMINFO_SUBTYPE", ITEMINFO_SUBTYPE, false, false);
+ script->set_constant("ITEMINFO_ELV", ITEMINFO_ELV, false, false);
+ script->set_constant("ITEMINFO_WLV", ITEMINFO_WLV, false, false);
+ script->set_constant("ITEMINFO_VIEWID", ITEMINFO_VIEWID, false, false);
+ script->set_constant("ITEMINFO_MATK", ITEMINFO_MATK, false, false);
+ script->set_constant("ITEMINFO_VIEWSPRITE", ITEMINFO_VIEWSPRITE, false, false);
+ script->set_constant("ITEMINFO_TRADE", ITEMINFO_TRADE, false, false);
+
+ script->constdb_comment("monster skill states");
+ script->set_constant("MSS_ANY", MSS_ANY, false, false);
+ script->set_constant("MSS_IDLE", MSS_IDLE, false, false);
+ script->set_constant("MSS_WALK", MSS_WALK, false, false);
+ script->set_constant("MSS_LOOT", MSS_LOOT, false, false);
+ script->set_constant("MSS_DEAD", MSS_DEAD, false, false);
+ script->set_constant("MSS_BERSERK", MSS_BERSERK, false, false);
+ script->set_constant("MSS_ANGRY", MSS_ANGRY, false, false);
+ script->set_constant("MSS_RUSH", MSS_RUSH, false, false);
+ script->set_constant("MSS_FOLLOW", MSS_FOLLOW, false, false);
+ script->set_constant("MSS_ANYTARGET", MSS_ANYTARGET, false, false);
+
+ script->constdb_comment("monster skill conditions");
+ script->set_constant("MSC_ANY", -1, false, false);
+ script->set_constant("MSC_ALWAYS", MSC_ALWAYS, false, false);
+ script->set_constant("MSC_MYHPLTMAXRATE", MSC_MYHPLTMAXRATE, false, false);
+ script->set_constant("MSC_MYHPINRATE", MSC_MYHPINRATE, false, false);
+ script->set_constant("MSC_FRIENDHPLTMAXRATE", MSC_FRIENDHPLTMAXRATE, false, false);
+ script->set_constant("MSC_FRIENDHPINRATE", MSC_FRIENDHPINRATE, false, false);
+ script->set_constant("MSC_MYSTATUSON", MSC_MYSTATUSON, false, false);
+ script->set_constant("MSC_MYSTATUSOFF", MSC_MYSTATUSOFF, false, false);
+ script->set_constant("MSC_FRIENDSTATUSON", MSC_FRIENDSTATUSON, false, false);
+ script->set_constant("MSC_FRIENDSTATUSOFF", MSC_FRIENDSTATUSOFF, false, false);
+ script->set_constant("MSC_ATTACKPCGT", MSC_ATTACKPCGT, false, false);
+ script->set_constant("MSC_ATTACKPCGE", MSC_ATTACKPCGE, false, false);
+ script->set_constant("MSC_SLAVELT", MSC_SLAVELT, false, false);
+ script->set_constant("MSC_SLAVELE", MSC_SLAVELE, false, false);
+ script->set_constant("MSC_CLOSEDATTACKED", MSC_CLOSEDATTACKED, false, false);
+ script->set_constant("MSC_LONGRANGEATTACKED", MSC_LONGRANGEATTACKED, false, false);
+ script->set_constant("MSC_SKILLUSED", MSC_SKILLUSED, false, false);
+ script->set_constant("MSC_AFTERSKILL", MSC_AFTERSKILL, false, false);
+ script->set_constant("MSC_CASTTARGETED", MSC_CASTTARGETED, false, false);
+ script->set_constant("MSC_RUDEATTACKED", MSC_RUDEATTACKED, false, false);
+ script->set_constant("MSC_MASTERHPLTMAXRATE", MSC_MASTERHPLTMAXRATE, false, false);
+ script->set_constant("MSC_MASTERATTACKED", MSC_MASTERATTACKED, false, false);
+ script->set_constant("MSC_ALCHEMIST", MSC_ALCHEMIST, false, false);
+ script->set_constant("MSC_SPAWN", MSC_SPAWN, false, false);
+
+ script->constdb_comment("monster skill targets");
+ script->set_constant("MST_TARGET", MST_TARGET, false, false);
+ script->set_constant("MST_RANDOM", MST_RANDOM , false, false);
+ script->set_constant("MST_SELF", MST_SELF, false, false);
+ script->set_constant("MST_FRIEND", MST_FRIEND , false, false);
+ script->set_constant("MST_MASTER", MST_MASTER , false, false);
+ script->set_constant("MST_AROUND5", MST_AROUND5, false, false);
+ script->set_constant("MST_AROUND6", MST_AROUND6, false, false);
+ script->set_constant("MST_AROUND7", MST_AROUND7, false, false);
+ script->set_constant("MST_AROUND8", MST_AROUND8, false, false);
+ script->set_constant("MST_AROUND1", MST_AROUND1, false, false);
+ script->set_constant("MST_AROUND2", MST_AROUND2, false, false);
+ script->set_constant("MST_AROUND3", MST_AROUND3, false, false);
+ script->set_constant("MST_AROUND4", MST_AROUND4, false, false);
+ script->set_constant("MST_AROUND", MST_AROUND , false, false);
+
+ script->constdb_comment("pc block constants, use with *setpcblock* and *checkpcblock*");
+ script->set_constant("PCBLOCK_NONE", PCBLOCK_NONE, false, false);
+ script->set_constant("PCBLOCK_MOVE", PCBLOCK_MOVE, false, false);
+ script->set_constant("PCBLOCK_ATTACK", PCBLOCK_ATTACK, false, false);
+ script->set_constant("PCBLOCK_SKILL", PCBLOCK_SKILL, false, false);
+ script->set_constant("PCBLOCK_USEITEM", PCBLOCK_USEITEM, false, false);
+ script->set_constant("PCBLOCK_CHAT", PCBLOCK_CHAT, false, false);
+ script->set_constant("PCBLOCK_IMMUNE", PCBLOCK_IMMUNE, false, false);
+ script->set_constant("PCBLOCK_SITSTAND", PCBLOCK_SITSTAND, false, false);
+ script->set_constant("PCBLOCK_COMMANDS", PCBLOCK_COMMANDS, false, false);
+
+ script->constdb_comment("private airship responds");
+ script->set_constant("P_AIRSHIP_NONE", P_AIRSHIP_NONE, false, false);
+ script->set_constant("P_AIRSHIP_RETRY", P_AIRSHIP_RETRY, false, false);
+ script->set_constant("P_AIRSHIP_INVALID_START_MAP", P_AIRSHIP_INVALID_START_MAP, false, false);
+ script->set_constant("P_AIRSHIP_INVALID_END_MAP", P_AIRSHIP_INVALID_END_MAP, false, false);
+ script->set_constant("P_AIRSHIP_ITEM_NOT_ENOUGH", P_AIRSHIP_ITEM_NOT_ENOUGH, false, false);
+ script->set_constant("P_AIRSHIP_ITEM_INVALID", P_AIRSHIP_ITEM_INVALID, false, false);
+
+ script->constdb_comment("questinfo types");
+ script->set_constant("QINFO_JOB", QINFO_JOB, false, false);
+ script->set_constant("QINFO_SEX", QINFO_SEX, false, false);
+ script->set_constant("QINFO_BASE_LEVEL", QINFO_BASE_LEVEL, false, false);
+ script->set_constant("QINFO_JOB_LEVEL", QINFO_JOB_LEVEL, false, false);
+ script->set_constant("QINFO_ITEM", QINFO_ITEM, false, false);
+ script->set_constant("QINFO_HOMUN_LEVEL", QINFO_HOMUN_LEVEL, false, false);
+ script->set_constant("QINFO_HOMUN_TYPE", QINFO_HOMUN_TYPE, false, false);
+ script->set_constant("QINFO_QUEST", QINFO_QUEST, false, false);
+ script->set_constant("QINFO_MERCENARY_CLASS", QINFO_MERCENARY_CLASS, false, false);
+
+ script->constdb_comment("function types");
+ script->set_constant("FUNCTION_IS_COMMAND", FUNCTION_IS_COMMAND, false, false);
+ script->set_constant("FUNCTION_IS_GLOBAL", FUNCTION_IS_GLOBAL, false, false);
+ script->set_constant("FUNCTION_IS_LOCAL", FUNCTION_IS_LOCAL, false, false);
+ script->set_constant("FUNCTION_IS_LABEL", FUNCTION_IS_LABEL, false, false);
+
+ script->constdb_comment("item trade restrictions");
+ script->set_constant("ITR_NONE", ITR_NONE, false, false);
+ script->set_constant("ITR_NODROP", ITR_NODROP, false, false);
+ script->set_constant("ITR_NOTRADE", ITR_NOTRADE, false, false);
+ script->set_constant("ITR_PARTNEROVERRIDE", ITR_PARTNEROVERRIDE, false, false);
+ script->set_constant("ITR_NOSELLTONPC", ITR_NOSELLTONPC, false, false);
+ script->set_constant("ITR_NOCART", ITR_NOCART, false, false);
+ script->set_constant("ITR_NOSTORAGE", ITR_NOSTORAGE, false, false);
+ script->set_constant("ITR_NOGSTORAGE", ITR_NOGSTORAGE, false, false);
+ script->set_constant("ITR_NOMAIL", ITR_NOMAIL, false, false);
+ script->set_constant("ITR_NOAUCTION", ITR_NOAUCTION, false, false);
+ script->set_constant("ITR_ALL", ITR_ALL, false, false);
+
+ script->constdb_comment("inventory expand ack responds");
+ script->set_constant("EXPAND_INV_ASK_CONFIRMATION", EXPAND_INVENTORY_ASK_CONFIRMATION, false, false);
+ script->set_constant("EXPAND_INV_FAILED", EXPAND_INVENTORY_FAILED, false, false);
+ script->set_constant("EXPAND_INV_OTHER_WORK", EXPAND_INVENTORY_OTHER_WORK, false, false);
+ script->set_constant("EXPAND_INV_MISSING_ITEM", EXPAND_INVENTORY_MISSING_ITEM, false, false);
+ script->set_constant("EXPAND_INV_MAX_SIZE", EXPAND_INVENTORY_MAX_SIZE, false, false);
+
+ script->constdb_comment("inventory expand final responds");
+ script->set_constant("EXPAND_INV_RESULT_SUCCESS", EXPAND_INVENTORY_RESULT_SUCCESS, false, false);
+ script->set_constant("EXPAND_INV_RESULT_FAILED", EXPAND_INVENTORY_RESULT_FAILED, false, false);
+ script->set_constant("EXPAND_INV_RESULT_OTHER_WORK", EXPAND_INVENTORY_RESULT_OTHER_WORK, false, false);
+ script->set_constant("EXPAND_INV_RESULT_MISSING_ITEM", EXPAND_INVENTORY_RESULT_MISSING_ITEM, false, false);
+ script->set_constant("EXPAND_INV_RESULT_MAX_SIZE", EXPAND_INVENTORY_RESULT_MAX_SIZE, false, false);
+
+ script->constdb_comment("trader type");
+ script->set_constant("NST_ZENY", NST_ZENY, false, false);
+ script->set_constant("NST_CASH", NST_CASH, false, false);
+ script->set_constant("NST_MARKET", NST_MARKET, false, false);
+ script->set_constant("NST_CUSTOM", NST_CUSTOM, false, false);
+ script->set_constant("NST_BARTER", NST_BARTER, false, false);
+
script->constdb_comment("Renewal");
#ifdef RENEWAL
script->set_constant("RENEWAL", 1, false, false);
@@ -21703,12 +26214,13 @@ void script_hardcoded_constants(void)
script->set_constant("RENEWAL_ASPD", 0, false, false);
#endif
script->constdb_comment(NULL);
+#include "constants.inc"
}
/**
* a mapindex_name2id wrapper meant to help with invalid name handling
**/
-unsigned short script_mapindexname2id (struct script_state *st, const char* name)
+static unsigned short script_mapindexname2id(struct script_state *st, const char *name)
{
unsigned short index;
@@ -21812,10 +26324,12 @@ void script_defaults(void)
script->get_val = get_val;
script->get_val2 = get_val2;
script->get_val_ref_str = get_val_npcscope_str;
+ script->get_val_pc_ref_str = get_val_pc_ref_str;
script->get_val_scope_str = get_val_npcscope_str;
script->get_val_npc_str = get_val_npcscope_str;
script->get_val_instance_str = get_val_instance_str;
script->get_val_ref_num = get_val_npcscope_num;
+ script->get_val_pc_ref_num = get_val_pc_ref_num;
script->get_val_scope_num = get_val_npcscope_num;
script->get_val_npc_num = get_val_npcscope_num;
script->get_val_instance_num = get_val_instance_num;
@@ -21844,10 +26358,12 @@ void script_defaults(void)
script->setarray_pc = script_setarray_pc;
script->config_read = script_config_read;
script->add_str = script_add_str;
+ script->add_variable = script_add_variable;
script->get_str = script_get_str;
script->search_str = script_search_str;
script->setd_sub = setd_sub;
script->attach_state = script_attach_state;
+ script->sprintf_helper = script_sprintf_helper;
script->queue = script_hqueue_get;
script->queue_add = script_hqueue_add;
@@ -21894,10 +26410,12 @@ void script_defaults(void)
script->errorwarning_sub = script_errorwarning_sub;
script->set_reg = set_reg;
script->set_reg_ref_str = set_reg_npcscope_str;
+ script->set_reg_pc_ref_str = set_reg_pc_ref_str;
script->set_reg_scope_str = set_reg_npcscope_str;
script->set_reg_npc_str = set_reg_npcscope_str;
script->set_reg_instance_str = set_reg_instance_str;
script->set_reg_ref_num = set_reg_npcscope_num;
+ script->set_reg_pc_ref_num = set_reg_pc_ref_num;
script->set_reg_scope_num = set_reg_npcscope_num;
script->set_reg_npc_num = set_reg_npcscope_num;
script->set_reg_instance_num = set_reg_instance_num;
@@ -21914,6 +26432,9 @@ void script_defaults(void)
script->db_free_code_sub = db_script_free_code_sub;
script->add_autobonus = script_add_autobonus;
script->menu_countoptions = menu_countoptions;
+ script->buildin_recovery_sub = buildin_recovery_sub;
+ script->buildin_recovery_pc_sub = buildin_recovery_pc_sub;
+ script->buildin_recovery_bl_sub = buildin_recovery_bl_sub;
script->buildin_areawarp_sub = buildin_areawarp_sub;
script->buildin_areapercentheal_sub = buildin_areapercentheal_sub;
script->buildin_delitem_delete = buildin_delitem_delete;