130 子 【战斗】战斗系统 / 【战斗】战斗系统-客户端 部分战斗逻辑
| | |
| | | isLoadFinished = false;
|
| | |
|
| | | // 加载配置文件
|
| | | int totalConfigs = 63;
|
| | | int totalConfigs = 65;
|
| | | Type[] configTypes = new Type[] {
|
| | | typeof(AppointItemConfig),
|
| | | typeof(AudioConfig),
|
| | |
| | | typeof(OrderInfoConfig),
|
| | | typeof(PlayerFaceConfig),
|
| | | typeof(PlayerFacePicConfig),
|
| | | typeof(PlayerFacePicStarConfig),
|
| | | typeof(PlayerFaceStarConfig),
|
| | | typeof(PlayerLVConfig),
|
| | | typeof(PlayerPropertyConfig),
|
| | | typeof(priorbundleConfig),
|
| | |
| | | ClearConfigDictionary<PlayerFaceConfig>();
|
| | | // 清空 PlayerFacePicConfig 字典
|
| | | ClearConfigDictionary<PlayerFacePicConfig>();
|
| | | // 清空 PlayerFacePicStarConfig 字典
|
| | | ClearConfigDictionary<PlayerFacePicStarConfig>();
|
| | | // 清空 PlayerFaceStarConfig 字典
|
| | | ClearConfigDictionary<PlayerFaceStarConfig>();
|
| | | // 清空 PlayerLVConfig 字典
|
| | | ClearConfigDictionary<PlayerLVConfig>();
|
| | | // 清空 PlayerPropertyConfig 字典
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月18日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月18日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月18日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月18日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: Tuesday, June 17, 2025
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月17日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月17日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: Wednesday, June 18, 2025
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月18日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月15日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月13日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月13日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月16日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | public int HPInheritPer; |
| | | public string BatAttrDict; |
| | | public int[] FetterIDList; |
| | | public string Tachie; |
| | | public string SquareIcon; |
| | | public string RectangleIcon; |
| | | public string SpineRes; |
| | | public string BigSizeSpine; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | |
| | | int.TryParse(FetterIDListStringArray[i],out FetterIDList[i]); |
| | | } |
| | | } |
| | | |
| | | Tachie = tables[11]; |
| | | |
| | | SquareIcon = tables[12]; |
| | | |
| | | RectangleIcon = tables[13]; |
| | | |
| | | SpineRes = tables[14]; |
| | | |
| | | BigSizeSpine = tables[15]; |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月16日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月13日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月13日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月13日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月13日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年6月13日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Threading; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class PlayerFacePicStarConfig : ConfigBase<int, PlayerFacePicStarConfig> |
| | | { |
| | | |
| | | public int index; |
| | | public int FacePicID; |
| | | public int FacePicStar; |
| | | public int[][] StarUpNeedItemList; |
| | | public int[] StarAttrType; |
| | | public int[] StarAttrValue; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | | int key = GetKey(_key); |
| | | return key; |
| | | } |
| | | |
| | | public override void LoadConfig(string input) |
| | | { |
| | | try { |
| | | string[] tables = input.Split('\t'); |
| | | int.TryParse(tables[0],out index); |
| | | |
| | | int.TryParse(tables[1],out FacePicID); |
| | | |
| | | int.TryParse(tables[2],out FacePicStar); |
| | | |
| | | StarUpNeedItemList = JsonMapper.ToObject<int[][]>(tables[3].Replace("(", "[").Replace(")", "]")); |
| | | |
| | | if (tables[4].Contains("[")) |
| | | { |
| | | StarAttrType = JsonMapper.ToObject<int[]>(tables[4]); |
| | | } |
| | | else |
| | | { |
| | | string[] StarAttrTypeStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | StarAttrType = new int[StarAttrTypeStringArray.Length]; |
| | | for (int i=0;i<StarAttrTypeStringArray.Length;i++) |
| | | { |
| | | int.TryParse(StarAttrTypeStringArray[i],out StarAttrType[i]); |
| | | } |
| | | } |
| | | |
| | | if (tables[5].Contains("[")) |
| | | { |
| | | StarAttrValue = JsonMapper.ToObject<int[]>(tables[5]); |
| | | } |
| | | else |
| | | { |
| | | string[] StarAttrValueStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | StarAttrValue = new int[StarAttrValueStringArray.Length]; |
| | | for (int i=0;i<StarAttrValueStringArray.Length;i++) |
| | | { |
| | | int.TryParse(StarAttrValueStringArray[i],out StarAttrValue[i]); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | | Debug.LogError(exception); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 71543467d1c8a4544b1e0441440327cb |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Threading; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class PlayerFaceStarConfig : ConfigBase<int, PlayerFaceStarConfig> |
| | | { |
| | | |
| | | public int index; |
| | | public int FaceID; |
| | | public int FaceStar; |
| | | public int[][] StarUpNeedItemList; |
| | | public int[] StarAttrType; |
| | | public int[] StarAttrValue; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | | int key = GetKey(_key); |
| | | return key; |
| | | } |
| | | |
| | | public override void LoadConfig(string input) |
| | | { |
| | | try { |
| | | string[] tables = input.Split('\t'); |
| | | int.TryParse(tables[0],out index); |
| | | |
| | | int.TryParse(tables[1],out FaceID); |
| | | |
| | | int.TryParse(tables[2],out FaceStar); |
| | | |
| | | StarUpNeedItemList = JsonMapper.ToObject<int[][]>(tables[3].Replace("(", "[").Replace(")", "]")); |
| | | |
| | | if (tables[4].Contains("[")) |
| | | { |
| | | StarAttrType = JsonMapper.ToObject<int[]>(tables[4]); |
| | | } |
| | | else |
| | | { |
| | | string[] StarAttrTypeStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | StarAttrType = new int[StarAttrTypeStringArray.Length]; |
| | | for (int i=0;i<StarAttrTypeStringArray.Length;i++) |
| | | { |
| | | int.TryParse(StarAttrTypeStringArray[i],out StarAttrType[i]); |
| | | } |
| | | } |
| | | |
| | | if (tables[5].Contains("[")) |
| | | { |
| | | StarAttrValue = JsonMapper.ToObject<int[]>(tables[5]); |
| | | } |
| | | else |
| | | { |
| | | string[] StarAttrValueStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | StarAttrValue = new int[StarAttrValueStringArray.Length]; |
| | | for (int i=0;i<StarAttrValueStringArray.Length;i++) |
| | | { |
| | | int.TryParse(StarAttrValueStringArray[i],out StarAttrValue[i]); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | | Debug.LogError(exception); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: ccdffb3c82145e64cb12c26fccdfa818 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月25日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月17日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月25日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月25日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | public int ExAttr3; |
| | | public int ExAttr4; |
| | | public int ExAttr5; |
| | | public int WarnInfo; |
| | | public int CtrlActionID; |
| | | public int BuffEffectID; |
| | | public int EffectName; |
| | | public string IconName; |
| | | public string SkillNameIcon; |
| | | public string Description; |
| | | public string BuffDescription; |
| | | public string Skillsource; |
| | | public int Skillactmark; |
| | | public int BuffDisplay; |
| | | public int CastPosition; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | |
| | | |
| | | int.TryParse(tables[66],out ExAttr5); |
| | | |
| | | int.TryParse(tables[67],out WarnInfo); |
| | | int.TryParse(tables[67],out BuffEffectID); |
| | | |
| | | int.TryParse(tables[68],out CtrlActionID); |
| | | int.TryParse(tables[68],out EffectName); |
| | | |
| | | int.TryParse(tables[69],out BuffEffectID); |
| | | IconName = tables[69]; |
| | | |
| | | int.TryParse(tables[70],out EffectName); |
| | | Description = tables[70]; |
| | | |
| | | IconName = tables[71]; |
| | | BuffDescription = tables[71]; |
| | | |
| | | SkillNameIcon = tables[72]; |
| | | int.TryParse(tables[72],out Skillactmark); |
| | | |
| | | Description = tables[73]; |
| | | int.TryParse(tables[73],out BuffDisplay); |
| | | |
| | | BuffDescription = tables[74]; |
| | | |
| | | Skillsource = tables[75]; |
| | | |
| | | int.TryParse(tables[76],out Skillactmark); |
| | | |
| | | int.TryParse(tables[77],out BuffDisplay); |
| | | int.TryParse(tables[74],out CastPosition); |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月26日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月17日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月17日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | public partial class TreasureItemLibConfig : ConfigBase<int, TreasureItemLibConfig>
|
| | | {
|
| | |
|
| | | public int LibID;
|
| | | public int ID;
|
| | | public int LibID;
|
| | | public int ItemID;
|
| | | public int ItemCount;
|
| | |
|
| | |
| | | {
|
| | | try {
|
| | | string[] tables = input.Split('\t');
|
| | | int.TryParse(tables[0],out LibID); |
| | | int.TryParse(tables[0],out ID); |
| | |
|
| | | int.TryParse(tables[1],out ItemID); |
| | | int.TryParse(tables[1],out LibID); |
| | |
|
| | | int.TryParse(tables[2],out ItemCount); |
| | | int.TryParse(tables[2],out ItemID); |
| | |
|
| | | int.TryParse(tables[3],out ItemCount); |
| | | }
|
| | | catch (Exception exception)
|
| | | {
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月17日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年6月17日
|
| | | // [ Date ]: Friday, June 27, 2025
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月22日 |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | |
|
| | | public static void OnSwitchToLoginScene()
|
| | | {
|
| | | ReleaseMgrs();
|
| | | // 前面有重新InitManagers了 这里就不在做清除
|
| | | // ReleaseMgrs();
|
| | | }
|
| | |
|
| | | private static void ReleaseMgrs()
|
| | |
| | | private Transform loadingTrans; |
| | | |
| | | // UI字典,存储所有已加载的UI,键为UI名称,值为UI实例 |
| | | private Dictionary<string, List<UIBase>> uiDict = new Dictionary<string, List<UIBase>>(); |
| | | |
| | | #if UNITY_EDITOR |
| | | public |
| | | #else |
| | | private |
| | | #endif |
| | | Dictionary<string, List<UIBase>> uiDict = new Dictionary<string, List<UIBase>>(); |
| | | |
| | | // 存储关闭但未销毁的UI,键为UI名称,值为UI实例 |
| | | private Dictionary<string, List<UIBase>> closedUIDict = new Dictionary<string, List<UIBase>>(); |
| | | |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class BattleField |
| | | { |
| | | public BattleMode battleMode; |
| | | |
| | | public BattleObjMgr battleObjMgr; |
| | | |
| | | public RecordPlayer recordPlayer; |
| | | |
| | | public IOperationAgent operationAgent; |
| | | |
| | | public int round = 0; |
| | | |
| | | public bool IsActive |
| | | { |
| | | get; |
| | | protected set; |
| | | } |
| | | |
| | | public bool IsBattleFinish |
| | | { |
| | | get; |
| | | protected set; |
| | | } |
| | | |
| | | public virtual bool IsPvp |
| | | { |
| | | get |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | private bool m_IsPause = false; |
| | | |
| | | public bool IsPause |
| | | { |
| | | get |
| | | { |
| | | return m_IsPause; |
| | | } |
| | | protected set |
| | | { |
| | | m_IsPause = value; |
| | | |
| | | if (m_IsPause) |
| | | { |
| | | PauseGame(); |
| | | } |
| | | else |
| | | { |
| | | ResumeGame(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public BattleRootNode battleRootNode; |
| | | |
| | | private BattleMode battleMode; |
| | | |
| | | public virtual void Init(TeamBase _redTeam, TeamBase _blueTeam) |
| | | { |
| | | GameObject go = ResManager.Instance.LoadAsset<GameObject>("Battle/Prefabs", "BattleRootNode"); |
| | | GameObject battleRootNodeGO = GameObject.Instantiate(go); |
| | | battleRootNode = battleRootNodeGO.GetComponent<BattleRootNode>(); |
| | | battleRootNodeGO.name = this.GetType().Name; |
| | | |
| | | battleObjMgr = new BattleObjMgr(); |
| | | battleObjMgr.Init(_redTeam, _blueTeam); |
| | | battleObjMgr.Init(this, _redTeam, _blueTeam); |
| | | |
| | | recordPlayer = new RecordPlayer(); |
| | | recordPlayer.Init(this); |
| | | } |
| | | |
| | | // 在Run之前要设置完毕 要创建Agent |
| | | public void SetBattleMode(BattleMode _battleMode) |
| | | { |
| | | battleMode = _battleMode; |
| | | CreateAgent(); |
| | | } |
| | | |
| | | public virtual void Release() |
| | |
| | | |
| | | public virtual void Run() |
| | | { |
| | | if (IsPause) |
| | | return; |
| | | |
| | | if (IsRoundReachLimit()) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | recordPlayer.Run(); |
| | | battleObjMgr.Run(); |
| | | |
| | | if (operationAgent == null) |
| | | { |
| | | Debug.LogError("you should SetBattleMode before Run"); |
| | | return; |
| | | } |
| | | |
| | | operationAgent.Run(); |
| | | } |
| | | |
| | | public void SetBattleMode(BattleMode _battleMode) |
| | | |
| | | protected virtual void CreateAgent() |
| | | { |
| | | battleMode = _battleMode; |
| | | // Hand,//手动战斗 |
| | | // Auto,//自动战斗 |
| | | // Record,//战报 |
| | | switch (battleMode) |
| | | { |
| | | case BattleMode.Hand: |
| | | operationAgent = new HandModeOperationAgent(this); |
| | | break; |
| | | case BattleMode.Auto: |
| | | operationAgent = new AutoModeOperationAgent(this); |
| | | break; |
| | | case BattleMode.Record: |
| | | operationAgent = new RecordModeOperationAgent(this); |
| | | break; |
| | | default: |
| | | operationAgent = new HandModeOperationAgent(this); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | public virtual void PlayRecord(RecordAction recordAction) |
| | |
| | | recordPlayer.PlayRecord(recordList); |
| | | } |
| | | |
| | | public virtual void OnActionOver(int attackId) |
| | | { |
| | | // |
| | | // 手动推点一下发一个包 收一个包 播放一次报文 之后就停住 直到战斗结束的包文 |
| | | // 自动的话 自动发包 播放报文 后 请求下一个包 循环 直到战斗结束的包文 |
| | | // 战报播放就是一直播放战报 知道战斗结束的包文 |
| | | if (battleMode == BattleMode.Auto) |
| | | { |
| | | // Request next action |
| | | } |
| | | else if (battleMode == BattleMode.Record) |
| | | { |
| | | // Play next record |
| | | } |
| | | else |
| | | { |
| | | // Wait for user input |
| | | } |
| | | } |
| | | |
| | | public virtual void ResumeGame() |
| | | protected virtual void ResumeGame() |
| | | { |
| | | battleObjMgr.ResumeGame(); |
| | | recordPlayer.ResumeGame(); |
| | | } |
| | | |
| | | public virtual void PauseGame() |
| | | protected virtual void PauseGame() |
| | | { |
| | | battleObjMgr.PauseGame(); |
| | | recordPlayer.PauseGame(); |
| | | } |
| | | |
| | | public bool IsRoundReachLimit() |
| | | { |
| | | // return round > xxx; |
| | | return false; |
| | | } |
| | | } |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections.Generic; |
| | | using UnityEngine.UI; |
| | | |
| | | public class BattleRootNode : MonoBehaviour |
| | | { |
| | | public List<GameObject> redTeamNodeList = new List<GameObject>(); |
| | | |
| | | public List<GameObject> blueTeamNodeList = new List<GameObject>(); |
| | | |
| | | public RawImage imgBackground; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 7ff74171c89d45d46995ac2dd01acd80 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 7659a019bc5e73b45b9d0cea3bba2e4a |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | |
| | | // 自己推进战斗的 Editor下使用就好 |
| | | public class AIOperationAgent : IOperationAgent |
| | | { |
| | | |
| | | protected List<BattleObject> attackList = new List<BattleObject>(); |
| | | |
| | | public AIOperationAgent(BattleField _battleField) : base (_battleField) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | base.Run(); |
| | | |
| | | bool isBattleBegin = battleField.round == 0 && attackList.Count <= 0; |
| | | |
| | | bool isRoundBegin = attackList.Count <= 0; |
| | | |
| | | if (attackList.Count <= 0 && !battleField.recordPlayer.IsPlaying()) |
| | | { |
| | | |
| | | // 战斗开始前,根据各自上阵武将战力之和决定谁为先攻方,战力之和高的为先攻主,先攻方优先攻击,确定先攻方后开始战斗。 |
| | | |
| | | |
| | | attackList.AddRange(battleField.battleObjMgr.redCampList); |
| | | attackList.AddRange(battleField.battleObjMgr.blueCampList); |
| | | |
| | | // // 排序 战斗力高的靠前 |
| | | // attackList.Sort((a, b) => { |
| | | // int power1 = a.teamHero.GetPower(); |
| | | // int power2 = b.teamHero.GetPower(); |
| | | // return power2.CompareTo(power1); |
| | | // }); |
| | | |
| | | battleField.round++; |
| | | } |
| | | |
| | | if (!battleField.recordPlayer.IsPlaying() && attackList.Count > 0) |
| | | { |
| | | List<RecordAction> playList = new List<RecordAction>(); |
| | | if (isBattleBegin) |
| | | { |
| | | playList.AddRange(CreateBattleBeginActionList()); |
| | | } |
| | | else |
| | | { |
| | | if (isRoundBegin) |
| | | { |
| | | playList.AddRange(CreateRoundBeginActionList()); |
| | | } |
| | | else |
| | | { |
| | | playList.AddRange(CreateActions(attackList[0])); |
| | | attackList.RemoveAt(0); |
| | | } |
| | | } |
| | | |
| | | battleField.recordPlayer.PlayRecord(playList); |
| | | } |
| | | } |
| | | |
| | | protected List<RecordAction> CreateBattleBeginActionList() |
| | | { |
| | | // 战斗开始前的轮次的操作 |
| | | List<RecordAction> returnList = new List<RecordAction>(); |
| | | // attackList |
| | | return returnList; |
| | | } |
| | | |
| | | protected List<RecordAction> CreateRoundBeginActionList() |
| | | { |
| | | // 每轮开始前的操作 |
| | | List<RecordAction> returnList = new List<RecordAction>(); |
| | | // attackList |
| | | return returnList; |
| | | } |
| | | |
| | | protected List<RecordAction> CreateActions(BattleObject _battleObj) |
| | | { |
| | | List<RecordAction> returnList = new List<RecordAction>(); |
| | | |
| | | List<RecordAction> beforeActionList = CreateBeforeActionActionList(_battleObj); |
| | | List<RecordAction> actionList = CreateActionList(_battleObj); |
| | | List<RecordAction> afterActionList = CreateAfterActionList(_battleObj); |
| | | List<RecordAction> afterDeathActionList = CreateAfterDeathActionList(_battleObj); |
| | | |
| | | returnList.AddRange(beforeActionList); |
| | | returnList.AddRange(actionList); |
| | | returnList.AddRange(afterActionList); |
| | | returnList.AddRange(afterDeathActionList); |
| | | |
| | | return returnList; |
| | | } |
| | | |
| | | protected List<RecordAction> CreateBeforeActionActionList(BattleObject _battleObj) |
| | | { |
| | | // 解异常 加减buff |
| | | List<RecordAction> returnList = new List<RecordAction>(); |
| | | return returnList; |
| | | } |
| | | |
| | | protected List<RecordAction> CreateActionList(BattleObject _battleObj) |
| | | { |
| | | // 放技能 或者被眩晕 |
| | | List<RecordAction> returnList = new List<RecordAction>(); |
| | | |
| | | |
| | | // // 能行动 |
| | | // if (_battleObj.IsCanDoActions()) |
| | | // { |
| | | // // 能放技能 |
| | | // if (_battleObj.IsCanCastSkill()) |
| | | // { |
| | | // SkillRecordAction action = new SkillRecordAction(_battleObj.teamHero.heroInfo.heroConfig.AngerSkillID, |
| | | // battleField, _battleObj); |
| | | |
| | | // // 在这里主动做一下伤害计算 正常都是服务器给的 |
| | | |
| | | |
| | | // returnList.Add(action); |
| | | // } |
| | | // else |
| | | // { |
| | | // //普攻 |
| | | // } |
| | | // } |
| | | // else |
| | | // { |
| | | // // 不能行动 飘字 过 |
| | | |
| | | // } |
| | | |
| | | return returnList; |
| | | } |
| | | |
| | | protected List<RecordAction> CreateAfterActionList(BattleObject _battleObj) |
| | | { |
| | | // 其他角色可能有连携攻击 有可能每回合buff有个dot |
| | | List<RecordAction> returnList = new List<RecordAction>(); |
| | | return returnList; |
| | | } |
| | | |
| | | protected List<RecordAction> CreateAfterDeathActionList(BattleObject _battleObj) |
| | | { |
| | | // 复活 给其他角色加buff之类的操作 |
| | | List<RecordAction> returnList = new List<RecordAction>(); |
| | | return returnList; |
| | | } |
| | | |
| | | protected void OnHeroDeath(BattleObject _battleObj) |
| | | { |
| | | |
| | | } |
| | | |
| | | protected void OnReviveHero(BattleObject _battleObj) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void DoNext() |
| | | { |
| | | base.DoNext(); |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 90516a907f902eb4b9fd00896d54f896 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | |
| | | |
| | | public class AutoModeOperationAgent : IOperationAgent |
| | | { |
| | | public AutoModeOperationAgent(BattleField battleField) : base(battleField) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | if (!battleField.IsBattleFinish) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | base.Run(); |
| | | |
| | | if (!battleField.recordPlayer.IsPlaying()) |
| | | { |
| | | DoNext(); |
| | | } |
| | | } |
| | | |
| | | public override void DoNext() |
| | | { |
| | | base.DoNext(); |
| | | |
| | | if (!battleField.recordPlayer.IsPlaying()) |
| | | { |
| | | // ask for next action |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 3c8b7e2da006e7e4bb1274bb6818582c |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | |
| | | |
| | | public class HandModeOperationAgent : IOperationAgent |
| | | { |
| | | public HandModeOperationAgent(BattleField battleField) : base(battleField) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | base.Run(); |
| | | } |
| | | |
| | | // 通过主界面的按钮推动(调用)DoNext |
| | | public override void DoNext() |
| | | { |
| | | base.DoNext(); |
| | | |
| | | if (!battleField.recordPlayer.IsPlaying()) |
| | | { |
| | | // ask for next action |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("action doesnt finish, wait a moment please"); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 4693561ca16ed084baf04d0e7734f77d |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | |
| | | public class IOperationAgent |
| | | { |
| | | protected BattleField battleField; |
| | | |
| | | public IOperationAgent(BattleField _battleField) |
| | | { |
| | | battleField = _battleField; |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | |
| | | } |
| | | |
| | | public virtual void DoNext() |
| | | { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 137d74c25e4a988499579eb125835572 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | |
| | | // record直接全程播放就好了 不需要其他操作 |
| | | |
| | | public class RecordModeOperationAgent : IOperationAgent |
| | | { |
| | | public RecordModeOperationAgent(BattleField battleField) : base(battleField) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | base.Run(); |
| | | } |
| | | |
| | | public override void DoNext() |
| | | { |
| | | base.DoNext(); |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 53b0f76e227371a46bc723a879c9953e |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 919949b557d0dc44ea63f47262263f21 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections.Generic; |
| | | |
| | | public class SkillRecordAction : RecordAction |
| | | { |
| | | public int SkillId; |
| | | |
| | | public SkillConfig skillConfig; |
| | | |
| | | protected SkillBase skillBase; |
| | | |
| | | protected List<Dictionary<int, List<int>>> damageList = new List<Dictionary<int, List<int>>>(); |
| | | |
| | | private bool isCast = false; |
| | | |
| | | |
| | | public SkillRecordAction(int _SkillId, BattleField _battleField, BattleObject _battleObj) |
| | | : base(RecordActionType.Skill, _battleField, _battleObj) |
| | | { |
| | | SkillId = _SkillId; |
| | | |
| | | skillConfig = SkillConfig.Get(SkillId); |
| | | |
| | | if (null == skillConfig) |
| | | { |
| | | Debug.LogError("找不到技能配置 " + SkillId); |
| | | } |
| | | |
| | | skillBase = SkillFactory.CreateSkill(skillConfig); |
| | | |
| | | // _battleObj使用了SkillId的技能 |
| | | damageList = skillBase.GetDamageList(battleObject, battleField); |
| | | } |
| | | |
| | | public SkillRecordAction(int _SkillId, BattleField _battleField, BattleObject _battleObj, List<Dictionary<int, List<int>>> _damageList) |
| | | : base(RecordActionType.Skill, _battleField, _battleObj) |
| | | { |
| | | SkillId = _SkillId; |
| | | |
| | | skillConfig = SkillConfig.Get(SkillId); |
| | | |
| | | if (null == skillConfig) |
| | | { |
| | | Debug.LogError("找不到技能配置 " + SkillId); |
| | | } |
| | | |
| | | skillBase = SkillFactory.CreateSkill(skillConfig); |
| | | |
| | | damageList = _damageList; |
| | | // _battleObj使用了SkillId的技能 |
| | | } |
| | | |
| | | public override bool IsFinished() |
| | | { |
| | | return skillBase.IsFinished(); |
| | | } |
| | | |
| | | |
| | | public override void Run() |
| | | { |
| | | base.Run(); |
| | | |
| | | if (null == skillBase) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (!skillBase.IsFinished()) |
| | | { |
| | | skillBase.Run(); |
| | | } |
| | | |
| | | if (isCast) |
| | | return; |
| | | |
| | | if (damageList.Count > 0) |
| | | { |
| | | skillBase.Cast(battleObject, battleField, damageList); |
| | | } |
| | | else |
| | | { |
| | | skillBase.ForceFinished(); |
| | | } |
| | | |
| | | isCast = true; |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c72895dea8c70844c9019d54023fbeb0 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | { |
| | | public override void Init(TeamBase _redTeam, TeamBase _blueTeam) |
| | | { |
| | | base.Init(_redTeam, _blueTeam); |
| | | |
| | | string savedStr = LocalSave.GetString("StoryBattleFieldBattleMode"); |
| | | if (string.IsNullOrEmpty(savedStr)) |
| | | { |
| | | savedStr = "Hand"; |
| | | } |
| | | battleMode = (BattleMode)Enum.Parse(typeof(BattleMode), savedStr); |
| | | |
| | | base.Init(_redTeam, _blueTeam); |
| | | |
| | | SetBattleMode((BattleMode)Enum.Parse(typeof(BattleMode), savedStr)); |
| | | } |
| | | |
| | | // public override void Run() |
| | | // { |
| | | // // 一定要记住这个 |
| | | // if (IsPause) |
| | | // return; |
| | | |
| | | // base.Run(); |
| | | // } |
| | | } |
| | |
| | | |
| | | public class BattleManager : GameSystemManager<BattleManager> |
| | | { |
| | | public StoryBattleField storyBattleField = new StoryBattleField();//主线战场 |
| | | public StoryBattleField storyBattleField = null; |
| | | |
| | | protected Dictionary<int, BattleField> battleFields = new Dictionary<int, BattleField>(); |
| | | |
| | | protected LogicUpdate logicUpdate = new LogicUpdate(); |
| | | |
| | | public override void Init() |
| | | { |
| | | base.Init(); |
| | | StartStoryBattle(); |
| | | logicUpdate.Start(Run); |
| | | } |
| | | |
| | | public override void Release() |
| | | { |
| | | Debug.LogError("who release this one"); |
| | | base.Release(); |
| | | logicUpdate.Destroy(); |
| | | } |
| | | |
| | | public void StartStoryBattle() |
| | |
| | | { |
| | | storyBattleField = new StoryBattleField(); |
| | | |
| | | TeamBase redTeam = GetStoryTeam();//TeamManager.Instance.GetTeam(TeamType.Story); |
| | | TeamBase blueTeam = GetStoryTeam(); |
| | | storyBattleField.Init(/*这里要加个创建背景的*/redTeam, blueTeam); |
| | | // storyBattleField.Start(); |
| | | storyBattleField.battleRootNode.transform.SetParent(Launch.Instance.transform); |
| | | } |
| | | } |
| | | |
| | | private TeamBase GetStoryTeam() |
| | | { |
| | | TeamBase teamBase = new TeamBase(); |
| | | #if UNITY_EDITOR |
| | | teamBase.FillWithFakeData(); |
| | | #else |
| | | // YYL TODO |
| | | // 根据配表塞英雄 后面可能还要塞其他东西 先放在这里反正 做主线了再转移 |
| | | #endif |
| | | |
| | | return teamBase; |
| | | } |
| | | |
| | | public void Run() |
| | | { |
| | | if (null != storyBattleField) |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System.Linq; |
| | | |
| | | public class BattleObjMgr : Singleton<BattleObjMgr> |
| | | public class BattleObjMgr |
| | | { |
| | | private List<BattleObject> redCampList => new List<BattleObject>(redCampDict.Values); |
| | | private List<BattleObject> blueCampList => new List<BattleObject>(blueCampDict.Values); |
| | | // 死亡不可以将BattleObject移出字典/列表 |
| | | public List<BattleObject> redCampList => new List<BattleObject>(redCampDict.Values); |
| | | public List<BattleObject> blueCampList => new List<BattleObject>(blueCampDict.Values); |
| | | private Dictionary<int, BattleObject> redCampDict = new Dictionary<int, BattleObject>(); |
| | | private Dictionary<int, BattleObject> blueCampDict = new Dictionary<int, BattleObject>(); |
| | | |
| | | public void Init(TeamBase _redTeam, TeamBase _blueTeam) |
| | | protected Dictionary<int, BattleObject> allBattleObjDict = new Dictionary<int, BattleObject>(); |
| | | |
| | | protected BattleField battleField; |
| | | |
| | | public void Init(BattleField _battleField, TeamBase _redTeam, TeamBase _blueTeam) |
| | | { |
| | | CreateTeam(redCampDict, _redTeam); |
| | | CreateTeam(blueCampDict, _blueTeam); |
| | | battleField = _battleField; |
| | | CreateTeam(battleField.battleRootNode.redTeamNodeList, redCampDict, _redTeam, BattleCamp.Red); |
| | | CreateTeam(battleField.battleRootNode.blueTeamNodeList, blueCampDict, _blueTeam, BattleCamp.Blue); |
| | | } |
| | | |
| | | protected void CreateTeam(Dictionary<int, BattleObject> campDict, TeamBase teamBase) |
| | | protected void CreateTeam(List<GameObject> posNodeList, Dictionary<int, BattleObject> campDict, TeamBase teamBase, BattleCamp _Camp) |
| | | { |
| | | DestroyTeam(campDict); |
| | | for (int i = 0; i < teamBase.teamHeros.Length; i++) |
| | |
| | | TeamHero teamHero = teamBase.teamHeros[i]; |
| | | if (teamHero != null) |
| | | { |
| | | BattleObject battleObj = BattleObjectFactory.CreateBattleObject(teamHero); |
| | | battleObj.Init(teamHero); |
| | | BattleObject battleObj = BattleObjectFactory.CreateBattleObject(battleField, posNodeList, teamHero, _Camp); |
| | | allBattleObjDict.Add(battleObj.BattleObjectId, battleObj); |
| | | campDict.Add(teamHero.heroIndex, battleObj); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public BattleObject GetBattleObject(int battleObjId) |
| | | { |
| | | if (allBattleObjDict.TryGetValue(battleObjId, out BattleObject battleObj)) |
| | | { |
| | | return battleObj; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | protected void DestroyTeam(Dictionary<int, BattleObject> campDict) |
| | |
| | | foreach (var item in campDict) |
| | | { |
| | | BattleObject battleObj = item.Value; |
| | | if (battleObj!= null) |
| | | if (battleObj != null) |
| | | { |
| | | BattleObjectFactory.DestroyBattleObject(battleObj); |
| | | allBattleObjDict.Remove(battleObj.BattleObjectId); |
| | | BattleObjectFactory.DestroyBattleObject(item.Key, battleObj); |
| | | } |
| | | } |
| | | campDict.Clear(); |
| | | |
| | | } |
| | | |
| | | public void Release() |
| | |
| | | foreach (var item in redCampDict) |
| | | { |
| | | item.Value.Run(); |
| | | |
| | | } |
| | | |
| | | foreach (var item in blueCampDict) |
| | |
| | | } |
| | | } |
| | | |
| | | public void ResumeGame() |
| | | public virtual void ResumeGame() |
| | | { |
| | | foreach (var item in redCampList) |
| | | foreach (var obj in redCampDict.Values) |
| | | { |
| | | item.ResumeGame(); |
| | | obj.Resume(); |
| | | } |
| | | |
| | | foreach (var item in blueCampList) |
| | | foreach(var obj in blueCampDict.Values) |
| | | { |
| | | item.ResumeGame(); |
| | | obj.Resume(); |
| | | } |
| | | } |
| | | |
| | | public void PauseGame() |
| | | public virtual void PauseGame() |
| | | { |
| | | foreach (var item in redCampList) |
| | | foreach (var obj in redCampDict.Values) |
| | | { |
| | | item.PauseGame(); |
| | | obj.Pause(); |
| | | } |
| | | |
| | | foreach (var item in blueCampList) |
| | | foreach(var obj in blueCampDict.Values) |
| | | { |
| | | item.PauseGame(); |
| | | obj.Pause(); |
| | | } |
| | | } |
| | | |
| | | public List<BattleObject> GetEnemyList(BattleObject _battleObj) |
| | | { |
| | | if (_battleObj.Camp == BattleCamp.Red) |
| | | { |
| | | return blueCampList; |
| | | } |
| | | |
| | | return redCampList; |
| | | } |
| | | |
| | | public List<BattleObject> GetFriendlyList(BattleObject _battleObj) |
| | | { |
| | | if (_battleObj.Camp == BattleCamp.Red) |
| | | { |
| | | return redCampList; |
| | | } |
| | | |
| | | return blueCampList; |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public void ReviveAll() |
| | | { |
| | | foreach (var kv in allBattleObjDict) |
| | | { |
| | | kv.Value.EditorRevive(); |
| | | } |
| | | } |
| | | |
| | | public List<BattleObject> GetTargetList(BattleObject battleObj, SkillTargetType targetType, SkillTargetRangeType rangeType) |
| | | { |
| | | List<BattleObject> returnList = new List<BattleObject>(); |
| | | |
| | | switch (targetType) |
| | | { |
| | | case SkillTargetType.Self: |
| | | returnList.Add(battleObj); |
| | | break; |
| | | case SkillTargetType.Own: |
| | | returnList.AddRange(GetFriendlyList(battleObj)); |
| | | break; |
| | | case SkillTargetType.Enemy: |
| | | returnList.AddRange(GetEnemyList(battleObj)); |
| | | break; |
| | | case SkillTargetType.OwnExceptSelf: |
| | | List<BattleObject> friendlyList = GetFriendlyList(battleObj); |
| | | friendlyList.Remove(battleObj); |
| | | returnList.AddRange(friendlyList); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | //普攻为群攻时,以当前单体时默认攻击对象为主对象,其它为溅射单位; |
| | | |
| | | switch (rangeType) |
| | | { |
| | | case SkillTargetRangeType.Front: |
| | | //暂时没有召唤物 |
| | | // 放在第7格的BOSS后排的。。位置放在正中间 |
| | | // a)前排,1、2、3号为前排,前排全部阵亡后,4、5、6号即是前排也是后排 7其实也是后排 |
| | | List<BattleObject> frontList = new List<BattleObject>(from BO in returnList where BO.teamHero.heroIndex < 3 && !BO.IsDead() select BO); |
| | | if (frontList.Count == 0) |
| | | { |
| | | frontList.AddRange(returnList); |
| | | } |
| | | returnList = frontList; |
| | | break; |
| | | case SkillTargetRangeType.Back: |
| | | List<BattleObject> backList = new List<BattleObject>(from BO in returnList where BO.teamHero.heroIndex >= 3 && !BO.IsDead() select BO); |
| | | if (backList.Count == 0) |
| | | { |
| | | backList.AddRange(returnList); |
| | | } |
| | | returnList = backList; |
| | | break; |
| | | case SkillTargetRangeType.Random: |
| | | |
| | | int randomNumber = 3; |
| | | returnList = new List<BattleObject>(from BO in returnList where !BO.IsDead() select BO); |
| | | returnList = returnList.Shuffle(); |
| | | while (returnList.Count > randomNumber) |
| | | { |
| | | returnList.RemoveAt(0); |
| | | } |
| | | break; |
| | | case SkillTargetRangeType.All: |
| | | break; |
| | | case SkillTargetRangeType.HighestAttack: |
| | | returnList = new List<BattleObject>(from BO in returnList where !BO.IsDead() select BO); |
| | | BattleObject mostHighestAttckObj = null; |
| | | for (int i = 0; i < returnList.Count; i++) |
| | | { |
| | | if (mostHighestAttckObj == null) |
| | | { |
| | | mostHighestAttckObj = returnList[i]; |
| | | continue; |
| | | } |
| | | if (returnList[i].teamHero.attack > mostHighestAttckObj.teamHero.attack) |
| | | { |
| | | mostHighestAttckObj = returnList[i]; |
| | | } |
| | | } |
| | | returnList.Clear(); |
| | | if (mostHighestAttckObj != null) |
| | | returnList.Add(mostHighestAttckObj); |
| | | break; |
| | | case SkillTargetRangeType.LowestHP: |
| | | returnList = new List<BattleObject>(from BO in returnList where !BO.IsDead() select BO); |
| | | BattleObject loweastHpObj = null; |
| | | for (int i = 0; i < returnList.Count; i++) |
| | | { |
| | | if (loweastHpObj == null) |
| | | { |
| | | loweastHpObj = returnList[i]; |
| | | continue; |
| | | } |
| | | if (returnList[i].teamHero.curHp < loweastHpObj.teamHero.curHp) |
| | | { |
| | | loweastHpObj = returnList[i]; |
| | | } |
| | | } |
| | | returnList.Clear(); |
| | | if (null != loweastHpObj) |
| | | returnList.Add(loweastHpObj); |
| | | break; |
| | | case SkillTargetRangeType.Deadman: |
| | | returnList = new List<BattleObject>(from BO in returnList where BO.IsDead() select BO); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return returnList; |
| | | } |
| | | #endif |
| | | } |
| | |
| | | using DG.Tweening; |
| | | using DG.Tweening.Core; |
| | | using DG.Tweening.Plugins.Options; |
| | | using Spine.Unity; |
| | | using UnityEngine.UI; |
| | | using System.Linq; |
| | | |
| | | public enum BattleCamp |
| | | { |
| | | Friendly, |
| | | Enemy |
| | | Red, |
| | | Blue |
| | | } |
| | | |
| | | public enum BattleState |
| | |
| | | |
| | | public class BattleObject |
| | | { |
| | | public string BattleObjectId { get; protected set; } |
| | | |
| | | public BattleCamp Camp { get; protected set; } = BattleCamp.Friendly; |
| | | |
| | | public BattleField battleField; |
| | | |
| | | public int BattleObjectId { get; set; } |
| | | |
| | | public BattleCamp Camp { get; protected set; } |
| | | |
| | | public TeamHero teamHero { get; protected set; } |
| | | |
| | | // public BuffMgr buffMgr; |
| | | |
| | | protected MotionBase motionBase; |
| | | |
| | | protected GameObject cardGO; |
| | | |
| | | public virtual void Init(TeamHero _teamHero) |
| | | protected GameObject heroGo; |
| | | |
| | | public BattleObject(BattleField _battleField) |
| | | { |
| | | this.teamHero = _teamHero; |
| | | battleField = _battleField; |
| | | } |
| | | |
| | | public virtual void Init(GameObject _heroGo, TeamHero _teamHero, BattleCamp _camp) |
| | | { |
| | | heroGo = _heroGo; |
| | | teamHero = _teamHero; |
| | | Camp = _camp; |
| | | motionBase = new MotionBase(); |
| | | motionBase.Init(heroGo.GetComponentInChildren<SkeletonGraphic>(true)); |
| | | } |
| | | |
| | | protected void LoadHero() |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | #region 战斗相关函数 |
| | | |
| | | public virtual void AttackTarget(List<BattleObject> targets) |
| | | { |
| | | // 找离自己最近的 |
| | | |
| | | if (0 == targets.Count) return; |
| | | |
| | | BattleObject target = targets[0]; |
| | | |
| | | if (1 != targets.Count) |
| | | { |
| | | for (int i = 1; i < targets.Count; i++) |
| | | { |
| | | if (Vector3.Distance(cardGO.transform.position, targets[i].cardGO.transform.position) < Vector3.Distance(cardGO.transform.position, target.cardGO.transform.position)) |
| | | { |
| | | target = targets[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | Vector3 tempPos = cardGO.transform.position; |
| | | |
| | | motionBase.OnAttackAnimationComplete = () => { |
| | | // 攻击动画结束之后 回到原来的位置 |
| | | |
| | | cardGO.transform.DOMove(tempPos, 1f).OnComplete(() => { |
| | | // motionBase.ClearEvent();// = null; |
| | | |
| | | // 通知本次攻击行动结束 |
| | | // 通过battleFieldId来告知BattleFieldMgr |
| | | }); |
| | | }; |
| | | |
| | | cardGO.transform.DOMove(target.cardGO.transform.position, 1f).OnComplete(() => { |
| | | // 播放攻击动画 |
| | | motionBase.OnAttackHitEvent = (int attackIndex) => { |
| | | for (int i = 0; i < targets.Count; i++) |
| | | { |
| | | targets[i].UnderAttack(this); |
| | | } |
| | | }; |
| | | |
| | | //普攻是hit1 |
| | | |
| | | motionBase.PlayAnimationEx(MotionName.atk1, false, new List<int>(){ |
| | | 5//假设是5帧 目前还没有数据 |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | public virtual void CastSkill(List<BattleObject> targets) |
| | | { |
| | | // 需不需要move 攻击目标是谁 |
| | | } |
| | | |
| | | public virtual float UnderAttack(BattleObject attacker) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | public virtual float HealTargets(List<BattleObject> targets) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | public virtual float BeHealed(BattleObject healer, float healAmount) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | public virtual bool Revive(BattleObject target) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | public virtual bool BeRevived(BattleObject reviver, float healthPercent = 0.5f) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 辅助函数 |
| | | |
| | | public virtual bool IsEnemy(BattleObject other) |
| | | { |
| | | if (other == null) return false; |
| | | |
| | | return Camp != other.Camp; |
| | | } |
| | | |
| | | public virtual bool IsFriendly(BattleObject other) |
| | | { |
| | | if (other == null) return false; |
| | | |
| | | return Camp == other.Camp; |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | motionBase.Run(); |
| | | } |
| | | |
| | | public virtual void PauseGame() |
| | | public virtual void Pause() |
| | | { |
| | | |
| | | motionBase.Pause(); |
| | | } |
| | | |
| | | public virtual void ResumeGame() |
| | | public virtual void Resume() |
| | | { |
| | | |
| | | motionBase.Resume(); |
| | | } |
| | | |
| | | #endregion |
| | | public virtual void Destroy() |
| | | { |
| | | if (heroGo != null) |
| | | { |
| | | GameObject.DestroyImmediate(heroGo); |
| | | heroGo = null; |
| | | } |
| | | |
| | | motionBase.Release(); |
| | | motionBase = null; |
| | | teamHero = null; |
| | | BattleObjectId = 0; |
| | | } |
| | | |
| | | // 眩晕 |
| | | public bool IsStunned() |
| | | { |
| | | return teamHero.isStunned; |
| | | } |
| | | |
| | | // 冰冻 |
| | | public bool IsFrozen() |
| | | { |
| | | return teamHero.isFrozen; |
| | | } |
| | | |
| | | // 石化 |
| | | public bool IsStoned() |
| | | { |
| | | return teamHero.isStoned; |
| | | } |
| | | |
| | | // // 禁锢 |
| | | // public bool IsConfined() |
| | | // { |
| | | // return false; |
| | | // } |
| | | |
| | | // 被沉默 |
| | | public bool IsSlient() |
| | | { |
| | | return teamHero.isSlient; |
| | | } |
| | | |
| | | // 被缴械 |
| | | public bool IsDisarmed() |
| | | { |
| | | return teamHero.isDisarmed; |
| | | } |
| | | |
| | | // 是否无敌 |
| | | public bool IsInvincable() |
| | | { |
| | | return teamHero.isInvinceble; |
| | | } |
| | | |
| | | // 是否死亡 |
| | | public bool IsDead() |
| | | { |
| | | return teamHero.isDead; |
| | | } |
| | | |
| | | // 是否被控住了 |
| | | public bool IsCrowdControlled() |
| | | { |
| | | return IsStunned() || IsStoned() || IsFrozen(); |
| | | } |
| | | |
| | | public virtual bool IsCanCastSkill() |
| | | { |
| | | // 被控住 |
| | | if (IsCrowdControlled()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // 被沉默 |
| | | if (IsSlient()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // 看看怒气是否达到释放要求 |
| | | return teamHero.rage >= 100; |
| | | } |
| | | |
| | | public virtual bool IsCanNormalAttack() |
| | | { |
| | | // 被控住 |
| | | if (IsCrowdControlled()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // 缴械 |
| | | if (IsDisarmed()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | public virtual void TakeDamage(List<int> damageValues) |
| | | { |
| | | if (IsDead()) |
| | | return; |
| | | |
| | | PopDamage(damageValues); |
| | | |
| | | motionBase.PlayAnimation(MotionName.hit, false); |
| | | |
| | | // 计算伤害 |
| | | int totalDamage = 0; |
| | | foreach (var damage in damageValues) |
| | | { |
| | | totalDamage += damage; |
| | | } |
| | | |
| | | // 扣血 |
| | | teamHero.curHp -= totalDamage; |
| | | |
| | | // 其实这里应该是等服务器发death的action |
| | | // if (IsDead()) |
| | | // { |
| | | // OnDeath(); |
| | | // } |
| | | } |
| | | |
| | | // 闪避开始 |
| | | public virtual void OnDodgeBegin() |
| | | { |
| | | float pingpongTime = 0.2f; |
| | | RectTransform rectTrans = heroGo.GetComponent<RectTransform>(); |
| | | rectTrans.DOAnchorPos(new Vector3(-50, 50, 0), pingpongTime) |
| | | .SetEase(Ease.OutCubic); |
| | | } |
| | | |
| | | // 闪避结束 |
| | | public virtual void OnDodgeEnd() |
| | | { |
| | | float pingpongTime = 0.2f; |
| | | RectTransform rectTrans = heroGo.GetComponent<RectTransform>(); |
| | | rectTrans.DOAnchorPos(Vector3.zero, pingpongTime) |
| | | .SetEase(Ease.OutCubic); |
| | | } |
| | | |
| | | protected virtual void OnDeath() |
| | | { |
| | | motionBase.OnOtherAnimationComplete = OnOtherAnimationComplete; |
| | | motionBase.PlayAnimation(MotionName.dead, false); |
| | | } |
| | | |
| | | protected virtual void OnOtherAnimationComplete(MotionName motionName) |
| | | { |
| | | if (motionName == MotionName.dead) |
| | | { |
| | | OnDeadAnimationComplete(); |
| | | } |
| | | } |
| | | |
| | | protected virtual void OnDeadAnimationComplete() |
| | | { |
| | | // 或许看看溶解特效? YYL TODO |
| | | heroGo.SetActive(false); |
| | | } |
| | | |
| | | // 伤害还要看 是否闪避 暴击 and so on 需要有一个DamageType 服务器应该会给 |
| | | protected virtual void PopDamage(List<int> damageValues) |
| | | { |
| | | // 其实应该通知出去给UI界面解耦 让UI界面自己来显示的 YYL TODO |
| | | // 播放伤害数字 |
| | | // 这里可以实现一个伤害数字的弹出效果 |
| | | // 比如使用一个UI组件来显示伤害数字 |
| | | foreach (var damage in damageValues) |
| | | { |
| | | Debug.Log($"Damage: {damage}"); |
| | | } |
| | | } |
| | | |
| | | public void PlaySkill(SkillConfig skillConfig, List<Dictionary<int, List<int>>> damageList, Action _onComplete) |
| | | { |
| | | bool moveToTarget = true; |
| | | |
| | | if (moveToTarget) |
| | | { |
| | | int targetId = damageList[0].First().Key; |
| | | BattleObject _targetObj = battleField.battleObjMgr.GetBattleObject(targetId); |
| | | |
| | | RectTransform selfRect = heroGo.GetComponent<RectTransform>(); |
| | | RectTransform targetRect = _targetObj.heroGo.GetComponent<RectTransform>(); |
| | | Vector2 curAnchoredPos = selfRect.anchoredPosition; |
| | | |
| | | MoveToTargetUI(selfRect, targetRect, new Vector2(100f, 0f), () => |
| | | { |
| | | PlaySkillAnimation(skillConfig, damageList, () => |
| | | { |
| | | // 回到原位置 |
| | | selfRect.DOAnchorPos(curAnchoredPos, 0.2f) |
| | | .SetEase(Ease.Linear) |
| | | .OnComplete(() => { |
| | | _onComplete?.Invoke(); |
| | | }); |
| | | }); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | PlaySkillAnimation(skillConfig, damageList, _onComplete); |
| | | } |
| | | } |
| | | |
| | | protected void MoveToTargetUI(RectTransform selfRect, RectTransform targetRect, Vector2 offset, Action _onComplete) |
| | | { |
| | | // 1. 目标的本地坐标转为世界坐标 |
| | | Vector3 targetWorldPos = targetRect.TransformPoint(targetRect.anchoredPosition + offset); |
| | | |
| | | // 2. 世界坐标转为自己父节点下的本地坐标 |
| | | RectTransform parentRect = selfRect.parent as RectTransform; |
| | | Vector2 targetAnchoredPos; |
| | | RectTransformUtility.ScreenPointToLocalPointInRectangle( |
| | | parentRect, |
| | | RectTransformUtility.WorldToScreenPoint(null, targetWorldPos), |
| | | null, |
| | | out targetAnchoredPos); |
| | | |
| | | // 3. DOTween 移动 |
| | | selfRect.DOAnchorPos(targetAnchoredPos, 0.2f) |
| | | .SetEase(Ease.Linear) |
| | | .OnComplete(() => _onComplete?.Invoke()); |
| | | } |
| | | |
| | | |
| | | protected void PlaySkillAnimation(SkillConfig skillConfig, List<Dictionary<int, List<int>>> damageList, Action _onComplete) |
| | | { |
| | | |
| | | // 关键帧列表 |
| | | List<int> keyFrameList = new List<int>() { 15 }; |
| | | motionBase.OnAttackHitEvent = (int _frame) => |
| | | { |
| | | Dictionary<int, List<int>> oneRoundDamage = damageList[keyFrameList.IndexOf(_frame)]; |
| | | |
| | | foreach (var kvp in oneRoundDamage) |
| | | { |
| | | int targetId = kvp.Key; |
| | | List<int> damageValues = kvp.Value; |
| | | |
| | | BattleObject targetObj = battleField.battleObjMgr.GetBattleObject(targetId); |
| | | if (targetObj != null && !targetObj.IsDead()) |
| | | { |
| | | targetObj.TakeDamage(damageValues); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | motionBase.OnAttackAnimationComplete = () => |
| | | { |
| | | _onComplete?.Invoke(); |
| | | |
| | | motionBase.OnAttackHitEvent = null; |
| | | motionBase.OnAttackAnimationComplete = null; |
| | | |
| | | // 死亡确定其实不应该在这里进行触发 应该由服务器下发 YYL TODO |
| | | |
| | | #if UNITY_EDITOR |
| | | // 暂时的处理 |
| | | HashSet<int> hitTargets = new HashSet<int>(); |
| | | |
| | | foreach (var dmgDict in damageList) |
| | | { |
| | | foreach (var kvp in dmgDict) |
| | | { |
| | | int targetId = kvp.Key; |
| | | hitTargets.Add(targetId); |
| | | } |
| | | } |
| | | |
| | | foreach (int targetId in hitTargets) |
| | | { |
| | | BattleObject targetObj = battleField.battleObjMgr.GetBattleObject(targetId); |
| | | if (targetObj != null && targetObj.IsDead()) |
| | | { |
| | | targetObj.OnDeath(); |
| | | } |
| | | } |
| | | #endif |
| | | }; |
| | | |
| | | motionBase.PlayAnimationEx(MotionName.attack, false, keyFrameList); |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public void EditorRevive() |
| | | { |
| | | teamHero.curHp = 100; |
| | | heroGo.SetActive(true); |
| | | motionBase.PlayAnimation(MotionName.idle, true); |
| | | } |
| | | |
| | | public List<int> TryAttack(BattleObject obj, SkillConfig skillConfig) |
| | | { |
| | | List<int> damageList = new List<int>(); |
| | | |
| | | int totalDamage = teamHero.attack - obj.teamHero.defense; |
| | | |
| | | damageList.Add(totalDamage); |
| | | |
| | | return damageList; |
| | | } |
| | | #endif |
| | | |
| | | } |
| | |
| | | |
| | | public class BattleObjectFactory |
| | | { |
| | | public static BattleObject CreateBattleObject(TeamHero teamHero) |
| | | // 本意是要在这里做池的内容的 但是想了一下 利用效率有点差 最多做一下红色方的缓存 蓝色方的即时用 即时删除 或者缓存上一次战斗的就行 |
| | | private static int AutoIncrementID = 100000; |
| | | |
| | | public static BattleObject CreateBattleObject(BattleField _battleField, List<GameObject> posNodeList, TeamHero teamHero, BattleCamp _Camp) |
| | | { |
| | | BattleObject battleObject = null; |
| | | // switch (teamCard.cardInfo.cardConfig.) |
| | | // { |
| | | |
| | | // } |
| | | |
| | | HeroSkinConfig skinCfg = teamHero.heroInfo.skinConfig; |
| | | GameObject battleGO = ResManager.Instance.LoadAsset<GameObject>("Hero/SpineRes", "Hero_001"/*skinCfg.SpineRes*/); |
| | | GameObject goParent = posNodeList[teamHero.heroIndex]; |
| | | BattleObject battleObject = new BattleObject(_battleField); |
| | | battleObject.BattleObjectId = AutoIncrementID++; |
| | | battleGO.name = battleObject.BattleObjectId.ToString(); |
| | | battleObject.Init(GameObject.Instantiate(battleGO, goParent.transform), teamHero, _Camp); |
| | | return battleObject; |
| | | } |
| | | |
| | | public static void DestroyBattleObject(BattleObject battleObj) |
| | | public static void DestroyBattleObject(int key, BattleObject battleObj) |
| | | { |
| | | |
| | | battleObj.Destroy(); |
| | | battleObj = null; |
| | | } |
| | | } |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine.UI; |
| | | using DG.Tweening; |
| | | using Cysharp.Threading.Tasks; |
| | | |
| | | public class BattleWin : UIBase |
| | | { |
| | | // 组件引用 |
| | | public Transform mountPoint; |
| | | |
| | | private BattleRootNode battleRootNode = null; |
| | | |
| | | // 生命周期 |
| | | protected override void InitComponent() |
| | | { |
| | | base.InitComponent(); |
| | | // 初始化组件引用 绑定按钮等UI组件事件 |
| | | } |
| | | |
| | | protected override void OnPreOpen() |
| | | { |
| | | base.OnPreOpen(); |
| | | |
| | | SetBattleField(BattleManager.Instance.storyBattleField); |
| | | } |
| | | |
| | | protected override void OnPreClose() |
| | | { |
| | | base.OnPreClose(); |
| | | } |
| | | |
| | | protected override void OnOpen() |
| | | { |
| | | base.OnOpen(); |
| | | } |
| | | |
| | | protected override void OnClose() |
| | | { |
| | | base.OnClose(); |
| | | |
| | | if (battleRootNode != null) |
| | | { |
| | | battleRootNode.transform.SetParent(null); |
| | | } |
| | | } |
| | | |
| | | protected override void NextFrameAfterOpen() |
| | | { |
| | | base.NextFrameAfterOpen(); |
| | | } |
| | | |
| | | protected override void CompleteClose() |
| | | { |
| | | base.CompleteClose(); |
| | | } |
| | | |
| | | public void SetBattleField(BattleField battleField) |
| | | { |
| | | if (battleRootNode != null) |
| | | { |
| | | battleRootNode.transform.SetParent(Launch.Instance.transform); |
| | | } |
| | | |
| | | battleRootNode = battleField.battleRootNode; |
| | | |
| | | battleRootNode.transform.SetParent(mountPoint); |
| | | battleRootNode.transform.localPosition = Vector3.zero; |
| | | battleRootNode.transform.localScale = Vector3.one; |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 9436c20bbc05d7443a4a55bdd8225747 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: fe16e4ea643c0f141869bc215e72e46f |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: d98f48e6efd31894f920108e541b4f69 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | |
| | | |
| | | public enum DamageType |
| | | { |
| | | Normal, //普通伤害 |
| | | Dodge, //闪避 |
| | | Heal, //治疗 |
| | | Continuous,//持续伤害 |
| | | Block, //格挡 |
| | | ReverseInjury,//反伤 |
| | | Recovery, //吸血 |
| | | Crit, //暴击 |
| | | Combo, //连击 |
| | | Stuned, //击晕 |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: d7487e4b249bbbb4b8504bbc03f47c82 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | // 2、目标类型2 |
| | | // a)前排,1、2、3号为前排,前排全部阵亡后,4、5、6号即是前排也是后排 |
| | | // b)后排,4、5、6号为后排,后排全部阵亡后,1、2、3号即是前排也是后排 |
| | | // c)随机 |
| | | // d)全体 |
| | | // e)攻击最高:有多个目标,优先对位对应号位目标,按顺序从1号开始选择 |
| | | // f)生命最低:有多个目标,优先对位对应号位目标,按顺序从1号开始选择 |
| | | // g)死亡目标:有多个目标,按顺序从1号开始选择 |
| | | |
| | | |
| | | public enum SkillTargetRangeType |
| | | { |
| | | Front, |
| | | Back, |
| | | Random, |
| | | All, |
| | | HighestAttack, |
| | | LowestHP, |
| | | Deadman |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: d7a05b1f4236c944585478475734d089 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | // 技能释放,需要根据技能配置,选择目标进行释放 |
| | | // 1、目标类型1 |
| | | // a)自身 |
| | | // b)己方 |
| | | // c)敌方 |
| | | // d)除自身外的己方 |
| | | public enum SkillTargetType |
| | | { |
| | | Self = 0, //自己 |
| | | Own, //己方 |
| | | Enemy, //地方 |
| | | OwnExceptSelf, //除自身外的己方 |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 1af57ceed7e65c549897d7220d060c61 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | |
| | | public WaitingTask(List<int> triggerFrame, MotionName motionName, Action<MotionName, int> _callback) |
| | | { |
| | | this.triggerFrame = triggerFrame; |
| | | this.triggerFrame = new List<int>(triggerFrame); |
| | | this.motionName = motionName; |
| | | this.currentFrame = 0; |
| | | this.callback = _callback; |
| | |
| | | |
| | | if (currentFrame >= triggerFrame[0]) |
| | | { |
| | | int frame = triggerFrame[0]; |
| | | triggerFrame.RemoveAt(0); |
| | | callback?.Invoke(motionName, currentFrame); |
| | | callback?.Invoke(motionName, frame); |
| | | } |
| | | } |
| | | } |
| | |
| | | // 动画事件 |
| | | public Action OnAttackAnimationComplete; |
| | | public Action OnHitAnimationComplete; |
| | | public Action<MotionName> OnOtherAnimationComplete; |
| | | public Action<int> OnAttackHitEvent; //trigger index |
| | | |
| | | #region 组件引用 |
| | |
| | | #region 动画设置 |
| | | |
| | | // 动画混合时间 |
| | | protected float defaultMixDuration = 0.2f; |
| | | protected float defaultMixDuration = 0f; |
| | | |
| | | #endregion |
| | | |
| | | protected List<WaitingTask> waitingTaskList = new List<WaitingTask>(); |
| | | protected List<WaitingTask> removeList = new List<WaitingTask>(); |
| | | |
| | | private Spine.TrackEntry currentTrackEntry; |
| | | |
| | | #region 初始化方法 |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | public virtual void Release() |
| | | { |
| | | if (spineAnimationState != null) |
| | | { |
| | | spineAnimationState.Complete -= OnAnimationComplete; |
| | | spineAnimationState.ClearTracks(); |
| | | spineAnimationState = null; |
| | | } |
| | | |
| | | skeletonGraphic = null; |
| | | skeleton = null; |
| | | currentTrackEntry = null; |
| | | |
| | | waitingTaskList.Clear(); |
| | | removeList.Clear(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | |
| | | #region 动画控制 |
| | | |
| | | |
| | | /// <summary> |
| | | /// 播放指定动画 |
| | | /// </summary> |
| | |
| | | public virtual Spine.TrackEntry PlayAnimation(MotionName motionName, bool loop) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | |
| | | // 直接使用 ToString() 而不是调用 GetAnimationName |
| | | return spineAnimationState.SetAnimation(0, motionName.ToString(), loop); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 播放指定动画(使用字符串名称) |
| | | /// </summary> |
| | | /// <param name="animationName">动画名称</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry PlayAnimation(string animationName, bool loop) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | return spineAnimationState.SetAnimation(0, animationName, loop); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加动画到队列 |
| | | /// </summary> |
| | | /// <param name="motionName">动画枚举</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <param name="delay">延迟时间</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry AddAnimation(MotionName motionName, bool loop, float delay) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | // 直接使用 ToString() 而不是调用 GetAnimationName |
| | | return spineAnimationState.AddAnimation(0, motionName.ToString(), loop, delay); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加动画到队列(使用字符串名称) |
| | | /// </summary> |
| | | /// <param name="animationName">动画名称</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <param name="delay">延迟时间</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry AddAnimation(string animationName, bool loop, float delay) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | return spineAnimationState.AddAnimation(0, animationName, loop, delay); |
| | | currentTrackEntry = spineAnimationState.SetAnimation(0, motionName.ToString(), loop); |
| | | return currentTrackEntry; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | string animation = trackEntry.Animation.Name; |
| | | |
| | | // 攻击动画完成后恢复到待机状态 |
| | | if (animation == MotionName.atk1.ToString() || |
| | | animation == MotionName.atk2.ToString()) |
| | | if (animation == MotionName.attack.ToString() || |
| | | animation == MotionName.angerSkill.ToString()) |
| | | { |
| | | OnAttackAnimationComplete?.Invoke(); |
| | | PlayAnimation(MotionName.idle, true); |
| | |
| | | { |
| | | OnHitAnimationComplete?.Invoke(); |
| | | PlayAnimation(MotionName.idle, true); |
| | | } |
| | | else |
| | | { |
| | | OnOtherAnimationComplete?.Invoke((MotionName)Enum.Parse(typeof(MotionName), animation)); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | removeList.Clear(); |
| | | } |
| | | |
| | | public virtual void Pause() |
| | | { |
| | | if (currentTrackEntry != null) |
| | | currentTrackEntry.TimeScale = 0f; |
| | | } |
| | | |
| | | public virtual void Resume() |
| | | { |
| | | if (currentTrackEntry != null) |
| | | currentTrackEntry.TimeScale = 1f; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | } |
| | |
| | | |
| | | // 每个武将都需有: |
| | | // 待机 |
| | | // 跑步 |
| | | // 被击 |
| | | // 死亡 |
| | | // 怒气技能动作 |
| | | // 普攻动作 |
| | | |
| | | |
| | | public enum MotionName |
| | | { |
| | | atk1, |
| | | atk2, |
| | | hit, |
| | | idle, |
| | | run, |
| | | idle,//待机 |
| | | run,//跑步 |
| | | hit,//被击 |
| | | dead,//死亡 |
| | | angerSkill,//怒气技能 |
| | | attack,//普攻 |
| | | } |
| | |
| | | |
| | | public class RecordAction |
| | | { |
| | | public RecordActionType actionType; |
| | | public int casterId; |
| | | protected BattleField battleField; |
| | | |
| | | public bool IsFinished() |
| | | protected BattleObject battleObject; |
| | | |
| | | public RecordAction(RecordActionType _actionType, BattleField _battleField, BattleObject _battleObj) |
| | | { |
| | | actionType = _actionType; |
| | | battleField = _battleField; |
| | | battleObject = _battleObj; |
| | | } |
| | | |
| | | public RecordActionType actionType; |
| | | |
| | | public virtual bool IsFinished() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | public void Run() |
| | | public virtual void Run() |
| | | { |
| | | |
| | | } |
| | |
| | | public enum RecordActionType |
| | | { |
| | | None, |
| | | Attack,//攻击 |
| | | Heal,//治疗 |
| | | Buff,//增益&减益 |
| | | Guard,//格挡 |
| | | Skill,//技能 |
| | | Death,//死亡 |
| | | } |
| | |
| | | battleField = _battleField; |
| | | } |
| | | |
| | | public bool IsPlaying() |
| | | { |
| | | return currentRecordAction != null || recordActionQueue.Count > 0; |
| | | } |
| | | |
| | | public void PlayRecord(RecordAction recordAction) |
| | | { |
| | | recordActionQueue.Enqueue(recordAction); |
| | |
| | | |
| | | public virtual void Run() |
| | | { |
| | | if (recordActionQueue.Count == 0) |
| | | if (currentRecordAction == null) |
| | | { |
| | | if (recordActionQueue.Count <= 0) |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | if (currentRecordAction != null && !currentRecordAction.IsFinished()) |
| | | { |
| | | currentRecordAction.Run(); |
| | | return; |
| | | } |
| | | |
| | | if (currentRecordAction == null || currentRecordAction.IsFinished()) |
| | | if (currentRecordAction != null && currentRecordAction.IsFinished()) |
| | | { |
| | | currentRecordAction = recordActionQueue.Dequeue(); |
| | | currentRecordAction = null; |
| | | } |
| | | |
| | | if (currentRecordAction != null) |
| | | if (currentRecordAction == null) |
| | | { |
| | | currentRecordAction.Run(); |
| | | if (recordActionQueue.Count > 0) |
| | | { |
| | | currentRecordAction = recordActionQueue.Dequeue(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 先预留 感觉用的上 |
| | | public virtual void ResumeGame() |
| | | { |
| | | |
| | | } |
| | | |
| | | public virtual void PauseGame() |
| | | { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: a1576f20f23a41249a6fd9f71fa49efa |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | using System.Collections.Generic; |
| | | |
| | | public class DirectlyDamageSkill : SkillBase |
| | | { |
| | | |
| | | public DirectlyDamageSkill(SkillConfig _skillCfg) : base(_skillCfg) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | base.Run(); |
| | | } |
| | | |
| | | public override void Cast(BattleObject _caster, BattleField _battleField, List<Dictionary<int, List<int>>> damageList) |
| | | { |
| | | _caster.PlaySkill(skillConfig, damageList, OnSkillAnimationFinished); |
| | | } |
| | | |
| | | protected void OnSkillAnimationFinished() |
| | | { |
| | | isFinished = true; |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | // 伤害列表理应由服务器发给客户端 这边只做粗浅模拟 |
| | | public override List<Dictionary<int, List<int>>> GetDamageList(BattleObject _caster, BattleField battleField) |
| | | { |
| | | List<Dictionary<int, List<int>>> damageList = new List<Dictionary<int, List<int>>>(); |
| | | |
| | | List<BattleObject> affectList = GetTargetList(_caster, battleField); |
| | | |
| | | Dictionary<int, List<int>> oneRoundDamage = new Dictionary<int, List<int>>(); |
| | | |
| | | for (int j = 0; j < affectList.Count; j++) |
| | | { |
| | | BattleObject obj = affectList[j]; |
| | | List<int> tryDmgList = _caster.TryAttack(obj, skillConfig); |
| | | oneRoundDamage.Add(obj.BattleObjectId, tryDmgList); |
| | | } |
| | | |
| | | damageList.Add(oneRoundDamage); |
| | | |
| | | return damageList; |
| | | } |
| | | #endif |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 6c38b8acedc80dc4594072a10e7df9d2 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | |
| | | public class SkillBase |
| | | { |
| | | protected SkillConfig skillConfig; |
| | | |
| | | protected bool isFinished = false; |
| | | |
| | | public SkillBase(SkillConfig _skillCfg) |
| | | { |
| | | skillConfig = _skillCfg; |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | |
| | | } |
| | | |
| | | public virtual void Cast(BattleObject _caster, BattleField battleField, List<Dictionary<int, List<int>>> damageList) |
| | | { |
| | | Debug.LogError("SkillBase Cast should be overridden by derived class"); |
| | | } |
| | | |
| | | public virtual bool IsFinished() |
| | | { |
| | | return isFinished; |
| | | } |
| | | |
| | | public virtual void ForceFinished() |
| | | { |
| | | isFinished = true; |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public virtual List<BattleObject> GetTargetList(BattleObject _caster, BattleField battleField) |
| | | { |
| | | SkillTargetType targetType = SkillTargetType.Enemy; |
| | | SkillTargetRangeType rangeType = SkillTargetRangeType.LowestHP; |
| | | |
| | | List<BattleObject> affectList = battleField.battleObjMgr.GetTargetList(_caster, targetType, rangeType); |
| | | return affectList; |
| | | } |
| | | |
| | | public virtual List<Dictionary<int, List<int>>> GetDamageList(BattleObject _caster, BattleField battleField) |
| | | { |
| | | Debug.LogError("SkillBase GetDamageList should be overridden by derived class"); |
| | | return null; |
| | | } |
| | | #endif |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 29aa0d4b5b5830a4990d8538740b9355 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | using UnityEngine; |
| | | |
| | | |
| | | public static class SkillFactory |
| | | { |
| | | // SkillType |
| | | // 技能类型 定义 |
| | | // 特殊 0 |
| | | // 攻击类 1 主动会造成瞬间伤害技能类型为1 |
| | | // 恢复类 2 主动会恢复生命值的技能类型为2 |
| | | // 持续增益BUFF 3 主动一段时间内间隔时间给予增益buff技能类型为3,比如持续回血 |
| | | // 持续减益BUFF 4 主动一段时间内间隔时间给予减益buff技能类型为4,比如中毒 |
| | | // 增益BUFF 5 主动持续一段时间给予增益buff,不会出现间隔时间buff类型为5,比如麒麟盾 |
| | | // 减益BUFF 6 主动持续一段时间给予减益buff,不会出现间隔时间buff类型为6,比如减速 |
| | | // 被动技 7 被动触发的技能类型为7 |
| | | // 复活 8 牧师复活队友技能,暂时无用 |
| | | // 增值技能(不可清除)9 和增益技能类似,无法点击图标取消,暂时无用 |
| | | // 光环技能 10 队友共享该技能的光环,类似魔兽争霸的强击光环,荆棘光环,暂时无这样技能 |
| | | // 装备技能 11 装备上附加了技能,比如套装附加攻击+50%,暂时无这样技能 |
| | | // 区域技能 12 "布怪器里 有个配置技能ID 比如配个火区域灼烧 |
| | | // " |
| | | // 召唤 13 主动召唤出一个怪物,则配置为13,暂时无这样的技能 |
| | | // 控制型BUFF 14 比如眩晕,定身技能需要配置控制型buff |
| | | // 多段伤害buff攻击类型(类xp技能) 15 多段伤害主动每秒伤害buff技能类型为15 |
| | | // 被动触发增益类buff 16 被动触发持续一段时间给予增益buff,不会出现间隔时间buff类型为16,如(50065疾风) |
| | | // 被动触发减益类buff 17 被动触发持续一段时间给予减益buff,不会出现间隔时间buff类型为17,如(50235负伤) |
| | | // 被动触发的控制类buff 18 被动触发持续一段时间的控制技能为17,如(50365激怒) |
| | | // 属性类技能 20(如坐骑属性,宠物属性) 被动增加了属性效果值,长期的技能为20,如(50605守护) |
| | | // 被动buff 19(暂时不知道干啥的) |
| | | // 被动触发持续类增益类buff 21 被动一段时间内间隔时间给予增益buff技能类型为3,比如(50635祝福) |
| | | // 被动触发持续类减益类buff 22 被动一段时间内间隔时间给予减益buff技能类型为4,比如毒龙嗜天 |
| | | |
| | | |
| | | // 攻击技能:本回合对敌人武将造成伤害 |
| | | // 治疗技能:本回合对已方武将回复生命值,回复生命值不可超过生命上限 |
| | | // 辅助技能:增加怒气、召唤、光环等 |
| | | // BUFF技能:提升已方属性的增益BUFF(加攻、加血、加状态等),降低敌方属性的减益BUFF(减攻、减血、控制等),持续多回合 |
| | | // 复活技能:复活已方已死武将并回复X生命值,复活:继承死亡前的所有状态(各种状态、各种BUFF、怒气值等),复活后错过本回合攻击时机则下一回合才能出手 |
| | | |
| | | |
| | | |
| | | public static SkillBase CreateSkill(SkillConfig _skillConfig) |
| | | { |
| | | SkillBase skill = null; |
| | | switch (_skillConfig.SkillType) |
| | | { |
| | | case 1: |
| | | skill = new DirectlyDamageSkill(_skillConfig); |
| | | break; |
| | | case 2: |
| | | // skill = new DirectlyHealSkill(_skillConfig); |
| | | break; |
| | | case 3: |
| | | // skill = new SupportSkill(_skillConfig); |
| | | break; |
| | | case 4: |
| | | // skill = new MountBuffSkill(_skillConfig); |
| | | break; |
| | | case 5: |
| | | // skill = new ReviveSkill(_skillConfig); |
| | | break; |
| | | default: |
| | | Debug.LogError("超出了技能类型范围 请检查配置"); |
| | | break; |
| | | } |
| | | |
| | | return skill; |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e2a0e020a4b71ca48aa80d5cb0536792 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | public int recoverResist = 0; |
| | | |
| | | // 特殊属性(待补充) |
| | | // 最终伤害 |
| | | public int finalDamageIncrease = 0; |
| | | // 最终免伤 |
| | | public int finalDamageReduce; |
| | | // 爆伤 |
| | | public int critDamageIncrease; |
| | | // 减少爆伤 |
| | | public int critDamageReduce; |
| | | // 治疗增益 |
| | | public int healIncrease; |
| | | // 治疗减益 |
| | | public int healReduce; |
| | | // 物理增伤 |
| | | public int damageIncrease; |
| | | // 减少物伤 |
| | | public int damageReduce; |
| | | // 法术增伤 |
| | | public int magicIncrease; |
| | | // 减少法伤 |
| | | public int magicReduce; |
| | | // 普攻增伤 |
| | | public int normalAttackIncrease; |
| | | // 减少普攻伤害 |
| | | public int normalAttackReduce; |
| | | // 增加技能伤害 |
| | | public int rageSkillAttackIncrease; |
| | | // 减少技能伤害 |
| | | public int rageSkillAttackReduce; |
| | | // 增加持续伤害的百分比 |
| | | public int continousSkillIncrease; |
| | | // 减少持续伤害的百分比 |
| | | public int continousSkillReduce; |
| | | // 增加护盾百分比 |
| | | public int shieldSkillIncrease; |
| | | // 减少护盾百分比 |
| | | public int shieldSkillReduce; |
| | | |
| | | |
| | | //计算个人/职业/种族养成属性加成 |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class HeroInfo |
| | | { |
| | |
| | | { |
| | | get |
| | | { |
| | | #if UNITY_EDITOR |
| | | if (null == itemHero) |
| | | { |
| | | return 520001; |
| | | } |
| | | #endif |
| | | |
| | | return itemHero.config.ID; |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | public readonly ItemModel itemHero; |
| | | public ItemModel itemHero; |
| | | |
| | | public readonly CB122_tagSCHeroInfo.tagSCHero scHeroInfo; |
| | | // public readonly CB122_tagSCHeroInfo.tagSCHero scHeroInfo; |
| | | |
| | | // 武将配置 |
| | | public HeroConfig heroConfig; |
| | |
| | | public List<HeroTalentInfo> talentList = new List<HeroTalentInfo>(); |
| | | |
| | | |
| | | public HeroInfo(CB122_tagSCHeroInfo.tagSCHero _scHeroInfo, ItemModel _itemHero) |
| | | public HeroInfo(/*CB122_tagSCHeroInfo.tagSCHero _scHeroInfo, */ItemModel _itemHero) |
| | | { |
| | | scHeroInfo = _scHeroInfo; |
| | | itemHero = _itemHero; |
| | | // scHeroInfo = _scHeroInfo; |
| | | UpdateHero(_itemHero); |
| | | |
| | | |
| | | InitConfigs(); |
| | | |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public HeroInfo() |
| | | { |
| | | heroLevel = 1; |
| | | heroStar = 1; |
| | | breakLevel = 1; |
| | | awakeLevel = 1; |
| | | SkinIndex = 0; |
| | | heroConfig = HeroConfig.Get(heroId); |
| | | awakeConfig = HeroAwakeConfig.GetHeroAwakeConfig(heroId, awakeLevel); |
| | | breakConfig = HeroBreakConfig.GetHeroBreakConfig(heroId, breakLevel); |
| | | qualityAwakeConfig = HeroQualityAwakeConfig.GetQualityAwakeConfig(Quality, awakeLevel); |
| | | qualityConfig = HeroQualityConfig.Get(Quality); |
| | | qualityBreakConfig = HeroQualityBreakConfig.GetQualityBreakConfig(Quality, awakeLevel); |
| | | CalculateProperties(); |
| | | } |
| | | #endif |
| | | |
| | | // public HeroInfo Clone() => JsonMapper.ToObject<HeroInfo>(JsonMapper.ToJson(this)); |
| | | |
| | | // 图鉴信息 |
| | | public void UpdateSCHero(CB122_tagSCHeroInfo.tagSCHero _scHeroInfo) |
| | | { |
| | | |
| | | } |
| | | |
| | | public void UpdateHero(ItemModel _itemHero) |
| | | { |
| | | itemHero = _itemHero; |
| | | // HeroConfigUtility |
| | | |
| | | // 70 # 英雄等级 |
| | |
| | | // 78 # 英雄使用的皮肤索引 |
| | | SkinIndex = itemHero.GetUseData(78)[0]; |
| | | |
| | | |
| | | // 71 # 英雄天赋ID列表 |
| | | List<int> talentSkillList = itemHero.GetUseData(71); |
| | | // 73 # 英雄天赋ID等级列表,对应71天赋ID的等级 |
| | | List<int> talentLvList = itemHero.GetUseData(73); |
| | | // 75 # 英雄天赋洗炼锁定索引列表,对应71天赋ID索引 |
| | | List<int> talentLockList = itemHero.GetUseData(75); |
| | | |
| | | InitConfigs(); |
| | | |
| | | if (talentLockList.Count != talentLvList.Count || talentLvList.Count != talentSkillList.Count) |
| | | { |
| | |
| | | // 77 # 英雄天赋洗炼随机ID列表 |
| | | // 79 # 英雄觉醒时随机天赋选项ID列表 |
| | | // 80 # 主阵型上阵位置 |
| | | |
| | | |
| | | } |
| | | |
| | | protected void InitConfigs() |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | |
| | | public class HeroManager : GameSystemManager<HeroManager> |
| | | { |
| | | protected Dictionary<long, HeroInfo> heroInfoDict = new Dictionary<long, HeroInfo>(); |
| | | protected Dictionary<string, HeroInfo> heroInfoDict = new Dictionary<string, HeroInfo>(); |
| | | |
| | | public Action<HeroInfo> onNewHeroEvent; |
| | | |
| | | public Action<HeroInfo> onHeroChangeEvent; |
| | | |
| | | public override void Init() |
| | | { |
| | | base.Init(); |
| | | |
| | | // 注册一点事件 |
| | | PackManager.Instance.refrechPackEvent += refrechPackEvent; |
| | | } |
| | | |
| | | public override void Release() |
| | | { |
| | | base.Release(); |
| | | PackManager.Instance.refrechPackEvent -= refrechPackEvent; |
| | | } |
| | | |
| | | public override void RequestNessaryData() |
| | |
| | | |
| | | } |
| | | |
| | | public void UpdateHeroInfo() |
| | | public void refrechPackEvent(PackType packType) |
| | | { |
| | | |
| | | if (packType == PackType.Hero) |
| | | { |
| | | // bool change = false; |
| | | bool isNew = false; |
| | | // 如果有分批次初始化可能还要麻烦一点?先看看 |
| | | bool isInit = heroInfoDict.Count >= 0; |
| | | |
| | | SinglePack heroPack = PackManager.Instance.GetSinglePack(packType); |
| | | |
| | | Dictionary<int, ItemModel> heroes = heroPack.GetAllItems(); |
| | | |
| | | foreach (ItemModel hero in heroes.Values) |
| | | { |
| | | HeroInfo heroInfo = null; |
| | | if (!heroInfoDict.TryGetValue(hero.guid, out heroInfo)) |
| | | { |
| | | heroInfo = new HeroInfo(hero); |
| | | heroInfoDict.Add(hero.guid, heroInfo); |
| | | if (!isInit) |
| | | { |
| | | isNew = true; |
| | | onNewHeroEvent?.Invoke(heroInfo); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | heroInfo.UpdateHero(hero); |
| | | // 也有可能不是change |
| | | // change = true; |
| | | // onHeroChangeEvent?.Invoke(heroInfo); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public List<HeroInfo> GetPowerfulHeroList() |
| | |
| | | case 4: |
| | | //currentSubUI = UIManager.Instance.OpenWindow<PlaceWin>(); |
| | | Debug.Log("打开冒险界面"); |
| | | BattleWin battleWin = UIManager.Instance.OpenWindow<BattleWin>(); |
| | | currentSubUI = battleWin; |
| | | break; |
| | | default: |
| | | Debug.LogWarning("未知的标签索引: " + index); |
| | |
| | | |
| | | // 阵型内卡牌的羁绊增益 |
| | | |
| | | public int fightPower = 0; |
| | | |
| | | protected void UpdateProperties() |
| | | { |
| | | // 羁绊 |
| | |
| | | |
| | | public void CalculatePower() |
| | | { |
| | | |
| | | // fightPower//的计算 |
| | | } |
| | | } |
| | |
| | | |
| | | public partial class TeamBase |
| | | { |
| | | public TeamHero[] teamHeros = new TeamHero[TeamConst.MaxTeamHeroCount]; |
| | | public TeamHero[] teamHeros = new TeamHero[TeamConst.MaxTeamSlotCount]; |
| | | |
| | | public int GetTeamHeroCount() |
| | | { |
| | |
| | | } |
| | | |
| | | return count; |
| | | } |
| | | } |
| | | |
| | | public bool SwapTeamHero(int index1, int index2) |
| | | { |
| | |
| | | { |
| | | |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public void FillWithFakeData() |
| | | { |
| | | for (int i = 0; i < TeamConst.MaxTeamHeroCount; i++) |
| | | { |
| | | TeamHero hero = new TeamHero(); |
| | | hero.curHp = 100; |
| | | hero.attack = UnityEngine.Random.Range(300, 500); |
| | | hero.defense = UnityEngine.Random.Range(80, 100); |
| | | hero.heroInfo = new HeroInfo(); |
| | | hero.teamBase = this; |
| | | hero.heroIndex = i; |
| | | teamHeros[i] = hero; |
| | | } |
| | | } |
| | | #endif |
| | | } |
| | |
| | | |
| | | public class TeamConst |
| | | { |
| | | public const int MaxTeamHeroCount = 6; |
| | | public const int MaxTeamHeroCount = 6;//最大布阵数量 |
| | | public const int MaxTeamSlotCount = 7;//最大槽位数量 |
| | | } |
New file |
| | |
| | | |
| | | |
| | | public partial class TeamHero |
| | | { |
| | | // 基础属性 |
| | | // 生命 |
| | | public int hp = 0; |
| | | // 攻击力 |
| | | public int attack = 0; |
| | | // 防御力 |
| | | public int defense = 0; |
| | | |
| | | |
| | | //战斗属性 击晕、暴击、连击、格挡、反击、吸血 |
| | | //眩晕概率 |
| | | public int stunRate = 0; |
| | | //暴击概率 |
| | | public int critRate = 0; |
| | | //连击概率 |
| | | public int comboRate = 0; |
| | | //格挡概率 |
| | | public int blockRate = 0; |
| | | //反击概率 |
| | | public int counterAttackRate = 0; |
| | | //攻击目标时,造成伤害转化成生命的百分比数值提升 |
| | | public int recoverRate = 0; |
| | | |
| | | //战斗抵抗属性 |
| | | //眩晕抵抗 |
| | | public int stunResist = 0; |
| | | //暴击抵抗 |
| | | public int critResist = 0; |
| | | //连击抵抗 |
| | | public int comboResist = 0; |
| | | //格挡抵抗 |
| | | public int blockResist = 0; |
| | | //反击抵抗 |
| | | public int counterAttackResist = 0; |
| | | //减少攻击时吸血转化成生命的百分比数值 |
| | | public int recoverResist = 0; |
| | | |
| | | |
| | | |
| | | |
| | | // 当前属性 |
| | | |
| | | // 怒气值 |
| | | public int rage = 0; |
| | | |
| | | // 当前血量 |
| | | public int curHp; |
| | | |
| | | // 最大血量 |
| | | public int maxHp; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 2f2a7e0a26d12c945829628eb982b0e4 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | |
| | | public partial class TeamHero |
| | | { |
| | | // 状态说明 |
| | | // 正常状态:可以正常进行战斗。 |
| | | // 控制状态:有眩晕、石化、冰冻等状态,持续X回合;其中冰冻状态中被攻击X次,可提前解除控制状态; 当角色处于控制状态时,武将无法进行普攻、无法释技能、不可触发释反击、追击等 |
| | | // 沉默状态:不可释放技能,可普攻 |
| | | // 缴械状态:无法进行普攻、追击、连击,可释放技能 |
| | | // 无敌状态:武将所受的伤害不扣血,可被攻击、治疗、添加BUFF |
| | | // 死亡状态:武将生命值为0时,从战斗消失,无法继续战斗。 |
| | | |
| | | public bool isStunned = false; |
| | | |
| | | public bool isStoned = false; |
| | | |
| | | public bool isFrozen = false; |
| | | |
| | | public bool isSlient = false; |
| | | |
| | | public bool isDisarmed = false; |
| | | |
| | | public bool isInvinceble = false; |
| | | |
| | | public bool isDead |
| | | { |
| | | get |
| | | { |
| | | return curHp <= 0; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 61b6dabe91e01264984e600d39ee34fe |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | |
| | | |
| | | public class TeamHero |
| | | public partial class TeamHero |
| | | { |
| | | public HeroInfo heroInfo; |
| | | public TeamBase teamBase; |
| | | public int heroIndex; |
| | | |
| | | public void MergeProperties() |
| | | { |
| | | if (heroInfo == null) |
| | | { |
| | | return; |
| | | } |
| | | // 最终属性 当前属性应该是要在这一层的 |
| | | |
| | | } |
| | | public int GetPower() |
| | | { |
| | | return heroInfo.CalculatePower(); |
| | | } |
| | | } |
| | |
| | | |
| | | if (!teamDict.TryGetValue(teamType, out team)) |
| | | { |
| | | team = GetStoryTeam(); |
| | | teamDict.Add(teamType, team); |
| | | } |
| | | |
| | | return team; |
| | | } |
| | | |
| | | public TeamBase GetStoryTeam() |
| | | { |
| | | TeamBase team = null; |
| | | |
| | | if (!teamDict.TryGetValue(TeamType.Story, out team)) |
| | | { |
| | | team = new TeamBase(); |
| | | team.AddTeamHeros(HeroManager.Instance.GetPowerfulHeroList()); |
| | | teamDict.Add(TeamType.Story, team); |
| | | teamDict.Add(teamType, team); |
| | | } |
| | | |
| | | return team; |
| | |
| | | { |
| | | public static void DelayFrame(this GameObject go, Action action) |
| | | { |
| | | DelayFrameInternal(action); |
| | | DelayFrameInternal(1, action); |
| | | } |
| | | |
| | | public static void DelayFrame(this Component cmp, Action action) |
| | | { |
| | | DelayFrameInternal(action); |
| | | DelayFrameInternal(1, action); |
| | | } |
| | | |
| | | private async static UniTask DelayFrameInternal(Action action) |
| | | private async static UniTask DelayFrameInternal(int frame, Action action) |
| | | { |
| | | await UniTask.DelayFrame(1); |
| | | await UniTask.DelayFrame(frame); |
| | | action?.Invoke(); |
| | | } |
| | | |
| | | public static void DelayFrames(this Component cmp, int frames, Action action) |
| | | { |
| | | DelayFrameInternal(frames, action); |
| | | } |
| | | |
| | | public static void DelayFrames(this GameObject go, int frames, Action action) |
| | | { |
| | | DelayFrameInternal(frames, action); |
| | | } |
| | | } |
| | |
| | | public static class VesselExtension |
| | | { |
| | | |
| | | public static System.Random rng = new System.Random(); |
| | | |
| | | public static bool IsNullOrEmpty<T>(this List<T> vessel) |
| | | { |
| | | return vessel == null || vessel.Count == 0; |
| | |
| | | return list[randomIndex]; |
| | | } |
| | | |
| | | public static List<T> Shuffle<T>(this IList<T> list) |
| | | { |
| | | var shuffled = new List<T>(list); // 创建副本 |
| | | for (int i = shuffled.Count - 1; i > 0; i--) |
| | | { |
| | | int j = rng.Next(i + 1); |
| | | (shuffled[i], shuffled[j]) = (shuffled[j], shuffled[i]); |
| | | } |
| | | return shuffled; |
| | | } |
| | | } |