summaryrefslogtreecommitdiff
path: root/src/emap
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-10-16 00:01:32 +0300
committerAndrei Karas <akaras@inbox.ru>2015-10-16 00:02:53 +0300
commit42cd207c4c5f0be387f85f4c89bdcf21929a7f84 (patch)
tree59c38e8d75180a252419af867d747191faa361a2 /src/emap
parentab731862f899dd87b84613ebf12a82cdc73e094f (diff)
downloadplugin-42cd207c4c5f0be387f85f4c89bdcf21929a7f84.tar.gz
plugin-42cd207c4c5f0be387f85f4c89bdcf21929a7f84.tar.bz2
plugin-42cd207c4c5f0be387f85f4c89bdcf21929a7f84.tar.xz
plugin-42cd207c4c5f0be387f85f4c89bdcf21929a7f84.zip
Add script function and packet to set group of cells to given mask (gat value)
New script function: setcells "map name", x1, y1, x2, y2, mask, "wall name"
Diffstat (limited to 'src/emap')
-rw-r--r--src/emap/clif.c23
-rw-r--r--src/emap/clif.h2
-rw-r--r--src/emap/init.c5
-rw-r--r--src/emap/map.c97
-rw-r--r--src/emap/map.h13
-rw-r--r--src/emap/script.c21
-rw-r--r--src/emap/script.h1
-rw-r--r--src/emap/send.c37
-rw-r--r--src/emap/send.h10
-rw-r--r--src/emap/struct/walldata2.h18
10 files changed, 220 insertions, 7 deletions
diff --git a/src/emap/clif.c b/src/emap/clif.c
index 4eec6a6..5618848 100644
--- a/src/emap/clif.c
+++ b/src/emap/clif.c
@@ -412,6 +412,17 @@ int eclif_send_actual(int *fd, void *buf, int *len)
return 0;
}
}
+ if (packet == 0xb1b)
+ {
+ struct SessionExt *data = session_get(*fd);
+ if (!data)
+ return 0;
+ if (data->clientVersion < 14)
+ { // not sending new packets to old clients
+ hookStop();
+ return 0;
+ }
+ }
}
return 0;
}
@@ -450,10 +461,22 @@ void eclif_move(struct unit_data *ud)
send_advmoving(ud, false, ud->bl, AREA_WOS);
}
+bool tempChangeMap;
+
void eclif_parse_LoadEndAck_pre(int *fdPtr __attribute__ ((unused)),
struct map_session_data *sd)
{
sd->state.warp_clean = 0;
+ tempChangeMap = sd->state.changemap;
+}
+
+void eclif_parse_LoadEndAck_post(int *fdPtr __attribute__ ((unused)),
+ struct map_session_data *sd)
+{
+ if (!tempChangeMap)
+ { // some messages not sent if map not changed
+ map->iwall_get(sd);
+ }
}
void eclif_changelook2(struct block_list *bl, int type, int val,
diff --git a/src/emap/clif.h b/src/emap/clif.h
index 9fa2adc..43c423c 100644
--- a/src/emap/clif.h
+++ b/src/emap/clif.h
@@ -24,6 +24,8 @@ void eclif_set_unit_walking(struct block_list* bl, TBL_PC *tsd,
void eclif_move(struct unit_data *ud);
void eclif_parse_LoadEndAck_pre(int *fdPtr,
struct map_session_data *sd);
+void eclif_parse_LoadEndAck_post(int *fdPtr,
+ struct map_session_data *sd);
void eclif_changelook2(struct block_list *bl, int type, int val,
struct item_data *id, int n);
void eclif_getareachar_item(struct map_session_data *sd, struct flooritem_data *fitem);
diff --git a/src/emap/init.c b/src/emap/init.c
index 271f98a..7f84c95 100644
--- a/src/emap/init.c
+++ b/src/emap/init.c
@@ -127,6 +127,7 @@ HPExport void plugin_init (void)
addScriptCommand("isstr", "v", isStr);
addScriptCommand("setbgteam", "ii", setBgTeam);
addScriptCommand("checknpccell", "siii", checkNpcCell);
+ addScriptCommand("setcells", "siiiiis", setCells);
do_init_langs();
@@ -185,6 +186,9 @@ HPExport void plugin_init (void)
addHookPre("map->gat2cell", emap_gat2cell);
addHookPre("map->getcellp", emap_getcellp);
addHookPre("map->setgatcell", emap_setgatcell);
+ addHookPre("map->iwall_set", emap_iwall_set);
+ addHookPre("map->iwall_get", emap_iwall_get);
+ addHookPre("map->iwall_remove", emap_iwall_remove);
addHookPre("script->get_val_npc_num", eget_val_npcscope_num);
addHookPre("script->get_val_ref_num", eget_val_npcscope_num);
addHookPre("script->get_val_npc_str", eget_val_npcscope_str);
@@ -199,6 +203,7 @@ HPExport void plugin_init (void)
addHookPost("clif->authok", eclif_authok_post);
addHookPost("clif->changemap", eclif_changemap_post);
addHookPost("clif->set_unit_idle", eclif_set_unit_idle_post);
+ addHookPost("clif->pLoadEndAck", eclif_parse_LoadEndAck_post);
addHookPost("status->set_viewdata", estatus_set_viewdata_post);
addHookPost("status->read_job_db_sub", estatus_read_job_db_sub);
addHookPost("status->calc_pc_", estatus_calc_pc__post);
diff --git a/src/emap/map.c b/src/emap/map.c
index f47d929..efbb7e9 100644
--- a/src/emap/map.c
+++ b/src/emap/map.c
@@ -29,6 +29,7 @@
#include "emap/struct/mobdext.h"
#include "emap/struct/npcdext.h"
#include "emap/struct/sessionext.h"
+#include "emap/struct/walldata2.h"
struct mapcell2
{
@@ -355,22 +356,17 @@ int emap_cell2gat(struct mapcell *cellPtr)
return 1;
}
-void emap_setgatcell(int16 *mPtr, int16 *xPtr, int16 *yPtr, int *gatPtr)
+void emap_setgatcell2(int16 m, int16 x, int16 y, int gat)
{
int j;
- const int16 m = *mPtr;
- const int16 x = *xPtr;
- const int16 y = *yPtr;
- const int gat = *gatPtr;
-
if (m < 0 || m >= map->count ||
x < 0 || x >= map->list[m].xs || y < 0 || y >= map->list[m].ys)
{
return;
}
- j = x + y*map->list[m].xs;
+ j = x + y * map->list[m].xs;
struct mapcell cell0 = map->gat2cell(gat);
struct mapcell2 *cell = (struct mapcell2 *)&cell0;
@@ -381,3 +377,90 @@ void emap_setgatcell(int16 *mPtr, int16 *xPtr, int16 *yPtr, int *gatPtr)
cell2->air = cell->air;
cell2->wall = cell->wall;
}
+
+void emap_setgatcell(int16 *mPtr, int16 *xPtr, int16 *yPtr, int *gatPtr)
+{
+ emap_setgatcell2(*mPtr, *xPtr, *yPtr, *gatPtr);
+ hookStop();
+}
+
+bool emap_iwall_set(int16 *m, int16 *x, int16 *y, int *size, int8 *dir, bool *shootable, const char* wall_name)
+{
+ ShowError("Unsupported set wall function\n");
+ return false;
+}
+
+void emap_iwall_get(struct map_session_data *sd)
+{
+ if (!sd || map->list[sd->bl.m].iwall_num < 1)
+ return;
+
+ DBIterator* iter = db_iterator(map->iwall_db);
+ struct WallData *wall;
+ for (wall = dbi_first(iter); dbi_exists(iter); wall = dbi_next(iter))
+ {
+ if (wall->m != sd->bl.m)
+ continue;
+ send_setwall_single(sd->fd, wall->m, wall->x1, wall->y1 , wall->x2 , wall->y2 , wall->mask);
+ }
+ dbi_destroy(iter);
+}
+
+void emap_iwall_remove(const char *name)
+{
+ struct WallData *wall;
+
+ if ((wall = (struct WallData *)strdb_get(map->iwall_db, name)) == NULL)
+ return; // Nothing to do
+
+ int x;
+ int y;
+ int mask = 0;
+ int x1 = wall->x1;
+ int y1 = wall->y1;
+ int x2 = wall->x2;
+ int y2 = wall->y2;
+ int m = wall->m;
+ for (y = y1; y <= y2; y ++)
+ {
+ for (x = x1; x <= x2; x ++)
+ emap_setgatcell2(m, x, y, mask); // default collision can be lost
+ }
+
+ send_setwall(m, x1, y1, x2, y2, mask, ALL_SAMEMAP);
+ map->list[wall->m].iwall_num--;
+ strdb_remove(map->iwall_db, wall->name);
+}
+
+bool emap_iwall_set2(int m, int x1, int y1, int x2, int y2, int mask, const char *name)
+{
+ struct WallData *wall;
+
+ if (!name)
+ return false;
+
+ if ((wall = (struct WallData *)strdb_get(map->iwall_db, name)) != NULL)
+ return false; // Already Exists
+
+ CREATE(wall, struct WallData, 1);
+ wall->m = m;
+ wall->x1 = x1;
+ wall->y1 = y1;
+ wall->x2 = x2;
+ wall->y2 = y2;
+ wall->mask = mask;
+ safestrncpy(wall->name, name, sizeof(wall->name));
+
+ int x;
+ int y;
+ for (y = y1; y <= y2; y ++)
+ {
+ for (x = x1; x <= x2; x ++)
+ emap_setgatcell2(m, x, y, mask);
+ }
+ send_setwall(m, x1, y1, x2, y2, mask, ALL_SAMEMAP);
+
+ strdb_put(map->iwall_db, wall->name, wall);
+ map->list[m].iwall_num++;
+ return true;
+}
diff --git a/src/emap/map.h b/src/emap/map.h
index 8f03cf9..f0bf8d5 100644
--- a/src/emap/map.h
+++ b/src/emap/map.h
@@ -25,5 +25,18 @@ int emap_cell2gat(struct mapcell *cellPtr);
void emap_setgatcell(int16 *mPtr,
int16 *xPtr, int16 *yPtr,
int *gatPtr);
+bool emap_iwall_set(int16 *m,
+ int16 *x, int16 *y,
+ int *size,
+ int8 *dir,
+ bool *shootable,
+ const char* wall_name);
+void emap_iwall_get(struct map_session_data *sd);
+void emap_iwall_remove(const char *name);
+bool emap_iwall_set2(int m,
+ int x1, int y1,
+ int x2, int y2,
+ int mask,
+ const char *name);
#endif // EVOL_MAP_MAP
diff --git a/src/emap/script.c b/src/emap/script.c
index 7eaa074..530a13f 100644
--- a/src/emap/script.c
+++ b/src/emap/script.c
@@ -26,6 +26,7 @@
#include "emap/script.h"
#include "emap/clif.h"
#include "emap/lang.h"
+#include "emap/map.h"
#include "emap/scriptdefines.h"
#include "emap/send.h"
#include "emap/data/bgd.h"
@@ -1806,3 +1807,23 @@ BUILDIN(checkNpcCell)
return true;
}
+
+BUILDIN(setCells)
+{
+ int m;
+
+ const char *mapname = script_getstr(st, 2);
+ int x1 = script_getnum(st, 3);
+ int y1 = script_getnum(st, 4);
+ int x2 = script_getnum(st, 5);
+ int y2 = script_getnum(st, 6);
+ int mask = script_getnum(st, 7);
+ const char *name = script_getstr(st, 8);
+
+ if ((m = map->mapname2mapid(mapname)) < 0)
+ return true; // Invalid Map
+
+ emap_iwall_set2(m, x1, y1, x2, y2, mask, name);
+
+ return true;
+}
diff --git a/src/emap/script.h b/src/emap/script.h
index 8e6ad3c..ca00e6e 100644
--- a/src/emap/script.h
+++ b/src/emap/script.h
@@ -60,5 +60,6 @@ BUILDIN(npcWalkTo);
BUILDIN(setBgTeam);
BUILDIN(chatJoin);
BUILDIN(checkNpcCell);
+BUILDIN(setCells);
#endif // EVOL_MAP_SCRIPT
diff --git a/src/emap/send.c b/src/emap/send.c
index 29e5d86..ccd4214 100644
--- a/src/emap/send.c
+++ b/src/emap/send.c
@@ -397,3 +397,40 @@ void send_changelook2(struct map_session_data* sd, struct block_list *bl, int id
}
clif->send(buf, 19, bl, target);
}
+
+void send_setwall(int m, int x1, int y1, int x2, int y2, int mask, enum send_target target)
+{
+ unsigned char buf[50];
+
+ WBUFW(buf, 0) = 0xb1b;
+ WBUFW(buf, 2) = x1;
+ WBUFW(buf, 4) = y1;
+ WBUFW(buf, 6) = x2;
+ WBUFW(buf, 8) = y2;
+ WBUFL(buf, 10) = mask;
+ mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name,(char*)WBUFP(buf, 14));
+
+ struct block_list dummy_bl;
+ dummy_bl.type = BL_NUL;
+ dummy_bl.x = x1;
+ dummy_bl.y = y1;
+ dummy_bl.m = m;
+ clif->send(buf, 30, &dummy_bl, target);
+}
+
+void send_setwall_single(int fd, int m, int x1, int y1, int x2, int y2, int mask)
+{
+ struct SessionExt *data = session_get(fd);
+ if (!data || data->clientVersion < 14)
+ return;
+
+ WFIFOHEAD (fd, 28);
+ WFIFOW(fd, 0) = 0xb1b;
+ WFIFOW(fd, 2) = x1;
+ WFIFOW(fd, 4) = y1;
+ WFIFOW(fd, 6) = x2;
+ WFIFOW(fd, 8) = y2;
+ WFIFOL(fd, 10) = mask;
+ mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name,(char*)WFIFOP(fd, 14));
+ WFIFOSET(fd, 30);
+}
diff --git a/src/emap/send.h b/src/emap/send.h
index 0addd9d..b11b0a7 100644
--- a/src/emap/send.h
+++ b/src/emap/send.h
@@ -33,5 +33,15 @@ void send_changelook2(struct map_session_data* sd, struct block_list *bl,
int id, int type,
int val, int val2, struct item_data *data, int n,
enum send_target target);
+void send_setwall(int m,
+ int x1, int y1,
+ int x2, int y2,
+ int mask,
+ enum send_target target);
+void send_setwall_single(int fd,
+ int m,
+ int x1, int y1,
+ int x2, int y2,
+ int mask);
#endif // EVOL_MAP_PC
diff --git a/src/emap/struct/walldata2.h b/src/emap/struct/walldata2.h
new file mode 100644
index 0000000..781ebb3
--- /dev/null
+++ b/src/emap/struct/walldata2.h
@@ -0,0 +1,18 @@
+// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// Copyright (c) 2014 - 2015 Evol developers
+
+#ifndef EVOL_MAP_WALLDATA
+#define EVOL_MAP_WALLDATA
+
+struct WallData
+{
+ char name[50];
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ int mask;
+ int m;
+};
+
+#endif // EVOL_MAP_WALLDATA