hedgewars/uVisualGears.pas
changeset 1505 3a96e93572cb
parent 1132 b4c0698fbb6b
child 1642 177b440773de
equal deleted inserted replaced
1504:1603a796f42a 1505:3a96e93572cb
    21 uses SDLh, uConsts, uFloat, GL;
    21 uses SDLh, uConsts, uFloat, GL;
    22 {$INCLUDE options.inc}
    22 {$INCLUDE options.inc}
    23 const AllInactive: boolean = false;
    23 const AllInactive: boolean = false;
    24 
    24 
    25 type PVisualGear = ^TVisualGear;
    25 type PVisualGear = ^TVisualGear;
    26      TVGearStepProcedure = procedure (Gear: PVisualGear; Steps: Longword);
    26 	TVGearStepProcedure = procedure (Gear: PVisualGear; Steps: Longword);
    27      TVisualGear = record
    27 	TVisualGear = record
    28              NextGear, PrevGear: PVisualGear;
    28 		NextGear, PrevGear: PVisualGear;
    29              Frame,
    29 		Frame,
    30              FrameTicks: Longword;
    30 		FrameTicks: Longword;
    31              X : hwFloat;
    31 		X : hwFloat;
    32              Y : hwFloat;
    32 		Y : hwFloat;
    33              dX: hwFloat;
    33 		dX: hwFloat;
    34              dY: hwFloat;
    34 		dY: hwFloat;
    35              mdY: QWord;
    35 		mdY: QWord;
    36              Angle, dAngle: real;
    36 		Angle, dAngle: real;
    37              Kind: TVisualGearType;
    37 		Kind: TVisualGearType;
    38              doStep: TVGearStepProcedure;
    38 		doStep: TVGearStepProcedure;
    39              end;
    39 		Tex: PTexture;
       
    40 		end;
    40 
    41 
    41 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
    42 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
    42 procedure ProcessVisualGears(Steps: Longword);
    43 procedure ProcessVisualGears(Steps: Longword);
    43 procedure DrawVisualGears(Layer: LongWord);
    44 procedure DrawVisualGears(Layer: LongWord);
    44 procedure DeleteVisualGear(Gear: PVisualGear);
    45 procedure DeleteVisualGear(Gear: PVisualGear);
    45 procedure AddClouds;
    46 procedure AddClouds;
       
    47 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
    46 
    48 
    47 var VisualGearsList: PVisualGear = nil;
    49 var VisualGearsList: PVisualGear = nil;
    48     vobFrameTicks, vobFramesCount: Longword;
    50 	vobFrameTicks, vobFramesCount: Longword;
    49     vobVelocity, vobFallSpeed: LongInt;
    51 	vobVelocity, vobFallSpeed: LongInt;
    50 
    52 
    51 implementation
    53 implementation
    52 uses uWorld, uMisc, uStore;
    54 uses uWorld, uMisc, uStore;
    53 const cExplFrameTicks = 110;
    55 const cExplFrameTicks = 110;
    54 
    56 
       
    57 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
       
    58 var s: shortstring;
       
    59 begin
       
    60 if cAltDamage then
       
    61 	with AddVisualGear(X, Y, vgtSmallDamageTag)^ do
       
    62 		begin
       
    63 		str(Damage, s);
       
    64 		Tex:= RenderStringTex(s, Color, fntSmall);
       
    65 		end;
       
    66 end;
       
    67 
       
    68 
    55 // ==================================================================
    69 // ==================================================================
    56 procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
    70 procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
    57 begin
    71 begin
    58 with Gear^ do
    72 with Gear^ do
    59   begin
    73 	begin
    60   inc(FrameTicks, Steps);
    74 	inc(FrameTicks, Steps);
    61   if FrameTicks > vobFrameTicks then
    75 	if FrameTicks > vobFrameTicks then
    62     begin
    76 		begin
    63     dec(FrameTicks, vobFrameTicks);
    77 		dec(FrameTicks, vobFrameTicks);
    64     inc(Frame);
    78 		inc(Frame);
    65     if Frame = vobFramesCount then Frame:= 0
    79 		if Frame = vobFramesCount then Frame:= 0
    66     end
    80 		end
    67   end;
    81 	end;
    68 
    82 
    69 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps;
    83 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps;
    70 Gear^.Y:= Gear^.Y + (Gear^.dY + cGravity * vobFallSpeed) * Steps;
    84 Gear^.Y:= Gear^.Y + (Gear^.dY + cGravity * vobFallSpeed) * Steps;
    71 Gear^.Angle:= Gear^.Angle + Gear^.dAngle * Steps;
    85 Gear^.Angle:= Gear^.Angle + Gear^.dAngle * Steps;
    72 
    86 
   122 	DeleteVisualGear(Gear)
   136 	DeleteVisualGear(Gear)
   123 else
   137 else
   124 	dec(Gear^.FrameTicks, Steps)
   138 	dec(Gear^.FrameTicks, Steps)
   125 end;
   139 end;
   126 
   140 
       
   141 procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword);
       
   142 begin
       
   143 Gear^.Y:= Gear^.Y - _0_02 * Steps;
       
   144 
       
   145 if Gear^.FrameTicks <= Steps then
       
   146 	DeleteVisualGear(Gear)
       
   147 else
       
   148 	dec(Gear^.FrameTicks, Steps)
       
   149 end;
       
   150 
   127 // ==================================================================
   151 // ==================================================================
   128 const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure =
   152 const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure =
   129                         (
   153 		(
   130                           @doStepFlake,
   154 			@doStepFlake,
   131                           @doStepCloud,
   155 			@doStepCloud,
   132                           @doStepExpl,
   156 			@doStepExpl,
   133                           @doStepExpl,
   157 			@doStepExpl,
   134                           @doStepFire
   158 			@doStepFire,
   135                         );
   159 			@doStepSmallDamage
       
   160 		);
   136 
   161 
   137 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
   162 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear;
   138 var Result: PVisualGear;
   163 var Result: PVisualGear;
   139 	t: Longword;
   164 	t: Longword;
   140 	sp: hwFloat;
   165 	sp: hwFloat;
   144 Result^.X:= int2hwFloat(X);
   169 Result^.X:= int2hwFloat(X);
   145 Result^.Y:= int2hwFloat(Y);
   170 Result^.Y:= int2hwFloat(Y);
   146 Result^.Kind := Kind;
   171 Result^.Kind := Kind;
   147 Result^.doStep:= doStepHandlers[Kind];
   172 Result^.doStep:= doStepHandlers[Kind];
   148 
   173 
   149 case Kind of
   174 with Result^ do
   150    vgtFlake: with Result^ do
   175 	case Kind of
   151                begin
   176 	vgtFlake: begin
   152                FrameTicks:= random(vobFrameTicks);
   177 				FrameTicks:= random(vobFrameTicks);
   153                Frame:= random(vobFramesCount);
   178 				Frame:= random(vobFramesCount);
   154                Angle:= random * 360;
   179 				Angle:= random * 360;
   155                dx.isNegative:= random(2) = 0;
   180 				dx.isNegative:= random(2) = 0;
   156                dx.QWordValue:= random(100000000);
   181 				dx.QWordValue:= random(100000000);
   157                dy.isNegative:= false;
   182 				dy.isNegative:= false;
   158                dy.QWordValue:= random(70000000);
   183 				dy.QWordValue:= random(70000000);
   159                dAngle:= (random(2) * 2 - 1) * (1 + random) * vobVelocity / 1000
   184 				dAngle:= (random(2) * 2 - 1) * (1 + random) * vobVelocity / 1000
   160                end;
   185 				end;
   161    vgtCloud: with Result^ do
   186 	vgtCloud: begin
   162                begin
   187 				Frame:= random(4);
   163                Frame:= random(4);
   188 				dx.isNegative:= random(2) = 0;
   164                dx.isNegative:= random(2) = 0;
   189 				dx.QWordValue:= random(214748364);
   165                dx.QWordValue:= random(214748364);
   190 				dy.isNegative:= random(2) = 0;
   166                dy.isNegative:= random(2) = 0;
   191 				dy.QWordValue:= 21474836 + random(64424509);
   167                dy.QWordValue:= 21474836 + random(64424509);
   192 				mdY:= dy.QWordValue
   168                mdY:= dy.QWordValue
   193 				end;
   169                end;
   194 	vgtExplPart,
   170   vgtExplPart,
   195 	vgtExplPart2: begin
   171  vgtExplPart2: with Result^ do
   196 				t:= random(1024);
   172                begin
   197 				sp:= _0_001 * (random(95) + 70);
   173                t:= random(1024);
   198 				dx:= AngleSin(t) * sp;
   174                sp:= _0_001 * (random(95) + 70);
   199 				dx.isNegative:= random(2) = 0;
   175                dx:= AngleSin(t) * sp;
   200 				dy:= AngleCos(t) * sp;
   176                dx.isNegative:= random(2) = 0;
   201 				dy.isNegative:= random(2) = 0;
   177                dy:= AngleCos(t) * sp;
   202 				Frame:= 7 - random(3);
   178                dy.isNegative:= random(2) = 0;
   203 				FrameTicks:= cExplFrameTicks
   179                Frame:= 7 - random(3);
   204 				end;
   180                FrameTicks:= cExplFrameTicks
   205 		vgtFire: begin
   181                end;
   206 				t:= random(1024);
   182       vgtFire: with Result^ do
   207 				sp:= _0_001 * (random(85) + 95);
   183                begin
   208 				dx:= AngleSin(t) * sp;
   184                t:= random(1024);
   209 				dx.isNegative:= random(2) = 0;
   185                sp:= _0_001 * (random(85) + 95);
   210 				dy:= AngleCos(t) * sp;
   186                dx:= AngleSin(t) * sp;
   211 				dy.isNegative:= random(2) = 0;
   187                dx.isNegative:= random(2) = 0;
   212 				FrameTicks:= 650 + random(250);
   188                dy:= AngleCos(t) * sp;
   213 				Frame:= random(8)
   189                dy.isNegative:= random(2) = 0;
   214 				end;
   190                FrameTicks:= 650 + random(250);
   215 	vgtSmallDamageTag: begin
   191                Frame:= random(8)
   216 				Result^.FrameTicks:= 1100
   192                end;
   217 				end;
   193      end;
   218 		end;
   194 
   219 
   195 if VisualGearsList <> nil then
   220 if VisualGearsList <> nil then
   196    begin
   221 	begin
   197    VisualGearsList^.PrevGear:= Result;
   222 	VisualGearsList^.PrevGear:= Result;
   198    Result^.NextGear:= VisualGearsList
   223 	Result^.NextGear:= VisualGearsList
   199    end;
   224 	end;
   200 VisualGearsList:= Result;
   225 VisualGearsList:= Result;
   201 
   226 
   202 AddVisualGear:= Result
   227 AddVisualGear:= Result
   203 end;
   228 end;
   204 
   229 
   205 procedure DeleteVisualGear(Gear: PVisualGear);
   230 procedure DeleteVisualGear(Gear: PVisualGear);
   206 begin
   231 begin
       
   232 if Gear^.Tex <> nil then
       
   233 	FreeTexture(Gear^.Tex);
       
   234 
   207 if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   235 if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   208 if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
   236 if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
   209    else VisualGearsList:= Gear^.NextGear;
   237    else VisualGearsList:= Gear^.NextGear;
   210 
   238 
   211 Dispose(Gear)
   239 Dispose(Gear)
   245 		begin
   273 		begin
   246 		case Gear^.Kind of
   274 		case Gear^.Kind of
   247 			vgtExplPart: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 7 - Gear^.Frame);
   275 			vgtExplPart: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 7 - Gear^.Frame);
   248 			vgtExplPart2: DrawSprite(sprExplPart2, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 7 - Gear^.Frame);
   276 			vgtExplPart2: DrawSprite(sprExplPart2, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 7 - Gear^.Frame);
   249 			vgtFire: DrawSprite(sprFlame, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, (RealTicks div 64 + Gear^.Frame) mod 8);
   277 			vgtFire: DrawSprite(sprFlame, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, (RealTicks div 64 + Gear^.Frame) mod 8);
       
   278 			vgtSmallDamageTag: DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
   250 			end;
   279 			end;
   251 		Gear:= Gear^.NextGear
   280 		Gear:= Gear^.NextGear
   252 		end
   281 		end
   253 	end
   282 	end
   254 end;
   283 end;