JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
fe66c4c3ba5bdc4effced5b5859c9cb06b53defb
[vor.git] / rocks.c
1 #include <SDL_image.h>
2 #include <math.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "config.h"
7 #include "file.h"
8 #include "globals.h"
9 #include "rocks.h"
10 #include "shape.h"
11
12 struct rock_struct {
13         float x,y,dx,dy;
14         int active;
15         int dead;  // has been blown out of the way
16                    // to make room for a new ship appearing.
17         SDL_Surface *image;
18         struct shape *shape;
19         int type_number;
20 }; 
21
22 struct rock_struct rock[MAXROCKS], *rockptr = rock;
23
24 float rockrate,rockspeed;
25
26 SDL_Surface *surf_rock[NROCKS];
27 struct shape rock_shapes[NROCKS];
28
29 int countdown = 0;
30
31 float rnd(void);
32
33 uint32_t area;
34
35 int
36 init_rocks(void)
37 {
38         int i;
39         char a[MAX_PATH_LEN];
40         SDL_Surface *temp;
41
42         area = 0;
43
44         for(i = 0; i<NROCKS; i++) {
45                 snprintf(a,MAX_PATH_LEN,add_path("sprites/rock%02d.png"),i);
46                 NULLERROR(temp = IMG_Load(a));
47                 NULLERROR(surf_rock[i] = SDL_DisplayFormat(temp));
48                 get_shape(surf_rock[i], &rock_shapes[i]);
49         }
50         return 0;
51 }
52
53 void
54 new_rocks(void)
55 {
56         if(--countdown <= 0 && (rnd()*100.0<(rockrate += 0.025))) {
57                 // Possibly create a rock
58                 rockptr++;
59                 if(rockptr-rock >= MAXROCKS) {
60                         rockptr = rock;
61                 }
62                 if(!rockptr->active) {
63                         rockptr->dx = -(rockspeed)*(1 + rnd());
64                         rockptr->dy = rnd()-0.5;
65                         rockptr->type_number = random() % NROCKS;
66                         rockptr->image = surf_rock[rockptr->type_number];
67                         rockptr->shape = &rock_shapes[rockptr->type_number];
68                         rockptr->x = (float)XSIZE;
69                         rockptr->y = rnd()*(YSIZE + rockptr->image->h);
70                         rockptr->active = 1;
71                         area += rockptr->shape->area;
72                 }
73                 if(gamerate>0.1) {
74                         countdown = (int)(ROCKRATE/gamerate);
75                 } else {
76                         countdown = 0;
77                 }
78         }
79 }
80
81 void
82 move_rocks(void)
83 {
84         int i;
85
86         // Move all the rocks
87         for(i = 0; i < MAXROCKS; i++) {
88                 if(rock[i].active) {
89                         rock[i].x += rock[i].dx*gamerate;
90                         rock[i].y += rock[i].dy*gamerate + yscroll;
91                         if(rock[i].y > YSIZE || rock[i].y < -rock[i].image->h) {
92                                 if(rock[i].dead) {
93                                         area -= rock[i].shape->area;
94                                         rock[i].dead = 0;
95                                         rock[i].active = 0;
96                                 } else {
97                                         // wrap
98                                         rock[i].y = (YSIZE - rock[i].image->h) - rock[i].y;
99                                         rock[i].y += (rock[i].dy*gamerate + yscroll) * 1.01;
100                                 }
101                         }
102                         if(rock[i].x < -rock[i].image->w || rock[i].x > XSIZE) {
103                                 area -= rock[i].shape->area;
104                                 rock[i].active = 0;
105                                 rock[i].dead = 0;
106                         }
107                 }
108         }
109 }
110
111 void
112 reset_rocks(void)
113 {
114         int i;
115
116         area = 0;
117         for(i = 0; i<MAXROCKS; i++ ) {
118                 rock[i].active = 0;
119                 rock[i].dead = 0;
120         }
121
122         rockrate = 54.0;
123         rockspeed = 5.0;
124 }
125
126 void
127 draw_rocks(void)
128 {
129         int i;
130         SDL_Rect src, dest;
131
132         src.x = 0; src.y = 0;
133
134         for(i = 0; i<MAXROCKS; i++) {
135                 if(rock[i].active) {
136                         src.w = rock[i].image->w;
137                         src.h = rock[i].image->h;
138
139                         dest.w = src.w;
140                         dest.h = src.h;
141                         dest.x = (int) rock[i].x;
142                         dest.y = (int) rock[i].y;
143
144                         SDL_BlitSurface(rock[i].image,&src,surf_screen,&dest);
145
146                 }
147         }
148 }
149
150 int
151 hit_rocks(float x, float y, struct shape *shape)
152 {
153         int i;
154
155         for(i=0; i<MAXROCKS; i++) {
156                 if(rock[i].active) {
157                         if(collide(x-rock[i].x, y-rock[i].y, rock[i].shape, shape)) 
158                                 return 1;
159                 }
160         }
161         return 0;
162 }
163
164 void
165 blast_rocks(float x, float y, float radius, int onlyslow)
166 {
167         int i;
168         float dx, dy, n;
169
170         for(i = 0; i<MAXROCKS; i++ ) {
171                 if(rock[i].x <= 0) continue;
172
173                 // This makes it so your explosion from dying magically doesn't leave
174                 // any rocks that aren't moving much on the x axis. If onlyslow is set,
175                 // only rocks that are barely moving will be pushed.
176                 if(onlyslow && (!rock[i].dead || rock[i].dx < -4 || rock[i].dx > 3)) {
177                         continue;
178                 }
179
180                 dx = rock[i].x - x;
181                 dy = rock[i].y - y;
182
183                 n = sqrt(dx*dx + dy*dy);
184                 if(n < radius) {
185                         n *= 20;
186                         rock[i].dx += rockrate*(dx+30)/n;
187                         rock[i].dy += rockrate*dy/n;
188                         rock[i].dead = 1;
189                 }
190         }
191 }