# HG changeset patch # User unc0rr # Date 1259513764 0 # Node ID 0e1208e92dfeee9316fe6fbcb85e8f3bd2176f46 # Parent 6a11856338727a1042edc19ab0be6f8b7070a2ee Smaxx patch with tuning by me: - hogs might worry/panic if they're next to explosives (grenade, dynamite, etc.) - play sndVaporice for each fire extinguished only once (not 3 times) - allow "on attack" voices/sounds for weapons (similar to water melon bomb) - allow one voice/sound to be played during emotes - print protocol version in version info (console) - rope sounds (disabled atm) - landscape background - optimized/rewrote explosion drawing - fixed "StopSound" called with an inactive sound to stop some random sound - disabled npott diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/GSHandlers.inc Sun Nov 29 16:56:04 2009 +0000 @@ -16,6 +16,32 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) +procedure makeHogsWorry(x, y: hwFloat; r: LongInt); +var gi: PGear; + d: LongInt; +begin + gi:= GearsList; + while gi <> nil do + begin + d:= r - hwRound(Distance(gi^.X - x, gi^.Y - y)); + if (d > 1) and (gi^.Kind = gtHedgehog) and not gi^.Invulnerable and (GetRandom(2) = 0) then + begin + if (CurrentHedgehog^.Gear = gi) then + PlaySound(sndOops, false, PHedgehog(gi^.Hedgehog)^.Team^.voicepack) + else + begin + if (gi^.State and gstMoving) = 0 then + gi^.State:= gi^.State or gstLoser; + if d > r div 2 then + PlaySound(sndNooo, false, PHedgehog(gi^.Hedgehog)^.Team^.voicepack) + else + PlaySound(sndUhOh, false, PHedgehog(gi^.Hedgehog)^.Team^.voicepack); + end; + end; + gi:= gi^.NextGear + end; +end; +//////////////////////////////////////////////////////////////////////////////// procedure doStepDrowningGear(Gear: PGear); forward; function CheckGearDrowning(Gear: PGear): boolean; @@ -161,6 +187,13 @@ doStepFallingGear(Gear); dec(Gear^.Timer); +if Gear^.Timer = 1000 then // might need adjustments + case Gear^.Kind of + gtAmmo_Bomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); + gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20); + gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75); + gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); + end; if Gear^.Timer = 0 then begin case Gear^.Kind of @@ -251,7 +284,6 @@ procedure doStepWatermelon(Gear: PGear); begin AllInactive:= false; -PlaySound(sndMelon, false, nil); Gear^.doStep:= @doStepBomb end; @@ -1157,6 +1189,8 @@ doStepFallingGear(Gear); AllInactive:= false; if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); +if Gear^.Timer = 1000 then // might need better timing + makeHogsWorry(Gear^.X, Gear^.Y, 75); if Gear^.Timer = 0 then begin doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); @@ -1323,10 +1357,8 @@ if (hwRound(Gear^.Y) > cWaterLine) then begin for i:= 0 to 3 do - begin AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 16 + Random(16), vgtSteam); - PlaySound(sndVaporize, false, nil); - end; + PlaySound(sndVaporize, false, nil); DeleteGear(Gear); exit end @@ -1529,7 +1561,6 @@ Gear^.Health:= 6; Gear^.doStep:= @doStepAirAttackWork; -PlaySound(sndIncoming, false, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) end; //////////////////////////////////////////////////////////////////////////////// @@ -2422,6 +2453,7 @@ end end; +//////////////////////////////////////////////////////////////////////////////// procedure doStepJetpack(Gear: PGear); var HHGear: PGear; begin diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/HHHandlers.inc --- a/hedgewars/HHHandlers.inc Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/HHHandlers.inc Sun Nov 29 16:56:04 2009 +0000 @@ -136,6 +136,8 @@ yy:= -AngleCos(Angle); if ((Gear^.State and gstHHHJump) <> 0) then xx:= - xx; + if Ammo^[CurSlot, CurAmmo].AttackVoice <> sndNone then + PlaySound(Ammo^[CurSlot, CurAmmo].AttackVoice, false, CurrentTeam^.voicepack); case Ammo^[CurSlot, CurAmmo].AmmoType of amGrenade: FollowGear:= AddGear(hwRound(X), hwRound(Y), gtAmmo_Bomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); amMolotov: FollowGear:= AddGear(hwRound(X), hwRound(Y), gtMolotov, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); @@ -149,16 +151,10 @@ amPickHammer: CurAmmoGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + cHHRadius, gtPickHammer, 0, _0, _0, 0); amSkip: ParseCommand('/skip', true); amRope: CurAmmoGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtRope, 0, xx, yy, 0); - amMine: begin - AddGear(hwRound(X) + hwSign(dX) * 7, hwRound(Y), gtMine, 0, SignAs(_0_02, dX), _0, 3000); - PlaySound(sndLaugh, false, CurrentTeam^.voicepack) - end; + amMine: AddGear(hwRound(X) + hwSign(dX) * 7, hwRound(Y), gtMine, 0, SignAs(_0_02, dX), _0, 3000); amDEagle: CurAmmoGear:= AddGear(hwRound(X + xx * cHHRadius), hwRound(Y + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0); amSniperRifle: CurAmmoGear:= AddGear(hwRound(X + xx * cHHRadius), hwRound(Y + yy * cHHRadius), gtSniperRifleShot, 0, xx * _0_5, yy * _0_5, 0); - amDynamite: begin - AddGear(hwRound(X) + hwSign(dX) * 7, hwRound(Y), gtDynamite, 0, SignAs(_0_03, dX), _0, 5000); - PlaySound(sndLaugh, false, CurrentTeam^.voicepack) - end; + amDynamite: AddGear(hwRound(X) + hwSign(dX) * 7, hwRound(Y), gtDynamite, 0, SignAs(_0_03, dX), _0, 5000); amFirePunch: CurAmmoGear:= AddGear(hwRound(X) + hwSign(dX) * 10, hwRound(Y), gtFirePunch, 0, xx, _0, 0); amWhip: begin CurAmmoGear:= AddGear(hwRound(X) + hwSign(dX) * 10, hwRound(Y), gtWhip, 0, SignAs(_1, dX), - _0_8, 0); @@ -184,10 +180,7 @@ PlaySound(sndRCPlane, true, nil) end; amKamikaze: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0); - amCake: begin - CurAmmoGear:= AddGear(hwRound(X) + hwSign(dX) * 3, hwRound(Y), gtCake, 0, xx, _0, 0); - PlaySound(sndLaugh, false, CurrentTeam^.voicepack) - end; + amCake: CurAmmoGear:= AddGear(hwRound(X) + hwSign(dX) * 3, hwRound(Y), gtCake, 0, xx, _0, 0); amSeduction: CurAmmoGear:= AddGear(hwRound(X + xx * cHHRadius * 2), hwRound(Y + yy * cHHRadius * 2), gtSeduction, 0, xx * _0_4, yy * _0_4, 0); amWatermelon: FollowGear:= AddGear(hwRound(X), hwRound(Y), gtWatermelon, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, Ammo^[CurSlot, CurAmmo].Timer); amHellishBomb: FollowGear:= AddGear(hwRound(X), hwRound(Y), gtHellishBomb, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); @@ -603,6 +596,7 @@ if (Gear^.State and gstAnimation) <> 0 then begin Gear^.Message:= 0; + if (Gear^.Pos = Wavez[TWave(Gear^.Tag)].VoiceDelay) and (Gear^.Timer = 0) then PlaySound(Wavez[TWave(Gear^.Tag)].Voice, false, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); inc(Gear^.Timer); if Gear^.Timer = Wavez[TWave(Gear^.Tag)].Interval then begin diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/hwengine.pas Sun Nov 29 16:56:04 2009 +0000 @@ -627,7 +627,7 @@ //////////////////////////////////////////////////////////////////////////////// begin -WriteLnToConsole('Hedgewars ' + cVersionString + ' engine'); +WriteLnToConsole('Hedgewars ' + cVersionString + ' engine (' + inttostr(cNetProtoVersion) + ')'); GetParams; // FIXME - hack in font with support for CJK if (cLocaleFName = 'zh_CN.txt') or (cLocaleFName = 'zh_TW.txt') or (cLocaleFName = 'ja.txt') then diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/tunsetborder.inc --- a/hedgewars/tunsetborder.inc Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/tunsetborder.inc Sun Nov 29 16:56:04 2009 +0000 @@ -16,12 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) - begin - X:= X + dX; - Y:= Y + dY; - tx:= hwRound(X); - ty:= hwRound(Y); - if ((ty and LAND_HEIGHT_MASK) = 0) and - ((tx and LAND_WIDTH_MASK) = 0) and - (Land[ty, tx] = COLOR_LAND) then LandPixels[ty, tx]:= cExplosionBorderColor - end; +begin +X:= X + dX; +Y:= Y + dY; +tx:= hwRound(X); +ty:= hwRound(Y); +if ((ty and LAND_HEIGHT_MASK) = 0) and + ((tx and LAND_WIDTH_MASK) = 0) and + ((Land[ty, tx] = COLOR_LAND) or (Land[ty, tx] = COLOR_OBJECT)) then LandPixels[ty, tx]:= cExplosionBorderColor +end; diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uConsts.pas Sun Nov 29 16:56:04 2009 +0000 @@ -84,7 +84,8 @@ TGearsType = set of TGearType; - TSound = (sndGrenadeImpact, sndExplosion, sndThrowPowerUp, sndThrowRelease, + TSound = (sndNone, + sndGrenadeImpact, sndExplosion, sndThrowPowerUp, sndThrowRelease, sndSplash, sndShotgunReload, sndShotgunFire, sndGraveImpact, sndMineTick, sndPickhammer, sndGun, sndUFO, sndJump1, sndJump2, sndJump3, sndYesSir, sndLaugh, sndIllGetYou, sndIncoming, @@ -96,7 +97,9 @@ sndMelon, sndHellish, sndYoohoo, sndRCPlane, sndWhipCrack, sndRideOfTheValkyries, sndDenied, sndPlaced, sndBaseballBat, sndVaporize, sndWarp, sndSuddenDeath, sndMortar, sndShutter, - sndHomerun, sndMolotov); + sndHomerun, sndMolotov, sndWalking, sndCover, sndUhOh, + sndOops, sndNooo, sndHello, sndRopeShot, sndRopeAttach, + sndRopeRelease); TAmmoType = (amNothing, amGrenade, amClusterBomb, amBazooka, amUFO, amShotgun, amPickHammer, amSkip, amRope, amMine, amDEagle, amDynamite, amFirePunch, amWhip, @@ -131,6 +134,7 @@ Timer: LongWord; Pos: LongWord; AmmoType: TAmmoType; + AttackVoice: TSound; end; TVertex2f = record @@ -201,6 +205,7 @@ COLOR_LAND = $FFFF; // white COLOR_INDESTRUCTIBLE = $88FF; // red + COLOR_OBJECT = $44FF; // no idea // some opengl headers do not have these macros GL_BGR = $80E0; @@ -337,7 +342,7 @@ htHealth = $04; htTransparent = $80; - cTagsMasks : array[0..7] of byte = ( + cTagsMasks : array[0..7] of byte = ( htTeamName or htName or htHealth, htName or htHealth, htHealth, @@ -643,20 +648,23 @@ FramesCount: Longword; Interval: Longword; cmd: String[20]; + Voice: TSound; + VoiceDelay: ShortInt; end = ( - (Sprite: sprKowtow; FramesCount: 12; Interval: 125; cmd: '/rollup'), - (Sprite: sprSad; FramesCount: 14; Interval: 125; cmd: '/sad'), - (Sprite: sprWave; FramesCount: 16; Interval: 125; cmd: '/wave'), - (Sprite: sprHurrah; FramesCount: 14; Interval: 125; cmd: '/hurrah'), - (Sprite: sprLemonade; FramesCount: 24; Interval: 125; cmd: '/ilovelotsoflemonade'), - (Sprite: sprShrug; FramesCount: 24; Interval: 125; cmd: '/shrug'), - (Sprite: sprJuggle; FramesCount: 49; Interval: 38; cmd: '/juggle') + (Sprite: sprKowtow; FramesCount: 12; Interval: 125; cmd: '/rollup'; Voice: sndNone; VoiceDelay: 0), + (Sprite: sprSad; FramesCount: 14; Interval: 125; cmd: '/sad'; Voice: sndNone; VoiceDelay: 0), + (Sprite: sprWave; FramesCount: 16; Interval: 125; cmd: '/wave'; Voice: sndHello; VoiceDelay: 5), + (Sprite: sprHurrah; FramesCount: 14; Interval: 125; cmd: '/hurrah'; Voice: sndNone; VoiceDelay: 0), + (Sprite: sprLemonade; FramesCount: 24; Interval: 125; cmd: '/ilovelotsoflemonade'; Voice: sndNone; VoiceDelay: 0), + (Sprite: sprShrug; FramesCount: 24; Interval: 125; cmd: '/shrug'; Voice: sndNone; VoiceDelay: 0), + (Sprite: sprJuggle; FramesCount: 49; Interval: 38; cmd: '/juggle'; Voice: sndNone; VoiceDelay: 0) ); Soundz: array[TSound] of record FileName: String[25]; Path : TPathType; end = ( + (FileName: ''; Path: ptNone ),// sndNone (FileName: 'grenadeimpact.ogg'; Path: ptSounds),// sndGrenadeImpact (FileName: 'explosion.ogg'; Path: ptSounds),// sndExplosion (FileName: 'throwpowerup.ogg'; Path: ptSounds),// sndThrowPowerUp @@ -715,7 +723,16 @@ (FileName: 'mortar.ogg'; Path: ptSounds),// sndMortar (FileName: 'shutterclick.ogg'; Path: ptSounds),// sndShutter (FileName: 'homerun.ogg'; Path: ptSounds),// sndHomerun - (FileName: 'molotov.ogg'; Path: ptSounds) // sndMolotov + (FileName: 'molotov.ogg'; Path: ptSounds),// sndMolotov + (FileName: 'walking.ogg'; Path: ptSounds),// sndWalking + (FileName: 'Takecover.ogg'; Path: ptVoices),// sndCover + (FileName: 'Uh-oh.ogg'; Path: ptVoices),// sndUhOh + (FileName: 'Oops.ogg'; Path: ptVoices),// sndOops + (FileName: 'Nooo.ogg'; Path: ptVoices),// sndNooo + (FileName: 'Hello.ogg'; Path: ptVoices),// sndHello + (FileName: ''; Path: ptSounds),// sndRopeShot + (FileName: ''; Path: ptSounds),// sndRopeAttach + (FileName: ''; Path: ptSounds) // sndRopeRelease ); Ammoz: array [TAmmoType] of record @@ -742,7 +759,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amNothing); + AmmoType: amNothing; + AttackVoice: sndNone); Slot: 0; TimeAfterTurn: 0; minAngle: 0; @@ -762,7 +780,8 @@ NumPerTurn: 0; Timer: 3000; Pos: 0; - AmmoType: amGrenade); + AmmoType: amGrenade; + AttackVoice: sndCover); Slot: 1; TimeAfterTurn: 3000; minAngle: 0; @@ -782,7 +801,8 @@ NumPerTurn: 0; Timer: 3000; Pos: 0; - AmmoType: amClusterBomb); + AmmoType: amClusterBomb; + AttackVoice: sndCover); Slot: 1; TimeAfterTurn: 3000; minAngle: 0; @@ -801,7 +821,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amBazooka); + AmmoType: amBazooka; + AttackVoice: sndNone); Slot: 0; TimeAfterTurn: 3000; minAngle: 0; @@ -821,7 +842,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amUFO); + AmmoType: amUFO; + AttackVoice: sndNone); Slot: 0; TimeAfterTurn: 3000; minAngle: 0; @@ -839,7 +861,8 @@ NumPerTurn: 1; Timer: 0; Pos: 0; - AmmoType: amShotgun); + AmmoType: amShotgun; + AttackVoice: sndNone); Slot: 2; TimeAfterTurn: 3000; minAngle: 0; @@ -860,7 +883,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amPickHammer); + AmmoType: amPickHammer; + AttackVoice: sndNone); Slot: 6; TimeAfterTurn: 0; minAngle: 0; @@ -879,7 +903,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amSkip); + AmmoType: amSkip; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -899,7 +924,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amRope); + AmmoType: amRope; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -920,7 +946,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amMine); + AmmoType: amMine; + AttackVoice: sndLaugh); Slot: 4; TimeAfterTurn: 5000; minAngle: 0; @@ -938,7 +965,8 @@ NumPerTurn: 3; Timer: 0; Pos: 0; - AmmoType: amDEagle); + AmmoType: amDEagle; + AttackVoice: sndNone); Slot: 2; TimeAfterTurn: 3000; minAngle: 0; @@ -959,7 +987,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amDynamite); + AmmoType: amDynamite; + AttackVoice: sndLaugh); Slot: 4; TimeAfterTurn: 5000; minAngle: 0; @@ -979,7 +1008,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amFirePunch); + AmmoType: amFirePunch; + AttackVoice: sndNone); Slot: 3; TimeAfterTurn: 3000; MinAngle: 0; @@ -997,7 +1027,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amWhip); + AmmoType: amWhip; + AttackVoice: sndNone); Slot: 3; TimeAfterTurn: 3000; MinAngle: 0; @@ -1015,7 +1046,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amBaseballBat); + AmmoType: amBaseballBat; + AttackVoice: sndNone); Slot: 3; TimeAfterTurn: 5000; minAngle: 0; @@ -1037,7 +1069,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amParachute); + AmmoType: amParachute; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -1059,7 +1092,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amAirAttack); + AmmoType: amAirAttack; + AttackVoice: sndIncoming); Slot: 5; TimeAfterTurn: 0; minAngle: 0; @@ -1081,7 +1115,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amMineStrike); + AmmoType: amMineStrike; + AttackVoice: sndNone); Slot: 5; TimeAfterTurn: 0; minAngle: 0; @@ -1099,7 +1134,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amBlowTorch); + AmmoType: amBlowTorch; + AttackVoice: sndNone); Slot: 6; TimeAfterTurn: 3000; minAngle: 768; @@ -1119,7 +1155,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amGirder); + AmmoType: amGirder; + AttackVoice: sndNone); Slot: 6; TimeAfterTurn: 3000; minAngle: 0; @@ -1141,7 +1178,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amTeleport); + AmmoType: amTeleport; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -1161,7 +1199,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amSwitch); + AmmoType: amSwitch; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1179,7 +1218,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amMortar); + AmmoType: amMortar; + AttackVoice: sndNone); Slot: 1; TimeAfterTurn: 3000; minAngle: 0; @@ -1199,7 +1239,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amKamikaze); + AmmoType: amKamikaze; + AttackVoice: sndNone); Slot: 3; TimeAfterTurn: 0; minAngle: 0; @@ -1219,7 +1260,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amCake); + AmmoType: amCake; + AttackVoice: sndLaugh); Slot: 4; TimeAfterTurn: 0; minAngle: 0; @@ -1237,7 +1279,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amSeduction); + AmmoType: amSeduction; + AttackVoice: sndNone); Slot: 2; TimeAfterTurn: 0; minAngle: 0; @@ -1257,7 +1300,8 @@ NumPerTurn: 0; Timer: 3000; Pos: 0; - AmmoType: amWatermelon); + AmmoType: amWatermelon; + AttackVoice: sndMelon); Slot: 1; TimeAfterTurn: 3000; minAngle: 0; @@ -1276,7 +1320,8 @@ NumPerTurn: 0; Timer: 5000; Pos: 0; - AmmoType: amHellishBomb); + AmmoType: amHellishBomb; + AttackVoice: sndNone); Slot: 4; TimeAfterTurn: 3000; minAngle: 0; @@ -1298,7 +1343,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amNapalm); + AmmoType: amNapalm; + AttackVoice: sndNone); Slot: 5; TimeAfterTurn: 0; minAngle: 0; @@ -1317,7 +1363,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amDrill); + AmmoType: amDrill; + AttackVoice: sndNone); Slot: 0; TimeAfterTurn: 3000; minAngle: 0; @@ -1336,7 +1383,8 @@ NumPerTurn: 0; Timer: 5001; Pos: 0; - AmmoType: amBallgun); + AmmoType: amBallgun; + AttackVoice: sndNone); Slot: 2; TimeAfterTurn: 0; minAngle: 0; @@ -1356,7 +1404,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amRCPlane); + AmmoType: amRCPlane; + AttackVoice: sndNone); Slot: 6; TimeAfterTurn: 0; minAngle: 0; @@ -1377,7 +1426,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amLowGravity); + AmmoType: amLowGravity; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1398,7 +1448,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amExtraDamage); + AmmoType: amExtraDamage; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1419,7 +1470,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amInvulnerable); + AmmoType: amInvulnerable; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1440,7 +1492,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amExtraTime); + AmmoType: amExtraTime; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -1461,7 +1514,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amLaserSight); + AmmoType: amLaserSight; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -1482,7 +1536,8 @@ NumPerTurn: 0; Timer: 0; Pos: 0; - AmmoType: amVampiric); + AmmoType: amVampiric; + AttackVoice: sndNone); Slot: 6; TimeAfterTurn: 0; minAngle: 0; @@ -1500,7 +1555,8 @@ NumPerTurn: 1; Timer: 0; Pos: 0; - AmmoType: amSniperRifle); + AmmoType: amSniperRifle; + AttackVoice: sndNone); Slot: 2; TimeAfterTurn: 3000; minAngle: 0; @@ -1522,7 +1578,8 @@ NumPerTurn: 1; Timer: 0; Pos: 0; - AmmoType: amJetpack); + AmmoType: amJetpack; + AttackVoice: sndNone); Slot: 3; TimeAfterTurn: 3000; minAngle: 0; @@ -1542,7 +1599,8 @@ NumPerTurn: 0; Timer: 3000; Pos: 0; - AmmoType: amMolotov); + AmmoType: amMolotov; + AttackVoice: sndNone); Slot: 1; TimeAfterTurn: 3000; minAngle: 0; diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uLand.pas --- a/hedgewars/uLand.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uLand.pas Sun Nov 29 16:56:04 2009 +0000 @@ -38,10 +38,12 @@ hasBorder: boolean; hasGirders: boolean; playHeight, playWidth, leftX, rightX, topY, MaxHedgehogs: Longword; // idea is that a template can specify height/width. Or, a map, a height/width by the dimensions of the image. If the map has pixels near top of image, it triggers border. + LandBackSurface: PSDL_Surface = nil; procedure GenMap; function GenPreview: TPreview; procedure CheckLandDigest(s: shortstring); +function LandBackPixel(x, y: LongInt): LongWord; implementation uses uConsole, uStore, uMisc, uRandom, uTeams, uLandObjects, uSHA, uIO, uAmmos, uLandTexture; @@ -307,6 +309,18 @@ end; end; +function LandBackPixel(x, y: LongInt): LongWord; +var p: PLongWordArray; +begin + if LandBackSurface = nil then + LandBackPixel:= 0 + else + begin + p:= LandBackSurface^.pixels; + LandBackPixel:= p^[LandBackSurface^.w * (y mod LandBackSurface^.h) + (x mod LandBackSurface^.w)];// or $FF000000; + end +end; + procedure ColorizeLand(Surface: PSDL_Surface); var tmpsurf: PSDL_Surface; r, rr: TSDL_Rect; @@ -326,6 +340,8 @@ end; SDL_FreeSurface(tmpsurf); +LandBackSurface:= LoadImage(Pathz[ptCurrTheme] + '/LandBackTex', ifIgnoreCaps or ifTransparent); + tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/Border', ifCritical or ifIgnoreCaps or ifTransparent); for x:= 0 to LAND_WIDTH - 1 do begin @@ -835,4 +851,7 @@ initialization +finalization +if LandBackSurface <> nil then + SDL_FreeSurface(LandBackSurface); end. diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uLandGraphics.pas Sun Nov 29 16:56:04 2009 +0000 @@ -30,7 +30,6 @@ function SweepDirty: boolean; function Despeckle(X, Y: LongInt): boolean; function CheckLandValue(X, Y: LongInt; Color: Word): boolean; -procedure Despeckle2(X, Y, Threesold: LongInt); procedure DrawExplosion(X, Y, Radius: LongInt); procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); @@ -42,44 +41,6 @@ implementation uses SDLh, uMisc, uLand, uLandTexture; -procedure Despeckle2(X, Y, Threesold: LongInt); -var - i, j: LongInt; - x0, x1, y0, y1: LongInt; - c: byte; -begin - // If the pixel has less than Threesold neightbours, it gets erased - // Erasing is outwards recursive - c := 0; - - x0 := max(X-1, 0); - x1 := min(X+1, LAND_WIDTH - 1); - y0 := max(Y-1, 0); - y1 := min(Y+1, LAND_HEIGHT - 1); - - for i:=x0 to x1 do begin - for j:=y0 to y1 do begin - if Land[j, i]<>0 then begin - c := c+1; - end; - end; - end; - - if c0 then begin - LandPixels[j, i] := cExplosionBorderColor; - Despeckle2(i, j, 5); - end; - end; - end; - end; - UpdateLandTexture(x0, x1-x0, y0, y1-y0); -end; - procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword); var i: LongInt; begin @@ -184,55 +145,84 @@ begin if ((y + dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y + dy, i] = COLOR_LAND then + if (Land[y + dy, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y + dy, i]:= 0; if ((y - dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y - dy, i] = COLOR_LAND then + if (Land[y - dy, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y - dy, i]:= 0; if ((y + dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y + dx, i] = COLOR_LAND then + if (Land[y + dx, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y + dx, i]:= 0; if ((y - dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y - dx, i] = COLOR_LAND then + if (Land[y - dx, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y - dx, i]:= 0; end; +procedure FillLandCircleLinesBG(x, y, dx, dy: LongInt); +var i: LongInt; +begin +if ((y + dy) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do + if (Land[y + dy, i] = COLOR_LAND) then + LandPixels[y + dy, i]:= LandBackPixel(i, y + dy) + else + if (Land[y + dy, i] = COLOR_OBJECT) then LandPixels[y + dy, i]:= 0; +if ((y - dy) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do + if (Land[y - dy, i] = COLOR_LAND) then + LandPixels[y - dy, i]:= LandBackPixel(i, y - dy) + else + if (Land[y - dy, i] = COLOR_OBJECT) then LandPixels[y - dy, i]:= 0; +if ((y + dx) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do + if (Land[y + dx, i] = COLOR_LAND) then + LandPixels[y + dx, i]:= LandBackPixel(i, y + dx) + else + if (Land[y + dx, i] = COLOR_OBJECT) then LandPixels[y + dx, i]:= 0; +if ((y - dx) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do + if (Land[y - dx, i] = COLOR_LAND) then + LandPixels[y - dx, i]:= LandBackPixel(i, y - dx) + else + if (Land[y - dx, i] = COLOR_OBJECT) then LandPixels[y - dx, i]:= 0; +end; + procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt); var i: LongInt; begin if ((y + dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y + dy, i] = COLOR_LAND then + if (Land[y + dy, i] = COLOR_LAND) or (Land[y + dy, i] = COLOR_OBJECT) then begin LandPixels[y + dy, i]:= cExplosionBorderColor; - Despeckle2(i, y + dy, 6); + Despeckle(i, y + dy); LandDirty[(y + dy) div 32, i div 32]:= 1; end; if ((y - dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y - dy, i] = COLOR_LAND then + if (Land[y - dy, i] = COLOR_LAND) or (Land[y - dy, i] = COLOR_OBJECT) then begin LandPixels[y - dy, i]:= cExplosionBorderColor; - Despeckle2(i, y - dy, 6); + Despeckle(i, y - dy); LandDirty[(y - dy) div 32, i div 32]:= 1; end; if ((y + dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y + dx, i] = COLOR_LAND then + if (Land[y + dx, i] = COLOR_LAND) or (Land[y + dx, i] = COLOR_OBJECT) then begin LandPixels[y + dx, i]:= cExplosionBorderColor; - Despeckle2(i, y + dx, 6); + Despeckle(i, y + dx); LandDirty[(y + dx) div 32, i div 32]:= 1; end; if ((y - dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y - dx, i] = COLOR_LAND then + if (Land[y - dx, i] = COLOR_LAND) or (Land[y - dx, i] = COLOR_OBJECT) then begin LandPixels[y - dx, i]:= cExplosionBorderColor; - Despeckle2(i, y - dy, 6); + Despeckle(i, y - dy); LandDirty[(y - dx) div 32, i div 32]:= 1; end; end; @@ -240,39 +230,70 @@ procedure DrawExplosion(X, Y, Radius: LongInt); var dx, dy, ty, tx, d: LongInt; begin - dx:= 0; - dy:= Radius; - d:= 3 - 2 * Radius; - while (dx < dy) do - begin - FillLandCircleLines0(x, y, dx, dy); - if (d < 0) - then d:= d + 4 * dx + 6 - else begin - d:= d + 4 * (dx - dy) + 10; - dec(dy) - end; - inc(dx) - end; - if (dx = dy) then FillLandCircleLines0(x, y, dx, dy); + +// draw background land texture + begin + dx:= 0; + dy:= Radius; + d:= 3 - 2 * Radius; + + while (dx < dy) do + begin + FillLandCircleLinesBG(x, y, dx, dy); + if (d < 0) + then d:= d + 4 * dx + 6 + else begin + d:= d + 4 * (dx - dy) + 10; + dec(dy) + end; + inc(dx) + end; + if (dx = dy) then FillLandCircleLinesBG(x, y, dx, dy); + end; + +// draw a hole in land +if Radius > 25 then + begin + dx:= 0; + dy:= Radius - 25; + d:= 3 - 2 * dy; + + while (dx < dy) do + begin + FillLandCircleLines0(x, y, dx, dy); + if (d < 0) + then d:= d + 4 * dx + 6 + else begin + d:= d + 4 * (dx - dy) + 10; + dec(dy) + end; + inc(dx) + end; + if (dx = dy) then FillLandCircleLines0(x, y, dx, dy); + end; + // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function - FillRoundInLand(X, Y, Radius, 0); - inc(Radius, 4); - dx:= 0; - dy:= Radius; - d:= 3 - 2 * Radius; - while (dx < dy) do - begin - FillLandCircleLinesEBC(x, y, dx, dy); - if (d < 0) - then d:= d + 4 * dx + 6 - else begin - d:= d + 4 * (dx - dy) + 10; - dec(dy) - end; - inc(dx) - end; - if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); + FillRoundInLand(X, Y, Radius, 0); + +// draw explosion border + begin + inc(Radius, 4); + dx:= 0; + dy:= Radius; + d:= 3 - 2 * Radius; + while (dx < dy) do + begin + FillLandCircleLinesEBC(x, y, dx, dy); + if (d < 0) + then d:= d + 4 * dx + 6 + else begin + d:= d + 4 * (dx - dy) + 10; + dec(dy) + end; + inc(dx) + end; + if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); + end; tx:= max(X - Radius - 1, 0); dx:= min(X + Radius + 1, LAND_WIDTH) - tx; @@ -285,13 +306,15 @@ var tx, ty, i: LongInt; begin for i:= 0 to Pred(Count) do - begin - for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do - for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do - if Land[ty, tx] = COLOR_LAND then - LandPixels[ty, tx]:= 0; - inc(y, dY) - end; + begin + for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do + for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do + if Land[ty, tx] = COLOR_LAND then + LandPixels[ty, tx]:= LandBackPixel(tx, ty) + else if Land[ty, tx] = COLOR_OBJECT then + LandPixels[ty, tx]:= 0; + inc(y, dY) + end; inc(Radius, 4); dec(y, Count * dY); @@ -300,10 +323,10 @@ begin for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do - if Land[ty, tx] = COLOR_LAND then + if (Land[ty, tx] = COLOR_LAND) or (Land[ty, tx] = COLOR_OBJECT) then begin LandPixels[ty, tx]:= cExplosionBorderColor; - LandDirty[trunc((y + dy)/32), trunc(i/32)]:= 1; + LandDirty[(y + dy) shr 5, i shr 5]:= 1; end; inc(y, dY) end; @@ -352,11 +375,13 @@ tx:= hwRound(X); ty:= hwRound(Y); if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) then - if Land[ty, tx] = COLOR_LAND then - begin - Land[ty, tx]:= 0; - LandPixels[ty, tx]:= 0; - end + begin + if Land[ty, tx] = COLOR_LAND then + LandPixels[ty, tx]:= LandBackPixel(tx, ty) + else if Land[ty, tx] = COLOR_OBJECT then + LandPixels[ty, tx]:= 0; + Land[ty, tx]:= 0; + end end; for t:= 0 to 7 do {$INCLUDE "tunsetborder.inc"} @@ -438,7 +463,7 @@ for x:= 0 to Pred(w) do if PLongword(@(p^[x * 4]))^ <> 0 then begin - Land[cpY + y, cpX + x]:= COLOR_LAND; + Land[cpY + y, cpX + x]:= COLOR_OBJECT; LandPixels[cpY + y, cpX + x]:= PLongword(@(p^[x * 4]))^ end; p:= @(p^[Image^.pitch]); @@ -474,7 +499,7 @@ if c < 4 then // 0-3 neighbours begin - LandPixels[Y, X]:= 0; + LandPixels[Y, X]:= ToggleLongInt(Land[Y, X] = COLOR_LAND, LandBackPixel(X, Y), 0); Land[Y, X]:= 0; exit(true); end; diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uLandObjects.pas --- a/hedgewars/uLandObjects.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uLandObjects.pas Sun Nov 29 16:56:04 2009 +0000 @@ -91,7 +91,7 @@ if LandPixels[cpY + y, cpX + x] = 0 then begin LandPixels[cpY + y, cpX + x]:= p^[x]; - if (p^[x] and AMask) <> 0 then Land[cpY + y, cpX + x]:= COLOR_LAND; + if (p^[x] and AMask) <> 0 then Land[cpY + y, cpX + x]:= COLOR_OBJECT; end; p:= @(p^[Image^.pitch shr 2]); end; diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uMisc.pas Sun Nov 29 16:56:04 2009 +0000 @@ -174,6 +174,9 @@ procedure MakeScreenshot(s: shortstring); {$ENDIF} +function ToggleLongInt(t: Boolean; a, b: LongInt): LongInt; +function ToggleString(t: Boolean; a, b: string): string; + function modifyDamage(dmg: Longword): Longword; var CursorPoint: TPoint; @@ -560,6 +563,24 @@ end; +{$inline on} +function ToggleLongInt(t: Boolean; a, b: LongInt): LongInt; +begin + if t then + ToggleLongInt:= a + else + ToggleLongInt:= b; +end; + +function ToggleString(t: Boolean; a, b: string): string; +begin + if t then + ToggleString:= a + else + ToggleString:= b; +end; +{$inline off} + initialization cDrownSpeed.QWordValue:= 257698038;// 0.06 cMaxWindSpeed.QWordValue:= 2147484;// 0.0005 diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uSound.pas --- a/hedgewars/uSound.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uSound.pas Sun Nov 29 16:56:04 2009 +0000 @@ -32,6 +32,7 @@ procedure ReleaseSound; procedure SoundLoad; procedure PlaySound(snd: TSound; infinite: boolean; voicepack: PVoicepack); +procedure LoopSound(snd: TSound; voicepack: PVoicepack); procedure PlayMusic; procedure PauseMusic; procedure ResumeMusic; @@ -67,6 +68,7 @@ end; procedure InitSound; +var i: TSound; begin if not isSoundEnabled then exit; WriteToConsole('Init sound...'); @@ -78,6 +80,9 @@ Mix_AllocateChannels(Succ(chanTPU)); if isMusicEnabled then Mix_VolumeMusic(50); +for i:= Low(TSound) to High(TSound) do + lastChan[i]:= -1; + Volume:= 0; ChangeVolume(cInitVolume) end; @@ -106,7 +111,7 @@ defVoicepack:= AskForVoicepack('Default'); for i:= Low(TSound) to High(TSound) do - if Soundz[i].Path <> ptVoices then + if (Soundz[i].Path <> ptVoices) and (Soundz[i].FileName <> '') then begin s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName; WriteToConsole(msgLoading + s + ' '); @@ -118,7 +123,7 @@ for t:= 0 to cMaxTeams do if voicepacks[t].name <> '' then for i:= Low(TSound) to High(TSound) do - if Soundz[i].Path = ptVoices then + if (Soundz[i].Path = ptVoices) and (Soundz[i].FileName <> '') then begin s:= Pathz[Soundz[i].Path] + '/' + voicepacks[t].name + '/' + Soundz[i].FileName; WriteToConsole(msgLoading + s + ' '); @@ -142,11 +147,25 @@ lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], loops, -1) end; +procedure LoopSound(snd: TSound; voicepack: PVoicepack); +begin +if (not isSoundEnabled) or fastUntilLag then exit; +if lastChan[snd] <> -1 then exit; + +if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then + lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1) +else + lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1) +end; + procedure StopSound(snd: TSound); begin if not isSoundEnabled then exit; -if Mix_Playing(lastChan[snd]) <> 0 then - Mix_HaltChannel(lastChan[snd]) +if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then + begin + Mix_HaltChannel(lastChan[snd]); + lastChan[snd]:= -1; + end; end; procedure PlayMusic; diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uStore.pas --- a/hedgewars/uStore.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uStore.pas Sun Nov 29 16:56:04 2009 +0000 @@ -1126,20 +1126,7 @@ {$IFNDEF IPHONEOS} -// since ATI seems to be unable to provide proper texture filtering/quality, -// do not even try to load the extension on ATI cards - -{$IFDEF DARWIN} -if true then -{$ELSE} -if cGPUVendor <> gvATI then -{$ENDIF} - SupportNPOTT:= glLoadExtension('GL_ARB_texture_non_power_of_two') -{$IFDEF DEBUGFILE} -else - AddFileLog('OpenGL: Skipped extension GL_ARB_texture_non_power_of_two due to ATI card') -{$ENDIF} -; // do not touch this line! :) +//SupportNPOTT:= glLoadExtension('GL_ARB_texture_non_power_of_two'); {$ENDIF} // set view port to whole window