As most of you will know, DIVI supports dynamic DTM's. DTM's can now be modified during runtime. You could even create your own DTM's using DIVI's powerfull DTM AddDTM; function while the script is running!
For this tut, I assume you have (basic) knowledge of DTM 's: knowing what they are, how to make 'm and how to use them.
TDTMPointdef
DTM 's are made of a number of Dynamic Deformable Template Model Point Definitions: TDTMPointdef. These TDTMPointdef records have the following members:
- TDTMPointdef.x
- TDTMPointdef.y
- TDTMPointdef.areasize
- TDTMPointdef.areashape
- TDTMPointdef.tolerance
- TDTMPointdef.color
If you have ever made a DTM, these variables must look familiair, exactly the same can be seen in the DTM-Editor:
There are two kind of TDTMPointdef's: one MainPoint and an arbitrary number of SubPoints. The MainPoint is the DTM's HotSpot, it's the coordinate that is returned by FindDTM. The SubPoints are the DTM's Reference Points grouped together in an array.
So, there can only be one MainPoint but many SubPoints. These indiviual TDTMPointdef are grouped together into the TDTM type.The TDTM consists of:
- TDTM.MainPoint
- TDTM.SubPoints
of type TDTMPointdef.
An example
SCAR Code:
var SubPoints: array[0..2] of TDTMPointDef;
var MainPoint : TDTMPointDef;
var MasterTDTM: TDTM;
var TheDTM:Integer;
procedure AssembleDTM;
begin
MainPoint .x:=625;
MainPoint .y:=34;
MainPoint .areasize:=1
MainPoint .areashape:=0;
MainPoint .color:=6843241;
MainPoint .tolerance:=10;
SubPoints[0].x:=630;
SubPoints[0].y:=31;
SubPoints[0].areasize:=1;
SubPoints[0].areashape:=0;
SubPoints[0].color:=6843241;
SubPoints[0].tolerance:=10;
SubPoints[1].x:=623;
SubPoints[1].y:=30;
SubPoints[1].areasize:=1;
SubPoints[1].areashape:=0;
SubPoints[1].color:=6843241;
SubPoints[1].tolerance:=10;
MasterTDTM.MainPoint := MainPoint;
MasterTDTM.SubPoints := SubPoints;
TheDTM:= AddDTM(MasterTDTM);
end;
We have succesfully made a DTM named TheDTM consisting of one MainPoint and two AnchorPoints. The last lines are most important:
SCAR Code:
MasterTDTM.MainPoint := MainPoint;
MasterTDTM.SubPoints := SubPoints;
TheDTM:= AddDTM(MasterTDTM);
We assign the individual TDTMPointDef's to the MasterTDTM and convert the MasterTDTM to TheDTM using function AddDTM(DTM: TDTM): Integer;
Advantages
The advantages are numereous. Whilst DTM's where pretty static objects in SCAR 2.03, now you can remodel to your hearts content. Some of the more obvious advantages:
- Assign variables to any Member of the TDTMPointDef.
- Assign your own Colors to any Point inside a DTM.
- Create or Modify Point Coordinates.
- Adjust the size, shape and tolerance of any given Point.
- Alter the length of the SubPoint-Array.
You could even write a DTM-maker tool, that scans for common colors and decides upon the best main and subpoints.
Making Dynamic DTM's
Alas, making Dynamic DTM's is still a troublesome process. You first need to make a normal DTM using the DTM-editor, and then you will need to manually fill in each variabe inside your TDTMPointDef's. Too bad SCAR "hangs" with the DTM-Editor open, so you will need a second SCAR open to type in the values into the TDTMPointDef's.
-------------------------------------------------------
Full Working RS-Example
Here is a full working Dynamic DTM example as posted before on the inside DIVI... forum.

Stand below Falador above Rimmington Mine. Fill in the RoadColor. The script will find centrepoint (tol 255 thus any color (!)) at almost any angle and move the mouse to the centre of the bifurcation.
SCAR Code:
program BifurcationFinder;
var CGPT: array[0..2] of TDTMPointDef;
var CGMainPT: TDTMPointDef;
var CG: TDTM;
var CGx, CGy: Integer;
var CGDTM: Integer;
var WhichAngle: Extended;
const RoadColor = 5921377; // ColorPick RoadColor.
const Tolerance = 1;
const AreaSize = 1;
const AreaShape = 0;
procedure SetCGDTM;
begin
CGMainPT.x:=648; // Centre Of Minimap
CGMainPT.y:=83;
CGMainPT.areasize:=1;
CGMainPT.areashape:=0;
CGMainPT.color:=0;
CGMainPT.tolerance:=255; // Any Color
CGPT[0].x:=615;
CGPT[0].y:=59;
CGPT[0].areasize:=AreaSize;
CGPT[0].areashape:=AreaShape;
CGPT[0].color:=RoadColor ;
CGPT[0].tolerance:=Tolerance;
CGPT[1].x:=672;
CGPT[1].y:=75;
CGPT[1].areasize:=AreaSize;
CGPT[1].areashape:=AreaShape;
CGPT[1].color:=RoadColor ;
CGPT[1].tolerance:=Tolerance;
CGPT[2].x:=632;
CGPT[2].y:=105;
CGPT[2].areasize:=AreaSize;
CGPT[2].areashape:=AreaShape;
CGPT[2].color:=RoadColor ;
CGPT[2].tolerance:=Tolerance;
CG.MainPoint := CGMainPT;
CG.SubPoints := CGPT;
end;
begin
SetCGDTM;
CGDTM:=AddDTM(CG);
Repeat
Wait(1000);
if FindDtmRotated(CGDTM, CGx, CGy, MMX1, MMY1, MMX2, MMY2, -PI*2, PI*2, 0.2,
WhichAngle) then
begin
Writeln(IntToStr(CGx)+' '+IntToStr(CGy) + ' at '+FLoatToStr(WhichAngle));
MoveMouse(CGx, CGy);
writeln('DTMRotated Found');
end else writeln('Not Found');
Wait(1000);
until False
end.
Another Example

This DTM is made of three RockColorpixels (= a constant), plus a "any" color MainPoint (color 0 and tol 255)
Provided you know this RockColor, you can callibrate in any direction! I use it in my priv. GoblinTrainer to keep my Players inside the GoblinHouse. Try and see for yourself. Position your Player at the GoblinHouse, Set RoadColor in line 9 and walk a little around the house, you can even walk upwards to the chickenchurn, DIVI checks if our MoveMouse is in Bounds with the MiniMap using the new function rs_OnMinimap. If it discovers the coords are out of bounds, it will move the mouse to the centre of the DTM. It will work from - Pi/2 til Pi/2, a halve circle.
SCAR Code:
program GoblinRock;
var DTMSubPoints: array[0..2] of TDTMPointDef;
var CGMainPoint: TDTMPointDef;
var RockTDTM: TDTM;
var CGx, CGy: Integer;
var RockDTM: Integer;
var WhichAngle: Extended;
const RoadColor = 6843241; // ColorPick RoadColor.
const Tolerance = 1;
const AreaSize = 1;
const AreaShape = 0;
procedure SetRockDTM;
begin
CGMainPoint.x:=625;
CGMainPoint.y:=34;
CGMainPoint.areasize:=1;
CGMainPoint.areashape:=0;
CGMainPoint.color:=0;
CGMainPoint.tolerance:=255; // Any Color
DTMSubPoints[0].x:=630;
DTMSubPoints[0].y:=31;
DTMSubPoints[0].areasize:=AreaSize;
DTMSubPoints[0].areashape:=AreaShape;
DTMSubPoints[0].color:=RoadColor;
DTMSubPoints[0].tolerance:=Tolerance;
DTMSubPoints[1].x:=623;
DTMSubPoints[1].y:=30;
DTMSubPoints[1].areasize:=AreaSize;
DTMSubPoints[1].areashape:=AreaShape;
DTMSubPoints[1].color:=RoadColor;
DTMSubPoints[1].tolerance:=Tolerance;
DTMSubPoints[2].x:=628;
DTMSubPoints[2].y:=37;
DTMSubPoints[2].areasize:=AreaSize;
DTMSubPoints[2].areashape:=AreaShape;
DTMSubPoints[2].color:=RoadColor;
DTMSubPoints[2].tolerance:=Tolerance;
RockTDTM.MainPoint := CGMainPoint;
RockTDTM.SubPoints := DTMSubPoints;
RockDTM := AddDTM(RockTDTM);
end;
begin
SetRockDTM;
Repeat
Wait(1000);
if FindDtmRotated(RockDTM, CGx, CGy, MMX1, MMY1, MMX2, MMY2, - Pi/2, Pi/2, 0.1,
WhichAngle) then
begin
if rs_OnMinimap(CGx + 10, CGy + 50) then
MoveMouse(CGx + 10, CGy + 50)
else
MoveMouse(CGx, CGy)
writeln('DTMRotated Found');
end
else
writeln('not found');
Wait(1000);
until False
end.