Xonotic
cl_minigames.qc
Go to the documentation of this file.
1 #include "cl_minigames.qh"
2 
3 // Draw a square in the center of the avaliable area
4 void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
5 {
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,
12  drawpic(pos, board_texture, mySize, '1 1 1', panel_bg_alpha, DRAWFLAG_NORMAL);
13 }
14 
15 // De-normalize (2D vector) v from relative coordinate inside pos mySize
17 {
18  v_x = pos_x + v_x * mySize_x;
19  v_y = pos_y + v_y * mySize_y;
20  return v;
21 }
22 // De-normalize (2D vector) v from relative size inside pos mySize
24 {
25  v_x = v_x * mySize_x;
26  v_y = v_y * mySize_y;
27  return v;
28 }
29 
30 // Normalize (2D vector) v to relative coordinate inside pos mySize
32 {
33  v_x = ( v_x - pos_x ) / mySize_x;
34  v_y = ( v_y - pos_y ) / mySize_y;
35  return v;
36 }
37 
38 // Check if the mouse is inside the given area
40 {
41  return mousepos_x >= pos_x && mousepos_x < pos_x + sz_x &&
42  mousepos_y >= pos_y && mousepos_y < pos_y + sz_y ;
43 }
44 
45 string minigame_texture_skin(string skinname, string name)
46 {
47  return sprintf("gfx/hud/%s/minigames/%s", skinname, name);
48 }
49 string minigame_texture(string name)
50 {
51  string path = minigame_texture_skin(autocvar_menu_skin,name);
52  if ( precache_pic(path) == "" )
53  path = minigame_texture_skin("default", name);
54  return path;
55 }
56 
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)
68 
69 #define MSLE(Name,Fields) \
70  void msle_entremove_##Name(entity this) { strunzone(this.netname); Fields }
72 #undef MSLE
73 #undef FIELD
74 
76 {
77  LOG_DEBUG("CL Auto-cleaned: ",ftos(etof(e)), " (",e.classname,")");
78  delete(e);
79 }
80 
84 {
85  if ( !active_minigame )
86  return;
87 
88  active_minigame.minigame_event(active_minigame,"deactivate");
89  entity e = NULL;
90  while( (e = findentity(e, owner, active_minigame)) )
91  if ( e.minigame_autoclean )
92  {
94  }
95 
98 
100  {
103  }
104  else
106 }
107 
109 {
110  if ( this == active_minigame )
112 }
113 
114 void activate_minigame(entity minigame)
115 {
116  if ( !minigame )
117  {
119  return;
120  }
121 
122  if ( !minigame.descriptor || minigame.classname != "minigame" )
123  {
124  LOG_TRACE("Trying to activate unregistered minigame ",minigame.netname," in client");
125  return;
126  }
127 
128  if ( minigame == active_minigame )
129  return;
130 
131  if ( active_minigame )
132  {
134  }
135 
136  if ( minigame_self.owner != minigame )
138  active_minigame = minigame;
139  active_minigame.minigame_event(active_minigame,"activate");
140 
143  else
144  {
147  }
148 }
149 
151 {
154 }
155 
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; \
165  } \
166  minigame_ent = this.owner; \
167  Fields \
168  }
170 {
171  string owner_name = ReadString_Raw();
172  this.owner = NULL;
173  do
174  this.owner = find(this.owner,netname,owner_name);
175  while ( this.owner && this.owner.classname != "minigame" );
176  if ( !this.owner )
177  LOG_TRACE("Got a minigame entity without a minigame!");
178 }
179 NET_HANDLE(ENT_CLIENT_MINIGAME, bool isnew)
180 {
181  float sf = ReadByte();
182  if ( sf & MINIG_SF_CREATE )
183  {
184  this.classname = msle_classname(ReadShort());
185  this.netname = ReadString_Zoned();
186  }
187 
188  entity minigame_ent = NULL;
189 
190  if ( this.classname == "minigame" )
191  {
192  minigame_ent = this;
193 
194  if ( sf & MINIG_SF_CREATE )
195  {
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!");
200  else
201  this.minigame_event = this.descriptor.minigame_event;
202  }
203  if ( sf & MINIG_SF_UPDATE )
204  this.minigame_flags = ReadLong();
205  }
206  else if ( this.classname == "minigame_player" )
207  {
208  float activate = 0;
209  if ( sf & MINIG_SF_CREATE )
210  {
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));
216 
217  activate = (ent == player_localnum+1 && this.owner && this.owner != active_minigame);
218 
219  }
220  minigame_ent = this.owner;
221 
222  if ( sf & MINIG_SF_UPDATE )
223  this.team = ReadByte();
224 
225  if ( activate )
226  {
227  minigame_self = this;
228  activate_minigame(this.owner);
229  minigame_self = this; // set it again (needed before, but may also be reset)
230  }
231  }
233 
234  if ( minigame_ent )
235  minigame_ent.minigame_event(minigame_ent,"network_receive",this,sf);
236 
237  if ( sf & MINIG_SF_CREATE )
238  {
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);
242  }
243  return true;
244 }
245 #undef ReadString
246 #undef FIELD
247 #undef MSLE
248 
250 {
251  string s = getWrappedLine_remaining;
252 
253  if(w <= 0)
254  {
256  return s; // the line has no size ANYWAY, nothing would be displayed.
257  }
258 
259  int take_until = textLengthUpToWidth(s, w, theFontSize, tw);
260 
261  if ( take_until > strlen(s) )
262  take_until = strlen(s);
263 
264  int skip = 0;
265  for ( int i = 0; i < take_until; i++ )
266  if ( substring(s,i,1) == "\n" )
267  {
268  take_until = i;
269  skip = 1;
270  break;
271  }
272 
273  if ( take_until > 0 || skip > 0 )
274  {
275  if ( skip == 0 && take_until < strlen(s) )
276  {
277  int last_word = take_until;
278  while(last_word > 0 && substring(s, last_word, 1) != " ")
279  --last_word;
280 
281  if ( last_word != 0 )
282  {
283  take_until = last_word;
284  skip = 1;
285  }
286  }
287 
288  getWrappedLine_remaining = substring(s, take_until+skip, strlen(s) - (take_until+skip));
289  if(getWrappedLine_remaining == "")
291  else if (tw("^7", theFontSize) == 0)
293  return substring(s, 0, take_until);
294  }
295  else
296  {
298  return s;
299  }
300 }
301 
302 vector minigame_drawstring_wrapped( float maxwidth, vector pos, string text,
303  vector fontsize, vector color, float theAlpha, int drawflags, float align )
304 {
306  vector mypos = pos;
307  while ( getWrappedLine_remaining )
308  {
309  string line = minigame_getWrappedLine(maxwidth,fontsize,stringwidth_nocolors);
310  if ( line == "" )
311  break;
312  mypos_x = pos_x + (maxwidth - stringwidth_nocolors(line, fontsize)) * align;
313  drawstring(mypos, line, fontsize, color, theAlpha, drawflags);
314  mypos_y += fontsize_y;
315  }
316  mypos_x = maxwidth;
317  mypos_y -= pos_y;
318  return mypos;
319 }
320 
322  string text, vector fontsize, float theAlpha, int drawflags, float align )
323 {
325  vector mypos = pos;
326  while ( getWrappedLine_remaining )
327  {
328  string line = minigame_getWrappedLine(maxwidth,fontsize,stringwidth_colors);
329  if ( line == "" )
330  break;
331  mypos_x = pos_x + (maxwidth - stringwidth_colors(line, fontsize)) * align;
332  drawcolorcodedstring(mypos, line, fontsize, theAlpha, drawflags);
333  mypos_y += fontsize_y;
334  }
335  mypos_x = maxwidth;
336  mypos_y -= pos_y;
337  return mypos;
338 }
339 
340 void minigame_drawstring_trunc(float maxwidth, vector pos, string text,
341  vector fontsize, vector color, float theAlpha, int drawflags )
342 {
343  string line = textShortenToWidth(text,maxwidth,fontsize,stringwidth_nocolors);
344  drawstring(pos, line, fontsize, color, theAlpha, drawflags);
345 }
346 
347 void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text,
348  vector fontsize, float theAlpha, int drawflags )
349 {
350  string line = textShortenToWidth(text,maxwidth,fontsize,stringwidth_colors);
351  drawcolorcodedstring(pos, line, fontsize, theAlpha, drawflags);
352 }
353 
354 void minigame_drawpic_centered( vector pos, string texture, vector sz,
355  vector color, float thealpha, int drawflags )
356 {
357  drawpic( pos-sz/2, texture, sz, color, thealpha, drawflags );
358 }
359 
360 // Workaround because otherwise variadic arguments won't work properly
361 // It could be a bug in the compiler or in darkplaces
362 void minigame_cmd_workaround(float dummy, string...cmdargc)
363 {
364  string cmd;
365  cmd = "cmd minigame ";
366  float i;
367  for ( i = 0; i < cmdargc; i++ )
368  cmd = strcat(cmd,...(i,string));
369  localcmd(strcat(cmd,"\n"));
370 }
371 
372 // Prompt the player to play in the current minigame
373 // (ie: it's their turn and they should get back to the minigame)
375 {
377  {
378  HUD_Notify_Push(sprintf("minigames/%s/icon_notif",active_minigame.descriptor.netname),
379  _("It's your turn"), "");
380  }
381 }
382 
383 // handle commands etc.
384 REGISTER_MUTATOR(minigames, true);
385 
386 MUTATOR_HOOKFUNCTION(minigames, HUD_Command)
387 {
388  if(MUTATOR_RETURNVALUE) { return false; } // command was already handled
389 
390  if(argv(1) == "minigame")
391  {
392  if (isdemo())
393  return true; // minigames can't function properly in demo mode
396  else
398  return true;
399  }
400 
401  return false;
402 }
vector color
string ReadString_Zoned()
float panel_bg_border
Definition: hud.qh:169
float minigame_playerslot
Definition: cl_minigames.qh:79
string minigame_getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
string string_null
Definition: nil.qh:9
string find_last_color_code(string s)
Definition: util.qc:845
string getWrappedLine_remaining
Definition: util.qh:108
float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLengthUpToWidth_widthFunction_t w)
Definition: util.qc:773
vector minigame_hud_denormalize_size(vector v, vector pos, vector mySize)
Definition: cl_minigames.qc:23
void minigame_read_owner(entity this)
string minigame_texture_skin(string skinname, string name)
Definition: cl_minigames.qc:45
bool HUD_MinigameMenu_IsOpened()
int team
Definition: main.qh:157
void HUD_MinigameMenu_Open()
entity() spawn
string() ReadString_Raw
string netname
Definition: powerups.qc:20
vector minigame_hud_normalize(vector v, vector pos, vector mySize)
Definition: cl_minigames.qc:31
void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
string textShortenToWidth(string theText, float maxWidth, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
Definition: util.qc:956
NET_HANDLE(ENT_CLIENT_MINIGAME, bool isnew)
string classname
Definition: csprogsdefs.qc:107
int minigame_flags
Definition: minigames.qh:103
const int MINIG_SF_UPDATE
Definition: minigames.qh:109
entity owner
Definition: main.qh:73
void minigame_cmd_workaround(float dummy, string...cmdargc)
void minigame_player_entremove(entity this)
float(string s, vector size) textLengthUpToWidth_widthFunction_t
Definition: util.qh:101
MUTATOR_HOOKFUNCTION(minigames, HUD_Command)
void deactivate_minigame()
Definition: cl_minigames.qc:83
void minigame_drawpic_centered(vector pos, string texture, vector sz, vector color, float thealpha, int drawflags)
string minigame_texture(string name)
Definition: cl_minigames.qc:49
#define MINIGAME_SIMPLELINKED_ENTITIES
How to create a minigame
Definition: all.qh:100
const float BORDER_MULTIPLIER
Definition: hud.qh:109
entity active_minigame
Definition: cl_minigames.qh:85
vector minigame_drawcolorcodedstring_wrapped(float maxwidth, vector pos, string text, vector fontsize, float theAlpha, int drawflags, float align)
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
entity minigame_get_descriptor(string id)
Definition: minigames.qc:5
float panel_bg_alpha
Definition: hud.qh:167
string autocvar_menu_skin
Definition: mapvoting.qh:7
#define NULL
Definition: post.qh:17
void activate_minigame(entity minigame)
const float DRAWFLAG_NORMAL
Definition: csprogsdefs.qc:317
entity panel
Definition: hud.qh:144
#define MUTATOR_RETURNVALUE
Definition: base.qh:303
float player_localentnum
Definition: csprogsdefs.qc:19
void minigame_drawstring_trunc(float maxwidth, vector pos, string text, vector fontsize, vector color, float theAlpha, int drawflags)
vector(float skel, float bonenum) _skel_get_boneabs_hidden
const int MINIG_SF_CREATE
Definition: minigames.qh:108
vector v
Definition: ent_cs.qc:116
void minigame_prompt()
#define LOG_TRACE(...)
Definition: log.qh:81
void minigame_entremove(entity this)
vector minigame_hud_denormalize(vector v, vector pos, vector mySize)
Definition: cl_minigames.qc:16
void HUD_MinigameMenu_CurrentButton()
void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text, vector fontsize, float theAlpha, int drawflags)
int enttype
Definition: main.qh:154
void HUD_Notify_Push(string icon, string attacker, string victim)
Definition: notify.qc:19
void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
Definition: cl_minigames.qc:4
MINIGAME_SIMPLELINKED_ENTITIES void minigame_autoclean_entity(entity e)
Definition: cl_minigames.qc:75
entity minigame_self
Definition: cl_minigames.qh:87
bool minigame_hud_mouse_in(vector pos, vector sz)
Definition: cl_minigames.qc:39
entity descriptor
For minigame sessions: minigame descriptor object.
Definition: minigames.qh:45
bool auto_close_minigamemenu
Definition: cl_minigames.qc:82
float player_localnum
Definition: csprogsdefs.qc:20
REGISTER_MUTATOR(minigames, true)
vector minigame_drawstring_wrapped(float maxwidth, vector pos, string text, vector fontsize, vector color, float theAlpha, int drawflags, float align)
#define LOG_DEBUG(...)
Definition: log.qh:85
string msle_classname(int id)
Definition: minigames.qc:110
vector panel_bg_color
Definition: hud.qh:162