Atrinik Client  4.0
effects.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <toolkit/string.h>
34 
36 static effect_struct *effects = NULL;
40 static const char *overlay_cols[] = {"r", "g", "b", "a"};
41 static int max_frames = 60;
42 
46 void effects_init(void)
47 {
48  FILE *fp;
49  char buf[MAX_BUF], *cp;
50  effect_struct *effect = NULL;
51  effect_sprite_def *sprite_def = NULL;
52  effect_overlay *overlay = NULL;
53 
54  /* Try to deinitialize all effects first. */
56 
57  fp = server_file_open_name(SERVER_FILE_EFFECTS);
58 
59  if (!fp) {
60  return;
61  }
62 
63  /* Read the file... */
64  while (fgets(buf, sizeof(buf) - 1, fp)) {
65  /* Ignore comments and blank lines. */
66  if (buf[0] == '#' || buf[0] == '\n') {
67  continue;
68  }
69 
70  /* End a previous 'effect xxx' or 'sprite xxx' block. */
71  if (!strcmp(buf, "end\n")) {
72  /* Inside effect block. */
73  if (effect) {
74  /* Inside sprite block. */
75  if (sprite_def) {
76  /* Add this sprite to the linked list. */
77  sprite_def->next = effect->sprite_defs;
78  effect->sprite_defs = sprite_def;
79  /* Update total chance value. */
80  effect->chance_total += sprite_def->chance;
81  sprite_def = NULL;
82  }/* Overlay block, just set it as the effect's overlay. */
83  else if (overlay) {
84  effect->overlay = overlay;
85  overlay = NULL;
86  }/* Inside effect block. */
87  else {
88  /* Add this effect to the linked list of effects. */
89  effect->next = effects;
90  effects = effect;
91  effect = NULL;
92  }
93  }
94 
95  continue;
96  }
97 
98  cp = strrchr(buf, '\n');
99 
100  /* Eliminate newline. */
101  if (cp) {
102  *cp = '\0';
103  }
104 
105  /* Parse definitions inside sprite block. */
106  if (sprite_def) {
107  if (!strncmp(buf, "chance ", 7)) {
108  sprite_def->chance = atoi(buf + 7);
109  } else if (!strncmp(buf, "weight ", 7)) {
110  sprite_def->weight = atof(buf + 7);
111  } else if (!strncmp(buf, "weight_mod ", 11)) {
112  sprite_def->weight_mod = atof(buf + 11);
113  } else if (!strncmp(buf, "delay ", 6)) {
114  sprite_def->delay = atoi(buf + 6);
115  } else if (!strncmp(buf, "wind ", 5)) {
116  sprite_def->wind = atoi(buf + 5);
117  } else if (!strncmp(buf, "wiggle ", 7)) {
118  sprite_def->wiggle = atof(buf + 7);
119  } else if (!strncmp(buf, "wind_mod ", 9)) {
120  sprite_def->wind_mod = atof(buf + 9);
121  } else if (!strncmp(buf, "x ", 2)) {
122  sprite_def->x = atoi(buf + 2);
123  } else if (!strncmp(buf, "y ", 2)) {
124  sprite_def->y = atoi(buf + 2);
125  } else if (!strncmp(buf, "xpos ", 5)) {
126  sprite_def->xpos = atoi(buf + 5);
127  } else if (!strncmp(buf, "ypos ", 5)) {
128  sprite_def->ypos = atoi(buf + 5);
129  } else if (!strncmp(buf, "reverse ", 8)) {
130  sprite_def->reverse = atoi(buf + 8);
131  sprite_def->y_mod = -sprite_def->y_mod;
132  } else if (!strncmp(buf, "y_rndm ", 7)) {
133  sprite_def->y_rndm = atof(buf + 7);
134  } else if (!strncmp(buf, "x_mod ", 6)) {
135  sprite_def->x_mod = atof(buf + 6);
136  } else if (!strncmp(buf, "y_mod ", 6)) {
137  sprite_def->y_mod = atof(buf + 6);
138  } else if (!strncmp(buf, "x_check_mod ", 12)) {
139  sprite_def->x_check_mod = atoi(buf + 12);
140  } else if (!strncmp(buf, "y_check_mod ", 12)) {
141  sprite_def->y_check_mod = atoi(buf + 12);
142  } else if (!strncmp(buf, "kill_sides ", 11)) {
143  sprite_def->kill_side_left = sprite_def->kill_side_right = atoi(buf + 11);
144  } else if (!strncmp(buf, "kill_side_left ", 15)) {
145  sprite_def->kill_side_left = atoi(buf + 15);
146  } else if (!strncmp(buf, "kill_side_right ", 16)) {
147  sprite_def->kill_side_right = atoi(buf + 16);
148  } else if (!strncmp(buf, "zoom ", 5)) {
149  sprite_def->zoom = atoi(buf + 5);
150  } else if (!strncmp(buf, "warp_sides ", 11)) {
151  sprite_def->warp_sides = atoi(buf + 11);
152  } else if (!strncmp(buf, "ttl ", 4)) {
153  sprite_def->ttl = atoi(buf + 4);
154  } else if (!strncmp(buf, "sound_file ", 11)) {
155  strncpy(sprite_def->sound_file, buf + 11, sizeof(sprite_def->sound_file) - 1);
156  sprite_def->sound_file[sizeof(sprite_def->sound_file) - 1] = '\0';
157  } else if (!strncmp(buf, "sound_volume ", 13)) {
158  sprite_def->sound_volume = atoi(buf + 13);
159  }
160  } else if (!strcmp(buf, "overlay")) {
161  size_t col;
162 
163  overlay = ecalloc(1, sizeof(effect_overlay));
164 
165  for (col = 0; col < arraysize(overlay_cols); col++) {
166  overlay->col[col].val = -1;
167  overlay->col[col].mod[4] = 1.0;
168  }
169  } else if (overlay) {
170  size_t col;
171 
172  for (col = 0; col < arraysize(overlay_cols); col++) {
173  if (!strncmp(buf, overlay_cols[col], strlen(overlay_cols[col]))) {
174  if (!strncmp(buf + 1, "_rndm_min ", 10)) {
175  overlay->col[col].rndm_min = atoi(buf + 11);
176  } else if (!strncmp(buf + 1, "_rndm_max ", 10)) {
177  overlay->col[col].rndm_max = atoi(buf + 11);
178  } else if (!strncmp(buf + 1, "_mod1 ", 6)) {
179  overlay->col[col].mod[0] = atof(buf + 7);
180  } else if (!strncmp(buf + 1, "_mod2 ", 6)) {
181  overlay->col[col].mod[1] = atof(buf + 7);
182  } else if (!strncmp(buf + 1, "_mod3 ", 6)) {
183  overlay->col[col].mod[2] = atof(buf + 7);
184  } else if (!strncmp(buf + 1, "_mod4 ", 6)) {
185  overlay->col[col].mod[3] = atof(buf + 7);
186  } else if (!strncmp(buf + 1, "_mod5 ", 6)) {
187  overlay->col[col].mod[4] = atof(buf + 7);
188  } else {
189  overlay->col[col].val = atoi(buf + 2);
190  }
191  }
192  }
193  }/* Parse definitions inside effect block. */
194  else if (effect) {
195  if (!strncmp(buf, "wind_chance ", 12)) {
196  effect->wind_chance = atof(buf + 12);
197  } else if (!strncmp(buf, "sprite_chance ", 14)) {
198  effect->sprite_chance = atof(buf + 14);
199  } else if (!strncmp(buf, "delay ", 6)) {
200  effect->delay = atoi(buf + 6);
201  } else if (!strncmp(buf, "wind_blow_dir ", 14)) {
202  effect->wind_blow_dir = atoi(buf + 14);
203  } else if (!strncmp(buf, "max_sprites ", 12)) {
204  effect->max_sprites = atoi(buf + 12);
205  } else if (!strncmp(buf, "wind_mod ", 9)) {
206  effect->wind_mod = atof(buf + 9);
207  } else if (!strncmp(buf, "sprites_per_move ", 17)) {
208  effect->sprites_per_move = atoi(buf + 17);
209  } else if (!strncmp(buf, "sound_effect ", 13)) {
210  strncpy(effect->sound_effect, buf + 13, sizeof(effect->sound_effect) - 1);
211  effect->sound_effect[sizeof(effect->sound_effect) - 1] = '\0';
212  } else if (!strncmp(buf, "sound_volume ", 13)) {
213  effect->sound_volume = atoi(buf + 13);
214  }/* Start of sprite block. */
215  else if (!strncmp(buf, "sprite ", 7)) {
216  sprite_def = ecalloc(1, sizeof(*sprite_def));
217  /* Store the sprite ID and name. */
218  sprite_def->id = image_get_id(buf + 7);
219  sprite_def->name = estrdup(buf + 7);
220  /* Initialize default values. */
221  sprite_def->chance = 1;
222  sprite_def->weight = 1.0;
223  sprite_def->weight_mod = 2.0;
224  sprite_def->wind = 1;
225  sprite_def->wiggle = 1.0;
226  sprite_def->wind_mod = 1.0;
227  sprite_def->x = -1;
228  sprite_def->y = -1;
229  sprite_def->reverse = 0;
230  sprite_def->y_rndm = 60.0;
231  sprite_def->x_mod = 1.0;
232  sprite_def->y_mod = 1.0;
233  sprite_def->x_check_mod = 1;
234  sprite_def->y_check_mod = 1;
235  sprite_def->kill_side_left = 1;
236  sprite_def->kill_side_right = 0;
237  sprite_def->zoom = 0;
238  sprite_def->warp_sides = 1;
239  sprite_def->ttl = 0;
240  sprite_def->sound_volume = 100;
241  }
242  }/* Start of effect block. */
243  else if (!strncmp(buf, "effect ", 7)) {
244  effect = ecalloc(1, sizeof(effect_struct));
245  /* Store the effect unique name. */
246  strncpy(effect->name, buf + 7, sizeof(effect->name) - 1);
247  effect->name[sizeof(effect->name) - 1] = '\0';
248  /* Initialize default values. */
249  effect->wind_chance = 0.98;
250  effect->sprite_chance = 60.0;
252  effect->wind_mod = 1.0;
253  effect->max_sprites = -1;
254  effect->sprites_per_move = 1;
255  effect->sound_channel = -1;
256  effect->sound_volume = 100;
257  }
258  }
259 
260  /* Close the file. */
261  fclose(fp);
262 }
263 
267 void effects_deinit(void)
268 {
269  effect_struct *effect, *effect_next;
270  effect_sprite_def *sprite_def, *sprite_def_next;
271 
272  /* Deinitialize all effects. */
273  for (effect = effects; effect; effect = effect_next) {
274  effect_next = effect->next;
275 
276  /* Deinitialize the effect's sprite definitions. */
277  for (sprite_def = effect->sprite_defs; sprite_def; sprite_def = sprite_def_next) {
278  sprite_def_next = sprite_def->next;
279  effect_sprite_def_free(sprite_def);
280  }
281 
282  /* Deinitialize the shown sprites and the actual effect. */
283  effect_sprites_free(effect);
284  effect_free(effect);
285  }
286 
287  effects = current_effect = NULL;
288 }
289 
294 void effects_reinit(void)
295 {
296  effect_struct *effect;
297  effect_sprite_def *sprite_def;
298 
299  for (effect = effects; effect; effect = effect->next) {
300  for (sprite_def = effect->sprite_defs; sprite_def; sprite_def = sprite_def->next) {
301  sprite_def->id = image_get_id(sprite_def->name);
302  }
303  }
304 }
305 
312 {
313  effect_sprite *tmp, *next;
314 
315  for (tmp = effect->sprites; tmp; tmp = next) {
316  next = tmp->next;
317  effect_sprite_free(tmp);
318  }
319 
320  effect->sprites = effect->sprites_end = NULL;
321 
322  if (effect->sound_channel != -1) {
323 #ifdef HAVE_SDL_MIXER
324  Mix_HaltChannel(effect->sound_channel);
325 #endif
326  effect->sound_channel = -1;
327  }
328 }
329 
336 {
337  if (effect->overlay) {
338  efree(effect->overlay);
339  }
340 
341  efree(effect);
342 }
343 
350 {
351  efree(sprite_def->name);
352  efree(sprite_def);
353 }
354 
361 {
362  efree(sprite);
363 }
364 
371 {
372  if (!sprite || !current_effect) {
373  return;
374  }
375 
376  if (sprite->prev) {
377  sprite->prev->next = sprite->next;
378  } else {
379  current_effect->sprites = sprite->next;
380  }
381 
382  if (sprite->next) {
383  sprite->next->prev = sprite->prev;
384  } else {
385  current_effect->sprites_end = sprite->prev;
386  }
387 
388  effect_sprite_free(sprite);
389 }
390 
402 {
403  int roll;
404  effect_sprite_def *tmp;
405  effect_sprite *sprite;
406 
407  if (!effect->sprite_defs) {
408  return NULL;
409  }
410 
411  /* Choose which sprite to use. */
412  roll = rndm(1, effect->chance_total) - 1;
413 
414  for (tmp = effect->sprite_defs; tmp; tmp = tmp->next) {
415  roll -= tmp->chance;
416 
417  if (roll < 0) {
418  break;
419  }
420  }
421 
422  if (!tmp) {
423  return NULL;
424  }
425 
426  /* Allocate a new sprite. */
427  sprite = ecalloc(1, sizeof(*sprite));
428  sprite->def = tmp;
429 
430  /* Add it to the linked list. */
431  if (!effect->sprites) {
432  effect->sprites = effect->sprites_end = sprite;
433  } else {
434  effect->sprites_end->next = sprite;
435  sprite->prev = effect->sprites_end;
436  effect->sprites_end = sprite;
437  }
438 
439  return sprite;
440 }
441 
446 {
447  effect_sprite *tmp, *next;
448  int num_sprites = 0;
449  int x_check, y_check;
450  uint32_t ticks;
452 
453  /* No current effect or not playing, quit. */
454  if (!current_effect || cpl.state != ST_PLAY) {
455  return;
456  }
457 
458  ticks = SDL_GetTicks();
459  memset(&sprite_effects, 0, sizeof(sprite_effects));
460 
461  for (tmp = current_effect->sprites; tmp; tmp = next) {
462  next = tmp->next;
463 
464  if (!FaceList[tmp->def->id].sprite) {
465  continue;
466  }
467 
468  /* Check if the sprite should be removed due to ttl being up. */
469  if (tmp->def->ttl && ticks - tmp->created_tick > tmp->def->ttl) {
471  continue;
472  }
473 
474  x_check = y_check = 0;
475 
476  if (tmp->def->x_check_mod) {
477  x_check = FaceList[tmp->def->id].sprite->bitmap->w;
478  }
479 
480  if (tmp->def->y_check_mod) {
481  y_check = FaceList[tmp->def->id].sprite->bitmap->h;
482  }
483 
484  if (tmp->def->warp_sides) {
485  if (tmp->x + x_check < 0) {
486  tmp->x = cur_widget[MAP_ID]->w;
487  continue;
488  } else if (tmp->x - x_check > cur_widget[MAP_ID]->w) {
489  tmp->x = -x_check;
490  continue;
491  }
492  }
493 
494  /* Off-screen? */
495  if ((tmp->def->kill_side_left && tmp->x + x_check < 0) || (tmp->def->kill_side_right && tmp->x - x_check > cur_widget[MAP_ID]->h) || tmp->y + y_check < 0 || tmp->y - y_check > cur_widget[MAP_ID]->h) {
497  continue;
498  }
499 
500  /* Show the sprite. */
501  sprite_effects.zoom_x = sprite_effects.zoom_y = tmp->def->zoom;
502  surface_show_effects(cur_widget[MAP_ID]->surface, tmp->x, tmp->y, NULL,
503  FaceList[tmp->def->id].sprite->bitmap, &sprite_effects);
504  num_sprites++;
505 
506  /* Move it if there is no delay configured or if enough time has passed.
507  * */
508  if (!tmp->def->delay || !tmp->delay_ticks || ticks - tmp->delay_ticks > tmp->def->delay) {
509  int xpos, ypos;
510 
511  xpos = (-1.0 + 3.0 * RANDOM() / (RAND_MAX + 1.0)) * tmp->def->wiggle;
512  ypos = tmp->def->weight * tmp->def->weight_mod;
513 
514  /* Apply wind. */
515  if (tmp->def->wind && current_effect->wind_blow_dir != WIND_BLOW_NONE) {
516  xpos += ((double) current_effect->wind / tmp->def->weight + tmp->def->weight * tmp->def->weight_mod * ((-1.0 + 2.0 * RANDOM() / (RAND_MAX + 1.0)) * tmp->def->wind_mod));
517  }
518 
519  if (tmp->def->reverse) {
520  ypos = -ypos;
521  }
522 
523  tmp->x += (double) xpos * (60.0 / (double) max_frames);
524  tmp->y += (double) ypos * (60.0 / (double) max_frames);
525 
526  tmp->delay_ticks = ticks;
527  map_redraw_flag = 1;
528  }
529  }
530 
531  /* Change wind direction... */
532  if (current_effect->wind_blow_dir == WIND_BLOW_RANDOM &&
533  !DBL_EQUAL(current_effect->wind_chance, 1.0) &&
534  (DBL_EQUAL(current_effect->wind_chance, 0.0) ||
535  RANDOM() / (RAND_MAX + 1.0) >= current_effect->wind_chance)) {
536  current_effect->wind += (-2.0 + 4.0 * RANDOM() / (RAND_MAX + 1.0)) *
537  current_effect->wind_mod;
538  }
539 
540  if (current_effect->wind_blow_dir == WIND_BLOW_LEFT) {
541  current_effect->wind = -1.0 * current_effect->wind_mod;
542  } else if (current_effect->wind_blow_dir == WIND_BLOW_RIGHT) {
543  current_effect->wind = 1.0 * current_effect->wind_mod;
544  }
545 
546  if ((current_effect->max_sprites == -1 || num_sprites < current_effect->max_sprites) && (!current_effect->delay || !current_effect->delay_ticks || ticks - current_effect->delay_ticks > current_effect->delay) && RANDOM() / (RAND_MAX + 1.0) >= (100.0 - current_effect->sprite_chance) / 100.0) {
547  int i;
548  effect_sprite *sprite;
549 
550  for (i = 0; i < current_effect->sprites_per_move; i++) {
551  /* Add the sprite. */
552  sprite = effect_sprite_create(current_effect);
553 
554  if (!sprite) {
555  return;
556  }
557 
558  /* Invalid sprite. */
559  if (sprite->def->id == -1 || !FaceList[sprite->def->id].sprite) {
560  LOG(INFO, "Invalid sprite ID %d", sprite->def->id);
561  effect_sprite_remove(sprite);
562  return;
563  }
564 
565  if (sprite->def->x != -1) {
566  sprite->x = sprite->def->x;
567  } else {
568  /* Calculate where to put the sprite. */
569  sprite->x = (double) cur_widget[MAP_ID]->w * RANDOM() / (RAND_MAX + 1.0) * sprite->def->x_mod;
570  }
571 
572  if (sprite->def->reverse) {
573  sprite->y = cur_widget[MAP_ID]->h - FaceList[sprite->def->id].sprite->bitmap->h;
574  } else if (sprite->def->y != -1) {
575  sprite->y = sprite->def->y;
576  }
577 
578  sprite->y += sprite->def->y_rndm * (RANDOM() / (RAND_MAX + 1.0) * sprite->def->y_mod);
579 
580  sprite->x += sprite->def->xpos;
581  sprite->y += sprite->def->ypos;
582 
583  if (sprite->def->sound_file[0] != '\0') {
584  sound_play_effect(sprite->def->sound_file, sprite->def->sound_volume);
585  }
586 
587  sprite->created_tick = ticks;
588  map_redraw_flag = 1;
589  }
590 
591  current_effect->delay_ticks = ticks;
592  }
593 }
594 
595 void effect_frames(int frames)
596 {
597  max_frames = frames;
598 
599  if (current_effect != NULL) {
600  map_redraw_flag = 1;
601  }
602 }
603 
612 int effect_start(const char *name)
613 {
614  effect_struct *tmp;
615 
616  /* Stop playing any effect. */
617  if (!strcmp(name, "none")) {
618  effect_stop();
619  return 1;
620  }
621 
622  /* Already playing the same effect? */
623  if (current_effect && !strcmp(current_effect->name, name)) {
624  return 1;
625  }
626 
627  /* Find the effect... */
628  for (tmp = effects; tmp; tmp = tmp->next) {
629  /* Found it? */
630  if (!strcmp(tmp->name, name)) {
631  /* Stop current effect (if any) */
632  effect_stop();
633  /* Reset wind direction. */
634  tmp->wind = 0;
635  /* Load it up. */
636  current_effect = tmp;
637 
638  if (current_effect->sound_effect[0] != '\0') {
639  current_effect->sound_channel = sound_play_effect_loop(current_effect->sound_effect, current_effect->sound_volume, -1);
640  }
641 
642  return 1;
643  }
644  }
645 
646  return 0;
647 }
648 
654 void effect_debug(const char *type)
655 {
656  if (!strcmp(type, "num")) {
657  uint32_t num = 0;
658  uint64_t bytes;
659  double kbytes;
660  effect_sprite *tmp;
661 
662  if (!current_effect) {
663  draw_info(COLOR_RED, "No effect is currently playing.");
664  return;
665  }
666 
667  for (tmp = current_effect->sprites; tmp; tmp = tmp->next) {
668  num++;
669  }
670 
671  bytes = ((uint64_t) sizeof(effect_sprite)) * num;
672  kbytes = (double) bytes / 1024;
673 
674  draw_info_format(COLOR_WHITE, "Visible sprites: [green]%d[/green] using [green]%"PRIu64 "[/green] bytes ([green]%2.2f[/green] KB)", num, bytes, kbytes);
675  } else if (!strcmp(type, "sizeof")) {
676  draw_info(COLOR_WHITE, "Information about various data structures used by effects:\n");
677  draw_info_format(COLOR_WHITE, "Size of a single sprite definition: [green]%"PRIu64 "[/green]", (uint64_t) sizeof(effect_sprite_def));
678  draw_info_format(COLOR_WHITE, "Size of a single visible sprite: [green]%"PRIu64 "[/green]", (uint64_t) sizeof(effect_sprite));
679  draw_info_format(COLOR_WHITE, "Size of a single effect structure: [green]%"PRIu64 "[/green]", (uint64_t) sizeof(effect_struct));
680  draw_info_format(COLOR_WHITE, "Size of a single overlay: [green]%"PRIu64 "[/green]", (uint64_t) sizeof(effect_overlay));
681  } else {
682  draw_info_format(COLOR_RED, "No such debug option '%s'.", type);
683  }
684 }
685 
689 void effect_stop(void)
690 {
691  if (!current_effect) {
692  return;
693  }
694 
695  effect_sprites_free(current_effect);
696  current_effect = NULL;
697 }
698 
704 uint8_t effect_has_overlay(void)
705 {
706  if (!current_effect) {
707  return 0;
708  }
709 
710  return current_effect->overlay ? 1 : 0;
711 }
712 
718 const char *effect_overlay_identifier(void)
719 {
720  if (current_effect == NULL || !current_effect->overlay) {
721  return "";
722  }
723 
724  return current_effect->name;
725 }
726 
734 SDL_Surface *effect_sprite_overlay(SDL_Surface *surface)
735 {
736  SDL_Surface *tmp = SDL_ConvertSurface(surface, FormatHolder->format,
737  FormatHolder->flags);
738  if (tmp == NULL) {
739  return NULL;
740  }
741 
742  for (int y = 0; y < tmp->h; y++) {
743  for (int x = 0; x < tmp->w; x++) {
744  Uint8 vals[4];
745  SDL_GetRGBA(getpixel(tmp, x, y), tmp->format, &vals[0], &vals[1],
746  &vals[2], &vals[3]);
747 
748  int idx = 0, r, g, b, a;
749  EFFECT_SCALE_ADJUST(r, current_effect->overlay);
750  EFFECT_SCALE_ADJUST(g, current_effect->overlay);
751  EFFECT_SCALE_ADJUST(b, current_effect->overlay);
752  EFFECT_SCALE_ADJUST(a, current_effect->overlay);
753 
754  putpixel(tmp, x, y, SDL_MapRGBA(tmp->format, r, g, b, a));
755  }
756  }
757 
758  SDL_Surface *ret = SDL_DisplayFormatAlpha(tmp);
759  SDL_FreeSurface(tmp);
760  return ret;
761 }
struct effect_sprite * sprites
Definition: effects.h:68
uint8_t rndm_max
Definition: effects.h:278
uint8_t rndm_min
Definition: effects.h:275
void surface_show_effects(SDL_Surface *surface, int x, int y, SDL_Rect *srcrect, SDL_Surface *src, const sprite_effects_t *effects)
Definition: sprite.c:830
struct effect_sprite * next
Definition: effects.h:124
#define WIND_BLOW_RIGHT
Definition: effects.h:42
char name[MAX_BUF]
Definition: effects.h:53
int sprites_per_move
Definition: effects.h:103
double wind_mod
Definition: effects.h:100
Definition: main.h:332
void effects_deinit(void)
Definition: effects.c:267
static uint32_t ticks
Definition: range_buttons.c:38
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
Definition: sprite.c:950
double sprite_chance
Definition: effects.h:65
struct effect_sprite_def * sprite_defs
Definition: effects.h:74
int effect_start(const char *name)
Definition: effects.c:612
void effects_init(void)
Definition: effects.c:46
uint8_t y_check_mod
Definition: effects.h:228
double weight_mod
Definition: effects.h:163
void draw_info(const char *color, const char *str)
Definition: textwin.c:448
double wind_mod
Definition: effects.h:188
SDL_Surface * bitmap
Definition: sprite.h:96
uint8_t wind
Definition: effects.h:176
uint8_t effect_has_overlay(void)
Definition: effects.c:704
uint8_t kill_side_right
Definition: effects.h:240
void sound_play_effect(const char *filename, int volume)
Definition: sound.c:367
int16_t zoom_x
Horizontal zoom.
Definition: sprite.h:50
struct effect_sprite * prev
Definition: effects.h:127
int chance_total
Definition: effects.h:77
struct effect_sprite_def * def
Definition: effects.h:142
static effect_sprite * effect_sprite_create(effect_struct *effect)
Definition: effects.c:401
Uint32 getpixel(SDL_Surface *surface, int x, int y)
Definition: sprite.c:910
SDL_Surface * FormatHolder
Definition: sprite.c:46
static effect_struct * current_effect
Definition: effects.c:38
#define WIND_BLOW_LEFT
Definition: effects.h:40
#define WIND_BLOW_RANDOM
Definition: effects.h:44
struct effect_overlay * overlay
Definition: effects.h:118
struct effect_sprite_def * next
Definition: effects.h:148
void effect_free(effect_struct *effect)
Definition: effects.c:335
const char * effect_overlay_identifier(void)
Definition: effects.c:718
#define WIND_BLOW_NONE
Definition: effects.h:38
void effect_sprite_def_free(effect_sprite_def *sprite_def)
Definition: effects.c:349
uint8_t reverse
Definition: effects.h:204
int sound_volume
Definition: effects.h:109
#define COLOR_RED
Definition: text.h:295
FILE * server_file_open_name(const char *name)
Definition: server_files.c:437
struct effect_struct * next
Definition: effects.h:50
uint32_t delay
Definition: effects.h:90
uint32_t ttl
Definition: effects.h:254
char sound_file[MAX_BUF]
Definition: effects.h:260
#define EFFECT_SCALE_ADJUST(i, overlay)
Definition: effects.h:290
uint8_t warp_sides
Definition: effects.h:251
int sound_play_effect_loop(const char *filename, int volume, int loop)
Definition: sound.c:390
uint32_t delay_ticks
Definition: effects.h:93
Client_Player cpl
Definition: client.c:50
_face_struct FaceList[MAX_FACE_TILES]
Definition: main.c:77
uint16_t zoom
Definition: effects.h:246
int image_get_id(const char *name)
Definition: image.c:448
widgetdata * cur_widget[TOTAL_SUBWIDGETS]
Definition: widget.c:75
double mod[5]
Definition: effects.h:272
int max_sprites
Definition: effects.h:96
uint32_t delay_ticks
Definition: effects.h:136
struct effect_sprite * sprites_end
Definition: effects.h:71
uint8_t wind_blow_dir
Definition: effects.h:84
uint32_t delay
Definition: effects.h:173
void effect_sprite_free(effect_sprite *sprite)
Definition: effects.c:360
uint32_t created_tick
Definition: effects.h:139
void effects_reinit(void)
Definition: effects.c:294
static const char * overlay_cols[]
Definition: effects.c:40
int w
Definition: widget.h:54
int h
Definition: widget.h:57
SDL_Surface * effect_sprite_overlay(SDL_Surface *surface)
Definition: effects.c:734
void effect_sprite_remove(effect_sprite *sprite)
Definition: effects.c:370
int16_t zoom_y
Vertical zoom.
Definition: sprite.h:51
void effect_sprites_play(void)
Definition: effects.c:445
long wind
Definition: effects.h:80
char sound_effect[MAX_BUF]
Definition: effects.h:106
void draw_info_format(const char *color, const char *format,...)
Definition: textwin.c:429
void effect_sprites_free(effect_struct *effect)
Definition: effects.c:311
uint8_t sound_volume
Definition: effects.h:263
int sound_channel
Definition: effects.h:115
uint8_t x_check_mod
Definition: effects.h:222
void effect_debug(const char *type)
Definition: effects.c:654
effect_overlay_col col[4]
Definition: effects.h:286
double wind_chance
Definition: effects.h:59
uint8_t kill_side_left
Definition: effects.h:234
static effect_struct * effects
Definition: effects.c:36
void effect_stop(void)
Definition: effects.c:689
#define COLOR_WHITE
Definition: text.h:289