func (m *Mob) SetDirection(direction int) {
	m.SetVar("direction", direction)
	m.SetSpriteUpdated()
}
SetDirection Sets the mobs direction.
package world
import (
	"math"
	"math/rand"
	"sync"
	"time"
	"github.com/spkaeros/rscgo/pkg/game/entity"
	"github.com/spkaeros/rscgo/pkg/log"
	"github.com/spkaeros/rscgo/pkg/isaac"
	rscRand "github.com/spkaeros/rscgo/pkg/rand"
	"github.com/spkaeros/rscgo/pkg/tasks"
)
type MobState = int
const (
	StateIdle MobState = 0
	StateChatting = 1 << iota
	StateFighting
	StateBanking
	StateMenu
	StateTrading
	StateDueling
	MSBatching
	StateSleeping
	StateChangingLooks
	StateShopping
	MSItemAction
	StateAction
	StateFightingDuel   = StateDueling | StateFighting
	StateChatChoosing   = StateMenu | StateChatting
	StateItemChoosing   = StateMenu | MSItemAction
	StateObjectChoosing = StateMenu | MSBatching
	StatePanelActive = StateBanking | StateShopping | StateChangingLooks | StateSleeping | StateTrading | StateDueling
	StateBusy      = StatePanelActive | StateChatting | MSItemAction | MSBatching | StateAction
	StateWaitEvent = StateMenu | StateChatting | MSItemAction | MSBatching
)
const (
	SyncInit = 0
	SyncSprite = 1 << iota
	SyncMoved
	SyncRemoved
	SyncAppearance
	SyncNeedsPosition = SyncRemoved | SyncMoved | SyncSprite
)
var mask = ^3
type mobSet []entity.MobileEntity
type MobList struct {
	mobSet
	sync.RWMutex
}
func NewMobList() *MobList {
	return &MobList{mobSet: make(mobSet, 0, 255)}
}
func (l *MobList) Add(m entity.MobileEntity) int {
	l.Lock()
	defer l.Unlock()
	l.mobSet = append(l.mobSet, m)
	return len(l.mobSet)
}
func (l *MobList) Range(action func(entity.MobileEntity) bool) int {
	l.RLock()
	defer l.RUnlock()
	for i, v := range l.mobSet {
		if action(v) {
			return i
		}
	}
	return -1
}
func (l *MobList) Size() int {
	l.RLock()
	defer l.RUnlock()
	return len(l.mobSet)
}
func (l *MobList) Contains(mob entity.MobileEntity) bool {
	l.RLock()
	defer l.RUnlock()
	for _, v := range l.mobSet {
		if v == mob {
			return true
		}
	}
	return false
}
func (l *MobList) Remove(m entity.MobileEntity) bool {
	l.Lock()
	defer l.Unlock()
	for i, v := range l.mobSet {
		if v == m {
			if i >= len(l.mobSet) {
				l.mobSet = l.mobSet[:i]
			} else {
				l.mobSet = append(l.mobSet[:i], l.mobSet[i+1:]...)
			}
			return true
		}
	}
	return false
}
func (l *MobList) RangePlayers(action func(*Player) bool) int {
	return l.Range(func(m entity.MobileEntity) bool {
		if p := AsPlayer(m); p != nil {
			return action(p)
		}
		return false
	})
}
func (l *MobList) RangeNpcs(action func(*NPC) bool) int {
	return l.Range(func(m entity.MobileEntity) bool {
		if n := AsNpc(m); n != nil {
			return action(n)
		}
		return false
	})
}
func (l *MobList) Get(idx int) entity.MobileEntity {
	l.RLock()
	defer l.RUnlock()
	for _, v := range l.mobSet {
		if v.ServerIndex() == idx{
			return v
		}
	}
	return nil
}
type Mob struct {
	SyncMask       int
	skills		   entity.SkillTable
	path		   *Pathway
	Prayers		   [15]bool
	entity.Entity
	*entity.AttributeList
	sync.RWMutex
}
func (m *Mob) ExperienceReward() float64 {
	meleeTotal := (m.Skills().Maximum(entity.StatStrength) + m.Skills().Maximum(entity.StatAttack) + m.Skills().Maximum(entity.StatDefense)) * 2.0
	total := float64(m.Skills().Maximum(entity.StatHits) + meleeTotal)
	return math.Floor(total/7.0) * 2.0 + 20.0
}
func (m *Mob) TargetMob() entity.MobileEntity {
	return m.VarMob("targetMob")
}
func (m *Mob) TargetNpc() *NPC {
	return AsNpc(m.TargetMob())
}
func (m *Mob) TargetPlayer() *Player {
	return AsPlayer(m.TargetMob())
}
func (p *Player) IsPlayer() bool {
	return true
}
func (p *Player) Type() entity.Type {
	return entity.TypePlayer
}
func (p *Player) IsNpc() bool {
	return false
}
func (n *NPC) Type() entity.Type {
	return entity.TypeNpc
}
func (n *NPC) IsPlayer() bool {
	return false
}
func (n *NPC) IsNpc() bool {
	return true
}
func (m *Mob) Skulls() map[uint64]time.Time {
	return nil
}
func (m *Mob) Busy() bool {
	return m.State()&StateBusy != 0
}
func (m *Mob) BusyInput() bool {
	filtered := m.State()&StateWaitEvent
	return filtered&StateMenu != 0 
}
func (m *Mob) IsFighting() bool {
	return m.HasState(StateFighting)
}
func (m *Mob) FightTarget() entity.MobileEntity {
	return m.VarMob("fightTarget")
}
func (m *Mob) SetFightTarget(m2 entity.MobileEntity) {
	m.SetVar("fightTarget", m2)
}
func (m *Mob) FightRound() int {
	return m.VarInt("fightRound", 0)
}
func (m *Mob) SetFightRound(i int) {
	m.SetVar("fightRound", i)
}
func (m *Mob) LastRetreat() time.Time {
	return m.VarTime("lastRetreat")
}
func (m *Mob) LastFight() time.Time {
	return m.VarTime("lastFight")
}
func (m *Mob) UpdateLastRetreat() {
	m.SetVar("lastRetreat", time.Now())
}
func (m *Mob) UpdateLastFight() {
	m.SetVar("lastFight", time.Now())
}
func (m *Mob) Direction() int {
	return m.VarInt("direction", North)
}