Bertilsson Posted August 22, 2013 Share Posted August 22, 2013 Wow, thank you! :) I will try poking around with the timing during the coming weekend. I don't think I personally will try any bigger modding than that in the action scrips. At least not any time soon and also since you have already addressed anything I can think of that was in need of improvement :cool: However I'm pretty sure the additional information will come in very handy sooner or later. Link to comment Share on other sites More sharing options...
Bertilsson Posted August 24, 2013 Share Posted August 24, 2013 Changing the initial delay was simple enough as it was only a single byte edit. (I removed it completely as I figure the fade-in effect itself is delay enough). Replace: 96 1c 00 08 0c 07 03 00 00 00 08 0a 04 01 00 61 6e 69 6d 61 74 65 43 6f 6d 70 6c 65 74 65 00 With: 96 1c 00 08 0c 07 00 00 00 00 08 0a 04 01 00 61 6e 69 6d 61 74 65 43 6f 6d 70 6c 65 74 65 00 But figuring out how to remove the delay before fade-out proved to be a tad overwhelming :sad: Sure I got the basic principle behind it all... Use the p-code-editor to modify and if the resulting size is different, use the padding string to compensate... So I figure this: this.txtItem1.animateComplete = function() { caurina.transitions.Tweener.addTween(this.textField,{transition:"linear",onComplete:mx.utils.Delegate.create(this,function() { this.textField._y = 0; } ),time:XComScrollingTextField.FADE_TIME,delay:XComScrollingTextField.REPEAT_DELAY,_alpha:0}); caurina.transitions.Tweener.addTween(this.textField,{transition:"linear",onComplete:mx.utils.Delegate.create(this,this.resetScroll),time:XComScrollingTextField.FADE_TIME,delay:XComScrollingTextField.REPEAT_DELAY + XComScrollingTextField.FADE_TIME,_alpha:100}); }; should probably be changed to something like this: ... ),time:XComScrollingTextField.FADE_TIME,delay:0,_alpha:0}); or possibly something like this: ... caurina.transitions.Tweener.addTween(this.textField,{transition:"linear",onComplete:mx.utils.Delegate.create(this,this.resetScroll),time:XComScrollingTextField.FADE_TIME,delay:0 + XComScrollingTextField.FADE_TIME,_alpha:100}); }; And then when the p-code-editor shows things like this: GetMember ; 96 11 00 00 61 6e 69 6d 61 74 65 43 6f 6d 70 6c 65 74 65 00 Push "animateComplete"; 8e 08 00 00 00 00 07 29 00 3b 01 DefineFunction2 "" 0 7 false false true false true false false true false { ; 96 11 00 00 5f 61 6c 70 68 61 00 07 00 00 00 00 08 0c 08 0d Push "_alpha" 0 "delay" "XComScrollingTextField"; 1c GetVariable ; 96 02 00 08 0e Push "REPEAT_DELAY"; 4e GetMember ; 96 04 00 08 0b 08 0d Push "time" "XComScrollingTextField"; 1c Then my head only hurts... Link to comment Share on other sites More sharing options...
kazzap Posted August 24, 2013 Share Posted August 24, 2013 Hey I don't know jack s#*! about coding or anything but I was just wondering if this is able to be used yet? Link to comment Share on other sites More sharing options...
jonezcom Posted August 24, 2013 Share Posted August 24, 2013 Yes it Works fine :) .. just needs a bit of tweaking.. hopefully ... they can figure out how to include pawns for the extra men/shivs .. just install with toolboks Link to comment Share on other sites More sharing options...
Bertilsson Posted August 24, 2013 Share Posted August 24, 2013 Installation instructionDownload and install (unzip) toolboks http://xcom.nexusmods.com/mods/79//? Download and unzip this file into the Custom Mods folder (inside the folder where you installed toolboks) http://forums.nexusmods.com/index.php?app=core&module=attach§ion=attach&attach_id=35090 Open toolboks and use the Custom Mods tab to install Increased_Squad_Size_v0_92.txt Optionally edit the last line in Increased_Squad_Size_v0_92.txt and repeat step 3 to change the number of soldiers (Vanilla seting is SkyRanger capacity = 4) Link to comment Share on other sites More sharing options...
kazzap Posted August 24, 2013 Share Posted August 24, 2013 Awesome I got it working with no problems. Just wondering one thing that might seem a little silly now. Is there a way I can increase the alien spawns as well? lol. I'm playing with the long war mod too so that helps but I can't help but feel even on impossible iron man that this amount of troops will upset the balance too much. If anyone here knows or is using a good mod to increase the enemy spawns or difficulty let me know. But seriously good work whoever worked on this, it really is bad ass to have this many people on the field. Link to comment Share on other sites More sharing options...
fys Posted August 25, 2013 Share Posted August 25, 2013 Does someone think it's feasible to reserve an extra squad slot specifically to SHIVs?During normal gameplay, training of soldiers is essential and makes you typically reject SHIVs; at least I feel that way. The idea is to have always one SHIV in the team as addition to the 4-6 human soldiers to avoid this dilemma. The specific "Add SHIV" slot would need to pop up an alternative soldier list. This list only contains soldiers that are checked for SHIV gear, like eItem_SHIVDeck_I. Link to comment Share on other sites More sharing options...
jonezcom Posted August 25, 2013 Share Posted August 25, 2013 I have used this mod for my Long War exp.(1.92) so that i have 7 (6 soldiers + 1 shiv) so i have 6 pawns and 1 without(shiv) aand it works great :) Yes that could be and excellent idea, but think that would require a bit of recoding :/ On a side-note .. tried it with 12 soldiers on beta 2 (with tired mechanics) and Boy was that tiresome, having to re-equip all the men for missions. lol .. Anyways .. you guys Rock !! :D keep up the good work Link to comment Share on other sites More sharing options...
Bertilsson Posted August 25, 2013 Share Posted August 25, 2013 Does someone think it's feasible to reserve an extra squad slot specifically to SHIVs?During normal gameplay, training of soldiers is essential and makes you typically reject SHIVs; at least I feel that way. The idea is to have always one SHIV in the team as addition to the 4-6 human soldiers to avoid this dilemma. The specific "Add SHIV" slot would need to pop up an alternative soldier list. This list only contains soldiers that are checked for SHIV gear, like eItem_SHIVDeck_I.The last slot(s) represent riding on the outside like an astromech? :smile: I guess an alternative way to do it would be to replace the RemainingPromotionsInSquad check/dialogue with a check that there are not too many human soldiers aboard and simply refuse to launch if that is the case.That way there would be no need to modify slot functionality and to verify that SHIV-only slots were not autopopulated with humans by the game itself. With some luck I could then also repurpose the entire confirmation dialogue to "Please confirm that soldier should be assigned to random class X" upon promotions. Which would be something I want a lot more than a warning that I have failed on debrief, loadout and anytime between, to promote my soldiers. Link to comment Share on other sites More sharing options...
XMarksTheSpot Posted August 25, 2013 Share Posted August 25, 2013 But figuring out how to remove the delay before fade-out proved to be a tad overwhelming :sad:Reading the disassembled byte code can be a little confusing at fist, but if you find out some underlying rules it starts to make sense. The basic principle behind it is the operand stack - every line of byte code either places elements onto or removes elements from the top of the stack for various purposes. As such the order in which stuff is set up in byte code appears somewhat backwards, e.g. function parameters are often defined in reverse order before the actual function call. A few basic examples, first storing a value in a local register and doing some operations on it. Registers can be thought of as a kind of a local variable with no name specified; register1 always refers to the class instance itself (e.g. this) while, depending on how the enclosing function is defined register2 may refer to the immediate superclass of the current class instance (e.g. super). Be aware that, as with local variables in UnrealScript, they may be shared among functions that call each other which can lead to problems. // simple variable assignment // var _loc3_ = 5; Push 5 // push integer '5' onto stack StoreRegister 3 // copy value of top stack element into register 3 Pop // remove top element from stack // variable assignment with simple arithmetic // _loc3_ = _loc3_ + 8; Push register3 8 // push value of register 3 and integer '8' onto stack (8 ends up on top) Add2 // combine top 2 elements of stack into one by performing addition, order of operands is in reverse stack position order StoreRegister 3 // store top element in register 3 Pop // remove top element // variable assignment with more complex arithmetic // _loc3_ = 1 - 2 * 3 * (4 + 5) / 9; Push 1 2 3 // push three integers onto stack Multiply // combine top two elements via multiplication (2*3) Push 4 5 // push two more integer onto stack Add2 // combine top two elements via addition (4+5) Multiply // combine top two elements via multiplication (2*3)*(4+5) Push 9 // push another integer onto stack Divide // combine top two elements via division ((2*3)*(4+5))/9 Subtract // combine top two elements via subtraction 1 - (((2*3)*(4+5))/9) StoreRegister 3 // store top element in register 3 Pop // remove top element Next examples, getting/setting instance variables: // simple instance variable assignment // this._x = 5; Push register1 "_x" 5 // push 'this', '_x' and integer '5' onto stack SetMember // combine top three stack elements, store value into instance variable, remove top element (no need for 'pop' here) // first (i.e. lowest stack position) element defines scope, second element defines instance variable name, third (i.e. top) element defines value // chained instance variable assignment // this.someChild._y = 10; Push register1 "someChild" // push 'this' (scope) and 'someChild' (instance variable name) onto stack GetMember // combine top two stack elements by getting reference to instance variable (top element) of scope (next lower element) Push "_y" 10 // push '_y' (instance variable name) and integer 10 (value) onto stack SetMember // combine top three stack elements by assigning value to instance variable // instance variable assignment using static class variables and arithmetic // this._width = 100 - SomeClass.someProperty * 2; Push register1 "_width" 100 "SomeClass" // push some values onto stack GetVariable // use top element value to get reference to class (also used to access local variables defined via 'DefineLocal') Push "someProperty" // push element to be used as variable name onto stack GetMember // combine top two stack elements ('SomeClass' reference and 'someProperty' variable name) Push 2 // push another integer onto stack Multiply // combine top two stack elements via multiplication (SomeClass.someProperty*2) Subtract // combine top two stack elements via subtraction (100-(SomeClass.someProperty*2)) SetMember // combine top three stack elements by assigning value to instance variable As you can see, the byte code primarily revolves around putting things onto the stack, removing some of them for performing operations on them and sometimes putting the combined results back onto the stack.More examples, method calls and object instantiation: // simple method call with two parameters // this.someMethod(45,18); Push 18 // push second parameter onto stack 45 // push first parameter 2 // push number of arguments register1 // push scope "someMethod" // push method name CallMethod // call method, put a return value onto stack (even if the method doesn't specifically define one) Pop // remove top element from stack // simple object instantiation without parameters // var _loc4_ = {}; Push 0 // push number of object parameters InitObject // combine top elements of stack into object (no parameters were defined, so an empty object is returned) StoreRegister 4 // copy top stack element into register 4 Pop // remove top stack element // object instantiation with parameters // var _loc4_ = {foo:8,bar:5}; Push "bar" // push name of second parameter onto stack 5 // value of second parameter "foo" // name of first parameter 8 // value of first parameter 2 // number of parameters InitObject // combine top elements of stack into object StoreRegister 4 // copy top stack element into register 4 Pop // remove top stack element // complex object instantiation // this.someMember = {_x:SomeClass.X_PADDING,_y:this._height - 50}; Push register1 // scope and variable name for final SetMember operation (this.someMember) "someMember" "_y" // second parameter of InitObject operation register1 // instance variable "_height" GetMember // get instance variable (this._height) Push 50 // arithmetic operand Subtract // perform arithmetic (this._height - 50) Push "_x" // first parameter of InitObject operation "SomeClass" // class name GetVariable // get reference to class Push "X_PADDING" // class variable name GetMember // get property value of static class variable Push 2 // number of parameters for InitObject operation InitObject // instantiate object SetMember // store result in instance variable (this.someMember = ...) Next up are function definitions: // define class instance method without parameters // function myMethod() // { // return 0; // } Push register2 "myMethod" // method name, scope always seems to point to register 2 for class methods DefineFunction2 "" 0 2 false false true false true false false true false { // not sure about the values here, '0' seems to indicate number of parameters, '2' has something to do with the number of registers available, I think, // booleans look different for functions that can access superclass Push 0 // method body Return } SetMember // assign method to scope // define class instance method with parameters and access to superclass // function doStuff(param1, param2) // { // return super.doMore(param1 + param2); // } Push register2 "doStuff" // method name and class scope DefineFunction2 "" 2 4 false false false true true false false true false 3 "param1" 4 "param2" { // note different booleans allowing access to superclass, final values define argument names and which local register they occupy Push register3 register4 // method body Add2 Push 1 register2 "doMore" CallMethod Return } SetMember // assign method to scope // define anonymous method and store it in instance variable // this.deg2rad = function(angle) // { // return Math.PI * angle / 180.0; // }; Push register1 "deg2rad" // set up scope and variable name for SetMember operation DefineFunction2 "" 1 3 false false true false true false false true false 3 "angle" { Push "Math" // function body GetVariable Push "PI" GetMember Push register3 Multiply Push 180.0 Divide Return } SetMember // assign function to scope What's neat about ActionScript is that methods in themselves are instances of the Function class and as such can be easily swapped out for another, which is exactly what I did to essentially override methods like animateComplete() in the unit box class. I suppose that covers about everything that's relevant to explaining how the vertical scrolling was implemented. As for general ActionScript byte code haxing there's still the matter of conditionals for flow control statements (i.e. if/else, while, switch) and ternary operators, both of which deal with jump offsets (which are much easier to handle here as thankfully JPEXS will auto-calculate them). I can go into details about that if anyone's interested :smile: Now, let's dissect the part related to the fade-out: Wall of text incoming: Push register1 "txtItem1" // scope of 'animateComplete' function instance GetMember Push "animateComplete" // function instance name DefineFunction2 "" 0 7 false false true false true false false true false { // body of 'animateComplete' function begins with defining second parameter of 'caurina.transitions.Tweener.addTween()' call Push "_alpha" 0 // target parameter for 'addTween()' call (fade alpha to zero) "delay" // 'delay' parameter "XComScrollingTextField" GetVariable Push "REPEAT_DELAY" GetMember // get value of static XComScrollingTextField.REPEAT_DELAY variable Push "time" // 'time' parameter "XComScrollingTextField" GetVariable Push "FADE_TIME" GetMember // get value of static XComScrollingTextField.FADE_TIME variable Push "onComplete" // 'onComplete' parameter, links to a function that is called after tweening ends DefineFunction2 "" 0 2 false false true false true false false true false { Push register1 "textField" GetMember Push "_y" 0 SetMember // reset '_y' variable to zero (reset y position to top) } // function as second argument of 'mx.utils.Delegate.create()' call Push register1 2 // 'this' as first argument, '2' = number of arguments "mx" // chain together mx.utils.Delegate.create() GetVariable Push "utils" GetMember Push "Delegate" GetMember Push "create" CallMethod Push "transition" "linear" // 'transition' parameter, use 'linear' interpolation preset 5 // number of elements for object instantiation InitObject // instantiate parameter object (second argument of 'addTween()' call) Push register1 "textField" // first argument of 'addTween()' call ('this.textField') GetMember Push 2 // number of arguments for 'addTween()' "caurina" // chain together 'caurina.transitions.Tweener.addTween()' GetVariable Push "transitions" GetMember Push "Tweener" GetMember Push "addTween" CallMethod // call 'addTween()' Pop // drop return value // next section is associated with a second call to 'addTween()', begins with defining second argument Push "_alpha" 100 // target parameter of second 'addTween()' call "delay" // 'delay' parameter "XComScrollingTextField" GetVariable Push "REPEAT_DELAY" GetMember Push "XComScrollingTextField" GetVariable Push "FADE_TIME" GetMember Add2 Push "time" // 'time' parameter "XComScrollingTextField" GetVariable Push "FADE_TIME" GetMember Push "onComplete" // 'onComplete' parameter register1 "resetScroll" GetMember Push register1 2 "mx" GetVariable Push "utils" GetMember Push "Delegate" GetMember Push "create" CallMethod // 'mx.utils.Delegate.create(this,this.resetScroll)' Push "transition" "linear" // 'transition' parameter 5 // instantiate parameter object with '5' parameters (second argument of 'addTween()') InitObject Push register1 "textField" // first argument of 'addTween()' GetMember Push 2 "caurina" // chain together 'caurina.transitions.Tweener.addTween()' GetVariable Push "transitions" GetMember Push "Tweener" GetMember Push "addTween" CallMethod // call 'addTween()' Pop // drop return value } SetMember // assign method to class Note that both tweens called in there are applied simultaneously, the time it takes to execute the first is added to the delay value of the second one. To remove the additional delay references to XComScrollingTextField.REPEAT_DELAY need to be dropped: first addTween() call: change ... Push "_alpha" 0 "delay" "XComScrollingTextField" GetVariable Push "REPEAT_DELAY" GetMember Push "time" ... to ... Push "_alpha" 0 "delay" 0 "time" ... or alternatively remove 'delay' parameter altogether: ... Push "_alpha" 0 "time" ... Push "transition" "linear" 4 InitObject ... second addTween() call: change ... Push "_alpha" 100 "delay" "XComScrollingTextField" GetVariable Push "REPEAT_DELAY" GetMember Push "XComScrollingTextField" GetVariable Push "FADE_TIME" GetMember Add2 Push "time" ... to ... Push "_alpha" 100 "delay" "XComScrollingTextField" GetVariable Push "FADE_TIME" GetMember Push "time" ... And then when the p-code-editor shows things like this: snipThen my head only hurts...The View Hex option of JPEXS' P-code editor is a little bugged, almost every other hex code line is missing a line break, the part you posted should look more like this: ; 96 11 00 00 61 6e 69 6d 61 74 65 43 6f 6d 70 6c 65 74 65 00 Push "animateComplete" ; 8e 08 00 00 00 00 07 29 00 3b 01 DefineFunction2 "" 0 7 false false true false true false false true false { ; 96 11 00 00 5f 61 6c 70 68 61 00 07 00 00 00 00 08 0c 08 0d Push "_alpha" 0 "delay" "XComScrollingTextField" ; 1c GetVariable ; 96 02 00 08 0e Push "REPEAT_DELAY" ; 4e GetMember ; 96 04 00 08 0b 08 0d Push "time" "XComScrollingTextField".Does someone think it's feasible to reserve an extra squad slot specifically to SHIVs?I second this motion :smile: SHIVs have a hard time being included in the squad roster as-is, so allowing some extra soldier slots to be occupied only by SHIVs sounds like a cool way to make players use them more. Plus, they don't show up in the mission loading screen or landing cinematic anyway, so it wouldn't be as immersion-breaking as additional soldiers :wink:Making those slots available could even be tied to some foundry projects, similar as the OTS upgrades for extra soldiers. Link to comment Share on other sites More sharing options...
Recommended Posts