Jump to content
ℹ️ Intermittent Download History issues ×

XMarksTheSpot

Members
  • Posts

    165
  • Joined

  • Last visited

Posts posted by XMarksTheSpot

  1. Firstly, some comments on the existing UI. As for the recommendations for using the standard Firaxis widgets to control various things, if I can reference these classes externally without needing to embed them in my .swf then I will see if I can use them. I don't want to have to embed any assets owned by Firaxis in the mod.

    From my experience it's possible to reference external ActionScript classes, you don't even need to explicitly import them like you do for sprite assets. Most of the game's Flash movies contain copies of commonly used classes, but those are just dummies; the actual classes reside in the gfxInterfaceMgr SWF movie. As menus are nested inside one another I suppose ActionScript classes are handed down along the hierarchy, too, i.e. sub-movies prefer to use classes from their ancestor movies instead of their local copies.

     

    I have sucessfully registered sprites as instances of AS classes that weren't embedded in the Flash movie I edited, so it's definitely possible. Adobe Flash won't allow exporting such a setup though, so at the very least you'll need stubs of the game's AS classes you're trying to reference.

     

     

    As for your data mining woes, I don't really know what the journal entries you're parsing look like, are they really plaintext items you're trying to parse? If that's the case, wouldn't it maybe make sense to hack into the code that prints those entries and alter them to be more compact and easier to parse? You could even go as far as encoding them in a binary format and printing them as Base64 strings. Or at the very least you could add missing information like the '[resource] increased from [old value] to [new value]' example you gave.

     

    If the journal is as large as you say, loading all of it into memory is probably a bad idea to begin with. In such a situation you'd typically want some form of parallelized streaming solution combined with an indexing system, but I kind of have my doubts that you can perform low-level tasks like this via UnrealScript, script languages typically aren't designed around that kind of functionality.

     

    Basically, a plaintext log is a very inefficient form of data storage, which puts considerable strain on re-parsing that into a data model. So my suggestion would be to condense the journal into something more usable - maybe some small additions could already help lessening the burden of data processing. For example, maybe it would be possible to insert a summary line of sorts at regular intervals (monthly, weekly, etc.) that would contain aggregated values. So to determine the value of a resource at any given point in time you wouldn't need to parse all those '[resource] has been incremented by [amount]' entries from the beginning, just from the last summary entry.

  2. Here's the current working status of the timeline:

    [snip]

    Looks like it's coming along nicely, good job :thumbsup:

     

    I think the layout could use some more work. Some notes:

     

    The "head" on the gutter doesn't move yet and can't yet be dragged, and the play button doesn't "play", stepping continuously through events. But the forward and backward buttons step through events.

    I'd suggest hooking up your timeline control to the existing XComSlider widget AS class, that should have all the interactivity features you're looking for out-of-the box. Or just place one of the default slider widgets, though that probably clashes with your intended green color scheme, so you'll want a re-skinned widget :smile:

     

    Events are shown with almost no processing. I did split out the date/time, but otherwise it's "raw" data from the journal. This looks crappy for certain events, especially mission results. They need more pretty-printing.

    What I think would be pretty nifty would be if the journal entries would be folded into the event list component you see in various base menus (main view, mission control, engineering, etc.). So in a sense playing back the timeline would also re-display the list of events that you were seeing at the corresponding points in time.

     

    Event list items allow you to categorize items (denoted via event icon) and are accompanied by a 'time left' display and a short text description. I imagine it would be nice if the event list could be filtered to only show items of specific categories, e.g. for tracking research progress or missions undertaken, etc.

     

    Text box doesn't scroll yet, so text is cut off at the bottom if the grouping of events is longer than it can show at once.

    Again, extending a stock XCOM widget class could help you out here. Depending on what you have in mind when talking about 'scrolling' there's a few options. For instance, you could employ an auto-scrolling text component as it is used for research reports (XComVerticalScrollingTextField, I think, not sure about the name off the top of my head).

     

    If you're thinking about manually scrolling, an XComList would probably be best, i.e. wrapping your journal entries in list items and populating a vertical list with it. This is basically what the aforementioned event list does, so personally I would favor that solution over a plain text dump :smile:

     

    My icons are aligned badly, but haven't yet been able to figure out how to get flash to center a shape inside another shape.

    What do you mean by 'get flash to...'? Are you talking about Adobe Flash as in the authoring software? In that case there should be the usual alignment options if you have one or more elements selected in the stage [further reading]. I think centering is based on the pivot of your movie clip objects, so you should make sure to neatly align your sub-clips to make things easier.

     

    If you're talking about aligning stuff with ActionScript, there's no convenient shortcut for it, but playing around with the _x, _y, _width and _height MovieClip properties is pretty straightforward. It's usually a matter of something along the lines of

    this._x = (this._parent._width - this._width) / 2.0
    

    if the object you want to align is a child of the object you want to align to. If 'aligner' and 'alignee' share a common parent it would be

    this._x = that._x + (that._width - this._width) / 2.0
    

    Again, taking good care of your movie clips' pivots is good practice as the _x property refers to the pivot location, not the left edge of the clip itself.

     

     

    Not sure if it'd be better to just replace them with plain vanilla text buttons "Play"/"Pause", "Next Event", "Prev Event".

    Using text-based buttons would be a viable alternative, however you'd have to take localization into consideration. The icons you're using are pretty universally understood, which is a rather elegant solution in my book :smile:

     

     

    Finally, a few random notes about the visuals (just my personal opinion, so to be taken with a grain of salt):

    • I don't think the slanted look suits the track and knob very well
    • the control buttons could use a slightly thicker border and maybe a few of the trademark double-thickness corner segments (might make them look too 'heavyweight' for their small-ish size though)
    • the bottom text view could stand to be much smaller horizontally, there's lots of wasted space currently that could be used for other components (e.g. event list view, filter buttons *nudge nudge* :wink:)
    • the timeline slider component on the other hand could be made much wider and more detailed, e.g. it could feature begin-of-month tick marks (maybe with month labels) or show little marker icons pointing to the track denoting certain events-of-interest, have a crappy mockup:

    • the bottom section could be moved down a bit to overlap a little less with with map portion

     

    I'm quite interested to see how this develops, looking pretty promising so far :)

     

  3. Attempt #2

     

    Getting mouse input back into unrealscript from flash turned out to be not so big of a deal once I figured out how to organize things in Firaxis' system. When using the built in screen/panel system, mouse input is managed by the interface manager, UIFxsMovie. To communicate between your flash movie and your UI_FxsScreen or UI_FxsPanel sub-class, you just need the following:

    [snip]

    Very interesting summary, much appreciated. I'm sure this'll come in handy.

     

    I knew a bit about how FlashRaiseMouseEvent() and OnMouseEvent() process stuff, but setting up everything is quite a different matter altogether :smile:

     

    As a general reminder, a good UI is also navigable using non-mouse inputs (i.e. keyboard, gamepad). From what I can see these types of input typically aren't funneled through the Flash movie like it's done for mouse events. Rather they're handled directly on the UnrealScript side in the corresponding UI class using OnMouseEvent()'s sister function OnUnrealCommand(), which usually contains a big old switch statement for determining the input command and then doing some further processing.

    This typically includes one or more ActionScript interface calls (either via the Invoke() method or via a special AS linker function [further reading]) to pass information to the Flash movie. A typical use case would be changing the currently focused interactive component in your menu (e.g. buttons, list items) using functions like SelectNext(), SelectPrevious(), SetSelectedIndex(), etc. in response to directional inputs (e.g. cursor keys, D-pad).

  4. I doubt *new* players would be interested by such campaign summary elements (and how they are designed)... as they'd most probably be immersed in the LW- Gameplay and having too much fun already to even try deciphering whatever we could come up with.

    As you yourself said: "I doubt *new* players would be interested by such campaign summary elements (and how they are designed)". If so, why are you prioritizing appearance over functionality? People will be visiting this screen for statistics, not pretty glowing bars and arbitrary percentages conveyed in a form that you can't get the actual data out of.

    I'll have to agree with Krazyguy here, saying new players wouldn't be interested in a campaign summary is bad attitude. If presented in an intuitively understandable fashion such a summary should appeal to all players alike, be it the seasoned veteran trying to min-max their strategy, the newbie trying to figure out what is happening to them or the casual player resuming an old game who wants to recall 'the story so far'.

     

    Therefore it is important to stick to a design that puts readability and ease-of-use at the forefront. It might seem tempting to cram as much information as possible into the limited space available, but you're doing so at the expense of at-a-glance understandability and will likely alienate the common player that way. After all there's a reason why the game's design is often more heavy on text than it is on icons.

     

    As for the discussion about colors, I typically don't mind color-coding information, but you need to be careful when doing so. Again, there's a reason the game sticks to its neutral cyan-on-black color scheme throughout most of its menus (mainly readability). As I see it a well-designed UI for the game should work fine using the neutral color scheme and should not depend on color-coding from the start.

     

    Again, color-coding isn't inherently bad, but it should only be used where it makes sense, i.e. when it provides additional and meaningful information. The game establishes precedents for that in several places, like the panic brick colors o the consistent use of purple for all things related psi. As such it would be wise to stick to established color schemes, for instance using the panic brick color series (which players are likely to have internalized already) as indicator of severity - the color defaults even have descriptive names that reflect this:

     

    0 ▱▱▱▱-▱▱▱▱ 19 #5CD16C GOOD

    20 ▰▱▱▱-▰▱▱▱ 39 #67E8ED NORMAL

    40 ▰▰▱▱-▰▰▰▱▱ 59 #FFD138 WARNING

    60 ▰▰▰▱-▰▰▰▰▱ 79 #F67420 WARNING2

    80 ▰▰▰▰▱-▰▰▰▰▰ 100 #EE1C25 BAD

     

    So basically you need to ask yourself about your design 'What does color-coding bring to the table in this particular case? What would the menu look like without?'. The panic bricks are an example of good color-coding; upon opening the situation room menu you immediately see at a glance which countries are endangered due to eye-popping warning colors. If everything would be rainbow-colored all around there would be a lot of visual noise in which meaningful information would be drowned out.

     

    Also two more important things about UI design for the game that haven't been touched upon much are input schemes and localization support.

     

    When designing a new menu it's always tempting to, for instance, put buttons everywhere that perform various functions, but you need to keep in mind that the menu should be navigable via non-mouse controls, too, i.e. via keyboard or gamepad inputs. For this reason interactive components are usually grouped in close proximity to each other in the game's menus. This way directional inputs or primary and secondary buttons are contextualized as 'next', 'previous', 'accept', 'cancel' and so on. So it's always good practice to take a step back after laying out interactive components and asking yourself 'How would I activate this particular component without a mouse?'.

     

    As for localization, this has a similar impact on how components should be laid out. Basically we're limited to using what's provided in the localization files, which means strings like 'S-Africa' or 'UK' are out of the question as those aren't even defined in the basic English localization. Furthermore you need to keep in mind that different languages often feature different string lengths for the same terms. So if 'United States' turns into 'États-Unis' your layout may not be compromised, but when 'Germany' turns into 'Deutschland' you're suddenly presented with a string that's about a third wider (depending on the font used). For this reason using a two-column layout may not be a good idea as you cannot guarantee that to look balanced for all language versions.

     

    Okay, I think that's enough 'Design 101' for now, I didn't intend to rant this much again :sweat:

  5. The idea with DynamicLoadObject looks good. This way is it possible to do without mutators at least when we need to spawn modded child class instead of original parent class.

    That sounds pretty nifty. One noob question about getting the game to recognize custom classes though, what's the preferred method? Can I simply drop cooked script files (*.u) in the game folder or do they need to be neatly packaged in a *.upk? In the latter case the *.upk needs to be registered in an *.ini, could that also work for loose script files?

  6. Hm, that's quite the setup you got there. I'm not sure the example you chose is a good one to demonstrate mutators with though. Since all XComStrategyAIMutator seems to be doing is spawning a strategy AI instance of a different type you could have simply done that right inside XGStrategy.NewGame(), e.g.

        if(m_kAI == none)
        {
            m_kAI = Spawn(class'XGStrategyAI_Mod');
        }
    

    Also your XComMutator setup using a string parameter feels a bit forced, but I suppose you need a way to determine what mutator(s) to actually use when calling Mutate(). From my understanding mutators are daisy-chained, so calling Mutate() on the base mutator will in turn call Mutate() on its designated 'next' mutator and so on, thereby propagating mutation along all mutators.

     

    So as Mutate() is essentially called on all mutators and since you only want specific mutators to apply in any given situation, you need to pass some extra information on to mutators that specify whether or not they should actually 'fire'.

     

    I guess I'm with you on that front, but as a programmer I kinda disagree on how you structured XComMutator using a bunch of string checks passing implementation to a method stub that is supposed to be overridden with an actual implementation in a subclass. What you created is essentially an abstract type, but you're defining too many quasi-abstract methods for my taste. As I see it this makes the class very rigid as you'll have to add more cases as you need them, providing ever more cover methods.

     

    There's several ways to go about that. I'd suggest to embrace the abstract type concept and have sub-classes deal with only one or two generic methods to implement at a time. Unfortunately it seems UnrealScript only allows classes to be abstract and not methods, though at least this allows you to provide default implementations for your quasi-abstract methods.

     

    Suppose your XComMutator base class would look like this:

     

    class XComMutator extends Mutator
    	abstract;
    
    function Mutate(string MutateString, PlayerController Sender)
    {
    	if (this.ShouldFire(MutateString))
    	{
    		this.MutateImpl(Sender);
    	}
    	Log("XComMutator: Current = " $ string(Name));
    	if (NextMutator != none)
    	{
    		Log("XComMutator: Next = " $ string(NextMutator.Name));
    	}
    	else
    	{
    		Log("XComMutator: Next = None");
    	}
    	// never forget to call for super.Mutate from inside subclass of XComMutator class
    	// if you do, you'll stop Mutate propagation along the chain of mutators
    	super.Mutate(MutateString, Sender);
    }
    
    // subclasses need to override this
    
    function bool ShouldFire(string MutateString)
    {
    	return true;
    }
    
    function MutateImpl(PlayerConroller Sender)
    {
    	// implementation goes here
    }
    

     

    Then you could provide XComMutator subclasses that only need to implement all of two methods and be done with it. Each mutator would deal with input checking on its own.

     

    This way it would also be possible to decouple input checking and implementation by putting those in different classes. So, for instance, if I would like to execute all mutators of a certain family of mutator types I could provide yet another abstract intermediate class that implements ShouldFire() using a type check and leave the implementation to the corresponding type instances, like so:

     

    class XComTypeMutator extends XComMutator
    	abstract;
    	
    function bool ShouldFire(string MutateString)
    {
    	// we expect MutateString to be a type name
    	return this.IsA(MutateString);
    }
    

    and

    class XComAIMutator extends XComTypeMutator;
    
    function MutateImpl(PlayerConroller Sender)
    {
    	// do AI stuff here
    }
    

    fire by calling Mutate("XComAIMutator", Sender)

     

     

     

    The type-checking implementation given as an example here could also be used as the default implementation inside the base XComMutator class if you find it workable enough. But as I see you're also doing some other string processing on the inputs to extract additional parameters in XComMutator this might not be desired :smile: In this case I'd furthermore suggest to standardize input processing and relocate it to a separate method. A further modified XComMutator base class could then have the following alterations, for example:

     

    function Mutate(string MutateString, PlayerController Sender)
    {
    	if (this.ShouldFire(MutateString))
    	{
    		this.MutateImpl(Sender, this.ExtractParameters(MutateString));
    	}
    	...
    }
    
    ...
    
    function array<Object> ExtractParameters(string MutateString)
    {
    	// default implementation does nothing, override as needed
    	return null;
    }
    
    function MutateImpl(PlayerConroller Sender, optional array<Object> params)
    {
    	// implementation goes here
    }
    

     

     

     

    Again, this would allow parameter extraction to be separated from the other parts and could be handled in a unified fashion for specific type families, for example, or you could provide a default implementation that breaks apart the input string along a specific delimiter, for instance.

     

    Okay, I think that's enough rambling for now, hope you don't mind the criticism :smile:

  7. CheckReplacement is not usable for XCOM because of all the back references. What I finally came to is inserting Mutate call before an object spawn code, pass a bunch of params to it as text (as it only accepts text) and then spawn the new object with mutator depending on these params. After that I add another check in the original code, which confirms if an object is spawned (its reference is not equal to 'none') and if not, executes vanilla code to spawn vanilla class.

    Can't say I can follow that. I, too, was curious about mutators a while ago and looked through what documentation you provided about the topic, but still couldn't figure out where to start. Your initial remarks back then about CheckReplacement looked promising initially, but then seemed to go nowhere and weren't mentioned later on, so that left me scratching my head.

     

    Looking at your example sources on GitHub didn't help much either. The scripts looked straightforward enough, but there was no indication how and where the MutateXYZ() methods need to be called. Documentation about the procedure is rather spotty currently, a more centralized how-to guide would be appreciated :)

  8. That's a native function, i.e. a function that is implemented in C++ instead of UnrealScript. You could probably remove the native modifier and turn it into a plain UnrealScript function, but you'd likely break it by severing its link to its C++ implementation that way. Theoretically you could re-implement the functionality in UnrealScript, but without knowing the C++ source this is rather futile.

  9. I don't use PatchUPK and wouldn't know about its pseudocode syntax. What I would do in case there is no precedence to using a specific variable is to grab a similar line of script code that is accessing a different instance variable and altering the value of the InstanceVariableToken (0x01) inside it to point to the desired variable instead. The InstanceVariableToken value seems to be a (typically negative) 4-byte integer, so most likely an index of sorts. I can't really make out how to determine the correct index for a specific instance variable (I suspected it to be related to the position in the Export table, but I don't see a correlation), but you could always just brute force it via trial and error, i.e. playing around with the value until you close in on the desired variable. Not really an elegant solution, I admit.

     

    Maybe someone else can shed some light on what the InstanceVariableToken value refers to.

  10. Looking through some UnrealScript documentation I'm seeing a few hints that could be useful. Instances of the SkeletalMeshComponent class maintain lists named LocalAtoms that store AnimNode.BoneAtom structs. The LocalAtoms list is described as a

    Temporary array of local-space (ie relative to parent bone) rotation/translation for each bone.

    and sure enough the BoneAtom struct contains members for rotation, translation and scale, i.e.

    struct BoneAtom
    {
        var quat Rotation;
        var float Scale;
        var vector Translation;
    }; 
    

    I'm thinking it might be possible to look up the index of the desired bone by its name, grab the corresponding BoneAtom and modify its Scale property. Maybe something along the lines of this:

        local array<name> names;
        local int index;
        local BoneAtom atom;
    	
        meshComp.GetBoneNames(names);
        index = names.Find("RigHead");
        atom = meshComp.LocalAtoms[index];
        atom.Scale = 2.0f;
    

    Could very well be that the BoneAtom structs are read-only and changing their member values has no effect, but it might be worth a shot.

  11. 1. Timeline recap view. Main features would be a big map view, a movieplayer like transit tool (play/pause, faster, slower, slider). Events would be listed as they happen, either beside or below the map, and blips placed on the map to match. I always refer to the civ map recap, that's the model I have in mind for this. Click on an event/blip for more detailed info. This view gives you a time lapse overview of your campaign.

    I can see where this is going, from the graphs point of view this is like presenting a vertical slice through all graphs. The side panels next to the map could then display the various values corresponding to the current point on the timeline, like current number of scientists/engineers, current research project, number of items manufactured and whatnot.

     

    2. Monthly summary view. Major elements are the map w/ mission blips and several month summary boxes as in xyzpsilon's mockups. Again click on missions for detailed info. This gives you a snapshot of the state of your campaign at a particular point. Can be shown in world or single country view.

    This feels pretty much like option 1 to me, like you'd just skip to somewhere in the month-of-interest on the timeline and see the corresponding values displayed in the side panels. Maybe all that's needed is some form of toggle or setting that determines how far back the value aggregation is reaching, e.g. showing campaign totals so far or showing only differences accrued since the last council end-of-month report.

     

    I think the side panels are ill-suited to display data spanning multiple time points - the monthly breakdown mockups presented so far are really crowded and hard to parse, in my opinion.

  12. Stubbing is pure grunt work, but its easy enough to do. Even if we don't get the .as sources we can continue with this method in xcom2. The biggest gripe I have over it is that it's currently unclear if we can share the stubs - right now everyone needs to reimplement their own.

    I suppose that depends, stubs can be rather detailed depending on your needs, e.g. Flash won't compile if you have a script accessing a variable in another class which hasn't been formally declared in it. So in the worst case a stub would have all variables and methods laid out, just without any actual logic, i.e. no variable assignments and empty methods. This may already be considered borderline intellectual property theft, but given Firaxis' rather lenient stance on sharing sources w.r.t. UnrealScript logic in XCOM2 I'd assume they'd turn a blind eye towards people extracting and sharing ActionScript sources.

     

    If push comes to shove there'd still be the option of creating a tool that creates stubs from your local game files, so no sharing of copyrighted assets required. Might as well automatically rip and decompile all the needed ActionScript byte code sources at that point though, no need for stubs if you can have (an approximation of) the real deal :smile:

     

    The downside to using decompiled sources is that they can be hard to read in many cases. This is mainly because the notion of local variables with distinct names typically gets lost in translation during the publishing procedure in Adobe Flash, i.e. variable names aren't part of the byte code and local variables are only referenced by pointing to a numbered memory register. Also I think for loops are transformed into while loops during the byte code compilation process, there's a number of things going on at the very least.

    So a bit of cleanup to reintroduce sensible variable names can help immensely to improve code readability, but that can't be automated easily.

  13. While I believe that Firaxis recognizes the general want for "more models, more textures, more scripts", I would think that XCOM2 mod support wouldn't extend far into Scaleform UI territory. Sadly, user interface stuff remains a mostly overlooked aspect of games and while Scaleform is a pretty powerful solution it's also a bit more technical, so providing support for models, textures, etc. seems like the 'easier' option.

     

    Take Skyrim as an example - a game that also uses Scaleform UI integration - of the myriads of mods available for that game only a handful concern the UI. Skyrim's modding kit is better suited to modifying game logic and putting new models into the game after all; digging around the UI requires similarly hacky approaches as we have to resort to for XCOM1 :)

     

    That said, I wouldn't count on Firaxis releasing .fla sources; that would be akin to them releasing .psd files for all their textures or .fbx files for all their models :) Nevertheless I think we can manage without; same as we can right now with XCOM1 as Flash decompilers do an admirable job of deconstructing the game's files - just not in an easily-accessible and editable fashion. So for the forseeable future I expect UI modding to remain an expert topic of sorts :)

  14. I've only skimmed over the previous 8 pages of this thread, so pardon me if this has been brought up before.

     

    First off, showing a detailed campaign breakdown, great idea - the fact that you successfully injected a new Flash movie into a scene is a great achievement in itself :thumbsup:

     

    From the looks of it the plan is to hijack the main situation room UI to display the breakdown, cramming lots of details into the country slots. Personally, I don't think that is a good plan of attack. You have very little screen real estate available in those slots and therefore you'd have to rely on pictograms, numbers, etc. to encode information which is a concern from a readability/usability point of view.

     

    If at all possible I'd suggest to create a separate view screen altogether, not unlike the XCOM Finances or Pending Requests screens accessible from the situation room menu. This way you could display one or more frames covering as much screen space as you need.

     

    As for the actual contents of that screen, why not try to go full retro and create chart views like in ye olde X-Com or X-Com: Apocalypse? A graph conveys the kind of timeline information you're aiming for much better than boxes of text and icons, in my opinion. I'd imagine such a screen could contain a tabbed view containing area or line charts displaying different aspects of the campaign, like XCOM/alien activity (i.e. missions presented vs. missions taken, UFOs sighted vs. UFOs shot down) or XCOM finances plotting different types of income (item sales, council funding, mission cash prizes, etc.) and spending (facility upkeep, manufacturing costs, interceptor/soldier purchases, etc.) over time. Depending on the time-resolution of the data I could image a chart view could allow zooming in from a yearly breakdown to a monthly breakdown allowing you to track individual events down to the day (or hour/minute/second even ;)).

     

    This may well be beyond the scope of this project or even nearly impossible, but one can dream, eh? :)

  15. I was curious about why the script files were included in every single package, when it seemed like they weren't actually being used. Is that fundamentally a name resolution thing because of how the movies are injected as sub-movies of the master movie? I.e. Environment.instance() in the sub-package actually refers to the Environment class in the root and you'd need to fully qualify the name (this.Environment?) to get the one in the package, or am I way off base on that?

    I think the main reason that those class duplicates exist is because Adobe Flash likes to publish fully self-sufficient Flash movies. As such a SWF/GFx file itself is not actually "aware" that its AS classes are supposed to be pulled from elsewhere - I believe this is the job of the in-engine Scaleform implementation. Similar to how several Flash movies are composited in the scene I expect the same to happen to their corresponding AS classes, i.e. discarding/ignoring duplicates in favor of those higher up in the hierarchy (rooted at interfaceMgr.gfx, I assume).

     

    It would be nice if local class duplicates could be used as some form of overrides for menu-specific implementations, but alas, that doesn't seem to be the case. Nevertheless it's pretty straightforward to provide your own subclasses extending core classes and linking them to your sprites of interest. All you need are stubs of the relevant AS classes so Flash will compile everything properly. If you want you can rip the actual classes using a Flash decompiler like JPEXS, but stubs will do as the embedded local class variants after export don't end up being used anyway :)

  16. Haha, that looks fun, good job so far :)

     

    And you're right, the head meshes share the same origin as the body meshes, i.e. they're anchored to (0,0,0) which is at the base of the body between the feet. Typically you don't want to scale the head mesh directly, but the bone its attached to in the soldier pawn's skeletal hierarchy - I don't know if this is feasible though. There is such a thing as Skeletal Controllers in UE3, so maybe you could look into those to find a way to adjust bone scale on the fly.

  17. And here I was thinking XCOM modding was dying down after LW went final :smile:

     

    Very glad to see more people picking up GFx modding; I find the parts about injecting new FxsMovie implementations very fascinating, I assume a similar procedure will be possible in XCOM 2, so I'm interested to learn more about that :smile:

     

    Your observations align with mine for the most part, I was going to point out the 'Runtime Shared Library' feature, but you happened to do so yourself today. One addition regarding that feature is worth mentioning though, certain resources are shared among GFx objects without explicitly being imported, namely ActionScript classes. While most GFx files contain duplicates of certain common classes (e.g. generic stuff like Environment or Colors as well as specific UI component implementations like XComList and XComButton), they are actually a side-product of the export process from Adobe Flash and are essentially dead weight as they aren't actually used in-game. Most of the common class templates are looked up from a central repository which is located inside the interfaceMgr GFx file inside XComGame.upk.

     

    To name a use case, to rework the way scrolling in list components works for LW I had to edit only the XComList and XComScrollbar classes inside the interfaceMgr file and this automagically applied to all menus where instances of those classes were used (there were some exceptions like the load/save dialog which implement scrolling differently).

     

    On the authoring front, I've successfully prototyped and exported assorted sprites and associated ActionScript classes using Flash CS6 and brought them into the game by injecting them into an existing GFx file via hex edits. I've also read lots of the SWF FIle Format Specification on which GFx files are fundamentally built, so I have a pretty good understanding of the inner workings of SWF/GFx files - which helped immensely when trying to figure out the whole hex injection business :smile:

    That said, I can definitely lend a hand with the authoring part of any UI projects you might have planned, if you want.

  18. Btw, there were exactly *FOUR* different instances of that OBJECT in the file... and i was able to manually add the correct custom elements on the fourth "group" -- and, it works. Yet, PatcherGUI refuses to detect the right OFFSETS for that specific area.

    My formatting must be invalid, indeed.

    You're still talking about Spazmo's Soldier List XP mod, right? That one's PatchUPK-based and contains multiple changes that include resize operations. As a result the target object in question gets cloned multiple times (each time for every resize) and appended to the UPK, explaining the additional instances.

     

    I'm not a big fan of this 'clone-and-append' procedure as this makes my work (and apparently yours, too, Zyx) harder, but that's just how PatchUPK rolls :smile:

     

    In any case, you should use the OBJECT=gfxSoldierList.SoldierList:AUTO line in your mod file instead of relative offsets to find the proper object, i.e. the most recent one that got added.

  19. Yeah, car paint colors are usually more subdued, e.g. check here or here for references, you won't see pure colors like [0, 255, 0] in there. I think darker, less saturated shades work best in-game as glowy, rainbow-y colors are rather distracting and unrealistic, in my opinion.

  20. Those scale values don't look right to me. Why do you change those anyway? Better leave them alone for now until you can figure out the scrolltext importing part.

     

    My guess is that having two objects defined using the same character ID (i.e. one using ImportAssets and the other using DefineEditText) is clashing. This happened to me when messing around with sprites and JPEXS does show error messages for that in its log window. So you might want to zero out the DefineEditText tag (so there is only one object with ID 31) or simply use a completely new ID and adjust the status field's PlaceObject tag to target the new ID instead.

     

    I can take a look at the Flash file if you upload it somewhere, maybe it's something entirely different you're missing.

  21. I don't quite understand how the positioning in the "matrix" works either. There are ScaleX/Y, TranslateX/Y values and nTranslateBits/nScaleBits etc

     

    How does that relate to the screen location?

    The translation values are relative to the parent into which an object is placed using a PlaceObject tag. Internally Flash uses twips as unit of measurement, i.e. 'twentieth of a pixel', so by dividing the values by 20 you get the actual pixel dimensions. JPEXS displays the values for the translate fields of PlaceObject tags in twips, ActionScript code however uses pixel measurements directly, although still subject to the 0.05 px grid limitation (i.e. all pixel positions are rounded to the nearest multiple of 0.05 internally).

     

    The scaling values used internally are decimal numbers stored in a compacted 16.16 signed fixed-point format, i.e. the nScaleBits value determines how many of the 32 available bits are used, which is usually 18 or larger (16 bits for decimal places, 1+ bits for the integer portion, 1 bit for the sign). Basically this encodes scaling factors that are typically around 1.0, though JPEXS (misleadingly) interprets and displays these values as integers. You can transform them to their intended values by dividing the displayed integers by 65536, so a scaling to ~220% would look like 144179 in JPEXS. ActionScript however handles scales differently, again. There it's defined as a percentage value, i.e. normal scaling is 100, double is 200, etc. Pretty straightforward, really, yet different from how sprites work, mind you.

     

    All of the information can be found in the SWF File Format Specification and the ActionScript 2.0 Language Reference. Before JPEXS integrated raw editing capabilities for tags (or before I became aware of that functionality) I did a lot of editing by hand, decoding and re-encoding those bit-packed values to move things around. Quite tedious, I can tell you :smile:

     

    I've been trying to convert the StatusText field to a XComScrollingTextField. There are no other XComScrollingTextFields imported into the SWF so I tried adding one via "others"->ImportAssets2 and giving it a new ID.

    Is there a special way to initialise these auto scrolling text fields? I think it might be there but maybe lacking formatting info or something, or it's off screen, or I'm not setting the value correctly.

    Using an ImportAssets tag to get an XComScrollingTextField sprite into the soldier list is good thinking, I assume you lifted the required url and tagName strings from a different Flash file and replaced the target character ID of the status text field's PlaceObject tag to point to the imported character instead.

     

    An XComScrollingTextField is actually a composite sprite that contains an actual text field inside, i.e. it is not a text field itself. As such using the text and htmlText properties to set its contents won't work, but the linked XComScrollingTextField AS class has cover methods for that purpose, setText() and setHTMLText() respectively. This means you'll have to edit the SoldierListItem class to use those methods as they also feature a bit of logic triggering the auto-scrolling behavior.

     

    As for formatting the scrolling text fields, the default format of the built-in text field of a standard XComScrollingTextField sprite should already look pretty similar to what the status text field uses. To be really sure you can transfer the text format from an existing text field to the scrolling text field using TextField.getNewTextFormat() and XComScrollingTextField.setNewTextFormat() which is a cover method for TextField.setNewTextFormat().

×
×
  • Create New...