]> www.fi.muni.cz Git - slotcarman.git/blob - SCX/Car.pm
31149a20dc95d97685578fe690df20363f66a815
[slotcarman.git] / SCX / Car.pm
1 #!/usr/bin/perl -w
2
3 package SCX::Car;
4
5 use strict;
6 use Time::HiRes qw(gettimeofday);
7
8 sub new {
9         my ($class, $args) = @_;
10
11         my $self = {
12                 gui      => $args->{gui},
13                 driver   => $args->{driver} || '--',    
14                 throttle => undef,
15                 fuel     => 0,
16                 lap      => 0,
17                 laptime  => 0,
18                 avg_lap  => 0,
19                 state    => 'greenflag',
20                 car_img  => $args->{car_img},
21                 id       => $args->{id},
22                 order    => $args->{id},
23                 track    => $args->{track},
24         };
25
26         bless $self, $class;
27
28         return $self;
29 }
30
31 sub gui { return shift->{gui}; }
32
33 sub track { return shift->{track}; }
34
35 sub same {
36         my ($self, $key, $val) = @_;
37
38         return 1 if !defined $self->{$key} && !defined $val
39                 || (defined $self->{$key} && defined $val
40                         && $self->{$key} eq $val);
41
42         $self->{$key} = $val;
43         return undef;
44 }
45
46 sub set_throttle {
47         my ($self, $val, $time) = @_;
48
49         return if $self->same('throttle', $val);
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);
64 }
65
66
67 sub set_fuel {
68         my ($self, $val) = @_;
69
70         return if $self->same('fuel', $val);
71         $self->gui->set_fuel($self->{order}, $val);
72 }
73
74 sub set_light {
75         # TODO
76 }
77
78 sub set_backbutton {
79         # TODO
80 }
81
82 sub set_model {
83         my ($self, $name) = @_;
84
85         return if $self->same('car_img', $name);
86         $self->gui->set_car_icon($self->{order}, $name);
87 }
88
89 sub set_lap {
90         my ($self, $lap_nr) = @_;
91
92         if (!$lap_nr) {
93                 $self->{avg_lap} = undef;
94                 $self->{lap} = $lap_nr;
95                 $self->gui->set_avg_lap($self->{order}, undef);
96                 $self->gui->set_lap($self->{order}, $lap_nr);
97                 return;
98         }
99                 
100         return if $self->same('lap', $lap_nr);
101         $self->gui->set_lap($self->{order}, $lap_nr);
102         if ($self->track->{race_running} && $self->{lap} > 1) {
103                 my $now = $self->{last_finish_time};
104                 my $avg = ($now - $self->track->{race_running_since})
105                         / ($self->{lap} - 1);
106                 $self->{avg_lap} = $avg;
107                 $self->gui->set_avg_lap($self->{order}, $self->{avg_lap});
108         }
109 }
110
111 sub set_laptime {
112         my ($self, $lap_time) = @_;
113
114         if (!defined $lap_time) {
115                 $self->gui->set_best_lap($self->{order}, undef);
116                 $self->{best_lap} = undef;
117         }
118
119         return if $self->same('laptime', $lap_time);
120
121         $self->gui->set_laptime($self->{order}, $lap_time);
122
123         if (defined $lap_time) {
124                 if ($lap_time > 1.0 && !$self->{in_pit_lane}
125                         && $self->track->{race_running}
126                         && (!defined $self->{best_lap}
127                                 || $self->{best_lap} > $lap_time
128                         )) {
129
130                         $self->{best_lap} = $lap_time;
131                         my $global = $self->{track}->check_best_lap($lap_time,
132                                 $self->{driver}
133                         );
134                         $self->gui->set_best_lap($self->{order}, $lap_time,
135                                 $global);
136                 }
137         }
138 }
139
140 sub set_driver {
141         my ($self, $driver_name) = @_;
142
143         return if $self->same('driver', $driver_name);
144         $self->gui->set_name($self->{order}, $driver_name);
145 }
146
147 sub enter_pit_lane {
148         my ($self) = @_;
149
150         return if $self->{in_pit_lane};
151
152         $self->{in_pit_lane} = 1;
153         $self->print_state;
154 }
155
156 sub leave_pit_lane {
157         my ($self) = @_;
158
159         return if !$self->{in_pit_lane};
160
161         $self->{in_pit_lane} = 0;
162         $self->print_state;
163 }
164
165 sub set_order {
166         my ($self, $pos) = @_;
167
168         $self->{order} = $pos;
169         
170         $self->gui->set_name($self->{order}, $self->{driver});
171         $self->gui->set_car_icon($self->{order}, $self->{car_img});
172         $self->gui->set_throttle($self->{order}, $self->{throttle});
173         $self->gui->set_lap($self->{order}, $self->{lap});
174         $self->gui->set_laptime($self->{order}, $self->{laptime});
175         $self->gui->set_best_lap($self->{order}, $self->{best_lap});
176         $self->gui->set_avg_lap($self->{order}, $self->{avg_lap});
177         $self->gui->set_fuel($self->{order}, $self->{fuel});
178         $self->gui->set_car_id($self->{order}, $self->{id} + 1);
179         $self->gui->set_distance($self->{order},
180                 $self->{time_diff}, $self->{lap_diff});
181         $self->gui->set_state($self->{order}, $self->{state});
182         if ($self->{in_pit_lane}) {
183                 $self->gui->enter_pit_lane;
184         }
185 }
186
187 sub print_state {
188         my ($self) = @_;
189
190         if ($self->{in_pit_lane}) {
191                 $self->{state} = 'pit';
192         } elsif ($self->{running}) {
193                 $self->{state} = 'go';
194         } elsif ($self->{finished}) {
195                 $self->{state} = 'finished';
196         } elsif ($self->{early_start}) {
197                 $self->{state} = 'disqualified';
198         } else {
199                 $self->{state} = 'greenflag';
200         }
201
202         $self->gui->set_state($self->{order}, $self->{state});
203 }
204         
205 sub reset {
206         my ($self) = @_;
207
208         $self->set_lap(0);
209         $self->set_laptime(undef);
210         $self->{in_pit_lane} = 0;
211         $self->{early_start} = undef;
212         $self->{last_finish_time} = undef;
213         $self->{first_finish_time} = undef;
214         $self->{time_diff} = undef;
215         $self->{lap_diff} = undef;
216 }
217
218 sub finish_line {
219         my ($self, $time, $regular) = @_;
220
221         if (defined $self->{last_finish_time} 
222                 && $time - $self->{last_finish_time} < 2) {
223
224                 $self->{last_finish_time} = $time;
225                 if ($regular && $self->{in_pit_lane}) {
226                         $self->leave_pit_lane;
227                 }
228                 return undef;
229         }
230
231         if ($regular) {
232                 if (defined $self->{first_finish_time}) {
233                         $self->set_laptime($time - $self->{first_finish_time});
234                 }
235         } else {
236                 $self->enter_pit_lane;
237         }
238
239         $self->{first_finish_time} = $self->{last_finish_time} = $time;
240
241         if ($self->track->{race_running}) {
242                 $self->set_lap($self->{lap} + 1);
243         }
244
245         return 1;
246 }
247
248 sub recalc_distance {
249         my ($self, $lap_first, $time_first) = @_;
250
251         return if !defined $lap_first || !defined $self->{lap}
252                 || !defined $time_first || !defined $self->{first_finish_time};
253
254         my $time;
255
256         if ($self->{lap} == $lap_first) {
257                 if ($self->{first_finish_time} == $time_first) {
258                         $time = $self->{first_finish_time}
259                                 - $self->track->{race_running_since};
260                 } else {
261                         $self->{time_diff} = $self->{first_finish_time}
262                                 - $time_first;
263                 }
264         } else {
265                 $self->{lap_diff} = $lap_first - $self->{lap};
266         }
267
268         $self->gui->set_distance($self->{order}, $time,
269                 $self->{lap_diff}, $self->{time_diff});
270 }
271
272 1;
273