From d9f34370343f92a966d7b16651e2af03db065683 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 3 Oct 2015 23:03:33 +0300 Subject: Add support for air collision. --- src/emap/init.c | 1 + src/emap/map.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++------ src/emap/map.h | 3 +++ 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/emap/init.c b/src/emap/init.c index beff644..f792f0d 100644 --- a/src/emap/init.c +++ b/src/emap/init.c @@ -180,6 +180,7 @@ HPExport void plugin_init (void) addHookPre("map->cell2gat", emap_cell2gat); addHookPre("map->gat2cell", emap_gat2cell); addHookPre("map->getcellp", emap_getcellp); + addHookPre("map->setgatcell", emap_setgatcell); addHookPre("script->set_reg_npc_num", eset_reg_npcscope_num); addHookPre("script->get_val_npc_num", eget_val_npcscope_num); addHookPre("script->get_val_ref_num", eget_val_npcscope_num); diff --git a/src/emap/map.c b/src/emap/map.c index b9f95bd..05f5a7c 100644 --- a/src/emap/map.c +++ b/src/emap/map.c @@ -28,6 +28,31 @@ #include "emap/struct/npcdext.h" #include "emap/struct/sessionext.h" +struct mapcell2 +{ + // terrain flags + unsigned char + walkable : 1, + shootable : 1, + water : 1; + + // dynamic flags + unsigned char + npc : 1, + basilica : 1, + landprotector : 1, + novending : 1, + nochat : 1, + icewall : 1, + noicewall : 1, + + air : 1; + +#ifdef CELL_NOSTACK + int cell_bl; //Holds amount of bls in this cell. +#endif +}; + int emap_addflooritem_post(int retVal, const struct block_list *bl, struct item *item, @@ -142,6 +167,7 @@ void emap_online_list(int fd) // 0000 0x0 - normal // 0001 0x1 - wall walk // 0010 0x2 - water walk +// 0100 0x4 - air walk static int getWalkMask(const struct block_list *bl) @@ -157,7 +183,7 @@ static int getWalkMask(const struct block_list *bl) return walkMask; } -static bool isWalkCell(const struct block_list *bl, struct mapcell cell) +static bool isWalkCell(const struct block_list *bl, struct mapcell2 cell) { if (cell.walkable) return true; @@ -165,6 +191,9 @@ static bool isWalkCell(const struct block_list *bl, struct mapcell cell) // water check if (cell.water && walkMask & 0x2) return true; + // air check + if ((cell.air || cell.water) && walkMask & 0x4) + return true; // wall check if (!cell.walkable && !cell.shootable && walkMask & 0x1) return true; @@ -172,7 +201,7 @@ static bool isWalkCell(const struct block_list *bl, struct mapcell cell) return false; } -static bool isWallCell(const struct block_list *bl, struct mapcell cell) +static bool isWallCell(const struct block_list *bl, struct mapcell2 cell) { if (cell.walkable || cell.shootable) return false; @@ -180,12 +209,16 @@ static bool isWallCell(const struct block_list *bl, struct mapcell cell) // water check if (cell.water && walkMask & 0x2) return false; + if ((cell.air || cell.water) && walkMask & 0x4) + return false; // wall check - if (!cell.walkable && !cell.shootable && walkMask & 0x1) + if (!cell.walkable && !cell.shootable && && walkMask & 0x1) return false; return true; } +#define strangeCast(type, val) *((type*)(&val)) + int emap_getcellp(struct map_data* m, const struct block_list *bl, int16 *xPtr, int16 *yPtr, @@ -199,7 +232,7 @@ int emap_getcellp(struct map_data* m, if (x < 0 || x >= m->xs - 1 || y < 0 || y >= m->ys - 1) return (cellchk == CELL_CHKNOPASS); - struct mapcell cell = m->cell[x + y * m->xs]; + struct mapcell2 cell = strangeCast(struct mapcell2, m->cell[x + y * m->xs]); if (cellchk == CELL_CHKWALL || cellchk == CELL_CHKPASS || @@ -244,7 +277,7 @@ int emap_getcellp(struct map_data* m, struct mapcell emap_gat2cell(int *gatPtr) { - struct mapcell cell; + struct mapcell2 cell; const int gat = *gatPtr; memset(&cell, 0, sizeof(struct mapcell)); @@ -255,26 +288,31 @@ struct mapcell emap_gat2cell(int *gatPtr) cell.walkable = 1; cell.shootable = 1; cell.water = 0; + cell.air = 0; break; case 1: // wall cell.walkable = 0; cell.shootable = 0; cell.water = 0; + cell.air = 0; break; case 2: // air allowed cell.walkable = 0; cell.shootable = 0; cell.water = 0; + cell.air = 1; break; case 3: // unwalkable water cell.walkable = 0; cell.shootable = 1; cell.water = 1; + cell.air = 0; break; case 4: // sit, walkable ground cell.walkable = 1; cell.shootable = 1; cell.water = 0; + cell.air = 0; break; default: ShowWarning("map_gat2cell: unrecognized gat type '%d'\n", gat); @@ -282,20 +320,48 @@ struct mapcell emap_gat2cell(int *gatPtr) } hookStop(); - return cell; + return strangeCast(struct mapcell, cell); } int emap_cell2gat(struct mapcell *cellPtr) { - struct mapcell cell = *cellPtr; + struct mapcell2 cell = *((struct mapcell2*)cellPtr); hookStop(); if (cell.walkable == 1 && cell.shootable == 1 && cell.water == 0) return 0; - if (cell.walkable == 0 && cell.shootable == 0 && cell.water == 0) + if (cell.walkable == 0 && cell.shootable == 0 && cell.water == 0 && cell.air == 0) return 1; + if (cell.walkable == 0 && cell.shootable == 0 && cell.water == 0 && cell.air == 1) + return 2; if (cell.walkable == 0 && cell.shootable == 1 && cell.water == 1) return 3; ShowWarning("map_cell2gat: cell has no matching gat type\n"); return 1; } + +void emap_setgatcell(int16 *mPtr, int16 *xPtr, int16 *yPtr, int *gatPtr) +{ + 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; + + struct mapcell cell0 = map->gat2cell(gat); + struct mapcell2 *cell = (struct mapcell2 *)&cell0; + struct mapcell2 *cell2 = (struct mapcell2 *)&map->list[m].cell[j]; + cell2->walkable = cell->walkable; + cell2->shootable = cell->shootable; + cell2->water = cell->water; + cell2->air = cell->air; +} diff --git a/src/emap/map.h b/src/emap/map.h index 5c6e899..8f03cf9 100644 --- a/src/emap/map.h +++ b/src/emap/map.h @@ -22,5 +22,8 @@ int emap_getcellp(struct map_data* m, cell_chk *cellchkPtr); struct mapcell emap_gat2cell(int *gatPtr); int emap_cell2gat(struct mapcell *cellPtr); +void emap_setgatcell(int16 *mPtr, + int16 *xPtr, int16 *yPtr, + int *gatPtr); #endif // EVOL_MAP_MAP -- cgit v1.2.3-60-g2f50