anUser Posted April 6, 2013 Share Posted April 6, 2013 @ johnnylump: have you tried skipping this STORAGE().AddItem(kInt.m_eWeapon); call? It seems so promising... unfortunately right now I'm unable to test anything... despite my own warnings I made a bunch of changes and now my game crashes at mission end... and worst of all I've lost track of the edits I've tested... :( damn, I'd swear I'd learnt this lesson a bunch of times already :p Link to comment Share on other sites More sharing options...
johnnylump Posted April 6, 2013 Share Posted April 6, 2013 If that is the call in GFacility_Hangar >> RemoveInterceptor() then I believe it also is in effect if you voluntarily dismiss a fighter, which is a problem -- you'll only want it to happen when one is shot down. Link to comment Share on other sites More sharing options...
anUser Posted April 6, 2013 Share Posted April 6, 2013 that is as simple as spending 1 day rearming the intercerptors with default weaponry... which I managed to make it limited, but if it's free and unlimited it's just the time it takes to rearm them Link to comment Share on other sites More sharing options...
Amineri Posted April 6, 2013 Author Share Posted April 6, 2013 Well done. Truth is this is quite breath-taking, I wouldn't like to have to make all this changes by hand when a new patch comes out. I take note of your discoveries, that's going to the wiki (can you believe I hadn't noticed foreach loops before? I just assumed they'd be just another (if I < arr.len) do stuff; i++; jump back). Btw, how do you negate a condition !(x), by comparing to false? Side note, In another code of yours I've seen this A < B < C, can you really write it like that? 'cause I only managed to write it like (A < B) && (B < C). That UnloadSoldier function being called when cancelling the in the select squad screen is terrible news for spendable grenades. I haven't had time to test it yet, so I'd like to know from your discoveries in this field. ps: just went to check, hex byte 81 is !, so I assume that's how you negate conditions, right? Do they use endParam 16 as any other operator? Well, l have some hope regarding patches. (1) Firaxis fixes this bug in the next patch, making it unnecessary to update (2) I have a complete set of the code broken down, and since I'm completely replacing the entire function (from header to endofscript) all that is necessary is to update variable/function references. Apparently the Unreal Engine has a built-in iterator function for arrays. It has a bunch of built-in (primitive) array functions, such as foreach, add, remove, find, etc. As to the A < B < C thing --- yes, that is just a math shorthand I use. In code it has to be written as you note: (A<B) && (B<C). I'm afraid the news is worse regarding UnloadSoldier(). It is also called when a wounded soldier is sent to the infirmary, and when a soldier is dismissed while still wearing gear. Now here's a challenge along these lines: the weapons from shot-down interceptors and firestorms should be removed from the player inventory, but they are instead returned to be mounted on another craft. XComStrategyGame >> XGInterception >> CompleteEngagement () -- Checks if interceptor hp < 0 and if so calls OnInterceptorDestroyed()XGFacility_Hangar >> OnInterceptorDestroyed() -- Some bookkeepingXGFacility_Hangar >> RemoveInterceptor() -- Used if interceptor is destroyed OR dismissed, it sends the interceptor's weapon back to the storage lockers. Well, that's terrible. Definitely will have to look into that as well. I had been thinking of trying to make the interceptor game more engaging (making the consumables less powerful, but usable multiple times per engagement, or something similar). Then I saw the link to http://armorgames.com/play/5426 from a post on the 2k forums, and realized that the entire thing really just needs to be reworked from scratch. Link to comment Share on other sites More sharing options...
Amineri Posted April 6, 2013 Author Share Posted April 6, 2013 @ johnnylump: have you tried skipping this STORAGE().AddItem(kInt.m_eWeapon);call? It seems so promising... unfortunately right now I'm unable to test anything... despite my own warnings I made a bunch of changes and now my game crashes at mission end... and worst of all I've lost track of the edits I've tested... :( damn, I'd swear I'd learnt this lesson a bunch of times already :P Here's a funny story. When I first started testing the re-written IsDefeat() function, I had done something wrong in the coding that caused the mission to automatically fail at the beginning, but with no soldiers dead or equipment lost. Completely the opposite of what the change was supposed to be. It turns out that the problems was I had re-used the AISquad local variable instead of the kSquad one for getting the number of XCOM soldiers. The difference was in one byte, changing it from D1 to D2. Just changing one byte by one value had such a dramatic effect on the game... craziness. Link to comment Share on other sites More sharing options...
anUser Posted April 6, 2013 Share Posted April 6, 2013 yeah, it's a funny story once you've solved it and you can laugh at it, while it lasts it's just pain... you were right about UnloadSoldier being called not only at mission end... I get ctd just clicking anything on the inventory but armor... odd enough... I hope that is the only crash-causing error in my game... Link to comment Share on other sites More sharing options...
johnnylump Posted April 6, 2013 Share Posted April 6, 2013 You know, the path to improving the interceptor game via buffs might be to turn the buffs into risk-reward tactical choices for the player that can be turned on during a battle. So each of the three buffs becomes a new doctrine or strategy for fighting an alien craft. They might improve your to-hit but the aliens' as well, or vice-versa. Link to comment Share on other sites More sharing options...
Amineri Posted April 6, 2013 Author Share Posted April 6, 2013 (edited) I think I see how to make interceptor weapons be lost on Interceptor shoot-down, but not when dismissing the Interceptor. This was a pair of functions without a lot of space, though. 1) In OnInterceptorLost(), reorder the calls: RemoveInterceptor(kInterceptor);m_iJetsLost += 1;m_bNarrLostJet = true; to m_bNarrLostJet = true;RemoveInterceptor(kInterceptor);m_iJetsLost += 1; This will make the class boolean m_bNarrLostJet true during the time RemoveInterceptor() is called. m_bNarrLostJet is checked and reset to false when the focus returns to the UI, so it should be still true since RemoveInterceptor is immediately being called. 2) In RemoveInterceptor, add the following conditional before STORAGE().AddItem(kInt.m_eWeapon): if(m_bNarrLostJet){ STORAGE().AddItem(kInt.m_eWeapon):} This if statement will require 9 bytes ( 3 for the jump/address, 1 for the boolean token, 5 for the class variable m_bNarrLostJet) to be freed up. To free the space, recode each of the two calls to kInt.GetEntity() to kInt.m_kEntity. That is, the code will change from: if(kInt.GetEntity() != none){ kInt.HideEntity(true); kInt.GetEntity().Destroy();} to if(kInt.m_kEntity != none){ kInt.HideEntity(true); kInt.m_kEntity.Destroy();}I've found that replacing a function access with a direct variable access reduces the file size by 5 bytes (but only reduces the virtual size by 1 byte, so the virtual size in the header will have to be increased). I'm not 100% about the kInt.m_kEntity.Destroy() call, as there could be a weird interaction because of the third item. If it works like I hope, then each will free up 5 bytes, making for 10 bytes saved total, just more than the 9 needed to fit in the extra conditional. EDIT : I just realized that this will do the opposite -- destroy interceptor weapons when it is not destroyed, and won't destroy them when interceptor is shot down. Obvious solution would be to add a negation before boolean, but that's +2 bytes, which puts us one over. I'll keep looking. Edited April 6, 2013 by Amineri Link to comment Share on other sites More sharing options...
Amineri Posted April 6, 2013 Author Share Posted April 6, 2013 Well, I found one way to squeeze out ONE more byte from that function, but it's not pretty, not at all. It involves the call to kInt.HideEntity(true); There are 10 calls to HideEntity() throughout the strategy game. XGEntity is one of the few classes in the strategy game that directly extends the Actor class, rather than extending XGStrategyActor. At any rate, all 10 calls to HideEntity pass the parameter (true). I'm thinking that the function was set up to require the boolean because HideEntity calls m_kEntity.SetHidden(bHide);, and SetHidden() is a built-in Unreal Engine function in the Actor class. Since it requires a boolean, I'm guessing the XCOM version was set up to require the boolean as well. Now, the ugly part. HideEntity can be rewritten to have no parameter passed, and all 10 calls to HideEntity modified to pass no parameter instead of true. One of those 10 calls is the one in XGRemoveInterceptor, which will free up the one additional byte needed to have the 11 free bytes needed to add if(!m_bNarrLostJet) as a condition of adding the item back into STORAGE(). It's a lot of code to change to free up one byte in that function, and it's hard to say if it would have unintended side effects, so I'm not planning on making such a change at this point. Link to comment Share on other sites More sharing options...
johnnylump Posted April 6, 2013 Share Posted April 6, 2013 (edited) It might be worth investigating whether the Storage.AddItem(weapon) could be moved to the function in which you dismiss the ship, but I can't find where that is! Edit: Ah, wait, it appears to be XGHangerUI >> OnEliminate(), what is likely a fat-free function. In removeinterceptor, whattheheck does this bit do? Maybe the conditional can go ... if(kInt.GetEntity() != none) { kInt.HideEntity(true); kInt.GetEntity().Destroy(); } Edited April 6, 2013 by johnnylump Link to comment Share on other sites More sharing options...
Recommended Posts