# HG changeset patch # User nemo # Date 1457040965 18000 # Node ID c453620cc6d60fd012cb110c3126f6f1b3c2d0e3 # Parent 7c8fd2f66e9b743553bce3833604d8ab667c82f4 Break up the hog/object collision. Currently is $7F, allowing 128 overlapping objects accurately. Breaking it up into 15 for hogs, 7 for other objects. I'm thinking the overall accuracy should be just fine as far as people noticing even with a ton of overlapping hogs, and this way we can tell the difference between a hog and "something else". For experiment and rope-breaking purposes, make rope pass through hogs. diff -r 7c8fd2f66e9b -r c453620cc6d6 hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Thu Mar 03 15:41:53 2016 -0500 +++ b/hedgewars/uCollisions.pas Thu Mar 03 16:36:05 2016 -0500 @@ -85,7 +85,7 @@ X:= hwRound(Gear^.X); Y:= hwRound(Gear^.Y); Radius:= Gear^.Radius; - ChangeRoundInLand(X, Y, Radius - 1, true, (Gear = CurrentHedgehog^.Gear) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen = 0))); + ChangeRoundInLand(X, Y, Radius - 1, true, ((CurrentHedgehog <> nil) and (Gear = CurrentHedgehog^.Gear)) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen = 0)), Gear^.Kind = gtHedgehog); cGear:= Gear end; Gear^.CollisionIndex:= Count; @@ -97,7 +97,7 @@ if Gear^.CollisionIndex >= 0 then begin with cinfos[Gear^.CollisionIndex] do - ChangeRoundInLand(X, Y, Radius - 1, false, ((CurrentHedgehog <> nil) and (Gear = CurrentHedgehog^.Gear)) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen = 0))); + ChangeRoundInLand(X, Y, Radius - 1, false, ((CurrentHedgehog <> nil) and (Gear = CurrentHedgehog^.Gear)) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen = 0)), Gear^.Kind = gtHedgehog); cinfos[Gear^.CollisionIndex]:= cinfos[Pred(Count)]; cinfos[Gear^.CollisionIndex].cGear^.CollisionIndex:= Gear^.CollisionIndex; Gear^.CollisionIndex:= -1; diff -r 7c8fd2f66e9b -r c453620cc6d6 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Thu Mar 03 15:41:53 2016 -0500 +++ b/hedgewars/uConsts.pas Thu Mar 03 16:36:05 2016 -0500 @@ -115,13 +115,24 @@ lfCurrentHog = $0080; // CurrentHog. It is also used to flag crates, for convenience of AI. Since an active hog would instantly collect the crate, this does not impact play lfNotCurrentMask = $FF7F; // inverse of above. frequently used - lfObjMask = $007F; // lower 7 bits used for hogs + lfObjMask = $007F; // lower 7 bits used for hogs and explosives and mines lfNotObjMask = $FF80; // inverse of above. + +// breaking up hogs would makes it easier to differentiate +// colliding with a hog from colliding with other things +// if overlapping hogs are less common than objects, the division can be altered. +// 3 bits for objects, 4 for hogs, that is, overlap 7 barrels/mines before possible dents, and 15 hogs. + lfHHMask = $000F; // lower 4 bits used only for hogs + lfNotHHObjMask = $0070; // next 3 bits used for non-hog things + lfNotHHObjShift = 4; + lfNotHHObjSize = lfNotHHObjMask shr lfNotHHObjShift; + // lower byte is for objects. // consists of 0-127 counted for object checkins and $80 as a bit flag for current hog. lfAllObjMask = $00FF; // lfCurrentHog or lfObjMask + cMaxPower = 1500; cMaxAngle = 2048; cPowerDivisor = 1500; diff -r 7c8fd2f66e9b -r c453620cc6d6 hedgewars/uGearsHandlersRope.pas --- a/hedgewars/uGearsHandlersRope.pas Thu Mar 03 15:41:53 2016 -0500 +++ b/hedgewars/uGearsHandlersRope.pas Thu Mar 03 16:36:05 2016 -0500 @@ -498,7 +498,7 @@ end; if Gear^.Elasticity < _20 then Gear^.CollisionMask:= lfLandMask - else Gear^.CollisionMask:= lfNotCurrentMask; + else Gear^.CollisionMask:= lfNotObjMask or lfNotHHObjMask; CheckCollision(Gear); if (Gear^.State and gstCollision) <> 0 then diff -r 7c8fd2f66e9b -r c453620cc6d6 hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Thu Mar 03 15:41:53 2016 -0500 +++ b/hedgewars/uGearsList.pas Thu Mar 03 16:36:05 2016 -0500 @@ -407,6 +407,7 @@ RopePoints.Count:= 0; gear^.Tint:= $D8D8D8FF; gear^.Tag:= 0; // normal rope render + gear^.CollisionMask:= lfNotObjMask or lfNotHHObjMask; end; gtMine: begin gear^.ImpactSound:= sndMineImpact; diff -r 7c8fd2f66e9b -r c453620cc6d6 hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Thu Mar 03 15:41:53 2016 -0500 +++ b/hedgewars/uLandGraphics.pas Thu Mar 03 16:36:05 2016 -0500 @@ -23,7 +23,7 @@ uses uFloat, uConsts, uTypes, Math, uRenderUtils; type - fillType = (nullPixel, backgroundPixel, ebcPixel, icePixel, setNotCurrentMask, changePixelSetNotCurrent, setCurrentHog, changePixelNotSetNotCurrent); + fillType = (nullPixel, backgroundPixel, ebcPixel, icePixel, addNotHHObj, removeNotHHObj, addHH, removeHH, setCurrentHog, removeCurrentHog); type TRangeArray = array[0..31] of record Left, Right: LongInt; @@ -41,7 +41,7 @@ procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); function FillRoundInLand(X, Y, Radius: LongInt; Value: Longword): Longword; function FillRoundInLandFT(X, Y, Radius: LongInt; fill: fillType): Longword; -procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean); +procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent, isHH: boolean); function LandBackPixel(x, y: LongInt): LongWord; procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword); function DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword): Longword; @@ -209,15 +209,28 @@ calculatePixelsCoordinates(i, y, px, py); DrawPixelIce(i, y, px, py); end; - setNotCurrentMask: + addNotHHObj: + for i:= fromPix to toPix do + begin + if Land[y, i] and lfNotHHObjMask shr lfNotHHObjShift < lfNotHHObjSize then + Land[y, i]:= (Land[y, i] and not lfNotHHObjMask) or ((Land[y, i] and lfNotHHObjMask shr lfNotHHObjShift + 1) shl lfNotHHObjShift); + end; + removeNotHHObj: for i:= fromPix to toPix do begin - Land[y, i]:= Land[y, i] and lfNotCurrentMask; + if Land[y, i] and lfNotHHObjMask <> 0 then + Land[y, i]:= (Land[y, i] and not lfNotHHObjMask) or ((Land[y, i] and lfNotHHObjMask shr lfNotHHObjShift - 1) shl lfNotHHObjShift); end; - changePixelSetNotCurrent: + addHH: for i:= fromPix to toPix do begin - if Land[y, i] and lfObjMask > 0 then + if Land[y, i] and lfHHMask < lfHHMask then + Land[y, i]:= Land[y, i] + 1 + end; + removeHH: + for i:= fromPix to toPix do + begin + if Land[y, i] and lfHHMask > 0 then Land[y, i]:= Land[y, i] - 1; end; setCurrentHog: @@ -225,11 +238,10 @@ begin Land[y, i]:= Land[y, i] or lfCurrentHog end; - changePixelNotSetNotCurrent: + removeCurrentHog: for i:= fromPix to toPix do begin - if Land[y, i] and lfObjMask < lfObjMask then - Land[y, i]:= Land[y, i] + 1 + Land[y, i]:= Land[y, i] and lfNotCurrentMask; end; end; end; @@ -360,16 +372,20 @@ inc(FillRoundInLand, FillCircleLines(x, y, dx, dy, Value)); end; -procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean); +procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent, isHH: boolean); begin if not doSet and isCurrent then - FillRoundInLandFT(X, Y, Radius, setNotCurrentMask) -else if not doSet and (not IsCurrent) then - FillRoundInLandFT(X, Y, Radius, changePixelSetNotCurrent) + FillRoundInLandFT(X, Y, Radius, removeCurrentHog) +else if (not doSet) and (not IsCurrent) and isHH then + FillRoundInLandFT(X, Y, Radius, removeHH) +else if (not doSet) and (not IsCurrent) and (not isHH) then + FillRoundInLandFT(X, Y, Radius, removeNotHHObj) else if doSet and IsCurrent then FillRoundInLandFT(X, Y, Radius, setCurrentHog) -else if doSet and (not IsCurrent) then - FillRoundInLandFT(X, Y, Radius, changePixelNotSetNotCurrent); +else if doSet and (not IsCurrent) and isHH then + FillRoundInLandFT(X, Y, Radius, addHH) +else if doSet and (not IsCurrent) and (not isHH) then + FillRoundInLandFT(X, Y, Radius, addNotHHObj); end; procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);