summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/pre-re/map_zone_db.conf2
-rw-r--r--db/pre-re/skill_db.conf3
-rw-r--r--db/re/map_zone_db.conf2
-rw-r--r--doc/script_commands.txt26
-rw-r--r--npc/re/merchants/shadow_refiner.txt2
-rw-r--r--npc/woe-se/agit_main_se.txt29
-rw-r--r--src/map/script.c198
7 files changed, 154 insertions, 108 deletions
diff --git a/db/pre-re/map_zone_db.conf b/db/pre-re/map_zone_db.conf
index cab00bbb9..a3d465c0a 100644
--- a/db/pre-re/map_zone_db.conf
+++ b/db/pre-re/map_zone_db.conf
@@ -66,7 +66,7 @@ zones: (
//heal: 70
}
skill_damage_cap: {
- //Exemple Below caps firebolt damage in maps within this zone to a maximum 50 damage,
+ //Example Below caps Cold Bolt damage in maps within this zone to a maximum 50 damage,
// (depends on HMAP_ZONE_DAMAGE_CAP_TYPE in src/config/core.h)
// when cast vs players and monsters.
//MG_COLDBOLT: (50,"PLAYER | MONSTER")
diff --git a/db/pre-re/skill_db.conf b/db/pre-re/skill_db.conf
index 95683a9e0..a5c27257f 100644
--- a/db/pre-re/skill_db.conf
+++ b/db/pre-re/skill_db.conf
@@ -14881,11 +14881,10 @@ skill_db: (
Range: -9
Hit: "BDT_MULTIHIT"
SkillType: {
- Self: true
+ Enemy: true
}
SkillInfo: {
Spirit: true
- NoCastSelf: true
}
AttackType: "Weapon"
Element: "Ele_Weapon"
diff --git a/db/re/map_zone_db.conf b/db/re/map_zone_db.conf
index 282a85abb..1dd4315b6 100644
--- a/db/re/map_zone_db.conf
+++ b/db/re/map_zone_db.conf
@@ -66,7 +66,7 @@ zones: (
//heal: 70
}
skill_damage_cap: {
- //Exemple Below caps firebolt damage in maps within this zone to a maximum 50 damage,
+ //Example Below caps Cold Bolt damage in maps within this zone to a maximum 50 damage,
// (depends on HMAP_ZONE_DAMAGE_CAP_TYPE in src/config/core.h)
// when cast vs players and monsters.
//MG_COLDBOLT: (50,"PLAYER | MONSTER")
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 77b361498..7015feec1 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -1371,11 +1371,10 @@ Examples:
---------------------------------------
-*getd("<variable name>"{, <GID>{, <default value>}})
+*getd("<variable name>")
Returns a reference to a variable, the name can be constructed dynamically.
-If <GID> is present, it can be used to get a variable from another player or
-npc. If the target player or npc is not found, <default value> is returned.
+Refer to setd() for usage.
This can also be used to set an array dynamically:
setarray(getd(".array[0]"), 1, 2, 3, 4, 5);
@@ -1410,6 +1409,27 @@ getvariableofnpc() should not be used on them.
---------------------------------------
+*getvariableofpc(<variable>, <account id>{, <default value>})
+
+Returns a reference to a PC variable from the target player.
+If <default value> is passed, it will return this value if the player is
+not found.
+
+Examples:
+
+//This will return the value of @var, note that this can't be used, since
+//the value isn't caught.
+ getvariableofpc(@var, getcharid(CHAR_ID_ACCOUNT, "player"));
+
+//This will set the .@v variable to the value of the player's @var
+//variable.
+ .@v = getvariableofpc(@var, getcharid(CHAR_ID_ACCOUNT, "player"));
+
+//This will set the @var variable of the player to 1.
+ set(getvariableofpc(@var, getcharid(CHAR_ID_ACCOUNT, "player")), 1);
+
+---------------------------------------
+
*goto(<label>)
This command will make the script jump to a label, usually used in
diff --git a/npc/re/merchants/shadow_refiner.txt b/npc/re/merchants/shadow_refiner.txt
index 4e5049e5f..2f8984498 100644
--- a/npc/re/merchants/shadow_refiner.txt
+++ b/npc/re/merchants/shadow_refiner.txt
@@ -158,7 +158,7 @@ itemmall,31,76,3 script Shadow Blacksmith#nomal 4_F_JOB_BLACKSMITH,{
}
delitem .@choose,1;
Zeny -= 20000;
- if (getequippercentrefinery(.@SelectedPart) > rand(100) || getequippercentrefinery(.@SelectedPart) > rand(100)) {
+ if (getequippercentrefinery(.@SelectedPart) > rand(100) || ( .@option == 1 && getequippercentrefinery(.@SelectedPart) > rand(100))) {
successrefitem .@SelectedPart;
mes "[Shadow Blacksmith]";
mes "Refine was successful.";
diff --git a/npc/woe-se/agit_main_se.txt b/npc/woe-se/agit_main_se.txt
index c9b34f610..5f291e658 100644
--- a/npc/woe-se/agit_main_se.txt
+++ b/npc/woe-se/agit_main_se.txt
@@ -1681,6 +1681,10 @@ OnEnable:
if (.@num == 3) set getd(".MyMobCount_"+.@num+strnpcinfo(NPC_NAME_HIDDEN)),4;
else if (.@num) set getd(".MyMobCount_"+.@num+strnpcinfo(NPC_NAME_HIDDEN)),6;
setwall strnpcinfo(NPC_NAME_HIDDEN),.@wall[0],.@wall[1],.@wall[2],.@wall[3],.@wall[4],substr(strnpcinfo(NPC_NAME_HIDDEN),0,1)+substr(strnpcinfo(NPC_NAME_HIDDEN),8,9)+"_"+strnpcinfo(NPC_NAME_VISIBLE);
+ if (.@num == 0)
+ setcell(strnpcinfo(NPC_NAME_HIDDEN), .@x[0], .@y[0], .@x[getarraysize(.@x)-1], .@y[getarraysize(.@y)-1], cell_basilica, true);
+ if (.@num == 1 && (strnpcinfo(NPC_NAME_HIDDEN) == "schg_cas01" || strnpcinfo(NPC_NAME_HIDDEN) == "schg_cas04" || strnpcinfo(NPC_NAME_HIDDEN) == "schg_cas05"))
+ setcell(strnpcinfo(NPC_NAME_HIDDEN), .@x[0], .@y[0], .@x[5], .@y[5], cell_basilica, true);
.@j = (getd(".MyMobCount_"+.@num+strnpcinfo(NPC_NAME_HIDDEN)))?getd(".MyMobCount_"+.@num+strnpcinfo(NPC_NAME_HIDDEN)):getarraysize(.@x);
for (.@i = 0; .@i<.@j; ++.@i)
guardian strnpcinfo(NPC_NAME_HIDDEN),.@x[.@i],.@y[.@i]," ",1905,strnpcinfo(NPC_NAME)+"::OnBarrierDestroyed";
@@ -1700,6 +1704,31 @@ OnBarrierDestroyed:
end;
OnDisable:
+ if (compare(strnpcinfo(NPC_NAME_HIDDEN),"arug")) {
+ if (strnpcinfo(NPC_NAME_HIDDEN) == "arug_cas01") {
+ setarray(.@x[0], 239, 245);
+ setarray(.@y[0], 73, 73);
+ } else if (strnpcinfo(NPC_NAME_HIDDEN) == "arug_cas02") {
+ setarray(.@x[0], 137, 143);
+ setarray(.@y[0], 137, 137);
+ } else { // Castles 3, 4, 5 are identical.
+ setarray(.@x[0], 139, 145);
+ setarray(.@y[0], 111, 111);
+ }
+ } else {
+ if (strnpcinfo(NPC_NAME_HIDDEN) == "schg_cas02") {
+ setarray(.@x[0], 289, 289);
+ setarray(.@y[0], 98, 104);
+ } else if (strnpcinfo(NPC_NAME_HIDDEN) == "schg_cas03") {
+ setarray(.@x[0], 326, 330);
+ setarray(.@y[0], 300, 300);
+ } else { // Castles 1, 4, 5 are identical.
+ setarray(.@x[0], 115, 125);
+ setarray(.@y[0], 49, 49);
+ setcell(strnpcinfo(NPC_NAME_HIDDEN), 115, 50, 125, 50, cell_basilica, false);
+ }
+ }
+ setcell(strnpcinfo(NPC_NAME_HIDDEN), .@x[0], .@y[0], .@x[1], .@y[1], cell_basilica, false);
delwall substr(strnpcinfo(NPC_NAME_HIDDEN),0,1)+substr(strnpcinfo(NPC_NAME_HIDDEN),8,9)+"_"+strnpcinfo(NPC_NAME_VISIBLE);
killmonster strnpcinfo(NPC_NAME_HIDDEN),strnpcinfo(NPC_NAME)+"::OnBarrierDestroyed";
end;
diff --git a/src/map/script.c b/src/map/script.c
index a1886d043..faaadb560 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2825,7 +2825,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
char postfix;
struct map_session_data *sd = NULL;
- if( !data_isreference(data) )
+ if (!data_isreference(data))
return data;// not a variable/constant
name = reference_getname(data);
@@ -2840,10 +2840,10 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
}
//##TODO use reference_tovariable(data) when it's confirmed that it works [FlavioJS]
- if( !reference_toconstant(data) && not_server_variable(prefix) ) {
+ if (!reference_toconstant(data) && not_server_variable(prefix) && reference_getref(data) == NULL) {
sd = script->rid2sd(st);
- if( sd == NULL ) {// needs player attached
- if( postfix == '$' ) {// string variable
+ if (sd == NULL) {// needs player attached
+ if (postfix == '$') {// string variable
ShowWarning("script_get_val: cannot access player variable '%s', defaulting to \"\"\n", name);
data->type = C_CONSTSTR;
data->u.str = "";
@@ -2919,7 +2919,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
} else if( reference_toparam(data) ) {
data->u.num = pc->readparam(sd, reference_getparamtype(data));
} else {
- switch(prefix) {
+ switch (prefix) {
case '@':
if (data->ref) {
data->u.num = script->get_val_ref_num(st, data->ref, data);
@@ -2933,7 +2933,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
case '#':
if (data->ref) {
data->u.num = script->get_val_ref_num(st, data->ref, data);
- } else if(name[1] == '#') {
+ } else if (name[1] == '#') {
data->u.num = pc_readaccountreg2(sd, data->u.num);// global
} else {
data->u.num = pc_readaccountreg(sd, data->u.num);// local
@@ -2960,7 +2960,6 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
break;
}
}
-
}
data->ref = NULL;
@@ -3133,38 +3132,43 @@ void script_array_add_member(struct script_array *sa, unsigned int idx) {
**/
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);
- switch( name[0] ) {
+
+ switch (name[0]) {
/* from player */
- default: /* char reg */
- case '@':/* temp char reg */
- case '#':/* account reg */
+ default: /* char reg */
+ case '@':/* temp char reg */
+ case '#':/* account reg */
+ if (ref != NULL) {
+ src = ref;
+ } else {
nullpo_retr(NULL, sd);
src = &sd->regs;
- break;
- case '$':/* map reg */
- src = &mapreg->regs;
- break;
- case '.':/* npc/script */
- if (ref != NULL) {
- src = ref;
- } else {
- nullpo_retr(NULL, st);
- src = (name[1] == '@') ? &st->stack->scope : &st->script->local;
- }
- break;
- case '\'':/* instance */
+ }
+ break;
+ case '$':/* map reg */
+ src = &mapreg->regs;
+ break;
+ case '.':/* npc/script */
+ if (ref != NULL) {
+ src = ref;
+ } else {
nullpo_retr(NULL, st);
- if( st->instance_id >= 0 ) {
- src = &instance->list[st->instance_id].regs;
- }
- break;
+ src = (name[1] == '@') ? &st->stack->scope : &st->script->local;
+ }
+ break;
+ case '\'':/* instance */
+ nullpo_retr(NULL, st);
+ if (st->instance_id >= 0) {
+ src = &instance->list[st->instance_id].regs;
+ }
+ break;
}
- if( src ) {
- if( !src->arrays )
+ if (src) {
+ if (!src->arrays) {
src->arrays = idb_alloc(DB_OPT_BASE);
+ }
return src;
}
return NULL;
@@ -3317,7 +3321,7 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
return 0;
}
- if(is_string_variable(name)) {// string variable
+ if (is_string_variable(name)) {// string variable
const char *str = (const char*)value;
switch (prefix) {
@@ -3329,7 +3333,8 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
}
return 1;
case '$':
- return mapreg->setregstr(num, str);
+ mapreg->setregstr(num, str);
+ return 1;
case '#':
if (ref) {
script->set_reg_ref_str(st, ref, num, name, str);
@@ -3364,16 +3369,17 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
// to a 32bit int, this will lead to overflows! [Panikon]
int val = (int)h64BPTRSIZE(value);
- if(script->str_data[script_getvarid(num)].type == C_PARAM) {
- if( pc->setparam(sd, script->str_data[script_getvarid(num)].val, val) == 0 ) {
- if( st != NULL ) {
+ if (script->str_data[script_getvarid(num)].type == C_PARAM) {
+ if (pc->setparam(sd, script->str_data[script_getvarid(num)].val, val) == 0) {
+ if (st != NULL) {
ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val);
script->reportsrc(st);
// Instead of just stop the script execution we let the character close
// the window if it was open.
st->state = (sd->state.dialog) ? CLOSE : END;
- if( st->state == CLOSE )
+ if(st->state == CLOSE) {
clif->scriptclose(sd, st->oid);
+ }
}
return 0;
}
@@ -3389,7 +3395,8 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
}
return 1;
case '$':
- return mapreg->setreg(num, val);
+ mapreg->setreg(num, val);
+ return 1;
case '#':
if (ref) {
script->set_reg_ref_num(st, ref, num, name, val);
@@ -16549,11 +16556,7 @@ BUILDIN(escape_sql)
return true;
}
-BUILDIN(getd)
-{
- struct block_list *bl = NULL;
- struct map_session_data *sd;
- struct npc_data *nd;
+BUILDIN(getd) {
char varname[100];
const char *buffer;
int elem;
@@ -16563,63 +16566,8 @@ BUILDIN(getd)
if (sscanf(buffer, "%99[^[][%d]", varname, &elem) < 2)
elem = 0;
- if (strlen(varname) < 1) {
- ShowError("script:getd: variable cannot be empty\n");
- script->reportdata(script_getdata(st, 2));
- script_pushnil(st);
- st->state = END;
- return false;
- }
-
- if (script_hasdata(st, 3)) {
- bl = map->id2bl(script_getnum(st, 3));
-
- if (bl == NULL) {
- // being not found, push default value
- if (script_hasdata(st, 4)) {
- script_pushcopy(st, 4);
- } else if (varname[strlen(varname) - 1] == '$') {
- script_pushconststr(st, "");
- } else {
- script_pushint(st, 0);
- }
- return false;
- } else if (bl->type == BL_NPC && (varname[0] != '.' || varname[1] == '@')) {
- ShowError("script:getd: invalid scope (not npc variable)\n");
- script->reportdata(script_getdata(st, 2));
- script_pushnil(st);
- st->state = END;
- return false;
- } else if (bl->type == BL_PC && (varname[0] == '.' || varname[0] == '$' || varname[0] == '\'')) {
- ShowError("script:getd: invalid scope (not pc variable)\n");
- script->reportdata(script_getdata(st, 2));
- script_pushnil(st);
- st->state = END;
- return false;
- }
- }
-
// Push the 'pointer' so it's more flexible [Lance]
-
- if (bl != NULL) {
- switch (bl->type) {
- case BL_PC:
- sd = map->id2sd(bl->id);
- script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem), &sd->regs);
- break;
- case BL_NPC:
- nd = map->id2nd(bl->id);
- script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem), &nd->u.scr.script->local);
- break;
- default:
- ShowError("script:getd: invalid being type (not npc or pc)\n");
- script_pushnil(st);
- st->state = END;
- return false;
- }
- } else {
- script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem), NULL);
- }
+ script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem),NULL);
return true;
}
@@ -17646,6 +17594,55 @@ BUILDIN(getvariableofnpc)
return true;
}
+BUILDIN(getvariableofpc)
+{
+ const char* name;
+ struct script_data* data = script_getdata(st, 2);
+ struct map_session_data *sd = map->id2sd(script_getnum(st, 3));
+
+ if (!data_isreference(data)) {
+ ShowError("script:getvariableofpc: not a variable\n");
+ script->reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return false;
+ }
+
+ name = reference_getname(data);
+
+ switch (*name)
+ {
+ case '#':
+ case '$':
+ case '.':
+ case '\'':
+ ShowError("script:getvariableofpc: illegal scope (not pc variable)\n");
+ script->reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return false;
+ }
+
+ if (sd == NULL)
+ {
+ // player not found, return default value
+ if (script_hasdata(st, 4)) {
+ script_pushcopy(st, 4);
+ } else if (is_string_variable(name)) {
+ script_pushconststr(st, "");
+ } else {
+ script_pushint(st, 0);
+ }
+ return true;
+ }
+
+ if (!sd->regs.vars)
+ sd->regs.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
+
+ script->push_val(st->stack, C_NAME, reference_getuid(data), &sd->regs);
+ return true;
+}
+
/// Opens a warp portal.
/// Has no "portal opening" effect/sound, it opens the portal immediately.
///
@@ -21257,7 +21254,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(md5,"s"),
BUILDIN_DEF(swap,"rr"),
// [zBuffer] List of dynamic var commands --->
- BUILDIN_DEF(getd,"s??"),
+ BUILDIN_DEF(getd,"s"),
BUILDIN_DEF(setd,"sv"),
// <--- [zBuffer] List of dynamic var commands
BUILDIN_DEF(petstat,"i"),
@@ -21305,6 +21302,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(sleep2,"i"),
BUILDIN_DEF(awake,"s"),
BUILDIN_DEF(getvariableofnpc,"rs"),
+ BUILDIN_DEF(getvariableofpc,"ri?"),
BUILDIN_DEF(warpportal,"iisii"),
BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn]
BUILDIN_DEF2(homunculus_mutate,"hommutate","?"),