1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

Solved Get the number of blocks under a play and remove them

Discussion in 'Development' started by Miste, Jul 27, 2017.

  1. Miste

    Miste Baby Zombie

    Messages:
    109
    GitHub:
    Misteboss
    Hey,
    I am actually trying to remove blocks under a player on PlayerMoveEvent for exemple.
    The problem is that the player can be supported by 2 blocks and when he is I want to remove these blocks.

    So my question is : How to know the number of blocks on which the player is ?

    I tried to use the getCollisonCubes fonction but I have an error (Maybe because I don't have know how to get the boundingBox ?)
    PHP:
    $sender->getLevel()->getCollisionCubes($sender$sender->boundingBox false));
    Thanks for your help :rolleyes:
     
  2. Eduardo

    Eduardo Baby Zombie

    Messages:
    100
    GitHub:
    xBeastMode
    In what range?
     
  3. Miste

    Miste Baby Zombie

    Messages:
    109
    GitHub:
    Misteboss
    The blocks who support the player, which prevent him from falling
     
  4. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    PHP:
    if($player->onGround){ // make sure the player is standing on ground
      
    $bb $player->getBoundingBox(); // $bb is the player BB which collides with the blocks' BBs such that the blocks can support the player
      
    $tv = new Vector3(0, (int) $player->y0);
      
    // $tv is a temporary vector to hold the three coordinates. This is micro-optimization to prevent instantiating a new Vector3 object every iteration.
      // $tv->y is a constant since the blocks that support the player are always at the same altitude
      // $tv->x and $tv->z are overwritten in the for loops below almost immediately, so the two 0s above are just placeholders used to initialize the Vector3.
      
    for($tv->= (int) $b->minX$tv-><= (int) $b->maxX; ++$tv->x){ // iterate over $tv->x
        
    for($tv->= (int) $b->minZ$tv-><= (int) $b->maxZ; ++$tv->z){ // iterate over $tv->z
          
    yield $player->getLevel()->getBlock($tv);
        }
      }
    }
    This method only works if the player is standing on a full block. If the player is standing on an incomplete block, think of your own way to fix the Y-coordinate :)
     
  5. Miste

    Miste Baby Zombie

    Messages:
    109
    GitHub:
    Misteboss
    Thanks @SOFe !;)


    EDIT : It doesn’t work, blocks are destroyed but they are next to the player and sometimes the calculation doesn’t work and don’t find any blocks @SOFe
     
    Last edited: Jul 28, 2017
  6. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    Then you should try to understand my code and do some debug info to see why it doesn't work :/
     
    Miste and jasonwynn10 like this.
  7. Miste

    Miste Baby Zombie

    Messages:
    109
    GitHub:
    Misteboss
    No problem, I think it’s coming from the floor() func, who should be replaced by round(), need to check that
     
  8. Miste

    Miste Baby Zombie

    Messages:
    109
    GitHub:
    Misteboss
    I checked and idk why but I still have the issue @SOFe :/, is it coming from the bounding box ?
    PHP:
    $bb $p->getBoundingBox();
    $tv = new Vector3(0, (int) (round($p->y)), 0);
     for(
    $tv->= (int) round($bb->minX); $tv-><= (int) round($bb->maxX); ++$tv->x){
      for(
    $tv->= (int) round($bb->minZ); $tv-><= (int) $bb->maxZ; ++$tv->z){
       
    //remove the block
      
    }
     }
     
  9. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    And did you try to check which blocks are evaluated?
     
  10. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    Actually never thought of that, neat!
     
  11. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    Code:
    NOTE: The figures were looking perfectly aligned on my machine.
    
    [X] = Blocks you are checking
    \0/ = Player
     /\
    
    Possibilities since $bb->minX, $bb->maxX, $bb->minZ, $bb->maxZ are floats:
    
    1. If player is standing right on the center of a block.
       \0/
    [Y][X][Y] - You are checking the block on player's foot! Probably air!
    
    
    2. If player is standing in the center of 4 blocks.
       \0/
    [X][X] - 3D wise, you will be checking all the 4 blocks... NOT. You'll be checking the blocks above all the four blocks!
    
    
    3. If player is jumping
       \0/
       /\
    [Y][Y] - No blocks!
    
    
    TL;DR
    PHP:
    $tv = new Vector3(0, (int) (round($p->y)), 0);
    //^is incorrect, it should've actually been:
    $tv = new Vector3(0, (int) (round($p->y) - 1), 0);
    But why (int) cast something rounded with a precision of 0?
     
    jasonwynn10 likes this.
  12. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    I don't know why you want to round the Y-coordinate. Do you assume that the player is standing on the chest when he's supported by a chest block, but standing on the ground below the redstone repeater when he is supported by a redstone repeater (height < 0.5) block?
    Why not use ceil()?
    Also note that the y axis may sometimes not be what you expect it to be. After jumping a few times, the player may be slightly above/below the ground by several millimeters. Not sure if it is still like this now, but it was like this back a few versions :p
     
    Miste, jasonwynn10 and Muqsit like this.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.