Je n'avais pas trouvé de sujet de topic là-dessus (enfin si, mais avec un script qui ne marche pas
), donc j'ai cherché un peu ce matin : comment modifier dynamiquement l'éclairage d'une case ?
Dans la théorie, c'est tout simple, nous avons les fonctions SetTileMainLightColor(location lTileLocation, int nMainLight1Color, int nMainLight2Color) et SetTileSourceLightColor(location lTileLocation, int nSourceLight1Color, int nSourceLight2Color) (qui fonctionnent de paire avec les GetTile..etc).
Dans le toolset, on sait qu'on peut modifier l'éclairage d'une case avec un clic droit dessus en mode terrain.
Dans un script, pour modifier dynamiquement l'éclairage de la case d'un PJ, je me suis dit qu'on pouvait faire quelque chose comme ça :
location lPlayer = GetLocation(oPlayer);
SetTileSourceLightColor(lPlayer, 0, 0);
// 0, 0, c'est black et black.
// On peut bien sûr passer par les constantes TILE_MAIN_LIGHT_COLOR_BLACK et autres,
// mais ce sera moins touffu comme ça
C'est insuffisant, il faut en fait forcer les joueurs à recalculer l'éclairage local pour que les modifications soient prises en compte. On rajoute donc :
RecomputeStaticLighting(GetArea(oPlayer));
Et ça ne marche pas non plus.
Le truc, c'est que l'éclairage n'est pas géré par location, mais par position sur la grille en cases de la zone. L'aide dit :
lTileLocation: the vector part of this is the tile grid (x,y) coordinate of the tile.
Donc le GetLocation sur le PJ ne fonctionne pas... Ca paraît bête une fois qu'on le sait, mais vu que c'est un cas particulier, c'est bon à savoir.
En gros, il faut paramétrer sa location à la main, comme ça par exemple :
object oArea = GetArea(oPlayer);
vector vTile = GetPosition(oPlayer);
vTile.x = vTile.x / 10;
vTile.y = vTile.y / 10;
location lTile = Location(oArea, vTile, 0.0);
GetPosition renvoie la position vectorielle en mètres, on divise par dix pour la convertir en cases sur la grille (dans l'idée : une zone de 10 cases de large fait 100m de large). On ne s'intéresse ici qu'aux x et y, le z ne change évidemment rien sur la grille (du moins je crois pas). Et la location est créée à partir de la zone, du vecteur de coordonnées sur la grille et de l'orientation (je mets 0.0, cette donnée n'a aucune importance pour l'éclairage).
Au final, ça nous fait donc quelque chose comme :
object oArea = GetArea(oPlayer);
vector vTile = GetPosition(oPlayer);
vTile.x = vTile.x / 10;
vTile.y = vTile.y / 10;
location lTile = Location(oArea, vTile, 0.0);
SetTileSourceLightColor(lTile, 0, 0);
RecomputeStaticLighting(oArea);
On peut s'amuser à faire des fade to black, des changements de couleurs variés, ou des clignotements, mais il faut penser à mettre le Recompute à chaque changement (ce qui peut faire ramer, donc). A noter que les TILE_MAIN_LIGHT_COLOR_* et TILE_SOURCE_LIGHT_COLOR_* sont des valeurs parmi une liste réduite, et on ne peut pas à ma connaissance donner à une case une valeur différente de celles-ci (avec les composantes RVB par exemple). Il faut jouer avec les deux Main et les deux Source, et avec les cases adjacentes.
Il me reste un problème de taille : l'éclairage inclus dans les tileset. Pour les placeables, no problemo, on a SetPlaceableIllumination (à 'recomputer' aussi à chaque changement). Mais pour ce que l'éditeur désigne comme "Animation" 1, 2, 3, dans les propriétés d'une case ? Les bougies, les torches, par exemple (du tileset, toujours). Je n'ai pas encore trouvé de moyen de les modifier en script, je ne sais pas comment y accéder... Si quelqu'un a une idée...