Skip to content

Instantly share code, notes, and snippets.

@yunruse
Last active June 21, 2016 09:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yunruse/7d0973a36a1a5e9d9ce90ff207326842 to your computer and use it in GitHub Desktop.
Save yunruse/7d0973a36a1a5e9d9ce90ff207326842 to your computer and use it in GitHub Desktop.
Better AutoLoot
// AutoLoot main file
function AL_CanLegallyTake( container : W3Container ) : bool
{
if( container.disableStealing || container.HasQuestItem() ||
(W3Herb)container || (W3ActorRemains)container )
return true;
else
return false;
}
// This function tries to loot as many items as possible (if the filters allow it) and
// returns a boolean value whether the container still has items or not
function AL_LootContainer( container : W3Container ) : bool
{
var ContainerInventory : CInventoryComponent;
var StillHasItems : bool;
var ContainerAllItems : array<SItemUniqueId>;
var ContainerAmount : int;
var i : int;
var NotificationText : string;
var NotificationShouldDisplay : bool;
var TreasureHuntContainer : W3treasureHuntContainer;
// Disable AutoLoot for quest containers
if(container.HasQuestItem())
return true;
// we begin with the assumption we will not display a notification
NotificationShouldDisplay = false;
// we initialize the notification text
NotificationText = "<u>Looted:</u>";
// we get the container's inventory in an array
ContainerInventory = container.GetInventory();
// we check if the container isn't already empty
if (ContainerInventory.GetAllItemsQuantity() > 0)
StillHasItems = true;
else
return false;
// first we fill an array with all the items
ContainerInventory.GetAllItems( ContainerAllItems );
// we cleanse our list from technical items, that aren't supposed to be seen by the player.
for( i = ContainerAllItems.Size()-1; i >= 0; i -= 1)
if( ContainerInventory.ItemHasTag(ContainerAllItems[i], theGame.params.TAG_DONT_SHOW ) && !ContainerInventory.ItemHasTag(ContainerAllItems[i], 'Lootable' ) )
ContainerAllItems.Erase(i);
// we get the number of items in the container, in order to parse them
ContainerAmount = ContainerAllItems.Size();
GetWitcherPlayer().StartInvUpdateTransaction();
// we go through each item and try to loot them if they match the filters
for( i = 0; i < ContainerAmount; i+=1 )
{
// Crash fix: disable autoloot on oils and potions that are refillable!
if( ContainerInventory.ItemHasTag(ContainerAllItems[i], 'QuickSlot') )
continue;
//Let's set up our filters
if ( AL_ItemFilter( container, ContainerAllItems[i], ContainerAmount ) )
{
// Add the item's notification text
NotificationText += "<br/>" + AL_GetNotificationItem( container, ContainerAllItems[i] );
AL_LootItem( container, ContainerAllItems[i] ); //Loot the item
// We remember to display a notification because we looted at least one item
NotificationShouldDisplay = true;
}
}
GetWitcherPlayer().FinishInvUpdateTransaction();
// Cleanup after looting
ContainerInventory.GetAllItems( ContainerAllItems );
for( i = ContainerAllItems.Size() - 1; i >= 0; i -= 1 )
if( (ContainerInventory.ItemHasTag(ContainerAllItems[i],theGame.params.TAG_DONT_SHOW) ||
ContainerInventory.ItemHasTag(ContainerAllItems[i],'NoDrop') ) &&
!ContainerInventory.ItemHasTag(ContainerAllItems[i], 'Lootable' ) )
ContainerAllItems.Erase(i);
// If we looted anything we display notification
if( NotificationShouldDisplay && AL_NotificationTime( ContainerAmount ) > 0.0 )
theGame.GetGuiManager().ShowNotification( NotificationText, AL_NotificationTime( ContainerAmount ) );
// we check if the containers still has items that the user may need
if (ContainerInventory.GetAllItemsQuantity() > 0)
StillHasItems = true;
else
StillHasItems = false;
// if we looted anything we play the sound
if( AL_LootSoundEnabled() && NotificationShouldDisplay == true )
theSound.SoundEvent("gui_loot_popup_close");
if(NotificationShouldDisplay || !StillHasItems)
container.AutoLootCleanup();
// fix for treasure containers
if( (W3treasureHuntContainer)container )
{
TreasureHuntContainer = (W3treasureHuntContainer)container;
TreasureHuntContainer.ProcessOnLootedEvents();
}
return StillHasItems;
}
// Loots items, sound-less
function AL_LootItem( Container : W3Container, Item : SItemUniqueId ) : void
{
var ItemQuantity : int;
ItemQuantity = Container.GetInventory().GetItemQuantity( Item );
if( Container.GetInventory().ItemHasTag(Item, 'Lootable' ) || !Container.GetInventory().ItemHasTag(Item, 'NoDrop') && !Container.GetInventory().ItemHasTag(Item, theGame.params.TAG_DONT_SHOW))
{
Container.GetInventory().NotifyItemLooted( Item );
Container.GetInventory().GiveItemTo( GetWitcherPlayer().inv, Item, ItemQuantity, true, false, true );
}
if( Container.GetInventory().ItemHasTag(Item, 'GwintCard'))
{
GetWitcherPlayer().AddGwentCard( Container.GetInventory().GetItemName(Item), ItemQuantity);
}
Container.InformClueStash();
}
// This function gets the language-correct name of the item with count and optional colouring
function AL_GetNotificationItem( container : W3Container, Item : SItemUniqueId ) : string
{
var ItemName : string;
// get localised item name
ItemName = GetLocStringByKeyExt( container.GetInventory().GetItemLocalizedNameByUniqueID( Item ) );
if ( ItemName == "" )
ItemName = " ";
if( AL_EnableNotificationColor() )
ItemName = "<font color='" + AL_NotificationColor( container.GetInventory().GetItemQuality( Item ) )
+ "'>" + ItemName + "</font>";
if( AL_EnableNotificationQuantity() && container.GetInventory().GetItemQuantity( Item ) > 1 )
ItemName += " x" + container.GetInventory().GetItemQuantity( Item );
return ItemName;
}
/* All settings are listed below.
* Make sure to delete AutoLootFilters.ws if installing BetterAutoLoot,
* and overwrite both this and AutoLootBase.ws!
*/
function AL_ItemFilter( container : W3Container, item : SItemUniqueId, ContainerAmount : int) : bool
{
var isLegal, isHerb, isArmor, isWeapon, isFood : bool;
var Price, Quality, Quantity : int;
var PricePerWeight, Weight : float;
isLegal = AL_CanLegallyTake( container );
Weight = container.GetInventory().GetItemEncumbrance(item);
Price = container.GetInventory().GetItemPrice(item);
Quality = container.GetInventory().GetItemQuality(item);
Quantity = container.GetInventory().GetItemQuantity(item);
isHerb = (W3Herb)container;
isArmor = container.GetInventory().IsItemAnyArmor(item);
isWeapon = container.GetInventory().IsItemWeapon(item);
isFood = container.GetInventory().IsItemFood(item);
if ( Weight > 0 )
PricePerWeight = Price / Weight;
else
PricePerWeight = 100000;
if (
///////////////////////////////////////////
///////// Customize filters here! /////////
///////////////////////////////////////////
/* You can combine different conditions here!
* Filters are:
* isLegal -> True if item is okay to take without stealing.
* isArmor, isWeapon, isFood -> Item types
* isHerb -> True if the container is a herb
*
* You can also make your own filters using the item's properties:
* Price, Weight -> For one item.
* Quantity -> The overall amount of items
* Quality -> The item's quality.
* 1 is common, 2 a Masterpiece, 3 a Magic Item, 4 a Relic, and 5 Witcher Gear.
* ContainerAmount -> Amount of different items in the container.
*
* You can compare the values with < > or ==
* like (Price > 100), (Weight < 3) or (Quantity == 2)
* If you feel like it you can even use some maths,
* like (Quantity * Weight < 1). (Use PricePerWeight to avoid dividing by zero.)
*
* You can program conditions with the symbols && (AND), || (OR), ! (NOT) and brackets.
* For example, `!(isArmor || isWeapon)` is true if the item is neither armor or weapon.
*
*
* Uncomment a few presets below if you want.
*/
isLegal
//
//
)
return true;
else
return false;
}
function AL_NotificationTime( amount : int ) : float
{
// The length of time in milliseconds the notification should last.
// You can involve the amount of unique items – for example, half a second
// per item listed would be `return amount * 500.0;`.
if( amount > 4 )
return 3000.0;
else
return ( amount + 1 ) * 500.0;
}
function AL_EnableNotificationColor() : bool
{
return true;
}
function AL_NotificationColor( quality: int ) : string
{
// The colour for the item.
switch ( quality ) {
default:
return "#000000"; // Common item
case 2:
return "#0000FF"; // Master items
case 3:
return "#656520"; // Magic items
case 4:
return "#844211"; // Relic items
case 5:
return "#006600"; // Witcher set items
}
}
function AL_EnableNotificationQuantity() : bool
{
return true;
}
function AL_EnableOnKillLoot() : bool
{
return true;
}
function AL_EnableRadiusLoot() : bool
{
return true;
}
function AL_RadiusLootMaxDistance() : float
{
return 10.0;
}
function AL_RadiusLootMaxContainersAtOnce() : int
{
return 10;
}
function AL_LootSoundEnabled() : bool
{
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment