Untitled - MARKUP 14.73 KB
                                
                                    --> Modules delay execute every random ms
local MOD_STEP = {900, 1300}			-- execute step near target every this time
local MOD_TURN = {600, 1100}			-- execute turn to target every this time
local MOD_DANCE = {8, 1100}			-- execute dance every this time
local MOD_PUSH = {3000, 5000, true}		-- execute push items every this time in miliseconds, enabled true/false
local MOD_DRAG = {7000, 10000, true}		-- execute drag item while moving without target, enabled true/false

local STEP_DIAGONAL = true 				-- allow step diagonal near target.
local STEP_DELAY = 500					-- step every x ms to avoid overdash.
local ALLOW_WALK_IDS = {123}			-- enter here id such as parcels, boxes etc we check for it.

-- DON'T EDIT BELOW THIS LINE
local targetTime, markTargetTime, lastTargetID, stepTime, modStepTime, modStepRand, modTurnTime, modTurnRand, modDanceTime, modDanceRand, modDancePosTime, modDancePos, modPushTime, modPushRand, modDragTime, modDragRand, modDragTries, modDragMaxTries = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 13

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		tileIsWalkable(x, y, z, player)
--> Description: 	Check is tile is walkable	
--> Params:			
-->					@x coordinate in the map on the x-axis
-->					@y coordinate in the map on the y-axis
-->					@z coordinate in the map on the z-axis
-->					@player bool (optional default true) read player as not walkable true false 
-->
--> Return: 		boolean true or false
----------------------------------------------------------------------------------------------------------------------------------------------------------
function tileIsWalkable(x, y, z, player)
	local path = 0
	local items = Map.GetItems(x, y, z)
	for i, item in ipairs(items) do
		if (player == nil or player == true) and item.id == 99 then return false end
		if Item.hasAttribute(item.id, ITEM_FLAG_NOT_WALKABLE) then return false end
		if Item.hasAttribute(item.id, ITEM_FLAG_NOT_PATHABLE) then
			if table.find(ALLOW_WALK_IDS, item.id) then
				path = path + 1
				if path >= 2 then return false end
			else
				return false	
			end	
		end	
	end
	return true
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		getAttackedCreature()
--> Description: 	Get creature you already attack	
--> Params:			None
-->
--> Return: 		-1 if no creature else table with creature
----------------------------------------------------------------------------------------------------------------------------------------------------------
function getAttackedCreature()
	local t = Self.TargetID()
	if t <= 0 then return -1 end
	local c = Creature.getCreatures(t)
	if table.count(c) < 2 then return -1 end
	targetTime = os.clock()
	if lastTargetID ~= c.id then
		markTargetTime = os.clock()
		lastTargetID = c.id
	end	
	return c
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		delayedStep(dir)
--> Description: 	Get creature you already attack	
--> Params:			
-->
-->					@dir number direction to step
--> Return: 		boolean true or false
----------------------------------------------------------------------------------------------------------------------------------------------------------
function delayedStep(dir)
	if os.clock() - stepTime > (STEP_DELAY / 1000) then
		Self.Step(dir)
		stepTime = os.clock()
		return true
	end
	return false	
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		getDirToStepNearTarget(c)
--> Description: 	Get possible steps dir near target.
--> Params:			
-->
-->					@c table with creature
--> Return: 		table dirs
----------------------------------------------------------------------------------------------------------------------------------------------------------
function getDirToStepNearTarget(c)
	local s = Self.Position()
	local dir = {-1 ,-1}
	if c.x == (s.x + 1) and c.y == (s.y + 1) then
		dir = {1, 2}
	elseif c.x == (s.x) and c.y == (s.y + 1) then
		dir = {3, 1, 6, 5}
	elseif c.x == (s.x - 1) and c.y == (s.y + 1) then
		dir = {3, 2}
	elseif c.x == (s.x - 1) and c.y == (s.y) then
		dir = {0, 2, 7, 6}
	elseif c.x == (s.x - 1) and c.y == (s.y - 1) then
		dir = {0, 3}	
	elseif c.x == (s.x) and c.y == (s.y - 1) then
		dir = {3, 1, 7, 4}
	elseif c.x == (s.x + 1) and c.y == (s.y - 1) then
		dir = {0, 1}
	elseif c.x == (s.x + 1) and c.y == (s.y) then
		dir = {0, 2, 4, 5}
	end
	return dir	
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		getTurnDirToTarget(c)
--> Description: 	Get possible steps dir near target.
--> Params:			
-->
-->					@c table with creature
--> Return: 		number dir
----------------------------------------------------------------------------------------------------------------------------------------------------------
function getTurnDirToTarget(c)
	local s = Self.Position()
	local dir = -1
	if c.x == (s.x + 1) and c.y == (s.y + 1) then
		dir = 1
	elseif c.x == (s.x) and c.y == (s.y + 1) then
		dir = 2
	elseif c.x == (s.x - 1) and c.y == (s.y + 1) then
		dir = 3
	elseif c.x == (s.x - 1) and c.y == (s.y) then
		dir = 3
	elseif c.x == (s.x - 1) and c.y == (s.y - 1) then
		dir = 0	
	elseif c.x == (s.x) and c.y == (s.y - 1) then
		dir = 0
	elseif c.x == (s.x + 1) and c.y == (s.y - 1) then
		dir = 1
	elseif c.x == (s.x + 1) and c.y == (s.y) then
		dir = 1
	end
	return dir	
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		getPushPositionFromDir
--> Description: 	Get push item direction from current self position
--> Params:			
-->					@len - number distance from your character (default 1)			
-->
--> Return: 		table pos
----------------------------------------------------------------------------------------------------------------------------------------------------------
function getPushPositionFromDir(len)
	local dir = Self.Direction()
	local s = Self.Position()
	local pos = {-1, -1, -1}
	if len == nil then len = 1 end
	if dir == 0 then
		pos = {s.x, s.y - len, s.z}
	elseif dir == 1 then
		pos = {s.x + len, s.y, s.z}
	elseif dir == 2 then
		pos = {s.x, s.y + len, s.z}
	elseif dir == 3 then
		pos = {s.x - len, s.y, s.z}
	end			
	return pos
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		updateSelfPosition()
--> Description: 	Update character position and measure time we dont moving.
--> Params:			None
-->
--> Return: 		void nothing.
----------------------------------------------------------------------------------------------------------------------------------------------------------
function updateSelfPosition()
	local pos = Self.Position()
	if modDancePos[1] ~= pos.x or modDancePos[2] ~= pos.y or modDancePos[3] ~= pos.z then
		modDancePos[1] = pos.x
		modDancePos[2] = pos.x
		modDancePos[3] = pos.x
		modDancePosTime = os.clock()
	end	
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		modStep(c)
--> Description: 	Step near target
--> Params:			
-->
-->					@c table with creature
--> Return: 		none
----------------------------------------------------------------------------------------------------------------------------------------------------------
function modStep(c)
	if Creature.DistanceFromSelf(c) == 1 and not Looter.isLooting() and not Self.isDancing() and not Self.isItemFunPlaying() then
		if os.clock() - modStepTime > (modStepRand / 1000) then
			local turnDir = getTurnDirToTarget(c)
			if turnDir ~= -1 and Self.Direction() == turnDir then
				local dirs = getDirToStepNearTarget(c)
				if dirs[1] ~= -1 then
					local pos1 = Self.getPositionFromDirection(dirs[1])
					local pos2 = Self.getPositionFromDirection(dirs[2])
					local dir = {}
					if tileIsWalkable(pos1.x, pos1.y, pos1.z) then
						table.insert(dir, dirs[1])
					end	
					if tileIsWalkable(pos2.x, pos2.y, pos2.z) then
						table.insert(dir, dirs[2])
					end
					if STEP_DIAGONAL then
						if table.count(dirs) == 4 then
							local pos3 = Self.getPositionFromDirection(dirs[3])
							local pos4 = Self.getPositionFromDirection(dirs[4])
							if tileIsWalkable(pos3.x, pos3.y, pos3.z) then
								table.insert(dir, dirs[3])
							end	
							if tileIsWalkable(pos4.x, pos4.y, pos4.z) then
								table.insert(dir, dirs[4])
							end	
						end
					end		
					if table.count(dir)	> 0 then
						dir = dir[math.random(1, table.count(dir))]
						if delayedStep(dir) then
							modStepTime = os.clock()
							modStepRand = math.random(MOD_STEP[1], MOD_STEP[2])
							if dir > 3 then 
								modStepRand = modStepRand + 1500
							end	
						end	
					end	
				end	
			end	
		end	
	end
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		modTurn(c)
--> Description: 	Turn into target direction
--> Params:			
-->
-->					@c table with creature
--> Return: 		none
----------------------------------------------------------------------------------------------------------------------------------------------------------
function modTurn(c)
	if Creature.DistanceFromSelf(c) == 1 and not Self.isDancing() and not Self.isItemFunPlaying() then
		if os.clock() - modTurnTime > (modTurnRand / 1000) then
			local dir = getTurnDirToTarget(c)
			if dir ~= -1 then
				Self.Turn(dir)
				modTurnTime = os.clock()
				modTurnRand = math.random(MOD_TURN[1], MOD_TURN[2])	
			end	
		end	
	end
end	

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		modDance()
--> Description: 	Dance like a pro.
--> Params:			None
-->
--> Return: 		none
----------------------------------------------------------------------------------------------------------------------------------------------------------
function modDance(c)
	if Creature.DistanceFromSelf(c) == 1 and os.clock() - modDanceTime > (modDanceRand / 700) and os.clock() - modDancePosTime > 0.7 then
		if not Self.isWalking() then
			Self.Dance()
			modDanceTime = os.clock()
			modDanceRand = math.random(MOD_DANCE[1], MOD_DANCE[2])	
		end	
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		modPush(c)
--> Description: 	Push items like a crazy.
--> Params:			@c table with creature
-->
--> Return: 		none
----------------------------------------------------------------------------------------------------------------------------------------------------------
function modPush(c)
	if MOD_PUSH[3] then
		if Creature.DistanceFromSelf(c) == 1 and os.clock() - modPushTime > (modPushRand / 1000) and not Looter.isLooting() and not Self.isDancing() and os.clock() - modDancePosTime > 1.5 and os.clock() - markTargetTime > 1 then
			if not Self.isWalking() then
				Self.ItemFunPlay()
				modPushTime = os.clock()
				modPushRand = math.random(MOD_DANCE[1], MOD_DANCE[2])	
			end		
		end
	end		
end

----------------------------------------------------------------------------------------------------------------------------------------------------------
--> Function:		modDrag()
--> Description: 	Drag items when walking.
--> Params:			None
-->
--> Return: 		none
----------------------------------------------------------------------------------------------------------------------------------------------------------
function modDrag()
	if MOD_DRAG[3] then
		if os.clock() - modDragTime > (modDragRand / 1000) and Self.isWalking() and not Looter.isLooting() and not Self.isDancing() and os.clock() - targetTime > 1 then
			local dir = Self.Direction()
			local pos = Self.Position()
			local map = Map.GetTopMoveItem(pos.x, pos.y, pos.z)
			local addX, addY = 0, 0
			if dir == 0 or dir == 2 then
				if Item.hasAttribute(map.id, ITEM_FLAG_NOT_MOVEABLE) or map.id == 99 then map = Map.GetTopMoveItem(pos.x + 1, pos.y, pos.z) addX = 1 end
				if Item.hasAttribute(map.id, ITEM_FLAG_NOT_MOVEABLE) or map.id == 99 then map = Map.GetTopMoveItem(pos.x -1, pos.y, pos.z) addX = -1 end
			else	
				if Item.hasAttribute(map.id, ITEM_FLAG_NOT_MOVEABLE) or map.id == 99 then map = Map.GetTopMoveItem(pos.x, pos.y + 1, pos.z) addY = 1 end
				if Item.hasAttribute(map.id, ITEM_FLAG_NOT_MOVEABLE) or map.id == 99 then map = Map.GetTopMoveItem(pos.x, pos.y - 1, pos.z) addY = -1 end
			end	
			if not Item.hasAttribute(map.id, ITEM_FLAG_NOT_MOVEABLE) and map.id ~= 99 then
				local dest = getPushPositionFromDir(math.random(1, 2))
				if dest[1] ~= -1 then
					if tileIsWalkable(dest[1] + addX, dest[2] + addY, dest[3], false) then 
						Map.MoveItem(pos.x + addX, pos.y + addY, pos.z, dest[1] + addX, dest[2] + addY, dest[3], map.id, map.count, math.random(150, 250))
					end
					modDragTries = modDragTries + 1
				end	
			else		

			end
			if modDragTries > modDragMaxTries then
				modDragTime = os.clock()
				modDragRand = math.random(MOD_DRAG[1], MOD_DRAG[2])
				modDragMaxTries = math.random(13, 17)
				modDragTries = 0
			end		
		end
	end				
end	


-- module run function in loop 200ms
Module.New("Imitate Player While Caveboting", function()
	if Self.isConnected() then
		updateSelfPosition()
		local t = getAttackedCreature()
		if t ~= -1 then
			modStep(t)
			modTurn(t)
			modDance(t)
			modPush(t)
		else		
			modDrag()
		end	
	end	
end)
                                
                            

Paste Hosted With By Wklejamy.pl