Author Topic: Spawn chest, add item  (Read 392 times)

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
Spawn chest, add item
« on: April 22, 2014, 04:29:46 pm »


               

I'm trying to have one script that will spawn a chest and randomly put something in it. I suppose I could spawn the chest and have a second script on the chest to generate the item, but I'm now just wondering if I can do both from one script. What I made below spawns two chests. 


 


string epicItem;

object oTarget;

object oSpawn;

location lTarget;

oTarget = OBJECT_SELF;

 

int x = Random(2);

 

switch(x)

{

case 1:  {epicItem = "zep_arabian"; break;}

case 2:  {epicItem = "zep_arabian"; break;}

default: break;

}

 

lTarget = GetLocation(oTarget);

 

oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "epiclootchest", lTarget);

CreateItemOnObject(epicItem, GetNearestObjectByTag("epiclootchest"));

 


               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Spawn chest, add item
« Reply #1 on: April 22, 2014, 05:59:47 pm »


               

This:



oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "epiclootchest", lTarget);
CreateItemOnObject(epicItem, GetNearestObjectByTag("epiclootchest"));

should be changed as follows:



oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "epiclootchest", lTarget);
DelayCommand(0.1, CreateItemOnObject(epicItem, oSpawn) );

so as you can see I did two things. First, I eliminated your search for the created chest. You already have the reference to the created chest. Second, I added a delay before creating an item in the chest. I am not positive that this is necessary, and so suggest that you try your script without it, but I have found in many instances that an object isn't always "ready" immediately after it is created. Example, I have tried to get spawned invisibles to play sounds, but they do not play the sound unless I put that delay in there. I suspect that a spawned placeable can however receive an item in inventory, but in case it fails, I suggest you try the delay I put in there.


 


Also, you said your script spawns two chests, but it doesn't appear to do so from what I can see. Why do you say it creates two? Is the script executing more than once?



               
               

               
            

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
Spawn chest, add item
« Reply #2 on: April 22, 2014, 07:07:00 pm »


               

Thanks for the reply. I did try the delay originally and receive a " ERROR: DECLARATION DOES NOT MATCH PARAMETERS". Same with your code. 


and yup, I get two chests. 


This is being triggered from a creatures OnDeath. I do have a debug (speakstring) on the creature and it only appears once, and a debug on the loot script and it only appears once.  I'm also building it before running.


 


 


 


can we use code boxes now test

               
               

               
            

Legacy_Zwerkules

  • Hero Member
  • *****
  • Posts: 1997
  • Karma: +0/-0
Spawn chest, add item
« Reply #3 on: April 22, 2014, 07:29:38 pm »


               

Make a function that creates the epic item and call that function with DelayCommand. That should work.


DelayCommand(0.1f, MakeEpicItem(oEpic));


 


Edit: CreateItemOnObject returns an object while DelayCommand needs a 'void' function. You also used CreateItemOnObject wrong which will give you the same error message again.


 


object CreateItemOnObject(string sItemTemplate, object oTarget=OBJECT_SELF, int nStackSize=1, string sNewTag="")


 


The function CreateItemOnObject needs the template of the item (a string), not an object.


               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Spawn chest, add item
« Reply #4 on: April 22, 2014, 07:31:17 pm »


               

Death scripts run twice if I recall correctly. You can easily test this. My solution for it was to mark a creature as dead with a local integer at the end of the script, and to check for it at the top. If it is found at the top, exit the script with "return".


 


Example:



if(GetLocalInt(OBJECT_SELF, "DEAD"))
    return;
else
    SetLocalInt(OBJECT_SELF,"DEAD",TRUE);

Put that at the top of your death script, and let me know if you get two chests. '<img'>


 


 


As for why the code didn't work, I overlooked the fact that CreateItemOnObject returns an object. This can be solved in a few ways. But why not first try the code without the delay. If the delay is needed, you can wrap CreateItemOnObject in a custom function (as Zwerkules suggests) or in a setlocalobject call.



               
               

               
            

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
Spawn chest, add item
« Reply #5 on: April 22, 2014, 07:43:35 pm »


               

I haven't noticed that before. I even had a speakstring on the OnDeath and it only ran once. I did put a local int check on it and it does run twice. Problem resolved, thanks guys!



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Spawn chest, add item
« Reply #6 on: April 22, 2014, 11:05:41 pm »


               Random(2) returns 0 or 1, so case 2 is unlikely to occur...


OnDeath scripts are potentially unreliable, because the creature may cease to exist before it can perform actions or delayed code. For safety, I assign anything that isn't executed instantly to a more permanent object, such as the module.
               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Spawn chest, add item
« Reply #7 on: April 23, 2014, 08:28:28 am »


               

Death scripts run twice if I recall correctly...

Curious; I can't reproduce this in vanilla 1.69. Is it possible that some popular customisation is responsible?
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Spawn chest, add item
« Reply #8 on: April 23, 2014, 12:31:43 pm »


               


Curious; I can't reproduce this in vanilla 1.69. Is it possible that some popular customisation is responsible?




IIRC this is a "badly" implemented custom XP system. Its a workaround to the "double xp" issue that is caused by the fact that builder doesnt set the XP scale slider to 0 in module properties. Set it to 0 and you wont have a double xp so you dont need to use the workaround causing double death script (AFAIK creature is killed again by ApplyEffectToObject(EffectDeath(()).


               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Spawn chest, add item
« Reply #9 on: April 23, 2014, 06:59:56 pm »


               

I vaguely share Shadooow's recollection, but I don't think it's the only explanation. We have a creature that fires multiple death scripts for a reason I've never quite been able to fathom. On the whole, though, death events are extremely reliable - we use them for all sorts of things without any issues. Whatever 'double fire' issue you're having is no doubt the result of some 'creative' coding (like my creature, above '<img'> ).


 


Funky



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Spawn chest, add item
« Reply #10 on: April 23, 2014, 09:53:07 pm »


               

On the whole, though, death events are extremely reliable - we use them for all sorts of things without any issues...

 

Funky




Agreed, for immediate biz, very reliable, and doesn't happen twice. I'd reiterate the caveat in the Lexicon, though, as I've often fallen into the timing trap (easily done if you fire another script or function without checking whether it contains delayed commands or actions for the corpse).