1 #include "cl_minigames.qh"
3 // Draw a square in the center of the avaliable area
4 void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
6 if(panel.current_panel_bg != "0" && panel.current_panel_bg != "")
7 draw_BorderPicture(pos - '1 1 0' * panel_bg_border,
8 panel.current_panel_bg,
9 mySize + '1 1 0' * 2 * panel_bg_border,
10 panel_bg_color, panel_bg_alpha,
11 '1 1 0' * (panel_bg_border/BORDER_MULTIPLIER));
12 drawpic(pos, board_texture, mySize, '1 1 1', panel_bg_alpha, DRAWFLAG_NORMAL);
15 // De-normalize (2D vector) v from relative coordinate inside pos mySize
16 vector minigame_hud_denormalize(vector v, vector pos, vector mySize)
18 v_x = pos_x + v_x * mySize_x;
19 v_y = pos_y + v_y * mySize_y;
22 // De-normalize (2D vector) v from relative size inside pos mySize
23 vector minigame_hud_denormalize_size(vector v, vector pos, vector mySize)
30 // Normalize (2D vector) v to relative coordinate inside pos mySize
31 vector minigame_hud_normalize(vector v, vector pos, vector mySize)
33 v_x = ( v_x - pos_x ) / mySize_x;
34 v_y = ( v_y - pos_y ) / mySize_y;
38 // Check if the mouse is inside the given area
39 bool minigame_hud_mouse_in(vector pos, vector sz)
41 return mousepos_x >= pos_x && mousepos_x < pos_x + sz_x &&
42 mousepos_y >= pos_y && mousepos_y < pos_y + sz_y ;
45 void initialize_minigames()
47 entity last_minig = world;
49 #define MINIGAME(name,nicename) \
51 minig.classname = "minigame_descriptor"; \
52 minig.netname = strzone(strtolower(#name)); \
53 minig.message = nicename; \
54 minig.minigame_hud_board = name##_hud_board; \
55 minig.minigame_hud_status = name##_hud_status; \
56 minig.minigame_event = name##_client_event; \
57 if ( !last_minig ) minigame_descriptors = minig; \
58 else last_minig.list_next = minig; \
66 string minigame_texture_skin(string skinname, string name)
68 return sprintf("gfx/hud/%s/minigames/%s", skinname, name);
70 string minigame_texture(string name)
72 string path = minigame_texture_skin(autocvar_menu_skin,name);
73 if ( precache_pic(path) == "" )
74 path = minigame_texture_skin("default", name);
78 #define FIELD(Flags, Type, Name) MSLE_CLEAN_##Type(self.Name)
79 #define MSLE_CLEAN_String(x) strunzone(x);
80 #define MSLE_CLEAN_Byte(x)
81 #define MSLE_CLEAN_Char(x)
82 #define MSLE_CLEAN_Short(x)
83 #define MSLE_CLEAN_Long(x)
84 #define MSLE_CLEAN_Coord(x)
85 #define MSLE_CLEAN_Angle(x)
86 #define MSLE_CLEAN_Float(x)
87 #define MSLE_CLEAN_Vector(x)
88 #define MSLE_CLEAN_Vector2D(x)
90 #define MSLE(Name,Fields) \
91 void msle_entremove_##Name() { strunzone(self.netname); Fields }
92 MINIGAME_SIMPLELINKED_ENTITIES
96 void minigame_autoclean_entity(entity e)
98 LOG_TRACE("CL Auto-cleaned: ",ftos(num_for_edict(e)), " (",e.classname,")\n");
102 void HUD_MinigameMenu_CurrentButton();
103 bool auto_close_minigamemenu;
104 void deactivate_minigame()
106 if ( !active_minigame )
109 active_minigame.minigame_event(active_minigame,"deactivate");
111 while( (e = findentity(e, owner, active_minigame)) )
112 if ( e.minigame_autoclean )
114 minigame_autoclean_entity(e);
117 minigame_self = world;
118 active_minigame = world;
120 if ( auto_close_minigamemenu )
122 HUD_MinigameMenu_Close();
123 auto_close_minigamemenu = 0;
126 HUD_MinigameMenu_CurrentButton();
129 void minigame_entremove()
131 if ( self == active_minigame )
132 deactivate_minigame();
135 void activate_minigame(entity minigame)
139 deactivate_minigame();
143 if ( !minigame.descriptor || minigame.classname != "minigame" )
145 LOG_TRACE("Trying to activate unregistered minigame ",minigame.netname," in client\n");
149 if ( minigame == active_minigame )
152 if ( active_minigame )
154 deactivate_minigame();
157 if ( minigame_self.owner != minigame )
158 minigame_self = world;
159 active_minigame = minigame;
160 active_minigame.minigame_event(active_minigame,"activate");
162 if ( HUD_MinigameMenu_IsOpened() )
163 HUD_MinigameMenu_CurrentButton();
166 auto_close_minigamemenu = 1;
167 HUD_MinigameMenu_Open();
171 void minigame_player_entremove()
173 if ( self.owner == active_minigame && self.minigame_playerslot == player_localentnum )
174 deactivate_minigame();
177 vector ReadVector2D() { vector v; v_x = ReadCoord(); v_y = ReadCoord(); v_z = 0; return v; }
178 vector ReadVector() { vector v; v_x = ReadCoord(); v_y = ReadCoord(); v_z = ReadCoord(); return v; }
179 string() ReadString_Raw = #366;
180 string ReadString_Zoned() { return strzone(ReadString_Raw()); }
181 #define ReadString ReadString_Zoned
182 #define FIELD(Flags, Type,Name) if ( sf & (Flags) ) self.Name = Read##Type();
183 #define MSLE(Name,Fields) \
184 else if ( self.classname == #Name ) { \
185 if ( sf & MINIG_SF_CREATE ) { \
186 minigame_read_owner(); \
187 self.entremove = msle_entremove_##Name; \
189 minigame_ent = self.owner; \
192 void minigame_read_owner()
194 string owner_name = ReadString_Raw();
197 self.owner = find(self.owner,netname,owner_name);
198 while ( self.owner && self.owner.classname != "minigame" );
200 LOG_TRACE("Got a minigame entity without a minigame!\n");
202 void ent_read_minigame()
204 float sf = ReadByte();
205 if ( sf & MINIG_SF_CREATE )
207 self.classname = msle_classname(ReadShort());
208 self.netname = ReadString_Zoned();
211 entity minigame_ent = world;
213 if ( self.classname == "minigame" )
217 if ( sf & MINIG_SF_CREATE )
219 self.entremove = minigame_entremove;
220 self.descriptor = minigame_get_descriptor(ReadString_Raw());
221 if ( !self.descriptor )
222 LOG_TRACE("Got a minigame without a client-side descriptor!\n");
224 self.minigame_event = self.descriptor.minigame_event;
226 if ( sf & MINIG_SF_UPDATE )
227 self.minigame_flags = ReadLong();
229 else if ( self.classname == "minigame_player" )
232 if ( sf & MINIG_SF_CREATE )
234 self.entremove = minigame_player_entremove;
235 minigame_read_owner();
236 float ent = ReadLong();
237 self.minigame_playerslot = ent;
238 LOG_TRACE("Player: ",GetPlayerName(ent-1),"\n");
240 activate = (ent == player_localnum+1 && self.owner && self.owner != active_minigame);
243 minigame_ent = self.owner;
245 if ( sf & MINIG_SF_UPDATE )
246 self.team = ReadByte();
250 minigame_self = self;
251 activate_minigame(self.owner);
254 MINIGAME_SIMPLELINKED_ENTITIES
257 minigame_ent.minigame_event(minigame_ent,"network_receive",self,sf);
259 if ( sf & MINIG_SF_CREATE )
261 LOG_TRACE("CL Reading entity: ",ftos(num_for_edict(self)),
262 " classname:",self.classname," enttype:",ftos(self.enttype) );
263 LOG_TRACE(" sf:",ftos(sf)," netname:",self.netname,"\n\n");
270 string minigame_getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
277 s = getWrappedLine_remaining;
281 getWrappedLine_remaining = string_null;
282 return s; // the line has no size ANYWAY, nothing would be displayed.
285 take_until = textLengthUpToWidth(s, w, theFontSize, tw);
287 if ( take_until > strlen(s) )
288 take_until = strlen(s);
290 for ( int i = 0; i < take_until; i++ )
291 if ( substring(s,i,1) == "\n" )
298 if ( take_until > 0 || skip > 0 )
300 if ( skip == 0 && take_until < strlen(s) )
302 last_word = take_until;
303 while(last_word > 0 && substring(s, last_word, 1) != " ")
306 if ( last_word != 0 )
308 take_until = last_word;
313 getWrappedLine_remaining = substring(s, take_until+skip, strlen(s) - (take_until+skip));
314 if(getWrappedLine_remaining == "")
315 getWrappedLine_remaining = string_null;
316 else if (tw("^7", theFontSize) == 0)
317 getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take_until)), getWrappedLine_remaining);
318 return substring(s, 0, take_until);
322 getWrappedLine_remaining = string_null;
327 vector minigame_drawstring_wrapped( float maxwidth, vector pos, string text,
328 vector fontsize, vector color, float theAlpha, int drawflags, float align )
330 getWrappedLine_remaining = text;
332 while ( getWrappedLine_remaining )
334 string line = minigame_getWrappedLine(maxwidth,fontsize,stringwidth_nocolors);
337 mypos_x = pos_x + (maxwidth - stringwidth_nocolors(line, fontsize)) * align;
338 drawstring(mypos, line, fontsize, color, theAlpha, drawflags);
339 mypos_y += fontsize_y;
346 vector minigame_drawcolorcodedstring_wrapped( float maxwidth, vector pos,
347 string text, vector fontsize, float theAlpha, int drawflags, float align )
349 getWrappedLine_remaining = text;
351 while ( getWrappedLine_remaining )
353 string line = minigame_getWrappedLine(maxwidth,fontsize,stringwidth_colors);
356 mypos_x = pos_x + (maxwidth - stringwidth_colors(line, fontsize)) * align;
357 drawcolorcodedstring(mypos, line, fontsize, theAlpha, drawflags);
358 mypos_y += fontsize_y;
365 void minigame_drawstring_trunc(float maxwidth, vector pos, string text,
366 vector fontsize, vector color, float theAlpha, int drawflags )
368 string line = textShortenToWidth(text,maxwidth,fontsize,stringwidth_nocolors);
369 drawstring(pos, line, fontsize, color, theAlpha, drawflags);
372 void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text,
373 vector fontsize, float theAlpha, int drawflags )
375 string line = textShortenToWidth(text,maxwidth,fontsize,stringwidth_colors);
376 drawcolorcodedstring(pos, line, fontsize, theAlpha, drawflags);
379 void minigame_drawpic_centered( vector pos, string texture, vector sz,
380 vector color, float thealpha, int drawflags )
382 drawpic( pos-sz/2, texture, sz, color, thealpha, drawflags );
385 // Workaround because otherwise variadic arguments won't work properly
386 // It could be a bug in the compiler or in darkplaces
387 void minigame_cmd_workaround(float dummy, string...cmdargc)
390 cmd = "cmd minigame ";
392 for ( i = 0; i < cmdargc; i++ )
393 cmd = strcat(cmd,...(i,string));
394 localcmd(strcat(cmd,"\n"));
397 // Prompt the player to play in the current minigame
398 // (ie: it's their turn and they should get back to the minigame)
399 void minigame_prompt()
401 if ( active_minigame && ! HUD_MinigameMenu_IsOpened() )
403 HUD_Notify_Push(sprintf("minigames/%s/icon_notif",active_minigame.descriptor.netname),
404 _("It's your turn"), "");