Skip to content

Destroying Object_Self from conversation

Trying to destroy a placable object from a conversation (with object).
void main()
{
    object oSelf = OBJECT_SELF;

    // Get the PC who is in this conversation.
    object oPC = GetPCSpeaker();

    // Give "fieldsmelter" to the PC.
    CreateItemOnObject("fieldfletching", oPC);
    AssignCommand(oSelf, ActionDoCommand(SetIsDestroyable(TRUE, FALSE, FALSE)));
    // Destroy an object (not fully effective until this script ends).
    DestroyObject(oSelf,1.0);
}


The object fades out then comes back. The curious thing is that it works on my henchmen. The plot flag is not set (although the lexicon says this doesn't matter). Any tips as to what could be causing this to happen?

Comments

  • ProlericProleric Member Posts: 1,283
    Did you try commenting out the SetIsDestroyable line? I believe that's only for creatures - action on placeables unknown.
  • vonstormvonstorm Member Posts: 66
    The original didn't have that line, (added it on your advice from another post on henchmen out of desperation :) ) and I just tried it commented out. No luck. There are no scripts on the object (ondestroyed etc).
  • ProlericProleric Member Posts: 1,283
    Maybe try
    AssignCommand(GetModule(), DestroyObject(oSelf));
    

    I've taken the delay out because it's redundant (DestroyObject will not happen until the script has finished). Sometimes the module seems to have permission to do stuff that placeables don't.

    ...all the same, given the behaviour, I can't help wondering whether some other script is respawning the placeable?
  • vonstormvonstorm Member Posts: 66
    Yup delay was another deperandum measure. So The placable is created by an item cast spell unique power single use . Further testing shows that if I place it manually in the world, it does despawn. When I create it via the Item, it doesn't.

    create code:
    void main()
    {
        object oSpawn;
        object oPC = GetItemActivator();
        object oActTarget = GetItemActivatedTarget();
        location lActTarget = GetItemActivatedTargetLocation();
        // This item must target a location (not an object).
        if ( GetIsObjectValid(oActTarget) )
        {
            SendMessageToPC(oPC, "Improper use of this item!");
            return;
        }
    
        // Spawn "workstation".
        oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "fsmelter", lActTarget);
    }
    
    

    Am I going insane? :)
  • ForSeriousForSerious Member Posts: 446
    Where is that create code being called from exactly?
  • vonstormvonstorm Member Posts: 66
    edited February 2021
    Tag-based spell effect script from item - cast spell unique power single use
  • ForSeriousForSerious Member Posts: 446
    So from the module event OnActivateItem?
  • vonstormvonstorm Member Posts: 66
    on module load -
    SetModuleSwitch (MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS, TRUE);

    I think it's internal game stuff, never looked into it :( it usually just works, which it does, it creates an indestructible object lol.
  • ForSeriousForSerious Member Posts: 446
    I blame that then.
    This is the simplest way I've seen to do tag based item activation.
    OnActivateItem:
    // Simple on activate redirect.
    void main()
    {
        object oItem = GetItemActivated();
        object oPC = GetItemActivator();
        if(GetIsObjectValid(oItem))
        {
            ExecuteScript(GetTag(oItem), oPC);
        }
    }
    
    The script with the same name as the tag of the activated item:
    void main()
    {
        // Gets if the item was targeted on an object.
        object oTarget = GetSpellTargetObject();
        if(GetIsObjectValid(oTarget))
        {
            // Do the stuff with oTarget
    	return;
        }
        // Gets if the item was targeted on the ground.
        location lLoc = GetSpellTargetLocation();
        // Do stuff with lLoc
    }
    
  • vonstormvonstorm Member Posts: 66
    Ill give that a try, and report back. I thought I was losing it :)
  • vonstormvonstorm Member Posts: 66
    Well, that fixed it. I turned off tag-based scripting, added on activate redirect onactivate (although I pointed to OBJECT_SELF, not oPC because most items are the source) and the resulting placable destroys as expected. I have no idea why they should be different. Thanks to all for their time and patience, as always
  • meaglynmeaglyn Member Posts: 149
    You should not need to turn off tag based scripting and create exactly the same functionality with a different set of scripts. I suspect your script was firing onAcquire as well. Probably having the tag based script check if it is the activate event would solve this without the work around. Adding something like this to the original script:
     int nEvent = GetUserDefinedItemEventNumber();
     if (nEvent != X2_ITEM_EVENT_ACTIVATE) return;
    
  • ForSeriousForSerious Member Posts: 446
    In some of the research I've done lately, I think most of those flags are used by the systems already in place. For example, I thought AI_LEVEL_VERY_LOW meant how cunning an enemy would be. With that logic, I called SetAILevel(AI_LEVEL_VERY_HIGH) on spawn. It didn't do anything.
    The pre-implemented system uses those variables to track how much interaction is going on between an NPC and a player. AI_LEVEL_VERY_HIGH actually just means that they are in combat. AI_LEVEL_VERY_LOW means there's no players in the same area.
    Maybe something similar is going on with MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS.
  • vonstormvonstorm Member Posts: 66
    edited February 2021
    meagln - You are right. I just re-added "a bag of coal" that when activated gives the player 10 coal lumps. I had taken it out because when a player purchased it by dragging it would give the bag and 10 lumps. Now it does not. So the onAquire firing makes sense. I totally forgot that tag-based scripting fires under multiple conditions, so by getting the item back it was probably creating again.
  • meaglynmeaglyn Member Posts: 149
    edited February 2021
    Tag based scripts will be called for all the item related module events. The placeable script here is creating a new copy of the item for the PC in the first script. So the module's onAcquire script will run. This will then run the tag-based script for that item. I suppose the engine does not clear the item activation data and so it comes up with a valid location and recreates the placeable.

    This has nothing to do with AI_LEVEL.

    Tag based scripting is very simple, it's added right into the various x2_mod_def* module scripts and does pretty much exactly what your wrapper does. It sets the userdefineditemeventnumber and then executes the script. But it does it for acquire, activate, equip, unequip, unacquire etc. So the tag based script itself should check and do the right thing for the right event number.
  • vonstormvonstorm Member Posts: 66
    Invaluable lessons from all, thanks again
Sign In or Register to comment.