A simple hat reservation mechanism. Can be worked around with a little effort, but to make it useful, you'd have to get everyone you played with to work around it too. Quite a bit of effort for a small reward feature.
(* * Hedgewars, a free turn based strategy game * Copyright (c) 2007, 2008 Andrey Korotaev <unC0Rr@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *){$INCLUDE "options.inc"}unit uFloat;interface{$IFDEF FPC}{$IFDEF ENDIAN_LITTLE}type hwFloat = record isNegative: boolean; case byte of 0: (Frac, Round: Longword); 1: (QWordValue : QWord); end;{$ELSE}type hwFloat = record isNegative: boolean; case byte of 0: (Round, Frac: Longword); 1: (QWordValue : QWord); end;{$ENDIF}function int2hwFloat (const i: LongInt) : hwFloat;operator + (const z1, z2: hwFloat) z : hwFloat;operator - (const z1, z2: hwFloat) z : hwFloat;operator - (const z1: hwFloat) z : hwFloat;operator * (const z1, z2: hwFloat) z : hwFloat;operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat;operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat;operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat;operator < (const z1, z2: hwFloat) b : boolean;operator > (const z1, z2: hwFloat) b : boolean;function cstr(const z: hwFloat): string;function hwRound(const t: hwFloat): LongInt;function hwAbs(const t: hwFloat): hwFloat;function hwSqr(const t: hwFloat): hwFloat;function hwSqrt(const t: hwFloat): hwFloat;function Distance(const dx, dy: hwFloat): hwFloat;function DistanceI(const dx, dy: LongInt): hwFloat;function AngleSin(const Angle: Longword): hwFloat;function AngleCos(const Angle: Longword): hwFloat;function SignAs(const num, signum: hwFloat): hwFloat;{$IFDEF FPC}{$J-}{$ENDIF}{$WARNINGS OFF}const _1div1024: hwFloat = (isNegative: false; QWordValue: 4194304); _1div10000: hwFloat = (isNegative: false; QWordValue: 429496); _1div50000: hwFloat = (isNegative: false; QWordValue: 85899); _1div100000: hwFloat = (isNegative: false; QWordValue: 42950); _1div3: hwFloat = (isNegative: false; QWordValue: 1431655766); hwPi: hwFloat = (isNegative: false; QWordValue: 13493037704); _0_000004: hwFloat = (isNegative: false; QWordValue: 17179); _0_0002: hwFloat = (isNegative: false; QWordValue: 858993); _0_0005: hwFloat = (isNegative: false; QWordValue: 2147484); _0_001: hwFloat = (isNegative: false; QWordValue: 4294967); _0_003: hwFloat = (isNegative: false; QWordValue: 12884902); _0_004: hwFloat = (isNegative: false; QWordValue: 17179869); _0_005: hwFloat = (isNegative: false; QWordValue: 21474836); _0_01: hwFloat = (isNegative: false; QWordValue: 42949673); _0_02: hwFloat = (isNegative: false; QWordValue: 85899345); _0_03: hwFloat = (isNegative: false; QWordValue: 128849018); _0_08: hwFloat = (isNegative: false; QWordValue: 343597383); _0_1: hwFloat = (isNegative: false; QWordValue: 429496730); _0_15: hwFloat = (isNegative: false; QWordValue: 644245094); _0_2: hwFloat = (isNegative: false; QWordValue: 858993459); _0_25: hwFloat = (isNegative: false; QWordValue: 1073741824); _0_3: hwFloat = (isNegative: false; QWordValue: 1288490189); _0_35: hwFloat = (isNegative: false; QWordValue: 1503238553); _0_375: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 8); _0_39: hwFloat = (isNegative: false; QWordValue: 1675037245); _0_4: hwFloat = (isNegative: false; QWordValue: 1717986918); _0_45: hwFloat = (isNegative: false; QWordValue: 1932735283); _0_5: hwFloat = (isNegative: false; QWordValue: 2147483648); _0_55: hwFloat = (isNegative: false; QWordValue: 2362232012); _0_6: hwFloat = (isNegative: false; QWordValue: 2576980377); _0_7: hwFloat = (isNegative: false; QWordValue: 3006477107); _0_8: hwFloat = (isNegative: false; QWordValue: 3435973837); _0_84: hwFloat = (isNegative: false; QWordValue: 3607772528); _0_87: hwFloat = (isNegative: false; QWordValue: 3736621547); _0_9: hwFloat = (isNegative: false; QWordValue: 3865470566); _0_93: hwFloat = (isNegative: false; QWordValue: 3994319585); _0_96: hwFloat = (isNegative: false; QWordValue: 4123168604); _0_995: hwFloat = (isNegative: false; QWordValue: 4273492459); _0_998: hwFloat = (isNegative: false; QWordValue: 4294967296); _0_999: hwFloat = (isNegative: false; QWordValue: 4290672328); _1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); _0: hwFloat = (isNegative: false; QWordValue: 0); _1: hwFloat = (isNegative: false; QWordValue: 4294967296); _1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); _2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); _3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); _4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); _5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); _6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); _10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); _16: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16); _19: hwFloat = (isNegative: false; QWordValue: 4294967296 * 19); _20: hwFloat = (isNegative: false; QWordValue: 4294967296 * 20); _0_3x70: hwFloat = (isNegative: false; QWordValue: 1288490189 * 70); _25: hwFloat = (isNegative: false; QWordValue: 4294967296 * 25); _30: hwFloat = (isNegative: false; QWordValue: 4294967296 * 30); _128: hwFloat = (isNegative: false; QWordValue: 4294967296 * 128); _256: hwFloat = (isNegative: false; QWordValue: 4294967296 * 256); _300: hwFloat = (isNegative: false; QWordValue: 4294967296 * 300); _450: hwFloat = (isNegative: false; QWordValue: 4294967296 * 450); _1024: hwFloat = (isNegative: false; QWordValue: 4294967296 * 1024); _2048: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2048); _4096: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4096); _10000: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10000); cLittle: hwFloat = (isNegative: false; QWordValue: 1); cHHKick: hwFloat = (isNegative: false; QWordValue: 42949673); // _0_01{$WARNINGS ON}{$ENDIF}{$IFNDEF FPC}type hwFloat = Extended;{$ENDIF}implementationuses uConsts, uMisc;{$IFDEF FPC}function int2hwFloat (const i: LongInt) : hwFloat;beginint2hwFloat.isNegative:= i < 0;int2hwFloat.Round:= abs(i);int2hwFloat.Frac:= 0end;operator + (const z1, z2: hwFloat) z : hwFloat;beginif z1.isNegative = z2.isNegative then begin z.isNegative:= z1.isNegative; z.QWordValue:= z1.QWordValue + z2.QWordValue endelse if z1.QWordValue > z2.QWordValue then begin z.isNegative:= z1.isNegative; z.QWordValue:= z1.QWordValue - z2.QWordValue end else begin z.isNegative:= z2.isNegative; z.QWordValue:= z2.QWordValue - z1.QWordValue endend;operator - (const z1, z2: hwFloat) z : hwFloat;beginif z1.isNegative = z2.isNegative then if z1.QWordValue > z2.QWordValue then begin z.isNegative:= z1.isNegative; z.QWordValue:= z1.QWordValue - z2.QWordValue end else begin z.isNegative:= not z2.isNegative; z.QWordValue:= z2.QWordValue - z1.QWordValue endelse begin z.isNegative:= z1.isNegative; z.QWordValue:= z1.QWordValue + z2.QWordValue endend;operator - (const z1: hwFloat) z : hwFloat;beginz:= z1;z.isNegative:= not z.isNegativeend;operator * (const z1, z2: hwFloat) z : hwFloat;beginz.isNegative:= z1.isNegative xor z2.isNegative;z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32);z.Round:= z.Round + QWord(z1.Round) * z2.Round;end;operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat;beginz.isNegative:= z1.isNegative xor (z2 < 0);z.QWordValue:= z1.QWordValue * abs(z2)end;operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat;var t: hwFloat;beginz.isNegative:= z1.isNegative xor z2.isNegative;z.Round:= z1.QWordValue div z2.QWordValue;t:= z1 - z2 * z.Round;if t.QWordValue = 0 then z.Frac:= 0else begin while ((t.QWordValue and $8000000000000000) = 0) and ((z2.QWordValue and $8000000000000000) = 0) do begin t.QWordValue:= t.QWordValue shl 1; z2.QWordValue:= z2.QWordValue shl 1 end; if z2.Round > 0 then z.Frac:= (t.QWordValue) div (z2.Round) else z.Frac:= 0 endend;operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat;beginz.isNegative:= z1.isNegative xor (z2 < 0);z.QWordValue:= z1.QWordValue div abs(z2)end;operator < (const z1, z2: hwFloat) b : boolean;beginif z1.isNegative xor z2.isNegative then b:= z1.isNegativeelse if z1.QWordValue = z2.QWordValue then b:= false else b:= (z1.QWordValue < z2.QWordValue) xor z1.isNegativeend;operator > (const z1, z2: hwFloat) b : boolean;beginif z1.isNegative xor z2.isNegative then b:= z2.isNegativeelse if z1.QWordValue = z2.QWordValue then b:= false else b:= (z1.QWordValue > z2.QWordValue) xor z2.isNegativeend;function cstr(const z: hwFloat): string;var tmpstr: string;beginstr(z.Round, cstr);if z.Frac <> 0 then begin str(z.Frac / $100000000:1:15, tmpstr); delete(tmpstr, 1, 2); cstr:= cstr + '.' + tmpstr end;if z.isNegative then cstr:= '-' + cstrend;function hwRound(const t: hwFloat): LongInt;beginif t.isNegative then hwRound:= -(t.Round and $7FFFFFFF) else hwRound:= t.Round and $7FFFFFFFend;function hwAbs(const t: hwFloat): hwFloat;beginhwAbs:= t;hwAbs.isNegative:= falseend;function hwSqr(const t: hwFloat): hwFloat;beginhwSqr.isNegative:= false;hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32);end;function hwSqrt(const t: hwFloat): hwFloat;var l, r: QWord; c: hwFloat;beginhwSqrt.isNegative:= false;if t.Round = 0 then begin l:= t.QWordValue; r:= $100000000 end else begin l:= $100000000; r:= t.QWordValue div 2 + $80000000; // r:= t / 2 + 0.5 if r > $FFFFFFFFFFFF then r:= $FFFFFFFFFFFF end;repeat c.QWordValue:= (l + r) div 2; if hwSqr(c).QWordValue > t.QWordValue then r:= c.QWordValue else l:= c.QWordValueuntil r - l <= 1;hwSqrt.QWordValue:= lend;function Distance(const dx, dy: hwFloat): hwFloat;beginDistance:= hwSqrt(hwSqr(dx) + hwSqr(dy))end;function DistanceI(const dx, dy: LongInt): hwFloat;beginDistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy)))end;function SignAs(const num, signum: hwFloat): hwFloat;beginSignAs.QWordValue:= num.QWordValue;SignAs.isNegative:= signum.isNegativeend;{$INCLUDE "SinTable.inc"}function AngleSin(const Angle: Longword): hwFloat;begin{$IFDEF DEBUGFILE}TryDo((Angle >= 0) and (Angle <= 2048), 'Sin param exceeds limits', true);{$ENDIF}AngleSin.isNegative:= false;if Angle < 1024 then AngleSin.QWordValue:= SinTable[Angle] else AngleSin.QWordValue:= SinTable[2048 - Angle]end;function AngleCos(const Angle: Longword): hwFloat;begin{$IFDEF DEBUGFILE}TryDo((Angle >= 0) and (Angle <= 2048), 'Cos param exceeds limits', true);{$ENDIF}AngleCos.isNegative:= Angle > 1024;if Angle < 1024 then AngleCos.QWordValue:= SinTable[1024 - Angle] else AngleCos.QWordValue:= SinTable[Angle - 1024]end;{$ENDIF}end.