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://svn.code.sf.net/p/rathena/svn/trunk@12009 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
416f151368
commit
e7bb626a80
@ -4,6 +4,17 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2008/01/04
|
||||
* Modified the map_setcell() code to to use a boolean flag instead of
|
||||
needing SET_ / CLR_ pairs of defines (topic:174323) [ultramage].
|
||||
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.
|
||||
* Fixed Music Lesson's effect on Assassin Cross of Sunset.
|
||||
* Fixed a possible crash in status_change_timer when debug mode is
|
||||
disabled. [Skotlex]
|
||||
@ -13,7 +24,7 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
- removed unused CELL_SAFETYWALL
|
||||
- removed custom CELL_REGEN, it just increased regen rate (r1192, r1518)
|
||||
* Fixed npc unloading not clearing NPC touch cells (bugreport:595)
|
||||
* Map cell mechanism rewrite
|
||||
* Map cell mechanism rewrite (bugreport:426)
|
||||
- defined a data structure for map cells (replaces 3 various cell arrays)
|
||||
- both terrain (gat) and dynamic (cell) information is now stored as
|
||||
C-style bit flags instead of #defines and bitmasks
|
||||
|
14
db/const.txt
14
db/const.txt
@ -224,12 +224,14 @@ mf_nochat 43
|
||||
mf_noexppenalty 44
|
||||
mf_guildlock 45
|
||||
|
||||
cell_wall 1
|
||||
cell_water 3
|
||||
cell_ground 5
|
||||
cell_regen 32
|
||||
cell_basilica 64
|
||||
cell_npc 128
|
||||
cell_walkable 0
|
||||
cell_shootable 1
|
||||
cell_water 2
|
||||
cell_npc 3
|
||||
cell_basilica 4
|
||||
cell_landprotector 5
|
||||
cell_icewall 6
|
||||
cell_novending 7
|
||||
|
||||
StatusPoint 9 1
|
||||
BaseLevel 11 1
|
||||
|
@ -95,6 +95,8 @@
|
||||
//= Corrected various mistakes mentioned in bugreport:373 [ultramage]
|
||||
//= 3.12.20071227
|
||||
//= Corrected description of scope and npc variables. [FlavioJS]
|
||||
//= 3.13.20080104
|
||||
//= Updated 'setcell' desc to match latest code changes [ultramage]
|
||||
//=========================================================
|
||||
|
||||
This document is a reference manual for all the scripting commands and functions
|
||||
@ -390,17 +392,6 @@ The code part is the script code that will execute whenever the function is
|
||||
called with 'callfunc'. It has to be in curly brackets, unlike elsewhere where
|
||||
we use curly brackets, these do NOT signify an optional parameter.
|
||||
|
||||
** Alter a map cell
|
||||
|
||||
<map name>%TAB%setcell%TAB%<type>,<x1>,<y1>,<x2>,<y2>
|
||||
|
||||
This is sneaky, and isn't used in any official scripts, but it will let you
|
||||
define an area (x1/y1-x2/y2 square) of a map as having cell type 'type', where
|
||||
type is a number, which, among other things, defines whether the area is
|
||||
walkable or not, whether it has Basilica working in it or not, and some other
|
||||
things. This is a solution just itching for a problem and there's a number of
|
||||
interesting things you could use it for. Further investigation on what types are
|
||||
valid and mean what exactly is pending.
|
||||
|
||||
Once an object is defined which has a 'code' field to it's definition, it
|
||||
contains script commands which can actually be triggered and executed.
|
||||
@ -6117,6 +6108,46 @@ invoking character.
|
||||
This will recalculate the homunculus stats acording to its level, of the
|
||||
current invoking character.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*setcell "<map name>",<x1>,<y1>,<x2>,<y2>,<type>,<flag>;
|
||||
|
||||
Each map cell has several 'flags' that specify the properties of that cell.
|
||||
These include terrain properties (walkability, shootability, presence of water),
|
||||
skills (basilica, land protector, ...) and other (npc nearby, no vending, ...).
|
||||
Each of these can be 'on' or 'off'. Together they define a cell's behavior.
|
||||
|
||||
This command lets you alter these flags for all map cells in the specified
|
||||
(x1,y1)-(x2,y2) rectangle. The 'flag' can be 0 or 1 (0:clear flag, 1:set flag).
|
||||
The 'type' defines which flag to modify. Possible options include cell_walkable,
|
||||
cell_shootable, cell_basilica. For a full list, see const.txt.
|
||||
|
||||
Example:
|
||||
|
||||
setcell "arena",0,0,300,300,cell_basilica,1;
|
||||
setcell "arena",140,140,160,160,cell_basilica,0;
|
||||
setcell "arena",135,135,165,165,cell_walkable,0;
|
||||
setcell "arena",140,140,160,160,cell_walkable,1;
|
||||
|
||||
This will add a makeshift ring into the center of the map. The ring will be
|
||||
surrounded by a 5-cell wide 'gap' to prevent interference from outside, and
|
||||
the rest of the map will be marked as 'basilica', preventing observers from
|
||||
casting any offensive skills or fighting among themselves. Note that the wall
|
||||
will not be shown nor known client-side, which may cause movement problems.
|
||||
|
||||
Another example:
|
||||
|
||||
OnBarricadeDeploy:
|
||||
setcell "schg_cas05",114,51,125,51,cell_walkable,0;
|
||||
end;
|
||||
OnBarricadeBreak:
|
||||
setcell "schg_cas05",114,51,125,51,cell_walkable,1;
|
||||
end;
|
||||
|
||||
This could be a part of the WoE:SE script, where attackers are not allowed
|
||||
to proceed until all barricades are destroyed. This script would place and
|
||||
remove a nonwalkable row of cells after the barricade mobs.
|
||||
|
||||
---------------------------------------
|
||||
Whew.
|
||||
That's about all of them.
|
||||
|
@ -468,7 +468,7 @@ int map_count_oncell(int m, int x, int y, int type)
|
||||
/*
|
||||
* ォサォ・セェホ<EFBFBD><EFBFBD>ェヒフクェトェアェソォケォュォ・讚ヒォテォネェ<EFBFBD><EFBFBD>ケ
|
||||
*/
|
||||
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)‚ĚŹó‘Ô‚đ<EFBFBD>Ý’č‚·‚é
|
||||
* 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)
|
||||
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;
|
||||
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_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;
|
||||
}
|
||||
}
|
||||
|
@ -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()で使用されるフラグ
|
||||
*/
|
||||
// used by map_setcell()
|
||||
typedef enum {
|
||||
CELL_GETTYPE, // セルタイプを返す
|
||||
CELL_WALKABLE,
|
||||
CELL_SHOOTABLE,
|
||||
CELL_WATER,
|
||||
|
||||
CELL_CHKWALL, // 壁(セルタイプ1)
|
||||
CELL_CHKWATER, // 水場(セルタイプ3)
|
||||
CELL_CHKCLIFF, // 地面障害物(セルタイプ5)
|
||||
|
||||
CELL_CHKPASS, // 通過可能(セルタイプ1,5以外)
|
||||
CELL_CHKREACH, // Same as PASS, but ignores the cell-stacking mod.
|
||||
CELL_CHKNOPASS, // 通過不可(セルタイプ1,5)
|
||||
CELL_CHKNOREACH, // Same as NOPASS, but ignores the cell-stacking mod.
|
||||
|
||||
CELL_CHKNPC=0x10, // タッチタイプのNPC(セルタイプ0x80フラグ)
|
||||
CELL_CHKBASILICA, // バジリカ(セルタイプ0x40フラグ)
|
||||
CELL_CHKLANDPROTECTOR,
|
||||
CELL_CHKICEWALL,
|
||||
CELL_CHKSTACK,
|
||||
CELL_CHKNOVENDING,
|
||||
CELL_NPC,
|
||||
CELL_BASILICA,
|
||||
CELL_LANDPROTECTOR,
|
||||
CELL_ICEWALL,
|
||||
CELL_NOVENDING,
|
||||
} cell_t;
|
||||
|
||||
// map_setcell()で使用されるフラグ
|
||||
enum {
|
||||
CELL_SETNPC=0x10, // タッチタイプのNPCをセット
|
||||
CELL_CLRNPC,
|
||||
CELL_SETBASILICA, // バジリカをセット
|
||||
CELL_CLRBASILICA, // バジリカをクリア
|
||||
CELL_SETLANDPROTECTOR=0x15, //Set/Clear Magnetic Earth
|
||||
CELL_CLRLANDPROTECTOR,
|
||||
CELL_SETICEWALL=0x1b,
|
||||
CELL_CLRICEWALL,
|
||||
CELL_SETNOVENDING,
|
||||
CELL_CLRNOVENDING,
|
||||
};
|
||||
// used by map_getcell()
|
||||
typedef enum {
|
||||
CELL_GETTYPE, // retrieves a cell's 'gat' type
|
||||
|
||||
CELL_CHKWALL, // wall (gat type 1)
|
||||
CELL_CHKWATER, // water (gat type 3)
|
||||
CELL_CHKCLIFF, // cliff/gap (gat type 5)
|
||||
|
||||
CELL_CHKPASS, // passable cell (gat type non-1/5)
|
||||
CELL_CHKREACH, // Same as PASS, but ignores the cell-stacking mod.
|
||||
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,
|
||||
CELL_CHKBASILICA,
|
||||
CELL_CHKLANDPROTECTOR,
|
||||
CELL_CHKICEWALL,
|
||||
CELL_CHKNOVENDING,
|
||||
} 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[];
|
||||
|
@ -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=<mapname>
|
||||
// w3=<type>,<x1>,<y1>,<x2>,<y2>
|
||||
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);
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -12943,6 +12943,33 @@ BUILDIN_FUNC(openmail)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Modifies flags of cells in the specified area.
|
||||
///
|
||||
/// setcell "<map name>",<x1>,<y1>,<x2>,<y2>,<type>,<flag>;
|
||||
///
|
||||
/// @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},
|
||||
};
|
||||
|
@ -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;i<size*size;i++) {
|
||||
x = src->x+(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;i<size*size;i++) {
|
||||
x = src->bl.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;i<size*size;i++) {
|
||||
x = src->x+(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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user