diff --git a/Readme.md b/Readme.md index cbfc02a..2ac8e33 100644 --- a/Readme.md +++ b/Readme.md @@ -55,6 +55,7 @@ Doom Tournament (currently the devel branch is required). - Unreal Bible & prototype build behaviour restoration - Stinger projectile remanence & explosion + - Stinger projectile bouncing - Razorjack hold fire to increase blade speed - Rifle restored rapid fire - Rifle restored flashlight diff --git a/cvarinfo.txt b/cvarinfo.txt index 734f662..830e36f 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -1,22 +1,76 @@ user int stinger_hudmode = 0; // hud mode + // 0 - full, large numbers, cummulative armor + // 1 - full, small numbers, individial armor + // 2 - all on bottom + // 3 - bottom corners only, no numbers + // 4 - minimal display on bottom right corner + // 5 - minimalistic top hud from 0.871 and up user int stinger_introtype = 0; // 0 - unreal '98 // 1 - unreal '97 // 2 - unreal '96 // 3 - unreal '95 server bool sting_telegun = false; // enable teleport capsules + // basically this game's own + // translocator before the translocator + // even existed server bool sting_flares = false; // enable light/dark flares + // only one can be active at a time + // for balance and performance reasons server bool sting_stinger = false; // unreal bible stinger detonation + // (projectiles attach to target and + // explode when hurt by splash damage + // or when target moves at high speed + // then comes to a sudden stop) +server bool sting_stingerb = false; // stinger projectiles bounce up to + // three times if they don't hit a + // surface straight on. this was a + // thing all the way until 0.86 + // strangely, the bBounce flag still + // remained on the projectile but since + // then it was hardcoded to explode + // when it hit a wall anyway server bool sting_rifle = false; // old rifle burst altfire + // three rapid shots server bool sting_riflel = false; // old rifle flashlight + // it's independent from the scope + // since that mesh part already is... + // you know... a scope server bool sting_razor = false; // razorjack blade charging + // hold primary fire to increase the + // spin up to 3x server bool sting_flamet = false; // use flamethrower model based on old // design and texture rather than the // modern redesign server bool sting_automags = false; // automag dual wielding + // oldskool did this, and you'll come + // to realize that it wasn't a good + // idea balance-wise server bool sting_protomags = false; // protomag dual wielding + // just for the sake of completion + // plus the off-hand mag will use the + // alternate skin server bool sting_dpistol = false; // d.pistol altfire always level 0 + // I always found this thing odd about + // the weapon, but it's very likely + // that this was kept like this for + // the sake of balance server bool sting_pshield = false; // p.shield does not drain over time + // this is unbalanced as all hell and + // it's not recommended to enable the + // compatibility option unless you are + // a die-hard purist who despises the + // change +server bool sting_nopstart = false; // players start only with the + // dispersion pistol, otherwise they + // also get an automag for the sake + // of consistency with doom defaults user bool sting_transext = false; // use an extended translator graphic // to fit more text + // thanks Kynikoss for this, it's much + // better than the trash garbage mods + // use server bool sting_olsmp = false; // adds the stupid oldskool SMP 7243 to // the BFG/Redeemer replacement pool + // this weapon is dumb, but just for + // the sake of completion it's there as + // an option diff --git a/language.txt b/language.txt index 0040e9d..97830b5 100644 --- a/language.txt +++ b/language.txt @@ -195,6 +195,7 @@ STING_POPTS = "Prototype features"; STING_TELEHAND = "Teleport Capsules"; STING_FLARES = "Light/Dark Flares"; STING_STINGER = "Stinger detonation"; +STING_STINGERB = "Stinger projectiles bounce"; STING_RIFLE = "Rifle burst altfire"; STING_RIFLEL = "Rifle flashlight"; STING_RAZOR = "Razorjack charging"; @@ -205,6 +206,7 @@ STING_PROTODUAL = "Protomags"; STING_UOPTS = "Compatibility options"; STING_DPISTOL = "Dispersion Pistol altfire isn't upgraded"; STING_PSHIELD = "Power Shield does not drain over time"; +STING_NOPSTART = "Players don't start up with an Automag"; STING_OLSMP = "Enable SMP 7243 from Oldskool Amp'd"; STING_MCREDS = "Unreal Credits"; STING_CDR = "Doomreal"; @@ -392,6 +394,7 @@ STING_POPTS = "Características de prototipo"; STING_TELEHAND = "Cápsulas de Teletransporte"; STING_FLARES = "Bengalas de luz/oscuridad"; STING_STINGER = "Detonación de Arma Aguijón"; +STING_STINGERB = "Los projectiles del Arma Aguijón rebotan"; STING_RIFLE = "Fuego alternativo en ráfaga de Rifle"; STING_RIFLEL = "Linterna de Rifle"; STING_RAZOR = "Carga de Razorjack"; @@ -402,6 +405,7 @@ STING_PROTODUAL = "Protoarmas"; STING_UOPTS = "Opciones de compatibilidad"; STING_DPISTOL = "El fuego alternativo de la Pistola de Dispersión no es mejorado"; STING_PSHIELD = "El Escudo de Fuerza no pierde carga con el tiempo"; +STING_NOPSTART = "Los jugadores no empiezan la partida con un Automag"; STING_OLSMP = "Habilitar SMP 7243 de Oldskool Amp'd"; STING_MCREDS = "Créditos de Unreal"; STING_CDR = "Doomreal"; diff --git a/menudef.txt b/menudef.txt index 277bf3c..9b4849f 100644 --- a/menudef.txt +++ b/menudef.txt @@ -27,6 +27,7 @@ OptionMenu "UnrealOptionMenu" Option "$STING_FLARES", "sting_flares", "YesNo" Command "$FLAK_APPLY", "netevent refreshtrans" Option "$STING_STINGER", "sting_stinger", "YesNo" + Option "$STING_STINGERB", "sting_stingerb", "YesNo" Option "$STING_RIFLE", "sting_rifle", "YesNo" Option "$STING_RIFLEL", "sting_riflel", "YesNo" Option "$STING_RAZOR", "sting_razor", "YesNo" @@ -39,6 +40,7 @@ OptionMenu "UnrealOptionMenu" StaticText "$STING_UOPTS", "Gold" Option "$STING_DPISTOL", "sting_dpistol", "YesNo" Option "$STING_PSHIELD", "sting_pshield", "YesNo" + Option "$STING_NOPSTART", "sting_nopstart", "YesNo" Option "$STING_OLSMP", "sting_olsmp", "YesNo" } diff --git a/zscript/unrealcommon.zsc b/zscript/unrealcommon.zsc index 7b3cc28..11ec1ac 100644 --- a/zscript/unrealcommon.zsc +++ b/zscript/unrealcommon.zsc @@ -8,6 +8,70 @@ Class UPlayer : UTPlayer Player.StartItem "DefaultAmmo", 50; } + override void GiveDefaultInventory() + { + if ( !player ) return; + // HexenArmor must always be the first item in the inventory because + // it provides player class based protection that should not affect + // any other protection item. + let myclass = GetClass(); + GiveInventoryType('HexenArmor'); + let harmor = HexenArmor(FindInventory('HexenArmor')); + harmor.Slots[4] = self.HexenArmor[0]; + for ( int i=0; i<4; ++i ) harmor.SlotsIncrement[i] = self.HexenArmor[i+1]; + // BasicArmor must come right after that. It should not affect any + // other protection item as well but needs to process the damage + // before the HexenArmor does. + GiveInventoryType('BasicArmor'); + // Now add the items from the DECORATE definition + let di = GetDropItems(); + for ( DropItem di=GetDropItems(); di; di=di.Next ) + { + Class ti = di.Name; + if ( !ti ) continue; + // no pistol start + if ( sting_nopstart && ((ti is 'Automag') || (ti is 'UMiniAmmo')) ) continue; + let tinv = (class)(ti); + if ( !tinv ) + { + Console.Printf(TEXTCOLOR_ORANGE.."%s is not an inventory item and cannot be given to a player as start item.\n",di.Name); + continue; + } + let item = FindInventory(tinv); + if ( item ) item.Amount = clamp(item.Amount+(di.Amount?di.Amount:item.default.Amount),0,item.MaxAmount); + else + { + item = Inventory(Spawn(ti)); + item.bIgnoreSkill = true; // no skill multipliers here + item.Amount = di.Amount; + let weap = Weapon(item); + if ( weap ) + { + // To allow better control any weapon is emptied of + // ammo before being given to the player. + weap.AmmoGive1 = weap.AmmoGive2 = 0; + } + bool res; + Actor check; + [res,check] = item.CallTryPickup(self); + if ( !res ) + { + item.Destroy(); + item = null; + } + else if ( check != self ) + { + // Player was morphed. This is illegal at game start. + // This problem is only detectable when it's too late to do something about it... + ThrowAbortException("Cannot give morph item '%s' when starting a game!",di.Name); + } + } + let weap = Weapon(item); + if ( weap && weap.CheckAmmo(Weapon.EitherFire,false) ) + player.ReadyWeapon = player.PendingWeapon = weap; + } + } + // Have to modify the give cheat to handle UT armor override void CheatGive( String name, int amount ) { diff --git a/zscript/unrealhud.zsc b/zscript/unrealhud.zsc index 08d942b..7a47576 100644 --- a/zscript/unrealhud.zsc +++ b/zscript/unrealhud.zsc @@ -153,8 +153,8 @@ Class UnrealHUD : BaseStatusBar FracTic = TicFrac; HudMode = CVar.GetCVar('stinger_hudmode',players[consoleplayer]).GetInt(); scalev.x = scalev.y = CVar.GetCVar('hud_scale',players[consoleplayer]).GetInt(); - if ( scalev.x == 0 ) scalev.x = scalev.y = max(1,min(Screen.GetWidth()/640.,Screen.GetHeight()/480.)); // the typical behavior is scaling to 640x400 but we're expecting 4:3 here - else if ( scalev.x < 0 ) + if ( scalev.x < 0 ) scalev.x = scalev.y = max(1,min(Screen.GetWidth()/640.,Screen.GetHeight()/480.)); // the typical behavior is scaling to 640x400 but we're expecting 4:3 here + else if ( scalev.x == 0 ) { scalev.x = CleanXFac_1; scalev.y = CleanYFac_1; @@ -201,7 +201,7 @@ Class UnrealHUD : BaseStatusBar CurY = TempY; } - private void DrawIconValue( int n ) + private void DrawIconValue( int n, bool bIsArmor = false ) { if ( !HudMode || (HudMode == 3) ) return; double TempX = CurX, TempY = CurY; @@ -237,7 +237,7 @@ Class UnrealHUD : BaseStatusBar } if ( (i is 'UnrealInventory') && (UnrealInventory(i).DefaultCharge > 0) && (UnrealInventory(i).bActive || (UnrealInventory(i).Charge < UnrealInventory(i).DefaultCharge)) ) Screen.DrawTexture(HudLine,false,CurX+2,CurY+29,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_WindowRightF,Min(28.*(UnrealInventory(i).Charge/double(UnrealInventory(i).DefaultCharge)),28.)); - else if ( (i is 'UTArmor') && !HudMode ) + else if ( (i is 'UTArmor') && ((HudMode == 0) || (HudMode == 3)) ) Screen.DrawTexture(HudLine,false,CurX+2,CurY+29,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_WindowRightF,Min(28.*(i.Amount/double(i.MaxAmount)),28.)); } @@ -372,6 +372,7 @@ Class UnrealHUD : BaseStatusBar if ( (HUDMode == 5) || !SelectedItem ) return; Count++; if ( Count > 20 ) Count = 0; + if ( !Next && !bDrawOne ) x += 32; // this was missing from the original, causing a gap when there's only two items in the inventory if ( Prev ) { bRed = ((Prev is 'UnrealInventory') && UnrealInventory(Prev).bActive) || (Prev is 'Powerup') || ((Prev is 'UTranslator') && bFlashTranslator); @@ -579,14 +580,14 @@ Class UnrealHUD : BaseStatusBar // Display Frag count if ( HudMode < 3 ) DrawFragCount(ClipX-32,ClipY-64); else if ( HudMode == 3 ) DrawFragCount(0,ClipY-64); - else if ( HudMode == 4 ) DrawFragCount(0,ClipY-32); + else if ( HudMode == 4 ) DrawFragCount(ClipX-96,ClipY-32); } else { // Display Keys - if ( HudMode < 3 ) DrawKeys(ClipX-(deathmatch?48:16),ClipY-48); - else if ( HudMode == 3 ) DrawKeys(deathmatch?32:0,ClipY-48,true); - else if ( HudMode == 4 ) DrawKeys(deathmatch?32:0,ClipY-16,true); + if ( HudMode < 3 ) DrawKeys(ClipX-16,ClipY-48); + else if ( HudMode == 3 ) DrawKeys(0,ClipY-48,true); + else if ( HudMode == 4 ) DrawKeys(ClipX-80,ClipY-16); } } @@ -744,7 +745,7 @@ Class UnrealHUD : BaseStatusBar override bool DrawChat( String txt ) { int xpos = 4*CleanXFac_1; - int ypos = (screenblocks<=10)?GetTopOfStatusBar():(Screen.GetHeight()-((screenblocks>11)?0:int(32*scalev.y))); + int ypos = ((screenblocks<=10)||automapactive)?GetTopOfStatusBar():(Screen.GetHeight()-((screenblocks>11)?0:int(32*scalev.y))); ypos -= (WhiteFont.GetHeight()+4)*CleanYFac_1; String fullstr = String.Format("(> Say %s%s",txt,WhiteFont.GetCursor()); // cut out until it fits @@ -803,7 +804,7 @@ Class UnrealHUD : BaseStatusBar [tmp,tmp,hres] = StatusbarToRealCoords(0,0,HorizontalResolution); double swidth = 0; double ltop = 0, rtop = 0; - if ( (HudMode < 6) && CPlayer.mo.InvSel ) + if ( (HudMode < 5) && CPlayer.mo.InvSel ) rtop += (32*scalev.y)/scale.Y; double cbottom = GetTopOfStatusBar()-textdist; int protrusion = GetProtrusion(swidth/hres);