Skip to content

Custom models and textures

import { MaterialSize, MaterialTextAlign } from "@sagl/server";

Models of your own, from your client files, and objects drawn with other textures or text: SA-MP's AddSimpleModel, SetObjectMaterial and SetObjectMaterialText.

Custom models

server.models.add(id, { base, dff, txd? })

server.models.add(-1000, { base: 1216, dff: "models/handset.dff", txd: "models/handset.txd" });
server.createObject(-1000, { x: 2069, y: -1766, z: 14 });
player.attachObject(0, -1000, Bone.LeftHand);

The model dff (with its textures, txd), both client files, as model id. Use the id anywhere a model goes: server.createObject, server.createPickup, player.attachObject, server.interactions.add.

id -1000 to -30000, as SA-MP's. One id, one model: it can't be redefined.
base A game object model. It stands in if the model can't load, and its collision is the model's (as SA-MP's).
dff The model: an object's, in one piece (one atomic). Not a vehicle or a ped.
txd Its textures. Left out: its base's.

Each player's game loads them as they join (their client files are there by then) and at once when they're added later.

server.models
add(id, { base, dff, txd? }) Adds one. Throws if the id is taken or a file isn't a client file.
has(id) Whether id is one.
list Every one: { id, base, dff, txd? }.

To make one, export it from a 3D editor as a San Andreas DFF (Blender with DragonFF, 3ds Max with Kam's scripts, ZModeler) and pack its textures in a TXD (Magic.TXD, TXD Workshop). Collision comes from base, so pick a game object close to its shape and size.

Materials

A model is drawn in materials: parts of it, each with its own texture (a payphone's body, its keypad, its sign). An object can have any of its model's materials drawn otherwise. Only that object changes, not its model's others.

Materials are numbered from 0, in the order the model has them (a model editor lists them; most simple objects have a few).

object.setMaterial(index, options)

atm.setMaterial(1, { model: 2942, txd: "kmb_atmx", texture: "kmb_chip1" }); // a game texture
atm.setMaterial(1, { image: "textures/poster.png" });                       // your own picture
atm.setMaterial(0, { color: "#ff3030" });                                   // its own, tinted
atm.setMaterial(1, { model: -1000, texture: "sign" });                      // from a custom model's TXD
Option
model number Where the texture comes from: a game model (its textures are loaded with it), or a custom model's id (then its own TXD).
txd string The game's texture dictionary it's in (SA-MP's txdname). Left out: model's own.
texture string The texture's name in it.
image string Or a PNG or JPG client file as the texture (up to 2048×2048).
color "#RRGGBB[AA]" or 0xRRGGBBAA Tints it: its own texture, or the new one.

object.setMaterialText(index, text, options?)

atm.setMaterialText(1, "{ffcc00}SAGL\nBANK", {
  size: MaterialSize.Size256x128, fontSize: 48, bold: true,
  align: MaterialTextAlign.Center, background: "#202020",
});

Text drawn on a canvas, in place of the material's texture. \n breaks a line; {RRGGBB} colours what follows. The lines are centred top to bottom.

Option Default
size Size256x128 The canvas (MaterialSize, SA-MP's sizes: Size32x32 to Size512x512).
font "Arial" A font by name, as Windows has them ("Arial", "Courier New", "Times New Roman", "Verdana"...). One a player's game doesn't have: SAGL's own.
fontSize 24 Its height in the canvas' pixels.
bold false
color white
background none Behind the text. None: clear, the object showing through.
align Left MaterialTextAlign: Left, Center, Right.

How the canvas lies on the material is the model's: a material made for a square texture squeezes a wide canvas, as in SA-MP.

object.resetMaterial(index?)

Material index as its model has it again; all of them, with none given.

Materials go to players joining later, and stay through the object moving. They go with the object.

For SA-MP scripters

SA-MP SAGL
AddSimpleModel(-1, baseid, newid, "x.dff", "x.txd") server.models.add(newid, { base: baseid, dff: "models/x.dff", txd: "models/x.txd" })
SetObjectMaterial(obj, i, model, txd, tex, 0xAARRGGBB) obj.setMaterial(i, { model, txd, texture: tex, color: 0xRRGGBBAA })
SetObjectMaterialText(obj, text, i, size, font, fsize, bold, fcol, bcol, align) obj.setMaterialText(i, text, { size, font, fontSize: fsize, bold, color, background, align })

Colours are SAGL's (0xRRGGBBAA), not SA-MP's 0xAARRGGBB. A model has no virtual world: every player has every model. Players' skins (AddCharModel) aren't supported yet.

Client scripts

Client scripts have the same: sagl.models.add for models of their own, and setMaterial, setMaterialText and resetMaterial on their objects.