Solved MOB_HEAD - Apply custom skin ?

Discussion in 'Development' started by benda95280, Aug 25, 2019.

  1. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    Hello,

    I'm looking how to apply a custom skin to a MOB_HEAD.
    I know it's possible to give a player head this way (PlayerHead plugin):
    PHP:
    (ItemFactory::get(Item::MOB_HEAD3))
                ->
    setCustomBlockData(new CompoundTag('Skin', [
                    new 
    StringTag('Name'$name),
                    new 
    ByteArrayTag('Data'$skin->getSkinData())
                ]));
    But, from what i've see, it take the head from a full player skin.
    Is it possible to apply to item only the head skin ? (https://minecraft-heads.com/)

    Thanks a lot for you time :)
     
  2. Emirhan Akpınar

    Emirhan Akpınar Witch

    Messages:
    62
    GitHub:
    EmirhanWSD
    http://github.com/Enes5519/PlayerHead
     
  3. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    I'm sorry, but i'm not able to understand your answer.

    Maybe you miss the part of my post, when i said i know PlayerHead should do it, but it seems it use the full player skin.
    I've post an issue on the plugin GitHub, and hope to have an answer soon, but i'll be happy if i could do it myself, and maybe send a PR to him :)
     
  4. TheDeibo

    TheDeibo HBIDamian Staff Member Poggit Reviewer

    Messages:
    351
    GitHub:
    HBIDamian
    Are you on about replacing a player’s head with a preset one?
    (Kind of like Java edition wearing a player’s head)
     
  5. MalakasPlayzMCPE

    MalakasPlayzMCPE Zombie Pigman

    Messages:
    668
    It's impossible in mcpe
     
  6. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    Hello, (sorry for the delay, haven't received notification mail ...)

    The final is to be able to give to a player, a 'head' with a custom Skin.
    So i can place, where i want :
    [​IMG] [​IMG] [​IMG]
    (Why ? To add many more item to my child on the server ! See possibilities on minecraft-heads)

    The PlayerHead plugin already do it, just need to find how to send a custom Skin file.

    It seems everything (almost) is possible with entity, and geometry, and skin :)
    (Turtle, Melon Launcher, Pets, Car, HotAirBalloon ...)
     
  7. MalakasPlayzMCPE

    MalakasPlayzMCPE Zombie Pigman

    Messages:
    668
    Is it possible?

    Get the skin in-game, save it using file_put_contents("skin.txt", $player->getSkin()->getSkinData()); and then use file_get_contents("skin.txt"); to get the skin. You kinda got the point, I'd save it in an array when the plugin enables.
     
  8. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    The idea is perfect, and should work, but:
    • It do not use skin as image (So most people won't be able to use it)
    • It use the full skin, instead of the head only
    My original question was how should i can apply a custom texture to the head.

    From what i've read, it seems he create a head by extending Human and creating a custom geometry:
    PHP:
        public const HEAD_GEOMETRY '{"geometry.player_head":{"texturewidth":64,"textureheight":64,"bones":[{"name":"head","pivot":[0,24,0],"cubes":[{"origin":[-4,0,-4],"size":[8,8,8],"uv":[0,0]}]}]}}';
    And override? the setSkin function :
    PHP:
    parent::setSkin(new Skin($skin->getSkinId(), $skin->getSkinData(), '''geometry.player_head'self::HEAD_GEOMETRY));
    I think my problem is near, and maybe need to find information about Skin function.
    I've done some research while writing this message, and it seems easy as just passing the Skin Data (Of the Head ?) to the 2nd argument.
    But, it seems he send the whole skin.
    I'm perplex... Will try tonight to pass only the HeadSkin in 2nd argument of the setSkin, but it won't work... :(
     
  9. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    I've try to import the geometry on BlockBench, no errror message, but nothing show up.
    I was hopping to be ablke to apply a headskin a see what's happen.

    EDIT to prevent Spam

    [1]
    I've been able to load the Geometry and skin at Home, on BlockBench !
    Seems to take only the head on Full Player Skin
    It can load texture from file, but the render is not correct, working on it !

    [2]
    Geometry: OK (Hard to use BlockBench)
    [​IMG]
    Integration in plugin will be tried after eating

    [3]
    Where not able to copy/modify the plugin to load skin.
    I'm stuck with " $this->getDataFolder() " not working, my knowledge is small.
    Geometry availaible here: https://pastebin.com/8bFxAue5
     
    Last edited: Aug 27, 2019
  10. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    Still working on it:

    I was wrong with the Gemotry Json, going to work with :
    Code:
    {  
        "geometry.player_headObj": {
            "texturewidth": 16,
            "textureheight": 16,
            "visible_bounds_width": 2,
            "visible_bounds_height": 1,
            "visible_bounds_offset": [0, 0.5, 0],
            "bones": [
                {
                    "name": "bone",
                    "pivot": [0, 0, 0],
                    "cubes": [
                        {"origin": [-4, 0, -4], "size": [8, 8, 8], "uv": [1.99, 1.99], "mirror": true},
                        {"origin": [-4.5, 0, -4.5], "size": [9, 9, 9], "uv": [9.99, 1.99], "mirror": true}
                    ]
                }
            ]
        }
    }
    And i'm stuck with my code :

    Code:
    [21:31:05] [Server thread/CRITICAL]: Error: "Call to undefined method pocketmine\Server::getDataFolder()" (EXCEPTION) in "plugins/PlayerHeadObj/src/Enes5519/PlayerHeadObj/commands/PHCommand" at line 60
    Source is:
    PHP:
    <?php

    declare(strict_types=1);

    namespace 
    Enes5519\PlayerHeadObj\commands;

    use 
    Enes5519\PlayerHeadObj\PlayerHeadObj;
    use 
    pocketmine\command\Command;
    use 
    pocketmine\command\CommandSender;
    use 
    pocketmine\command\utils\InvalidCommandSyntaxException;
    use 
    pocketmine\Player;
    use 
    pocketmine\utils\TextFormat;
    use 
    pocketmine\utils\Config;
    use 
    pocketmine\plugin\PluginBase;



    class 
    PHCommand extends Command{
        
    /** @var array */
        
    private $messages;

        public function 
    __construct(array $messages){
            
    $this->messages $messages;
            
    parent::__construct('PlayerHeadObj''Give a player head''/PlayerHeadObj <playerName:string>', ['pho']);
            
    $this->setPermission('PlayerHeadObj.give');
        }

        public function 
    execute(CommandSender $senderstring $commandLabel, array $args){
            if(!
    $this->testPermission($sender) or !($sender instanceof Player)){
                return 
    true;
            }

            if(empty(
    $args)){
                throw new 
    InvalidCommandSyntaxException();
            }


                unset(
    $args[0]);
                
    $skinName $sender->getServer()->getPlayer($name implode(' '$args));
               
                if(
    file_exists($sender->getServer()->getDataFolder() . $skinName ".png")) {
                
    // new Skin("Standard_Custom", $this->createSkin($skin))
                    // $sender->getInventory()->addItem(PlayerHeadObj::getPlayerHeadItem($player->getSkin(), $player->getName()));
                    
    $sender->getInventory()->addItem(PlayerHead::getPlayerHeadItem($player->getSkin(), $skinName));
                    
    $sender->sendMessage(PlayerHeadObj::PREFIX TextFormat::colorize(sprintf($this->messages['message-head-added'], $skinName)));

                }
                else {
                    
    $player->sendMessage("Error: Skin do not exist !");
                }          

           
            return 
    true;
        }

    }

    Error line is:
    PHP:
                if(file_exists($sender->getServer()->getDataFolder() . $skinName ".png")) {
     
  11. Kenn Fatt

    Kenn Fatt Slime

    Messages:
    83
    GitHub:
    kennfatt
    Its actually:
    PHP:
    PluginBase::getDataFolder();
    So the solution is to use your PluginBase's class and directly use getDataFolder().
    You can create an instance variable on your main class and call it from PHCommand class.

    Here are some examples of how you can implement:
    Main class (a class that extends PluginBase)
    PHP:
    class Main extends PluginBase {
        
    /** @var Main */
        
    private static $instance;

        public function 
    onEnable() {
            if (
    self::$instance === null) {
                
    self::$instance $this;
            }
        }

        public static function 
    getInstance() : Main {
            return 
    self::$instance;
        }
    }
    Command class (or any classes that need to call PluginBase's API)
    * Use the main class.
    PHP:
    use namespaces\Main;
    * Call the API:
    PHP:
    Main::getInstance()->getDataFolder(); // plugin's folder.
     
  12. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    Thanks, You Are Insane !

    I've been able to do some little modifications and it works as you said.
    (And i've learn something)

    Skin loading is working very well, and apply to the model :
    [​IMG]

    But my model is not really the same as in BlockBench, don't know why:
    [​IMG]

    Model source: https://pastebin.com/6ULPiWeR
    Code:
    {
        "geometry.player_headObj": {
            "texturewidth": 64,
            "textureheight": 64,
            "visible_bounds_width": 2,
            "visible_bounds_height": 1,
            "visible_bounds_offset": [0, 0.5, 0],
            "bones": [
                {
                    "name": "head",
                    "pivot": [0, 0, 0],
                    "cubes": [
                        {"origin": [-4, 0, -4], "size": [8, 8, 8], "uv": [0, 0], "mirror": true},
                        {"origin": [-4, 0, -4], "size": [8, 8, 8], "uv": [32, 0], "inflate": 0.5, "mirror": true}
                    ]
                }
            ]
        }
    }
    
     
  13. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    ## Beta 1 ##

    Yes, it's working (it seems) !

    I've encountered some strange bug, like removing the geometry from source code, it's still working.
    PHP:
    public const HEAD_GEOMETRY '';
    This is why i was having old head geometry ... Don't know why and how it's possible

    [​IMG]
    (I don't know why, but geometry seems near correct, but seems not correct too ... Maybe just me or my eyes ...)

    Source on my GitHub or: https://github.com/benda95280/PlayerHeadObj
    Please, this is first attempt, code is ugly.

    If someone want to try it and tell me if it's working for him.
     
    Mango, Kenn Fatt and HimbeersaftLP like this.
  14. HimbeersaftLP

    HimbeersaftLP Chicken

    Messages:
    1,687
    GitHub:
    HimbeersaftLP
    This is so cool, I gave you a star on GitHub.
     
  15. Kenn Fatt

    Kenn Fatt Slime

    Messages:
    83
    GitHub:
    kennfatt
    Great move! Starred.
     
  16. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    I've been stared by my idol, soooo Happyy :)
    Thank you so much !

    ## Beta 2 ##

    New update pushed:
    - Remove usless thing
    - Readme Updated
    - Some functions removed or changed
    - Item message and name change ...


    But i'm back with some questions:

    - Is it possible to change animation when item breaked (dead) ?

    - Isn't it too big ? (Thiking to add possibility to choice small or normal (Or normal and big ...)

    - How should i manage the 'Yaw' of the item ?
    (Item are always having strange/wrong position)
    PHP:
        public function onPlace(BlockPlaceEvent $event) : void{
            
    $player $event->getPlayer();
            if(
    $player->hasPermission('PlayerHeadObj.spawn') and ($item $player->getInventory()->getItemInHand())->getId() === Item::MOB_HEAD and ($blockData $item->getCustomBlockData()) !== null){
                
    $nbt Entity::createBaseNBT($event->getBlock()->add(0.500.5), nullself::getYaw($event->getBlock(), $player));
                
    $blockData->setName('Skin');
                
    $nbt->setTag($blockData);
                (new 
    HeadEntityObj($player->level$nbt))->spawnToAll();
                if(!
    $player->isCreative()){
                    
    $player->getInventory()->setItemInHand($item->setCount($item->getCount() - 1));
                }
                
    $event->setCancelled();
            }
        }

        private static function 
    getYaw(Vector3 $posVector3 $target) : float{
            
    $yaw atan2($target->$pos->z$target->$pos->x) / M_PI 180 90;
            if(
    $yaw 0){
                
    $yaw += 360.0;
            }

            foreach([
    4590135180225270315360] as $direction){
                if(
    $yaw <= $direction){
                    return 
    $direction;
                }
            }

            return 
    $yaw;
        }
    [​IMG]
    [ Entity placed in front of me ]
     
    HimbeersaftLP likes this.
  17. HimbeersaftLP

    HimbeersaftLP Chicken

    Messages:
    1,687
    GitHub:
    HimbeersaftLP
    You could add some particles.
    I think it's fine
    That's be cool, or just let the user input a scale?
    I don't see what's wrong with the jaw
     
  18. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    Sorry, was thinking about the dead animation (Red, and rotation) because it don't apply to it, possible to cancel it or change it ?

    I was thinking to add size option inside the name of the skin, like:
    • book-1.medium.png
    • book-2.normal.png
    Working to add support by command line, to be compatible with plugin like Shop.

    I'm looking to check why it's not in facing me, but it's placed with +45°.
    (It you try to place a radio, it will be placed not facing you)
    Maybe just remove this part of the code.

    Looking too, to add support for 'mask', by looking the code/source of EverybodyThonk script
     
  19. benda95280

    benda95280 Spider Jockey

    Messages:
    39
    GitHub:
    benda95280
    I'm stuck :(

    I'm looking how to handle the size of the Entity.

    What i've think think / tried was:
    • HardCode it in the Entity (entities\HeadEntityObj)
    Seems impossible, because how to know it size inside the Entity code (Line 72) ?​
    • Create a new entity
    Tried, but in the OnPlace, how to know my size, to switch to the other entity ?​
    • Right Click to change the size
    Not tried, but how to handle right click on my entity and switch geometry inside the code of the entity?​
     
  20. HimbeersaftLP

    HimbeersaftLP Chicken

    Messages:
    1,687
    GitHub:
    HimbeersaftLP
    Here: https://github.com/benda95280/PlayerHeadObj/pull/1
    tbh I wouldn't move away from standard head sizes, that way you could later add a feature that can automatically download a player's head.
    Fixed it: https://github.com/benda95280/PlayerHeadObj/pull/1
     

Share This Page

  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.