JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
started on new rock generation.
[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         SDL_Surface *image;
16         struct shape *shape;
17         int type_number;
18 }; 
19
20 struct rock_struct rock[MAXROCKS], *rockptr = rock;
21
22 float rockrate;
23
24 SDL_Surface *surf_rock[NROCKS];
25 struct shape rock_shapes[NROCKS];
26
27 float rockhtimer = 0;
28 int nrocks = 41;
29
30 float rnd(void);
31
32 // used for rock generation.
33 #define KH (1.0/32.0)
34 #define KV (1.0/24.0)
35 #define RXMIN 5.0
36 #define RXMAX 10.0
37 #define RYMIN (-0.5)
38 #define RYMAX 0.5
39
40
41 int
42 init_rocks(void)
43 {
44         int i;
45         char a[MAX_PATH_LEN];
46         SDL_Surface *temp;
47
48         for(i = 0; i<NROCKS; i++) {
49                 snprintf(a,MAX_PATH_LEN,add_path("sprites/rock%02d.png"),i);
50                 NULLERROR(temp = IMG_Load(a));
51                 NULLERROR(surf_rock[i] = SDL_DisplayFormat(temp));
52                 get_shape(surf_rock[i], &rock_shapes[i]);
53         }
54         return 0;
55 }
56
57 void
58 reset_rocks(void)
59 {
60         int i;
61
62         for(i = 0; i<MAXROCKS; i++ ) rock[i].active = 0;
63
64         rockrate = 54.0;
65 }
66
67 void
68 new_rocks(void)
69 {
70         int i = 0;
71         float hfactor = KH*nrocks*7.5;
72
73         rockhtimer += hfactor*gamerate/20;
74         if(rockhtimer >= 1) {
75                 while(rockptr->active && i<MAXROCKS) {
76                         if(++rockptr - rock >= MAXROCKS) rockptr = rock;
77                         i++;
78                 }
79                 if(!rockptr->active) {
80                         rockhtimer -= 1;
81                         rockptr->dx = -5.0*(1.0 + rnd());
82                         rockptr->dy = rnd()-0.5;
83                         rockptr->type_number = random() % NROCKS;
84                         rockptr->image = surf_rock[rockptr->type_number];
85                         rockptr->shape = &rock_shapes[rockptr->type_number];
86                         rockptr->x = (float)XSIZE;
87                         rockptr->y = rnd()*(YSIZE + rockptr->image->h);
88                         rockptr->active = 1;
89                 }
90         }
91 }
92
93 void
94 move_rocks(void)
95 {
96         int i;
97
98         // Move all the rocks
99         for(i = 0; i < MAXROCKS; i++) {
100                 if(rock[i].active) {
101                         // move
102                         rock[i].x += rock[i].dx*gamerate;
103                         rock[i].y += rock[i].dy*gamerate + yscroll;
104                         // clip
105                         if(rock[i].y < -rock[i].image->h || rock[i].y > YSIZE) {
106                                 // rock[i].active = 0;
107                                 rock[i].y = (YSIZE - rock[i].image->h) - rock[i].y;
108                                 rock[i].y += (rock[i].dy*gamerate + yscroll) * 1.01;
109                         }
110                         if(rock[i].x < -rock[i].image->w || rock[i].x > XSIZE) rock[i].active = 0;
111                 }
112         }
113 }
114
115 void
116 draw_rocks(void)
117 {
118         int i;
119         SDL_Rect src, dest;
120
121         src.x = 0; src.y = 0;
122
123         for(i = 0; i<MAXROCKS; i++) {
124                 if(rock[i].active) {
125                         src.w = rock[i].image->w;
126                         src.h = rock[i].image->h;
127
128                         dest.w = src.w;
129                         dest.h = src.h;
130                         dest.x = (int) rock[i].x;
131                         dest.y = (int) rock[i].y;
132
133                         SDL_BlitSurface(rock[i].image,&src,surf_screen,&dest);
134
135                 }
136         }
137 }
138
139 int
140 hit_rocks(float x, float y, struct shape *shape)
141 {
142         int i;
143
144         for(i=0; i<MAXROCKS; i++) {
145                 if(rock[i].active) {
146                         if(collide(x-rock[i].x, y-rock[i].y, rock[i].shape, shape)) 
147                                 return 1;
148                 }
149         }
150         return 0;
151 }
152
153 void
154 blast_rocks(float x, float y, float radius, int onlyslow)
155 {
156         int i;
157         float dx, dy, n;
158
159         for(i = 0; i<MAXROCKS; i++ ) {
160                 if(rock[i].x <= 0) continue;
161
162                 // This makes it so your explosion from dying magically doesn't leave
163                 // any rocks that aren't moving much on the x axis. If onlyslow is set,
164                 // only rocks that are barely moving will be pushed.
165                 if(onlyslow && (rock[i].dx < -4 || rock[i].dx > 3)) continue;
166
167                 dx = rock[i].x - x;
168                 dy = rock[i].y - y;
169
170                 n = sqrt(dx*dx + dy*dy);
171                 if(n < radius) {
172                         n *= 20;
173                         rock[i].dx += rockrate*(dx+30)/n;
174                         rock[i].dy += rockrate*dy/n;
175                 }
176         }
177 }