Aller au contenu

Vengelis_

Administrateur
  • Compteur de contenus

    710
  • Inscription

  • Dernière visite

  • Jours gagnés

    58
  • Crédits

    351 [Faire un don]

Messages posté(e)s par Vengelis_


  1. Tu es sur la bonne voix mais ce n'est pas tout à fait cela. Il faut essayer de "réécrire" l'integer. Théoriquement il suffit de spliter la chaine tout les 3 caractères et lui coller une virgule tout les trois chiffres.

  2. Aide


    J'ai vu ces lignes: 

    Il y a 19 heures, FireNinja - DevSkript a dit :

    Version de Minecraft : 1.8.9
    Version de Skript :  2.1.2

    POURQUOI UNE VERSION SKRIPT 2.1.2 QUAND ON EST EN 1.8.9 !!!!!!!!!!!!

    Bref change de version déjà x)

    • Bruh 1

  3. Ça dépend de ce que tu veux faire. Dans l’utilisation que j’ai décrit c’est long de la pour l’utilisation avec world edit. Exemple d’un générateur de champs de force quand tu veux faire des machines. C’est aussi utilisé pour de la génération de structures automatiques etc... ce que world edit ne supporte pas quand on veut automatiser nos systèmes. World edit c’est aussi pourles petits joueurs xD

     

    Le 08/03/2019 à 23:29, Vengelis_ a dit :

    Dans ce cas, on va générer une sphère de deux types de verres différents, qui ne cassent pas les blocs solides mais uniquement les blocs transparents (feuillages, herbes, etc.) ,qui se génère longitude par longitude, qui retire les liquides qui sont à l’intérieur de la sphère, qui se régénère si un bloc de la sphère et cassé, et avec un rayon allant de 5 à 80 (au-delà de 80 le serveur demande beaucoup de ressources de calculs donc on cap la limite à 80 blocs de rayon).

    Exemple concret


  4. C’est Biosphere2

    Difficulté: Partie 1: Facile | Partie 2: Difficile (voir Hardcore pour les maths)

    Partie 1 - Les bases

    Biosphere2 c'est quoi ?

    Biosphere2 est un add-on de Skript permettant d'utiliser des vecteurs, de générer des formes géométriques, bref plein de trucs mathématiques qui, on va pas se le cacher, hyper facilement. Cet add-on peut être puissant dans un cadre bien précis (génération de structures, etc...)

    Les bases, ça donne quoi ?

    On va commencer doucement avec les vecteurs.

    Un vecteur c'est quoi ? Un vecteur est un segment de droite orienté, formant une entité mathématique sur lequel on peut effectuer des opérations. Plus d'info sur la page wikipédia si vous ne savez pas ce qu'est un vecteur 😉 .

    Pour générer un vecteur basique, y'a pas plus simple, il faut juste regarder la syntaxe:

    set {_line::*} to line with length 10 and density 5
    show happy villager at player offset by {_line::*}

    Cela va vous tracer un segment de particules de villageois contents avec une densité de 5 (donc 5 particules à 1 point du segment) et long de 10 blocs au-dessus de la tête du joueur. L'offset permet de tracer la ligne au-dessus du joueur et ne prend pas les coordonnées relatives. Ce sont des coordonnées absolues.
    Bon c'est bien mignon les particules mais le mieux ça reste avec des blocs  imaginez la construction d'un dôme de verre qui se construit petit à petit ! On va y venir.
    Le vecteur linéaire peut être utile pour tracer des chemins par exemple. Faisons une ligne de cube en or:

    command /genLine:
    	trigger:
    		set {_location} to location of player
    		set {_length} to 20
    		set {_density} to 1
    		set {_player} to player
    		set {_line::*} to line with length {_length} and density {_density}
    		set {_looped} to 0
    		
    		loop {_length} times:
    			set {_x} to ({_location} offset by {_line::%{_looped}%})'s x-location
    			set {_y} to ({_location} offset by {_line::%{_looped}%})'s y-location
    			set {_z} to ({_location} offset by {_line::%{_looped}%})'s z-location
    			set {_locationFinale} to location {_x}, {_y}, {_z} in world of {_player}
    			set block at {_locationFinale} to gold block
    			add 1 to {_looped}
    			wait 1 tick

    Bon, ce n'est pas dur à comprendre. On va commencer à créer des variables temporaires qui vont permettre d'initialiser la ligne. Pour commencer, on définition la location du joueur où la ligne va se générer, ensuite on demande une ligne de 20 blocs de long (en réalité il en retire deux à la fin donc si on définit une longueur de 20, on va avoir une ligne de 18 blocs de long), ensuite la densité (0.1 = très espacée, +20 = très proche) on va prendre une densité de 1, ensuite on définit une variable {_player} pour définir l’exécuteur, on définit la ligne avec les paramètres choisis au-dessus puis pour finir un variable compteur.
    Retenez bien ce paterne car il va nous servir pour plein d'autres formes.

    Une fois l'initialisation faites, on va tracer la ligne:

    - On va d'une part faire une boucle suivant la longueur de la ligne

    - On défini ensuite les positions X, Y et Z une part une sur la position {_location} défini dans l'initialisation

    - On défini une variable finale regroupant X, Y, Z et le monde de l’exécuteur

    - On pose le bloc à la position donnée par la variable finale

    - On fini par ajouter 1 à la variable de bouclage pour passer au bloc suivant et ainsi de suite jusqu'à ce que la longueur totale soit parcourue et posée.

     

    Voilà. Bon le problème c'est que cette syntaxe nous permet de tracer uniquement suivant une suite X+1 de l’exécuteur. On va maintenant faire des vecteurs personnalisés avec les directions que l'on souhaite. C'est presque la même chose mais avec quelques modifications:

    command /genLine2:
    	trigger:
    		set {_location} to location of player
    		set {_density} to 1
    		set {_player} to player
    		set {_line::*} to vector line between vector 0, 0, 0 and vector 8, 0, 8 with density {_density}
    		set {_looped} to 1
    
    		while {_line::%{_looped}%} is set:
    			set {_x} to ({_location} offset by {_line::%{_looped}%})'s x-location
    			set {_y} to ({_location} offset by {_line::%{_looped}%})'s y-location
    			set {_z} to ({_location} offset by {_line::%{_looped}%})'s z-location
    			set {_locationFinale} to location {_x}, {_y}, {_z} in world of {_player}
    			set block at {_locationFinale} to gold block
    			add 1 to {_looped}
    			wait 1 tick

    Bon, on peut constater qu'on a presque la même initialisation et la même procédure de pose: On définit une position, une densité, un exécuteur et un compteur. On retire la longueur car ça serait trop chiant à calculer et on remplace la boucle par le while. Techniquement on pourrait utiliser le while partout pour des choses basiques.

    Dans la définition du vecteur linéaire, on peut constater qu'il y a deux points de vecteurs. Ce sont les coordonnées absolues. Le premier point définit la position de départ du vecteur en position absolue (comme si vous utilisiez les ~ dans un command bloc) et le second point désigne les points d'arrivée. Les deux points vont donc former un vecteur. Je vous laisse faire le test ça fonctionne parfaitement

    Bon, je vous ai donné les bases à savoir. Vous êtes maintenant en mesure d'utiliser n'importe quelle forme que biosphere2 vous propose. En voici une petite liste avec leur syntaxe:

    - Ligne: 

    set {_line::*} to line with length {longueur} and density {densité}
    
    set {_line::*} to vector line between vector X1, Y1, Z1 and vector X2, Y2, Z2

    - Cercle:

    set {_circle::*} to circle with radius {radius} and density {densité}

    - Sommets d'un cube:

    set {_cube::*} to cube with radius {radius}

    - Arrêtes et sommets d'un cube:

    set {_cubeoutline::*} to cube outline with radius {radius} and density {densité}

    - Spirale:

    set {_helix::*} to helix with radius {radius}, height {hauteur}, step {pas de montée} and density {densité}

    - Sphère:

    set {_cubeoutline::*} to sphere with radius {radius} and density {densité}

    Ces formes vous pouvez les utiliser pour les particules aussi et pas que pour poser des blocs. Cet add-on utilise le système de coordonnées absolues donc vous pouvez faire tout et n'importe quoi. 

    Voila c'est fini pour les bases et pour son utilisation basique 😉 On se retrouve pour la seconde partie qui devient un peu plus difficile.

     

     

    Partie 2 - Expert

    Bon, maintenant je vais vous montrer un cas concret d'utilisation. Ce cas m'a demandé quelques mois de travail mine de rien et je pense que vous pouvez être confronté à ce genre de chose si vous utilisez des formes géométriques de manières poussées. Commençons !

    Dans ce cas, on va générer une sphère de deux types de verres différents, qui ne cassent pas les blocs solides mais uniquement les blocs transparents (feuillages, herbes, etc.) ,qui se génère longitude par longitude, qui retire les liquides qui sont à l’intérieur de la sphère, qui se régénère si un bloc de la sphère et cassé, et avec un rayon allant de 5 à 80 (au-delà de 80 le serveur demande beaucoup de ressources de calculs donc on cap la limite à 80 blocs de rayon).

    Ça fait beaucoup de paramètres mais faisables en quelques lignes et avec une bonne dose de mathématiques.

    Commençons par l'initialisation (le plus simple):

    options:
    	densité: 5    #Pour être sur de ne rater aucun bloc
    	ignoreBlocks: air or sapling or plants or water or stationary water or water source or flowing water or falling water or moving water or lava or stationary lava or lava source or flowing lava or falling lava or moving lava or 175:2
    	fluidSponge: water or stationary water or water source or flowing water or falling water or moving water or lava or stationary lava or lava source or flowing lava or falling lava or moving lava

    C'est tout ?! Oui.

    On va maintenant procéder par fonctions. On va faire la plus simple en première.

    Faire la fonction de génération de la sphère:

    function DOME_LOAD(l: location, p: player):
        set {_count} to 0
        while {Dome::Enable} is true:
            set {_number} to 1
    	    loop {Dome::coefCirculation} times:
       	        set {_x} to ({_l} offset by {_cubeoutline::%{_number}%})'s x-location
        	    set {_y} to ({_l} offset by {_cubeoutline::%{_number}%})'s y-location
                set {_z} to ({_l} offset by {_cubeoutline::%{_number}%})'s z-location
                set {_loopedLocation} to location {_x}, {_y}, {_z} in world of {_p}
                set {_loopedBlock} to block at {_loopedLocation}
                if {_loopedBlock} is {@ignoreBlocks} or air:
                    set block at {_loopedLocation} to glass
                add 1 to {_number}
                chance of 3%:
                    wait 1 tick                                                             #Sinon serveur crash
            message "Génération terminée" to {_p}
            add 1 to {_count}
        message "Nombre de génération effectuée: %{_count}%" to {_p}

    Faisons maintenant la partie la plus compliquée, générons le nombre qui va nous permettre de savoir combien de blocs il va devoir vérifier (c'est la variable {Dôme: :coefCirculation} qu'il va falloir définir). Ce nombre peut être en premier temps déduit à l’arrache c'est-à-dire qu'on y met un grand nombre au pif et on regarde si la sphère va jusqu'au bout de son check. Une fois qu'on a un nombre plutôt correct et facile à arrondir, on l'arrondi. Par exemple pour un radius de 10 avec une densité de 5 c'est 22771588.52 checks pour la sphère. Oui c'est énorme et pour le calculer ce n'est pas simple du tout. Par exemple si on veut une sphère de 10 blocs de radius, on va essayer de faire un loop de 10 fois. On définit {Dôme: : coef Circulation} = 10 et on se rend compte que 10 nous pose 3 blocs.

    On se creuse la tête encore plus mais ce n'est pas simple. Je vais vous simplifier l'affaire et vous épargner l'étape ultra difficile mais il va falloir savoir la maîtriser. Pour trouver ce nombre, on doit élever le radius au cube qui forme notre premier facteur (donc {radius}^3) puis on y ajoute un nombre déduit par une régression exponentielle. Voici comment on calcule notre régression exponentielle:

    Tout d'abord on va dresser un tableau:

    Pour un radius de    (x)   :    5   |   10   |   20   |   40   |   80     

    Il nous faut:               (y)   :   50  |   25   | 12.5 |  6.25 | 3.125  

    Ça c'est les valeurs dont j'ai trouvé quand j'ai généré une sphère avec ({radius}^3)*(nombre du tableau). Pour l'instant on a seulement 5 points mais comment trouver les autres ? Par la régression exponentielle. La régression va nous permettre de trouver la courbe entre les points à partir de deux points connus. Faisons entre 5 et 10 (car on ne peut pas faire entre 5 et 80 directement, vous allez comprendre pourquoi):

    On remarque que quand on multiplie x par 2, on divise y par 2 donc notre fonction se présentera sous cette forme là: f(x) = k*exp(a*x). Trouvons k et a. ( exp() = exponentielle )

    On a f(5) = 50 et f(10) = 25

    On commence par trouver a et prendre le x le plus haut donc f(10)

    f(10) = 25 <=> k*exp(10*a) = 25 <=> k*exp(10*a)/k*exp(5*a) =  exp(10*a)/exp(5*a) = 25/50 (on supprime les k car on les retrouve au numérateur et dénominateur) <=> exp(5*a) = 1/2 <=> a = ln (1/2)/5 ( ln = logarithme népérien ). On a trouvé le a pour 5 =< x < 10.

    On cherche ensuite k avec le x le plus bas donc f(5) (c'est plus simple):

    f(5) = 50 <=> k*exp(5*a) = 50 <=> k*(1/2) = 50 <=> k = 100

    Voila on a notre k et notre a, on regroupe le tout et on trouve: k*exp(a*x) = 100 * exp( ( (ln (1/2) /5) * x ). Maintenant on réitère l'opération pour 10 =< x < 20 ; 20 =< x < 40 ; 40 =< x < 80.

    Voici notre fonction: 

    set {_l} to location of player
    		set {Dome::Enable} to false
    		if arg-1 > 4:
    			if arg-1 < 11:
    				set {Dome::Longeur} to ((arg-1^3)*(100*exp(arg-1*(ln(0.5)/5))))
    				set {Dome::Enable} to true
    			else:
    				if arg-1 > 10:
    					if arg-1 < 21:
    						set {Dome::Longeur} to ((arg-1^3)*(50*exp(arg-1*(ln(0.5)/10))))
    						set {Dome::Enable} to true
    					else:
    						if arg-1 > 20:
    							if arg-1 < 41:
    								set {Dome::Longeur} to ((arg-1^3)*(25*exp(arg-1*(ln(0.5)/20))))
    								set {Dome::Enable} to true
    							else:
    								if arg-1 > 40:
    									if arg-1 < 81:
    										set {Dome::Longeur} to ((arg-1^3)*(6.25*exp(arg-1*(ln(0.5)/40))))
    										set {Dome::Enable} to true

    Voilà. Cette partie était la plus difficile (et sans doute la plus difficile à comprendre aussi) mais pour faire ça il m'a fallu des mois pour comprendre comment fonctionnait la régression exponentielle. Je vous ai fait un petit cours donc voilà ^^. Mais faut suivre en maths car ce n'est pas simple.

    On regroupe tout notre code et on en arrive à ça:

    options:
    	ignoreBlocks: air or sapling or plants or water or stationary water or water source or flowing water or falling water or moving water or lava or stationary lava or lava source or flowing lava or falling lava or moving lava or 175:2
    	fluidSponge: water or stationary water or water source or flowing water or falling water or moving water or lava or stationary lava or lava source or flowing lava or falling lava or moving lava
    
    command /genSphere <integer>:
    	trigger:
    
    		set {_l} to location of player
    		set {Dome::Enable} to false
    		if arg-1 > 4:
    			if arg-1 < 11:
    				set {Dome::Longeur} to ((arg-1^3)*(100*exp(arg-1*(ln(0.5)/5))))		# On défini notre variable de longueur avec la régression exponentielle
    				set {Dome::Enable} to true											# On Enable le while
    			else:
    				if arg-1 > 10:
    					if arg-1 < 21:
    						set {Dome::Longeur} to ((arg-1^3)*(50*exp(arg-1*(ln(0.5)/10))))
    						set {Dome::Enable} to true
    					else:
    						if arg-1 > 20:
    							if arg-1 < 41:
    								set {Dome::Longeur} to ((arg-1^3)*(25*exp(arg-1*(ln(0.5)/20))))
    								set {Dome::Enable} to true
    							else:
    								if arg-1 > 40:
    									if arg-1 < 81:
    										set {Dome::Longeur} to ((arg-1^3)*(6.25*exp(arg-1*(ln(0.5)/40))))
    										set {Dome::Enable} to true
    		set {_sphere::*} to sphere with radius arg-1 and density 5		# On génère les points de la sphère dans une variable
    		set {_count} to 0
    		while {Dome::Enable} is true:
    			set {_number} to 1
    			loop {Dome::Longeur} times:
    				set {_x} to ({_l} offset by {_sphere::%{_number}%})'s x-location
    				set {_y} to ({_l} offset by {_sphere::%{_number}%})'s y-location
    				set {_z} to ({_l} offset by {_sphere::%{_number}%})'s z-location
    				set {_loopedLocation} to location {_x}, {_y}, {_z} in world of player
    				set {_loopedBlock} to block at {_loopedLocation}
    				if {_loopedBlock} is {@ignoreBlocks} or air:
    					set block at {_loopedLocation} to stone
    				chance of 3%:										# On oublit pas l'anti crash
    					wait 1 ticks
    				add 1 to {_number}
    			loop blocks in radius arg-1 of {_l}:					# La fonction qui supprime les liquides
    				if loop-block is water or lava:
    					loop blocks in radius 10 of position of loop-value:
    						if loop-block-2 is {@fluidSponge}:
    							set block at loop-value-2 to air
    			message "Génération terminée"
    			add 1 to {_count}
    			wait 5 ticks
    		message "Nombre de génération effectuée: %{_count}%"
    			
    command /ws:																			# Et on fait une commande d'arret de génération.
    	trigger:
    		set {Dome::Enable} to false
    		message "Stop whiling"

    Et voilà, on a un script de génération de sphères qui ne casse pas les blocs solides mais uniquement les blocs transparents (feuillage, herbes, etc...) ,qui se génère longitude par longitude et blocs par blocs, qui retire les liquides qui sont à l’intérieur de la sphère, qui se régénère si un bloc de la sphère est cassé, et avec un rayon allant de 5 à 80.

    Bon amusement avec les géométries 😉

    Vengelis

     

    • J'aime 1
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.