Example #1
0
/*==========================================
 * (x,y)が移動不可能地帯かどうか
 * flag 0x10000 遠距離攻撃判定
 *------------------------------------------
 */
static
bool can_place(struct map_local *m, int x, int y)
{
    nullpo_ret(m);

    return !bool(read_gatp(m, x, y) & MapCell::UNWALKABLE);
}
Example #2
0
/*==========================================
 * (x,y)が移動不可能地帯かどうか
 * flag 0x10000 遠距離攻撃判定
 *------------------------------------------
 */
static inline int can_place(struct map_data *m,int x,int y,int flag)
{
	int c=read_gatp(m,x,y);
	if(c==1)
		return 0;
	if(!(flag&0x10000) && c==5)
		return 0;
	return 1;
}
Example #3
0
/*==========================================
 * path探索 (x0,y0)->(x1,y1)
 *------------------------------------------
 */
int path_search(struct walkpath_data *wpd, map_local *m, int x0, int y0, int x1, int y1, int flag)
{
    int heap[MAX_HEAP + 1];
    int i, rp, x, y;
    int dx, dy;

    nullpo_ret(wpd);

    assert (m->gat);
    map_local *md = m;
    if (x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys
        || bool(read_gatp(md, x1, y1) & MapCell::UNWALKABLE))
        return -1;

    // easy
    dx = (x1 - x0 < 0) ? -1 : 1;
    dy = (y1 - y0 < 0) ? -1 : 1;
    for (x = x0, y = y0, i = 0; x != x1 || y != y1;)
    {
        if (i >= sizeof(wpd->path))
            return -1;
        if (x != x1 && y != y1)
        {
            if (!can_move(md, x, y, x + dx, y + dy))
                break;
            x += dx;
            y += dy;
            wpd->path[i++] = (dx < 0)
                ? ((dy > 0) ? DIR::SW : DIR::NW)
                : ((dy < 0) ? DIR::NE : DIR::SE);
        }
        else if (x != x1)
        {
            if (!can_move(md, x, y, x + dx, y))
                break;
            x += dx;
            wpd->path[i++] = (dx < 0) ? DIR::W : DIR::E;
        }
        else
        {                       // y!=y1
            if (!can_move(md, x, y, x, y + dy))
                break;
            y += dy;
            wpd->path[i++] = (dy > 0) ? DIR::S : DIR::N;
        }
        if (x == x1 && y == y1)
        {
            wpd->path_len = i;
            wpd->path_pos = 0;
            wpd->path_half = 0;
            return 0;
        }
    }
    if (flag & 1)
        return -1;

    struct tmp_path tp[MAX_WALKPATH * MAX_WALKPATH] {};

    i = calc_index(x0, y0);
    tp[i].x = x0;
    tp[i].y = y0;
    tp[i].dist = 0;
    tp[i].dir = DIR::S;
    tp[i].before = 0;
    tp[i].cost = calc_cost(&tp[i], x1, y1);
    tp[i].flag = 0;
    heap[0] = 0;
    push_heap_path(heap, tp, calc_index(x0, y0));
    while (1)
    {
        int e = 0;

        if (heap[0] == 0)
            return -1;
        rp = pop_heap_path(heap, tp);
        x = tp[rp].x;
        y = tp[rp].y;
        if (x == x1 && y == y1)
        {
            int len, j;

            for (len = 0, i = rp; len < 100 && i != calc_index(x0, y0);
                 i = tp[i].before, len++);
            if (len == 100 || len >= sizeof(wpd->path))
                return -1;
            wpd->path_len = len;
            wpd->path_pos = 0;
            wpd->path_half = 0;
            for (i = rp, j = len - 1; j >= 0; i = tp[i].before, j--)
                wpd->path[j] = tp[i].dir;

            return 0;
        }
        if (can_move(md, x, y, x + 1, y - 1))
            e += add_path(heap, tp, x + 1, y - 1, tp[rp].dist + 14, DIR::NE, rp, x1, y1);
        if (can_move(md, x, y, x + 1, y))
            e += add_path(heap, tp, x + 1, y, tp[rp].dist + 10, DIR::E, rp, x1, y1);
        if (can_move(md, x, y, x + 1, y + 1))
            e += add_path(heap, tp, x + 1, y + 1, tp[rp].dist + 14, DIR::SE, rp, x1, y1);
        if (can_move(md, x, y, x, y + 1))
            e += add_path(heap, tp, x, y + 1, tp[rp].dist + 10, DIR::S, rp, x1, y1);
        if (can_move(md, x, y, x - 1, y + 1))
            e += add_path(heap, tp, x - 1, y + 1, tp[rp].dist + 14, DIR::SW, rp, x1, y1);
        if (can_move(md, x, y, x - 1, y))
            e += add_path(heap, tp, x - 1, y, tp[rp].dist + 10, DIR::W, rp, x1, y1);
        if (can_move(md, x, y, x - 1, y - 1))
            e += add_path(heap, tp, x - 1, y - 1, tp[rp].dist + 14, DIR::NW, rp, x1, y1);
        if (can_move(md, x, y, x, y - 1))
            e += add_path(heap, tp, x, y - 1, tp[rp].dist + 10, DIR::N, rp, x1, y1);
        tp[rp].flag = 1;
        if (e || heap[0] >= MAX_HEAP - 5)
            return -1;
    }
}
Example #4
0
/*==========================================
 * path探索 (x0,y0)->(x1,y1)
 *------------------------------------------
 */
int path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag)
{
	int heap[MAX_HEAP+1];
	struct tmp_path tp[MAX_WALKPATH*MAX_WALKPATH];
	int i,rp,x,y;
	struct map_data *md;
	int dx,dy;

	if(!map[m].gat)
		return -1;
	md=&map[m];
	if(x1<0 || x1>=md->xs || y1<0 || y1>=md->ys || (i=read_gatp(md,x1,y1))==1 || i==5)
		return -1;

	// easy
	dx = (x1-x0<0) ? -1 : 1;
	dy = (y1-y0<0) ? -1 : 1;
	for(x=x0,y=y0,i=0;x!=x1 || y!=y1;){
		if(i>=sizeof(wpd->path))
			return -1;
		if(x!=x1 && y!=y1){
			if(!can_move(md,x,y,x+dx,y+dy,flag))
				break;
			x+=dx;
			y+=dy;
			wpd->path[i++]=(dx<0) ? ((dy>0)? 1 : 3) : ((dy<0)? 5 : 7);
		} else if(x!=x1){
			if(!can_move(md,x,y,x+dx,y   ,flag))
				break;
			x+=dx;
			wpd->path[i++]=(dx<0) ? 2 : 6;
		} else { // y!=y1
			if(!can_move(md,x,y,x   ,y+dy,flag))
				break;
			y+=dy;
			wpd->path[i++]=(dy>0) ? 0 : 4;
		}
		if(x==x1 && y==y1){
			wpd->path_len=i;
			wpd->path_pos=0;
			wpd->path_half=0;
			return 0;
		}
	}
	if(flag&1)
		return -1;

	memset(tp,0,sizeof(tp));

	i=calc_index(x0,y0);
	tp[i].x=x0;
	tp[i].y=y0;
	tp[i].dist=0;
	tp[i].dir=0;
	tp[i].before=0;
	tp[i].cost=calc_cost(&tp[i],x1,y1);
	tp[i].flag=0;
	heap[0]=0;
	push_heap_path(heap,tp,calc_index(x0,y0));
	while(1){
		int e=0,fromdir;

		if(heap[0]==0)
			return -1;
		rp=pop_heap_path(heap,tp);
		x=tp[rp].x;
		y=tp[rp].y;
		if(x==x1 && y==y1){
			int len,j;

			for(len=0,i=rp;len<100 && i!=calc_index(x0,y0);i=tp[i].before,len++);
			if(len==100 || len>=sizeof(wpd->path))
				return -1;
			wpd->path_len=len;
			wpd->path_pos=0;
			wpd->path_half=0;
			for(i=rp,j=len-1;j>=0;i=tp[i].before,j--)
				wpd->path[j]=tp[i].dir;

			return 0;
		}
		fromdir=tp[rp].dir;
		if(can_move(md,x,y,x+1,y-1,flag))
			e+=add_path(heap,tp,x+1,y-1,tp[rp].dist+14,5,rp,x1,y1);
		if(can_move(md,x,y,x+1,y  ,flag))
			e+=add_path(heap,tp,x+1,y  ,tp[rp].dist+10,6,rp,x1,y1);
		if(can_move(md,x,y,x+1,y+1,flag))
			e+=add_path(heap,tp,x+1,y+1,tp[rp].dist+14,7,rp,x1,y1);
		if(can_move(md,x,y,x  ,y+1,flag))
			e+=add_path(heap,tp,x  ,y+1,tp[rp].dist+10,0,rp,x1,y1);
		if(can_move(md,x,y,x-1,y+1,flag))
			e+=add_path(heap,tp,x-1,y+1,tp[rp].dist+14,1,rp,x1,y1);
		if(can_move(md,x,y,x-1,y  ,flag))
			e+=add_path(heap,tp,x-1,y  ,tp[rp].dist+10,2,rp,x1,y1);
		if(can_move(md,x,y,x-1,y-1,flag))
			e+=add_path(heap,tp,x-1,y-1,tp[rp].dist+14,3,rp,x1,y1);
		if(can_move(md,x,y,x  ,y-1,flag))
			e+=add_path(heap,tp,x  ,y-1,tp[rp].dist+10,4,rp,x1,y1);
		tp[rp].flag=1;
		if(e || heap[0]>=MAX_HEAP-5)
			return -1;
	}
	return -1;
}