Code: Select all
{###############################################################
# Author: Gauhar #
# Script: Treasure Hunter (lite).sc #
# Stealth Client: v6.+ (http://stealth.od.ua/forum/) #
# Shard: #
# Server: RunUO #
# UO Client: v7.0.23.1 #
# ----------------------------------------------------------- #
# ОПИСАНИЕ: #
# Показывает на карте Stealth'а координаты и напрвление для #
# последней открытой карты сокровищ. Точность +/- 1 тайл. #
###############################################################}
PROGRAM TreasureHunter;
CONST
{ РАСТОЯНИЕ ДО КЛАДА ПРИ КОТОРОМ ВКЛЮЧИТЬ ПОДСКАЗКИ КУДА ИДТИ: }
distanceForTips = 10;
VAR
idMap: Cardinal;
xMap, yMap: Integer;
xTreasure, yTreasure: Integer;
idText, idLine: Cardinal;
xSelf, ySelf: Integer;
Procedure Navigator(X, Y: Integer);
Var
XS, YS, D: Integer;
AC, BC: Integer;
AB, cosBAC: Double;
Begin
XS := GetX(Self);
YS := GetY(Self);
D := Dist(XS, YS, X, Y);
if D = 0 then
begin
ClientPrint('Вы на месте!');
EXIT;
end;
AC := XS - X;
BC := YS - Y;
AB := sqrt(AC*AC + BC*BC);
cosBAC := abs(AC) / AB;
if cosBAC > 0.92388 then //0.0° .. 22.5°
begin
if ((AC >= 0) and (BC < 0)) or ((AC > 0) and (BC >= 0)) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Запад.')
else
if ((AC < 0) and (BC <= 0)) or ((AC <= 0) and (BC > 0)) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Восток.');
end
else
if cosBAC > 0.38268 then //22.5° .. 67.5°
begin
if (AC >= 0) and (BC < 0) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Юго-Запад.')
else
if (AC < 0) and (BC <= 0) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Юго-Восток.')
else
if (AC <= 0) and (BC > 0) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Северо-Восток')
else
if (AC > 0) and (BC >= 0) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Северо-Запад.');
end
else //67.5° .. 90.0°
begin
if ((AC >= 0) and (BC < 0)) or ((AC < 0) and (BC <= 0)) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Юг.')
else
if ((AC <= 0) and (BC > 0)) or ((AC > 0) and (BC >= 0)) then
ClientPrint('Растояние ' + IntTostr(D) + ' на Север.');
end;
End;
Procedure DrawLineToTreasure(X, Y: Integer);
Var
Figure: TMapFigure;
Begin
if idText <> $FFFFFFFF then RemoveFigure(idText);
Figure.kind := fkText;
Figure.coord := fcWorld;
Figure.x1 := X;
Figure.y1 := Y;
Figure.x2 := 0;
Figure.y2 := 0;
Figure.brushStyle := bsSolid; //фон: bsSolid, bsClear
Figure.brushColor := $000000; //цвет фона
Figure.color := $00FF00; //цвет текста
Figure.text := '* ' + IntToStr(X) + ' ' + IntToStr(Y);
idText := AddFigure(Figure);
if idLine <> $FFFFFFFF then RemoveFigure(idLine);
Figure.kind := fkDirection;
Figure.coord := fcWorld;
Figure.x1 := X;
Figure.y1 := Y;
Figure.x2 := 0;
Figure.y2 := 0;
Figure.brushStyle := bsClear;
Figure.brushColor := $000000;
Figure.color := $FFFF00; //цвет линии
Figure.text := '';
idLine := AddFigure(Figure);
End;
Procedure eventIncomingGump(Serial, GumpID, X, Y: Cardinal);
Var
GumpInfo: TGumpInfo;
Begin
//Remove the Treasure Chest.
GetGumpInfo(GetGumpsCount - 1, GumpInfo);
if Length(GumpInfo.XmfHTMLGumpColor) > 0 then
if GumpInfo.XmfHTMLGumpColor[0].Cliloc_id = 1048125 then
NumGumpButton(GetGumpsCount - 1, 1);
End;
Procedure eventMapMessage(ID: Cardinal; centerX, centerY: Integer);
Var
tooltipMap: String;
Begin
tooltipMap := LowerCase(GetTooltip(ID));
if Pos('treasure map', tooltipMap) > 0 then
begin
if Pos('completed by', tooltipMap) = 0 then
begin
idMap := ID
xMap := centerX;
yMap := centerY;
end
else
begin
idMap := 0;
end;
end;
End;
Procedure eventMapPin(ID: Cardinal; Action: Byte; PinID: Byte; PinX, PinY: Word);
Var
xDif, yDif: Integer;
wMap, hMap: Integer;
scaleMap: Byte;
Begin
// Пояснение по ивенту EvMapPin.
//EvMapPin срабатывает сразу после EvMapMessage, если на карте есть метки.
//Ивент срабатывает столько раз сколько меток есть на карте.
//Action = 1 - Добавяет на карту метку. (другие Action не интересны)
//PinX и PinY - Положение метки относительно верхнего левого угла карты
//сокровищ или карты нарисованной картографом. (в пикселях)
if Action = 1 then
begin
if idMap = ID then
begin
//Как я определяю координаты клада?
//Данный алгоритм опирается на информацию из дефолтных скриптов RunUO:
//размер карты = 300х300 пикселей (также можно увидеть в журнале Stealth'a),
//маштаб карты = 1:2.
wMap := 300;
hMap := 300;
scaleMap := 2;
//Разница между центром карты и координатами метки клада (в пикселях):
xDif := wMap/2 - PinX;
yDif := hMap/2 - PinY;
//Маштабировав результат получим разницу в мировых координатах:
xDif := xDif * scaleMap;
yDif := yDif * scaleMap;
//Отняв полученный результат из координат центра карты, полученных в
//ивенте EvMapMessage, узнаем мировые координаты клада:
xTreasure := xMap - xDif;
yTreasure := yMap - yDif;
//Точность: +/- 1 тайл.
if WorldNum < 2 then
begin
DrawLineToTreasure(xTreasure, yTreasure);
ClientPrint('Координаты клада: ' + IntToStr(xTreasure) + ' ' + IntToStr(yTreasure));
ClientPrint('Следуйте указателю на карте.');
end
else
begin
AddToSystemJournal('Вы должны находиться в мире Felucca или Trammel.');
ClientPrint('Вы должны находиться в мире Felucca или Trammel.');
end;
end;
end;
End;
BEGIN
SetEventProc(EvIncomingGump, 'eventIncomingGump');
SetEventProc(EvMapMessage, 'eventMapMessage');
SetEventProc(EvMapPin, 'eventMapPin');
ClearFigures;
idText := $FFFFFFFF;
idLine := $FFFFFFFF;
while TRUE do
begin
if not Connected or Dead then
begin
while not Connected or Dead do wait(1000);
wait(5000);
end
else
wait(10);
if (idMap > 0) and ((xSelf <> GetX(self)) or (ySelf <> GetY(Self))) then
begin
xSelf := GetX(Self);
ySelf := GetY(Self);
if Dist(xSelf, ySelf, xTreasure, yTreasure) <= distanceForTips then
Navigator(xTreasure, yTreasure);
end;
if (idMap > 0) and (Pos('completed by', LowerCase(GetTooltip(idMap))) > 0) then
begin
ClientPrint('Вы выкопали клад!');
idMap := 0;
RemoveFigure(idLine); //Если закомментировать, то метка к кладу будет удалена,
RemoveFigure(idTExt); //когда будет открыта карта с еще не найденными сокровищами.
end;
end;
END.
Code: Select all
{###############################################################
# Author: Gauhar #
# Script: SOS Hunter (lite).sc #
# Stealth Client: v4.3.6+ (http://stealth.od.ua/forum/) #
# Shard: #
# Server: RunUO #
# UO Client: v7.0.23.1 #
# ----------------------------------------------------------- #
# ОПИСАНИЕ: #
# Показывает на карте Stealth'а координаты и напрвление для #
# последнего открытого SOS сообщения. #
###############################################################}
PROGRAM SOSHunter;
TYPE
TSextantData = record
LatY, LonX, MinsY, MinsX: Integer;
SouthY, EastX: String;
end;
TWorldCoordinates = record
X, Y: Integer;
end;
Function SextantToWorld(yLat, yMins: Integer; ySouth: String;
xLong, xMins: Integer; xEast: String;
NMap: Byte): TWorldCoordinates;
Var
xCenter, yCenter: Integer;
xWidth, yHeight: Integer;
absLong, absLat: Double;
x, y: Integer;
Begin
xCenter := 0;
yCenter := 0;
if (NMap = 0) or (NMap = 1) then //Felucca и Trammel только Britannia без Lost Lands.
begin
xCenter := 1323;
yCenter := 1624;
xWidth := 5120;
yHeight := 4096;
end;
if NMap = 2 then //Ilshenar
begin
xWidth := 2304;
yHeight := 1600;
end;
if NMap = 3 then //Malas
begin
xWidth := 2560;
yHeight := 2048;
end;
if NMap = 4 then //Tokuno
begin
xWidth := 1448;
yHeight := 1448;
end;
if NMap = 5 then //Ter-Mur
begin
xWidth := 1280;
yHeight := 4096;
end;
absLong := xLong + (xMins / 60.0);
absLat := yLat + (yMins / 60.0);
if xEast <> 'E' then
absLong := 360.0 - absLong;
if ySouth <> 'S' then
absLat := 360.0 - absLat;
x := xCenter + Trunc((absLong * xWidth) / 360.0);
y := yCenter + Trunc((absLat * yHeight) / 360.0);
if x < 0 then
x := x + xWidth
else if x >= xWidth then
x := x - xWidth;
if y < 0 then
y := y + yHeight
else if y >= yHeight then
y := y - yHeight;
Result.X := x;
Result.Y := y;
End;
Function DeleteSubStr(StrWhere, SubStr: String): String;
Begin
while pos(SubStr, StrWhere) > 0 do
StrWhere := copy(StrWhere, 1, pos(SubStr, StrWhere) - 1) +
copy(StrWhere, pos(SubStr, StrWhere) + length(SubStr), length(StrWhere));
Result := StrWhere;
End;
Function ParsingSextantCoordinates(S: String): TSextantData;
Begin
//Примеры координат с двух разных шардов:
//112° 19'N, 19° 20'E
//112°19'N,19°20'E
S := DeleteSubStr(S, ' ');
if pos('°', S) > 0 then
begin
Result.LatY := StrToInt( copy(S, 1, pos('°', S) - 1) );
Delete(S, 1, pos('°', S));
Result.MinsY := StrToInt( copy(S, 1, pos('''', S) - 1) );
Delete(S, 1, pos('''', S));
Result.SouthY := copy(S, 1, 1);
Delete(S, 1, pos(',', S));
Result.LonX := StrToInt( copy(S, 1, pos('°', S) - 1) );
Delete(S, 1, pos('°', S));
Result.MinsX := StrToInt( copy(S, 1, pos('''', S) - 1) );
Delete(S, 1, pos('''', S));
Result.EastX := S;
end;
End;
Function GetSextantCoordinatesFromGump(): String;
Var
gumpInfo: TGumpInfo;
Begin
GetGumpInfo(GetGumpsCount - 1, gumpInfo);
if Length(gumpInfo.XmfHtmlGump) > 0 then
if gumpInfo.XmfHtmlGump[0].Cliloc_id = 1018326 then //Текст SOS сообщения.
Result := gumpInfo.Text[0] //Координаты в SOS сообщении.
else
Result := '';
End;
Procedure DrawDirectionToSOS(X, Y: Integer);
Var
Figure: TMapFigure;
Begin
Figure.kind := fkDirection;
Figure.coord := fcWorld;
Figure.x1 := X;
Figure.y1 := Y;
Figure.x2 := 0;
Figure.y2 := 0;
Figure.brushStyle := bsClear;
Figure.brushColor := $000000;
Figure.color := $FFFF00; //цвет линии
Figure.text := '';
AddFigure(Figure);
Figure.kind := fkText;
Figure.coord := fcWorld;
Figure.x1 := X;
Figure.y1 := Y;
Figure.x2 := 0;
Figure.y2 := 0;
Figure.brushStyle := bsSolid; //фон: bsSolid, bsClear
Figure.brushColor := $000000; //цвет фона
Figure.color := $00FF00; //цвет текста
Figure.text := '* ' + IntToStr(X) + ' ' + IntToStr(Y);
AddFigure(Figure);
ClientPrint('Координаты SOS отмечены на карте Stealth''a.');
End;
Procedure eventIncomingGump(Serial, GumpID, X, Y: Cardinal);
Var
SextantCoordinates: String;
WorldCoordinates: TWorldCoordinates;
SextantData: TSextantData;
Begin
SextantCoordinates := GetSextantCoordinatesFromGump();
if SextantCoordinates <> '' then
begin
ClearFigures;
if WorldNum < 2 then
begin
SextantData := ParsingSextantCoordinates(SextantCoordinates);
with SextantData do
begin
WorldCoordinates := SextantToWorld(LatY, MinsY, SouthY, LonX, MinsX, EastX, WorldNum);
AddToSystemJournal('Координаты кораблекрушения: ' +
IntToStr(LatY) + '°' + IntToStr(MinsY) + '''' + SouthY + ',' +
IntToStr(LonX) + '°' + IntToStr(MinsX) + '''' + EastX + ' -> (' +
IntToStr(WorldCoordinates.X) + ',' + IntToStr(WorldCoordinates.Y) + ')');
end;
DrawDirectionToSOS(WorldCoordinates.X, WorldCoordinates.Y);
end
else
begin
AddToSystemJournal('Вы должны находиться в мире Felucca или Trammel.');
ClientPrint('Вы должны находиться в мире Felucca или Trammel.');
end;
CloseSimpleGump(GetGumpsCount - 1);
end;
End;
BEGIN
SetEventProc(EvIncomingGump, 'eventIncomingGump');
ClearFigures;
while TRUE do wait(100);
END.