Is this possible?

- create playertype that uses the hat as a base shape, with no pain or death sounds
- when mounting a hat to a player, instantiate an AIPlayer with that playertype
- kill that AIPlayer, and package Armor::onDeath or something to prevent it from disappearing
- mount it to the player's head mount
- change it's color using the setNodeColor method
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 initializationdatablock 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.