I used this method mostly, except i didn't kill the hat bot. i dont think dead bodies are mountable, most mods that let you carry dead bodies simply create a body dummy out of an aiplayer and make it playdead. Instead I made it invincible but when i modeled the hats i also gave them insanely small collision and possibly bounds so i dont remember if it was hard to hit or if it was just invincible. Also, i dont remember getting stuck in crouch or anything when i used it. Only glitch i found was that the hat would studder a bit if you move to quickly, because the engine has to update the hat's transform very quickly.
Also changing hat color through a chat command is kinda inefficient and stupid. my advice is that you let the hat inherit the player's avatar colors. So if they set their hat or accent color, the bothat will take on those same colors. these are fields under Gameconnection, ie hatcolor, accentcolor, larmcolor, etc. If you want to find the exact names use findclientbyname(yourname).dump();
here is an example on how i did it
Datablock initialization
datablock TSShapeConstructor(Mask_TophatData)
{
baseShape = "./tophat.dts";
//sequence0 = "./root.dsq root";
};
datablock PlayerData(Mask_TopHatBot : PlayerNoJet)
{
class = "MaskData";
shapeFile = "./tophat.dts";
dustEmitter = LiftoffDustEmitter;
Mask_slot = 5;
Mask_nodeCount = 3;
Mask_node[0] = "black";
Mask_nodeColor[0] = "0 0 0 1";
Mask_node[1] = "hat";
Mask_nodeInherit[1] = "hat";
Mask_node[2] = "accent";
Mask_nodeInherit[2] = "accent";
};
exec("./masks.cs");
function Player::Mask_mountMask(%this,%data,%nodeString)
{
if(!isObject(%this))
return;
if(!isObject(%data))
return;
if(%data.class !$= "MaskData")
return;
%slot = %data.Mask_slot;
%this.mask_currentMask[%slot].delete();
%mask = new AiPlayer() { datablock = %data; class = "MaskBot"; }; MissionCleanup.add(%mask);
announce(%mask SPC %data SPC %slot);
%mask.setScale("1.4 1.4 1.4");
%this.mountObject(%mask,%slot);
%this.Mask_currentMask[%slot] = %mask;
%mask.Mask_onMount(%this);
}
function Player::Mask_unMountMask(%this,%slot)
{
if(!isObject(%this))
return;
%mask = %this.mask_currentMask[%slot];
if(isObject(%mask))
{
%mask.Mask_onUnMount(%this);
%this.mask_currentMask[%slot] = "";
}
%this.client.applyBodyParts();
%this.client.applyBodyColors();
}
function AiPlayer::Mask_onMount(%this,%obj)
{
if(%this.class !$= "MaskBot")
return;
%this.Mask_applyColors(%obj);
}
function AiPlayer::Mask_onUnMount(%this,%obj)
{
if(%this.class !$= "MaskBot")
return;
%this.delete();
}
function Mask_subtractiveColor(%color,%sub)
{
%cr = getWord(%color,0); %cg = getWord(%color,1); %cb = getWord(%color,2);
%sr = getWord(%sub,0); %sg = getWord(%sub,1); %sb = getWord(%sub,2);
if((%r = %cr*%sr) <= 0)
%r = 0;
if((%g = %cg*%sg) <= 0)
%g = 0;
if((%b = %cb*%sb) <= 0)
%b = 0;
%s = %r SPC %g SPC %b SPC "1";
//announce(%s);
return %s;
}
function AiPlayer::Mask_applyColors(%this,%obj)
{
if(%this.class !$= "MaskBot")
return;
%data = %this.getDatablock();
for(%i=0; %i < %data.Mask_nodeCount; %i++)
{
if(%data.Mask_nodeInherit[%i] !$= "")
{
if(%data.Mask_nodeSubtractiveColor[%i] !$= ""){
//announce(%data.mask_nodeInherit[%i] SPC Mask_SubtractiveColor(%obj.client.hatcolor,%data.Mask_nodeSubtractiveColor[%i]));
eval("%this.setNodeColor(%data.Mask_node[%i],Mask_subtractiveColor(%obj.client." @ %data.Mask_nodeInherit[%i] @ "color,%data.Mask_nodeSubtractiveColor[%i]));"); }
else
eval("%this.setNodeColor(%data.Mask_node[%i],getWords(%obj.client." @ %data.Mask_nodeInherit[%i] @ "color,0,2) SPC 1);");
}
else if(%data.Mask_nodeColor[%i] !$= "")
%this.setNodeColor(%data.Mask_node[%i],%data.Mask_nodeColor[%i]);
}
%obj.client.applyBodyColors();
%obj.hideNode("visor");
%obj.hideNode("plume");
%obj.hideNode("triplume");
%obj.hideNode("septplume");
%obj.hideNode("helmet");
%obj.hideNode("pointyHelmet");
%obj.hideNode("flareHelmet");
%obj.hideNode("bicorn");
%obj.hideNode("cophat");
%obj.hideNode("knithat");
%obj.hideNode("scouthat");
}
package MaskMod
{
function Player::unHideNode(%this,%node)
{
%maskeye = %this.mask_currentMask[6];
%maskhead = %this.mask_currentMask[5];
parent::unHideNode(%this,%node);
for(%i=0;%i<9;%i++)
{
%mask = %this.Mask_currentMask[%i];
if(%mask.class $= "MaskBot")
{
%mask.Mask_applyColors(%this);
}
}
}
};
deactivatepackage(maskmod);
activatepackage(maskMod);
the code is possibly non-functional but if you test it out it should work.
i made this system a while ago and i wanted to implement into the hatmod system but i kinda got spooked by the complexity of the support_hatmod code so i gave up. It would also be kinda conflicting if i made a separate hatmod interface because then it would render the current hatmod kinda obsolete.
I figured that if someone were to merge the two together or if you simply updated the hatmod system to this new system it would be more painless, but w/e its your choice if you want to use any of this stuff, i dont do development for blockland anymore.