GMDX Open Source Bug Fixes

A refuge for those migrating from the fallen DXEditing.com and a place for general discussion relating to Deus Ex editing (coding, mapping, etc).
Post Reply
Cybernetic pig
Illuminati
Posts: 2284
Joined: Thu Mar 08, 2012 3:21 am

GMDX Open Source Bug Fixes

Post by Cybernetic pig »

This will be a compilation of many, but not all GMDX-exclusive code bugfixes for other mod makers to adapt into their mods. I'll leave out level design fixes done via the editor because I don't even remember the majority, and I'll also leave out fixes that are a bit too complicated to detail and explain, as well as those I didn't bother to leave a comment on and have probably forgot by now. I'll also be updating this over time, whenever I feel like adding to it (there's a lot, most of this is just from two classes so far).

Straight-up Technical Bugfixes:

BUG: Augmentations can be activated even when the player has 0 bioenergy, resulting in a very short time window where the aug/s can be used, e.g speed enhance jumps or seeing through walls.

SOLUTION: in Augmentation.uc Activate():

Code: Select all

function Activate()
{
	// can't do anything if we don't have it
	if (!bHasIt)
		return;

	if (player.Energy == 0) //CyberP: fix: augs won't activate if no energy.
      { player.ClientMessage(player.EnergyDepleted); return; }
----

BUG: Melee weapons mid-swing still connect with the target even if the owner is dying or the attack is interrupted by a pain animation.

SOLUTION: In DeusExWeapon.uc ProcessTraceHit() add this at the top:

Code: Select all

if (bHandToHand && Owner != None && AccurateRange < 200)
    {
      if (Owner.IsInState('Dying'))
           return;             //CyberP: death cancels melee attacks
      else if (Owner.IsA('ScriptedPawn') && Owner.IsInState('TakingHit'))
           return;            //CyberP: Pain animation cancels melee attacks
    }
----

BUG: Castle Clinton Navarre hostile vs nonlethal reaction: In addition to Shifters fix, the following is also required as picking up a knocked out NPC in castle clinton wipes their tag, causing the game to think those NPCs are dead.

SOLUTION: make the corpse pass on their tag to the player when picked up, as well as passing it back to the corpse when dropped. Simple if you know what you are doing.

----

BUG: Laser weapon mod has no effect on projectile based weapons (Mini-Crossbow, Plasma Rifle).

SOLUTION: Add this near the top of ProjectileFire() in DeusExWeapon.uc:

Code: Select all

if (bLasing || bZoomed)
		currentAccuracy = 0.0; //CyberP: fix: laser & scope had no effect on xbow and plasma rifle accuracy
----

BUG: Attempting to drop an inventory item while looking at and highlighting certain other items was not possible, resulting in much annoyance.

SOLUTION: Ctrl+F this comment in DeusExPlayer.uc: "// if we are highlighting something, try to place the object on the target"
...and then change the line below said comment like so:

Code: Select all

// if we are highlighting something, try to place the object on the target 
		if ((FrobTarget != None) && !item.IsA('POVCorpse') && !FrobTarget.IsA('Pawn') && !FrobTarget.IsA('Pickup')
             && !FrobTarget.IsA('DeusExWeapon') && !FrobTarget.IsA('Decoration'))
//CyberP: more lenience when dropping
----

BUG: The Sawed-Off Shotgun does not play its cocking sound on the last bullet fired.

SOLUTION: In DeusExWeapon.uc:

Code: Select all

simulated function SawedOffCockSound()
{
local float shakeTime, shakeRoll, shakeVert;

	if ((AmmoType.AmmoAmount >= 0) && (WeaponSawedOffShotgun(Self) != None))  //CyberP: bugfix: was > 0, now >=
----

BUG: When clipping/slipping right on the edges of geometry (such as fumbling at the top of a ladder) your carried decoration drops out of your hand and falls through the floor. Easily can be replicated.

SOLUTION: Place this right at the top of HandleWalking() in DeusExPlayer.uc. Note: Overrides the super function in playerpawn.uc

Code: Select all

// ----------------------------------------------------------------------
// HandleWalking()
//
// subclassed from PlayerPawn so we can control run/walk defaults
// ----------------------------------------------------------------------

function HandleWalking()
{
	//Super.HandleWalking(); //CyberP: super function override
    local rotator carried;

	// this is changed from Unreal -- default is now walk - DEUS_EX CNN
	bIsWalking = ((bRun == 0) || (bDuck != 0)) && !Region.Zone.IsA('WarpZoneInfo');

	if ( CarriedDecoration != None )
	{
		if ( (Role == ROLE_Authority) && (standingcount == 0) )
		   PutCarriedDecorationInHand(); //CyberP: hacky fix to a weird vanilla bug.
                   //{CarriedDecoration = None; }
		if ( CarriedDecoration != None ) //verify its still in front
		{
			bIsWalking = true;
			if ( Role == ROLE_Authority )
			{
				carried = Rotator(CarriedDecoration.Location - Location);
				carried.Yaw = ((carried.Yaw & 65535) - (Rotation.Yaw & 65535)) & 65535;
				//if ( (carried.Yaw > 3072) && (carried.Yaw < 62463) )  //CyberP: Another fix
				//	DropDecoration();
			}
		}
	}
DESCRIPTION: calls PutCarriedDecorationInHand(), which will basically reset your carried deco immediately after it is dropped. It's a hacky fix, but works nicely, is barely noticable and from what I gather fixing the problem at its core is not possible (must be located in native code).

BONUS: at the bottom of the above block there is another fix. It prevents an issue where picking up decoration from a certain angle immediately made you drop it, or kept spam-attempting to drop it every tick if something was blocking the drop. This is a risky fix however as I have no idea why the original devs wrote that code in the first place, but so far the fix seems fine. I've no idea why they'd want to force you to drop a deco just because the Yaw Rotation wasn't as specified.

----

BUG: You can reload even when you have no reserve ammo.

SOLUTION: Edits to ReloadWeapon() in DeusExWeapon.uc:

Code: Select all

exec function ReloadWeapon()
{
	local DeusExWeapon W;
        
	W = DeusExWeapon(Weapon);  //CyberP: cannot reload when ammo in mag but none in reserves.
	if (W != None && (W.AmmoLeftInClip() != W.AmmoType.AmmoAmount || W.IsA('WeaponHideAGun') || W.GoverningSkill == class'DeusEx.SkillDemolition'))
		W.ReloadAmmo();
}
----

BUG: the exploit where you can loot your own body to duplicate items.

SOLUTION: In DeusExPlayer.uc SpawnCarcass():

Code: Select all

for (item=Inventory; item!=None; item=Inventory)
		{
		  DeleteInventory(item);
                  if ( Level.NetMode != NM_Standalone )
	             carc.AddInventory(item);   //CyberP: prevent suicide inventory exploit. by only giving corpse inventory in multiplayer
		}
----

BUG: The super jump exploit.

SOLUTION: in DoJump() just reset the player's jumpZ var back to default * SpeedEnhancementAugValue before the jump is executed.

----

BUG: dynamic FOV modifications (such as when drugged/poisoned) causes the held weapon to not be rendered.

SOLUTION: in DeusExWeapon.uc RenderOverlays()

Code: Select all

if ( PlayerOwner != None )
	{
		//if ( PlayerOwner.DesiredFOV != PlayerOwner.DefaultFOV )
		//	return;
		if (bZoomed)
		    return;
Simply comment out the two lines as above, then add the if statement immediately after.

----

BUG: shooting or reloading upon death causes the death animation to be overriden.

SOLUTION: human.uc

Code: Select all

function PlayWeaponSwitch(Weapon newWeapon)
{
//	ClientMessage("PlayWeaponSwitch()");
	if (!bIsCrouching && !bForceDuck && !bCrouchOn && !IsLeaning() && !IsInState('Dying')) //CyberP: bugfix: added !state dying
		PlayAnim('Reload');
}
This is the fix for the reload anim only. For the shooting one you have to do something similar, as well as not let the player shoot when dying to begin with.

----

BUG: Thrown grenades instantly explode when hitting carcasses and pickups.

SOLUTION: add a special case exclusion for those two things in ThrownProjectile.uc ProcessTouch()

----

-------------------------------------------
-------------------------------------------

Purist Design Fixes:

Meaning not strictly technical fixes, but rather design issues that when fixed changes how the game plays to varying degrees. However, they're such no-brainer fixes they may as well be argued to be objective improvements, and therefore suitable for all mods and patches.

----

ISSUE: NPCs do not react when they spot unconscious NPCs, only dead. They simply walk on past.

SOLUTION: In DeusExCarcass.uc InitFor():

Code: Select all

function InitFor(Actor Other)
{
	if (Other != None)
	{
		// set as unconscious or add the pawns name to the description
		if (!bAnimalCarcass)
		{
		    bEmitCarcass = true; //CyberP: AI is aware of carcasses whether dead or unconscious!
Note: requires the reacting NPC also have the bReactCarcass bool set to true to work.
NPC dialogue responses to corpses are ambiguous and open to interpretation, and therefore compatible with knocked-out NPCs as well as dead.

----

ISSUE: Guns are near-silent when shooting, even with no silencer attached, rendering silencers near-pointless and adding to the clusterfuck that is the AI issues (or was, if you have GMDX installed).

SOLUTION: raise NoiseLevel value individually for each weapon. The scale GMDX uses is 0.1 = Silent, 10 = loudest weapon, and noise level is also reduced based on difficulty level in GMDX. 0.1 is the value vanilla sets NoiseLevel to when a silencer is attached, otherwise most weapons were 1.0 which an enemy a few meters in front couldn't hear.

----

ISSUE: AI do not hear us smacking things with melee weapons.

SOLUTION: Add the final two lines below in DeusExWeapon.uc SpawnEffects().

Code: Select all

	if (bHandToHand)
	{
		// if we are hand to hand, play an appropriate sound
		if (Other.IsA('DeusExDecoration'))
			Owner.PlaySound(Misc3Sound, SLOT_None,,, 1024);
		else if (Owner.IsA('Doberman') && FRand() < 0.6)
            Owner.PlaySound(Misc3Sound, SLOT_None,,, 1024);
		else if (Other.IsA('Pawn'))
			Owner.PlaySound(Misc1Sound, SLOT_None,,, 1024);
		else if (Other.IsA('BreakableGlass'))
			Owner.PlaySound(sound'GlassHit1', SLOT_None,,, 1024);
		else if (GetWallMaterial(HitLocation, HitNormal) == 'Glass')
			Owner.PlaySound(sound'BulletProofHit', SLOT_None,,, 1024);
		else
			Owner.PlaySound(Misc2Sound, SLOT_None,,, 1024);
	    if (Other != none && !Other.IsA('Pawn'))
			AISendEvent('LoudNoise', EAITYPE_Audio, TransientSoundVolume, 768); //CyberP: AI hear us smacking things
	}

----

ISSUE: Attaching a scope reduced accuracy by 10% permanently, unless looking through the scope. Dynamic crosshairs did not represent this reduction as it was calculated after firing.

SOLUTION: Either make the crosshairs represent the accuracy reduction (a reduction that never allows you to be more than 90% accurate unless using the scope), or remove it (recommend, as it is stupid) like so in TraceFire():

Code: Select all

if (bHasScope && !bZoomed && !bLasing)
		{
        //Accuracy += 0.2;  //CyberP: commented out. This was -10% accuracy even if game weapon info and xhairs showed 100%.
		}
	// if the laser sight is on, make this shot dead on
	// also, if the scope is on, zero the accuracy so the shake makes the shot inaccurate
	else if (bLasing || bZoomed)
		Accuracy = 0.0;


----

ISSUE: opening computer terminals (the security type that lets you config cameras + Turrets) plays an animation before drawing the hack window, enabling the player plenty time to run quite some distance from the terminal they are supposed to be interfaced with. It's immersion breaking and open to exploitation.

SOLUTION: Speed up the anim rate is the best solution.

----

ISSUE: Human NPCs turn extremely slowly causing some behavioral problems, and it looks especially ridiculous in combat.

SOLUTION: Raise their YawRotationSpeed var (GMDX raises it almost two-fold).

----

ISSUE: the ability to stop looking through a weapon's scope is restricted by the weapon's rate of fire, which can be very long in duration (e.g, sniper rifle).

SOLUTION: DeusExWeapon.uc ScopeToggle() edits:

Code: Select all

exec function ToggleScope()
{
	local DeusExWeapon W;

	//log("ToggleScope "@IsInState('Interpolating')@" "@IsInState('Dying')@" "@IsInState('Paralyzed'));
	if (RestrictInput())
		return;

	W = DeusExWeapon(Weapon);
	if (W != None)
	{
	  if (W.IsInState('Idle') || (W.bZoomed == False && W.AnimSequence == 'Shoot') || (W.bZoomed == True && RecoilTime==0)) //CyberP: far less restrictive
	  {
Post Reply