forked from jamespetts/simutrans-extended
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wolke.cc
179 lines (139 loc) · 3.62 KB
/
wolke.cc
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
* This file is part of the Simutrans-Extended project under the Artistic License.
* (see LICENSE.txt)
*/
#include <stdio.h>
#include <string.h>
#include "../simworld.h"
#include "simobj.h"
#include "../utils/simrandom.h"
#include "wolke.h"
#include "../dataobj/loadsave.h"
#include "../tpl/vector_tpl.h"
vector_tpl<const skin_desc_t *>wolke_t::all_clouds(0);
bool wolke_t::register_desc(const skin_desc_t* desc)
{
// avoid duplicates with same name
for(skin_desc_t const* & i : all_clouds) {
if (strcmp(i->get_name(), desc->get_name()) == 0) {
i = desc;
return true;
}
}
return all_clouds.append_unique( desc );
}
wolke_t::wolke_t(koord3d pos, sint8 x_off, sint8 y_off, const skin_desc_t* desc ) :
#ifdef INLINE_OBJ_TYPE
obj_no_info_t(obj_t::sync_wolke, pos)
#else
obj_no_info_t(pos)
#endif
{
cloud_nr = all_clouds.index_of(desc);
base_y_off = clamp( (sint16)y_off - 8, -128, 127 );
set_xoff( x_off );
set_yoff( base_y_off );
purchase_time = 0;
}
wolke_t::~wolke_t()
{
mark_image_dirty( get_image(), 0 );
if( purchase_time != 2499 ) {
welt->sync_way_eyecandy.remove( this );
}
}
wolke_t::wolke_t(loadsave_t* const file) :
#ifdef INLINE_OBJ_TYPE
obj_no_info_t(obj_t::sync_wolke)
#else
obj_no_info_t()
#endif
{
rdwr(file);
}
image_id wolke_t::get_image() const
{
const skin_desc_t *desc = all_clouds[cloud_nr];
return desc->get_image_id( (purchase_time*desc->get_count())/2500 );
}
void wolke_t::rdwr(loadsave_t *file)
{
// not saving clouds! (and loading only for compatibility)
assert(file->is_loading());
obj_t::rdwr( file );
cloud_nr = 0;
purchase_time = 0;
uint32 ldummy = 0;
file->rdwr_long(ldummy);
uint16 dummy = 0;
file->rdwr_short(dummy);
file->rdwr_short(dummy);
// do not remove from this position, since there will be nothing
obj_t::set_flag(obj_t::not_on_map);
}
sync_result wolke_t::sync_step(uint32 delta_t)
{
const image_id old_img = get_image();
purchase_time += delta_t;
if (purchase_time >= 2499) {
// delete wolke ...
purchase_time = 2499;
return SYNC_DELETE;
}
const image_id new_img = get_image();
// move cloud up
const sint8 new_yoff = base_y_off - ((purchase_time * OBJECT_OFFSET_STEPS) >> 12);
if (new_yoff != get_yoff() || new_img != old_img) {
// move/change cloud ... (happens much more often than image change => image change will be always done when drawing)
if (!get_flag(obj_t::dirty)) {
set_flag(obj_t::dirty);
mark_image_dirty(old_img, 0);
if (new_img != old_img) {
mark_image_dirty(new_img, 0);
}
}
set_yoff(new_yoff);
}
return SYNC_OK;
}
// called during map rotation
void wolke_t::rotate90()
{
// restore pure yoff
set_yoff( base_y_off + 8 );
obj_t::rotate90();
// .. and recalc smoke offsets
base_y_off = clamp( (sint16)get_yoff()-8, -128, 127 );
set_yoff( base_y_off - ((purchase_time*OBJECT_OFFSET_STEPS) >> 12) );
}
/***************************** just for compatibility, the old raucher and smoke clouds *********************************/
raucher_t::raucher_t(loadsave_t *file) :
#ifdef INLINE_OBJ_TYPE
obj_t(obj_t::raucher)
#else
obj_t()
#endif
{
assert(file->is_loading());
obj_t::rdwr( file );
const char *s = NULL;
file->rdwr_str(s);
free(const_cast<char *>(s));
// do not remove from this position, since there will be nothing
obj_t::set_flag(obj_t::not_on_map);
}
async_wolke_t::async_wolke_t(loadsave_t *file) :
#ifdef INLINE_OBJ_TYPE
obj_t(obj_t::async_wolke)
#else
obj_t()
#endif
{
// not saving clouds!
assert(file->is_loading());
obj_t::rdwr( file );
uint32 dummy;
file->rdwr_long(dummy);
// do not remove from this position, since there will be nothing
obj_t::set_flag(obj_t::not_on_map);
}