Furthermore there were two GridInfo variables, and the scheduleMaterialUpdate doesn't work the way we use it.
Here is a working example:
DefineEngineFunction(paintTerrainUnderPlayer, void, (U32 mat), (1), "")
{
// Create a new instance of the TerrainEditor so we can use its functionality.
TerrainEditor *mTerrainEditor = new TerrainEditor();
// Get the connection to the player.
GameConnection* connection = GameConnection::getConnectionToServer();
// Fetch the player.
Player* playerObject = dynamic_cast< Player* >(connection->getControlObject());
// Get the player's position.
Point3F pos = playerObject->getPosition();
// Grab a point above the player.
pos.z + 5;
// Fetch the terrain with a ray-trace. There are probably more efficient ways to get this.
TerrainBlock *terrain;
RayInfo r;
bool hit = gClientContainer.castRay(pos, Point3F(pos.x, pos.y, pos.z - 1000), TerrainObjectType, &r);
if (hit) {
terrain = dynamic_cast<TerrainBlock*>(r.object);
}
// Initialize the GridInfo and GridPoint that our player's position maps to.
GridInfo gi;
GridPoint gp;
// Specify the terrain this GridPoint belongs to.
gp.terrainBlock = terrain;
// Map the player position to a point on the grid.
gp.gridPos = gp.terrainBlock->getGridPos(pos);
// Get the Terrain information at that point on the grid (such as texture, height etc.)
mTerrainEditor->getGridInfo(gp, gi);
// Map the material as dirty.
gi.mMaterialChanged = true;
// Change the material (to a layer which can be between 0 and 31).
gi.mMaterial = mat;
// Update the grid.
mTerrainEditor->setGridInfo(gi, true);
// Repaint the terrain.
terrain->updateGridMaterials(gp.gridPos, gp.gridPos);
}
Tested it on newest Development branch and it works. Notice that the "mat" parameter, is the index of the desired texture layer as they are ordered in the TerrainPainter.
Furthermore this code is designed to run client-side in a single-player scenario. You would have to do some extra tricks to make it work in multiplayer.