~ubuntu-branches/ubuntu/edgy/xbill/edgy

« back to all changes in this revision

Viewing changes to Bill.c

  • Committer: Bazaar Package Importer
  • Author(s): Adrian Bridgett
  • Date: 2004-09-07 09:52:14 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040907095214-d0m46ojc8f7upuqm
Tags: 2.1-4
maintainer upload of NMU - many thanks Tollef (closes: #268885) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
 
 
3
#include "types.h"
 
4
#include "util.h"
 
5
 
 
6
#include "Bill.h"
 
7
#include "Computer.h"
 
8
#include "Game.h"
 
9
#include "Horde.h"
 
10
#include "Network.h"
 
11
#include "OS.h"
 
12
#include "UI.h"
 
13
 
 
14
/* speed at which OS drops */
 
15
#define GRAVITY 3
 
16
 
 
17
/* speed of moving Bill */
 
18
#define SLOW 0
 
19
#define FAST 1
 
20
 
 
21
#define WCELS 4                 /* # of bill walking animation frames */
 
22
#define DCELS 5                 /* # of bill dying animation frames */
 
23
#define ACELS 13                /* # of bill switching OS frames */
 
24
 
 
25
static Picture *lcels[WCELS], *rcels[WCELS], *acels[ACELS], *dcels[DCELS];
 
26
static int width, height;
 
27
 
 
28
static void
 
29
get_border(int *x, int *y) {
 
30
        int i = RAND(0, 3);
 
31
        int screensize = Game_screensize();
 
32
 
 
33
        if (i % 2 == 0)
 
34
                *x = RAND(0, screensize - width);
 
35
        else
 
36
                *y = RAND(0, screensize - height);
 
37
 
 
38
        switch (i) {
 
39
                case 0:
 
40
                        *y = -height - 16;
 
41
                        break;
 
42
                case 1:
 
43
                        *x = screensize + 1;
 
44
                        break;
 
45
                case 2:
 
46
                        *y = screensize + 1;
 
47
                        break;
 
48
                case 3:
 
49
                        *x = - width - 2;
 
50
                        break;
 
51
        }
 
52
}
 
53
 
 
54
/* Adds a bill to the in state */
 
55
void
 
56
Bill_enter(Bill **billp) {
 
57
        Bill *bill;
 
58
        Computer *computer;
 
59
 
 
60
        bill = xalloc(sizeof *bill);
 
61
 
 
62
        bill->state = BILL_STATE_IN;
 
63
        get_border(&bill->x, &bill->y);
 
64
        bill->index = 0;
 
65
        bill->cels = lcels;
 
66
        bill->cargo = OS_WINGDOWS;
 
67
        bill->x_offset = -2;
 
68
        bill->y_offset = -15;
 
69
        bill->target_c = RAND(0, Network_num_computers() - 1);
 
70
        computer = Network_get_computer(bill->target_c);
 
71
        bill->target_x = computer->x + Computer_width() - BILL_OFFSET_X;
 
72
        bill->target_y = computer->y + BILL_OFFSET_Y;
 
73
        Horde_inc_counter(HORDE_COUNTER_ON, 1);
 
74
        Horde_inc_counter(HORDE_COUNTER_OFF, -1);
 
75
        bill->prev = NULL;
 
76
        bill->next = NULL;
 
77
        *billp = bill;
 
78
}
 
79
 
 
80
static int
 
81
step_size(unsigned int level) {
 
82
        return MIN(11 + level, 15);
 
83
}
 
84
 
 
85
/*  Moves bill toward his target - returns whether or not he moved */
 
86
static int
 
87
move(Bill *bill, int mode) {
 
88
        int xdist = bill->target_x - bill->x;
 
89
        int ydist = bill->target_y - bill->y;
 
90
        int step = step_size(Game_level());
 
91
        int dx, dy;
 
92
        int signx = xdist >= 0 ? 1 : -1;
 
93
        int signy = ydist >= 0 ? 1 : -1;
 
94
        xdist = abs(xdist);
 
95
        ydist = abs(ydist);
 
96
        if (!xdist && !ydist)
 
97
                return 0;
 
98
        else if (xdist < step && ydist < step) {
 
99
                bill->x = bill->target_x;
 
100
                bill->y = bill->target_y;
 
101
        }
 
102
        else {
 
103
                dx = (xdist*step*signx)/(xdist+ydist);
 
104
                dy = (ydist*step*signy)/(xdist+ydist);
 
105
                if (mode == FAST) {
 
106
                        dx *= 1.25;
 
107
                        dy *= 1.25;
 
108
                }
 
109
                bill->x += dx;
 
110
                bill->y += dy;
 
111
                if (dx < 0)
 
112
                        bill->cels = lcels;
 
113
                else if (dx > 0)
 
114
                        bill->cels = rcels;
 
115
        }
 
116
        return 1;
 
117
}
 
118
 
 
119
static void
 
120
draw_std(Bill *bill) {
 
121
        if (bill->cargo >= 0)
 
122
                OS_draw(bill->cargo, bill->x + bill->x_offset,
 
123
                        bill->y + bill->y_offset);
 
124
        UI_draw(bill->cels[bill->index], bill->x, bill->y);
 
125
}
 
126
 
 
127
static void
 
128
draw_at(Bill *bill) {
 
129
        Computer *computer = Network_get_computer(bill->target_c);
 
130
        if (bill->index > 6 && bill->index < 12)
 
131
                OS_draw(0, bill->x + bill->sx, bill->y + bill->sy);
 
132
        if (bill->cargo >= 0)
 
133
                OS_draw(bill->cargo, bill->x + bill->x_offset,
 
134
                        bill->y + bill->y_offset);
 
135
        UI_draw(bill->cels[bill->index], computer->x, computer->y);
 
136
}
 
137
 
 
138
static void
 
139
draw_stray(Bill *bill) {
 
140
        OS_draw(bill->cargo, bill->x, bill->y);
 
141
}
 
142
 
 
143
void
 
144
Bill_draw(Bill *bill) {
 
145
        switch (bill->state) {
 
146
                case BILL_STATE_IN:
 
147
                case BILL_STATE_OUT:
 
148
                case BILL_STATE_DYING:
 
149
                        draw_std(bill);
 
150
                        break;
 
151
                case BILL_STATE_AT:
 
152
                        draw_at(bill);
 
153
                        break;
 
154
                case BILL_STATE_STRAY:
 
155
                        draw_stray(bill);
 
156
                        break;
 
157
                default:
 
158
                        break;
 
159
        }
 
160
}
 
161
 
 
162
/*  Update Bill's position */   
 
163
static void
 
164
update_in(Bill *bill) {
 
165
        int moved = move(bill, SLOW);
 
166
        Computer *computer = Network_get_computer(bill->target_c);
 
167
        if (!moved && computer->os != OS_WINGDOWS && !computer->busy) {
 
168
                computer->busy = 1;
 
169
                bill->cels = acels;
 
170
                bill->index = 0;
 
171
                bill->state = BILL_STATE_AT;
 
172
                return;
 
173
        }
 
174
        else if (!moved) {
 
175
                int i;
 
176
                do {
 
177
                        i = RAND(0, Network_num_computers() - 1);
 
178
                } while (i == bill->target_c);
 
179
                computer = Network_get_computer(i);
 
180
                bill->target_c = i;
 
181
                bill->target_x = computer->x + Computer_width() - BILL_OFFSET_X;
 
182
                bill->target_y = computer->y + BILL_OFFSET_Y;
 
183
        }
 
184
        bill->index++;
 
185
        bill->index %= WCELS;
 
186
        bill->y_offset += (8 * (bill->index % 2) - 4);
 
187
}
 
188
 
 
189
/*  Update Bill standing at a computer */
 
190
static void
 
191
update_at(Bill *bill) {
 
192
        Computer *computer = Network_get_computer(bill->target_c);
 
193
        if (bill->index == 0 && computer->os == OS_OFF) {
 
194
                bill->index = 6;
 
195
                if (computer->stray == NULL)
 
196
                        bill->cargo = -1;
 
197
                else {
 
198
                        bill->cargo = computer->stray->cargo;
 
199
                        Horde_remove_bill(computer->stray);
 
200
                        computer->stray = NULL;
 
201
                }
 
202
        } else
 
203
                bill->index++;
 
204
        if (bill->index == 13) {
 
205
                bill->y_offset = -15;
 
206
                bill->x_offset = -2;
 
207
                get_border(&bill->target_x, &bill->target_y);
 
208
                bill->index = 0;
 
209
                bill->cels = lcels;
 
210
                bill->state = BILL_STATE_OUT;
 
211
                computer->busy = 0;
 
212
                return;
 
213
        }
 
214
        bill->y_offset = height - OS_height();
 
215
        switch (bill->index) {
 
216
        case 1: 
 
217
        case 2:
 
218
                bill->x -= 8;
 
219
                bill->x_offset +=8;
 
220
                break;
 
221
        case 3:
 
222
                bill->x -= 10;
 
223
                bill->x_offset +=10;
 
224
                break;
 
225
        case 4:
 
226
                bill->x += 3;
 
227
                bill->x_offset -=3;
 
228
                break;
 
229
        case 5:
 
230
                bill->x += 2;
 
231
                bill->x_offset -=2;
 
232
                break;
 
233
        case 6:
 
234
                if (computer->os != OS_OFF) {
 
235
                        Network_inc_counter(NETWORK_COUNTER_BASE, -1);
 
236
                        Network_inc_counter(NETWORK_COUNTER_OFF, 1);
 
237
                        bill->cargo = computer->os;
 
238
                }
 
239
                else {
 
240
                        bill->x -= 21;
 
241
                        bill->x_offset += 21;
 
242
                }
 
243
                computer->os = OS_OFF;
 
244
                bill->y_offset = -15;
 
245
                bill->x += 20;
 
246
                bill->x_offset -=20;
 
247
                break;
 
248
        case 7:
 
249
                bill->sy = bill->y_offset;
 
250
                bill->sx = -2;
 
251
                break;
 
252
        case 8:
 
253
                bill->sy = -15;
 
254
                bill->sx = -2;
 
255
                break;
 
256
        case 9:
 
257
                bill->sy = -7;
 
258
                bill->sx = -7;
 
259
                bill->x -= 8;
 
260
                bill->x_offset +=8;
 
261
                break;  
 
262
        case 10:
 
263
                bill->sy = 0;
 
264
                bill->sx = -7;
 
265
                bill->x -= 15;
 
266
                bill->x_offset +=15;
 
267
                break;
 
268
        case 11:
 
269
                bill->sy = 0;
 
270
                bill->sx = -7;
 
271
                computer->os = OS_WINGDOWS;
 
272
                Network_inc_counter(NETWORK_COUNTER_OFF, -1);
 
273
                Network_inc_counter(NETWORK_COUNTER_WIN, 1);
 
274
                break;
 
275
        case 12:
 
276
                bill->x += 11;
 
277
                bill->x_offset -=11;
 
278
        }
 
279
}
 
280
 
 
281
/* Updates Bill fleeing with his ill gotten gain */
 
282
static void
 
283
update_out(Bill *bill) {
 
284
        int screensize = Game_screensize();
 
285
        if (UI_intersect(bill->x, bill->y, width, height, 0, 0,
 
286
                         screensize, screensize))
 
287
        {
 
288
                move(bill, FAST);
 
289
                bill->index++;
 
290
                bill->index %= WCELS;
 
291
                bill->y_offset += (8*(bill->index%2)-4); 
 
292
        }
 
293
        else {
 
294
                Horde_remove_bill(bill);
 
295
                Horde_inc_counter(HORDE_COUNTER_ON, -1);
 
296
                Horde_inc_counter(HORDE_COUNTER_OFF, 1);
 
297
        }
 
298
}
 
299
 
 
300
 
 
301
/* Updates a Bill who is dying */
 
302
static void
 
303
update_dying(Bill *bill) {
 
304
        if (bill->index < DCELS - 1){
 
305
                bill->y_offset += (bill->index * GRAVITY);
 
306
                bill->index++;  
 
307
        }
 
308
        else {
 
309
                bill->y += bill->y_offset;
 
310
                if (bill->cargo < 0 || bill->cargo == OS_WINGDOWS)
 
311
                        Horde_remove_bill(bill);
 
312
                else {
 
313
                        Horde_move_bill(bill);
 
314
                        bill->state = BILL_STATE_STRAY;
 
315
                }
 
316
                Horde_inc_counter(HORDE_COUNTER_ON, -1);
 
317
        }
 
318
}
 
319
 
 
320
void
 
321
Bill_update(Bill *bill) {
 
322
        switch (bill->state) {
 
323
                case BILL_STATE_IN:
 
324
                        update_in(bill);
 
325
                        break;
 
326
                case BILL_STATE_AT:
 
327
                        update_at(bill);
 
328
                        break;
 
329
                case BILL_STATE_OUT:
 
330
                        update_out(bill);
 
331
                        break;
 
332
                case BILL_STATE_DYING:
 
333
                        update_dying(bill);
 
334
                        break;
 
335
                default:
 
336
                        break;
 
337
        }
 
338
}
 
339
 
 
340
void
 
341
Bill_set_dying(Bill *bill) {
 
342
        bill->index = -1;
 
343
        bill->cels = dcels;
 
344
        bill->x_offset = -2;
 
345
        bill->y_offset = -15;
 
346
        bill->state = BILL_STATE_DYING;
 
347
}
 
348
 
 
349
int
 
350
Bill_clicked(Bill *bill, int locx, int locy) {
 
351
        return (locx > bill->x && locx < bill->x + width &&
 
352
                locy > bill->y && locy < bill->y + height);
 
353
}
 
354
 
 
355
int
 
356
Bill_clickedstray(Bill *bill, int locx, int locy) {
 
357
        return (locx > bill->x && locx < bill->x + OS_width() &&
 
358
                locy > bill->y && locy < bill->y + OS_height());
 
359
}
 
360
 
 
361
void
 
362
Bill_load_pix () {
 
363
        int i;
 
364
        for (i = 0; i < WCELS - 1; i++) {
 
365
                UI_load_picture_indexed("billL", i, 1, &lcels[i]);
 
366
                UI_load_picture_indexed("billR", i, 1, &rcels[i]);
 
367
        }
 
368
        lcels[WCELS - 1] = lcels[1];
 
369
        rcels[WCELS - 1] = rcels[1];
 
370
 
 
371
        for (i = 0; i < DCELS; i++)
 
372
                UI_load_picture_indexed("billD", i, 1, &dcels[i]);
 
373
        width = UI_picture_width(dcels[0]);
 
374
        height = UI_picture_height(dcels[0]);
 
375
 
 
376
        for (i = 0; i < ACELS; i++)
 
377
                UI_load_picture_indexed("billA", i, 1, &acels[i]);
 
378
}
 
379
 
 
380
int
 
381
Bill_width() {
 
382
        return width;
 
383
}
 
384
 
 
385
int
 
386
Bill_height() {
 
387
        return height;
 
388
}
 
389
 
 
390
int
 
391
Bill_get_state(Bill *bill) {
 
392
        return bill->state;
 
393
}