//:://///////////////////////////////////////////// //:: el_loot_include //:: main library for Looting Script ver 5.4 //:: By: Emmanuel Lusinchi (Sentur Signe) //:: Last modified: 11/21/2002 // //:: New from 5.2 //:: a) Corpse placeable is deleted after a random time //:: (between 1 and 3 seconds) if the corresponding creature possessed //:: no lootable items //:: b) Corpse moving due to the 'animal empathy ceasing' solved (I think) //:: c) Corrected one bug in which destroying a corpse placeable would not cause //:: the real creature to decay if EL_CORPSE_CLEANING_DELAY was set to 0.0f //:: //:: New from 5.3 //:: a) Solved problem with double-click destroying the corpse placeable //:: b) Took some steps to prevent endless looting animation. Animation *will* //:: stop when closing the placeable. Note that if you open & close a //:: placeable (any placeable with an associated onopen script) fast enough //:: and long enough, you *will* eventually confuse NWN on the state of the //:: placeable (ie: it won't know whether it's open or closed) //:: //::////////////////////////////////////////////// int bUSEDELAYINLOOTING = FALSE; float fDELAYCHEST = 6.0f; float fDELAYITEMS = 2.0f; int GetDropeableFlag(object oInv) {return GetDroppableFlag(oInv);} // el_SetCorpseCondition(int EL_FLAG_NO_CHEST_LOOT, int EL_FLAG_2X_CHEST_LOOT,float EL_CORPSE_TIMEOUT_NOLOOT,float EL_CORPSE_TIMEOUT_IFLOOT,float EL_CORPSE_CLEANING_DELAY, EL_ONDESTRUCTION_MESSY_EFFECT) // // - EL_FLAG_NO_CHEST_LOOT: if set to TRUE, the chest item can never be looted // - EL_FLAG_2X_CHEST_LOOT: obsolete // - EL_CORPSE_TIMEOUT_IFLOOT, EL_CORPSE_TIMEOUT_NOLOOT: delay for decay to happen // - EL_CORPSE_CLEANING_DELAY: setting to 0.0f disable clean-up. Clean-up also only // works if some form of decay is happening. // - EL_ONDESTRUCTION_MESSY_EFFECT : A value of -1 will use the default blood&bone animation, 0 will disable the animation, and any VFX_ instant animation constant can be used (eg: VFX_COM_CHUNK_GREEN_MEDIUM ) void el_SetCorpseCondition(int EL_FLAG_NO_CHEST_LOOT, int EL_FLAG_2X_CHEST_LOOT,float EL_CORPSE_TIMEOUT_NOLOOT,float EL_CORPSE_TIMEOUT_IFLOOT,float EL_CORPSE_CLEANING_DELAY, int EL_ONDESTRUCTION_MESSY_EFFECT); void destroyObjectIfNotPlot(object oItem); int getNextSlot(int iSlot); void lootInventory(object oOwner, object oLooter, object oCleaner); void lootSlot(object oOwner, object oLooter, object oCleaner, int iSlot); void lootChest(object oOwner, object oLooter, object oCleaner, int iCounter); void lootOnOpen(); void lootOnClose(); void lootCleanUp(); void lootCleanUpPart2(); void lootTakeNote(object oOwner); void lootGold(object oOwner, object oPlaceable, object oCleaner); void lootQuickly(); void lootQuicklyOnClose(); int lootIsEmpty(object oOwner); void el_LootMobOnUserDef(); void el_LootPlaceableOnOpen(int iLootedByPC); void el_LootPlaceableOnClose(); void el_LootPlaceableOnUserDef(); void el_LootPlaceableOnDeath(); /////////////////////////////////////////////// /////////////////////////////////////////////// void el_SetCorpseCondition(int EL_FLAG_NO_CHEST_LOOT, int EL_FLAG_2X_CHEST_LOOT,float EL_CORPSE_TIMEOUT_NOLOOT,float EL_CORPSE_TIMEOUT_IFLOOT,float EL_CORPSE_CLEANING_DELAY, int EL_ONDESTRUCTION_MESSY_EFFECT) { SetIsDestroyable(FALSE, TRUE, FALSE); SetLocalInt(OBJECT_SELF, "EL_FLAG_LEAVE_CORPSE", TRUE); SetLocalInt(OBJECT_SELF, "EL_FLAG_NO_CHEST_LOOT", EL_FLAG_NO_CHEST_LOOT); SetLocalInt(OBJECT_SELF, "EL_FLAG_2X_CHEST_LOOT", EL_FLAG_2X_CHEST_LOOT); // The Chest item is where clothes are located for player-like creature // If you set "EL_FLAG_NO_CHEST_LOOT" to: // TRUE = will not loot the chest area (Clothes will stay on!) // FALSE = will loot the chest area but if the chest item Dropeable flag is not set, // the item will be removed from the mob but NOT given to the players (ie: it will // be destroyed). // If the Dropeable property is set on the item and EL_FLAG_NO_CHEST_LOOT is TRUE, // the chest item WILL be available upon destruction of the corpse, which is the normal // expected behavior. // If EL_FLAG_2X_CHEST_LOOT is TRUE and EL_FLAG_NO_CHEST_LOOT is FALSE, first looting // of the corpse will remove everything except the chest item and a *second* looting will // remove the chest item. // In NO CASE, flag or no flag, tag or not tag, will players have access to an item // if the 'Dropeable' property wasn't checked on the item itself. So, the use of the // Corpse Lootable feature is always 100% safe regardless // of EL_FLAG_NO_CHEST_LOOT and EL_FLAG_2X_CHEST_LOOT // EL_CORPSE_CLEANING_DELAY is the time before the dead creature's objects // get cleaned-up and destroyed. // Only those objects that are close enough to the location of death & not // in a player's inventory will be cleaned out. SetLocalFloat(OBJECT_SELF, "EL_CORPSE_TIMEOUT_IFLOOT", EL_CORPSE_TIMEOUT_IFLOOT); SetLocalFloat(OBJECT_SELF, "EL_CORPSE_TIMEOUT_NOLOOT", EL_CORPSE_TIMEOUT_NOLOOT); if ( ( EL_CORPSE_TIMEOUT_IFLOOT == 0.0f) && ( EL_CORPSE_TIMEOUT_NOLOOT == 0.0f ) ) SetLocalFloat(OBJECT_SELF, "EL_CORPSE_CLEANING_DELAY", 0.0f); else SetLocalFloat(OBJECT_SELF, "EL_CORPSE_CLEANING_DELAY", EL_CORPSE_CLEANING_DELAY); if (EL_ONDESTRUCTION_MESSY_EFFECT != 0) { SetLocalInt(OBJECT_SELF, "EL_FLAG_MESSY_DEATH",TRUE); if (EL_ONDESTRUCTION_MESSY_EFFECT == -1) { SetLocalInt(OBJECT_SELF, "EL_ONDESTRUCTION_MESSY_EFFECT",VFX_COM_CHUNK_RED_SMALL); } else { SetLocalInt(OBJECT_SELF, "EL_ONDESTRUCTION_MESSY_EFFECT",EL_ONDESTRUCTION_MESSY_EFFECT); } } } void el_LootMobOnUserDef() { int nUser = GetUserDefinedEventNumber(); // ON DEATH if ( nUser == 1007 ) { ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 1.0f); vector vHere = GetPosition(OBJECT_SELF); vector vUnder = Vector(vHere.x, vHere.y,vHere.z-0.1f); location lUnder = Location(GetArea(OBJECT_SELF), vUnder, 0.0f); object oPlaceable = CreateObject(OBJECT_TYPE_PLACEABLE, "el_corpsetoloot", lUnder, FALSE); object oCleaner = CreateObject(OBJECT_TYPE_PLACEABLE, "el_cleaner", lUnder, FALSE); SetLocalObject(oPlaceable, "oOwner", OBJECT_SELF); SetLocalObject(oCleaner, "oOwner", OBJECT_SELF); SetLocalObject(oPlaceable, "oCleaner", oCleaner); SetLocalObject(oCleaner, "oPlaceable", oPlaceable); DelayCommand(1.0f+d20()*0.1f, SignalEvent(oCleaner, EventUserDefined(2003))); // Check if inventory is empty float fDelayNoLoot = GetLocalFloat(OBJECT_SELF, "EL_CORPSE_TIMEOUT_NOLOOT"); if (fDelayNoLoot != 0.0f) DelayCommand(fDelayNoLoot, SignalEvent(oCleaner, EventUserDefined(2001))); // remove sleep resistance... object oTemp; oTemp = GetItemInSlot(INVENTORY_SLOT_CARMOUR, OBJECT_SELF); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, OBJECT_SELF); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, OBJECT_SELF); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, OBJECT_SELF); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(EffectDispelMagicAll(20)),OBJECT_SELF); ApplyEffectToObject(DURATION_TYPE_INSTANT, ExtraordinaryEffect(EffectDispelMagicAll(20)),OBJECT_SELF); } } void el_LootPlaceableOnOpen(int iLootedByPC) { if (bUSEDELAYINLOOTING) lootOnOpen(); else lootQuickly(); return; } void el_LootPlaceableOnClose() { if (bUSEDELAYINLOOTING) lootOnClose(); else lootQuicklyOnClose(); return; } void el_LootPlaceableOnDeath() { object oCleaner = GetLocalObject(OBJECT_SELF,"oCleaner"); SetLocalInt(oCleaner, "bForceDecay", TRUE); object oOwner = GetLocalObject(OBJECT_SELF,"oOwner"); if ( GetLocalInt(oOwner, "EL_FLAG_MESSY_DEATH") ) ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectVisualEffect(GetLocalInt(oOwner, "EL_ONDESTRUCTION_MESSY_EFFECT")),oOwner); DestroyObject(GetLocalObject(oCleaner, "oWait")); SignalEvent(oCleaner, EventUserDefined(2001)); return; } void el_LootPlaceableOnUserDef() { int nUser = GetUserDefinedEventNumber(); // Decay if never touched. Part I if ( ( nUser == 2001 ) || ( nUser == 2002) ) { lootCleanUp(); return; } if (nUser == 2003) { object oOwner = GetLocalObject(OBJECT_SELF,"oOwner"); // New in ver 5.3 ///////////// !!!!!!!!!!!! // We put it here rather than on the owner's ondeath to prevent // spurious 'coup de grace' messages :) object oTemp; oTemp = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oOwner); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oOwner); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oOwner); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oOwner); SetPlotFlag(oTemp, FALSE); DestroyObject(oTemp); ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSleep()),oOwner); ApplyEffectToObject(DURATION_TYPE_PERMANENT, ExtraordinaryEffect(EffectSleep()),oOwner); if (lootIsEmpty(oOwner)) DestroyObject(GetLocalObject(OBJECT_SELF,"oPlaceable")); return; } } void destroyObjectIfNotPlot(object oItem) { if (!GetPlotFlag(oItem)) DestroyObject(oItem); } int getNextSlot(int iSlot) { if (iSlot == INVENTORY_SLOT_RIGHTHAND ) return INVENTORY_SLOT_LEFTHAND; if (iSlot == INVENTORY_SLOT_LEFTHAND ) return INVENTORY_SLOT_HEAD; if (iSlot == INVENTORY_SLOT_HEAD ) return INVENTORY_SLOT_ARMS; if (iSlot == INVENTORY_SLOT_ARMS ) return INVENTORY_SLOT_CLOAK; if (iSlot == INVENTORY_SLOT_CLOAK ) return INVENTORY_SLOT_RIGHTRING; if (iSlot == INVENTORY_SLOT_RIGHTRING ) return INVENTORY_SLOT_LEFTRING; if (iSlot == INVENTORY_SLOT_LEFTRING ) return INVENTORY_SLOT_NECK; if (iSlot == INVENTORY_SLOT_NECK ) return INVENTORY_SLOT_BOOTS; if (iSlot == INVENTORY_SLOT_BOOTS ) return INVENTORY_SLOT_ARROWS; if (iSlot == INVENTORY_SLOT_ARROWS ) return INVENTORY_SLOT_BOLTS; if (iSlot == INVENTORY_SLOT_BOLTS ) return INVENTORY_SLOT_BULLETS; if (iSlot == INVENTORY_SLOT_BULLETS ) return INVENTORY_SLOT_BELT; if (iSlot == INVENTORY_SLOT_BELT ) return INVENTORY_SLOT_CHEST; return -1; } void lootInventory(object oOwner, object oLooter, object oCleaner) { if (GetLocalInt(OBJECT_SELF, "bAbortLooting")) return; object oItem = GetFirstItemInInventory(oOwner); int bFound = FALSE; while (bFound == FALSE) { // nothing in inventory. We move on to slots. if (oItem == OBJECT_INVALID) { DelayCommand(0.1f, lootSlot(oOwner, oLooter, oCleaner, INVENTORY_SLOT_RIGHTHAND)); AssignCommand(oLooter, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.0f)); return; } if (GetDropeableFlag(oItem)) bFound = TRUE; else { DestroyObject(oItem); oItem = GetNextItemInInventory(oOwner); } } // setup for the loot of the next object ActionTakeItem(oItem, oOwner); int iIndex = GetLocalInt(oCleaner, "iIndex"); SetLocalObject(oCleaner, "oToClean_"+IntToString(iIndex), oItem); SetLocalInt(oCleaner, "iIndex", iIndex+1); DelayCommand(fDELAYITEMS,lootInventory(oOwner, oLooter, oCleaner)); AssignCommand(oLooter, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, fDELAYITEMS)); return; } void lootSlot(object oOwner, object oLooter, object oCleaner, int iSlot) { if (GetLocalInt(OBJECT_SELF, "bAbortLooting")) return; int iCurrentSlot = iSlot; object oItem = GetItemInSlot(iCurrentSlot, oOwner); int bFound = FALSE; while (bFound == FALSE) { if (oItem != OBJECT_INVALID) { if (GetDropeableFlag(oItem)) { bFound = TRUE; } else { if ( (iCurrentSlot != INVENTORY_SLOT_CHEST) && (iCurrentSlot != INVENTORY_SLOT_RIGHTHAND) && (iCurrentSlot !=INVENTORY_SLOT_LEFTHAND ) ) DestroyObject(oItem); iCurrentSlot = getNextSlot(iCurrentSlot); oItem = GetItemInSlot(iCurrentSlot, oOwner); } } else { iCurrentSlot = getNextSlot(iCurrentSlot); if (iCurrentSlot != -1) oItem = GetItemInSlot(iCurrentSlot, oOwner); else { FloatingTextStringOnCreature("Nothing Left To Loot", oLooter, TRUE); SetLocalInt(OBJECT_SELF, "bNothingLeftToLoot", TRUE); return; } } } if (iCurrentSlot == INVENTORY_SLOT_CHEST) { if (GetLocalInt(oOwner, "EL_FLAG_NO_CHEST_LOOT")) return; FloatingTextStringOnCreature("Looting Armor / Cloth", oLooter, TRUE); DelayCommand(fDELAYCHEST, lootChest(oOwner, oLooter,oCleaner, 0)); if (GetItemPossessedBy(OBJECT_SELF, "LootingArmororClothPleaseWait") == OBJECT_INVALID) { object oWait = CreateItemOnObject("lootingarmororcl", OBJECT_SELF); SetLocalObject(oCleaner, "oWait", oWait); } AssignCommand(oLooter, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, fDELAYCHEST)); return; } else { ActionTakeItem(oItem, oOwner); int iIndex = GetLocalInt(oCleaner, "iIndex"); SetLocalObject(oCleaner, "oToClean_"+IntToString(iIndex), oItem); SetLocalInt(oCleaner, "iIndex", iIndex+1); iCurrentSlot = getNextSlot(iCurrentSlot); DelayCommand(fDELAYITEMS, lootSlot(oOwner, oLooter, oCleaner, iCurrentSlot)); AssignCommand(oLooter, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, fDELAYITEMS)); return; } } void lootChest(object oOwner, object oLooter, object oCleaner, int iCounter) { DestroyObject(GetLocalObject(oCleaner, "oWait")); if (GetLocalInt(OBJECT_SELF, "bAbortLooting")) return; object oItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oOwner); if (oItem == OBJECT_INVALID) { FloatingTextStringOnCreature("Nothing Left To Loot", oLooter, TRUE); SetLocalInt(OBJECT_SELF, "bNothingLeftToLoot", TRUE); return; } else { if (iCounter == 10) return; // some problem... we give up ActionTakeItem(oItem, oOwner); int iIndex = GetLocalInt(oCleaner, "iIndex"); SetLocalObject(oCleaner, "oToClean_"+IntToString(iIndex), oItem); // take the item and check periodically that it succeeded. Yes I am a bit on the paranoid side nowadays DelayCommand(1.0f, lootChest(oOwner, oLooter, oCleaner, iCounter+1)); return; } } void lootOnOpen() { SetLocalInt(OBJECT_SELF, "bAbortLooting", FALSE); if (GetLocalInt(OBJECT_SELF, "bNothingLeftToLoot")) return; object oOwner = GetLocalObject(OBJECT_SELF,"oOwner"); object oCleaner = GetLocalObject(OBJECT_SELF,"oCleaner"); int bAlreadyUsed = GetLocalInt(OBJECT_SELF, "bAlreadyUsed"); if (bAlreadyUsed == FALSE) { SetLocalInt(OBJECT_SELF, "bAlreadyUsed", TRUE); lootGold(oOwner, OBJECT_SELF, oCleaner); float fDelayIfLoot = GetLocalFloat(oOwner, "EL_CORPSE_TIMEOUT_IFLOOT"); if (fDelayIfLoot!=0.0f) DelayCommand(fDelayIfLoot, SignalEvent(oCleaner, EventUserDefined(2002))); } lootInventory(oOwner, GetLastOpenedBy(), oCleaner); return; } void lootOnClose() { DestroyObject(GetLocalObject(GetLocalObject(OBJECT_SELF, "oCleaner"), "oWait")); SetLocalInt(OBJECT_SELF, "bAbortLooting", TRUE); AssignCommand(GetLastClosedBy(),ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 1.0f)); if (GetLocalInt(OBJECT_SELF, "bNothingLeftToLoot")) { object oItem = GetFirstItemInInventory(); if (oItem == OBJECT_INVALID) DestroyObject(OBJECT_SELF); } } void lootCleanUp() { object oOwner = GetLocalObject(OBJECT_SELF,"oOwner"); object oPlaceable = GetLocalObject(OBJECT_SELF,"oPlaceable"); lootGold(oOwner, oPlaceable, OBJECT_SELF); // if never looted, we need to get the gold now float fCleaningDelay = GetLocalFloat(oOwner, "EL_CORPSE_CLEANING_DELAY"); if ( GetLocalInt(OBJECT_SELF, "bForceDecay") == FALSE ) { if (fCleaningDelay == 0.0f) return; ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_INVISIBILITY), oOwner); } lootTakeNote(oOwner); // AssignCommand(oOwner, SetIsDestroyable(TRUE)); // done in lootTakeNote DestroyObject(oPlaceable); if (fCleaningDelay != 0.0f) DelayCommand (fCleaningDelay, lootCleanUpPart2()); } void lootCleanUpPart2() { object oGold = GetLocalObject(OBJECT_SELF, "oGold"); SetPlotFlag(oGold, FALSE); DestroyObject(oGold); int iMaxIndex = GetLocalInt(OBJECT_SELF, "iIndex"); // if no item have been indexed, nothing to clean-up... just allow dead mob to decay if (iMaxIndex == 0) { DestroyObject(OBJECT_SELF, 1.0f); return; } object oToClean; object oPossessor; int iIndex = 0; while (iIndex <= iMaxIndex) { oToClean = GetLocalObject(OBJECT_SELF, "oToClean_"+IntToString(iIndex)); oPossessor = GetItemPossessor(oToClean); if ( (GetObjectType(oPossessor) != OBJECT_TYPE_CREATURE) || (GetIsDead(oPossessor) == TRUE) ) if (GetDistanceBetween(OBJECT_SELF, oToClean) < 500.0f) { destroyObjectIfNotPlot(oToClean); } iIndex++; } DestroyObject(OBJECT_SELF, 1.0f); return; } void lootTakeNote(object oOwner) { int iIndex = GetLocalInt(OBJECT_SELF, "iIndex"); object oItem = GetFirstItemInInventory(oOwner); while (oItem != OBJECT_INVALID) { SetLocalObject(OBJECT_SELF, "oToClean_"+IntToString(iIndex), oItem); iIndex++; oItem = GetNextItemInInventory(oOwner); } int iSlot = INVENTORY_SLOT_RIGHTHAND; oItem = GetItemInSlot(iSlot, oOwner); while (iSlot != -1) { if (oItem != OBJECT_INVALID) { SetLocalObject(OBJECT_SELF, "oToClean_"+IntToString(iIndex), oItem); iIndex++; } iSlot = getNextSlot(iSlot); if (iSlot != -1) oItem = GetItemInSlot(iSlot, oOwner); } SetLocalInt(OBJECT_SELF, "iIndex", iIndex); AssignCommand(oOwner, SetIsDestroyable(TRUE)); } void lootGold(object oOwner, object oPlaceable, object oCleaner) { int iGold = GetGold(oOwner); if (iGold == 0) return; TakeGoldFromCreature(iGold, oOwner, TRUE); object oGold = CreateItemOnObject("nw_it_gold001", oPlaceable, iGold); SetLocalObject(oCleaner, "oGold", oGold); return; } void lootQuickly() { int bAlreadyUsed = GetLocalInt(OBJECT_SELF, "bAlreadyUsed"); if (bAlreadyUsed == TRUE) return; object oOwner = GetLocalObject(OBJECT_SELF,"oOwner"); object oCleaner = GetLocalObject(OBJECT_SELF,"oCleaner"); object oLooter = GetLastOpenedBy(); SetLocalInt(OBJECT_SELF, "bAlreadyUsed", TRUE); lootGold(oOwner, OBJECT_SELF, oCleaner); float fDelayIfLoot = GetLocalFloat(oOwner, "EL_CORPSE_TIMEOUT_IFLOOT"); if (fDelayIfLoot!=0.0f) DelayCommand(fDelayIfLoot, SignalEvent(oCleaner, EventUserDefined(2002))); AssignCommand(oLooter, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 3.0f, 1.0f)); int iIndex = GetLocalInt(oCleaner, "iIndex"); object oItem = GetFirstItemInInventory(oOwner); while (oItem != OBJECT_INVALID) { if ( GetDropeableFlag(oItem) ) { SetLocalObject(oCleaner, "oToClean_"+IntToString(iIndex), oItem); iIndex++; ActionTakeItem(oItem, oOwner); } else { DestroyObject(oItem); // save resources and noone will notice } oItem = GetNextItemInInventory(oOwner); } int iSlot = INVENTORY_SLOT_RIGHTHAND; oItem = GetItemInSlot(iSlot, oOwner); while (iSlot != -1) { if (oItem != OBJECT_INVALID) { if ( GetDropeableFlag(oItem) ) { ActionTakeItem(oItem, oOwner); SetLocalObject(oCleaner, "oToClean_"+IntToString(iIndex), oItem); iIndex++; } else { if ( (iSlot != INVENTORY_SLOT_CHEST) && (iSlot != INVENTORY_SLOT_RIGHTHAND) && (iSlot != INVENTORY_SLOT_LEFTHAND) ) DestroyObject(oItem); // save resources and noone will noticeINVENTORY_SLOT_RIGHTRING } } iSlot = getNextSlot(iSlot); if (iSlot != -1) oItem = GetItemInSlot(iSlot, oOwner); } SetLocalInt(oCleaner, "iIndex", iIndex); // SetLocalInt(OBJECT_SELF, "bNothingLeftToLoot", TRUE); } void checkAgain() { object oOwner = GetLocalObject(OBJECT_SELF,"oOwner"); if (oOwner == OBJECT_INVALID) return; if (lootIsEmpty(oOwner)) { if (GetFirstItemInInventory() == OBJECT_INVALID) { DestroyObject(OBJECT_SELF, 1.0f); } } } void lootQuicklyOnClose() { // if (GetLocalInt(OBJECT_SELF, "bNothingLeftToLoot")) // { // object oItem = GetFirstItemInInventory(); // if (oItem == OBJECT_INVALID) DestroyObject(OBJECT_SELF); // } AssignCommand(GetLastClosedBy(), ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT)); if (GetFirstItemInInventory() == OBJECT_INVALID) { DelayCommand(10.0f, checkAgain()); } } // Index the loot & check if empty int lootIsEmpty(object oOwner) { // ChangeToStandardFaction(oOwner, STANDARD_FACTION_COMMONER); // int iIndex = GetLocalInt(OBJECT_SELF, "iIndex"); object oItem = GetFirstItemInInventory(oOwner); int bEmpty = TRUE; while (oItem != OBJECT_INVALID) { if (GetDropeableFlag(oItem)) { bEmpty = FALSE; // SetLocalObject( OBJECT_SELF, "oToClean_"+IntToString(iIndex), oItem); // iIndex++; } else { DestroyObject(oItem); } oItem = GetNextItemInInventory(oOwner); } int iSlot = INVENTORY_SLOT_RIGHTHAND; oItem = GetItemInSlot(iSlot, oOwner); while (iSlot != -1) { if (oItem != OBJECT_INVALID) { if (GetDropeableFlag(oItem)) { bEmpty = FALSE; // SetLocalObject(OBJECT_SELF, "oToClean_"+IntToString(iIndex), oItem); // iIndex++; } else { if ( (iSlot != INVENTORY_SLOT_CHEST) && (iSlot != INVENTORY_SLOT_RIGHTHAND) && (iSlot !=INVENTORY_SLOT_LEFTHAND ) ) DestroyObject(oItem); } } iSlot = getNextSlot(iSlot); if (iSlot != -1) oItem = GetItemInSlot(iSlot, oOwner); } // SetLocalInt(OBJECT_SELF, "iIndex", iIndex); return bEmpty; }