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.c129
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);