Skip to content

Commit

Permalink
feat: port to modern hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
LordMidas committed Nov 8, 2023
1 parent 746ea08 commit 2b74c76
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 100 deletions.
126 changes: 28 additions & 98 deletions mod_stack_based_skills/mod_stack_based_skills_v4.nut
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,29 @@ If I want to remove the stack which wasn't serialized, I have to manually reques

::MSU.Skills.ClassNameHashToIsSerializedMap <- {};

::MSU.AfterQueue.add(::StackBasedSkills.ID, function() {
foreach (script in ::IO.enumerateFiles("scripts/skills"))
{
if (script == "scripts/skills/skill_container" || script == "scripts/skills/skill") continue;

try
{
// Store the default value of every skill's IsSerialized
// This is used in the `removeSelf` function to pass the default value for this skill
local skill = ::new(script);
::MSU.Skills.ClassNameHashToIsSerializedMap[skill.ClassNameHash] <- skill.isSerialized();
}
catch (error)
{
::logError("Could not instaniate or get ClassNameHash or isSerialized() of skill: " + script + ". Error: " + error);
}
}
});

::mods_hookBaseClass("skills/skill", function(o) {
o = o[o.SuperName];

o.m.MSU_AddedStack <- 1;
o.m.MSU_IsSerializedStack <- {
::StackBasedSkills.HooksMod.hook("scripts/skills/skill", function(q) {
q.m.MSU_AddedStack <- 1;
q.m.MSU_IsSerializedStack <- {
[true] = 0,
[false] = 0
};

o.isKeepingAddRemoveHistory <- function()
q.isKeepingAddRemoveHistory <- function()
{
return !this.isStacking() && !this.isType(::Const.SkillType.Special) && (this.isType(::Const.SkillType.Perk) || !this.isType(::Const.SkillType.StatusEffect));
}

local removeSelf = o.removeSelf;
o.removeSelf = function()
local removeSelf;
q.removeSelf = function( __original )
{
this.removeSelfByStack(::MSU.Skills.ClassNameHashToIsSerializedMap[this.ClassNameHash]);
removeSelf = __original;
return function()
{
this.removeSelfByStack(::MSU.Skills.ClassNameHashToIsSerializedMap[this.ClassNameHash]);
}
}

o.updateIsSerialized <- function()
q.updateIsSerialized <- function()
{
if (this.m.MSU_IsSerializedStack[true] == 0 && this.m.MSU_IsSerializedStack[false] == 0)
{
Expand All @@ -66,7 +49,7 @@ If I want to remove the stack which wasn't serialized, I have to manually reques
this.m.IsSerialized = this.m.MSU_IsSerializedStack[true] > 0;
}

o.removeSelfByStack <- function( _isSerialized = false )
q.removeSelfByStack <- function( _isSerialized = false )
{
if (!this.isKeepingAddRemoveHistory()) return removeSelf();

Expand Down Expand Up @@ -115,17 +98,16 @@ If I want to remove the stack which wasn't serialized, I have to manually reques
}
});

::mods_hookNewObject("skills/skill_container", function(o) {
o.addByStack <- function( _skill, _order = 0 )
::StackBasedSkills.HooksMod.hook("scripts/skills/skill_container", function(q) {
q.addByStack <- function( _skill, _order = 0 )
{
_skill.m.IsSerialized = false;
return this.add(_skill, _order);
}

local add = o.add;
o.add = function( _skill, _order = 0 )
q.add = @(__original) function( _skill, _order = 0 )
{
if (!_skill.isKeepingAddRemoveHistory()) return add(_skill, _order);
if (!_skill.isKeepingAddRemoveHistory()) return __original(_skill, _order);

_skill.m.MSU_IsSerializedStack[_skill.m.IsSerialized] = 1;

Expand Down Expand Up @@ -190,33 +172,31 @@ If I want to remove the stack which wasn't serialized, I have to manually reques
if (::StackBasedSkills.Mod.Debug.isEnabled()) ::MSU.Log.printData(skillToKeep.m.MSU_IsSerializedStack, 99, false, 99);
}

return add(_skill, _order);
return __original(_skill, _order);
}

local remove = o.remove;
o.remove = function( _skill )
q.remove = @(__original) function( _skill )
{
// ::logInfo(_skill.getID() + ": " + _skill.m.MSU_AddedStack);
if (_skill.m.MSU_AddedStack == 1) return remove(_skill);
if (_skill.m.MSU_AddedStack == 1) return __original(_skill);
else return _skill.removeSelf();
}

local removeByID = o.removeByID;
o.removeByID = function( _skillID )
q.removeByID = @(__original) function( _skillID )
{
local skill = this.getSkillByID(_skillID);
if (skill == null) return;

if (skill.m.MSU_AddedStack == 1) return removeByID(_skillID);
if (skill.m.MSU_AddedStack == 1) return __original(_skillID);
else return skill.removeSelf();
}

o.removeByStack <- function( _skill, _isSerialized = false )
q.removeByStack <- function( _skill, _isSerialized = false )
{
return skill.removeSelfByStack(_isSerialized);
}

o.removeByStackByID <- function( _skillID, _isSerialized = false )
q.removeByStackByID <- function( _skillID, _isSerialized = false )
{
local skill = this.getSkillByID(_skillID);
if (skill == null) return;
Expand All @@ -225,68 +205,18 @@ If I want to remove the stack which wasn't serialized, I have to manually reques
}
});

::mods_hookNewObject("items/item_container", function(o) {
o.m.MSU_ItemBeingUnequipped <- null;
::StackBasedSkills.HooksMod.hook("scripts/items/item_container", function(q) {
q.m.MSU_ItemBeingUnequipped <- null;

local unequip = o.unequip;
o.unequip = function( _item )
q.unequip = @(__original) function( _item )
{
// This variable is needed for proper functionality in the skill.removeSelf function because
// in that function we want to know if the item being unequipped is the one that is attached to that skill
// and skills are removed before the item is unequipped
this.m.MSU_ItemBeingUnequipped = _item;
local ret = unequip(_item);
local ret = __original(_item);
this.m.MSU_ItemBeingUnequipped = null;

return ret;
}
});

// Test perk
// ::mods_hookExactClass("skills/perks/perk_colossus", function(o) {
// o.onEquip <- function( _item )
// {
// if (_item.getSlotType() != ::Const.ItemSlot.Mainhand) return;

// // // Add Shield Expert, Reach Advantage, and Duelist while a weapon is equipped
// // // But add non-permanent (i.e. IsSerialized = false) versions of these skills

// this.getContainer().addByStack(::new("scripts/skills/perks/perk_shield_expert"));
// this.getContainer().addByStack(::new("scripts/skills/perks/perk_reach_advantage"));
// this.getContainer().addByStack(::new("scripts/skills/perks/perk_duelist"));
// }

// o.onUnequip <- function( _item )
// {
// // Remove the Shield Expert, Reach Advantage and Duelist skills when a weapon is unequipped
// // But we must remove the "non-permanent" i.e. "IsSerialized = false" versions of these skills (that we added in onEquip)
// if (_item.getSlotType() != ::Const.ItemSlot.Mainhand) return;

// this.getContainer().removeByStackByID("perk.shield_expert");
// this.getContainer().removeByStackByID("perk.reach_advantage");
// this.getContainer().removeByStackByID("perk.duelist");
// }

// o.onAdded <- function()
// {
// // this.getContainer().addByStack(::new("scripts/skills/perks/perk_shield_expert"));
// // this.getContainer().addByStack(::new("scripts/skills/perks/perk_reach_advantage"));
// // this.getContainer().addByStack(::new("scripts/skills/perks/perk_duelist"));
// local equippedItem = this.getContainer().getActor().getMainhandItem();
// if (equippedItem != null)
// {
// this.getContainer().getActor().getItems().unequip(equippedItem);
// this.getContainer().getActor().getItems().equip(equippedItem);
// }
// }

// o.onRemoved <- function()
// {
// // local equippedItem = this.getContainer().getActor().getMainhandItem();
// // if (equippedItem != null)
// // {
// // this.getContainer().getActor().getItems().unequip(equippedItem);
// // this.getContainer().getActor().getItems().equip(equippedItem);
// // }
// }
// });
24 changes: 22 additions & 2 deletions scripts/!mods_preload/mod_stack_based_skills.nut
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
Name = "Stack Based Skills",
};

::mods_registerMod(::StackBasedSkills.ID, ::StackBasedSkills.Version, ::StackBasedSkills.Name);
::mods_queue(::StackBasedSkills.ID, "mod_msu(>=1.2.0.rc.2)", function() {
::StackBasedSkills.HooksMod <- ::Hooks.register(::StackBasedSkills.ID, ::StackBasedSkills.Version, ::StackBasedSkills.Name);
::StackBasedSkills.HooksMod.require("mod_msu"); // TODO: Can't put a version requirement right now due to a bug in Modern Hooks
::StackBasedSkills.HooksMod.queue(">mod_msu", function() {

::StackBasedSkills.Mod <- ::MSU.Class.Mod(::StackBasedSkills.ID, ::StackBasedSkills.Version, ::StackBasedSkills.Name);
::StackBasedSkills.Mod.Registry.addModSource(::MSU.System.Registry.ModSourceDomain.GitHub, "https://github.com/Battle-Modders/stack-based-skills");
Expand All @@ -22,3 +23,22 @@

::include("mod_stack_based_skills/mod_stack_based_skills_v4.nut");
});

::StackBasedSkills.HooksMod.queue(">mod_msu", function() {
foreach (script in ::IO.enumerateFiles("scripts/skills"))
{
if (script == "scripts/skills/skill_container" || script == "scripts/skills/skill") continue;

try
{
// Store the default value of every skill's IsSerialized
// This is used in the `removeSelf` function to pass the default value for this skill
local skill = ::new(script);
::MSU.Skills.ClassNameHashToIsSerializedMap[skill.ClassNameHash] <- skill.isSerialized();
}
catch (error)
{
::logError("Could not instaniate or get ClassNameHash or isSerialized() of skill: " + script + ". Error: " + error);
}
}
}, ::Hooks.QueueBucket.FirstWorldInit);

0 comments on commit 2b74c76

Please sign in to comment.