diff --git a/DXRCore/DeusEx/Classes/DXRActorsBase.uc b/DXRCore/DeusEx/Classes/DXRActorsBase.uc index 77c77d8c6..d445d9e95 100644 --- a/DXRCore/DeusEx/Classes/DXRActorsBase.uc +++ b/DXRCore/DeusEx/Classes/DXRActorsBase.uc @@ -48,6 +48,11 @@ function SwapAll(string classname, float percent_chance) temp[num++] = a; } + if(num<2) { + l("SwapAll(" $ classname $ ", " $ percent_chance $ ") only found " $ num); + return; + } + for(i=0; i> dxm.Rotation; + dxm.BasePos = dxm.BasePos - vectm(pivot.X,pivot.Y,pivot.Z); + dxm.PrePivot=vect(0,0,0); + dxm.SetLocation(dxm.BasePos); +} + static function Actor GlowUp(Actor a, optional byte hue, optional byte saturation) { // if `a` is a datacube, spawn a new light instead @@ -1734,7 +1752,7 @@ static function Actor GlowUp(Actor a, optional byte hue, optional byte saturatio function DebugMarkKeyActor(Actor a, coerce string id) { local ActorDisplayWindow actorDisplay; - if( ! #defined(locdebug)) { + if( ! #bool(locdebug)) { err("Don't call DebugMarkKeyActor without locdebug mode! Add locdebug to the compiler_settings.default.json file"); return; } @@ -1760,7 +1778,7 @@ function DebugMarkKeyPosition(vector pos, coerce string id) { local ActorDisplayWindow actorDisplay; local Actor a; - if( ! #defined(locdebug)) { + if( ! #bool(locdebug)) { err("Don't call DebugMarkKeyPosition without locdebug mode! Add locdebug to the compiler_settings.default.json file"); return; } diff --git a/DXRCore/DeusEx/Classes/DXRBase.uc b/DXRCore/DeusEx/Classes/DXRBase.uc index d12f99af1..4de5a0d71 100644 --- a/DXRCore/DeusEx/Classes/DXRBase.uc +++ b/DXRCore/DeusEx/Classes/DXRBase.uc @@ -41,6 +41,7 @@ simulated function DXRando GetDXR() static function DXRBase Find() { + if(class'DXRando'.default.dxr == None) return None; return class'DXRando'.default.dxr.FindModule(default.class); } diff --git a/DXRCore/DeusEx/Classes/DXRInfo.uc b/DXRCore/DeusEx/Classes/DXRInfo.uc index fbd9f5a83..cd56a9821 100644 --- a/DXRCore/DeusEx/Classes/DXRInfo.uc +++ b/DXRCore/DeusEx/Classes/DXRInfo.uc @@ -58,14 +58,13 @@ simulated final function #var(PlayerPawn) player(optional bool quiet) local #var(PlayerPawn) p; local DXRando dxr; dxr = GetDXR(); - //p = #var(PlayerPawn)(GetPlayerPawn()); - p = dxr.Player; + if(dxr != None) p = dxr.Player; if( p == None ) { p = #var(PlayerPawn)(GetPlayerPawn()); if(p==None){ //If GetPlayerPawn() didn't work (probably in HX) foreach AllActors(class'#var(PlayerPawn)', p){break;} } - dxr.Player = p; + if(dxr != None) dxr.Player = p; } if( p == None && !quiet ) warning("player() found None"); return p; @@ -227,7 +226,7 @@ function bool OnTitleScreen() { local DXRando dxr; dxr = class'DXRando'.default.dxr; - + if(dxr == None) return true; return dxr.LocalURL=="DX" || dxr.LocalURL=="DXONLY"; } diff --git a/DXRCore/DeusEx/Classes/DXRMenuSelectDifficulty.uc b/DXRCore/DeusEx/Classes/DXRMenuSelectDifficulty.uc index 1cc385ea5..5bf1c7cdd 100644 --- a/DXRCore/DeusEx/Classes/DXRMenuSelectDifficulty.uc +++ b/DXRCore/DeusEx/Classes/DXRMenuSelectDifficulty.uc @@ -139,6 +139,9 @@ function BindControls(optional string action) NewMenuItem("", "Use the installer to download the mirrored map files, or go to the unreal-map-flipper Releases page on Github"); EnumOption("Mirror Map Files Not Found", -1, f.mirroredmaps); } +#else + //Disable mirrored maps entirely if map variants aren't supported + f.mirroredmaps=-1; #endif NewMenuItem("Seed", "Enter a seed if you want to play the same game again. Leave it blank for a random seed."); @@ -171,7 +174,7 @@ function string SetEnumValue(int e, string text) // HACK: this allows you to override the autosave option instead of SetDifficulty forcing it by game mode Super.SetEnumValue(e, text); if(e == gamemode_enum && #defined(injections)) { - if(InStr(text, "Halloween Mode")==0 || InStr(text, "WaltonWare Halloween")==0) + if(InStr(text, "Halloween")!=-1) { Super.SetEnumValue(autosave_enum, "Limited Fixed Saves"); } diff --git a/DXRCore/DeusEx/Classes/DXRMenuSetupRando.uc b/DXRCore/DeusEx/Classes/DXRMenuSetupRando.uc index 9cc965708..32f97a7bd 100644 --- a/DXRCore/DeusEx/Classes/DXRMenuSetupRando.uc +++ b/DXRCore/DeusEx/Classes/DXRMenuSetupRando.uc @@ -247,7 +247,7 @@ function BindControls(optional string action) NewMenuItem("Non-Human Chance %", "Reduce the chance of new enemies being non-humans."); Slider(f.settings.enemies_nonhumans, 0, 100); - NewMenuItem("Enemy Respawn Seconds", "(Beta) How many seconds for enemies to respawn. Leave blank or 0 to disable."); + NewMenuItem("Enemy Respawn Seconds", "How many seconds for enemies to respawn. Leave blank or 0 to disable."); Slider(f.settings.enemyrespawn, 0, 10000); NewMenuItem("Move Turrets", "Randomizes locations of turrets, cameras, and security computers for them."); diff --git a/DXRCore/DeusEx/Classes/DXRVersion.uc b/DXRCore/DeusEx/Classes/DXRVersion.uc index 5d31108a5..d4fbdbf40 100644 --- a/DXRCore/DeusEx/Classes/DXRVersion.uc +++ b/DXRCore/DeusEx/Classes/DXRVersion.uc @@ -5,7 +5,7 @@ simulated static function CurrentVersion(optional out int major, optional out in major=3; minor=2; patch=0; - build=1;//build can't be higher than 99 + build=2;//build can't be higher than 99 } simulated static function bool VersionIsStable() @@ -60,6 +60,20 @@ simulated static function int VersionNumber() return VersionToInt(major, minor, patch, build); } +simulated static function bool FeatureFlag(int major, int minor, int patch, string feature) // make sure to have an issue in GitHub with the feature flag name! and it should be attached to a milestone +{ + if(#bool(allfeatures)) return true; + #ifdef enablefeature + if("#var(enablefeature)" == feature) return true; + #endif + + if(VersionNumber() >= VersionToInt(major, minor, patch, 0)) { + log("WARNING: FeatureFlag " $ feature $ " only requires v" $ major $ "." $ minor $ "." $ patch, default.class.name); + return true; + } + return false; +} + simulated static function bool VersionOlderThan(int config_version, int major, int minor, int patch, int build) { return config_version < VersionToInt(major, minor, patch, build); diff --git a/DXRFixes/DeusEx/Classes/ElevatorMover.uc b/DXRFixes/DeusEx/Classes/ElevatorMover.uc index e354f5ddf..4acf19ab2 100644 --- a/DXRFixes/DeusEx/Classes/ElevatorMover.uc +++ b/DXRFixes/DeusEx/Classes/ElevatorMover.uc @@ -2,13 +2,13 @@ class ElevatorMover merges ElevatorMover; // can't do injects because it uses a state var float lastTime, moveSpeed, originalMoveTime; -var int numKeyPos; +var int numKeyPos, prevSeqNum; var bool initialized; function Initialize() { local SequenceTrigger st; - local float dist, maxDist, avgDist, distSum; + local float dist, maxDist, maxDist2, avgDist, distSum; local int validKeyPos[8]; local int i, j; @@ -34,13 +34,18 @@ function Initialize() for (i = 0; i < numKeyPos; i++) { for (j = i + 1; j < numKeyPos; j++) { dist = VSize(KeyPos[validKeyPos[i]] - KeyPos[validKeyPos[j]]); - maxDist = FMax(maxDist, dist); + if(dist > maxDist) { + maxDist2 = maxDist; + maxDist = dist; + } else if(dist > maxDist2) { + maxDist2 = dist; + } distSum += dist; } } avgDist = distSum / (numKeyPos * (numKeyPos - 1) / 2.0); - moveSpeed = (maxDist*0.33 + avgDist*0.67) / MoveTime; + moveSpeed = (maxDist*0.5 + maxDist2*0.5) / MoveTime; originalMoveTime = MoveTime; initialized = true; @@ -68,7 +73,7 @@ function SetSeq(int seqnum) Initialize(); - if( MoveTime/10 < Level.TimeSeconds-lastTime ) + if( seqnum != prevSeqNum && MoveTime/3 < Level.TimeSeconds-lastTime ) // HACK: for 12_vandenberg_cmd elevator oldSeq = true; if ( bIsMoving && !oldSeq ) @@ -81,6 +86,7 @@ function SetSeq(int seqnum) if (KeyNum != seqnum || oldSeq) { + prevSeqNum = seqnum; prevKeyNum = KeyNum; KeyNum = seqnum; @@ -91,3 +97,8 @@ function SetSeq(int seqnum) else lastTime = Level.TimeSeconds; } } + +defaultproperties +{ + prevSeqNum=-1 +} diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM01.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM01.uc index 5d08e2af5..af495fe7f 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM01.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM01.uc @@ -6,8 +6,6 @@ function PostFirstEntryMapFixes() local DeusExMover m; local BlockPlayer bp; - FixUNATCORetinalScanner(); - switch(dxr.localURL) { case "01_NYC_UNATCOISLAND": AddBox(class'#var(prefix)CrateUnbreakableSmall', vectm(6720.866211, -3346.700684, -445.899597));// electrical hut @@ -27,9 +25,11 @@ function PostFirstEntryMapFixes() SetAllLampsState(,, false, vect(-5724.620605, 1435.543213, -79.614632), 0.01); SetAllLampsState(,, false, vect(3313.0954215, -1662.294768, -176.938141), 0.01); + break; + case "01_NYC_UNATCOHQ": + FixUNATCORetinalScanner(); break; } - } diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc index 3de3234ef..549c3c39e 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM03.uc @@ -20,9 +20,13 @@ function PostFirstEntryMapFixes() RevisionMaps = class'DXRMapVariants'.static.IsRevisionMaps(player()); - FixUNATCORetinalScanner(); - switch(dxr.localURL) { + case "03_NYC_UNATCOHQ": + FixUNATCORetinalScanner(); + break; + case "03_NYC_BatteryPark": + player().StartDataLinkTransmission("dl_batterypark"); + break; case "03_NYC_BrooklynBridgeStation": if (!RevisionMaps){ a = AddActor(class'Barrel1', vect(-27.953907, -3493.229980, 45.101418)); diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc index 8b30197cd..3b2b367bf 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM04.uc @@ -383,7 +383,20 @@ function PreFirstEntryMapFixes() function PostFirstEntryMapFixes() { - FixUNATCORetinalScanner(); + local DeusExGoal goal; + + switch(dxr.localURL) + { + case "04_NYC_UNATCOHQ": + FixUNATCORetinalScanner(); + break; + case "04_NYC_STREET": + goal = player().FindGoal('TellJaime'); + if (goal != None) { + goal.SetCompleted(); + } + break; + } } function AnyEntryMapFixes() diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc index 14efcbe89..86019df5d 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM05.uc @@ -331,18 +331,45 @@ function BalanceJailbreak() else { // put the items in the surgery ward - itemLocations[num++] = vectm(2174.416504,-569.534729,-213.660309);// paul's bed - itemLocations[num++] = vectm(2176.658936,-518.937012,-213.659302);// paul's bed - itemLocations[num++] = vectm(1792.696533,-738.417175,-213.660248);// bed 2 - itemLocations[num++] = vectm(1794.898682,-802.133301,-213.658630);// bed 2 - itemLocations[num++] = vectm(1572.443237,-739.527649,-213.660095);// bed 1 - itemLocations[num++] = vectm(1570.557007,-801.213806,-213.660095);// bed 1 - itemLocations[num++] = vectm(1269.494019,-522.082458,-221.659180);// near ambrosia - itemLocations[num++] = vectm(1909.302979,-376.711639,-221.660095);// desk with microscope and datacube - itemLocations[num++] = vectm(1572.411865,-967.828735,-261.659546);// on the floor, at the wall with the monitors - itemLocations[num++] = vectm(1642.170532,-968.813354,-261.660736); - itemLocations[num++] = vectm(1715.513062,-965.846558,-261.657837); - itemLocations[num++] = vectm(1782.731689,-966.754700,-261.661041); + itemLocations[num++] = vectm(2160,-585,-203);// paul's bed + itemLocations[num++] = vectm(2160,-505,-203);// paul's bed + itemLocations[num++] = vectm(1805,-730,-203);// middle bed + itemLocations[num++] = vectm(1805,-810,-203);// middle bed + itemLocations[num++] = vectm(1555,-730,-203);// bed near ambrosia + itemLocations[num++] = vectm(1555,-810,-203);// bed near ambrosia + + //Third bed locations + itemLocations[num++] = vectm(2190,-545,-203);// paul's bed + itemLocations[num++] = vectm(1775,-770,-203);// middle bed + itemLocations[num++] = vectm(1585,-770,-203);// bed near ambrosia + + + itemLocations[num++] = vectm(1270,-522,-211);// near ambrosia + itemLocations[num++] = vectm(1275,-710,-211);// table with two microscopes and datacube (left) + itemLocations[num++] = vectm(1275,-805,-211);// table with two microscopes and datacube (right) + itemLocations[num++] = vectm(1910,-375,-211);// desk with microscope and datacube + itemLocations[num++] = vectm(2160,-327,-211);// table with two monitors (left) + itemLocations[num++] = vectm(2055,-327,-211);// table with two monitors (right) + itemLocations[num++] = vectm(2110,-327,-211);// table with two monitors (middle) + + // on the floor, at the wall with the monitors, starting in the center, working out + itemLocations[num++] = vectm(1575,-950,-251); + itemLocations[num++] = vectm(1650,-950,-251); + itemLocations[num++] = vectm(1500,-950,-251); + itemLocations[num++] = vectm(1725,-950,-251); + itemLocations[num++] = vectm(1425,-950,-251); + itemLocations[num++] = vectm(1800,-950,-251); + itemLocations[num++] = vectm(1350,-950,-251); + itemLocations[num++] = vectm(1875,-950,-251); + itemLocations[num++] = vectm(1275,-950,-251); + + // seriously, why do you have so much stuff, I never want to see these spots get used + // on the floor, at the wall with the monitors, emergency second row + itemLocations[num++] = vectm(1575,-900,-251); + itemLocations[num++] = vectm(1650,-900,-251); + itemLocations[num++] = vectm(1500,-900,-251); + itemLocations[num++] = vectm(1725,-900,-251); + itemLocations[num++] = vectm(1425,-900,-251); foreach AllActors(class'#var(prefix)DataLinkTrigger', dlt) { if(dlt.datalinkTag != 'dl_equipment') continue; diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc index 09941f8cd..1961072a5 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM06.uc @@ -4,6 +4,7 @@ var bool raidStarted; function CheckConfig() { + local Rotator rot; local int i; add_datacubes[i].map = "06_HONGKONG_VERSALIFE"; @@ -22,6 +23,13 @@ function CheckConfig() add_datacubes[i].text = "It's so handy being able to quickly grab some cash from the Quick Stop before getting to the club!|nAccount: 2332316 |nPIN: 1608 "; i++; + add_datacubes[i].map = "06_HONGKONG_WANCHAI_STREET"; + add_datacubes[i].text = "Miss Chow,|nOur agents have ascertained the access codes to the police evidence vault in the market. When you are ready, our agents can enter the vault and remove the evidence located within using the code 87342.|n|nCommander Triolet"; + add_datacubes[i].Location = vect(-300.4, -1544.0, 1970.4); + rot.Yaw = -2250.0; + add_datacubes[i].rotation = rot; + i++; + add_datacubes[i].map = "06_HONGKONG_WANCHAI_UNDERWORLD"; add_datacubes[i].text = "Max,|nIf you need to get into the freezer again, I've connected the door to the security terminal in the meeting room.|n|nLogin: LUCKYMONEY |nPassword: REDARROW |n|nRemember, that's the same account as your own computer."; add_datacubes[i].Location = vect(367,-2511,-334); @@ -841,7 +849,10 @@ function AnyEntryMapFixes() local ConEventSpeech ces; local ConEventSetFlag cesf; local ConEventTrigger cet; + local OrdersTrigger ot; local #var(prefix)Pigeon pigeon; + local #var(prefix)MaggieChow maggie; + local #var(prefix)Maid maysung; // if flag Have_ROM, set flags Have_Evidence and KnowsAboutNanoSword? // or if flag Have_ROM, Gordon Quick should let you into the compound? requires Have_Evidence and MaxChenConvinced @@ -953,8 +964,23 @@ function AnyEntryMapFixes() m.bLocked = false; m.bHighlight = true; } + HandleJohnSmithDeath(); FixMaggieMoveSpeed(); + + if (dxr.flagbase.GetBool('MaxChenConvinced')) { + foreach AllActors(class'#var(prefix)MaggieChow', maggie) { + maggie.LeaveWorld(); + break; + } + + dxr.flagbase.SetBool('MeetMaySung_Played', true); + foreach AllActors(class'OrdersTrigger', ot, 'MaySungFollows') { + ot.Trigger(None, None); + break; + } + } + break; case "06_HONGKONG_WANCHAI_CANAL": diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc index fdc008a33..74c71b280 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM08.uc @@ -18,7 +18,6 @@ function AnyEntryMapFixes() RemoveReactions(s); } - Player().StartDataLinkTransmission("DL_Entry"); RearrangeMJ12ConvergingInfolink(); RearrangeJockExitDialog(); @@ -302,3 +301,8 @@ function PreFirstEntryMapFixes() } } } + +function PostFirstEntryMapFixes() +{ + Player().StartDataLinkTransmission("DL_Entry"); // play on any start +} diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc index 48b543961..6e8493a53 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupM15.uc @@ -617,6 +617,25 @@ function AnyEntryMapFixes() } } + +function PostFirstEntryMapFixes() +{ + local #var(prefix)Keypad k; + + switch(dxr.localURL) { + case "15_area51_final": + if(dxr.flags.IsSpeedrunMode() && FeatureFlag(3,3,0, "Area51EndingBalancePass2")) { + foreach AllActors(class'#var(prefix)Keypad', k) { + if(k.Event == 'blastdoor_upper') { + k.bHackable = false; + break; + } + } + } + break; + } +} + function TimerMapFixes() { switch(dxr.localURL) diff --git a/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc b/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc index fb973e745..c2a1bddc3 100644 --- a/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc +++ b/DXRMapFixups/DeusEx/Classes/DXRFixupVandenberg.uc @@ -4,6 +4,18 @@ var bool M14GaryNotDone; var bool M12GaryHostageBriefing; var int storedBotCount;// MJ12 bots in CMD +function CheckConfig() +{ + local int i; + + add_datacubes[i].map = "12_VANDENBERG_GAS"; + add_datacubes[i].imageClass = class'Image12_Tiffany_HostagePic'; + add_datacubes[i].location = vect(-107.1, 901.3, -939.4); + i++; + + Super.CheckConfig(); +} + function PreFirstEntryMapFixes() { local ElevatorMover e; @@ -221,9 +233,7 @@ function PreFirstEntryMapFixes() //Fix prepivot, since the upper door was set way off to the side. Just adjust both in the same way //so that they are centered roughly in the middle of the door - door.BasePos = door.BasePos - vectm(door.PrePivot.X,door.PrePivot.Y,door.PrePivot.Z); - door.PrePivot=vect(0,0,0); - door.SetLocation(door.BasePos); + RemoveDXMoverPrePivot(door); } } AddSwitch( vect(654.545,3889.5397,-367.262), rot(0, 16384, 0), 'ShedDoor'); diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc index 6bdc2237e..71ce0af21 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM03.uc @@ -230,9 +230,6 @@ function AnyEntry() Super.AnyEntry(); switch(dxr.localURL) { - case "03_NYC_BATTERYPARK": - Player().StartDataLinkTransmission("dl_batterypark"); - break; case "03_NYC_AIRFIELDHELIBASE": UpdateGoalWithRandoInfo('FindAmbrosiaBarrels', "The Ambrosia could be anywhere in the helibase or airfield."); break; diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc b/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc index e464cf0f2..34c2e3f62 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsM15.uc @@ -71,6 +71,26 @@ function int InitGoals(int mission, string map) AddGoalActor(goal, 1, 'DataLinkTrigger21', PHYS_None); // DL_Blue_Fusion loc = AddGoalLocation("15_AREA51_PAGE", "Observation Deck", NORMAL_GOAL | VANILLA_GOAL, vect(6029.028809, -8301.839844, -5148.736328), rot(0, -36944, 0)); AddMapMarker(class'Image15_Area51_Sector4',192,77,"E","Ending", loc,"One of the end game goals can be located on the base of the Blue Fusion Reactor in the top floor Observation Deck overlooking Bob Page."); + + if (FeatureFlag(3,3,0, "Area51EndingBalancePass2")){ + if (#bool(shuffleucswitches)){ + //Shuffle the UC switches themselves + goal = AddGoal("15_AREA51_PAGE", "Upper UC Shutdown", NORMAL_GOAL, 'DeusExMover72', PHYS_MovingBrush); + loc = AddGoalLocation("15_AREA51_PAGE", "Upper UC Control Room", NORMAL_GOAL | VANILLA_GOAL, vect(7873,-7548,-5096), rot(0, 16384, 0)); + + goal = AddGoal("15_AREA51_PAGE", "Middle UC Shutdown", NORMAL_GOAL, 'DeusExMover51', PHYS_MovingBrush); + loc = AddGoalLocation("15_AREA51_PAGE", "Middle UC Control Room", NORMAL_GOAL | VANILLA_GOAL, vect(5518,-8644,-5540), rot(0, 16384, 0)); + + goal = AddGoal("15_AREA51_PAGE", "Bottom UC Shutdown", NORMAL_GOAL, 'DeusExMover49', PHYS_MovingBrush); + loc = AddGoalLocation("15_AREA51_PAGE", "Bottom UC Control Room", NORMAL_GOAL | VANILLA_GOAL, vect(7956,-7495,-5931), rot(0, 32768, 0)); + } else { + //Only use the rooms as extra locations + loc = AddGoalLocation("15_AREA51_PAGE", "Upper UC Control Room", NORMAL_GOAL, vect(7991,-7395,-5096), rot(0, 32768, 0)); + loc = AddGoalLocation("15_AREA51_PAGE", "Middle UC Control Room", NORMAL_GOAL, vect(5382,-8556,-5540), rot(0, 0, 0)); + loc = AddGoalLocation("15_AREA51_PAGE", "Bottom UC Control Room", NORMAL_GOAL, vect(7868,-7631,-5931), rot(0, 16384, 0)); + } + } + break; } @@ -132,6 +152,8 @@ function PreFirstEntryMapFixes() { local Trigger t; local FlagTrigger ft; + local #var(DeusExPrefix)Mover dxm; + local vector v; local bool RevisionMaps; RevisionMaps = class'DXRMapVariants'.static.IsRevisionMaps(player()); @@ -151,6 +173,25 @@ function PreFirstEntryMapFixes() ft.Destroy(); } } + } else if (dxr.localURL=="15_AREA51_PAGE" && !RevisionMaps) { + if (FeatureFlag(3,3,0, "Area51EndingBalancePass2")){ + //Remove the insane prepivot on the UC door closers + foreach AllActors(class'#var(DeusExPrefix)Mover',dxm){ + if (dxm.Event=='UC_shutdoor1' || + dxm.Event=='UC_shutdoor2' || + dxm.Event=='UC_shutdoor3'){ + + v=vectm(0,0,dxm.PrePivot.Z); + + RemoveDXMoverPrePivot(dxm); + + //Return the Z component of the prepivot so the switches rotate on center + dxm.PrePivot=v; + dxm.BasePos=dxm.BasePos+v; + dxm.SetLocation(dxm.BasePos); + } + } + } } } @@ -220,6 +261,7 @@ function AfterMoveGoalToLocation(Goal g, GoalLocation Loc) local #var(prefix)FlagTrigger ft; local #var(prefix)Switch1 button; local Dispatcher disp; + local rotator r; local string dctext; if (g.name=="Area 51 Blast Door Computer" && Loc.name != "the tower") { @@ -263,6 +305,19 @@ function AfterMoveGoalToLocation(Goal g, GoalLocation Loc) else if (g.name=="Aquinas Substation Computer") { g.actors[0].a.Event = 'AquinasDoorComputer'; } + else if (g.name=="Upper UC Shutdown" || g.name=="Middle UC Shutdown" || g.name=="Bottom UC Shutdown"){ + if (FeatureFlag(3,3,0, "Area51EndingBalancePass2")){ + r = g.actors[0].a.rotation; + r.Yaw = r.Yaw - 32768; + if (r.Pitch!=0){ //Adjust the pitch for the coolant control panel location + r.Pitch = -r.Pitch; + } + g.actors[0].a.SetRotation(r); + #var(DeusExPrefix)Mover(g.actors[0].a).BaseRot=r; + + class'DXRHoverHint'.static.Create(self, g.name, g.actors[0].a.Location, 15, 10, g.actors[0].a); + } + } if(Loc.name=="Observation Deck") {// for releasing the bots behind you foreach AllActors(class'Dispatcher', disp, 'node1') { diff --git a/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc b/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc index e81fea79a..d47db155c 100644 --- a/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc +++ b/DXRMissions/DeusEx/Classes/DXRMissionsParis.uc @@ -334,9 +334,11 @@ function AfterMoveGoalToLocation(Goal g, GoalLocation Loc) if (Loc.name=="Media Store"){ if ((g.name=="Nicolette") || (g.name=="Jaime" && dxr.flagbase.GetBool('JaimeLeftBehind'))){ //Spawn a small spotlight just to make it a bit easier to spot them through the window - dl = Spawn(class'DynamicLight',,,vectm(1025,1768,200)); - dl.LightRadius=3; - dl.LightBrightness=100; + dl = DynamicLight(Spawnm(class'DynamicLight',,,vect(990,1768,300),rot(-16385,0,0))); + dl.LightRadius=6; + dl.LightCone=1; + dl.LightBrightness=255; + dl.LightEffect=LE_Spotlight; } } diff --git a/DXRModules/DeusEx/Classes/DXRAutosave.uc b/DXRModules/DeusEx/Classes/DXRAutosave.uc index 036d90fea..a7054db4f 100644 --- a/DXRModules/DeusEx/Classes/DXRAutosave.uc +++ b/DXRModules/DeusEx/Classes/DXRAutosave.uc @@ -68,8 +68,14 @@ function ReEntry(bool IsTravel) function PostAnyEntry() { + local MemConUnit mcu; + if(bNeedSave) NeedSave(); + + foreach AllActors(class'MemConUnit', mcu) { + mcu.PostPostBeginPlay(); + } } function NeedSave() @@ -180,7 +186,7 @@ static function string GetSaveFailReason(DeusExPlayer player) } } if( f.autosave == FixedSaves || f.autosave == UnlimitedFixedSaves ) { - if(Computers(player.FrobTarget) == None) { + if(Computers(player.FrobTarget) == None && ATM(player.FrobTarget) == None) { return "You need to have a computer highlighted to save! Good Luck!"; } } @@ -242,6 +248,7 @@ static function UseSaveItem(DeusExPlayer player) item = DeusExPickup(player.FindInventoryType(class'MemConUnit')); if(item == None) return; + player.ClientMessage("You used " $ item.ItemArticle @ item.ItemName $ " to save."); item.UseOnce(); } @@ -344,15 +351,6 @@ function MapAdjustments() fixed = dxr.flags.autosave==FixedSaves || dxr.flags.autosave==UnlimitedFixedSaves; limited = dxr.flags.autosave == FixedSaves || dxr.flags.autosave == LimitedSaves; - switch(dxr.localURL) { - case "03_NYC_BrooklynBridgeStation": - // fixed saves needs a computer in M03 before helibase - if(fixed) { - AddActor(class'#var(prefix)ComputerPublic', vect(-1417.867065, -1937.349854, 446), rot(0,16384,0)); - } - break; - } - if(limited) { SetSeed("spawn MCU"); if(chance_single(80)) { diff --git a/DXRModules/DeusEx/Classes/DXRDatacubes.uc b/DXRModules/DeusEx/Classes/DXRDatacubes.uc index 50faeb495..26fcef4aa 100644 --- a/DXRModules/DeusEx/Classes/DXRDatacubes.uc +++ b/DXRModules/DeusEx/Classes/DXRDatacubes.uc @@ -551,7 +551,30 @@ function vanilla_datacubes_rules() case "15_AREA51_FINAL": //Code for stairwell blastdoor + //Not in the reactor lab datacubes_rules[i].item_name = '15_Datacube08'; + datacubes_rules[i].min_pos = vect(-3868,-5302,-2096); + datacubes_rules[i].max_pos = vect(-2435,-3906,-1442); + datacubes_rules[i].allow = false; + i++; + + //anywhere before the stairwell blastdoor + datacubes_rules[i].item_name = '15_Datacube08'; + datacubes_rules[i].min_pos = vect(-5655, -5190, -1700); + datacubes_rules[i].max_pos = vect(-2376, -2527, -534); + datacubes_rules[i].allow = true; + i++; + + //Code for Reactor lab + //Not in the reactor lab + datacubes_rules[i].item_name = '15_Datacube19'; + datacubes_rules[i].min_pos = vect(-3868,-5302,-2096); + datacubes_rules[i].max_pos = vect(-2435,-3906,-1442); + datacubes_rules[i].allow = false; + i++; + + //anywhere before the stairwell blastdoor + datacubes_rules[i].item_name = '15_Datacube19'; datacubes_rules[i].min_pos = vect(-5655, -5190, -1700); datacubes_rules[i].max_pos = vect(-2376, -2527, -534); datacubes_rules[i].allow = true; diff --git a/DXRModules/DeusEx/Classes/DXRDoors.uc b/DXRModules/DeusEx/Classes/DXRDoors.uc index ae59df4db..3c318ce21 100644 --- a/DXRModules/DeusEx/Classes/DXRDoors.uc +++ b/DXRModules/DeusEx/Classes/DXRDoors.uc @@ -203,6 +203,17 @@ function CheckConfig() i++; break; + case "15_area51_final": + // aquinas hub access, makes tong ending somewhat more viable + if(dxr.flags.IsSpeedrunMode() && FeatureFlag(3,3,0, "Area51EndingBalancePass2")) { + door_fixes[i].tag = 'blastdoor_upper'; + door_fixes[i].bBreakable = false; + door_fixes[i].bPickable = false; + door_fixes[i].bHighlight = true; + i++; + } + break; + case "15_area51_page": //Make it so the exploding door doesn't become breakable door_fixes[i].tag = 'door_clone_exit'; diff --git a/DXRModules/DeusEx/Classes/DXREnemies.uc b/DXRModules/DeusEx/Classes/DXREnemies.uc index c3b9629be..581214dcf 100644 --- a/DXRModules/DeusEx/Classes/DXREnemies.uc +++ b/DXRModules/DeusEx/Classes/DXREnemies.uc @@ -367,6 +367,15 @@ function AddDXRCredits(CreditsWindow cw) { local int i, f; local string weaponName, factionName; + local string factHeaders[6],factTexts[6],hdrs[3],texts[3]; + #ifdef injections + local CreditsWindow ncw; + ncw=cw; + #else + local NewGamePlusCreditsWindow ncw; + ncw = NewGamePlusCreditsWindow(cw); + #endif + if(dxr.flags.IsZeroRando()) return; for(f=FactionAny+1; f type) +{ + local String weaponName; + switch(type){ + case class'WeaponRobotMachinegun': + return "Robot Machine Gun"; + case class'WeaponRobotRocket': + return "Robot Rocket"; + case class'WeaponMJ12Rocket': + return "MJ12 Commando Rocket"; + case class'WeaponSpiderBot': + return "Big Spiderbot Zap"; + case class'WeaponSpiderBot2': + return "Small Spiderbot Zap"; + default: + weaponName = type.default.ItemName; if (InStr(weaponName,"DEFAULT WEAPON NAME")!=-1){ //Many NPC weapons don't have proper names set - weaponName = String(_randombotweapons[i].type.default.Class); + weaponName = String(type.default.Class); } - cw.PrintText( weaponName $ ": " $ FloatToString(_randombotweapons[i].chance, 1) $ "%" ); - } - cw.PrintLn(); + return weaponName; } } diff --git a/DXRModules/DeusEx/Classes/DXREnemyRespawn.uc b/DXRModules/DeusEx/Classes/DXREnemyRespawn.uc index 2c5b36546..8913ee37b 100644 --- a/DXRModules/DeusEx/Classes/DXREnemyRespawn.uc +++ b/DXRModules/DeusEx/Classes/DXREnemyRespawn.uc @@ -39,6 +39,7 @@ function PostFirstEntry() if( dxr.flags.settings.enemyrespawn <= 0 ) return; if( dxr.flags.IsHordeMode() ) return; + if( dxr.flags.IsHalloweenMode() ) return; time=0; foreach AllActors(class'ScriptedPawn', p) { @@ -119,6 +120,7 @@ function AnyEntry() Super.AnyEntry(); if( dxr.flags.IsHordeMode() ) return; + if( dxr.flags.IsHalloweenMode() ) return; if( dxr.flags.settings.enemyrespawn <= 0 ) return; diff --git a/DXRModules/DeusEx/Classes/DXRFixup.uc b/DXRModules/DeusEx/Classes/DXRFixup.uc index c742af6a6..6581c8aec 100644 --- a/DXRModules/DeusEx/Classes/DXRFixup.uc +++ b/DXRModules/DeusEx/Classes/DXRFixup.uc @@ -20,6 +20,8 @@ struct AddDatacube { var string map; var string text; var vector location;// 0,0,0 for random + var class imageClass; + var rotator rotation; // spawned in PreFirstEntry, so if you set a location then it will be moved according to the logic of DXRPasswords }; var AddDatacube add_datacubes[32]; @@ -655,17 +657,11 @@ function FixUNATCORetinalScanner() { local RetinalScanner r; - switch(dxr.localURL) { - case "01_NYC_UNATCOHQ": - case "03_NYC_UNATCOHQ": - case "04_NYC_UNATCOHQ": - foreach AllActors(class'RetinalScanner', r) { - if( r.Event != 'retinal_msg_trigger' ) continue; - r.bHackable = false; - r.hackStrength = 0; - r.msgUsed = ""; - } - break; + foreach AllActors(class'RetinalScanner', r) { + if( r.Event != 'retinal_msg_trigger' ) continue; + r.bHackable = false; + r.hackStrength = 0; + r.msgUsed = ""; } } @@ -920,6 +916,7 @@ function SpawnDatacubes() #endif local vector loc; + local rotator rot; local int i; if(dxr.flags.IsReducedRando()) @@ -938,11 +935,13 @@ function SpawnDatacubes() loc = add_datacubes[i].location * coords_mult; if( loc.X == 0 && loc.Y == 0 && loc.Z == 0 ) loc = GetRandomPosition(); + rot = add_datacubes[i].rotation; + rot = rotm(rot.Pitch, rot.Yaw, rot.Roll, 0.0); #ifdef injections - dc = Spawn(class'#var(prefix)DataCube',,, loc, rotm(0,0,0,0)); + dc = Spawn(class'#var(prefix)DataCube',,, loc, rot); #else - dc = Spawn(class'DXRInformationDevices',,, loc, rotm(0,0,0,0)); + dc = Spawn(class'DXRInformationDevices',,, loc, rot); #endif if( dc != None ){ @@ -950,9 +949,10 @@ function SpawnDatacubes() if(dxr.flags.settings.infodevices > 0) GlowUp(dc); dc.plaintext = add_datacubes[i].text; - l("add_datacubes spawned "$dc @ dc.plaintext @ loc); + dc.imageClass = add_datacubes[i].imageClass; + l("add_datacubes spawned "$dc$", text: \""$dc.plaintext$"\", image: "$dc.imageClass$", location: "$loc); } - else warning("failed to spawn datacube at "$loc$", text: "$add_datacubes[i].text); + else warning("failed to spawn datacube at "$loc$", text: \""$add_datacubes[i].text$"\", image: "$dc.imageClass); } } diff --git a/DXRModules/DeusEx/Classes/DXRFlags.uc b/DXRModules/DeusEx/Classes/DXRFlags.uc index 0cc286425..d32f43290 100644 --- a/DXRModules/DeusEx/Classes/DXRFlags.uc +++ b/DXRModules/DeusEx/Classes/DXRFlags.uc @@ -12,7 +12,9 @@ const RandoMedium = 9; const WaltonWareHardcore = 10; const WaltonWarex3 = 11; const ZeroRandoPlus = 12; -const HordeZombies = 1030; +const HordeZombies = 1020; +const WaltonWareHalloweenEntranceRando = 1029; +const HalloweenEntranceRando = 1030; const HalloweenMode = 1031; const WaltonWareHalloween = 1032;// why didn't they put leap day at the end of October? @@ -39,7 +41,7 @@ simulated function PlayerAnyEntry(#var(PlayerPawn) p) p.bCrowdControl = (crowdcontrol!=0); #endif - if(!VersionIsStable() || #defined(debug)) + if(!VersionIsStable() || #bool(debug)) p.bCheatsEnabled = true; if(difficulty_names[difficulty] == "Super Easy QA" && dxr.dxInfo.missionNumber > 0 && dxr.dxInfo.missionNumber < 99) { @@ -679,6 +681,7 @@ function FlagsSettings SetDifficulty(int new_difficulty) if (IsHalloweenMode()){ clothes_looting = 1; settings.speedlevel = 0;// in DXRLoadouts we override level 0 speed to mean lvl 1 run silent + settings.enemyrespawn = 20; } else { clothes_looting = 0; } @@ -702,7 +705,9 @@ function int GameModeIdForSlot(int slot) if(slot--==0) return 0; if(IsOctoberUnlocked() && slot--==0) return HalloweenMode; if(slot--==0) return EntranceRando; + if(IsOctoberUnlocked() && slot--==0) return HalloweenEntranceRando; if(IsOctoberUnlocked() && slot--==0) return WaltonWareHalloween; + if(IsOctoberUnlocked() && slot--==0) return WaltonWareHalloweenEntranceRando; if(slot--==0) return WaltonWare; if(slot--==0) return WaltonWareEntranceRando; if(!VersionIsStable()) { @@ -728,6 +733,8 @@ function string GameModeName(int gamemode) #ifdef injections case EntranceRando: return "Entrance Randomization"; + case HalloweenEntranceRando: + return "Halloween Entrance Randomization"; case HordeMode: return "Horde Mode"; case HordeZombies: @@ -754,6 +761,8 @@ function string GameModeName(int gamemode) #ifdef injections case WaltonWareEntranceRando: return "WaltonWare Entrance Rando"; + case WaltonWareHalloweenEntranceRando: + return "WaltonWare Halloween Entrance Rando"; #endif case WaltonWareHardcore: return "WaltonWare Hardcore"; @@ -771,7 +780,7 @@ function string GameModeName(int gamemode) function bool IsEntranceRando() { - return gamemode == EntranceRando || gamemode == WaltonWareEntranceRando; + return gamemode == EntranceRando || gamemode == WaltonWareEntranceRando || gamemode == HalloweenEntranceRando || gamemode == WaltonWareHalloweenEntranceRando; } function bool IsHordeMode() @@ -801,7 +810,7 @@ function bool IsSpeedrunMode() function bool IsWaltonWare() { - return gamemode == WaltonWare || gamemode == WaltonWareEntranceRando || gamemode == WaltonWareHardcore || gamemode == WaltonWarex3 || gamemode == WaltonWareHalloween; + return gamemode == WaltonWare || gamemode == WaltonWareEntranceRando || gamemode == WaltonWareHardcore || gamemode == WaltonWarex3 || gamemode == WaltonWareHalloween || gamemode == WaltonWareHalloweenEntranceRando; } function bool IsWaltonWareHardcore() @@ -811,7 +820,7 @@ function bool IsWaltonWareHardcore() function bool IsHalloweenMode() { - return gamemode == HalloweenMode || gamemode == HordeZombies || gamemode == WaltonWareHalloween; + return gamemode == HalloweenMode || gamemode == HordeZombies || gamemode == WaltonWareHalloween || gamemode == HalloweenEntranceRando || gamemode == WaltonWareHalloweenEntranceRando; } simulated function AddDXRCredits(CreditsWindow cw) diff --git a/DXRModules/DeusEx/Classes/DXRFlagsBase.uc b/DXRModules/DeusEx/Classes/DXRFlagsBase.uc index 4662d3b81..f130f6227 100644 --- a/DXRModules/DeusEx/Classes/DXRFlagsBase.uc +++ b/DXRModules/DeusEx/Classes/DXRFlagsBase.uc @@ -1215,8 +1215,17 @@ function ExtendedTests() text = VersionString(); testbool(VersionIsStable(), InStr(text, "Alpha")==-1 && InStr(text, "Beta")==-1, "VersionIsStable() matches version text, " $ text); - testbool( #defined(debug), false, "debug is disabled"); - testbool( #defined(locdebug), false, "locdebug is disabled"); + testbool( #bool(debug), false, "debug is disabled"); + testbool( #bool(locdebug), false, "locdebug is disabled"); + testbool( #bool(debugnames), false, "debugnames is disabled"); + if(#bool(allfeatures)) { // we MIGHT want to ship alphas and betas with this? + if(VersionIsStable()) test(false, "allfeatures is defined"); + else warning("!!! allfeatures is defined !!!"); + } + if(#bool(enablefeature)) { + if(VersionIsStable()) test(false, "allfeatures is defined as #var(enablefeature)"); + else warning("!!! enablefeature is defined as #var(enablefeature) !!!"); + } } function TestTime() diff --git a/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc b/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc index f1ebe5d99..1b8eaa4e0 100644 --- a/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc +++ b/DXRModules/DeusEx/Classes/DXRFlagsNGPMaxRando.uc @@ -92,7 +92,10 @@ simulated function RandomizeSettings(bool forceMenuOptions) settings.enemiesshuffled = 100; MaxRandoVal(settings.enemies_nonhumans); - if(chance_single(33) && !DXRFlags(self).IsHalloweenMode()) { // this cast is pretty nasty + if(DXRFlags(self).IsHalloweenMode()) { + settings.enemyrespawn = rng(10) + 15; + } + if(chance_single(33)) { // this cast is pretty nasty settings.enemyrespawn = rng(120) + 120; } else { settings.enemyrespawn = 0; diff --git a/DXRModules/DeusEx/Classes/DXRHalloween.uc b/DXRModules/DeusEx/Classes/DXRHalloween.uc index 7315e7146..24c38ab96 100644 --- a/DXRModules/DeusEx/Classes/DXRHalloween.uc +++ b/DXRModules/DeusEx/Classes/DXRHalloween.uc @@ -53,6 +53,12 @@ function CheckCarcasses() { local int i; local #var(DeusExPrefix)Carcass carc; + local float zombie_time, dog_zombie_time; + + if( dxr.flags.settings.enemyrespawn <= 0 ) return; + zombie_time = dxr.flags.settings.enemyrespawn - 5; + zombie_time = FClamp(zombie_time, 1, 10000); + dog_zombie_time = zombie_time / 5; for(i=0; i < num_carcs; i++) { if(CheckResurrectCorpse(carcs[i], times[i])) { @@ -77,6 +83,7 @@ function CheckCarcasses() continue; } } + if(carc.bDeleteMe) continue; for(i=0; i < num_carcs; i++) { if(carcs[i] == carc) { break; @@ -85,9 +92,9 @@ function CheckCarcasses() if(carcs[i] != carc) { carcs[num_carcs] = carc; if(#var(prefix)DobermanCarcass(carc) != None || #var(prefix)MuttCarcass(carc) != None) { // special sauce for dogs - times[num_carcs] = Level.TimeSeconds + 3 + FRand()*2; + times[num_carcs] = Level.TimeSeconds + dog_zombie_time + FRand()*2; } else { - times[num_carcs] = Level.TimeSeconds + 15 + FRand()*10; + times[num_carcs] = Level.TimeSeconds + zombie_time + FRand()*10; } carc.MaxDamage = 0.1 * carc.Mass;// easier to destroy carcasses num_carcs++; @@ -150,6 +157,7 @@ function bool CheckResurrectCorpse(#var(DeusExPrefix)Carcass carc, float time) { // return true to compress the array if(carc == None) return true; + if(carc.bDeleteMe) return true; // wait for Zombie Time! if(time > Level.TimeSeconds) return false; @@ -194,6 +202,8 @@ static function bool ResurrectCorpse(DXRActorsBase module, #var(DeusExPrefix)Car local bool removeItem; local string s; + if(carc==None || carc.bDeleteMe) return False; + livingClassName = GetPawnClassNameFromCarcass(module, carc.class); livingClass = module.GetClassFromString(livingClassName,class'ScriptedPawn'); @@ -306,9 +316,23 @@ function MapFixes() local PathNode p; local #var(DeusExPrefix)Carcass carc; local class<#var(DeusExPrefix)Carcass> carcclass; + local ScriptedPawn sp; local float dist; switch(dxr.localURL) { + case "01_NYC_UNATCOHQ": + case "03_NYC_UNATCOHQ": + case "04_NYC_UNATCOHQ": + foreach AllActors(class'#var(DeusExPrefix)Carcass', carc) { + carc.bNotDead = true; + carc.itemName = ReplaceText(carc.itemName, " (Dead)", " (Unconscious)"); + } + foreach AllActors(class'ScriptedPawn', sp) { + if(sp.bInvincible) { + RemoveFears(sp); + } + } + break; case "09_NYC_GRAVEYARD": SetSeed("DXRHalloween MapFixes graveyard bodies"); foreach AllActors(class'PathNode', p) { @@ -464,6 +488,7 @@ function SpawnJackOLantern(vector loc) r2.Yaw = rng(20000) - 10000; loc = wall1.loc + (wall1.norm << r2) * 64; jacko = spawn(class'DXRJackOLantern',,, loc, r); + if(jacko == None) continue; size = rngf() + 0.6; jacko.DrawScale *= size; jacko.SetCollisionSize(jacko.CollisionRadius*size, jacko.CollisionHeight*size); @@ -477,6 +502,12 @@ function SpawnSpiderweb(vector loc) local rotator rot; local ZoneInfo zone; local class webClass; + // Used for texture trace + local vector EndTrace, StartTrace, HitLocation, HitNormal; + local actor target; + local int texFlags; + local name texName, texGroup; + local bool bInvisibleWall; loc.X += rngfn() * 256.0;// 16 feet in either direction loc.Y += rngfn() * 256.0;// 16 feet in either direction @@ -496,6 +527,14 @@ function SpawnSpiderweb(vector loc) if(chance_single(100-dist)) return; } + EndTrace = loc + vector(rot) * -32; + foreach TraceTexture(class'Actor', target, texName, texGroup, texFlags, HitLocation, HitNormal, EndTrace, loc) { + if ((texFlags & 1) !=0) { // 1 = PF_Invisible + return; + } + break; + } + rot.roll = rng(65536); switch(rng(3)){ diff --git a/DXRModules/DeusEx/Classes/DXRMapVariants.uc b/DXRModules/DeusEx/Classes/DXRMapVariants.uc index 7e05ccbb7..0c410ee5f 100644 --- a/DXRModules/DeusEx/Classes/DXRMapVariants.uc +++ b/DXRModules/DeusEx/Classes/DXRMapVariants.uc @@ -142,6 +142,9 @@ static function bool IsVanillaMaps(#var(PlayerPawn) player) function int GetMirrorMapsSetting() { +#ifndef injections + return -1; //Ignore the mirroredmaps setting, since we don't support them without injections +#endif return dxr.flags.mirroredmaps; } @@ -239,6 +242,7 @@ function ExtendedTests() TestCoords("02_NYC_BatteryPark.dx", "02_NYC_BatteryPark_1_2_1.dx", 1,2,1); TestCoords("02_NYC_BatteryPark.dx", "02_NYC_BatteryPark_0.1_1.2_-1.3.dx", 0.1, 1.2, -1.3); + #ifdef injections oldmirroredmaps = dxr.flags.mirroredmaps; dxr.flags.mirroredmaps = 100; teststring(VaryURL("test#"), "test_-1_1_1#", "VaryURL 1"); @@ -247,4 +251,5 @@ function ExtendedTests() teststring(VaryURL("test.dx"), "test_-1_1_1.dx", "VaryURL 4"); teststring(VaryURL("test?query=param"), "test_-1_1_1?query=param", "VaryURL 5"); dxr.flags.mirroredmaps = oldmirroredmaps; + #endif } diff --git a/DXRModules/DeusEx/Classes/DXRMemes.uc b/DXRModules/DeusEx/Classes/DXRMemes.uc index 0f2872283..9a3ea051f 100644 --- a/DXRModules/DeusEx/Classes/DXRMemes.uc +++ b/DXRModules/DeusEx/Classes/DXRMemes.uc @@ -45,8 +45,8 @@ function RandomLiberty() foreach AllActors(class'NYLibertyTop',top){ if(IsOctober()) { - liberty.style = STY_Translucent; - liberty.ScaleGlow = 0.5; + top.style = STY_Translucent; + top.ScaleGlow = 0.5; } } diff --git a/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc b/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc index cf86a8547..345377b34 100644 --- a/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc +++ b/DXRModules/DeusEx/Classes/DXRMusicPlayer.uc @@ -92,6 +92,7 @@ function ClientSetMusic( playerpawn NewPlayer, music NewSong, byte NewSection, b { local bool changed_song, set_seed; local bool rando_music_setting; + local bool use_random_music, play_music; local int continuous_setting; p = #var(PlayerPawn)(NewPlayer); @@ -119,9 +120,23 @@ function ClientSetMusic( playerpawn NewPlayer, music NewSong, byte NewSection, b CombatSection = 26;// idk why but section 3 takes time to start playing the song } - // ignore complicated logic if everything is disabled + use_random_music=True; + play_music=True; if( p == None || dxr == None || (continuous_setting == c.default.disabled && rando_music_setting == false) ) { - _ClientSetMusic(NewSong, NewSection, NewCdTrack, NewTransition); + use_random_music = False; + } +#ifdef revision + if (class'RevJCDentonMale'.Default.bUseRevisionSoundtrack){ + use_random_music = False; + play_music=False; + } +#endif + + // ignore complicated logic if everything is disabled + if( !use_random_music ) { + if(play_music){ + _ClientSetMusic(NewSong, NewSection, NewCdTrack, NewTransition); + } // really make sure we clean the config PrevSong = NewSong; PrevMusicMode = 0; @@ -218,6 +233,11 @@ function PlayRandomSong(bool setseed) l("PlayRandomSong " $ setseed @ p); if(p == None) return; +#ifdef revision + //Don't play music via the DXRMusicPlayer if Revision soundtrack is enabled + if (class'RevJCDentonMale'.Default.bUseRevisionSoundtrack) return; +#endif + continuous_setting = class'MenuChoice_ContinuousMusic'.default.value; rando_music_setting = class'MenuChoice_RandomMusic'.static.IsEnabled(dxr.flags); l("PlayRandomSong 1: "$p@dxr@dxr.dxInfo.missionNumber@continuous_setting@rando_music_setting); @@ -318,6 +338,12 @@ simulated event Tick(float deltaTime) if(p == None && string(Level.Game.class.name) == "DXRandoTests") return; +#ifdef revision + //Don't do anything with the music player if Revision soundtrack is enabled + if (class'RevJCDentonMale'.Default.bUseRevisionSoundtrack) + return; +#endif + // DEUS_EX AMSD In singleplayer, do the old thing. // In multiplayer, we can come out of dying. if (!p.PlayerIsClient()) diff --git a/DXRModules/DeusEx/Classes/DXRReduceItems.uc b/DXRModules/DeusEx/Classes/DXRReduceItems.uc index 7de1715cb..b6344e1f3 100644 --- a/DXRModules/DeusEx/Classes/DXRReduceItems.uc +++ b/DXRModules/DeusEx/Classes/DXRReduceItems.uc @@ -5,6 +5,11 @@ struct _ItemReduction { var int percent; }; +struct AmmoInfo { + var class type; + var String backupName; +}; + var int mission_scaling[16]; var _ItemReduction _item_reductions[16]; var _ItemReduction _max_ammo[16]; @@ -413,9 +418,9 @@ simulated function SetMaxAmmo(class type, int percent) simulated function AddDXRCredits(CreditsWindow cw) { - local int i; + //local int i; local DXREnemies e; - local class w; + //local class w; if(dxr.flags.IsZeroRando()) return; cw.PrintHeader( "Items" ); @@ -429,27 +434,53 @@ simulated function AddDXRCredits(CreditsWindow cw) cw.PrintHeader( "Ammo: "$dxr.flags.settings.ammo$"%" ); e = DXREnemies(dxr.FindModule(class'DXREnemies')); if(e != None) { - for(i=0; i < 100; i++) { - w = e.GetWeaponConfig(i).type; - if( w == None ) break; - PrintAmmoRates(cw, w); - } + GatherAmmoRates(cw,e); } cw.PrintLn(); } -simulated function PrintAmmoRates(CreditsWindow cw, class w) + +simulated function GatherAmmoRates(CreditsWindow cw, DXREnemies e) +{ + local int i,j; + local class w; + local AmmoInfo ammoTypes[50]; + + + for(i=0; i < 100; i++) { + w = e.GetWeaponConfig(i).type; + if( w == None ) break; + + AddAmmoInfo(w.Default.AmmoName,w,ammoTypes); + for(j=0; j a, class w, out AmmoInfo types[50]) { - local class a; local int i; - a = w.default.AmmoName; - PrintItemRate(cw, a, dxr.flags.settings.ammo, true, w.default.ItemName $ " Ammo"); - for(i=0; i c, int percent, optional bool AllowIncrease, optional string BackupName) diff --git a/DXRModules/DeusEx/Classes/DXRStartMap.uc b/DXRModules/DeusEx/Classes/DXRStartMap.uc index 5edfdc590..3dc53a524 100644 --- a/DXRModules/DeusEx/Classes/DXRStartMap.uc +++ b/DXRModules/DeusEx/Classes/DXRStartMap.uc @@ -296,7 +296,7 @@ static function string _GetStartMap(int start_map_val, optional out string frien { friendlyName = ""; // clear the out param to protect against reuse by the caller - if (#defined(allstarts)) + if (#bool(allstarts)) bShowInMenu=1; switch(start_map_val) { @@ -523,6 +523,35 @@ static function AddNote(#var(PlayerPawn) player, bool bEmptyNotes, string text) } } +function DeusExNote AddNoteFromConv(#var(PlayerPawn) player, bool bEmptyNotes, name convname, optional int which) +{ + local Conversation con; + local ConEvent ce; + local ConEventAddNote cean; + local DeusExNote note; + + if (bEmptyNotes == false) { + return None; + } + + con = GetConversation(convname); + + // passing a negative value for `which` adds all notes, and returns None + for (ce = con.eventList; ce != None; ce = ce.nextEvent) { + cean = ConEventAddNote(ce); + if (cean != None) { + if (which <= 0) { + note = player.Addnote(cean.noteText); + if (which == 0) { + return note; + } + } + which--; + } + } + return None; +} + function MarkConvPlayed(string flagname, bool bFemale) { flagname = flagname$"_Played"; @@ -545,12 +574,6 @@ function PreFirstEntryStartMapFixes(#var(PlayerPawn) player, FlagBase flagbase, MarkConvPlayed("DL_SeeManderley", bFemale); break; case 5: - if(start_flag > 50) { - AddNote(player, bEmptyNotes, "Facility exit: 1125."); - AddNote(player, bEmptyNotes, "Until the grid is fully restored, the detention block door code has been reset to 4089 while _all_ detention cells have been reset to 4679."); - MarkConvPlayed("DL_NoPaul", bFemale); - flagbase.SetBool('MS_InventoryRemoved',true,,6); - } flagbase.SetBool('KnowsSmugglerPassword',true,,-1); break; case 6: @@ -611,43 +634,45 @@ function PreFirstEntryStartMapFixes(#var(PlayerPawn) player, FlagBase flagbase, MarkConvPlayed("M03MeetTerroristLeader", bFemale); case 34: // fallthrough case 33: - AddNote(player, bEmptyNotes, "6653 -- Code to the phone-booth entrance to mole-people hideout."); + AddNoteFromConv(player, bEmptyNotes, 'MeetCurly', 0); // 6653 -- Code to the phone-booth entrance MarkConvPlayed("dl_batterypark", bFemale); // We're dropping you off in Battery Park break; case 31: MarkConvPlayed("DL_WelcomeBack", bFemale); break; - case 41: - AddGoalFromConv(player, 'SeeManderley', 'DL_SeeManderley'); - break; - case 43: - AddGoalFromConv(player, 'CheckOnPaul', 'DL_JockParkStart'); - break; case 45: flagbase.SetBool('KnowsSmugglerPassword',true,,-1); // Paul ordinarily tells you the password if you don't know it flagbase.SetBool('GatesOpen',true,,5); - AddGoalFromConv(player, 'InvestigateNSF', 'PaulInjured'); MarkConvPlayed("PaulInjured", bFemale); GiveImage(player, class'Image04_NSFHeadquarters'); break; - case 75: - case 71:// anything greater than 70 should get these, even though this isn't an actual value currently - AddNote(player, bEmptyNotes, "Access code to the Versalife nanotech research wing on Level 2: 55655. There is a back entrance at the north end of the Canal Road Tunnel, which is just east of the temple."); + case 55: + AddNoteFromConv(player, bEmptyNotes, 'PaulInMedLab', 0); // Anna Navarre's killphrase is stored in two pieces on two computers + AddNoteFromConv(player, bEmptyNotes, 'DL_paul', 0); // Facility exit: 1125 + MarkConvPlayed("DL_NoPaul", bFemale); + MarkConvPlayed("PaulInMedLab", bFemale); + MarkConvPlayed("DL_Paul", bFemale); + flagbase.SetBool('MS_InventoryRemoved',true,,6); + break; + + case 75:// anything greater than 70 should get these, even though this isn't an actual value currently + AddNoteFromConv(player, bEmptyNotes, 'M07Briefing'); // Access code to the Versalife nanotech research wing on Level 2: 55655 MarkConvPlayed("M07Briefing", bFemale);// also spawns big spider in MJ12Lab case 70://fallthrough flagbase.SetBool('Disgruntled_Guy_Dead', true); MarkConvPlayed("Meet_MJ12Lab_Supervisor", bFemale); case 68://fallthrough - AddNote(player, bEmptyNotes, "VersaLife elevator code: 6512."); + AddNoteFromConv(player, bEmptyNotes, 'M06SupervisorConvos', 0); // VersaLife elevator code: 6512 case 67://fallthrough - AddNote(player, bEmptyNotes, "Versalife employee ID: 06288. Use this to access the VersaLife elevator north of the market."); + AddNoteFromConv(player, bEmptyNotes, 'MeetTracerTong2', -1); // VersaLife employee ID: 06288 MarkConvPlayed("MeetTracerTong", bFemale); MarkConvPlayed("MeetTracerTong2", bFemale); flagbase.SetBool('KillswitchFixed',true,,-1); case 66://fallthrough - AddNote(player, bEmptyNotes, "Luminous Path door-code: 1997."); + AddNoteFromConv(player, bEmptyNotes, 'Gate_Guard2', 1); // Luminous Path door-code: 1997 + flagbase.SetBool('MaxChenConvinced',true,,-1); flagbase.SetBool('QuickLetPlayerIn',true,,-1); flagbase.SetBool('QuickConvinced',true,,-1); MarkConvPlayed("Gate_Guard2", bFemale); @@ -673,6 +698,7 @@ function PreFirstEntryStartMapFixes(#var(PlayerPawn) player, FlagBase flagbase, GiveKey(player, 'cathedralgatekey', "Gatekeeper's Key"); GiveImage(player, class'Image11_Paris_Cathedral'); GiveImage(player, class'Image11_Paris_CathedralEntrance'); + MarkConvPlayed("DL_intro_cathedral", bFemale); case 109: GiveImage(player, class'Image10_Paris_Metro'); case 106: @@ -686,6 +712,12 @@ function PreFirstEntryStartMapFixes(#var(PlayerPawn) player, FlagBase flagbase, MarkConvPlayed("GaryHostageBriefing", bFemale); flagbase.SetBool('Heliosborn',true,,-1); //Make sure Daedalus and Icarus have merged break; + case 122: + AddNoteFromConv(player, bEmptyNotes, 'MeetTonyMares', 0); // Gary savage is thought to be in the control room + case 121: // fallthrough + AddNoteFromConv(player, bEmptyNotes, 'MeetCarlaBrown', 0); // Backup power for the bot security system + break; + case 145: flagbase.SetBool('schematic_downloaded',true,,-1); //Make sure the oceanlab UC schematics are downloaded // fallthrough @@ -707,9 +739,9 @@ function PreFirstEntryStartMapFixes(#var(PlayerPawn) player, FlagBase flagbase, MarkConvPlayed("DL_Final_Page02", bFemale); // Barely a scratch. MarkConvPlayed("DL_elevator", bFemale); // Bet you didn't know your mom and dad tried to protest when we put you in training. MarkConvPlayed("DL_conveyor_room", bFemale); // Page is further down. Find the elevator. - MarkConvPlayed("M15MeetEverett", bFemale); // Not far. You will reach Page. I just wanted to let you know that Alex hacked the Sector 2 security grid + // MarkConvPlayed("M15MeetEverett", bFemale); // Not far. You will reach Page. I just wanted to let you know that Alex hacked the Sector 2 security grid flagbase.SetBool('MS_EverettAppeared',true,,-1); - AddNote(player, bEmptyNotes, "Crew-complex security code: 8946."); + AddNoteFromConv(player, bEmptyNotes, 'M15MeetEverett', 0); // Crew-complex security code: 8946; TODO: figure out why Everett refuses to appear for this conversation on later starts // fallthrough case 151: MarkConvPlayed("DL_tong1", bFemale); // Here's a satellite image of the damage from the missile. @@ -747,34 +779,54 @@ function PostFirstEntryStartMapFixes(#var(PlayerPawn) player, FlagBase flagbase, case 35: AddGoalFromConv(player, 'LocateAirfield', 'ManderleyDebriefing02'); break; + case 36: + player.StartDataLinkTransmission("DL_LebedevKill"); + break; case 37: AddGoalFromConv(player, 'AssassinateLebedev', 'DL_LebedevKill'); break; - case 62: - case 63: - case 64: - AddGoalFromConv(player, 'FindTracerTong', 'DL_Jock_05'); - AddGoalFromConv(player, 'CheckCompound', 'DL_Jock_05'); + case 45: + AddGoalFromConv(player, 'InvestigateNSF', 'PaulInjured'); break; - case 65: - AddGoalFromConv(player, 'FindTracerTong', 'DL_Jock_05'); - AddGoalFromConv(player, 'CheckCompound', 'DL_Jock_05'); - AddGoalFromConv(player, 'ConvinceRedArrow', 'DL_Tong_00'); + case 43: + player.StartDataLinkTransmission("DL_JockParkStart"); break; - case 66: - AddGoalFromConv(player, 'FindTracerTong', 'DL_Jock_05'); + case 41: + AddGoalFromConv(player, 'SeeManderley', 'DL_SeeManderley'); break; - case 67: - case 68: - AddGoalFromConv(player, 'GetROM', 'MeetTracerTong2'); + + case 55: + AddGoalFromConv(player, 'FindEquipment', 'DL_Choice'); + AddGoalFromConv(player, 'FindAnnasKillprhase', 'PaulInMedLab'); + break; + + case 75: + AddGoalFromConv(player, 'GetVirusSchematic', 'M07Briefing'); + AddGoalFromConv(player, 'HaveDrinksWithDragonHeads', 'TriadCeremony'); break; case 70: AddGoalFromConv(player, 'ReportToTong', 'TriadCeremony'); AddGoalFromConv(player, 'HaveDrinksWithDragonHeads', 'TriadCeremony'); break; - case 75: - AddGoalFromConv(player, 'HaveDrinksWithDragonHeads', 'TriadCeremony'); + case 68: + case 67: + AddGoalFromConv(player, 'GetROM', 'MeetTracerTong2'); + break; + case 66: + AddGoalFromConv(player, 'FindTracerTong', 'DL_Jock_05'); + AddGoalFromConv(player, 'GetSword', 'DL_Tong_00B'); + break; + case 65: + AddGoalFromConv(player, 'FindTracerTong', 'DL_Jock_05'); + AddGoalFromConv(player, 'CheckCompound', 'DL_Jock_05'); + AddGoalFromConv(player, 'ConvinceRedArrow', 'DL_Tong_00'); + AddGoalFromConv(player, 'GetSword', 'DL_Tong_00B'); + break; + case 64: + case 63: + case 62: + player.StartDataLinkTransmission("DL_Jock_05"); break; case 90: @@ -802,11 +854,38 @@ function PostFirstEntryStartMapFixes(#var(PlayerPawn) player, FlagBase flagbase, AddGoalFromConv(player, 'FindEverett', 'NicoletteOutside'); break; + case 119: + goal = player.AddGoal('ContactIlluminati', true); + goal.SetText("Make contact with the Illuminati in Paris, where the former Illuminati leader, Morgan Everett, is rumored to be in hiding."); + break; + case 115: + goal = player.AddGoal('ContactIlluminati', true); + goal.SetText("Make contact with the Illuminati in Paris, where the former Illuminati leader, Morgan Everett, is rumored to be in hiding."); + AddGoalFromConv(player, 'GoToMetroStation', 'DL_morgan_uplink'); + AddGoalFromConv(player, 'RecoverGold', 'DL_intro_cathedral'); + break; + case 110: + goal = player.AddGoal('ContactIlluminati', true); + goal.SetText("Make contact with the Illuminati in Paris, where the former Illuminati leader, Morgan Everett, is rumored to be in hiding."); + goal = player.AddGoal('AccessTemplarComputer', true); + goal.SetText("Access the Templar computer system so that Morgan Everett can complete work on a cure for the Gray Death."); + break; + + case 129: + AddGoalFromConv(player, 'RescueTiffany', 'GaryHostageBriefing'); + break; + case 125: + case 122: + AddGoalFromConv(player, 'FindGarySavage', 'MeetTonyMares'); + break; + case 121: + AddGoalFromConv(player, 'GoToCommunicationsCenter', 'DL_command_bots_destroyed'); + break; + case 153: AddGoalFromConv(player, 'DestroyArea51', 'M15MeetTong'); AddGoalFromConv(player, 'DeactivateLocks', 'MeetHelios'); - //fallthrough - case 152: + case 152: // fallthrough AddGoalFromConv(player, 'KillPage', 'M15MeetEverett'); break; } @@ -884,20 +963,15 @@ static function bool BingoGoalImpossible(string bingo_event, int start_map, int break; case 6: // Hong Kong + case 7: switch(bingo_event) { - // // these two goals can actually be done with the way these starts currently work, but would normally be impossible - // case "ClubEntryPaid": + case "MaggieCanFly": + return start_map >= 66; // can technically be done still by carrying her body out of VersaLife but it's not really sensible to have as a goal at this point + // // this goal can actually be done with the way these starts currently work, but would normally be impossible // case "M06JCHasDate": // return start_map > 65; } - case 7: // fallthrough to 2nd half of Hong Kong - switch(bingo_event) - { - case "MaggieCanFly": - case "PoliceVaultBingo": // TODO: remove once a datacube with the vault code is added - return start_map > 70; - } break; case 8: // return to NYC diff --git a/DXRModules/DeusEx/Classes/DXRWeapons.uc b/DXRModules/DeusEx/Classes/DXRWeapons.uc index 6902da13b..f6d208faf 100644 --- a/DXRModules/DeusEx/Classes/DXRWeapons.uc +++ b/DXRModules/DeusEx/Classes/DXRWeapons.uc @@ -12,9 +12,21 @@ simulated function PlayerAnyEntry(#var(PlayerPawn) p) foreach AllActors(class'DeusExWeapon', w) { RandoWeapon(w); } + if(!#defined(injections)) SetTimer(1, true); } -simulated function RandoWeapon(DeusExWeapon w) +simulated function Timer() +{ + local DeusExWeapon w; + Super.Timer(); + if( dxr == None ) return; + + foreach AllActors(class'DeusExWeapon', w) { + RandoWeapon(w, true); + } +} + +simulated function RandoWeapon(DeusExWeapon w, optional bool silent) { local int oldseed, i; local float min_weapon_dmg, max_weapon_dmg, min_weapon_shottime, max_weapon_shottime, new_damage, default_shottime; @@ -36,7 +48,7 @@ simulated function RandoWeapon(DeusExWeapon w) new_damage = rngrange(new_damage, min_weapon_dmg, max_weapon_dmg); w.HitDamage = int(new_damage + 0.5); if(w.HitDamage < 2 && w.HitDamage < w.default.HitDamage) { - l(w $ " w.HitDamage ("$ w.HitDamage $") < 2"); + if(!silent) l(w $ " w.HitDamage ("$ w.HitDamage $") < 2"); w.HitDamage = 2; } @@ -53,7 +65,7 @@ simulated function RandoWeapon(DeusExWeapon w) max_weapon_shottime = float(dxr.flags.settings.max_weapon_shottime) / 100; default_shottime = GetDefaultShottime(w); w.ShotTime = rngrange(default_shottime, min_weapon_shottime, max_weapon_shottime); - l(w $ " w.HitDamage="$ w.HitDamage $ ", ShotTime=" $ w.ShotTime); + if(!silent) l(w $ " w.HitDamage="$ w.HitDamage $ ", ShotTime=" $ w.ShotTime); /*f = w.default.ReloadTime * (rngf()+0.5); w.ReloadTime = f; f = float(w.default.MaxRange) * (rngf()+0.5); @@ -66,7 +78,8 @@ simulated function RandoWeapon(DeusExWeapon w) } static function float GetDefaultShottime(DeusExWeapon w) { - if(w.ProjectileClass != None && (w.AmmoNames[1] != None || w.AmmoNames[2] != None)) { + // HACK: changing ammo types is awkward because there's no array for ShotTime, technically a nerf to the crossbow? + if(/*w.default.ProjectileClass == None &&*/ w.ProjectileClass != None && (w.AmmoNames[1] != None || w.AmmoNames[2] != None)) { return 1;// ShotTime of 1 is hardcoded when switching ammo to something with a projectile } return w.default.ShotTime; @@ -163,3 +176,10 @@ simulated function bool RandoProjectile(DeusExWeapon w, out class p, return true; } + +#ifndef injections +defaultproperties +{ + bAlwaysTick=True +} +#endif diff --git a/DXRNonVanilla/DeusEx/Classes/DXRandoGameInfo.uc b/DXRNonVanilla/DeusEx/Classes/DXRandoGameInfo.uc index 3204179bd..d41609cf6 100644 --- a/DXRNonVanilla/DeusEx/Classes/DXRandoGameInfo.uc +++ b/DXRNonVanilla/DeusEx/Classes/DXRandoGameInfo.uc @@ -136,8 +136,19 @@ event Super_PostLogin( playerpawn NewPlayer ) { local Pawn P; local DXRMusicPlayer m; + local bool useDXRMusicPlayer; + // Start player's music. - m = DXRMusicPlayer(GetDXR().LoadModule(class'DXRMusicPlayer')); + useDXRMusicPlayer=True; + + #ifdef revision + if (class'RevJCDentonMale'.Default.bUseRevisionSoundtrack){ + useDXRMusicPlayer=False; + } + #endif + + if(useDXRMusicPlayer) + m = DXRMusicPlayer(GetDXR().LoadModule(class'DXRMusicPlayer'));// this can get called before the module is loaded if(m!=None) m.ClientSetMusic( NewPlayer, Level.Song, Level.SongSection, Level.CdTrack, MTRAN_Fade ); else diff --git a/DXRVanilla/DeusEx/Classes/Player.uc b/DXRVanilla/DeusEx/Classes/Player.uc index 4cada089d..4a029ff4f 100644 --- a/DXRVanilla/DeusEx/Classes/Player.uc +++ b/DXRVanilla/DeusEx/Classes/Player.uc @@ -1313,17 +1313,18 @@ function _ClientSetMusic( music NewSong, byte NewSection, byte NewCdTrack, EMusi function ClientSetMusic( music NewSong, byte NewSection, byte NewCdTrack, EMusicTransition NewTransition ) { local DXRMusicPlayer m; - GetDXR(); - if (dxr==None){ //Probably only during ENDGAME4? + if (GetDXR()==None){ //Probably only during ENDGAME4? log("Couldn't find a DXR so we can set the music to " $ NewSong); return; } - m = DXRMusicPlayer(dxr.LoadModule(class'DXRMusicPlayer')); + m = DXRMusicPlayer(dxr.LoadModule(class'DXRMusicPlayer'));// this can get called before the module is loaded if (m==None){ - log("Found a DXR but no DXRMusicPlayer module to set the music"); + log("WARNING: DXRMusicPlayer module not found"); + _ClientSetMusic(NewSong, NewSection, NewCdTrack, NewTransition); return; + } else { + m.ClientSetMusic(self, NewSong, NewSection, NewCdTrack, NewTransition); } - m.ClientSetMusic(self, NewSong, NewSection, NewCdTrack, NewTransition); } //=========== END OF MUSIC STUFF @@ -1333,7 +1334,7 @@ function UpdateRotation(float DeltaTime, float maxPitch) local DataStorage datastorage; local int rollAmount; datastorage = class'DataStorage'.static.GetObjFromPlayer(self); - rollAmount = int(datastorage.GetConfigKey('cc_cameraRoll')); + if(datastorage != None) rollAmount = int(datastorage.GetConfigKey('cc_cameraRoll')); if(rollAmount == 0) { Super.UpdateRotation(DeltaTime,maxPitch); diff --git a/DXRVanilla/DeusEx/Classes/Weapon.uc b/DXRVanilla/DeusEx/Classes/Weapon.uc index dbc2a43e0..e38dc1982 100644 --- a/DXRVanilla/DeusEx/Classes/Weapon.uc +++ b/DXRVanilla/DeusEx/Classes/Weapon.uc @@ -15,7 +15,8 @@ function PostBeginPlay() local DXRWeapons m; Super.PostBeginPlay(); - foreach AllActors(class'DXRWeapons', m) { + m = DXRWeapons(class'DXRWeapons'.static.Find()); + if(m != None) { m.RandoWeapon(self); } } @@ -146,11 +147,9 @@ function bool LoadAmmo(int ammoNum) ret = Super.LoadAmmo(ammoNum); // we need to re-randomize the shottime - if(class'DXRando'.default.dxr != None) { - dxrw = DXRWeapons(class'DXRando'.default.dxr.FindModule(class'DXRWeapons')); - if(dxrw != None) { - dxrw.RandoWeapon(self); - } + dxrw = DXRWeapons(class'DXRWeapons'.static.Find()); + if(dxrw != None) { + dxrw.RandoWeapon(self); } return ret; diff --git a/DXRando/DeusEx/Classes/DXRAnimTracker.uc b/DXRando/DeusEx/Classes/DXRAnimTracker.uc index 9196c3d0d..8aac793da 100644 --- a/DXRando/DeusEx/Classes/DXRAnimTracker.uc +++ b/DXRando/DeusEx/Classes/DXRAnimTracker.uc @@ -44,8 +44,8 @@ function Init(string part) local rotator rot; local int a, i; - if(#defined(debug)) SaveConfig();// create/update the config file - if(#defined(debug) && part == config_part) return; + if(#bool(debug)) SaveConfig();// create/update the config file + if(#bool(debug) && part == config_part) return; for(a=0; a=100) hint = ""; + } + + if(hint!="") { + ces = class'DXRActorsBase'.static.GetSpeechEvent(con.eventList, "Hehehehe"); + ces.conSpeech.speech = "Hehehehe, thank you. Here's a tip: " $ hint @ details; + ces = class'DXRActorsBase'.static.GetSpeechEvent(con.eventList, "Come back"); + ces.conSpeech.speech = "Come back anytime. Here's a tip: " $ hint @ details; + ces = class'DXRActorsBase'.static.GetSpeechEvent(con.eventList, "Not enough cash"); + ces.conSpeech.speech = "Not enough cash, stranger. Here's a tip: " $ hint @ details; + } lastHint = newHint; diff --git a/Pawns/DeusEx/Classes/MrH.uc b/Pawns/DeusEx/Classes/MrH.uc index 19d97b785..a6c65eb7d 100644 --- a/Pawns/DeusEx/Classes/MrH.uc +++ b/Pawns/DeusEx/Classes/MrH.uc @@ -7,6 +7,10 @@ var Actor closestDestPoint, farthestDestPoint; var float maxDist; // for iterative farthestDestPoint var float proxyHeight; +// for bumping pawns +var Actor lastBumpActor; +var float lastBumpTime; + static function MrH Create(DXRActorsBase a) { local vector loc; @@ -22,7 +26,7 @@ static function MrH Create(DXRActorsBase a) h = None; for(i=0; i<100 && h == None; i++) { - loc = a.GetRandomPosition(a.player().Location, 16*150, 999999); + loc = a.GetRandomPosition(a.player().Location, 16*100, 999999); h = a.Spawn(class'MrH',,, loc); } if(h == None) return None; @@ -213,7 +217,9 @@ state Wandering local float magnitude, dist1, dist2; local rotator rot1; - target = GetFarthestNavPoint(self); + if(closestDestPoint != None) { + target = GetFarthestNavPoint(self); + } if(target != None) { farthestDestPoint = target; } @@ -344,6 +350,30 @@ function bool ShouldDropWeapon() return false; } +event Bump( Actor Other ) +{ + if(Teleporter(Other) != None || #var(prefix)MapExit(Other) != None) { + Other.SetCollision( Other.bCollideActors, false, Other.bBlockPlayers ); + } else if(Decoration(Other) != None) { + BumpDamage(Other, 55, 1000); + } else if(ScriptedPawn(Other) != None) { + BumpDamage(Other, 1, 20000); + } else if(DamageProxy(Other) != None) { + return; + } + + Super.Bump(Other); +} + +function BumpDamage(Actor Other, int damage, float momentum) +{ + if(Other != lastBumpActor || lastBumpTime < Level.TimeSeconds-1) { + Other.TakeDamage(damage, None, Location, Vect(0,1,0.5)*momentum, 'Shot'); + lastBumpActor = Other; + lastBumpTime = Level.TimeSeconds; + } +} + function PlayFootStep() { local CCResidentEvilCam cam; @@ -396,7 +426,7 @@ defaultproperties DrawScale=1.3 CollisionRadius=25 CollisionHeight=60 - proxyHeight=8 + proxyHeight=12 Mass=1000 WalkSound=Sound'DeusExSounds.Robot.MilitaryBotWalk' Health=1800 diff --git a/RevRandomizer.u b/RevRandomizer.u index c9a441b19..7413fa47a 100644 Binary files a/RevRandomizer.u and b/RevRandomizer.u differ diff --git a/VMDRandomizer.u b/VMDRandomizer.u index e35770d73..966f72fa5 100644 Binary files a/VMDRandomizer.u and b/VMDRandomizer.u differ diff --git a/compiler_settings.default.json b/compiler_settings.default.json index a7b40b4f1..c6db5ab04 100644 --- a/compiler_settings.default.json +++ b/compiler_settings.default.json @@ -4,7 +4,7 @@ "out_dir": "C:/Program Files (x86)/Steam/steamapps/common/Deus Ex Rando/", "preproc_definitions": { "vanilla":1, "singleplayer":1, "fixes":1, "mapfixes":1, "balance":1, "backtracking":1, "injections":1, "flags": 1, "prefix":"", "vanillamaps":1, - "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "DeusEx", "injectsprefix": "" + "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "DeusEx", "injectsprefix": "", "allfeatures": false }, "mods_paths": [ "../Lay-D-Denton-Project", "./" ], "packages": [ "DeusEx" ], @@ -22,7 +22,7 @@ "out_dir": "C:/Program Files (x86)/Steam/steamapps/common/Deus Ex HX/", "preproc_definitions": { "hx":1, "multiplayer":1, "mapfixes":1, "balance":1, "noflags":1, "prefix":"HX", - "DeusExPrefix":"HX", "PlayerPawn":"HXPlayerPawn", "flagvarprefix": "config", "package": "HXRandomizer", "injectsprefix": "DXR" + "DeusExPrefix":"HX", "PlayerPawn":"HXPlayerPawn", "flagvarprefix": "config", "package": "HXRandomizer", "injectsprefix": "DXR", "allfeatures": false }, "mods_paths": [ "./" ], "packages": [ "HXRandomizer" ], @@ -37,7 +37,7 @@ "out_dir": "C:/Program Files (x86)/Steam/steamapps/common/Deus Ex GMDX/", "preproc_definitions": { "gmdx":1, "singeplayer":1, "mapfixes":1, "flags":1, "prefix":"", - "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "GMDXRandomizer", "injectsprefix": "DXR" + "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "GMDXRandomizer", "injectsprefix": "DXR", "allfeatures": false }, "mods_paths": [ "./" ], "packages": [ "GMDXRandomizer" ], @@ -52,7 +52,7 @@ "out_dir": "C:/Program Files (x86)/Steam/steamapps/common/Deus Ex Revision/", "preproc_definitions": { "revision":1, "singeplayer":1, "mapfixes":1, "flags":1, "prefix":"", - "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "RevRandomizer", "injectsprefix": "DXR" + "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "RevRandomizer", "injectsprefix": "DXR", "allfeatures": false }, "mods_paths": [ "./" ], "packages": [ "RevRandomizer" ], @@ -67,7 +67,7 @@ "out_dir": "C:/Program Files (x86)/Steam/steamapps/common/Deus Ex VMD/", "preproc_definitions": { "vmd":1, "vmd175":1, "singeplayer":1, "mapfixes":1, "flags":1, "prefix":"", "vanillamaps":1, - "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "VMDRandomizer", "injectsprefix": "DXR" + "DeusExPrefix":"DeusEx", "PlayerPawn":"Human", "flagvarprefix": "", "package": "VMDRandomizer", "injectsprefix": "DXR", "allfeatures": false }, "mods_paths": [ "./" ], "packages": [ "VMDRandomizer" ], diff --git a/notes/notes.txt b/notes/notes.txt index 96ee87d80..538dc18cb 100644 --- a/notes/notes.txt +++ b/notes/notes.txt @@ -30,21 +30,6 @@ static final function SetGameRenderDevice(string RenderDevicePath) ----------------------------- ----------------------------- -check gas grenades ammo -loadouts score boosts? - -allow loadouts to mess with skills? remove the config crap? loadouts give bonus points? -taking some items/ammo out of a stack but not all when full -make aquinas router door keypad unhackable maybe? - -manually add actors to the safety checks for keys and datacubes, as an easier version of the safe_rules, basically a whitelist of actor names (and/or a quick way to generate safety rules based on actor names?) - -check gmdx augs list -add a note for every mission change? -What if consuming the VialAmbrosia yourself gave you a full heal or something lol -check mission 5 jailbreak in all mods - - Needed this to run UnrealEd http://download.microsoft.com/download/vb50pro/utility/1/win98/EN-US/Msvbvm50.exe Patched editor https://coding.hanfling.de/launch/#dxstuff @@ -82,8 +67,6 @@ EditPackages=HX EditPackages=HXRandomizer HX scale difficulty with extra players like diablo, slightly increase enemy randomization and combat difficulty -can I partially re-enable Paul's conversation in liberty island and remove the part where he gives you a weapon? - will need to mark it as played when entering unatco though, pretty sure it can break stuff GUI for NG+? can open a window similar to the advanced settings page create new "stories", start with a hub area (either hell's kitchen or hong kong, but which hell's kitchen?) class DXRStories extends DXREntranceRando; @@ -93,11 +76,6 @@ create new "stories", start with a hub area (either hell's kitchen or hong kong, remove all vanilla npcs and dialog and add new ones after beating a hub area, it can take you to the "next" area just by running a different seed, maybe do something to ensure it's based on a different hub area I need to reuse the data in DXREntranceRando, maybe by subclassing it -dynamically generate patrol routes? will probably need a new state for scriptedpawns to replace patrolling -randomize item pool by replacing 50% of items? -with flags binding, maybe I could convert some of them to floats or ints x100 -flashbang grenades? - for flashbang grenades, stun duration is hardcoded to sleep for 15 seconds in ScriptedPawn state Stunned Begin, maybe have to call them stun grenades CleanerBot Tick function could also cleanup Effects, TrashPaper, Fragment... @@ -193,6 +171,10 @@ https://web.archive.org/web/20201023054944/http://wiki.beyondunreal.com/Legacy:C http://www.unrealtexture.com/Unreal/Downloads/3DEditing/UnrealEd/Tutorials/unrealwiki-offline/unrealscript.html +Various UnrealEd information (mostly for the very detailed Lighting information): https://lodev.org/unrealed/ + +Texture Reference List (rather than squinting at the tiny previews in UEd): https://dxgalaxy.org/docs/reference/textures/ + http://dark191.333networks.com/uncodex/ https://www.bunnytrack.net/package-explorer/ @@ -203,8 +185,6 @@ https://ut99.org/viewtopic.php?t=5985 https://www.dx-revision.com/dxtutorials/constructor/tutorials.htm -charisma setting/skill that disables random dialog options with low charisma? - https://forums.epicgames.com/unreal-tournament-3/unreal-tournament-3-programming-unrealscript/176322-decompile-u-files https://ut99.org/viewtopic.php?t=12363