diff --git a/Assembly-CSharp/Assembly-CSharp.csproj b/Assembly-CSharp/Assembly-CSharp.csproj index 03ba1e83f..ea2cf667c 100644 --- a/Assembly-CSharp/Assembly-CSharp.csproj +++ b/Assembly-CSharp/Assembly-CSharp.csproj @@ -12,7 +12,7 @@ Assembly-CSharp v3.5 512 - Unity Full v3.5 + Client $(SolutionDir)\References\ latest diff --git a/Assembly-CSharp/Assets/Sources/Scripts/EventEngine/Utils/CalcStack.cs b/Assembly-CSharp/Assets/Sources/Scripts/EventEngine/Utils/CalcStack.cs index aaa00a788..a1b6efe50 100644 --- a/Assembly-CSharp/Assets/Sources/Scripts/EventEngine/Utils/CalcStack.cs +++ b/Assembly-CSharp/Assets/Sources/Scripts/EventEngine/Utils/CalcStack.cs @@ -1,67 +1,79 @@ using System; +using System.Collections.Generic; using Memoria.Prime; namespace Assets.Sources.Scripts.EventEngine.Utils { public class CalcStack { - public Boolean push(Int32 arg0) + public Boolean push(Int32 val) { - if (this.topOfStackID >= this.stack.Length - 1) - return false; - this.stack[this.topOfStackID] = arg0; - this.topOfStackID++; + while (topOfStackID >= stack.Count) + stack.Add(0); + stack[topOfStackID++] = val; return true; } public Boolean pop(out Int32 output) { - if (this.topOfStackID == 0) + if (topOfStackID == 0) { - Log.Error($"[{nameof(CalcStack)}.{nameof(pop)}] this.topOfStackID == 0"); + Log.Error($"[{nameof(CalcStack)}.{nameof(pop)}] topOfStackID == 0"); output = default; return false; } - output = this.stack[this.topOfStackID - 1]; - this.topOfStackID--; + output = stack[--topOfStackID]; return true; } public Boolean advanceTopOfStack() { - if (this.topOfStackID >= this.stack.Length - 1) - return false; - this.topOfStackID++; + topOfStackID++; + while (topOfStackID > stack.Count) + stack.Add(0); return true; } public Boolean retreatTopOfStack() { - if (this.topOfStackID == 0) + if (topOfStackID == 0) return false; - this.topOfStackID--; + topOfStackID--; return true; } public void emptyCalcStack() { - for (Int32 i = 0; i < this.stack.Length; i++) - this.stack[i] = 0; - this.topOfStackID = 0; + substack.Clear(); + for (Int32 i = 0; i < stack.Count; i++) + stack[i] = 0; + topOfStackID = 0; } public Int32 getTopOfStackID() { - return this.topOfStackID; + return topOfStackID; } public Int32 getValueAtOffset(Int32 offset) { - return this.stack[this.topOfStackID + offset]; + return stack[topOfStackID + offset]; + } + + public void pushSubs(params Int32[] val) + { + substack[topOfStackID] = new List(val); + } + + public List getSubs() + { + if (substack.TryGetValue(topOfStackID, out List result)) + return result; + return new List(); } - private const Int32 STACK_SIZE = 16; - private Int32[] stack = new Int32[STACK_SIZE]; + private Dictionary> substack = new Dictionary>(); + private List stack = new List(16); private Int32 topOfStackID; } } diff --git a/Assembly-CSharp/Global/EBin.cs b/Assembly-CSharp/Global/EBin.cs index dabd40cca..472c3e941 100644 --- a/Assembly-CSharp/Global/EBin.cs +++ b/Assembly-CSharp/Global/EBin.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Collections.Generic; using Assets.Sources.Scripts.EventEngine.Utils; using FF9; using Memoria; @@ -414,28 +415,28 @@ private void expr_customSubCommand() args[i] = EvaluateValueExpression(); _v0 = 0; switch (commandId) - { - case flexible_varfunc.ITEM_REGULAR_TO_ID: - _v0 = ff9item.GetItemIdFromRegularId((RegularItem)args[0]); - break; + { + case flexible_varfunc.ITEM_REGULAR_TO_ID: + _v0 = ff9item.GetItemIdFromRegularId((RegularItem)args[0]); + break; case flexible_varfunc.ITEM_ID_TO_REGULAR: _v0 = (Int32)ff9item.GetRegularIdFromItemId(args[0]); break; case flexible_varfunc.ITEM_KEY_TO_ID: - _v0 = ff9item.GetItemIdFromImportantId(args[0]); - break; + _v0 = ff9item.GetItemIdFromImportantId(args[0]); + break; case flexible_varfunc.ITEM_ID_TO_KEY: _v0 = (Int32)ff9item.GetImportantIdFromItemId(args[0]); break; case flexible_varfunc.ITEM_CARD_TO_ID: - _v0 = ff9item.GetItemIdFromCardId((TetraMasterCardId)args[0]); - break; + _v0 = ff9item.GetItemIdFromCardId((TetraMasterCardId)args[0]); + break; case flexible_varfunc.ITEM_ID_TO_CARD: _v0 = (Int32)ff9item.GetCardIdFromItemId(args[0]); break; case flexible_varfunc.ABILITY_ACTIVE_TO_ID: - _v0 = ff9abil.GetAbilityIdFromActiveAbility((BattleAbilityId)args[0]); - break; + _v0 = ff9abil.GetAbilityIdFromActiveAbility((BattleAbilityId)args[0]); + break; case flexible_varfunc.ABILITY_ID_TO_ACTIVE: _v0 = (Int32)ff9abil.GetActiveAbilityFromAbilityId(args[0]); break; @@ -443,20 +444,20 @@ private void expr_customSubCommand() _v0 = ff9abil.GetAbilityIdFromSupportAbility((SupportAbility)args[0]); break; case flexible_varfunc.ABILITY_ID_TO_SUPPORT: - _v0 = (Int32)ff9abil.GetSupportAbilityFromAbilityId(args[0]); - break; - case flexible_varfunc.PARTY_MEMBER: - _v0 = (Int32)ff9play.CharacterIDToOldIndex(FF9StateSystem.Common.FF9.party.GetCharacterId(args[0])); - break; - case flexible_varfunc.ITEM_FULL_COUNT: - _v0 = ff9item.FF9Item_GetAnyCount((RegularItem)args[0]); - break; - case flexible_varfunc.PLAYER_EQUIP: - _v0 = (Int32)(FF9StateSystem.Common.FF9.GetPlayer(ff9play.CharacterOldIndexToID((CharacterOldIndex)args[0]))?.equip[args[1]] ?? RegularItem.NoItem); - break; - case flexible_varfunc.PLAYER_LEVEL: - _v0 = FF9StateSystem.Common.FF9.GetPlayer(ff9play.CharacterOldIndexToID((CharacterOldIndex)args[0]))?.level ?? 0; - break; + _v0 = (Int32)ff9abil.GetSupportAbilityFromAbilityId(args[0]); + break; + case flexible_varfunc.PARTY_MEMBER: + _v0 = (Int32)ff9play.CharacterIDToOldIndex(FF9StateSystem.Common.FF9.party.GetCharacterId(args[0])); + break; + case flexible_varfunc.ITEM_FULL_COUNT: + _v0 = ff9item.FF9Item_GetAnyCount((RegularItem)args[0]); + break; + case flexible_varfunc.PLAYER_EQUIP: + _v0 = (Int32)(FF9StateSystem.Common.FF9.GetPlayer(ff9play.CharacterOldIndexToID((CharacterOldIndex)args[0]))?.equip[args[1]] ?? RegularItem.NoItem); + break; + case flexible_varfunc.PLAYER_LEVEL: + _v0 = FF9StateSystem.Common.FF9.GetPlayer(ff9play.CharacterOldIndexToID((CharacterOldIndex)args[0]))?.level ?? 0; + break; case flexible_varfunc.PLAYER_EXP: _v0 = (Int32)(FF9StateSystem.Common.FF9.GetPlayer(ff9play.CharacterOldIndexToID((CharacterOldIndex)args[0]))?.exp ?? 0); break; @@ -468,7 +469,7 @@ private void expr_customSubCommand() else _v0 = (Int32)ff9level.CharacterLevelUps[args[0] - 1].ExperienceToLevel; break; - case flexible_varfunc.PLAYER_ABILITY_LEARNT: + case flexible_varfunc.PLAYER_ABILITY_LEARNT: { PLAYER player = FF9StateSystem.Common.FF9.GetPlayer(ff9play.CharacterOldIndexToID((CharacterOldIndex)args[0])); if (player == null || !ff9abil.FF9Abil_HasAp(new Character(player))) @@ -483,19 +484,31 @@ private void expr_customSubCommand() _v0 = 1; break; } - case flexible_varfunc.PLAYER_SUPPORT_ENABLED: + case flexible_varfunc.PLAYER_SUPPORT_ENABLED: { PLAYER player = FF9StateSystem.Common.FF9.GetPlayer(ff9play.CharacterOldIndexToID((CharacterOldIndex)args[0])); _v0 = player != null && player.saExtended.Contains((SupportAbility)args[1]) ? 1 : 0; break; } - case flexible_varfunc.SHOP_ITEM: + case flexible_varfunc.SHOP_ITEM: _v0 = ff9buy.ShopItems.ContainsKey(args[0]) && ff9buy.ShopItems[args[0]].ItemIds.Contains((RegularItem)args[1]) ? 1 : 0; break; - case flexible_varfunc.SHOP_SYNTH: + case flexible_varfunc.SHOP_SYNTH: _v0 = ff9mix.SynthesisData.ContainsKey(args[1]) && ff9mix.SynthesisData[args[1]].Shops.Contains(args[0]) ? 1 : 0; break; - } + case flexible_varfunc.VECTOR: + _s7.pushSubs(args[0], args[1]); + _s7.push(encodeTypeAndVarClass(VariableSource.Null, VariableType.Vector)); + return; + case flexible_varfunc.VECTOR_SIZE: + _s7.pushSubs(args[0]); + _s7.push(encodeTypeAndVarClass(VariableSource.Null, VariableType.VectorSize)); + return; + case flexible_varfunc.DICTIONARY: + _s7.pushSubs(args[0], args[1]); + _s7.push(encodeTypeAndVarClass(VariableSource.Null, VariableType.Dictionary)); + return; + } expr_Push_v0_Int24(); } @@ -524,7 +537,7 @@ public Int32 setVarManually(Int32 varOperation, Int32 value) varCode |= varArrayIndex; _s7.push(varCode); SetVariableValue(value); - varCode |= encodeTypeAndVarClass(7); + varCode |= encodeVarClass(VariableSource.Int26); _s7.push(varCode); return varCode; @@ -684,7 +697,7 @@ private void expr_jumpToSubCommand(op_binary arg0) _v0 = EvaluateValueExpression(); if (t3 == 0) { - expr_adZ(); + expr_Push_v0_Int24(); } else { @@ -699,7 +712,7 @@ private void expr_jumpToSubCommand(op_binary arg0) _v0 = EvaluateValueExpression(); if (t3 == 0) { - expr_adZ(); + expr_Push_v0_Int24(); } else { @@ -891,8 +904,7 @@ private void expr_jumpToSubCommand(op_binary arg0) { Int32 a0 = s1.getByteIP(); s1.ip++; - int a1 = encodeTypeAndVarClass(6); - a0 |= a1; + a0 |= encodeVarClass(VariableSource.Member); _s7.push(a0); break; } @@ -977,7 +989,7 @@ private void expr_jumpToSubCommand(op_binary arg0) _s7.advanceTopOfStack(); if (t3 == 0) { - expr_adZ(); + expr_Push_v0_Int24(); } else { @@ -996,7 +1008,7 @@ private void expr_jumpToSubCommand(op_binary arg0) _s7.advanceTopOfStack(); if (t3 == 0) { - expr_adZ(); + expr_Push_v0_Int24(); } else { @@ -1236,54 +1248,33 @@ private void expr_jumpToSubCommand(op_binary arg0) } case op_binary.B_OBJSPECA: { - Int32 a0 = s1.getByteIP(); - int a1 = s1.getByteIP(1); + _s7.push(s1.getByteIP(1) | (s1.getByteIP() << 8) | encodeVarClass(VariableSource.Object)); s1.ip += 2; - a0 <<= 8; - a0 |= a1; - a1 = encodeTypeAndVarClass(4); - a0 |= a1; - _s7.push(a0); break; } case op_binary.B_SYSLIST: { - Int32 a0 = s1.getByteIP(); + _s7.push(s1.getByteIP() | encodeVarClass(VariableSource.System)); s1.ip++; - int a1 = encodeTypeAndVarClass(5); - a0 |= a1; - _s7.push(a0); break; } case op_binary.B_SYSVAR: { - Int32 a0 = s1.getByteIP(); + _v0 = _eventEngine.GetSysvar(s1.getByteIP()); s1.ip++; - _v0 = _eventEngine.GetSysvar(a0); - a0 = 0x3FFFFFF; // 26 bit (unsigned?) - a0 = _v0 & a0; - int a1 = encodeTypeAndVarClass(7); - a0 |= a1; - _s7.push(a0); + _s7.push((_v0 & 0x3FFFFFF) | encodeVarClass(VariableSource.Int26)); // 26 bit (signed) break; } case op_binary.B_CONST: { - Int32 a0 = s1.getShortIP(); + _s7.push((Int32)s1.getShortIP() | encodeVarClass(VariableSource.Int26)); s1.ip += 2; - int a1 = encodeTypeAndVarClass(7); - a0 |= a1; - _s7.push(a0); break; } case op_binary.B_CONST4: { - Int32 a0 = s1.getIntIP(); + _s7.push((s1.getIntIP() & 0x3FFFFFF) | encodeVarClass(VariableSource.Int26)); // 26 bit (signed) s1.ip += 4; - a0 &= 0x3FFFFFF; // 26 bit (unsigned?) - int a1 = encodeTypeAndVarClass(7); - a0 |= a1; - _s7.push(a0); break; } case op_binary.B_EXPR_END: @@ -1311,16 +1302,10 @@ private static Int32 ConvertFloatAngleToFixedPoint(Single floatAngle) private void expr_Push_v0_Int24() { - int a1 = encodeTypeAndVarClass(7); - _v0 |= a1; + _v0 |= encodeVarClass(VariableSource.Int26); _s7.push(_v0); } - private void expr_adZ() - { - expr_Push_v0_Int24(); - } - public Int32 bra() { Int16 shortIP = s1.getShortIP(); @@ -1677,8 +1662,8 @@ public Int32 CollisionAngle(PosObj po, PosObj pot, Single myrot) public Int32 EvaluateValueExpression() { _s7.pop(out var t0); - VariableType varType = (VariableType)((getTypeAndVarClass(t0) >> 3) & 7); - VariableSource cls = (VariableSource)getVarClass(t0); + VariableType varType = getVarType(t0); + VariableSource cls = getVarClass(t0); switch (cls) { case VariableSource.Global: @@ -1688,8 +1673,43 @@ public Int32 EvaluateValueExpression() case VariableSource.Instance: return GetVariableValueInternal(_instance, t0 & 0xFFFF, varType, _instanceVOfs); case VariableSource.Null: - if (varType == VariableType.SBit) - return GetMemoriaCustomVariable((memoria_variable)(t0 & 0xFFFF)); + switch (varType) + { + case VariableType.Any: + return GetMemoriaCustomVariable((memoria_variable)(t0 & 0xFFFF)); + case VariableType.Vector: + { + List subs = _s7.getSubs(); + if (subs.Count < 2) + return 0; + Int32 vectID = subs[0]; + Int32 arrayIndex = subs[1]; + if (FF9StateSystem.EventState.gScriptVector.TryGetValue(vectID, out List vect) && arrayIndex >= 0 && arrayIndex < vect.Count) + return vect[arrayIndex]; + return 0; + } + case VariableType.VectorSize: + { + List subs = _s7.getSubs(); + if (subs.Count < 1) + return 0; + Int32 vectID = subs[0]; + if (FF9StateSystem.EventState.gScriptVector.TryGetValue(vectID, out List vect)) + return vect.Count; + return 0; + } + case VariableType.Dictionary: + { + List subs = _s7.getSubs(); + if (subs.Count < 2) + return 0; + Int32 dictID = subs[0]; + Int32 entryID = subs[1]; + if (FF9StateSystem.EventState.gScriptDictionary.TryGetValue(dictID, out Dictionary dict) && dict.TryGetValue(entryID, out Int32 val)) + return val; + return 0; + } + } return 0; case VariableSource.Object: _v0 = getvobj(_eventEngine.GetObjUID((t0 >> 8) & 0xFF), t0 & 0xFF); @@ -1890,8 +1910,8 @@ public Int32 SetVariableValue(Int32 arg0) { _s7.pop(out var t0); Int32 varValue = arg0; - VariableType varType = (VariableType)((getTypeAndVarClass(t0) >> 3) & 7); - VariableSource cls = (VariableSource)getVarClass(t0); + VariableType varType = getVarType(t0); + VariableSource cls = getVarClass(t0); switch (cls) { case VariableSource.Global: @@ -1904,8 +1924,74 @@ public Int32 SetVariableValue(Int32 arg0) SetVariableValueInternal(_instance, t0 & 0xFFFF, varType, varValue, _instanceVOfs); break; case VariableSource.Null: - if (varType == VariableType.SBit) - SetMemoriaCustomVariable((memoria_variable)(t0 & 0xFFFF), varValue); + switch (varType) + { + case VariableType.Any: + SetMemoriaCustomVariable((memoria_variable)(t0 & 0xFFFF), varValue); + break; + case VariableType.Vector: + { + List subs = _s7.getSubs(); + if (subs.Count < 2) + break; + Int32 vectID = subs[0]; + Int32 arrayIndex = subs[1]; + if (FF9StateSystem.EventState.gScriptVector.TryGetValue(vectID, out List vect)) + { + if (arrayIndex == vect.Count) + vect.Add(varValue); + else if (arrayIndex >= 0 && arrayIndex < vect.Count) + vect[arrayIndex] = varValue; + } + else if (arrayIndex == 0) + { + vect = new List(); + vect.Add(varValue); + FF9StateSystem.EventState.gScriptVector.Add(vectID, vect); + } + break; + } + case VariableType.VectorSize: + { + List subs = _s7.getSubs(); + if (subs.Count < 1 || varValue < 0) + break; + Int32 vectID = subs[0]; + if (FF9StateSystem.EventState.gScriptVector.TryGetValue(vectID, out List vect)) + { + if (varValue > vect.Count) + vect.AddRange(Enumerable.Repeat(0, varValue - vect.Count)); + else if (varValue < vect.Count) + vect.RemoveRange(varValue, vect.Count - varValue); + } + else + { + vect = new List(varValue); + vect.AddRange(Enumerable.Repeat(0, varValue)); + FF9StateSystem.EventState.gScriptVector.Add(vectID, vect); + } + break; + } + case VariableType.Dictionary: + { + List subs = _s7.getSubs(); + if (subs.Count < 2) + break; + Int32 dictID = subs[0]; + Int32 entryID = subs[1]; + if (FF9StateSystem.EventState.gScriptDictionary.TryGetValue(dictID, out Dictionary dict)) + { + dict[entryID] = varValue; + } + else + { + dict = new Dictionary(); + dict[entryID] = varValue; + FF9StateSystem.EventState.gScriptDictionary.Add(dictID, dict); + } + break; + } + } break; case VariableSource.System: _eventEngine.SetSysList(t0 & 0xFF, varValue); @@ -1993,20 +2079,24 @@ public Int32 putv(Int32 a) return _v0; } - private Int32 getVarClass(Int32 value) + private VariableSource getVarClass(Int32 value) + { + return (VariableSource)((value >> 26) & 7); + } + + private VariableType getVarType(Int32 value) { - Int32 typeAndVarClass = getTypeAndVarClass(value); - return typeAndVarClass & 7; + return (VariableType)((value >> 29) & 7); } - private Int32 getTypeAndVarClass(Int32 value) + private Int32 encodeTypeAndVarClass(VariableSource varSrc, VariableType varType) { - return value >> 26; + return ((Int32)varSrc << 26) | ((Int32)varType << 29); } - private Int32 encodeTypeAndVarClass(Int32 typeAndClass) + private Int32 encodeVarClass(VariableSource varSrc) { - return typeAndClass << 26; + return (Int32)varSrc << 26; } public enum event_code_binary @@ -2294,6 +2384,8 @@ public enum event_code_binary MOVE_EX, TURN_OBJ_EX, AANIM_EX, + VECTOR_CLEAR, + DICTIONARY_CLEAR, } public enum flexible_varfunc : ushort @@ -2319,6 +2411,9 @@ public enum flexible_varfunc : ushort PLAYER_SUPPORT_ENABLED, SHOP_ITEM, SHOP_SYNTH, + VECTOR, + VECTOR_SIZE, + DICTIONARY, } public enum memoria_variable : ushort @@ -2481,5 +2576,9 @@ public enum VariableType Byte = 5, Int16 = 6, UInt16 = 7, + Any = 0, + Vector = 1, + VectorSize = 2, + Dictionary = 3, } } \ No newline at end of file diff --git a/Assembly-CSharp/Global/Event/Engine/EventEngine.DoEventCode.cs b/Assembly-CSharp/Global/Event/Engine/EventEngine.DoEventCode.cs index 855fb61f8..4abc79b5c 100644 --- a/Assembly-CSharp/Global/Event/Engine/EventEngine.DoEventCode.cs +++ b/Assembly-CSharp/Global/Event/Engine/EventEngine.DoEventCode.cs @@ -2853,6 +2853,20 @@ public Int32 DoEventCode() AnimationFactory.AddAnimWithAnimatioName(actor.go, FF9DBAll.AnimationDB.GetValue(anim)); return 0; } + case EBin.event_code_binary.VECTOR_CLEAR: + { + Int32 vectID = this.getv3(); + if (FF9StateSystem.EventState.gScriptVector.TryGetValue(vectID, out List vect)) + vect.Clear(); + return 0; + } + case EBin.event_code_binary.DICTIONARY_CLEAR: + { + Int32 dictID = this.getv3(); + if (FF9StateSystem.EventState.gScriptDictionary.TryGetValue(dictID, out Dictionary dict)) + dict.Clear(); + return 0; + } default: { switch (this.gMode) diff --git a/Assembly-CSharp/Global/Event/Engine/EventEngine.Initialize.cs b/Assembly-CSharp/Global/Event/Engine/EventEngine.Initialize.cs index 1a19dffc6..1bfc90466 100644 --- a/Assembly-CSharp/Global/Event/Engine/EventEngine.Initialize.cs +++ b/Assembly-CSharp/Global/Event/Engine/EventEngine.Initialize.cs @@ -42,6 +42,9 @@ public void NewGame() { FF9StateSystem.EventState.gStepCount = 0; FF9StateSystem.EventState.gEventGlobal = new Byte[2048]; + FF9StateSystem.EventState.gAbilityUsage.Clear(); + FF9StateSystem.EventState.gScriptVector.Clear(); + FF9StateSystem.EventState.gScriptDictionary.Clear(); FF9StateSystem.Common.FF9.fldMapNo = (Int16)70; // Opening-For FMV FF9StateSystem.Common.FF9.fldLocNo = (Int16)EventEngineUtils.eventIDToMESID[70]; FF9StateSystem.Settings.time = 0.0; diff --git a/Assembly-CSharp/Global/Event/EventState.cs b/Assembly-CSharp/Global/Event/EventState.cs index b42d45bec..89372c205 100644 --- a/Assembly-CSharp/Global/Event/EventState.cs +++ b/Assembly-CSharp/Global/Event/EventState.cs @@ -10,6 +10,8 @@ public class EventState : MonoBehaviour public Byte[] gEventGlobal = new Byte[2048]; public Dictionary gAbilityUsage = new Dictionary(); + public Dictionary> gScriptVector = new Dictionary>(); + public Dictionary> gScriptDictionary = new Dictionary>(); public Int32 ScenarioCounter { diff --git a/Assembly-CSharp/Global/Field/Map/NarrowMapList.cs b/Assembly-CSharp/Global/Field/Map/NarrowMapList.cs index 2e4607530..4bb4a8343 100644 --- a/Assembly-CSharp/Global/Field/Map/NarrowMapList.cs +++ b/Assembly-CSharp/Global/Field/Map/NarrowMapList.cs @@ -347,7 +347,6 @@ public static class NarrowMapList 2501, // I. Castle/Entrance 2502, // I. Castle/Hall 2503, - 2504, // I. Castle/Small Room 2505, // I. Castle/Inverted Roo 2510, // I. Castle/Mural Room 2512, // I. Castle/Mural Room diff --git a/Assembly-CSharp/Global/JsonParser.cs b/Assembly-CSharp/Global/JsonParser.cs index c2382341b..ea296443b 100644 --- a/Assembly-CSharp/Global/JsonParser.cs +++ b/Assembly-CSharp/Global/JsonParser.cs @@ -512,6 +512,8 @@ private void ParseEventJsonToData(JSONNode jsonData, Boolean oldSaveFormat = tru if (jsonData["gEventGlobal"] != null) eventState.gEventGlobal = Convert.FromBase64String(jsonData["gEventGlobal"].Value); eventState.gAbilityUsage.Clear(); + eventState.gScriptVector.Clear(); + eventState.gScriptDictionary.Clear(); if (jsonData["gAbilityUsage"] != null) { for (Int32 i = 0; i < jsonData["gAbilityUsage"].Count; i++) @@ -527,6 +529,38 @@ private void ParseEventJsonToData(JSONNode jsonData, Boolean oldSaveFormat = tru for (Int32 i = 1; i < 192; i++) eventState.gAbilityUsage[(BattleAbilityId)i] = eventState.gEventGlobal[1100 + i]; } + if (jsonData["gScriptVector"] != null) + { + for (Int32 i = 0; i < jsonData["gScriptVector"].Count; i++) + { + JSONClass vectorClass = jsonData["gScriptVector"][i].AsObject; + if (vectorClass != null && vectorClass["id"] != null && vectorClass["entries"] != null && vectorClass["entries"].Count > 0) + { + List vect = new List(); + for (Int32 j = 0; j < vectorClass["entries"].Count; j++) + vect.Add(vectorClass["entries"][j].AsInt); + eventState.gScriptVector[vectorClass["id"].AsInt] = vect; + } + } + } + if (jsonData["gScriptDictionary"] != null) + { + for (Int32 i = 0; i < jsonData["gScriptDictionary"].Count; i++) + { + JSONClass dictionaryClass = jsonData["gScriptDictionary"][i].AsObject; + if (dictionaryClass != null && dictionaryClass["id"] != null && dictionaryClass["entries"] != null && dictionaryClass["entries"].Count > 0) + { + Dictionary dict = new Dictionary(); + for (Int32 j = 0; j < dictionaryClass["entries"].Count; j++) + { + JSONClass entry = dictionaryClass["entries"][j].AsObject; + if (entry != null && entry["id"] != null && entry["value"] != null) + dict[entry["id"].AsInt] = entry["value"].AsInt; + } + eventState.gScriptDictionary[dictionaryClass["id"].AsInt] = dict; + } + } + } } private void ParseEventDataToJson(EventState data, JSONClass dataNode, JSONClass schemaNode, Boolean oldSaveFormat = true) @@ -546,6 +580,38 @@ private void ParseEventDataToJson(EventState data, JSONClass dataNode, JSONClass }); } dataProfileClass.Add("gAbilityUsage", abilArray); + JSONArray vectorArray = new JSONArray(); + foreach (KeyValuePair> kp in data.gScriptVector) + { + JSONArray entryArray = new JSONArray(); + foreach (Int32 entry in kp.Value) + entryArray.Add(entry.ToString()); + vectorArray.Add(new JSONClass + { + { "id", kp.Key.ToString() }, + { "entries", entryArray } + }); + } + dataProfileClass.Add("gScriptVector", vectorArray); + JSONArray dictionaryArray = new JSONArray(); + foreach (KeyValuePair> kp in data.gScriptDictionary) + { + JSONArray entryArray = new JSONArray(); + foreach (KeyValuePair entry in kp.Value) + { + entryArray.Add(new JSONClass + { + { "id", entry.Key.ToString() }, + { "value", entry.Value.ToString() } + }); + } + dictionaryArray.Add(new JSONClass + { + { "id", kp.Key.ToString() }, + { "entries", entryArray } + }); + } + dataProfileClass.Add("gScriptDictionary", dictionaryArray); } dataNode.Add("20000_Event", dataProfileClass); if (!oldSaveFormat) diff --git a/Memoria.Launcher/Catalogs/MemoriaCatalog.xml b/Memoria.Launcher/Catalogs/MemoriaCatalog.xml index 916a69d61..3812bdc7b 100644 --- a/Memoria.Launcher/Catalogs/MemoriaCatalog.xml +++ b/Memoria.Launcher/Catalogs/MemoriaCatalog.xml @@ -21,14 +21,15 @@ Note: this mod doesn't support automatic installation yet. Download it from its https://sites.google.com/view/moguri-mod In most situations, it is better to keep 'MoguriFiles' at the lowest priority + https://i.imgur.com/nddT44g.jpg Alternate Fantasy - 6.1 + 6.2 AlternateFantasy Tirlititi - 11 Jun 2023 + 28 Sep 2023 Requires Memoria v2023.06.11 This mod aims at increasing the difficulty and, above all, to give a new fresh experience of FF9 for those who already know the game well. It includes: @@ -103,7 +104,7 @@ This is actually a lighter version of Alternate Fantasy, to benefit from its add Garnet is Main Character GarnetIsMainCharacter piano221 - 5 Apr 2021 + 2021-04-05 This mod allow you to change Zidane for Garnet as the field main character. Character Swap https://forums.qhimm.com/index.php?topic=20605.0 @@ -116,7 +117,7 @@ This is actually a lighter version of Alternate Fantasy, to benefit from its add 0.5 FreyaGamePlus ChikoLad - 30 Jul 2020 + 2020-07-30 Freya Game+ is a Final Fantasy IX mod that allows you to have Freya in your party at almost all times throughout the game. This mod removes the need to do any save editing or setting personal restrictions if you want to do a Freya Solo Run. @@ -133,7 +134,7 @@ Note: this mod doesn't support automatic installation yet. Download it from its 0.1 PlayAsKuja Tirlititi - 17 Apr 2021 + 2021-04-17 Requires Memoria between v2021.05.10 and v2022.09.09 to work in battles Turn Zidane's 3D model on the field and in battles into Kuja's 3D model. The animations on the field are messed up. @@ -146,10 +147,10 @@ You should better use the Playable Characters Pack instead. This later one doesn Playable Character Pack - 1.0 + 1.1 PlayableCharacterPack Tirlititi - 11 Jun 2023 + 2023-09-28 Requires Memoria v2023.06.11 Add Kuja, Fratley and Lani as playable characters. You can press Alt+F2 in-game to access the party menu (changing the party at any time is a feature of Memoria, not related to this mod). @@ -175,7 +176,7 @@ You should set the priority of this mod to be higher than the priority of the Mo David Bowie Edition DavidBowie Clem Fandango - 18 Mar 2020 + 2020-03-18 Final Fantasy IX: David Bowie Edition (DBE) is a gameplay mod that is meant to function as a rebalance, or better yet a remix of the original game. This mod includes new skills, items, enemy behavior, Chocograph rewards and a number of smaller tweaks. Gameplay https://forums.qhimm.com/index.php?topic=19499.0 @@ -184,34 +185,40 @@ You should set the priority of this mod to be higher than the priority of the Mo Mog Add-ons - 3.1 + 3.3 MogAddons - 28 July 2023, 12:32PM + 2023-12-01 faospark - UI, Buttons , Portraits, and more... an Easy to install collection of enhancements for Final Fantasy IX Steam. -:: Requirements :: -- Memoria version v2022.11.11 or higher - + UI, Buttons , Portraits, Tweaks and more... an Easy to install collection of enhancements for Final Fantasy IX Steam. :: Features :: Default : FFXI Darker/Sane UI , Opera Omnia Style Portraits , PlayStation Gloss prompts +Tweaks : AP GAIN , EXP GAIN and Requirements Portrait options : Default with extended cast, Opera Omnia and Upscaled PS1 Portrait Artwork Button Prompts Options: PS Gloss , PS5 , Pixel Style, PlayStation Vanilla prompts, UI : Default , Darker UI and Flat :: Submod activation :: -Use the Mod Manager UI to activate each submods you like - -:: 3.0 and 3.1 Log :: -- Added 1 Gem Compatibility with Alternate Fantasy -- Replaced Amaranth's Opera Omnia Portrait -- Split default feature of halved EXP and 1 Gem passive ability to ech submod - -- Bump compatibility to the recent version of memoria +Use the Mod Manager UI to activate each submods you like and pick :: Compatibility :: - Compatible with Alternate Fantasy - Not compatible for older versions of the game and repacks. +Requires Memoria v2023.06.11 + ::3.3 :: +-Added 4x AP gain +-Added 99 AP gain +-Added 2x+ EXP gain +-Added 4x+ EXP gain +-Added NO EXP AND AP GAIN +::3.2 :: +-Added double exp and halved ability gems +:: 3.0 and 3.1 Log :: +- Added 1 Gem Compatibility with Alternate Fantasy +- Replaced Amaranth's Opera Omnia Portrait +- Split default feature of halved EXP and 1 Gem passive ability to ech submod +- Bump compatibility to the recent version of memoria + Visual https://www.nexusmods.com/finalfantasy9/mods/31 https://www.dropbox.com/s/o1wjflgm0s3dicx/Mog%20Add-ons%20Mod%20FFIX.zip?dl=1 @@ -284,21 +291,63 @@ Use the Mod Manager UI to activate each submods you like 1 - Tweak Enable : 1 Gem Ability + Tweak: 1 Gem Ability Features/Tweaks/Ability Enables 1 gem for passive abilities to be enabled 1 - Tweak Enable : 1 Gem Ability for Alternate Fantasy + Tweak: Halved Gem Ability + Features/Tweaks/AbilityHalf + Cuts ability gems to half for passive abilities to be enabled + 1 + + + Tweak: 1 Gem Ability for Alternate Fantasy Features/Tweaks/AF Ability Enables 1 gem for passive abilities to be enabled for alternate fantasy 1 - Tweak Enable : Halved EXP - Features/Tweaks/Exp - Cuts the EXP requirement feature to level up by Half + Tweak: 4x AP Gain + Features/Tweaks/AP4x + Gains 4x AP after battle + 1 + + + Tweak: 99 AP Gain + Features/Tweaks/AP99 + Gains 99 AP after battle + 1 + + + Tweak: 2x+ EXP Gain + Features/Tweaks/EXP2x + Gains 2x+ EXP after battle + 1 + + + Tweak: 4x+ EXP Gain + Features/Tweaks/EXP4x + Gains 4x+ EXP after battle + 1 + + + Tweak: No / Zero AP and EXP Gain + Features/Tweaks/EXPAP0 + If you like things hard. + 1 + + + Tweak: Halved EXP + Features/Tweaks/ExpHalf + Cuts the EXP requirement to level up faster + 1 + + + Tweak: Doubled EXP + Features/Tweaks/ExpX2 + Doubles EXP requirement so you level up slower 1 @@ -307,21 +356,21 @@ Use the Mod Manager UI to activate each submods you like High-Res Chocographs HDChocographs Caledor - 12 May 2021 + 2021-05-12 Chocographs remade from scratch by taking actual screenshots in FF9 Steam modded with Moguri Mod 8.2. (English layout only) Visual https://forums.qhimm.com/index.php?topic=20657.0 https://i.imgur.com/tpdfrUQ.png SingleFileWithPath:FF9_Data/EmbeddedAsset/UI/Atlas/Chocograph Atlas - https://i.imgur.com/M4ce7hE.png + https://i.imgur.com/RCVuINt.png Tweaked Portraits TweakedPortraits Lykon - 16 May 2020 + 2020-05-16 This is a simple mod that slightly tweaks the portrait shown in the main menu. Visual https://forums.qhimm.com/index.php?topic=19964.0 @@ -335,17 +384,16 @@ Use the Mod Manager UI to activate each submods you like 0.2.13 TranceSeek DVlad666 - - A hard mod that allows you to experience a new whole adventure! All the monsters and bosses have been redesigned (not only a stats boost but all the AIs are revisited), new skills, mechanics and many other things! - A multitude of additional fights/bosses are also introduced. - (This is not an very hardcore difficult mod: it only adds a higher difficulty than the original version while keeping a constant progression.) + A hard mod that allows you to experience a new whole adventure! All the monsters and bosses have been redesigned (not only a stats boost but all the AIs are revisited), new skills, mechanics and many other things! +A multitude of additional fights/bosses are also introduced. +(This is not an very hardcore difficult mod: it only adds a higher difficulty than the original version while keeping a constant progression.) - It's currently a demo : CD1 and CD2 only available, CD3 WIP. - Don't hesitate to try! +It's currently a demo : CD1 and CD2 only available, CD3 WIP. +Don't hesitate to try! Gameplay https://steamcommunity.com/app/377840/discussions/0/5362100202713255072/ - https://drive.google.com/uc?export=download&id=1ONGayLWtVctUgM33aYWVvzSGqDBEsOIE&confirm=t + https://www.dropbox.com/scl/fi/6dz48odlx0hn1b2o0hp9w/TranceSeek-Demo-CD3-by-DV.zip?rlkey=dxnyl6me6d1cbatkkdjcvkowo&dl=1 @@ -353,13 +401,12 @@ Use the Mod Manager UI to activate each submods you like 2.0 PlaystationSounds DVlad666 - - Replace the sound assets by the PSX sounds (specially Battle + Tetra Master + Miscellaneous). - More than 1540 sound files fixed! + Replace the sound assets by the PSX sounds (specially Battle + Tetra Master + Miscellaneous). +More than 1540 sound files fixed! Audio https://steamcommunity.com/app/377840/discussions/0/3189117724409401717/ - https://drive.google.com/uc?export=download&id=1RLcIQ9M6AB19IPGDXskoBGcC3siVbLQQ&confirm=t + https://www.dropbox.com/scl/fi/mm4tc5k1g2admrl5klw3g/FF9_Sounds_Fix-by-DV.zip?rlkey=d2q5gk289coixe9s4kcdat1ir&dl=1 @@ -367,12 +414,11 @@ Use the Mod Manager UI to activate each submods you like 1.0 TripleTriad DVlad666 - - Change the music and background to the Triple Triad FF8 version (based on Tripod !) - Change some card textures (add boss + characters) + Change the music and background to the Triple Triad FF8 version (based on Tripod !) +Change some card textures (add boss + characters) Visual - https://drive.google.com/uc?export=download&id=1H2Z-a656qBdjht2h7UfhujzfW1znpJdU&confirm=t + https://www.dropbox.com/scl/fi/tgs1ivzinnhivry5zxac7/TripleTriad-by-DV.zip?rlkey=nnebxpvw10ovvk516xzr6xdcx&dl=1 @@ -391,12 +437,27 @@ many download links should be changed and several ones use the "[Import] Text" f Brazilian-Portuguese Translation BrazilianTranslation - P.O.B.R.E. / Brigandier - Tradução do jogo em português do Brasil. + Harleyquinn / dkPsycho / JonasJTG + Tradução totalmente revisada e atualizada para ser usada somente com o Mod Moguri. O jogo está completamente traduzido, incluindo história principal, diálogos secundários, sidequests, informações e outras coisas. + +Informações Importantes +- Não foram traduzidos os nomes dos Itens, equipamentos e magias. Fiz essa escolha para melhor experiência dos veteranos e iniciantes. +- Ao baixar a tradução existe duas opções na pasta de instalação: 30 FPS e 60 FPS. Instale somente a versão correspondente que queira usar. +- Alguns mods são imcompatíveis com a tradução pois susbstituem os arquivos de texto ou de textura. Então verifique bem antes de instala-los. +- Para jogar a versão 60 FPS basta baixar e executar a útima versão do Memoria, encontrada aqui: (https://github.com/Albeoris/Memoria/releases/tag/v2023.06.11) + +Para ver o tutorial de como instalar a tradução e acompanhar atualizações e conteúdos de FFIX entrem no meu canal. +(https://www.youtube.com/@dkpsycho/videos) + +Créditos: +- Harleyquinn: Porte para versão Moguri +- dkPsycho: Toda parte de tradução, revisão e melhoria +- JonasJTG: Edição dos Gráficos Note: this mod doesn't support automatic installation yet. Download it from its website. Translation https://steamcommunity.com/sharedfiles/filedetails/?id=2111796362 + https://i.imgur.com/wYsiAog.jpeg diff --git a/Memoria.Launcher/Images/btnActivateAllimg.png b/Memoria.Launcher/Images/btnActivateAllimg.png new file mode 100644 index 000000000..98075285d Binary files /dev/null and b/Memoria.Launcher/Images/btnActivateAllimg.png differ diff --git a/Memoria.Launcher/Images/btnActivateAllimg.psd b/Memoria.Launcher/Images/btnActivateAllimg.psd new file mode 100644 index 000000000..cc00e2972 Binary files /dev/null and b/Memoria.Launcher/Images/btnActivateAllimg.psd differ diff --git a/Memoria.Launcher/Images/btnCancelimg.png b/Memoria.Launcher/Images/btnCancelimg.png new file mode 100644 index 000000000..f2cebe70e Binary files /dev/null and b/Memoria.Launcher/Images/btnCancelimg.png differ diff --git a/Memoria.Launcher/Images/btnCancelimg.psd b/Memoria.Launcher/Images/btnCancelimg.psd new file mode 100644 index 000000000..274414c2c Binary files /dev/null and b/Memoria.Launcher/Images/btnCancelimg.psd differ diff --git a/Memoria.Launcher/Images/btnCheckCompatibilityimg.png b/Memoria.Launcher/Images/btnCheckCompatibilityimg.png new file mode 100644 index 000000000..aeca7c166 Binary files /dev/null and b/Memoria.Launcher/Images/btnCheckCompatibilityimg.png differ diff --git a/Memoria.Launcher/Images/btnCheckCompatibilityimg.psd b/Memoria.Launcher/Images/btnCheckCompatibilityimg.psd new file mode 100644 index 000000000..f409ea318 Binary files /dev/null and b/Memoria.Launcher/Images/btnCheckCompatibilityimg.psd differ diff --git a/Memoria.Launcher/Images/btnDeactivateAllimg.png b/Memoria.Launcher/Images/btnDeactivateAllimg.png new file mode 100644 index 000000000..822c9b53d Binary files /dev/null and b/Memoria.Launcher/Images/btnDeactivateAllimg.png differ diff --git a/Memoria.Launcher/Images/btnDeactivateAllimg.psd b/Memoria.Launcher/Images/btnDeactivateAllimg.psd new file mode 100644 index 000000000..c0e5a2052 Binary files /dev/null and b/Memoria.Launcher/Images/btnDeactivateAllimg.psd differ diff --git a/Memoria.Launcher/Images/btnDownloadimg.png b/Memoria.Launcher/Images/btnDownloadimg.png new file mode 100644 index 000000000..3d2aa0df9 Binary files /dev/null and b/Memoria.Launcher/Images/btnDownloadimg.png differ diff --git a/Memoria.Launcher/Images/btnDownloadimg.psd b/Memoria.Launcher/Images/btnDownloadimg.psd new file mode 100644 index 000000000..f32047570 Binary files /dev/null and b/Memoria.Launcher/Images/btnDownloadimg.psd differ diff --git a/Memoria.Launcher/Images/btnMoveDownimg.png b/Memoria.Launcher/Images/btnMoveDownimg.png new file mode 100644 index 000000000..c8758e5e1 Binary files /dev/null and b/Memoria.Launcher/Images/btnMoveDownimg.png differ diff --git a/Memoria.Launcher/Images/btnMoveDownimg.psd b/Memoria.Launcher/Images/btnMoveDownimg.psd new file mode 100644 index 000000000..bdf0898fc Binary files /dev/null and b/Memoria.Launcher/Images/btnMoveDownimg.psd differ diff --git a/Memoria.Launcher/Images/btnMoveUpimg.png b/Memoria.Launcher/Images/btnMoveUpimg.png new file mode 100644 index 000000000..92c84fefa Binary files /dev/null and b/Memoria.Launcher/Images/btnMoveUpimg.png differ diff --git a/Memoria.Launcher/Images/btnMoveUpimg.psd b/Memoria.Launcher/Images/btnMoveUpimg.psd new file mode 100644 index 000000000..6e24141ea Binary files /dev/null and b/Memoria.Launcher/Images/btnMoveUpimg.psd differ diff --git a/Memoria.Launcher/Images/btnUninstallimg.png b/Memoria.Launcher/Images/btnUninstallimg.png new file mode 100644 index 000000000..8d60dc0a6 Binary files /dev/null and b/Memoria.Launcher/Images/btnUninstallimg.png differ diff --git a/Memoria.Launcher/Images/btnUninstallimg.psd b/Memoria.Launcher/Images/btnUninstallimg.psd new file mode 100644 index 000000000..c1a3ea0d3 Binary files /dev/null and b/Memoria.Launcher/Images/btnUninstallimg.psd differ diff --git a/Memoria.Launcher/Images/new_launcher_bg.bak.png b/Memoria.Launcher/Images/new_launcher_bg.bak.png new file mode 100644 index 000000000..73eb52f5a Binary files /dev/null and b/Memoria.Launcher/Images/new_launcher_bg.bak.png differ diff --git a/Memoria.Launcher/Images/new_launcher_bg.png b/Memoria.Launcher/Images/new_launcher_bg.png index 73eb52f5a..5481761c0 100644 Binary files a/Memoria.Launcher/Images/new_launcher_bg.png and b/Memoria.Launcher/Images/new_launcher_bg.png differ diff --git a/Memoria.Launcher/Images/new_launcher_bg.psd b/Memoria.Launcher/Images/new_launcher_bg.psd new file mode 100644 index 000000000..bf26905e9 Binary files /dev/null and b/Memoria.Launcher/Images/new_launcher_bg.psd differ diff --git a/Memoria.Launcher/Languages/Lang.cs b/Memoria.Launcher/Languages/Lang.cs index a0976103c..3692cdabf 100644 --- a/Memoria.Launcher/Languages/Lang.cs +++ b/Memoria.Launcher/Languages/Lang.cs @@ -163,6 +163,7 @@ private static String GetSettings(string name) public static readonly string BattleInterfaceType2 = GetSettings(nameof(BattleInterfaceType2)); public static readonly string BattleInterfaceTooltip = GetSettings(nameof(BattleInterfaceTooltip)); public static readonly string SkipIntrosToMainMenu = GetSettings(nameof(SkipIntrosToMainMenu)); + public static readonly string SkipBattleSwirl = GetSettings(nameof(SkipBattleSwirl)); public static readonly string SkipBattleLoading = GetSettings(nameof(SkipBattleLoading)); public static readonly string HideCardsBubbles = GetSettings(nameof(HideCardsBubbles)); public static readonly string HideSteamBubbles = GetSettings(nameof(HideSteamBubbles)); diff --git a/Memoria.Launcher/Languages/en.xml b/Memoria.Launcher/Languages/en.xml index 056d202ff..005cb853b 100644 --- a/Memoria.Launcher/Languages/en.xml +++ b/Memoria.Launcher/Languages/en.xml @@ -23,11 +23,11 @@ Rollback = "Cancel" Inject = "Inject" SaveAs = "Save as..." - Exit = "E X I T" + Exit = "EXIT" Exiting = "Exiting..." - Launch = "P L A Y" + Launch = "PLAY" Launching = "Launching..." - ModManager = "Install Mods" + ModManager = "MOD MANAGER" /> + /> + + + + + + + + - - - - - + + + + + + IsTabStop="False" /> - - - - - + + + + + - - + + - + - + - - - - - + - - + + - + - - - + + + + + - -