Aller au contenu

Photo

Creating an object in midair [solved]


2 réponses à ce sujet

#1
BillHoyt

BillHoyt
  • Members
  • 109 messages
I have a quest where I create an invisible placeable container on the wall (Z coordinate 2 or 3).  If the PC places a gift painting (in this case, Portrait of a Goose Girl) into the object, it self-destroys and spawns a painting (custom placeable) in its place. The script (below) works masterfully and the painting appears - the only problem is that it appears on the floor.  Not exactly good placement for a "hung" painting.

I have even tried putting a placeable shelf under it to "catch" it if the CreateObject function puts it in place but it falls because there's nothing beneath it, but it appears to be generating at Z coordinate 0 rather than moving through the shelf.

Does anyone know if that's how CreateObject works? It would make perfect sense, but it would make this quest rather pointless.

If it must spawn on the ground, is there a way to raise an object?  Most of the "move" functions seem to either move an item from one character to another or move a character to a waypoint.  Thanks,

// -----------------------------------------------------------------------------
// painting_hook script
// Owner: Bill Hoyt
// -----------------------------------------------------------------------------
/*

    operates a small, invisible "hook" placeable container.
    If character puts a gift painting in the hole, places portrait on the wall.
    Awards 500xp for success

    Note: this script redirects all events not handled into placeable_core.

*/
// -----------------------------------------------------------------------------

#include "placeable_h"
#include "plt_interior_decoration"
object oPC = GetHero();

//------------------------------------------------------------------------------
//  Functions
//------------------------------------------------------------------------------

/** @brief Increases oCreatures experience by nXp.
* @param nXp        - the amount of experience points to award
* @param oCreature  - the creature to benefit from the award
* @author Sunjammer
**/
void AddCreatureExperience(int nXp, object oCreature=OBJECT_SELF)
{
    float fXp = IntToFloat(GetExperience(oCreature) + nXp);
    SetCreatureProperty(oCreature, PROPERTY_SIMPLE_EXPERIENCE, fXp);
}

void main()
{
    event ev          = GetCurrentEvent();
    int nEventType    = GetEventType(ev);
    int bEventHandled = FALSE;

    switch (nEventType)
    {
        //----------------------------------------------------------------------
        // Sent by engine when a creature uses the placeable.
        //----------------------------------------------------------------------
        case EVENT_TYPE_USE:
        {
            object  oUser           = GetEventCreator(ev);
            int     nAction         = GetPlaceableAction(OBJECT_SELF);
            int     nVariation      = GetEventInteger(ev, 0);
            int     nActionResult   = TRUE;

            OpenInventory(OBJECT_SELF, oUser, TRUE);
            bEventHandled = TRUE;
            break;
        }
        //----------------------------------------------------------------------
        // Checks for Goose Girl in inventory.
        //----------------------------------------------------------------------
        case EVENT_TYPE_INVENTORY_ADDED:
        {
             object oItem = GetEventObject(ev, 0);
             if    (oItem == GetObjectByTag("gen_im_gift_mdpnt1",0))
             {
                location lPaintingSpot = GetLocation(OBJECT_SELF);
                Safe_Destroy_Object(oItem); //to prevent removal of painting
                Safe_Destroy_Object(OBJECT_SELF); //container destroyed on close
                // create a painting placeable at the location
                object oNewPainting = CreateObject(OBJECT_TYPE_PLACEABLE,
                    R"goose_girl.utp", lPaintingSpot);
                WR_SetPlotFlag(PLT_INTERIOR_DECORATION, CARPET_PLACED, TRUE);
                AddCreatureExperience(500, oPC);
             }
            bEventHandled = TRUE;
            break;
        }
    }

    if (!bEventHandled)
    {
        HandleEvent(ev, RESOURCE_SCRIPT_PLACEABLE_CORE);
    }
}
// end script

Modifié par BillHoyt, 01 mai 2010 - 04:54 .


#2
DavidSims

DavidSims
  • BioWare Employees
  • 196 messages
Is this in your own module, or an add-in to single player? If it's in an area you can edit, it would be easier to pre-place the painting, set it as innactive then activate it when you deposit the painting.

If you need to spawn it dynamicaly, my guess is that GetLocation by default returns a safe location, which is a location on valid pathfinding ie the floor. I can't remember if there's an optional paramater to not get a safe location but I suspect there is.

If there isn't, try SetPosition, using GetPosition(OBJECT_SELF) as the position paramater. Make sure to move the destroy object call after the set position. If the placement is still a little bit off, you may need to find the exact coordinates you want the painting to be at, create a position vector with Vector(1.0, 2.0, 3.0), substituting your coordinates, and pass that into SetPositon instead.

Modifié par DavidSims, 01 mai 2010 - 02:56 .


#3
BillHoyt

BillHoyt
  • Members
  • 109 messages

DavidSims wrote...

"...set it as inactive then activate it when you deposit the painting."


Great idea, David, I hadn't thought of that. And it would sure simplify the script. The only downside I can see is that it would necessarily limit which "gift" can go where (unless I put all of them "in place" and activate the correct one in the script).  Yeah, I think this will work.

And to think, I was just ready to head off to bed.  Mountain Dew, here I come.

Edit: That worked. Thanks, David.

Modifié par BillHoyt, 01 mai 2010 - 03:54 .