From ff2dd3a0c696cbcd659837ff736f927fab8937e3 Mon Sep 17 00:00:00 2001 From: ultramage Date: Fri, 4 Jan 2008 12:41:49 +0000 Subject: Modified the map_setcell() code to to use a boolean flag instead of needing SET_ / CLR_ pairs of defines (topic:174323). Also removed script object 'setcell', added script function 'setcell'. - Now you can manipulate cell information without needing @loadnpc - You can also manipulate the terrain ('gat') type itself, using the new cell_walkable, cell_shootable and cell_water constants (currently the implementation uses bit flags too, so to get the type you want, you need to adjust the flags one by one) - This breaks current scripts, so please adjust places that use setcell (also be sure to _only_ use predefined constants, not direct numbers) - Details can be found in the script reference. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12009 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/map.c | 53 ++++++++++++++++++++-------------------- src/map/map.h | 67 ++++++++++++++++++++++----------------------------- src/map/npc.c | 49 ++----------------------------------- src/map/path.c | 4 ++-- src/map/path.h | 4 ++-- src/map/script.c | 28 ++++++++++++++++++++++ src/map/skill.c | 73 +++++++++++++++++++++++--------------------------------- src/map/skill.h | 1 - 8 files changed, 120 insertions(+), 159 deletions(-) (limited to 'src/map') diff --git a/src/map/map.c b/src/map/map.c index 2d11b5725..bc5235192 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -468,7 +468,7 @@ int map_count_oncell(int m, int x, int y, int type) /* * «»«EΎͺΞυΜτψͺΛΜΈͺΔͺ±ͺΏ«Ή«­«Eζ«Λ«Γ«ΘͺςΪχͺΉ */ -struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,int y,int skill_id,struct skill_unit *out_unit) +struct skill_unit* map_find_skill_unit_oncell(struct block_list* target,int x,int y,int skill_id,struct skill_unit* out_unit) { int m,bx,by; struct block_list *bl; @@ -485,10 +485,11 @@ struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,in { if (bl->x != x || bl->y != y || bl->type != BL_SKILL) continue; + unit = (struct skill_unit *) bl; - if (unit==out_unit || !unit->alive || !unit->group || unit->group->skill_id!=skill_id) + if( unit == out_unit || !unit->alive || !unit->group || unit->group->skill_id != skill_id ) continue; - if (battle_check_target(&unit->bl,target,unit->group->target_flag)>0) + if( battle_check_target(&unit->bl,target,unit->group->target_flag) > 0 ) return unit; } return NULL; @@ -2136,12 +2137,12 @@ static int map_cell2gat(struct mapcell cell) /*========================================== * (m,x,y)‚̏σ‘Ԃ𒲂ׂι *------------------------------------------*/ -int map_getcell(int m,int x,int y,cell_t cellchk) +int map_getcell(int m,int x,int y,cell_chk cellchk) { return (m < 0 || m >= MAX_MAP_PER_SERVER) ? 0 : map_getcellp(&map[m],x,y,cellchk); } -int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk) +int map_getcellp(struct map_data* m,int x,int y,cell_chk cellchk) { struct mapcell cell; @@ -2149,10 +2150,7 @@ int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk) //NOTE: this intentionally overrides the last row and column if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1) - { - if(cellchk==CELL_CHKNOPASS) return 1; - return 0; - } + return( cellchk == CELL_CHKNOPASS ); cell = m->cell[x + y*m->xs]; @@ -2213,28 +2211,31 @@ int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk) } /*========================================== - * (m,x,y)‚̏σ‘Τ‚πέ’θ‚·‚ι + * Change the type/flags of a map cell + * 'cell' - which flag to modify + * 'flag' - true = on, false = off *------------------------------------------*/ -void map_setcell(int m,int x,int y,int cell) +void map_setcell(int m, int x, int y, cell_t cell, bool flag) { int j; - if(x<0 || x>=map[m].xs || y<0 || y>=map[m].ys) + + if( m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) return; - j=x+y*map[m].xs; - - switch (cell) { - case CELL_SETNPC: map[m].cell[j].npc = 1; break; - case CELL_CLRNPC: map[m].cell[j].npc = 0; break; - case CELL_SETICEWALL: map[m].cell[j].icewall = 1; break; - case CELL_CLRICEWALL: map[m].cell[j].icewall = 0; break; - case CELL_SETBASILICA: map[m].cell[j].basilica = 1; break; - case CELL_CLRBASILICA: map[m].cell[j].basilica = 0; break; - case CELL_SETLANDPROTECTOR: map[m].cell[j].landprotector = 1; break; - case CELL_CLRLANDPROTECTOR: map[m].cell[j].landprotector = 0; break; - case CELL_SETNOVENDING: map[m].cell[j].novending = 1; break; - case CELL_CLRNOVENDING: map[m].cell[j].novending = 0; break; + + j = x + y*map[m].xs; + + switch( cell ) { + case CELL_WALKABLE: map[m].cell[j].walkable = flag; break; + case CELL_SHOOTABLE: map[m].cell[j].shootable = flag; break; + case CELL_WATER: map[m].cell[j].water = flag; break; + + case CELL_NPC: map[m].cell[j].npc = flag; break; + case CELL_ICEWALL: map[m].cell[j].icewall = flag; break; + case CELL_BASILICA: map[m].cell[j].basilica = flag; break; + case CELL_LANDPROTECTOR: map[m].cell[j].landprotector = flag; break; + case CELL_NOVENDING: map[m].cell[j].novending = flag; break; default: - //map[m].gat[j] = cell; FIXME + ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell); break; } } diff --git a/src/map/map.h b/src/map/map.h index ffa4685fc..2eaf4c2c1 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1107,48 +1107,39 @@ enum _look { LOOK_SHOES }; -// CELLs for non-permanent cell-based effects (Pneuma, Basilica, Npcs, etc) -#define CELL_NPC 0x1 -#define CELL_LANDPROTECTOR 0x10 -#define CELL_BASILICA 0x20 -#define CELL_NOVENDING 0x40 -#define CELL_ICEWALL 0x80 -/* - * map_getcell()‚ΕŽg—p‚³‚κ‚ιƒtƒ‰ƒO - */ +// used by map_setcell() typedef enum { - CELL_GETTYPE, // ƒZƒ‹ƒ^ƒCƒv‚π•Τ‚· + CELL_WALKABLE, + CELL_SHOOTABLE, + CELL_WATER, + + CELL_NPC, + CELL_BASILICA, + CELL_LANDPROTECTOR, + CELL_ICEWALL, + CELL_NOVENDING, +} cell_t; + +// used by map_getcell() +typedef enum { + CELL_GETTYPE, // retrieves a cell's 'gat' type - CELL_CHKWALL, // •Η(ƒZƒ‹ƒ^ƒCƒv1) - CELL_CHKWATER, // …κ(ƒZƒ‹ƒ^ƒCƒv3) - CELL_CHKCLIFF, // ’n–ʏαŠQ•¨(ƒZƒ‹ƒ^ƒCƒv5) + CELL_CHKWALL, // wall (gat type 1) + CELL_CHKWATER, // water (gat type 3) + CELL_CHKCLIFF, // cliff/gap (gat type 5) - CELL_CHKPASS, // ’Κ‰ί‰Β”\(ƒZƒ‹ƒ^ƒCƒv1,5ˆΘŠO) + CELL_CHKPASS, // passable cell (gat type non-1/5) CELL_CHKREACH, // Same as PASS, but ignores the cell-stacking mod. - CELL_CHKNOPASS, // ’Κ‰ί•s‰Β(ƒZƒ‹ƒ^ƒCƒv1,5) + CELL_CHKNOPASS, // non-passable cell (gat types 1 and 5) CELL_CHKNOREACH, // Same as NOPASS, but ignores the cell-stacking mod. + CELL_CHKSTACK, // whether cell is full (reached cell stacking limit) - CELL_CHKNPC=0x10, // ƒ^ƒbƒ`ƒ^ƒCƒv‚ΜNPC(ƒZƒ‹ƒ^ƒCƒv0x80ƒtƒ‰ƒO) - CELL_CHKBASILICA, // ƒoƒWƒŠƒJ(ƒZƒ‹ƒ^ƒCƒv0x40ƒtƒ‰ƒO) + CELL_CHKNPC, + CELL_CHKBASILICA, CELL_CHKLANDPROTECTOR, CELL_CHKICEWALL, - CELL_CHKSTACK, CELL_CHKNOVENDING, -} cell_t; - -// map_setcell()‚ΕŽg—p‚³‚κ‚ιƒtƒ‰ƒO -enum { - CELL_SETNPC=0x10, // ƒ^ƒbƒ`ƒ^ƒCƒv‚ΜNPC‚πƒZƒbƒg - CELL_CLRNPC, - CELL_SETBASILICA, // ƒoƒWƒŠƒJ‚πƒZƒbƒg - CELL_CLRBASILICA, // ƒoƒWƒŠƒJ‚πƒNƒŠƒA - CELL_SETLANDPROTECTOR=0x15, //Set/Clear Magnetic Earth - CELL_CLRLANDPROTECTOR, - CELL_SETICEWALL=0x1b, - CELL_CLRICEWALL, - CELL_SETNOVENDING, - CELL_CLRNOVENDING, -}; +} cell_chk; struct mapcell { @@ -1254,8 +1245,13 @@ struct map_data_other_server { uint16 port; }; +int map_getcell(int,int,int,cell_chk); +int map_getcellp(struct map_data*,int,int,cell_chk); +void map_setcell(int m, int x, int y, cell_t cell, bool flag); + extern struct map_data map[]; extern int map_num; + extern int autosave_interval; extern int minsave_interval; extern int save_settings; @@ -1264,11 +1260,6 @@ extern int night_flag; // 0=day, 1=night [Yor] extern int enable_spy; //Determines if @spy commands are active. extern char db_path[256]; -// gat?Φ§ -int map_getcell(int,int,int,cell_t); -int map_getcellp(struct map_data*,int,int,cell_t); -void map_setcell(int,int,int,int); - extern char motd_txt[]; extern char help_txt[]; extern char help2_txt[]; diff --git a/src/map/npc.c b/src/map/npc.c index f18ba07a1..79747dbf3 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1970,7 +1970,7 @@ void npc_setcells(struct npc_data* nd) for (j = x-xs; j <= x+xs; j++) { if (map_getcell(m, j, i, CELL_CHKNOPASS)) continue; - map_setcell(m, j, i, CELL_SETNPC); + map_setcell(m, j, i, CELL_NPC, true); } } } @@ -2010,7 +2010,7 @@ void npc_unsetcells(struct npc_data* nd) //Erase this npc's cells for (i = y-ys; i <= y+ys; i++) for (j = x-xs; j <= x+xs; j++) - map_setcell(m, j, i, CELL_CLRNPC); + map_setcell(m, j, i, CELL_NPC, false); //Re-deploy NPC cells for other nearby npcs. map_foreachinarea( npc_unsetcells_sub, m, x0, y0, x1, y1, BL_NPC, nd->bl.id ); @@ -2512,47 +2512,6 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con return strchr(start,'\n');// continue } -/*========================================== - * Setting up map cells - *------------------------------------------*/ -static const char* npc_parse_mapcell(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) -{ - int m, cell, x, y, x0, y0, x1, y1; - char type[32], mapname[32]; - - // w1= - // w3=,,,, - if( sscanf(w1, "%31[^,]", mapname) != 1 - || sscanf(w3, "%31[^,],%d,%d,%d,%d", type, &x0, &y0, &x1, &y1) < 5 ) - { - ShowError("npc_parse_mapcell: Invalid mapcell definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); - return strchr(start,'\n');// skip and continue - } - m = map_mapname2mapid(mapname); - if( m < 0 ) - { - ShowWarning("npc_parse_mapcell: Unknown map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", mapname, filepath, strline(buffer,start-buffer), w1, w2, w3, w4); - return strchr(start,'\n');// skip and continue - } - - cell = strtol(type, (char **)NULL, 0); - - if( x0 > x1 ) - swap(x0, x1); - if( y0 > y1 ) - swap(y0, y1); - - for( x = x0; x <= x1; ++x ) - for( y = y0; y <= y1; ++y ) - { - if( map_getcell(m, x, y, CELL_CHKWALL) || map_getcell(m, x, y, CELL_CHKCLIFF) ) - continue; - map_setcell(m, x, y, cell); - } - - return strchr(start,'\n');// continue -} - void npc_parsesrcfile(const char* filepath) { int m, lines = 0; @@ -2678,10 +2637,6 @@ void npc_parsesrcfile(const char* filepath) { p = npc_parse_mapflag(w1, w2, w3, w4, p, buffer, filepath); } - else if( strcmpi(w2,"setcell") == 0 && count >= 3 ) - { - p = npc_parse_mapcell(w1, w2, w3, w4, p, buffer, filepath); - } else { ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4); diff --git a/src/map/path.c b/src/map/path.c index d58adddd0..3316f9657 100644 --- a/src/map/path.c +++ b/src/map/path.c @@ -197,7 +197,7 @@ int path_blownpos(int m,int x0,int y0,int dx,int dy,int count) /*========================================== * is ranged attack from (x0,y0) to (x1,y1) possible? *------------------------------------------*/ -bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_t cell) +bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_chk cell) { int dx, dy; int wx = 0, wy = 0; @@ -270,7 +270,7 @@ bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int * flag: &1 = easy path search only * cell: type of obstruction to check for *------------------------------------------*/ -bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_t cell) +bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_chk cell) { int heap[MAX_HEAP+1]; struct tmp_path tp[MAX_WALKPATH*MAX_WALKPATH]; diff --git a/src/map/path.h b/src/map/path.h index 83992b546..761d9de26 100644 --- a/src/map/path.h +++ b/src/map/path.h @@ -8,10 +8,10 @@ int path_blownpos(int m,int x0,int y0,int dx,int dy,int count); // tries to find a walkable path -bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_t cell); +bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_chk cell); // tries to find a shootable path -bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_t cell); +bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_chk cell); // distance related functions diff --git a/src/map/script.c b/src/map/script.c index a52bf0323..e5bed56a6 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12943,6 +12943,33 @@ BUILDIN_FUNC(openmail) return 0; } +/// Modifies flags of cells in the specified area. +/// +/// setcell "",,,,,,; +/// +/// @see cell_* constants in const.txt for the types +BUILDIN_FUNC(setcell) +{ + int m = map_mapname2mapid(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); + cell_t type = (cell_t)script_getnum(st,7); + bool flag = (bool)script_getnum(st,8); + + int x,y; + + if( x1 > x2 ) swap(x1,x2); + if( y1 > y2 ) swap(y1,y2); + + for( y = y1; y <= y2; ++y ) + for( x = x1; x <= x2; ++x ) + map_setcell(m, x, y, type, flag); + + return 0; +} + // declarations that were supposed to be exported from npc_chat.c #ifdef PCRE_SUPPORT @@ -13285,5 +13312,6 @@ struct script_function buildin_func[] = { BUILDIN_DEF(checkvending,"*"), BUILDIN_DEF(checkchatting,"*"), BUILDIN_DEF(openmail,""), + BUILDIN_DEF(setcell,"siiiiii"), {NULL,NULL,NULL}, }; diff --git a/src/map/skill.c b/src/map/skill.c index 692a94e23..3e8ca67fa 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1996,24 +1996,27 @@ int skill_area_sub_count (struct block_list *src, struct block_list *target, int int skill_count_water (struct block_list *src, int range) { - int i,x,y,cnt = 0,size = range*2+1; + int x,y,cnt = 0; struct skill_unit *unit; - for (i=0;ix+(i%size-range); - y = src->y+(i/size-range); - if (map_getcell(src->m,x,y,CELL_CHKWATER)) { - cnt++; - continue; - } - unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL); - if (!unit) - unit = map_find_skill_unit_oncell(src,x,y,NJ_SUITON,NULL); - if (unit) { - cnt++; - skill_delunit(unit); + for( y = src->y - range; y <= src->y + range; ++y ) + { + for( x = src->x - range; x <= src->x + range; ++x ) + { + if (map_getcell(src->m,x,y,CELL_CHKWATER)) { + cnt++; + continue; + } + unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL); + if (!unit) + unit = map_find_skill_unit_oncell(src,x,y,NJ_SUITON,NULL); + if (unit) { + cnt++; + skill_delunit(unit); + } } } + return cnt; } @@ -7066,6 +7069,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in if (sce) status_change_end(bl,type,-1); break; + case UNT_HERMODE: //Clear Hermode if the owner moved. if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id) status_change_end(bl,type,-1); @@ -8758,33 +8762,16 @@ int skill_frostjoke_scream (struct block_list *bl, va_list ap) /*========================================== * *------------------------------------------*/ -void skill_unitsetmapcell (struct skill_unit *src, int skill_num, int skill_lv, int flag) +static void skill_unitsetmapcell (struct skill_unit *src, int skill_num, int skill_lv, cell_t cell, bool flag) { - int i,x,y,range = skill_get_unit_range(skill_num,skill_lv); - int size = range*2+1; + int range = skill_get_unit_range(skill_num,skill_lv); + int x,y; - for (i=0;ibl.x+(i%size-range); - y = src->bl.y+(i/size-range); - map_setcell(src->bl.m,x,y,flag); - } + for( y = src->bl.y - range; y <= src->bl.y + range; ++y ) + for( x = src->bl.x - range; x <= src->bl.x + range; ++x ) + map_setcell(src->bl.m, x, y, cell, flag); } -/*========================================== - * Sets a map cell around the caster, according to the skill's splash range. - *------------------------------------------*/ -void skill_setmapcell (struct block_list *src, int skill_num, int skill_lv, int flag) -{ - int i,x,y,range = skill_get_splash(skill_num, skill_lv); - int size = range*2+1; - - for (i=0;ix+(i%size-range); - y = src->y+(i/size-range); - map_setcell(src->m,x,y,flag); - } -} - /*========================================== * *------------------------------------------*/ @@ -9241,13 +9228,13 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int switch (group->skill_id) { case SA_LANDPROTECTOR: - skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_SETLANDPROTECTOR); + skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,true); break; case HP_BASILICA: - skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_SETBASILICA); + skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,true); break; case WZ_ICEWALL: - skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_SETICEWALL); + skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,true); break; default: if (group->state.song_dance&0x1) //Check for dissonance. @@ -9282,13 +9269,13 @@ int skill_delunit (struct skill_unit* unit) switch (group->skill_id) { case SA_LANDPROTECTOR: - skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_CLRLANDPROTECTOR); + skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false); break; case HP_BASILICA: - skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_CLRBASILICA); + skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,false); break; case WZ_ICEWALL: - skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_CLRICEWALL); + skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false); break; } diff --git a/src/map/skill.h b/src/map/skill.h index 7b14e537a..1a76e3417 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -225,7 +225,6 @@ int skill_check_unit_cell(int skillid,int m,int x,int y,int unit_id); int skill_unit_out_all( struct block_list *bl,unsigned int tick,int range); int skill_unit_move(struct block_list *bl,unsigned int tick,int flag); int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int dy); -void skill_setmapcell(struct block_list *src, int skill_num, int skill_lv, int flag); struct skill_unit_group *skill_check_dancing( struct block_list *src ); void skill_stop_dancing(struct block_list *src); -- cgit v1.2.3-70-g09d2