LawrenceKnight Posted December 4, 2017 Share Posted December 4, 2017 Bonjour, https://community.multitheftauto.com/index.php?p=resources&s=details&id=6277 Le script fonctionne très bien, mais j'aimerais savoir comment faire en sorte que lorsqu'un zombie est équipé du sabre, qu'on puisse entendre les sons? Car à priori, il n'y a que le joueur qui peu entendre les sons.. Une second question, comment faire en sorte qu'une bat de Baseball (par exemple) puisse one shot un zombie? Merci de votre aide. Link to comment
Wumbaloo Posted December 4, 2017 Share Posted December 4, 2017 (edited) Il faudrait utiliser playSound3D au lieu de playSound Edited December 4, 2017 by Wumbaloo Link to comment
LawrenceKnight Posted December 4, 2017 Author Share Posted December 4, 2017 cest justement un playSound3D ^^ Link to comment
Moderators Citizen Posted December 4, 2017 Moderators Share Posted December 4, 2017 (edited) Wumbaloo qui répond plus vite que son ombre ... Un petit check rapide du code montre bien que c'est un playSound3D qui est utilisé et en plus tu n'as pas dû comprendre la question de LawrenceKnight, il a pas parlé d'un problème de position du son hein ! Alors ce script a visiblement été réalisé par un novice qui n'a pas pensé que son script ne marcherai pas avec d'autres joueurs sur son serveur. Voilà la traduction strict du code (la partie son seulement): * En tant que joueur, si je(1) tire avec une arme et que l'id de cette arme est égal à 8 (Katana), alors je joue pour moi(1) et en 3D un des 3 sons dispo à l'emplacement du bout de l'arme.(1) Parce que c'est un script côté client = le joueur local S'il avait eu une autre personne pour tester, il aurait remarqué que lorsqu'un 2ème joueur "tire" avec le katana, aucun son ait joué pour le 1er joueur. Ma première idée pour le corriger rapidement était d'appeler la fonction jedi avec l'event onClientPedWeaponFire et d'utiliser source au lieu de localPlayer: Quote The source of this event is the ped who fired the weapon. Mais en fait on peut pas parce que: Quote This does not trigger for projectiles based, or melee weapons. oh Bon bah du coup plan B, il faut séparer la partie (A)détection d'un tire au katana de la partie (B)jouer un des 3 sons à l'embout de l'arme du joueur responsable avec (A) => côté serveur (B) => côté client Je te propose donc cet exercice car ça doit être dans tes cordes. Il te faudra la fonction triggerClientEvent pour que depuis le serveur tu puisses déclencher la fonction du son côté client (indice: ne renseigne pas l'option sendTo au début pour que ça le déclenche chez tous le monde. Pour ta 2ème question: Il suffit d'utiliser l'event onClientPedDamage, tester si l'argument weapon vaut 5 (Batte), et si c'est le cas, tu killPed(source, attacker, weapon, bodypart) et ça devrait faire le taff. En revanche un Player est considéré comme un Ped spécifique car contrôlé par un joueur donc ça va 1 shot les joueurs aussi (sauf s'ils sont dans la même team et que le friendly fire est désactivé). Donc en plus du check du weapon qui vaut 5, il faut rajouter un check pour vérifier si la source est un zombie, pour ça il faudra regarder dans la fonction qui spawn un zombie s'il y a un element data spécifique qu'on pourrait utiliser afin d'identifier de façon sûr que ça soit un zombie (genre si y a un setElementData(bidule, "isZombie", true) c'est bingo pour nous, il suffira de faire un if getElementData(source, "isZombie") then et la correction est torchée/terminée ^^) Bon courage en attendant ton retour Cordialement, Citizen Edited December 5, 2017 by Citizen Link to comment
LawrenceKnight Posted December 4, 2017 Author Share Posted December 4, 2017 Etant moi aussi inexpérimenté j'ai quand même essayer mais sans résultat.. Je n'ai pas peur d'avoir honte, alors je vais exposé ce que j'ai essayé de faire (même si je sais que j'ai fais pas mal de cochonneries): côté client: local JediSound = { "a.mp3", "b.mp3", "c.mp3" } function sounds ( ) local muzzleX, muzzleY, muzzleZ = getPedWeaponMuzzlePosition ( localPlayer ) local px, py, pz = getElementPosition ( localPlayer ) local weaponID = getPedWeapon ( localPlayer ) local sound = playSound3D ( JediSound[ math.random( 1,#JediSound ) ], muzzleX, muzzleY, muzzleZ, false ) setSoundMaxDistance ( sound, 40 ) end addEvent( "PlaySound", true ) addEventHandler( "PlaySound", getRootElement(), sounds ) côté server: function jedi () if ( weaponID == 15 and isControlEnabled ( "fire" ) ) then triggerClientEvent ( "PlaySound", getRootElement() ) end end bindKey ( "fire", "down", jedi ) En ce qui concerne ma deuxième question, je pense avoir bien fait, mais cela ne tue pas les zombies. function killp () if weaponID == 5 then if (getElementData (source, "zombie") == true) then killPed(source, attacker, weapon, bodypart) end end end addEvent( "onClientPedDamage", true ) addEventHandler ( "onClientPedDamage", killp ) Link to comment
Moderators Citizen Posted December 5, 2017 Moderators Share Posted December 5, 2017 30 minutes ago, LawrenceKnight said: Je n'ai pas peur d'avoir honte Et t'as bien raison ! Ceux qui devraient avoir honte sont ceux qui disent: "j'ai essayé mais j'ai pas réussi, je montre pas ce que j'ai fait peux-tu le faire à ma place ?". Souvent ils n'y ont passé que 10 minutes max, n'ont pas envie d'apprendre et veulent quand même sortir un serveur ! LOL J'apprécie que tu es testé toi-même de faire les corrections vu le temps que j'ai passé à tout détailler (pourquoi, comment) avec le raisonnement pour bien visualiser. Et tu vas être content, tu es vraiment pas loin !! C'est quasiment tout bon ! addEvent( "PlaySound", true ) -- Ok addEventHandler( "PlaySound", getRootElement(), sounds ) -- Ok Nickel, c'est ce qu'il fallait faire, créer un event qu'on peut trigger du côté serveur (true) et attaché la fonction sounds à cet event. Juste je changerai le nom de l'event pour éviter un conflit avec une autre ressource. Exemple: onLaserSaberSwing (Il faut se lever de bonne heure pour trouver une autre ressource qui utilise ce nom sur ton serveur haha) function jedi ( player ) -- bindKey envoi le joueur qui a appuyé en 1er paramètre, il faut le "receptionner" -- Ici tu avais oublié de ramener la fonction qui récupère l'arme actuelle du joueur: local weaponID = getPedWeapon ( player ) -- On récupère l'arme du joueur qui a "fire" if ( weaponID == 15 and isControlEnabled ( "fire" ) ) then -- Ok pour la cane triggerClientEvent ( "PlaySound", player ) -- Ici on met le joueur en source de l'event à la place car root = tout le monde (on le récupérera côté client pour jouer le son à la bonne position) end end bindKey ( "fire", "down", jedi ) -- Ok local JediSound = { "a.mp3", "b.mp3", "c.mp3" } function sounds ( ) local muzzleX, muzzleY, muzzleZ = getPedWeaponMuzzlePosition ( source ) -- remplacer par source car on veut pas le joueur local mais bien celui qui a tiré -- local px, py, pz = getElementPosition ( localPlayer ) -- Heuuu px, py, pz ne sont pas utilisé, un oubli de l'auteur. A supprimer ! -- local weaponID = getPedWeapon ( source ) -- plus besoin de weaponID ici, on n'en a besoin que du côté serveur maintenant. A supprimer ! local sound = playSound3D ( JediSound[ math.random( 1,#JediSound ) ], muzzleX, muzzleY, muzzleZ, false ) setSoundMaxDistance ( sound, 40 ) end addEvent( "PlaySound", true ) addEventHandler( "PlaySound", getRootElement(), sounds ) Et là on devrait retrouver le même fonctionnement d'origine mais qui marche également si d'autres joueurs donnent des coups avec le sabre laser. Mais le problème des sabres lasers des zombies qui ne font pas de bruits est toujours là (ouai j'ai oublié d'en parler dans mon post précédent, mais de toute façon il fallait faire ça avant). Une fois les corrections fonctionnelles, je ne vois pas d'autre solution que de faire le même triggerClientEvent mais dans la fonction attack de la ressource zombie en mettant le zombie en source de l'event (et c'est tout, ça marchera direct normalement). Pour la 2ème question: Ultra proche du bon résultat ! Juste il te manquait la "réception" des argument que t'envoie l'event onClientPedDamage et il ne faut pas faire de addEvent pour les events fournit par MTA. function killp ( attacker, weapon, bodypart ) -- on doit réceptionner ce que nous envoie l'event pour les utiliser dans la fonction (exception pour 'source') if weapon == 5 then -- Du coup comme je l'ai nommé weapon pour le killPed, je change le nom de la variable à tester if (getElementData (source, "zombie") == true) then -- C'est juste mais comme c'est un boolean et qu'il n'y a qu'un test, on peut raccourcir à: if getElementData(source, "zombie") then killPed(source, attacker, weapon, bodypart) end end end -- addEvent( "onClientPedDamage", true ) -- Event MTA. A supprimer ! addEventHandler ( "onClientPedDamage", getRootElement(), killp ) -- manquait le 2ème argument (= qui peut en être la source) Cordialement, Citizen Link to comment
LawrenceKnight Posted December 5, 2017 Author Share Posted December 5, 2017 Super! Mais j'ai des problèmes pour les deux. En fait lorsque j'applique le corrigé, dans la console ça m'indique: "WARNING: lightsaber\server.lua:7: Bad argument @ 'bindkey' [Expected player at argument 1, got string 'fire']" Et puis concernant les dégâts avec la batte, ça ne tue pas les zombies.. Link to comment
Moderators Citizen Posted December 5, 2017 Moderators Share Posted December 5, 2017 (edited) Arf j'avais zappé que la version server du bindKey doit avoir un argument player obligatoire en 1er (je le pensais optionnel). Fait le bind lorsque le joueur se connecte: addEventHandler("onPlayerJoin", root, function () -- root = raccourci de getRootElement(), et je donne la fonction directement en argument en même temps que je la défini, donc elle ne peut pas porter de nom (on parle de fonction anonyme) bindKey ( source, "fire", "down", jedi ) end) Pour le 2 il faut débuguer, as-tu une erreur affichée via /debugscript 3 ? Si tu outputChatBox weapon, quel valeur s'affiche dans le chat ? La même chose pour getElementData (source, "zombie") (pour afficher un boolean, il faut le passer à la fonction tostring d'abord, ce qui n'est pas nécessaire pour les nombres) ? Edited December 5, 2017 by Citizen Link to comment
LawrenceKnight Posted December 5, 2017 Author Share Posted December 5, 2017 Donc pour le bind j'ai juste à remplacer le "bindKey ( source, "fire", "down", jedi )" du côté server? Si c'est le cas, dans la console je n'ai plus le Bad Argument mais le son ne se joue toujours pas, pourtant je prend la bonne arme.. Pour le /debugscript 3 apparemment rien ne s'affiche.. Et je n'ai pas très bien compris comment faire le reste.. Link to comment
Moderators Citizen Posted December 5, 2017 Moderators Share Posted December 5, 2017 (edited) 6 hours ago, LawrenceKnight said: Si c'est le cas, dans la console je n'ai plus le Bad Argument mais le son ne se joue toujours pas, pourtant je prend la bonne arme.. Ouai en fait il faut se reconnecter et je pense que ça devrait marcher. J'ai oublié le cas où on restart la ressource et que des joueurs restent sur le serveur. Le bindKey n'est rejoué vu qu'il n'est que sur le onPlayerJoin. Pour le 2 je pensais à ça: function killp ( attacker, weapon, bodypart ) outputChatBox(weapon) -- là if weapon == 5 then outputChatBox(tostring(getElementData (source, "zombie"))) -- et là if (getElementData (source, "zombie") == true) then killPed(source, attacker, weapon, bodypart) end end end addEventHandler ( "onClientPedDamage", getRootElement(), killp ) Edited December 5, 2017 by Citizen Modifications plus visibles Link to comment
LawrenceKnight Posted December 5, 2017 Author Share Posted December 5, 2017 Oui, j'ai déjà pensé à me reconnecter justement et ça ne fonctionne pas. D'ailleurs dans la console cette fois-ci ça m'affiche "WARNING: lightsaber\server.lua:3: Bad argument @ 'IsControlEnabled' [Expected player at argument 1, got string 'fire']" Et pour leoutputchatbox ça m'affiche du 7, du 5 ou false. C'est grave docteur? Link to comment
Moderators Citizen Posted December 5, 2017 Moderators Share Posted December 5, 2017 28 minutes ago, LawrenceKnight said: "WARNING: lightsaber\server.lua:3: Bad argument @ 'IsControlEnabled' [Expected player at argument 1, got string 'fire']" La version server de cette fonction doit prendre un joueur en 1er argument, rajoute le. 30 minutes ago, LawrenceKnight said: Et pour leoutputchatbox ça m'affiche du 7, du 5 ou false. C'est grave docteur? Tu vois pas le problème ?? 7 = tu as tapé avec la canne (on s'en fou) 5 = tu a tapé avec la batte mais false = pas un zombie. Si tu as vraiment tapé un zombie, ton test pour savoir si c'est un zombie n'est pas bon. Peux-tu montrer le code que t'as trouvé dans la ressource zombie qui t'a indiqué que ça serait bon ? (Si tu veux que ça oneshot tout le monde (zombies, autres joueurs) retire juste ce test). Link to comment
LawrenceKnight Posted December 5, 2017 Author Share Posted December 5, 2017 function Zomb_Idle (ped) if isElement(ped) then if ( getElementData ( ped, "status" ) == "idle" ) and ( isPedDead ( ped ) == false ) and (getElementData (ped, "zombie") == true) then local action = math.random( 1, 6 ) if action < 4 then -- walk a random direction local rdmangle = math.random( 1, 359 ) setPedRotation( ped, rdmangle ) setPedAnimation ( ped, "PED", "Player_Sneak", -1, true, true, true) setTimer ( Zomb_Idle, 7000, 1, ped ) elseif action == 4 then -- get on the ground setPedAnimation ( ped, "MEDIC", "cpr", -1, false, true, true) setTimer ( Zomb_Idle, 4000, 1, ped ) elseif action == 5 then -- stand still doing nothing setPedAnimation ( ped ) setTimer ( Zomb_Idle, 4000, 1, ped ) end end end end Voici un exemple de code que j'ai trouvé. Link to comment
Moderators Citizen Posted December 5, 2017 Moderators Share Posted December 5, 2017 Effectivement, ton raisonnement est bon du coup mais il y a visiblement un truc qui cloche. Les element data ne sont pas cloisonnés par ressource, c'est à dire l'ajout/modification d'un element data dans la ressource zombie est assurément visible/récupérable dans une autre ressource donc ça aurait dû marcher. La seul possibilité que je vois actuellement c'est que tu regardes le code d'une ressource zombie qui n'est pas celle qui tourne sur ton serveur. Mais je pense que tu n'en as pas 36 milles... Peux-tu trouver et copier le code du spawn zombie ? On va vérifier qu'il le met bien cet element data à true et on va rajouter un outputChatBox pour vérifier ingame que c'est bien cette fonction (et donc cette ressource) qui spawn actuellement les zombies sur ton serveur. Link to comment
Wumbaloo Posted December 6, 2017 Share Posted December 6, 2017 Yep, désolé j'ai répondu trop vite sans inspecter le code de la ressource que tu as posté. Link to comment
LawrenceKnight Posted December 6, 2017 Author Share Posted December 6, 2017 Si si, le script tourne bien sur mon serveur. Je pense que c'est ça function outbreak(startedResource) newZombieLimit = get("" .. getResourceName(startedResource) .. ".Zlimit") if newZombieLimit ~= false then if newZombieLimit > ZombieLimit then newZombieLimit = ZombieLimit end else newZombieLimit = ZombieLimit end WoodTimer = setTimer ( WoodSetup, 2000, 1) -- CHECKS FOR BARRIERS if startedResource == getThisResource() then -- call(getResourceFromName("scoreboard"), "scoreboardAddColumn", "Zombie kills") --ADDS TO SCOREBOARD local allplayers = getElementsByType ( "player" ) for pKey,thep in ipairs(allplayers) do setElementData ( thep, "dangercount", 0 ) end local alivePlayers = getAlivePlayers () for playerKey, playerValue in ipairs(alivePlayers) do setElementData ( playerValue, "alreadyspawned", true ) end if ZombieSpeed == 2 then MainTimer1 = setTimer ( setangle, 200, 0) -- KEEPS ZOMBIES FACING THE RIGHT DIRECTION (fast) else MainTimer1 = setTimer ( setangle, 400, 0) -- KEEPS ZOMBIES FACING THE RIGHT DIRECTION end MainTimer3 = setTimer ( clearFarZombies, 3000, 0) --KEEPS ALL THE ZOMBIES CLOSE TO PLAYERS if ZombieStreaming == 1 then MainTimer2 = setTimer ( SpawnZombie, 2500, 0 ) --Spawns zombies in random locations elseif ZombieStreaming == 2 then MainTimer2 = setTimer ( SpawnpointZombie, 2500, 0 ) --spawns zombies in zombie spawnpoints end end end addEventHandler("onResourceStart", getRootElement(), outbreak) Aucun problème Wumbaloo. if ( weaponID == 15 and isControlEnabled ( player,"fire" ) ) then C'est bien ce qu'il fallait faire pour l'argument? (j'ai rajouter le "player" avant le "fire") Link to comment
Moderators Citizen Posted December 6, 2017 Moderators Share Posted December 6, 2017 (edited) Non je cherchais à voir la fonction qui spawn les zombies et d'après la ligne 28, il y a une fonction qui s'appelle SpawnZombie 3 hours ago, LawrenceKnight said: C'est bien ce qu'il fallait faire pour l'argument? oui Edited December 6, 2017 by Citizen Link to comment
LawrenceKnight Posted December 7, 2017 Author Share Posted December 7, 2017 Donc c'est ça alors: function SpawnZombie () local pacecount = 0 while pacecount < 5 do --4 ZOMBIES AT A TIME TO PREVENT FPS DROP if (table.getn( everyZombie )+pacecount < newZombieLimit ) and (ZombieStreaming == 1) then local xcoord = 0 local ycoord = 0 local xdirection = math.random(1,2) if xdirection == 1 then xcoord = math.random(15,40) else xcoord = math.random(-40,-15) end local ydirection = math.random(1,2) if ydirection == 1 then ycoord = math.random(15,40) else ycoord = math.random(-40,-15) end local liveplayers = getAlivePlayers () if (table.getn( liveplayers ) > 0 ) then local lowestcount = 99999 local lowestguy = nil for PKey,thePlayer in ipairs(liveplayers) do if isElement(thePlayer) then if (getElementData (thePlayer, "dangercount")) and (getElementData(thePlayer, "zombieProof") ~= true) and (getElementData(thePlayer, "alreadyspawned" ) == true) then if (getElementData (thePlayer, "dangercount") < lowestcount) then local safezone = 0 local gx, gy, gz = getElementPosition( thePlayer ) local allradars = getElementsByType("radararea") for theKey,theradar in ipairs(allradars) do if getElementData(theradar, "zombieProof") == true then if isInsideRadarArea ( theradar, gx, gy ) then safezone = 1 end end end if safezone == 0 then lowestguy = thePlayer lowestcount = getElementData (thePlayer, "dangercount") end end end end end pacecount = pacecount+1 if isElement(lowestguy) then triggerClientEvent ( "Spawn_Placement", lowestguy, ycoord, xcoord ) else pacecount = pacecount+1 end else pacecount = pacecount+1 end else pacecount = pacecount+1 end end end Ah donc c'est bien ce que j'ai fais, mais toujours pas.. j'ai l'impression qu'on peut rien faire pour les sons.. Link to comment
Wumbaloo Posted December 11, 2017 Share Posted December 11, 2017 De ce que j'ai compris il y a un problème avec l'élément data "zombie" mais je ne vois pas cet element data dans la fonction "SpawnZombie", il est en client dans la fonction "Spawn_Placement" peut-être? Link to comment
Moderators Citizen Posted December 11, 2017 Moderators Share Posted December 11, 2017 Ok alors j'ai reçu une notif par mail du message de Wumbaloo mais pas pour celui de LawrenceKnight de Jeudi ... Désolé de ne pas t'avoir répondu du coup. Bon du coup on dirait une vieille version du mode DayZ mais j'ai réussi à trouver des traces de codes sur des forums et en gros il y a une fonction qui s'appelle RanSpawn_Z qui crée le zombie via un local zomb = createPed( tonumber( ZombiePedSkins[randomZskin] ), gx, gy, gz ) Puis il fait un setElementData ( zomb, "zombie", true ) Peux-tu confirmer que tu es bien ça de ton côté ? Si c'est bien le cas, notre test devrait être bon et notre outputChatBox(tostring(getElementData (source, "zombie"))) aurait dû nous afficher true plutôt que false dans la chatbox. Peux-tu refaire le test avec ce code modifié (histoire de lever tout doute sur qui affiche quoi ?): function killp ( attacker, weapon, bodypart ) outputChatBox("weapon ? "..weapon) -- là if weapon == 5 then outputChatBox("zombie ? "..tostring(getElementData (source, "zombie"))) -- et là if (getElementData (source, "zombie") == true) then outputChatBox("yes ok instakill it !") killPed(source, attacker, weapon, bodypart) end end end addEventHandler ( "onClientPedDamage", getRootElement(), killp ) ######################################## Pour le son des sabres lasers, je pense que ceci devrait marcher: -- Server function jedi ( player ) local weaponID = getPedWeapon ( player ) if ( weaponID == 15 and isControlEnabled ( "fire" ) ) then triggerClientEvent ( "onLaserSaberSwing ", player ) end end -- Exécuté au démarrage du gamemode pour tous les joueurs déjà co: for _, player in pairs(getElementsByType("player")) do bindKey ( player, "fire", "down", jedi ) end -- Exécuté pour chaque joueur qui se connecteront plus tard: addEventHandler("onPlayerJoin", root, function () bindKey ( source, "fire", "down", jedi ) end) -- Client local JediSound = { "a.mp3", "b.mp3", "c.mp3" } function onLaserSaberSwingFunc ( ) local muzzleX, muzzleY, muzzleZ = getPedWeaponMuzzlePosition ( source ) local sound = playSound3D ( JediSound[ math.random( 1,#JediSound ) ], muzzleX, muzzleY, muzzleZ, false ) setSoundMaxDistance ( sound, 40 ) end addEvent( "onLaserSaberSwing ", true ) addEventHandler( "onLaserSaberSwing ", root, onLaserSaberSwingFunc ) Et pour un zombie, il faudra modifier le code de ton DayZ à l'endroit qui le fait attaquer et faire ceci en testant d'abord qu'il a bien le sabre laser en main: triggerClientEvent ( "onLaserSaberSwing ", laVariableDuZombie ) 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