hedgewars/uVisualGears.pas
changeset 2948 3f21a9dc93d0
parent 2941 566f967ec22f
child 2972 82828fd23dea
equal deleted inserted replaced
2947:803b277e4894 2948:3f21a9dc93d0
    20 
    20 
    21 unit uVisualGears;
    21 unit uVisualGears;
    22 interface
    22 interface
    23 uses SDLh, uConsts, uFloat,
    23 uses SDLh, uConsts, uFloat,
    24 {$IFDEF GLES11}
    24 {$IFDEF GLES11}
    25 	gles11;
    25     gles11;
    26 {$ELSE}
    26 {$ELSE}
    27 	GL;
    27     GL;
    28 {$ENDIF}
    28 {$ENDIF}
    29 
    29 
    30 type PVisualGear = ^TVisualGear;
    30 type PVisualGear = ^TVisualGear;
    31 	TVGearStepProcedure = procedure (Gear: PVisualGear; Steps: Longword);
    31     TVGearStepProcedure = procedure (Gear: PVisualGear; Steps: Longword);
    32 	TVisualGear = record
    32     TVisualGear = record
    33 		NextGear, PrevGear: PVisualGear;
    33         NextGear, PrevGear: PVisualGear;
    34 		Frame,
    34         Frame,
    35 		FrameTicks: Longword;
    35         FrameTicks: Longword;
    36 		X : hwFloat;
    36         X : hwFloat;
    37 		Y : hwFloat;
    37         Y : hwFloat;
    38 		dX: hwFloat;
    38         dX: hwFloat;
    39 		dY: hwFloat;
    39         dY: hwFloat;
    40 		mdY: QWord;
    40         mdY: QWord;
    41 		Timer: Longword;
    41         Timer: Longword;
    42 		Angle, dAngle: real;
    42         Angle, dAngle: real;
    43 		Kind: TVisualGearType;
    43         Kind: TVisualGearType;
    44 		doStep: TVGearStepProcedure;
    44         doStep: TVGearStepProcedure;
    45 		Tex: PTexture;
    45         Tex: PTexture;
    46         Hedgehog: pointer;
    46         Hedgehog: pointer;
    47         Text: shortstring
    47         Text: shortstring
    48 		end;
    48         end;
    49 
    49 
    50 procedure init_uVisualGears;
    50 procedure init_uVisualGears;
    51 procedure free_uVisualGears;
    51 procedure free_uVisualGears;
    52 
    52 
    53 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
    53 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
    65 uses uWorld, uMisc, uStore, uTeams, uSound;
    65 uses uWorld, uMisc, uStore, uTeams, uSound;
    66 const cExplFrameTicks = 110;
    66 const cExplFrameTicks = 110;
    67 
    67 
    68 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
    68 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
    69 var s: shortstring;
    69 var s: shortstring;
    70 	Gear: PVisualGear;
    70     Gear: PVisualGear;
    71 begin
    71 begin
    72 if cAltDamage then
    72 if cAltDamage then
    73 	begin
    73     begin
    74 	Gear:= AddVisualGear(X, Y, vgtSmallDamageTag);
    74     Gear:= AddVisualGear(X, Y, vgtSmallDamageTag);
    75 	if Gear <> nil then
    75     if Gear <> nil then
    76 		with Gear^ do
    76         with Gear^ do
    77 			begin
    77             begin
    78 			str(Damage, s);
    78             str(Damage, s);
    79 			Tex:= RenderStringTex(s, Color, fntSmall);
    79             Tex:= RenderStringTex(s, Color, fntSmall);
    80 			end
    80             end
    81 	end
    81     end
    82 end;
    82 end;
    83 
    83 
    84 
    84 
    85 // ==================================================================
    85 // ==================================================================
    86 procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
    86 procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
    87 begin
    87 begin
    88 with Gear^ do
    88 with Gear^ do
    89 	begin
    89     begin
    90 	inc(FrameTicks, Steps);
    90     inc(FrameTicks, Steps);
    91 	if FrameTicks > vobFrameTicks then
    91     if FrameTicks > vobFrameTicks then
    92 		begin
    92         begin
    93 		dec(FrameTicks, vobFrameTicks);
    93         dec(FrameTicks, vobFrameTicks);
    94 		inc(Frame);
    94         inc(Frame);
    95 		if Frame = vobFramesCount then Frame:= 0
    95         if Frame = vobFramesCount then Frame:= 0
    96 		end
    96         end
    97 	end;
    97     end;
    98 
    98 
    99 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps;
    99 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps;
   100 Gear^.Y:= Gear^.Y + (Gear^.dY + cGravity * vobFallSpeed) * Steps;
   100 Gear^.Y:= Gear^.Y + (Gear^.dY + cGravity * vobFallSpeed) * Steps;
   101 Gear^.Angle:= Gear^.Angle + Gear^.dAngle * Steps;
   101 Gear^.Angle:= Gear^.Angle + Gear^.dAngle * Steps;
   102 
   102 
   110 var i: Longword;
   110 var i: Longword;
   111 begin
   111 begin
   112 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps;
   112 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps;
   113 
   113 
   114 for i:= 0 to Steps - 1 do
   114 for i:= 0 to Steps - 1 do
   115 	begin
   115     begin
   116 	if hwRound(Gear^.Y) > LAND_HEIGHT-1184 then // TODO - configure in theme
   116     if hwRound(Gear^.Y) > LAND_HEIGHT-1184 then // TODO - configure in theme
   117 		Gear^.dY:= Gear^.dY - _1div50000
   117         Gear^.dY:= Gear^.dY - _1div50000
   118 	else
   118     else
   119 		Gear^.dY:= Gear^.dY + _1div50000;
   119         Gear^.dY:= Gear^.dY + _1div50000;
   120 
   120 
   121 	Gear^.Y:= Gear^.Y + Gear^.dY
   121     Gear^.Y:= Gear^.Y + Gear^.dY
   122 	end;
   122     end;
   123 
   123 
   124 if hwRound(Gear^.X) < -cScreenWidth - 256 then Gear^.X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else
   124 if hwRound(Gear^.X) < -cScreenWidth - 256 then Gear^.X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else
   125 if hwRound(Gear^.X) > cScreenWidth + LAND_WIDTH then Gear^.X:= int2hwFloat(-cScreenWidth - 256)
   125 if hwRound(Gear^.X) > cScreenWidth + LAND_WIDTH then Gear^.X:= int2hwFloat(-cScreenWidth - 256)
   126 end;
   126 end;
   127 
   127 
   131 
   131 
   132 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
   132 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
   133 //Gear^.dY:= Gear^.dY + cGravity;
   133 //Gear^.dY:= Gear^.dY + cGravity;
   134 
   134 
   135 if Gear^.FrameTicks <= Steps then
   135 if Gear^.FrameTicks <= Steps then
   136 	if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   136     if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   137 	else
   137     else
   138 		begin
   138         begin
   139 		dec(Gear^.Frame);
   139         dec(Gear^.Frame);
   140 		Gear^.FrameTicks:= cExplFrameTicks
   140         Gear^.FrameTicks:= cExplFrameTicks
   141 		end
   141         end
   142 	else dec(Gear^.FrameTicks, Steps)
   142     else dec(Gear^.FrameTicks, Steps)
   143 end;
   143 end;
   144 
   144 
   145 procedure doStepFire(Gear: PVisualGear; Steps: Longword);
   145 procedure doStepFire(Gear: PVisualGear; Steps: Longword);
   146 begin
   146 begin
   147 Gear^.X:= Gear^.X + Gear^.dX * Steps;
   147 Gear^.X:= Gear^.X + Gear^.dX * Steps;
   150 Gear^.dY:= Gear^.dY + cGravity * Steps;
   150 Gear^.dY:= Gear^.dY + cGravity * Steps;
   151 
   151 
   152 if Gear^.FrameTicks <= Steps then
   152 if Gear^.FrameTicks <= Steps then
   153        DeleteVisualGear(Gear)
   153        DeleteVisualGear(Gear)
   154 else
   154 else
   155 	dec(Gear^.FrameTicks, Steps)
   155     dec(Gear^.FrameTicks, Steps)
   156 end;
   156 end;
   157 
   157 
   158 procedure doStepShell(Gear: PVisualGear; Steps: Longword);
   158 procedure doStepShell(Gear: PVisualGear; Steps: Longword);
   159 begin
   159 begin
   160 Gear^.X:= Gear^.X + Gear^.dX * Steps;
   160 Gear^.X:= Gear^.X + Gear^.dX * Steps;
   163 Gear^.dY:= Gear^.dY + cGravity * Steps;
   163 Gear^.dY:= Gear^.dY + cGravity * Steps;
   164 
   164 
   165 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
   165 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
   166 
   166 
   167 if Gear^.FrameTicks <= Steps then
   167 if Gear^.FrameTicks <= Steps then
   168 	DeleteVisualGear(Gear)
   168     DeleteVisualGear(Gear)
   169 else
   169 else
   170 	dec(Gear^.FrameTicks, Steps)
   170     dec(Gear^.FrameTicks, Steps)
   171 end;
   171 end;
   172 
   172 
   173 procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword);
   173 procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword);
   174 begin
   174 begin
   175 Gear^.Y:= Gear^.Y - _0_02 * Steps;
   175 Gear^.Y:= Gear^.Y - _0_02 * Steps;
   176 
   176 
   177 if Gear^.FrameTicks <= Steps then
   177 if Gear^.FrameTicks <= Steps then
   178 	DeleteVisualGear(Gear)
   178     DeleteVisualGear(Gear)
   179 else
   179 else
   180 	dec(Gear^.FrameTicks, Steps)
   180     dec(Gear^.FrameTicks, Steps)
   181 end;
   181 end;
   182 
   182 
   183 procedure doStepBubble(Gear: PVisualGear; Steps: Longword);
   183 procedure doStepBubble(Gear: PVisualGear; Steps: Longword);
   184 begin
   184 begin
   185 	Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps;
   185     Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps;
   186 	Gear^.Y:= Gear^.Y - cDrownSpeed * Steps;
   186     Gear^.Y:= Gear^.Y - cDrownSpeed * Steps;
   187 
   187 
   188 	if (Gear^.FrameTicks <= Steps) or (hwRound(Gear^.Y) < cWaterLine) then
   188     if (Gear^.FrameTicks <= Steps) or (hwRound(Gear^.Y) < cWaterLine) then
   189 		DeleteVisualGear(Gear)
   189         DeleteVisualGear(Gear)
   190 	else
   190     else
   191 		dec(Gear^.FrameTicks, Steps)
   191         dec(Gear^.FrameTicks, Steps)
   192 end;
   192 end;
   193 
   193 
   194 procedure doStepHealth(Gear: PVisualGear; Steps: Longword);
   194 procedure doStepHealth(Gear: PVisualGear; Steps: Longword);
   195 begin
   195 begin
   196 Gear^.X:= Gear^.X + Gear^.dX * Steps;
   196 Gear^.X:= Gear^.X + Gear^.dX * Steps;
   197 Gear^.Y:= Gear^.Y - Gear^.dY * Steps;
   197 Gear^.Y:= Gear^.Y - Gear^.dY * Steps;
   198 
   198 
   199 if Gear^.FrameTicks <= Steps then
   199 if Gear^.FrameTicks <= Steps then
   200 	DeleteVisualGear(Gear)
   200     DeleteVisualGear(Gear)
   201 else
   201 else
   202 	dec(Gear^.FrameTicks, Steps);
   202     dec(Gear^.FrameTicks, Steps);
   203 end;
   203 end;
   204 
   204 
   205 procedure doStepSteam(Gear: PVisualGear; Steps: Longword);
   205 procedure doStepSteam(Gear: PVisualGear; Steps: Longword);
   206 begin
   206 begin
   207 	Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps;
   207     Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps;
   208 	Gear^.Y:= Gear^.Y - cDrownSpeed * Steps;
   208     Gear^.Y:= Gear^.Y - cDrownSpeed * Steps;
   209 
   209 
   210 	if Gear^.FrameTicks <= Steps then
   210     if Gear^.FrameTicks <= Steps then
   211 		if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   211         if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   212 		else
   212         else
   213 			begin
   213             begin
   214 			if Random(2) = 0 then dec(Gear^.Frame);
   214             if Random(2) = 0 then dec(Gear^.Frame);
   215 			Gear^.FrameTicks:= cExplFrameTicks
   215             Gear^.FrameTicks:= cExplFrameTicks
   216 			end
   216             end
   217 		else dec(Gear^.FrameTicks, Steps)
   217         else dec(Gear^.FrameTicks, Steps)
   218 end;
   218 end;
   219 
   219 
   220 procedure doStepSmoke(Gear: PVisualGear; Steps: Longword);
   220 procedure doStepSmoke(Gear: PVisualGear; Steps: Longword);
   221 begin
   221 begin
   222 	Gear^.X:= Gear^.X + (cWindSpeed + Gear^.dX) * Steps;
   222     Gear^.X:= Gear^.X + (cWindSpeed + Gear^.dX) * Steps;
   223 	Gear^.Y:= Gear^.Y - (cDrownSpeed + Gear^.dY) * Steps;
   223     Gear^.Y:= Gear^.Y - (cDrownSpeed + Gear^.dY) * Steps;
   224 
   224 
   225 	Gear^.dX := Gear^.dX + (cWindSpeed * _0_3 * Steps);
   225     Gear^.dX := Gear^.dX + (cWindSpeed * _0_3 * Steps);
   226 	//Gear^.dY := Gear^.dY - (cDrownSpeed * _0_995);
   226     //Gear^.dY := Gear^.dY - (cDrownSpeed * _0_995);
   227 
   227 
   228 	if Gear^.FrameTicks <= Steps then
   228     if Gear^.FrameTicks <= Steps then
   229 		if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   229         if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   230 		else
   230         else
   231 			begin
   231             begin
   232 			if Random(2) = 0 then dec(Gear^.Frame);
   232             if Random(2) = 0 then dec(Gear^.Frame);
   233 			Gear^.FrameTicks:= cExplFrameTicks
   233             Gear^.FrameTicks:= cExplFrameTicks
   234 			end
   234             end
   235 		else dec(Gear^.FrameTicks, Steps)
   235         else dec(Gear^.FrameTicks, Steps)
   236 end;
   236 end;
   237 
   237 
   238 procedure doStepDust(Gear: PVisualGear; Steps: Longword);
   238 procedure doStepDust(Gear: PVisualGear; Steps: Longword);
   239 begin
   239 begin
   240 	Gear^.X:= Gear^.X + (cWindSpeed + (cWindSpeed * _0_03 * Steps) + Gear^.dX) * Steps;
   240     Gear^.X:= Gear^.X + (cWindSpeed + (cWindSpeed * _0_03 * Steps) + Gear^.dX) * Steps;
   241 	Gear^.Y:= Gear^.Y - (Gear^.dY) * Steps;
   241     Gear^.Y:= Gear^.Y - (Gear^.dY) * Steps;
   242 
   242 
   243 	Gear^.dX := Gear^.dX - (Gear^.dX * _0_005 * Steps);
   243     Gear^.dX := Gear^.dX - (Gear^.dX * _0_005 * Steps);
   244 	Gear^.dY := Gear^.dY - (cDrownSpeed * _0_001 * Steps);
   244     Gear^.dY := Gear^.dY - (cDrownSpeed * _0_001 * Steps);
   245 
   245 
   246 	if Gear^.FrameTicks <= Steps then
   246     if Gear^.FrameTicks <= Steps then
   247 		if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   247         if Gear^.Frame = 0 then DeleteVisualGear(Gear)
   248 		else
   248         else
   249 			begin
   249             begin
   250 			dec(Gear^.Frame);
   250             dec(Gear^.Frame);
   251 			Gear^.FrameTicks:= cExplFrameTicks
   251             Gear^.FrameTicks:= cExplFrameTicks
   252 			end
   252             end
   253 		else dec(Gear^.FrameTicks, Steps)
   253         else dec(Gear^.FrameTicks, Steps)
   254 end;
   254 end;
   255 
   255 
   256 ////////////////////////////////////////////////////////////////////////////////
   256 ////////////////////////////////////////////////////////////////////////////////
   257 const cSorterWorkTime = 640;
   257 const cSorterWorkTime = 640;
   258 var thexchar: array[0..cMaxTeams] of
   258 var thexchar: array[0..cMaxTeams] of
   259 			record
   259             record
   260 			dy, ny, dw: LongInt;
   260             dy, ny, dw: LongInt;
   261 			team: PTeam;
   261             team: PTeam;
   262 			SortFactor: QWord;
   262             SortFactor: QWord;
   263 			end;
   263             end;
   264     currsorter: PVisualGear = nil;
   264     currsorter: PVisualGear = nil;
   265 
   265 
   266 procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword);
   266 procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword);
   267 var i, t: LongInt;
   267 var i, t: LongInt;
   268 begin
   268 begin
   269 for t:= 1 to Steps do
   269 for t:= 1 to Steps do
   270 	begin
   270     begin
   271 	dec(Gear^.Timer);
   271     dec(Gear^.Timer);
   272 	if (Gear^.Timer and 15) = 0 then
   272     if (Gear^.Timer and 15) = 0 then
   273 		for i:= 0 to Pred(TeamsCount) do
   273         for i:= 0 to Pred(TeamsCount) do
   274 			with thexchar[i] do
   274             with thexchar[i] do
   275 				begin
   275                 begin
   276 				{$WARNINGS OFF}
   276                 {$WARNINGS OFF}
   277 				team^.DrawHealthY:= ny + dy * Gear^.Timer div 640;
   277                 team^.DrawHealthY:= ny + dy * Gear^.Timer div 640;
   278 				team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * Gear^.Timer div cSorterWorkTime;
   278                 team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * Gear^.Timer div cSorterWorkTime;
   279 				{$WARNINGS ON}
   279                 {$WARNINGS ON}
   280 				end;
   280                 end;
   281 
   281 
   282 	if (Gear^.Timer = 0) or (currsorter <> Gear) then
   282     if (Gear^.Timer = 0) or (currsorter <> Gear) then
   283 		begin
   283         begin
   284 		if currsorter = Gear then currsorter:= nil;
   284         if currsorter = Gear then currsorter:= nil;
   285 		DeleteVisualGear(Gear);
   285         DeleteVisualGear(Gear);
   286 		exit
   286         exit
   287 		end
   287         end
   288 	end
   288     end
   289 end;
   289 end;
   290 
   290 
   291 procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword);
   291 procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword);
   292 var i: Longword;
   292 var i: Longword;
   293 	b: boolean;
   293     b: boolean;
   294 	t: LongInt;
   294     t: LongInt;
   295 begin
   295 begin
   296 for t:= 0 to Pred(TeamsCount) do
   296 for t:= 0 to Pred(TeamsCount) do
   297 	with thexchar[t] do
   297     with thexchar[t] do
   298 		begin
   298         begin
   299 		dy:= TeamsArray[t]^.DrawHealthY;
   299         dy:= TeamsArray[t]^.DrawHealthY;
   300 		dw:= TeamsArray[t]^.TeamHealthBarWidth - TeamsArray[t]^.NewTeamHealthBarWidth;
   300         dw:= TeamsArray[t]^.TeamHealthBarWidth - TeamsArray[t]^.NewTeamHealthBarWidth;
   301 		team:= TeamsArray[t];
   301         team:= TeamsArray[t];
   302 		SortFactor:= TeamsArray[t]^.Clan^.ClanHealth;
   302         SortFactor:= TeamsArray[t]^.Clan^.ClanHealth;
   303 		SortFactor:= (SortFactor shl  3) + TeamsArray[t]^.Clan^.ClanIndex;
   303         SortFactor:= (SortFactor shl  3) + TeamsArray[t]^.Clan^.ClanIndex;
   304 		SortFactor:= (SortFactor shl 30) + TeamsArray[t]^.TeamHealth;
   304         SortFactor:= (SortFactor shl 30) + TeamsArray[t]^.TeamHealth;
   305 		end;
   305         end;
   306 
   306 
   307 if TeamsCount > 1 then
   307 if TeamsCount > 1 then
   308 	repeat
   308     repeat
   309 	b:= true;
   309     b:= true;
   310 	for t:= 0 to TeamsCount - 2 do
   310     for t:= 0 to TeamsCount - 2 do
   311 		if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then
   311         if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then
   312 			begin
   312             begin
   313 			thexchar[cMaxTeams]:= thexchar[t];
   313             thexchar[cMaxTeams]:= thexchar[t];
   314 			thexchar[t]:= thexchar[Succ(t)];
   314             thexchar[t]:= thexchar[Succ(t)];
   315 			thexchar[Succ(t)]:= thexchar[cMaxTeams];
   315             thexchar[Succ(t)]:= thexchar[cMaxTeams];
   316 			b:= false
   316             b:= false
   317 			end
   317             end
   318 	until b;
   318     until b;
   319 
   319 
   320 t:= - 4;
   320 t:= - 4;
   321 for i:= 0 to Pred(TeamsCount) do
   321 for i:= 0 to Pred(TeamsCount) do
   322 	with thexchar[i] do
   322     with thexchar[i] do
   323 		begin
   323         begin
   324 		dec(t, team^.HealthTex^.h + 2);
   324         dec(t, team^.HealthTex^.h + 2);
   325 		ny:= t;
   325         ny:= t;
   326 		dy:= dy - ny
   326         dy:= dy - ny
   327 		end;
   327         end;
   328 
   328 
   329 Gear^.Timer:= cSorterWorkTime;
   329 Gear^.Timer:= cSorterWorkTime;
   330 Gear^.doStep:= @doStepTeamHealthSorterWork;
   330 Gear^.doStep:= @doStepTeamHealthSorterWork;
   331 currsorter:= Gear;
   331 currsorter:= Gear;
   332 //doStepTeamHealthSorterWork(Gear, Steps)
   332 //doStepTeamHealthSorterWork(Gear, Steps)
   335 procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword);
   335 procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword);
   336 begin
   336 begin
   337 if Gear^.Timer > Steps then dec(Gear^.Timer, Steps) else Gear^.Timer:= 0;
   337 if Gear^.Timer > Steps then dec(Gear^.Timer, Steps) else Gear^.Timer:= 0;
   338 
   338 
   339 if (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then
   339 if (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then
   340 	begin
   340     begin
   341 	Gear^.X:= PHedgehog(Gear^.Hedgehog)^.Gear^.X + int2hwFloat(Gear^.Tex^.w div 2  - Gear^.FrameTicks);
   341     Gear^.X:= PHedgehog(Gear^.Hedgehog)^.Gear^.X + int2hwFloat(Gear^.Tex^.w div 2  - Gear^.FrameTicks);
   342 	Gear^.Y:= PHedgehog(Gear^.Hedgehog)^.Gear^.Y - int2hwFloat(16 + Gear^.Tex^.h);
   342     Gear^.Y:= PHedgehog(Gear^.Hedgehog)^.Gear^.Y - int2hwFloat(16 + Gear^.Tex^.h);
   343 	end;
   343     end;
   344 
   344 
   345 if Gear^.Timer = 0 then
   345 if Gear^.Timer = 0 then
   346 	begin
   346     begin
   347 	if PHedgehog(Gear^.Hedgehog)^.SpeechGear = Gear then
   347     if PHedgehog(Gear^.Hedgehog)^.SpeechGear = Gear then
   348 		PHedgehog(Gear^.Hedgehog)^.SpeechGear:= nil;
   348         PHedgehog(Gear^.Hedgehog)^.SpeechGear:= nil;
   349 	DeleteVisualGear(Gear)
   349     DeleteVisualGear(Gear)
   350 	end;
   350     end;
   351 end;
   351 end;
   352 
   352 
   353 procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword);
   353 procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword);
   354 begin
   354 begin
   355 with PHedgehog(Gear^.Hedgehog)^ do
   355 with PHedgehog(Gear^.Hedgehog)^ do
   372 Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h)
   372 Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h)
   373 end;
   373 end;
   374 
   374 
   375 // ==================================================================
   375 // ==================================================================
   376 const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure =
   376 const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure =
   377 		(
   377         (
   378 			@doStepFlake,
   378             @doStepFlake,
   379 			@doStepCloud,
   379             @doStepCloud,
   380 			@doStepExpl,
   380             @doStepExpl,
   381 			@doStepExpl,
   381             @doStepExpl,
   382 			@doStepFire,
   382             @doStepFire,
   383 			@doStepSmallDamage,
   383             @doStepSmallDamage,
   384 			@doStepTeamHealthSorter,
   384             @doStepTeamHealthSorter,
   385 			@doStepSpeechBubble,
   385             @doStepSpeechBubble,
   386 			@doStepBubble,
   386             @doStepBubble,
   387 			@doStepSteam,
   387             @doStepSteam,
   388 			@doStepSmoke,
   388             @doStepSmoke,
   389 			@doStepSmoke,
   389             @doStepSmoke,
   390 			@doStepHealth,
   390             @doStepHealth,
   391 			@doStepShell,
   391             @doStepShell,
   392 			@doStepDust
   392             @doStepDust
   393 		);
   393         );
   394 
   394 
   395 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
   395 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
   396 var gear: PVisualGear;
   396 var gear: PVisualGear;
   397 	t: Longword;
   397     t: Longword;
   398 	sp: hwFloat;
   398     sp: hwFloat;
   399 begin
   399 begin
   400 if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then // we are scrolling now
   400 if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then // we are scrolling now
   401 	if Kind <> vgtCloud then
   401     if Kind <> vgtCloud then
   402 		begin
   402         begin
   403 		AddVisualGear:= nil;
   403         AddVisualGear:= nil;
   404 		exit
   404         exit
   405 		end;
   405         end;
   406 
   406 
   407 if cReducedQuality and
   407 if cReducedQuality and
   408    (Kind <> vgtTeamHealthSorter) and
   408    (Kind <> vgtTeamHealthSorter) and
   409    (Kind <> vgtSmallDamageTag) and
   409    (Kind <> vgtSmallDamageTag) and
   410    (Kind <> vgtSpeechBubble) then
   410    (Kind <> vgtSpeechBubble) then
   411 	begin
   411     begin
   412 	AddVisualGear:= nil;
   412     AddVisualGear:= nil;
   413 	exit
   413     exit
   414 	end;
   414     end;
   415 
   415 
   416 New(gear);
   416 New(gear);
   417 FillChar(gear^, sizeof(TVisualGear), 0);
   417 FillChar(gear^, sizeof(TVisualGear), 0);
   418 gear^.X:= int2hwFloat(X);
   418 gear^.X:= int2hwFloat(X);
   419 gear^.Y:= int2hwFloat(Y);
   419 gear^.Y:= int2hwFloat(Y);
   420 gear^.Kind := Kind;
   420 gear^.Kind := Kind;
   421 gear^.doStep:= doStepHandlers[Kind];
   421 gear^.doStep:= doStepHandlers[Kind];
   422 
   422 
   423 with gear^ do
   423 with gear^ do
   424 	case Kind of
   424     case Kind of
   425 	vgtFlake: begin
   425     vgtFlake: begin
   426 				FrameTicks:= random(vobFrameTicks);
   426                 FrameTicks:= random(vobFrameTicks);
   427 				Frame:= random(vobFramesCount);
   427                 Frame:= random(vobFramesCount);
   428 				Angle:= random * 360;
   428                 Angle:= random * 360;
   429 				dx.isNegative:= random(2) = 0;
   429                 dx.isNegative:= random(2) = 0;
   430 				dx.QWordValue:= random(100000000);
   430                 dx.QWordValue:= random(100000000);
   431 				dy.isNegative:= false;
   431                 dy.isNegative:= false;
   432 				dy.QWordValue:= random(70000000);
   432                 dy.QWordValue:= random(70000000);
   433 				dAngle:= (random(2) * 2 - 1) * (1 + random) * vobVelocity / 1000
   433                 dAngle:= (random(2) * 2 - 1) * (1 + random) * vobVelocity / 1000
   434 				end;
   434                 end;
   435 	vgtCloud: begin
   435     vgtCloud: begin
   436 				Frame:= random(4);
   436                 Frame:= random(4);
   437 				dx.isNegative:= random(2) = 0;
   437                 dx.isNegative:= random(2) = 0;
   438 				dx.QWordValue:= random(214748364);
   438                 dx.QWordValue:= random(214748364);
   439 				dy.isNegative:= random(2) = 0;
   439                 dy.isNegative:= random(2) = 0;
   440 				dy.QWordValue:= 21474836 + random(64424509);
   440                 dy.QWordValue:= 21474836 + random(64424509);
   441 				mdY:= dy.QWordValue
   441                 mdY:= dy.QWordValue
   442 				end;
   442                 end;
   443 	vgtExplPart,
   443     vgtExplPart,
   444 	vgtExplPart2: begin
   444     vgtExplPart2: begin
   445 				t:= random(1024);
   445                 t:= random(1024);
   446 				sp:= _0_001 * (random(95) + 70);
   446                 sp:= _0_001 * (random(95) + 70);
   447 				dx:= AngleSin(t) * sp;
   447                 dx:= AngleSin(t) * sp;
   448 				dx.isNegative:= random(2) = 0;
   448                 dx.isNegative:= random(2) = 0;
   449 				dy:= AngleCos(t) * sp;
   449                 dy:= AngleCos(t) * sp;
   450 				dy.isNegative:= random(2) = 0;
   450                 dy.isNegative:= random(2) = 0;
   451 				Frame:= 7 - random(3);
   451                 Frame:= 7 - random(3);
   452 				FrameTicks:= cExplFrameTicks
   452                 FrameTicks:= cExplFrameTicks
   453 				end;
   453                 end;
   454 		vgtFire: begin
   454         vgtFire: begin
   455 				t:= random(1024);
   455                 t:= random(1024);
   456 				sp:= _0_001 * (random(85) + 95);
   456                 sp:= _0_001 * (random(85) + 95);
   457 				dx:= AngleSin(t) * sp;
   457                 dx:= AngleSin(t) * sp;
   458 				dx.isNegative:= random(2) = 0;
   458                 dx.isNegative:= random(2) = 0;
   459 				dy:= AngleCos(t) * sp;
   459                 dy:= AngleCos(t) * sp;
   460 				dy.isNegative:= random(2) = 0;
   460                 dy.isNegative:= random(2) = 0;
   461 				FrameTicks:= 650 + random(250);
   461                 FrameTicks:= 650 + random(250);
   462 				Frame:= random(8)
   462                 Frame:= random(8)
   463 				end;
   463                 end;
   464 		vgtShell: FrameTicks:= 500;
   464         vgtShell: FrameTicks:= 500;
   465 	vgtSmallDamageTag: begin
   465     vgtSmallDamageTag: begin
   466 				gear^.FrameTicks:= 1100
   466                 gear^.FrameTicks:= 1100
   467 				end;
   467                 end;
   468 	vgtBubble: begin
   468     vgtBubble: begin
   469 				dx.isNegative:= random(2) = 0;
   469                 dx.isNegative:= random(2) = 0;
   470 				dx.QWordValue:= random(100000000);
   470                 dx.QWordValue:= random(100000000);
   471 				dy:= _0_001 * (random(85) + 95);
   471                 dy:= _0_001 * (random(85) + 95);
   472 				dy.isNegative:= false;
   472                 dy.isNegative:= false;
   473 				FrameTicks:= 250 + random(1751);
   473                 FrameTicks:= 250 + random(1751);
   474 				Frame:= random(5)
   474                 Frame:= random(5)
   475 				end;
   475                 end;
   476 	vgtSteam: begin
   476     vgtSteam: begin
   477 				dx.isNegative:= random(2) = 0;
   477                 dx.isNegative:= random(2) = 0;
   478 				dx.QWordValue:= random(100000000);
   478                 dx.QWordValue:= random(100000000);
   479 				dy:= _0_001 * (random(85) + 95);
   479                 dy:= _0_001 * (random(85) + 95);
   480 				dy.isNegative:= false;
   480                 dy.isNegative:= false;
   481 				Frame:= 7 - random(3);
   481                 Frame:= 7 - random(3);
   482 				FrameTicks:= cExplFrameTicks * 2;
   482                 FrameTicks:= cExplFrameTicks * 2;
   483 				end;
   483                 end;
   484   vgtSmokeWhite, 
   484   vgtSmokeWhite, 
   485   vgtSmoke: begin
   485   vgtSmoke: begin
   486 				dx:= _0_0002 * (random(45) + 10);
   486                 dx:= _0_0002 * (random(45) + 10);
   487 				dx.isNegative:= random(2) = 0;
   487                 dx.isNegative:= random(2) = 0;
   488 				dy:= _0_0002 * (random(45) + 10);
   488                 dy:= _0_0002 * (random(45) + 10);
   489 				dy.isNegative:= false;
   489                 dy.isNegative:= false;
   490 				Frame:= 7 - random(2);
   490                 Frame:= 7 - random(2);
   491 				FrameTicks:= cExplFrameTicks * 2;
   491                 FrameTicks:= cExplFrameTicks * 2;
   492 				end;
   492                 end;
   493 	vgtHealth: begin
   493     vgtHealth: begin
   494 				dx:= _0_001 * random(45);
   494                 dx:= _0_001 * random(45);
   495 				dx.isNegative:= random(2) = 0;
   495                 dx.isNegative:= random(2) = 0;
   496 				dy:= _0_001 * (random(20) + 25);
   496                 dy:= _0_001 * (random(20) + 25);
   497 				Frame:= 0;
   497                 Frame:= 0;
   498 				FrameTicks:= random(750) + 1250;
   498                 FrameTicks:= random(750) + 1250;
   499 				end;
   499                 end;
   500   vgtDust: begin
   500   vgtDust: begin
   501 				dx:= _0_005 * (random(15) + 10);
   501                 dx:= _0_005 * (random(15) + 10);
   502 				dx.isNegative:= random(2) = 0;
   502                 dx.isNegative:= random(2) = 0;
   503 				dy:= _0_001 * (random(40) + 20);
   503                 dy:= _0_001 * (random(40) + 20);
   504 				Frame:= 7 - random(2);
   504                 Frame:= 7 - random(2);
   505 				FrameTicks:= random(20) + 15;
   505                 FrameTicks:= random(20) + 15;
   506 				end;
   506                 end;
   507 		end;
   507         end;
   508 
   508 
   509 if VisualGearsList <> nil then
   509 if VisualGearsList <> nil then
   510 	begin
   510     begin
   511 	VisualGearsList^.PrevGear:= gear;
   511     VisualGearsList^.PrevGear:= gear;
   512 	gear^.NextGear:= VisualGearsList
   512     gear^.NextGear:= VisualGearsList
   513 	end;
   513     end;
   514 VisualGearsList:= gear;
   514 VisualGearsList:= gear;
   515 
   515 
   516 AddVisualGear:= gear;
   516 AddVisualGear:= gear;
   517 end;
   517 end;
   518 
   518 
   519 procedure DeleteVisualGear(Gear: PVisualGear);
   519 procedure DeleteVisualGear(Gear: PVisualGear);
   520 begin
   520 begin
   521 if Gear^.Tex <> nil then
   521 if Gear^.Tex <> nil then
   522 	FreeTexture(Gear^.Tex);
   522     FreeTexture(Gear^.Tex);
   523 
   523 
   524 if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   524 if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   525 if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
   525 if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
   526    else VisualGearsList:= Gear^.NextGear;
   526    else VisualGearsList:= Gear^.NextGear;
   527 
   527 
   545 procedure DrawVisualGears(Layer: LongWord);
   545 procedure DrawVisualGears(Layer: LongWord);
   546 var Gear: PVisualGear;
   546 var Gear: PVisualGear;
   547 begin
   547 begin
   548 Gear:= VisualGearsList;
   548 Gear:= VisualGearsList;
   549 case Layer of
   549 case Layer of
   550 	0: while Gear <> nil do
   550     0: while Gear <> nil do
   551 		begin
   551         begin
   552 		case Gear^.Kind of
   552         case Gear^.Kind of
   553 			vgtFlake: if vobVelocity = 0 then
   553             vgtFlake: if vobVelocity = 0 then
   554 						DrawSprite(sprFlake, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame)
   554                         DrawSprite(sprFlake, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame)
   555 					else
   555                     else
   556 						DrawRotatedF(sprFlake, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   556                         DrawRotatedF(sprFlake, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   557 			vgtCloud: DrawSprite(sprCloud, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame);
   557             vgtCloud: DrawSprite(sprCloud, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame);
   558 			end;
   558             end;
   559 		Gear:= Gear^.NextGear
   559         Gear:= Gear^.NextGear
   560 		end;
   560         end;
   561 	1: while Gear <> nil do
   561     1: while Gear <> nil do
   562 		begin
   562         begin
   563 			if not cReducedQuality then
   563             if not cReducedQuality then
   564 				case Gear^.Kind of
   564                 case Gear^.Kind of
   565 					vgtSmoke: DrawSprite(sprSmoke, hwRound(Gear^.X) + WorldDx - 11, hwRound(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   565                     vgtSmoke: DrawSprite(sprSmoke, hwRound(Gear^.X) + WorldDx - 11, hwRound(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   566 					vgtSmokeWhite: DrawSprite(sprSmokeWhite, hwRound(Gear^.X) + WorldDx - 11, hwRound(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   566                     vgtSmokeWhite: DrawSprite(sprSmokeWhite, hwRound(Gear^.X) + WorldDx - 11, hwRound(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   567 					vgtDust: DrawSprite(sprDust, hwRound(Gear^.X) + WorldDx - 11, hwRound(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   567                     vgtDust: DrawSprite(sprDust, hwRound(Gear^.X) + WorldDx - 11, hwRound(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   568 				end;
   568                 end;
   569 		Gear:= Gear^.NextGear
   569         Gear:= Gear^.NextGear
   570 		end;
   570         end;
   571 	2: while Gear <> nil do
   571     2: while Gear <> nil do
   572 		begin
   572         begin
   573         if not cReducedQuality then
   573         if not cReducedQuality then
   574             case Gear^.Kind of
   574             case Gear^.Kind of
   575                 vgtExplPart: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
   575                 vgtExplPart: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
   576                 vgtExplPart2: DrawSprite(sprExplPart2, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
   576                 vgtExplPart2: DrawSprite(sprExplPart2, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
   577                 vgtFire: DrawSprite(sprFlame, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy, (RealTicks div 64 + Gear^.Frame) mod 8);
   577                 vgtFire: DrawSprite(sprFlame, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy, (RealTicks div 64 + Gear^.Frame) mod 8);
   578 				vgtBubble: DrawSprite(sprBubbles, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8);
   578                 vgtBubble: DrawSprite(sprBubbles, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8);
   579 				vgtSteam: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
   579                 vgtSteam: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
   580 				vgtHealth:  begin
   580                 vgtHealth:  begin
   581 							case Gear^.Frame div 10 of
   581                             case Gear^.Frame div 10 of
   582 								0:glColor4f(0, 1, 0, Gear^.FrameTicks / 1000);
   582                                 0:glColor4f(0, 1, 0, Gear^.FrameTicks / 1000);
   583 								1:glColor4f(1, 0, 0, Gear^.FrameTicks / 1000);
   583                                 1:glColor4f(1, 0, 0, Gear^.FrameTicks / 1000);
   584 							end;
   584                             end;
   585 							DrawSprite(sprHealth, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy - 8, 0);
   585                             DrawSprite(sprHealth, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy - 8, 0);
   586 							glColor4f(1, 1, 1, 1);
   586                             glColor4f(1, 1, 1, 1);
   587 							end;
   587                             end;
   588 				vgtShell: begin
   588                 vgtShell: begin
   589 							if Gear^.FrameTicks < 250 then
   589                             if Gear^.FrameTicks < 250 then
   590 								glColor4f(1, 1, 1, Gear^.FrameTicks / 250);
   590                                 glColor4f(1, 1, 1, Gear^.FrameTicks / 250);
   591 							DrawRotatedF(sprShell, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   591                             DrawRotatedF(sprShell, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   592 							if Gear^.FrameTicks < 250 then
   592                             if Gear^.FrameTicks < 250 then
   593 								glColor4f(1, 1, 1, 1);
   593                                 glColor4f(1, 1, 1, 1);
   594 							end;
   594                             end;
   595             end;
   595             end;
   596         case Gear^.Kind of
   596         case Gear^.Kind of
   597             vgtSmallDamageTag: DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
   597             vgtSmallDamageTag: DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
   598             vgtSpeechBubble: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
   598             vgtSpeechBubble: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
   599         end;
   599         end;
   600 		Gear:= Gear^.NextGear
   600         Gear:= Gear^.NextGear
   601 		end
   601         end
   602 	end
   602     end
   603 end;
   603 end;
   604 
   604 
   605 procedure AddClouds;
   605 procedure AddClouds;
   606 var i: LongInt;
   606 var i: LongInt;
   607 begin
   607 begin
   609     AddVisualGear( - cScreenWidth + i * ((cScreenWidth * 2 + (LAND_WIDTH+256)) div (cCloudsNumber + 1)), LAND_HEIGHT-1184, vgtCloud)
   609     AddVisualGear( - cScreenWidth + i * ((cScreenWidth * 2 + (LAND_WIDTH+256)) div (cCloudsNumber + 1)), LAND_HEIGHT-1184, vgtCloud)
   610 end;
   610 end;
   611 
   611 
   612 procedure init_uVisualGears;
   612 procedure init_uVisualGears;
   613 begin
   613 begin
   614 	VisualGearsList:= nil;
   614     VisualGearsList:= nil;
   615 end;
   615 end;
   616 
   616 
   617 procedure free_uVisualGears;
   617 procedure free_uVisualGears;
   618 begin
   618 begin
   619 	while VisualGearsList <> nil do DeleteVisualGear(VisualGearsList);
   619     while VisualGearsList <> nil do DeleteVisualGear(VisualGearsList);
   620 end;
   620 end;
   621 
   621 
   622 end.
   622 end.