From 42cd207c4c5f0be387f85f4c89bdcf21929a7f84 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 16 Oct 2015 00:01:32 +0300 Subject: 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" --- src/emap/clif.c | 23 +++++++++++ src/emap/clif.h | 2 + src/emap/init.c | 5 +++ src/emap/map.c | 97 +++++++++++++++++++++++++++++++++++++++++---- src/emap/map.h | 13 ++++++ src/emap/script.c | 21 ++++++++++ src/emap/script.h | 1 + src/emap/send.c | 37 +++++++++++++++++ src/emap/send.h | 10 +++++ src/emap/struct/walldata2.h | 18 +++++++++ 10 files changed, 220 insertions(+), 7 deletions(-) create mode 100644 src/emap/struct/walldata2.h (limited to 'src/emap') 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 -- cgit v1.2.3-70-g09d2