diff options
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 129 |
1 files changed, 106 insertions, 23 deletions
diff --git a/src/map/script.c b/src/map/script.c index 43f1252c7..b9a826b93 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 @@ -43,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" @@ -11222,10 +11223,15 @@ int buildin_getunits_sub(struct block_list *bl, va_list ap) 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 (index >= SCRIPT_MAX_ARRAYSIZE || *count > limit) { - return 1; + 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, @@ -11235,16 +11241,31 @@ int buildin_getunits_sub(struct block_list *bl, va_list ap) return 0; } +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); +} + BUILDIN(getunits) { - const char *mapname, *name; - int16 m, x1, y1, x2, y2; + 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, limit = script_getnum(st, 4); + uint32 count = 0; + uint32 limit = script_getnum(st, 4); struct map_session_data *sd = NULL; if (!data_isreference(data) || reference_toconstant(data)) { @@ -11277,20 +11298,50 @@ BUILDIN(getunits) limit = SCRIPT_MAX_ARRAYSIZE; } - mapname = script_getstr(st, 5); - m = map->mapname2mapid(mapname); - - if (script_hasdata(st, 9)) { - x1 = script_getnum(st, 6); - y1 = script_getnum(st, 7); - x2 = script_getnum(st, 8); - y2 = script_getnum(st, 9); - - map->foreachinarea(buildin_getunits_sub, m, x1, y1, x2, y2, type, - st, sd, id, start, &count, limit, name, ref); + 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); + + // FIXME: map_foreachinarea does NOT stop iterating when the callback + // function returns -1. we still limit the array size, but + // this doesn't break the loop. We need a foreach function + // that behaves like map_foreachiddb, but for areas + map->foreachinarea(buildin_getunits_sub, m, x1, y1, x2, y2, type, + st, sd, id, start, &count, limit, name, ref, type); + } else { + // FIXME: map_foreachinmap does NOT stop iterating when the callback + // function returns -1. we still limit the array size, but + // this doesn't break the loop. We need a foreach function + // that behaves like map_foreachiddb, but for maps + map->foreachinmap(buildin_getunits_sub, m, type, + st, sd, id, start, &count, limit, name, ref, type); + } } else { - map->foreachinmap(buildin_getunits_sub, m, type, - st, sd, id, start, &count, limit, name, ref); + // 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); @@ -12937,7 +12988,9 @@ BUILDIN(getmapflag) 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; + 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; } } @@ -13063,6 +13116,8 @@ BUILDIN(setmapflag) { 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; } } @@ -19753,7 +19808,7 @@ BUILDIN(getunitdata) #undef getunitdata_sub - return false; + return true; } /** @@ -21862,7 +21917,9 @@ BUILDIN(setcashmount) return true; if (pc_hasmount(sd)) { - clif->msgtable(sd, MSG_REINS_CANT_USE_MOUNTED); +#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]) { @@ -24049,6 +24106,23 @@ BUILDIN(clan_master) return true; } +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) */ @@ -24376,7 +24450,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(deltimer,"s?"), BUILDIN_DEF(addtimercount,"si?"), BUILDIN_DEF(gettimer,"i??"), - BUILDIN_DEF(getunits,"iris????"), + BUILDIN_DEF(getunits,"iri?????"), BUILDIN_DEF(initnpctimer,"??"), BUILDIN_DEF(stopnpctimer,"??"), BUILDIN_DEF(startnpctimer,"??"), @@ -24800,6 +24874,7 @@ void script_parse_builtin(void) { 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(_,"s"), BUILDIN_DEF2(_, "_$", "s"), @@ -25186,6 +25261,14 @@ void script_hardcoded_constants(void) 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("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); |