Skip to content

Commit

Permalink
Adds Gadget slot, ability to hide icons if no cooldown running
Browse files Browse the repository at this point in the history
  • Loading branch information
Earthfiredrake committed Mar 29, 2018
1 parent 7b067f0 commit 34bd390
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 105 deletions.
36 changes: 21 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,55 @@
# SWL-FreeHUD
Free floating ability markers for easier cooldown tracking
Free-floating ability icons for easier cooldown tracking

## Overview
Mirrors the active ability and gadget slots from the ability bar as individual free-floating icons that can be customized using the standard GUI edit mode (lock icon at the right end of the topbar, drag to place, scroll-wheel to resize). Abilities with no possible cooldown are hidden automatically, and the others can be set to only display when on cooldown with `/setoption efdFreeHUDHideReady true`.

Each icon links to one ability slot, layout may need adjustment between builds.

## Installation
Any packaged release should be unzipped (including the internal folder) into the appropriate folder and the client restarted.
<br/>TSW: [TSW Directory]\Data\Gui\Customized\Flash.
<br/>SWL: [SWL Directory]\Data\Gui\Custom\Flash.

The safest method for upgrading (required for installing) is to have the client closed and delete any existing .bxml files in the Cartographer directory. Hotpatching (using /reloadui) works as long as neither Modules.xml or LoginPrefs.xml have changed.
The safest method for upgrading (required for installing) is to have the client closed and delete any existing .bxml files in the Cartographer directory. Hotpatching (using /reloadui) works as long as none of Modules.xml, LoginPrefs.xml, or CharPrefs.xml have changed.

I intend to permit setting migration from the first public beta to v1.0.x, but this may be subject to change. As with my other mods, this update compatibility window will occasionally be shifted to reduce legacy code clutter.
Upgrading should retain settings as much as possible. All settings are currently saved per character.

## Change Log

Version Initial

Version 0.0.1-beta
+ Initial release
+ Active ability and gadget icons
+ Customizable layout (on ability slots, one per character)
+ Option to only show running cooldowns (/setoption efdFreeHUDHideReady true)

## Known Issues

This is an early version of this mod. There are many issues, some of them are known.
I'm always open to hearing comments and suggestions as well, easier to start with good ideas than rewrite from bad ones.
This is an early version of this mod, so there's likely to be a few issues discovered:
+ Abilities (mostly weapon gimmicks) may not accurately reflect the disabled state when first loaded
+ Default layout doesn't match the ability bar (Won't fix: whole point is to rearrange them anyway)

As always, defect reports, suggestions, and contributions are welcome. They can be sent to Peloprata in SWL (by mail or pm), via the github issues system, or @Peloprata in #modding on discord.

## Wishlist

+ Let GEM mode reveal hidden icons so they can be positioned without swapping slots
+ Option to hide icon when not on cooldown, and to hide cooldown clock
+ Gadget (maybe pot) cooldowns
+ Option to hide when going into cooldown (opposite behaviour to HideReady)
+ Option to hide cooldown clock display
+ Pot cooldowns?
+ Work with action swap outs (Shotgun ammo, maybe fist/ele? what other weapons behave like this?)
+ Integrate with build manager and BooBuilds(?) so that icon placement can be customized on a per build basis

## Websites

Source Repository: https://github.com/Earthfiredrake/SWL-FreeHUD

Curse Mirror: TBD
Curse Mirror: https://www.curseforge.com/swlegends/tswl-mods/freehud

## Building from Source
Requires copies of the SWL and Scaleform CLIK APIs. Existing project files are configured for Flash Pro CS5.5.

Master/Head is the most recent packaged release. Develop/Head is usually a commit or two behind my current test build. As much as possible I try to avoid regressions or unbuildable commits but new features may be incomplete and unstable and there may be additional debug code that will be removed or disabled prior to release.

Once built, 'FreeHUD.swf' and the contents of 'config' should be copied to the directory 'FreeHUD' in the game's mod directory. '/reloadui' is sufficient to force the game to load an updated swf or mod data file, but changes to the game config files (LoginPrefs.xml and Modules.xml) will require a restart of the client and possible deletion of .bxml caches from the mod directory.
Once built, 'FreeHUD.swf' and the contents of 'config' should be copied to the directory 'FreeHUD' in the game's mod directory. '/reloadui' is sufficient to force the game to load an updated swf or mod data file, but changes to the game config files (*Prefs.xml and Modules.xml) will require a restart of the client and possible deletion of .bxml caches from the mod directory.

## License and Attribution
Copyright (c) 2018 Earthfiredrake<br/>
Expand All @@ -58,9 +63,10 @@ https://github.com/eltorqiro/TSW-UITweaks
TSW, SWL, the related API, and most graphics elements are copyright (c) 2012 Funcom GmBH<br/>
Used under the terms of the Funcom UI License<br/>

Curseforge icon based off of game assets and:
https://commons.wikimedia.org/wiki/File:Simpleicons_Interface_unlocked-padlock.svg (CC Attribution 3.0)

Special Thanks to:<br/>
The TSW modding community for neglecting to properly secure important intel in their faction vaults<br/>
The usual suspects<br/>
Shivvies for the idea<br/>
Everyone who provided suggestions, testing and feedback<br/>

111 changes: 91 additions & 20 deletions efd/FreeHUD/FreeHUD.as
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
// Released under the terms of the MIT License
// https://github.com/Earthfiredrake/SWL-FreeHUD

import com.GameInterface.DistributedValue;
import com.GameInterface.Game.Character;
import com.GameInterface.Game.Shortcut;
import com.GameInterface.Game.ShortcutData;
import com.GameInterface.Inventory;
import com.GameInterface.Utils;
import com.Utils.ID32;

import efd.FreeHUD.lib.Mod;
import efd.FreeHUD.lib.sys.ConfigManager;
Expand All @@ -14,7 +19,7 @@ class efd.FreeHUD.FreeHUD extends Mod {
// Debug flag at top so that commenting out leaves no hanging ','
// Debug : true,
Name : "FreeHUD",
Version : "0.0.1.alpha",
Version : "0.0.1.beta",
Subsystems : {
Config : {
Init : ConfigManager.Create
Expand All @@ -25,7 +30,7 @@ class efd.FreeHUD.FreeHUD extends Mod {
// LeftMouseInfo : IconMouse_ToggleConfigWindow,
// RightMouseInfo : IconMouse_ToggleUserEnabled
}
},
},
LinkVTIO : {
Init : VTIOHelper.Create,
InitObj : {
Expand All @@ -39,38 +44,61 @@ class efd.FreeHUD.FreeHUD extends Mod {
public function FreeHUD(hostMovie:MovieClip) {
super(GetModInfo(), hostMovie);
Config.NewSetting("CooldownLayout", GetDefaultLayout());
Config.NewSetting("HideReady", false);

Equipment = new Inventory(new ID32(_global.Enums.InvType.e_Type_GC_WeaponContainer, Character.GetClientCharID().GetInstance()));
}

private function Activate():Void {
if (!CooldownViews) {
CooldownViews = new Object;
CooldownViews = new Array;
var layoutSettings:Array = Config.GetValue("CooldownLayout");
for (var i:Number = 0; i < AbilityCount; ++i) {
var hideReady:Boolean = Config.GetValue("HideReady");
for (var i:Number = 0; i < CooldownCount; ++i) {
var layout:Object = layoutSettings[i];
CooldownViews[i] = HostClip.attachMovie("efdFreeHUDCooldownDisplay", "CooldownDisplay" + i, HostClip.getNextHighestDepth(),
{_x : layout.x, _y : layout.y, _xscale : layout.scale, _yscale : layout.scale, SlotID : i + AbilityOffset});
var cooldown:MovieClip = HostClip.attachMovie("efdFreeHUDCooldownDisplay", "CooldownDisplay" + i, HostClip.getNextHighestDepth(),
{_x : layout.x, _y : layout.y, _xscale : layout.scale, _yscale : layout.scale,
SlotID : (i == GadgetIndex ? 0 : i + AbilityOffset),
HideReady : hideReady});
cooldown.ChangeAbility(i < AbilityCount ?
Shortcut.m_ShortcutList[i + AbilityOffset] :
Equipment.GetItemAt(_global.Enums.ItemEquipLocation.e_Aegis_Talisman_1));
CooldownViews.push(cooldown);
}
}
Shortcut.SignalShortcutAdded.Connect(AbilityChanged, this);
Shortcut.SignalShortcutRemoved.Connect(AbilityChanged, this);
Shortcut.SignalShortcutMoved.Connect(AbilityMoved, this);
Shortcut.SignalShortcutEnabled.Connect(EnableAbility, this);
Shortcut.SignalCooldownTime.Connect(AbilityCooldown, this);

Equipment.SignalItemAdded.Connect(ItemChanged, this);
Equipment.SignalItemLoaded.Connect(ItemChanged, this);
Equipment.SignalItemRemoved.Connect(ItemChanged, this);
Equipment.SignalItemCooldown.Connect(ItemCooldown, this);
Equipment.SignalItemCooldownRemoved.Connect(ItemCooldown, this);
}

private function Deactivate():Void {
var layout = new Array();
for (var i:Number = 0; i < AbilityCount; ++i) {
for (var i:Number = 0; i < CooldownCount; ++i) {
var clip:MovieClip = CooldownViews[i];
layout.push({x : clip._x, y : clip._y, scale : clip._xscale});
}
Config.SetValue("CooldownLayout", layout);
}


private function LoadComplete():Void {
VisibilityBehaviourDV = DistributedValue.Create(DVPrefix + ModName + "HideReady");
VisibilityBehaviourDV.SetValue(Config.GetValue("HideReady"));
VisibilityBehaviourDV.SignalChanged.Connect(VisibilityBehaviourChanged, this);
super.LoadComplete();
}

private function ConfigChanged(setting:String, newValue, oldValue):Void {
switch(setting) {
case "CooldownLayout": {
for (var i:Number = 0; i < AbilityCount; ++i) {
for (var i:Number = 0; i < CooldownCount; ++i) {
var clip:MovieClip = CooldownViews[i];
var layout = newValue[i];
clip._x = layout.x;
Expand All @@ -80,33 +108,53 @@ class efd.FreeHUD.FreeHUD extends Mod {
}
break;
}
default: super.ConfigChanged(setting, newValue, oldValue);
case "HideReady": {
for (var i:Number = 0; i < CooldownCount; ++i) {
CooldownViews[i].SetVisibilityBehaviour(newValue);
}
break;
}
default: super.ConfigChanged(setting, newValue, oldValue);
}
}

private function VisibilityBehaviourChanged(dv:DistributedValue):Void {
Config.SetValue("HideReady", dv.GetValue());
}

private function UpdateMod(newVersion:String, oldVersion:String):Void {
var layouts:Array = Config.GetValue("CooldownLayout");
var defaultLayouts:Array = Config.GetDefault("CooldownLayout");
if (layouts.length < defaultLayouts.length) {
for (var i:Number = layouts.length; i < defaultLayouts.length; ++i) {
layouts.push(defaultLayouts[i]);
}
}
}

private function GetDefaultLayout():Array {
var layout = new Array();
for (var i:Number = 0; i < AbilityCount; ++i) {
for (var i:Number = 0; i < CooldownCount; ++i) {
layout.push({x : 575 + i * 50, y : 450, scale : 100});
}
return layout;
}

// Despite documentation to the contrary, SignalShortcutAdded only emits the first parameter
private function AbilityChanged(pos:Number) {
CooldownViews[pos-AbilityOffset].ChangeAbility();
CooldownViews[pos-AbilityOffset].ChangeAbility(Shortcut.m_ShortcutList[pos]);
}

// Triggers once only
private function AbilityMoved(oldPos:Number, newPos:Number) {
AbilityChanged(oldPos);
AbilityChanged(newPos);
}

private function EnableAbility(pos:Number, enabled:Boolean):Void {
CooldownViews[pos-AbilityOffset].EnableAbility(enabled);
}

private function AbilityCooldown(pos:Number, start:Number, end:Number, type:Number) {
var remains:Number = end - start;
if (type > 0 && remains > 0) {
Expand All @@ -115,8 +163,31 @@ class efd.FreeHUD.FreeHUD extends Mod {
CooldownViews[pos-AbilityOffset].RemoveCooldown();
}
}

private var CooldownViews:Object;

private function ItemChanged(inventoryID:com.Utils.ID32, itemPos:Number):Void {
if (itemPos == _global.Enums.ItemEquipLocation.e_Aegis_Talisman_1) {
CooldownViews[GadgetIndex].ChangeAbility(Equipment.GetItemAt(_global.Enums.ItemEquipLocation.e_Aegis_Talisman_1));
}
}

private function ItemCooldown(inventoryID:com.Utils.ID32, itemPos:Number, seconds:Number):Void {
if (itemPos == _global.Enums.ItemEquipLocation.e_Aegis_Talisman_1) {
if (seconds) {
var now:Number = Utils.GetGameTime();
CooldownViews[GadgetIndex].AddCooldown(now, now + seconds, 0);
} else {
Debug.TraceMsg("Cooldown force removed");
CooldownViews[GadgetIndex].RemoveCooldown();
}
}
}

private static var AbilityOffset:Number = 100;
private static var AbilityCount:Number = 6;
private static var CooldownCount:Number = AbilityCount + 1;
private static var GadgetIndex = AbilityCount;

private var CooldownViews:Array;
private var VisibilityBehaviourDV:DistributedValue;
private var Equipment:Inventory;
}
Loading

0 comments on commit 34bd390

Please sign in to comment.