diff options
-rw-r--r-- | db/pre-re/map_zone_db.conf | 2 | ||||
-rw-r--r-- | db/pre-re/skill_db.conf | 3 | ||||
-rw-r--r-- | db/re/map_zone_db.conf | 2 | ||||
-rw-r--r-- | doc/script_commands.txt | 26 | ||||
-rw-r--r-- | npc/re/merchants/shadow_refiner.txt | 2 | ||||
-rw-r--r-- | npc/woe-se/agit_main_se.txt | 29 | ||||
-rw-r--r-- | src/map/script.c | 198 |
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","?"), |