]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/minigames/cl_minigames.qc
Nades code: don't use booleans as array indexes for m_projectile, optimize spawn_held...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / minigames / cl_minigames.qc
index 93147d4041b2ab44388870e634cec5dc00cb6bb9..a4241ba97b14d4349170db7229cd5700fcf29d21 100644 (file)
@@ -8,7 +8,7 @@ void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
                                        panel.current_panel_bg,
                                        mySize + '1 1 0' * 2 * panel_bg_border,
                                        panel_bg_color, panel_bg_alpha,
-                                        '1 1 0' * (panel_bg_border/BORDER_MULTIPLIER));
+                                       '1 1 0' * BORDER_MULTIPLIER * panel_bg_border);
        drawpic(pos, board_texture, mySize, '1 1 1', panel_bg_alpha, DRAWFLAG_NORMAL);
 }
 
@@ -54,7 +54,7 @@ string minigame_texture(string name)
        return path;
 }
 
-#define FIELD(Flags, Type, Name) MSLE_CLEAN_##Type(self.Name)
+#define FIELD(Flags, Type, Name) MSLE_CLEAN_##Type(this.Name)
 #define MSLE_CLEAN_String(x) strunzone(x);
 #define MSLE_CLEAN_Byte(x)
 #define MSLE_CLEAN_Char(x)
@@ -67,15 +67,15 @@ string minigame_texture(string name)
 #define MSLE_CLEAN_Vector2D(x)
 
 #define MSLE(Name,Fields) \
-       void msle_entremove_##Name() { SELFPARAM(); strunzone(self.netname); Fields }
+       void msle_entremove_##Name(entity this) { strunzone(this.netname); Fields }
 MINIGAME_SIMPLELINKED_ENTITIES
 #undef MSLE
 #undef FIELD
 
 void minigame_autoclean_entity(entity e)
 {
-       LOG_DEBUG("CL Auto-cleaned: ",ftos(etof(e)), " (",e.classname,")\n");
-       remove(e);
+       LOG_DEBUG("CL Auto-cleaned: ",ftos(etof(e)), " (",e.classname,")");
+       delete(e);
 }
 
 void HUD_MinigameMenu_CurrentButton();
@@ -86,28 +86,28 @@ void deactivate_minigame()
                return;
 
        active_minigame.minigame_event(active_minigame,"deactivate");
-       entity e = world;
+       entity e = NULL;
        while( (e = findentity(e, owner, active_minigame)) )
                if ( e.minigame_autoclean )
                {
                        minigame_autoclean_entity(e);
                }
 
-       minigame_self = world;
-       active_minigame = world;
+       minigame_self = NULL;
+       active_minigame = NULL;
 
        if ( auto_close_minigamemenu )
        {
-               HUD_MinigameMenu_Close();
+               HUD_MinigameMenu_Close(NULL, NULL, NULL);
                auto_close_minigamemenu = 0;
        }
        else
                HUD_MinigameMenu_CurrentButton();
 }
 
-void minigame_entremove()
-{SELFPARAM();
-       if ( self == active_minigame )
+void minigame_entremove(entity this)
+{
+       if ( this == active_minigame )
                deactivate_minigame();
 }
 
@@ -121,7 +121,7 @@ void activate_minigame(entity minigame)
 
        if ( !minigame.descriptor || minigame.classname != "minigame" )
        {
-               LOG_TRACE("Trying to activate unregistered minigame ",minigame.netname," in client\n");
+               LOG_TRACE("Trying to activate unregistered minigame ",minigame.netname," in client");
                return;
        }
 
@@ -134,7 +134,7 @@ void activate_minigame(entity minigame)
        }
 
        if ( minigame_self.owner != minigame )
-               minigame_self = world;
+               minigame_self = NULL;
        active_minigame = minigame;
        active_minigame.minigame_event(active_minigame,"activate");
 
@@ -147,97 +147,98 @@ void activate_minigame(entity minigame)
        }
 }
 
-void minigame_player_entremove()
-{SELFPARAM();
-       if ( self.owner == active_minigame && self.minigame_playerslot == player_localentnum )
+void minigame_player_entremove(entity this)
+{
+       if ( this.owner == active_minigame && this.minigame_playerslot == player_localentnum )
                deactivate_minigame();
 }
 
 string() ReadString_Raw = #366;
 string ReadString_Zoned() { return strzone(ReadString_Raw()); }
 #define ReadString ReadString_Zoned
-#define FIELD(Flags, Type,Name) if ( sf & (Flags) ) self.Name = Read##Type();
+#define FIELD(Flags, Type,Name) if ( sf & (Flags) ) this.Name = Read##Type();
 #define MSLE(Name,Fields) \
-       else if ( self.classname == #Name ) { \
+       else if ( this.classname == #Name ) { \
                if ( sf & MINIG_SF_CREATE ) { \
-                       minigame_read_owner(); \
-                       self.entremove = msle_entremove_##Name; \
+                       minigame_read_owner(this); \
+                       this.entremove = msle_entremove_##Name; \
                } \
-               minigame_ent = self.owner; \
+               minigame_ent = this.owner; \
                Fields \
        }
-void minigame_read_owner()
-{SELFPARAM();
+void minigame_read_owner(entity this)
+{
        string owner_name = ReadString_Raw();
-       self.owner = world;
+       this.owner = NULL;
        do
-               self.owner = find(self.owner,netname,owner_name);
-       while ( self.owner && self.owner.classname != "minigame" );
-       if ( !self.owner )
-               LOG_TRACE("Got a minigame entity without a minigame!\n");
+               this.owner = find(this.owner,netname,owner_name);
+       while ( this.owner && this.owner.classname != "minigame" );
+       if ( !this.owner )
+               LOG_TRACE("Got a minigame entity without a minigame!");
 }
 NET_HANDLE(ENT_CLIENT_MINIGAME, bool isnew)
 {
        float sf = ReadByte();
        if ( sf & MINIG_SF_CREATE )
        {
-               self.classname = msle_classname(ReadShort());
-               self.netname = ReadString_Zoned();
+               this.classname = msle_classname(ReadShort());
+               this.netname = ReadString_Zoned();
        }
 
-       entity minigame_ent = world;
+       entity minigame_ent = NULL;
 
-       if ( self.classname == "minigame" )
+       if ( this.classname == "minigame" )
        {
-               minigame_ent = self;
+               minigame_ent = this;
 
                if ( sf & MINIG_SF_CREATE )
                {
-                       self.entremove = minigame_entremove;
-                       self.descriptor = minigame_get_descriptor(ReadString_Raw());
-                       if ( !self.descriptor )
-                               LOG_TRACE("Got a minigame without a client-side descriptor!\n");
+                       this.entremove = minigame_entremove;
+                       this.descriptor = minigame_get_descriptor(ReadString_Raw());
+                       if ( !this.descriptor )
+                               LOG_TRACE("Got a minigame without a client-side descriptor!");
                        else
-                               self.minigame_event = self.descriptor.minigame_event;
+                               this.minigame_event = this.descriptor.minigame_event;
                }
                if ( sf & MINIG_SF_UPDATE )
-                       self.minigame_flags = ReadLong();
+                       this.minigame_flags = ReadLong();
        }
-       else if ( self.classname == "minigame_player" )
+       else if ( this.classname == "minigame_player" )
        {
                float activate = 0;
                if ( sf & MINIG_SF_CREATE )
                {
-                       self.entremove = minigame_player_entremove;
-                       minigame_read_owner();
+                       this.entremove = minigame_player_entremove;
+                       minigame_read_owner(this);
                        float ent = ReadLong();
-                       self.minigame_playerslot = ent;
-                       LOG_DEBUG("Player: ",entcs_GetName(ent-1),"\n");
+                       this.minigame_playerslot = ent;
+                       LOG_DEBUG("Player: ",entcs_GetName(ent-1));
 
-                       activate = (ent == player_localnum+1 && self.owner && self.owner != active_minigame);
+                       activate = (ent == player_localnum+1 && this.owner && this.owner != active_minigame);
 
                }
-               minigame_ent = self.owner;
+               minigame_ent = this.owner;
 
                if ( sf & MINIG_SF_UPDATE )
-                       self.team = ReadByte();
+                       this.team = ReadByte();
 
                if ( activate )
                {
-                       minigame_self = self;
-                       activate_minigame(self.owner);
+                       minigame_self = this;
+                       activate_minigame(this.owner);
+                       minigame_self = this; // set it again (needed before, but may also be reset)
                }
        }
        MINIGAME_SIMPLELINKED_ENTITIES
 
        if ( minigame_ent )
-               minigame_ent.minigame_event(minigame_ent,"network_receive",self,sf);
+               minigame_ent.minigame_event(minigame_ent,"network_receive",this,sf);
 
        if ( sf & MINIG_SF_CREATE )
        {
-               LOG_DEBUG("CL Reading entity: ",ftos(etof(self)),
-                       " classname:",self.classname," enttype:",ftos(self.enttype) );
-               LOG_DEBUG(" sf:",ftos(sf)," netname:",self.netname,"\n\n");
+               LOG_DEBUG("CL Reading entity: ",ftos(etof(this)),
+                       " classname:",this.classname," enttype:",ftos(this.enttype) );
+               LOG_DEBUG(" sf:",ftos(sf)," netname:",this.netname);
        }
        return true;
 }
@@ -245,14 +246,54 @@ NET_HANDLE(ENT_CLIENT_MINIGAME, bool isnew)
 #undef FIELD
 #undef MSLE
 
-string minigame_getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
+void minigame_show_allspecs(vector boardpos, vector boardsize)
 {
-       int last_word;
-       string s;
-       int take_until;
-       int skip = 0;
+       string allspecs = "";
+       float allspecs_width = 0;
+       float max_allspecs_width = boardsize.x;
+       float max_current_spec_width = hud_fontsize.x * 5;
+       int allspecs_lines = 2;
+
+       entity e;
+       FOREACH_MINIGAME_ENTITY(e)
+       {
+               if (allspecs_width >= 0 && e.classname == "minigame_player" && e.team == C4_SPECTATOR_TEAM)
+               {
+                       string current_spec = ColorTranslateRGB(entcs_GetName(e.minigame_playerslot - 1));
+                       current_spec = textShortenToWidth(current_spec, max_current_spec_width, hud_fontsize, stringwidth_colors);
+                       if (allspecs != "")
+                               current_spec = strcat(", ", current_spec);
+                       else
+                               current_spec = current_spec;
 
-       s = getWrappedLine_remaining;
+                       allspecs_width = stringwidth(allspecs, true, hud_fontsize);
+
+                       float max_width = max_allspecs_width * allspecs_lines - max_current_spec_width;
+                       if (allspecs_width + stringwidth(current_spec, true, hud_fontsize) < max_width)
+                               allspecs = strcat(allspecs, current_spec);
+                       else
+                       {
+                               // current_spec doesn't fit in the list
+                               allspecs = strcat(allspecs, ", ...");
+                               allspecs_width = -1; // skip remaining spectators
+                       }
+               }
+       }
+
+       if (allspecs != "")
+       {
+               vector pos = boardpos;
+               pos.y -= panel_bg_border + hud_fontsize.y * (1.25 + allspecs_lines + 0.5);
+               minigame_drawstring_wrapped(max_allspecs_width, pos, _("Spectators:"), hud_fontsize * 1.25, '0.85 0.47 0.42', panel_fg_alpha, DRAWFLAG_NORMAL, 0);
+
+               pos.y += hud_fontsize.y * 1.25;
+               minigame_drawcolorcodedstring_wrapped(max_allspecs_width, pos, allspecs, hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL, 0);
+       }
+}
+
+string minigame_getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
+{
+       string s = getWrappedLine_remaining;
 
        if(w <= 0)
        {
@@ -260,12 +301,13 @@ string minigame_getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_
                return s; // the line has no size ANYWAY, nothing would be displayed.
        }
 
-       take_until = textLengthUpToWidth(s, w, theFontSize, tw);
+       int take_until = textLengthUpToWidth(s, w, theFontSize, tw);
 
        if ( take_until > strlen(s) )
                take_until = strlen(s);
 
-       for ( int i = 0; i < take_until; i++ )
+       int skip = 0;
+       for ( int i = 0; i < take_until; ++i )
                if ( substring(s,i,1) == "\n" )
                {
                        take_until = i;
@@ -277,7 +319,7 @@ string minigame_getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_
        {
                if ( skip == 0 && take_until < strlen(s) )
                {
-                       last_word = take_until;
+                       int last_word = take_until;
                        while(last_word > 0 && substring(s, last_word, 1) != " ")
                                --last_word;
 
@@ -367,7 +409,7 @@ void minigame_cmd_workaround(float dummy, string...cmdargc)
        string cmd;
        cmd = "cmd minigame ";
        float i;
-       for ( i = 0; i < cmdargc; i++ )
+       for ( i = 0; i < cmdargc; ++i )
                cmd = strcat(cmd,...(i,string));
        localcmd(strcat(cmd,"\n"));
 }
@@ -392,8 +434,10 @@ MUTATOR_HOOKFUNCTION(minigames, HUD_Command)
 
        if(argv(1) == "minigame")
        {
+               if (isdemo())
+                       return true; // minigames can't function properly in demo mode
                if (HUD_MinigameMenu_IsOpened())
-                       HUD_MinigameMenu_Close();
+                       HUD_MinigameMenu_Close(NULL, NULL, NULL);
                else
                        HUD_MinigameMenu_Open();
                return true;