Atrinik Client  4.0
active_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 
38 typedef struct active_effect_struct {
43 
48 
52  object *op;
53 
57  int32_t sec;
58 
62  char *msg;
64 
69  active_effect_struct *active_effects;
70 
71  uint32_t update_ticks;
73 
75 static void widget_draw(widgetdata *widget)
76 {
78  active_effect_struct *effect;
79  SDL_Rect box;
80 
81  tmp = widget->subwidget;
82 
83  if (SDL_GetTicks() - tmp->update_ticks > 1000) {
84  uint8_t redraw;
85  int sec;
86 
87  redraw = 0;
88  sec = (SDL_GetTicks() - tmp->update_ticks) / 1000;
89  tmp->update_ticks = SDL_GetTicks();
90 
91  DL_FOREACH(tmp->active_effects, effect)
92  {
93  if (effect->sec > 0) {
94  effect->sec -= sec;
95 
96  if (effect->sec < 0) {
97  effect->sec = 0;
98  }
99 
100  redraw = 1;
101  }
102  }
103 
104  widget->redraw += redraw;
105  }
106 
107  if (!widget->surface || widget->w != widget->surface->w || widget->h != widget->surface->h) {
108  if (widget->surface) {
109  SDL_FreeSurface(widget->surface);
110  }
111 
112  widget->surface = SDL_CreateRGBSurface(get_video_flags(), widget->w, widget->h, video_get_bpp(), 0, 0, 0, 0);
113  SDL_SetColorKey(widget->surface, SDL_SRCCOLORKEY | SDL_ANYFORMAT, 0);
114  }
115 
116  if (widget->redraw) {
117  int x, y;
118  sprite_struct *sprite;
119 
120  x = y = 0;
121 
122  SDL_FillRect(widget->surface, NULL, 0);
123 
124  DL_FOREACH(tmp->active_effects, effect)
125  {
126  sprite = FaceList[effect->op->face].sprite;
127 
128  if (!sprite) {
129  continue;
130  }
131 
132  if (x + sprite->bitmap->w > widget->w) {
133  x = 0;
134  y += sprite->bitmap->h + 5;
135  }
136 
137  if (y + sprite->bitmap->h > widget->h) {
138  resize_widget(widget, RESIZE_BOTTOM, y + sprite->bitmap->h);
139  widget->redraw++;
140  }
141 
142  if (effect->op->face != -1 &&
143  FaceList[effect->op->face].sprite != NULL) {
144  surface_show(widget->surface, x, y, NULL,
145  FaceList[effect->op->face].sprite->bitmap);
146  }
147 
148  if (effect->sec != -1) {
149  SDL_Rect textbox;
150  char buf[MAX_BUF];
151 
152  textbox.w = sprite->bitmap->w;
153 
154  if (effect->sec > 60) {
155  snprintf(buf, sizeof(buf), "%d:%02d", effect->sec / 60, effect->sec % 60);
156  } else {
157  snprintf(buf, sizeof(buf), "%d", effect->sec);
158  }
159 
160  text_show(widget->surface, FONT_MONO8, buf, x, y + sprite->bitmap->h - FONT_HEIGHT(FONT_MONO8), COLOR_WHITE, TEXT_OUTLINE | TEXT_ALIGN_CENTER, &textbox);
161  }
162 
163  x += sprite->bitmap->w + 5;
164  }
165  }
166 
167  box.x = widget->x;
168  box.y = widget->y;
169  SDL_BlitSurface(widget->surface, NULL, ScreenSurface, &box);
170 }
171 
173 static int widget_event(widgetdata *widget, SDL_Event *event)
174 {
176 
177  tmp = widget->subwidget;
178 
179  if (event->type == SDL_MOUSEMOTION) {
180  active_effect_struct *effect;
181  int x, y;
182  sprite_struct *sprite;
183 
184  x = y = 0;
185 
186  DL_FOREACH(tmp->active_effects, effect)
187  {
188  sprite = FaceList[effect->op->face].sprite;
189 
190  if (!sprite) {
191  continue;
192  }
193 
194  if (x + sprite->bitmap->w > widget->w) {
195  x = 0;
196  y += sprite->bitmap->h + 5;
197  }
198 
199  if (event->motion.x >= widget->x + x && event->motion.x < widget->x + x + sprite->bitmap->w && event->motion.y >= widget->y + y && event->motion.y < widget->y + y + sprite->bitmap->h) {
200  char buf[HUGE_BUF];
201 
202  snprintf(buf, sizeof(buf), "[b]%s[/b]%s%s", effect->op->s_name, effect->msg[0] != '\0' ? "\n" : "", effect->msg);
203  tooltip_create(event->motion.x, event->motion.y, FONT_ARIAL11, buf);
204  tooltip_multiline(200);
205  break;
206  }
207 
208  x += sprite->bitmap->w + 5;
209  }
210  }
211 
212  return 0;
213 }
214 
215 void widget_active_effects_update(widgetdata *widget, object *op, int32_t sec, const char *msg)
216 {
218  active_effect_struct *effect;
219 
220  tmp = widget->subwidget;
221 
222  if (!(op->flags & CS_FLAG_APPLIED)) {
223  return;
224  }
225 
226  DL_FOREACH(tmp->active_effects, effect)
227  {
228  if (effect->op == op) {
229  break;
230  }
231  }
232 
233  if (!effect) {
234  effect = ecalloc(1, sizeof(*effect));
235  DL_APPEND(tmp->active_effects, effect);
236  } else {
237  efree(effect->msg);
238  }
239 
240  effect->op = op;
241  effect->sec = sec;
242  effect->msg = estrdup(msg);
243 
244  WIDGET_REDRAW(widget);
245 }
246 
247 void widget_active_effects_remove(widgetdata *widget, object *op)
248 {
250  active_effect_struct *effect, *next;
251 
252  tmp = widget->subwidget;
253 
254  DL_FOREACH_SAFE(tmp->active_effects, effect, next)
255  {
256  if (effect->op == op) {
257  DL_DELETE(tmp->active_effects, effect);
258  efree(effect->msg);
259  efree(effect);
260  WIDGET_REDRAW(widget);
261  break;
262  }
263  }
264 }
265 
270 {
272 
273  tmp = ecalloc(1, sizeof(*tmp));
274 
275  widget->draw_func = widget_draw;
276  widget->event_func = widget_event;
277  widget->subwidget = tmp;
278 }
static void widget_draw(widgetdata *widget)
char s_name[NAME_LEN]
Definition: item.h:60
void widget_active_effects_init(widgetdata *widget)
SDL_Surface * bitmap
Definition: sprite.h:96
void * subwidget
Definition: widget.h:107
SDL_Surface * surface
Definition: widget.h:110
uint32_t get_video_flags(void)
Definition: video.c:365
int16_t face
Definition: item.h:72
void text_show(SDL_Surface *surface, font_struct *font, const char *text, int x, int y, const char *color_notation, uint64_t flags, SDL_Rect *box)
Definition: text.c:1983
void tooltip_create(int mx, int my, font_struct *font, const char *text)
Definition: tooltip.c:60
struct active_effect_struct active_effect_struct
static int widget_event(widgetdata *widget, SDL_Event *event)
SDL_Surface * ScreenSurface
Definition: main.c:47
#define TEXT_ALIGN_CENTER
Definition: text.h:230
int video_get_bpp(void)
Definition: video.c:334
_face_struct FaceList[MAX_FACE_TILES]
Definition: main.c:77
uint8_t redraw
Definition: widget.h:72
#define FONT_HEIGHT(font)
Definition: text.h:327
struct active_effect_struct * prev
int x
Definition: widget.h:48
#define WIDGET_REDRAW(__tmp)
Definition: widget.h:398
#define TEXT_OUTLINE
Definition: text.h:255
int w
Definition: widget.h:54
int h
Definition: widget.h:57
void tooltip_multiline(int max_width)
Definition: tooltip.c:96
void surface_show(SDL_Surface *surface, int x, int y, SDL_Rect *srcrect, SDL_Surface *src)
Definition: sprite.c:761
struct widget_active_effects_struct widget_active_effects_struct
uint32_t flags
Definition: item.h:87
struct active_effect_struct * next
#define COLOR_WHITE
Definition: text.h:289
int y
Definition: widget.h:51