nike / Kamihime Project R - Better battle status icons

// ==UserScript==
// @name         Kamihime Project R - Better battle status icons
// @description  Replaces some default battle status icons like Fire ATK↑ and Fire RST↑ with unique images so there is no confusion
// @updateURL    https://openuserjs.org/meta/nike/Kamihime_Project_R_-_Better_battle_status_icons.meta.js
// @license      MIT
// @match        https://gnkh-api-r.prod.nkh.dmmgames.com/front/cocos2d-proj/components-pc/game/app.html
// @run-at       document-start
// ==/UserScript==
(function() {

    var interval = setInterval(function() {

        var resourceIdDefined = false
        try {
            ResourceId;
            resourceIdDefined = true
        } catch (ex) {
            resourceIdDefined = false
        }

        if (typeof kh !== 'undefined' && resourceIdDefined && kh.StatusEffectIcon && kh.BattleCommand && kh.BattleCommand.EventLogic && kh.EventSettings && kh.createInstance("playerGameConfig")?._config) {
            clearInterval(interval);

            ResourceId.makeFromPath = function(path) {
                if (path.startsWith(kh.env.scenarioRootBase)) {
                    return new ResourceId('scenario-' + path.substring(kh.env.imgRootBase.length + 1).replace(pathExp, '-'), 'scenario', path);
                }
                if (path.startsWith('https://i.imgur.com')) {
                    return new ResourceId('imgur-' + path.substring("https://i.imgur.com".length + 1).split(".")[0], 'imgur', path);
                }
                if (path.startsWith('http')) {
                    return new ResourceId('upload-' + path.substring(kh.env.imgRootBase.length + 1).replace(pathExp, '-'), 'upload', path);
                }
                if (path.startsWith('res/')) {
                    let component = kh.createInstance('router').getCurrentComponent() || this.getComponentName();
                    let name = path.substring(4).replace(pathExp, '-');
                    return new ResourceId(component + '-' + name, component, "../" + component + "/" + path);
                }
                let resolvedPath = khutil.resolvePath(path);
                let resPosition = resolvedPath.lastIndexOf('/res/');
                let component = resolvedPath.substring(resolvedPath.lastIndexOf('/', resPosition - 1) + 1, resPosition);
                let name = khutil.resolvePath(resolvedPath.substring(resPosition + 5)).replace(pathExp, '-');
                return new ResourceId(component + '-' + name, component, resolvedPath);
            }

            kh.newStatusIcons = new Map();
            (function initNewIcons() {
                kh.newStatusIcons.set(176, {
                    newIcon: "https://i.imgur.com/J6OZSIX.png"
                }) // vigor
                kh.newStatusIcons.set(84, {
                    newIcon: "https://i.imgur.com/p5xZHu0.png"
                }) // counterattack

                kh.newStatusIcons.set(101, {
                    newIcon: "https://i.imgur.com/5E42kjW.png"
                })
                kh.newStatusIcons.set(102, {
                    newIcon: "https://i.imgur.com/1rlP2WN.png"
                })
                kh.newStatusIcons.set(103, {
                    newIcon: "https://i.imgur.com/q2wVIyF.png"
                })
                kh.newStatusIcons.set(104, {
                    newIcon: "https://i.imgur.com/o76J1YJ.png"
                })
                kh.newStatusIcons.set(105, {
                    newIcon: "https://i.imgur.com/dS2vJ1Q.png"
                })
                kh.newStatusIcons.set(106, {
                    newIcon: "https://i.imgur.com/f0L3JPB.png"
                })

                kh.newStatusIcons.set(40009, {
                    newIcon: "https://i.imgur.com/5E42kjW.png"
                })
                kh.newStatusIcons.set(40010, {
                    newIcon: "https://i.imgur.com/1rlP2WN.png"
                })
                kh.newStatusIcons.set(40011, {
                    newIcon: "https://i.imgur.com/q2wVIyF.png"
                })
                kh.newStatusIcons.set(40012, {
                    newIcon: "https://i.imgur.com/o76J1YJ.png"
                })
                kh.newStatusIcons.set(40013, {
                    newIcon: "https://i.imgur.com/dS2vJ1Q.png"
                })
                kh.newStatusIcons.set(40014, {
                    newIcon: "https://i.imgur.com/f0L3JPB.png"
                })

                kh.newStatusIcons.set(107, {
                    newIcon: "https://i.imgur.com/dlvh0k3.png"
                })
                kh.newStatusIcons.set(108, {
                    newIcon: "https://i.imgur.com/lCDI7Hy.png"
                })
                kh.newStatusIcons.set(109, {
                    newIcon: "https://i.imgur.com/2djnNur.png"
                })
                kh.newStatusIcons.set(110, {
                    newIcon: "https://i.imgur.com/xMjIQiK.png"
                })
                kh.newStatusIcons.set(111, {
                    newIcon: "https://i.imgur.com/nVApvyz.png"
                })
                kh.newStatusIcons.set(112, {
                    newIcon: "https://i.imgur.com/Qd3ep64.png"
                })
                kh.newStatusIcons.set(476, {
                    newIcon: "https://i.imgur.com/CKQlb9g.png"
                }) // phantom atk down

                kh.newStatusIcons.set(546, {
                    newIcon: "https://i.imgur.com/dlvh0k3.png"
                })

                kh.newStatusIcons.set(40021, {
                    newIcon: "https://i.imgur.com/dlvh0k3.png"
                })
                kh.newStatusIcons.set(40022, {
                    newIcon: "https://i.imgur.com/lCDI7Hy.png"
                })
                kh.newStatusIcons.set(40023, {
                    newIcon: "https://i.imgur.com/2djnNur.png"
                })
                kh.newStatusIcons.set(40024, {
                    newIcon: "https://i.imgur.com/xMjIQiK.png"
                })
                kh.newStatusIcons.set(40025, {
                    newIcon: "https://i.imgur.com/nVApvyz.png"
                })
                kh.newStatusIcons.set(40026, {
                    newIcon: "https://i.imgur.com/Qd3ep64.png"
                })

                kh.newStatusIcons.set(113, {
                    newIcon: "https://i.imgur.com/3oLyyye.png"
                })
                kh.newStatusIcons.set(114, {
                    newIcon: "https://i.imgur.com/QNAfrkH.png"
                })
                kh.newStatusIcons.set(115, {
                    newIcon: "https://i.imgur.com/5oI0K0h.png"
                })
                kh.newStatusIcons.set(116, {
                    newIcon: "https://i.imgur.com/HO56ILX.png"
                })
                kh.newStatusIcons.set(117, {
                    newIcon: "https://i.imgur.com/07GLdiK.png"
                })
                kh.newStatusIcons.set(118, {
                    newIcon: "https://i.imgur.com/MGfX2OE.png"
                })
                kh.newStatusIcons.set(505, {
                    newIcon: "https://i.imgur.com/7sUwJht.png"
                })
                kh.newStatusIcons.set(40039, {
                    newIcon: "https://i.imgur.com/7sUwJht.png"
                })

                kh.newStatusIcons.set(40015, {
                    newIcon: "https://i.imgur.com/3oLyyye.png"
                })
                kh.newStatusIcons.set(40016, {
                    newIcon: "https://i.imgur.com/QNAfrkH.png"
                })
                kh.newStatusIcons.set(40017, {
                    newIcon: "https://i.imgur.com/5oI0K0h.png"
                })
                kh.newStatusIcons.set(40018, {
                    newIcon: "https://i.imgur.com/HO56ILX.png"
                })
                kh.newStatusIcons.set(40019, {
                    newIcon: "https://i.imgur.com/07GLdiK.png"
                })
                kh.newStatusIcons.set(40020, {
                    newIcon: "https://i.imgur.com/MGfX2OE.png"
                })

                kh.newStatusIcons.set(119, {
                    newIcon: "https://i.imgur.com/RhaYt23.png"
                })
                kh.newStatusIcons.set(120, {
                    newIcon: "https://i.imgur.com/Ijh2sOQ.png"
                })
                kh.newStatusIcons.set(121, {
                    newIcon: "https://i.imgur.com/nagFTqj.png",
                })
                kh.newStatusIcons.set(122, {
                    newIcon: "https://i.imgur.com/DPCSsXD.png"
                })
                kh.newStatusIcons.set(123, {
                    newIcon: "https://i.imgur.com/26Ddje4.png"
                })
                kh.newStatusIcons.set(124, {
                    newIcon: "https://i.imgur.com/BbCfeZG.png"
                })
                kh.newStatusIcons.set(477, {
                    newIcon: "https://i.imgur.com/8CWlQ8c.png"
                }) // phantom rst down

                kh.newStatusIcons.set(608, {
                    newIcon: "https://i.imgur.com/Ijh2sOQ.png"
                })

                // cut
                kh.newStatusIcons.set(1019, {
                    newIcon: "https://i.imgur.com/IeESMit.png"
                })
                kh.newStatusIcons.set(37, {
                    newIcon: "https://i.imgur.com/IeESMit.png"
                })
                kh.newStatusIcons.set(38, {
                    newIcon: "https://i.imgur.com/IeESMit.png"
                })

                // GDA
                kh.newStatusIcons.set(27, {
                    newIcon: "https://i.imgur.com/djXh0tJ.png",
                    animation: "colorRotate"
                })
                // GTA
                kh.newStatusIcons.set(28, {
                    newIcon: "https://i.imgur.com/kv8ZeLI.png",
                    animation: "colorRotate"
                })

                // Reflect
                kh.newStatusIcons.set(41, {
                    newIcon: "https://i.imgur.com/JeSRTfj.png"
                })

                // Mali successful condition
                kh.newStatusIcons.set(1723, {
                    newIcon: "https://i.imgur.com/3kb8iJu.png"
                })

                // Energy drain
                kh.newStatusIcons.set(75, {
                    newIcon: "https://i.imgur.com/P1YGd7I.png"
                })

                // Normal attack heal allies
                kh.newStatusIcons.set(357, {
                    newIcon: "https://i.imgur.com/P1YGd7I.png"
                })

                // Wound
                kh.newStatusIcons.set(463, {
                    newIcon: "https://i.imgur.com/w71c9wq.png"
                })

                // DMG Dealt up (Byakko)
                kh.newStatusIcons.set(377, {
                    animation: "colorRotate"
                })

                // Burst seal
                kh.newStatusIcons.set(64, {
                    newIcon: kh.Img("coreimg", "statusicon", _.padZero(201, 4)).png
                })

                // Ability seal
                kh.newStatusIcons.set(65, {
                    newIcon: kh.Img("coreimg", "statusicon", _.padZero(200, 4)).png
                })

                // MAX BURST DMG
                kh.newStatusIcons.set(152, {
                    newIcon: "https://i.imgur.com/VCsYBh3.png"
                })
                kh.newStatusIcons.set(165, {
                    newIcon: "https://i.imgur.com/VCsYBh3.png"
                })
                kh.newStatusIcons.set(521, {
                    newIcon: "https://i.imgur.com/VCsYBh3.png"
                })
                kh.newStatusIcons.set(40036, {
                    newIcon: "https://i.imgur.com/VCsYBh3.png"
                })

                // MAX ABI DMG
                kh.newStatusIcons.set(188, {
                    newIcon: "https://i.imgur.com/yFBkJjt.png"
                })
                kh.newStatusIcons.set(194, {
                    newIcon: "https://i.imgur.com/yFBkJjt.png"
                })
                kh.newStatusIcons.set(327, {
                    newIcon: "https://i.imgur.com/yFBkJjt.png"
                })
                kh.newStatusIcons.set(1313, {
                    newIcon: "https://i.imgur.com/yFBkJjt.png"
                })
                kh.newStatusIcons.set(1051, {
                    newIcon: "https://i.imgur.com/yFBkJjt.png"
                })
                kh.newStatusIcons.set(40038, {
                    newIcon: "https://i.imgur.com/yFBkJjt.png"
                })

                // MAX NATK DMG
                kh.newStatusIcons.set(185, {
                    newIcon: "https://i.imgur.com/4XfLvfa.png"
                })
                kh.newStatusIcons.set(198, {
                    newIcon: "https://i.imgur.com/4XfLvfa.png"
                })
                kh.newStatusIcons.set(40037, {
                    newIcon: "https://i.imgur.com/4XfLvfa.png"
                })
                // Recovery cap up
                kh.newStatusIcons.set(32, {
                    newIcon: "https://i.imgur.com/R9nRv2Z.png"
                })

                // Zeal
                kh.newStatusIcons.set(90, {
                    newIcon: "https://i.imgur.com/cHTZgr2.png"
                })

                // BG gain per turn
                kh.newStatusIcons.set(239, {
                    newIcon: "https://i.imgur.com/FGWw4MI.png"
                })
                // Cheer (BG gain per turn separate status)
                kh.newStatusIcons.set(313, {
                    newIcon: "https://i.imgur.com/FGWw4MI.png"
                })

                // Special attack
                kh.newStatusIcons.set(276, {
                    newIcon: "https://i.imgur.com/zzOb9S2.png"
                })
                kh.newStatusIcons.set(276, {
                    newIcon: "https://i.imgur.com/zzOb9S2.png"
                })
                kh.newStatusIcons.set(254, {
                    newIcon: "https://i.imgur.com/zzOb9S2.png"
                })
                kh.newStatusIcons.set(40033, {
                    newIcon: "https://i.imgur.com/zzOb9S2.png"
                })

            })();

            let rotateAnimBuilder = function(increment) {
                return function(widget) {
                    let rotation = widget.rotation
                    let newRotation = rotation + increment
                    if (newRotation >= 360) {
                        newRotation = 0
                    }
                    widget.setRotation(newRotation)
                }
            }

            let colorAnimBuilder = function(colorTransform) {
                return function(widget) {
                    let color = widget.color
                    let newColor = colorTransform(color)
                    widget.setColor(newColor)
                }
            }

            let colorRotateBuilder = function(step, minimumValue) {
                return (color) => {
                    let r = color.r
                    let g = color.g
                    let b = color.b
                    let newR, newG, newB
                    if ((r > 128 || b > 128) && g >= 255) {
                        newR = r - step
                        newB = b - step
                        newG = g + step
                        if (newR < 128) {
                            newR = 128
                        }
                        if (newB < 128) {
                            newB = 128
                        }
                        if (newG > 255) {
                            newG = 255
                        }

                    } else if ((g > 128 && b <= 128) && r < 255) {
                        newR = r + step
                        newB = b - step
                        newG = g - step
                        if (newR > 255) {
                            newR = 255
                        }
                        if (newB < 128) {
                            newB = 128
                        }
                        if (newG < 128) {
                            newG = 128
                        }
                    } else if ((r > 128 && g <= 128) && b < 255) {
                        newR = r - step
                        newB = b + step
                        newG = g - step
                        if (newR <= 128) {
                            newR = 128
                        }
                        if (newB > 255) {
                            newB = 255
                        }
                        if (newG < 128) {
                            newG = 128
                        }
                    } else {
                        newR = r + step
                        newB = b + step
                        newG = g + step
                        if (newR > 255) {
                            newR = 255
                        }
                        if (newB > 255) {
                            newB = 255
                        }
                        if (newG > 255) {
                            newG = 255
                        }
                    }
                    return cc.color(newR, newG, newB)
                }
            }

            let yellowBlinkBuilder = function(step, minimumValue) {
                let func = function(color) {
                    let r = color.r
                    let g = color.g
                    let b = color.b
                    let newR, newG, newB
                    if (this.stage == 1) {
                        newB = b - step
                        if (newB < 128) {
                            newB = 128
                        }
                        if (newB <= 128) {
                            this.stage = 2
                        }
                    } else {
                        newB = b + step
                        if (newB >= 255) {
                            newB = 255
                        }
                        if (newB >= 255) {
                            this.stage = 1
                        }
                    }
                    return cc.color(newR, newG, newB)
                }
                func.stage = 1
                return func
            }

            kh.statusEffectAnimations = new Map()
            kh.statusEffectAnimations.set("rotate", {
                updateFunc: rotateAnimBuilder(4),
                interval: 0
            })

            kh.statusEffectAnimations.set("colorRotate", {
                updateFunc: colorAnimBuilder(colorRotateBuilder(16, 192)),
                interval: 0
            })

            kh.statusEffectAnimations.set("yellowBlink", {
                updateFunc: colorAnimBuilder(yellowBlinkBuilder(16, 192)),
                interval: 0
            })

            kh.StatusEffectIcon.prototype._drawTexture = function() {
                var iconInfo = kh.newStatusIcons.get(this._statusEffect._id)
                var animation = kh.statusEffectAnimations.get(iconInfo?.animation)

                let clearAnimation = () => {
                    this._widget.unschedule(this.animFunc)
                    this._widget.setRotation(0)
                    this._widget.setColor(cc.color(255, 255, 255))
                }

                clearAnimation()

                if (iconInfo?.newIcon) {
                    if (this._widget.loadTexture != null) {
                        this._widget.loadTexture(iconInfo.newIcon);
                    }
                    if (this._widget.loadTextureNormal != null) {
                        this._widget.loadTextureNormal(iconInfo.newIcon);
                    }
                    if (this._widget.loadTexturePressed != null) {
                        this._widget.loadTexturePressed(iconInfo.newIcon);
                    }
                } else {
                    if (this._widget.loadTexture != null) {
                        this._widget.loadTexture(this._texture.png || this._texture.jpg);
                    }
                    if (this._widget.loadTextureNormal != null) {
                        this._widget.loadTextureNormal(this._texture.png || this._texture.jpg);
                    }
                    if (this._widget.loadTexturePressed != null) {
                        this._widget.loadTexturePressed(this._texture.png || this._texture.jpg);
                    }

                }

                if (animation) {
                    this.animFunc = () => {
                        animation.updateFunc(this._widget)
                    }
                    this._widget.schedule(this.animFunc, animation.interval, cc.REPEAT_FOREVER)
                }

            };

             (function() {
                let e = kh
                let n = _
                let a = cc
                let i = console;

                kh.BattleCommand.EventLogic.prototype.__registerStatusIcon = function(t) {
                    var e = n.flatten(this._getTargets().slice(0)),
                        a = this.battleCommand.statusEffectData,
                        r = n.pluck(a.affected_avatars.players || {}, "applied").concat(n.pluck(a.affected_avatars.enemies || {}, "applied")),
                        s = function() {
                            if (0 === e.length)
                                return void i.warn("KHBattleCommandEventLogic.__registerStatusIcon: target not found");
                            var t = e.shift(),
                                n = r.shift(),
                                s = a.type;
                            n && null == s || t.playReceiveStatusEffectAnimation(a, n)
                        }
                        .bind(this.battleCommand);
                    n.invoke(this._getVisualEffects(), "addAnimationEventCallback", t, s)
                }
            })();

            (function() {
                let e, n = cc,
                    a = kh,
                    i = "applied",
                    c = "miss",
                    E = "guard",
                    s = "cancel",
                    o = "max_count",
                    r = (e = {},
                        e[c] = "m",
                        e[s] = "c",
                        e[E] = "g",
                        e[o] = "x",
                        e);
                a.EventSettings.statusEffect = function(t, e, c) {
                    if (c instanceof a.BattleWorld) {
                        t.addEventListener("show_status_effect", function(t, e, o) {
                            var r = o === i ? s(e) : E(o),
                                T = a.STATUS_EFFECT_ICON_RANDOM_POS_RECT.SIZE,
                                _ = a.STATUS_EFFECT_ICON_RANDOM_POS_RECT.ANCHOR,
                                d = n.rect(t.x - _.x * T.width, t.y - _.y * T.height, T.width, T.height);
                            r.setPosition(a.createInstance("PositionGenerator").generateRandomPositionInRect(d)),
                                c.UIBackLayer.addChild(r)
                        });
                        var E = function(t) {
                                var e = a.createInstance("DisposableAnimationNode", [a.NUMBER_ACTION_STRATEGY.MISS]),
                                    n = a.NUMBER_FONT_BY_ELEMENT_TYPE[a.ELEMENT_TYPE.NONELEMENTAL],
                                    i = r[t];
                                return e.addChild(a.createInstance("LabelBMFont", [i, n])),
                                    e
                            },
                            s = function(t) {
                                var iconInfo = kh.newStatusIcons.get(t.id)
                                var resultUrl
                                if (iconInfo?.newIcon) {
                                    resultUrl = iconInfo.newIcon
                                } else {
                                    resultUrl = kh.Img("coreimg", "statusicon", _.padZero(t.type, 4)).png
                                }
                                var e = a.createInstance("DisposableAnimationNode", [a.NUMBER_ACTION_STRATEGY.STATUS_EFFECT]),
                                    n = resultUrl;
                                return e.addChild(new ccui.ImageView(resultUrl)),
                                    e
                            }
                    }
                }
            })();

        }
    }, 10);

})();