/[anoncvs]/projects/roguelike/World.cpp


UCC Code Repository

Contents of /projects/roguelike/World.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.18 - (show annotations) (download)
Fri May 12 06:18:30 2006 UTC (14 years, 11 months ago) by banana
Branch: MAIN
CVS Tags: HEAD
Changes since 1.17: +2 -1 lines
Starting design of class system

1 #include "World.h"
2 #include "port.h"
3 using namespace std;
4
5 /***********
6 * Internal *
7 ***********/
8
9 bool fov_test(void *map, int x, int y) {
10 World *world = reinterpret_cast<World*>(map);
11 if (x >= 0 && y >= 0)
12 return (!(world->at(x, y).terrain->transparent()) || world->at(x, y).character != NULL);
13 else
14 return false;
15 }
16
17 void fov_apply(void *map, int x, int y, int dx, int dy, void *src) {
18 World *world = reinterpret_cast<World*>(map);
19 vector<vector<bool> > *cache = reinterpret_cast<vector<vector<bool> > *>(src);
20
21 if (y >= 0 && x >= 0) {
22 cache->at(y)[x] = true;
23 world->remember(x, y);
24 }
25 }
26
27 void World::initLOSCache() {
28
29 fov_settings_init(&libfov_settings);
30 fov_settings_set_opaque_apply(&libfov_settings, FOV_OPAQUE_APPLY);
31 fov_settings_set_opacity_test_function(&libfov_settings, &fov_test);
32 fov_settings_set_apply_lighting_function(&libfov_settings, &fov_apply);
33 //fov_settings_set_shape(&libfov_settings, FOV_SHAPE_CIRCLE);
34
35 updateLOSCache();
36 }
37
38 void World::updateLOSCache() {
39 for (int y = 0; y < height; y++)
40 for (int x = 0; x < width; x++)
41 LOSCache[y][x] = false;
42 LOSCache[py][px] = true;
43
44 fov_circle(&libfov_settings, this, &LOSCache, px, py, max(width, height)/2);
45 }
46
47 void World::init() {
48 //Initialise the world empty of characters
49 for (int y = 0; y < height; y++) {
50 characters.push_back(vector<Character*>());
51 for (int x = 0; x < width; x++) {
52 characters[y].push_back(NULL);
53 }
54 }
55 for (int y = 0; y < height; y++) {
56 LOSCache.push_back(vector<bool>());
57 for (int x = 0; x < width; x++) {
58 LOSCache[y].push_back(false);
59 }
60 }
61 for (int y = 0; y < height; y++) {
62 memoryCache.push_back(vector<bool>());
63 for (int x = 0; x < width; x++) {
64 memoryCache[y].push_back(false);
65 }
66 }
67 }
68
69 /***************
70 * Constructors *
71 ***************/
72
73 World::World(int x, int y) {
74 name = L"";
75 width = x;
76 height = y;
77 time = 0;
78
79 //Initialise the world to a grid of dots
80 Terrain *loc;
81 for (y = 0; y < height; y++) {
82 terrains.push_back(vector<Terrain*>());
83 for (x = 0; x < width; x++) {
84 loc = new Terrain(0);
85 terrains[y].push_back(loc);
86 }
87 }
88
89 init();
90 }
91
92 World::World(wstring n, int x, int y, vector<vector<int> > &t) {
93 name = n;
94 width = x;
95 height = y;
96 time = 0;
97
98 //Initialise the world with a grid of terrain IDs
99 Terrain *loc;
100 for (y = 0; y < height; y++) {
101 terrains.push_back(vector<Terrain*>());
102 for (x = 0; x < width; x++) {
103 loc = new Terrain(t[y][x]);
104 terrains[y].push_back(loc);
105 }
106 }
107
108 init();
109 }
110
111 /************
112 * Accessors *
113 ************/
114
115 //Simple data members. Technically these could just be public.
116 int World::getWidth() {
117 return width;
118 }
119
120 int World::getHeight() {
121 return height;
122 }
123
124 //This is for use by functions like render, which want to know everything about a square (x, y)
125 World::location World::at(int x, int y) {
126 location loc;
127
128 loc.terrain = terrains[y][x]; //Exactly 1 terrain
129 loc.character = characters[y][x]; //Either 0 or 1 characters
130 loc.los = LOSCache[y][x];
131 loc.memory = memoryCache[y][x];
132
133 return loc;
134 }
135
136 /***********
137 * Mutators *
138 ***********/
139
140 void World::add(Character *c, int x, int y) {
141 characters[y][x] = c;
142 c->x = x;
143 c->y = y;
144
145 //Add the character to the action queue
146 c->time = time;
147 actors.push_front(c);
148 }
149
150 void World::add(Player *p, int x, int y) {
151 px = x;
152 py = y;
153
154 add((Character*)p, x, y);
155
156 initLOSCache();
157 }
158
159 //Mark a square empty - it's assumed that the caller deleted the character here already
160 void World::remove(int x, int y) {
161 characters[y][x] = NULL;
162 }
163
164 void World::remember(int x, int y) {
165 memoryCache[y][x] = memoryCache[y][x] || terrains[y][x]->memorable();
166 }
167
168 /*************
169 * Procedures *
170 *************/
171
172 //This handles an _attempt_ by c to move to (x, y). If there's something there, consequences occur.
173 void World::move(Character *c, int x, int y) {
174 if (characters[y][x]) { //Collision
175 c->time += c->attackDelay();
176 printf("%lu: %ls attacks!\n", time, c->describe().c_str());
177 } else if (terrains[y][x]->traversable()) {
178 characters[y][x] = c;
179 characters[c->y][c->x] = NULL;
180
181 c->x = x;
182 c->y = y;
183 c->time += c-> moveDelay();
184
185 updateLOSCache();
186 }
187 }
188
189 //Loop through all characters, advancing time, until one (the player) requires input to act
190 void World::act() {
191 Character *c;
192
193 bool requiresInput = false;
194
195 while (!requiresInput) {
196 //Sort the list
197 c = actors.front(); //C may have just acted and therefore need to move
198 actors.pop_front(); //Take C out
199 list<Character*>::iterator i; //Move this iterator to something with higher time than c
200 for (i = actors.begin(); i != actors.end() && c->time >= (*i)->time; i++);
201 actors.insert(i, c); //Reinsert C
202
203 //Run AI, or wait for player input
204 c = actors.front();
205 time = c->time;
206 requiresInput = c->act();
207 }
208 }

Managed by UCC Webmasters ViewVC Help
Powered by ViewVC 1.1.26