Amineri Posted May 25, 2014 Share Posted May 25, 2014 I was assembling a fix for LW beta 9a and noticed that iTestPod has 'protectedwrite' flag set, which is wrong. I can confirm it has this flag in beta 9a too. There's no such flag in Random Pods original code, so this must be a typo, which can potentially cause a problem. iTestPod flags should be all zero. I had to do this in order to alloy UPKmodder to be able to revert the change out (back to the vanilla hex). The problem is that the BEFORE HEX is idential to the AFTER HEX except for the addition Core:Vector@Object@Core at the end. So when UPKmodder checks whether the BEFORE or AFTER hex is installed, it finds matching patterns for both after the install is made. The workaround was to find some innocuous flag setting so that the main "body" of the AFTER hex (without the extra 4 bytes tagged onto mark the object as a vector) is different than the BEFORE HEX so that UPKmodder can detect the install state of the file. Since iTestPod is only used as a local variable, the protected write flag shouldn't impact it's use, and so far I haven't. If you have a better suggestion for a flag to set that won't have any impact, I'm open to suggestions! -------------------- I tend to be a bit more particular (perhaps overly so) about making sure that all of the modfiles are revertable and properly can be tested for current install status. One way that helps JL and me is when we coordinate our changes. Long War EW is up around 900+ modfiles now, so coordinating everything manually would be a huge pain. So what we instead is exchange our patched UPKs and redirect UPKmodder to look at the alternate versions, then run test status. And inconsistencies will be marked as either "green" = missing install in other person's version, "red" = inconsistent modfile versions, or "yellow" = partially inconsistent. "blue" = files match, so we know we are synched up when all files test blue. A bulk test-status for the entire Long War project takes me about 20 or seconds, which isn't bad for 900+ files, which includes all of the actionscript changes. Link to comment Share on other sites More sharing options...
wghost81 Posted May 25, 2014 Author Share Posted May 25, 2014 (edited) Amineri, it has different type and different size. Doesn't UPKModder check for those? I don't have a better suggestion for UPKModder as I'm not using it as extensively as you and jonnylump do. But I have some experience in programming and modding and can say this: if more than one person is involved in development process, you sure need a version control system. If you can batch-apply all 900+ modfiles to clean vanilla packages and get a working copy of the mod, the best way would be to use VCS to store and exchange those modfiles. Edited May 25, 2014 by wghost81 Link to comment Share on other sites More sharing options...
Amineri Posted May 25, 2014 Share Posted May 25, 2014 UPKmodder very rarely explicitly defines a new size for an object -- instead it works off of relative size increase/decrease compared to the BEFORE hex. So it doesn't check the size to determine before/after install status. It's only using the pattern matching of before/after hex, which is problematic when the either is a proper subset of the other. Hence my rather ugly workaround to change a flag to prevent that situation. And yes, we really should properly use a VCS (X Marks The Spot and I used code.google and subversion when working on UPKmodder). I think the reason we're resistant to it is that it requires continual rebuilds of the upks, and since there's just the two of us we kind of muddle along. I guess it's mostly just inertia ... for about the first half of Long War EW development UPKmodder didn't have the batch apply/revert capabilities, so we sort of evolved a system and haven't bothered to change it. The primary driver for getting the bulk install working was that UPKmodder still occasionally corrupts a UPK (I get it maybe once every 2 or 3 weeks), and manually installing a big chunk of files takes about an hour or two. The bulk installer takes about a minute. So, mostly just lame excuses as to why we aren't using a full VCS :) Link to comment Share on other sites More sharing options...
wghost81 Posted May 25, 2014 Author Share Posted May 25, 2014 (edited) it requires continual rebuilds of the upksYou can uninstall just changed parts and then install a new versions. UPKModder has uninstall feature, am I correct? And if you'll add vanilla object size info, you won't even need old modfile to perform an uninstall procedure. The bulk installer takes about a minute.Why worry about upk rebuilds then? :smile: Edited May 25, 2014 by wghost81 Link to comment Share on other sites More sharing options...
Amineri Posted July 8, 2014 Share Posted July 8, 2014 Based on some fairly minor bug reports from the Long War beta testers, I've made a couple of tweaks to the version 2 (the latest I've seen) for the pod randomization module. The two issues are :1) Command pods sometimes spawn on the roof of the UFO. This is a problem on some small scout UFOs when the player cannot get on the roof, and cannot get LOS to the outsider's spawn position. It makes the mission unbeatable in that case. 2) Pods were sometimes spawning within LOS of the XCOM squad, and moving the person with sight of the aliens would immediately trigger them on the first turn. --------------- Issue #1 required the most in-depth code change. The core issue is that the iTestPod was being used as an iterated random spawn point for both regular pod spawnpoints as well as the commander pod, but the iTestPod.Z position was not being reset for the commander spawnpoint -- it was using the last randomized Z position from the previous regular pod. Setting the Z value to 0 resulted in the outsider spawning under the floor in the CrashedSmallScout Nuked City map, so I used the vanilla commander Z location + 128 (2 meters), similar to what the XComAlienPod.GetDistributedPointAround function does. The inserted code looks like : foreach WorldInfo.AllActors(class'XComAlienPod', kPod) { if(kPod.bCommanderPod) { iTestPod.Z = kPod.Location.Z; } } iTestPod.Z += 128.0; Issue #2 was partly because we are using a larger distributed pod radius for larger pods, but also because the point m_vPlayerSpawn in if(VSizeSq(iTestPod - m_vPlayerSpawn) < 5914624.0) is defined via : m_vPlayerSpawn = arrSpawns[1].Location That is it is only 1 of the 6 possible XCOM starting spawnpoints (#1 in the array 0 to 5). Since other soldier might spawn up to 6 meters away, the keep away radius of 30 meters sometimes allowed aliens to spawn within sight of one of the other soldiers. To fix these, I increased the keepaway from the covert operative from 30 meters to 32 meters (to handle the increased pod distributed distance), and the keepaway for the squad from 30 meters to 38 meters (to handle both the increased pod distributed distance and the other XCOM soldier spawnpoints). ------------------------- The complete hex for the UPKmodder file with all changes : MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=GetPossibleSpawns@XGDeployAI RESIZE=5B0 [BEFORE_HEX] [HEADER] C0 02 00 00 E0 01 00 00 [/HEADER] [CODE] 2F 19 01 A6 F9 FF FF 30 00 00 00 00 00 00 61 30 20 32 42 00 00 00 73 BA 00 00 4A 16 45 00 //foreach WorldInfo.AllActors(class'XComAlienPod', kPod) 55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 //arrPods.AddItem(kPod) 31 // 30 0f 00 70 BA 00 00 25 //iPod = 0 07 72 01 96 00 70 BA 00 00 36 00 72 BA 00 00 16 //if(iPod < arrPods.Length) 0F 00 73 BA 00 00 10 00 70 BA 00 00 00 72 BA 00 00 //kPod = arrPods[iPod] 07 EB 00 82 81 19 1B 25 63 00 00 00 00 00 00 16 0A 00 D7 BF 00 00 00 1B C6 29 00 00 00 00 00 00 16 16 18 23 00 F2 19 00 73 BA 00 00 0A 00 F6 3F 00 00 00 2D 01 F6 3F 00 00 28 16 16 //if(!OVERMIND().Enabled() && kPod.bUse == false) 55 00 71 BA 00 00 0A 00 00 73 BA 00 00 16 //arrRemove.AddItem(kPod) 06 64 01 //goto J0x164 07 13 01 F2 19 00 73 BA 00 00 0A 00 F6 3F 00 00 00 2D 01 F6 3F 00 00 28 16 //if(kPod.bUse == false) 06 64 01 //goto J0x164 07 64 01 81 19 00 73 BA 00 00 0B 00 56 40 00 00 00 1B 3E 45 00 00 00 00 00 00 25 16 16 //if(!kPod.IsInGroup(0)) 55 01 34 BA 00 00 0A 00 00 73 BA 00 00 16 //m_arrBackupSpawns.AddItem(kPod) 55 00 71 BA 00 00 0A 00 00 73 BA 00 00 16 //arrRemove.AddItem(kPod) A5 00 70 BA 00 00 16 //++ iPod 06 51 00 //goto J0x51 58 00 71 BA 00 00 00 73 BA 00 00 00 4A A0 01 //foreach arrRemove(kPod,) 56 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 //arrPods.RemoveItem(kPod) 31 //IN(1/1) 30 //IP(1/1) 58 00 72 BA 00 00 00 73 BA 00 00 00 4A A9 02 //foreach arrPods(kPod,) 0F 00 6F BA 00 00 25 //iTestPod = 0 07 7F 02 96 00 6F BA 00 00 36 01 36 BA 00 00 16 //if(iTestPod < m_arrPossibleSpawns.Length) 07 71 02 B0 E4 D8 19 00 73 BA 00 00 09 00 94 F8 FF FF 00 01 94 F8 FF FF 01 32 BA 00 00 16 16 E4 D8 19 10 00 6F BA 00 00 01 36 BA 00 00 09 00 94 F8 FF FF 00 01 94 F8 FF FF 01 32 BA 00 00 16 16 16 //if(VSizeSq(kPod.Location - m_vPlayerSpawn) < VSizeSq(m_arrPossibleSpawns[iTestPod].Location - m_vPlayerSpawn)) 57 01 36 BA 00 00 13 00 00 6F BA 00 00 00 73 BA 00 00 16 //m_arrPossibleSpawns.InsertItem(iTestPod, kPod) 0F 00 6F BA 00 00 1D FF FF FF FF //iTestPod = -1 06 7F 02 //goto J0x27F A5 00 6F BA 00 00 16 //++ iTestPod 06 C3 01 //goto J0x1C3 07 A8 02 9B 00 6F BA 00 00 1D FF FF FF FF 16 //if(iTestPod != -1) 55 01 36 BA 00 00 0A 00 00 73 BA 00 00 16 //m_arrPossibleSpawns.AddItem(kPod) 31 IN(1/1) 30 IP(1/1) 0F 01 35 BA 00 00 01 36 BA 00 00 //m_arrOriginalSpawns = m_arrPossibleSpawns 04 0B //return 53 // [/CODE] [/BEFORE_HEX] ALIAS=numPods:1A 2C 00 00 <.iPod> // num pods ALIAS=numSecL:1A 2C 01 00 <.iPod> // num sectors on the larger side ALIAS=numSecS:1A 2C 02 00 <.iPod> // num sectors on the smaller side ALIAS=mapNumX:1A 2C 03 00 <.iPod> // map X length in tiles ALIAS=mapNumY:1A 2C 04 00 <.iPod> // map Y length in tiles ALIAS=mapNumZ:1A 2C 11 00 <.iPod> // map Z length in tiles ALIAS=stepX:1A 2C 05 00 <.iPod> // X step in tiles ALIAS=stepY:1A 2C 06 00 <.iPod> // Y step in tiles ALIAS=randX:1A 2C 07 00 <.iPod> // X randomization interval in tiles ALIAS=randY:1A 2C 08 00 <.iPod> // Y randomization interval in tiles ALIAS=startX:1A 2C 09 00 <.iPod> // X start point in tiles ALIAS=startY:1A 2C 0A 00 <.iPod> // Y start point in tiles ALIAS=pointFound:1A 2C 0B 00 <.iPod> // found spawn point flag ALIAS=commandFound:1A 2C 0C 00 <.iPod> // found command point flag ALIAS=UFOIdx:1A 2C 0D 00 <.iPod> // UFO volume index ALIAS=TileX:1A 2C 0E 00 <.iPod> ALIAS=TileY:1A 2C 0F 00 <.iPod> ALIAS=TileZ:1A 2C 10 00 <.iPod> [AFTER_HEX] [HEADER] 7C 0A 00 00 90 07 00 00 [/HEADER] [CODE] //numPods = m_kSquad.arrPods.Length 0F 1A 2C 00 00 70 BA 00 00 36 35 42 00 00 00 43 00 00 00 00 00 01 38 BA 00 00 //if (numPods < 5) 07 5E 00 96 1A 2C 00 00 70 BA 00 00 2C 05 16 //numSecL = 3; 0F 1A 2C 01 00 70 BA 00 00 2C 03 //numSecS = 2; 0F 1A 2C 02 00 70 BA 00 00 2C 02 //goto (else) 06 B0 00 //else if (numPods < 7) 07 92 00 96 1A 2C 00 00 70 BA 00 00 2C 07 16 //numSecL = 3; 0F 1A 2C 01 00 70 BA 00 00 2C 03 //numSecS = 3; 0F 1A 2C 02 00 70 BA 00 00 2C 03 //goto (else) 06 B0 00 //numSecL = 4; 0F 1A 2C 01 00 70 BA 00 00 2C 04 //numSecS = 3; 0F 1A 2C 02 00 70 BA 00 00 2C 03 //mapNumX = World().NumX; 0F 1A 2C 03 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 30 0D 00 00 00 01 30 0D 00 00 //mapNumY = World().NumY; 0F 1A 2C 04 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 2F 0D 00 00 00 01 2F 0D 00 00 //mapNumZ = World().NumZ; 0F 1A 2C 11 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 2E 0D 00 00 00 01 2E 0D 00 00 //if (mapNumX > mapNumY) 07 A2 01 97 1A 2C 03 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 //stepX = mapNumX / numSecL; 0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 //stepY = mapNumY / numSecS; 0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 //goto (else) 06 F0 01 //stepX = mapNumX / numSecS; 0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 //stepY = mapNumY / numSecL; 0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 //randX = (stepX * 3) / 4; 0F 1A 2C 07 00 70 BA 00 00 91 90 1A 2C 05 00 70 BA 00 00 2C 03 16 2C 04 16 //randY = (stepY * 3) / 4; 0F 1A 2C 08 00 70 BA 00 00 91 90 1A 2C 06 00 70 BA 00 00 2C 03 16 2C 04 16 //startX = (stepX - randX) / 2; 0F 1A 2C 09 00 70 BA 00 00 91 93 1A 2C 05 00 70 BA 00 00 1A 2C 07 00 70 BA 00 00 16 2C 02 16 //if (startX < mapNumX) // x loop 07 72 05 96 1A 2C 09 00 70 BA 00 00 1A 2C 03 00 70 BA 00 00 16 //startY = (stepY - randY) / 2; 0F 1A 2C 0A 00 70 BA 00 00 91 93 1A 2C 06 00 70 BA 00 00 1A 2C 08 00 70 BA 00 00 16 2C 02 16 //if (startY < mapNumY) // y loop 07 55 05 96 1A 2C 0A 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 //pointFound = 0; 0F 1A 2C 0B 00 70 BA 00 00 2C 00 //if (pointFound < 10) // 10 attempts to find good spawn point 07 C4 04 96 1A 2C 0B 00 70 BA 00 00 2C 0A 16 //++pointFound; A3 1A 2C 0B 00 70 BA 00 00 16 //iTestPod = World().FindClosestValidLocation(World().GetPositionFromTileCoordinates(iPod[ 9] + Rand(randX),startY + Rand(randY), Rand(mapNumZ)),false, false, true); 0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 73 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 19 1B A1 7F 00 00 00 00 00 00 16 50 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 92 1A 2C 09 00 70 BA 00 00 A7 1A 2C 07 00 70 BA 00 00 16 16 92 1A 2C 0A 00 70 BA 00 00 A7 1A 2C 08 00 70 BA 00 00 16 16 A7 1A 2C 11 00 70 BA 00 00 16 16 28 28 27 16 //World().GetFloorTileForPosition(iTestPod, TileX, TileY, TileZ, true) 19 1B A1 7F 00 00 00 00 00 00 16 38 00 C4 0C 00 00 00 1B E8 38 00 00 00 00 00 00 00 6F BA 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 27 16 //iTestPod = World().GetPositionFromTileCoordinates(TileX, TileY, TileZ) 0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 2E 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 16 //if(VSizeSq(iTestPod - m_vPlayerSpawn) < 5914624.0) // far from player (38m) // 4AB48000 07 44 04 B0 E4 D8 00 6F BA 00 00 01 32 BA 00 00 16 16 1E 00 80 B4 4A 16 //goto loop3 break 06 D1 02 //if(XGBattle_SPCovertOpsExtraction(BATTLE()) != none) // far from covert operative (32m) // 4A800000 07 B5 04 77 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 2A 16 //if(VSizeSq(iTestPod - XGBattle_SPCovertOpsExtraction(BATTLE()).ChooseCovertOperativeSpawnPoint().Location) < 4194304.0) 07 B5 04 B0 E4 D8 00 6F BA 00 00 19 19 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 0A 00 FF B3 00 00 00 1C 00 B4 00 00 16 09 00 94 F8 FF FF 00 01 94 F8 FF FF 16 16 1E 00 00 80 4A 16 //goto loop3 break 06 D1 02 //pointFound = 0; // found good spawn point 0F 1A 2C 0B 00 70 BA 00 00 2C 00 //if (pointFound == 0) // if found good spawn point 07 38 05 9A 1A 2C 0B 00 70 BA 00 00 2C 00 16 //kPod = Spawn(class'XComAlienPod',,, iTestPod,,, true) 0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 //kPod.Init() 19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 //arrPods.AddItem(kPod) 55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 //startY += stepY; A1 1A 2C 0A 00 70 BA 00 00 1A 2C 06 00 70 BA 00 00 16 //while loop 06 A5 02 //startX += stepX; A1 1A 2C 09 00 70 BA 00 00 1A 2C 05 00 70 BA 00 00 16 //goto loop1; 06 5D 02 //if(((BattleDesc().m_iMissionType == 8) || BattleDesc().m_iMissionType == 10) || BattleDesc().m_eUFOType == 9) // eMission_AlienBase || eMission_Final || eShip_UFOEthereal 07 FE 05 84 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 08 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 0A 16 16 18 28 00 9A 38 3A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 AF B4 00 00 00 01 AF B4 00 00 38 3A 24 09 16 16 //commandFound = 0; 0F 1A 2C 0C 00 70 BA 00 00 2C 00 //else 06 C9 09 //[@missionCheckEnd] //if((BattleDesc().m_iMissionType == 3) || BattleDesc().m_iMissionType == 4) // eMission_Crash || eMission_LandedUFO 07 BA 09 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 03 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 04 16 16 //UFOIdx = OVERMIND().m_kLayout.GetUFOVolumeIndex(); 0F 1A 2C 0D 00 70 BA 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 0A 00 AB BC 00 00 00 1B F2 3B 00 00 00 00 00 00 16 //arrRemove = OVERMIND().m_kLayout.GetBuildingByIndex(UFOIdx).rectBuilding; 0F 00 71 BA 00 00 35 90 AF 00 00 91 AF 00 00 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 16 00 AE BC 00 00 00 1B CA 37 00 00 00 00 00 00 1A 2C 0D 00 70 BA 00 00 16 //arrRemove = ScaleRect(arrRemove, 0.750) 0F 00 71 BA 00 00 1B 14 6B 00 00 00 00 00 00 00 71 BA 00 00 1E 00 00 40 3F 16 //iTestPod.X = arrRemove.fLeft + (FRand() * (RectWidth(arrRemove))) 0F 35 0C FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 00 FD FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 56 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 //iTestPod.Y = arrRemove.fTop + (FRand() * (RectHeight(arrRemove))) 0F 35 0B FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 FE FC FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 50 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 //foreach WorldInfo.AllActors(class'XComAlienPod', kPod) 2F 19 01 A6 F9 FF FF 83 00 00 00 00 00 00 61 30 20 32 42 00 00 00 73 BA 00 00 4A 16 51 08 //if(kPod.bCommanderPod) 07 50 08 19 00 73 BA 00 00 0A 00 EC 3F 00 00 00 2D 01 EC 3F 00 00 //iTestPod.Z = kPod.Location.Z 0F 35 0A FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 35 0A FD FF FF 16 F9 FF FF 00 00 19 00 73 BA 00 00 09 00 94 F8 FF FF 00 01 94 F8 FF FF //IN 31 //IP 30 //iTestPod.Z += 128.0 // reset Z to zero to prevent command pod from appearing on roof // 43000000 B8 35 0A FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 1E 00 00 00 43 16 //iTestPod = World().FindClosestValidLocation(iTestPod, false, false, true) 0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 16 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 00 6F BA 00 00 28 28 27 16 //World().GetFloorTileForPosition(iTestPod, TileX, TileY, TileZ, true) 19 1B A1 7F 00 00 00 00 00 00 16 38 00 C4 0C 00 00 00 1B E8 38 00 00 00 00 00 00 00 6F BA 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 27 16 //iTestPod = World().GetPositionFromTileCoordinates(TileX, TileY, TileZ) 0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 2E 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 16 //kPod = Spawn(class'XComAlienPod',,, iTestPod,,, true) 0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 //kPod.Init() 19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 //arrPods.AddItem(kPod) 55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 //commandFound = 1; 0F 1A 2C 0C 00 70 BA 00 00 2C 01 //goto (else) 06 C9 09 //[@missionCheckEnd] //commandFound = 1; 0F 1A 2C 0C 00 70 BA 00 00 2C 01 //if (commandFound == 0) // extract original commander pod from map 07 53 0A 9A 1A 2C 0C 00 70 BA 00 00 2C 00 16 //foreach WorldInfo.AllActors(class'XComAlienPod', kPod) 2F 19 01 A6 F9 FF FF 5A 00 00 00 00 00 00 61 30 20 32 42 00 00 00 73 BA 00 00 4A 16 52 0A //if(kPod.bCommanderPod) 07 51 0A 19 00 73 BA 00 00 0A 00 EC 3F 00 00 00 2D 01 EC 3F 00 00 //arrPods.AddItem(kPod) 55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 //commandFound = 1; 0F 1A 2C 0C 00 70 BA 00 00 2C 01 //IN 31 //IP 30 //m_arrPossibleSpawns = arrPods 0F 01 36 BA 00 00 00 72 BA 00 00 //m_arrOriginalSpawns = m_arrPossibleSpawns 0F 01 35 BA 00 00 01 36 BA 00 00 //return; 04 0B //null ops //0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B //EOS 53 [/CODE] [/AFTER_HEX] Link to comment Share on other sites More sharing options...
wghost81 Posted July 8, 2014 Author Share Posted July 8, 2014 To fix these, I increased the keepaway from the covert operative from 30 meters to 32 meters (to handle the increased pod distributed distance), and the keepaway for the squad from 30 meters to 38 meters (to handle both the increased pod distributed distance and the other XCOM soldier spawnpoints).This leaves a very small available area for enemy spawns on small maps and on Covert Ops maps. I think being able to activate a pod from the very start is lesser evil in this case. Thanks for finding an error in command pod placement code! Will fix it for Random Pods mod too. Link to comment Share on other sites More sharing options...
wghost81 Posted August 17, 2014 Author Share Posted August 17, 2014 A small progress report on Council missions randomization. I've managed to replace original set of alien drop-down points with randomly generated drop-down points. Here's PatchUPK/PatcherGUI modfile: UPK_FILE=XComGame.upk //change ThisObj local var type to XComWorldData OBJECT=SeqAct_SpawnAlien.Activated.ThisObj REL_OFFSET=40 OBJIDX=XComWorldData //convert SpawnObj local var to vector EXPORT_ENTRY=SeqAct_SpawnAlien.Activated.SpawnObj OBJIDX=Core.StructProperty OBJECT=SeqAct_SpawnAlien.Activated.SpawnObj REL_OFFSET=40 OBJIDX=Core.Object.Vector OBJECT=SeqAct_SpawnAlien.Activated:AUTO ALIAS=numX:19 00 <.ThisObj> 09 00 <XComWorldData.NumX> 00 01 <XComWorldData.NumX> ALIAS=numY:19 00 <.ThisObj> 09 00 <XComWorldData.NumY> 00 01 <XComWorldData.NumY> ALIAS=numZ:19 00 <.ThisObj> 09 00 <XComWorldData.NumZ> 00 01 <XComWorldData.NumZ> [REPLACEMENT_CODE] //if(!bEnabled) 07 [@NotEnabled] 81 2D 01 <@bEnabled> 16 //return 04 0B [#NotEnabled] //get XComWorldData object //ThisObj = class'XComWorldData'.static.GetWorldData() 0F 00 <.ThisObj> 12 20 <Class.XComWorldData> 0A 00 <XComWorldData.GetWorldData.ReturnValue> 00 1B <GetWorldData> 16 //SpawnedUnit = none 0F 01 <@SpawnedUnit> 2A //OutputLinks[1].bHasImpulse = false 14 2D 35 <Engine.SequenceOp.SeqOpOutputLink.bHasImpulse> <Engine.SequenceOp.SeqOpOutputLink> 00 01 10 26 01 <Engine.SequenceOp.OutputLinks> 28 //m_kDropIn = new class'XGAISpawnMethod_DropIn' 0F 01 <@m_kDropIn> 11 0B 0B 0B 20 <Class.XGAISpawnMethod_DropIn> 0B //m_kDropIn.InitDropIn(iDropHeight, bUseOverwatch, bTriggerOverwatch, bPlaySound, bRevealSpawn, bSpawnImmediately, ForceAlienType, kAdditionalSound, self) 19 01 <@m_kDropIn> 59 00 <NullRef> 00 1B <InitDropIn> 01 <@iDropHeight> 2D 01 <@bUseOverwatch> 2D 01 <@bTriggerOverwatch> 2D 01 <@bPlaySound> 2D 01 <@bRevealSpawn> 2D 01 <@bSpawnImmediately> 01 <@ForceAlienType> 01 <@kAdditionalSound> 17 4A 16 //SpawnObj = ThisObj.FindClosestValidLocation(ThisObj.GetPositionFromTileCoordinates(Rand(numX), Rand(numY), numZ - 1), false, true, false); 0F 00 <.SpawnObj> 19 00 <.ThisObj> <%s141> <XComWorldData.FindClosestValidLocation.ReturnValue> 00 1B <FindClosestValidLocation> 19 00 <.ThisObj> <%s107> <XComWorldData.GetPositionFromTileCoordinates.ReturnValue> 00 1B <GetPositionFromTileCoordinates> A7 <!numX> 16 A7 <!numY> 16 93 <!numZ> 26 16 16 28 27 28 16 //SpawnPt = Spawn(class'XComSpawnPoint_Alien',,,SpawnObj,,, true) 0F 00 <.SpawnPt> 1C <Engine.Actor.Spawn> 20 <Class.XComSpawnPoint_Alien> 4A 4A 00 <.SpawnObj> 4A 4A 27 4A 16 //m_kDropIn.AddSpawnPoint(SpawnPt) 19 01 <@m_kDropIn> 14 00 <NullRef> 00 1B <AddSpawnPoint> 00 <.SpawnPt> 4A 16 //if(bSpawnImmediately) 07 [@NotImmediately] 2D 01 <@bSpawnImmediately> //m_kDropIn.CheckContentLoaded() 19 01 <@m_kDropIn> 0A 00 <NullRef> 00 1B <CheckContentLoaded> 16 [#NotImmediately] //OutputLinks[0].bHasImpulse = true 14 2D 35 <Engine.SequenceOp.SeqOpOutputLink.bHasImpulse> <Engine.SequenceOp.SeqOpOutputLink> 00 01 10 25 01 <Engine.SequenceOp.OutputLinks> 27 //ActivateOutputLink(0) 1C <Engine.SequenceOp.ActivateOutputLink> 25 16 //return 04 0B //EOS 53 Placement is completely random with this new code, i.e. ThinMen can drop right in the middle of your squad or at the farthest map edge. Drop-downs are triggered by VIP movement as usual. This code is compatible with vanilla game, Random Pods mod, Long War and existing saves. Ideas on how to improve drop-downs placement are welcomed. :smile: Link to comment Share on other sites More sharing options...
wghost81 Posted August 18, 2014 Author Share Posted August 18, 2014 And last but not least - random meld placement in action: http://i.imgur.com/DfuL1QL.jpg Working, but not yet finished. Link to comment Share on other sites More sharing options...
Krazyguy75 Posted August 18, 2014 Share Posted August 18, 2014 For council mission randomization, if you eliminated the lowest coordinates (like bottom 2 layers) that would definitely help. Because Thin Men very rarely drop on the lower areas. Don't know if this would screw with any council missions too much. Link to comment Share on other sites More sharing options...
wghost81 Posted August 18, 2014 Author Share Posted August 18, 2014 You mean drop ThinMen on the roofs only? Link to comment Share on other sites More sharing options...
Recommended Posts