Bean666 Posted April 8, 2021 Share Posted April 8, 2021 (edited) Hi, this script works fine if you're seeing it on your own perspective, you could see the zombies walking smoothly and fine, but when you see others being chased by their own zombies, the zombies is kinda laggy and kinda slow, is there anyway to sync with other players on what you're seeing as well? this is a clientside script so. yeah that might be the problem but im sure there might be something? the peds are created serverside, but the chase function is on client. Chase function: local function trackMe() local zombies = getElementsByType("ped",resourceRoot,true) for index,zombie in ipairs(zombies) do if math.random(1,60) == 15 and isPedDead(zombie) == false then local sound = playSound3D("sounds/mgroan"..tostring(math.random(1,10))..".ogg",zombie.position) setSoundMaxDistance(sound, 30) end local zombieTarget = zombieData[zombie].target if zombieTarget and isElement(zombieTarget) then local lx,ly,lz = getElementPosition(zombieTarget) local lVector = Vector3(lx,ly,lz) local hVector = Vector3(getPedBonePosition(zombie,6)) local zVector = Vector3(getElementPosition(zombie)) local doesZombieSeePlayer = isLineOfSightClear(hVector,lVector,true,false,false,true,false,true,true,zombie) local distanceToPlayer = getDistanceBetweenPoints2D(zVector.x,zVector.y,lVector.x,lVector.y) if timesExecuted%5 == 0 and zombieData[zombie].target == localPlayer then local newTarget,doesSee,distance = getNewTarget(zombie) if newTarget and doesSee and distance < distanceToPlayer and newTarget ~= zombieData[zombie].target then triggerServerEvent("Zday:setZombieNewTarget",zombie,newTarget) end end if zombieData[zombie].target == localPlayer and doesZombieSeePlayer == false and isPedDead(zombieTarget)==false then local newTarget,doesSee = getNewTarget(zombie,localPlayer) if newTarget and doesSee and newTarget ~= zombieData[zombie].target then triggerServerEvent("Zday:setZombieNewTarget",zombie,newTarget) end end if zombieData[zombie].hunting then if not zombieData[zombie].positions then zombieData[zombie].positions = 0 end if not zombieData[zombie].paths then zombieData[zombie].paths = {} end local dist = false if #zombieData[zombie].paths > 1 then local llx,lly,llz = unpack(zombieData[zombie].paths[#zombieData[zombie].paths-1]) dist = getDistanceBetweenPoints3D(llx,lly,llz,lx,ly,lz) end if dist and dist > 0.7 then table.insert(zombieData[zombie].paths,{lx,ly,lz,getPedControlState(zombieTarget,"jump"),getPedControlState(zombieTarget,"sprint")}) elseif not dist then table.insert(zombieData[zombie].paths,{lx,ly,lz,getPedControlState(zombieTarget,"jump"),getPedControlState(zombieTarget,"sprint")}) end if zombieData[zombie].paths[zombieData[zombie].positions+1] and not zombieData[zombie].eating then local nx,ny,nz,jump,sprint = unpack(zombieData[zombie].paths[zombieData[zombie].positions+1]) local nVector = Vector3(nx,ny,nz) local isClear = isLineOfSightClear(zVector,nVector,true,true,false,true,false,true,true,zombie) local notMoving = false if zombieData[zombie].lastPosition then local dist = getDistanceBetweenPoints3D(zombieData[zombie].lastPosition,zVector) if dist < 0.01 then local action = math.random(1,2) if action == 1 then setPedControlState(zombie,"fire",true) elseif action == 2 then notMoving = true end else setPedControlState(zombie,"fire",false) end end local needToJump = (jump or getPedSimplestTask(zombie) == "TASK_SIMPLE_CLIMB" or arePedLegsBlocked(zombie) or notMoving) if needToJump then if (getPedMoveState(zombie) ~= "jump" or getPedMoveState(zombie) ~= "climb") then setPedControlState(zombie,"forwards",false) end if sprint then setPedControlState(zombie,"sprint",true) end setPedControlState(zombie,"jump",true) else setPedControlState(zombie,"sprint",false) setPedControlState(zombie,"jump",false) end local dist = getDistanceBetweenPoints2D(zVector.x,zVector.y,nVector.x,nVector.y) local pathDistance = getZombieCalculatedPathDistance(zombie) local diff = pathDistance/distanceToPlayer if pathDistance > distanceToPlayer and diff > 1.1 and doesZombieSeePlayer then zombieData[zombie].paths = {} zombieData[zombie].positions = 0 zombieData[zombie].changingPath = true zombieData[zombie].changePathTick = getTickCount() end if zombieData[zombie].changingPath then if (getTickCount() - zombieData[zombie].changePathTick) > 500 then zombieData[zombie].changingPath = nil zombieData[zombie].changePathTick = nil end end local angle = rot(zVector.x,zVector.y,nVector.x,nVector.y) setPedCameraRotation(zombie,-angle) setPedControlState(zombie,"forwards",true) if zombie.inWater then setElementRotation(zombie,0,0,angle) setPedControlState(zombie,"sprint",true) elseif not sprint then setPedControlState(zombie,"sprint",false) end zombieData[zombie].lastPosition = Vector3(getElementPosition(zombie)) if isClear and dist < 1 then zombieData[zombie].positions = zombieData[zombie].positions + 1 end else if isPedDead(zombie) == false and getDistanceBetweenPoints3D(zVector,lVector) < 1 and not playersDoomed[zombieTarget] then murderPlayerByZombie(zombieTarget,zombie) if isPedDead(zombieTarget) then playersDoomed[zombieTarget] = true end elseif getDistanceBetweenPoints3D(zVector,lVector) < 1 and ((isPedDead(zombieTarget) or zombieTarget.health<1) and playersEatable[zombieTarget] and not playerEated[zombieTarget]) then playerEated[zombieTarget] = true zombieData[zombie].eating = true setPedAnimation(zombie,"MEDIC","cpr",-1,false,true,false) setTimer(resetZombieAnimation,10000,1,zombie) end setPedControlState(zombie,"forwards",false) end else if doesZombieSeePlayer and not zombieData[zombie].hunting then zombieData[zombie].hunting = true zombieData[zombie].positions = 0 elseif not zombieData[zombie].hunting then local newTarget = getNewTarget(zombie,localPlayer),doesSee if newTarget and doesSee and not zombieData[zombie].changingTarget then triggerServerEvent("Zday:setZombieNewTarget",zombie,newTarget) zombieData[zombie].changingTarget = true end end if not zombieData[zombie].changingPath then setPedControlState(zombie,"forwards",false) end end else setPedControlState(zombie,"forwards",false) end end timesExecuted=timesExecuted+1 end setTimer(trackMe,100,0) Edited April 8, 2021 by Bean666 Link to comment
Moderators IIYAMA Posted April 8, 2021 Moderators Share Posted April 8, 2021 1 hour ago, Bean666 said: yeah that might be the problem but im sure there might be something? You can reduce the ped sync interval from 400 to 200 (mtaserver.conf): https://wiki.multitheftauto.com/wiki/Server_mtaserver.conf#ped_sync_interval (https://wiki.multitheftauto.com/wiki/SetServerConfigSetting) The server has to be stopped first in case of editing the config file. Link to comment
Bean666 Posted April 8, 2021 Author Share Posted April 8, 2021 (edited) 13 minutes ago, IIYAMA said: You can reduce the ped sync interval from 400 to 200 (mtaserver.conf): https://wiki.multitheftauto.com/wiki/Server_mtaserver.conf#ped_sync_interval (https://wiki.multitheftauto.com/wiki/SetServerConfigSetting) The server has to be stopped first in case of editing the config file. will 100 hurt the server? as when i start the script an info is saying it needs to set ped sync interval to a 100. Edited April 8, 2021 by Bean666 Link to comment
Moderators IIYAMA Posted April 8, 2021 Moderators Share Posted April 8, 2021 17 minutes ago, Bean666 said: will 100 hurt the server? as when i start the script an info is saying it needs to set ped sync interval to a 100. According to wiki the minimum for peds value is 200. If you can set it to 100, it shouldn't be working, that is if wiki is up to date. Will it hurt the server? That depends on the internet connection of the players. Link to comment
Bean666 Posted April 8, 2021 Author Share Posted April 8, 2021 1 minute ago, IIYAMA said: According to wiki the minimum for peds value is 200. If you can set it to 100, it shouldn't be working, that is if wiki is up to date. it says valid 50-4000 so yeah maybe 100 is valid though idk ill try. 1 Link to comment
Moderators IIYAMA Posted April 8, 2021 Moderators Share Posted April 8, 2021 15 minutes ago, Bean666 said: it says valid 50-4000 so yeah maybe 100 is valid though idk ill try. yea give it a try. Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 (edited) tried 100 ped sync interval, works better than before but other's peds still kinda looking stuttery. local function trackMe() local zombies = getElementsByType("ped",resourceRoot,true) for index,zombie in ipairs(zombies) do if math.random(1,60) == 15 and isPedDead(zombie) == false then local sound = playSound3D("sounds/mgroan"..tostring(math.random(1,10))..".ogg",zombie.position) setSoundMaxDistance(sound, 50) end local zombieTarget = zombieData[zombie].target if zombieTarget and isElement(zombieTarget) and isPedDead(zombieTarget) == false then local lx,ly,lz = getElementPosition(zombieTarget) local lVector = Vector3(lx,ly,lz) local hVector = Vector3(getPedBonePosition(zombie,6)) local zVector = Vector3(getElementPosition(zombie)) local doesZombieSeePlayer = isLineOfSightClear(hVector,lVector,true,false,false,true,false,true,true,zombie) local distanceToPlayer = getDistanceBetweenPoints2D(zVector.x,zVector.y,lVector.x,lVector.y) if timesExecuted%5 == 0 and zombieData[zombie].target == localPlayer then local newTarget,doesSee,distance = getNewTarget(zombie) if newTarget and doesSee and distance < distanceToPlayer and newTarget ~= zombieData[zombie].target then triggerServerEvent("Zday:setZombieNewTarget",zombie,newTarget) end end if getDistanceBetweenPoints3D(zVector,lVector) > 100 then triggerServerEvent("Zday:destroyZombie",zombie) end if zombieData[zombie].hunting then if not zombieData[zombie].positions then zombieData[zombie].positions = 0 end if not zombieData[zombie].paths then zombieData[zombie].paths = {} end local dist = false if #zombieData[zombie].paths > 1 then local llx,lly,llz = unpack(zombieData[zombie].paths[#zombieData[zombie].paths-1]) dist = getDistanceBetweenPoints3D(llx,lly,llz,lx,ly,lz) end if dist and dist > 0.7 then table.insert(zombieData[zombie].paths,{lx,ly,lz,getPedControlState(zombieTarget,"jump"),getPedControlState(zombieTarget,"sprint")}) elseif not dist then table.insert(zombieData[zombie].paths,{lx,ly,lz,getPedControlState(zombieTarget,"jump"),getPedControlState(zombieTarget,"sprint")}) end if zombieData[zombie].paths[zombieData[zombie].positions+1] and not zombieData[zombie].eating then local nx,ny,nz,jump,sprint = unpack(zombieData[zombie].paths[zombieData[zombie].positions+1]) local nVector = Vector3(nx,ny,nz) local isClear = isLineOfSightClear(zVector,nVector,true,true,false,true,false,true,true,zombie) local notMoving = false if zombieData[zombie].lastPosition then local dist = getDistanceBetweenPoints3D(zombieData[zombie].lastPosition,zVector) if dist < 0.01 then local action = math.random(1,2) if action == 1 then setPedControlState(zombie,"fire",true) elseif action == 2 then notMoving = true end else setPedControlState(zombie,"fire",false) end end local needToJump = (jump or getPedSimplestTask(zombie) == "TASK_SIMPLE_CLIMB" or arePedLegsBlocked(zombie) or notMoving) if needToJump then if (getPedMoveState(zombie) ~= "jump" or getPedMoveState(zombie) ~= "climb") then setPedControlState(zombie,"forwards",false) end if sprint then setPedControlState(zombie,"sprint",true) end setPedControlState(zombie,"jump",true) else setPedControlState(zombie,"sprint",false) setPedControlState(zombie,"jump",false) end local dist = getDistanceBetweenPoints2D(zVector.x,zVector.y,nVector.x,nVector.y) local pathDistance = getZombieCalculatedPathDistance(zombie) local diff = pathDistance/distanceToPlayer if pathDistance > distanceToPlayer and diff > 1.1 and doesZombieSeePlayer then zombieData[zombie].paths = {} zombieData[zombie].positions = 0 zombieData[zombie].changingPath = true zombieData[zombie].changePathTick = getTickCount() end if zombieData[zombie].changingPath then if (getTickCount() - zombieData[zombie].changePathTick) > 500 then zombieData[zombie].changingPath = nil zombieData[zombie].changePathTick = nil end end local angle = rot(zVector.x,zVector.y,nVector.x,nVector.y) local mutatedZombie = getElementData(zombie, "mutatedZombie") setPedCameraRotation(zombie,-angle) setPedControlState(zombie,"forwards",true) if mutatedZombie == "Runner" then setPedControlState(zombie,"sprint",true) end if zombie.inWater then setElementRotation(zombie,0,0,angle) setPedControlState(zombie,"sprint",true) elseif not sprint then if mutatedZombie == "Runner" then setPedControlState(zombie,"sprint",true) else setPedControlState(zombie,"sprint",false) end end zombieData[zombie].lastPosition = Vector3(getElementPosition(zombie)) if isClear and dist < 1 then zombieData[zombie].positions = zombieData[zombie].positions + 1 end if getDistanceBetweenPoints3D(zVector,lVector) < 4 then if getPedControlState(zombie, "sprint") == true then setPedControlState(zombie, "sprint", false) end end else if getDistanceBetweenPoints3D(zVector,lVector) > 100 then triggerServerEvent("Zday:destroyZombie",zombie) elseif isPedDead(zombie) == false and getDistanceBetweenPoints3D(zVector,lVector) < 2 and not playersDoomed[zombieTarget] then murderPlayerByZombie(zombieTarget,zombie) if isPedDead(zombieTarget) then playersDoomed[zombieTarget] = true end elseif getDistanceBetweenPoints3D(zVector,lVector) < 1 and ((isPedDead(zombieTarget) or zombieTarget.health<1) and playersEatable[zombieTarget] and not playerEated[zombieTarget]) then playerEated[zombieTarget] = true zombieData[zombie].eating = true setPedAnimation(zombie,"MEDIC","cpr",-1,false,true,false) setTimer(resetZombieAnimation,10000,1,zombie) end if getDistanceBetweenPoints3D(zVector,lVector) < 4 then if getPedControlState(zombie, "sprint") == true then setPedControlState(zombie, "sprint", false) end end setPedControlState(zombie,"forwards",false) end else if doesZombieSeePlayer and not zombieData[zombie].hunting then zombieData[zombie].hunting = true zombieData[zombie].positions = 0 elseif not zombieData[zombie].hunting then local newTarget = getNewTarget(zombie,localPlayer),doesSee if newTarget and doesSee and not zombieData[zombie].changingTarget then triggerServerEvent("Zday:setZombieNewTarget",zombie,newTarget) zombieData[zombie].changingTarget = true end end if not zombieData[zombie].changingPath then setPedControlState(zombie,"forwards",false) end end else setPedControlState(zombie,"forwards",false) triggerServerEvent("Zday:delayDestroyZombie", zombie) end end timesExecuted=timesExecuted+1 end setTimer(trackMe,100,0) client follow func. syncer(Server): local function setZombieTarget(zombie,target) if target and isElement(target) then triggerClientEvent(root,"Zday:setZombieTarget",zombie,zombie,target) zombieTargets[zombie] = target if getElementSyncer(zombie) ~= target then setElementSyncer(zombie,target) end end end overall nothings wrong, it's just the sync. Edited April 10, 2021 by Bean666 Link to comment
Moderators IIYAMA Posted April 10, 2021 Moderators Share Posted April 10, 2021 4 hours ago, Bean666 said: tried 100 ped sync interval, works better than before but other's peds still kinda looking stuttery. It looks pretty good. I have seen worse. One of the reasons for the stuttering is because some ped interactions are based on each client individuality. At the moment the peds are resynced by the syncer (position, rotation and velocity are being reset), the interactions that are set by the syncer player does not match up with the non syncer players. Interactions like: Animations Initial running speed Jumping etc. That being said, there is always some variation of stuttering involved when streaming element orientations. How to solve this interaction de-sync problem? You might want to consider doing some of the ped interactions serverside. Or the same way as the streamer works: You set an <animation/interaction> for your ped Send a message to serverside. Serverside sends a message to all other clients (excluding yourself). And those clients set the <animation/interaction>. 1 Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 11 minutes ago, IIYAMA said: It looks pretty good. I have seen worse. One of the reasons for the stuttering is because some ped interactions are based on each client individuality. At the moment the peds are resynced by the syncer (position, rotation and velocity are being reset), the interactions that are set by the syncer player does not match up with the non syncer players. Interactions like: Animations Initial running speed Jumping etc. That being said, there is always some variation of stuttering involved when streaming element orientations. How to solve this interaction de-sync problem? You might want to consider doing some of the ped interactions serverside. Or the same way as the streamer works: You set an <animation/interaction> for your ped Send a message to serverside. Serverside sends a message to all other clients (excluding yourself). And those clients set the <animation/interaction>. i might do the same way as the streamer works, but first thing, wdym by animations/interactions? if u mean by walking anims i can't set it since it does not update, peds wont rotate and just keep going the same direction, even tho updatePosition bool is set to true, thats why i only have the state "forward" set to true instead. Link to comment
Moderators IIYAMA Posted April 10, 2021 Moderators Share Posted April 10, 2021 32 minutes ago, Bean666 said: but first thing, wdym by animations/interactions? Every function that makes the ped do anything, that also includes the "forward" state. 33 minutes ago, Bean666 said: if u mean by walking anims i can't set it since it does not update (You are able to do that. Take a closer look at the zombie resource. That is if you want that.) Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 (edited) 4 minutes ago, IIYAMA said: Every function that makes the ped do anything, that also includes the "forward" state. (You are able to do that. Take a closer look at the zombie resource. That is if you want that.) Animations is an option for me, i'll take a look on that after i fix the sync. and the zombie script i'm using isn't slothmans thats why the walking anims kinda aren't suited on it, but i'll try. anyway, about: Send a message to server-side. Serverside sends a message to all other clients (excluding yourself). By this how do I do this? The send message kinda thingy. is it like a trigger Client/Server Event or some sort? Can i have a short example, I'm kind of new to sync stuff. I might have an idea once I see how it's done. Edited April 10, 2021 by Bean666 Link to comment
Moderators IIYAMA Posted April 10, 2021 Moderators Share Posted April 10, 2021 19 minutes ago, Bean666 said: is it like a trigger Client/Server Event or some sort? Yes 48 minutes ago, Bean666 said: Can i have a short example, I'm kind of new to sync stuff. I might have an idea once I see how it's done. A small one, you have to fill in the blanks: --[[...]] Syncer (clientside): triggerServerEvent(--[[...]]) Server: addEvent(--[[...]]) function functionName (ped, action, status) -- get all players except for the one that triggered the the event -- local players = getElementsByType("player") for i=1, #players do if players[i] == client then table.remove(players, i) break end end -- -- triggerClientEvent(players, --[[...]]) end addEventHandler(--[[...]]) Other players (clientside): addEvent(--[[...]]) function functionName (ped, action, status) end addEventHandler(--[[...]]) Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 (edited) 9 minutes ago, IIYAMA said: Yes A small one, you have to fill in the blanks: --[[...]] Syncer (clientside): triggerServerEvent(--[[...]]) let's say i put this on the trackMe function, which initiates every 100 ms, would that be fine? or would I have to create it's own timer that's not 100 ms since I feel like that would eat bandwidth or something. What do you suggest? Edited April 10, 2021 by Bean666 Link to comment
Moderators IIYAMA Posted April 10, 2021 Moderators Share Posted April 10, 2021 8 minutes ago, Bean666 said: which initiates every 100 ms, would that be fine? or would I have to create it's own timer that's not 100 ms since I feel like that would eat bandwidth or something. What do you suggest? That data rate is a bit too high, especially if you are sending the data separately, that is a multiplier after all. All data merged in to 1 packet/message: triggerServerEvent/triggerClientEvent Do not send data double. If you set the ped to sprinting, do not tell the other players that over and over. Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 2 minutes ago, IIYAMA said: That data rate is a bit too high, especially if you are sending the data separately, that is a multiplier after all. All data merged in to 1 packet/message: triggerServerEvent/triggerClientEvent Do not send data double. If you set the ped to sprinting, do not tell the other players that over and over. I can see that as well, so anyway to do this without having to put it on the 100 ms function? Link to comment
Moderators IIYAMA Posted April 10, 2021 Moderators Share Posted April 10, 2021 18 minutes ago, Bean666 said: I can see that as well, so anyway to do this without having to put it on the 100 ms function? The 100ms function is not the issue. The issue is the synchronization with the server. Which means that the syncer has to keep track of what the ped is actually doing. And only send a message to the server and other players when the ped is doing something else. Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 (edited) 3 minutes ago, IIYAMA said: The 100ms function is not the issue. The issue is the synchronization with the server. Which means that the syncer has to keep track of what the ped is actually doing. And only send a message to the server and other players when the ped is doing something else. so will it be okay if i only send the message while the ped is following? so it would look smoother than it was? forget the attacking, etc etc. Edited April 10, 2021 by Bean666 Link to comment
Moderators IIYAMA Posted April 10, 2021 Moderators Share Posted April 10, 2021 Just now, Bean666 said: so it would look smoother than it was? More consistent and at the right timing. Not sure about 'smoother'. 1 Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 (edited) 37 minutes ago, IIYAMA said: More consistent and at the right timing. Not sure about 'smoother'. wdyt about this? tried it on myself, without the sync yet, setelementposition with bool false doesnt look weird. curious what itll look like to other players. Send zombie element to server: triggerServerEvent("zombieSyncServer", resourceRoot, zombie) Server, get position of zombie: addEvent("zombieSyncServer", true) function syncSendToClient (ped, x, y, z) -- get all players except for the one that triggered the the event -- local players = getElementsByType("player") for i=1, #players do if players[i] == client then table.remove(players, i) break end end -- -- local Zx, Zy, Zz = getElementPosition(ped) triggerClientEvent(players, "zombieSyncClient", resourceRoot, ped, Zx, Zy, Zz) end addEventHandler("zombieSyncServer", root, syncSendToClient) back to client: addEvent("zombieSyncClient", true) function syncReceiveFromServer (ped, x, y, z) setElementPosition ( ped, x, y, z, false ) end addEventHandler("zombieSyncClient", root, syncReceiveFromServer) I don't know what im doing for now but that's what i came up first with. Edited April 10, 2021 by Bean666 Link to comment
Moderators IIYAMA Posted April 10, 2021 Moderators Share Posted April 10, 2021 28 minutes ago, Bean666 said: Server, get position of zombie: Position synchronization is already handled by the server. Better to try something else. Link to comment
Bean666 Posted April 10, 2021 Author Share Posted April 10, 2021 3 hours ago, IIYAMA said: Position synchronization is already handled by the server. Better to try something else. noticed that. tested already with someone , hell looks terrible hahaha, any ideas u can suggest? or what functions to use or what do i need to get and set. Link to comment
Moderators IIYAMA Posted April 11, 2021 Moderators Share Posted April 11, 2021 11 hours ago, Bean666 said: noticed that. tested already with someone , hell looks terrible hahaha, any ideas u can suggest? or what functions to use or what do i need to get and set. For example jumping. 1 Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now