import { Entity , ObjectIdColumn , Column } from 'typeorm' ; import { find , pull , sumBy } from 'lodash' ; import { PlayerOwned } from './PlayerOwned' ; import { Item } from '../Item' ; import { ItemSlot , TeleportItemLocation , IBuffScrollItem , IBuff , GuildResource } from '../../interfaces' ; import { Player } from './Player.entity' ; @ Entity ( ) export class Inventory extends PlayerOwned { @ ObjectIdColumn ( ) public _id : string ; @ Column ( ) private equipment : { [ key in ItemSlot ] ? : Item ; } ; @ Column ( ) private items : Item [ ] ; @ Column ( ) private size : number ; @ Column ( ) private teleportScrolls : { [ key in TeleportItemLocation ] ? : number ; } ; @ Column ( ) private buffScrolls : IBuffScrollItem [ ] ; @ Column ( ) private resources : { astralium : number ; wood : number ; clay : number ; stone : number ; } ; public get $inventoryData ( ) { return { equipment : this . equipment , items : this . items , size : this . size , teleportScrolls : this . teleportScrolls , buffScrolls : this . buffScrolls , resources : this . resources } ; } constructor ( ) { super ( ) ; if ( ! this . equipment ) this . equipment = { } ; if ( ! this . items ) this . items = [ ] ; if ( ! this . teleportScrolls ) this . teleportScrolls = { } ; if ( ! this . buffScrolls ) this . buffScrolls = [ ] ; if ( ! this . resources ) { this . resources = { [ GuildResource . Astralium ] : 0 , [ GuildResource . Wood ] : 0 , [ GuildResource . Clay ] : 0 , [ GuildResource . Stone ] : 0 } ; } } private calcSize ( player ) { return player . $statistics . get ( 'Game/Premium/Upgrade/InventorySize' ) ; } public init ( player ) { this . updateSize ( player ) ; this . items = this . items . map ( item => { const itemRef = new Item ( ) ; itemRef . init ( item ) ; return itemRef ; } ) ; Object . keys ( this . equipment ) . forEach ( itemSlot => { if ( ! this . equipment [ itemSlot ] || ! this . equipment [ itemSlot ] . name ) { this . equipment [ itemSlot ] = null ; return ; } const itemRef = new Item ( ) ; itemRef . init ( this . equipment [ itemSlot ] ) ; this . equipment [ itemSlot ] = itemRef ; } ) ; this . buffScrolls = this . buffScrolls . filter ( x => x . expiresAt > Date . now ( ) ) ; } public updateSize ( player ) { this . size = this . calcSize ( player ) ; } public isNeedingNewbieItems ( ) { return Object . keys ( this . equipment ) . length === 0 ; } public totalItemScore ( ) { return sumBy ( Object . values ( this . equipment ) , item => item ? item . score : 0 ) ; } public itemInEquipmentSlot ( slot ) { return this . equipment [ slot ] ; } public equipItem ( item ) { if ( ! item ) return ; if ( ! item . type ) throw new Error ( `Item ${ JSON . stringify ( item ) } has no type so it cannot be equipped.` ) ; this . equipment = this . equipment || { } ; this . equipment [ item . type ] = item ; } public unequipItem ( item ) { if ( ! item ) return ; const itemExisting = this . itemInEquipmentSlot ( item . type ) ; if ( item !== itemExisting ) throw new Error ( `Could not unequip ${ item . name } since it is not equipped.` ) ; this . equipment [ item . type ] = null ; } public canAddItemsToInventory ( ) { return this . items . length < this . size ; } public addItemToInventory ( item ) { if ( ! this . canAddItemsToInventory ( ) ) return ; this . items = this . items || [ ] ; this . items . push ( item ) ; } public removeItemFromInventory ( ... items ) { pull ( this . items , ... items ) ; } public getItemFromInventory ( itemId ) { return find ( this . items , { id : itemId } ) ; } public itemsFromInventory ( ) { return this . items ; } public unlockedItems ( ) { return this . items . filter ( item => ! item . locked ) ; } public clearInventory ( ) { this . items = [ ] ; } public addTeleportScroll ( scroll ) { this . teleportScrolls [ scroll ] = this . teleportScrolls [ scroll ] || 0 ; this . teleportScrolls [ scroll ] ++ ; } public useTeleportScroll ( player , scroll ) { if ( this . teleportScrolls [ scroll ] <= 0 || player . region === scroll ) return false ; player . $$game . movementHelper . doTeleport ( player , { toLoc : scroll } ) ; player . increaseStatistic ( 'Item/Use/TeleportScroll' , 1 ) ; this . teleportScrolls [ scroll ] -- ; return true ; } public clearBuffScrolls ( ) { this . buffScrolls = [ ] ; } public addBuffScroll ( scroll ) { this . buffScrolls . push ( scroll ) ; } public useBuffScroll ( player , scrollId ) { const scroll = find ( this . buffScrolls , { id : scrollId } ) ; if ( ! scroll || scroll . expiresAt < Date . now ( ) ) return false ; player . addBuff ( { booster : true , name : scroll . name , statistic : 'Character/Ticks' , duration : Math . max ( 720 , ( 720 * player . $statistics . get ( 'Game/Premium/Upgrade/BuffScrollDuration' ) ) ) , stats : scroll . stats } ) ; player . increaseStatistic ( 'Item/Use/BuffScroll' , 1 ) ; pull ( this . buffScrolls , scroll ) ; return true ; } public addResources ( opts = { [ GuildResource . Wood ] : 0 , [ GuildResource . Clay ] : 0 , [ GuildResource . Stone ] : 0 , [ GuildResource . Astralium ] : 0 } ) { if ( opts [ GuildResource . Wood ] ) this . resources [ GuildResource . Wood ] += opts [ GuildResource . Wood ] ; if ( opts [ GuildResource . Clay ] ) this . resources [ GuildResource . Clay ] += opts [ GuildResource . Clay ] ; if ( opts [ GuildResource . Stone ] ) this . resources [ GuildResource . Stone ] += opts [ GuildResource . Stone ] ; if ( opts [ GuildResource . Astralium ] ) this . resources [ GuildResource . Astralium ] += opts [ GuildResource . Astralium ] ; } public hasResource ( res , amount ) { return this . resources [ res ] >= amount ; } public spendResource ( res , amount ) { this . resources [ res ] -= amount ; } }