1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "ultima/nuvie/misc/u6_misc.h"
24 #include "ultima/nuvie/core/map.h"
25 #include "ultima/nuvie/pathfinder/path.h"
26 
27 namespace Ultima {
28 namespace Nuvie {
29 
Path()30 Path::Path()
31 	: path(0), step_count(0), path_size(0), pf(0) {
32 }
33 
~Path()34 Path::~Path() {
35 	delete_path();
36 }
37 
set_path_size(int alloc_size)38 void Path::set_path_size(int alloc_size) {
39 	path_size = alloc_size;
40 	path = (MapCoord *)nuvie_realloc(path, path_size * sizeof(MapCoord));
41 }
42 
43 /* Take estimate of a path, and return the highest allowed score of any nodes
44  * in the search of that path.
45  */
get_max_score(uint32 cost)46 uint32 Path::get_max_score(uint32 cost) {
47 	uint32 max_score = cost * 2;
48 	// search at least this far (else short paths will have too
49 	//                           low of a maximum score to move around walls)
50 	if (max_score < 8 * 2 * 3)
51 		max_score = 8 * 2 * 3;
52 	return (max_score);
53 }
54 
55 /* Return a weighted estimate of the highest cost from location `s' to `g'.
56  */
path_cost_est(MapCoord & s,MapCoord & g)57 uint32 Path::path_cost_est(MapCoord &s, MapCoord &g) {
58 	uint32 major = (s.xdistance(g) >= s.ydistance(g))
59 	               ? s.xdistance(g) : s.ydistance(g);
60 	uint32 minor = (s.xdistance(g) >= s.ydistance(g))
61 	               ? s.ydistance(g) : s.xdistance(g);
62 	return (2 * major + minor);
63 }
64 
65 /* Free and zero path.
66  */
delete_path()67 void Path::delete_path() {
68 	if (path)
69 		free(path);
70 	path = NULL;
71 	step_count = 0;
72 	path_size = 0;
73 }
74 
get_first_step()75 MapCoord Path::get_first_step() {
76 	return (Path::get_step(0));
77 }
78 
get_last_step()79 MapCoord Path::get_last_step() {
80 	return (Path::get_step(step_count - 1));
81 }
82 
get_step(uint32 step_index)83 MapCoord Path::get_step(uint32 step_index) {
84 	MapCoord step(0, 0, 0);
85 	step = path[step_index];
86 	return (step);
87 }
88 
have_path()89 bool Path::have_path() {
90 	return (path && step_count > 0);
91 }
92 
get_path(MapCoord ** path_start,uint32 & pathSize)93 void Path::get_path(MapCoord **path_start, uint32 &pathSize) {
94 	if (path_start)
95 		*path_start = path;
96 	pathSize = step_count;
97 }
98 
99 /* Increases path size in blocks and adds a step to the end of the path. */
add_step(MapCoord loc)100 void Path::add_step(MapCoord loc) {
101 	const int path_block_size = 8;
102 	if (step_count >= path_size) {
103 		path_size += path_block_size;
104 		path = (MapCoord *)nuvie_realloc(path, path_size * sizeof(MapCoord));
105 	}
106 	path[step_count++] = loc;
107 }
108 
remove_first_step()109 bool Path::remove_first_step() {
110 	if (have_path()) {
111 		step_count -= 1;
112 		path_size = step_count;
113 		MapCoord *new_path = (MapCoord *)malloc(path_size * sizeof(MapCoord));
114 		memcpy(new_path, &(path[1]), step_count * sizeof(MapCoord));
115 		free(path);
116 		path = new_path;
117 		return true;
118 	}
119 	return false;
120 }
121 
check_dir(const MapCoord & loc,MapCoord & rel)122 bool Path::check_dir(const MapCoord &loc, MapCoord &rel) {
123 	return pf->check_dir(loc, rel);
124 }
125 
check_loc(const MapCoord & loc)126 bool Path::check_loc(const MapCoord &loc) {
127 	return pf->check_loc(loc);
128 }
129 
130 } // End of namespace Nuvie
131 } // End of namespace Ultima
132