Guievent area loadscreen finished

Has anyone made a mod that allows the area loadscreen to persist for a time after the new “loadscreen finished” event?

For example, it might use the NUI functions to redisplay the loadscreen, so that it appears seamless.

Using black screen for now.

The reason for asking is that some unwanted area visuals (e.g. many NPCs sitting) are no longer covered up by the loadscreen.

Don’t want to reinvent the wheel.

There’s no get function for setareatransitionbmp, so it’d have to be rewrite the standard nwscript without engine change and gui change (so you don’t have to reassemble the displayed image in nui which I don’t think you can do without a break in the center, you can of course have the same image in different formats but that feels inelegant).

But that might not be what you’re trying to do.

Thanks for that.

Which script did you have in mind?

There are so few cases that I guess I could take a screenshot of the load screen… not sure which formats to consider?

I wonder why you want that… The loadhints are now written in combat log if exposing them more is your intention. Displaying a secondary fullscreen image that prevents me to play seems very intrusive to me…

It’s not that I really want the loadscreen to linger - I just want it to obscure set-up activity in the area, which wasn’t visible before the loadscreen timing was changed.

Definitely doesn’t seem worth replacing a bunch of things (nw_g0_transition and friends) wholesale just to do that. Can the setup be triggered before the area trans? That sounds easiest.

For the quotes: area load images are split to be square images and uv mapped onto whichever model used for the loadscreen. They can be normal images if you redo the uv mapping of them. Different formats would just mean having the original split image then a displayed version to show in nui, which I think isn’t a great solution (don’t think there’s anything the game will swallow to display as a loadscreen that nui won’t).

1 Like

Yeah, set it up before the JumpToObject send player to area.

Alternatively you can send player to system area which will then send it to original target. So basically double loading screens. I use that method for immersion purpose myself.

1 Like

Looking into that.

Currently I have common code for wandering citizens and tavern patrons, which are created anew on area entry (for performance reasons, and to vary their appearance).

There are obviously lots of ways that could be preloaded, but I was hoping not to have to rework it.

Alternatively, is there any way to force NPCs into a sitting position instantly, without tweaking the animation (which is required in other cases)?

Sometimes you can do a black screen and fadefromblack after a few seconds to give the NPCs a chance to get organized.

Yes, that’s what I’m doing for now.

Trial-and-error indicates that 2 seconds is optimum.

You can visually sit them instantly with PlayAnimation(ANIMATION_LOOPING_SIT_CHAIR, 100.0f, 10.0f) but due to weird model positions they’ll likely be sitting in the air, so you’ll need to SetObjectVisualTransform() translate them onto the chair.
Then, also make them actually do ActionSit() since sitting has gameplay effects, and once that is done, clear the OVT (or, better yet, make it lerp so that there’s no visual movement).

1 Like

That seems to work.

As luck would have it, the sitters in question are just eye-candy, so I think I can avoid the difficulty of lerping around ActionSit, by making the sitters not usable.

Applying the cutscene ghost effect ensures that the actual position of the sitters is walkable.

LOL animation speed 100.0f makes the sitter’s head vibrate like they are on a rollercoster but 1.0f looks fine.

Proof of concept working in game:

object oPC       = GetFirstPC();
object oChair    = GetNearestObjectByTag("ChairCustomerF", oPC);
vector vChair    = GetPosition(oChair);
object oNPC      = GetNearestObjectByTag("CustomerF", oPC);
vector vNPC      = GetPosition(oNPC);
float  fRotation = 180.0;// May vary by chair

  SetObjectVisualTransform(oNPC, OBJECT_VISUAL_TRANSFORM_TRANSLATE_X, vChair.x - vNPC.x);
  SetObjectVisualTransform(oNPC, OBJECT_VISUAL_TRANSFORM_TRANSLATE_Y, vChair.y - vNPC.y);
  SetObjectVisualTransform(oNPC, OBJECT_VISUAL_TRANSFORM_ROTATE_X, GetFacing(oChair) - GetFacing(oNPC) + fRotation);
  AssignCommand(oNPC, PlayAnimation(ANIMATION_LOOPING_SIT_CHAIR, 1.0f, FOREVER));
  ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oNPC);
  SetUseableFlag(oNPC, FALSE);

where

const float  FOREVER  = 1000000000000.0;  // 1 trillion seconds = about 5000 years of gameplay

I’ll now test this on the larger scale.

I seem to remember that visual transform vector math needs validation with objects of different orientation.

I suspect the rotation of the NPC to facing in the correct direction may vary from one chair model to the next, so it probably should be a local variable.

Now fully tested on a large-scale example.

Tweaks:

  • Animation speed 100.0f is required briefly to make sitting appear instant
  • Animation speed 1.0 thereafter suppresses the unwanted head movement
  • z translation added for good order
  vector vNPC      = GetPosition(oNPC);
  vector vChair    = GetPosition(oChair);
  float  fRotation = GetLocalFloat(oNPC, "SitRotation");          // This adjustment, which might vary by chair model, is to get the NPC facing the right direction relative to the chair

  SetObjectVisualTransform(oNPC, OBJECT_VISUAL_TRANSFORM_TRANSLATE_X, vChair.x - vNPC.x);
  SetObjectVisualTransform(oNPC, OBJECT_VISUAL_TRANSFORM_TRANSLATE_Y, vChair.y - vNPC.y);
  SetObjectVisualTransform(oNPC, OBJECT_VISUAL_TRANSFORM_TRANSLATE_Z, vChair.z - vNPC.z);
  SetObjectVisualTransform(oNPC, OBJECT_VISUAL_TRANSFORM_ROTATE_X, GetFacing(oChair) - GetFacing(oNPC) + fRotation);
  AssignCommand(oNPC, PlayAnimation(ANIMATION_LOOPING_SIT_CHAIR, 100.0f, 1.0));     // Sit down really fast
  AssignCommand(oNPC, PlayAnimation(ANIMATION_LOOPING_SIT_CHAIR, 1.0f, FOREVER));   // Sustain sitting position
  ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oNPC);        // Make actual locaton of NPC walkable
  SetUseableFlag(oNPC, FALSE); 

Presumably, the same approach would work for creatures playing any animation, whether the location is accessible or not.

1 Like