1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
* libtcod 1.6.3
* Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The name of Jice or Mingos may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <fov.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <libtcod_int.h>
#include <libtcod_utility.h>
static int mult[4][8]= {
{1,0,0,-1,-1,0,0,1},
{0,1,-1,0,0,-1,1,0},
{0,1,1,0,0,-1,-1,0},
{1,0,0,1,-1,0,0,-1},
};
static void cast_light(map_t *map,int cx, int cy,int row,float start, float end, int radius, int r2,
int xx, int xy, int yx, int yy, int id, bool light_walls) {
int j;
float new_start=0.0f;
if ( start < end ) return;
for (j=row; j< radius+1; j++) {
int dx=-j-1;
int dy=-j;
bool blocked=false;
while ( dx <= 0 ) {
int X,Y;
dx++;
X=cx+dx*xx+dy*xy;
Y=cy+dx*yx+dy*yy;
if ((unsigned)X < (unsigned)map->width && (unsigned)Y < (unsigned)map->height) {
float l_slope,r_slope;
int offset;
offset=X+Y*map->width;
l_slope=(dx-0.5f)/(dy+0.5f);
r_slope=(dx+0.5f)/(dy-0.5f);
if( start < r_slope ) continue;
else if( end > l_slope ) break;
if ( dx*dx+dy*dy <= r2
&& (light_walls || map->cells[offset].transparent)) map->cells[offset].fov=1;
if ( blocked ) {
if (!map->cells[offset].transparent) {
new_start=r_slope;
continue;
} else {
blocked=false;
start=new_start;
}
} else {
if (!map->cells[offset].transparent && j < radius ) {
blocked=true;
cast_light(map,cx,cy,j+1,start,l_slope,radius,r2,xx,xy,yx,yy,id+1,light_walls);
new_start=r_slope;
}
}
}
}
if ( blocked ) break;
}
}
void TCOD_map_compute_fov_recursive_shadowcasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) {
int oct,c,r2;
map_t *m = (map_t *)map;
/* clean the map */
for (c=m->nbcells-1; c >= 0; c--) {
m->cells[c].fov=0;
}
if ( max_radius == 0 ) {
int max_radius_x=m->width-player_x;
int max_radius_y=m->height-player_y;
max_radius_x=MAX(max_radius_x,player_x);
max_radius_y=MAX(max_radius_y,player_y);
max_radius = (int)(sqrt(max_radius_x*max_radius_x+max_radius_y*max_radius_y))+1;
}
r2=max_radius*max_radius;
/* recursive shadow casting */
for (oct=0; oct < 8; oct++) cast_light(m,player_x,player_y,1,1.0,0.0,max_radius,r2,
mult[0][oct],mult[1][oct],mult[2][oct],mult[3][oct],0,light_walls);
m->cells[player_x+player_y*m->width].fov=1;
}