From afa08d61312ede8144681d9d3a9c3ce6234a14e5 Mon Sep 17 00:00:00 2001 From: alexpolo1 Date: Tue, 11 Apr 2023 23:53:21 +0200 Subject: [PATCH] nbnb bnnb --- data/Actors.json | 23 +- data/MapInfos.json | 2 +- data/System.json | 2 +- js/plugins.js | 6 +- js/plugins/FELSKI_TECHTREE.js | 4722 +++++++++++++++++++++++++++ js/plugins/YEP_ClassChangeCore.js | 1479 +++++++++ js/plugins/YEP_CoreEngine.js | 404 +-- js/plugins/YEP_Extra_Enemy_Drops.js | 77 - js/plugins/YEP_JobPoints.js | 9 +- js/plugins/YEP_LoadCustomFonts.js | 109 + js/plugins/YEP_X_Subclass.js | 1133 +++++++ 11 files changed, 7502 insertions(+), 464 deletions(-) create mode 100644 js/plugins/FELSKI_TECHTREE.js create mode 100644 js/plugins/YEP_ClassChangeCore.js delete mode 100644 js/plugins/YEP_Extra_Enemy_Drops.js create mode 100644 js/plugins/YEP_LoadCustomFonts.js create mode 100644 js/plugins/YEP_X_Subclass.js diff --git a/data/Actors.json b/data/Actors.json index 9d34bc6..ddbc6ff 100644 --- a/data/Actors.json +++ b/data/Actors.json @@ -1,18 +1,11 @@ [ null, -{"id":1,"battlerName":"Actor1_7","characterIndex":6,"characterName":"Actor1","classId":1,"equips":[1,1,2,3,0],"faceIndex":6,"faceName":"Actor1","traits":[],"initialLevel":1,"maxLevel":99,"name":"Harold","nickname":"","note":"","profile":""}, -{"id":2,"battlerName":"Actor1_8","characterIndex":7,"characterName":"Actor1","classId":2,"equips":[2,1,2,3,0],"faceIndex":7,"faceName":"Actor1","traits":[],"initialLevel":1,"maxLevel":99,"name":"Therese","nickname":"","note":"","profile":""}, -{"id":3,"battlerName":"Actor3_8","characterIndex":7,"characterName":"Actor3","classId":3,"equips":[3,0,2,3,4],"faceIndex":7,"faceName":"Actor3","traits":[],"initialLevel":1,"maxLevel":99,"name":"Marsha","nickname":"","note":"","profile":""}, -{"id":4,"battlerName":"Actor2_7","characterIndex":6,"characterName":"Actor2","classId":4,"equips":[4,0,2,3,4],"faceIndex":6,"faceName":"Actor2","traits":[],"initialLevel":1,"maxLevel":99,"name":"Lucius","nickname":"","note":"","profile":""}, -{"id":5,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":6,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":7,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":8,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":9,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":10,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":11,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":12,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":13,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":14,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""}, -{"id":15,"battlerName":"","characterIndex":0,"characterName":"","classId":1,"equips":[0,0,0,0,0],"faceIndex":0,"faceName":"","traits":[],"initialLevel":1,"maxLevel":99,"name":"","nickname":"","note":"","profile":""} +{"id":1,"battlerName":"Actor1_1","characterIndex":0,"characterName":"3_Actor1","classId":1,"equips":[1,0,46,3,0],"faceIndex":0,"faceName":"Harold-Emotes","traits":[],"initialLevel":1,"maxLevel":99,"name":"Harold","nickname":"","note":"\n\nKanna1\n","profile":""}, +{"id":2,"battlerName":"Actor1_8","characterIndex":7,"characterName":"Actor1","classId":4,"equips":[25,27,0,9,0],"faceIndex":7,"faceName":"Actor1","traits":[],"initialLevel":1,"maxLevel":99,"name":"Therese","nickname":"","note":"","profile":""}, +{"id":3,"battlerName":"Actor3_8","characterIndex":7,"characterName":"Actor3","classId":9,"equips":[0,0,65,20,0],"faceIndex":7,"faceName":"Actor3","traits":[],"initialLevel":1,"maxLevel":99,"name":"Marsha","nickname":"","note":"\n\nHEALER\n","profile":""}, +{"id":4,"battlerName":"Actor2_7","characterIndex":6,"characterName":"Actor2","classId":3,"equips":[13,0,0,20,100],"faceIndex":6,"faceName":"Actor2","traits":[],"initialLevel":1,"maxLevel":99,"name":"Lucius","nickname":"","note":"\n\nHEALER\nHOLY\n","profile":""}, +{"id":5,"battlerName":"Actor1_5","characterIndex":4,"characterName":"Actor1","classId":7,"equips":[37,0,0,8,0],"faceIndex":4,"faceName":"Actor1","traits":[],"initialLevel":1,"maxLevel":99,"name":"Fred","nickname":"","note":"","profile":""}, +{"id":6,"battlerName":"Actor2_2","characterIndex":1,"characterName":"Actor2","classId":6,"equips":[1,0,0,20,0],"faceIndex":1,"faceName":"Actor2","traits":[],"initialLevel":1,"maxLevel":99,"name":"Ilia","nickname":"","note":"","profile":""}, +{"id":7,"battlerName":"Actor1_3","characterIndex":2,"characterName":"Actor1","classId":5,"equips":[31,0,0,3,0],"faceIndex":2,"faceName":"Actor1","traits":[],"initialLevel":1,"maxLevel":99,"name":"Vice","nickname":"","note":"","profile":""}, +{"id":8,"battlerName":"Actor1_6","characterIndex":5,"characterName":"Actor1","classId":8,"equips":[43,43,0,3,0],"faceIndex":5,"faceName":"Actor1","traits":[],"initialLevel":1,"maxLevel":99,"name":"Eliza","nickname":"","note":"","profile":""} ] \ No newline at end of file diff --git a/data/MapInfos.json b/data/MapInfos.json index 62806c5..820dad4 100644 --- a/data/MapInfos.json +++ b/data/MapInfos.json @@ -1,7 +1,7 @@ [ null, {"id":1,"expanded":false,"name":"Dungeon3","order":5,"parentId":3,"scrollX":3393,"scrollY":3405}, -{"id":2,"expanded":true,"name":"Dungeon1","order":3,"parentId":4,"scrollX":2660,"scrollY":3676}, +{"id":2,"expanded":true,"name":"Dungeon1","order":3,"parentId":4,"scrollX":2628,"scrollY":3644}, {"id":3,"expanded":true,"name":"Dungeon2","order":4,"parentId":2,"scrollX":3393,"scrollY":3405}, {"id":4,"expanded":true,"name":"House","order":2,"parentId":5,"scrollX":1518.6666666666667,"scrollY":854.6666666666666}, {"id":5,"expanded":true,"name":"Intro","order":1,"parentId":0,"scrollX":1139,"scrollY":641} diff --git a/data/System.json b/data/System.json index 81b5f4a..aceb7db 100644 --- a/data/System.json +++ b/data/System.json @@ -1 +1 @@ -{"airship":{"bgm":{"name":"Ship3","pan":0,"pitch":100,"volume":90},"characterIndex":3,"characterName":"Vehicle","startMapId":0,"startX":0,"startY":0},"armorTypes":["","General Armor","Magic Armor","Light Armor","Heavy Armor","Small Shield","Large Shield"],"attackMotions":[{"type":0,"weaponImageId":0},{"type":1,"weaponImageId":1},{"type":1,"weaponImageId":2},{"type":1,"weaponImageId":3},{"type":1,"weaponImageId":4},{"type":1,"weaponImageId":5},{"type":1,"weaponImageId":6},{"type":2,"weaponImageId":7},{"type":2,"weaponImageId":8},{"type":2,"weaponImageId":9},{"type":0,"weaponImageId":10},{"type":0,"weaponImageId":11},{"type":0,"weaponImageId":12}],"battleBgm":{"name":"Battle1","pan":0,"pitch":100,"volume":90},"battleback1Name":"Grassland","battleback2Name":"Grassland","battlerHue":0,"battlerName":"Dragon","boat":{"bgm":{"name":"Ship1","pan":0,"pitch":100,"volume":90},"characterIndex":0,"characterName":"Vehicle","startMapId":0,"startX":0,"startY":0},"currencyUnit":"G","defeatMe":{"name":"Defeat1","pan":0,"pitch":100,"volume":90},"editMapId":2,"elements":["","Physical","Fire","Ice","Thunder","Water","Earth","Wind","Light","Darkness"],"equipTypes":["","Weapon","Shield","Head","Body","Accessory"],"gameTitle":"Blades and Shadows: A Dungeon Adventure","gameoverMe":{"name":"Gameover1","pan":0,"pitch":100,"volume":90},"locale":"en_US","magicSkills":[1],"menuCommands":[true,true,true,true,false,true],"optDisplayTp":true,"optDrawTitle":true,"optExtraExp":false,"optFloorDeath":false,"optFollowers":true,"optSideView":true,"optSlipDeath":false,"optTransparent":false,"partyMembers":[1],"ship":{"bgm":{"name":"Ship2","pan":0,"pitch":100,"volume":90},"characterIndex":1,"characterName":"Vehicle","startMapId":0,"startX":0,"startY":0},"skillTypes":["","Magic","Special"],"sounds":[{"name":"Cursor2","pan":0,"pitch":100,"volume":90},{"name":"Decision1","pan":0,"pitch":100,"volume":90},{"name":"Cancel2","pan":0,"pitch":100,"volume":90},{"name":"Buzzer1","pan":0,"pitch":100,"volume":90},{"name":"Equip1","pan":0,"pitch":100,"volume":90},{"name":"Save","pan":0,"pitch":100,"volume":90},{"name":"Load","pan":0,"pitch":100,"volume":90},{"name":"Battle1","pan":0,"pitch":100,"volume":90},{"name":"Run","pan":0,"pitch":100,"volume":90},{"name":"Attack3","pan":0,"pitch":100,"volume":90},{"name":"Damage4","pan":0,"pitch":100,"volume":90},{"name":"Collapse1","pan":0,"pitch":100,"volume":90},{"name":"Collapse2","pan":0,"pitch":100,"volume":90},{"name":"Collapse3","pan":0,"pitch":100,"volume":90},{"name":"Damage5","pan":0,"pitch":100,"volume":90},{"name":"Collapse4","pan":0,"pitch":100,"volume":90},{"name":"Recovery","pan":0,"pitch":100,"volume":90},{"name":"Miss","pan":0,"pitch":100,"volume":90},{"name":"Evasion1","pan":0,"pitch":100,"volume":90},{"name":"Evasion2","pan":0,"pitch":100,"volume":90},{"name":"Reflection","pan":0,"pitch":100,"volume":90},{"name":"Shop1","pan":0,"pitch":100,"volume":90},{"name":"Item3","pan":0,"pitch":100,"volume":90},{"name":"Item3","pan":0,"pitch":100,"volume":90}],"startMapId":5,"startX":1,"startY":0,"switches":["","","","","","","","","","","","","","","","","","","","",""],"terms":{"basic":["Level","Lv","HP","HP","MP","MP","TP","TP","EXP","EXP"],"commands":["Fight","Escape","Attack","Guard","Item","Skill","Equip","Status","Formation","Save","Game End","Options","Weapon","Armor","Key Item","Equip","Optimize","Clear","New Game","Continue",null,"To Title","Cancel",null,"Buy","Sell"],"params":["Max HP","Max MP","Attack","Defense","M.Attack","M.Defense","Agility","Luck","Hit","Evasion"],"messages":{"actionFailure":"There was no effect on %1!","actorDamage":"%1 took %2 damage!","actorDrain":"%1 was drained of %2 %3!","actorGain":"%1 gained %2 %3!","actorLoss":"%1 lost %2 %3!","actorNoDamage":"%1 took no damage!","actorNoHit":"Miss! %1 took no damage!","actorRecovery":"%1 recovered %2 %3!","alwaysDash":"Always Dash","bgmVolume":"BGM Volume","bgsVolume":"BGS Volume","buffAdd":"%1's %2 went up!","buffRemove":"%1's %2 returned to normal!","commandRemember":"Command Remember","counterAttack":"%1 counterattacked!","criticalToActor":"A painful blow!!","criticalToEnemy":"An excellent hit!!","debuffAdd":"%1's %2 went down!","defeat":"%1 was defeated.","emerge":"%1 emerged!","enemyDamage":"%1 took %2 damage!","enemyDrain":"%1 was drained of %2 %3!","enemyGain":"%1 gained %2 %3!","enemyLoss":"%1 lost %2 %3!","enemyNoDamage":"%1 took no damage!","enemyNoHit":"Miss! %1 took no damage!","enemyRecovery":"%1 recovered %2 %3!","escapeFailure":"However, it was unable to escape!","escapeStart":"%1 has started to escape!","evasion":"%1 evaded the attack!","expNext":"To Next %1","expTotal":"Current %1","file":"File","levelUp":"%1 is now %2 %3!","loadMessage":"Load which file?","magicEvasion":"%1 nullified the magic!","magicReflection":"%1 reflected the magic!","meVolume":"ME Volume","obtainExp":"%1 %2 received!","obtainGold":"%1\\G found!","obtainItem":"%1 found!","obtainSkill":"%1 learned!","partyName":"%1's Party","possession":"Possession","preemptive":"%1 got the upper hand!","saveMessage":"Save to which file?","seVolume":"SE Volume","substitute":"%1 protected %2!","surprise":"%1 was surprised!","useItem":"%1 uses %2!","victory":"%1 was victorious!"}},"testBattlers":[{"actorId":1,"equips":[1,1,2,3,0],"level":1},{"actorId":2,"equips":[2,1,2,3,0],"level":1},{"actorId":3,"equips":[3,0,2,3,4],"level":1},{"actorId":4,"equips":[4,0,2,3,4],"level":1}],"testTroopId":4,"title1Name":"Gates","title2Name":"","titleBgm":{"name":"Theme6","pan":0,"pitch":100,"volume":90},"variables":["","","","","","","","","","","","","","","","","","","","",""],"versionId":83605456,"victoryMe":{"name":"Victory1","pan":0,"pitch":100,"volume":90},"weaponTypes":["","Dagger","Sword","Flail","Axe","Whip","Cane","Bow","Crossbow","Gun","Claw","Glove","Spear"],"windowTone":[-255,-255,187,0]} \ No newline at end of file +{"airship":{"bgm":{"name":"Ship3","pan":0,"pitch":100,"volume":90},"characterIndex":3,"characterName":"Vehicle","startMapId":0,"startX":0,"startY":0},"armorTypes":["","General Armor","Magic Armor","Light Armor","Heavy Armor","Small Shield","Large Shield"],"attackMotions":[{"type":0,"weaponImageId":0},{"type":1,"weaponImageId":1},{"type":1,"weaponImageId":2},{"type":1,"weaponImageId":3},{"type":1,"weaponImageId":4},{"type":1,"weaponImageId":5},{"type":1,"weaponImageId":6},{"type":2,"weaponImageId":7},{"type":2,"weaponImageId":8},{"type":2,"weaponImageId":9},{"type":0,"weaponImageId":10},{"type":0,"weaponImageId":11},{"type":0,"weaponImageId":12}],"battleBgm":{"name":"Battle1","pan":0,"pitch":100,"volume":90},"battleback1Name":"Grassland","battleback2Name":"Grassland","battlerHue":0,"battlerName":"Dragon","boat":{"bgm":{"name":"Ship1","pan":0,"pitch":100,"volume":90},"characterIndex":0,"characterName":"Vehicle","startMapId":0,"startX":0,"startY":0},"currencyUnit":"G","defeatMe":{"name":"Defeat1","pan":0,"pitch":100,"volume":90},"editMapId":2,"elements":["","Physical","Fire","Ice","Thunder","Water","Earth","Wind","Light","Darkness"],"equipTypes":["","Weapon","Shield","Head","Body","Accessory"],"gameTitle":"Blades and Shadows: A Dungeon Adventure","gameoverMe":{"name":"Gameover1","pan":0,"pitch":100,"volume":90},"locale":"en_US","magicSkills":[1],"menuCommands":[true,true,true,true,false,true],"optDisplayTp":true,"optDrawTitle":true,"optExtraExp":false,"optFloorDeath":false,"optFollowers":true,"optSideView":true,"optSlipDeath":false,"optTransparent":false,"partyMembers":[1],"ship":{"bgm":{"name":"Ship2","pan":0,"pitch":100,"volume":90},"characterIndex":1,"characterName":"Vehicle","startMapId":0,"startX":0,"startY":0},"skillTypes":["","Magic","Special"],"sounds":[{"name":"Cursor2","pan":0,"pitch":100,"volume":90},{"name":"Decision1","pan":0,"pitch":100,"volume":90},{"name":"Cancel2","pan":0,"pitch":100,"volume":90},{"name":"Buzzer1","pan":0,"pitch":100,"volume":90},{"name":"Equip1","pan":0,"pitch":100,"volume":90},{"name":"Save","pan":0,"pitch":100,"volume":90},{"name":"Load","pan":0,"pitch":100,"volume":90},{"name":"Battle1","pan":0,"pitch":100,"volume":90},{"name":"Run","pan":0,"pitch":100,"volume":90},{"name":"Attack3","pan":0,"pitch":100,"volume":90},{"name":"Damage4","pan":0,"pitch":100,"volume":90},{"name":"Collapse1","pan":0,"pitch":100,"volume":90},{"name":"Collapse2","pan":0,"pitch":100,"volume":90},{"name":"Collapse3","pan":0,"pitch":100,"volume":90},{"name":"Damage5","pan":0,"pitch":100,"volume":90},{"name":"Collapse4","pan":0,"pitch":100,"volume":90},{"name":"Recovery","pan":0,"pitch":100,"volume":90},{"name":"Miss","pan":0,"pitch":100,"volume":90},{"name":"Evasion1","pan":0,"pitch":100,"volume":90},{"name":"Evasion2","pan":0,"pitch":100,"volume":90},{"name":"Reflection","pan":0,"pitch":100,"volume":90},{"name":"Shop1","pan":0,"pitch":100,"volume":90},{"name":"Item3","pan":0,"pitch":100,"volume":90},{"name":"Item3","pan":0,"pitch":100,"volume":90}],"startMapId":5,"startX":1,"startY":0,"switches":["","","","","","","","","","","","","","","","","","","","",""],"terms":{"basic":["Level","Lv","HP","HP","MP","MP","TP","TP","EXP","EXP"],"commands":["Fight","Escape","Attack","Guard","Item","Skill","Equip","Status","Formation","Save","Game End","Options","Weapon","Armor","Key Item","Equip","Optimize","Clear","New Game","Continue",null,"To Title","Cancel",null,"Buy","Sell"],"params":["Max HP","Max MP","Attack","Defense","M.Attack","M.Defense","Agility","Luck","Hit","Evasion"],"messages":{"actionFailure":"There was no effect on %1!","actorDamage":"%1 took %2 damage!","actorDrain":"%1 was drained of %2 %3!","actorGain":"%1 gained %2 %3!","actorLoss":"%1 lost %2 %3!","actorNoDamage":"%1 took no damage!","actorNoHit":"Miss! %1 took no damage!","actorRecovery":"%1 recovered %2 %3!","alwaysDash":"Always Dash","bgmVolume":"BGM Volume","bgsVolume":"BGS Volume","buffAdd":"%1's %2 went up!","buffRemove":"%1's %2 returned to normal!","commandRemember":"Command Remember","counterAttack":"%1 counterattacked!","criticalToActor":"A painful blow!!","criticalToEnemy":"An excellent hit!!","debuffAdd":"%1's %2 went down!","defeat":"%1 was defeated.","emerge":"%1 emerged!","enemyDamage":"%1 took %2 damage!","enemyDrain":"%1 was drained of %2 %3!","enemyGain":"%1 gained %2 %3!","enemyLoss":"%1 lost %2 %3!","enemyNoDamage":"%1 took no damage!","enemyNoHit":"Miss! %1 took no damage!","enemyRecovery":"%1 recovered %2 %3!","escapeFailure":"However, it was unable to escape!","escapeStart":"%1 has started to escape!","evasion":"%1 evaded the attack!","expNext":"To Next %1","expTotal":"Current %1","file":"File","levelUp":"%1 is now %2 %3!","loadMessage":"Load which file?","magicEvasion":"%1 nullified the magic!","magicReflection":"%1 reflected the magic!","meVolume":"ME Volume","obtainExp":"%1 %2 received!","obtainGold":"%1\\G found!","obtainItem":"%1 found!","obtainSkill":"%1 learned!","partyName":"%1's Party","possession":"Possession","preemptive":"%1 got the upper hand!","saveMessage":"Save to which file?","seVolume":"SE Volume","substitute":"%1 protected %2!","surprise":"%1 was surprised!","useItem":"%1 uses %2!","victory":"%1 was victorious!"}},"testBattlers":[{"actorId":1,"equips":[1,1,2,3,0],"level":1},{"actorId":2,"equips":[2,1,2,3,0],"level":1},{"actorId":3,"equips":[3,0,2,3,4],"level":1},{"actorId":4,"equips":[4,0,2,3,4],"level":1}],"testTroopId":4,"title1Name":"Gates","title2Name":"","titleBgm":{"name":"Theme6","pan":0,"pitch":100,"volume":90},"variables":["","","","","","","","","","","","","","","","","","","","",""],"versionId":71086764,"victoryMe":{"name":"Victory1","pan":0,"pitch":100,"volume":90},"weaponTypes":["","Dagger","Sword","Flail","Axe","Whip","Cane","Bow","Crossbow","Gun","Claw","Glove","Spear"],"windowTone":[-255,-255,187,0]} \ No newline at end of file diff --git a/js/plugins.js b/js/plugins.js index 5c6f11b..e991510 100644 --- a/js/plugins.js +++ b/js/plugins.js @@ -14,8 +14,8 @@ var $plugins = {"name":"WeaponSkill","status":true,"description":"Change skill id of attack for each weapon.","parameters":{}}, {"name":"--------------------","status":true,"description":"------------------------------------------------------------","parameters":{}}, {"name":"SRD_BattlePopupCustomizer","status":false,"description":"Adds more options to the Battle Popups; customization over the attributes of the popups and the ability to add more.","parameters":{"== Global Options ==":"","Font":"GameFont","Font Size":"34","X Shift":"0","Y Shift":"34","Global Condition":"target.isAppeared()","== HP Damage ==":"","HP Damage Condition":"result.hpDamage > 0","HP Damage Text":"-%1 HP","HP Damage Location":"0, 0","HP Damage Colors":"#FF4D4D | #000000","HP Damage Animations":"default","HP Damage Duration":"120","HP Damage Flash":"0, 0, 0, 0, 0","== HP Heal ==":"","HP Heal Condition":"result.hpDamage < 0","HP Heal Text":"+%1 HP","HP Heal Location":"0, 0","HP Heal Colors":"#8CFF66 | #000000","HP Heal Animations":"default","HP Heal Duration":"120","HP Heal Flash":"0, 0, 0, 0, 0","== MP Damage ==":"","MP Damage Condition":"result.mpDamage > 0","MP Damage Text":"-%1 MP","MP Damage Location":"0, 0","MP Damage Colors":"#66B3FF | #000000","MP Damage Animations":"default","MP Damage Duration":"120","MP Damage Flash":"0, 0, 0, 0, 0","== MP Heal ==":"","MP Heal Condition":"result.mpDamage < 0","MP Heal Text":"+%1 MP","MP Heal Location":"0, 0","MP Heal Colors":"#FFFF99 | #000000","MP Heal Animations":"default","MP Heal Duration":"120","MP Heal Flash":"0, 0, 0, 0, 0","== TP Damage ==":"","TP Damage Condition":"result.tpDamage > 0","TP Damage Text":"-%1 TP","TP Damage Location":"0, 0","TP Damage Colors":"#FFB3FF | #000000","TP Damage Animations":"default","TP Damage Duration":"120","TP Damage Flash":"0, 0, 0, 0, 0","== TP Heal ==":"","TP Heal Condition":"result.tpDamage < 0","TP Heal Text":"+%1 TP","TP Heal Location":"0, 0","TP Heal Colors":"#99FF66 | #000000","TP Heal Animations":"default","TP Heal Duration":"120","TP Heal Flash":"0, 0, 0, 0, 0","== Miss ==":"","Miss Condition":"result.used && result.missed","Miss Text":"MISS","Miss Location":"24, this._sprite.height * (-1/3)","Miss Colors":"#FFFFFF | #000000","Miss Animations":"float","Miss Duration":"45","Miss Flash":"0, 0, 0, 0, 0","== Evade ==":"","Evade Condition":"result.evaded","Evade Text":"EVADE","Evade Location":"24, this._sprite.height * (-1/3)","Evade Colors":"#FFFFFF | #000000","Evade Animations":"float","Evade Duration":"45","Evade Flash":"0, 0, 0, 0, 0","== Critical ==":"","Critical Condition":"result.critical && result.used && !result.missed","Critical Text":"CRITICAL","Critical Location":"24, this._sprite.height * (-1/3)","Critical Colors":"#FFFFFF | #000000","Critical Animations":"float","Critical Duration":"60","Critical Flash":"255, 0, 0, 160, 60","== Guarded ==":"","Guarded Condition":"result.guarded && result.used && !result.missed","Guarded Text":"GUARDED","Guarded Location":"24, this._sprite.height * (-1/3)","Guarded Colors":"#FFFFFF | #000000","Guarded Animations":"float","Guarded Duration":"60","Guarded Flash":"0, 130, 130, 160, 60","== Custom 1 ==":"","Custom 1 Condition":"result.drain && result.used && !result.missed","Custom 1 Text":"DRAINED","Custom 1 Location":"24, this._sprite.height * (-1/3)","Custom 1 Colors":"#FFFFFF | #000000","Custom 1 Animations":"float","Custom 1 Duration":"60","Custom 1 Flash":"204, 153, 255, 160, 60","== Custom 2 ==":"","Custom 2 Condition":"false","Custom 2 Text":"","Custom 2 Location":"24, -48","Custom 2 Colors":"#FFFFFF | #000000","Custom 2 Animations":"float","Custom 2 Duration":"60","Custom 2 Flash":"0, 0, 0, 0, 0","== Custom 3 ==":"","Custom 3 Condition":"false","Custom 3 Text":"","Custom 3 Location":"24, -48","Custom 3 Colors":"#FFFFFF | #000000","Custom 3 Animations":"float","Custom 3 Duration":"60","Custom 3 Flash":"0, 0, 0, 0, 0","== Custom 4 ==":"","Custom 4 Condition":"false","Custom 4 Text":"","Custom 4 Location":"24, -48","Custom 4 Colors":"#FFFFFF | #000000","Custom 4 Animations":"float","Custom 4 Duration":"60","Custom 4 Flash":"0, 0, 0, 0, 0","== Custom 5 ==":"","Custom 5 Condition":"false","Custom 5 Text":"","Custom 5 Location":"24, -48","Custom 5 Colors":"#FFFFFF | #000000","Custom 5 Animations":"float","Custom 5 Duration":"60","Custom 5 Flash":"0, 0, 0, 0, 0","== Custom 6 ==":"","Custom 6 Condition":"false","Custom 6 Text":"","Custom 6 Location":"24, -48","Custom 6 Colors":"#FFFFFF | #000000","Custom 6 Animations":"float","Custom 6 Duration":"60","Custom 6 Flash":"0, 0, 0, 0, 0","== Custom 7 ==":"","Custom 7 Condition":"false","Custom 7 Text":"","Custom 7 Location":"24, -48","Custom 7 Colors":"#FFFFFF | #000000","Custom 7 Animations":"float","Custom 7 Duration":"60","Custom 7 Flash":"0, 0, 0, 0, 0","== Custom 8 ==":"","Custom 8 Condition":"false","Custom 8 Text":"","Custom 8 Location":"24, -48","Custom 8 Colors":"#FFFFFF | #000000","Custom 8 Animations":"float","Custom 8 Duration":"60","Custom 8 Flash":"0, 0, 0, 0, 0","== Custom 9 ==":"","Custom 9 Condition":"false","Custom 9 Text":"","Custom 9 Location":"24, -48","Custom 9 Colors":"#FFFFFF | #000000","Custom 9 Animations":"float","Custom 9 Duration":"60","Custom 9 Flash":"0, 0, 0, 0, 0","== Custom 10 ==":"","Custom 10 Condition":"false","Custom 10 Text":"","Custom 10 Location":"24, -48","Custom 10 Colors":"#FFFFFF | #000000","Custom 10 Animations":"float","Custom 10 Duration":"60","Custom 10 Flash":"0, 0, 0, 0, 0","== Custom 11 ==":"","Custom 11 Condition":"false","Custom 11 Text":"","Custom 11 Location":"24, -48","Custom 11 Colors":"#FFFFFF | #000000","Custom 11 Animations":"float","Custom 11 Duration":"60","Custom 11 Flash":"0, 0, 0, 0, 0","== Custom 12 ==":"","Custom 12 Condition":"false","Custom 12 Text":"","Custom 12 Location":"24, -48","Custom 12 Colors":"#FFFFFF | #000000","Custom 12 Animations":"float","Custom 12 Duration":"60","Custom 12 Flash":"0, 0, 0, 0, 0","== Custom 13 ==":"","Custom 13 Condition":"false","Custom 13 Text":"","Custom 13 Location":"24, -48","Custom 13 Colors":"#FFFFFF | #000000","Custom 13 Animations":"float","Custom 13 Duration":"60","Custom 13 Flash":"0, 0, 0, 0, 0","== Custom 14 ==":"","Custom 14 Condition":"false","Custom 14 Text":"","Custom 14 Location":"24, -48","Custom 14 Colors":"#FFFFFF | #000000","Custom 14 Animations":"float","Custom 14 Duration":"60","Custom 14 Flash":"0, 0, 0, 0, 0","== Custom 15 ==":"","Custom 15 Condition":"false","Custom 15 Text":"","Custom 15 Location":"24, -48","Custom 15 Colors":"#FFFFFF | #000000","Custom 15 Animations":"float","Custom 15 Duration":"60","Custom 15 Flash":"0, 0, 0, 0, 0","== Custom 16 ==":"","Custom 16 Condition":"false","Custom 16 Text":"","Custom 16 Location":"24, -48","Custom 16 Colors":"#FFFFFF | #000000","Custom 16 Animations":"float","Custom 16 Duration":"60","Custom 16 Flash":"0, 0, 0, 0, 0","== Custom 17 ==":"","Custom 17 Condition":"false","Custom 17 Text":"","Custom 17 Location":"24, -48","Custom 17 Colors":"#FFFFFF | #000000","Custom 17 Animations":"float","Custom 17 Duration":"60","Custom 17 Flash":"0, 0, 0, 0, 0","== Custom 18 ==":"","Custom 18 Condition":"false","Custom 18 Text":"","Custom 18 Location":"24, -48","Custom 18 Colors":"#FFFFFF | #000000","Custom 18 Animations":"float","Custom 18 Duration":"60","Custom 18 Flash":"0, 0, 0, 0, 0","== Custom 19 ==":"","Custom 19 Condition":"false","Custom 19 Text":"","Custom 19 Location":"24, -48","Custom 19 Colors":"#FFFFFF | #000000","Custom 19 Animations":"float","Custom 19 Duration":"60","Custom 19 Flash":"0, 0, 0, 0, 0","== Custom 20 ==":"","Custom 20 Condition":"false","Custom 20 Text":"","Custom 20 Location":"24, -48","Custom 20 Colors":"#FFFFFF | #000000","Custom 20 Animations":"float","Custom 20 Duration":"60","Custom 20 Flash":"0, 0, 0, 0, 0","== Custom 21 ==":"","Custom 21 Condition":"false","Custom 21 Text":"","Custom 21 Location":"24, -48","Custom 21 Colors":"#FFFFFF | #000000","Custom 21 Animations":"float","Custom 21 Duration":"60","Custom 21 Flash":"0, 0, 0, 0, 0","== Custom 22 ==":"","Custom 22 Condition":"false","Custom 22 Text":"","Custom 22 Location":"24, -48","Custom 22 Colors":"#FFFFFF | #000000","Custom 22 Animations":"float","Custom 22 Duration":"60","Custom 22 Flash":"0, 0, 0, 0, 0","== Custom 23 ==":"","Custom 23 Condition":"false","Custom 23 Text":"","Custom 23 Location":"24, -48","Custom 23 Colors":"#FFFFFF | #000000","Custom 23 Animations":"float","Custom 23 Duration":"60","Custom 23 Flash":"0, 0, 0, 0, 0","== Custom 24 ==":"","Custom 24 Condition":"false","Custom 24 Text":"","Custom 24 Location":"24, -48","Custom 24 Colors":"#FFFFFF | #000000","Custom 24 Animations":"float","Custom 24 Duration":"60","Custom 24 Flash":"0, 0, 0, 0, 0","== Custom 25 ==":"","Custom 25 Condition":"false","Custom 25 Text":"","Custom 25 Location":"24, -48","Custom 25 Colors":"#FFFFFF | #000000","Custom 25 Animations":"float","Custom 25 Duration":"60","Custom 25 Flash":"0, 0, 0, 0, 0","== Custom 26 ==":"","Custom 26 Condition":"false","Custom 26 Text":"","Custom 26 Location":"24, -48","Custom 26 Colors":"#FFFFFF | #000000","Custom 26 Animations":"float","Custom 26 Duration":"60","Custom 26 Flash":"0, 0, 0, 0, 0","== Custom 27 ==":"","Custom 27 Condition":"false","Custom 27 Text":"","Custom 27 Location":"24, -48","Custom 27 Colors":"#FFFFFF | #000000","Custom 27 Animations":"float","Custom 27 Duration":"60","Custom 27 Flash":"0, 0, 0, 0, 0","== Custom 28 ==":"","Custom 28 Condition":"false","Custom 28 Text":"","Custom 28 Location":"24, -48","Custom 28 Colors":"#FFFFFF | #000000","Custom 28 Animations":"float","Custom 28 Duration":"60","Custom 28 Flash":"0, 0, 0, 0, 0","== Custom 29 ==":"","Custom 29 Condition":"false","Custom 29 Text":"","Custom 29 Location":"24, -48","Custom 29 Colors":"#FFFFFF | #000000","Custom 29 Animations":"float","Custom 29 Duration":"60","Custom 29 Flash":"0, 0, 0, 0, 0","== Custom 30 ==":"","Custom 30 Condition":"false","Custom 30 Text":"","Custom 30 Location":"24, -48","Custom 30 Colors":"#FFFFFF | #000000","Custom 30 Animations":"float","Custom 30 Duration":"60","Custom 30 Flash":"0, 0, 0, 0, 0","== Custom 31 ==":"","Custom 31 Condition":"false","Custom 31 Text":"","Custom 31 Location":"24, -48","Custom 31 Colors":"#FFFFFF | #000000","Custom 31 Animations":"float","Custom 31 Duration":"60","Custom 31 Flash":"0, 0, 0, 0, 0","== Custom 32 ==":"","Custom 32 Condition":"false","Custom 32 Text":"","Custom 32 Location":"24, -48","Custom 32 Colors":"#FFFFFF | #000000","Custom 32 Animations":"float","Custom 32 Duration":"60","Custom 32 Flash":"0, 0, 0, 0, 0","== Custom 33 ==":"","Custom 33 Condition":"false","Custom 33 Text":"","Custom 33 Location":"24, -48","Custom 33 Colors":"#FFFFFF | #000000","Custom 33 Animations":"float","Custom 33 Duration":"60","Custom 33 Flash":"0, 0, 0, 0, 0","== Custom 34 ==":"","Custom 34 Condition":"false","Custom 34 Text":"","Custom 34 Location":"24, -48","Custom 34 Colors":"#FFFFFF | #000000","Custom 34 Animations":"float","Custom 34 Duration":"60","Custom 34 Flash":"0, 0, 0, 0, 0","== Custom 35 ==":"","Custom 35 Condition":"false","Custom 35 Text":"","Custom 35 Location":"24, -48","Custom 35 Colors":"#FFFFFF | #000000","Custom 35 Animations":"float","Custom 35 Duration":"60","Custom 35 Flash":"0, 0, 0, 0, 0","== Custom 36 ==":"","Custom 36 Condition":"false","Custom 36 Text":"","Custom 36 Location":"24, -48","Custom 36 Colors":"#FFFFFF | #000000","Custom 36 Animations":"float","Custom 36 Duration":"60","Custom 36 Flash":"0, 0, 0, 0, 0","== Custom 37 ==":"","Custom 37 Condition":"false","Custom 37 Text":"","Custom 37 Location":"24, -48","Custom 37 Colors":"#FFFFFF | #000000","Custom 37 Animations":"float","Custom 37 Duration":"60","Custom 37 Flash":"0, 0, 0, 0, 0","== Custom 38 ==":"","Custom 38 Condition":"false","Custom 38 Text":"","Custom 38 Location":"24, -48","Custom 38 Colors":"#FFFFFF | #000000","Custom 38 Animations":"float","Custom 38 Duration":"60","Custom 38 Flash":"0, 0, 0, 0, 0","== Custom 39 ==":"","Custom 39 Condition":"false","Custom 39 Text":"","Custom 39 Location":"24, -48","Custom 39 Colors":"#FFFFFF | #000000","Custom 39 Animations":"float","Custom 39 Duration":"60","Custom 39 Flash":"0, 0, 0, 0, 0","== Custom 40 ==":"","Custom 40 Condition":"false","Custom 40 Text":"","Custom 40 Location":"24, -48","Custom 40 Colors":"#FFFFFF | #000000","Custom 40 Animations":"float","Custom 40 Duration":"60","Custom 40 Flash":"0, 0, 0, 0, 0","== Custom 41 ==":"","Custom 41 Condition":"false","Custom 41 Text":"","Custom 41 Location":"24, -48","Custom 41 Colors":"#FFFFFF | #000000","Custom 41 Animations":"float","Custom 41 Duration":"60","Custom 41 Flash":"0, 0, 0, 0, 0","== Custom 42 ==":"","Custom 42 Condition":"false","Custom 42 Text":"","Custom 42 Location":"24, -48","Custom 42 Colors":"#FFFFFF | #000000","Custom 42 Animations":"float","Custom 42 Duration":"60","Custom 42 Flash":"0, 0, 0, 0, 0","== Custom 43 ==":"","Custom 43 Condition":"false","Custom 43 Text":"","Custom 43 Location":"24, -48","Custom 43 Colors":"#FFFFFF | #000000","Custom 43 Animations":"float","Custom 43 Duration":"60","Custom 43 Flash":"0, 0, 0, 0, 0","== Custom 44 ==":"","Custom 44 Condition":"false","Custom 44 Text":"","Custom 44 Location":"24, -48","Custom 44 Colors":"#FFFFFF | #000000","Custom 44 Animations":"float","Custom 44 Duration":"60","Custom 44 Flash":"0, 0, 0, 0, 0","== Custom 45 ==":"","Custom 45 Condition":"false","Custom 45 Text":"","Custom 45 Location":"24, -48","Custom 45 Colors":"#FFFFFF | #000000","Custom 45 Animations":"float","Custom 45 Duration":"60","Custom 45 Flash":"0, 0, 0, 0, 0","== Custom 46 ==":"","Custom 46 Condition":"false","Custom 46 Text":"","Custom 46 Location":"24, -48","Custom 46 Colors":"#FFFFFF | #000000","Custom 46 Animations":"float","Custom 46 Duration":"60","Custom 46 Flash":"0, 0, 0, 0, 0","== Custom 47 ==":"","Custom 47 Condition":"false","Custom 47 Text":"","Custom 47 Location":"24, -48","Custom 47 Colors":"#FFFFFF | #000000","Custom 47 Animations":"float","Custom 47 Duration":"60","Custom 47 Flash":"0, 0, 0, 0, 0","== Custom 48 ==":"","Custom 48 Condition":"false","Custom 48 Text":"","Custom 48 Location":"24, -48","Custom 48 Colors":"#FFFFFF | #000000","Custom 48 Animations":"float","Custom 48 Duration":"60","Custom 48 Flash":"0, 0, 0, 0, 0","== Custom 49 ==":"","Custom 49 Condition":"false","Custom 49 Text":"","Custom 49 Location":"24, -48","Custom 49 Colors":"#FFFFFF | #000000","Custom 49 Animations":"float","Custom 49 Duration":"60","Custom 49 Flash":"0, 0, 0, 0, 0","== Custom 50 ==":"","Custom 50 Condition":"false","Custom 50 Text":"","Custom 50 Location":"24, -48","Custom 50 Colors":"#FFFFFF | #000000","Custom 50 Animations":"float","Custom 50 Duration":"60","Custom 50 Flash":"0, 0, 0, 0, 0"}}, -{"name":"SRD_EnemyBulkDrops","status":false,"description":"Adds more Notetag options for YEP_ExtraEnemyDrops for bulk processing","parameters":{}}, {"name":"SRD_EquipCompareUpgrade","status":true,"description":"Allows for developers to customize all the visible parameters that can be seen on the Equip Screen.","parameters":{"Default Pos Color":"#80ff80","Default Neg Color":"#c08080","Window Width":"356","Font Size":"24","Line Padding":"8","== Stat 1 ==":"","Stat 1 Name":"Max HP","Stat 1 Eval":"actor.mhp","Stat 1 Format":"val","== Stat 2 ==":"","Stat 2 Name":"Max MP","Stat 2 Eval":"actor.mmp","Stat 2 Format":"val","== Stat 3 ==":"","Stat 3 Name":"Attack","Stat 3 Eval":"actor.atk","Stat 3 Format":"val","== Stat 4 ==":"","Stat 4 Name":"Defense","Stat 4 Eval":"actor.def","Stat 4 Format":"val","== Stat 5 ==":"","Stat 5 Name":"M. Attack","Stat 5 Eval":"actor.mat","Stat 5 Format":"val","== Stat 6 ==":"","Stat 6 Name":"M. Defense","Stat 6 Eval":"actor.mdf","Stat 6 Format":"val","== Stat 7 ==":"","Stat 7 Name":"Agility","Stat 7 Eval":"actor.agi","Stat 7 Format":"val","== Stat 8 ==":"","Stat 8 Name":"Luck","Stat 8 Eval":"actor.luk","Stat 8 Format":"val","== Stat 9 ==":"","Stat 9 Name":"Hit Rate","Stat 9 Eval":"Math.floor(actor.hit * 100)","Stat 9 Format":"val%","== Stat 10 ==":"","Stat 10 Name":"Evade Rate","Stat 10 Eval":"Math.floor(actor.eva * 100)","Stat 10 Format":"val%","== Stat 11 ==":"","Stat 11 Name":"Critical Rate","Stat 11 Eval":"Math.floor(actor.cri * 100)","Stat 11 Format":"val%","== Stat 12 ==":"","Stat 12 Name":"Critical Evade","Stat 12 Eval":"Math.floor(actor.cev * 100)","Stat 12 Format":"val%","== Stat 13 ==":"","Stat 13 Name":"M. Evasion","Stat 13 Eval":"Math.floor(actor.mev * 100)","Stat 13 Format":"val%","== Stat 14 ==":"","Stat 14 Name":"M. Reflect","Stat 14 Eval":"Math.floor(actor.mrf * 100)","Stat 14 Format":"val%","== Stat 15 ==":"","Stat 15 Name":"Counter Rate","Stat 15 Eval":"Math.floor(actor.cnt * 100)","Stat 15 Format":"val%","== Stat 16 ==":"","Stat 16 Name":"HP Regen","Stat 16 Eval":"Math.floor(actor.hrg * 100)","Stat 16 Format":"val%","== Stat 17 ==":"","Stat 17 Name":"MP Regen","Stat 17 Eval":"Math.floor(actor.mrg * 100)","Stat 17 Format":"val%","== Stat 18 ==":"","Stat 18 Name":"TP Regen","Stat 18 Eval":"Math.floor(actor.trg * 100)","Stat 18 Format":"val%","== Stat 19 ==":"","Stat 19 Name":"Target Rate","Stat 19 Eval":"Math.floor(actor.tgr * 100)","Stat 19 Format":"val%","== Stat 20 ==":"","Stat 20 Name":"Guard Effect","Stat 20 Eval":"Math.floor(actor.grd * 100)","Stat 20 Format":"val%","== Stat 21 ==":"","Stat 21 Name":"Recover Rate","Stat 21 Eval":"Math.floor(actor.rec * 100)","Stat 21 Format":"val%","== Stat 22 ==":"","Stat 22 Name":"Pharmacology","Stat 22 Eval":"Math.floor(actor.pha * 100)","Stat 22 Format":"val%","== Stat 23 ==":"","Stat 23 Name":"MP Cost Rate","Stat 23 Eval":"Math.floor(actor.mcr * 100)","Stat 23 Format":"val%","== Stat 24 ==":"","Stat 24 Name":"TP Cost Rate","Stat 24 Eval":"Math.floor(actor.tcr * 100)","Stat 24 Format":"val%","== Stat 25 ==":"","Stat 25 Name":"Damage Rate","Stat 25 Eval":"Math.floor(actor.pdr * 100)","Stat 25 Format":"val%","== Stat 26 ==":"","Stat 26 Name":"M. Damage Rate","Stat 26 Eval":"Math.floor(actor.mdr * 100)","Stat 26 Format":"val%","== Stat 27 ==":"","Stat 27 Name":"Floor Damage Rate","Stat 27 Eval":"Math.floor(actor.fdr * 100)","Stat 27 Format":"val%","== Stat 28 ==":"","Stat 28 Name":"EXP Rate","Stat 28 Eval":"Math.floor(actor.exr * 100)","Stat 28 Format":"val%","== Stat 29 ==":"","Stat 29 Name":"","Stat 29 Eval":"","Stat 29 Format":"val","== Stat 30 ==":"","Stat 30 Name":"","Stat 30 Eval":"","Stat 30 Format":"val","== Stat 31 ==":"","Stat 31 Name":"","Stat 31 Eval":"","Stat 31 Format":"val","== Stat 32 ==":"","Stat 32 Name":"","Stat 32 Eval":"","Stat 32 Format":"val","== Stat 33 ==":"","Stat 33 Name":"","Stat 33 Eval":"","Stat 33 Format":"val","== Stat 34 ==":"","Stat 34 Name":"","Stat 34 Eval":"","Stat 34 Format":"val","== Stat 35 ==":"","Stat 35 Name":"","Stat 35 Eval":"","Stat 35 Format":"val","== Stat 36 ==":"","Stat 36 Name":"","Stat 36 Eval":"","Stat 36 Format":"val","== Stat 37 ==":"","Stat 37 Name":"","Stat 37 Eval":"","Stat 37 Format":"val","== Stat 38 ==":"","Stat 38 Name":"","Stat 38 Eval":"","Stat 38 Format":"val","== Stat 39 ==":"","Stat 39 Name":"","Stat 39 Eval":"","Stat 39 Format":"val","== Stat 40 ==":"","Stat 40 Name":"","Stat 40 Eval":"","Stat 40 Format":"val","== Stat 41 ==":"","Stat 41 Name":"","Stat 41 Eval":"","Stat 41 Format":"val","== Stat 42 ==":"","Stat 42 Name":"","Stat 42 Eval":"","Stat 42 Format":"val","== Stat 43 ==":"","Stat 43 Name":"","Stat 43 Eval":"","Stat 43 Format":"val","== Stat 44 ==":"","Stat 44 Name":"","Stat 44 Eval":"","Stat 44 Format":"val","== Stat 45 ==":"","Stat 45 Name":"","Stat 45 Eval":"","Stat 45 Format":"val","== Stat 46 ==":"","Stat 46 Name":"","Stat 46 Eval":"","Stat 46 Format":"val","== Stat 47 ==":"","Stat 47 Name":"","Stat 47 Eval":"","Stat 47 Format":"val","== Stat 48 ==":"","Stat 48 Name":"","Stat 48 Eval":"","Stat 48 Format":"val","== Stat 49 ==":"","Stat 49 Name":"","Stat 49 Eval":"","Stat 49 Format":"val","== Stat 50 ==":"","Stat 50 Name":"","Stat 50 Eval":"","Stat 50 Format":"val","== Stat 51 ==":"","Stat 51 Name":"","Stat 51 Eval":"","Stat 51 Format":"val","== Stat 52 ==":"","Stat 52 Name":"","Stat 52 Eval":"","Stat 52 Format":"val","== Stat 53 ==":"","Stat 53 Name":"","Stat 53 Eval":"","Stat 53 Format":"val","== Stat 54 ==":"","Stat 54 Name":"","Stat 54 Eval":"","Stat 54 Format":"val","== Stat 55 ==":"","Stat 55 Name":"","Stat 55 Eval":"","Stat 55 Format":"val","== Stat 56 ==":"","Stat 56 Name":"","Stat 56 Eval":"","Stat 56 Format":"val","== Stat 57 ==":"","Stat 57 Name":"","Stat 57 Eval":"","Stat 57 Format":"val","== Stat 58 ==":"","Stat 58 Name":"","Stat 58 Eval":"","Stat 58 Format":"val","== Stat 59 ==":"","Stat 59 Name":"","Stat 59 Eval":"","Stat 59 Format":"val","== Stat 60 ==":"","Stat 60 Name":"","Stat 60 Eval":"","Stat 60 Format":"val","== Stat 61 ==":"","Stat 61 Name":"","Stat 61 Eval":"","Stat 61 Format":"val","== Stat 62 ==":"","Stat 62 Name":"","Stat 62 Eval":"","Stat 62 Format":"val","== Stat 63 ==":"","Stat 63 Name":"","Stat 63 Eval":"","Stat 63 Format":"val","== Stat 64 ==":"","Stat 64 Name":"","Stat 64 Eval":"","Stat 64 Format":"val","== Stat 65 ==":"","Stat 65 Name":"","Stat 65 Eval":"","Stat 65 Format":"val","== Stat 66 ==":"","Stat 66 Name":"","Stat 66 Eval":"","Stat 66 Format":"val","== Stat 67 ==":"","Stat 67 Name":"","Stat 67 Eval":"","Stat 67 Format":"val","== Stat 68 ==":"","Stat 68 Name":"","Stat 68 Eval":"","Stat 68 Format":"val","== Stat 69 ==":"","Stat 69 Name":"","Stat 69 Eval":"","Stat 69 Format":"val","== Stat 70 ==":"","Stat 70 Name":"","Stat 70 Eval":"","Stat 70 Format":"val","== Stat 71 ==":"","Stat 71 Name":"","Stat 71 Eval":"","Stat 71 Format":"val","== Stat 72 ==":"","Stat 72 Name":"","Stat 72 Eval":"","Stat 72 Format":"val","== Stat 73 ==":"","Stat 73 Name":"","Stat 73 Eval":"","Stat 73 Format":"val","== Stat 74 ==":"","Stat 74 Name":"","Stat 74 Eval":"","Stat 74 Format":"val","== Stat 75 ==":"","Stat 75 Name":"","Stat 75 Eval":"","Stat 75 Format":"val","== Stat 76 ==":"","Stat 76 Name":"","Stat 76 Eval":"","Stat 76 Format":"val","== Stat 77 ==":"","Stat 77 Name":"","Stat 77 Eval":"","Stat 77 Format":"val","== Stat 78 ==":"","Stat 78 Name":"","Stat 78 Eval":"","Stat 78 Format":"val","== Stat 79 ==":"","Stat 79 Name":"","Stat 79 Eval":"","Stat 79 Format":"val","== Stat 80 ==":"","Stat 80 Name":"","Stat 80 Eval":"","Stat 80 Format":"val","== Stat 81 ==":"","Stat 81 Name":"","Stat 81 Eval":"","Stat 81 Format":"val","== Stat 82 ==":"","Stat 82 Name":"","Stat 82 Eval":"","Stat 82 Format":"val","== Stat 83 ==":"","Stat 83 Name":"","Stat 83 Eval":"","Stat 83 Format":"val","== Stat 84 ==":"","Stat 84 Name":"","Stat 84 Eval":"","Stat 84 Format":"val","== Stat 85 ==":"","Stat 85 Name":"","Stat 85 Eval":"","Stat 85 Format":"val","== Stat 86 ==":"","Stat 86 Name":"","Stat 86 Eval":"","Stat 86 Format":"val","== Stat 87 ==":"","Stat 87 Name":"","Stat 87 Eval":"","Stat 87 Format":"val","== Stat 88 ==":"","Stat 88 Name":"","Stat 88 Eval":"","Stat 88 Format":"val","== Stat 89 ==":"","Stat 89 Name":"","Stat 89 Eval":"","Stat 89 Format":"val","== Stat 90 ==":"","Stat 90 Name":"","Stat 90 Eval":"","Stat 90 Format":"val","== Stat 91 ==":"","Stat 91 Name":"","Stat 91 Eval":"","Stat 91 Format":"val","== Stat 92 ==":"","Stat 92 Name":"","Stat 92 Eval":"","Stat 92 Format":"val","== Stat 93 ==":"","Stat 93 Name":"","Stat 93 Eval":"","Stat 93 Format":"val","== Stat 94 ==":"","Stat 94 Name":"","Stat 94 Eval":"","Stat 94 Format":"val","== Stat 95 ==":"","Stat 95 Name":"","Stat 95 Eval":"","Stat 95 Format":"val","== Stat 96 ==":"","Stat 96 Name":"","Stat 96 Eval":"","Stat 96 Format":"val","== Stat 97 ==":"","Stat 97 Name":"","Stat 97 Eval":"","Stat 97 Format":"val","== Stat 98 ==":"","Stat 98 Name":"","Stat 98 Eval":"","Stat 98 Format":"val","== Stat 99 ==":"","Stat 99 Name":"","Stat 99 Eval":"","Stat 99 Format":"val","== Stat 100 ==":"","Stat 100 Name":"","Stat 100 Eval":"","Stat 100 Format":"val"}}, +{"name":"SRD_EnemyBulkDrops","status":false,"description":"Adds more Notetag options for YEP_ExtraEnemyDrops for bulk processing","parameters":{}}, {"name":"SRD_SuperToolsEngine","status":false,"description":"The heart of all maker-style plugins; it adds a playtesting editor that can be opened with F12.","parameters":{"Connect Editor":"true","Auto Open Window":"false","Auto Move Window":"true","Menu Editor Exempt List":"[\"Window_BattleLog\",\"Window_MapName\"]"}}, {"name":"SRD_StatDistribution","status":false,"description":"Allows players to distribute points to different stats of the Actors at his or her discretion.","parameters":{"Default Stats":"mhp, mmp, atk, def, mat, mdf, agi, luk","Default Formula":"Math.ceil(level / 10)","Show on Menu":"true","== Stat Reset ==":"","Allow Stat Resets":"true","Reset Gold Cost":"points * 100","== Custom Texts ==":"","Level Up Message":"Got %1 stat points!","Command Name":"Stat Boost","Points Text":"Stat Points:","Upgrade Text":"Upgrade Cost:","Spend Text":"Spend","Reset Text":"Reset","Finish Text":"Finish","== Gauge Options ==":"","Use Gauges":"true","Gauge Height":"14","== Points Label ==":"","Point Icon":"87","Point Text":"Points","Point Color":"#66ff66"}}, {"name":"SRD_SummonCore","status":false,"description":"Allows developers to create skills that summon Actors into the player's party using various parameters.","parameters":{"Battlelog Message":"%1 has been summoned!","Max Summons":"4","Restrict Per Skill":"true","Restrict Per Position":"true","== Defaults ==":"","Default Actor ID":"1","Default Level":"1","Default Animation":"51","Default Exit Ani.":"51","Default Turns":"-1","Default X Pos":"master._homeX - 120","Default Y Pos":"master._homeY"}}, @@ -55,5 +55,7 @@ var $plugins = {"name":"YEP_X_CoreUpdatesOpt","status":true,"description":"v1.62 (Req YEP_CoreEngine.js) Update your game without needing\nto change your base rpg_x.js files and optimize it for desktop.","parameters":{"---Official Updates---":"","110_Updates":"true","120_Updates":"true","130_Updates":"true","131_Updates":"true","132_Updates":"true","133_Updates":"true","134_Updates":"true","140_Updates":"true","150_Updates":"true","151_Updates":"true","152_Updates":"true","162_Updates":"true","---Custom---":"","Desktop_Updates":"true"}}, {"name":"YEP_X_ExtMovePack1","status":true,"description":"v1.01 (Requires YEP_MoveRouteCore.js) Adds extra movement\noptions to create specific behaviors in movement patterns.","parameters":{}}, {"name":"YEP_X_ItemUpgradeSlots","status":true,"description":"v1.10 (Requires YEP_ItemCore.js) Allows independent items to\nbe upgradeable and gain better stats.","parameters":{"Default Slots":"3","Slot Variance":"1","Upgrade Command":"Upgrade %1","Show Only":"true","Slots Available":"Slots Available","Show Slot Upgrades":"true","Slot Upgrade Format":"\\}Slot%1: %2\\{","Default Sound":"Heal2"}}, -{"name":"YEP_X_SkillCooldowns","status":true,"description":"v1.12 (Requires YEP_SkillCore.js) Cooldowns can be applied\nto skills to prevent them from being used continuously.","parameters":{"---Cooldown---":"","Cooldown Format":"%1CD","Cooldown Font Size":"20","Cooldown Text Color":"6","Cooldown Icon":"75","Cooldown After Battle":"-10","Cooldown Steps":"5","Cooldown Bypass":"1 2 3 4 5 6 7","Cooldown Bypass List":"[]","---Warmup---":"","Warmup Format":"%1WU","Warmup Font Size":"20","Warmup Text Color":"4","Warmup Icon":"75","---Battle Core---":"","Time Based":"false","Turn Time":"100"}} +{"name":"YEP_X_SkillCooldowns","status":true,"description":"v1.12 (Requires YEP_SkillCore.js) Cooldowns can be applied\nto skills to prevent them from being used continuously.","parameters":{"---Cooldown---":"","Cooldown Format":"%1CD","Cooldown Font Size":"20","Cooldown Text Color":"6","Cooldown Icon":"75","Cooldown After Battle":"-10","Cooldown Steps":"5","Cooldown Bypass":"1 2 3 4 5 6 7","Cooldown Bypass List":"[]","---Warmup---":"","Warmup Format":"%1WU","Warmup Font Size":"20","Warmup Text Color":"4","Warmup Icon":"75","---Battle Core---":"","Time Based":"false","Turn Time":"100"}}, +{"name":"--------------------","status":true,"description":"------------------------------------------------------------","parameters":{}}, +{"name":"FELSKI_TECHTREE","status":true,"description":"v1.3.0 A techtree plugin.","parameters":{"General Settings":"","onMap":"false","Menu Text":"Skilltree","Menu Visible":"true","Menu Background":"true","Menu Only Display":"false","Menu Background Opacity":"192","Confirm Background Opacity":"192","No Skilltree Message Format":"There is no techtree maintained for %1.","Update Skill Trees":"false","Class Change Settings":"","Class Change Unlearn Skills":"true","Class Change Relearn Skills":"true","Class Change Remove Stats":"true","Class Change Readd Stats":"true","Class Change Run Deactivate Eval":"true","Class Change Run Activate Eval":"true","Class Change Deactivate Nodes":"false","Add Skilltree Command to Change Class":"false","Header Settings":"","Update On Header Change":"false","Header Columns":"4","Header Draw Leading Icons":"true","Header Draw Trailing Icons":"true","Currency Font":"GameFont","Currency Font Size":"18","Currency Font Color":"0","Lanes Settings":"","Lanes":"3","Horizontal Lanes":"true","Node Visual Settings":"","Node Height":"200","Node Width":"300","Node Border Width":"0","Node Gap":"60","Node Opacity":"160","Node Cursor Size Offset":"0","Nodes Left Margin":"20","Nodes Top Margin":"20","Node Options":"","Hidden Icon":"93","Hidden Text":"This skill is hidden. You will reveal it somehow...","Active Nodes Are Always Visible":"false","Node Show Learned Icon":"true","Node Show Learned Icon ID":"90","Hide Node Cost":"true","Node Activation Settings":"","Standard Animation ID":"15","Animation X Offset":"20","Animation Y Offset":"20","Suppress Default Unlock Sound":"false","Node Text Settings":"","Node Action Unlock":"Unlock","Node Action Cancel":"Cancel","Node Action Already Unlocked":"Already Unlocked","Node Action Close":"Close","Node Show Tech Description":"true","Node Show Skill Name":"true","Node Show Skill Description":"true","Node Show Skill Icon":"true","Font Settings":"","Font":"GameFont","Font Size":"28","Font Color":"0","Header Font":"GameFont","Header Font Size":"28","Header Font Color":"0","Header Description Font":"GameFont","Header Description Font Size":"28","Header Description Font Color":"0","Node Header Font":"GameFont","Node Header Font Size":"28","Node Header Font Color":"0","Node Header Font Color Greyed Out":"8","Node Level Requirement Font":"GameFont","Node Level Requirement Font Size":"28","Node Level Requirement Font Color":"8","Node Text Font":"GameFont","Node Text Font Size":"28","Node Text Font Color":"0","Node Text Font Color Greyed Out":"8","Node Cost Font":"GameFont","Node Cost Font Size":"28","Node Cost Font Color":"0","Node Cost Font Color Greyed Out":"8"}} ]; diff --git a/js/plugins/FELSKI_TECHTREE.js b/js/plugins/FELSKI_TECHTREE.js new file mode 100644 index 0000000..0735587 --- /dev/null +++ b/js/plugins/FELSKI_TECHTREE.js @@ -0,0 +1,4722 @@ +"use strict"; +//============================================================================= +// Felskis Techtree Plugin +// FELSKI_TECHTREE.js +//============================================================================= + +var Imported = Imported || {}; +Imported.Felski_Techtree = true; + +var Felski = Felski || {}; +Felski.Techtree = {}; +Felski.Techtree.version = 1.3; + +/*: +* @plugindesc v1.3.0 A techtree plugin. +* @author Felski +* @help +* This is a complex skill tree plugin for actors. The term skill tree and tech tree are both used. They refer to the same. +* Each actor can have multiple trees. +* Each node in the tree requires a specific amount of parent nodes to be +* active in order to be unlockable. The actor learns skills on node activation. +* Additionally you can activate switches on activation. +* +* To create a techtree you need to provide a techtrees.json file, which +* contains all techtrees. The file can be created using the treebuilder that +* can be found in the project files. +* +* ============================================================================ +* How to install the plugin +* ============================================================================ +* - Download the demo file from https://felski.itch.io/felski-skilltree. +* - Copy the FELSKI_TECHTREE.js into your plugin folder. +* - Add the plugin to your game. +* - Open the Treebuilder folder in the demo folder. +* - Open the treebuilder.html. +* - Use the editor to define your tree. +* - Copy the Techtree JSON Output into a new file. +* - Save the file as Techtrees.json into your projects data folder. +* - Add notetags(see below) to actors or classes. +* - Test the plugin in testplay. +* - Enjoy! +* +* ============================================================================ +* Example Techtrees.json +* ============================================================================ +* for a tree with 2 nodes: +* [ +* { +* "uid": "HOLY", +* "header": "Saint", +* "tech_description": "Saint Tech Tree", +* "icon": 70, +* "bgimg": "Sword", +* "nodes": [ +* { +* "technode": { +* "uid": "HOLY01", +* "lane": 1, +* "depth": 1, +* "header": "Saint", +* "tech_description": "Triggers the common event 5 after you close the skilltree.", +* "bgimg": "Crystal", +* "parents": [], +* "neededParents": 0, +* "visibility": { +* "switches": [] +* }, +* "costs": { +* "gold": 0, +* "jp": 200, +* "items": [], +* "weapons": [], +* "armors": [] +* }, +* "onActivate": { +* "switches": [ +* { +* "id": 5, +* "value": true +* } +* ], +* "skills": [ +* 141, +* 144 +* ], +* "commonevents": [ +* { +* "id": 5, +* "close": false +* } +* ], +* "stats": { +* "0": 0, +* "1": 0, +* "2": 0, +* "3": 0, +* "4": 0, +* "5": 0, +* "6": 0, +* "7": 0 +* }, +* "eval": { +* "onActivate": "", +* "onDeactivate": "" +* } +* } +* } +* }, +* { +* "technode": { +* "uid": "HOLY02", +* "lane": 1, +* "depth": 2, +* "header": "Holy Saint", +* "tech_description": "Triggers the common event 6 as soon as you unlock it.", +* "parents": [ +* { +* "parent": "HOLY01" +* } +* ], +* "neededParents": 1, +* "visibility": { +* "switches": [] +* }, +* "costs": { +* "gold": 0, +* "jp": 200, +* "items": [], +* "weapons": [], +* "armors": [] +* }, +* "onActivate": { +* "switches": [], +* "skills": [ +* 145, +* 148 +* ], +* "commonevents": [ +* { +* "id": 6, +* "close": true +* } +* ], +* "stats": { +* "0": 0, +* "1": 0, +* "2": 0, +* "3": 0, +* "4": 0, +* "5": 0, +* "6": 0, +* "7": 0 +* }, +* "eval": { +* "onActivate": "", +* "onDeactivate": "" +* } +* } +* } +* } +* ], +* "hideGoldCost": false, +* "hideJPCost": false, +* "costItems": [] +* } +* ] +* +* ============================================================================ +* Tree attributes +* ============================================================================ +* - uid: unique identifier to distinguish trees. Needs to be unique. +* - header: Header line for a tree. +* - tech_description: Description text for a tree. +* - icon: icon id of the tree. +* - bgimg: name of the background image file. +* - nodes: object containing all the node data. +* - uid: unique identifier to distinguish nodes. Needs to be unique. +* - lane: row in the skill tree. Row 2 would appear below row 1. It +* - defines on which line in the skilltree a node appears. +* - depth: column in the skill tree. It defines how far into the tree a +* node should appear. +* - header: Header line for a node. +* - tech_description: Description text for a node. +* - bgimg: name of the background image file. +* - parents: Unique ids of the parent nodes. Used to draw arrows between +* the nodes. +* - neededParents: Amount of active parents needed for the node to be +* unlockable. +* - visibility: required switches for the node to be fully visible +* - switches: +* - id: id of the switch +* - costs: multiple cost options like: gold, yanflys jobpoints, items, +* weapons and armors +* - onActivate: what should happen when the player activates this node +* - switches: switches can be turned on and off +* - id: id of the switch +* - value: should the switch be set to true or false (on or off) +* - skills: id of the skills that will be learnt on activate +* - animation: id of the animation played when node is activated +* - stats: adjustment to common character stats +* - eval: run custom JS code +* - commonevents: common events that will be triggered on activate +* - id: id of the common event +* - close: return to map on activate +* - animation: id of the animation played when a node is activated +* - hideGoldCost: should gold be hidden in the techtree menu +* - hideJPCost: should jp be hidden in the techtree menu +* - costItems: ids of items that are shown in the cost window +* +* ============================================================================ +* Notetags +* ============================================================================ +* You can add a tree to an actor by adding the uids of the trees via notetags: +* +* HOLY +* HEALER +* +* +* ============================================================================ +* Controls +* ============================================================================ +* Mouse: +* - Nodes are clickable with the mouse to select them. +* - Clicking again opens the node. +* Scrolling: +* - Scrolling down or up is like press right or left. +* Arrowkeys: +* - When pressing an arrow key, the cursor attempts to find a node in that +* direction, until he hits an edge (first lane, first depth, max lane, +* max depth). Then the cursor will turn counter clockwise and continue in +* that new direction. The cursor will stop at the first node he finds. +* +* ============================================================================ +* Plugin Commands +* ============================================================================ +* You can directly open the skill tree scene. +* - TECHTREE [actorId] +* You can prepare the scene using the following commands: +* - TECHTREE DISPLAYONLY +* opens the tree in display only mode, similar to the new plugin parameter +* - TECHTREE PRESELECT [tree uid] +* preselects a specific tree for the actor. If the tree isnt found, the default selection is used. +* - TECHTREE SINGLE +* prevents the user from changing trees +* +* You can reset all techtrees for an actor. +* - RESETTECHTREES [actorId] [refund] +* You can reset a specific techtree for an actor by uid. Put in true or false for [refund]. +* - RESETTECHTREE [actorId] [tree uid] [refund] +* You can save the amount of active nodes in a tree by uid in a variable. Put in true or false for [refund]. +* - ACTIVENODES [actorId] [tree uid] [variable Id] +* You can add a techtree during the game: +* - ADDTECHTREE [actorId] [tree uid] +* You can activate a specific node during the game for an actor using: +* - ACTIVATENODE [actorId] [tree uid] [node uid] +* You can deactivate a specific node during the game for an actor using (the usually unlearn settings will be applied): +* - DEACTIVATENODE [actorId] [tree uid] [node uid] +* +* ============================================================================ +* Additional Infos +* ============================================================================ +* Advices: +* - The plugin works best with hierarchic trees. +* - It is also adviced to keep parents and children close together. +* - Keep the trees simple. +* - You can add multiple trees to one actor. +* +* First selected node: +* - The first selected node in a tree is always the first defined node. So if +* you define a node at 2,2 and then another at 1,1 the node at 2,2 will be +* selected when the tree is opened. +* +* Limitations: +* - Only left to right skilltrees can be created. +* +* Changing the system: +* - You can alter the system look by changing the files in /img/system/techtree. +* +* Requirements: +* - This plugin is developed and tested in RPG Maker v1.6.1. +* - It might work with older version, but you have to test this by yourself. +* +* Compatiblity: +* - Yanfly's Class Change Core - http://yanfly.moe/2015/11/27/yep-32-class-change-core/ +* - Yanfly's Jobpoints - http://yanfly.moe/2015/11/13/yep-27-job-points/ +* - Yanfly's Load Custom Font - http://yanfly.moe/2016/07/23/yep-112-load-custom-font-rpg-maker-mv/ +* +* Tested Incompatiblity: +* - Yanfly's Subclass - http://yanfly.moe/2015/11/29/yep-34-subclass/ +* There might be more incompatible plugins. You need to test this yourself. +* But anything that will changes the way characters learn skills or change classes could be incompatible. +* +* ============================================================================ +* Terms of Use +* ============================================================================ +* Copyright (C) 2018 Felski +* +* These plugins may be used in free or commercial games. +* 'Felski' must be given credit in your games. +* You are allowed to edit the code. +* Do NOT claim the plugins as your own. +* Do NOT change the filename, parameters, and information of the plugin. +* You are NOT allowed to redistribute these plugins. +* You may NOT take code for your own released plugins without credit. +* +* ============================================================================ +* Changelog +* ============================================================================ +* V1.0.1 +* - added a parameter to change the visibility of the skill tree menu in the main menu. +* - added a plugin command to reset all skill trees for an actor. +* - added a plugin command to reset a specific skill tree for an actor. +* - fixed a bug where two actors having the same tech tree would unlock the node in both trees. +* - added a javascript function to get the amount of active nodes for a skill tree. +* +* V1.0.2 +* - fixed an error that the plugin wouldn't work, when a not existing tech tree was referenced in notetags. +* - added a warning when a tree is referenced in the notetags that isn't in the Techtree.json. +* - added the ability to set custom background for trees and single nodes. This is done via the Techtree.json. +* - added a folder for techtree backgrounds at ../img/system/techtree/bgimg/. All background images need to go there. +* - updated the json schema for the techtree editor for custom backgrounds. +* - added a plugin command to add a techtree to an actor. +* +* v1.1.0 +* Bugfixes: +* - increased performance for the techtree windows. +* - changed how images are loaded, so they should load more consitently and without errors. +* +* Minor Changes: +* - split up the tree window into 3 windows. An info window, a header window and a window for the tree itself. +* - you can now select another tree using the header window. +* - added a parameter to toggle preloading of the tree when selecting it in the header window. +* - added font and other parameters for the header window. +* - added a parameter to change the message that is shown when an actor has no trees available. +* - added a step by step guide to the help. +* +* Major Changes: +* - you can now bind skilltrees to classes. +* - an actor can have skilltrees from himself and from his class. +* - skilltrees bound to the actor will always be available. +* - skilltrees bound to the class will only be available when the actor has the class. +* - on class change, the actor will forget all skills he learnt from the old skill tree(s). This can be changed with a plugin parameter. +* - on class change, the actor will relearn all skills from the new skill tree(s), if there are already active nodes in the tree. So switching back to a class will relearn the skills. +* - on class change, all switches that have been set on or off will be set off or on. This happend for the old and the new skill tree(s). +* - activated nodes in a skill tree will remain on class change. So when the player changes back, the nodes are still active. This can be changed with a plugin parameter. +* - on class change, the common events will not be triggered again. +* - added the above mentioned plugin parameters. +* +* v1.1.1 +* Bugfixes: +* - fixed an issue with the automatic autowrap in the node confirm window. +* Changes: +* - added a parameter to change the text of a hidden node. +* - added a parameter to show/hide skill names in the node activation window. +* - added a parameter to show/hide skill descriptions in the node activation window. +* - added a parameter to show/hide skill icons in the node activation window. +* +* - added the option to play an animation when activating a node. +* - added a parameter to set a default animation when activating any node. +* - added a field in the techtree editor to set a default animation when activating any node in a specific tree. +* - added a field in the techtree editor to set a animation when activating a specific node. +* - added to offset parameters for the postion of animations. +* - this allows you to play animation effects, screen flashes and sound effect on node activation. +* +* v1.2.0 +* Bugfixes: +* - fixed an autowrap bug in the tree description in the tree selecting window. +* - fixed a bug with autowrap. Autowrap now uses the fontsize for the lineheight so it properly scales different fontsizes. +* - fixed a bug where the plugin would break when a not existing parent node was referenced. A console warning is shown now instead. +* +* Major Changes: +* - added the feature to increase/decrease stats (max HP, max MP, Attack, Defense, Magic Attack, Magic Defense, Agility and Luck) on node activation. +* - added plugin parameters for stat changes handling for class changes. +* - added corresponding options to the techtree builder app. +* +* - added the feature to run custom javascript code on node activation and deactivation. +* - added plugin parameters for custom javascript code handling for class changes. +* - added corresponding options to the techtree builder app. +* +* - added a header window that shows the current amount of currency (like gold or JP). +* - you can define up to 5 currencys that are shown here per tree. +* - added the corresponding option to the techtree builder app for gold, jp and specific items. +* - added a font plugin parameters for the currency window. See Header Settings. +* +* Minor Changes: +* - added a new parameter "Node Border Width" in the Node Visual Settings. +* - this parameter is used for the graphical border of a node. That way overlapping text can be prevented. +* +* - added the feature to use icons in all descriptions of the plugin. This feature also works for skill descriptions. +* - to add icons to the skill tree descriptions you need to use \\i[iconIndex] within the description. +* - to add icons to the skill description use \i[iconIndex] within the description of the skill in the RPG Maker MV database. This only affects the skill tree windows. +* +* - added the option to show an icon for learned nodes instead of the costs. +* - you can activate this by setting the "Node Show Learned Icon" plugin parameter to true. +* - you can change the icon shown by changing the "Node Show Learned Icon ID" plugin parameter. +* +* - added a new parameter "Hide Node Cost" in the Node Options. +* - with this parameter you can hide the costs in the tree overview for all nodes. +* - the costs still appear in the confirmation window. +* +* - added the plugin command ACTIVATENODE [actorId] [tree uid] [node uid]. +* - it can be used to unlock a specific node in a tree for an actor. +* +* - added the plugin command DEACTIVATENODE [actorId] [tree uid] [node uid]. +* - it can be used to reset a specific node in a tree for an actor. +* - all skill will be forgotton +* - all stats removed +* - all switches toggled +* - onDeactivate evals will be run +* - common events will not run again +* - this affects deactivating nodes using plugin commands +* +* - changed the plugin command RESETTECHTREES [actorId] [refund]. +* - it now has the option to refund the costs for the actor. +* - you cannot use this plugin command together with class changes. +* +* - changed the plugin command RESETTECHTREE [actorId] [tree uid] [refund]. +* - it now has the option to refund the costs for the actor. +* +* Tree Builder App Changes: +* - added Main Cost Items to the techtree builder. +* - you can define item ids here that will be shown as currency for the tree. This is a visual thing only and doesn't affect any mechanics. +* - added "Don't show gold currency for this tree?" option to the techtree builder. +* - you can decide wheter you want to show gold for this tree or not. +* - added "Don't show Jobpoints (JP) currency for this tree?" option to the techtree builder. +* - you can decide wheter you want to show gold for this tree or not. +* - added "Stat Changes" to the On Activate part of a node in the techtree builder. +* - you can define stat increases for a node here. +* - removed some cluttering options from the tree editor. To reactivate them see options. +* +* v1.2.1 +* Bugfixes: +* - fixed a bug that would prevent the plugin from working when classes have not existing trees assigned. A warning is shown instead. +* +* v1.2.2 +* Bugfixes: +* - fixed a bug with nodes that use more than one of a item/weapon/armor to unlock. These nodes can now be unlocked properly. +* - fixed an error with cost info window that happend when an actor didn't have a tree assigned. This now works properly. +* +* v1.3.0 +* Minor Changes: +* - added a new plugin parameter to make the skill tree scene in the menu display only. +* - added plugins commands to prepare the TECHTREE command. +* TECHTREE DISPLAYONLY +* opens the tree in display only mode, similar to the new plugin parameter +* TECHTREE PRESELECT [tree uid] +* preselects a specific tree for the actor. If the tree isnt found, the default selection is used. +* TECHTREE SINGLE +* prevents the user from changing trees +* +* - these two changes can be used to make the plugin work with skill trainers. +* Example: +* Enable the plugin parameter so the skill tree is only for display in the +* menu and then add skill trainers all over the world (use the plugin command +* TECHTREE to open the trees in change mode). +* +* - added a new plugin parameter "Update Skill Trees". With this enabled, the skill trees of saved games will update when you change the Techtrees.json file. +* - actors will properly unlearn skills that you have removed and learn skills you've added. Stat changes will also apply properly. Switches will change accordingly and Evals will run again. +* - Common Events will NOT run again. +* - this feature is experimental. Any feedback is much appreciated! +* +* - added level requirements to the skill trees. Added the corresponding field to the Tree Builder App. Actors can only unlock the node when they reached the required level. +* +* - added a new plugin parameter "Active Nodes Are Always Visible". With this enabled, nodes that are active are visible, even when the visibility requirements are not met. +* +* ============================================================================ +* END OF HELP +* ============================================================================ +* +* @param General Settings +* +* @param onMap +* @parent General Settings +* @desc NOT IMPLEMENTED: Should the techtree be available on the map +* @type Boolean +* @default false +* +* @param Menu Text +* @parent General Settings +* @desc Text shown in the menu for the tech tree command +* @type String +* @default Skilltree +* +* @param Menu Visible +* @parent General Settings +* @desc Visibility of the skill tree in the main menu +* @type Boolean +* @default true +* +* @param Menu Background +* @parent General Settings +* @desc Is the custom background image visible? +* @type Boolean +* @default true +* +* @param Menu Only Display +* @parent General Settings +* @desc Skill tree in the menu is only for display. You cannot unlock nodes there. +* @type Boolean +* @default false +* +* @param Update On Header Change +* @parent Header Settings +* @desc Instant update the techtree when selecting another tree in the header window. (This might decrease performance.) +* @type Boolean +* @default false +* +* @param Menu Background Opacity +* @parent General Settings +* @desc Default opacity for menu background image +* @type Integer +* @default 192 +* +* @param Confirm Background Opacity +* @parent General Settings +* @desc Default opacity for the confirm window background image +* @type Integer +* @default 192 +* +* @param No Skilltree Message Format +* @parent General Settings +* @desc Format of the message, when no skilltree is found for the actor. +* %1 - Actor Name +* @type String +* @default There is no techtree maintained for %1. +* +* @param Update Skill Trees +* @parent General Settings +* @desc [EXPERIMENTAL] Update the existing skill trees when the Techtrees.json changes. +* @type Boolean +* @default false +* +* +* @param Class Change Settings +* +* @param Class Change Unlearn Skills +* @parent Class Change Settings +* @desc Will the actor forget the skills he learned from a class skilltree on class change? +* @type Boolean +* @default true +* +* @param Class Change Relearn Skills +* @parent Class Change Settings +* @desc Will the actor forget the skills he learned from a class skilltree on class change? +* @type Boolean +* @default true +* +* @param Class Change Remove Stats +* @parent Class Change Settings +* @desc Will the actor get the stats removed he gained through nodes on class change? +* @type Boolean +* @default true +* +* @param Class Change Readd Stats +* @parent Class Change Settings +* @desc Will the actor get the stats readded he gained through nodes on class change? +* @type Boolean +* @default true +* +* @param Class Change Run Deactivate Eval +* @parent Class Change Settings +* @desc Should the onDeactivate Eval be ran on class change? +* @type Boolean +* @default true +* +* @param Class Change Run Activate Eval +* @parent Class Change Settings +* @desc Should the onActivate Eval be ran on class change +* @type Boolean +* @default true +* +* @param Class Change Deactivate Nodes +* @parent Class Change Settings +* @desc Will all nodes of the skilltree be set to unactive on class change? +* @type Boolean +* @default false +* +* @param Add Skilltree Command to Change Class +* @parent Class Change Settings +* @desc Should the skilltree command be added to the change class scene +* (Requires Yanfly's Class Change Core) +* @type Boolean +* @default false +* +* +* @param Header Settings +* +* @param Header Columns +* @parent Header Settings +* @desc Instant update the techtree when selecting another tree in the header window. (This might decrease performance.) +* @type Integer +* @default 4 +* +* @param Header Draw Leading Icons +* @parent Header Settings +* @desc Should there be a icon infront of the header text? +* @type Boolean +* @default true +* +* @param Header Draw Trailing Icons +* @parent Header Settings +* @desc Should there be a icon behind of the header text? +* @type Boolean +* @default true +* +* @param Currency Font +* @parent Header Settings +* @desc Name of the font used for the currency in currency window. +* @type string +* @default GameFont +* +* @param Currency Font Size +* @parent Header Settings +* @desc Size of the font used for the currency in currency window. +* @type number +* @min 1 +* Default: 18 +* @default 18 +* +* @param Currency Font Color +* @parent Header Settings +* @desc Color of the font used for the currency in currency window. +* @type number +* @min 0 +* @max 31 +* @default 0 +* +* +* @param Lanes Settings +* +* @param Lanes +* @parent Lanes Settings +* @desc Amount of lanes in a techtree. +* @type Integer +* @default 3 +* +* @param Horizontal Lanes +* @parent Lanes Settings +* @desc NOT IMPLEMENTED: Are the lanes show horizontally? +* @type Boolean +* @on lanes are horizonal +* @off lanes are vertical +* @default true +* +* +* @param Node Visual Settings +* @desc Settings for the nodes in the tree overview. +* +* @param Node Height +* @parent Node Visual Settings +* @desc Height of a node in the techtree. +* @type Integer +* @default 200 +* +* @param Node Width +* @parent Node Visual Settings +* @desc Width of a node in the techtree. Node Width + Node Gap should be a fraction of your (Screen Width - Nodes Left Margin) +* @type Integer +* @default 300 +* +* @param Node Border Width +* @parent Node Visual Settings +* @desc Width of the graphical border of a node in the tech tree. Used to prevent text overlapping. +* @type Integer +* @default 0 +* +* @param Node Gap +* @parent Node Visual Settings +* @desc Gap in pixels between each node. Should be atleast 60. +* @type Integer +* @default 60 +* +* @param Node Opacity +* @parent Node Visual Settings +* @desc Opacity of a node. +* @type Integer +* @min 0 +* @max 255 +* @default 160 +* +* @param Node Cursor Size Offset +* @parent Node Visual Settings +* @desc Cursor size offset in pixel. +* @type Integer +* @default 0 +* +* @param Nodes Left Margin +* @parent Node Visual Settings +* @desc Margin between first node and left window border. +* @type Integer +* @default 20 +* +* @param Nodes Top Margin +* @parent Node Visual Settings +* @desc Margin between first node and header part of the techtree. +* @type Integer +* @default 20 +* +* +* @param Node Options +* @desc Settings for the nodes in the tree overview. +* +* @param Hidden Icon +* @parent Node Options +* @desc Icon index of a hidden node +* @type Integer +* @default 93 +* +* @param Hidden Text +* @parent Node Options +* @desc Text shown for a hidde node +* @type String +* @default This skill is hidden. You will reveal it somehow... +* +* @param Active Nodes Are Always Visible +* @parent Node Options +* @desc Any active node is always visible, even when the visiblity requirements are not met. +* @type Boolean +* @on Always visible +* @off Only when requirements are met +* @default false +* +* @param Node Show Learned Icon +* @parent Node Options +* @desc Display an icon instead of nothing once the node is learned. +* @type Boolean +* @on Learned icon is shown +* @off Learned icon is hidden +* @default true +* +* @param Node Show Learned Icon ID +* @parent Node Options +* @desc ID of the icon shown for learned nodes. +* @type Number +* @min 1 +* @default 90 +* +* @param Hide Node Cost +* @parent Node Options +* @desc Hide the costs of a node in the tree overview. They are still shown in the confirmation window. +* @type Boolean +* @on Costs are hidden +* @off Costs are shown +* @default true +* +* +* @param Node Activation Settings +* +* @param Standard Animation ID +* @parent Node Activation Settings +* @desc ID of the edefault animation that is played when activating a node. Can be overwritten via the Techtrees.json for specific nodes. Set it to 0 to play no animation. +* @type Integer +* @default 15 +* +* @param Animation X Offset +* @parent Node Activation Settings +* @desc X Offset for the animation position that is played when activating a node. (can be negative) +* @type Integer +* @default 20 +* +* @param Animation Y Offset +* @parent Node Activation Settings +* @desc Y Offset for the animation position that is played when activating a node. (can be negative) +* @type Integer +* @default 20 +* +* @param Suppress Default Unlock Sound +* @parent Node Activation Settings +* @desc Should the unlock sound in the node confirm window be suppress. (Good when you want to play your own sounds.) +* @type Boolean +* @on suppress unlock sound +* @off not suppress unlock sound +* @default false +* +* +* @param Node Text Settings +* @desc Settings confirmation window shown once you clicked on a node. +* +* @param Node Action Unlock +* @parent Node Text Settings +* @desc Text for the unlock node command +* @type String +* @default Unlock +* +* @param Node Action Cancel +* @parent Node Text Settings +* @desc Text for the cancel node command +* @type String +* @default Cancel +* +* @param Node Action Already Unlocked +* @parent Node Text Settings +* @desc Text for the already unlocked node command +* @type String +* @default Already Unlocked +* +* @param Node Action Close +* @parent Node Text Settings +* @desc Text for the close node command +* @type String +* @default Close +* +* @param Node Show Tech Description +* @parent Node Text Settings +* @desc Should the tech description in the node confirm window (the one from the techtree.js) be visible +* @type Boolean +* @on Tech description is shown +* @off Tech description is hidden +* @default true +* +* @param Node Show Skill Name +* @parent Node Text Settings +* @desc Should the skill name in the node confirm window be visible +* @type Boolean +* @on Skill name is shown +* @off Skill name is hidden +* @default true +* +* @param Node Show Skill Description +* @parent Node Text Settings +* @desc Should the skill description in the node confirm window be visible +* @type Boolean +* @on Skill description is shown +* @off Skill description is hidden +* @default true +* +* @param Node Show Skill Icon +* @parent Node Text Settings +* @desc Should the skill icon in the node confirm window be visible +* @type Boolean +* @on Skill icon is shown +* @off Skill icon is hidden +* @default true +* +* +* @param Font Settings +* +* @param Font +* @parent Font Settings +* @desc Name of the font used in the techtree. +* @type string +* @default GameFont +* +* @param Font Size +* @parent Font Settings +* @desc Size of the font used in the techtree. +* @type number +* @min 1 +* Default: 28 +* @default 28 +* +* @param Font Color +* @parent Font Settings +* @desc Color of the font used in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 0 +* +* @param Header Font +* @parent Font Settings +* @desc Name of the font used for the header window in the techtree. +* @type string +* @default GameFont +* +* @param Header Font Size +* @parent Font Settings +* @desc Size of the font used for the header window in the techtree. +* @type number +* @min 1 +* Default: 28 +* @default 28 +* +* @param Header Font Color +* @parent Font Settings +* @desc Color of the font used for the header window in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 0 +* +* @param Header Description Font +* @parent Font Settings +* @desc Name of the font used for the description in the header window in the techtree. +* @type string +* @default GameFont +* +* @param Header Description Font Size +* @parent Font Settings +* @desc Size of the font used for the description in the header window in the techtree. +* @type number +* @min 1 +* Default: 28 +* @default 28 +* +* @param Header Description Font Color +* @parent Font Settings +* @desc Color of the font used for the description in the header window in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 0 +* +* +* @param Node Header Font +* @parent Font Settings +* @desc Name of the font used for the header text of nodes in the techtree. +* @type string +* @default GameFont +* +* @param Node Header Font Size +* @parent Font Settings +* @desc Size of the font used for the header text of nodes in the techtree. +* @type number +* @min 1 +* Default: 28 +* @default 28 +* +* @param Node Header Font Color +* @parent Font Settings +* @desc Color of the font used for the header text of nodes in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 0 +* +* @param Node Header Font Color Greyed Out +* @parent Font Settings +* @desc Color of the font used for the out greyed header text of nodes in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 8 +* +* @param Node Level Requirement Font +* @parent Font Settings +* @desc Name of the font used for the level requirement of nodes in the techtree. +* @type string +* @default GameFont +* +* @param Node Level Requirement Font Size +* @parent Font Settings +* @desc Size of the font used for the level requirement of nodes in the techtree. +* @type number +* @min 1 +* Default: 28 +* @default 28 +* +* @param Node Level Requirement Font Color +* @parent Font Settings +* @desc Color of the font used for the level requirement of nodes in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 8 +* +* +* @param Node Text Font +* @parent Font Settings +* @desc Name of the font used for the text of nodes in the techtree. +* @type string +* @default GameFont +* +* @param Node Text Font Size +* @parent Font Settings +* @desc Size of the font used for the text of nodes in the techtree. +* @type number +* @min 1 +* Default: 28 +* @default 28 +* +* @param Node Text Font Color +* @parent Font Settings +* @desc Color of the font used for the text of nodes in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 0 +* +* @param Node Text Font Color Greyed Out +* @parent Font Settings +* @desc Color of the font used for the out greyed text of nodes in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 8 +* +* +* @param Node Cost Font +* @parent Font Settings +* @desc Name of the font used for the cost of nodes in the techtree. +* @type string +* @default GameFont +* +* @param Node Cost Font Size +* @parent Font Settings +* @desc Size of the font used for the cost of nodes in the techtree. +* @type number +* @min 1 +* Default: 28 +* @default 28 +* +* @param Node Cost Font Color +* @parent Font Settings +* @desc Color of the font used for the cost of nodes in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 0 +* +* @param Node Cost Font Color Greyed Out +* @parent Font Settings +* @desc Color of the font used for the cost of nodes in the techtree. +* @type number +* @min 0 +* @max 31 +* @default 8 +* +* +*/ + +var $dataTechtrees = null; +DataManager._databaseFiles.push({name: '$dataTechtrees', src: 'Techtrees.json'}); + +var parameters = PluginManager.parameters('FELSKI_TECHTREE'); + +// General Settings +Felski.Techtree.onMap = false; +Felski.Techtree.horizontal = true; +Felski.Techtree.Lanes = Number(parameters['Lanes'] || 1); +Felski.Techtree.NoTreeText = String(parameters['No Skilltree Message Format']); +//Felski.Techtree.onMap = Boolean(parameters['onMap'] || false); +//Felski.Techtree.horizontal = Boolean(parameters['Horizontal Lanes'] || true); +Felski.Techtree.menuOnlyDisplay = String(parameters['Menu Only Display'] || 'false'); +Felski.Techtree.menuOnlyDisplay = eval(Felski.Techtree.menuOnlyDisplay); +Felski.Techtree.menuOnlyDisplayBuffer = false; +Felski.Techtree.preselectedTree = null; +Felski.Techtree.singleTreeView = false; +Felski.Techtree.updateTechtrees = String(parameters["Update Skill Trees"] || 'false'); +Felski.Techtree.updateTechtrees = eval(Felski.Techtree.updateTechtrees); + +// Class Settings +Felski.Techtree.CCUnlearn = String(parameters['Class Change Unlearn Skills'] || 'true'); +Felski.Techtree.CCUnlearn = eval(Felski.Techtree.CCUnlearn); +Felski.Techtree.CCRelearn = String(parameters['Class Change Relearn Skills'] || 'true'); +Felski.Techtree.CCRelearn = eval(Felski.Techtree.CCRelearn); +Felski.Techtree.CCRemoveStats = String(parameters['Class Change Remove Stats'] || 'true'); +Felski.Techtree.CCRemoveStats = eval(Felski.Techtree.CCRemoveStats); +Felski.Techtree.CCReaddStats = String(parameters['Class Change Readd Stats'] || 'true'); +Felski.Techtree.CCReaddStats = eval(Felski.Techtree.CCReaddStats); +Felski.Techtree.CCRunDeEval = String(parameters['Class Change Run Deactivate Eval'] || 'true'); +Felski.Techtree.CCRunDeEval = eval(Felski.Techtree.CCRunDeEval); +Felski.Techtree.CCRunAcEval = String(parameters['Class Change Run Activate Eval'] || 'true'); +Felski.Techtree.CCRunAcEval = eval(Felski.Techtree.CCRunAcEval); +Felski.Techtree.CCDeactive = String(parameters['Class Change Deactivate Nodes'] || 'false'); +Felski.Techtree.CCDeactive = eval(Felski.Techtree.CCDeactive); +Felski.Techtree.CCCommand = String(parameters['Add Skilltree Command to Change Class'] || 'false'); +Felski.Techtree.CCCommand = eval(Felski.Techtree.CCCommand); + +// Main Menu Settings +Felski.Techtree.TTMenuText = String(parameters['Menu Text'] || 'Skilltree'); +Felski.Techtree.TTMenuVisible = String(parameters['Menu Visible'] || 'true'); +Felski.Techtree.TTMenuVisible = eval(Felski.Techtree.TTMenuVisible); + +// Header Settings +Felski.Techtree.TTHeaderUpdate = String(parameters['Update On Header Change'] || 'false'); +Felski.Techtree.TTHeaderUpdate = eval(Felski.Techtree.TTHeaderUpdate); +Felski.Techtree.TTHeaderCols = Number(parameters['Header Columns'] || 4); +Felski.Techtree.TTHeaderLIcons = String(parameters['Header Draw Leading Icons'] || 'true'); +Felski.Techtree.TTHeaderLIcons = eval(Felski.Techtree.TTHeaderLIcons); +Felski.Techtree.TTHeaderTIcons = String(parameters['Header Draw Trailing Icons'] || 'true'); +Felski.Techtree.TTHeaderTIcons = eval(Felski.Techtree.TTHeaderTIcons); +// Currency Font +Felski.Techtree.TTHeaderCurFont = String(parameters['Currency Font'] || 'GameFont'); +Felski.Techtree.TTHeaderCurFontColor = Number(parameters['Currency Font Color'] || 0); +Felski.Techtree.TTHeaderCurFontSize = Number(parameters['Currency Font Size'] || 18); + + +// Backgrounds +Felski.Techtree.TTMenuBackground = String(parameters['Menu Background'] || 'false'); +Felski.Techtree.TTMenuBackground = eval(Felski.Techtree.TTMenuBackground); +Felski.Techtree.TTMenuBackgroundOpacity = Number(parameters['Menu Background Opacity'] || 192); +Felski.Techtree.TTMenuConfirmBackgroundOpacity = Number(parameters['Confirm Background Opacity'] || 192); + +// Node Settings +Felski.Techtree.HiddenIcon = Number(parameters['Hidden Icon'] || 93); +Felski.Techtree.HiddenText = String(parameters['Hidden Text'] || "This skill is hidden. You will reveal it somehow..."); +Felski.Techtree.NodeHeight = Number(parameters['Node Height'] || 200); +Felski.Techtree.NodeWidth = Number(parameters['Node Width'] || 300); +Felski.Techtree.NodeBorderWidth = Number(parameters['Node Border Width'] || 0); +Felski.Techtree.NodeGap = Number(parameters['Node Gap'] || 60); +Felski.Techtree.NodeOpacity = Number(parameters['Node Opacity'] || 160); +Felski.Techtree.NodeCursorSize = Number(parameters['Node Cursor Size Offset'] || 0); +Felski.Techtree.NodesLeftMargin = Number(parameters['Nodes Left Margin'] || 20); +Felski.Techtree.NodesTopMargin = Number(parameters['Nodes Top Margin'] || 20); +Felski.Techtree.NodesLearnedIconShown = String(parameters['Node Show Learned Icon'] || 'false'); +Felski.Techtree.NodesLearnedIconShown = eval(Felski.Techtree.NodesLearnedIconShown); +Felski.Techtree.NodesLearnedIconID = Number(parameters['Node Show Learned Icon ID'] || 90); +Felski.Techtree.NodesCostHidden = String(parameters['Hide Node Cost'] || 'false'); +Felski.Techtree.NodesCostHidden = eval(Felski.Techtree.NodesCostHidden); +Felski.Techtree.NodesActiveVisible = String(parameters['Active Nodes Are Always Visible'] || 'false'); +Felski.Techtree.NodesActiveVisible = eval(Felski.Techtree.NodesActiveVisible); + +// Animation Settings +Felski.Techtree.NodeAnimDefaultID = Number(parameters['Standard Animation ID'] || 15); +Felski.Techtree.NodeAnimXOffset = Number(parameters['Animation X Offset'] || 0); +Felski.Techtree.NodeAnimYOffset = Number(parameters['Animation Y Offset'] || 0); + +// Sound Settings +Felski.Techtree.suppressConfirmSound = String(parameters['Suppress Default Unlock Sound'] || 'false'); +Felski.Techtree.suppressConfirmSound = eval(Felski.Techtree.suppressConfirmSound); +Felski.Techtree.NodeSoundName = String(parameters['Default Sound Name']); +Felski.Techtree.NodeSoundVolume = Number(parameters['Default Sound Volume'] || 100); +Felski.Techtree.NodeSoundPitch = Number(parameters['Default Sound Pitch'] || 100); +Felski.Techtree.NodeSoundPan = Number(parameters['Default Sound Pan'] || 0); + +// Texts +Felski.Techtree.TTNShowTechDesc = String(parameters['Node Show Tech Description'] || 'true'); +Felski.Techtree.TTNShowTechDesc = eval(Felski.Techtree.TTMenuBackground); + +Felski.Techtree.TTNShowSkillName = String(parameters['Node Show Skill Name'] || 'true'); +Felski.Techtree.TTNShowSkillName = eval(Felski.Techtree.TTNShowSkillName); + +Felski.Techtree.TTNShowSkillDesc = String(parameters['Node Show Skill Description'] || 'true'); +Felski.Techtree.TTNShowSkillDesc = eval(Felski.Techtree.TTNShowSkillDesc); + +Felski.Techtree.TTNShowSkillIcon = String(parameters['Node Show Skill Icon'] || 'true'); +Felski.Techtree.TTNShowSkillIcon = eval(Felski.Techtree.TTNShowSkillIcon); + +// Fonts +// Tree +Felski.Techtree.TTFont = String(parameters['Font'] || 'GameFont'); +Felski.Techtree.TTFontColor = Number(parameters['Font Color'] || 0); +Felski.Techtree.TTFontSize = Number(parameters['Font Size'] || 28); + +// Header +Felski.Techtree.TTHeaderFont = String(parameters['Header Font'] || 'GameFont'); +Felski.Techtree.TTHeaderFontSize = Number(parameters['Header Font Size'] || 28); +Felski.Techtree.TTHeaderFontColor = Number(parameters['Header Font Color'] || 0); + +// Header Description +Felski.Techtree.TTHeaderDescFont = String(parameters['Header Description Font'] || 'GameFont'); +Felski.Techtree.TTHeaderDescFontSize = Number(parameters['Header Description Font Size'] || 28); +Felski.Techtree.TTHeaderDescFontColor = Number(parameters['Header Description Font Color'] || 0); + +// Node Header +Felski.Techtree.TTNHFont = String(parameters['Node Header Font'] || 'GameFont'); +Felski.Techtree.TTNHFontSize = Number(parameters['Node Header Font Size'] || 28); +Felski.Techtree.TTNHFontColor = Number(parameters['Node Header Font Color'] || 0); +Felski.Techtree.TTNHFontColorGreyedOut = Number(parameters['Node Header Font Color Greyed Out'] || 8); + +// Node Level Requirement +Felski.Techtree.TTLevelRequirementFont = String(parameters['Node Level Requirement Font'] || 'GameFont'); +Felski.Techtree.TTLevelRequirementFontSize = Number(parameters['Node Level Requirement Font Size'] || 28); +Felski.Techtree.TTLevelRequirementFontColor = Number(parameters['Node Level Requirement Font Color'] || 8); + +// Node Texts +Felski.Techtree.TTNTFont = String(parameters['Node Text Font'] || 'GameFont'); +Felski.Techtree.TTNTFontSize = Number(parameters['Node Text Font Size'] || 28); +Felski.Techtree.TTNTFontColor = Number(parameters['Node Text Font Color'] || 0); +Felski.Techtree.TTNTFontColorGreyedOut = Number(parameters['Node Text Font Color Greyed Out'] || 8); + +// Node Action Texts +Felski.Techtree.TTNAUnlock = String(parameters['Node Action Unlock'] || 'Unlock'); +Felski.Techtree.TTNAAlreadyUnlocked = String(parameters['Node Action Already Unlocked'] || 'Already Unlocked'); +Felski.Techtree.TTNAClose = String(parameters['Node Action Close'] || 'Close'); +Felski.Techtree.TTNACancel = String(parameters['Node Action Cancel'] || 'Cancel'); + +// Cost +Felski.Techtree.TTNCFont = String(parameters['Node Cost Font'] || 'GameFont'); +Felski.Techtree.TTNCFontSize = Number(parameters['Node Cost Font Size'] || 28); +Felski.Techtree.TTNCFontColor = Number(parameters['Node Cost Font Color'] || 0); +Felski.Techtree.TTNCFontColorGreyedOut = Number(parameters['Node Cost Font Color Greyed Out'] || 8); + + +function Scene_Techtree() { + this.initialize.apply(this, arguments); +} + +function Window_Techtree_Info() { + this.initialize.apply(this, arguments); +} + +function Window_Techtree() { + this.initialize.apply(this, arguments); +} + +function Window_Techtree_Select() { + this.initialize.apply(this, arguments); +} + +function Window_Techtree_Confirm() { + this.initialize.apply(this, arguments); +} + +function Window_Techtree_Currency() { + this.initialize.apply(this, arguments); +} + +(function() { + + +//************************************************************************************************ +// +// Game_Interpreter +// +//************************************************************************************************ + + Felski.Techtree.Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand; + Game_Interpreter.prototype.pluginCommand = function(command, args) { + Felski.Techtree.Game_Interpreter_pluginCommand.call(this, command, args); + command = command.toUpperCase(); + if (command === 'TECHTREE'){ + var arg0 = args[0].toUpperCase(); + if(arg0 === 'DISPLAYONLY'){ + Felski.Techtree.menuOnlyDisplayBuffer = true; + }else if(arg0 === 'PRESELECT'){ + Felski.Techtree.preselectedTree = args[1]; + }else if(arg0 === 'SINGLE'){ + Felski.Techtree.singleTreeView = true; + }else{ + var id = Number(args[0]); + SceneManager.push(Scene_Techtree); + SceneManager.prepareNextScene(id, Felski.Techtree.preselectedTree); + Felski.Techtree.preselectedTree = null; + } + } + if (command === 'RESETTECHTREES'){ // actor + var bool = Boolean(args[1]); + $gameActors.actor(args[0]).resetSkilltrees(bool); + } + if (command === 'RESETTECHTREE'){ // actor, tree uid + var bool = Boolean(args[2]); + $gameActors.actor(args[0]).resetSkilltree(args[1], bool); + } + if (command === 'ACTIVENODES'){ // actor, tree uid, target variable + $gameVariables.setValue(args[2], $gameActors.actor(args[0]).getUnlockedNodesCount(args[1])); + } + if (command === 'ADDTECHTREE'){ // actor, tree uid + $gameActors.actor(args[0]).addSkilltree(args[1]); + } + if (command === 'ACTIVATENODE'){ // actor, tree uid, node uid + $gameActors.actor(args[0]).activateNode(args[1], args[2], false); + } + if (command === 'DEACTIVATENODE'){ // actor, tree uid, node uid + $gameActors.actor(args[0]).deactivateNode(args[1], args[2]); + } + }; + +//************************************************************************************************ +// +// Database Load +// +//************************************************************************************************ + + DataManager.initTechtrees = function() { + for (var i = 0; i < $dataTechtrees.length; i++) { + var nodes = $dataTechtrees[i].nodes; + for (var j = 0; j < nodes.length; j++) { + nodes[j].active = false; + } + } + }; + + Felski.Techtree.DataManager_onLoad = DataManager.onLoad; + DataManager.onLoad = function(object) { + Felski.Techtree.DataManager_onLoad.call(this, object); + if (object === $dataTechtrees ){ + Felski.Techtree.techtreeHash = Felski.Techtree.hash(JSON.stringify($dataTechtrees)); + DataManager.initTechtrees(); + } + }; + + Felski.Techtree.hash = function(str){ // based on https://stackoverflow.com/a/7616484, credits to https://stackoverflow.com/users/495174/esmiralha + var hash = 0; + var i; + var chr; + if (str.length === 0) return hash; + for (i = 0; i < str.length; i++) { + chr = str.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + return hash; + }; + + +//************************************************************************************************ +// +// Game Object Init +// +//************************************************************************************************ + + Felski.Techtree.DataManager_createGameObjects = DataManager.createGameObjects; + DataManager.createGameObjects = function() { + Felski.Techtree.DataManager_createGameObjects.call(this); + DataManager.readTechtreeNodes($dataActors); + DataManager.readTechtreeNodes($dataClasses); + }; + + DataManager.readTechtreeNodes = function(group) { + var note1 = /<(?:techtree)>/i; + var note2 = /<(?:\/techtree)>/i; + var techtree = false; + for (var i = 1; i < group.length; i++) { + var obj = group[i]; + obj.techtrees = []; + var notedata = obj.note.split(/[\r\n]+/); + for (var j = 0; j < notedata.length; j++) { + var line = notedata[j]; + if (line.match(note1)) { + techtree = true; + }else if (line.match(note2)) { + techtree = false; + }else if (techtree) { + obj.techtrees.push(line); + } + } + } + }; + + DataManager.bindClassTrees = function(group) { + for (var i = 1; i < $dataClasses.length; i++) { + var techtrees = $dataClasses[i].techtrees; + $dataClasses[i].techtrees = []; + for (var j = 0; j < techtrees.length; j++) { + var techtreeData = $gameSystem.searchTechtrees(techtrees[j]); + if(techtreeData){ + $dataClasses[i].techtrees.push(jsonCopy(techtreeData)); + }else{ + console.warn($dataClasses[i].name()+" has a techtree notetag that points to no tree in the Techtrees.json file. UID: " + techtrees[j]); + } + } + } + }; + + Felski.Techtree.Scene_Boot_loadSystemImages = Scene_Boot.loadSystemImages; + Scene_Boot.loadSystemImages = function() { + Felski.Techtree.Scene_Boot_loadSystemImages.call(this); + ImageManager.reserveTechtree('Tech_Hidden'); + ImageManager.reserveTechtree('Tech_Inactive'); + ImageManager.reserveTechtree('Tech_Unlockable'); + ImageManager.reserveTechtree('Tech_Active'); + ImageManager.reserveTechtree('Arrows'); + ImageManager.reserveTechtree('Arrows_Active'); + }; + + ImageManager.reserveTechtree = function(filename, hue, reservationId) { + return this.reserveBitmap('img/system/techtree/', filename, hue, false, reservationId || this._systemReservationId); + }; + + ImageManager.reserveTechtreeBGIMG = function(filename, hue, reservationId) { + return this.reserveBitmap('img/system/techtree/bgimg/', filename, hue, false, reservationId || this._systemReservationId); + }; + + ImageManager.loadTechtree = function(filename, hue) { + return this.loadBitmap('img/system/techtree/', filename, hue, false); + }; + + ImageManager.loadTechtreeBGIMG = function(filename, hue) { + return this.loadBitmap('img/system/techtree/bgimg/', filename, hue, false); + }; + + +//************************************************************************************************ +// +// Saving and Loading - Update Techtree +// +//************************************************************************************************ + + Felski.Techtree.DataManager_makeSaveContents = DataManager.makeSaveContents; + DataManager.makeSaveContents = function() { + var contents = Felski.Techtree.DataManager_makeSaveContents.call(this); + contents.techtreeHash = Felski.Techtree.techtreeHash; + return contents; + }; + + Felski.Techtree.DataManager_extractSaveContents = DataManager.extractSaveContents; + DataManager.extractSaveContents = function(contents) { + Felski.Techtree.DataManager_extractSaveContents.call(this, contents); + if(Felski.Techtree.techtreeHash === contents.techtreeHash){ + // same tree + console.log("Saved tree and tree in game files are the same."); + }else{ + // new tree + console.warn("Loading game with different tree."); + if(Felski.Techtree.updateTechtrees){ + this.updateTechtrees(); + } + } + }; + + DataManager.updateTechtrees = function() { + for (var i = 0; i < $gameActors._data.length; i++) { + if($gameActors._data[i]){ + $gameActors._data[i].updateSkilltrees(); + } + } + }; + + +//************************************************************************************************ +// +// Game_Actor Techtree Technical Functions +// +//************************************************************************************************ + + Felski.Techtree.Game_Actor_initMembers = Game_Actor.prototype.initMembers; + Game_Actor.prototype.initMembers = function() { + Felski.Techtree.Game_Actor_initMembers.call(this); + this._techtrees = []; + }; + + Felski.Techtree.Game_Actor_setup = Game_Actor.prototype.setup; + Game_Actor.prototype.setup = function(actorId) { + Felski.Techtree.Game_Actor_setup.call(this, actorId); + this._classInited = [this._classId]; + var actor = $dataActors[actorId]; + this._techtrees = actor.techtrees || []; + this.initSkilltrees(); + this.initClassSkilltrees(); + }; + + Game_Actor.prototype.addSkilltree = function(uid) { + var techtreeData = $gameSystem.searchTechtrees(uid); + if(techtreeData){ + this._techtrees.push(jsonCopy(techtreeData)); + }else{ + console.warn(this.name()+" has a techtree notetag that points to no tree in the Techtrees.json file. UID: " + uid); + } + }; + + Game_Actor.prototype.updateSkilltrees = function() { + for (var i = 0; i < this._techtrees.length; i++) { + var activeNodes = this.getActiveNodeIds(this._techtrees[i]); + this.resetSkilltree(this._techtrees[i].uid, false); + var techtreeData = $gameSystem.searchTechtrees(this._techtrees[i].uid); + if(techtreeData){ + this._techtrees[i] = jsonCopy(techtreeData); + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(activeNodes.indexOf(this._techtrees[i].nodes[j].technode.uid) >= 0){ + this.activateNode(this._techtrees[i].uid, this._techtrees[i].nodes[j].technode.uid, true); + } + } + /* + // activate nodes that were active before. + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(activeNodes.indexOf(this._techtrees[i].nodes[j].technode.uid) >= 0){ + this._techtrees[i].nodes[j].active = true; + } + } + */ + }else{ + console.warn(this.name()+" loads a techtree that points to no tree in the Techtrees.json file. UID: " + this._techtrees[i].uid); + } + } + }; + + Game_Actor.prototype.getActiveNodeIds = function(tree) { + var ret = []; + for (var i = 0; i < tree.nodes.length; i++) { + if(tree.nodes[i].active){ + ret.push(tree.nodes[i].technode.uid); + } + } + return ret; + }; + + Game_Actor.prototype.onActivateTechtreeNode = function(technode, loading) { + // Switches + var onActivate = technode.onActivate; + for (var i = 0; i < onActivate.switches.length; i++) { + var lever = onActivate.switches[i]; + $gameSwitches.setValue(lever.id, lever.value); + } + + // Skills + for (var i = 0; i < onActivate.skills.length; i++) { + this.learnSkill(onActivate.skills[i]); + } + + // Stats + for (var i = 0; i < 8; i++) { + if(onActivate.stats){ + if(onActivate.stats[i]){ + this.addParam(i, onActivate.stats[i]); + } + } + } + + // Eval + if(onActivate.eval){ + if(onActivate.eval.onActivate){ + var code = String(onActivate.eval.onActivate); + try { + eval(code); + } catch (e) { + console.log(message); + console.log(code || 'NON-EXISTENT'); + console.error(e); + } + } + } + + // Common Events + if(!loading){ + for (var i = 0; i < onActivate.commonevents.length; i++) { + $gameTemp.reserveCommonEvent(onActivate.commonevents[i].id); + if(onActivate.commonevents[i].close){ + SceneManager.goto(Scene_Map); + } + } + } + }; + + Game_Actor.prototype.onDeactivateTechtreeNode = function(technode) { + // Switches + var onActivate = technode.onActivate; + for (var i = 0; i < onActivate.switches.length; i++) { + var lever = onActivate.switches[i]; + $gameSwitches.setValue(lever.id, !lever.value); + } + + // Skills + for (var i = 0; i < onActivate.skills.length; i++) { + this.forgetSkill(onActivate.skills[i]); + } + + // Stats + for (var i = 0; i < 8; i++) { + if(onActivate.stats){ + if(onActivate.stats[i]){ + this.addParam(i, -1*onActivate.stats[i]); + } + } + } + + // Eval + if(onActivate.eval){ + if(onActivate.eval.onDeactivate){ + var code = String(onActivate.eval.onDeactivate); + try { + eval(code); + } catch (e) { + console.log(message); + console.log(code || 'NON-EXISTENT'); + console.error(e); + } + } + } + /* + // Common Events + for (var i = 0; i < onActivate.commonevents.length; i++) { + $gameTemp.reserveCommonEvent(onActivate.commonevents[i].id); + if(onActivate.commonevents[i].close){ + SceneManager.goto(Scene_Map); + } + } + */ + }; + + Game_Actor.prototype.initSkilltrees = function() { + var techtrees = this._techtrees; + this._techtrees = []; + for (var i = 0; i < techtrees.length; i++) { + this.addSkilltree(techtrees[i]); + } + }; + + Game_Actor.prototype.initClassSkilltrees = function() { + var techtrees = $dataClasses[this._classId].techtrees; + for (var i = 0; i < techtrees.length; i++) { + var techtreeData = $gameSystem.searchTechtrees(techtrees[i]); + if(techtreeData){ + var data = jsonCopy(techtreeData); + data.fromClass = this._classId; + this._techtrees.push(data); + }else{ + console.warn($dataClasses[this._classId].name+" has a techtree notetag that points to no tree in the Techtrees.json file. UID: " + techtrees[i]); + } + } + }; + +//************************************************************************************************ +// +// Plugin Command Functions +// +//************************************************************************************************ + + Game_Actor.prototype.activateNode = function(treeUid, nodeUid, loading) { + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].uid === treeUid){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].technode.uid === nodeUid){ + this._techtrees[i].nodes[j].active = true; + this.onActivateTechtreeNode(this._techtrees[i].nodes[j].technode, loading); + return; + } + } + } + } + console.warn("Activating node "+nodeUid+" for "+this.name()+" in tree "+treeUid+" has failed."); + }; + + Game_Actor.prototype.deactivateNode = function(treeUid, nodeUid) { + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].uid === treeUid){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].technode.uid === nodeUid){ + this._techtrees[i].nodes[j].active = false; + this.onDeactivateTechtreeNode(this._techtrees[i].nodes[j].technode); + return; + } + } + } + } + console.warn("Deactivating node "+nodeUid+" for "+this.name()+" in tree "+treeUid+" has failed."); + }; + + Game_Actor.prototype.resetSkilltrees = function(refund) { + for (var i = 0; i < this._techtrees.length; i++) { + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active){ + this._techtrees[i].nodes[j].active = false; + this.onDeactivateTechtreeNode(this._techtrees[i].nodes[j].technode); + if(refund){ + var costs = this._techtrees[i].nodes[j].technode.costs; + this.refundCosts(costs); + } + } + } + } + }; + + Game_Actor.prototype.resetSkilltree = function(uid, refund) { + var found = false; + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].uid === uid){ + found = true; + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active){ + this._techtrees[i].nodes[j].active = false; + this.onDeactivateTechtreeNode(this._techtrees[i].nodes[j].technode); + if(refund){ + var costs = this._techtrees[i].nodes[j].technode.costs; + var classId = this._techtrees[i].fromClass; + this.refundCosts(costs, classId); + } + } + } + } + } + if(!found){ + console.warn("Resetting skilltree "+uid+" has failed for Actor "+this.name()); + } + }; + + Game_Actor.prototype.refundCosts = function(costs, classId) { + if(costs.gold > 0){ + $gameParty.gainGold(costs.gold); + } + if(costs.jp > 0 && Imported.YEP_JobPoints){ + if(classId){ + this.gainJp(costs.jp, classId); + }else{ + this.gainJp(costs.jp); + } + } + if(costs.items.length > 0){ + for (var i = 0; i < costs.items.length; i++) { + var item = $dataItems[costs.items[i].id]; + var cost = costs.items[i].amount; + $gameParty.gainItem(item, cost, false); + } + } + if(costs.weapons.length > 0){ + for (var i = 0; i < costs.weapons.length; i++) { + var weapon = $dataWeapons[costs.weapons[i].id]; + var cost = costs.weapons[i].amount; + $gameParty.gainItem(weapon, cost, false); + } + } + if(costs.armors.length > 0){ + for (var i = 0; i < costs.armors.length; i++) { + var armor = $dataArmors[costs.armors[i].id]; + var cost = costs.armors[i].amount; + $gameParty.gainItem(armor, cost, false); + } + } + }; + + Game_Actor.prototype.getUnlockedNodesCount = function(uid) { + var count = 0; + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].uid === uid){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active) count++; + } + } + } + return count; + }; + +//************************************************************************************************ +// +// Class Change +// +//************************************************************************************************ + + Felski.Techtree.Game_Actor_changeClass = Game_Actor.prototype.changeClass; + Game_Actor.prototype.changeClass = function(classId, keepExp) { + this._oldClassId = this._classId; + Felski.Techtree.Game_Actor_changeClass.call(this, classId, keepExp); + if(Felski.Techtree.CCUnlearn) this.unlearnSkilltree(classId); + if(Felski.Techtree.CCRemoveStats) this.removeStats(classId); + if(Felski.Techtree.CCRunDeEval) this.runDeactivateEval(classId); + this.addSkilltreeIfNeeded(classId); + this.toggleSkilltreeSwitches(classId); + if(Felski.Techtree.CCRelearn) this.relearnSkilltree(classId); + if(Felski.Techtree.CCReaddStats) this.reAddStats(classId); + if(Felski.Techtree.CCRunAcEval) this.runActivateEval(classId); + }; + + Game_Actor.prototype.addSkilltreeIfNeeded = function(classId) { //adds the new skilltree if needed + if(!this._classInited.includes(classId)){ + this._classInited.push(classId); + var techtrees = $dataClasses[classId].techtrees; + if(!techtrees) return; + for (var i = 0; i < techtrees.length; i++) { + var techtreeData = $gameSystem.searchTechtrees(techtrees[i]); + var data = jsonCopy(techtreeData); + data.fromClass = this._classId; + if(techtreeData){ + this._techtrees.push(data); + }else{ + console.warn(this.name()+" has a techtree notetag that points to no tree in the Techtrees.json file. UID: " + techtrees[i]); + } + } + } + }; + +//************************************************************************************************ +// +// Class Change onActivates +// +//************************************************************************************************ + + Game_Actor.prototype.unlearnSkilltree = function(classId) { //unlearns all skills/stats except the ones from classId and undefined + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass !== classId && this._techtrees[i].fromClass !== undefined){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + for (var k = 0; k < this._techtrees[i].nodes[j].technode.onActivate.skills.length; k++) { + this.forgetSkill(this._techtrees[i].nodes[j].technode.onActivate.skills[k]); + } + } + } + } + }; + + Game_Actor.prototype.relearnSkilltree = function(classId) { //relearns all skills from classId + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass === classId && this._techtrees[i].fromClass !== undefined){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active){ + for (var k = 0; k < this._techtrees[i].nodes[j].technode.onActivate.skills.length; k++) { + this.learnSkill(this._techtrees[i].nodes[j].technode.onActivate.skills[k]); + } + } + } + } + } + }; + + Game_Actor.prototype.removeStats = function(classId) { + if(this._oldClassId === classId) return; + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass === this._oldClassId && this._techtrees[i].fromClass !== undefined){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active){ + if(this._techtrees[i].nodes[j].technode.onActivate.stats){ + for (var k = 0; k < 8; k++) { + if(this._techtrees[i].nodes[j].technode.onActivate.stats[k]){ + this.addParam(k, -1*this._techtrees[i].nodes[j].technode.onActivate.stats[k]); + } + } + } + } + } + } + } + }; + + Game_Actor.prototype.reAddStats = function(classId) { + if(this._oldClassId === classId) return; + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass === classId && this._techtrees[i].fromClass !== undefined){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active){ + if(this._techtrees[i].nodes[j].technode.onActivate.stats){ + for (var k = 0; k < 8; k++) { + if(this._techtrees[i].nodes[j].technode.onActivate.stats[k]){ + this.addParam(k, this._techtrees[i].nodes[j].technode.onActivate.stats[k]); + } + } + } + } + } + } + } + }; + + Game_Actor.prototype.runDeactivateEval = function(classId) { + if(this._oldClassId === classId) return; + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass === this._oldClassId && this._techtrees[i].fromClass !== undefined){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active){ + if(this._techtrees[i].nodes[j].technode.onActivate.eval){ + if(this._techtrees[i].nodes[j].technode.onActivate.eval.onDeactivate){ + var code = String(this._techtrees[i].nodes[j].technode.onActivate.eval.onDeactivate); + try { + eval(code); + } catch (e) { + console.log(message); + console.log(code || 'NON-EXISTENT'); + console.error(e); + } + } + } + } + } + } + } + }; + + Game_Actor.prototype.runActivateEval = function(classId) { + if(this._oldClassId === classId) return; + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass === classId && this._techtrees[i].fromClass !== undefined){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + if(this._techtrees[i].nodes[j].active){ + if(this._techtrees[i].nodes[j].technode.onActivate.eval){ + if(this._techtrees[i].nodes[j].technode.onActivate.eval.onActivate){ + var code = String(this._techtrees[i].nodes[j].technode.onActivate.eval.onActivate); + try { + eval(code); + } catch (e) { + console.log(message); + console.log(code || 'NON-EXISTENT'); + console.error(e); + } + } + } + } + } + } + } + }; + + Game_Actor.prototype.toggleSkilltreeSwitches = function(classId) { //toggles all switches except the ones from classId and undefined + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass !== classId && this._techtrees[i].fromClass !== undefined){ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + for (var k = 0; k < this._techtrees[i].nodes[j].technode.onActivate.switches.length; k++) { + var lever = this._techtrees[i].nodes[j].technode.onActivate.switches[k]; + $gameSwitches.setValue(lever.id, !lever.value); + } + } + }else{ + for (var j = 0; j < this._techtrees[i].nodes.length; j++) { + for (var k = 0; k < this._techtrees[i].nodes[j].technode.onActivate.switches.length; k++) { + if(this._techtrees[i].nodes[j].active){ + var lever = this._techtrees[i].nodes[j].technode.onActivate.switches[k]; + $gameSwitches.setValue(lever.id, lever.value); + } + } + } + } + } + }; + +//************************************************************************************************ +// +// Search Functions +// +//************************************************************************************************ + + Game_System.prototype.searchTechtrees = function(name) { + var search = name; + var obj = $dataTechtrees.filter(function ( obj ){ + return obj.uid === search; + })[0]; + return obj; + }; + + Game_System.prototype.searchTechtree = function(tree, uid) { + var search = uid; + var obj = tree.nodes.filter(function ( obj ){ + return obj.technode.uid === search; + })[0]; + return obj; + }; + + Game_System.prototype.searchTechtreeDepthLane = function(tree, depth, lane) { + var search1 = depth; + var search2 = lane; + var obj = tree.nodes.filter(function ( obj ){ + return obj.technode.depth == search1 && obj.technode.lane == search2; + })[0]; + return obj; + }; + +//************************************************************************************************ +// +// Menu Adjustments +// +//************************************************************************************************ + + Felski.Techtree.Window_MenuCommand_addMainCommands = Window_MenuCommand.prototype.addMainCommands; + Window_MenuCommand.prototype.addMainCommands = function() { + Felski.Techtree.Window_MenuCommand_addMainCommands.call(this); + var enabled = this.areMainCommandsEnabled(); + if(Felski.Techtree.TTMenuVisible){ + this.addCommand(Felski.Techtree.TTMenuText, 'skilltree', enabled); + } + }; + + Felski.Techtree.Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow; + Scene_Menu.prototype.createCommandWindow = function() { + Felski.Techtree.Scene_Menu_createCommandWindow.call(this); + if(Felski.Techtree.TTMenuVisible){ + this._commandWindow.setHandler('skilltree', this.commandPersonal.bind(this)); + } + }; + + Felski.Techtree.Scene_Menu_onPersonalOk = Scene_Menu.prototype.onPersonalOk; + Scene_Menu.prototype.onPersonalOk = function() { + Felski.Techtree.Scene_Menu_onPersonalOk.call(this); + if(Felski.Techtree.TTMenuVisible){ + switch (this._commandWindow.currentSymbol()) { + case 'skilltree': + SceneManager.push(Scene_Techtree); + break; + } + } + }; + + Felski.Techtree.Scene_Menu_initialize = Scene_Menu.prototype.initialize; + Scene_Menu.prototype.initialize = function() { + var members = $gameParty.allMembers(); + for (var i = 0; i < members.length; i++) { + if(members[i]._techtrees){ + for (var j = 0; j < members[i]._techtrees.length; j++) { + if(members[i]._techtrees[j].bgimg) ImageManager.reserveTechtreeBGIMG(members[i]._techtrees[j].bgimg); + for (var h = 0; h < members[i]._techtrees[j].nodes.length; h++) { + if(members[i]._techtrees[j].nodes[h].technode.bgimg) ImageManager.reserveTechtreeBGIMG(members[i]._techtrees[j].nodes[h].technode.bgimg); + } + } + } + } + Felski.Techtree.Scene_Menu_initialize.call(this); + }; + + //Felski.Techtree.Scene_Class_commandLearnSkill = Scene_Class.prototype.commandLearnSkill; +if(Imported.YEP_ClassChangeCore) { + if (Felski.Techtree.CCCommand) { + Scene_Class.prototype.commandLearnSkill = function() { + SceneManager.push(Scene_Techtree); + }; + + Window_ClassCommand.prototype.addSkillLearnCommand = function() { + this.addCommand(Felski.Techtree.TTMenuText, 'learnSkill', true); + }; + } +} + +//************************************************************************************************ +// +// Scene_Techtree +// +//************************************************************************************************ + + Scene_Techtree.prototype = Object.create(Scene_MenuBase.prototype); + Scene_Techtree.prototype.constructor = Scene_Techtree; + + Scene_Techtree.prototype.initialize = function() { + Scene_MenuBase.prototype.initialize.call(this); + }; + + Scene_Techtree.prototype.create = function() { + Scene_MenuBase.prototype.create.call(this); + }; + + Scene_Techtree.prototype.start = function() { + Scene_MenuBase.prototype.start.call(this); + this._activeTree = null; + this.createTechtreeInfo(); + this.createTechtreeWindow(); + this.createTechtreeSelect(); + var x = this._window_TechtreeSelect.windowWidth() + this._window_TechtreeInfo.windowWidth(); + this.createTechtreeCurrency(x); + this.createTechtreeConfirmWindow(); + + if(Felski.Techtree.singleTreeView){ + this._window_Techtree.activate(); + }else{ + this._window_TechtreeSelect.activate(); + } + }; + + Scene_Techtree.prototype.prepare = function(actorId, treeId) { + $gameParty.setMenuActor($gameActors.actor(actorId)); + this._startTreeId = treeId || false; + }; + + Scene_Techtree.prototype.createTechtreeInfo = function(){ + this._window_TechtreeInfo = new Window_Techtree_Info(0, 0, this._actor); + this.addWindow(this._window_TechtreeInfo); + this._window_TechtreeInfo.deactivate(); + }; + + Scene_Techtree.prototype.createTechtreeSelect = function(){ + var x = this._window_TechtreeInfo.windowWidth() || 0; + var h = this._window_TechtreeInfo.windowHeight() || 0; + var w = Graphics.width - x*2; + this._window_TechtreeSelect = new Window_Techtree_Select(x, 0, w, h, this._actor); + var trees = this._actor._techtrees; + for (var i = 0; i < trees.length; i++) { + this._window_TechtreeSelect.setHandler(i, this.onTechtreeSelectOk.bind(this, arguments)); + } + this._window_TechtreeSelect.setHandler('cancel', this.onTechtreeLeave.bind(this)); + this._window_TechtreeSelect.setTechtreeWindow(this._window_Techtree); + + this.addWindow(this._window_TechtreeSelect); + this._window_TechtreeSelect.select(this._window_Techtree.activeTreeIndex()); + if(Felski.Techtree.singleTreeView){ + this._window_TechtreeSelect.deactivate(); + }else{ + this._window_TechtreeSelect.activate(); + } + }; + + Scene_Techtree.prototype.createTechtreeWindow = function(){ + var y = this._window_TechtreeInfo.windowHeight() || 0; + this._window_Techtree = new Window_Techtree(0, y, y, this._actor, this._startTreeId); + this._window_Techtree.setOkHandler(this.onTechtreeOk.bind(this, arguments)); + this._window_Techtree.setCancelHandler(this.onTechtreeCancel.bind(this)); + this.addWindow(this._window_Techtree); + if(Felski.Techtree.singleTreeView){ + this._window_Techtree.activate(); + }else{ + this._window_Techtree.deactivate(); + } + }; + + Scene_Techtree.prototype.createTechtreeConfirmWindow = function(){ + if(SceneManager._stack[SceneManager._stack.length-1] !== Scene_Map && Felski.Techtree.menuOnlyDisplay){ + this._onlyDisplay = true; + }else{ + this._onlyDisplay = Felski.Techtree.menuOnlyDisplayBuffer; + } + Felski.Techtree.menuOnlyDisplayBuffer = false; + this._window_TechtreeConfirm = new Window_Techtree_Confirm(this._actor, this._onlyDisplay); + this._window_TechtreeConfirm.setOkHandler(this.onTechtreeConfirmOk.bind(this, arguments)); + this._window_TechtreeConfirm.setCancelHandler(this.onTechtreeConfirmCancel.bind(this)); + this.addWindow(this._window_TechtreeConfirm); + this._window_TechtreeConfirm.deactivate(); + this._window_TechtreeConfirm.hide(); + }; + + + Scene_Techtree.prototype.createTechtreeCurrency = function(x){ + this._window_TechtreeCurrency = new Window_Techtree_Currency(x, 0, this._actor); + this._window_TechtreeSelect.setTechtreeCurrencyWindow(this._window_TechtreeCurrency); + this.addWindow(this._window_TechtreeCurrency); + this._window_TechtreeCurrency.deactivate(); + }; + + + Scene_Techtree.prototype.update = function() { + Scene_MenuBase.prototype.update.call(this); + this.removeAnimation(); + }; + + Scene_Techtree.prototype.onTechtreeLeave = function() { + Felski.Techtree.singleTreeView = false; + SceneManager.pop(); + }; + + Scene_Techtree.prototype.onTechtreeSelectOk = function(args, treeId) { + this._window_TechtreeSelect.deactivate(); + this._window_TechtreeCurrency.setTree(treeId); + this._window_Techtree.changeTree(treeId); + this._window_Techtree.activate(); + }; + + Scene_Techtree.prototype.onTechtreeOk = function(args, node, tree, rect) { + this._window_Techtree.deactivate(); + this._window_TechtreeConfirm.setNode(node); + this._window_TechtreeConfirm.setAnimationPos(rect.x, rect.y); + this._window_TechtreeConfirm.setTree(tree); + this._window_TechtreeConfirm.changebgimg(); + this._window_TechtreeConfirm.show(); + this._window_TechtreeConfirm.activate(); + }; + + Scene_Techtree.prototype.onTechtreeCancel = function() { + if(Felski.Techtree.singleTreeView){ + this.onTechtreeLeave(); + }else{ + this._window_Techtree.deactivate(); + this._window_TechtreeSelect.activate(); + } + }; + + Scene_Techtree.prototype.onTechtreeConfirmCancel = function() { + this._window_TechtreeConfirm.deactivate(); + this._window_TechtreeConfirm.hide(); + this._window_Techtree.activate(); + }; + + Scene_Techtree.prototype.onTechtreeConfirmOk = function(args, node) { + node.active = true; + this._window_TechtreeConfirm.deactivate(); + this._window_TechtreeConfirm.hide(); + this._window_Techtree.changed(); + this._window_Techtree.activate(); + }; + + Scene_Techtree.prototype.removeAnimation = function(){ + if(!this._activateAnimation) return; + if(this._activateAnimation.finished()){ + this.removeChild(this._activateAnimation); + } + }; + + +//************************************************************************************************ +// +// Window_Techtree +// +//************************************************************************************************ + + Window_Techtree.prototype = Object.create(Window_Base.prototype); + Window_Techtree.prototype.constructor = Window_Techtree; + + Window_Techtree.prototype.initialize = function(x, y, h2, actor, startTree) { + this._topMargin = h2 || 0; + var width = this.windowWidth(); + var height = this.windowHeight(); + + this._actor = actor; + this._techtrees = this._actor._techtrees; + this._activeTree; + this._activeTreeIndex = 0; + this._startTree = startTree || false; + this._selectedDepth = -1; + this._selectedLane = -1; + this._selectedNode = null; + this._changed = true; + this._buttonSprites = []; + + this.initCursorInfos(); + this.initActiveTree(); + this.initTreeInfos(); + Window_Base.prototype.initialize.call(this, x, y, width, height); + this.changebgimg(); + }; + + Window_Techtree.prototype.initCursorInfos = function(){ + this._maxDepth = 0; + this._maxLanes = 0; + this._firstVisibleDepth = 1; + this._firstVisibleLane = 1; + this._lastVisibleDepth = this._firstVisibleDepth + this.visibleDepths(); + this._lastVisibleLane = this._firstVisibleLane + this.visibleLanes(); + }; + + Window_Techtree.prototype.initActiveTree = function() { + if(this._startTree){ + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].uid === this._startTree){ + this._activeTree = this._techtrees[i]; + this._activeTreeIndex = i; + return; + } + } + } + for (var i = 0; i < this._techtrees.length; i++) { + if(this._techtrees[i].fromClass === this._actor._classId || this._techtrees[i].fromClass === undefined){ + this._activeTree = this._techtrees[i]; + this._activeTreeIndex = i; + return; + } + } + }; + + Window_Techtree.prototype.initTreeInfos = function() { + if(!this.hasTechtrees()) return; + var lane = 0; + var depth = 0; + var parents; + if(this._activeTree){ + var tree = this._activeTree; + var nodes = tree.nodes; + for (var i = 0; i < nodes.length; i++) { // reset children + nodes[i].technode.children = []; + } + for (var i = 0; i < nodes.length; i++) { // init children, max depth and max lane + if(nodes[i].technode.parents.length > 0){ + parents = nodes[i].technode.parents; + for (var j = 0; j < parents.length; j++) { + var node = $gameSystem.searchTechtree(tree, parents[j].parent); + if(!node){ + console.warn("Couldn't find parent " + parents[j].parent + " for node " + nodes[i].technode.uid + "("+nodes[i].technode.header+")."); + }else{ + node.technode.children.push(nodes[i].technode.uid); + } + } + } + if(nodes[i].technode.depth > depth){ + depth = nodes[i].technode.depth; + if(this._selectedDepth === -1){ + this._selectedDepth = depth; + if(depth > 1){ + this._firstVisibleDepth = depth - 1; + }else{ + this._firstVisibleDepth = depth; + } + this._lastVisibleDepth = this._firstVisibleDepth + this.visibleDepths(); + } + } + if(nodes[i].technode.lane > lane){ + lane = nodes[i].technode.lane; + if(this._selectedLane === -1){ + this._selectedLane = lane; + if(lane > 1){ + this._firstVisibleLane = lane - 1; + }else{ + this._firstVisibleLane = lane; + } + this._lastVisibleLane = this._firstVisibleLane + this.visibleLanes(); + } + } + } + } + this._maxDepth = depth; + this._maxLanes = lane; + this._selectedNode = $gameSystem.searchTechtreeDepthLane(this._activeTree, this._selectedDepth, this._selectedLane); + }; + + Window_Techtree.prototype.changebgimg = function() { + if(!Felski.Techtree.TTMenuBackground) return; + if(this._activeTree){ + if(this._activeTree.bgimg){ + var bitmap = ImageManager.loadTechtreeBGIMG(this._activeTree.bgimg); + var newWidth = Graphics.boxWidth; + var newHeight = Graphics.boxHeight; + this.backOpacity = Felski.Techtree.TTMenuBackgroundOpacity; + this._windowBackSprite.bitmap = new Bitmap(newWidth, newHeight); + this._windowBackSprite.bitmap.blt(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, newWidth, newHeight); + } + } + }; + + Window_Techtree.prototype.changed = function() { + this._changed = true; + }; + + Window_Techtree.prototype.changeTree = function(id) { + if(this._activeTree !== this._techtrees[id]){ + this._activeTree = this._techtrees[id]; + this._selectedDepth = -1; + this._selectedLane = -1; + this.initCursorInfos(); + this.initTreeInfos(); + this.changed(); + } + }; + + +//************************************************************************************************ +// +// Window_Techtree // Technical Functions +// +//************************************************************************************************ + + Window_Techtree.prototype.update = function() { + Window_Base.prototype.update.call(this); + if(this.visible){ + this.processCursorMove(); + this.processHandling(); + this.processWheel(); + this.processTouch(); + if(this._changed){ + this.drawAll(); + this._changed = false; + } + } + }; + + Window_Techtree.prototype.show = function() { + Window_Base.prototype.show.call(this); + }; + + Window_Techtree.prototype.windowWidth = function() { + return Graphics.width; + }; + + Window_Techtree.prototype.windowHeight = function() { + return Graphics.height - this._topMargin; + }; + + Window_Techtree.prototype.laneHeight = function() { + if(Felski.Techtree.horizontal){ + return (this.windowHeight() - this.standardPadding()) / Felski.Techtree.Lanes; + }else{ + return this.windowHeight(); + } + }; + + Window_Techtree.prototype.laneWidth = function() { + if(Felski.Techtree.horizontal){ + return this.windowWidth(); + }else{ + return (this.windowWidth() - this.standardPadding()) / Felski.Techtree.Lanes; + } + }; + + Window_Techtree.prototype.selectedNode = function() { + return this._selectedNode; + }; + + Window_Techtree.prototype.indexObj = function() { + return {"depth": this._selectedDepth, "lane": this._selectedLane}; + }; + + Window_Techtree.prototype.maxDepth = function() { + return this._maxDepth; + }; + + Window_Techtree.prototype.maxLanes = function() { + return this._maxLanes; + }; + + Window_Techtree.prototype.firstVisibleDepth = function() { + return this._firstVisibleDepth; + }; + + Window_Techtree.prototype.firstVisibleLane = function() { + return this._firstVisibleLane; + }; + + Window_Techtree.prototype.lastVisibleDepth = function() { + return this._lastVisibleDepth; + }; + + Window_Techtree.prototype.lastVisibleLane = function() { + return this._lastVisibleLane; + }; + + Window_Techtree.prototype.visibleDepths = function() { + return Math.floor(this.windowWidth() / (Felski.Techtree.NodeWidth + Felski.Techtree.NodeGap)) - 1; + }; + + Window_Techtree.prototype.visibleLanes = function() { + return Felski.Techtree.Lanes - 1; + }; + + Window_Techtree.prototype.isActive = function() { + return (this.active); + }; + + Window_Techtree.prototype.isOpenAndActive = function() { + return this.isOpen() && this.active; + }; + + Window_Techtree.prototype.activeTreeIndex = function() { + return this._activeTreeIndex; + }; +//************************************************************************************************ +// +// Window_Techtree // Draw Functions +// +//************************************************************************************************ + + Window_Techtree.prototype.drawAll = function() { + this.contents.clear(); + if(this.hasTechtrees()){ + this.drawTechtree(); + this.updateCursor(); + }else{ + //this.drawInfo(); + } + }; + + Window_Techtree.prototype.drawInfo = function() { + var w = this.windowWidth(); + var h = this.windowHeight(); + var x = 0; + var y = h/3; + var lh = this.lineHeight(); + var text = "There is no techtree maintained for "+this._actor.name()+"."; + this.drawText(text, x, y, w, 'center'); + this.drawText(Felski.Techtree.TTNAClose, x, y+lh, w, 'center'); + this.setCursorRect(w/3, y+lh, w/3, lh); + }; + + Window_Techtree.prototype.drawActorInfo = function() { + var w = Window_Base._faceWidth; + var w2 = (w/4)*3 - w/4; + var w3 = w - w/4; + var lh = this.lineHeight(); + + var actor = this._actor; + var name = actor.name(); + var level = actor.level; + this.setFont(Felski.Techtree.TTFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTFontColor)); + this.setFontSize(Felski.Techtree.TTFontSize); + this.drawActorFace(actor, 0, 0, w, w); + this.drawText("N", w2, lh*0, w3, 'left'); + this.drawText(name, w2, lh*0, w3, 'right'); + this.drawText("L", w2, lh*1, w3, 'left'); + this.drawText(level, w2, lh*1, w3, 'right'); + this.resetFontSettings(); + }; + + Window_Techtree.prototype.drawHeader = function() { + this.clearSprites(); + var x = 200 + this.standardPadding(); + var y = 0; + var y2 = this.standardPadding(); + var ip = Window_Base._iconWidth + this.standardPadding(); + var trees = this._techtrees; + this.setFont(Felski.Techtree.TTFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTFontColor)); + this.setFontSize(Felski.Techtree.TTFontSize); + for (var i = 0; i < trees.length; i++) { + if(this._techtrees[i] === this._activeTree){ + this.drawIcon(trees[i].icon, x, y); + var w = this.textWidth(trees[i].header); + x = x + ip; + this.drawText(trees[i].header, x, y, w, 'center'); + x = x + w; + }else{ + var sprite = this.createButton(x, y2, i, trees[i].icon); + this._buttonSprites.push(sprite); + } + x = x + ip; + } + this.resetFontSettings(); + }; + + Window_Techtree.prototype.drawTechtree = function() { + var techtree = this._activeTree; + var nodes = techtree.nodes; + for (var i = 0; i < nodes.length; i++) { + if(nodes[i].technode.depth >= this.firstVisibleDepth() && nodes[i].technode.depth <= this.lastVisibleDepth()+1){ + if(nodes[i].technode.lane >= this.firstVisibleLane() && nodes[i].technode.lane <= this.lastVisibleLane()+1){ + this.drawNode(nodes[i]); + } + } + } + }; + + Window_Techtree.prototype.drawNode = function(nodeData) { + var technode = nodeData.technode; + var rect = this.getNodeRect(technode); + var ip = Window_Base._iconWidth + this.standardPadding(); + var lh = this.lineHeight(); + var x = rect.x; + var y = rect.y; + + this.setFont(Felski.Techtree.TTNHFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTNHFontColor)); + this.setFontSize(Felski.Techtree.TTNHFontSize); + // Box + if(this.isNodeVisible(nodeData)){ + //visible + if(nodeData.active){ + var bitmap = ImageManager.loadTechtree('Tech_Active'); + this.drawBoxFrameBackgroundBitmap(x, y, rect.width, rect.height, bitmap, Felski.Techtree.NodeOpacity); + this.drawBoxFrameBitmap(x, y, rect.width, rect.height, bitmap); + }else if(this.isNodeUnlockable(nodeData)){ + var bitmap = ImageManager.loadTechtree('Tech_Unlockable'); + this.drawBoxFrameBackgroundBitmap(x, y, rect.width, rect.height, bitmap, Felski.Techtree.NodeOpacity); + this.drawBoxFrameBitmap(x, y, rect.width, rect.height, bitmap); + }else{ + var bitmap = ImageManager.loadTechtree('Tech_Inactive'); + this.drawBoxFrameBackgroundBitmap(x, y, rect.width, rect.height, bitmap, Felski.Techtree.NodeOpacity); + this.drawBoxFrameBitmap(x, y, rect.width, rect.height, bitmap); + } + + // Header + this.drawText(technode.header, x+Felski.Techtree.NodeBorderWidth, y, rect.width-Felski.Techtree.NodeBorderWidth*2, 'center'); + + // onActivate + var onActivate = technode.onActivate; + var l = onActivate.skills.length; + l = l*ip; + l = l-this.standardPadding(); + l = l/2; + x = rect.x + rect.width/2-l; + for (var i = 0; i < onActivate.skills.length; i++) { + var icon = $dataSkills[onActivate.skills[i]].iconIndex; + this.drawIcon(icon, x, y+lh*1); + x = x + ip; + } + + // Cost + if(!Felski.Techtree.NodesCostHidden) { + if(nodeData.active && Felski.Techtree.NodesLearnedIconShown){ + var mid = rect.x + rect.width/2; + mid = mid - Window_Base._iconWidth/2; + var lastLine = rect.y + rect.height - this.lineHeight() - Felski.Techtree.NodeBorderWidth; + this.drawIcon(Felski.Techtree.NodesLearnedIconID, mid, lastLine); + }else{ + var costs = this.createCostArray(technode.costs); + this.drawCosts(rect, costs); + } + } + + // Arrows + for (var i = 0; i < technode.parents.length; i++) { + var parent = $gameSystem.searchTechtree(this._activeTree, technode.parents[i].parent); + if(parent){ + var rect1 = this.getNodeRect(parent.technode); + var rect2 = this.getNodeRect(technode); + var skin; + if(parent.active){ + skin = ImageManager.loadTechtree('Arrows_Active'); + }else{ + skin = ImageManager.loadTechtree('Arrows'); + } + this.drawArrow(rect1.x+rect1.width, rect1.y+(rect1.height/2), rect2.x, rect2.y+(rect2.height/2), skin); + } + } + for (var i = 0; i < technode.children.length; i++) { + var child = $gameSystem.searchTechtree(this._activeTree, technode.children[i]); + if(child){ + var rect1 = this.getNodeRect(technode); + var rect2 = this.getNodeRect(child.technode); + if(nodeData.active){ + var skin = ImageManager.loadTechtree('Arrows_Active'); + }else{ + var skin = ImageManager.loadTechtree('Arrows'); + } + this.drawArrow(rect1.x+rect1.width, rect1.y+(rect1.height/2), rect2.x, rect2.y+(rect2.height/2), skin); + } + } + this.resetFontSettings(); + + }else{ + //not visible + var bitmap = ImageManager.loadTechtree('Tech_Hidden'); + this.drawBoxFrameBackgroundBitmap(x, y, rect.width, rect.height, bitmap, Felski.Techtree.NodeOpacity); + this.drawBoxFrameBitmap(x, y, rect.width, rect.height, bitmap); + x = rect.x + (rect.width - Window_Base._iconWidth)/2; + y = rect.y + (rect.height - Window_Base._iconHeight)/2; + this.drawIcon(Felski.Techtree.HiddenIcon, x, y); + + // Arrows + for (var i = 0; i < technode.parents.length; i++) { + var parent = $gameSystem.searchTechtree(this._activeTree, technode.parents[i].parent); + if(parent){ + var rect1 = this.getNodeRect(parent.technode); + var rect2 = this.getNodeRect(technode); + if(parent.active){ + var skin = ImageManager.loadTechtree('Arrows_Active'); + }else{ + var skin = ImageManager.loadTechtree('Arrows'); + } + this.drawArrow(rect1.x+rect1.width, rect1.y+(rect1.height/2), rect2.x, rect2.y+(rect2.height/2), skin); + } + } + for (var i = 0; i < technode.children.length; i++) { + var child = $gameSystem.searchTechtree(this._activeTree, technode.children[i]); + if(child){ + var rect1 = this.getNodeRect(technode); + var rect2 = this.getNodeRect(child.technode); + if(nodeData.active){ + var skin = ImageManager.loadTechtree('Arrows_Active'); + }else{ + var skin = ImageManager.loadTechtree('Arrows'); + } + this.drawArrow(rect1.x+rect1.width, rect1.y+(rect1.height/2), rect2.x, rect2.y+(rect2.height/2), skin); + } + } + } + }; + + Window_Techtree.prototype.drawCosts = function(rect, costs) { + // Cost + this.setFont(Felski.Techtree.TTNCFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTNCFontColor)); + this.setFontSize(Felski.Techtree.TTNCFontSize); + var hp = this.standardPadding()/2; + var ip = Window_Base._iconWidth + hp; + var costWidth = this.measureCostArrayWidth(costs); + var tw; + var x = rect.x + ((rect.width/2)-(costWidth/2)); + var y = rect.y + rect.height - this.lineHeight() - hp; + for (var i = 0; i < costs.length; i++) { + tw = this.textWidth(costs[i].amount); + this.drawText(costs[i].amount, x, y, tw, 'left'); + x = x+tw+hp; + if(costs[i].icon){ + this.drawIcon(costs[i].icon, x, y); + x = x+ip+hp; + }else if(costs[i].text){ + tw = this.textWidth(costs[i].text); + this.drawText(costs[i].text, x, y, tw, 'left'); + x = x+tw+hp; + } + } + this.resetFontSettings(); + }; + + Window_Techtree.prototype.createCostArray = function(costsObject) { + var costArr = []; + var costs = costsObject; + if(costs.gold > 0){ + var gold; + if(Imported.YEP_CoreEngine === true){ + gold = {"icon":Yanfly.Icon.Gold, "amount":costs.gold}; + }else{ + gold = {"text":TextManager.currencyUnit, "amount":costs.gold}; + } + costArr.push(gold); + } + if(costs.jp > 0 && Imported.YEP_JobPoints){ + var jp = {"icon":Yanfly.Icon.Jp, "amount":costs.jp}; + costArr.push(jp); + } + if(costs.items){ + for (var i = 0; i < costs.items.length; i++) { + var item = $dataItems[costs.items[i].id]; + if(item){ + var cost = costs.items[i].amount; + var itemcost = {"icon":item.iconIndex, "amount":cost}; + costArr.push(itemcost); + }else{ + console.warn("There is an item cost that points to no item. Item ID: "+costs.items[i].id); + } + } + } + return costArr; + }; + + Window_Techtree.prototype.measureCostArrayWidth = function(costsArray) { + var costs = costsArray; + var hp = this.standardPadding()/2; + var ip = Window_Base._iconWidth + hp; + var amountWidth = 0; + var textWidth = 0; + var costWidth = 0; + for (var i = 0; i < costs.length; i++) { + if(costs[i].icon){ + costWidth = costWidth + ip; + }else if(costs[i].text){ + textWidth = this.textWidth(costs[i].text); + costWidth = costWidth + textWidth + hp; + } + amountWidth = this.textWidth(costs[i].amount); + costWidth = costWidth + amountWidth + hp; + } + return costWidth; + }; + + +//************************************************************************************************ +// +// Window_Techtree // Sprite Handling +// +//************************************************************************************************ + + Window_Techtree.prototype.createButton = function(x, y, id, icon) { + var bitmap = ImageManager.loadSystem('IconSet'); + var sprite = new Sprite_FelskiButton(x, y, id); + sprite.bitmap = bitmap; + var frame = this.getIconFrame(icon); + sprite.setFrame(frame.x, frame.y, frame.width, frame.height); + sprite.setTouchHandler(this.onButtonTouch.bind(this, arguments)); + this.addChild(sprite); + return sprite; + }; + + Window_Techtree.prototype.clearSprites = function(){ + for (var i = 0; i < this._buttonSprites.length; i++) { + this.removeChild(this._buttonSprites[i]); + } + this._buttonSprites = []; + }; + + +//************************************************************************************************ +// +// Window_Techtree // cursorMovement +// +//************************************************************************************************ + + Window_Techtree.prototype.cursorDown = function() { + var node = this.selectedNode(); + var depth = node.technode.depth; + var lane = node.technode.lane; + var maxLanes = this.maxLanes(); + if (lane < maxLanes) { + this.select(depth, lane + 1, "down"); + } + }; + + Window_Techtree.prototype.cursorUp = function() { + var node = this.selectedNode(); + var depth = node.technode.depth; + var lane = node.technode.lane; + if (lane > 1) { + this.select(depth, lane - 1, "up"); + } + }; + + Window_Techtree.prototype.cursorRight = function() { + var node = this.selectedNode(); + var depth = node.technode.depth; + var lane = node.technode.lane; + var maxDepth = this.maxDepth(); + if (depth < maxDepth) { + this.select(depth + 1, lane, "right"); + } + }; + + Window_Techtree.prototype.cursorLeft = function() { + var node = this.selectedNode(); + var depth = node.technode.depth; + var lane = node.technode.lane; + if (depth > 1) { + this.select(depth - 1, lane, "left"); + } + }; + + Window_Techtree.prototype.scrollDown = function() { + var node = this.selectedNode(); + var depth = node.technode.depth; + var lane = node.technode.lane; + var maxDepth = this.maxDepth(); + if (depth < maxDepth) { + this.select(depth + 1, lane, "right"); + } + }; + + Window_Techtree.prototype.scrollUp = function() { + var node = this.selectedNode(); + var depth = node.technode.depth; + var lane = node.technode.lane; + if (depth > 1) { + this.select(depth - 1, lane, "left"); + } + }; + + Window_Techtree.prototype.select = function(depth, lane, direction) { + var oldDepth = this._selectedDepth; + var oldLane = this._selectedLane; + this._selectedDepth = depth; + this._selectedLane = lane; + this._selectedNode = $gameSystem.searchTechtreeDepthLane(this._activeTree, depth, lane); + if(this.selectedNode() === null || this.selectedNode() === undefined){ + if(direction == "right"){ // right + if(this._selectedDepth >= this._maxDepth && this._selectedLane >= this._maxLanes){ + this.select(this._selectedDepth - 1, this._selectedLane, "left"); + }else if(this._selectedDepth >= this._maxDepth){ + this.select(this._maxDepth, this._selectedLane + 1, "down"); + }else{ + this.select(this._selectedDepth + 1, this._selectedLane, "right"); + } + }else if(direction == "left"){ // left + if(this._selectedDepth <= 1 && this._selectedLane <= 1){ + this.select(2, 1, "right"); + }else if(this._selectedDepth <= 1){ + this.select(1, this._selectedLane - 1, "up"); + }else{ + this.select(this._selectedDepth - 1, this._selectedLane, "left"); + } + }else if(direction == "down"){ // down + if(this._selectedDepth >= this._maxDepth && this._selectedLane >= this._maxLanes){ + this.select(this._maxDepth, this._maxLanes - 1 , "up"); + }else if(this._selectedLane >= this._maxLanes){ + this.select(this._selectedDepth + 1, this._maxLanes, "right"); + }else{ + this.select(this._selectedDepth, this._selectedLane + 1, "down"); + } + }else{ // up + if(this._selectedDepth <= 1 && this._selectedLane <= 1){ + this.select(1, 2, "down"); + }else if(this._selectedLane <= 1){ + this.select(this._selectedDepth - 1, 1, "left"); + }else{ + this.select(this._selectedDepth, this._selectedLane - 1, "up"); + } + } + } + this.ensureCursorVisible(direction); + this.updateCursor(); + }; + + Window_Techtree.prototype.ensureCursorVisible = function(direction) { + var node = this.indexObj(); + if(node.lane < this.firstVisibleLane()){ + this._firstVisibleLane = node.lane; + this._lastVisibleLane = this._firstVisibleLane + this.visibleLanes(); + } + if(node.lane > this.lastVisibleLane()){ + this._lastVisibleLane = node.lane; + this._firstVisibleLane = this._lastVisibleLane - this.visibleLanes(); + } + if(node.depth < this.firstVisibleDepth()){ + this._firstVisibleDepth = node.depth; + this._lastVisibleDepth = this._firstVisibleDepth + this.visibleDepths(); + } + if(node.depth > this.lastVisibleDepth()){ + this._lastVisibleDepth = node.depth; + this._firstVisibleDepth = this._lastVisibleDepth - this.visibleDepths(); + } + }; + + Window_Techtree.prototype.updateCursor = function() { + var node = this.selectedNode(); + if(node){ + var rect = this.getNodeRect(node.technode); + var w = rect.width + (Felski.Techtree.NodeCursorSize * 2); + var h = rect.height + (Felski.Techtree.NodeCursorSize * 2); + var x = rect.x + (rect.width - w)/2; + var y = rect.y + (rect.height - h)/2; + this.setCursorRect(x, y, w, h); + } + }; + + +//************************************************************************************************ +// +// Window_Techtree // onEvent Handling +// +//************************************************************************************************ + + Window_Techtree.prototype.onButtonTouch = function(args, x, y, id) { + this._activeTree = this._techtrees[id]; + this._selectedDepth = -1; + this._selectedLane = -1; + this.initCursorInfos(); + this.initTreeInfos(); + this.changed(); + }; + + Window_Techtree.prototype.onTouch = function(triggered) { + if(!this.hasTechtrees() && triggered) {this.processCancel(); return;} + var lastNode = this.selectedNode(); + var x = this.canvasToLocalX(TouchInput.x); + var y = this.canvasToLocalY(TouchInput.y); + var hitNode = this.hitTest(x, y); + if (hitNode !== null) { + if (hitNode === this.selectedNode()) { + //if (triggered && this.isTouchOkEnabled()) { + if (triggered) { + this.processOk(); + } + } else { + var depth = hitNode.technode.depth; + var lane = hitNode.technode.lane; + this.select(depth, lane); + } + } else if (this._stayCount >= 10) { + if (y < this.padding) { + this.cursorUp(); + } else if (y >= this.height - this.padding) { + this.cursorDown(); + } + } + if (this.selectedNode() !== lastNode) { + SoundManager.playCursor(); + } + }; + + +//************************************************************************************************ +// +// Window_Techtree // process Input +// +//************************************************************************************************ + + Window_Techtree.prototype.processCursorMove = function() { + if (this.isOpenAndActive() && this.hasTechtrees()) { + var lastNode = this.selectedNode(); + if (Input.isRepeated('down')) { + this.cursorDown(Input.isTriggered('down')); + } + if (Input.isRepeated('up')) { + this.cursorUp(Input.isTriggered('up')); + } + if (Input.isRepeated('right')) { + this.cursorRight(Input.isTriggered('right')); + } + if (Input.isRepeated('left')) { + this.cursorLeft(Input.isTriggered('left')); + } + /* + if (!this.isHandled('pagedown') && Input.isTriggered('pagedown')) { + this.cursorPagedown(); + } + if (!this.isHandled('pageup') && Input.isTriggered('pageup')) { + this.cursorPageup(); + } + */ + if (lastNode !== this.selectedNode()) { + this.changed(); + SoundManager.playCursor(); + } + } + }; + + Window_Techtree.prototype.processHandling = function() { + if (this.isOpenAndActive()) { + if (this.isOkTriggered()) { + this.processOk(); + } else if (this.isCancelTriggered()) { + this.processCancel(); + } /*else if (this.isHandled('pagedown') && Input.isTriggered('pagedown')) { + this.processPagedown(); + } else if (this.isHandled('pageup') && Input.isTriggered('pageup')) { + this.processPageup(); + } */ + } + }; + + Window_Techtree.prototype.processCancel = function() { + SoundManager.playCancel(); + this.updateInputData(); + this.deactivate(); + this.callCancelHandler(); + }; + + Window_Techtree.prototype.processOk = function() { + if (this.isCurrentItemEnabled()) { + this.playOkSound(); + this.updateInputData(); + this.deactivate(); + this.callOkHandler(); + } else if(!this.hasTechtrees()){ + SoundManager.playCancel(); + this.updateInputData(); + this.deactivate(); + this.callCancelHandler(); + } else{ + this.playBuzzerSound(); + } + }; + + Window_Techtree.prototype.processTouch = function() { + if (this.isOpenAndActive()) { + var lastNode = this.selectedNode(); + if (TouchInput.isTriggered() && this.isTouchedInsideFrame()) { + this._touching = true; + this.onTouch(true); + } else if (TouchInput.isCancelled()) { + this.processCancel(); + } + if (this._touching) { + if (TouchInput.isPressed()) { + this.onTouch(false); + } else { + this._touching = false; + } + } + if (lastNode !== this.selectedNode()) { + this.changed(); + } + } else { + this._touching = false; + } + }; + + Window_Techtree.prototype.processWheel = function() { + if (this.isOpenAndActive()) { + var threshold = 20; + if (TouchInput.wheelY >= threshold) { + this.scrollDown(); + this.changed(); + } + if (TouchInput.wheelY <= -threshold) { + this.scrollUp(); + this.changed(); + } + } + }; + + +//************************************************************************************************ +// +// Window_Techtree // Checks +// +//************************************************************************************************ + + Window_Techtree.prototype.isNodeUnlockable = function(node) { + if(node){ + var parents = node.technode.parents; + var neededParents = node.technode.neededParents; + var activeParents = 0; + for (var i = 0; i < parents.length; i++) { + var parent = $gameSystem.searchTechtree(this._activeTree, parents[i].parent); + if(parent){ + if(parent.active){ + activeParents = activeParents + 1; + } + } + } + if(neededParents <= activeParents){ + return true; + }else{ + return false; + } + }else{ + return false; + } + }; + + Window_Techtree.prototype.isNodeVisible = function(node) { + if(node){ + if(node.active && Felski.Techtree.NodesActiveVisible){ + return true; + } + var visibility = node.technode.visibility; + var switches = visibility.switches; + var visible = false; + if(switches.length > 0){ + for (var i = 0; i < switches.length; i++) { + if(!$gameSwitches.value(switches[i].id)){ + return false; + }else{ + visible = true; + } + } + return visible; + }else{ + return true; + } + }else{ + return false; + } + }; + + Window_Techtree.prototype.isCurrentItemEnabled = function() { + return (!!this._selectedNode); + }; + + Window_Techtree.prototype.hasTechtrees = function() { + return (this._activeTree); + }; + + Window_Techtree.prototype.isOkTriggered = function() { + return Input.isRepeated('ok'); + }; + + Window_Techtree.prototype.isCancelTriggered = function() { + return Input.isRepeated('cancel'); + }; + + Window_Techtree.prototype.hitTest = function(x, y) { + if(!this.hasTechtrees()) return null; + if (this.isContentsArea(x, y)) { + var cx = x - this.padding; + var cy = y - this.padding; + var nodes = this._activeTree.nodes; + for (var i = 0; i < nodes.length; i++) { + var rect = this.getNodeRect(nodes[i].technode); + var right = rect.x + rect.width; + var bottom = rect.y + rect.height; + if (cx >= rect.x && cy >= rect.y && cx < right && cy < bottom) { + return nodes[i]; + } + } + } + return null; + }; + + Window_Techtree.prototype.isContentsArea = function(x, y) { + var left = this.padding; + var top = this.padding; + var right = this.width - this.padding; + var bottom = this.height - this.padding; + return (x >= left && y >= top && x < right && y < bottom); + }; + + Window_Techtree.prototype.isTouchedInsideFrame = function() { + var x = this.canvasToLocalX(TouchInput.x); + var y = this.canvasToLocalY(TouchInput.y); + return x >= 0 && y >= 0 && x < this.width && y < this.height; + }; + + +//************************************************************************************************ +// +// Window_Techtree // Handler Methods +// +//************************************************************************************************ + + Window_Techtree.prototype.setOkHandler = function(method) { + this._okHandler = method; + }; + + Window_Techtree.prototype.callOkHandler = function() { + if (this._okHandler) { + var rect = this.getNodeRect(this._selectedNode.technode); + rect.x = rect.x + Math.floor(rect.width/2); + rect.y = rect.y + this._topMargin + Math.floor(rect.height/2); + this._okHandler(this._selectedNode, this._activeTree, rect); + } + }; + + Window_Techtree.prototype.setCancelHandler = function(method) { + this._cancelHandler = method; + }; + + Window_Techtree.prototype.callCancelHandler = function() { + if (this._cancelHandler) { + this._cancelHandler(); + } + }; + + Window_Techtree.prototype.updateInputData = function() { + Input.update(); + TouchInput.update(); + }; + + +//************************************************************************************************ +// +// Window_Techtree // Sounds +// +//************************************************************************************************ + + Window_Techtree.prototype.playOkSound = function() { + SoundManager.playOk(); + }; + + Window_Techtree.prototype.playBuzzerSound = function() { + SoundManager.playBuzzer(); + }; + + +//************************************************************************************************ +// +// Window_Techtree // Helping Functions +// +//************************************************************************************************ + + Window_Techtree.prototype.getIconFrame = function(iconIndex){ + var w = Window_Base._iconWidth; + var h = Window_Base._iconHeight; + var x = iconIndex % 16 * w; + var y = Math.floor(iconIndex / 16) * h; + var rect = new Rectangle(x, y, w, h); + return rect; + }; + + Window_Techtree.prototype.getNodeRect = function(technode) { + var depth = technode.depth - this._firstVisibleDepth; + var lane = technode.lane - this._firstVisibleLane; + var w = Felski.Techtree.NodeWidth; + var h = Felski.Techtree.NodeHeight; + var x = Felski.Techtree.NodesLeftMargin || 0; + var y = Felski.Techtree.NodesTopMargin; + if(Felski.Techtree.horizontal){ + x = x + (Felski.Techtree.NodeWidth + Felski.Techtree.NodeGap) * depth ; + y = y + (Felski.Techtree.NodeHeight + this.standardPadding()) * lane; + }else{ + x = x + (Felski.Techtree.NodeWidth + this.standardPadding()) * lane; + y = y + (Felski.Techtree.NodeHeight + Felski.Techtree.NodeGap) * depth ; + } + var rect = new Rectangle(x, y, w, h); + return rect; + }; + + +//************************************************************************************************ +// +// Window_Techtree_Select +// +//************************************************************************************************ + + Window_Techtree_Select.prototype = Object.create(Window_HorzCommand.prototype); + Window_Techtree_Select.prototype.constructor = Window_Techtree_Select; + + Window_Techtree_Select.prototype.initialize = function(x, y, w, h, actor) { + this._newW = w; + this._newH = h; + this._actor = actor; + this._hasTechtrees = false; + this.hasTechtrees(); + this._firstVisibleCol = 0; + this._lastVisibleCol = this.maxCols() - 1; + Window_HorzCommand.prototype.initialize.call(this, x, y); + }; + + Window_Techtree_Select.prototype.windowWidth = function() { + return this._newW; + }; + + Window_Techtree_Select.prototype.windowHeight = function() { + return this._newH; + }; + + Window_Techtree_Select.prototype.maxCols = function() { + return Felski.Techtree.TTHeaderCols; + }; + + Window_Techtree_Select.prototype.update = function() { + Window_HorzCommand.prototype.update.call(this); + if(this._oldIndex !== this.index()){ + this._oldIndex = this.index(); + this.refresh(); + } + }; + + Window_Techtree_Select.prototype.setTechtreeWindow = function(techtreeWindow) { + this._techtreeWindow = techtreeWindow; + }; + + Window_Techtree_Select.prototype.setTechtreeCurrencyWindow = function(techtreeCurrencyWindow) { + this._techtreeCurrencyWindow = techtreeCurrencyWindow; + }; + + Window_Techtree_Select.prototype.hasTechtrees = function() { + var trees = this._actor._techtrees; + for (var i = 0; i < trees.length; i++) { + if(trees[i].fromClass === this._actor._classId || trees[i].fromClass === undefined){ + this._hasTechtrees = true; + return; + } + } + }; + + Window_Techtree_Select.prototype.makeCommandList = function() { + if(this._hasTechtrees){ + var trees = this._actor._techtrees; + for (var i = 0; i < trees.length; i++) { + var tree = trees[i]; + if(tree.fromClass === this._actor._classId || tree.fromClass === undefined){ + this.addCommand(tree.header, String(i)); + } + } + }else{ + this.addCommand("close", "cancel", true); + } + }; + + Window_Techtree_Select.prototype.callHandler = function(symbol) { + if (this.isHandled(symbol)) { + this._handlers[symbol](symbol); + } + }; + + Window_Techtree_Select.prototype.cursorDown = function(wrap) { + Window_Selectable.prototype.cursorRight.call(this, wrap); + }; + + Window_Techtree_Select.prototype.cursorUp = function(wrap) { + Window_Selectable.prototype.cursorLeft.call(this, wrap); + }; + + Felski.Techtree.Window_Selectable_drawAllItems = Window_Selectable.prototype.drawAllItems; + Window_Techtree_Select.prototype.drawAllItems = function() { + if(this._hasTechtrees){ + Window_Selectable.prototype.drawAllItems.call(this); + }else{ + this.drawInfo(); + } + }; + + Felski.Techtree.Window_Selectable_itemRect = Window_Selectable.prototype.itemRect; + Window_Techtree_Select.prototype.itemRect = function(index) { + if(this._hasTechtrees){ + return Felski.Techtree.Window_Selectable_itemRect.call(this, index); + }else{ + var w = this.windowWidth(); + var h = this.windowHeight(); + var y = h/3; + var lh = this.lineHeight(); + var rect = new Rectangle(); + rect.width = w/3; + rect.height = lh; + rect.x = w/3; + rect.y = y+lh; + return rect; + } + }; + + Window_Techtree_Select.prototype.drawInfo = function() { + var w = this.windowWidth(); + var h = this.windowHeight(); + var x = 0; + var y = h/3; + var lh = this.lineHeight(); + var text = Felski.Techtree.NoTreeText; + text = text.format(this._actor.name()); + this.drawText(text, x, y, w, 'center'); + this.drawText(Felski.Techtree.TTNAClose, x, y+lh, w, 'center'); + this.setCursorRect(w/3, y+lh, w/3, lh); + }; + + Window_Techtree_Select.prototype.drawItem = function(index) { + if(index < 0) return; + var symbol = this.commandSymbol(index); + symbol = Number(symbol); + var tree = this._actor._techtrees[symbol]; + if(this.isCommandVisible(index)) { + var rect = this.itemRectForText(index - this._firstVisibleCol); + var align = this.itemTextAlign(); + + // Header Line + this.resetTextColor(); + this.changePaintOpacity(this.isCommandEnabled(index) && !Felski.Techtree.singleTreeView); + this.setFont(Felski.Techtree.TTHeaderFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTHeaderFontColor)); + this.setFontSize(Felski.Techtree.TTHeaderFontSize); + if(Felski.Techtree.TTHeaderLIcons) this.drawIcon(tree.icon, rect.x, rect.y+2); + if(Felski.Techtree.TTHeaderTIcons) this.drawIcon(tree.icon, rect.x + rect.width-Window_Base._iconWidth, rect.y+2); + this.drawText(this.commandName(index), rect.x, rect.y, rect.width, align); + + if(this.index() === index){ + var desc = tree.tech_description; + this.setFont(Felski.Techtree.TTHeaderDescFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTHeaderDescFontColor)); + this.setFontSize(Felski.Techtree.TTHeaderDescFontSize); + this.drawTextAutoWrap(desc, 0, rect.height, this.windowWidth() - this.standardPadding()*2); + } + this.resetTextColor(); + } + }; + + Window_Techtree_Select.prototype.isCommandVisible = function(index) { + return (index >= this._firstVisibleCol && index <= this._lastVisibleCol); + }; + + Window_Techtree_Select.prototype.select = function(index) { + if(index >= 0){ + if(index > this._lastVisibleCol){ + this._lastVisibleCol = index; + this._firstVisibleCol = index - (this.maxCols() - 1); + }else if(index < this._firstVisibleCol){ + this._lastVisibleCol = index + (this.maxCols() - 1); + this._firstVisibleCol = index; + } + if(this._techtreeWindow){ + var symbol = this.commandSymbol(index); + symbol = Number(symbol); + if(Felski.Techtree.TTHeaderUpdate){ + if(this._techtreeWindow){ + this._techtreeWindow.changeTree(symbol); + } + if(this._techtreeCurrencyWindow){ + this._techtreeCurrencyWindow.setTree(symbol); + } + } + } + } + Window_Selectable.prototype.select.call(this, index); + }; + + Window_Techtree_Select.prototype.reselect = function() { + }; + + Window_Techtree_Select.prototype.updateCursor = function() { + if (this._cursorAll) { + var allRowsHeight = this.maxRows() * this.itemHeight(); + this.setCursorRect(0, 0, this.contents.width, allRowsHeight); + this.setTopRow(0); + } else if (this.isCursorVisible()) { + var rect = this.itemRect(this.index() - this._firstVisibleCol); + this.setCursorRect(rect.x, rect.y, rect.width, rect.height); + } else { + this.setCursorRect(0, 0, 0, 0); + } + }; + + +//************************************************************************************************ +// +// Window_Techtree_Info +// +//************************************************************************************************ + + Window_Techtree_Info.prototype = Object.create(Window_Base.prototype); + Window_Techtree_Info.prototype.constructor = Window_Techtree_Info; + + Window_Techtree_Info.prototype.initialize = function(x, y, actor) { + var width = this.windowWidth(); + var height = this.windowHeight(); + this._actor = actor; + Window_Base.prototype.initialize.call(this, x, y, width, height); + }; + + Window_Techtree_Info.prototype.windowWidth = function() { + return Window_Base._faceWidth + this.standardPadding(); + }; + + Window_Techtree_Info.prototype.windowHeight = function() { + return Window_Base._faceHeight + this.standardPadding(); + }; + + Window_Techtree_Info.prototype.update = function() { + Window_Base.prototype.update.call(this); + if (this._actor) { + this.refresh(); + } + }; + + Window_Techtree_Info.prototype.refresh = function() { + this.contents.clear(); + var w = Window_Base._faceWidth; + var w2 = (w/4)*3 - w/4; + var w3 = w - w/4; + var lh = this.lineHeight(); + + var actor = this._actor; + var name = actor.name(); + var level = actor.level; + this.setFont(Felski.Techtree.TTFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTFontColor)); + this.setFontSize(Felski.Techtree.TTFontSize); + this.drawActorFace(actor, 0, 0, w, w); + //this.drawText("N", w2, lh*0, w3, 'left'); + this.drawText(name, 0, 0, w3, 'left'); + //this.drawText("L", w2, lh*1, w3, 'left'); + //this.drawText(level, w2, lh*1, w3, 'right'); + this.resetFontSettings(); + }; + + +//************************************************************************************************ +// +// Window_Techtree_Confirm +// +//************************************************************************************************ + + + + Window_Techtree_Confirm.prototype = Object.create(Window_Base.prototype); + Window_Techtree_Confirm.prototype.constructor = Window_Techtree_Confirm; + + Window_Techtree_Confirm.prototype.initialize = function(actor, onlyDisplay) { + var x = Graphics.width/6; + var y = Graphics.height/6; + var width = this.windowWidth(); + var height = this.windowHeight(); + this._index = true; + this._maxDepth = 0; + this._maxLanes = 0; + this._actor = actor; + this._node = null; + this._activeTree = null; + this._costsArray = null; + this._costsArrayWidth = null; + this._buttonSprites = []; + this._onlyDisplay = onlyDisplay || false; + Window_Base.prototype.initialize.call(this, x, y, width, height); + }; + + Window_Techtree_Confirm.prototype.activate = function() { + Window_Base.prototype.activate.call(this); + if(this.isNodeActive()){ + this._index = false; + }else if (this.canBeUnlocked()){ + this._index = true; + }else{ + this._index = false; + } + this.updateCursor(); + }; + + Window_Techtree_Confirm.prototype.changebgimg = function() { + if(!Felski.Techtree.TTMenuBackground) return; + if(this._activeTree){ + if(this._node.technode.bgimg){ + var bitmap = ImageManager.loadTechtreeBGIMG(this._node.technode.bgimg); + var newWidth = this.windowWidth() - this.textPadding(); + var newHeight = this.windowHeight() - this.textPadding(); + this.backOpacity = Felski.Techtree.TTMenuConfirmBackgroundOpacity; + this._windowBackSprite.bitmap = new Bitmap(newWidth, newHeight); + this._windowBackSprite.bitmap.blt(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, newWidth, newHeight); + }else if(this._activeTree.bgimg){ + var bitmap = ImageManager.loadTechtreeBGIMG(this._activeTree.bgimg); + var newWidth = this.windowWidth(); + var newHeight = this.windowHeight(); + this.backOpacity = Felski.Techtree.TTMenuBackgroundOpacity; + this._windowBackSprite.bitmap = new Bitmap(newWidth, newHeight); + this._windowBackSprite.bitmap.blt(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, newWidth, newHeight); + } + } + }; + + + Window_Techtree_Confirm.prototype.removeAnimation = function(){ + if(!this._animation) return; + if(this._animation.finished()){ + this.removeChild(this._animation); + } + }; + +//************************************************************************************************ +// +// Window_Techtree // Technical Functions +// +//************************************************************************************************ + + Window_Techtree_Confirm.prototype.update = function() { + Window_Base.prototype.update.call(this); + this.processCursorMove(); + this.processHandling(); + this.processTouch(); + if(this.visible){ + this.drawAll(); + } + this.removeAnimation(); + }; + + Window_Techtree_Confirm.prototype.windowHeight = function() { + return (Graphics.height/3)*2; + }; + + Window_Techtree_Confirm.prototype.windowWidth = function() { + return (Graphics.width/3)*2; + }; + + Window_Techtree_Confirm.prototype.setNode = function(node) { + this._costsArray = this.createCostArray(node.technode.costs) || null; + this._costsArrayWidth = this.measureCostArrayWidth(this._costsArray) || null; + this._node = node; + }; + + Window_Techtree_Confirm.prototype.setTree = function(tree) { + this._activeTree = tree; + }; + + Window_Techtree_Confirm.prototype.setAnimationPos = function(x, y) { + this._animX = x; + this._animY = y; + }; + + Window_Techtree_Confirm.prototype.index = function() { + return this._index; + }; + +//************************************************************************************************ +// +// Window_Techtree // Draw Functions +// +//************************************************************************************************ + + Window_Techtree_Confirm.prototype.drawAll = function() { + this.contents.clear(); + if(this._node){ + if(this.isNodeVisible()){ + this.drawHeader(); + this.drawRequirement(); + this.drawNodeInfo(); + }else{ + this.drawInfo(); + } + this.drawActionTexts(); + this.updateCursor(); + } + }; + + Window_Techtree_Confirm.prototype.drawInfo = function() { + var w = this.windowWidth(); + var h = this.windowHeight(); + var x = 0; + var y = (h-this.lineHeight())/2 - this.lineHeight(); + + this.setFont(Felski.Techtree.TTNTFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTNTFontColor)); + this.setFontSize(Felski.Techtree.TTNTFontSize); + this.drawText(Felski.Techtree.HiddenText, x, y, w, 'center'); + }; + + Window_Techtree_Confirm.prototype.drawHeader = function() { + var x = 0; + var y = 0; + var w = this.windowWidth(); + var technode = this._node.technode; + + this.setFont(Felski.Techtree.TTNHFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTNHFontColor)); + this.setFontSize(Felski.Techtree.TTNHFontSize); + this.drawText(technode.header, x, y, w, 'center'); + }; + + Window_Techtree_Confirm.prototype.drawRequirement = function() { + var x = 0; + var y = this.lineHeight(); + var w = this.windowWidth(); + var technode = this._node.technode; + if(technode.levelRequirement){ + this.setFont(Felski.Techtree.TTLevelRequirementFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTLevelRequirementFontColor)); + this.setFontSize(Felski.Techtree.TTLevelRequirementFontSize); + this.drawText("Requires Level "+technode.levelRequirement, x, y, w, 'center'); + } + }; + + Window_Techtree_Confirm.prototype.drawActionTexts = function() { + var x = 0; + var y = this.windowHeight() - this.lineHeight() - this.standardPadding()*2; + var w = (this.windowWidth()-this.standardPadding()*2)/2; + + this.setFont(Felski.Techtree.TTNHFont); + this.setFontSize(Felski.Techtree.TTNHFontSize); + if(this.canBeUnlocked() && this.canPayCost()){ + this.changeTextColor(this.textColor(Felski.Techtree.TTNHFontColor)); + }else{ + this.changeTextColor(this.textColor(Felski.Techtree.TTNHFontColorGreyedOut)); + } + if(this.isNodeActive()){ + this.drawText(Felski.Techtree.TTNAAlreadyUnlocked, x, y, w, 'center'); + this.changeTextColor(this.textColor(Felski.Techtree.TTNHFontColor)); + this.drawText(Felski.Techtree.TTNAClose, w, y, w, 'center'); + }else{ + this.drawText(Felski.Techtree.TTNAUnlock, x, y, w, 'center'); + this.changeTextColor(this.textColor(Felski.Techtree.TTNHFontColor)); + this.drawText(Felski.Techtree.TTNACancel, w, y, w, 'center'); + } + this.resetFontSettings(); + }; + + Window_Techtree_Confirm.prototype.drawNodeInfo = function() { + var x = 0; + var y = 0; + var w = this.windowWidth(); + var h = this.windowHeight(); + var ip = Window_Base._iconWidth + this.standardPadding(); + var lh = this.lineHeight(); + var technode = this._node.technode; + + this.setFont(Felski.Techtree.TTNTFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTNTFontColor)); + this.setFontSize(Felski.Techtree.TTNTFontSize); + // Description + if(Felski.Techtree.TTNShowTechDesc){ + this.drawTextAutoWrap(technode.tech_description, x, y+lh*2, w); + } + + // onActivate + var onActivate = technode.onActivate; + y = y+lh*2; + for (var i = 0; i < onActivate.skills.length; i++) { + x = 0; + var ih = lh*3; // item height + var skill = $dataSkills[onActivate.skills[i]]; + if(Felski.Techtree.TTNShowSkillIcon) this.drawIcon(skill.iconIndex, x, y+ih*i+lh*1); + x = x + ip; + if(Felski.Techtree.TTNShowSkillName) this.drawText(skill.name, x, y+ih*i+lh*1, (w-ip), 'left'); + if(Felski.Techtree.TTNShowSkillDesc) this.drawTextAutoWrap(skill.description, x, y+ih*i+lh*2, (w-ip)); + } + + var statsX = 0; + var statsY = y + lh + onActivate.skills.length*lh*2; + if(onActivate.stats){ + var stats = onActivate.stats; + var statsArr = []; + var sign = ""; + var count = 0; + var statsObj; + var nextLine = false; + for (var i = 0; i < 8; i++) { + if(stats[i]){ + statsObj = {"id": i, "stat":stats[i]}; + statsArr.push(statsObj); + } + } + for (var i = 0; i < statsArr.length; i++) { + if(statsArr[i].stat < 0){ + sign = "-"; + }else{ + sign = "+"; + } + var w2; + if(nextLine){ + w2 = (w - this.standardPadding()) / (statsArr.length - Math.ceil(statsArr.length/2)); + }else{ + w2 = (w - this.standardPadding()) / Math.ceil(statsArr.length/2); + } + this.drawText(sign+statsArr[i].stat+" "+TextManager.param(statsArr[i].id), statsX+w2*(count%(Math.ceil(statsArr.length/2))), statsY, w2, 'center'); + count++; + if(count === Math.ceil(statsArr.length/2)){ + statsY = statsY + lh; + nextLine = true; + + } + } + } + + // Cost + this.setFont(Felski.Techtree.TTNCFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTNCFontColor)); + this.setFontSize(Felski.Techtree.TTNCFontSize); + if(!this._costsArray) {this._costsArray = this.createCostArray(technode.costs);} + var costs = this._costsArray; + this.drawCosts(costs); + + this.resetFontSettings(); + }; + + Window_Techtree_Confirm.prototype.drawCosts = function(costs) { + if(!this._costsArrayWidth) {this._costsArrayWidth = this.measureCostArrayWidth(costs);} + this.setFont(Felski.Techtree.TTNCFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTNCFontColor)); + this.setFontSize(Felski.Techtree.TTNCFontSize); + var hp = this.standardPadding()/2; + var ip = Window_Base._iconWidth + hp; + var costWidth = this._costsArrayWidth; + var tw; + var x = ((this.windowWidth()/2)-(costWidth/2)); + var y = this.windowHeight() - this.lineHeight()*2 - this.standardPadding()*2; + for (var i = 0; i < costs.length; i++) { + tw = this.textWidth(costs[i].amount); + this.drawText(costs[i].amount, x, y, tw, 'left'); + x = x+tw+hp; + if(costs[i].icon){ + this.drawIcon(costs[i].icon, x, y); + x = x+ip+hp; + }else if(costs[i].text){ + tw = this.textWidth(costs[i].text); + this.drawText(costs[i].text, x, y, tw, 'left'); + x = x+tw+hp; + } + } + this.resetFontSettings(); + }; + + + Window_Techtree_Confirm.prototype.updateCursor = function() { + var x = 0; + var y = this.windowHeight() - this.lineHeight() - this.standardPadding()*2; + var w = (this.windowWidth()-this.standardPadding()*2)/2; + var h = this.lineHeight(); + if(this._index){ + this.setCursorRect(x, y, w, h); + }else{ + this.setCursorRect(w, y, w, h); + } + }; + + +//************************************************************************************************ +// +// Window_Techtree_Confirm // Cost Handling +// +//************************************************************************************************ + + Window_Techtree_Confirm.prototype.createCostArray = function(costsObject) { + var costArr = []; + var costs = costsObject; + if(costs.gold > 0){ + var gold; + if(Imported.YEP_CoreEngine === true){ + gold = {"icon":Yanfly.Icon.Gold, "amount":costs.gold, "canPay": ($gameParty.gold()>=costs.gold ? true : false)}; + }else{ + gold = {"text":TextManager.currencyUnit, "amount":costs.gold, "canPay": ($gameParty.gold()>=costs.gold ? true : false)}; + } + costArr.push(gold); + } + if(costs.jp > 0 && Imported.YEP_JobPoints){ + var jp = {"icon":Yanfly.Icon.Jp, "amount":costs.jp, "canPay": (this._actor.jp()>=costs.jp ? true : false)}; + costArr.push(jp); + } + if(costs.items){ + for (var i = 0; i < costs.items.length; i++) { + var item = $dataItems[costs.items[i].id]; + if(item){ + var cost = costs.items[i].amount; + var itemcost = {"icon":item.iconIndex, "amount":cost, "canPay": ($gameParty.numItems(item)>=cost ? true : false)}; + costArr.push(itemcost); + }else{ + console.warn("There is an item cost that points to no item. Item ID: "+costs.items[i].id); + } + } + } + if(costs.weapons){ + for (var i = 0; i < costs.weapons.length; i++) { + var weapon = $dataWeapons[costs.weapons[i].id]; + if(weapon){ + var cost = costs.weapons[i].amount; + var itemcost = {"icon":weapon.iconIndex, "amount":cost, "canPay": ($gameParty.numItems(weapon)>=cost ? true : false)}; + costArr.push(itemcost); + }else{ + console.warn("There is an weapon cost that points to no weapon. Weapon ID: "+costs.weapons[i].id); + } + } + } + if(costs.armors){ + for (var i = 0; i < costs.armors.length; i++) { + var armor = $dataArmors[costs.armors[i].id]; + if(armor){ + var cost = costs.armors[i].amount; + var itemcost = {"icon":armor.iconIndex, "amount":cost, "canPay": ($gameParty.numItems(armor)>=costs ? true : false)}; + costArr.push(itemcost); + }else{ + console.warn("There is an armor cost that points to no armor. Armor ID: "+costs.armors[i].id); + } + } + } + return costArr; + }; + + Window_Techtree_Confirm.prototype.measureCostArrayWidth = function(costsArray) { + var costs = costsArray; + var hp = this.standardPadding()/2; + var ip = Window_Base._iconWidth + hp; + var amountWidth = 0; + var textWidth = 0; + var costWidth = 0; + for (var i = 0; i < costs.length; i++) { + if(costs[i].icon){ + costWidth = costWidth + ip; + }else if(costs[i].text){ + textWidth = this.textWidth(costs[i].text); + costWidth = costWidth + textWidth + hp; + } + amountWidth = this.textWidth(costs[i].amount); + costWidth = costWidth + amountWidth + hp; + } + return costWidth; + }; + + Window_Techtree_Confirm.prototype.canPayCost = function() { + var costs = this._costsArray; + var canPay = true; + for (var i = 0; i < costs.length; i++) { + if(!costs[i].canPay){ + canPay = false; + } + } + return canPay; + }; + + Window_Techtree_Confirm.prototype.payCost = function() { + var costs = this._node.technode.costs; + if(costs.gold > 0){ + $gameParty.loseGold(costs.gold); + } + if(costs.jp > 0 && Imported.YEP_JobPoints){ + this._actor.loseJp(costs.jp); + } + if(costs.items.length > 0){ + for (var i = 0; i < costs.items.length; i++) { + var item = $dataItems[costs.items[i].id]; + var cost = costs.items[i].amount; + $gameParty.loseItem(item, cost, false); + } + } + if(costs.weapons.length > 0){ + for (var i = 0; i < costs.weapons.length; i++) { + var weapon = $dataWeapons[costs.weapons[i].id]; + var cost = costs.weapons[i].amount; + $gameParty.loseItem(weapon, cost, false); + } + } + if(costs.armors.length > 0){ + for (var i = 0; i < costs.armors.length; i++) { + var armor = $dataArmors[costs.armors[i].id]; + var cost = costs.armors[i].amount; + $gameParty.loseItem(armor, cost, false); + } + } + }; + + Window_Techtree_Confirm.prototype.onActivate = function() { + this._actor.onActivateTechtreeNode(this._node.technode); + var onActivate = this._node.technode.onActivate; + // Animation + var animation; + if(Felski.Techtree.NodeAnimDefaultID){ + animation = $dataAnimations[Felski.Techtree.NodeAnimDefaultID]; + } + if(this._activeTree.animation){ + if(this._activeTree.animation.id){ + animation = $dataAnimations[this._activeTree.animation.id]; + } + } + if(onActivate.animation){ + if(onActivate.animation.id){ + animation = $dataAnimations[onActivate.animation.id]; + } + } + if(animation){ + this.parent._activateAnimation = new Sprite_Techtree_Animation(animation); + this.parent._activateAnimation.move(this._animX + Felski.Techtree.NodeAnimXOffset, this._animY + Felski.Techtree.NodeAnimYOffset); + this.parent.addChild(this.parent._activateAnimation); + } + }; + + +//************************************************************************************************ +// +// Window_Techtree_Confirm // Event Handling +// +//************************************************************************************************ + + Window_Techtree_Confirm.prototype.processHandling = function() { + if (this.isOpenAndActive()) { + if (this.isOkTriggered()) { + this.processOk(); + } else if (this.isCancelTriggered()) { + this.processCancel(); + } /*else if (this.isHandled('pagedown') && Input.isTriggered('pagedown')) { + this.processPagedown(); + } else if (this.isHandled('pageup') && Input.isTriggered('pageup')) { + this.processPageup(); + } */ + } + }; + + Window_Techtree_Confirm.prototype.processCursorMove = function() { + if (this.isOpenAndActive()) { + var lastIndex = this._index; + if (Input.isRepeated('down')) { + this.cursorMove(Input.isTriggered('down')); + } + if (Input.isRepeated('up')) { + this.cursorMove(Input.isTriggered('up')); + } + if (Input.isRepeated('right')) { + this.cursorMove(Input.isTriggered('right')); + } + if (Input.isRepeated('left')) { + this.cursorMove(Input.isTriggered('left')); + } + /* + if (!this.isHandled('pagedown') && Input.isTriggered('pagedown')) { + this.cursorPagedown(); + } + if (!this.isHandled('pageup') && Input.isTriggered('pageup')) { + this.cursorPageup(); + } + */ + if (this._index !== lastIndex) { + SoundManager.playCursor(); + } + } + }; + + Window_Techtree_Confirm.prototype.cursorMove = function() { + if(this._index){ + this._index = false; + }else{ + this._index = true; + } + }; + + Window_Techtree_Confirm.prototype.processCancel = function() { + SoundManager.playCancel(); + this.updateInputData(); + this.deactivate(); + this.callCancelHandler(); + }; + + Window_Techtree_Confirm.prototype.processOk = function() { + if(this.canBeUnlocked() && this.canPayCost()){ + if(this._index){ + this.payCost(); + this.onActivate(); + if(!Felski.Techtree.suppressConfirmSound) this.playOkSound(); + this.updateInputData(); + this.deactivate(); + this.callOkHandler(); + }else{ + this.processCancel(); + } + }else{ + if(this._index){ + this.playBuzzerSound(); + this.updateInputData(); + }else{ + this.processCancel(); + } + } + }; + + Window_Techtree_Confirm.prototype.processTouch = function() { + if (this.isOpenAndActive()) { + if (TouchInput.isTriggered() && this.isTouchedInsideFrame()) { + this._touching = true; + this.onTouch(true); + } else if (TouchInput.isCancelled()) { + this.processCancel(); + } + if (this._touching) { + if (TouchInput.isPressed()) { + this.onTouch(false); + } else { + this._touching = false; + } + } + } else { + this._touching = false; + } + }; + + Window_Techtree_Confirm.prototype.onTouch = function(triggered) { + var lastIndex = this.index(); + var x = this.canvasToLocalX(TouchInput.x); + var y = this.canvasToLocalY(TouchInput.y); + var hitIndex = this.hitTest(x, y); + + if (hitIndex === true) { + if (hitIndex == lastIndex) { + if(triggered){ + this.processOk(); + } + } else { + this.cursorMove(); + } + } else if (hitIndex === false) { + if (hitIndex == lastIndex) { + if(triggered){ + this.processCancel(); + } + } else { + this.cursorMove(); + } + } + if (this.index() !== lastIndex) { + SoundManager.playCursor(); + } + }; + + Window_Techtree_Confirm.prototype.hitTest = function(x, y) { + if (this.isContentsArea(x, y)) { + var cx = x - this.padding; + var cy = y - this.padding; + var x = 0; + var y = this.windowHeight() - this.lineHeight() - this.standardPadding()*2; + var w = (this.windowWidth()-this.standardPadding()*2)/2; + var h = this.lineHeight(); + var right = x + w; + var bottom = y + h; + if (cx >= x && cy >= y && cx < right && cy < bottom) { + return true; + } + var right = w + w; + var bottom = y + h; + if (cx >= x && cy >= y && cx < right && cy < bottom) { + return false; + } + } + return -1; + }; + +//************************************************************************************************ +// +// Window_Techtree_Confirm // Checks +// +//************************************************************************************************ + + Window_Techtree_Confirm.prototype.isNodeVisible = function() { + if(this._node){ + var switches = this._node.technode.visibility.switches; + var visible = false; + if(switches.length > 0){ + for (var i = 0; i < switches.length; i++) { + if(!$gameSwitches.value(switches[i].id)){ + return false; + }else{ + visible = true; + } + } + return visible; + }else{ + return true; + } + }else{ + return false; + } + }; + + Window_Techtree_Confirm.prototype.isCurrentItemEnabled = function() { + return (!!this._node); + }; + + Window_Techtree_Confirm.prototype.isNodeActive = function() { + if(this._node){ + return this._node.active; + }else{ + return false; + } + }; + + Window_Techtree_Confirm.prototype.isContentsArea = function(x, y) { + var left = this.padding; + var top = this.padding; + var right = this.width - this.padding; + var bottom = this.height - this.padding; + return (x >= left && y >= top && x < right && y < bottom); + }; + + Window_Techtree_Confirm.prototype.isTouchedInsideFrame = function() { + var x = this.canvasToLocalX(TouchInput.x); + var y = this.canvasToLocalY(TouchInput.y); + return x >= 0 && y >= 0 && x < this.width && y < this.height; + }; + + Window_Techtree_Confirm.prototype.canBeUnlocked = function() { + if(!this._node){ + return false; + }else if(this._node.active){ + return false; + }else if(!this.isNodeVisible()){ + return false; + }else if(this._onlyDisplay){ + return false; + }else if(this._actor.level < this._node.technode.levelRequirement){ + return false; + }else{ + var parents = this._node.technode.parents; + var neededParents = this._node.technode.neededParents; + var activeParents = 0; + for (var i = 0; i < parents.length; i++) { + var parent = $gameSystem.searchTechtree(this._activeTree, parents[i].parent); + if(parent){ + if(parent.active){ + activeParents = activeParents + 1; + } + } + } + if(neededParents <= activeParents){ + return true; + }else{ + return false; + } + } + }; + +//************************************************************************************************ +// +// Window_Techtree_Confirm // Handler Methods +// +//************************************************************************************************ + + Window_Techtree_Confirm.prototype.setOkHandler = function(method) { + this._okHandler = method; + }; + + Window_Techtree_Confirm.prototype.callOkHandler = function() { + if (this._okHandler) { + this._okHandler(this._node); + } + }; + + Window_Techtree_Confirm.prototype.setCancelHandler = function(method) { + this._cancelHandler = method; + }; + + Window_Techtree_Confirm.prototype.callCancelHandler = function() { + if (this._cancelHandler) { + this._cancelHandler(); + } + }; + + Window_Techtree_Confirm.prototype.isOkTriggered = function() { + return Input.isRepeated('ok'); + }; + + Window_Techtree_Confirm.prototype.isCancelTriggered = function() { + return Input.isRepeated('cancel'); + }; + + Window_Techtree_Confirm.prototype.updateInputData = function() { + Input.update(); + TouchInput.update(); + }; + + Window_Techtree_Confirm.prototype.playOkSound = function() { + SoundManager.playOk(); + }; + + Window_Techtree_Confirm.prototype.playBuzzerSound = function() { + SoundManager.playBuzzer(); + }; + + Window_Techtree_Confirm.prototype.isOpenAndActive = function() { + return this.isOpen() && this.active; + }; + + +//************************************************************************************************ +// +// Window_Techtree_Currency +// +//************************************************************************************************ + + Window_Techtree_Currency.prototype = Object.create(Window_Base.prototype); + Window_Techtree_Currency.prototype.constructor = Window_Techtree_Currency; + + Window_Techtree_Currency.prototype.initialize = function(x, y, actor) { + var width = this.windowWidth(); + var height = this.windowHeight(); + this._actor = actor; + this._techtrees = this._actor._techtrees; + this._activeTree = this._techtrees[0]; + Window_Base.prototype.initialize.call(this, x, y, width, height); + }; + + Window_Techtree_Currency.prototype.windowWidth = function() { + return (Window_Base._faceWidth + this.standardPadding())*1; + }; + + Window_Techtree_Currency.prototype.windowHeight = function() { + return Window_Base._faceHeight + this.standardPadding(); + }; + + Window_Techtree_Currency.prototype.update = function() { + Window_Base.prototype.update.call(this); + if (this._actor && this._activeTree) { + this.refresh(); + } + }; + + Window_Techtree_Currency.prototype.setTree = function(treeId) { + if(treeId >= 0 && treeId < this._techtrees.length){ + this._activeTree = this._techtrees[treeId]; + } + }; + + Window_Techtree_Currency.prototype.refresh = function() { + this.contents.clear(); + var lh = this.lineHeight(); + var sp = this.standardPadding(); + var w = Window_Base._faceWidth; + var x = 0; + var y = 0; + var x2 = w - Window_Base._iconWidth - sp; + var y2 = w/2 - lh/2; + var w2 = x2; + + this.setFont(Felski.Techtree.TTHeaderCurFont); + this.changeTextColor(this.textColor(Felski.Techtree.TTHeaderCurFontColor)); + this.setFontSize(Felski.Techtree.TTHeaderCurFontSize); + + lh = Felski.Techtree.TTHeaderCurFontSize + 4; + + var actor = this._actor; + var classId = actor.currentClass().id; + var tree = this._activeTree; + var icon = 1; + + var c = 0; + if(!tree.hideGoldCost){ + var gold = $gameParty.gold(); + if(Imported.YEP_CoreEngine === true){ + icon = Yanfly.Icon.Gold; + }else{ + icon = TextManager.currencyUnit; + } + this.drawText(gold, 0, y+lh*c, w2, 'right'); + this.drawIcon(icon, w2, y+lh*c); + c++; + } + + if(!tree.hideJPCost && Imported.YEP_JobPoints){ + var jp = actor.jp(classId); + icon = Yanfly.Icon.Jp; + this.drawText(jp, 0, y+lh*c, w2, 'right'); + this.drawIcon(icon, w2, y+lh*c); + c++; + } + + if(tree.costItems){ + for (var i = 0; i <= tree.costItems.length - 1; i++) { + var item = $dataItems[tree.costItems[i]]; + if(item){ + var amount = $gameParty.numItems(item); + var icon = item.iconIndex; + this.drawText(amount, 0, y+lh*c, w2, 'right'); + this.drawIcon(icon, w2, y+lh*c); + c++; + }else{ + console.warn("Couldn't find costItem with the ID "+tree.costItems[i]+" for tree "+tree.uid+"("+tree.header+")."); + } + } + } + + this.resetFontSettings(); + }; + + +//************************************************************************************************ +// +// Window_Base // Drawing Helping Functions +// +//************************************************************************************************ + + Window_Base.prototype.drawBoxFrameBitmap = function(x, y, w, h, skin) { + var m = 24; + var bitmap = new Bitmap(w, h); + if (w > 0 && h > 0 && skin) { + var p = 96; + var q = 96; + bitmap.blt(skin, p+m, 0+0, p-m*2, m, m, 0, w-m*2, m); //upper line + bitmap.blt(skin, p+m, 0+q-m, p-m*2, m, m, h-m, w-m*2, m); // bottom line + bitmap.blt(skin, p+0, 0+m, m, p-m*2, 0, m, m, h-m*2); // left line + bitmap.blt(skin, p+q-m, 0+m, m, p-m*2, w-m, m, m, h-m*2); // right line + bitmap.blt(skin, p+0, 0+0, m, m, 0, 0, m, m); // top left corner + bitmap.blt(skin, p+q-m, 0+0, m, m, w-m, 0, m, m); // top right corner + bitmap.blt(skin, p+0, 0+q-m, m, m, 0, h-m, m, m); // bottom left corner + bitmap.blt(skin, p+q-m, 0+q-m, m, m, w-m, h-m, m, m); // bottom right corner + } + this.contents.blt(bitmap, 0, 0, w, h, x, y); + }; + + Window_Base.prototype.drawBoxFrameBackgroundBitmap = function(x, y, w, h, skin, opacity) { + var m = this._margin; + //var m = this._margin; + var w = w - m * 2; + var h = h - m * 2; + var opacity = opacity || 255; + var bitmap = new Bitmap(w, h); + if (w > 0 && h > 0 && skin) { + var p = 96; + bitmap.blt(skin, 0, 0, p, p, 0, 0, w, h); + var tone = this._colorTone; + bitmap.adjustTone(tone[0], tone[1], tone[2]); + } + var oldOpacity = this.contents.paintOpacity; + this.contents.paintOpacity = opacity; + this.contents.blt(bitmap, 0, 0, w, h, x+m, y+m); + this.contents.paintOpacity = oldOpacity; + }; + + Window_Base.prototype.drawArrow = function(x1, y1, x2, y2, skin) { + var sw = skin.width/4; + var sh = skin.height/3; + y1 = y1 - sh/2; + y2 = y2 - sh/2; + var tx = Math.min(x1, x2); + var ty = Math.min(y1, y2); + var w = x1 - x2; + var h = y1 - y2; + if(w<0){ + w = w * -1; + } + if(h<0) { + h = h * -1; + } + h = h + sh; + var bitmap = new Bitmap(w, h); + /** + * Performs a block transfer. + * + * @method blt + * @param {Bitmap} source The bitmap to draw + * @param {Number} sx The x coordinate in the source + * @param {Number} sy The y coordinate in the source + * @param {Number} sw The width of the source image + * @param {Number} sh The height of the source image + * @param {Number} dx The x coordinate in the destination + * @param {Number} dy The y coordinate in the destination + * @param {Number} [dw=sw] The width to draw the image in the destination + * @param {Number} [dh=sh] The height to draw the image in the destination + */ + if (w > 0 && h > 0 && skin) { + if(y1 == y2){ // same height + bitmap.blt(skin, 0, sh, sw, sh, x1-tx, y1-ty, sw, sh); //middle left + bitmap.blt(skin, 0, sh, sw, sh, x1-tx+sw, y1-ty, w-sw*2, sh); //middle left + bitmap.blt(skin, sw*3, sh, sw, sh, x1-tx+w-sw, y1-ty, sw, sh); //arrowhead + }else if (y1 < y2){ // target below + bitmap.blt(skin, 0, sh, sw, sh, x1-tx, y1-ty, sw, sh); //middle left + bitmap.blt(skin, sw*2, 0, sw, sh, x1-tx+sw, y1-ty, sw, sh); //top right + bitmap.blt(skin, sw, sh, sw, sh, x1-tx+sw, y1-ty+sh, sw, h-sh*2); //middle middle + if(w>sw*3) bitmap.blt(skin, 0, sh, sw, sh, x1-tx+sw*2, y1-ty+h-sh, w-sw*3, sh); //middle left + bitmap.blt(skin, 0, sh*2, sw, sh, x1-tx+sw, y1-ty+h-sh, sw, sh); //bottom left + bitmap.blt(skin, sw*3, sh, sw, sh, x1-tx+w-sw, y1-ty+h-sh, sw, sh); //arrowhead + }else if (y1 > y2){ // target above + bitmap.blt(skin, 0, sh, sw, sh, x1-tx, y2-ty+h-sh, sw, sh); //middle left + bitmap.blt(skin, sw*2, sh*2, sw, sh, x1-tx+sw, y2-ty+h-sh, sw, sh); //bottom right + bitmap.blt(skin, sw, sh, sw, sh, x1-tx+sw, y2-ty+sh, sw, h-sh*2); //middle middle + if(w>sw*3) bitmap.blt(skin, 0, sh, sw, sh, x1-tx+sw*2, y2-ty, w-sw*3, sh); //middle left + bitmap.blt(skin, 0, 0, sw, sh, x1-tx+sw, y2-ty, sw, sh); //top left + bitmap.blt(skin, sw*3, sh, sw, sh, x1-tx+w-sw, y2-ty, sw, sh); //arrowhead + }else{ + + } + } + this.contents.blt(bitmap, 0, 0, w, h, tx, ty); + }; + + Window_Base.prototype.setFontSize = function(size) { + this.contents.fontSize = size; + }; + + Window_Base.prototype.setFont = function(font) { + this.contents.fontFace = font; + }; + + +//************************************************************************************************ +// +// Sprite_FelskiButton +// +//************************************************************************************************ + + function Sprite_FelskiButton() { + this.initialize.apply(this, arguments); + } + + Sprite_FelskiButton.prototype = Object.create(Sprite.prototype); + Sprite_FelskiButton.prototype.constructor = Sprite_FelskiButton; + + Sprite_FelskiButton.prototype.initialize = function(x, y, id) { + Sprite.prototype.initialize.call(this); + this.x = x; + this.y = y; + this._id = id; + this._touching = false; + this._hovering = false; + this._hoverHandler = null; + this._endHoverHandler = null; + this._rightClickHandler = null; + this._clickHandler = null; + this._touchHandler = null; + this._releaseHandler = null; + }; + +//************************************************************************************************ +// +// Sprite_FelskiButton // Handler Methods +// +//************************************************************************************************ + + Sprite_FelskiButton.prototype.setHoverHandler = function(method) { + this._hoverHandler = method; + }; + + Sprite_FelskiButton.prototype.callHoverHandler = function() { + if (this._hoverHandler) { + this._hoverHandler(this.position.x, this.position.y, this._id); + } + }; + + Sprite_FelskiButton.prototype.setEndHoverHandler = function(method) { + this._endHoverHandler = method; + }; + + Sprite_FelskiButton.prototype.callEndHoverHandler = function() { + if (this._endHoverHandler) { + this._endHoverHandler(this.position.x, this.position.y, this._id); + } + }; + + Sprite_FelskiButton.prototype.setRightClickHandler = function(method) { + this._rightClickHandler = method; + }; + + Sprite_FelskiButton.prototype.callRightClickHandler = function() { + if (this._rightClickHandler) { + this._rightClickHandler(this.position.x, this.position.y, this._id); + } + }; + + Sprite_FelskiButton.prototype.setClickHandler = function(method) { + this._clickHandler = method; + }; + + Sprite_FelskiButton.prototype.callClickHandler = function() { + if (this._clickHandler) { + this._clickHandler(this.position.x, this.position.y, this._id); + } + }; + + Sprite_FelskiButton.prototype.setTouchHandler = function(method) { + this._touchHandler = method; + }; + + Sprite_FelskiButton.prototype.callTouchHandler = function() { + if (this._touchHandler) { + this._touchHandler(this.position.x, this.position.y, this._id); + } + }; + + Sprite_FelskiButton.prototype.setReleaseHandler = function(method) { + this._releaseHandler = method; + }; + + Sprite_FelskiButton.prototype.callReleaseHandler = function() { + if (this._releaseHandler) { + this._releaseHandler(this.position.x, this.position.y, this._id); + } + }; + +//************************************************************************************************ +// +// Sprite_FelskiButton // Update Flow +// +//************************************************************************************************ + + Sprite_FelskiButton.prototype.update = function() { + Sprite.prototype.update.call(this); + this.processTouch(); + }; + + Sprite_FelskiButton.prototype.processTouch = function() { + if (this.isActive()) { + if(!this._touching){ + if(this.isSpriteHovered()){ + this._hovering = true; + this.callHoverHandler(); + }else{ + if(this._hovering === true){ + this._hovering = false; + this.callEndHoverHandler(); + } + } + } + if (TouchInput.isTriggered() && this.isButtonTouched()) { + this._touching = true; + this.callTouchHandler(); + } + if (this._touching) { + if (TouchInput.isReleased()) { + this._touching = false; + if (TouchInput.isReleased()) { + this.callReleaseHandler(); + } + }else{ + } + } + if (TouchInput.isCancelled() && this.isButtonTouched()){ + this.callRightClickHandler(); + } + } else { + this._touching = false; + } + }; + +//************************************************************************************************ +// +// Sprite_FelskiButton // Checks +// +//************************************************************************************************ + + Sprite_FelskiButton.prototype.isActive = function() { + var node = this; + while (node) { + if (!node.visible) { + return false; + } + node = node.parent; + } + return true; + }; + + Sprite_FelskiButton.prototype.isButtonTouched = function() { + var x = this.canvasToLocalX(TouchInput.x); + var y = this.canvasToLocalY(TouchInput.y); + return x >= 0 && y >= 0 && x < this.width && y < this.height; + }; + + Sprite_FelskiButton.prototype.isSpriteHovered = function() { + var x = this.canvasToLocalX(TouchInput.x); + var y = this.canvasToLocalY(TouchInput.y); + return x >= 0 && y >= 0 && x < this.width && y < this.height; + }; + +//************************************************************************************************ +// +// Sprite_FelskiButton // Util +// +//************************************************************************************************ + + Sprite_FelskiButton.prototype.canvasToLocalX = function(x) { + var node = this; + while (node) { + x -= node.x; + node = node.parent; + } + return x; + }; + + Sprite_FelskiButton.prototype.canvasToLocalY = function(y) { + var node = this; + while (node) { + y -= node.y; + node = node.parent; + } + return y; + }; + + Sprite_FelskiButton.prototype.resetPosition = function() { + this.position.x = this._oldPosX; + this.position.y = this._oldPosY; + }; + +//************************************************************************************************ +// +// Sprite_Techtree_Animation +// +//************************************************************************************************ + + function Sprite_Techtree_Animation() { + this.initialize.apply(this, arguments); + } + + Sprite_Techtree_Animation.prototype = Object.create(Sprite_Base.prototype); + Sprite_Techtree_Animation.prototype.constructor = Sprite_Techtree_Animation; + + Sprite_Techtree_Animation.prototype.initialize = function(animation) { + Sprite_Base.prototype.initialize.call(this); + this.z = 9; + this._realX = this.x; + this._realY = this.y; + this._animation = animation; + this._hasStarted = false; + this._hasFinished = false; + }; + + Sprite_Techtree_Animation.prototype.update = function() { + Sprite_Base.prototype.update.call(this); + if (!this._hasStarted && this.parent) { + this.startAnimation(this._animation, false, 0); + this._hasStarted = true; + } + if (this._hasStarted && !this.isAnimationPlaying()) { + this._hasFinished = true; + } + }; + + Sprite_Techtree_Animation.prototype.finished = function() { + return this._hasFinished; + }; + + +//************************************************************************************************ +// +// Utility Stuff +// +//************************************************************************************************ +/* + Window_Base.prototype.drawTextAutoWrap = function (text, x, y, maxWidth) { + if (!text) { + return 0; + } + const words = text.split(' '); + let lines = 1; + let x2 = x; + let y2 = y; + words.forEach((word) => { + word = this.convertEscapeCharacters(word); + const width = this.textWidth(word + ' '); + // Check for linebreak symbol '/n' + if (word === `\x1bn`) { + lines++; + y2 += this.lineHeight(); + x2 = 0; + } + if (x2 + width >= maxWidth) { + lines++; + y2 += this.lineHeight(); + x2 = 0; + } + this.drawText(word + ' ', x+x2, y2); + x2 += width; + }); + return lines; + }; +*/ + Window_Base.prototype.drawTextAutoWrap = function (text, x, y, maxWidth) { + const iconRegex = /\x1bi\[(\d+)\]/; + if (!text) { + return 0; + } + const words = text.split(' '); + let lines = 1; + let x2 = x; + let y2 = y; + words.forEach((word) => { + word = this.convertEscapeCharacters(word); + const width = this.textWidth(word + ' '); + // Check for linebreak symbol '/n' + if (word === `\x1bn`) { + lines++; + y2 += this.techTreeLineHeight(); + x2 = 0; + } + // Check for \i[iconIndex] + if(word.match(iconRegex)){ + if (x2 + width >= maxWidth) { + lines++; + y2 += this.techTreeLineHeight(); + x2 = 0; + } + var iconIndex = Number(RegExp.$1); + this.drawIcon(iconIndex, x+x2, y2); + x2 = x2 + Window_Base._iconWidth + this.standardPadding(); + return; + } + if (x2 + width >= maxWidth) { + lines++; + y2 += this.techTreeLineHeight(); + x2 = 0; + } + this.drawText(word + ' ', x+x2, y2); + x2 += width; + }); + return lines; + }; + + Window_Base.prototype.techTreeLineHeight = function() { + return this.contents.fontSize+8; + }; + + function jsonCopy(src) { //Credits and thanks to Farzad YZ on medium.com + return JSON.parse(JSON.stringify(src)); + } + +})(); \ No newline at end of file diff --git a/js/plugins/YEP_ClassChangeCore.js b/js/plugins/YEP_ClassChangeCore.js new file mode 100644 index 0000000..232f9a0 --- /dev/null +++ b/js/plugins/YEP_ClassChangeCore.js @@ -0,0 +1,1479 @@ +//============================================================================= +// Yanfly Engine Plugins - Class Change Core +// YEP_ClassChangeCore.js +//============================================================================= + +var Imported = Imported || {}; +Imported.YEP_ClassChangeCore = true; + +var Yanfly = Yanfly || {}; +Yanfly.CCC = Yanfly.CCC || {}; +Yanfly.CCC.version = 1.13; + +//============================================================================= + /*: + * @plugindesc v1.13 This plugin creates a system where your player + * can change classes through the main menu. + * @author Yanfly Engine Plugins + * + * @param ---General--- + * @default + * + * @param Class Command + * @parent ---General--- + * @desc This is the text used for the menu command. + * @default Class + * + * @param Auto Add Menu + * @parent ---General--- + * @desc Automatically add the 'Class' command to the main menu? + * NO - false YES - true + * @default true + * + * @param Show Command + * @parent ---General--- + * @type boolean + * @on Show + * @off Hide + * @desc Show the Class command in the main menu by default? + * NO - false YES - true + * @default true + * + * @param Enable Command + * @parent ---General--- + * @type boolean + * @on Enable + * @off Disable + * @desc Enable the Class command in the main menu by default? + * NO - false YES - true + * @default true + * + * @param Auto Place Command + * @parent ---General--- + * @type boolean + * @on Automatic + * @off Manual + * @desc Allow this plugin to decide the menu placement position? + * NO - false YES - true + * @default true + * + * @param Default Icon + * @parent ---General--- + * @desc This is the default icon index used for all classes. + * @default 78 + * + * @param Maintain Levels + * @parent ---General--- + * @type number + * @min 0 + * @desc Maintain levels throughout all classes? + * NO - false YES - true Default: false + * @default false + * + * @param Unlocked Classes + * @parent ---General--- + * @desc These are the classes that are unlocked by default. List + * the ID's of the classes with spaces in between them. + * @default 1 2 3 4 + * + * @param ---Command Window--- + * @default + * + * @param Class Change Command + * @parent ---Command Window--- + * @desc The command text used for changing the primary class. + * @default Class + * + * @param Show Class Change + * @parent ---Command Window--- + * @type boolean + * @on Show + * @off Hide + * @desc Show the class change command by default? + * NO - false YES - true + * @default true + * + * @param Enable Class Change + * @parent ---Command Window--- + * @type boolean + * @on Enable + * @off Disable + * @desc Enable the class change command by default? + * NO - false YES - true + * @default true + * + * @param Show Skill Learn + * @parent ---Command Window--- + * @type boolean + * @on Show + * @off Hide + * @desc If you have Skill Learn System, show 'Learn Skill'? + * NO - false YES - true + * @default true + * + * @param Finish Command + * @parent ---Command Window--- + * @desc The command text used for exiting the class scene. + * @default Finish + * + * @param Text Alignment + * @parent ---Command Window--- + * @type combo + * @option left + * @option center + * @option right + * @desc How to align the text for the command window. + * left center right + * @default center + * + * @param ---Window Settings--- + * @default + * + * @param Current Class Color + * @parent ---Window Settings--- + * @type number + * @min 0 + * @max 31 + * @desc This is the text color used for the actor's current class. + * @default 17 + * + * @param Class Level Format + * @parent ---Window Settings--- + * @desc This is the text format for the Class Level. + * @default LV%1 + * + * @param Class Level Font Size + * @parent ---Window Settings--- + * @type number + * @min 1 + * @desc This is the font size used for the class level. + * @default 20 + * + * @help + * ============================================================================ + * Introduction + * ============================================================================ + * + * This plugin adds the ability for your player to freely change the classes of + * actors outside of battle from a menu. When changing classes, this script + * gives the option for the developer to choose whether or not classes have + * their own levels (causing the actor’s level to reset back to the class’s + * level) or to maintain the current level. + * + * ============================================================================ + * Notetags + * ============================================================================ + * + * The following are some notetags you can use with the Class Change Core + * plugin. + * + * Actor Notetags: + * + * + * + * This actor will have class(es) x unlocked at the start of the game in + * addition to its current class and access to any of the global classes. + * + * + * This prevents this actor from being able to change primary classes. This + * could be reversed from plugin commands, however. + * + * + * When this actor's class is x, the actor's character sprite will become + * 'filename' and index y on the fieldmap. + * + * + * + * If you prefer to use class names instead of the class ID, use the above + * format. When this actor is this class, the actor's character sprite will + * become 'filename' and index y on the fieldmap. + * + * + * When this actor's class is x, the actor's face graphic will become + * 'filename' and index y for menus. + * + * + * + * If you prefer to use class names instead of the class ID, use the above + * format. When this actor is this class, the actor's face graphic will + * become 'filename' and index y for menus. + * + * + * When this actor's class is x, the actor's battler sprite will become + * 'filename' in battle. + * + * + * + * If you prefer to use class names instead of the class ID, use the above + * format. When this actor is this class, the actor's battler sprite will + * become 'filename' in battle. + * + * Class Notetags: + * + * Sets the icon for this class to x. This icon is used in the Class Change + * menu listing. + * + * + * This will cause the class to use the nickname used by the actor instead + * of the class name. + * + * + * Text + * Text + * + * Sets the help description for the class to the specified text. + * + * + * Class x: Level y + * Class x: Level y + * + * Sets the requirements for unlocking that particular class. The unlocking + * of the class will require classes x to be at level y. Insert multiple of + * the strings in between the two opening and closing notetags to require all + * of the class levels to be met. + * + * + * Hero: Level y + * Warrior: Level y + * + * If you prefer to use class names instead of the class ID, use the above + * format. This will set the level requirement for the mentioned class to y. + * If there are multiple classes with the same name, the class with the + * highest ID value will be taken. + * + * ============================================================================ + * Plugin Commands + * ============================================================================ + * + * Included in this plugin are multiple Plugin Commands to help assist you with + * class changing for your game. + * + * Plugin Command + * OpenClass + * - This opens the class changing scene. + * + * ShowClass + * HideClass + * - This shows/hides the Class option from the main menu. + * + * EnableClass + * DisableClass + * - This makes the Class option enabled/disabled. + * + * UnlockClass 5 6 + * - This allows Actor 5 to unlock Class 6. + * + * RemoveClass 5 7 + * - This causes Actor 5 to no longer access Class 7. + * + * UnlockClassAll 8 + * - This unlocks Class 8 for the global pool. + * + * RemoveClassAll 9 + * - This removes Class 9 from the global pool. + * + * EnablePrimaryClassChange 5 + * DisablePrimaryClassChange 5 + * - This enables/disables primary class changing for actor 5. + * + * ============================================================================ + * Main Menu Manager - Positioning the Class Command + * ============================================================================ + * + * For those using the Main Menu Manager and would like to position the Row + * command in a place you'd like, use the following format: + * + * Name: Yanfly.Param.CCCCmdName + * Symbol: class + * Show: $gameSystem.isShowClass() + * Enabled: $gameSystem.isEnableClass() + * Ext: + * Main Bind: this.commandPersonal.bind(this) + * Actor Bind: SceneManager.push(Scene_Class) + * + * Insert the above setup within a Main Menu Manager slot. Provided you copy + * the exact settings to where you need it, it will appear there while using + * all of the naming, enabling, disabling, hiding, and showing effects done by + * the plugin parameters. + * + * Remember to turn off 'Auto Add Menu' from the plugin parameters. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version 1.13: + * - Updated for RPG Maker MV version 1.5.0. + * + * Version 1.12: + * - Optimization update. + * + * Version 1.11: + * - Added notetag for classes. This will cause the class to use + * the actor's nickname instead when listed in the class list. + * + * Version 1.10: + * - Added notetag for actors and two plugin commands: + * EnablePrimaryClassChange and DisablePrimaryClassChange for actors. + * - Added 'Auto Add Menu' to plugin parameters. This way, users don't have to + * make conflict with it if manually positioning the command with the Main Menu + * Manager plugin. + * + * Version 1.09a: + * - Optimization update. + * - When switching classes to a globally unlocked class, actors won't unlock + * those classes anymore. This is to keep the RemoveClassAll working without + * having to manually use RemoveClass for all classes individually. + * + * Version 1.08: + * - Updated for RPG Maker MV version 1.1.0. + * + * Version 1.07: + * - Fixed a bug that carried over a previously changed actor's stats into the + * stat comparison window. + * + * Version 1.06: + * - Made an update to the 'Change Actor Images' to give changes to actor + * images priority over class images. Setting the 'Change Actor Images' to + * (None) will return it back to using class images. + * + * Version 1.05: + * - If using the Skill Learn System and Skill Menu Integration, the + * "Learn Skill" command now carries over to the Skill menu itself to utilize + * the integrated system. + * + * Version 1.04: + * - Fixed a bug that would revive dead party members by changing their class. + * + * Version 1.03: + * - Fixed a bug that would duplicate non-independent items. + * - Fixed a bug that prevented visual appearances from updating until entering + * a new map. + * + * Version 1.02a: + * - Added a failsafe for users to prevent them from attempting to learn skills + * from classes that don't exist. + * + * Version 1.01: + * - Fixed an asynch issue with changing class images when moving to another + * face graphic that isn't on the same image. + * + * Version 1.00: + * - Finished Plugin! + */ +//============================================================================= + +//============================================================================= +// Parameter Variables +//============================================================================= + +Yanfly.Parameters = PluginManager.parameters('YEP_ClassChangeCore'); +Yanfly.Param = Yanfly.Param || {}; +Yanfly.Icon = Yanfly.Icon || {}; + +Yanfly.Param.CCCCmdName = String(Yanfly.Parameters['Class Command']); +Yanfly.Param.CCCAutoAdd = eval(String(Yanfly.Parameters['Auto Add Menu'])); +Yanfly.Param.CCCShowCmd = String(Yanfly.Parameters['Show Command']); +Yanfly.Param.CCCShowCmd = eval(Yanfly.Param.CCCShowCmd); +Yanfly.Param.CCCEnableCmd = String(Yanfly.Parameters['Enable Command']); +Yanfly.Param.CCCEnableCmd = eval(Yanfly.Param.CCCEnableCmd); +Yanfly.Param.CCCAutoPlace = String(Yanfly.Parameters['Auto Place Command']); +Yanfly.Param.CCCAutoPlace = eval(Yanfly.Param.CCCAutoPlace); +Yanfly.Icon.DefaultClass = Number(Yanfly.Parameters['Default Icon']); +Yanfly.Param.CCCMaintainLv = String(Yanfly.Parameters['Maintain Levels']); +Yanfly.Param.CCCMaintainLv = eval(Yanfly.Param.CCCMaintainLv); +Yanfly.Param.CCCUnlock = String(Yanfly.Parameters['Unlocked Classes']); +Yanfly.Param.CCCUnlock = Yanfly.Param.CCCUnlock.split(' '); +if (Yanfly.Param.CCCUnlock === '') Yanfly.Param.CCCUnlock = []; +for (Yanfly.i = 0; Yanfly.i < Yanfly.Param.CCCUnlock.length; ++Yanfly.i) { + Yanfly.Param.CCCUnlock[Yanfly.i] = parseInt(Yanfly.Param.CCCUnlock[Yanfly.i]); +} + +Yanfly.Param.CCCClassCmd = String(Yanfly.Parameters['Class Change Command']); +Yanfly.Param.CCCShowClass = String(Yanfly.Parameters['Show Class Change']); +Yanfly.Param.CCCShowClass = eval(Yanfly.Param.CCCShowClass); +Yanfly.Param.CCCEnableClass = String(Yanfly.Parameters['Enable Class Change']); +Yanfly.Param.CCCEnableClass = eval(Yanfly.Param.CCCEnableClass); +Yanfly.Param.CCCShowLearn = String(Yanfly.Parameters['Show Skill Learn']); +Yanfly.Param.CCCShowLearn = eval(Yanfly.Param.CCCShowLearn); +Yanfly.Param.CCCFinishCmd = String(Yanfly.Parameters['Finish Command']); +Yanfly.Param.CCCTextAlign = String(Yanfly.Parameters['Text Alignment']); + +Yanfly.Param.CCCClassColor = Number(Yanfly.Parameters['Current Class Color']); +Yanfly.Param.CCCLvFmt = String(Yanfly.Parameters['Class Level Format']); +Yanfly.Param.CCCLvFontSize = Number(Yanfly.Parameters['Class Level Font Size']); + +//============================================================================= +// DataManager +//============================================================================= + +Yanfly.CCC.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded; +DataManager.isDatabaseLoaded = function() { + if (!Yanfly.CCC.DataManager_isDatabaseLoaded.call(this)) return false; + if (!Yanfly._loaded_YEP_ClassChangeCore) { + this.processCCCNotetags1($dataClasses); + this.processCCCNotetags2($dataActors); + this.processCCCNotetags3($dataClasses); + Yanfly._loaded_YEP_ClassChangeCore = true; + } + return true; +}; + +DataManager.processCCCNotetags1 = function(group) { + if (Yanfly.ClassIdRef) return; + Yanfly.ClassIdRef = {}; + for (var n = 1; n < group.length; n++) { + var obj = group[n]; + if (obj.name.length <= 0) continue; + Yanfly.ClassIdRef[obj.name.toUpperCase()] = n; + } +}; + +DataManager.processCCCNotetags2 = function(group) { + var note1a = /<(?:UNLOCK CLASS|unlock classes):[ ]*(\d+(?:\s*,\s*\d+)*)>/i; + var note1b = /<(?:UNLOCK CLASS|unlock classes):[ ](\d+)[ ](?:TO)[ ](\d+)>/i; + var note2a = /<(?:CLASS)[ ](\d+)[ ](?:CHARACTER|SPRITE):[ ](.*)[ ](\d+)>/i; + var note2b = /<(.*)[ ](?:CHARACTER|SPRITE):[ ](.*)[ ](\d+)>/i; + var note3a = /<(?:CLASS)[ ](\d+)[ ](?:FACE):[ ](.*)[ ](\d+)>/i; + var note3b = /<(.*)[ ](?:FACE):[ ](.*)[ ](\d+)>/i; + var note4a = /<(?:CLASS)[ ](\d+)[ ](?:BATTLER):[ ](.*)>/i; + var note4b = /<(.*)[ ](?:BATTLER):[ ](.*)>/i; + for (var n = 1; n < group.length; n++) { + var obj = group[n]; + var notedata = obj.note.split(/[\r\n]+/); + + obj.unlockedClasses = []; + obj.classCharacter = {}; + obj.classFace = {}; + obj.classBattler = {}; + obj.canChangeClass = true; + + for (var i = 0; i < notedata.length; i++) { + var line = notedata[i]; + if (line.match(note1a)) { + var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']'); + obj.unlockedClasses = obj.unlockedClasses.concat(array); + } else if (line.match(note1b)) { + var range = Yanfly.Util.getRange(parseInt(RegExp.$1), + parseInt(RegExp.$2)); + obj.unlockedClasses = obj.unlockedClasses.concat(range); + } else if (line.match(note2a)) { + var classId = parseInt(RegExp.$1); + var filename = String(RegExp.$2); + var index = parseInt(RegExp.$3); + obj.classCharacter[classId] = [filename, index]; + } else if (line.match(note2b)) { + var name = String(RegExp.$1).toUpperCase(); + var filename = String(RegExp.$2); + var index = parseInt(RegExp.$3); + var classId = Yanfly.ClassIdRef[name]; + if (classId) obj.classCharacter[classId] = [filename, index]; + } else if (line.match(note3a)) { + var classId = parseInt(RegExp.$1); + var filename = String(RegExp.$2); + var index = parseInt(RegExp.$3); + obj.classFace[classId] = [filename, index]; + } else if (line.match(note3b)) { + var name = String(RegExp.$1).toUpperCase(); + var filename = String(RegExp.$2); + var index = parseInt(RegExp.$3); + var classId = Yanfly.ClassIdRef[name]; + if (classId) obj.classFace[classId] = [filename, index]; + } else if (line.match(note4a)) { + var classId = parseInt(RegExp.$1); + var filename = String(RegExp.$2); + obj.classBattler[classId] = filename; + } else if (line.match(note4b)) { + var name = String(RegExp.$1).toUpperCase(); + var filename = String(RegExp.$2); + var classId = Yanfly.ClassIdRef[name]; + if (classId) obj.classBattler[classId] = filename; + } else if (line.match(/<(?:CANNOT CHANGE CLASS|CANT CHANGE CLASS)>/i)) { + obj.canChangeClass = false; + } + } + obj.unlockedClasses = obj.unlockedClasses.filter(Yanfly.Util.onlyUnique); + } +}; + +DataManager.processCCCNotetags3 = function(group) { + for (var n = 1; n < group.length; n++) { + var obj = group[n]; + var notedata = obj.note.split(/[\r\n]+/); + + obj.iconIndex = Yanfly.Icon.DefaultClass; + obj.useNickname = false; + obj.description = ''; + var descMode = false; + obj.levelUnlockRequirements = {}; + var evalMode = 'none'; + + for (var i = 0; i < notedata.length; i++) { + var line = notedata[i]; + if (line.match(/<(?:ICON):[ ](\d+)>/i)) { + obj.iconIndex = parseInt(RegExp.$1); + } else if (line.match(/<(?:HELP DESCRIPTION)>/i)) { + descMode = true; + } else if (line.match(/<\/(?:HELP DESCRIPTION)>/i)) { + descMode = false; + } else if (descMode) { + obj.description += line + '\n'; + } else if (line.match(//i)) { + obj.useNickname = true; + } else if (line.match(/<(?:LEVEL UNLOCK REQUIREMENTS)>/i)) { + evalMode = 'level unlock requirements'; + } else if (line.match(/<\/(?:LEVEL UNLOCK REQUIREMENTS)>/i)) { + evalMode = 'none'; + } else if (evalMode === 'level unlock requirements') { + if (line.match(/CLASS[ ](\d+):[ ]LEVEL[ ](\d+)/i)) { + var classId = parseInt(RegExp.$1); + var level = parseInt(RegExp.$2); + obj.levelUnlockRequirements[classId] = level; + } else if (line.match(/(.*):[ ]LEVEL[ ](\d+)/i)) { + var name = String(RegExp.$1).toUpperCase(); + var level = parseInt(RegExp.$2); + var classId = Yanfly.ClassIdRef[name]; + if (classId) obj.levelUnlockRequirements[classId] = level; + } + } + } + } +}; + +//============================================================================= +// Game_System +//============================================================================= + +Yanfly.CCC.Game_System_initialize = Game_System.prototype.initialize; +Game_System.prototype.initialize = function() { + Yanfly.CCC.Game_System_initialize.call(this); + this.initClasses(); +}; + +Game_System.prototype.initClasses = function() { + this._showClass = Yanfly.Param.CCCShowCmd; + this._enableClass = Yanfly.Param.CCCEnableCmd; + this._showClassChange = Yanfly.Param.CCCShowClass; + this._enableClassChange = Yanfly.Param.CCCEnableClass; +}; + +Game_System.prototype.isShowClass = function() { + if (this._showClass === undefined) this.initClasses(); + return this._showClass; +}; + +Game_System.prototype.isEnableClass = function() { + if (this._enableClass === undefined) this.initClasses(); + return this._enableClass; +}; + +Game_System.prototype.isShowClassEnabled = function() { + if (this._showClassChange === undefined) this.initClasses(); + return this._showClassChange; +}; + +Game_System.prototype.isEnableClassEnabled = function() { + if (this._enableClassChange === undefined) this.initClasses(); + return this._enableClassChange; +}; + +//============================================================================= +// Game_Actor +//============================================================================= + +Yanfly.CCC.Game_Actor_setup = Game_Actor.prototype.setup; +Game_Actor.prototype.setup = function(actorId) { + Yanfly.CCC.Game_Actor_setup.call(this, actorId); + this.initClasses(); +}; + +Game_Actor.prototype.initClasses = function() { + if (!this.actor().unlockedClasses) return; + this._unlockedClasses = this.actor().unlockedClasses.slice(); + this.unlockClass(this._classId); + this._unlockedClasses.sort(function(a, b) { return a - b }); +}; + +Yanfly.CCC.Game_Actor_turnEndOnMap = Game_Actor.prototype.turnEndOnMap; +Game_Actor.prototype.turnEndOnMap = function() { + $gameTemp._noUpdateUnlockedSkills = true; + Yanfly.CCC.Game_Actor_turnEndOnMap.call(this); + $gameTemp._noUpdateUnlockedSkills = undefined; +}; + +Yanfly.CCC.Game_Actor_refresh = Game_Actor.prototype.refresh; +Game_Actor.prototype.refresh = function() { + this.updateUnlockedClassSkills(); + Yanfly.CCC.Game_Actor_refresh.call(this); +}; + +Game_Actor.prototype.unlockedClasses = function() { + if (this._unlockedClasses === undefined) this.initClasses(); + this.checkLevelUnlockedClasses(); + var classes = this._unlockedClasses.sort(function(a, b) { return a - b }); + classes = classes.concat($gameParty.unlockedClasses()); + return classes.filter(Yanfly.Util.onlyUnique); +}; + +Game_Actor.prototype.unlockClass = function(classId) { + if (this._unlockedClasses === undefined) this.initClasses(); + if (this._unlockedClasses.contains(classId)) return; + this._unlockedClasses.push(classId); + this._unlockedClasses.sort(function(a, b) { return a - b }); + this.refresh(); +}; + +Game_Actor.prototype.removeClass = function(classId) { + if (this._unlockedClasses === undefined) this.initClasses(); + if (!this._unlockedClasses.contains(classId)) return; + if (classId === this._classId) return; + var index = this._unlockedClasses.indexOf(classId); + if (index >= 0) this._unlockedClasses.splice(index, 1); + this.refresh(); +}; + +Yanfly.CCC.Game_Actor_changeClass = Game_Actor.prototype.changeClass; +Game_Actor.prototype.changeClass = function(classId, keepExp) { + keepExp = Yanfly.Param.CCCMaintainLv; + if (keepExp) { + this._exp[classId] = this._exp[this._classId]; + keepExp = false; + } + Yanfly.CCC.Game_Actor_changeClass.call(this, classId, keepExp); + //this.updateLearnedSkills(classId); + if (!$gameParty.unlockedClasses().contains(classId)) { + this.unlockClass(classId); + } + $gamePlayer.refresh(); +}; + +Game_Actor.prototype.updateUnlockedClassSkills = function() { + if ($gameTemp._noUpdateUnlockedSkills) return; + if ($gameParty.inBattle()) return; + var unlocked = this.unlockedClasses(); + var length = unlocked.length; + for (var i = 0; i < length; ++i) { + var classId = unlocked[i]; + this.updateLearnedSkills(classId); + } +}; + +Game_Actor.prototype.updateLearnedSkills = function(classId) { + if (!$dataClasses[classId]) return; + $dataClasses[classId].learnings.forEach(function(learning) { + if (this.classLevel(classId) >= learning.level) { + this.learnSkill(learning.skillId); + } + }, this); +}; + +Game_Actor.prototype.classLevel = function(classId) { + if (Yanfly.Param.CCCMaintainLv) return this.level; + if (this._exp[classId] === undefined) this._exp[classId] = 0; + var level = 1; + for (;;) { + if (level >= this.maxLevel()) break; + if (this.expForLevel(level + 1) > this._exp[classId]) break; + level++; + } + return level; +}; + +Yanfly.CCC.Game_Actor_setCharacterImage = + Game_Actor.prototype.setCharacterImage; +Game_Actor.prototype.setCharacterImage = function(name, index) { + if (name !== '') { + this._priorityCharacterName = name; + this._priorityCharacterIndex = index; + } else { + this._priorityCharacterName = undefined; + this._priorityCharacterIndex = undefined; + Yanfly.CCC.Game_Actor_setCharacterImage.call(this, name, index); + } +}; + +Yanfly.CCC.Game_Actor_characterName = Game_Actor.prototype.characterName; +Game_Actor.prototype.characterName = function() { + if (this._priorityCharacterName !== undefined) { + return this._priorityCharacterName; + } + if (this.actor().classCharacter) { + if (this.actor().classCharacter[this._classId] !== undefined) { + return this.actor().classCharacter[this._classId][0]; + } + } + return Yanfly.CCC.Game_Actor_characterName.call(this); +}; + +Yanfly.CCC.Game_Actor_characterIndex = Game_Actor.prototype.characterIndex; +Game_Actor.prototype.characterIndex = function() { + if (this._priorityCharacterIndex !== undefined) { + return this._priorityCharacterIndex; + } + if (this.actor().classCharacter) { + if (this.actor().classCharacter[this._classId] !== undefined) { + return this.actor().classCharacter[this._classId][1]; + } + } + return Yanfly.CCC.Game_Actor_characterIndex.call(this); +}; + +Yanfly.CCC.Game_Actor_setFaceImage = Game_Actor.prototype.setFaceImage; +Game_Actor.prototype.setFaceImage = function(name, index) { + if (name !== '') { + this._priorityFaceName = name; + this._priorityFaceIndex = index; + } else { + this._priorityFaceName = undefined; + this._priorityFaceIndex = undefined; + Yanfly.CCC.Game_Actor_setFaceImage.call(this, name, index); + } +}; + +Yanfly.CCC.Game_Actor_faceName = Game_Actor.prototype.faceName; +Game_Actor.prototype.faceName = function() { + if (this._priorityFaceName !== undefined) { + return this._priorityFaceName; + } + if (this.actor().classFace) { + if (this.actor().classFace[this._classId] !== undefined) { + return this.actor().classFace[this._classId][0]; + } + } + return Yanfly.CCC.Game_Actor_faceName.call(this); +}; + +Yanfly.CCC.Game_Actor_faceIndex = Game_Actor.prototype.faceIndex; +Game_Actor.prototype.faceIndex = function() { + if (this._priorityFaceIndex !== undefined) { + return this._priorityFaceIndex; + } + if (this.actor().classFace) { + if (this.actor().classFace[this._classId] !== undefined) { + return this.actor().classFace[this._classId][1]; + } + } + return Yanfly.CCC.Game_Actor_faceIndex.call(this); +}; + +Yanfly.CCC.Game_Actor_setBattlerImage = Game_Actor.prototype.setBattlerImage; +Game_Actor.prototype.setBattlerImage = function(name) { + if (name !== '') { + this._priorityBattlerName = name; + } else { + this._priorityBattlerName = undefined; + Yanfly.CCC.Game_Actor_setBattlerImage.call(this, name); + } +}; + +Yanfly.CCC.Game_Actor_battlerName = Game_Actor.prototype.battlerName; +Game_Actor.prototype.battlerName = function() { + if (this._priorityBattlerName !== undefined) { + return this._priorityBattlerName; + } + if (this.actor().classBattler) { + if (this.actor().classBattler[this._classId] !== undefined) { + return this.actor().classBattler[this._classId]; + } + } + return Yanfly.CCC.Game_Actor_battlerName.call(this); +}; + +Game_Actor.prototype.checkLevelUnlockedClasses = function() { + for (var i = 0; i < $dataClasses.length; ++i) { + var item = $dataClasses[i]; + if (!item) continue; + if (this._unlockedClasses.contains(item.id)) continue; + if (Yanfly.Util.isEmptyObj(item.levelUnlockRequirements)) continue; + if (!this.classUnlockLevelRequirementsMet(item)) continue; + this.unlockClass(item.id); + } +}; + +Game_Actor.prototype.classUnlockLevelRequirementsMet = function(item) { + var classId; + for (classId in item.levelUnlockRequirements) { + var level = item.levelUnlockRequirements[classId]; + if (this.classLevel(classId) < level) return false; + } + return true; +}; + +Yanfly.CCC.Game_Actor_releaseUnequippableItems = + Game_Actor.prototype.releaseUnequippableItems; +Game_Actor.prototype.releaseUnequippableItems = function(forcing) { + if (Yanfly.CCC.PreventReleaseItem) return; + Yanfly.CCC.Game_Actor_releaseUnequippableItems.call(this, forcing); +}; + +Game_Actor.prototype.canChangeClass = function() { + if (this._canChangeClass) return this._canChangeClass; + this._canChangeClass = this.actor().canChangeClass; + return this._canChangeClass; +}; + +Game_Actor.prototype.setCanChangeClass = function(value) { + this._canChangeClass = value; +}; + +//============================================================================= +// Game_Party +//============================================================================= + +Yanfly.CCC.Game_Party_initialize = Game_Party.prototype.initialize; +Game_Party.prototype.initialize = function() { + Yanfly.CCC.Game_Party_initialize.call(this); + this.initClasses(); +}; + +Game_Party.prototype.initClasses = function() { + this._unlockedClasses = Yanfly.Param.CCCUnlock.slice(); + this._unlockedClasses.sort(function(a, b) { return a - b }); +}; + +Game_Party.prototype.unlockedClasses = function() { + if (this._unlockedClasses === undefined) this.initClasses(); + var classes = this._unlockedClasses.sort(function(a, b) { return a - b }); + return classes.filter(Yanfly.Util.onlyUnique); +}; + +Game_Party.prototype.unlockClass = function(classId) { + if (this._unlockedClasses === undefined) this.initClasses(); + if (this._unlockedClasses.contains(classId)) return; + this._unlockedClasses.push(classId); + this._unlockedClasses.sort(function(a, b) { return a - b }); +}; + +Game_Party.prototype.removeClass = function(classId) { + if (this._unlockedClasses === undefined) this.initClasses(); + if (!this._unlockedClasses.contains(classId)) return; + if (classId === this._classId) return; + var index = this._unlockedClasses.indexOf(classId); + if (index >= 0) this._unlockedClasses.splice(index, 1); +}; + +//============================================================================= +// Game_Interpreter +//============================================================================= + +Yanfly.CCC.Game_Interpreter_pluginCommand = + Game_Interpreter.prototype.pluginCommand; +Game_Interpreter.prototype.pluginCommand = function(command, args) { + Yanfly.CCC.Game_Interpreter_pluginCommand.call(this, command, args) + if (command === 'OpenClass') { + this.gotoSceneClass(); + } else if (command === 'ShowClass') { + $gameSystem._showClass = true; + } else if (command === 'HideClass') { + $gameSystem._showClass = false; + } else if (command === 'EnableClass') { + $gameSystem._enableClass = true; + } else if (command === 'DisableClass') { + $gameSystem._enableClass = false; + } else if (command === 'UnlockClass') { + this.unlockClass(args); + } else if (command === 'RemoveClass') { + this.removeClass(args); + } else if (command === 'UnlockClassAll') { + this.unlockClassAll(args); + } else if (command === 'RemoveClassAll') { + this.removeClassAll(args); + } else if (command === 'EnablePrimaryClassChange') { + this.setPrimaryClassChange(args, true); + } else if (command === 'DisablePrimaryClassChange') { + this.setPrimaryClassChange(args, false); + } +}; + +Game_Interpreter.prototype.gotoSceneClass = function() { + if (!$gameParty.inBattle()) { + SceneManager.push(Scene_Class); + } + return true; +}; + +Game_Interpreter.prototype.unlockClass = function(args) { + var actorId = parseInt(args[0]); + var actor = $gameActors.actor(actorId); + if (!actor) return; + var classId = parseInt(args[1]); + if (!$dataClasses[classId]) return; + actor.unlockClass(classId); +}; + +Game_Interpreter.prototype.removeClass = function(args) { + var actorId = parseInt(args[0]); + var actor = $gameActors.actor(actorId); + if (!actor) return; + var classId = parseInt(args[1]); + if (!$dataClasses[classId]) return; + actor.removeClass(classId); +}; + +Game_Interpreter.prototype.unlockClassAll = function(args) { + var classId = parseInt(args[0]); + if (!$dataClasses[classId]) return; + $gameParty.unlockClass(classId); +}; + +Game_Interpreter.prototype.removeClassAll = function(args) { + var classId = parseInt(args[0]); + if (!$dataClasses[classId]) return; + $gameParty.removeClass(classId); +}; + +Game_Interpreter.prototype.setPrimaryClassChange = function(args, enable) { + var actorId = parseInt(args[0]); + var actor = $gameActors.actor(actorId); + if (!actor) return; + actor.setCanChangeClass(enable); +}; + +//============================================================================= +// Window_Base +//============================================================================= + +Window_Base.prototype.drawActorClass = function(actor, x, y, width) { + width = width || 168; + this.resetTextColor(); + var text = actor.currentClass().name; + if (actor.currentClass().useNickname) { + text = actor.nickname(); + } + this.drawText(text, x, y, width); +}; + +//============================================================================= +// Window_SkillStatus +//============================================================================= + +Yanfly.CCC.Window_SkillStatus_refresh = + Window_SkillStatus.prototype.refresh; +Window_SkillStatus.prototype.refresh = function() { + if (this._actor) { + var bitmap = ImageManager.loadFace(this._actor.faceName()); + if (bitmap.width <= 0) { + return setTimeout(this.refresh.bind(this), 5); + } + } + Yanfly.CCC.Window_SkillStatus_refresh.call(this); +}; + +//============================================================================= +// Window_MenuCommand +//============================================================================= + +Yanfly.CCC.Window_MenuCommand_addOriginalCommands = + Window_MenuCommand.prototype.addOriginalCommands; +Window_MenuCommand.prototype.addOriginalCommands = function() { + Yanfly.CCC.Window_MenuCommand_addOriginalCommands.call(this); + if (Yanfly.Param.CCCAutoAdd) this.addClassCommand(); +}; + +Window_MenuCommand.prototype.addClassCommand = function() { + if (!Yanfly.Param.CCCAutoPlace) return; + if (!$gameSystem.isShowClass()) return; + if (this.findSymbol('class') > -1) return; + var text = Yanfly.Param.CCCCmdName; + var enabled = $gameSystem.isEnableClass(); + this.addCommand(text, 'class', enabled); +}; + +//============================================================================= +// Window_ClassCommand +//============================================================================= + +function Window_ClassCommand() { + this.initialize.apply(this, arguments); +} + +Window_ClassCommand.prototype = Object.create(Window_Command.prototype); +Window_ClassCommand.prototype.constructor = Window_ClassCommand; + +Window_ClassCommand.prototype.initialize = function() { + Window_Command.prototype.initialize.call(this, 0, 0); +}; + +Window_ClassCommand.prototype.windowWidth = function() { + return 240; +}; + +Window_ClassCommand.prototype.numVisibleRows = function() { + return 4; +}; + +Window_ClassCommand.prototype.itemTextAlign = function() { + return Yanfly.Param.CCCTextAlign; +}; + +Window_ClassCommand.prototype.makeCommandList = function() { + this.addClassCommand(); + this.addSkillLearnCommand(); + this.addCustomCommand(); + this.addFinishCommand(); +}; + +Window_ClassCommand.prototype.addClassCommand = function() { + if (!$gameSystem.isShowClassEnabled()) return; + var enabled = this.isClassEnabled(); + this.addCommand(Yanfly.Param.CCCClassCmd, 'class', enabled); +}; + +Window_ClassCommand.prototype.isClassEnabled = function() { + var actor = SceneManager._scene.actor(); + if (actor && !actor.canChangeClass()) return false; + return $gameSystem.isEnableClassEnabled(); +}; + +Window_ClassCommand.prototype.addSkillLearnCommand = function() { + if (!Imported.YEP_SkillLearnSystem) return; + if (!Yanfly.Param.CCCShowLearn) return; + var name = Yanfly.Param.SLSCommand; + if (Yanfly.Param.SLSIntegrate) name = TextManager.skill; + var enabled = $gameSystem.isEnableLearnSkill(); + this.addCommand(name, 'learnSkill', enabled); +}; + +Window_ClassCommand.prototype.addCustomCommand = function() { +}; + +Window_ClassCommand.prototype.addFinishCommand = function() { + this.addCommand(Yanfly.Param.CCCFinishCmd, 'cancel', true); +}; + +//============================================================================= +// Window_ClassList +//============================================================================= + +function Window_ClassList() { + this.initialize.apply(this, arguments); +} + +Window_ClassList.prototype = Object.create(Window_Selectable.prototype); +Window_ClassList.prototype.constructor = Window_ClassList; + +Window_ClassList.prototype.initialize = function(x, y, width, height) { + Window_Selectable.prototype.initialize.call(this, x, y, width, height); + this._actor = null; + this._data = []; +}; + +Window_ClassList.prototype.setActor = function(actor) { + if (this._actor === actor) return; + this._actor = actor; + this.refresh(); + this.resetScroll(); +}; + +Window_ClassList.prototype.setStatusWindow = function(statusWindow) { + this._statusWindow = statusWindow; + this.callUpdateHelp(); +}; + +Window_ClassList.prototype.maxItems = function() { + return this._data ? this._data.length : 1; +}; + +Window_ClassList.prototype.item = function() { + return this._data && this.index() >= 0 ? this._data[this.index()] : null; +}; + +Window_ClassList.prototype.makeItemList = function() { + if (this._actor) { + var data = this._actor.unlockedClasses().slice(); + } else { + var data = []; + } + this._data = []; + for (var i = 0; i < data.length; ++i) { + var classId = data[i]; + if ($dataClasses[classId] && !this._data.contains(classId)) { + this._data.push(classId); + } + } + this._data.sort(function(a, b) { return a - b }); +}; + +Window_ClassList.prototype.isCurrentItemEnabled = function() { + return this.isEnabled(this.item()); +}; + +Window_ClassList.prototype.isEnabled = function(item) { + return true; +}; + +Window_ClassList.prototype.drawItem = function(index) { + var item = $dataClasses[this._data[index]]; + if (!item) return; + var rect = this.itemRect(index); + this.changePaintOpacity(this.isEnabled(this._data[index])); + this.drawClassName(item, rect.x, rect.y, rect.width); + var rect = this.itemRectForText(index); + this.drawClassLevel(item, rect.x, rect.y, rect.width); + this.changePaintOpacity(true); +}; + +Window_ClassList.prototype.drawClassName = function(item, x, y, width) { + this.resetFontSettings(); + var iconBoxWidth = Window_Base._iconWidth + 4; + this.changeClassNameColor(item); + this.drawIcon(item.iconIndex, x + 2, y + 2); + var text = item.name; + if (this._actor && item.useNickname) { + text = this._actor.nickname(); + } + this.drawText(text, x + iconBoxWidth, y, width - iconBoxWidth); +}; + +Window_ClassList.prototype.changeClassNameColor = function(item) { + if (item === this._actor.currentClass()) { + this.changeTextColor(this.textColor(Yanfly.Param.CCCClassColor)); + } else { + this.changeTextColor(this.normalColor()); + } +}; + +Window_ClassList.prototype.drawClassLevel = function(item, x, y, width) { + var level = Yanfly.Util.toGroup(this._actor.classLevel(item.id)); + var fmt = Yanfly.Param.CCCLvFmt; + var text = fmt.format(level); + this.resetFontSettings(); + this.changeTextColor(this.normalColor()); + this.contents.fontSize = Yanfly.Param.CCCLvFontSize; + this.drawText(text, x, y, width, 'right'); +}; + +Window_ClassList.prototype.updateHelp = function() { + this.setHelpWindowItem($dataClasses[this.item()]); + this.updateCompare(); +}; + +Window_ClassList.prototype.updateCompare = function() { + if (this._actor && this.item() && this._statusWindow) { + var actor = JsonEx.makeDeepCopy(this._actor); + if (this.isEnabled(this.item())) { + Yanfly.CCC.PreventReleaseItem = true; + actor.changeClass(this.item(), false); + Yanfly.CCC.PreventReleaseItem = undefined; + } + this._statusWindow.setTempActor(actor); + } +}; + +Window_ClassList.prototype.refresh = function() { + this.makeItemList(); + this.createContents(); + this.drawAllItems(); +}; + +Window_ClassList.prototype.selectLast = function() { + this._index = this._data.indexOf(this._actor._classId); + this.select(this._index); +}; + +Window_ClassList.prototype.playOkSound = function() { + if (SceneManager._scene instanceof Scene_Class) return; + Window_Selectable.prototype.playOkSound.call(this); +}; + +//============================================================================= +// Window_StatCompare +//============================================================================= + +function Window_StatCompare() { + this.initialize.apply(this, arguments); +} + +Window_StatCompare.prototype = Object.create(Window_Base.prototype); +Window_StatCompare.prototype.constructor = Window_StatCompare; + +Window_StatCompare.prototype.initialize = function(wx, wy, ww, wh) { + Window_Base.prototype.initialize.call(this, wx, wy, ww, wh); + this._actor = null; + this._tempActor = null; + this.refresh(); +}; + +Window_StatCompare.prototype.createWidths = function() { + this._paramNameWidth = 0; + this._paramValueWidth = 0; + this._arrowWidth = this.textWidth('\u2192' + ' '); + var buffer = this.textWidth(' '); + for (var i = 0; i < 8; ++i) { + var value1 = this.textWidth(TextManager.param(i)); + var value2 = this.textWidth(Yanfly.Util.toGroup(this._actor.paramMax(i))); + this._paramNameWidth = Math.max(value1, this._paramNameWidth); + this._paramValueWidth = Math.max(value2, this._paramValueWidth); + } + this._bonusValueWidth = this._paramValueWidth; + this._bonusValueWidth += this.textWidth('(+)') + buffer; + this._paramNameWidth += buffer; + this._paramValueWidth; + if (this._paramNameWidth + this._paramValueWidth * 2 + this._arrowWidth + + this._bonusValueWidth > this.contents.width) this._bonusValueWidth = 0; +}; + +Window_StatCompare.prototype.setActor = function(actor) { + if (this._actor === actor) return; + this._actor = actor; + this.createWidths(); + this.refresh(); +}; + +Window_StatCompare.prototype.refresh = function() { + this.contents.clear(); + if (!this._actor) return; + for (var i = 0; i < 8; ++i) { + this.drawItem(0, this.lineHeight() * i, i); + } +}; + +Window_StatCompare.prototype.setTempActor = function(tempActor) { + if (this._tempActor === tempActor) return; + this._tempActor = tempActor; + this.refresh(); +}; + +Window_StatCompare.prototype.drawItem = function(x, y, paramId) { + this.drawDarkRect(x, y, this.contents.width, this.lineHeight()); + this.drawParamName(y, paramId); + this.drawCurrentParam(y, paramId); + this.drawRightArrow(y); + if (!this._tempActor) return; + this.drawNewParam(y, paramId); + this.drawParamDifference(y, paramId); +}; + +Window_StatCompare.prototype.drawDarkRect = function(dx, dy, dw, dh) { + var color = this.gaugeBackColor(); + this.changePaintOpacity(false); + this.contents.fillRect(dx + 1, dy + 1, dw - 2, dh - 2, color); + this.changePaintOpacity(true); +}; + +Window_StatCompare.prototype.drawParamName = function(y, paramId) { + var x = this.textPadding(); + this.changeTextColor(this.systemColor()); + this.drawText(TextManager.param(paramId), x, y, this._paramNameWidth); +}; + +Window_StatCompare.prototype.drawCurrentParam = function(y, paramId) { + var x = this.contents.width - this.textPadding(); + x -= this._paramValueWidth * 2 + this._arrowWidth + this._bonusValueWidth; + this.resetTextColor(); + var actorparam = Yanfly.Util.toGroup(this._actor.param(paramId)); + this.drawText(actorparam, x, y, this._paramValueWidth, 'right'); +}; + +Window_StatCompare.prototype.drawRightArrow = function(y) { + var x = this.contents.width - this.textPadding(); + x -= this._paramValueWidth + this._arrowWidth + this._bonusValueWidth; + var dw = this.textWidth('\u2192' + ' '); + this.changeTextColor(this.systemColor()); + this.drawText('\u2192', x, y, dw, 'center'); +}; + +Window_StatCompare.prototype.drawNewParam = function(y, paramId) { + var x = this.contents.width - this.textPadding(); + x -= this._paramValueWidth + this._bonusValueWidth; + var newValue = this._tempActor.param(paramId); + var diffvalue = newValue - this._actor.param(paramId); + var actorparam = Yanfly.Util.toGroup(newValue); + this.changeTextColor(this.paramchangeTextColor(diffvalue)); + this.drawText(actorparam, x, y, this._paramValueWidth, 'right'); +}; + +Window_StatCompare.prototype.drawParamDifference = function(y, paramId) { + var x = this.contents.width - this.textPadding(); + x -= this._bonusValueWidth; + var newValue = this._tempActor.param(paramId); + var diffvalue = newValue - this._actor.param(paramId); + if (diffvalue === 0) return; + var actorparam = Yanfly.Util.toGroup(newValue); + this.changeTextColor(this.paramchangeTextColor(diffvalue)); + var text = Yanfly.Util.toGroup(diffvalue); + if (diffvalue > 0) { + text = ' (+' + text + ')'; + } else { + text = ' (' + text + ')'; + } + this.drawText(text, x, y, this._bonusValueWidth, 'left'); +}; + +//============================================================================= +// Scene_Menu +//============================================================================= + +Yanfly.CCC.Scene_Menu_createCommandWindow = + Scene_Menu.prototype.createCommandWindow; +Scene_Menu.prototype.createCommandWindow = function() { + Yanfly.CCC.Scene_Menu_createCommandWindow.call(this); + this._commandWindow.setHandler('class', this.commandPersonal.bind(this)); +}; + +Yanfly.CCC.Scene_Menu_onPersonalOk = Scene_Menu.prototype.onPersonalOk; +Scene_Menu.prototype.onPersonalOk = function() { + if (this._commandWindow.currentSymbol() === 'class') { + SceneManager.push(Scene_Class); + } else { + Yanfly.CCC.Scene_Menu_onPersonalOk.call(this); + } +}; + +//============================================================================= +// Scene_Class +//============================================================================= + +function Scene_Class() { + this.initialize.apply(this, arguments); +} + +Scene_Class.prototype = Object.create(Scene_MenuBase.prototype); +Scene_Class.prototype.constructor = Scene_Class; + +Scene_Class.prototype.initialize = function() { + Scene_MenuBase.prototype.initialize.call(this); +}; + +Scene_Class.prototype.create = function() { + Scene_MenuBase.prototype.create.call(this); + this.createHelpWindow(); + this.createCommandWindow(); + this.createStatusWindow(); + this.createItemWindow(); + this.createCompareWindow(); + this.refreshActor(); +}; + +Scene_Class.prototype.createCommandWindow = function() { + this._commandWindow = new Window_ClassCommand(); + var win = this._commandWindow; + win.y = this._helpWindow.height; + win.setHandler('class', this.commandClass.bind(this)); + win.setHandler('learnSkill', this.commandLearnSkill.bind(this)); + win.setHandler('cancel', this.popScene.bind(this)); + win.setHandler('pagedown', this.nextActor.bind(this)); + win.setHandler('pageup', this.previousActor.bind(this)); + this.addWindow(win); +}; + +Scene_Class.prototype.createStatusWindow = function() { + var wx = this._commandWindow.width; + var wy = this._helpWindow.height; + var ww = Graphics.boxWidth - wx; + var wh = this._commandWindow.height; + this._statusWindow = new Window_SkillStatus(wx, wy, ww, wh); + this.addWindow(this._statusWindow); +}; + +Scene_Class.prototype.createItemWindow = function() { + var wx = 0; + var wy = this._statusWindow.y + this._statusWindow.height; + var ww = Graphics.boxWidth / 2; + var wh = Graphics.boxHeight - wy; + this._itemWindow = new Window_ClassList(wx, wy, ww, wh); + this._itemWindow.setHelpWindow(this._helpWindow); + this._itemWindow.setHandler('ok', this.onItemOk.bind(this)); + this._itemWindow.setHandler('cancel', this.onItemCancel.bind(this)); + this.addWindow(this._itemWindow); +}; + +Scene_Class.prototype.createCompareWindow = function() { + var wx = this._itemWindow.width; + var wy = this._itemWindow.y; + var ww = Graphics.boxWidth - wx; + var wh = Graphics.boxHeight - wy; + this._compareWindow = new Window_StatCompare(wx, wy, ww, wh); + this._itemWindow.setStatusWindow(this._compareWindow); + this.addWindow(this._compareWindow); +}; + +Scene_Class.prototype.refreshActor = function() { + var actor = this.actor(); + this._commandWindow.refresh(); + this._statusWindow.setActor(actor); + this._itemWindow.setActor(actor); + this._compareWindow.setActor(actor); +}; + +Scene_Class.prototype.refreshWindows = function() { + this._commandWindow.refresh(); + this._itemWindow.refresh(); + this._statusWindow.refresh(); + this._compareWindow.refresh(); +}; + +Scene_Class.prototype.commandClass = function() { + this._itemWindow.activate(); + this._itemWindow.refresh(); + this._itemWindow.selectLast(); +}; + +Scene_Class.prototype.commandLearnSkill = function() { + if (Yanfly.Param.SLSIntegrate) { + SceneManager.push(Scene_Skill); + } else { + SceneManager.push(Scene_LearnSkill); + } +}; + +Scene_Class.prototype.onItemOk = function() { + SoundManager.playEquip(); + var classId = this._itemWindow.item(); + var hpRate = this.actor().hp / this.actor().mhp; + var mpRate = this.actor().mp / Math.max(1, this.actor().mmp); + this.actor().changeClass(classId, Yanfly.Param.CCCMaintainLv); + var max = this.actor().isDead() ? 0 : 1; + var hpAmount = Math.max(max, parseInt(this.actor().mhp * hpRate)); + this.actor().setHp(hpAmount); + this.actor().setMp(parseInt(this.actor().mmp * mpRate)); + this._itemWindow.activate(); + this.refreshWindows(); +}; + +Scene_Class.prototype.onItemCancel = function() { + this._itemWindow.deselect(); + this._commandWindow.activate(); + this._helpWindow.setItem(null); + this._itemWindow.refresh(); + this._compareWindow.setTempActor(null); +}; + +Scene_Class.prototype.onActorChange = function() { + this.refreshActor(); + this._commandWindow.activate(); +}; + +//============================================================================= +// Utilities +//============================================================================= + +Yanfly.Util = Yanfly.Util || {}; + +if (!Yanfly.Util.toGroup) { + Yanfly.Util.toGroup = function(inVal) { + return inVal; + } +}; + +Yanfly.Util.getRange = function(n, m) { + var result = []; + for (var i = n; i <= m; ++i) result.push(i); + return result; +}; + +Yanfly.Util.onlyUnique = function(value, index, self) { + return self.indexOf(value) === index; +}; + +Yanfly.Util.isEmptyObj = function(obj) { + var key; + for (key in obj) { + return false; + } + return true; +}; + +//============================================================================= +// End of File +//============================================================================= diff --git a/js/plugins/YEP_CoreEngine.js b/js/plugins/YEP_CoreEngine.js index 56c32da..c8fbb64 100644 --- a/js/plugins/YEP_CoreEngine.js +++ b/js/plugins/YEP_CoreEngine.js @@ -8,11 +8,11 @@ Imported.YEP_CoreEngine = true; var Yanfly = Yanfly || {}; Yanfly.Core = Yanfly.Core || {}; -Yanfly.Core.version = 1.32; +Yanfly.Core.version = 1.25; //============================================================================= /*: - * @plugindesc v1.32 Needed for the majority of Yanfly Engine Scripts. Also + * @plugindesc v1.25 Needed for the majority of Yanfly Engine Scripts. Also * contains bug fixes found inherently in RPG Maker. * @author Yanfly Engine Plugins * @@ -255,36 +255,6 @@ Yanfly.Core.version = 1.32; * SHOW - true HIDE - false Default: false * @default true * - * @param ---Map Optimization--- - * @desc - * - * @param Refresh Update HP - * @parent ---Map Optimization--- - * @type boolean - * @on Show - * @off Hide - * @desc Do a full actor refresh when updating HP on map? - * YES - true NO - false Default: true - * @default true - * - * @param Refresh Update MP - * @parent ---Map Optimization--- - * @type boolean - * @on Show - * @off Hide - * @desc Do a full actor refresh when updating MP on map? - * YES - true NO - false Default: true - * @default true - * - * @param Refresh Update TP - * @parent ---Map Optimization--- - * @type boolean - * @on Show - * @off Hide - * @desc Do a full actor refresh when updating TP on map? - * YES - true NO - false Default: true - * @default false - * * @param ---Font--- * @desc * @@ -590,14 +560,6 @@ Yanfly.Core.version = 1.32; * distorted by a series of overlayed effects. The plugin fixes this issue by * having only one animation played over the group instead of every one. * - * Audio Volume Stacking - * Sometimes when multiple sound effects are played in the same frame with - * the exact settings (usually due to animaitons), the volume stacks upon - * each other, causing them to not play the intended volume for the effect. - * This plugin fixes this issue by preventing sound effects of the same exact - * settings from playing during the same frame, allowing only the first to - * go through without stacking the volume higher. - * * Event Movement Speed * The movement speed of events are slightly slower than what they should be * due a small error in the source code. The plugin fixes this issue and they @@ -720,47 +682,6 @@ Yanfly.Core.version = 1.32; * Changelog * ============================================================================ * - * Version 1.32: - * - Reversed the disable for the screen jitter fix from version 1.24. Somehow - * it came back and I don't know when, but now it needs to go. - * - * Version 1.31: - * - Added Fallen Angel Olivia's full error message display to the Core Engine - * (with her permission of course). - * - Bug fixed regarding blend modes and bush depth making sprites not blend - * properly in-game. - * - Tab key no longer requires you to press it twice before triggering Tab-key - * related inputs. - * - * Version 1.30: - * - Bug fixed for audio Sound Effect stacking. - * - Optimization update. - * - * Version 1.29: - * - Bypass the isDevToolsOpen() error when bad code is inserted into a script - * call or custom Lunatic Mode code segment due to updating to MV 1.6.1. - * - * Version 1.28: - * - Upon pressing F5 to reload your game, this will close the DevTools Debug - * Console if it is opened before reloading. This is because reloading with it - * closed ends up reloading the game faster. - * - New plugin parameters added: Refresh Update HP, MP, and TP - * - Option to choose to do a full actor refresh upon changing HP, MP, or TP - * - This is to reduce overall map lagging. - * - * Version 1.27: - * - Updated for RPG Maker MV version 1.6.0: - * - Fixing script call checks made with switches and self switches under - * conditional branches due to how ES6 handles === differently. - * - * Version 1.26: - * - Updated for RPG Maker MV version 1.6.0: - * - Removal of the destructive code in Scene_Item.update function. - * - Open Console parameter now occurs after the map's been loaded or after - * the battle has started. This is because after the 1.6.0 changes, loading - * the console before anything else will lock up other aspects of RPG Maker - * from loading properly. - * * Version 1.25: * - Updated for RPG Maker MV version 1.5.0. * - Updated Scale Title and Scale GameOver to work with 1.5.0. @@ -900,8 +821,8 @@ Yanfly.Param.ScreenWidth = Number(Yanfly.Parameters['Screen Width'] || 816); Yanfly.Param.ScreenHeight = Number(Yanfly.Parameters['Screen Height'] || 624); Yanfly.Param.ScaleBattleback = String(Yanfly.Parameters['Scale Battlebacks']); Yanfly.Param.ScaleBattleback = eval(Yanfly.Param.ScaleBattleback); -Yanfly.Param.ScaleTitle = eval(String(Yanfly.Parameters['Scale Title'])); -Yanfly.Param.ScaleGameOver = eval(String(Yanfly.Parameters['Scale Game Over'])); +Yanfly.Param.ScaleTitle = String(Yanfly.Parameters['Scale Title']); +Yanfly.Param.ScaleGameOver = String(Yanfly.Parameters['Scale Game Over']); Yanfly.Param.OpenConsole = String(Yanfly.Parameters['Open Console']); Yanfly.Param.OpenConsole = eval(Yanfly.Param.OpenConsole); Yanfly.Param.ReposBattlers = String(Yanfly.Parameters['Reposition Battlers']); @@ -935,20 +856,13 @@ Yanfly.Param.ShowEvTrans = eval(Yanfly.Param.ShowEvTrans); Yanfly.Param.ShowEvSnap = String(Yanfly.Parameters['Show Events Snapshot']); Yanfly.Param.ShowEvSnap = eval(Yanfly.Param.ShowEvSnap); -Yanfly.Param.RefreshUpdateHp = String(Yanfly.Parameters['Refresh Update HP']); -Yanfly.Param.RefreshUpdateHp = eval(Yanfly.Param.RefreshUpdateHp); -Yanfly.Param.RefreshUpdateMp = String(Yanfly.Parameters['Refresh Update MP']); -Yanfly.Param.RefreshUpdateMp = eval(Yanfly.Param.RefreshUpdateMp); -Yanfly.Param.RefreshUpdateTp = String(Yanfly.Parameters['Refresh Update TP']); -Yanfly.Param.RefreshUpdateTp = eval(Yanfly.Param.RefreshUpdateTp); - Yanfly.Param.ChineseFont = String(Yanfly.Parameters['Chinese Font']); Yanfly.Param.KoreanFont = String(Yanfly.Parameters['Korean Font']); Yanfly.Param.DefaultFont = String(Yanfly.Parameters['Default Font']); Yanfly.Param.FontSize = Number(Yanfly.Parameters['Font Size']); Yanfly.Param.TextAlign = String(Yanfly.Parameters['Text Align']); -Yanfly.Param.DigitGroup = eval(String(Yanfly.Parameters['Digit Grouping'])); +Yanfly.Param.DigitGroup = String(Yanfly.Parameters['Digit Grouping']); Yanfly.Param.LineHeight = Number(Yanfly.Parameters['Line Height']); Yanfly.Param.IconWidth = Number(Yanfly.Parameters['Icon Width'] || 32);; Yanfly.Param.IconHeight = Number(Yanfly.Parameters['Icon Height'] || 32);; @@ -957,9 +871,9 @@ Yanfly.Param.FaceHeight = Number(Yanfly.Parameters['Face Height'] || 144); Yanfly.Param.WindowPadding = Number(Yanfly.Parameters['Window Padding']); Yanfly.Param.TextPadding = Number(Yanfly.Parameters['Text Padding']); Yanfly.Param.WindowOpacity = Number(Yanfly.Parameters['Window Opacity']); -Yanfly.Param.GaugeOutline = eval(String(Yanfly.Parameters['Gauge Outline'])); +Yanfly.Param.GaugeOutline = String(Yanfly.Parameters['Gauge Outline']); Yanfly.Param.GaugeHeight = Number(Yanfly.Parameters['Gauge Height']); -Yanfly.Param.MenuTpGauge = eval(String(Yanfly.Parameters['Menu TP Bar'])); +Yanfly.Param.MenuTpGauge = String(Yanfly.Parameters['Menu TP Bar']); Yanfly.Param.ColorNormal = Number(Yanfly.Parameters['Color: Normal']); Yanfly.Param.ColorSystem = Number(Yanfly.Parameters['Color: System']); @@ -1025,7 +939,6 @@ Yanfly.Core.Bitmap_drawText = Bitmap.prototype.drawText; Bitmap.prototype.drawText = function(text, x, y, mW, l, align) { x = Math.floor(x); y = Math.floor(y); - if (mW < 0) mW = 0; mW = Math.floor(mW); l = Math.floor(l); Yanfly.Core.Bitmap_drawText.call(this, text, x, y, mW, l, align); @@ -1054,65 +967,6 @@ Graphics._updateRealScale = function() { }; // Yanfly.Param.UpdateRealScale -Graphics.printFullError = function(name, message, stack) { - stack = this.processErrorStackMessage(stack); - if (this._errorPrinter) { - this._errorPrinter.innerHTML = - this._makeFullErrorHtml(name, message, stack); - } - this._applyCanvasFilter(); - this._clearUpperCanvas(); -}; - -Graphics._makeFullErrorHtml = function(name, message, stack) { - var text = ''; - for (var i = 2; i < stack.length; ++i) { - text += '' + stack[i] + '
'; - } - return ('' + stack[0] + '
' + - '' + stack[1] + '
' + text); -}; - -Graphics.processErrorStackMessage = function(stack) { - var data = stack.split(/(?:\r\n|\r|\n)/); - data.unshift('Game has encountered a bug. Please report it.
'); - for (var i = 1; i < data.length; ++i) { - data[i] = data[i].replace(/[\(](.*[\/])/, '('); - } - data.push('
Press F5 to restart the game.' + - '
'); - return data; -}; - -Yanfly.Core.Graphics_updateErrorPrinter = Graphics._updateErrorPrinter; -Graphics._updateErrorPrinter = function() { - Yanfly.Core.Graphics_updateErrorPrinter.call(this); - this._errorPrinter.height = this._height * 0.5; - this._errorPrinter.style.textAlign = 'left'; - this._centerElement(this._errorPrinter); -}; - -SceneManager.catchException = function(e) { - if (e instanceof Error) { - Graphics.printFullError(e.name, e.message, e.stack); - console.error(e.stack); - } else { - Graphics.printError('UnknownError', e); - } - AudioManager.stopAll(); - this.stop(); -}; - -//============================================================================= -// Input -//============================================================================= - -Yanfly.Core.Input_shouldPreventDefault = Input._shouldPreventDefault; -Input._shouldPreventDefault = function(keyCode) { - if (keyCode === 9) return true; - return Yanfly.Core.Input_shouldPreventDefault.call(this, keyCode); -}; - //============================================================================= // Sprite //============================================================================= @@ -1329,34 +1183,6 @@ DataManager.processCORENotetags4 = function(group) { } }; -//============================================================================= -// AudioManager Stacking Volume Bug Fix -//============================================================================= - -Yanfly.Core.AudioManager_playSe = AudioManager.playSe; -AudioManager.playSe = function(se) { - this._frameSe = this._frameSe || []; - if (this.uniqueCheckSe(se)) { - Yanfly.Core.AudioManager_playSe.call(this, se); - this._frameSe.push(se); - } -}; - -AudioManager.uniqueCheckSe = function(se1) { - if (this._frameSe.contains(se1)) return false; - return true; -}; - -AudioManager.clearUniqueCheckSe = function() { - this._frameSe = []; -}; - -Yanfly.Core.SceneManager_updateInputData = SceneManager.updateInputData; -SceneManager.updateInputData = function() { - Yanfly.Core.SceneManager_updateInputData.call(this); - AudioManager.clearUniqueCheckSe(); -}; - //============================================================================= // SceneManager //============================================================================= @@ -1369,9 +1195,8 @@ SceneManager._boxHeight = Yanfly.Param.ScreenHeight Yanfly.Core.SceneManager_run = SceneManager.run; SceneManager.run = function(sceneClass) { Yanfly.Core.SceneManager_run.call(this, sceneClass); - Yanfly.updateResolution(); if (!Utils.isNwjs()) return; - if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") return; + Yanfly.updateResolution(); if (Yanfly.Param.OpenConsole) Yanfly.openConsole(); }; @@ -1385,55 +1210,15 @@ Yanfly.updateResolution = function() { }; Yanfly.openConsole = function() { - Yanfly._openedConsole = true; if (Utils.isNwjs() && Utils.isOptionValid('test')) { var _debugWindow = require('nw.gui').Window.get().showDevTools(); - if (_debugWindow) _debugWindow.moveTo(0, 0); - window.focus(); - } -}; - -Yanfly.Core.SceneManager_onKeyDown = SceneManager.onKeyDown; -SceneManager.onKeyDown = function(event) { - if (!event.ctrlKey && !event.altKey && event.keyCode === 116) { - if (Utils.isNwjs() && Utils.isOptionValid('test')) { - var win = require('nw.gui').Window.get(); - win.closeDevTools(); + if (_debugWindow) { + _debugWindow.moveTo(0, 0); + window.focus(); } } - Yanfly.Core.SceneManager_onKeyDown.call(this, event); }; -if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") { - -Yanfly.openConsole = function() { - Yanfly._openedConsole = true; - if (!Yanfly.Param.OpenConsole) return; - if (Utils.isNwjs() && Utils.isOptionValid('test')) { - var win = require('nw.gui').Window.get(); - win.showDevTools(); - setTimeout(this.focusWindow.bind(this, win), 500); - } -}; - -Yanfly.focusWindow = function(win) { - win.focus(); -}; - -Yanfly.Core.Scene_Map_update = Scene_Map.prototype.update; -Scene_Map.prototype.update = function() { - Yanfly.Core.Scene_Map_update.call(this); - if (!Yanfly._openedConsole) Yanfly.openConsole(); -}; - -Yanfly.Core.Scene_Battle_update = Scene_Battle.prototype.update; -Scene_Battle.prototype.update = function() { - Yanfly.Core.Scene_Battle_update.call(this); - if (!Yanfly._openedConsole) Yanfly.openConsole(); -}; - -}; // 1.6.0 - //============================================================================= // BattleManager //============================================================================= @@ -1479,61 +1264,6 @@ Game_BattlerBase.prototype.paramMax = function(paramId) { } }; -Yanfly.Core.Game_BattlerBase_refresh = Game_BattlerBase.prototype.refresh; - -Game_BattlerBase.prototype.mapRegenUpdateCheck = function(type) { - if ($gameParty.inBattle()) return true; - if (type === 'hp') { - return Yanfly.Param.RefreshUpdateHp; - } else if (type === 'mp') { - return Yanfly.Param.RefreshUpdateMp; - } else if (type === 'tp') { - return Yanfly.Param.RefreshUpdateTp; - } -}; - -Game_BattlerBase.prototype.setHp = function(hp) { - if (this._hp === hp) return; - this._hp = hp; - if (this.mapRegenUpdateCheck('hp')) { - this.refresh(); - } else { - Yanfly.Core.Game_BattlerBase_refresh.call(this); - } -}; - -Game_BattlerBase.prototype.setMp = function(mp) { - if (this._mp === mp) return; - this._mp = mp; - if (this.mapRegenUpdateCheck('mp')) { - this.refresh(); - } else { - Yanfly.Core.Game_BattlerBase_refresh.call(this); - } -}; - -Game_BattlerBase.prototype.setTp = function(tp) { - if (this._tp === tp) return; - this._tp = tp; - if (this.mapRegenUpdateCheck('tp')) { - this.refresh(); - } else { - Yanfly.Core.Game_BattlerBase_refresh.call(this); - } -}; - -//============================================================================= -// Game_Battler -//============================================================================= - -Game_Battler.prototype.onTurnEnd = function() { - this.clearResult(); - this.regenerateAll(); - this.updateStateTurns(); - this.updateBuffTurns(); - this.removeStatesAuto(2); -}; - //============================================================================= // Game_Actor //============================================================================= @@ -1622,7 +1352,6 @@ Game_Party.prototype.onPlayerWalk = function() { //============================================================================= Yanfly.isPreventScreenJittering = function() { - if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= '1.5.0') return true; if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= '1.3.4') return false; return true; }; @@ -1785,29 +1514,6 @@ Yanfly.Core.Game_Interpreter_command111 = Game_Interpreter.prototype.command111 = function() { var result = false; switch (this._params[0]) { - case 0: // Switch - if (this._params[2] === 0) { - result = $gameSwitches.value(this._params[1]); - } else { - result = !$gameSwitches.value(this._params[1]); - } - this._branch[this._indent] = result; - if (this._branch[this._indent] === false) this.skipBranch(); - return true - break; - case 2: // Self Switch - if (this._eventId > 0) { - var key = [this._mapId, this._eventId, this._params[1]]; - if (this._params[2] === 0) { - result = $gameSelfSwitches.value(key); - } else { - result = !$gameSelfSwitches.value(key); - } - } - this._branch[this._indent] = result; - if (this._branch[this._indent] === false) this.skipBranch(); - return true - break; case 12: // Script var code = this._params[1]; try { @@ -1955,18 +1661,6 @@ Scene_Boot.prototype.isGameFontLoaded = function() { } }; -//============================================================================= -// Scene_Item -//============================================================================= - -if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") { - -Scene_Item.prototype.update = function() { - Scene_ItemBase.prototype.update.call(this); -}; - -}; // Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0" - //============================================================================= // Scene_Title //============================================================================= @@ -1974,7 +1668,7 @@ Scene_Item.prototype.update = function() { Yanfly.Core.Scene_Title_start = Scene_Title.prototype.start; Scene_Title.prototype.start = function() { Yanfly.Core.Scene_Title_start.call(this); - if (Yanfly.Param.ScaleTitle) this.rescaleTitle(); + if (eval(Yanfly.Param.ScaleTitle)) this.rescaleTitle(); }; Scene_Title.prototype.rescaleTitle = function() { @@ -2022,7 +1716,7 @@ Scene_Map.prototype.snapForBattleBackground = function() { Yanfly.Core.Scene_Gameover_start = Scene_Gameover.prototype.start; Scene_Gameover.prototype.start = function() { Yanfly.Core.Scene_Gameover_start.call(this); - if (Yanfly.Param.ScaleGameOver) this.rescaleBackground(); + if (eval(Yanfly.Param.ScaleGameOver)) this.rescaleBackground(); }; Scene_Gameover.prototype.rescaleBackground = function() { @@ -2102,7 +1796,7 @@ Yanfly.Core.Sprite_Enemy_setBattler = Sprite_Enemy.prototype.setBattler; Sprite_Enemy.prototype.setBattler = function(battler) { Yanfly.Core.Sprite_Enemy_setBattler.call(this, battler); if (!this._enemy._alteredScreenY) { - this._homeY += Math.floor((Graphics.boxHeight - 624) / 2); + this._homeY += Graphics.boxHeight - 624; this._enemy._screenY = this._homeY; this._enemy._alteredScreenY = true; } @@ -2185,20 +1879,6 @@ Sprite_Battleback.prototype.scaleSprite = function() { } }; -//============================================================================= -// Sprite_Character -//============================================================================= - -Yanfly.Core.Sprite_Character_updateHalfBodySprites = - Sprite_Character.prototype.updateHalfBodySprites; -Sprite_Character.prototype.updateHalfBodySprites = function() { - Yanfly.Core.Sprite_Character_updateHalfBodySprites.call(this); - if (this._bushDepth > 0) { - this._upperBody.blendMode = this.blendMode; - this._lowerBody.blendMode = this.blendMode; - } -}; - //============================================================================= // Spriteset_Map //============================================================================= @@ -2256,8 +1936,8 @@ Spriteset_Battle.prototype.locateBattleback = function() { }; Spriteset_Battle.prototype.rescaleBattlebacks = function() { - this.rescaleBattlebackSprite(this._back1Sprite); - this.rescaleBattlebackSprite(this._back2Sprite); + this.rescaleBattlebackSprite(this._back1Sprite, 'fnord'); + this.rescaleBattlebackSprite(this._back2Sprite, 'blah'); }; Spriteset_Battle.prototype.rescaleBattlebackSprite = function(sprite) { @@ -2404,7 +2084,7 @@ Window_Base.prototype.drawGauge = function(dx, dy, dw, rate, color1, color2) { var fillW = Math.floor(dw * rate).clamp(0, dw); var gaugeH = this.gaugeHeight(); var gaugeY = dy + this.lineHeight() - gaugeH - 2; - if (Yanfly.Param.GaugeOutline) { + if (eval(Yanfly.Param.GaugeOutline)) { color3.paintOpacity = this.translucentOpacity(); this.contents.fillRect(dx, gaugeY - 1, dw, gaugeH, color3); fillW = Math.max(fillW - 2, 0); @@ -2477,7 +2157,7 @@ Window_Base.prototype.drawActorSimpleStatus = function(actor, x, y, width) { this.drawActorClass(actor, x2, y, width2); this.drawActorHp(actor, x2, y + lineHeight * 1, width2); this.drawActorMp(actor, x2, y + lineHeight * 2, width2); - if (Yanfly.Param.MenuTpGauge) { + if (eval(Yanfly.Param.MenuTpGauge)) { this.drawActorTp(actor, x2, y + lineHeight * 3, width2); } }; @@ -2509,6 +2189,17 @@ Window_Base.prototype.usingGoldIcon = function(unit) { return Yanfly.Icon.Gold > 0; }; +Window_Base.prototype.drawItemName = function(item, x, y, width) { + width = width || 312; + if (item) { + var iconBoxWidth = this.lineHeight(); + var padding = (iconBoxWidth - Window_Base._iconWidth) / 2; + this.resetTextColor(); + this.drawIcon(item.iconIndex, x + padding, y + padding); + this.drawText(item.name, x + iconBoxWidth, y, width - iconBoxWidth); + } +}; + //============================================================================= // Window_Command //============================================================================= @@ -2535,10 +2226,10 @@ Window_MenuStatus.prototype.drawItemStatus = function(index) { var rect = this.itemRect(index); var xpad = Yanfly.Param.WindowPadding + Window_Base._faceWidth; var x = rect.x + xpad; - if (!Yanfly.Param.MenuTpGauge) { - var y = Math.floor(rect.y + rect.height / 2 - this.lineHeight() * 1.5); + if (!eval(Yanfly.Param.MenuTpGauge)) { + var y = rect.y + rect.height / 2 - this.lineHeight() * 1.5; } else { - var y = Math.floor(rect.y); + var y = rect.y; } var width = rect.width - x - this.textPadding(); this.drawActorSimpleStatus(actor, x, y, width); @@ -2569,7 +2260,7 @@ Window_SkillStatus.prototype.refresh = function() { if (this._actor) { var w = this.width - this.padding * 2; var h = this.height - this.padding * 2; - if (!Yanfly.Param.MenuTpGauge) { + if (!eval(Yanfly.Param.MenuTpGauge)) { var y = h / 2 - this.lineHeight() * 1.5; } else { var y = 0; @@ -2735,8 +2426,8 @@ Window_BattleStatus.prototype.drawBasicArea = function(rect, actor) { Window_BattleStatus.prototype.drawGaugeAreaWithTp = function(rect, actor) { var totalArea = this.gaugeAreaWidth() - 30; - var hpW = Math.floor(parseInt(totalArea * 108 / 300)); - var otW = Math.floor(parseInt(totalArea * 96 / 300)); + var hpW = parseInt(totalArea * 108 / 300); + var otW = parseInt(totalArea * 96 / 300); this.drawActorHp(actor, rect.x + 0, rect.y, hpW); this.drawActorMp(actor, rect.x + hpW + 15, rect.y, otW); this.drawActorTp(actor, rect.x + hpW + otW + 30, rect.y, otW); @@ -2744,8 +2435,8 @@ Window_BattleStatus.prototype.drawGaugeAreaWithTp = function(rect, actor) { Window_BattleStatus.prototype.drawGaugeAreaWithoutTp = function(rect, actor) { var totalArea = this.gaugeAreaWidth() - 15; - var hpW = Math.floor(parseInt(totalArea * 201 / 315)); - var otW = Math.floor(parseInt(totalArea * 114 / 315)); + var hpW = parseInt(totalArea * 201 / 315); + var otW = parseInt(totalArea * 114 / 315); this.drawActorHp(actor, rect.x + 0, rect.y, hpW); this.drawActorMp(actor, rect.x + hpW + 15, rect.y, otW); }; @@ -2779,37 +2470,18 @@ animationId, mirror) { Yanfly.Util = Yanfly.Util || {}; -if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= '1.5.0') { - -Yanfly.Util.toGroup = function(inVal) { - if (typeof inVal === 'string') return inVal; - if (!Yanfly.Param.DigitGroup) return inVal; - return inVal.toLocaleString('en'); - return inVal.replace(/(^|[^\w.])(\d{4,})/g, function($0, $1, $2) { - return $1 + $2.replace(/\d(?=(?:\d\d\d)+(?!\d))/g, "$&,"); - }); -}; - -} else { - Yanfly.Util.toGroup = function(inVal) { if (typeof inVal !== 'string') { inVal = String(inVal); } - if (!Yanfly.Param.DigitGroup) return inVal; - return inVal.toLocaleString('en'); + if (!eval(Yanfly.Param.DigitGroup)) return inVal; return inVal.replace(/(^|[^\w.])(\d{4,})/g, function($0, $1, $2) { return $1 + $2.replace(/\d(?=(?:\d\d\d)+(?!\d))/g, "$&,"); }); }; -} // Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= '1.5.0' - - - Yanfly.Util.displayError = function(e, code, message) { console.log(message); console.log(code || 'NON-EXISTENT'); console.error(e); - if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") return; if (Utils.isNwjs() && Utils.isOptionValid('test')) { if (!require('nw.gui').Window.get().isDevToolsOpen()) { require('nw.gui').Window.get().showDevTools(); diff --git a/js/plugins/YEP_Extra_Enemy_Drops.js b/js/plugins/YEP_Extra_Enemy_Drops.js deleted file mode 100644 index b2aaef7..0000000 --- a/js/plugins/YEP_Extra_Enemy_Drops.js +++ /dev/null @@ -1,77 +0,0 @@ -#Extra Enemy Drops v1.0 -#----------# -#Features: Let's you set, via notes, more than just three item drops -# from an enemy. Yay! -# -#Usage: Plug and play, customize as needed -# -# Enemy Notetags: -# -# type is 1 for item, 2 for weapon, 3 for armor -# id is the id of the item -# rate is the 1/rate of the item, 20 would be 1/20 chance -# -# A weapon of id 3 that drops 1 out of 5 times would be: -# -# -#----------# -#-- Script by: V.M of D.T -# -#- Questions or comments can be: -# given by email: sumptuaryspade@live.ca -# provided on facebook: http://www.facebook.com/DaimoniousTailsGames -# All my other scripts and projects can be found here: http://daimonioustails.weebly.com/ -# -#- Free to use in any project with credit given, donations always welcome! - -#Maximum number of items that can drop from one enemy in a battle -MAX_ENEMY_DROPS = 3 - -class RPG::Enemy - def add_drop(type,id,rate) - @drop_items.push(RPG::Enemy::DropItem.new) - @drop_items[-1].kind = type - @drop_items[-1].data_id = id - @drop_items[-1].denominator = rate - end - def add_drops - snote = self.note.clone - while snote.include?("/ - add_drop($1.to_i,$2.to_i,$3.to_i) - snote[snote.index(" 0 && rand * di.denominator < drop_item_rate && iter < MAX_ENEMY_DROPS - iter += 1 - r.push(item_object(di.kind, di.data_id)) - else - r - end - end - end -end \ No newline at end of file diff --git a/js/plugins/YEP_JobPoints.js b/js/plugins/YEP_JobPoints.js index 53e7f5b..973acb2 100644 --- a/js/plugins/YEP_JobPoints.js +++ b/js/plugins/YEP_JobPoints.js @@ -8,11 +8,11 @@ Imported.YEP_JobPoints = true; var Yanfly = Yanfly || {}; Yanfly.JP = Yanfly.JP || {}; -Yanfly.JP.version = 1.09; +Yanfly.JP.version = 1.10; //============================================================================= /*: - * @plugindesc v1.09 This plugin by itself doesn't do much, but it enables + * @plugindesc v1.10 This plugin by itself doesn't do much, but it enables * actors to acquire JP (job points) used for other plugins. * @author Yanfly Engine Plugins * @@ -223,6 +223,10 @@ Yanfly.JP.version = 1.09; * Changelog * ============================================================================ * + * Version 1.10: + * - Bypass the isDevToolsOpen() error when bad code is inserted into a script + * call or custom Lunatic Mode code segment due to updating to MV 1.6.1. + * * Version 1.09: * - Updated for RPG Maker MV version 1.5.0. * @@ -792,6 +796,7 @@ Yanfly.Util.displayError = function(e, code, message) { console.log(message); console.log(code || 'NON-EXISTENT'); console.error(e); + if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") return; if (Utils.isNwjs() && Utils.isOptionValid('test')) { if (!require('nw.gui').Window.get().isDevToolsOpen()) { require('nw.gui').Window.get().showDevTools(); diff --git a/js/plugins/YEP_LoadCustomFonts.js b/js/plugins/YEP_LoadCustomFonts.js new file mode 100644 index 0000000..cc094d7 --- /dev/null +++ b/js/plugins/YEP_LoadCustomFonts.js @@ -0,0 +1,109 @@ +//============================================================================= +// Yanfly Engine Plugins - Load Custom Fonts +// YEP_LoadCustomFonts.js +//============================================================================= + +var Imported = Imported || {}; +Imported.YEP_LoadCustomFonts = true; + +var Yanfly = Yanfly || {}; +Yanfly.LCF = Yanfly.LCF || {}; +Yanfly.LCF.version = 1.01; + +//============================================================================= + /*: + * @plugindesc v1.01 Load custom fonts from the /fonts/ folder. This will + * allow you to use custom fonts without installing them. + * @author Yanfly Engine Plugins + * + * @param Font Filenames + * @desc These are full filenames of the fonts to be loaded from the + * /fonts/ folder of your project. Separate each with , + * @default cc-wild-words.ttf, ds-pixel-cyr.ttf + * + * @param Font Families + * @desc The font family names of the fonts. Keep them in the same + * order as the parameter above. Separate each with , + * @default CC Wild Words, DS Pixel Cyr + * + * @help + * ============================================================================ + * Introduction & Instructions + * ============================================================================ + * + * For those using custom fonts, you may have noticed that not all fonts from + * the /fonts/ directory are loaded at the time the game is loaded. This plugin + * let's you place the fonts into the /fonts/ directory and then load them as + * the game starts. + * + * To use this plugin, follow these instructions: + * + * The plugin parameters 'Font Filenames' and 'Font Families' have to be filled + * out in correspondence to each other. The order of each font entry must match + * each other's. For example: + * + * Font Filenames: cc-wild-words.ttf, ds-pixel-cyr.ttf + * + * Font Families: CC Wild Words, DS Pixel Cyr + * + * In the above example, 'cc-wild-words.ttf' will use 'CC Wild Words' as its + * font family and 'ds-pixel-cyr.ttf' will use 'DS Pixel Cyr'. For the plugins + * that use font names such as YEP's Message Core, you will be using the Font + * Family name instead of the filename. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version 1.01: + * - Updated for RPG Maker MV version 1.5.0. + * + * Version 1.00: + * - Finished Plugin! + */ +//============================================================================= + +//============================================================================= +// Parameter Variables +//============================================================================= + +Yanfly.Parameters = PluginManager.parameters('YEP_LoadCustomFonts'); +Yanfly.Param = Yanfly.Param || {}; + +Yanfly.Param.LCFFontFilenames = String(Yanfly.Parameters['Font Filenames']); +Yanfly.Param.LCFFontFamilies = String(Yanfly.Parameters['Font Families']); + +//============================================================================= +// Utilities +//============================================================================= + +Yanfly.Util = Yanfly.Util || {}; + +Yanfly.Util.loadCustomFonts = function() { + var filenames = Yanfly.Param.LCFFontFilenames.split(','); + var fontfamilies = Yanfly.Param.LCFFontFamilies.split(','); + if (filenames.length !== fontfamilies.length) { + if (filenames.length > fontfamilies.length) { + console.log('You are missing fonts in the Font Families parameter.'); + } + if (filenames.length < fontfamilies.length) { + console.log('You are missing fonts in the Font Filenames parameter.'); + } + console.log('Loading custom fonts aborted.'); + return; + } + var projectDirectory = window.location.pathname.substring(0, + window.location.pathname.lastIndexOf('/')); + var length = filenames.length; + for (var i = 0; i < length; ++i) { + var filename = filenames[i].trim(); + var fontfamily = fontfamilies[i].trim(); + Graphics.loadFont(fontfamily, projectDirectory + '/fonts/' + filename); + } +}; +Yanfly.Util.loadCustomFonts(); + +//============================================================================= +// End of File +//============================================================================= + diff --git a/js/plugins/YEP_X_Subclass.js b/js/plugins/YEP_X_Subclass.js new file mode 100644 index 0000000..f26a34d --- /dev/null +++ b/js/plugins/YEP_X_Subclass.js @@ -0,0 +1,1133 @@ +//============================================================================= +// Yanfly Engine Plugins - Class Change Core Extension - Subclass +// YEP_X_Subclass.js +//============================================================================= + +var Imported = Imported || {}; +Imported.YEP_X_Subclass = true; + +var Yanfly = Yanfly || {}; +Yanfly.Subclass = Yanfly.Subclass || {}; +Yanfly.Subclass.version = 1.11 + +//============================================================================= + /*: + * @plugindesc v1.11 (Requires YEP_ClassChangeCore.js) Allow your actors + * to subclass into a secondary class! + * @author Yanfly Engine Plugins + * + * @param ---Class Menu--- + * @default + * + * @param Subclass Command + * @parent ---Class Menu--- + * @desc The text used for 'Subclass' command. + * @default Subclass + * + * @param Show Command + * @parent ---Class Menu--- + * @type boolean + * @on Show + * @off Hide + * @desc Show the Subclass command by default? + * NO - false YES - true + * @default true + * + * @param Enable Command + * @parent ---Class Menu--- + * @type boolean + * @on Enable + * @off Disable + * @desc Enable the Subclass command by default? + * NO - false YES - true + * @default true + * + * @param Name Format + * @parent ---Class Menu--- + * @desc How do you wish to display the class/subclass text? + * %1 - Current Class %2 - Subclass + * @default %1/%2 + * + * @param Subclass Color + * @parent ---Class Menu--- + * @type number + * @min 0 + * @max 31 + * @desc This is the text color used for the actor's subclass. + * @default 5 + * + * @param ---Parameters--- + * @default + * + * @param MaxHP + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass MaxHP should be added? + * @default 0.10 + * + * @param MaxMP + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass MaxMP should be added? + * @default 0.10 + * + * @param ATK + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass ATK should be added? + * @default 0.20 + * + * @param DEF + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass DEF should be added? + * @default 0.20 + * + * @param MAT + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass MAT should be added? + * @default 0.20 + * + * @param MDF + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass MDF should be added? + * @default 0.20 + * + * @param AGI + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass AGI should be added? + * @default 0.20 + * + * @param LUK + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc What rate of the Subclass LUK should be added? + * @default 0.20 + * + * @param EXP + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc When gaining EXP, how much should subclasses earn? + * @default 0.25 + * + * @param JP + * @parent ---Parameters--- + * @type number + * @decimals 2 + * @min 0 + * @desc When gaining JP, how much should subclasses earn? + * @default 0.25 + * + * @param ---Traits--- + * @default + * + * @param Skill Types + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc User can use skill types owned by the subclass? + * NO - false YES - true + * @default true + * + * @param Added Skills + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over added skills from subclass? + * NO - false YES - true + * @default true + * + * @param Param Rates + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over parameter rates from subclass? + * NO - false YES - true + * @default false + * + * @param X-Param Values + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over x-parameter values from subclass? + * NO - false YES - true + * @default false + * + * @param S-Param Rates + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over s-parameter rates from subclass? + * NO - false YES - true + * @default false + * + * @param Element Rates + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over element rates from subclass? + * NO - false YES - true + * @default false + * + * @param Debuff Rates + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over debuff rates from subclass? + * NO - false YES - true + * @default false + * + * @param State Rates + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over parameter rates from subclass? + * NO - false YES - true + * @default false + * + * @param State Resist + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over state resistances from subclass? + * NO - false YES - true + * @default false + * + * @param Attack Element + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over attack elements from subclass? + * NO - false YES - true + * @default false + * + * @param Attack State + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over attack states from subclass? + * NO - false YES - true + * @default false + * + * @param Weapons + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over equippable weapons from subclass? + * NO - false YES - true + * @default false + * + * @param Armors + * @parent ---Traits--- + * @type boolean + * @on YES + * @off NO + * @desc Carry over equippable armors from subclass? + * NO - false YES - true + * @default false + * + * @help + * ============================================================================ + * Introduction + * ============================================================================ + * + * This plugin requires YEP_ClassChangeCore. Make sure this plugin is located + * under YEP_ClassChangeCore in the plugin list. + * + * This class enables subclassing for your actors. Actors, when subclassing, + * can gain the benefits of the subclass, usually either by having access to + * the subclass skill set, weapons, and armor options. Also with this plugin, + * you can enable what kind of stat bonuses you can get by having a particular + * subclass enabled for the actor. + * + * ============================================================================ + * Notetags + * ============================================================================ + * + * You can use the following notetags to modify subclassing aspects. + * + * Actor Notetag: + * + * Sets the actor's default subclass to x. + * + * + * This prevents this actor from being able to change subclasses. This could + * be reversed from plugin commands, however. + * + * + * + * + * This particular actor cannot switch his or her primary class to class(es) + * x (to y). This does not apply to the subclass. The actor can still change + * to this class via event. + * + * + * + * + * This particular actor cannot switch his or her subclass to class(es) + * x (to y). This does not apply to the primary class. The actor can still + * change to this subclass via event. + * + * Class Notetags: + * + * This class can only be class changed to a primary class and nothing more. + * Actors can still change to this class via event. + * + * + * This class can only be class changed to a subclass and nothing more. + * Actors can still change to this subclass via event. + * + * + * If this class is the primary and the subclass is class ID x, then the + * class name displayed will be 'text'. For example, if the class combination + * is Warrior/Wizard, the name can appear as Spellblade. + * + * + * + * If you choose to use the class's name instead, you can write out the name + * of the class in place of Subclass x. If you have multiple classes with the + * same name, priority will be given to the class with the highest ID. + * + * Skill and Item Notetags: + * + * + * + * Replace x with the class's ID. This skill/item can only be used by the + * listed class(es) x. This does not apply to enemies. + * + * + * + * + * Replace x with the class's ID. This skill/item can only be used by the + * listed subclass(es) x. This does not apply to enemies. + * + * ============================================================================ + * Plugin Commands + * ============================================================================ + * + * You can use these following plugin commands to change subclassing throughout + * the game! + * + * Plugin Command: + * + * ShowSubclass + * HideSubclass + * - Shows/Hides the Subclass command in the Class Change Menu. + * + * EnableSubclass + * DisableSubclass + * - Enables/Disables the Subclass command in the Class Change Menu. + * + * ChangeSubclass x y + * - Changes actor x's subclass to y. Replace y with 0 to remove a subclass. + * + * EnableSubclassChange 5 + * DisableSubclassChange 5 + * - This enables/disables subclass changing for actor 5. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version 1.11: + * - Updated for RPG Maker MV version 1.5.0. + * + * Version 1.10: + * - Compatibility update with Class Change Core's notetag. + * + * Version 1.09: + * - Added notetag for actors. Added plugin commands: + * EnableSubclassChange and DisableSubclassChange for actors. + * + * Version 1.08: + * - Compatibility update with other plugins. + * + * Version 1.07: + * - Updated for RPG Maker MV version 1.1.0. + * + * Version 1.06: + * - Added 'EXP' plugin parameter. This determines the rate the equipped + * subclass will earn EXP. + * - Added 'JP' plugin parameter. This determines the rate the equipped + * subclass will earn JP. + * + * Version 1.05: + * - Fixed a bug where changing a dead actor's subclass would revive them. + * + * Version 1.04: + * - Fixed an issue that would turn the ATB gauge in battle a different color. + * + * Version 1.03: + * - Fixed a bug that would duplicate non-independent items. + * + * Version 1.02: + * - Fixed a bug that would heal an actor's HP to full by switching subclasses. + * + * Version 1.01: + * - Fixed a bug that added maximum rate for certain subclass inheritances. + * - Added a failsafe for undefined subclasses due to MV's database not + * updating the Classes.JSON file properly. + * + * Version 1.00: + * - Finished Plugin! + */ +//============================================================================= + +if (Imported.YEP_ClassChangeCore) { + +//============================================================================= +// Parameter Variables +//============================================================================= + +Yanfly.Parameters = PluginManager.parameters('YEP_X_Subclass'); +Yanfly.Param = Yanfly.Param || {}; + +Yanfly.Param.SubclassCmd = String(Yanfly.Parameters['Subclass Command']); +Yanfly.Param.SubclassShowCmd = String(Yanfly.Parameters['Show Command']); +Yanfly.Param.SubclassEnableCmd = String(Yanfly.Parameters['Enable Command']); +Yanfly.Param.SubclassFmt = String(Yanfly.Parameters['Name Format']); +Yanfly.Param.SubclassColor = Number(Yanfly.Parameters['Subclass Color']); + +Yanfly.Subclass.Param = {}; +Yanfly.Subclass.Param[0] = Number(Yanfly.Parameters['MaxHP']); +Yanfly.Subclass.Param[1] = Number(Yanfly.Parameters['MaxMP']); +Yanfly.Subclass.Param[2] = Number(Yanfly.Parameters['ATK']); +Yanfly.Subclass.Param[3] = Number(Yanfly.Parameters['DEF']); +Yanfly.Subclass.Param[4] = Number(Yanfly.Parameters['MAT']); +Yanfly.Subclass.Param[5] = Number(Yanfly.Parameters['MDF']); +Yanfly.Subclass.Param[6] = Number(Yanfly.Parameters['AGI']); +Yanfly.Subclass.Param[7] = Number(Yanfly.Parameters['LUK']); +Yanfly.Param.SubclassExp = Number(Yanfly.Parameters['EXP']); +Yanfly.Param.SubclassJp = Number(Yanfly.Parameters['JP']); + +Yanfly.Param.SubclassSType = eval(String(Yanfly.Parameters['Skill Types'])); +Yanfly.Param.SubParamRates = eval(String(Yanfly.Parameters['Param Rates'])); +Yanfly.Param.SubXParamVal = eval(String(Yanfly.Parameters['X-Param Values'])); +Yanfly.Param.SubSParamRates = eval(String(Yanfly.Parameters['S-Param Rates'])); +Yanfly.Param.SubSEleRates = eval(String(Yanfly.Parameters['Element Rates'])); +Yanfly.Param.SubDebuffRates = eval(String(Yanfly.Parameters['Debuff Rates'])); +Yanfly.Param.SubStateRates = eval(String(Yanfly.Parameters['Debuff Rates'])); +Yanfly.Param.SubStateRes = eval(String(Yanfly.Parameters['State Resist'])); +Yanfly.Param.SubAttackEle = eval(String(Yanfly.Parameters['Attack Element'])); +Yanfly.Param.SubAttackState = eval(String(Yanfly.Parameters['Attack State'])); +Yanfly.Param.SubAddedSkills = eval(String(Yanfly.Parameters['Added Skills'])); +Yanfly.Param.SubclassWeapons = eval(String(Yanfly.Parameters['Weapons'])); +Yanfly.Param.SubclassArmors = eval(String(Yanfly.Parameters['Armors'])); + +//============================================================================= +// DataManager +//============================================================================= + +Yanfly.Subclass.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded; +DataManager.isDatabaseLoaded = function() { + if (!Yanfly.Subclass.DataManager_isDatabaseLoaded.call(this)) return false; + if (!Yanfly._loaded_YEP_X_Subclass) { + DataManager.processSubclassNotetags1($dataActors); + DataManager.processSubclassNotetags2($dataClasses); + DataManager.processSubclassNotetags3($dataSkills); + DataManager.processSubclassNotetags3($dataItems); + Yanfly._loaded_YEP_X_Subclass = true; + } + return true; +}; + +DataManager.processSubclassNotetags1 = function(group) { + var note1a = /<(?:RESTRICT CLASS):[ ]*(\d+(?:\s*,\s*\d+)*)>/i; + var note1b = /<(?:RESTRICT CLASS):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i; + var note2a = /<(?:RESTRICT SUBCLASS):[ ]*(\d+(?:\s*,\s*\d+)*)>/i; + var note2b = /<(?:RESTRICT SUBCLASS):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i; + var note3 = /<(?:CANNOT CHANGE SUBCLASS|CANT CHANGE SUBCLASS)>/i; + for (var n = 1; n < group.length; n++) { + var obj = group[n]; + var notedata = obj.note.split(/[\r\n]+/); + + obj.subclassId = 0; + obj.restrictClassChange = []; + obj.restrictSubclassChange = []; + obj.canChangeSubclass = true; + + for (var i = 0; i < notedata.length; i++) { + var line = notedata[i]; + if (line.match(/<(?:SUBCLASS):[ ](\d+)>/i)) { + obj.subclassId = parseInt(RegExp.$1); + } else if (line.match(note1a)) { + var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']'); + obj.restrictClassChange = obj.restrictClassChange.concat(array); + } else if (line.match(note1b)) { + var range = Yanfly.Util.getRange(parseInt(RegExp.$1), + parseInt(RegExp.$2)); + obj.restrictClassChange = obj.restrictClassChange.concat(range); + } else if (line.match(note2a)) { + var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']'); + obj.restrictSubclassChange = obj.restrictSubclassChange.concat(array); + } else if (line.match(note2b)) { + var range = Yanfly.Util.getRange(parseInt(RegExp.$1), + parseInt(RegExp.$2)); + obj.restrictSubclassChange = obj.restrictSubclassChange.concat(range); + } else if (line.match(note3)) { + obj.canChangeSubclass = false; + } + } + } +}; + +DataManager.processSubclassNotetags2 = function(group) { + var note1a = /<(?:SUBCLASS)[ ](\d+)[ ](?:COMBO NAME):[ ](.*)>/i; + var note1b = /<(.*)[ ](?:COMBO NAME):[ ](.*)>/i; + for (var n = 1; n < group.length; n++) { + var obj = group[n]; + var notedata = obj.note.split(/[\r\n]+/); + + obj.primaryAllowed = true; + obj.subclassAllowed = true; + obj.subclassComboName = {}; + + for (var i = 0; i < notedata.length; i++) { + var line = notedata[i]; + if (line.match(/<(?:PRIMARY ONLY)>/i)) { + obj.primaryAllowed = true; + obj.subclassAllowed = false; + } else if (line.match(/<(?:SUBCLASS ONLY)>/i)) { + obj.primaryAllowed = false; + obj.subclassAllowed = true; + } else if (line.match(note1a)) { + var classId = parseInt(RegExp.$1); + var className = String(RegExp.$2); + obj.subclassComboName[classId] = className; + } else if (line.match(note1b)) { + var name = String(RegExp.$1).toUpperCase(); + var className = String(RegExp.$2); + var classId = Yanfly.ClassIdRef[name]; + if (classId) obj.subclassComboName[classId] = className; + } + } + } +}; + +DataManager.processSubclassNotetags3 = function(group) { + var note1a = /<(?:REQUIRE CLASS):[ ]*(\d+(?:\s*,\s*\d+)*)>/i; + var note1b = /<(?:REQUIRE CLASS):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i; + var note2a = /<(?:REQUIRE SUBCLASS):[ ]*(\d+(?:\s*,\s*\d+)*)>/i; + var note2b = /<(?:REQUIRE SUBCLASS):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i; + for (var n = 1; n < group.length; n++) { + var obj = group[n]; + var notedata = obj.note.split(/[\r\n]+/); + + obj.requiredClasses = []; + obj.requiredSubclasses = []; + + for (var i = 0; i < notedata.length; i++) { + var line = notedata[i]; + if (line.match(note1a)) { + var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']'); + obj.requiredClasses = obj.requiredClasses.concat(array); + } else if (line.match(note1b)) { + var range = Yanfly.Util.getRange(parseInt(RegExp.$1), + parseInt(RegExp.$2)); + obj.requiredClasses = obj.requiredClasses.concat(range); + } else if (line.match(note2a)) { + var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']'); + obj.requiredSubclasses = obj.requiredSubclasses.concat(array); + } else if (line.match(note2b)) { + var range = Yanfly.Util.getRange(parseInt(RegExp.$1), + parseInt(RegExp.$2)); + obj.requiredSubclasses = obj.requiredSubclasses.concat(range); + } + } + } +}; + +//============================================================================= +// Game_System +//============================================================================= + +Yanfly.Subclass.Game_System_initialize = Game_System.prototype.initialize; +Game_System.prototype.initialize = function() { + Yanfly.Subclass.Game_System_initialize.call(this); + this.initSubclasses(); +}; + +Game_System.prototype.initSubclasses = function() { + this._showSubclass = eval(Yanfly.Param.SubclassShowCmd); + this._enableSubclass = eval(Yanfly.Param.SubclassEnableCmd); +}; + +Game_System.prototype.isShowSubclass = function() { + if (this._showSubclass === undefined) this.initSubClasses(); + return this._showSubclass; +}; + +Game_System.prototype.isEnableSubclass = function() { + if (this._enableSubclass === undefined) this.initSubClasses(); + return this._enableSubclass; +}; + +//============================================================================= +// Game_BattlerBase +//============================================================================= + +Game_BattlerBase.prototype.piSubclassTraits = function(code, id) { + if (!this.subclass()) return 1; + var r = 1; + for (var i = 0; i < this.subclass().traits.length; ++i) { + var trait = this.subclass().traits[i]; + if (trait.code !== code) continue; + if (trait.dataId !== id) continue; + r *= trait.value; + } + return r; +}; + +Game_BattlerBase.prototype.sumSubclassTraits = function(code, id) { + if (!this.subclass()) return 0; + var r = 0; + for (var i = 0; i < this.subclass().traits.length; ++i) { + var trait = this.subclass().traits[i]; + if (trait.code !== code) continue; + if (trait.dataId !== id) continue; + r += trait.value; + } + return r; +}; + +Game_BattlerBase.prototype.addSubclassTraitSet = function(array, code) { + if (!this.subclass()) return array; + for (var i = 0; i < this.subclass().traits.length; ++i) { + var trait = this.subclass().traits[i]; + if (trait.code === code) array.push(trait.dataId); + } + return array; +}; + +Yanfly.Subclass.Game_BattlerBase_addedSkillTypes = + Game_BattlerBase.prototype.addedSkillTypes; +Game_BattlerBase.prototype.addedSkillTypes = function() { + var array = Yanfly.Subclass.Game_BattlerBase_addedSkillTypes.call(this); + if (this.isActor() && Yanfly.Param.SubclassSType) { + this.addSubclassTraitSet(array, Game_BattlerBase.TRAIT_STYPE_ADD); + } + return array.filter(Yanfly.Util.onlyUnique); +}; + +Yanfly.Subclass.Game_BattlerBase_paramRate = + Game_BattlerBase.prototype.paramRate; +Game_BattlerBase.prototype.paramRate = function(paramId) { + var rate = Yanfly.Subclass.Game_BattlerBase_paramRate.call(this, paramId); + if (this.isActor() && Yanfly.Param.SubParamRates) { + rate *= this.piSubclassTraits(Game_BattlerBase.TRAIT_PARAM, paramId); + } + return rate; +}; + +Yanfly.Subclass.Game_BattlerBase_xparam = Game_BattlerBase.prototype.xparam; +Game_BattlerBase.prototype.xparam = function(xparamId) { + var value = Yanfly.Subclass.Game_BattlerBase_xparam.call(this, xparamId); + if (this.isActor() && Yanfly.Param.SubXParamVal) { + value += this.sumSubclassTraits(Game_BattlerBase.TRAIT_XPARAM, xparamId); + } + return value; +}; + +Yanfly.Subclass.Game_BattlerBase_sparam = Game_BattlerBase.prototype.sparam; +Game_BattlerBase.prototype.sparam = function(sparamId) { + var rate = Yanfly.Subclass.Game_BattlerBase_sparam.call(this, sparamId); + if (this.isActor() && Yanfly.Param.SubSParamRates) { + rate *= this.piSubclassTraits(Game_BattlerBase.TRAIT_SPARAM, sparamId); + } + return rate; +}; + +Yanfly.Subclass.Game_BattlerBase_elementRate = + Game_BattlerBase.prototype.elementRate; +Game_BattlerBase.prototype.elementRate = function(eleId) { + var rate = Yanfly.Subclass.Game_BattlerBase_elementRate.call(this, eleId); + if (this.isActor() && Yanfly.Param.SubSEleRates) { + rate *= this.piSubclassTraits(Game_BattlerBase.TRAIT_ELEMENT_RATE, eleId); + } + return rate; +}; + +Yanfly.Subclass.Game_BattlerBase_debuffRate = + Game_BattlerBase.prototype.debuffRate; +Game_BattlerBase.prototype.debuffRate = function(paramId) { + var rate = Yanfly.Subclass.Game_BattlerBase_debuffRate.call(this, paramId); + if (this.isActor() && Yanfly.Param.SubDebuffRates) { + rate *= this.piSubclassTraits(Game_BattlerBase.TRAIT_DEBUFF_RATE, paramId); + } + return rate; +}; + +Yanfly.Subclass.Game_BattlerBase_stateRate = + Game_BattlerBase.prototype.stateRate; +Game_BattlerBase.prototype.stateRate = function(stateId) { + var rate = Yanfly.Subclass.Game_BattlerBase_stateRate.call(this, stateId); + if (this.isActor() && Yanfly.Param.SubStateRates) { + rate *= this.piSubclassTraits(Game_BattlerBase.TRAIT_STATE_RATE, stateId); + } + return rate; +}; + +Yanfly.Subclass.Game_BattlerBase_stateResistSet = + Game_BattlerBase.prototype.stateResistSet; +Game_BattlerBase.prototype.stateResistSet = function() { + var array = Yanfly.Subclass.Game_BattlerBase_stateResistSet.call(this); + if (this.isActor() && Yanfly.Param.SubStateRes) { + this.addSubclassTraitSet(array, Game_BattlerBase.TRAIT_STATE_RESIST); + } + return array; +}; + +Yanfly.Subclass.Game_BattlerBase_attackElements = + Game_BattlerBase.prototype.attackElements; +Game_BattlerBase.prototype.attackElements = function() { + var array = Yanfly.Subclass.Game_BattlerBase_attackElements.call(this); + if (this.isActor() && Yanfly.Param.SubAttackEle) { + this.addSubclassTraitSet(array, Game_BattlerBase.TRAIT_ATTACK_ELEMENT); + } + return array; +}; + +Yanfly.Subclass.Game_BattlerBase_attackStates = + Game_BattlerBase.prototype.attackStates; +Game_BattlerBase.prototype.attackStates = function() { + var array = Yanfly.Subclass.Game_BattlerBase_attackStates.call(this); + if (this.isActor() && Yanfly.Param.SubAttackState) { + this.addSubclassTraitSet(array, Game_BattlerBase.TRAIT_ATTACK_STATE); + } + return array; +}; + +Yanfly.Subclass.Game_BattlerBase_addedSkills = + Game_BattlerBase.prototype.addedSkills; +Game_BattlerBase.prototype.addedSkills = function() { + var array = Yanfly.Subclass.Game_BattlerBase_addedSkills.call(this); + if (this.isActor() && Yanfly.Param.SubAddedSkills) { + this.addSubclassTraitSet(array, Game_BattlerBase.TRAIT_SKILL_ADD); + } + return array; +}; + +Yanfly.Subclass.Game_BattlerBase_Wtype = + Game_BattlerBase.prototype.isEquipWtypeOk; +Game_BattlerBase.prototype.isEquipWtypeOk = function(wtypeId) { + var value = Yanfly.Subclass.Game_BattlerBase_Wtype.call(this, wtypeId); + if (value) return true; + var array = []; + if (this.isActor() && Yanfly.Param.SubclassWeapons) { + this.addSubclassTraitSet(array, Game_BattlerBase.TRAIT_EQUIP_WTYPE); + } + return array.contains(wtypeId); +}; + +Yanfly.Subclass.Game_BattlerBase_Atype = + Game_BattlerBase.prototype.isEquipAtypeOk; +Game_BattlerBase.prototype.isEquipAtypeOk = function(atypeId) { + var value = Yanfly.Subclass.Game_BattlerBase_Atype.call(this, atypeId); + if (value) return true; + var array = []; + if (this.isActor() && Yanfly.Param.SubclassArmors) { + this.addSubclassTraitSet(array, Game_BattlerBase.TRAIT_EQUIP_ATYPE); + } + return array.contains(atypeId); +}; + +Yanfly.Game_BattlerBase_canUse = Game_BattlerBase.prototype.canUse; +Game_BattlerBase.prototype.canUse = function(item) { + if (!item) return false; + if (this.isActor()) { + if (!this.meetsClassCanUseRequirements(item)) return false; + } + return Yanfly.Game_BattlerBase_canUse.call(this, item); +}; + +Game_BattlerBase.prototype.meetsClassCanUseRequirements = function(item) { + if (item.requiredClasses && item.requiredClasses.length > 0) { + if (!item.requiredClasses.contains(this._classId)) return false; + } + if (item.requiredSubclasses && item.requiredSubclasses.length > 0) { + if (!this.subclass()) return false; + if (!item.requiredSubclasses.contains(this._subclassId)) return false; + }; + return true; +}; + +//============================================================================= +// Game_Actor +//============================================================================= + +Yanfly.Subclass.Game_Actor_setup = Game_Actor.prototype.setup; +Game_Actor.prototype.setup = function(actorId) { + Yanfly.Subclass.Game_Actor_setup.call(this, actorId); + this.initSubclasses(); +}; + +Game_Actor.prototype.initSubclasses = function() { + if (this.actor().subclassId === this._classId) return; + this.setSubclass(this.actor().subclassId); + if (this._subclassId > 0) this.unlockClass(this._subclassId); +}; + +Game_Actor.prototype.subclass = function() { + if (this._subclassId === undefined) this.initSubclasses(); + return $dataClasses[this._subclassId]; +}; + +Game_Actor.prototype.className = function() { + if (!this.subclass()) { + if (this.currentClass().useNickname) { + return this.nickname(); + } else { + return this.currentClass().name; + } + } + if (this.currentClass().subclassComboName[this._subclassId]) { + var text = this.currentClass().subclassComboName[this._subclassId]; + } else { + var name1 = this.currentClass().name; + if (this.currentClass().useNickname) { + name1 = this.nickname(); + } + var name2 = this.subclass().name; + if (this.subclass().useNickname) { + name2 = this.nickname(); + } + var fmt = Yanfly.Param.SubclassFmt; + var text = fmt.format(name1, name2); + } + return text; +}; + +Yanfly.Subclass.Game_Actor_changeClass = Game_Actor.prototype.changeClass; +Game_Actor.prototype.changeClass = function(classId, keepExp) { + if (this._subclassId === classId) this._subclassId = 0; + Yanfly.Subclass.Game_Actor_changeClass.call(this, classId, keepExp); +}; + +Game_Actor.prototype.setSubclass = function(classId) { + if (this._classId === classId) return; + this.unlockClass(classId); + this._subclassId = classId; + this.refresh(); +}; + +Game_Actor.prototype.changeSubclass = function(classId) { + if (this._classId === classId) return; + this.unlockClass(classId); + if (this._subclassId === classId) classId = 0; + this.setSubclass(classId); +}; + +Yanfly.Subclass.Game_Actor_paramBase = Game_Actor.prototype.paramBase; +Game_Actor.prototype.paramBase = function(paramId) { + var value = Yanfly.Subclass.Game_Actor_paramBase.call(this, paramId); + value += Math.floor(this.subclassParamBase(paramId)); + return value; +}; + +Game_Actor.prototype.subclassParamBase = function(paramId) { + if (!this.subclass()) return 0; + var rate = Yanfly.Subclass.Param[paramId]; + if (!rate) return 0; + if (this.subclass().baseParamFormula) { + var formula = this.subclass().baseParamFormula[paramId]; + if (formula !== '') { + return this.classBaseParamFormula(formula, paramId) * rate; + } + } + var level = this.classLevel(this._subclassId); + if (level > 99) { + var i = this.subclass().params[paramId][99]; + var j = this.subclass().params[paramId][98]; + i += (i - j) * (level - 99); + var value = i; + } else { + var value = this.subclass().params[paramId][level]; + } + return value * rate; +}; + +Game_Actor.prototype.restrictClassChange = function(classId) { + return this.actor().restrictClassChange.contains(classId); +}; + +Game_Actor.prototype.restrictSubclassChange = function(classId) { + return this.actor().restrictSubclassChange.contains(classId); +}; + +Yanfly.Subclass.Game_Actor_gainExp = Game_Actor.prototype.gainExp; +Game_Actor.prototype.gainExp = function(exp) { + this.gainExpSubclass(exp); + Yanfly.Subclass.Game_Actor_gainExp.call(this, exp); +}; + +Game_Actor.prototype.gainExpSubclass = function(exp) { + if (!this.subclass()) return; + exp *= Yanfly.Param.SubclassExp; + var curExp = this._exp[this._subclassId] || 0; + var newExp = curExp + Math.round(exp * this.finalExpRate()); + this._exp[this._subclassId] = Math.max(newExp, 0); +}; + +Game_Actor.prototype.canChangeSubclass = function() { + if (this._canChangeSubclass) return this._canChangeSubclass; + this._canChangeSubclass = this.actor().canChangeSubclass; + return this._canChangeSubclass; +}; + +Game_Actor.prototype.setCanChangeSubclass = function(value) { + this._canChangeSubclass = value; +}; + +//============================================================================= +// Game_Interpreter +//============================================================================= + +Yanfly.Subclass.Game_Interpreter_pluginCommand = + Game_Interpreter.prototype.pluginCommand; +Game_Interpreter.prototype.pluginCommand = function(command, args) { + Yanfly.Subclass.Game_Interpreter_pluginCommand.call(this, command, args); + if (command === 'ShowSubclass') { + $gameSystem._showSubclass = true; + } else if (command === 'HideSubclass') { + $gameSystem._showSubclass = false; + } else if (command === 'EnableSubclass') { + $gameSystem._enableSubclass = true; + } else if (command === 'DisableSubclass') { + $gameSystem._enableSubclass = false; + } else if (command === 'ChangeSubclass') { + this.changeSubclass(args); + } else if (command === 'EnableSubclassChange') { + this.setSubclassChange(args, true); + } else if (command === 'DisableSubclassChange') { + this.setSubclassChange(args, false); + } +}; + +Game_Interpreter.prototype.changeSubclass = function(args) { + if (!args) return; + var actorId = parseInt(args[0]); + var subclassId = parseInt(args[1]); + var actor = $gameActors.actor(actorId); + if (actor) actor.setSubclass(subclassId); +}; + +Yanfly.Subclass.Game_Interpreter_command315 = + Game_Interpreter.prototype.command315; +Game_Interpreter.prototype.command315 = function() { + var value = this.operateValue(this._params[2], this._params[3], + this._params[4]); + this.iterateActorEx(this._params[0], this._params[1], function(actor) { + actor.gainExpSubclass(value); + }.bind(this)); + return Yanfly.Subclass.Game_Interpreter_command315.call(this); +}; + +Game_Interpreter.prototype.setSubclassChange = function(args, enable) { + var actorId = parseInt(args[0]); + var actor = $gameActors.actor(actorId); + if (!actor) return; + actor.setCanChangeSubclass(enable); +}; + +//============================================================================= +// Window_Base +//============================================================================= + +Window_Base.prototype.drawActorClass = function(actor, x, y, width) { + width = width || 168; + this.resetTextColor(); + this.drawText(actor.className(), x, y, width); +}; + +//============================================================================= +// Window_ClassCommand +//============================================================================= + +Yanfly.Subclass.Window_ClassCommand_addClassCommand = + Window_ClassCommand.prototype.addClassCommand; +Window_ClassCommand.prototype.addClassCommand = function() { + Yanfly.Subclass.Window_ClassCommand_addClassCommand.call(this); + this.addSubclassCommand(); +}; + +Window_ClassCommand.prototype.addSubclassCommand = function() { + if (!$gameSystem.isShowSubclass()) return; + var enabled = this.isSubclassEnabled(); + this.addCommand(Yanfly.Param.SubclassCmd, 'subclass', enabled); +}; + +Window_ClassCommand.prototype.isSubclassEnabled = function() { + var actor = SceneManager._scene.actor(); + if (actor && !actor.canChangeSubclass()) return false; + return $gameSystem.isEnableSubclass(); +}; + +//============================================================================= +// Window_ClassList +//============================================================================= + +Yanfly.Subclass.Window_ClassList_isEnabled = + Window_ClassList.prototype.isEnabled; +Window_ClassList.prototype.isEnabled = function(item) { + if (!this.checkSubclassEnabled(item)) return false; + return Yanfly.Subclass.Window_ClassList_isEnabled.call(this, item); +}; + +Window_ClassList.prototype.checkSubclassEnabled = function(item) { + if (SceneManager._scene instanceof Scene_Class) { + var win = SceneManager._scene._commandWindow; + if (!win) return true; + if (!this.active) return true; + if (win.currentSymbol() === 'class') { + if ($dataClasses[item]) { + if (!$dataClasses[item].primaryAllowed) return false; + } + if (this._actor.restrictClassChange(item)) return false; + } else if (win.currentSymbol() === 'subclass') { + if (item === this._actor.currentClass().id) return false; + if ($dataClasses[item]) { + if (!$dataClasses[item].subclassAllowed) return false; + } + if (this._actor.restrictSubclassChange(item)) return false; + } + } + return true; +}; + +Yanfly.Subclass.Window_ClassList_changeClassNameColor = + Window_ClassList.prototype.changeClassNameColor; +Window_ClassList.prototype.changeClassNameColor = function(item) { + if (item === this._actor.subclass()) { + this.changeTextColor(this.textColor(Yanfly.Param.SubclassColor)); + } else { + Yanfly.Subclass.Window_ClassList_changeClassNameColor.call(this, item); + } +}; + +Yanfly.Subclass.Window_ClassList_selectLast = + Window_ClassList.prototype.selectLast; +Window_ClassList.prototype.selectLast = function() { + var win = SceneManager._scene._commandWindow; + if (win && win.currentSymbol() === 'subclass' && this._actor.subclass()) { + this.selectLastSubclass(); + } else { + Yanfly.Subclass.Window_ClassList_selectLast.call(this); + } +}; + +Window_ClassList.prototype.selectLastSubclass = function() { + this._index = this._data.indexOf(this._actor._subclassId); + this.select(this._index); +}; + +Yanfly.Subclass.Window_ClassList_updateCompare = + Window_ClassList.prototype.updateCompare; +Window_ClassList.prototype.updateCompare = function() { + var win = SceneManager._scene._commandWindow; + if (win && win.currentSymbol() === 'subclass') { + this.updateSubclassCompare(); + } else { + Yanfly.Subclass.Window_ClassList_updateCompare.call(this); + } +}; + +Window_ClassList.prototype.updateSubclassCompare = function() { + if (this._actor && this.item() && this._statusWindow) { + var actor = JsonEx.makeDeepCopy(this._actor); + if (this.isEnabled(this.item())) { + Yanfly.CCC.PreventReleaseItem = true; + actor.changeSubclass(this.item()); + Yanfly.CCC.PreventReleaseItem = undefined; + } + this._statusWindow.setTempActor(actor); + } +}; + +//============================================================================= +// Scene_Class +//============================================================================= + +Yanfly.Subclass.Scene_Class_createCommandWindow = + Scene_Class.prototype.createCommandWindow; +Scene_Class.prototype.createCommandWindow = function() { + Yanfly.Subclass.Scene_Class_createCommandWindow.call(this); + var win = this._commandWindow; + win.setHandler('subclass', this.commandClass.bind(this)); +}; + +Yanfly.Subclass.Scene_Class_onItemOk = Scene_Class.prototype.onItemOk; +Scene_Class.prototype.onItemOk = function() { + if (this._commandWindow.currentSymbol() === 'class') { + Yanfly.Subclass.Scene_Class_onItemOk.call(this); + } else { + this.onSubclassOk(); + } +}; + +Scene_Class.prototype.onSubclassOk = function() { + SoundManager.playEquip(); + var classId = this._itemWindow.item(); + var hpRate = this.actor().hp / this.actor().mhp; + var mpRate = this.actor().mp / Math.max(1, this.actor().mmp); + this.actor().changeSubclass(classId); + var max = this.actor().isDead() ? 0 : 1; + var hpAmount = Math.max(max, parseInt(this.actor().mhp * hpRate)); + this.actor().setHp(hpAmount); + this.actor().setMp(parseInt(this.actor().mmp * mpRate)); + this._itemWindow.activate(); + this.refreshWindows(); +}; + +//============================================================================= +// Utilities +//============================================================================= + +Yanfly.Util = Yanfly.Util || {}; + +Yanfly.Util.getRange = function(n, m) { + var result = []; + for (var i = n; i <= m; ++i) result.push(i); + return result; +}; + +Yanfly.Util.onlyUnique = function(value, index, self) { + return self.indexOf(value) === index; +}; + +//============================================================================= +// End of File +//============================================================================= +}; \ No newline at end of file