Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.98a is out! (03/27/25)

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Kaysaar

Pages: [1]
1
Mods / [0.98] Building Menu Overhaul 1.1.6
« on: January 04, 2025, 12:30:06 AM »
Building Menu Overhaul


NOTE ! Requieres Ashlib ver 1.1.4 or higher
This mod features overhaul to building menu introducing few useful things
Searchbar
Spoiler
Dynamically searches through list of industries that meet tag criteria

Showcase
Spoiler
[close]
[close]
Tag filters
Spoiler
You can filter industries using various tags, including mod tags!

Showcase
Spoiler
[close]
[close]
Dropdown buttons for variable industries
Spoiler
Now instead of going to different section with only certain industries present (Example Stations) all is now located in Dropdown menu

Showcase
Spoiler
[close]
[close]
Upgrade path showcase
Spoiler
Shows upgrade path for each industry

Showcase
Spoiler
[close]
[close]
Items usage
Spoiler
Shows which items can be used on this industry, or its upgrades, and if it can be installed on this market!

Showcase
Spoiler
[close]
[close]
Upgrade Queue
Spoiler
Allows for queue not only industries, but their upgrades!

Showcase
Spoiler
[close]
[close]
Current plans
- Add upgrade path showcase to each industry (DONE!)
 - Add sort of income estimator/ production estimator for various sizes of colony (Wip, will be done later)
 - Add ability to instatly build upgrade of industry, instead of building industry a then upgrading to b then to c etc etc.(DONE!)
 - Add info about what items can be installed and if you have them (DONE!)

Changelog
Spoiler
1.1.6
-Fixed issue with Codex closing not only codex itself but also building UI
-Fixed issue with displaying industries that have tag to not be shown in building menu

1.1.5
-Update to .98

1.1.4
 -Fixed issues with displaying cost not properly
 -Added animations to pop up (Ashlib)

1.1.3
 -Fixed issues with Arthur mod

1.1.2
 -Fixed random crash with currentOne beign null

1.1.1
 -Fixed random crash

1.1.0
 -Added queue for upgrades
 -Fixed crash with getIndustryTree method
 -Fixed issue where stations still were capable of being built when in queue

1.0.4
 -Adjusted title of industry showcase to be centered
 -Added dynamic color change based on where menu have been opened (faction market)
 -Adjusted tooltip methods for future AoTD - Vok versions

1.0.3
 -Increased performance even more

1.0.2
 -Fixed bug with industries appearing in menu that are already in construction queue
 -Fixed issue with not having any support for vanilla extended tooltips ( now it is possible press f1 will extend tooltips)
 -Slightly improved performance of UI generation

1.0.1
 -Integrated which industry into mod

1.0.0
 -Add item showcase ability together if it can be used on specific market

0.2.0
 -Fix that some tags are not read ( cause they are changed when sector is being loaded )
 -Added upgrade path showcase
 -Added new tag - Has upgrade
 -Fixed issue of industries displaying sometimes wrong image

0.1.1
 -fix small memory leak issue
 -added arrow to dropdown menu
 -fixed issues with tag buttons
[close]

Current ver : 1.1.6( Safe to add mid save)

Support

In case you are interested in supporting me financially you can do it via Patreon !
Any donations allow me to commision more and more people, so i can increase quality of my own mods !


2
Modding / [0.98] AshLib 1.2.0
« on: October 13, 2024, 03:49:00 PM »
Ashlib
NOTE ! IF you have Ashlib folder without "_" delete it and place this one posted in download link!
So basically this is library sort of mod(I would say more like utilitary mod even) that I have decied to post, since few people asked for it and because a lot of functions i have created is used by more than 1 mod , so for my own life to be easier decided to release this as lib mod, hey maybe someone else will also use those features
Horizontal Scrollbar
Spoiler
To use it look at HorizontalTooltipPlugin
NOTE!
1.First create instance then call method init
2.True width and true height are sizes of tooltips themself whether width and height are sizes of scrolable area
3.Set width and heigt AT MAX to twice the size of max width and max height, if its more then tooltip will  have some weird behaviours
4.True width and true height can be basically like 10k but place tooltip and panel as such, that their border is equal to border of game itself
Spoiler
[close]
Spoiler
[close]
[close]
Access  to nearly 1:1 replica of weapon/fighter/ship tooltips
Spoiler
Methods for those are accessable from AshInfoTooltipGenerator
Spoiler
Code
   //Note ! Spec can be either Hullspec, WeaponSpec, or FighterWingSpec!
    public static void generateTooltip(TooltipMakerAPI tooltip,Object spec){
        float width = 400f;
        if(spec instanceof ShipHullSpecAPI){
            width= 990f;
            final CustomPanelAPI panelAPIs = ShipInfoGenerator.getShipImage((ShipHullSpecAPI) spec, 250, null).one;
            ShipInfoGenerator.generate(tooltip, AshMisc.getFleetMemberFromSpec((ShipHullSpecAPI) spec),null,panelAPIs,width);
            return;

        }
        if(spec instanceof WeaponSpecAPI){
            WeaponInfoGenerator.generate(tooltip, (WeaponSpecAPI) spec,width);
            return;

        }
        if(spec instanceof FighterWingSpecAPI){
            FighterInfoGenerator.generate(tooltip, (FighterWingSpecAPI) spec,width);
            return;

        }

    }
[close]
Ship
Spoiler
[close]
Weapon
Spoiler
[close]
Fighter
Spoiler
[close]
[close]
Allowing to correctly render modular ships, fighters and weapons (even with missles!)
Spoiler
Methods for those are accessable from Ship/Weapon/FighterInfoGenerator
Spoiler
[close]
Spoiler
[close]
Spoiler
[close]
Spoiler
[close]

[close]
Custom AI core skill poll
Spoiler
So with this lib you will be able to fully customize what skills should appear in skill selection menu , you can insert there up to 16 different skills.
To implement this , copy file  ai_core_skill_poll.csv from data/campaign to same directory but in your mod.
Field id is id of core,  where skillPoll is list of id's of all skills that should appear
Spoiler

[close]
Spoiler

[close]
[close]
Pop up UI and replica of vanilla Dialog
Spoiler
More about that later, but basically PopUpUI and BasePopUpDialog are classes you are looking for
[close]
Current ver : 1.2.0( Safe to add mid save)
Special thanks
Lukas04 for some of scripts that are used there
CY/Milkydrommeda as it was his idea in first place for Custom AI Core skill poll


3
Mods / [0.98] Animated Colony Items (Vanilla edition) (1.0.1)
« on: August 07, 2024, 12:32:46 PM »
I deciede to make this mod to make colony items even more special in your inventory !

Note ! if you crash re-download , i posted firstly version with unfinished mantle bore animation (whoops)

Showcase
Spoiler
[close]

Items covered
Spoiler
Corrupted Nanoforge:Done
Pristine Nanoforge:Done
Synchrotron Core:Done
Orbital Fusion Lamp :Done
Hypershunt Tap :Done
Autonomous Mantle Bore:WIP
Catalytic Core:Done
Soil Nanites:WIP
Biofactory Embryo:WIP
Fullerene Spool: How you wanna animate cable hmm?
Plasma Dynamo:Done
Cryoarithmetic Engine:Done
Combat Drone Replicator:Done
Dealmaker Holosuite:Done

[close]
Patchnotes
Spoiler
1.0.1
Spoiler
Fixed stuff related to JaydeePiracy and items not working with planet search
[close]
[close]

Thanks to :
Minideth, NeoLemon and Kumomo : Main contribiutors in terms of lightmaps



Support

In case you are interested in supporting me financially you can do it via Patreon !
Any donations allow me to commision more and more people, so i can increase quality of my own mods !


4
What I mean by that ?
We have that already with sector width and sector height
If I correctly guess height and width of star system are hard-codded.
Can we have option in next patch to have ability to change that ?
For example current dimensions for star system are 52000 x 52000
I think ( I dont know exactly) such change would not be hard to implement.
I am mainly asking as i have currently been experimenting with hyperspace as star system and found out that you can only zoom into positions within -26000 x 26000 coords

For now i have worked around with grid itself by rendering terrain that functions as grid

5

Requires LunaLib, MagicLib, LazyLib
SAFE TO ADD IN EXISTING SAVES.


Before you will download important note!
Spoiler
Hi, a lof of you know me as main developer of Ashes of the Domain. Due to recent events prev author of exotica - Matt, was banned from this community. I asked him for permission to basically take exotica under my umbrella.I always liked this mod and did not wanted this to basically fall int obscurity, due to previous author's actions.

For now I can only promise life support, at least for first few months. Isssue here is that I also have a gigantic mod to maintain (AoTD), and currently I am involved with development of UAF.
Once my workload wont be that much I start work on this mod. So far I already have few plans , two potential collabs and UI overhaul of Exotica interface.

I have checked and this version does not have any crash-code. But if you will spot, that I missed something, please report to me that immediately. Then i ll basically do fix asap.
[close]

Inspired by Extra Systems Reloaded, Exotica Technologies offers an RPG element to Starsector that makes your ships AND enemies harder, better, faster, stronger through upgrades and exotics! These upgrades do not take OP or hullmod slots! Each ship has a limit to the number of upgrades they can install so choose wisely! The cost of each upgrade will require common materials salvaged across the sector such as metal and transplutonics. However, as upgrades get more complex and specialized, they tend to consume more resources and even demand special items found through research stations and mining stations!

How does it work?!
Encounter any fleet that might randomly have Exotica Technologies and fight them as they drop for it.



OR find them at derelict ships and wrecks!
Then, start equipping them and upgrading them at any friendly market!


Still unfamiliar? Hover over every icon and button you see. I encourage you to do so!
[close]
Mod Integration!
We welcome mod integration and are willing to help with integrating mods with Exotica Technologies to ensure a great end-user experience!
ModNotes
Industrial EvolutionSupports Ship and Rare components to be used in purchases and installations of upgrades for your ships!
Iron ShellUnlocks Iron Shell - Armor is more effective versus high explosive damage, but doesn't fare as well against other kind of damage types
(TBD)
Tahlan ShipworksTBD
[close]

Obviously! some fights might be much, much harder with this mod installed because the AI are equipped with technologies as well!
Be prepared, and take advantage of everything that Exotica Technologies has to offer you to overcome these increased threats.
This mod is NOT compatible with ESR and no further development will be continued for ESR (who I formerly modded).

Thanks to many people for this:
  • Matt for creating this mod
  • LazyWizard for LazyLib
  • Tartiflette, Wisp and the modding community for MagicLib.
  • Lukas04 for LunaLib
  • Haplogynae for the shop music
  • Wisp for making the Gradle mod template that this mod uses.
  • Histidine for making Nexerelin, which this mod has (some) integration for, and also for an update to the scanning UI.
  • Techpriest/Tim for making Iron Shell, which this mod has (some) integration for, and also for making this forum thread.
  • Zym from the Unofficial Starsector Chat discord for being a great help with ideas and balance for the mod.
  • Ms. Vella from the Unofficial Starsector Chat discord for making the plasma flux catalyst cargo item icon
  • Thyrork, Phearlock, Ishman, Strb 103D for being a beta tester for the mod's update, which had undergone extensive changes and crashes.
  • Thyrork again for making a post-release guide for the mod, which you can read below.
  • Originem and Iridicens for making the original mod and its 0.9.1 update.
  • The community at large for using this new version of the mod. I greatly appreciate any and all feedback, even if you want to say you like the mod, or don't.

Changelog


v1.8.6
Updated to .97 version
Ensured previously detected crash-code was deleted

v1.8.5

    fixed GUERRILLA type not calculating positive and negative mult correctly
    made Exotic Type tooltips easier to find
    fixed IndEvo upgrade methods not saving properly
    Quick Jets and Drive Flux Vent are now more controllable by the AI
    Exotica markets now refresh every month
    exotic generation is reduced a lot. exotic chance is now based on DP rather than hull size.
    exotic recovery is twice as likely now.

v1.8.4

hotfix:

    fixed a crash that occurred due to loading a save applying fleet member stats before the fleets are populated with members.
    -- second hotfix for the same issue because APPARENTLY the same issue applies to the player fleet. which is ridiculous.
    fixed a crash when attempting to install upgrades on module ships with Industrial Evolution enabled.
    -- second hotfix for the same issue.

1.8.3:
hotfix:
- fixed a crash that occurred due to loading a save applying fleet member stats before the fleets are populated with members.
-- second hotfix for the same issue because APPARENTLY the same issue applies to the player fleet. which is ridiculous.

1.8.2:
hotfix:
    fixed a crash that occurred due to loading a save applying fleet member stats before the fleets are populated with members.

1.8.1:
hotfix
    PURE type now uses base bandwidth when calculating the used bandwidth ratio.
    -- this is because Alpha Subcore has a positive multiplier for the extra bandwidth it gives from its Exotic type, creating a circular dependency that would crash your game.
    -- as a result, PURE-type exotics can now get much worse.


1.8.0:
- Scan Fleet option now appears in the main dialog rather than comm link (thanks AtlanticAccent)
- modifications can now be installed on modules directly
-- parent ship modifications will no longer propagate to modules
-- this does mean fitting module ships is much more expensive
- added Quick Jets upgrade, which adds an ability that makes a ship turn much faster
- drive flux vent's active is now 25% longer
- full metal salvo now works again (?)
- overclocked fabricators now spawns more often on carriers.
- spooled feeders now spawns more often on ships with Safety Overrides.
- hacked missile forge recovery chance reduced by 75%
-- it's still stupidly common in pirate fleets
-- also reduced damage further, from 25% TO 40%. use other exotics pls
- reduced cost and bandwidth of Wasp Defense Drones
-- also added more wasps
- PURE-type exotics no longer count themselves after installation
- rewrote UI code to be more performant
- post-battle salvage data expires after 1 day now, rather than uselessly staying in the save until the fleet is despawned/destroyed.

1.7.0:
- misc fixes
- added music by Haplogynae

1.6.6 hotfix:
- fixed exploration crash (upgrades were being generated with level 0)
- fixed fleet UI being broken
- fixed scanner UI not displaying exotics correctly with high UI scaling

1.6.5
- fixed crate disappearing when you open it (sorry)
-- crates now share a global inventory
- added filters to upgrade and exotic UI
- added new upgrade Oversized Magazines
- fixed OCD in ship mod panel
- fixed debris field generation and scanning again
- fixed newer exotics not dropping from salvage loot (like research stations)
- fixed exotic types not appearing in salvage loot
- added upgrades to salvage loot. total value of exotica drops has increased to offset this
- nerfed terminator subsystems
-- range reduced by 33% (this means it is 66% of the original ship system's range)
-- drone recharge time increased from 20 seconds to 30 seconds
-- also tri tachyon will use them less now lol

1.6.4
- multiple UI level improvements
-- fixed refit menu scaling
-- chip lists now use refit variant, fixing multiple bugs with that display
-- upgrade chip list now displays all upgrade chips for an upgrade, but sorts based on whether you can actually apply it.
-- fixed resource displays not displaying quantity stored in the current market's storage
- opening a crate now merges all other creates in your inventory into it
- phase ship check now checks for the phase hint
- added flux use for terminator subsystem use
- fleet mods generation will now generate for all allied and enemy fleets in an encounter. before, it only generated for the main enemy fleet.

1.6.3
    buffed exotic and upgrade drop rates from enemy fleets
    fixed drive flux vent AI activation, and it now has reduced cooldown (15s to 10s)
    updated terminator subsystems AI to use drones more frequently if it has more
    fixed drone stuff applying to modules
    fixed pain from dropping as part of certain ships (it is now removed after battle)
    noticed that pure type exotics were the most used ones:
    -- corrupted type exotics positive mult increased (150% to 200%), and negative mult (150% to 175%)
    -- guerilla type exotics positive mult increased (175% to 200%). note that it still scales with fleet size
    blocked alpha subcore from having any effect if the SHU Armament Support System is installed
    -- additionally prevented alpha subcore from being installed if the SHU Armament Support System is installed
    multiple UI level improvements
    -- upgrades and exotics now display both description and effects at once
    -- overview tab is now the main source to view all upgrades/exotics that your ship has at once
    -- removed hullmod expanding info

1.6.2
- fixed wasp bp dropping
- performance improvements for refit button

1.6.1
- fixed some bugs with certain exotics
- fixed upgrade filters being broken
- added in-refit menu thanks to Lukas04, creator of LunaLib

1.6.0
- improved generation of upgrades by making it prefer already-generated upgrades even more, so upgrade distribution should generate higher-leveled upgrades for a spikier distribution
- fixed antimatter boosters (sindrian diktat exclusive upgrade) not having description
- exotics and upgrades can now have multiple tags
- fixed automated ship checking not checking for automated hullmod
- fixed equalizer core giving 100x the damage bonus for over-ranged weapons
- fixed bandwidth button not updating when buying credit upgrades
- generate enemy ships with much higher bandwidths
- exotic destruction and bandwidth degradation on death for enemy ships so overall loot doesn't change as much and you can't as easily extract nice exotics from salvaged ships
- curate exotic lists per faction more
- upgrades and exotics now weight more towards ships and variants that they would be better on (e.g. armored ships or ships with Heavy Armor hullmod will get the Welded Armor upgrade for even more armor)
- added some drone upgrade and exotic
- added some pain

1.5.3
- updated for 0.96a
- fixed guerilla penance engine sometimes disabling the ship permanently
- fixed hacked missile forge reloading much faster than intended
- fixed phased fighter tether breaking terminator sequence
- fixed exotica market allowing you to go into debt
- fixed hyperspec LPC adding 1% for each fighter bay removed rather than multiplying
- reduced exotic drop rate from fleets

1.5.1
hotfix:
- fixed drive flux vent crash
- fixed equalizer core giving a lot of damage

1.5.0

general:
- attempted improvement to crate code to fix instances of it not pulling chips into itself
- improved chip rendering code and icons
- added a market for chips to the exotica technologies branch for each market

exotics:
- added TWO exotics, one exclusive to the path
- tier 3b drive now stacks
- missile forge now reduces damage but enables you to spam missiles, and reloads weapons individually
- added combat activators for salvo, feeder, and drive flux vent exotics
- hangar forge -> phased fighter tether
- daemon core now correctly applies bandwidth from types, and does not drop as salvage. you must use archdaemon cores to install this now.
- alpha subcore has salvage chance reduced by 75%. you will probably have to use alpha cores to install this now.
- exotics generate more commonly on larger ship sizes
- exotics generate less on civilian ships
- pure type now scales on base bandwidth used and exotics used
- improved type overlay icons to be more visible

upgrades:
- added FOUR upgrades
- buffed assault wings, forced overtime, infernal engines, welded armor, commissioned crews
- nerfed advanced flux coils and derelict weapons assistant by giving them drawbacks that don't really hurt either faction's ships much
- nerfed hel engines by increasing bandwidth slightly (this will probably result in some existing ships going over their bandwidth cap. good for you!)
- rebalanced overcharged shields by shifting more into promoting active shield play by increasing unfold rate further, and both flux/s and flux/dam stats are increased
- fixed a bunch of upgrade drawbacks not starting at level 3
- reduced salvage chance of faction-specific upgrades to 10% (from 450%) (if you change this you have weak bones)
- reduced salvage change of high-level upgrades by up to 75%
- upgrades generate more commonly on larger ship sizes
- added upgrade level to icon

1.3.0
- added a couple of exotics and an upgrade
- refactored a bunch of exotics, also use new MagicLib status bars
- added overview tab to shop
- added some console commands that tim kept bothering me about

1.2.9
removed alpha subcore's non-functioning downside. its primary downside is not having a more interesting exotic
full metal salvo now works for the initial burst of damage and actually speeds up projectiles, although the initial burst can't be sped up due to game limitations.
fixed some stats not applying completely (i.e. 100x less than they should be)

1.2.7
exotic rebalancing for alpha subcore, equalizer core, hangar forge
fixed phasefield engine again
battle carrier wing upgrade
missile guidance upgrade
new exotic

1.2.4
new UI!
upgrades now configuration-based so you can make them as overpowered as you want them to be! who cares about balance???????????? also mods can implement their own too.
iron shell now has an upgrade.

1.1.6
destroyed gradle
fixed crate duping issue
fixed derelict mods not showing up
added ship name to fleet member in generation

1.1.5
added a crate to contain chips
rebalanced a lot of upgrades and some exotics

1.1.4
fixed fleets with 4 or more S-mods causing freeze

1.1.3
fixed being able to upgrade past max level.

1.1.1
fixed upgrades not applying until you upgraded bandwidth.
fixed hangar forge being weird in certain cases.

1.1.0
added two new logistics upgrades.
upgrades and exotics from enemy ships now have a (very large) chance to drop from a ship that has them.
ships with s-mods will now have higher quality and are more likely to generate upgrades and exotics. this scales, so ships with 3 s-mods will have extremely high quality.
refactored upgrade generation. it should more strongly favor smaller amounts of higher leveled upgrades especially on ships that have more S-mods.
fixed some upgrades not spawning on random fleets.
added a blacklist for the missile forge that can prevent it from reloading certain weapons. see modSettings.json
block random generation of ship modifications on ships in the player fleet.
fully integrated new UI from Histidine (thanks)
woops went and made a whole UI over the past week.
probably some other things.

1.0.12
- fixed infernal engines deceleration buff not displaying in tooltip
- fixed indevo component methods not allowing to purchase upgrades if you had the exact amount required

1.0.11
- fixed a rare issue with salvaging a debris field that had a ship with exotica modifications. also fixed all (surely) instances of recovered ships not keeping their upgrades.

1.0.10
- fixed a bug when loading a save while a fleet with special upgrades was out and about

1.0.9
- fixed a bug with special interactable objects
Spoiler
red planet, in particular
[close]
- hacked missile forge now reduces missile capacity by half and reloads the final capacity fully

1.0.8a/b
- fixed a crash on startup/when you generate bandwidth
- fixed a crash when interacting with a derelict fleet

1.0.8
- nerfed drops of exotics by a lot
- removed a debug log that was probably raising the file size of logs by a ton.
- buffed drive flux vent
- added more debug logs that should help explain why some people's upgrades are disappearing.
- potentially fixed an issue where upgrades were disappearing due to putting them into a different submarket e.g. indevo's repair docks
- fixed alpha subcore (and potential future bandwidth-increasing exotics) preventing base bandwidth upgrades
- nerfed overcharged shields slightly, but reduced upkeep for ships with high shield upkeep
- changed equalizer core to modify weapon base range (now it acts like ballistic rangefinder)

1.0.7
added a derelict upgrade
fixed upgrade colors being off
fixed relic component upgrade method using ship component pricing
fixed bandwidth calculation being too high
use upgrade spawnchance stat

1.0.6
fixed saves failing to load due to the game not loading the sector seed until after the game actually loads all game object data (alex why)

1.0.5
fixed saves failing to load due to vanilla code that switches a very special ship's ID around a lot (the ship's ID is generated on sector load, changed when you recover it, and returned when you restart the game.)
1.0.4
updated Plasma Flux Catalyst icon with new one provided by Ms. Vella on the Unofficial Starsector Chat discord
fixed a crash related to one of the final fights in the sector
fixed an incorrect Deceleration tooltip in Infernal Engines upgrade

1.0.3
most upgrade drawbacks now start at level 3 instead of level 1
[close]

6
Modding Resources / Custom UI Guide : Necessary Basics
« on: November 28, 2023, 09:38:13 AM »
When i was starting my journey with starsector modding i saw, that there were no guides about making UI. Same goes with knowledge, which was scattered. This is my attempt of trying to collect knowledge i gained so when someone starts their journey with UI



The knowledge here is based only on my experience, if you think I told sth wrong, or there is a better way, than what I presented, feel free to contribute. This is meant for all.
This one's for UI that uses CustomVisualDialogDelegate, forum link here
This guide is to show the basic of how to do your full custom UI from scratch telling process one by one

Designing:
Spoiler
Before you begin coding UI you first need to design it. As obvious as it might sound this is most important step, you plan your UI to be scalable with resolution, to avoid issues
Basically you test on two resolutions which i find most notorious

1280x960
1366x768

[close]
Basics:
Spoiler
First what we need is to describe hierarchy of UI:



Main panel(CustomPanelAPI class) - > we can call it as foundations, all is bound to the main panel, we will use it to build our UI layer by layer. Of course you can directly create Tooltip (this will be discussed later what is tooltip) but in a much more complex UI this will only create a mess, that will be very hard to clean up later and for you as codder even harder to make adjustments in future.

To create such custom panel of our precious checkbox we use sth like this :

CustomPanelAPi customPanel = mainPanel.createCustomPanel(float width, float height, CustomPanelPlugin plugin);

CustomPanels are mainly used I say as “containers” of true UI.
TooltipMakerAPI is basically a class that is all about creating buttons, text and all that fancy stuff we always want in the UI.

TooltipMakerAPI customTooltip = customPanel.createUIElement(float width, float height, boolean withScroller)

Tooltips and custom panels are a little tricky as you can insert panels into tooltips and tooltips into panels.

Let’s start by going for the small component. First you insert panels into the tooltip (let’s call it tooltipA), so that you can have a more complex UI component which can use the scrollbar fairly easily. Then you can insert that tooltipA into the “container” panels so that not only can you place the container wherever you want, you can move it relatively easily.

Side note: If you were to place panel A directly inside panel B, the scroll bar no longer effects on panel A
   
In summary, tooltip is for creating whole UI stuff like buttons while panel is more of container where tooltip is placed , tooltip must be placed in container to work , but it can also hold other panels as UI components.

Important:
Panels you can only create from CustomPanelAPI, not the tooltip. So panel 2 and panel 3 must be initialized from panel 1 createCustomPanel method.
Tooltips MUST be initialized from PANELS you plan to place them in, so TOOLTIP 3  must be initialized from PANEL 3.

By making such a design you are able to create a much more advanced UI with ease.

Example of it you have right here:
[close]
Using CustomUIPanelPlugin:
Spoiler
When you initialize panel, the third argument is CustomUIPanelPlugin. Such plugins can make life easier.
For example rendering borders with UI, or making your own plugins to display images.
I personally use this plugin for both things, but I know they can be utilized much more efficiently, like for example creating your own horizontal scrollbar.

Example of UIPlugin displaying borders of panel;

Code:
Spoiler
Code
package data.kaysaar.aotd.vok.campaign.econ.globalproduction.ui.components;


import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.campaign.CustomUIPanelPlugin;
import com.fs.starfarer.api.graphics.SpriteAPI;
import com.fs.starfarer.api.input.InputEventAPI;
import com.fs.starfarer.api.ui.CustomPanelAPI;
import com.fs.starfarer.api.ui.PositionAPI;
import com.fs.starfarer.api.util.Misc;


import java.awt.*;
import java.util.ArrayList;
import java.util.List;


public class UILinesRenderer implements CustomUIPanelPlugin {
   ArrayList<CustomPanelAPI> panels = new ArrayList<>();
   SpriteAPI box = Global.getSettings().getSprite("rendering","GlitchSquare");
   Color boxColor = Misc.getDarkPlayerColor();
   public void setPanels(ArrayList<CustomPanelAPI> panels) {
       this.panels = panels;
   }
   public void setPanel(CustomPanelAPI panel) {
       panels.add(panel);
   }
   float widthPadding = 10f;
   public ArrayList<CustomPanelAPI> getPanels() {
       return panels;
   }


   @Override
   public void positionChanged(PositionAPI position) {


   }
   public UILinesRenderer(float widthPadding){
       this.widthPadding = widthPadding;
   }
   public void setBoxColor(Color boxColor) {
       this.boxColor = boxColor;
   }


   @Override
   public void renderBelow(float alphaMult) {






   }


   @Override
   public void render(float alphaMult) {
       for (CustomPanelAPI panel : panels) {
           if (panel != null) {
               box.setSize(panel.getPosition().getWidth()+widthPadding,1);
               box.setColor(boxColor);
               box.render(panel.getPosition().getX(),panel.getPosition().getY());
               box.render(panel.getPosition().getX(),panel.getPosition().getY()+panel.getPosition().getHeight());
               box.setSize(1,panel.getPosition().getHeight());
               box.render(panel.getPosition().getX(),panel.getPosition().getY());
               box.render(panel.getPosition().getX()+panel.getPosition().getWidth()+widthPadding,panel.getPosition().getY());
           }
       }
   }


   @Override
   public void advance(float amount) {


   }


   @Override
   public void processInput(List<InputEventAPI> events) {


   }


   @Override
   public void buttonPressed(Object buttonId) {


   }
}
[close]
Image:
Spoiler
[close]

Also as I mentioned before you can use it to much more advanced stuff, like for example rendering modular ships with weapon slots.

Code:
Spoiler
Code
package data.kaysaar.aotd.vok.misc.shipinfo;


import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.campaign.CustomUIPanelPlugin;
import com.fs.starfarer.api.graphics.SpriteAPI;
import com.fs.starfarer.api.input.InputEventAPI;
import com.fs.starfarer.api.loading.WeaponSpecAPI;
import com.fs.starfarer.api.ui.CustomPanelAPI;
import com.fs.starfarer.api.ui.PositionAPI;
import com.fs.starfarer.ui.P;
import com.fs.state.AppDriver;
import org.jetbrains.annotations.NotNull;


import java.awt.*;
import java.util.*;
import java.util.List;


public class ShipRenderer implements CustomUIPanelPlugin {
   LinkedHashMap<CustomPanelAPI, ShipRenderInfo.Module> partsOfShip = new LinkedHashMap<>();
   transient SpriteAPI spriteToRender = Global.getSettings().getSprite("rendering", "GlitchSquare");
   CustomPanelAPI absoultePanel = null;


   public void setAbsoultePanel(CustomPanelAPI absoultePanel) {
       this.absoultePanel = absoultePanel;
   }


   public void setPartsOfShip(HashMap<CustomPanelAPI, ShipRenderInfo.Module> partsOfShip, CustomPanelAPI test) {
       this.partsOfShip = sortPartsOfShipByRenderingOrder(partsOfShip);
       this.test = test;


   }


   public boolean canRender() {
       if (absoultePanel == null) return true;
       for (CustomPanelAPI panelAPI : partsOfShip.keySet()) {
           if (panelAPI.getPosition().getY() < absoultePanel.getPosition().getY() - 60) {
               return false;
           }
           if (panelAPI.getPosition().getY() > absoultePanel.getPosition().getY() + absoultePanel.getPosition().getHeight() + 60) {
               return false;
           }
       }
       return true;
   }


   private LinkedHashMap<CustomPanelAPI, ShipRenderInfo.Module> sortPartsOfShipByRenderingOrder(HashMap<CustomPanelAPI, ShipRenderInfo.Module> parts) {
       // Convert the entries of the HashMap to a list
       List<Map.Entry<CustomPanelAPI, ShipRenderInfo.Module>> entries = new ArrayList<>(parts.entrySet());


       // Sort the list based on the renderingOrder
       Collections.sort(entries, new Comparator<Map.Entry<CustomPanelAPI, ShipRenderInfo.Module>>() {
           @Override
           public int compare(Map.Entry<CustomPanelAPI, ShipRenderInfo.Module> e1, Map.Entry<CustomPanelAPI, ShipRenderInfo.Module> e2) {
               return Integer.compare(e1.getValue().renderingOrder, e2.getValue().renderingOrder);
           }
       });


       // Create a LinkedHashMap to preserve the sorted order
       LinkedHashMap<CustomPanelAPI, ShipRenderInfo.Module> sortedMap = new LinkedHashMap<>();
       for (Map.Entry<CustomPanelAPI, ShipRenderInfo.Module> entry : entries) {
           sortedMap.put(entry.getKey(), entry.getValue());
       }


       return sortedMap;
   }


   CustomPanelAPI test;
   public float scale = 1f;


   public void setScale(float scale) {
       this.scale = scale;
   }


   @Override
   public void positionChanged(PositionAPI position) {
       return;
   }


   @Override
   public void renderBelow(float alphaMult) {
       return;
   }


   @Override
   public void render(float alphaMult) {
//        if(test!=null){
//            spriteToRender.setColor(Color.ORANGE);
//            spriteToRender.setSize(test.getPosition().getWidth(),test.getPosition().getHeight());
//            spriteToRender.renderAtCenter(test.getPosition().getCenterX(),test.getPosition().getCenterY());
//        }
       if (!canRender()) return;
       for (Map.Entry<CustomPanelAPI, ShipRenderInfo.Module> entry : partsOfShip.entrySet()) {
           SpriteAPI sprite = Global.getSettings().getSprite(Global.getSettings().getHullSpec(entry.getValue().slotOnOriginal.id).getSpriteName());
           sprite.setAngle(entry.getValue().slotOnOriginal.angle);
           sprite.setSize((float) entry.getValue().width * scale, (float) entry.getValue().height * scale);
           sprite.renderAtCenter(entry.getKey().getPosition().getCenterX(), entry.getKey().getPosition().getCenterY());
           for (ShipRenderInfo.Slot builtInSlot : entry.getValue().built_in_slots) {
               WeaponSpecAPI weapon = Global.getSettings().getWeaponSpec(builtInSlot.id);
               String base = weapon.getTurretSpriteName();
               SpriteAPI baseSprite = Global.getSettings().getSprite(base);
               setSizeOfSpriteToScale(baseSprite);
               baseSprite.setAngle(builtInSlot.angle);
               float x = entry.getKey().getPosition().getX() + entry.getValue().center.x * scale;
               float y = entry.getKey().getPosition().getY() + entry.getValue().center.y * scale;
               renderSlotMoved(baseSprite, x + builtInSlot.locationOnShip.x * scale, y + builtInSlot.locationOnShip.y * scale);


           }
       }




   }




   private static void renderSlotMoved(SpriteAPI underSprite, float x, float y) {
       underSprite.renderAtCenter(x, y);
   }


   private void setSizeOfSpriteToScale(@NotNull SpriteAPI baseSprite) {
       baseSprite.setSize((float) baseSprite.getWidth() * scale, (float) baseSprite.getHeight() * scale);
   }


   @Override
   public void advance(float amount) {
       return;
   }


   @Override
   public void processInput(List<InputEventAPI> events) {
       return;
   }


   @Override
   public void buttonPressed(Object buttonId) {
       return;
   }
}
[close]
Image:
Spoiler
[close]
[close]
Tooltip method examples:
Spoiler
Button
Spoiler
Okay so first to create such a button we will lay out layers. First custom panel and Tooltip. Because I want this button to basically cover the entire panel I’ll write on paint


To insert button, we have 2 options

addButton
Code
tooltip.addButton("Special Project", null, base, bg, Alignment.MID, CutStyle.TOP, 150, 20, 0f);
Here with such button you have more freedom, not with coloring, but with how button outline looks like
Result
Spoiler
[close]

addAreaCheckbox
Code
tooltip.addAreaCheckbox("Name", SortingState.NON_INITIALIZED, base, bg, bright, UIData.WIDTH_OF_NAMES_ORDER, 20, 0f);

Result
Spoiler
[close]

As you might see, I have passed in this button in the second argument of my own class SortingState. This is where you can  define custom data contained in the button, which can be used later to trigger events related to this button.

Handling Buttons (advance method)
Spoiler
Code
for (ButtonAPI button : sortingButtons) {
   if (button.isChecked()) {
       if (button.getCustomData() instanceof String) {
           button.setChecked(false);
           SortingState state = mapOfButtonStates.get(button.getCustomData());
           if(state == SortingState.NON_INITIALIZED){
               state = SortingState.ASCENDING;
           }
           else if(state == SortingState.ASCENDING){
               state = SortingState.DESCENDING;
           }
           else if(state == SortingState.DESCENDING){
               state = SortingState.NON_INITIALIZED;
           }
           for (String s : mapOfButtonStates.keySet()) {
               mapOfButtonStates.put(s,SortingState.NON_INITIALIZED);
           }
           mapOfButtonStates.put((String) button.getCustomData(),state);
           currPage = 0;
           reset = true;
       }
       break;
   }
}


if (reset) {
   reset();
}

Here is an example of your own button handler.
Note here: If you want to update the UI, you need to remove it and re-create again!
This is why chopping the UI into smaller pieces comes  into play, as you just need to remove that one panel, where you had that part of the UI, which needs updating.

[close]
[close]
Images
Spoiler
With images same we can have two routes, of how we can achieve that.Either as
A: Using CustomUIPanelPlugin (like i showcased in Using CustomUIPanelPlugin part)
B:Using dedicated method in tooltip : addImage
Code
CustomPanelAPI mainPanel = this.absoultePanel;
UILinesRenderer renderer  = new UILinesRenderer(0f);// here we initalize our plugin much faster than panel
CustomPanelAPI testingPanel = Global.getSettings().createCustom(195,90,renderer);//width and size of industry image
TooltipMakerAPI tooltip = testingPanel.createUIElement(195,90,false);
String pathToImage = Global.getSettings().getIndustrySpec(Industries.HEAVYINDUSTRY).getImageName();
tooltip.addImage(pathToImage,0f);
testingPanel.addUIElement(tooltip).inTL(0,0);
renderer.setPanel(testingPanel);
mainPanel.addComponent(testingPanel).inTL(0,0);
With addImage you can also specify width and height of image. If you only specify width, the method will adjust height based on the ratio of image.


Because addimage does not return any variable, if you wanna move an image , for example repositioning to the middle you should use the tooltip.getPrev() method!

Example here
Code
WeaponSpecAPI spec = Global.getSettings().getWeaponSpec(id);
                String base = spec.getTurretSpriteName();
                String under = spec.getTurretUnderSpriteName();
                tooltip.addImage(under,0);
                tooltip.getPrev().getPosition().inMid();
                tooltip.addImage(base,0);
                tooltip.getPrev().getPosition().inMid();
[close]
Headers:
Spoiler
To make your UI more readable, instead of a big pile of text, you can divide it with headers. Like for example Industry tooltip does !
Code example:
Code
tooltip.addSectionHeading("Produced resources", Alignment.MID, 0f);
tooltip.addPara("Construction speed bonus: %s",5f,Color.ORANGE,"50%");
tooltip.addPara("Orbital Skunk-work bonus %s",5f, Misc.getPositiveHighlightColor(),"Each built ship have 1 built-in s-mod");
tooltip.addPara("Hypershunt bonus %s",5f, Misc.getPositiveHighlightColor(),"Decrease cost of special project stages by 50%");

Result
Spoiler
[close]
[close]
Text
Spoiler
If you wanna add text you can use addPara. As you can also see  there are 5 different methods having addPara;
Code
LabelAPI addPara(String str, float pad);
LabelAPI addPara(String str, Color color, float pad);
LabelAPI addPara(String format, float pad, Color hl, String... highlights);
LabelAPI addPara(String format, float pad, Color[] hl, String ... highlights);
LabelAPI addPara(String format, float pad, Color color, Color hl, String ... highlights);

1: We use that to simply add text
2: We use that to add coloured text
3 We use that one to add text, where specific bits of text are highlighted (where %s is) on specific color
4 We use that one to add text, where specific bits of text are highlighted (where %s is) on specific colors
5. We use that one to add text which have different color and on top of where specific bits of text are highlighted (where %s is) on specific color

Here is example usage of :
Code
LabelAPI addPara(String format, float pad, Color hl, String... highlights);

Code
tooltip.addPara("Construction speed bonus: %s",5f,Color.ORANGE,"50%");
tooltip.addPara("Orbital Skunk-work bonus %s",5f, Misc.getPositiveHighlightColor(),"Each built ship have 1 built-in s-mod");
tooltip.addPara("Hypershunt bonus %s",5f, Misc.getPositiveHighlightColor(),"Decrease cost of special project stages by 50%");

Result
Spoiler
[close]

Useful things to know about LabelAPI:
I think the best way for you to learn all about LabelAPI, would be extensively using it, but as small highlight with LabelAPI you can do things like
Calculating both  text height and width ( useful when positioning)
Autosizing text width (For example if we want text to be more compact)

Custom Fonts
Spoiler
Current version of starsector (0.97 as this is written) has support for adding custom fonts!
All you need is .fnt file of your font you wanna use
Code
String filename = "graphics/fonts/";
ArrayList<Integer>fontSizes = new ArrayList<>();
fontSizes.add(12);
fontSizes.add(15);
fontSizes.add(18);
fontSizes.add(20);
fontSizes.add(24);
fontSizes.add(35);
for (Integer fontSize : fontSizes) {
   try {
       Global.getSettings().loadFont(filename+"ACES07_Regular_"+fontSize+".fnt");
   } catch (IOException e) {
       throw new RuntimeException(e);
 

Before you will use addPara method, for this font to be used you also need to do this
Code
tooltip.setParaFont("graphics/fonts/ACES07_Regular_15.fnt");

And result of such changes?
Spoiler
[close]
[close]
[close]
On Hover Tooltips:
Spoiler
Sometimes you will find yourself in a situation, that for example you would wanna display additional info about some part of the mechanic in your UI, but something as optional, like for example cargo info when you hover over the cargo icon.
For it you will use addTooltipToPrevious
Code
tooltip.setTitleOrbitronLarge();
LabelAPI labelAPI= tooltip.addPara("Technology Tree of "+ AoTDMainResearchManager.getInstance().getManagerForPlayer().getFaction().getDisplayName(), Color.ORANGE,10f);
labelAPI.getPosition().inTL(150-labelAPI.computeTextWidth(labelAPI.getText())/2,10);
tooltip.setParaFontDefault();
specialProjectButton=tooltip.addButton("Special Projects","UI_SPECIAL_PROJECTS",290,30,10f);
specialProjectButton.getPosition().inTL(5,52);
tooltip.addTooltipToPrevious(new TooltipMakerAPI.TooltipCreator() {
   @Override
   public boolean isTooltipExpandable(Object tooltipParam) {
       return true;
   }


   @Override
   public float getTooltipWidth(Object tooltipParam) {
       return 500;
   }


   @Override
   public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
       tooltip.addPara("Special projects are special type of research options, that appear once certain criteria are met.\nThese projects unlike research options in the tech tree are not guaranteed to be successful." +
               "\nCurrently special projects are inaccessible due to being WIP",10f);
   }
}, TooltipMakerAPI.TooltipLocation.RIGHT,false);

Result
Spoiler
[close]
[close]
Custom Components:
Spoiler
Other Panels:
Yes you can add whole panels to tooltip. The best way to do it avoid any troubles is to add Panels initalized with  Global.getSettings().createCustom(width,height,CustomUIPanelPlugin);
Code
CustomPanelAPI panel = Global.getSettings().createCustom(100,100,null);
mainTooltip.addCustom(panel ,5f);
Sub tooltip:
I find this to be more efficient sometimes as adding too much panels is not also a good idea (Check what you need to look for )
Code
CustomPanelAPI panel = Global.getSettings().createCustom(300,100,null);
TooltipMakerAPI tooltip = panel.createUIElement(300,100,true);
TooltipMakerAPI subTooltip = tooltip.beginSubTooltip(300);
subTooltip.addPara("My own subTooltip",0f);
tooltip.endSubTooltip();
tooltip.addCustom(subTooltip,5f);
[close]
Spacers
Spoiler
If you wanna create spaces between two Ui components in tooltip ( a gap between them), a safe bet to do it is with using spacers.
Code
tooltip.addSpacer(30f);
[close]
[close]
Using PositionAPI
Spoiler
Panels, buttons, Tooltips and all of the UI components have fields with PositionAPI. You can use it to directly retrieve coordinates of certain UI parts. This is very helpful in designing responsive UI. Where instead of hard setting coordinates of UI, you use coordinates of relative parts of UI.

Note! Using PositionAPI on components that are placed on tooltip which has not been placed yet on panel, will result in Y coordinates to be on minus. So whenever  retrieving coordinates of for example the last text you placed , multiply the Y cord by -1.
[close]
Using Stencil Mask:
Spoiler
Using Stencil Mask

To avoid blue lines rendered with openGL like on that image below:



You need to use Stencil Mask.

First before you even start using stencil you need to include this in advance method.
Code
 glClearStencil(0);
glStencilMask(0xff);

Here is function for : drawmask as we will be using that below:
Code
 void drawmask(CustomPanelAPI p) {
        GL11.glBegin(GL_QUADS);
        float x = p.getPosition().getX() - 6;
        float y = p.getPosition().getY();
        float w = p.getPosition().getWidth() + 11;
        float h = p.getPosition().getHeight();
        GL11.glVertex2f(x, y);
        GL11.glVertex2f(x + w, y);
        GL11.glVertex2f(x + w, y + h);
        GL11.glVertex2f(x, y + h);
        GL11.glEnd();
    }

Then moving on to render method section.
Code
  glClear(GL_STENCIL_BUFFER_BIT);
            glColorMask(false, false, false, false); //disable colour
            glEnable(GL_STENCIL_TEST); //enable stencil
            openGlUtilis.drawmask(panel1);
            glStencilFunc(GL_ALWAYS, 1, 0xff); // Do not test the current value in the stencil buffer, always accept any value on there for drawing
            glStencilMask(0xff);
            glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); // Make every test succeed
            openGlUtilis.drawmask(panel1);
            glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // Make sure you will no longer (over)write stencil values, even if any test succeeds
            glColorMask(true, true, true, true); // Make sure we draw on the backbuffer again.
            glStencilFunc(GL_EQUAL, 1, 0xFF); // Now we will only draw pixels where the corresponding stencil buffer value equals 1

//here you have code for drawing panels for example with drawPanelBorder we mentioned , that will be located in stencil mask

         glDisable(GL_STENCIL_TEST);
[close]
What you need to look for:
Spoiler
As you go with designing UI there are few things you need to look for.
Don’t use too many Panels at once !
Spoiler
As I said, it is good to use a lot of panels, for easy work with UI, but at the same time, each panel has its own render,  and advanced method, which when you start to stack it more and more, it will generate lag.
You won’t probably exceed such a number easily, as this is when you have dozens of panels in UI.
[close]
Check those resolutions!
Spoiler
I am serious, you might think that people no longer use such small resolutions, and here you will be mistaken. A good UI is a UI that looks good on all resolutions.
[close]
Use relative positioning
Spoiler
With ever changing resolution (because not everyone is playing 1920x1080) using relative positioning can be very helpful in creating a cohesive UI.
[close]
Pre calculate width and height of tooltips and panels/b]
Spoiler
Once you place panel or tooltip, you cant resize them , you need to remove them , change parameters and then insert them back, so it has any effect!
[close]
[close]
Useful Codding Snippets
Spoiler
I will be posting here useful codding snippets, that might come in handy in future for those who wants to dive into creating UI

Drawing stencil mask based on Panel (arg scale is used for how much height should be used in stencil) and endStencil
Spoiler
Code
 public static void startStencil(CustomPanelAPI panel,float scale) {
        GL11.glClearStencil(0);
        GL11.glStencilMask(0xff);
        GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);

        GL11.glColorMask(false, false, false, false);
        GL11.glEnable(GL11.GL_STENCIL_TEST);

        GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 0xff);
        GL11.glStencilMask(0xff);
        GL11.glStencilOp(GL11.GL_REPLACE, GL11.GL_REPLACE, GL11.GL_REPLACE);

        GL11.glBegin(GL11.GL_POLYGON);
        PositionAPI position = panel.getPosition();
        float x = position.getX();
        float y = position.getY();
        float width = position.getWidth();
        float height = position.getHeight();

        // Define the rectangle
        GL11.glVertex2f(x, y);
        GL11.glVertex2f(x + width, y);
        GL11.glVertex2f(x + width, y + height*scale);
        GL11.glVertex2f(x, y + height*scale);
        GL11.glEnd();

        GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
        GL11.glColorMask(true, true, true, true);

        GL11.glStencilFunc(GL11.GL_EQUAL, 1, 0xFF);
    }
    public static void endStencil() {
        GL11.glDisable(GL11.GL_STENCIL_TEST);
    }
[close]

[close]




7
Modding / [0.96a-RC10] Which-industry
« on: November 01, 2023, 11:24:53 AM »
What Can I say ?
It's simple mod that adds to industry tooltip info from what mod industry/structure is


Download Here

Pages: [1]