diff --git a/excel/global.xlsx b/excel/global.xlsx index 56ed5e1..98f592d 100644 Binary files a/excel/global.xlsx and b/excel/global.xlsx differ diff --git a/excel/item.xlsx b/excel/item.xlsx index 8e4432d..f5c902d 100644 Binary files a/excel/item.xlsx and b/excel/item.xlsx differ diff --git a/excel/level.xlsx b/excel/level.xlsx index eb0604a..80dfa16 100644 Binary files a/excel/level.xlsx and b/excel/level.xlsx differ diff --git a/src/ReplicatedStorage/Data/SignalEnum.luau b/src/ReplicatedStorage/Data/SignalEnum.luau index 0e793e0..92e1547 100644 --- a/src/ReplicatedStorage/Data/SignalEnum.luau +++ b/src/ReplicatedStorage/Data/SignalEnum.luau @@ -2,6 +2,7 @@ local SignalEnum = {} SignalEnum = { SHOW_ABILITY = "SHOW_ABILITY", + CHALLENGE_LEVEL_END = "CHALLENGE_LEVEL_END", } return SignalEnum \ No newline at end of file diff --git a/src/ReplicatedStorage/Json/Level.json b/src/ReplicatedStorage/Json/Level.json index 7d55442..d2d95a9 100644 --- a/src/ReplicatedStorage/Json/Level.json +++ b/src/ReplicatedStorage/Json/Level.json @@ -1,52 +1,52 @@ [ -{"id":1,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1],[10,1,1],[10,1,1],[10,1,1]],"finishRewards":[50000,1]}, -{"id":2,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1],[10,1,1],[10,1,1],[10,1,1]],"finishRewards":[50001,1]}, -{"id":3,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50002,1]}, -{"id":4,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50003,1]}, -{"id":5,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[50004,1]}, -{"id":6,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50005,1]}, -{"id":7,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50006,1]}, -{"id":8,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50007,1]}, -{"id":9,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50008,1]}, -{"id":10,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[50009,1]}, -{"id":11,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50010,1]}, -{"id":12,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50011,1]}, -{"id":13,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50012,1]}, -{"id":14,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50013,1]}, -{"id":15,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[50014,1]}, -{"id":16,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50015,1]}, -{"id":17,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":18,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":19,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":20,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[]}, -{"id":21,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":22,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":23,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":24,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":25,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[]}, -{"id":26,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":27,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":28,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":29,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":30,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[]}, -{"id":31,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":32,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":33,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":34,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":35,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[]}, -{"id":36,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":37,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":38,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":39,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":40,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[]}, -{"id":41,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":42,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":43,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":44,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":45,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[]}, -{"id":46,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":47,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":48,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":49,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, -{"id":50,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]],"finishRewards":[]} +{"id":1,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1],[10,1,1],[10,1,1],[10,1,1]],"finishRewards":[50001,1]}, +{"id":2,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1],[10,1,1],[10,1,1],[10,1,1]],"finishRewards":[50002,1]}, +{"id":3,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50003,1]}, +{"id":4,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50004,1]}, +{"id":5,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[50005,1]}, +{"id":6,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50006,1]}, +{"id":7,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50007,1]}, +{"id":8,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50008,1]}, +{"id":9,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50009,1]}, +{"id":10,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[50010,1]}, +{"id":11,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50011,1]}, +{"id":12,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50012,1]}, +{"id":13,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50013,1]}, +{"id":14,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[50014,1]}, +{"id":15,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[50015,1]}, +{"id":16,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":17,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":18,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":19,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":20,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[]}, +{"id":21,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":22,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":23,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":24,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":25,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[]}, +{"id":26,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":27,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":28,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":29,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":30,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[]}, +{"id":31,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":32,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":33,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":34,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":35,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[]}, +{"id":36,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":37,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":38,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":39,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":40,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[]}, +{"id":41,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":42,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":43,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":44,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":45,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[]}, +{"id":46,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":47,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":48,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":49,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1],[10,1,1,50,1,1]],"finishRewards":[]}, +{"id":50,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[30,1000,1]],"finishRewards":[]} ] \ No newline at end of file diff --git a/src/ReplicatedStorage/Json/Param.json b/src/ReplicatedStorage/Json/Param.json index 987b3db..4937522 100644 --- a/src/ReplicatedStorage/Json/Param.json +++ b/src/ReplicatedStorage/Json/Param.json @@ -3,5 +3,7 @@ {"id":2,"key":"level_get_bonus","intValue":null,"stringValue":null,"intArray":[5,0]}, {"id":3,"key":"mob_died_get","intValue":null,"stringValue":null,"intArray":[2,4]}, {"id":4,"key":"default_weapon","intValue":null,"stringValue":"Sword","intArray":[]}, -{"id":5,"key":"quality_show","intValue":null,"stringValue":null,"intArray":[101,102,103,104,105,106,107,108]} +{"id":5,"key":"quality_show","intValue":null,"stringValue":null,"intArray":[101,102,103,104,105,106,107,108]}, +{"id":6,"key":"new_player_book_rewards","intValue":null,"stringValue":null,"intArray":[50000,1]}, +{"id":7,"key":"new_player_item_rewards","intValue":null,"stringValue":null,"intArray":[2,10]} ] \ No newline at end of file diff --git a/src/ServerStorage/Proxy/BookProxy.luau b/src/ServerStorage/Proxy/BookProxy.luau index 6d7a335..dcf04ba 100644 --- a/src/ServerStorage/Proxy/BookProxy.luau +++ b/src/ServerStorage/Proxy/BookProxy.luau @@ -12,6 +12,7 @@ local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy) --> Json local JsonItem = require(ReplicatedStorage.Json.ItemProp) local JsonGem = require(ReplicatedStorage.Json.Gem) +local JsonParam = require(ReplicatedStorage.Json.Param) --> Events local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip @@ -39,15 +40,26 @@ function BookProxy:InitPlayer(Player: Player) local BookFolder = Utils:CreateFolder("Book", pData) -- 新玩家数据初始化 + local isNew = false if not ArchiveProxy.pData[Player.UserId][STORE_NAME] then ArchiveProxy.pData[Player.UserId][STORE_NAME] = {} ArchiveProxy.pData[Player.UserId][STORE_NAME].Books = {} + + isNew = true end -- 创建玩家信息实例 for BookId, BookData in ArchiveProxy.pData[Player.UserId][STORE_NAME].Books do Utils:CreateDataInstance(Player, BookId, BookData, BookFolder) end + + if isNew then + local ItemProxy = require(ServerStorage.Proxy.ItemProxy) + local newData = Utils:GetIdDataFromJson(JsonParam, 6) + for i = 1, #newData.intArray, 2 do + ItemProxy:AddItem(Player, newData.intArray[i], newData.intArray[i + 1]) + end + end end -------------------------------------------------------------------------------- diff --git a/src/ServerStorage/Proxy/DamageProxy.luau b/src/ServerStorage/Proxy/DamageProxy.luau index 6c70367..069887a 100644 --- a/src/ServerStorage/Proxy/DamageProxy.luau +++ b/src/ServerStorage/Proxy/DamageProxy.luau @@ -48,6 +48,61 @@ DamageProxy.ElementType = ElementType -------------------------------------------------------------------------------- +-- 对象生命周期管理器 +local LifecycleManager = {} +LifecycleManager.__index = LifecycleManager + +function LifecycleManager.new() + local self = setmetatable({}, LifecycleManager) + self.activeObjects = {} -- 使用弱引用表 + self.objectCallbacks = {} -- 对象销毁时的回调 + return self +end + +function LifecycleManager:RegisterObject(obj, onDestroy) + if not obj then return end + + -- 使用弱引用存储对象 + self.activeObjects[obj] = true + self.objectCallbacks[obj] = onDestroy + + -- 监听对象销毁 + if obj.Instance then + obj.Instance.AncestryChanged:Connect(function(_, parent) + if not parent then + self:OnObjectDestroyed(obj) + end + end) + end +end + +function LifecycleManager:OnObjectDestroyed(obj) + if self.objectCallbacks[obj] then + self.objectCallbacks[obj](obj) + self.objectCallbacks[obj] = nil + end + self.activeObjects[obj] = nil +end + +function LifecycleManager:IsObjectValid(obj) + return self.activeObjects[obj] and obj.Instance and obj.Instance.Parent +end + +function LifecycleManager:GetValidObjects(objects) + local validObjects = {} + for _, obj in pairs(objects) do + if self:IsObjectValid(obj) then + table.insert(validObjects, obj) + end + end + return validObjects +end + +-- 创建全局生命周期管理器 +local globalLifecycleManager = LifecycleManager.new() + +-------------------------------------------------------------------------------- + function DamageProxy:GetHumanoid(Target: Model) if not Target:IsA("Model") then warn("Target is not a Model") @@ -66,12 +121,31 @@ function DamageProxy:IsDied(Target: Model) return Humanoid:GetAttribute("hp") <= 0 end --- 获取范围内敌人 +-- 获取范围内敌人(改进版本) function DamageProxy:GetAoeEnemies(Caster: TypeList.Character, Position: Vector3, Radius: number) + -- 基础参数验证 + if not Caster or not Position or not Radius or Radius <= 0 then + return {} + end + local Enemies = {} local MobsProxy = require(ServerStorage.Proxy.MobsProxy) - for _, enemy in pairs(MobsProxy:GetPlayerMobs(Caster.Player)) do - if enemy ~= Caster and enemy.Instance then + + -- 获取所有敌人并注册到生命周期管理器 + local allEnemies = MobsProxy:GetPlayerMobs(Caster.Player) or {} + for _, enemy in pairs(allEnemies) do + if enemy and enemy ~= Caster then + globalLifecycleManager:RegisterObject(enemy, function(destroyedObj) + -- 对象销毁时的回调 + print("敌人对象被销毁:", destroyedObj) + end) + end + end + + -- 只处理有效的敌人 + local validEnemies = globalLifecycleManager:GetValidObjects(allEnemies) + for _, enemy in pairs(validEnemies) do + if enemy ~= Caster then local enemy_pos = enemy.Instance:GetPivot().Position if (enemy_pos - Position).Magnitude <= Radius then table.insert(Enemies, enemy) @@ -81,8 +155,14 @@ function DamageProxy:GetAoeEnemies(Caster: TypeList.Character, Position: Vector3 return Enemies end --- 弹道伤害 +-- 弹道伤害(改进版本) function DamageProxy:CastFreeProjectile(Caster: TypeList.Character, StartPos: Vector3, EndPos: Vector3, Duration: number, Range: number, OnHit: (Target: TypeList.Character) -> (boolean?)) + -- 参数验证 + if not Caster or not StartPos or not EndPos or not Duration or Duration <= 0 or not Range or Range <= 0 then + warn("CastFreeProjectile: 参数无效") + return + end + local projectileTask = nil local step_time = 0.05 -- 每帧检测间隔 local elapsed = 0 @@ -100,20 +180,37 @@ function DamageProxy:CastFreeProjectile(Caster: TypeList.Character, StartPos: Ve end end + -- 注册施法者到生命周期管理器 + globalLifecycleManager:RegisterObject(Caster, function() + cancelTask() -- 施法者被销毁时取消弹道 + end) + projectileTask = task.spawn(function() while elapsed < Duration and not cancelled do + -- 检查施法者是否仍然有效 + if not globalLifecycleManager:IsObjectValid(Caster) then + break + end + -- 计算当前位置 current_pos = StartPos + direction * speed * elapsed + -- 检测范围内敌人 local MobsProxy = require(ServerStorage.Proxy.MobsProxy) - for _, enemy in pairs(MobsProxy:GetPlayerMobs(Caster.Player)) do - if enemy ~= Caster and enemy.Instance then + local allEnemies = MobsProxy:GetPlayerMobs(Caster.Player) or {} + local validEnemies = globalLifecycleManager:GetValidObjects(allEnemies) + + for _, enemy in pairs(validEnemies) do + if enemy ~= Caster then local enemy_pos = enemy.Instance:GetPivot().Position if (enemy_pos - current_pos).Magnitude <= Range then if not hit_targets[enemy] then hit_targets[enemy] = true local stop = OnHit(enemy) - if stop then cancelTask() break end + if stop then + cancelTask() + break + end end end end @@ -124,8 +221,24 @@ function DamageProxy:CastFreeProjectile(Caster: TypeList.Character, StartPos: Ve end) end - +-- 伤害处理(改进版本) function DamageProxy:TakeDamage(Caster: TypeList.Character, Victim: TypeList.Character, DamageInfos: {DamageInfo}) + -- 基础参数验证 + if not Caster or not Victim or not DamageInfos or #DamageInfos == 0 then + warn("TakeDamage: 基础参数无效") + return + end + + -- 注册对象到生命周期管理器 + globalLifecycleManager:RegisterObject(Caster) + globalLifecycleManager:RegisterObject(Victim) + + -- 检查对象是否仍然有效 + if not globalLifecycleManager:IsObjectValid(Caster) or not globalLifecycleManager:IsObjectValid(Victim) then + warn("TakeDamage: 施法者或受害者已被销毁") + return + end + -- 给前端发送伤害信息 local clientDamageInfos = {} clientDamageInfos.Caster = Caster.Instance @@ -135,23 +248,31 @@ function DamageProxy:TakeDamage(Caster: TypeList.Character, Victim: TypeList.Cha clientDamageInfos.DamageInfos = Utils:DeepCopyTable(DamageInfos) for _, DamageInfo in DamageInfos do - if not Victim then continue end - -- if not Victim.Parent then continue end + -- 检查受害者是否仍然有效 + if not globalLifecycleManager:IsObjectValid(Victim) then + warn("TakeDamage: 受害者在处理过程中被销毁") + break + end - local Damage = DamageInfo.Damage + local Damage = DamageInfo.Damage or 0 local DamageType = DamageInfo.DamageType local DamageTag = DamageInfo.DamageTag local ElementType = DamageInfo.ElementType -- 伤害计算 - local VictimHealth = Victim:GetAttributeValue("hp") + local VictimHealth = Victim:GetAttributeValue("hp") or 0 local resultValue, isDied = Victim:ChangeAttributeValue("hp", math.max(0, VictimHealth - Damage)) - -- print("伤害数据打印", Damage, VictimHealth, resultValue, isDied) if isDied then break end end - -- 实际发送数据 - Communicate:SendToClient(RE_DamagePerformance, "Damage", Caster.Player, clientDamageInfos) + + -- 发送数据到客户端 + local success, error = pcall(function() + Communicate:SendToClient(RE_DamagePerformance, "Damage", Caster.Player, clientDamageInfos) + end) + + if not success then + warn("TakeDamage: 发送伤害数据失败:", error) + end end - return DamageProxy \ No newline at end of file diff --git a/src/ServerStorage/Proxy/LevelProxy.luau b/src/ServerStorage/Proxy/LevelProxy.luau index ef6e15b..d753fa3 100644 --- a/src/ServerStorage/Proxy/LevelProxy.luau +++ b/src/ServerStorage/Proxy/LevelProxy.luau @@ -36,6 +36,7 @@ local ENUM_LEVEL_TYPE = { -- 初始化生成关卡目录 local LevelFolder = Utils:CreateFolder(STORE_NAME, game.Workspace) +local SpawnLocation = game.Workspace:WaitForChild("SpawnLocation") -------------------------------------------------------------------------------- @@ -66,9 +67,12 @@ local function CreateLevelInstance(Player: Player, Folder: Instance, LevelKey: s InstanceType = "BoolValue" elseif type(LevelValue) == "string" then InstanceType = "StringValue" + elseif type(LevelValue) == "vector" then + InstanceType = "Vector3Value" else InstanceType = "NumberValue" end + local LevelInstance = Instance.new(InstanceType) LevelInstance.Name = LevelKey LevelInstance.Parent = Folder @@ -174,6 +178,7 @@ function LevelProxy:InitPlayer(Player: Player) LevelProxy.pData[Player.UserId].ShouldWave = 0 LevelProxy.pData[Player.UserId].SpawnWaveFinish = false LevelProxy.pData[Player.UserId].Mobs = {} + LevelProxy.pData[Player.UserId].LevelPosition = Vector3.new(0, 0, 30) -- 关卡挑战信息前端 for key, value in LevelProxy.pData[Player.UserId] do @@ -218,7 +223,7 @@ function LevelProxy:ChallengeLevel(Player: Player, LevelId: number) local mobCount = waveData[i + 2] for _ = 1, mobCount do print("怪物增益", LevelData.atkBonus, LevelData.hpBonus) - local mob = MobsProxy:CreateMob(Player, mobId, LevelData.atkBonus, LevelData.hpBonus, OnMobDied) + local mob = MobsProxy:CreateMob(Player, mobId, LevelProxy.pData[Player.UserId].LevelPosition, LevelData.atkBonus, LevelData.hpBonus, OnMobDied) table.insert(LevelProxy.pData[Player.UserId].Mobs, mob) end end @@ -300,6 +305,18 @@ function LevelProxy:GetLevelGetBonus(Player: Player) return level_get_bonus["intArray"][1] + (level - 1) * level_get_bonus["intArray"][2] end +-- 传送到关卡 +function LevelProxy:TeleportToLevel(Player: Player) + local LevelPosition = LevelProxy.pData[Player.UserId].LevelPosition + Vector3.new(0, 3, 0) + Player.Character.HumanoidRootPart.CFrame = CFrame.new(LevelPosition) +end + +-- 传送到城镇 +function LevelProxy:TeleportToTown(Player: Player) + local TownPosition = SpawnLocation.Position + Vector3.new(0, 3, 0) + Player.Character.HumanoidRootPart.CFrame = CFrame.new(TownPosition) +end + function LevelProxy:OnPlayerRemoving(Player: Player) -- 关卡文件夹清除 local PlayerLevelFolder = GetPlayerLevelWorkspaceFolder(Player.UserId) diff --git a/src/ServerStorage/Proxy/MobsProxy/init.luau b/src/ServerStorage/Proxy/MobsProxy/init.luau index 458ff6b..77021e2 100644 --- a/src/ServerStorage/Proxy/MobsProxy/init.luau +++ b/src/ServerStorage/Proxy/MobsProxy/init.luau @@ -41,7 +41,7 @@ local Mob = {} Mob.__index = Mob setmetatable(Mob, {__index = Character}) -function Mob.new(Player: Player, MobId: number, OnMobDied: ((Player: Player, Mob: TypeList.Character) -> ())?) +function Mob.new(Player: Player, MobId: number, Position: Vector3, OnMobDied: ((Player: Player, Mob: TypeList.Character) -> ())?) -- 获取玩家怪物目录 local playerMobsFolder = GetPlayerMobsFolder(Player) if not playerMobsFolder then return end @@ -56,6 +56,7 @@ function Mob.new(Player: Player, MobId: number, OnMobDied: ((Player: Player, Mob -- 克隆怪物模型 local newMobModel = MobInstance:Clone() + newMobModel.PrimaryPart.CFrame = CFrame.new(Position) -- 调用父类Character的new方法,初始化通用属性 local self = Character.new(Player, newMobModel, MobData) @@ -93,8 +94,8 @@ end -------------------------------------------------------------------------------- -- 给玩家创建怪物 -function MobsProxy:CreateMob(Player: Player, MobId: number, AtkBonus: number?, HpBonus: number?, OnMobDied: ((Player: Player, Mob: TypeList.Character) -> ())?) - local Mob = Mob.new(Player, MobId, OnMobDied) +function MobsProxy:CreateMob(Player: Player, MobId: number, Position: Vector3, AtkBonus: number?, HpBonus: number?, OnMobDied: ((Player: Player, Mob: TypeList.Character) -> ())?) + local Mob = Mob.new(Player, MobId, Position, OnMobDied) AI:StartTracking(Mob) -- 关卡系数 if AtkBonus then Mob:ChangeAttributeValue("attack", math.floor(Mob.Config.attack * (AtkBonus / 1000))) end diff --git a/src/ServerStorage/Proxy/PlayerFightProxy/LevelLoop.luau b/src/ServerStorage/Proxy/PlayerFightProxy/LevelLoop.luau index fd2c4bd..f7deabd 100644 --- a/src/ServerStorage/Proxy/PlayerFightProxy/LevelLoop.luau +++ b/src/ServerStorage/Proxy/PlayerFightProxy/LevelLoop.luau @@ -18,7 +18,6 @@ local Utils = require(ReplicatedStorage.Tools.Utils) local JsonLevel = require(ReplicatedStorage.Json.Level) --> Constants -local SpawnLocation = game.Workspace:WaitForChild("SpawnLocation") local ChallengeLocation -------------------------------------------------------------------------------- @@ -32,7 +31,7 @@ function LevelLoop.new(Player: Player, PlayerRole: TypeList.Character) self.Player = Player self.PlayerRole = PlayerRole self.TaskAutoChallenge = nil - self.AutoChallenge = false + self.IsAutoChallenge = false self.ConChallengeEnd = BD_ChallengeEnd.Event:Connect(function(Player: Player, LevelId: number) if Player ~= self.Player then return end @@ -53,21 +52,21 @@ end -- 手动挑战关卡 function LevelLoop:OnChallengeLevel(isStart: boolean) - self.AutoChallenge = isStart + self.IsAutoChallenge = isStart if isStart then self:AutoChallenge() else - -- TODO: 传送回城镇 - + LevelProxy:TeleportToTown(self.Player) LevelProxy:ChallengeEnd(self.Player, false) + self.PlayerRole:Recover() end end function LevelLoop:AutoChallenge(ignoreBoss: boolean?) - if not self.AutoChallenge then return end + if not self.IsAutoChallenge then return end print("AutoChallenge") - -- TODO: 传送到关卡起点 + LevelProxy:TeleportToLevel(self.Player) -- TODO: 回退有bug,不能一关一关回退 @@ -87,7 +86,7 @@ function LevelLoop:AutoChallenge(ignoreBoss: boolean?) end function LevelLoop:OnChallengeEnd(Player: Player, LevelId: number, result: boolean) - if not self.AutoChallenge then return end + if not self.IsAutoChallenge then return end if self.ChallengeBoss then self.ChallengeBoss = nil return end self.TaskAutoChallenge = task.spawn(function() task.wait(3) diff --git a/src/ServerStorage/Proxy/PlayerFightProxy/PlayerAI.luau b/src/ServerStorage/Proxy/PlayerFightProxy/PlayerAI.luau index 8304845..4544910 100644 --- a/src/ServerStorage/Proxy/PlayerFightProxy/PlayerAI.luau +++ b/src/ServerStorage/Proxy/PlayerFightProxy/PlayerAI.luau @@ -71,6 +71,11 @@ function PlayerAI.new(Player: Player, PlayerRole: TypeList.Character) self.ExecutingState = false end end) + -- task.spawn(function() + -- while task.wait(0.25) do + -- print(self) + -- end + -- end) return self end diff --git a/src/ServerStorage/Proxy/PlayerFightProxy/init.luau b/src/ServerStorage/Proxy/PlayerFightProxy/init.luau index 2c016b3..89d95bc 100644 --- a/src/ServerStorage/Proxy/PlayerFightProxy/init.luau +++ b/src/ServerStorage/Proxy/PlayerFightProxy/init.luau @@ -76,11 +76,17 @@ function PlayerRole:Respawn() self:ChangeState("Died", false) self.Humanoid.WalkSpeed = self.Config.walkSpeed self:ChangeAttributeValue("hp", self.Config.maxhp) - -- TODO: 重置玩家位置 + -- 重置玩家关卡位置 + LevelProxy:TeleportToLevel(self.Player) PlayerFightProxy:UpdatePlayerFightData(self.Player) end +function PlayerRole:Recover() + self:ChangeState("Died", false) + self:ChangeAttributeValue("hp", self.Config.maxhp) +end + -------------------------------------------------------------------------------- function PlayerFightProxy:InitPlayer(Player: Player) diff --git a/src/ServerStorage/Proxy/PlayerInfoProxy.luau b/src/ServerStorage/Proxy/PlayerInfoProxy.luau index f8a402e..7bcda75 100644 --- a/src/ServerStorage/Proxy/PlayerInfoProxy.luau +++ b/src/ServerStorage/Proxy/PlayerInfoProxy.luau @@ -15,6 +15,7 @@ local JsonLvUpgrade = require(ReplicatedStorage.Json.LvUpgrade) local JsonItem = require(ReplicatedStorage.Json.ItemProp) local JsonAttributesUpgrade = require(ReplicatedStorage.Json.AttributesUpgrade) local JsonForge = require(ReplicatedStorage.Json.Forge) +local JsonParam = require(ReplicatedStorage.Json.Param) --> Events local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip @@ -99,6 +100,11 @@ function PlayerInfoProxy:InitPlayer(Player: Player) ArchiveProxy.pData[Player.UserId][STORE_NAME].Stats = {} ArchiveProxy.pData[Player.UserId][STORE_NAME].Items = {} ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade = {} + + local newData = Utils:GetIdDataFromJson(JsonParam, 7) + for i = 1, #newData.intArray, 2 do + ArchiveProxy.pData[Player.UserId][STORE_NAME].Items[newData.intArray[i]] = newData.intArray[i + 1] + end end -- 放在外面是为了以后系统新增内容方便(同时不用在初始化数据是做写入了) diff --git a/src/StarterPlayerScripts/UI/UIManager.luau b/src/StarterPlayerScripts/UI/UIManager.luau index 708b3f0..19365f2 100644 --- a/src/StarterPlayerScripts/UI/UIManager.luau +++ b/src/StarterPlayerScripts/UI/UIManager.luau @@ -8,6 +8,7 @@ UIManager.WindowStack = {} -- 窗口堆栈 UIManager.ExcludeFromStack = { -- 不受堆栈影响的窗口列表 "TipsWindow", -- 主窗口 "AbilityStateWindow", + "LevelStageWindow", -- 可以继续添加其他窗口名称 } diff --git a/src/StarterPlayerScripts/UI/Windows/LevelStageWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/LevelStageWindow/init.luau new file mode 100644 index 0000000..4b61188 --- /dev/null +++ b/src/StarterPlayerScripts/UI/Windows/LevelStageWindow/init.luau @@ -0,0 +1,121 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") + +--> Dependencies +local UIWindow = require(ReplicatedStorage.Base.UIWindow) +local UIEnums = require(ReplicatedStorage.Base.UIEnums) +local Signal = require(ReplicatedStorage.Tools.Signal) + +--> Json +local JsonLevel = require(ReplicatedStorage.Json.Level) +local JsonForge = require(ReplicatedStorage.Json.Forge) + +local Utils = require(ReplicatedStorage.Tools.Utils) + +--> Events +local RE_ChallengeBoss = ReplicatedStorage.Events.RE_ChallengeBoss +local RE_ChallengeLevel = ReplicatedStorage.Events.RE_ChallengeLevel + +local LocalPlayer = game:GetService("Players").LocalPlayer +local challengeLevelEndSignal = Signal.new(Signal.ENUM.CHALLENGE_LEVEL_END) + +-------------------------------------------------------------------------------- + +local LevelStageWindow = {} +LevelStageWindow.__index = LevelStageWindow +setmetatable(LevelStageWindow, {__index = UIWindow}) + +function LevelStageWindow:Init(UIManager: table, Data: table?) + local self = UIWindow:Init(UIManager, Data) + setmetatable(self, LevelStageWindow) + self.Variables = { + ["_btnStopChallenge"] = 0, + + -- 关卡 + ["_tmpNowLevel"] = 0, + ["_imgBoss"] = 0, + ["_btnChallengeBoss"] = 0, + } + self.UIRootName = "ui_w_level_stage" + self.UIParentName = UIEnums.UIParent.UIRoot + + return self +end + +-- 设置关卡显示 +function LevelStageWindow:SetShowLevel(level: number) + self.Variables["_tmpNowLevel"].Text = string.format("第%d关", level) + local levelData = Utils:GetIdDataFromJson(JsonLevel, level) + if levelData.type == 2 then + self.Variables["_imgBoss"].Visible = true + else + self.Variables["_imgBoss"].Visible = false + end +end + +-- 设置boss挑战按钮显示 +function LevelStageWindow:SetShowBossChallenge(newValue: number) + local playerDataFolder = game.Workspace:WaitForChild("Level"):WaitForChild(LocalPlayer.UserId) + local ProgressFolder = playerDataFolder:WaitForChild("Progress") + local mainValue = ProgressFolder:FindFirstChild("Main").Value + local levelIdValue = playerDataFolder:WaitForChild("Challenge"):WaitForChild("LevelId").Value + + if levelIdValue == mainValue then + self.Variables["_btnChallengeBoss"].Visible = false + else + self.Variables["_btnChallengeBoss"].Visible = (newValue == mainValue) + end +end + +-- 手动点击按钮,挑战boss +function LevelStageWindow:OnClickChallengeBoss() + RE_ChallengeBoss:FireServer() + self.Variables["_btnChallengeBoss"].Visible = false +end + +function LevelStageWindow:OnClickChallengeButton() + challengeLevelEndSignal:Fire(false) + -- TODO: 之后这里做临时传送特效,可以打断,要不就独立个脚本,用signal触发对应特效 + -- task.wait(2) + RE_ChallengeLevel:FireServer(false) + self.UIManager:CloseWindow(script.Name) +end + +function LevelStageWindow:OnOpenWindow() + UIWindow.OnOpenWindow(self) + + local challengeBossCon = self.Variables["_btnChallengeBoss"].Activated:Connect(function() + self:OnClickChallengeBoss() + end) + local stopChallengeCon = self.Variables["_btnStopChallenge"].Activated:Connect(function() + self:OnClickChallengeButton(false) + end) + + table.insert(self.Connections, challengeBossCon) + table.insert(self.Connections, stopChallengeCon) + + -- TODO: 暂时用主关卡数显示,我记得之前这里主要是记录的,Challenge中才是正在挑战的内容 + -- TODO: 之后LevelProxy也应该挪到ReplicatedStorage下,之前可能是因为觉得Challenge是临时的内容所以放在workspace下,但是逻辑做的不统一 + local playerDataFolder = game.Workspace:WaitForChild("Level"):WaitForChild(LocalPlayer.UserId) + local StatsFolder = playerDataFolder:WaitForChild("Challenge") + local ProgressFolder = playerDataFolder:WaitForChild("Progress") + + local levelCon = StatsFolder.LevelId.Changed:Connect(function(newValue) + self:SetShowLevel(newValue) + self:SetShowBossChallenge(ProgressFolder.BossFail.Value) + end) + local bossChallengeCon = ProgressFolder.BossFail.Changed:Connect(function(newValue) + self:SetShowBossChallenge(newValue) + end) + + -- 初始值设置 + if StatsFolder.LevelId.Value ~= 0 then + self:SetShowLevel(StatsFolder.LevelId.Value) + end + self:SetShowBossChallenge(ProgressFolder.BossFail.Value) + + table.insert(self.Connections, levelCon) + table.insert(self.Connections, bossChallengeCon) +end + +return LevelStageWindow \ No newline at end of file diff --git a/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau index 7219843..3978378 100644 --- a/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau +++ b/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau @@ -4,6 +4,7 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") --> Dependencies local UIWindow = require(ReplicatedStorage.Base.UIWindow) local UIEnums = require(ReplicatedStorage.Base.UIEnums) +local Signal = require(ReplicatedStorage.Tools.Signal) --> Json local JsonLevel = require(ReplicatedStorage.Json.Level) @@ -11,11 +12,15 @@ local JsonForge = require(ReplicatedStorage.Json.Forge) local Utils = require(ReplicatedStorage.Tools.Utils) + --> Events local RE_ChallengeBoss = ReplicatedStorage.Events.RE_ChallengeBoss local RE_ChallengeLevel = ReplicatedStorage.Events.RE_ChallengeLevel +--> Local local LocalPlayer = game:GetService("Players").LocalPlayer +local forgeRedPointSignal = Signal.new(Signal.ENUM.FORGE_RED_POINT) +local challengeLevelEndSignal = Signal.new(Signal.ENUM.CHALLENGE_LEVEL_END) -------------------------------------------------------------------------------- @@ -81,14 +86,8 @@ function MainWindow:Init(UIManager: table, Data: table?) ["_btnMainCreate"] = 0, ["_btnMainCha"] = 0, ["_btnMainAttributeUpgrade"] = 0, - ["_btnStopChallenge"] = 0, ["_btnStartChallenge"] = 0, - -- 关卡 - ["_tmpNowLevel"] = 0, - ["_imgBoss"] = 0, - ["_btnChallengeBoss"] = 0, - -- 锻造条 ["_goForgeBar"] = 0, ["_goForgeFill"] = 0, @@ -104,35 +103,12 @@ function MainWindow:Init(UIManager: table, Data: table?) return self end --- 设置关卡显示 -function MainWindow:SetShowLevel(level: number) - self.Variables["_tmpNowLevel"].Text = string.format("第%d关", level) - local levelData = Utils:GetIdDataFromJson(JsonLevel, level) - if levelData.type == 2 then - self.Variables["_imgBoss"].Visible = true - else - self.Variables["_imgBoss"].Visible = false - end -end - --- 设置boss挑战按钮显示 -function MainWindow:SetShowBossChallenge(newValue: number) - local playerDataFolder = game.Workspace:WaitForChild("Level"):WaitForChild(LocalPlayer.UserId) - local ProgressFolder = playerDataFolder:WaitForChild("Progress") - local mainValue = ProgressFolder:FindFirstChild("Main").Value - local levelIdValue = playerDataFolder:WaitForChild("Challenge"):WaitForChild("LevelId").Value - - if levelIdValue == mainValue then - self.Variables["_btnChallengeBoss"].Visible = false - else - self.Variables["_btnChallengeBoss"].Visible = (newValue == mainValue) - end -end - --- 手动点击按钮,挑战boss -function MainWindow:OnClickChallengeBoss() - RE_ChallengeBoss:FireServer() - self.Variables["_btnChallengeBoss"].Visible = false +function MainWindow:OnClickChallengeButton() + self.Variables["_btnStartChallenge"].Visible = false + -- TODO: 之后这里做临时传送特效,可以打断,要不就独立个脚本,用signal触发对应特效 + task.wait(2) + RE_ChallengeLevel:FireServer(true) + self.UIManager:OpenWindow("LevelStageWindow") end function MainWindow:SetShowForgeBar(nowForgeTime : number, moneyValue: number) @@ -160,18 +136,6 @@ function MainWindow:SetShowForgeBar(nowForgeTime : number, moneyValue: number) end end -function MainWindow:OnClickChallengeButton(isStart: boolean) - if isStart then - RE_ChallengeLevel:FireServer(true) - self.Variables["_btnStartChallenge"].Visible = false - self.Variables["_btnStopChallenge"].Visible = true - else - RE_ChallengeLevel:FireServer(false) - self.Variables["_btnStartChallenge"].Visible = true - self.Variables["_btnStopChallenge"].Visible = false - end -end - function MainWindow:OnOpenWindow() UIWindow.OnOpenWindow(self) @@ -184,47 +148,28 @@ function MainWindow:OnOpenWindow() local attributeUpgradeCon = self.Variables["_btnMainAttributeUpgrade"].Activated:Connect(function() self.UIManager:OpenWindow("AttributeLvupWindow") end) - local challengeBossCon = self.Variables["_btnChallengeBoss"].Activated:Connect(function() - self:OnClickChallengeBoss() - end) - local stopChallengeCon = self.Variables["_btnStopChallenge"].Activated:Connect(function() - self:OnClickChallengeButton(false) - end) local startChallengeCon = self.Variables["_btnStartChallenge"].Activated:Connect(function() - self:OnClickChallengeButton(true) + self:OnClickChallengeButton() end) table.insert(self.Connections, createCon) table.insert(self.Connections, chaCon) table.insert(self.Connections, attributeUpgradeCon) - table.insert(self.Connections, challengeBossCon) - table.insert(self.Connections, stopChallengeCon) table.insert(self.Connections, startChallengeCon) - - -- TODO: 暂时用主关卡数显示,我记得之前这里主要是记录的,Challenge中才是正在挑战的内容 - -- TODO: 之后LevelProxy也应该挪到ReplicatedStorage下,之前可能是因为觉得Challenge是临时的内容所以放在workspace下,但是逻辑做的不统一 - local playerDataFolder = game.Workspace:WaitForChild("Level"):WaitForChild(LocalPlayer.UserId) - local StatsFolder = playerDataFolder:WaitForChild("Challenge") - local ProgressFolder = playerDataFolder:WaitForChild("Progress") - local levelCon = StatsFolder.LevelId.Changed:Connect(function(newValue) - self:SetShowLevel(newValue) - self:SetShowBossChallenge(ProgressFolder.BossFail.Value) + local forgeRedPointCon = forgeRedPointSignal:Connect(function(show: boolean) + self.Variables["_tmpRedCreate"].Visible = show end) - local bossChallengeCon = ProgressFolder.BossFail.Changed:Connect(function(newValue) - self:SetShowBossChallenge(newValue) + table.insert(self.Connections, forgeRedPointCon) + + local challengeLevelEndCon = challengeLevelEndSignal:Connect(function(result: boolean) + self.Variables["_btnStartChallenge"].Visible = true end) - - -- 初始值设置 - self:SetShowLevel(StatsFolder.LevelId.Value) - self:SetShowBossChallenge(ProgressFolder.BossFail.Value) - - table.insert(self.Connections, levelCon) - table.insert(self.Connections, bossChallengeCon) - + table.insert(self.Connections, challengeLevelEndCon) + -- 货币进度条显示 - local rePlayerDataFolder = Utils:GetPlayerDataFolder(LocalPlayer) + local rePlayerDataFolder = Utils:WaitPlayerDataFolder(LocalPlayer) local playerInfoFolder = rePlayerDataFolder:WaitForChild("PlayerInfo") local forgeInstance = playerInfoFolder:WaitForChild("Stats"):WaitForChild("forge")