]> www.fi.muni.cz Git - slotcarman.git/blob - SCX/Car.pm
5a1f90e7bb5b052653643d0e1b74c6870972f83d
[slotcarman.git] / SCX / Car.pm
1 #!/usr/bin/perl -w
2
3 package SCX::Car;
4
5 use strict;
6
7 sub new {
8         my ($class, $args) = @_;
9
10         my $self = {
11                 gui      => $args->{gui},
12                 driver   => $args->{driver} || '--',    
13                 throttle => undef,
14                 button   => undef,
15                 fuel     => 0,
16                 lap      => 0,
17                 laptime  => 0,
18                 car_img  => $args->{car_img},
19                 id       => $args->{id},
20                 track    => $args->{track},
21         };
22
23         bless $self, $class;
24
25         $self->set_order($self->{id});
26
27         return $self;
28 }
29
30 sub gui { return shift->{gui}; }
31
32 sub track { return shift->{track}; }
33
34 sub same {
35         my ($self, $key, $val) = @_;
36
37         return 1 if !defined $self->{$key} && !defined $val
38                 || (defined $self->{$key} && defined $val
39                         && $self->{$key} eq $val);
40
41         $self->{$key} = $val;
42         return undef;
43 }
44
45 sub set_throttle {
46         my ($self, $val, $button, $time) = @_;
47
48         return if $self->same('throttle', $val)
49                 && $self->same('button', $button);
50
51         if ($self->track->{start_in_progress} && $val) {
52                 $self->{early_start} = 1;
53                 $self->gui->set_name($self->{order}, 'Early start!');
54         }
55
56         if ($self->{in_pit_lane} && defined $val) {
57                 $self->{last_finish_time} = $time;
58                 if ($val > 3) {
59                         $self->leave_pit_lane;
60                 }
61         }
62
63         $self->gui->set_throttle($self->{order}, $val, $button);
64 }
65
66
67 sub set_fuel {
68         my ($self, $val) = @_;
69
70         my $prev = $self->{fuel};
71         return if $self->same('fuel', $val);
72         if (defined $val && defined $prev && $val < 8) {
73                 if ($val == $prev + 1 && !$self->{in_pit_lane}) {
74                         print STDERR $self->track->{now}, ' car ',
75                                 $self->{id}, ' missed pit lane entry', "\n";
76                         $self->enter_pit_lane;
77                 }
78                 if ($val == $prev - 1 && $val <= 2 && !$self->{in_pit_lane}) {
79                         $self->track->{sound}->box($self->{id});
80                 }
81         }
82         if (defined $val && defined $prev && $val == 8 && $prev == 7
83                 && $self->{in_pit_lane}) {
84                         $self->track->{sound}->filled($self->{id});
85         }
86
87         $self->gui->set_fuel($self->{order}, $val);
88 }
89
90 sub set_light {
91         # TODO
92 }
93
94 sub set_backbutton {
95         # TODO
96 }
97
98 sub set_model {
99         my ($self, $name) = @_;
100
101         return if $self->same('car_img', $name);
102         $self->gui->set_car_icon($self->{order}, $name);
103 }
104
105 sub set_lap {
106         my ($self, $lap_nr) = @_;
107
108         if (!$lap_nr) {
109                 $self->{lap} = $lap_nr;
110                 $self->gui->set_lap($self->{order}, $lap_nr);
111                 return;
112         }
113                 
114         return if $self->same('lap', $lap_nr);
115         if (defined $self->{lap} && defined $self->track->{race_rounds}
116                 && $self->track->{race_rounds} > 0
117                 && $self->{lap} > $self->track->{race_rounds}) {
118                 $self->{finished} = 1;
119                 $self->print_state;
120         }
121         $self->gui->set_lap($self->{order}, $lap_nr);
122         if ($self->track->{race_running} && $self->{lap} > 1) {
123                 my $now = $self->{last_finish_time};
124         }
125 }
126
127 sub set_laptime {
128         my ($self, $lap_time) = @_;
129
130         if (!defined $lap_time) {
131                 $self->{best_lap} = undef;
132                 $self->{global_best_lap} = undef;
133                 $self->print_best_lap;
134         }
135
136         return if $self->same('laptime', $lap_time);
137
138         $self->gui->set_laptime($self->{order}, $lap_time);
139
140         return if !defined $lap_time || $lap_time <= 1.0
141                 || $self->{in_pit_lane};
142
143         return if $self->{finished};
144
145         return if defined $self->{best_lap} && $self->{best_lap} <= $lap_time;
146
147         $self->{best_lap} = $lap_time;
148         $self->print_best_lap;
149         $self->{track}->notify_best_lap($self->{id}, $lap_time,
150                 $self->{driver});
151 }
152
153 sub print_best_lap {
154         my ($self) = @_;
155         $self->gui->set_best_lap($self->{order}, $self->{best_lap},
156                 $self->{global_best_lap});
157 }
158
159 sub set_global_best {
160         my ($self, $val) = @_;
161
162         $self->{global_best_lap} = $val ? 1 : undef;
163 }
164
165 sub set_driver {
166         my ($self, $driver_name) = @_;
167
168         return if $self->same('driver', $driver_name);
169         $self->gui->set_name($self->{order}, $driver_name);
170 }
171
172 sub enter_pit_lane {
173         my ($self) = @_;
174
175         return if $self->{in_pit_lane};
176
177         $self->{in_pit_lane} = 1;
178         $self->print_state;
179 }
180
181 sub leave_pit_lane {
182         my ($self) = @_;
183
184         return if !$self->{in_pit_lane};
185
186         $self->{in_pit_lane} = 0;
187         $self->print_state;
188 }
189
190 sub set_order {
191         my ($self, $pos) = @_;
192
193         $self->{order} = $pos;
194         
195         $self->gui->set_name($self->{order}, $self->{driver});
196         $self->gui->set_car_icon($self->{order}, $self->{car_img});
197         $self->gui->set_throttle($self->{order}, $self->{throttle},
198                 $self->{button});
199         $self->gui->set_lap($self->{order}, $self->{lap});
200         $self->gui->set_laptime($self->{order}, $self->{laptime});
201         $self->gui->set_fuel($self->{order}, $self->{fuel});
202         $self->gui->set_car_id($self->{order}, $self->{id} + 1);
203         $self->gui->set_distance($self->{order},
204                 $self->{time_diff}, $self->{lap_diff}, $self->{grey_diff});
205         $self->print_state;
206         $self->print_best_lap;
207 }
208
209 sub print_state {
210         my ($self) = @_;
211
212         if ($self->{in_pit_lane}) {
213                 $self->{state} = 'pit';
214         } elsif ($self->{finished}) {
215                 $self->{state} = 'finished';
216         } elsif ($self->{early_start}) {
217                 $self->{state} = 'disqualified';
218         } else {
219                 $self->{state} = 'greenflag';
220         }
221
222         $self->gui->set_state($self->{order}, $self->{state});
223 }
224         
225 sub reset {
226         my ($self) = @_;
227
228         $self->set_lap(0);
229         $self->set_laptime(undef);
230         $self->{finished} = 0;
231         $self->{in_pit_lane} = 0;
232         $self->{early_start} = undef;
233         $self->{last_finish_time} = undef;
234         $self->{first_finish_time} = undef;
235         $self->{time_diff} = undef;
236         $self->{lap_diff} = undef;
237         $self->{total_time} = undef;
238         $self->{grey_diff} = undef;
239         $self->print_state;
240 }
241
242 sub finish_line {
243         my ($self, $time, $regular) = @_;
244
245         if (defined $self->{last_finish_time} 
246                 && $time - $self->{last_finish_time} < 2) {
247
248                 $self->{last_finish_time} = $time;
249                 if ($regular && $self->{in_pit_lane}) {
250                         $self->leave_pit_lane;
251                 }
252                 return undef;
253         }
254
255         if ($regular) {
256                 if (defined $self->{first_finish_time}) {
257                         $self->set_laptime($time - $self->{first_finish_time});
258                 }
259         } else {
260                 $self->enter_pit_lane;
261         }
262
263         $self->{first_finish_time} = $self->{last_finish_time} = $time;
264
265         if ($self->track->{race_running}) {
266                 $self->set_lap($self->{lap} + 1);
267         } elsif ($self->track->{qualification_running} && !$self->{finished}) {
268                 $self->set_lap($self->{lap} + 1);
269                 if ($self->{lap} > $self->track->{race_rounds}) {
270                         $self->{finished} = 1;
271                         $self->print_state;
272                 }
273         }
274
275         return 1;
276 }
277
278 sub recalc_distance {
279         my ($self, $lap_first, $time_first, $finishing) = @_;
280
281         return if !defined $lap_first || !defined $self->{lap}
282                 || !defined $time_first || !defined $self->{first_finish_time};
283
284         $self->{total_time} = undef;
285         $self->{lap_diff} = undef;
286         $self->{time_diff} = undef;
287         $self->{grey_diff} = undef;
288
289         if ($self->{lap} == $lap_first) {
290                 if ($self->{first_finish_time} == $time_first) {
291                         $self->{total_time} = $self->{first_finish_time}
292                                 - $self->track->{race_running_since};
293                 } else {
294                         $self->{time_diff} = $self->{first_finish_time}
295                                 - $time_first;
296                 }
297         } else {
298                 $self->{lap_diff} = $lap_first - $self->{lap};
299         }
300
301         $self->gui->set_distance($self->{order}, $self->{total_time},
302                 $self->{lap_diff}, $self->{time_diff}, $self->{grey_diff});
303
304         if ($finishing) {
305                 $self->{finished} = 1;
306                 $self->print_state;
307         }
308 }
309
310 sub recalc_qual_distance {
311         my ($self, $time_first) = @_;
312
313         return if !defined $self->{best_lap} || $self->{best_lap} <= 0;
314
315         $self->{total_time} = undef;
316         $self->{time_diff} = undef;
317         $self->{grey_diff} = undef;
318         $self->{lap_diff} = undef;
319
320         if ($self->{best_lap} == $time_first) {
321                 $self->{total_time} = $self->{best_lap};
322         } else {
323                 $self->{time_diff} = $self->{best_lap} - $time_first;
324         }
325
326         $self->gui->set_distance($self->{order}, $self->{total_time},
327                 $self->{lap_diff}, $self->{time_diff}, $self->{grey_diff});
328 }
329
330 sub greyout_distance {
331         my ($self) = @_;
332
333         return if $self->{grey_diff};
334         $self->{grey_diff} = 1;
335         $self->gui->set_distance($self->{order}, $self->{total_time},
336                 $self->{lap_diff}, $self->{time_diff}, $self->{grey_diff});
337 }
338
339 1;
340