Announcement

Collapse
No announcement yet.

Possible to have a coop server auto restart when 'end' has been won?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #61
    It is working. Before you i was using self which only really works client side but in that case could not work. Localcmd sends the command to the server. Which allows you to see if if you are the local server/client or from the server console. You are correct that the client would not be able to see it but it doesn't make any sense for the client to see it. What we are doing here isn't meant to be done the way you are doing it. I already gave you a function that will make the aliases automatically from an array. Then I gave you a function that will look for a command to be used. Then would run a specific function depending on the situation. This isn't the best way to send visible commands to the client anyway. I thought you were simply trying to test that this was indeed allowing for code to execute which from what I can tell we have established that is does. This isn't the normal means it which you would send a message to the player that would print on the client screen. If you want things like sprint, centerprint, etc to be sent to the player you'll have to do it in something like postthink or putclientinserver from client.qc. This type of function we are trying to do happens only on the server side. So it has no way to identify the player as self or whatever so those type of commands will not work even if sent to the player. dprint only works in code with to a self or other, etc. So it can only work on a entity. Which means in this case it wouldn't be able to spit anything out. The type of functions I am sending you to use for this are not setup to send messages to the players screens. We would load this code in a completely different place if we were accomplishing this. But the localcmd example did let you see it while in the server console or in game if you are the local server. Like I said, if we've already tested that the code works so I don't see the issue.

    is any of this making sense? Think of how your MOTD works now. See how the code is placed in a location where it can be called to the player? It works because the check for it is placed in PostThink of the player in client.qc. Which means we can use self. and thus can assign the command to an entity. Like I said, commands like sprint, centerprint, etc require this and thus cannot be run via world.qc in a function like startframe because it has no frame of reference to assign a self.

    Again, all of the code I gave above works server side via the startframe () in world.qc. It has nothing to do with the client per say. It just sets up everything that the client will use. Like impulses, this temp1 command, and aliases. All of those things can be sent to the client via various means without the need for the code to be placed in client.qc or in reference to an entity. If we wanted to we could even create an entity to use server side. But in this case it's just simply not needed.

    I think we both just got confused about what you are trying to do. But obviously the code works but you are trying to use it in an in correct way.
    Last edited by PrimalLove; 09-11-2014, 07:54 PM.

    Comment


    • #62
      All I can do is put in the alias code then I guess and see if it makes a difference. I wasn't really concerned about the self to send a message to. I was interested to see if typing 'temp1 5' on a client would be recognised by the server, and it doesn't look like it is. Maybe creating aliases will make a difference.

      -r0t.uk- cOOp - Mapvote - r0t.uk:26001
      -r0t.uk- DM - Mapvote - r0t.uk:26000

      Comment


      • #63
        Originally posted by slackhead View Post
        Looking at and testing it, command never resolves to anything but 0. I think that the client isn't sending the var temp1 to the server. Maybe that's why so many of the tutorials I've looked at use impulse...
        It does change just fine. Server side. Again the code resets the temp1 to 0 so that it can be used again. Check out weapons.qc down at weaponframe () to see an example of how impulse is used in a similar way to reset it to 0 for use. This method I presented you is valid just not the way you are trying to use it.

        Comment


        • #64
          Originally posted by slackhead View Post
          All I can do is put in the alias code then I guess and see if it makes a difference. I wasn't really concerned about the self to send a message to. I was interested to see if typing 'temp1 5' on a client would be recognised by the server, and it doesn't look like it is. Maybe creating aliases will make a difference.

          The impulse information and the aliases will need to be send to the player via something like stuffcmd in a postthink scenario. So when the client joins all the impulses and aliases will be set for him/her to use. This code just simply looks for whether the command is being used. It is detecting it because when I run it with the code I gave you:

          Code:
          void () vote_command =
          {
          	local float command;
          	command = cvar("temp1");
          	cvar_set("temp1", "0");
          	if (command)
          	   if (command == 1)
          	   {
                          localcmd("echo ");
          		localcmd("TEST");
          		localcmd("\n");
          	   }
          	  else
          	   {
          		localcmd("echo ");
          		localcmd("unknown command");
          		localcmd("\n");
          	   }
          	    
          };

          it spits out the echo either if you are in the server console or if you are playing on a local server (like single player). Which proves the code is working correctly and it is seeing it. Then if you type temp1 after and it is 0 again then we know the code is also resetting temp1 for the next use.

          Comment


          • #65
            I think the big disconnect for you is you may not be grasping the server/client relationship here. When the client sends a command in the console it will try to send it to the server. If the server allows the command or the result can affect the player something will happen. But in this case using localcmd it only affects the server itself. And sense clients cannot send localcmd to a server nothing seems to happen on the client's end. Same thing if you try to use sprint or similar. There is nothing to point to because the code gets run on the server, not the client. So using localcmd we can simulate this by you either using it in a local server environment or from the server console itself. You send the command to the server and it reads it, spits out the echo we set up and then in the server console you type temp1 and it has reset to 0. Which is exactly what we need the function in StartFrame() to do for us. It detected we used temp1 1 and then sent the appropriate localcmd we setup back to you on the server console. Think of the server console as a client that is local to the server. Like in singleplayer. Does that make a bit more sense? It's the same reason the localcmd example above would work in single player. You effectively are the local server and thus the command comes back to you.

            Comment


            • #66
              Well I'll show you what I have so far. I took your code from a few pages back and set it up for just two maps - start and end - and I also used temp1 so there shouldn't be any problems (I left your comments in):

              vote.qc:
              Code:
              //These two will add more strings to basic localcmd
              void (string s1, string s2) localcmd2 =
              {
                  localcmd(s1);
                  localcmd(s2);
              };
              
              void (string s1, string s2, string s3) localcmd3 =
              {
                  localcmd(s1);
                  localcmd(s2);
                  localcmd(s3);
              };
              
              //This is to add some extra strings to sprint and it uses the same builtin function for sprint
              void (entity client, string s1, string s2, string s3) sprint3 = #24;
              
              //Call this at the end of StartFrame() in World.qc. This will basically always be looking for commands.
              void () vote_command =
              {
                  local float command;
                  command = cvar("temp1");
                  cvar_set("temp1", "0");
              
                  if (command)
                      localcmd("echo something happened\n");
              };
              
              
              //Defines strings
              string array_user_map0;
              string array_user_map1;
              string array_user_map2;
              string array_user_map3;
              string array_user_map4;
              string array_user_map5;
              string array_user_map6;
              string array_user_map7;
              string array_user_map8;
              string array_user_map9;
              
              // Setup an array of custom user maps. Could theoretically do as many as you want?
              void (float index, string name) array_set_user_map =
              {
                  if (index == 0)
                      array_user_map0 = "start";
                  else if (index == 1)
                      array_user_map1 = "end";
              };
              
              
              //  This ones gets called by the string_get_map ()
              
              string (float index) array_get_user_map =
              {
                  if (index == 0)
                      return array_user_map0;
                  else if (index == 1)
                      return array_user_map1;
                  else
                      return "";
              };
              
              // Used to create alias for base maps and custom map additions from above string array
              string (float mapnum) strings_get_mapname =
              {
                  if (mapnum < 10)
                  {
                      if (mapnum == 0)
                          return "start";
                      else if (mapnum == 1)
                          return "end";
                      else
                          return "e2m1";
                  }
                  else if (mapnum < 20)
                  {
                      if (mapnum == 10)
                          return "e2m2";
                      else if (mapnum == 11)
                          return "e2m3";
                      else if (mapnum == 12)
                          return "e2m4";
                      else if (mapnum == 13)
                          return "e2m5";
                      else if (mapnum == 14)
                          return "e2m6";
                      else if (mapnum == 15)
                          return "e2m7";
                      else if (mapnum == 16)
                          return "e3m1";
                      else if (mapnum == 17)
                          return "e3m2";
                      else if (mapnum == 18)
                          return "e3m3";
                      else
                          return "e3m4";
                  }
                  else if (mapnum < 30)
                  {
                      if (mapnum == 20)
                          return "e3m5";
                      else if (mapnum == 21)
                          return "e3m6";
                      else if (mapnum == 22)
                          return "e3m7";
                      else if (mapnum == 23)
                          return "e4m1";
                      else if (mapnum == 24)
                          return "e4m2";
                      else if (mapnum == 25)
                          return "e4m3";
                      else if (mapnum == 26)
                          return "e4m4";
                      else if (mapnum == 27)
                          return "e4m5";
                      else if (mapnum == 28)
                          return "e4m6";
                      else
                          return "e4m7";
                  }
                  else if (mapnum < 40)
                  {
                      if (mapnum == 30)
                          return "e4m8";
                      else if (mapnum == 31)
                          return "end";
                      else if (mapnum == 32)
                          return "dm1";
                      else if (mapnum == 33)
                          return "dm2";
                      else if (mapnum == 34)
                          return "dm3";
                      else if (mapnum == 35)
                          return "dm4";
                      else if (mapnum == 36)
                          return "dm5";
                      else
                          return "dm6";
                  }
                  else
                      return array_get_user_map(mapnum - 38);
              }
              
              //This code will look for map aliases to setup automatically.
              //Will go through the list in strings_get_mapname one by one and assign each an alias.
              //This also will go in world.qc  in worldspawn () at the end.
              // You'll need to change this a bit to accommodate more maps.
              void () map_set_aliases =
              {
                  local float temp;
                  local string maptemp;
                  temp = 150;
              
                  while (temp < 200)
                  {
                      maptemp = strings_get_mapname(temp - 150);
                      if (maptemp != "")
                      {
                          localcmd3("alias ", maptemp, " \"temp1 ");
                          maptemp = ftos(temp);
                          localcmd2(maptemp, ";wait\"\n");
                      }
                      temp = temp + 1;
                  }
              };
              world.qc:
              Code:
              void() StartFrame =
              {
                  teamplay = cvar("teamplay");
                  skill = cvar("skill");
                  framecount = framecount + 1;
                  vote_command();
              };
              In progs.sec before world.qc:
              vote.qc

              In world.qc end of worldspawn():
              Code:
              map_set_aliases();
              Compiles fine with no warnings. Start server with -game r0t-newvote. Start game client and connect to server. Type 'start' in console:

              Unknown command "start"

              I don't know where I'm going wrong :/

              Edit* I also tried map_set_aliases(); in ClientConnect(0 in client.qc and that doesn't output an error but nothing is output on either client or server console for the localcmd("echo ...");

              Edit2* When I used it in ClientConnect I used stuffcmd(). With it as it was I would get the 'Unknown command'
              Last edited by slackhead; 09-11-2014, 09:49 PM.

              -r0t.uk- cOOp - Mapvote - r0t.uk:26001
              -r0t.uk- DM - Mapvote - r0t.uk:26000

              Comment


              • #67
                Ok a few things. One:

                Code:
                void () vote_command =
                {
                    local float command;
                    command = cvar("temp1");
                    cvar_set("temp1", "0");
                
                   [COLOR="Red"] if (command)
                        localcmd("echo something happened\n");[/COLOR]
                };
                This code does pretty much nothing now except send you an echo. It resets temp1 to 0 which we need but this code is also used to see if a command is being used but right now you have no check created so check for the commands you just created using the map_alias function. Making them is one thing, but next they have to be defined using this code:


                Code:
                void () vote_command =
                {
                	local float command;
                	command = cvar("temp1");
                	cvar_set("temp1", "0");
                	[COLOR="Lime"]if (command)
                	console_command(command);[/COLOR]
                };
                The green highlight is the additional function that will tell this function what commands to look for and what they do. So now we will need this:

                Code:
                [COLOR="lime"]//This would also go in world.qc StartFrame ()[/COLOR]
                void (float command) console_command =
                {
                
                  if (command >= 150 && command <= 199)
                     console_mapcheck(command - 150);
                  
                };
                This will also always run with the previous function to keep it up to date on what commands to look for. In this case, if command is between 150 and 199 then we need to run console_mapcheck. Then console_mapcheck would be something like this:


                Code:
                void (float newmap) console_mapcheck =
                {
                        nextmap = strings_get_mapname(newmap);
                
                };
                So now this looks at the number provided by the console command function and uses it to set the nextmap to the appropriate number in strings_get_mapname. I know this all is kinda convoluted but this is basically saying that yeah, that alias you made called start, well it is equal to start (or whatever the map you pressed) So the commands you are making are acting more like conduits that are sending information to this last check. Once this check is done basically nothing will happen until you set up your voting code.

                But lets step back a bit.....

                if you want to use the existing code you have then I see no reason why you can't. Most of this has just been a concept. Technically you can use temp1 instead of impulse for the vote map code you have now. I mean temp1 is already a built in and then you don't have to build new vote code. I am gonna tell ya now you'll need to change everything to work with this method we are doing here.

                I think that will be the least confusing way to proceed. Don't you? The code you have now uses impulses correct? So just change the maps to use temp1 instead of using impulse and viola! No impulse limitation. Give that a go before we start reinventing the wheel. I blame myself because I started looking at this as a proof of concept and it really can be compatible with what you already have with little modification needed. And this way the code would run on the client the way you are use to seeing it done. The player will intitate a vote using the same impulses as before and same to vote as before but the maps will just use temp1 instead of impulse. This make sense?

                Comment


                • #68
                  Originally posted by PrimalLove View Post
                  Ok a few things. One:

                  Code:
                  void () vote_command =
                  {
                      local float command;
                      command = cvar("temp1");
                      cvar_set("temp1", "0");
                  
                     [COLOR="Red"] if (command)
                          localcmd("echo something happened\n");[/COLOR]
                  };
                  This code does pretty much nothing now except send you an echo.
                  It puts a line in the server terminal output so I know something happend

                  Rewriting the current mapvote I have would be a long and messy thing I think. I'm trying to go from scratch so that I understand at every part what's happening. There are some parts of the BAM mapvote that I don't quite get - like it waits for a second impulse it seems before acting on it. No idea why.

                  I'll try the bits that you added.

                  -r0t.uk- cOOp - Mapvote - r0t.uk:26001
                  -r0t.uk- DM - Mapvote - r0t.uk:26000

                  Comment


                  • #69
                    If you want to do this warp method then this example source will show you it in action. This uses the method I was describing here. Otherwise it may just be easier for you to stick with the code you already have and adapt it using temp1. You'll need to compile it first. Pretty sure it will compile with no errors. or actually it may already have the prog.dat ready. This should be the same way r00k is doing it in his mod.

                    Comment


                    • #70
                      Originally posted by slackhead View Post
                      It puts a line in the server terminal output so I know something happend

                      Of course that is fine, but I was mentioning that the command part needs to define what each command that it sees is suppose to do. But try out the example source I sent you that basically does this exact same type of process.

                      Comment


                      • #71
                        You know, I've just had an idea: what about defining some vars like .votemap and then scan for those?

                        Once the server sees one set it knows that a vote has begun and act on it.

                        Just a thought...

                        -r0t.uk- cOOp - Mapvote - r0t.uk:26001
                        -r0t.uk- DM - Mapvote - r0t.uk:26000

                        Comment


                        • #72
                          Originally posted by slackhead View Post
                          You know, I've just had an idea: what about defining some vars like .votemap and then scan for those?

                          Once the server sees one set it knows that a vote has begun and act on it.

                          Just a thought...
                          This method could work to initiate a vote. Basically you would create an invisible entity in the map while the vote is going and when it ends it will remove itself. That way you can assign the appropriate actions to the entity. This is kinda what i mentioned before. In order for the server to use things like .votemap it will need to assign it to an entity. It can do this by either creating one (spawn) or using an existing one in the map. This is a limiting feature to qc but necessary to work with the code. This method would allow the server to run all the code on it's side without needing to initiate anything to the client. The client only has to type the map name to start the vote which will create the entity while the vote is in progress. The code I sent you also happens to use this method to intitates a vote. Check out the code in vote.qc for the example.

                          Comment


                          • #73
                            Well, I meant attach it to the player. That way we know who voted for what. But either way may work.

                            Actually I've just realised that's exactly what BAM's does...
                            Last edited by slackhead; 09-11-2014, 11:12 PM.

                            -r0t.uk- cOOp - Mapvote - r0t.uk:26001
                            -r0t.uk- DM - Mapvote - r0t.uk:26000

                            Comment


                            • #74
                              Yes

                              Code:
                              vote_spawn =
                              {
                              	local entity e;
                              	
                              	if (intermission_running)
                              		return;
                              	
                              	e = spawn ();
                              	e.owner 		= self;
                              	e.use 			= func; 
                              	e.classname 	= "vote_counter";
                              	e.message 		= mode_name;
                              	e.vdelay		= time + VOTE_PRINT_DELAY;
                              	e.vcount		= 0;
                              	e.think 		= vote_think;
                              	e.nextthink 	= time + 0.25;
                              	
                              	vote_print (1);
                              };

                              Comment


                              • #75
                                I won't do it the same way. But having the mapname setas self.votemap will allow to do a running total I think

                                -r0t.uk- cOOp - Mapvote - r0t.uk:26001
                                -r0t.uk- DM - Mapvote - r0t.uk:26000

                                Comment

                                Working...
                                X