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' * BORDER_MULTIPLIER * panel_bg_border);
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 string minigame_texture_skin(string skinname, string name)
47 return sprintf("gfx/hud/%s/minigames/%s", skinname, name);
49 string minigame_texture(string name)
51 string path = minigame_texture_skin(autocvar_menu_skin,name);
52 if ( precache_pic(path) == "" )
53 path = minigame_texture_skin("default", name);
57 #define FIELD(Flags, Type, Name) MSLE_CLEAN_##Type(this.Name)
58 #define MSLE_CLEAN_String(x) strunzone(x);
59 #define MSLE_CLEAN_Byte(x)
60 #define MSLE_CLEAN_Char(x)
61 #define MSLE_CLEAN_Short(x)
62 #define MSLE_CLEAN_Long(x)
63 #define MSLE_CLEAN_Coord(x)
64 #define MSLE_CLEAN_Angle(x)
65 #define MSLE_CLEAN_Float(x)
66 #define MSLE_CLEAN_Vector(x)
67 #define MSLE_CLEAN_Vector2D(x)
69 #define MSLE(Name,Fields) \
70 void msle_entremove_##Name(entity this) { strunzone(this.netname); Fields }
71 MINIGAME_SIMPLELINKED_ENTITIES
75 void minigame_autoclean_entity(entity e)
77 LOG_DEBUG("CL Auto-cleaned: ",ftos(etof(e)), " (",e.classname,")");
81 void HUD_MinigameMenu_CurrentButton();
82 bool auto_close_minigamemenu;
83 void deactivate_minigame()
85 if ( !active_minigame )
88 active_minigame.minigame_event(active_minigame,"deactivate");
90 while( (e = findentity(e, owner, active_minigame)) )
91 if ( e.minigame_autoclean )
93 minigame_autoclean_entity(e);
97 active_minigame = NULL;
99 if ( auto_close_minigamemenu )
101 HUD_MinigameMenu_Close(NULL, NULL, NULL);
102 auto_close_minigamemenu = 0;
105 HUD_MinigameMenu_CurrentButton();
108 void minigame_entremove(entity this)
110 if ( this == active_minigame )
111 deactivate_minigame();
114 void activate_minigame(entity minigame)
118 deactivate_minigame();
122 if ( !minigame.descriptor || minigame.classname != "minigame" )
124 LOG_TRACE("Trying to activate unregistered minigame ",minigame.netname," in client");
128 if ( minigame == active_minigame )
131 if ( active_minigame )
133 deactivate_minigame();
136 if ( minigame_self.owner != minigame )
137 minigame_self = NULL;
138 active_minigame = minigame;
139 active_minigame.minigame_event(active_minigame,"activate");
141 if ( HUD_MinigameMenu_IsOpened() )
142 HUD_MinigameMenu_CurrentButton();
145 auto_close_minigamemenu = 1;
146 HUD_MinigameMenu_Open();
150 void minigame_player_entremove(entity this)
152 if ( this.owner == active_minigame && this.minigame_playerslot == player_localentnum )
153 deactivate_minigame();
156 string() ReadString_Raw = #366;
157 string ReadString_Zoned() { return strzone(ReadString_Raw()); }
158 #define ReadString ReadString_Zoned
159 #define FIELD(Flags, Type,Name) if ( sf & (Flags) ) this.Name = Read##Type();
160 #define MSLE(Name,Fields) \
161 else if ( this.classname == #Name ) { \
162 if ( sf & MINIG_SF_CREATE ) { \
163 minigame_read_owner(this); \
164 this.entremove = msle_entremove_##Name; \
166 minigame_ent = this.owner; \
169 void minigame_read_owner(entity this)
171 string owner_name = ReadString_Raw();
174 this.owner = find(this.owner,netname,owner_name);
175 while ( this.owner && this.owner.classname != "minigame" );
177 LOG_TRACE("Got a minigame entity without a minigame!");
179 NET_HANDLE(ENT_CLIENT_MINIGAME, bool isnew)
181 float sf = ReadByte();
182 if ( sf & MINIG_SF_CREATE )
184 this.classname = msle_classname(ReadShort());
185 this.netname = ReadString_Zoned();
188 entity minigame_ent = NULL;
190 if ( this.classname == "minigame" )
194 if ( sf & MINIG_SF_CREATE )
196 this.entremove = minigame_entremove;
197 this.descriptor = minigame_get_descriptor(ReadString_Raw());
198 if ( !this.descriptor )
199 LOG_TRACE("Got a minigame without a client-side descriptor!");
201 this.minigame_event = this.descriptor.minigame_event;
203 if ( sf & MINIG_SF_UPDATE )
204 this.minigame_flags = ReadLong();
206 else if ( this.classname == "minigame_player" )
209 if ( sf & MINIG_SF_CREATE )
211 this.entremove = minigame_player_entremove;
212 minigame_read_owner(this);
213 float ent = ReadLong();
214 this.minigame_playerslot = ent;
215 LOG_DEBUG("Player: ",entcs_GetName(ent-1));
217 activate = (ent == player_localnum+1 && this.owner && this.owner != active_minigame);
220 minigame_ent = this.owner;
222 if ( sf & MINIG_SF_UPDATE )
223 this.team = ReadByte();
227 minigame_self = this;
228 activate_minigame(this.owner);
229 minigame_self = this; // set it again (needed before, but may also be reset)
232 MINIGAME_SIMPLELINKED_ENTITIES
235 minigame_ent.minigame_event(minigame_ent,"network_receive",this,sf);
237 if ( sf & MINIG_SF_CREATE )
239 LOG_DEBUG("CL Reading entity: ",ftos(etof(this)),
240 " classname:",this.classname," enttype:",ftos(this.enttype) );
241 LOG_DEBUG(" sf:",ftos(sf)," netname:",this.netname);
249 string minigame_getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
256 s = getWrappedLine_remaining;
260 getWrappedLine_remaining = string_null;
261 return s; // the line has no size ANYWAY, nothing would be displayed.
264 take_until = textLengthUpToWidth(s, w, theFontSize, tw);
266 if ( take_until > strlen(s) )
267 take_until = strlen(s);
269 for ( int i = 0; i < take_until; i++ )
270 if ( substring(s,i,1) == "\n" )
277 if ( take_until > 0 || skip > 0 )
279 if ( skip == 0 && take_until < strlen(s) )
281 last_word = take_until;
282 while(last_word > 0 && substring(s, last_word, 1) != " ")
285 if ( last_word != 0 )
287 take_until = last_word;
292 getWrappedLine_remaining = substring(s, take_until+skip, strlen(s) - (take_until+skip));
293 if(getWrappedLine_remaining == "")
294 getWrappedLine_remaining = string_null;
295 else if (tw("^7", theFontSize) == 0)
296 getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take_until)), getWrappedLine_remaining);
297 return substring(s, 0, take_until);
301 getWrappedLine_remaining = string_null;
306 vector minigame_drawstring_wrapped( float maxwidth, vector pos, string text,
307 vector fontsize, vector color, float theAlpha, int drawflags, float align )
309 getWrappedLine_remaining = text;
311 while ( getWrappedLine_remaining )
313 string line = minigame_getWrappedLine(maxwidth,fontsize,stringwidth_nocolors);
316 mypos_x = pos_x + (maxwidth - stringwidth_nocolors(line, fontsize)) * align;
317 drawstring(mypos, line, fontsize, color, theAlpha, drawflags);
318 mypos_y += fontsize_y;
325 vector minigame_drawcolorcodedstring_wrapped( float maxwidth, vector pos,
326 string text, vector fontsize, float theAlpha, int drawflags, float align )
328 getWrappedLine_remaining = text;
330 while ( getWrappedLine_remaining )
332 string line = minigame_getWrappedLine(maxwidth,fontsize,stringwidth_colors);
335 mypos_x = pos_x + (maxwidth - stringwidth_colors(line, fontsize)) * align;
336 drawcolorcodedstring(mypos, line, fontsize, theAlpha, drawflags);
337 mypos_y += fontsize_y;
344 void minigame_drawstring_trunc(float maxwidth, vector pos, string text,
345 vector fontsize, vector color, float theAlpha, int drawflags )
347 string line = textShortenToWidth(text,maxwidth,fontsize,stringwidth_nocolors);
348 drawstring(pos, line, fontsize, color, theAlpha, drawflags);
351 void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text,
352 vector fontsize, float theAlpha, int drawflags )
354 string line = textShortenToWidth(text,maxwidth,fontsize,stringwidth_colors);
355 drawcolorcodedstring(pos, line, fontsize, theAlpha, drawflags);
358 void minigame_drawpic_centered( vector pos, string texture, vector sz,
359 vector color, float thealpha, int drawflags )
361 drawpic( pos-sz/2, texture, sz, color, thealpha, drawflags );
364 // Workaround because otherwise variadic arguments won't work properly
365 // It could be a bug in the compiler or in darkplaces
366 void minigame_cmd_workaround(float dummy, string...cmdargc)
369 cmd = "cmd minigame ";
371 for ( i = 0; i < cmdargc; i++ )
372 cmd = strcat(cmd,...(i,string));
373 localcmd(strcat(cmd,"\n"));
376 // Prompt the player to play in the current minigame
377 // (ie: it's their turn and they should get back to the minigame)
378 void minigame_prompt()
380 if ( active_minigame && ! HUD_MinigameMenu_IsOpened() )
382 HUD_Notify_Push(sprintf("minigames/%s/icon_notif",active_minigame.descriptor.netname),
383 _("It's your turn"), "");
387 // handle commands etc.
388 REGISTER_MUTATOR(minigames, true);
390 MUTATOR_HOOKFUNCTION(minigames, HUD_Command)
392 if(MUTATOR_RETURNVALUE) { return false; } // command was already handled
394 if(argv(1) == "minigame")
397 return true; // minigames can't function properly in demo mode
398 if (HUD_MinigameMenu_IsOpened())
399 HUD_MinigameMenu_Close(NULL, NULL, NULL);
401 HUD_MinigameMenu_Open();