Getting players in world help.

Discussion in 'CommandHelper' started by MPKingJulian, Jul 8, 2017.

  1. MPKingJulian

    MPKingJulian New Member

    Hi.

    I've made a full mini-game in commandhelper although I'm having a bit of issues.

    Basically each game "server" is a world. I'd like to have my script so when there is a minimum of 2 players in a world it will start the game (or trigger something).

    Also when the game starts there is a countdown and I have the countdown for 10 seconds. The problem is it's announced in other worlds.

    I was wondering if anyone can help me with this and possibly show an example.

    Thanks!
  2. PseudoKnight

    PseudoKnight Well-Known Member

    Here's one common method I use:
    PHP:
    foreach(@player in all_players(@world)) {
      tmsg(@player, @message);
    }

    I've even tucked this into a procedure in auto_include.ms so I can use it in any script. This is great if you intend to re-use this a lot. Though you should use a procedure name that makes the most sense to you if you choose to do this.
    PHP:
    # auto_include.ms
    proc _worldmsg(@world, @message) {
      foreach(@player in all_players(@world)) {
        tmsg(@player, @message);
      }
    }
    PHP:
    # another script
    _worldmsg('world', 'The game is about to start.');
     
  3. MPKingJulian

    MPKingJulian New Member

    Thanks so much. Although is this possible to do with sound? And do you know how to check if a minimum of 2 players are in a world to trigger an alias?

    Thanks again!
  4. PseudoKnight

    PseudoKnight Well-Known Member

    What do you mean with sound? play_sound()?

    To check a minimum, you could use all_players() again.
    PHP:
    if(array_size(all_players('world')) > 1) {
  5. MPKingJulian

    MPKingJulian New Member

    Thanks for that and yes with play_sound.
  6. PseudoKnight

    PseudoKnight Well-Known Member

    Are you talking about like this?

    PHP:
    foreach(@player in all_players(@world)) {
        tmsg(@player, @message);
        play_sound(ploc(@player), array('sound': 'CHICKEN_EGG_POP'));
    }
  7. MPKingJulian

    MPKingJulian New Member

    Thanks so much! This worked. Now one last thing.

    So basically before the game starts I have a /kit command where you can choose your kit (so example /kit hacker). There is a total of 3 kits although I'm not sure how to make it where you get the kit when the game starts you receive the items in the kit. Also how would I detect the "last man standing" which would be the winner? (Last man standing is the one who is the winner as they didn't die).

    Thanks!
  8. MPKingJulian

    MPKingJulian New Member

    (so basically what I'm asking is how do I detect the last person standing? and how can I find out what kit someone selected so I can apply it when the game starts?)
  9. PseudoKnight

    PseudoKnight Well-Known Member

    There's a lot of ways to do this, so I'm trying to figure out what is the best way to demonstrate it.

    I'm not sure how you're doing kits, but let's assume something simple like this:
    PHP:
    *:/kit $type = >>>
    // I might not normally use a switch to do this, but it's in-code, so I don't have to waste time demonstrating loading kit configs or saving to persistence
        switch($type) {
            case 'one':
                        // so for the sake of example, we're defining a basic bow and arrow inventory kit
                @kit = array(
                    0: array('name': 'BOW'),
                                    1: array('name': 'ARROW', 'qty': 64),
                )
            case 'two':
                        // and there'd be multiple options
                @kit = array(
                    0: array('name': 'DIAMOND_SWORD')
                )
        }
        msg('Selected '.$type.' kit.');
        // and now the important bit
        export(player().'kit', @kit); // here we export the inventory array under a key with the player's name to be used by another script
    <<<
    Then in another script where we're starting the game.
    PHP:
    // Start with a countdown
    @secondsLeft = array(10); // We put this in an array so we can modify it by reference and each interval will use the updated value. Only arrays can do this.
    set_interval(1000, closure() {
        if(@secondsLeft[0] > 0) {
            @secondsLeft[0]--;
            _worldmsg(@world, @secondsLeft[0]);
        } else {
            clear_task();
            // Here we can prepare for the game
            foreach(@player in all_players(@world)) {
                 set_phealth(@player, 20); // we can do a few things like making sure their health and hunger is max
                 @kit = import(@player.'kit');
                 if(@kit) {
                     set_pinv(@player, @kit); // this assume their inventory is empty, otherwise we'd probably want to clear it too
                     export(@player.'kit', null): // this cleans up the export, but this is optional, and maybe you want to keep their choice for multiple games
                 } else {
                     // maybe they didn't choose a kit! here we can load a default
                 }
            }
            // Here we can start the game, but this is where organizing your code comes into play.
            // We could clear this interval and create a new one. Or we can use the existing interval in some way.
            // But for clarity I'm going to separate this part out into a procedure.
           _start_game(@world);
        }
    });
    Let's look at the file with the procedure.
    PHP:
    proc _start_game(@world) {
        // We could use event binds to trigger checks for how many valid players are in the world.
        // But here I'll just use an interval.
        set_interval(1000, closure() {
            @count = 0;
            @winner = '';
            foreach(@player in all_players(@world)) {
                if(pmode(@player) != 'SPECTATOR') {  // Let's not count spectators. We could add other checks here if we want.
                    @winner = @player; // we might need this if there's only one player
                    @count++;
                }
            }
            if(@count == 0) {
                clear_task(); // No players, so we can just end the game.
            } else if(@count == 1) {
                clear_task();
                // We have a winner!
                _worldmsg(@world, @winner.' won the game!');
            }
        });
    }
    Hopefully I didn't overload you here. Creating full game logic can get complex quickly. Like, if someone dies you'll probably want to put them in spectator mode. Some plugin may handle this for you, I don't know. But this is probably not the end of this script for you.
    Last edited: Jul 10, 2017
  10. MPKingJulian

    MPKingJulian New Member

    Thanks man you always have the answer. Last thing:

    How can I get all users in a world to run a command? Thanks!
  11. PseudoKnight

    PseudoKnight Well-Known Member

    You'd use runas() instead of tmsg() in the foreach loop of all_players(@world).
  12. MPKingJulian

    MPKingJulian New Member

    Honestly thanks so much. You always have the answer :p