Author Topic: How do i correctly display the player model on the main menu?  (Read 1581 times)

Borrowing code from City RPG's stats file, i'm trying to have the player's Blockhead appear on the main menu and layered above jes00's wallpaper add-on, which, the GUI used for the wallpaper is called MM_Wallpaper, for reference

The problem is that the player model is stuck being layered below the wallpaper, which i can fix by typing MainMenuGui.pushToBack(MM_BlockheadDisplay); into the console, but having that in my CS file doesn't work

Then the player model itself is just m.dts with no player prefs applied


But i don't know how to execute the code in a way that would fix it up and keep the model consistent with the player's settings like in the appearance menu

The GUI
Code: [Select]
new GuiObjectView(MM_BlockheadDisplay)
{
   profile = "GuiDefaultProfile";
   horizSizing = "right";
   vertSizing = "bottom";
      position = "0 100";
      extent = "800 800";
      minExtent = "8 4";
      enabled = "1";
      visible = "1";
      clipToParent = "1";
      cameraZRot = "-7.5";
      forceFOV = "35";
      lightDirection = "0.125 0.5 0.25";
      lightColor = "0.875 0.875 0.875 1";
      ambientColor = "0.35 0.35 0.35 1";
};

client.cs
Code: [Select]
exec("./ui/MM_Blockhead.gui");

MainMenuGui.add(MM_BlockheadDisplay);
MainMenuGui.pushToBack(MM_BlockheadDisplay);
MainMenuGui.pushToBack(MM_AuthBar);

MM_BlockheadDisplay.setEmpty();
MM_BlockheadDisplay.dynamicObject = "MM_Blockhead_Object";
MM_BlockheadDisplay.setObject(MM_BlockheadDisplay.dynamicObject, "base/data/shapes/player/m.dts", "", 0);

function MM_Blockhead::adjustAvatar(%gui)
{
MM_BlockheadDisplay.setSequence(MM_BlockheadDisplay.dynamicObject, 0, "headup", 0);
MM_BlockheadDisplay.setOrbitDist(7.5);
MM_BlockheadDisplay.setCameraRot(0, 0, 3);

if(MM_BlockheadDisplay.parts > 0)
{
%gui.hideAllNodes();
%gui.adjustAvatarNodes();
%gui.adjustAvatarColors();
}
else
{
%gui.applyDefaultPrefs();
}
}

function MM_Blockhead::adjustAvatarColors(%gui)
{
if(MM_BlockheadDisplay.parts > 0)
{
MM_BlockheadDisplay.setNodeColor(MM_BlockheadDisplay.dynamicObject, "headskin", $pref::Avatar::HeadColor);

for(%i = 0; %i < MM_BlockheadDisplay.parts; %i++)
{
%color = MM_BlockheadDisplay.color[%i];

if(%color $= "skin")
{
%color = $pref::Avatar::HeadColor;
}

MM_BlockheadDisplay.setNodeColor(MM_BlockheadDisplay.dynamicObject, MM_BlockheadDisplay.part[%i], %color);
}
}
}

function MM_Blockhead::adjustAvatarNodes(%gui)
{
MM_BlockheadDisplay.unHideNode(MM_BlockheadDisplay.dynamicObject, "headskin");

if(MM_BlockheadDisplay.parts > 0)
{
for(%i = 0; %i < MM_BlockheadDisplay.parts; %i++)
{
MM_BlockheadDisplay.unHideNode(MM_BlockheadDisplay.dynamicObject, MM_BlockheadDisplay.part[%i]);
}
}

MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "face", getIflFrame("face", $Pref::Avatar::FaceName));
MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "decal", getIflFrame("decal", MM_BlockheadDisplay.decal));
}

function MM_Blockhead::applyDefaultPrefs(%gui)
{
%gui.hideAllNodes();

%nodeCount = 0;

%node[%nodeCount++] = "headSkin" TAB "1 1 0 1";
%node[%nodeCount++] = "chest" TAB "1 1 1 1";
%node[%nodeCount++] = "LArm" TAB "1 1 1 1";
%node[%nodeCount++] = "RArm" TAB "1 1 1 1";
%node[%nodeCount++] = "LHand" TAB "1 1 0 1";
%node[%nodeCount++] = "RHand" TAB "1 1 0 1";
%node[%nodeCount++] = "pants" TAB "0 0 0.8 1";
%node[%nodeCount++] = "LShoe" TAB "0.2 0.2 0.2 1";
%node[%nodeCount++] = "RShoe" TAB "0.2 0.2 0.2 1";

for(%i = 1; %i <= %nodeCount; %i++)
{
MM_BlockheadDisplay.unHideNode(MM_BlockheadDisplay.dynamicObject, getField(%node[%i], 0));
MM_BlockheadDisplay.setNodeColor(MM_BlockheadDisplay.dynamicObject, getField(%node[%i], 0), getField(%node[%i], 1));
}

MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "face", 0);
MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "decal", 0);
}

function MM_Blockhead::hideAllNodes(%gui)
{
%nodeCount = 0;

%node[%nodeCount++] = "plume";
%node[%nodeCount++] = "triPlume";
%node[%nodeCount++] = "septPlume";
%node[%nodeCount++] = "Visor";

%node[%nodeCount++] = "helmet";
%node[%nodeCount++] = "pointyHelmet";
%node[%nodeCount++] = "flareHelmet";
%node[%nodeCount++] = "scoutHat";
%node[%nodeCount++] = "bicorn";
%node[%nodeCount++] = "copHat";
%node[%nodeCount++] = "knitHat";

%node[%nodeCount++] = "chest";
%node[%nodeCount++] = "femchest";

%node[%nodeCount++] = "pants";
%node[%nodeCount++] = "skirtHip";

%node[%nodeCount++] = "armor";
%node[%nodeCount++] = "bucket";
%node[%nodeCount++] = "cape";
%node[%nodeCount++] = "pack";
%node[%nodeCount++] = "quiver";
%node[%nodeCount++] = "tank";

%node[%nodeCount++] = "epaulets";
%node[%nodeCount++] = "epauletsRankA";
%node[%nodeCount++] = "epauletsRankB";
%node[%nodeCount++] = "epauletsRankC";
%node[%nodeCount++] = "epauletsRankD";
%node[%nodeCount++] = "ShoulderPads";

%node[%nodeCount++] = "LArm";
%node[%nodeCount++]  = "LArmSlim";

%node[%nodeCount++]  = "LHand";
%node[%nodeCount++]  = "LHook";

%node[%nodeCount++]  = "RArm";
%node[%nodeCount++]  = "RArmSlim";

%node[%nodeCount++]  = "RHand";
%node[%nodeCount++]  = "RHook";

%node[%nodeCount++]  = "pants";
%node[%nodeCount++]  = "skirtHip";

%node[%nodeCount++]  = "LShoe";
%node[%nodeCount++]  = "LPeg";

%node[%nodeCount++]  = "RShoe";
%node[%nodeCount++]  = "RPeg";

%node[%nodeCount++]  = "SkirtTrimLeft";
%node[%nodeCount++]  = "SkirtTrimRight";
%node[%nodeCount++]  = "LSki";
%node[%nodeCount++]  = "RSki";

for(%i = 1; %i <= %nodeCount; %i++)
{
MM_BlockheadDisplay.hideNode(MM_BlockheadDisplay.dynamicObject, %node[%i]);
}
}

function getIflFrame(%node, %name)
{
%file = "base/data/shapes/player/" @ %node @ ".ifl";

if(isFile(%file))
{
%name = stripTrailingSpaces(fileBase(%name));

if(%name !$= "")
{
%fo = new FileObject() {};
%fo.openForRead(%file);

%hasFound = false;
%lineNum = 0;

while(!%fo.isEOF())
{
%line = %fo.readLine();
%thisDecal = stripTrailingSpaces(fileBase(%line));

if(%thisDecal $= %name)
{
%hasFound = true;
break;
}
else
{
%lineNum++;
}
}

%fo.close();
%fo.delete();

if(%hasFound)
{
return %lineNum;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else
{
echo("\c2getIflFrame(\"" @ %node @ "\", \"" @ %name @ "\") : You did not supply a proper IFL file name to read from.");
return 0;
}
}

Iban made a post explaining what those scripts do if you need that for reference
https://forum.blockland.us/index.php?topic=148190.msg3473367#msg3473367

Also, the decals are broken, but that's because getIflFrame has the directory of base/data/shapes/player/, but if the player is using any face or torso decal that isn't the base ones, the directory becomes base/data/shapes/player/Add-Ons/Face_Default/smileyBlonde and base/data/shapes/player/Add-Ons/Decal_Hoodie/Hoodie, which of course are not the correct directories for those decals

But i don't know how to fix that either

Instead of adding the object gui to the main menu you could add it to the MainMenuButtonsGui and just send it to the back of that, which will always be on top while at the main menu.

If you were to do that you should call setMouse(canZoom, canSpin) on the object view to disable people from messing with it like they can in the avatar gui (unless you want that of course)

As for updating it you could call your MM_Blockhead.adjustAvatar(); function when Avatar_Done(); gets called, as that's the button for submitting your player. You'll also have to figure out the appropriate time to call your update function for the first time as if you do it too soon it won't correctly load as the avatar data hasn't been loaded yet.

I had to work with this stuff a lot while doing it for Glass so I ended up calling AvatarGui.onWake() before creating my object view for the player so all the avatar data would be loaded.

I got the GuiObjectView to appear on the MainMenuGui by using canvas::setContent, i've disabled mouse interactions, and i also got setOrbitDist and setCameraRot working via scheduling

Code: [Select]
exec("./ui/MM_Blockhead.gui");

MainMenuGui.add(MM_BlockheadDisplay);
MM_BlockheadDisplay.setEmpty();
MM_BlockheadDisplay.dynamicObject = "MM_Blockhead_Object";
MM_BlockheadDisplay.setObject(MM_BlockheadDisplay.dynamicObject, "base/data/shapes/player/m.dts", "", 0);
MM_BlockheadDisplay.setMouse(0, 0);

function MM_BlockheadDisplay::adjustCamera(%gui)
{
%gui.setOrbitDist(7.5);
%gui.setCameraRot(0.2, 0, 3);
}
MM_BlockheadDisplay.schedule(100,adjustCamera);

function MM_BlockheadDisplay::animateAvatar(%gui)
{
%gui.setSequence(MM_BlockheadDisplay.dynamicObject, 0, "headup", 0);
%gui.setSequence(MM_BlockheadDisplay.dynamicObject, 1, "run", 1);
}

function MM_BlockheadDisplay::adjustAvatar(%gui)
{
if(MM_BlockheadDisplay.parts > 0)
{
%gui.hideAllNodes();
%gui.adjustAvatarNodes();
%gui.adjustAvatarColors();
}
else
{
%gui.applyDefaultPrefs();
}
}

function MM_BlockheadDisplay::adjustAvatarColors(%gui)
{
if(MM_BlockheadDisplay.parts > 0)
{
MM_BlockheadDisplay.setNodeColor(MM_BlockheadDisplay.dynamicObject, "headskin", $pref::Avatar::HeadColor);

for(%i = 0; %i < MM_BlockheadDisplay.parts; %i++)
{
%color = MM_BlockheadDisplay.color[%i];

if(%color $= "skin")
{
%color = $pref::Avatar::HeadColor;
}

MM_BlockheadDisplay.setNodeColor(MM_BlockheadDisplay.dynamicObject, MM_BlockheadDisplay.part[%i], %color);
}
}
}

function MM_BlockheadDisplay::adjustAvatarNodes(%gui)
{
MM_BlockheadDisplay.unHideNode(MM_BlockheadDisplay.dynamicObject, "headskin");

if(MM_BlockheadDisplay.parts > 0)
{
for(%i = 0; %i < MM_BlockheadDisplay.parts; %i++)
{
MM_BlockheadDisplay.unHideNode(MM_BlockheadDisplay.dynamicObject, MM_BlockheadDisplay.part[%i]);
}
}

MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "face", getIflFrame("face", $Pref::Avatar::FaceName));
MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "decal", getIflFrame("decal", MM_BlockheadDisplay.decal));
}

function MM_BlockheadDisplay::applyDefaultPrefs(%gui)
{
%gui.hideAllNodes();

%nodeCount = 0;

%node[%nodeCount++] = "headSkin" TAB "1 1 0 1";
%node[%nodeCount++] = "chest" TAB "1 1 1 1";
%node[%nodeCount++] = "LArm" TAB "1 1 1 1";
%node[%nodeCount++] = "RArm" TAB "1 1 1 1";
%node[%nodeCount++] = "LHand" TAB "1 1 0 1";
%node[%nodeCount++] = "RHand" TAB "1 1 0 1";
%node[%nodeCount++] = "pants" TAB "0 0 0.8 1";
%node[%nodeCount++] = "LShoe" TAB "0.2 0.2 0.2 1";
%node[%nodeCount++] = "RShoe" TAB "0.2 0.2 0.2 1";

for(%i = 1; %i <= %nodeCount; %i++)
{
MM_BlockheadDisplay.unHideNode(MM_BlockheadDisplay.dynamicObject, getField(%node[%i], 0));
MM_BlockheadDisplay.setNodeColor(MM_BlockheadDisplay.dynamicObject, getField(%node[%i], 0), getField(%node[%i], 1));
}

MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "face", 0);
MM_BlockheadDisplay.setIflFrame(MM_BlockheadDisplay.dynamicObject, "decal", 0);
}

function MM_BlockheadDisplay::hideAllNodes(%gui)
{
%nodeCount = 0;

%node[%nodeCount++] = "plume";
%node[%nodeCount++] = "triPlume";
%node[%nodeCount++] = "septPlume";
%node[%nodeCount++] = "Visor";

%node[%nodeCount++] = "helmet";
%node[%nodeCount++] = "pointyHelmet";
%node[%nodeCount++] = "flareHelmet";
%node[%nodeCount++] = "scoutHat";
%node[%nodeCount++] = "bicorn";
%node[%nodeCount++] = "copHat";
%node[%nodeCount++] = "knitHat";

%node[%nodeCount++] = "chest";
%node[%nodeCount++] = "femchest";

%node[%nodeCount++] = "pants";
%node[%nodeCount++] = "skirtHip";

%node[%nodeCount++] = "armor";
%node[%nodeCount++] = "bucket";
%node[%nodeCount++] = "cape";
%node[%nodeCount++] = "pack";
%node[%nodeCount++] = "quiver";
%node[%nodeCount++] = "tank";

%node[%nodeCount++] = "epaulets";
%node[%nodeCount++] = "epauletsRankA";
%node[%nodeCount++] = "epauletsRankB";
%node[%nodeCount++] = "epauletsRankC";
%node[%nodeCount++] = "epauletsRankD";
%node[%nodeCount++] = "ShoulderPads";

%node[%nodeCount++] = "LArm";
%node[%nodeCount++]  = "LArmSlim";

%node[%nodeCount++]  = "LHand";
%node[%nodeCount++]  = "LHook";

%node[%nodeCount++]  = "RArm";
%node[%nodeCount++]  = "RArmSlim";

%node[%nodeCount++]  = "RHand";
%node[%nodeCount++]  = "RHook";

%node[%nodeCount++]  = "pants";
%node[%nodeCount++]  = "skirtHip";

%node[%nodeCount++]  = "LShoe";
%node[%nodeCount++]  = "LPeg";

%node[%nodeCount++]  = "RShoe";
%node[%nodeCount++]  = "RPeg";

%node[%nodeCount++]  = "SkirtTrimLeft";
%node[%nodeCount++]  = "SkirtTrimRight";
%node[%nodeCount++]  = "LSki";
%node[%nodeCount++]  = "RSki";

for(%i = 1; %i <= %nodeCount; %i++)
{
MM_BlockheadDisplay.hideNode(MM_BlockheadDisplay.dynamicObject, %node[%i]);
}
}

function getIflFrame(%node, %name)
{
%file = "base/data/shapes/player/" @ %node @ ".ifl";

if(isFile(%file))
{
%name = stripTrailingSpaces(fileBase(%name));

if(%name !$= "")
{
%fo = new FileObject() {};
%fo.openForRead(%file);

%hasFound = false;
%lineNum = 0;

while(!%fo.isEOF())
{
%line = %fo.readLine();
%thisDecal = stripTrailingSpaces(fileBase(%line));

if(%thisDecal $= %name)
{
%hasFound = true;
break;
}
else
{
%lineNum++;
}
}

%fo.close();
%fo.delete();

if(%hasFound)
{
return %lineNum;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else
{
echo("\c2getIflFrame(\"" @ %node @ "\", \"" @ %name @ "\") : You did not supply a proper IFL file name to read from.");
return 0;
}
}

package MMBlockheadDisplay
{
function canvas::setContent(%this,%content)
{
if(%content $= "MainMenuGui")
{
MainMenuGui.pushToBack(MM_BlockheadDisplay);
MainMenuGui.pushToBack(MM_AuthBar);
MM_BlockheadDisplay.adjustAvatar();
MM_BlockheadDisplay.schedule(500,setSequence, MM_BlockheadDisplay.dynamicObject, 0, headup, 1);
MM_BlockheadDisplay.schedule(500,setSequence, MM_BlockheadDisplay.dynamicObject, 1, run, 1);
}
Parent::setContent(%this,%content);
}
function AvatarGui::onSleep(%this)
{
MM_BlockheadDisplay.adjustAvatar();
MM_BlockheadDisplay.animateAvatar();
Parent::onSleep(%this);
}
};
activatePackage(MMBlockheadDisplay);

However, setSequence, animateAvatar();, or either one of those put into a schedule, refuse to work from within the setContent block, it only works when it's entered via console, when you exit out of the AvatarGui or exit from the game back to the main menu

This is the last problem i need to solve before i move onto setting the Blockhead's appearance
« Last Edit: March 22, 2017, 10:22:27 AM by Masterlegodude »

I'm not usually good with this stuff but could it be something to do with lighting?

I'm not usually good with this stuff but could it be something to do with lighting?
unrelated. mld is trying to make a gui display of your avatar over the main menu gui, like the one in your options > avatar menu.

unrelated. mld is trying to make a gui display of your avatar over the main menu gui, like the one in your options > avatar menu.
i was thinking of it like it it was blender but it am new to coding and all this stuff and I'm only thing to help and maybe bring an idea that will help

I'm not usually good with this stuff but could it be something to do with lighting?
unrelated. mld is trying to make a gui display of your avatar over the main menu gui, like the one in your options > avatar menu.
This, but also, what you're seeing in that first picture is the player model with all of the items un-hidden and the textures applied to them are opaque instead of being transparent with the player's colors applied to them

What i have now looks like this


Which is fine as far as lighting and positioning goes, but what i currently need help with is getting animations to work right when the game opens to the main menu so the player doesn't have to enter a console command or exit out of the avatar menu
However, setSequence, animateAvatar();, or either one of those put into a schedule, refuse to work from within the setContent block, it only works when it's entered via console, when you exit out of the AvatarGui or exit from the game back to the main menu

hold on so you're saying it was black because it was transparent but the colours weren't applied?

Your issue is that when the main menu gui is first started the default playertype and its sequences have not loaded. You should be able to fix your issue by calling AvatarGui.OnWake(); before adjusting and doing your sequences. You also don't need to schedule the sequences at all.

To avoid another headache, I'll just tell you that any time the object view is rendered the camera is going to just reset. Calling setCamera() on the object view every time you adjust it should fix that. You'll need to add a 0 ms schedule for the setCamera, I'd add it to your adjustCamera() function and call it whenever the main menu gui is woken.

hold on so you're saying it was black because it was transparent but the colours weren't applied?

That's what the player object looks like before hiding or coloring any nodes.

You also don't need to schedule the sequences at all.
That was just one of the many failed attempts at getting the sequences to work, i didn't use schedules before, and only did so just because it worked for the camera stuff

Your issue is that when the main menu gui is first started the default playertype and its sequences have not loaded. You should be able to fix your issue by calling AvatarGui.OnWake(); before adjusting and doing your sequences.
How would i do that?

To avoid another headache, I'll just tell you that any time the object view is rendered the camera is going to just reset.
I don't think i've had that happen, even after going through various menus and going in and out of the game

I'd add it to your adjustCamera() function and call it whenever the main menu gui is woken.
Unfortunately, using onWake instead of setContent and checking for the MainMenuGui results in everything not working, the player model is back to having all nodes visible and camera angle being defaulted, until you exit the AvatarGui, but then everything works, including the animations, but the camera angle doesn't work

This is the code with your suggested changes excluding the script blocks between these ones that weren't changed
Code: [Select]
function MM_BlockheadDisplay::adjustCamera(%gui)
{
%gui.schedule(0, setOrbitDist, 7.5);
%gui.schedule(0, setCameraRot, "0.2, 0, 3");
}

function MM_BlockheadDisplay::animateAvatar(%gui)
{
%gui.setSequence(MM_BlockheadDisplay.dynamicObject, 0, "headup", 0);
%gui.setSequence(MM_BlockheadDisplay.dynamicObject, 1, "run", 1);
}

function MM_BlockheadDisplay::adjustAvatar(%gui)
{
MM_BlockheadDisplay.adjustCamera();
MM_BlockheadDisplay.animateAvatar();

if(MM_BlockheadDisplay.parts > 0)
{
%gui.hideAllNodes();
%gui.adjustAvatarNodes();
%gui.adjustAvatarColors();
}
else
{
%gui.applyDefaultPrefs();
}
}
Code: [Select]
package MMBlockheadDisplay
{
function MainMenuGui::onWake(%this)
{
if(MainMenuGui.isAwake())
{
MainMenuGui.pushToBack(MM_BlockheadDisplay);
MainMenuGui.pushToBack(MM_AuthBar);
MM_BlockheadDisplay.adjustAvatar();
}
Parent::onWake(%this);
}
function AvatarGui::onSleep(%this)
{
MM_BlockheadDisplay.adjustAvatar();
Parent::onSleep(%this);
}
};
activatePackage(MMBlockheadDisplay);

Nothing changes if i remove the check for the MainMenuGui being awake