Heres the code and a short video that shows it working, you can read a brief description on the Scripts Download section.
http://www.youtube.com/watch?v=1vQ3JPAhdTwCode:
//Magnetic Super Sheep. An orignal idea of Drumstick
//Contains some Gravity Gun code
//Feel free to tweak, or reuse as you wish
//Diego
var
Key_Q_Pressed : array[1..2] of Boolean;
Gravitied, Dragging: array [1..4] of Boolean;
CurrentObj: array[1..4] of TWPobj;
AlmPosX, AlmPosY, dx, dy : array [1..4] of Double;
Dist : Double;
TGTlol, z:integer;
LastTimer, BTurnTime : Integer;
procedure InitHooks;
begin
RegisterHook('Init', ON_INIT);
RegisterHook('Frame', ON_FRAME);
RegisterHook('TurnEnd', ON_TURN_END);
RegisterHook('TurnStart', ON_TURN_BEGIN);
RegisterHook('PrepareMess', ON_PREPARE_MESSAGES);
RegisterHook('RecvMess', ON_RECV_PXMESS);
end;
{-------------------------}
{-------------------------}
function IsRegistered(a : twpobj): boolean;
var
i: integer;
begin
Result:=false;
for i:=1 to GetPObjCount-1 do
begin
if GetPObj(i)=a then
begin
Result:=true;
Exit;
end;
end;
end;
{-------------------------}
function Find(ChargeObj : TWPobj) : TWPobj;
var i:integer;
FindObj : TWPobj;
// dx, dy : double;
WormObj : TWorm;
begin
WormObj := GetTekWormObj;
Result:=nil;
for i := 1 to (GetPObjCount - 1) do begin
FindObj := GetPObj(i);
if (FindObj <> nil) then begin
if (ObjInCircle(FindObj, ChargeObj.PosX, ChargeObj.PosY, 200)) and (FindObj.objtype <> OBJ_CHARGE) and (FindObj <> CurrentObj[1]) and (FindObj <> CurrentObj[2]) and (FindObj <> CurrentObj[3]) and (FindObj <> CurrentObj[4]) then begin
Result := FindObj;
end;
end;
if (Result <> nil) then break;
end;
end;
{-------------------------}
function DragIn(Obj,ChargeObj : TWPObj) : boolean;
var
WormObj : TWorm;
// dx, dy, AlmostPosX, AlmostPosY : double;
// i : integer;
begin
Result:=false;
WormObj := GetTekWormObj;
CurrentObj[z] := Obj;
// ShowMessageOnTop(23, 'dx='+IntToStr(Round(dx))+', dy='+IntToStr(Round(dy)));
if not ObjInCircle(CurrentObj[z],ChargeObj.PosX,ChargeObj.PosY, Round(Dist+15)) then
begin
Dragging[z] := true;
Gravitied[z] := false;
end
else begin
Gravitied[z] := true;
end;
// if Dragging=false then
// begin
// Obj.PosX := Round(AlmPosX);
// Obj.PosY := Round(AlmPosY);
// Obj.SpX := GetSyncRandom(20,1)-10;
// Obj.SpY := GetSyncRandom(20,1)-10;
// end;
// if ((TGTlol mod 60) = 0) then ShowMessageOnTop(23,'ObjSpX='+FloatToStr(Obj.SpX)+', ObjSpY='+FloatToStr(Obj.SpY));
// Gravitied[z]:=true;
Result:=true;
end;
{-------------------------}
function Drag(ChargeObj:TWPObj) : boolean;
var
cx,cy : double;
WormObj:TWorm;
begin
WormObj:=GetTekWormObj;
if (CurrentObj[z].PosX=Round(AlmPosX[z])) and (CurrentObj[z].PosY=Round(AlmPosY[z])) then Dragging[z]:=false;
cx:=(CurrentObj[z].PosX-Round(ChargeObj.PosX))/Sqrt((Round(ChargeObj.PosX)-CurrentObj[z].PosX)*(Round(ChargeObj.PosX)-CurrentObj[z].PosX)+(Round(ChargeObj.PosY)-CurrentObj[z].PosY)*(Round(ChargeObj.PosY)-CurrentObj[z].PosY));
cy:=(CurrentObj[z].PosY-Round(ChargeObj.PosY))/Sqrt((Round(ChargeObj.PosX)-CurrentObj[z].PosX)*(Round(ChargeObj.PosX)-CurrentObj[z].PosX)+(Round(ChargeObj.PosY)-CurrentObj[z].PosY)*(Round(ChargeObj.PosY)-CurrentObj[z].PosY));
// ShowMessageOnTop(23,'cx='+FloatToStr(cx*1000)+', cy='+FloatToStr(cy*1000));
if (TGTlol mod 5) = 0 then
begin
CurrentObj[z].SpX:=CurrentObj[z].SpX-125/Dist*cx;
CurrentObj[z].SpY:=CurrentObj[z].SpY-125/Dist*cy-0.2399903;
end;
Result := true;
end;
{-------------------------}
procedure Init;
begin
Key_Q_Pressed[1] := false;
Key_Q_Pressed[2] := false;
TGTlol:=0;
BTurnTime:=0;
LastTimer:=0;
end;
{-------------------------}
procedure TurnStart;
begin
Gravitied[1] := false ; Gravitied[2] := false; Gravitied[3] := false ; Gravitied[4] := false;
Dragging[1] := false; Dragging[2] := false; Dragging[3] := false; Dragging[4] := false;
end;
{-------------------------}
procedure Frame;
var
i, k, m : Integer;
b, ChargeObj, Obj : twpobj;
WormObj : TWorm;
begin
for i := 1 to GetPOBjCount - 1 do begin
b := GetPObj(i);
if b <> nil then begin
if b.objtype = OBJ_CHARGE then begin
ChargeObj := b;
end;
end;
end;
WormObj := GetTekWormObj;
if (WormObj = nil) then begin
for m := 1 to 4 do begin
Gravitied[m]:=false;
Dragging[m] :=false;
CurrentObj[m] := nil;
end;
exit;
end;
if ChargeObj = nil then begin
for m := 1 to 4 do begin
Gravitied[m]:=false;
Dragging[m]:=false;
CurrentObj[m] := nil
end;
exit;
end;
if (WormObj <> nil) then begin
if (WormObj.Health <= 0) then exit;
end;
TGTlol:=TGTlol+1;
if (WormObj.SelWeapon.WT = 1) and (WormObj.SelWeapon.WN = 24) and (ChargeObj <> nil) and Key_Q_Pressed[1] then begin
if ((TGTlol mod 4) = 0) then begin
for z := 1 to 4 do begin
if (WormObj.WormState = WSTATUS_ROPING) {or (WormObj.WormState = WSTATUS_AFTER_ROPING) or (WormObj.WormState = WSTATUS_FIRING_ROPE)} then exit;
// Result:=false;
if not Gravitied[z] and not Dragging[z] then begin
CurrentObj[z] := nil;
Obj := Find(ChargeObj);
if Obj <> nil then DragIn(Obj,ChargeObj) {then ShowMessageOnTop(23,'Hurray! Hurray!')} ;
end;
end; end;
for z := 1 to 4 do begin
if (not (Key_Q_Pressed[1])) then begin Gravitied[z] :=false; Dragging[z] := false; end;
if TurnTimer = LastTimer then BTurnTime := BTurnTime + 1;
if BTurnTime > 600 then begin
BTurnTime := 0;
for k := 1 to getpobjCOunt - 1 do begin
b := GetPObj(i);
if b <> nil then if b.ObjType = Obj_Mine then begin
b.SpX := b.SpX + GetSyncRandom(6,k+TGTlol)-3;
b.SpY := b.SpY + GetSyncRandom(6,k+TGTlol)-3;
end;
end;
end;
LastTimer := TurnTimer;
if Gravitied[z] then begin
AlmPosX[z] := (ChargeObj.PosX - 50*dx[z]);
AlmPosY[z] := (ChargeObj.PosY - 50*dy[z]);
// CurrentObj.PosX := Round(AlmPosX);
// CurrentObj.PosY := Round(AlmPosY);
CurrentObj[z].SpX := ChargeObj.SpX;
CurrentObj[z].SpY := ChargeObj.SpY;
if not ObjInCircle(CurrentObj[z],ChargeObj.PosX,ChargeObj.PosY, Round(Dist+15)) then
begin
Dragging[z] := true;
Gravitied[z] := false;
end
// DragIn(CurrentObj[z],ChargeObj);
end;
if not IsRegistered(WormObj) then Gravitied[z]:=false;
// REEMPLAZADO dx := sin(WormObj.WeapAngle*pi)*WormObj.Direction;
// REEMPLAZADO dy := cos(WormObj.WeapAngle*pi);
// dx[z] := 0.766;
// dy := 0.642;
// Dist := sqrt((Round(AlmPosX)-ChargeObj.PosX)*(Round(AlmPosX)-ChargeObj.PosX)+(Round(AlmPosY)-ChargeObj.PosY)*(Round(AlmPosY)-ChargeObj.PosY))
Dist := 50;
if Dragging[z]=true then
begin
if not ObjInCircle(CurrentObj[z],Round(ChargeObj.PosX),Round(ChargeObj.PosY), 400) then begin Gravitied[z]:=false; Dragging[z]:=false; CurrentObj[z] := nil ; exit; end;
Drag(ChargeObj);
if ObjInCircle(CurrentObj[z], Round(ChargeObj.PosX), Round(ChargeObj.PosY), Round(Dist)) then
begin
Gravitied[z] := true;
Dragging[z] := false;
AlmPosX[z] := Round(CurrentObj[z].PosX);
AlmPosY[z] := Round(CurrentObj[z].PosY);
dx[z] := (ChargeObj.PosX - CurrentObj[z].PosX)/50;
dy[z] := (ChargeObj.PosY - CurrentObj[z].PosY)/50;
// ShowMessageOnTop(23, 'gravitied = True');
// DragIn(CurrentObj[z],ChargeObj);
end;
end;
end;
end;
end;
{-------------------------}
procedure TurnEnd;
var
g: integer;
begin
for g := 1 to 4 do begin
Gravitied[g]:=false;
Dragging[g]:=false;
CurrentObj[g] := nil;
end;
end;
{-------------------------}
{ Start of Key syncronization, You may use this part in your code }
procedure PrepareMess;
begin
Key_Q_Pressed[1] := false
if gettekwormobj<>nil then
begin
if ispressed(81)=1 then Key_Q_Pressed[1]:=true;{Q}
if Key_Q_Pressed[2] <> Key_Q_Pressed[1] then
begin
Key_Q_Pressed[2]:=Key_Q_Pressed[1];
if Key_Q_Pressed[2] then sendpxmessage(5,1,1)
else sendpxmessage(5,1,0);
end;
end;
end;
procedure RecvMess(Messtype, MessDataA,MessDataB: integer);
begin
if messtype=5 then
if messdatab=1 then Key_Q_Pressed[1]:=true
else Key_Q_Pressed[1]:=false;
end;