Tailor dropping item it crafted after player kills him


#1

I’m sure this is a very old issue but I have little idea how to stop this from happening I am no scripter. Any help would be greatly appreciated.


#2

Arr. :slight_smile: Try cleaning out their inventory on death, like this:

    object oItem = GetFirstItemInInventory();
    while (oItem != OBJECT_INVALID)
        {
        DestroyObject(oItem);

        oItem = GetNextItemInInventory();
        }

Or otherwise mark crafted items with a local int, to preserve the tailor dropping their normal loot.

    if (GetLocalInt(oItem, "DESTROY_ON_DEATH"))
        DestroyObject(oItem);

#3

This is what I have on script. I’m not sure how I should change this , or is this script just for cleaning the area not the inventory of the tailor so it wont drop items being crafted. It seems very similar to your script.

// OnExit script to get rid of an areas NPCs
// Twainer

void main()
{
if(!GetIsPC(GetExitingObject())) return;

//Count players to see if we're the last out
object oPC = GetFirstPC();
int PCcount = 0;
while(GetIsObjectValid(oPC)){
    if(GetArea(oPC) == OBJECT_SELF && !GetIsDM(oPC))
        PCcount ++;

    oPC = GetNextPC();
}
if(PCcount > 0)
    return;

// Loop through objects to see if they have the local on them
object oObject = GetFirstObjectInArea(OBJECT_SELF);
while(GetIsObjectValid(oObject)){
    if(GetLocalInt(oObject, "TWN_SPAWN_NPC") == 1)
        DestroyObject(oObject);

    oObject = GetNextObjectInArea(OBJECT_SELF);
}
//ExecuteScript("k_area_cleaner", OBJECT_SELF);

}


#4

I’ve line-by-line commented that for you, so you can see what’s happening in it:

// OnExit script to get rid of an areas NPCs
// Twainer

void main()
{
    // If the exiting object that caused this OnExit event to be called is not a PC...
    if(!GetIsPC(GetExitingObject()))
        // ... abort the script at this point.
        return;

    //Count players to see if we're the last out

    // Declare an object called "oPC", and define it as the first PC in the module.
    object oPC = GetFirstPC();
    // Declare an integer called PCcount, and define it as 0.
    int PCcount = 0;
    // For as long as oPC is a valid object, repeat the following action:
    while(GetIsObjectValid(oPC)){
        // If oPC's area is OBJECT_SELF (the caller of the script), and oPC is not a DM...
        if(GetArea(oPC) == OBJECT_SELF && !GetIsDM(oPC))
            // ... increase integer PCcount by 1.
            PCcount ++;

        // Change oPC to be the next PC.
        oPC = GetNextPC();
        // Once the next PC is not a valid object anymore,
        // the while loop will stop, because it's condition
        // (that oPC must be a valid object) is no longer being met.
    }
    // If the value of PCcount is greater than 0...
    if(PCcount > 0)
        // ... abort the script at this point.
        return;

    // Loop through objects to see if they have the local on them
    // Declare an object called "oObject", and define it as the first object in
    // the area that called this script.
    object oObject = GetFirstObjectInArea(OBJECT_SELF);
    // For as long as oObject is a valid object, repeat the following action:
    while(GetIsObjectValid(oObject)){
        // If oObject has a local integer called "TWN_SPAWN_NPC" on it whose exact value is 1...
        if(GetLocalInt(oObject, "TWN_SPAWN_NPC") == 1)
            // ... destroy that object.
            DestroyObject(oObject);

        // Change oObject to be the next object in the area.
        oObject = GetNextObjectInArea(OBJECT_SELF);
        // Same deal as with the previous while loop.
    }
    // This line is currently commented out, but ExecuteScript would make OBJECT_SELF here
    // execute another script, called "k_area_cleaner".
    //ExecuteScript("k_area_cleaner", OBJECT_SELF);
}

Yes. What you’ve posted there is a script set up for an area OnExit event, and it destroys objects within an area (placeables, creatures, whatnot). It cycles through the objects within the calling area via GetFirstObjectInArea() and GetNextObjectInArea(), as opposed to GetFirstItemInInventory() and GetNextItemInInventory(), like an inventory clean-out would.

Quick scripting basics pull-you-up: There are events (examples: something is exiting an area, a creature has died, a placeable has been opened, something is entering a floor trigger), and there are functions we can call in those events, causing stuff to happen.

You could grab the tailor NPCs’ OnDeath event, and destroy the items that are in their inventory at their time of death, by cycling through them one at a time, as posted in the first example. They’re in the Scripts tab of the Creature Properties.

To be on the safe side, clone the existing script (when it’s open, save via Save As / CTRL+ALT+S), creating a copy of the original, so you don’t accidentally make more NPCs than just the tailors erase their inventories on death. Multiple different NPCs can be making use of the same scripts in their events, so if you edit a script they all share, everyones’ behaviour changes at once.


#5

Why not keep it simple with SetDroppableFlag and GetDroppableFlag? You’d set the flag when finished item is transferred to PC. If anything “bad” happens in the meantime, no item will be spawned in loot bag.


#6

Umm, make the tailor plot ?


#7

I think I will try making it a plot seems like the easiest way to try first. Thank you to all that gave me suggestions , its great to have this forum to get advice from the people who are the true preservers of this game.


#8

If you wanted a bit more fun, you could also have the tailor protected by armed guards (that are bad mo’fos), and have any Watch or Guard or whatever passes for police in your world respond immediately upon your attack, either killing the attacker or ‘knocking them out’ and putting them in jail, assessing fines, whatnot.


#9

Yeah I feel like doing that ,I’m sure players took advantage of the tailor for free gold for a while.