1 /*
2  *  Copyright (c) 1997 - 2002 by Volker Meyer & Hansj�rg Malthaner
3  *
4  * This file is part of the Simutrans project under the artistic licence.
5  *
6  *  Description:
7  *      This files describes way objects like electrifications
8  */
9 #ifndef __WAY_OBJ_DESC_H
10 #define __WAY_OBJ_DESC_H
11 
12 #include "image_list.h"
13 #include "obj_base_desc.h"
14 #include "skin_desc.h"
15 #include "../dataobj/ribi.h"
16 #include "../network/checksum.h"
17 
18 
19 class tool_t;
20 class checksum_t;
21 
22 /**
23  * Way objects type description (like overhead lines).
24  *
25  * Child nodes:
26  *	0	Name
27  *	1	Copyright
28  *	2	Image on flat ways
29  *	3	Image on sloped ways
30  *	4	Image on diagonal ways
31  *	5	Skin (cursor and icon)
32  *
33  * @author  Volker Meyer, Hj. Malthaner
34  */
35 class way_obj_desc_t : public obj_desc_transport_infrastructure_t {
36     friend class way_obj_reader_t;
37 
38 private:
39 
40 	/**
41 	 * Type of the object, only overheadlines_wt is currently used.
42 	 */
43 	uint8 own_wtyp;
44 
45 public:
46 
is_overhead_line()47 	bool is_overhead_line() const { return (waytype_t)own_wtyp == overheadlines_wt; }
48 
49 	// way objects can have a front and a backimage, unlike ways ...
get_front_image_id(ribi_t::ribi ribi)50 	image_id get_front_image_id(ribi_t::ribi ribi) const { return get_child<image_list_t>(2)->get_image_id(ribi); }
51 
52 	image_id get_crossing_image_id(ribi_t::ribi ribi, bool nw, bool front = false) const
53 	{
54 		if(  front  &&  !get_child<image_list_t>(2)->get_count()  ) {
55 			return IMG_EMPTY;
56 		}
57 		image_list_t const* const imglist = get_child<image_list_t>(3-front);
58 		// only do this if extended switches are there
59 		if(  imglist->get_count()>16  ) {
60 			static uint8 ribi_to_extra[16] = {
61 				255, 255, 255, 255, 255, 255, 255, 0,
62 				255, 255, 255, 1, 255, 2, 3, 4
63 			};
64 			return imglist->get_image_id( ribi_to_extra[ribi]+16+(nw*5) );
65 		}
66 		// else return standard values
67 		return imglist->get_image_id( ribi );
68 	}
69 
get_back_image_id(ribi_t::ribi ribi)70 	image_id get_back_image_id(ribi_t::ribi ribi) const { return get_child<image_list_t>(3)->get_image_id(ribi); }
71 
get_front_slope_image_id(slope_t::type slope)72 	image_id get_front_slope_image_id(slope_t::type slope) const
73 	{
74 		uint16 nr;
75 		switch(slope) {
76 			case 4:
77 				nr = 0;
78 				break;
79 			case 12:
80 				nr = 1;
81 				break;
82 			case 28:
83 				nr = 2;
84 				break;
85 			case 36:
86 				nr = 3;
87 				break;
88 			case 8:
89 				nr = 4;
90 				break;
91 			case 24:
92 				nr = 5;
93 				break;
94 			case 56:
95 				nr = 6;
96 				break;
97 			case 72:
98 				nr = 7;
99 				break;
100 			default:
101 				return IMG_EMPTY;
102 		}
103 		image_id slope_img = get_child<image_list_t>(4)->get_image_id(nr);
104 		if(  nr > 3  &&  slope_img == IMG_EMPTY  ) {
105 			// hack for old ways without double height images to use single slope images for both
106 			nr -= 4;
107 			slope_img = get_child<image_list_t>(4)->get_image_id(nr);
108 		}
109 		return slope_img;
110 	}
111 
get_back_slope_image_id(slope_t::type slope)112 	image_id get_back_slope_image_id(slope_t::type slope) const
113 	{
114 		uint16 nr;
115 		switch(slope) {
116 			case 4:
117 				nr = 0;
118 				break;
119 			case 12:
120 				nr = 1;
121 				break;
122 			case 28:
123 				nr = 2;
124 				break;
125 			case 36:
126 				nr = 3;
127 				break;
128 			case 8:
129 				nr = 4;
130 				break;
131 			case 24:
132 				nr = 5;
133 				break;
134 			case 56:
135 				nr = 6;
136 				break;
137 			case 72:
138 				nr = 7;
139 				break;
140 			default:
141 				return IMG_EMPTY;
142 		}
143 		image_id slope_img = get_child<image_list_t>(5)->get_image_id(nr);
144 		if(  nr > 3  &&  slope_img == IMG_EMPTY  ) {
145 			// hack for old ways without double height images to use single slope images for both
146 			nr -= 4;
147 			slope_img = get_child<image_list_t>(5)->get_image_id(nr);
148 		}
149 		return slope_img;
150 	}
151 
get_front_diagonal_image_id(ribi_t::ribi ribi)152 	image_id get_front_diagonal_image_id(ribi_t::ribi ribi) const
153 	{
154 		if(!ribi_t::is_bend(ribi)) {
155 			return IMG_EMPTY;
156 		}
157 		return get_child<image_list_t>(6)->get_image_id(ribi / 3 - 1);
158 	}
159 
get_back_diagonal_image_id(ribi_t::ribi ribi)160 	image_id get_back_diagonal_image_id(ribi_t::ribi ribi) const
161 	{
162 		if(!ribi_t::is_bend(ribi)) {
163 			return IMG_EMPTY;
164 		}
165 		return get_child<image_list_t>(7)->get_image_id(ribi / 3 - 1);
166 	}
167 
has_diagonal_image()168 	bool has_diagonal_image() const {
169 		if (get_child<image_list_t>(4)->get_image(0)) {
170 			// has diagonal fontimage
171 			return true;
172 		}
173 		if (get_child<image_list_t>(5)->get_image(0)) {
174 			// or diagonal back image
175 			return true;
176 		}
177 		return false;
178 	}
179 
180 	/**
181 	* Skin: cursor (index 0) and icon (index 1)
182 	* @author Hj. Malthaner
183 	*/
get_cursor()184 	skin_desc_t const* get_cursor() const { return get_child<skin_desc_t>(8); }
185 
186 
calc_checksum(checksum_t * chk)187 	void calc_checksum(checksum_t *chk) const
188 	{
189 		obj_desc_transport_infrastructure_t::calc_checksum(chk);
190 		chk->input(own_wtyp);
191 	}
192 };
193 
194 #endif
195