-- LUA Script - precede every function and global member with lowercase name of script + '_main' -- Default script - does nothing. local xpos = {} local ypos = {} local zpos = {} local setpos = {} local animationSpeed = {} local animSet = {} local speed = {} local speedSet = {} local started = {} local range = {} local tooClose = {} local timer = {} local timer2 = {} local terrainHeight = {} local goalx = {} local goaly = {} local goalz = {} local waterHeight = {} local fleeing = {} local fleex = {} local fleez = {} local fleeset = {} local fleeRange = {} local detectionRange = {} function flock_init(e) xpos[e] = 0 ypos[e] = 0 zpos[e] = 0 setpos[e] = 0 animationSpeed[e] = 1 animSet[e] = 0 speed[e] = 30 speedSet[e] = 0 started[e] = 0 range[e] = 500 tooClose[e] = 0 timer[e] = 0 timer2[e] = 0 terrainHeight[e] = 0 goalx[e] = 0 goaly[e] = 0 goalz[e] = 0 waterHeight[e] = 1000 fleeing[e] = 0 fleex[e] = 0 fleez[e] = 0 fleeset[e] = 0 fleeRange[e] = 1000 detectionRange[e] =300 end function flock_main(e) --Prompt(speed[e]) terrainHeight[e] = GetTerrainHeight(g_Entity[e]['x'],g_Entity[e]['z']) if setpos[e] == 0 then xpos[e] = g_Entity[e]['x'] zpos[e] = g_Entity[e]['z'] ypos[e] = g_Entity[e]['y'] setpos[e] = 1 end if GetTimer(e) - timer[e] > (10000 + math.random(-2000,2000)) then goalx[e] = xpos[e] + math.random(-range[e],range[e]) goalz[e] = zpos[e] + math.random(-range[e],range[e]) if waterHeight[e] > GetTerrainHeight(goalx[e],goalz[e]) then goaly[e] = math.random(GetTerrainHeight(goalx[e],goalz[e]),waterHeight[e]) elseif GetTerrainHeight(goalx[e],goalz[e]) > waterHeight[e] then goaly[e] = math.random(waterHeight[e],GetTerrainHeight(goalx[e],goalz[e])) end timer[e] = GetTimer(e) end if GoalDistance(e) < 50 then tooClose[e] = 1 else tooClose[e] = 0 end if GetPlayerDistance(e) < detectionRange[e] then fleeing[e] = 1 end if GetPlayerDistance(e) > 1000 then fleeing[e] = 0 end if fleeing[e] == 0 then if g_Entity[e]['y'] - terrainHeight[e] < 20 then MoveUp(e,10) end if g_Entity[e]['y'] > goaly[e] then MoveUp(e,-10) end CollisionOff(e) MoveForward(e,speed[e]) CollisionOn(e) if tooClose[e] == 0 then RotateToPointSlowly(e,goalx[e],goalz[e],0.5) end SetAnimationSpeedModulation(e,1) end if fleeing[e] == 1 then speedSet[e] = 0 if g_Entity[e]['anglex'] > 1 then RotateX(e,-10) end if g_Entity[e]['anglex'] <-1 then RotateX(e,10) end if fleeset[e] == 0 then if g_PlayerPosX < g_Entity[e]['x'] then fleex[e] = g_Entity[e]['x'] + fleeRange[e] else fleex[e] = g_Entity[e]['x'] - fleeRange[e] end if g_PlayerPosZ < g_Entity[e]['z'] then fleez[e] = g_Entity[e]['z'] + fleeRange[e] else fleez[e] = g_Entity[e]['z'] - fleeRange[e] end fleeset[e] = 1 end SetAnimationSpeedModulation(e,3) CollisionOff(e) MoveForward(e,150) CollisionOn(e) if fleeing[e] == 1 and saltfishFleeDistance(e) < 100 then fleeing[e] = 0 fleeset[e] = 0 end end if animSet[e] == 0 then animationSpeed[e] = math.random(1,10) ModulateSpeed(e,(1+1/animationSpeed[e])) animSet[e]=1 end if speedSet[e] == 0 then speed[e] = 30+ math.random(0,5) speedSet[e] = 1 end if g_PlayerHealth < 100 then SetPlayerHealth(100) end end function RotateToPointSlowly(e,x,z,v) if g_Entity[e] ~= nil and x > 0 and z > 0 then if v == nil then v = 1 end local destx = x - g_Entity[e]['x'] local destz = z - g_Entity[e]['z'] local angleneeded = math.atan2(destx,destz) angleneeded = angleneeded * (180.0 / math.pi) if angleneeded < 0 then angleneeded = 360 + angleneeded elseif angleneeded > 360 then angleneeded = angleneeded - 360 end local current_angy = g_Entity[e]['angley'] while current_angy < 0 or current_angy > 360 do if current_angy <= 0 then current_angy = 360 + current_angy elseif current_angy > 360 then current_angy = current_angy - 360 end end local L = angleneeded - v local R = angleneeded + v if L <= 0 then L = 360 + L elseif L > 360 then L = L - 360 end if R <= 0 then R = 360 + R elseif R > 360 then R = R - 360 end --if not already facing the target direction (+/- the rotation speed) if current_angy < L or current_angy > R then --do it in 2 halfs so we can account for 0/360 wrap if current_angy > 180 then if angleneeded > current_angy - 180 and angleneeded < current_angy then current_angy = current_angy - v else current_angy = current_angy + v end else if angleneeded < current_angy + 180 and angleneeded > current_angy then current_angy = current_angy + v else current_angy = current_angy - v end end SetRotation(e,0,current_angy,0) return current_angy end end end function GoalDistance(e) if g_Entity[e] ~= nil and g_Entity[e] ~= 0 then local disx = g_Entity[e]['x'] - goalx[e] local disz = g_Entity[e]['z'] - goalz[e] return math.sqrt(disx^2 + disz^2) end end function saltfishFleeDistance(e) fleeDX = (g_Entity[e]['x'] - fleex[e]) fleeDZ = (g_Entity[e]['z'] - fleez[e]) return math.sqrt(math.abs(fleeDX*fleeDX)+math.abs(fleeDZ*fleeDZ)); end