diff options
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 315 |
1 files changed, 248 insertions, 67 deletions
diff --git a/src/map/script.c b/src/map/script.c index 367c9927d..1dc02bf82 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12779,6 +12779,76 @@ BUILDIN(setmapflagnosave) { return true; } +enum mapinfo_info { + MAPINFO_NAME, + MAPINFO_ID, + MAPINFO_SIZE_X, + MAPINFO_SIZE_Y, + MAPINFO_ZONE +}; + +BUILDIN(getmapinfo) +{ + enum mapinfo_info mode = script_getnum(st, 2); + int16 m; + + if (script_hasdata(st, 3)) { + if (script_isstringtype(st, 3)) { + const char *str = script_getstr(st, 3); + m = map->mapname2mapid(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; +} + BUILDIN(getmapflag) { int16 m,i; @@ -12841,6 +12911,7 @@ 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_NOAUTOLOOT: script_pushint(st, map->list[m].flag.noautoloot); break; case MF_NOVIEWID: script_pushint(st,map->list[m].flag.noviewid); break; } } @@ -12965,6 +13036,7 @@ 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; } } @@ -13052,6 +13124,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; } } @@ -14197,31 +14270,36 @@ BUILDIN(setequipoption) if (equip_index > 0 && equip_index <= ARRAYLENGTH(script->equip)) { if ((i = pc->checkequip(sd, script->equip[equip_index - 1])) == -1) { - ShowError("buildin_setequipoptioninfo: No equipment is equipped in the given index %d.\n", equip_index); + ShowError("buildin_setequipoption: No equipment is equipped in the given index %d.\n", equip_index); script_pushint(st, 0); return false; } } else { - ShowError("buildin_setequipoptioninfo: Invalid equipment index %d provided.\n", equip_index); + 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 ((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; + 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; } - /* 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 @@ -15785,19 +15863,38 @@ 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) { - 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; } @@ -18120,6 +18217,8 @@ BUILDIN(setunitdata) 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: @@ -19058,6 +19157,40 @@ BUILDIN(setunitdata) 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); @@ -19468,6 +19601,18 @@ BUILDIN(getunitdata) 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); @@ -20355,15 +20500,18 @@ BUILDIN(questinfo) 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 PACKETVER >= 20170315 + if (icon < 0 || (icon > 10 && icon != 9999)) + icon = 9999; +#elif 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 qi.quest_id = quest_id; qi.icon = (unsigned char)icon; @@ -20557,15 +20705,18 @@ 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 +#if PACKETVER >= 20170315 + if (icon < 0 || (icon > 10 && icon != 9999)) + icon = 9999; +#elif 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 clif->quest_show_event(sd, &nd->bl, icon, color); return true; @@ -21037,72 +21188,90 @@ BUILDIN(has_instance) 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; } @@ -23414,7 +23583,7 @@ BUILDIN(dressroom) clif->dressroom_open(sd, 0); break; default: - ShowWarning("script:dressroom: unknown mode (%i).\n", mode); + ShowWarning("script:dressroom: unknown mode (%u).\n", mode); script_pushint(st, 0); return false; } @@ -23994,6 +24163,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"), @@ -24070,7 +24240,7 @@ void script_parse_builtin(void) { 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] @@ -24597,6 +24767,10 @@ void script_hardcoded_constants(void) 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); @@ -24648,6 +24822,13 @@ void script_hardcoded_constants(void) 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("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); |