799 lines
25 KiB
C#
799 lines
25 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace TcgEngine
|
|
{
|
|
//Represent the current state of a card during the game (data only)
|
|
|
|
[System.Serializable]
|
|
public class Card
|
|
{
|
|
public string card_id;
|
|
public string uid;
|
|
public int player_id;
|
|
public string variant_id;
|
|
|
|
public Slot slot;
|
|
public bool exhausted;
|
|
public int damage = 0;
|
|
|
|
public int mana = 0;
|
|
public int attack = 0;
|
|
public int hp = 0;
|
|
|
|
// 新增:三种元素法力值
|
|
public int mana_fire = 0;
|
|
public int mana_forest = 0;
|
|
public int mana_water = 0;
|
|
|
|
// 新增:三种元素法力值的临时加成
|
|
public int mana_fire_ongoing = 0;
|
|
public int mana_forest_ongoing = 0;
|
|
public int mana_water_ongoing = 0;
|
|
|
|
public int mana_ongoing = 0;
|
|
public int attack_ongoing = 0;
|
|
public int hp_ongoing = 0;
|
|
|
|
public string equipped_uid = null;
|
|
|
|
public List<CardTrait> traits = new List<CardTrait>();
|
|
public List<CardTrait> ongoing_traits = new List<CardTrait>();
|
|
|
|
public List<CardStatus> status = new List<CardStatus>();
|
|
public List<CardStatus> ongoing_status = new List<CardStatus>();
|
|
|
|
public List<string> abilities = new List<string>();
|
|
public List<string> abilities_ongoing = new List<string>();
|
|
|
|
[System.NonSerialized] private int hash = 0;
|
|
[System.NonSerialized] private CardData data = null;
|
|
[System.NonSerialized] private VariantData vdata = null;
|
|
[System.NonSerialized] private List<AbilityData> abilities_data = null;
|
|
|
|
public Card(string card_id, string uid, int player_id) { this.card_id = card_id; this.uid = uid; this.player_id = player_id; }
|
|
|
|
public virtual void Refresh() { exhausted = false; }
|
|
public virtual void ClearOngoing()
|
|
{
|
|
ongoing_status.Clear(); ongoing_traits.Clear(); ClearOngoingAbility(); attack_ongoing = 0; hp_ongoing = 0; mana_ongoing = 0;
|
|
// 新增:清除元素法力值临时加成
|
|
mana_fire_ongoing = 0;
|
|
mana_forest_ongoing = 0;
|
|
mana_water_ongoing = 0;
|
|
}
|
|
|
|
public virtual void Clear()
|
|
{
|
|
ClearOngoing(); Refresh(); damage = 0; status.Clear();
|
|
SetCard(CardData, VariantData); //Reset to initial stats
|
|
equipped_uid = null;
|
|
}
|
|
|
|
public virtual int GetAttack() { return Mathf.Max(attack + attack_ongoing, 0); }
|
|
public virtual int GetHP() { return Mathf.Max(hp + hp_ongoing - damage, 0); }
|
|
public virtual int GetHP(int offset) { return Mathf.Max(hp + hp_ongoing - damage + offset, 0); }
|
|
public virtual int GetHPMax() { return Mathf.Max(hp + hp_ongoing, 0); }
|
|
public virtual int GetMana() { return Mathf.Max(mana + mana_ongoing, 0); }
|
|
|
|
public virtual void SetCard(CardData icard, VariantData cvariant)
|
|
{
|
|
data = icard;
|
|
card_id = icard.id;
|
|
variant_id = cvariant.id;
|
|
attack = icard.attack;
|
|
hp = icard.hp;
|
|
// 设置法力值
|
|
mana = icard.mana;
|
|
mana_fire = icard.mana_fire;
|
|
mana_forest = icard.mana_forest;
|
|
mana_water = icard.mana_water;
|
|
SetTraits(icard);
|
|
SetAbilities(icard);
|
|
}
|
|
|
|
public void SetTraits(CardData icard)
|
|
{
|
|
traits.Clear();
|
|
foreach (TraitData trait in icard.traits)
|
|
SetTrait(trait.id, 0);
|
|
if (icard.stats != null)
|
|
{
|
|
foreach (TraitStat stat in icard.stats)
|
|
SetTrait(stat.trait.id, stat.value);
|
|
}
|
|
}
|
|
|
|
public void SetAbilities(CardData icard)
|
|
{
|
|
abilities.Clear();
|
|
abilities_ongoing.Clear();
|
|
if (abilities_data != null)
|
|
abilities_data.Clear();
|
|
foreach (AbilityData ability in icard.abilities)
|
|
AddAbility(ability);
|
|
}
|
|
|
|
//------ Custom Traits/Stats ---------
|
|
|
|
public void SetTrait(string id, int value)
|
|
{
|
|
CardTrait trait = GetTrait(id);
|
|
if (trait != null)
|
|
{
|
|
trait.value = value;
|
|
}
|
|
else
|
|
{
|
|
trait = new CardTrait(id, value);
|
|
traits.Add(trait);
|
|
}
|
|
}
|
|
|
|
public void AddTrait(string id, int value)
|
|
{
|
|
CardTrait trait = GetTrait(id);
|
|
if (trait != null)
|
|
trait.value += value;
|
|
else
|
|
SetTrait(id, value);
|
|
}
|
|
|
|
public void AddOngoingTrait(string id, int value)
|
|
{
|
|
CardTrait trait = GetOngoingTrait(id);
|
|
if (trait != null)
|
|
{
|
|
trait.value += value;
|
|
}
|
|
else
|
|
{
|
|
trait = new CardTrait(id, value);
|
|
ongoing_traits.Add(trait);
|
|
}
|
|
}
|
|
|
|
public void RemoveTrait(string id)
|
|
{
|
|
for (int i = traits.Count - 1; i >= 0; i--)
|
|
{
|
|
if (traits[i].id == id)
|
|
traits.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
public CardTrait GetTrait(string id)
|
|
{
|
|
foreach (CardTrait trait in traits)
|
|
{
|
|
if (trait.id == id)
|
|
return trait;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public CardTrait GetOngoingTrait(string id)
|
|
{
|
|
foreach (CardTrait trait in ongoing_traits)
|
|
{
|
|
if (trait.id == id)
|
|
return trait;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public int GetTraitValue(TraitData trait)
|
|
{
|
|
if (trait != null)
|
|
return GetTraitValue(trait.id);
|
|
return 0;
|
|
}
|
|
|
|
public virtual int GetTraitValue(string id)
|
|
{
|
|
int val = 0;
|
|
CardTrait stat1 = GetTrait(id);
|
|
CardTrait stat2 = GetOngoingTrait(id);
|
|
if (stat1 != null)
|
|
val += stat1.value;
|
|
if (stat2 != null)
|
|
val += stat2.value;
|
|
return val;
|
|
}
|
|
|
|
public bool HasTrait(TraitData trait)
|
|
{
|
|
if (trait != null)
|
|
return HasTrait(trait.id);
|
|
return false;
|
|
}
|
|
|
|
public bool HasTrait(string id)
|
|
{
|
|
return GetTrait(id) != null || GetOngoingTrait(id) != null;
|
|
}
|
|
|
|
public List<CardTrait> GetAllTraits()
|
|
{
|
|
List<CardTrait> all_traits = new List<CardTrait>();
|
|
all_traits.AddRange(traits);
|
|
all_traits.AddRange(ongoing_traits);
|
|
return all_traits;
|
|
}
|
|
|
|
//Alternate names since traits/stats are stored in same var
|
|
public void SetStat(string id, int value) => SetTrait(id, value);
|
|
public void AddStat(string id, int value) => AddTrait(id, value);
|
|
public void AddOngoingStat(string id, int value) => AddOngoingTrait(id, value);
|
|
public void RemoveStat(string id) => RemoveTrait(id);
|
|
public int GetStatValue(TraitData trait) => GetTraitValue(trait);
|
|
public int GetStatValue(string id) => GetTraitValue(id);
|
|
public bool HasStat(TraitData trait) => HasTrait(trait);
|
|
public bool HasStat(string id) => HasTrait(id);
|
|
public List<CardTrait> GetAllStats() => GetAllTraits();
|
|
|
|
// 新增:获取元素法力值的方法
|
|
public virtual int GetManaFire() { return Mathf.Max(mana_fire + mana_fire_ongoing, 0); }
|
|
public virtual int GetManaForest() { return Mathf.Max(mana_forest + mana_forest_ongoing, 0); }
|
|
public virtual int GetManaWater() { return Mathf.Max(mana_water + mana_water_ongoing, 0); }
|
|
|
|
|
|
// 新增:设置元素法力值的方法
|
|
public void SetManaFire(int value) { mana_fire = value; }
|
|
public void SetManaForest(int value) { mana_forest = value; }
|
|
public void SetManaWater(int value) { mana_water = value; }
|
|
|
|
// 新增:增加元素法力值的方法
|
|
public void AddManaFire(int value) { mana_fire += value; }
|
|
public void AddManaForest(int value) { mana_forest += value; }
|
|
public void AddManaWater(int value) { mana_water += value; }
|
|
|
|
// 新增:增加元素法力值临时加成的方法
|
|
public void AddManaFireOngoing(int value) { mana_fire_ongoing += value; }
|
|
public void AddManaForestOngoing(int value) { mana_forest_ongoing += value; }
|
|
public void AddManaWaterOngoing(int value) { mana_water_ongoing += value; }
|
|
|
|
//------ Status Effects ---------
|
|
|
|
public void AddStatus(StatusData status, int value, int duration)
|
|
{
|
|
if (status != null)
|
|
AddStatus(status.effect, value, duration);
|
|
}
|
|
|
|
public void AddOngoingStatus(StatusData status, int value)
|
|
{
|
|
if (status != null)
|
|
AddOngoingStatus(status.effect, value);
|
|
}
|
|
|
|
public void AddStatus(StatusType type, int value, int duration)
|
|
{
|
|
if (type != StatusType.None)
|
|
{
|
|
CardStatus status = GetStatus(type);
|
|
if (status == null)
|
|
{
|
|
status = new CardStatus(type, value, duration);
|
|
this.status.Add(status);
|
|
}
|
|
else
|
|
{
|
|
status.value += value;
|
|
status.duration = Mathf.Max(status.duration, duration);
|
|
status.permanent = status.permanent || duration == 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void AddOngoingStatus(StatusType type, int value)
|
|
{
|
|
if (type != StatusType.None)
|
|
{
|
|
CardStatus status = GetOngoingStatus(type);
|
|
if (status == null)
|
|
{
|
|
status = new CardStatus(type, value, 0);
|
|
ongoing_status.Add(status);
|
|
}
|
|
else
|
|
{
|
|
status.value += value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RemoveStatus(StatusType type)
|
|
{
|
|
for (int i = status.Count - 1; i >= 0; i--)
|
|
{
|
|
if (status[i].type == type)
|
|
status.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
public List<CardStatus> GetAllStatus()
|
|
{
|
|
List<CardStatus> all_status = new List<CardStatus>();
|
|
all_status.AddRange(status);
|
|
all_status.AddRange(ongoing_status);
|
|
return all_status;
|
|
}
|
|
|
|
public bool HasStatus(StatusType type)
|
|
{
|
|
return GetStatus(type) != null || GetOngoingStatus(type) != null;
|
|
}
|
|
|
|
public CardStatus GetStatus(StatusType type)
|
|
{
|
|
foreach (CardStatus status in status)
|
|
{
|
|
if (status.type == type)
|
|
return status;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public CardStatus GetOngoingStatus(StatusType type)
|
|
{
|
|
foreach (CardStatus status in ongoing_status)
|
|
{
|
|
if (status.type == type)
|
|
return status;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public virtual int GetStatusValue(StatusType type)
|
|
{
|
|
CardStatus status1 = GetStatus(type);
|
|
CardStatus status2 = GetOngoingStatus(type);
|
|
int v1 = status1 != null ? status1.value : 0;
|
|
int v2 = status2 != null ? status2.value : 0;
|
|
return v1 + v2;
|
|
}
|
|
|
|
public virtual void ReduceStatusDurations()
|
|
{
|
|
for (int i = status.Count - 1; i >= 0; i--)
|
|
{
|
|
if (!status[i].permanent)
|
|
{
|
|
status[i].duration -= 1;
|
|
if (status[i].duration <= 0)
|
|
status.RemoveAt(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
//----- Abilities ------------
|
|
|
|
public void AddAbility(AbilityData ability)
|
|
{
|
|
abilities.Add(ability.id);
|
|
if (abilities_data != null)
|
|
abilities_data.Add(ability);
|
|
}
|
|
|
|
public void RemoveAbility(AbilityData ability)
|
|
{
|
|
abilities.Remove(ability.id);
|
|
if (abilities_data != null)
|
|
abilities_data.Remove(ability);
|
|
}
|
|
|
|
public void AddOngoingAbility(AbilityData ability)
|
|
{
|
|
if (!abilities_ongoing.Contains(ability.id) && !abilities.Contains(ability.id))
|
|
{
|
|
abilities_ongoing.Add(ability.id);
|
|
if (abilities_data != null)
|
|
abilities_data.Add(ability);
|
|
}
|
|
}
|
|
|
|
public void ClearOngoingAbility()
|
|
{
|
|
if (abilities_data != null)
|
|
{
|
|
for (int i = abilities_data.Count - 1; i >= 0; i--)
|
|
{
|
|
AbilityData ability = abilities_data[i];
|
|
if (abilities_ongoing.Contains(ability.id))
|
|
abilities_data.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
abilities_ongoing.Clear();
|
|
}
|
|
|
|
public AbilityData GetAbility(AbilityTrigger trigger)
|
|
{
|
|
foreach (AbilityData iability in GetAbilities())
|
|
{
|
|
if (iability.trigger == trigger)
|
|
return iability;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public bool HasAbility(AbilityData ability)
|
|
{
|
|
foreach (AbilityData iability in GetAbilities())
|
|
{
|
|
if (iability.id == ability.id)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool HasAbility(AbilityTrigger trigger)
|
|
{
|
|
AbilityData iability = GetAbility(trigger);
|
|
if (iability != null)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public bool HasAbility(AbilityTrigger trigger, AbilityTarget target)
|
|
{
|
|
foreach (AbilityData iability in GetAbilities())
|
|
{
|
|
if (iability.trigger == trigger && iability.target == target)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool HasActiveAbility(Game data, AbilityTrigger trigger)
|
|
{
|
|
AbilityData iability = GetAbility(trigger);
|
|
if (iability != null && CanDoAbilities() && iability.AreTriggerConditionsMet(data, this))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public bool AreAbilityConditionsMet(AbilityTrigger ability_trigger, Game data, Card caster, Card triggerer)
|
|
{
|
|
foreach (AbilityData ability in GetAbilities())
|
|
{
|
|
if (ability && ability.trigger == ability_trigger && ability.AreTriggerConditionsMet(data, caster, triggerer))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public List<AbilityData> GetAbilities()
|
|
{
|
|
//Load abilities data, important to do this here since this array will be null after being sent through networking (cant serialize it)
|
|
if (abilities_data == null)
|
|
{
|
|
abilities_data = new List<AbilityData>(abilities.Count + abilities_ongoing.Count);
|
|
for (int i = 0; i < abilities.Count; i++)
|
|
abilities_data.Add(AbilityData.Get(abilities[i]));
|
|
for (int i = 0; i < abilities_ongoing.Count; i++)
|
|
abilities_data.Add(AbilityData.Get(abilities_ongoing[i]));
|
|
}
|
|
|
|
//Return
|
|
return abilities_data;
|
|
}
|
|
|
|
//---- Action Check ---------
|
|
|
|
public virtual bool CanAttack(bool skip_cost = false)
|
|
{
|
|
if (HasStatus(StatusType.Paralysed))
|
|
return false;
|
|
if (!skip_cost && exhausted)
|
|
return false; //no more action
|
|
return true;
|
|
}
|
|
|
|
public virtual bool CanMove(bool skip_cost = false)
|
|
{
|
|
//In demo we can move freely, since it has no effect
|
|
//if (HasStatusEffect(StatusEffect.Paralysed))
|
|
// return false;
|
|
//if (!skip_cost && exhausted)
|
|
// return false; //no more action
|
|
return true;
|
|
}
|
|
|
|
public virtual bool CanDoActivatedAbilities()
|
|
{
|
|
if (HasStatus(StatusType.Paralysed))
|
|
return false;
|
|
if (HasStatus(StatusType.Silenced))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public virtual bool CanDoAbilities()
|
|
{
|
|
if (HasStatus(StatusType.Silenced))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
public virtual bool CanDoAnyAction()
|
|
{
|
|
return CanAttack() || CanMove() || CanDoActivatedAbilities();
|
|
}
|
|
|
|
//----------------
|
|
|
|
public CardData CardData
|
|
{
|
|
get
|
|
{
|
|
if (data == null || data.id != card_id)
|
|
data = CardData.Get(card_id); //Optimization, store for future use
|
|
return data;
|
|
}
|
|
}
|
|
|
|
public VariantData VariantData
|
|
{
|
|
get
|
|
{
|
|
if (vdata == null || vdata.id != variant_id)
|
|
vdata = VariantData.Get(variant_id); //Optimization, store for future use
|
|
return vdata;
|
|
}
|
|
}
|
|
|
|
public CardData Data => CardData; //Alternate name
|
|
|
|
public int Hash
|
|
{
|
|
get
|
|
{
|
|
if (hash == 0)
|
|
hash = Mathf.Abs(uid.GetHashCode()); //Optimization, store for future use
|
|
return hash;
|
|
}
|
|
}
|
|
|
|
public static Card Create(CardData icard, VariantData ivariant, Player player)
|
|
{
|
|
return Create(icard, ivariant, player, GameTool.GenerateRandomID(11, 15));
|
|
}
|
|
|
|
public static Card Create(CardData icard, VariantData ivariant, Player player, string uid)
|
|
{
|
|
Card card = new Card(icard.id, uid, player.player_id);
|
|
card.SetCard(icard, ivariant);
|
|
player.cards_all[card.uid] = card;
|
|
return card;
|
|
}
|
|
|
|
public static Card CloneNew(Card source)
|
|
{
|
|
Card card = new Card(source.card_id, source.uid, source.player_id);
|
|
Clone(source, card);
|
|
return card;
|
|
}
|
|
|
|
//Clone all card variables into another var, used mostly by the AI when building a prediction tree
|
|
public static void Clone(Card source, Card dest)
|
|
{
|
|
dest.card_id = source.card_id;
|
|
dest.uid = source.uid;
|
|
dest.player_id = source.player_id;
|
|
|
|
dest.variant_id = source.variant_id;
|
|
dest.slot = source.slot;
|
|
dest.exhausted = source.exhausted;
|
|
dest.damage = source.damage;
|
|
|
|
dest.attack = source.attack;
|
|
dest.hp = source.hp;
|
|
dest.mana = source.mana;
|
|
|
|
dest.mana_fire = source.mana_fire;
|
|
dest.mana_forest = source.mana_forest;
|
|
dest.mana_water = source.mana_water;
|
|
|
|
dest.mana_fire_ongoing = source.mana_fire_ongoing;
|
|
dest.mana_forest_ongoing = source.mana_forest_ongoing;
|
|
dest.mana_water_ongoing = source.mana_water_ongoing;
|
|
|
|
dest.mana_ongoing = source.mana_ongoing;
|
|
dest.attack_ongoing = source.attack_ongoing;
|
|
dest.hp_ongoing = source.hp_ongoing;
|
|
|
|
dest.equipped_uid = source.equipped_uid;
|
|
|
|
CardTrait.CloneList(source.traits, dest.traits);
|
|
CardTrait.CloneList(source.ongoing_traits, dest.ongoing_traits);
|
|
CardStatus.CloneList(source.status, dest.status);
|
|
CardStatus.CloneList(source.ongoing_status, dest.ongoing_status);
|
|
GameTool.CloneList(source.abilities, dest.abilities);
|
|
GameTool.CloneList(source.abilities_ongoing, dest.abilities_ongoing);
|
|
GameTool.CloneListRefNull(source.abilities_data, ref dest.abilities_data); //No need to deep copy since AbilityData doesn't change dynamically, its just a reference
|
|
}
|
|
|
|
//Clone a var that could be null
|
|
public static void CloneNull(Card source, ref Card dest)
|
|
{
|
|
//Source is null
|
|
if (source == null)
|
|
{
|
|
dest = null;
|
|
return;
|
|
}
|
|
|
|
//Dest is null
|
|
if (dest == null)
|
|
{
|
|
dest = CloneNew(source);
|
|
return;
|
|
}
|
|
|
|
//Both arent null, just clone
|
|
Clone(source, dest);
|
|
}
|
|
|
|
//Clone dictionary completely
|
|
public static void CloneDict(Dictionary<string, Card> source, Dictionary<string, Card> dest)
|
|
{
|
|
foreach (KeyValuePair<string, Card> pair in source)
|
|
{
|
|
bool valid = dest.TryGetValue(pair.Key, out Card val);
|
|
if (valid)
|
|
Clone(pair.Value, val);
|
|
else
|
|
dest[pair.Key] = CloneNew(pair.Value);
|
|
}
|
|
}
|
|
|
|
//Clone list by keeping references from ref_dict
|
|
public static void CloneListRef(Dictionary<string, Card> ref_dict, List<Card> source, List<Card> dest)
|
|
{
|
|
for (int i = 0; i < source.Count; i++)
|
|
{
|
|
Card scard = source[i];
|
|
bool valid = ref_dict.TryGetValue(scard.uid, out Card rcard);
|
|
if (valid)
|
|
{
|
|
if (i < dest.Count)
|
|
dest[i] = rcard;
|
|
else
|
|
dest.Add(rcard);
|
|
}
|
|
}
|
|
|
|
if (dest.Count > source.Count)
|
|
dest.RemoveRange(source.Count, dest.Count - source.Count);
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class CardStatus
|
|
{
|
|
public StatusType type;
|
|
public int value;
|
|
public int duration = 1;
|
|
public bool permanent = true;
|
|
|
|
[System.NonSerialized]
|
|
private StatusData data = null;
|
|
|
|
public CardStatus() { }
|
|
|
|
public CardStatus(StatusType type, int value, int duration)
|
|
{
|
|
this.type = type;
|
|
this.value = value;
|
|
this.duration = duration;
|
|
this.permanent = (duration == 0);
|
|
}
|
|
|
|
public StatusData StatusData
|
|
{
|
|
get
|
|
{
|
|
if (data == null || data.effect != type)
|
|
data = StatusData.Get(type);
|
|
return data;
|
|
}
|
|
}
|
|
|
|
public StatusData Data => StatusData; //Alternate name
|
|
|
|
public static CardStatus CloneNew(CardStatus copy)
|
|
{
|
|
CardStatus status = new CardStatus(copy.type, copy.value, copy.duration);
|
|
status.permanent = copy.permanent;
|
|
return status;
|
|
}
|
|
|
|
public static void Clone(CardStatus source, CardStatus dest)
|
|
{
|
|
dest.type = source.type;
|
|
dest.value = source.value;
|
|
dest.duration = source.duration;
|
|
dest.permanent = source.permanent;
|
|
}
|
|
|
|
public static void CloneList(List<CardStatus> source, List<CardStatus> dest)
|
|
{
|
|
for (int i = 0; i < source.Count; i++)
|
|
{
|
|
if (i < dest.Count)
|
|
Clone(source[i], dest[i]);
|
|
else
|
|
dest.Add(CloneNew(source[i]));
|
|
}
|
|
|
|
if (dest.Count > source.Count)
|
|
dest.RemoveRange(source.Count, dest.Count - source.Count);
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class CardTrait
|
|
{
|
|
public string id;
|
|
public int value;
|
|
|
|
[System.NonSerialized]
|
|
private TraitData data = null;
|
|
|
|
public CardTrait(string id, int value)
|
|
{
|
|
this.id = id;
|
|
this.value = value;
|
|
}
|
|
|
|
public CardTrait(TraitData trait, int value)
|
|
{
|
|
this.id = trait.id;
|
|
this.value = value;
|
|
}
|
|
|
|
public TraitData TraitData
|
|
{
|
|
get
|
|
{
|
|
if (data == null || data.id != id)
|
|
data = TraitData.Get(id);
|
|
return data;
|
|
}
|
|
}
|
|
|
|
public TraitData Data => TraitData; //Alternate name
|
|
|
|
|
|
public static CardTrait CloneNew(CardTrait copy)
|
|
{
|
|
CardTrait status = new CardTrait(copy.id, copy.value);
|
|
return status;
|
|
}
|
|
|
|
public static void Clone(CardTrait source, CardTrait dest)
|
|
{
|
|
dest.id = source.id;
|
|
dest.value = source.value;
|
|
}
|
|
|
|
public static void CloneList(List<CardTrait> source, List<CardTrait> dest)
|
|
{
|
|
for (int i = 0; i < source.Count; i++)
|
|
{
|
|
if (i < dest.Count)
|
|
Clone(source[i], dest[i]);
|
|
else
|
|
dest.Add(CloneNew(source[i]));
|
|
}
|
|
|
|
if (dest.Count > source.Count)
|
|
dest.RemoveRange(source.Count, dest.Count - source.Count);
|
|
}
|
|
}
|
|
}
|