Author Topic: Swapping a node's model when spawning a custom player type?  (Read 1092 times)

So I'm creating a custom player type which is 100% the same as the standard player, bar that I want it to have a modified version of the player's chest (which is UV mapped on both sides).

I know how to mount the image, but I'm a bit stuck as to what function I should be overriding. Does anyone know what I should override to achieve this (that would cover spawning, changing the datablock etc)?

Armor::onAdd is called when an armor object is added. Try searching the forums for onMount and see if you can use that to manipulate player nodes.

The problem I encountered with Armor::onAdd is that GameConnection::applyBodyParts was being called after onAdd, causing the chest node to be un-hidden. Also, Armor::onAdd doesn't seem to be called if the player changes their datablock through events. What I've just tried (that ostensibly seems to work) is overriding applyBodyParts itself, checking if the players datablock is my playertype and then mounting the chest image from there.
Code: [Select]
datablock PlayerData(PlayerCloneTrooper : PlayerStandardArmor) {
uiName = "Clone Trooper Player";
};

datablock ShapeBaseImageData(CloneChestImage) {
shapeFile = "./Chest.dts";
emap = true;
mountPoint = $BackSlot;
offset = "0 0 0";
eyeOffset = "0 0 10";
rotation = eulerToMatrix("0 0 0");
scale = "1 1 1";
doColorShift = false;
};

function CloneChestImage::onUnMount(%this, %obj, %slot) {
%player = %obj;
%player.unhideNode("Chest");
}

function CloneChestImage::onMount(%this, %obj, %slot) {
%player = %obj;
%player.hideNode("Chest");
}

package ClonePlayerPackage {
function GameConnection::applyBodyParts(%client) {
parent::applyBodyParts(%client);
if(%client.player.dataBlock $= PlayerCloneTrooper) {
%client.player.mountImage(CloneChestImage,1);
echo("GameConnection::applyBodyParts Client:" SPC %client);
} else {
if(%client.player.getMountedImage(1) == nameToID(CloneChestImage)) {
%client.player.unMountImage(1);
}
}
}
}; activatePackage(ClonePlayerPackage);

Is there any reason why doing it this way would be a bad idea?
« Last Edit: October 29, 2015, 03:36:42 AM by Darryl McKoy »

If it works, I can't think of any.

I think this is how most playertypes do similar things, so yeah its totally fine. (Other than you should be doing an isObject(%client.player) check)
« Last Edit: October 29, 2015, 08:52:35 AM by boodals 2 »

I think this is how most playertypes do similar things, so yeah its totally fine. (Other than you should be doing an isObject(%client.player) check)
Good catch, thanks.

I had to modify my code because while it worked with default minigames, it didn't work with Slayer. Slayer overrides applyBodyParts and instead calls its own applyUniform function.
Code: [Select]
package ClonePlayerPackage {
function GameConnection::applyBodyParts(%client) {
parent::applyBodyParts(%client);

%player = %client.player;
if(!isObject(%player))
return;

if(%player.dataBlock $= PlayerCloneTrooper) {
%player.mountImage(CloneChestImage,1);
                        %player.hideNode("Chest");
} else {
if(%player.getMountedImage(1) == nameToID(CloneChestImage)) {
%player.unMountImage(1);
}
}
}

function GameConnection::applyUniform(%client) {
parent::applyUniform(%client);

%player = %client.player;
if(!isObject(%player))
return;

if(%player.dataBlock $= PlayerCloneTrooper) {
%player.mountImage(CloneChestImage,1);
                        %player.hideNode("Chest");
} else {
if(%player.getMountedImage(1) == nameToID(CloneChestImage)) {
%player.unMountImage(1);
}
}
}

}; activatePackage(ClonePlayerPackage);
..Which leads to my next question: Is this the right way to go about overriding a function created by another addon? Should I be putting the overridden applyUniform in a separate package and only activating it if I know slayer exists? What I have above works, I just want to make sure I'm following best practices.
« Last Edit: October 29, 2015, 04:50:38 PM by Darryl McKoy »

This is the way you're supposed to do it so you're good.

If I may nippick at the formatting, put each opening and closing bracket on a seperate line, it makes the code easier to read.

This is the way you're supposed to do it so you're good.

If I may nippick at the formatting, put each opening and closing bracket on a seperate line, it makes the code easier to read.
Personal preference, I find it easier to read than the alternative