How do I mount a hat and change its color?

Author Topic: How do I mount a hat and change its color?  (Read 2725 times)

I have several models that I want to be mounted onto the player, but I want the player to be able to choose the color via a command.

Is this possible? How can I do this?

you'd probably want to go the bot route if you wanted the player to be able to input any color value. it also wouldn't take up any mount slots on the player, which are pretty limited to begin with.

- 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

only problems you might run into with this are most likely weird collision problems (client getting stuck in crouch). the other method would be create an image and mount it to the player as if it were a gun (but mount it to the head instead of the right hand), but this would mean you'd lose the ability to use the setNodeColor method

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 initialization
Code: [Select]
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";
};

Code: [Select]
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.
« Last Edit: March 08, 2018, 11:04:51 AM by PhantOS »

Dead bodies are mountable, Conan does this for his dueling weapons. The reason you dont want to use bots for hats is because if more than one is mounted (some weapons use bots for the model), the first bot mounted will become visible first person, in this case the hat.

Edit: In addition, dead bots avert the crouch-stuck issue.
« Last Edit: March 08, 2018, 02:36:48 PM by Mocha »

You can create an empty bot and mount the hat to that. The empty bot will technically be visible in first person but it wont because its an empty model. Then the hat will be invisible

Images mounted to bots mounted to you are visible.

Yes but bots mounted to bots that are mounted to you are invisible.

On the contrary, bots mounted to bots mounted to you are always visible. If you can prove this to be the case, I’d be very surprised, as every case I’ve seen so far has supported my view. A number of mods I’ve seen using bots explicitly does this to ensure the bot they want visible will be visible

Sorry i got the order mixed up.

The first bot mounted to you is invisible in first person, while every other subsequent bot mounted is visible in first person (and sorta buggy because it follows your pitch path)

so if you mount a hat first, it will be invisible in first person. so this:

the first bot mounted will become visible first person, in this case the hat.
is wrong

Ah, right, you are correct about that. However, you can't make that assumption as there are various mods out there that depend on bots mounted to players, for example the dueling weapons. I also have heard of a new mod in progress to handle armor/suits (aka Suitmod) that will also make use of bots to save on image slot space, which would further increase the chances of this issue arising.

To be exact, the following situations are my understanding how bot visibility in first person works:
1) If only one bot is mounted to the player, that bot is invisible.
2) If two or more bots are mounted to the player, the first bot mounted will stay invisible while the rest will be visible
  • Caveat: If the first bot is mounted to the driver seat/slot 0 as defined in the datablock, that will become visible rather than the second bot mounted. The rest will still show up as normal iirc.

3) Anything mounted to bots mounted to you is always visible.

Note that depending on the bounding box of the bot datablock, the visibility of it can pop in/out. The stable, reliable bot-based mods I've seen utilize dead bots with large bounding boxes as a result, ex vectorScale("20 20 20", 4).

yeah i tried making recolorable armor + hat but the armor would appear in first person. so, if i make the bounds of the armor extremely large, it wont show up in first person?

No, it would guarantee it will always show up in first person. Making the bounds big guarantees/increases visibility, which is important if you are doing something like a card mod where many bots are in your hand, and the renderer has problems realizing you can see them while facing certain angles and so skips rendering them.


No, it would guarantee it will always show up in first person. Making the bounds big guarantees/increases visibility, which is important if you are doing something like a card mod where many bots are in your hand, and the renderer has problems realizing you can see them while facing certain angles and so skips rendering them.
set the model bounds to be very large as well as the playertype bounds to be very large make sure the bot is dead so it is on the corpse typemask

this should remove any issues with rendering in first person

also the holder bot that is invisible also needs large bounds

set the model bounds to be very large as well as the playertype bounds to be very large make sure the bot is dead so it is on the corpse typemask

this should remove any issues with rendering in first person

also the holder bot that is invisible also needs large bounds
your goal is to make the hat bot invisible in first person, otherwise it will block your view