mirror of
				https://bitbucket.org/Ioncannon/project-meteor-server.git
				synced 2025-05-20 08:26:59 -04:00 
			
		
		
		
	added status effect loading
- todo: populate table (and test this doesnt break everything ever), send charawork and message packets
This commit is contained in:
		| @@ -7,6 +7,7 @@ using FFXIVClassic_Map_Server.packets.send.actor; | ||||
| using FFXIVClassic_Map_Server.utils; | ||||
| using FFXIVClassic_Map_Server.actors.chara.ai; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
|  | ||||
| namespace FFXIVClassic_Map_Server.Actors | ||||
| { | ||||
| @@ -73,7 +74,7 @@ namespace FFXIVClassic_Map_Server.Actors | ||||
|         public DateTime lastAiUpdate; | ||||
|  | ||||
|         public AIContainer aiContainer; | ||||
|         public StatusEffects statusEffects; | ||||
|         public StatusEffectContainer statusEffects; | ||||
|  | ||||
|         public CharacterTargetingAllegiance allegiance; | ||||
|  | ||||
| @@ -83,7 +84,7 @@ namespace FFXIVClassic_Map_Server.Actors | ||||
|             for (int i = 0; i < charaWork.statusShownTime.Length; i++) | ||||
|                 charaWork.statusShownTime[i] = 0xFFFFFFFF; | ||||
|  | ||||
|             this.statusEffects = new StatusEffects(this); | ||||
|             this.statusEffects = new StatusEffectContainer(this); | ||||
|         } | ||||
|  | ||||
|         public SubPacket CreateAppearancePacket() | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| using System; | ||||
| using FFXIVClassic_Map_Server.Actors; | ||||
| using FFXIVClassic_Map_Server.lua; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using FFXIVClassic_Map_Server.Actors; | ||||
| using FFXIVClassic_Map_Server.lua; | ||||
| using FFXIVClassic_Map_Server.actors.area; | ||||
| 
 | ||||
| namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
| { | ||||
| @@ -359,13 +358,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|         private DateTime lastTick;  // when did this effect last tick | ||||
|         private uint durationMs;    // how long should this effect last in ms | ||||
|         private uint tickMs;        // how often should this effect proc | ||||
|         private int magnitude;      // a value specified by scripter which is guaranteed to be used by all effects | ||||
|         private UInt64 magnitude;   // a value specified by scripter which is guaranteed to be used by all effects | ||||
|         private byte tier;          // same effect with higher tier overwrites this | ||||
|         private Dictionary<string, UInt64> variables; // list of variables which belong to this effect, to be set/retrieved with GetVariable(key), SetVariable(key, val) | ||||
|         private UInt64 extra;       // optional value | ||||
|         private StatusEffectFlags flags;              // death/erase/dispel etc | ||||
|         private StatusEffectOverwrite overwrite;      // how to handle adding an effect with same id (see StatusEfectOverwrite) | ||||
| 
 | ||||
|         public StatusEffect(Character owner, uint id, int magnitude, uint tickMs, uint durationMs, byte tier = 0) | ||||
|         public StatusEffect(Character owner, uint id, UInt64 magnitude, uint tickMs, uint durationMs, byte tier = 0) | ||||
|         { | ||||
|             this.owner = owner; | ||||
|             this.id = (StatusEffectId)id; | ||||
| @@ -373,7 +372,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|             this.tickMs = tickMs; | ||||
|             this.durationMs = durationMs; | ||||
|             this.tier = tier; | ||||
|              | ||||
| 
 | ||||
|             // todo: use tick instead of now? | ||||
|             this.startTime = DateTime.Now; | ||||
|             this.lastTick = startTime; | ||||
| @@ -399,7 +398,15 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|             this.name = effect.name; | ||||
|             this.flags = effect.flags; | ||||
|             this.overwrite = effect.overwrite; | ||||
|             this.variables = effect.variables; | ||||
|             this.extra = effect.extra; | ||||
|         } | ||||
| 
 | ||||
|         public StatusEffect(uint id, string name, uint flags, uint overwrite) | ||||
|         { | ||||
|             this.id = (StatusEffectId)id; | ||||
|             this.name = name; | ||||
|             this.flags = (StatusEffectFlags)flags; | ||||
|             this.overwrite = (StatusEffectOverwrite)overwrite; | ||||
|         } | ||||
| 
 | ||||
|         // return true when duration has elapsed | ||||
| @@ -411,6 +418,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|                 // todo: call effect's onTick | ||||
|                 // todo: maybe keep a global lua object instead of creating a new one each time we wanna call a script | ||||
|                 lastTick = tick; | ||||
|                 LuaEngine.CallLuaStatusEffectFunction(this.owner, this, "onTick", this.owner, this); | ||||
|             } | ||||
|             // todo: handle infinite duration effects? | ||||
|             if (durationMs != 0 && startTime.Millisecond + durationMs >= tick.Millisecond) | ||||
| @@ -447,7 +455,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|             return tickMs; | ||||
|         } | ||||
| 
 | ||||
|         public int GetMagnitude() | ||||
|         public UInt64 GetMagnitude() | ||||
|         { | ||||
|             return magnitude; | ||||
|         } | ||||
| @@ -457,9 +465,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|             return tier; | ||||
|         } | ||||
| 
 | ||||
|         public UInt64 GetVariable(string key) | ||||
|         public UInt64 GetExtra() | ||||
|         { | ||||
|             return variables?[key] ?? 0; | ||||
|             return extra; | ||||
|         } | ||||
| 
 | ||||
|         public uint GetFlags() | ||||
| @@ -482,6 +490,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|             this.name = name; | ||||
|         } | ||||
| 
 | ||||
|         public void SetMagnitude(UInt64 magnitude) | ||||
|         { | ||||
|             this.magnitude = magnitude; | ||||
|         } | ||||
| 
 | ||||
|         public void SetDurationMs(uint durationMs) | ||||
|         { | ||||
|             this.durationMs = durationMs; | ||||
| @@ -497,17 +510,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|             this.tier = tier; | ||||
|         } | ||||
| 
 | ||||
|         public void SetVariable(string key, UInt64 val) | ||||
|         public void SetExtra(UInt64 val) | ||||
|         { | ||||
|             if (variables != null) | ||||
|             { | ||||
|                 variables[key] = val; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 variables = new Dictionary<string, ulong>(); | ||||
|                 variables[key] = val; | ||||
|             } | ||||
|             this.extra = val; | ||||
|         } | ||||
| 
 | ||||
|         public void SetFlags(uint flags) | ||||
| @@ -520,96 +525,4 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
|             this.overwrite = (StatusEffectOverwrite)overwrite; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     class StatusEffects | ||||
|     { | ||||
|         private Character owner; | ||||
|         private List<StatusEffect> effects; | ||||
| 
 | ||||
|         public StatusEffects(Character owner) | ||||
|         { | ||||
|             this.owner = owner; | ||||
|             this.effects = new List<StatusEffect>(); | ||||
|         } | ||||
| 
 | ||||
|         public void Update(DateTime tick) | ||||
|         { | ||||
|             // list of effects to remove | ||||
|             var removeEffects = new List<StatusEffect>(); | ||||
|             foreach (var effect in effects) | ||||
|             { | ||||
|                 // effect's update function returns true if effect has completed | ||||
|                 if (effect.Update(tick)) | ||||
|                     removeEffects.Add(effect); | ||||
|             } | ||||
| 
 | ||||
|             // remove effects from this list | ||||
|             foreach (var effect in removeEffects) | ||||
|                 effects.Remove(effect); | ||||
|         } | ||||
| 
 | ||||
|         public bool AddStatusEffect(StatusEffect effect) | ||||
|         { | ||||
|             // todo: check flags/overwritable and add effect to list | ||||
|             effects.Add(effect); | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         public StatusEffect CopyEffect(StatusEffect effect) | ||||
|         { | ||||
|             var newEffect = new StatusEffect(this.owner, effect); | ||||
|             newEffect.SetOwner(this.owner); | ||||
| 
 | ||||
|             return AddStatusEffect(newEffect) ? newEffect : null; | ||||
|         } | ||||
| 
 | ||||
|         public bool RemoveStatusEffectsByFlags(uint flags) | ||||
|         { | ||||
|             // build list of effects to remove | ||||
|             var removeEffects = new List<StatusEffect>(); | ||||
|             foreach (var effect in effects) | ||||
|                 if ((effect.GetFlags() & flags) > 0) | ||||
|                     removeEffects.Add(effect); | ||||
| 
 | ||||
|             // remove effects from main list | ||||
|             foreach (var effect in removeEffects) | ||||
|                 effects.Remove(effect); | ||||
| 
 | ||||
|             // removed an effect with one of these flags | ||||
|             return removeEffects.Count > 0; | ||||
|         } | ||||
| 
 | ||||
|         public StatusEffect GetStatusEffectById(uint id, uint tier = 0xFF) | ||||
|         { | ||||
|             foreach (var effect in effects) | ||||
|             { | ||||
|                 if (effect.GetEffectId() == id && (tier != 0xFF ? effect.GetTier() == tier : true)) | ||||
|                     return effect; | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public List<StatusEffect> GetStatusEffectsByFlag(uint flag) | ||||
|         { | ||||
|             var list = new List<StatusEffect>(); | ||||
|             foreach (var effect in effects) | ||||
|             { | ||||
|                 if ((effect.GetFlags() & flag) > 0) | ||||
|                 { | ||||
|                     list.Add(effect); | ||||
|                 } | ||||
|             } | ||||
|             return list; | ||||
|         } | ||||
| 
 | ||||
|         public bool HasStatusEffectsByFlag(uint flag) | ||||
|         { | ||||
|             foreach (var effect in effects) | ||||
|             { | ||||
|                 if ((effect.GetFlags() & flag) > 0) | ||||
|                     return true; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										162
									
								
								FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using FFXIVClassic_Map_Server.Actors; | ||||
| using FFXIVClassic_Map_Server.lua; | ||||
| using FFXIVClassic_Map_Server.actors.area; | ||||
| using FFXIVClassic_Map_Server.packets.send; | ||||
| using FFXIVClassic_Map_Server.packets.send.actor; | ||||
| using System.Collections.ObjectModel; | ||||
|  | ||||
| namespace FFXIVClassic_Map_Server.actors.chara.ai | ||||
| { | ||||
|     class StatusEffectContainer | ||||
|     { | ||||
|         private Character owner; | ||||
|         private readonly Dictionary<uint, StatusEffect> effects; | ||||
|  | ||||
|         public StatusEffectContainer(Character owner) | ||||
|         { | ||||
|             this.owner = owner; | ||||
|             this.effects = new Dictionary<uint, StatusEffect>(20); | ||||
|         } | ||||
|  | ||||
|         public void Update(DateTime tick) | ||||
|         { | ||||
|             // list of effects to remove | ||||
|             var removeEffects = new List<StatusEffect>(); | ||||
|             foreach (var effect in effects.Values) | ||||
|             { | ||||
|                 // effect's update function returns true if effect has completed | ||||
|                 if (effect.Update(tick)) | ||||
|                     removeEffects.Add(effect); | ||||
|             } | ||||
|  | ||||
|             // remove effects from this list | ||||
|             foreach (var effect in removeEffects) | ||||
|             { | ||||
|                 RemoveStatusEffect(effect); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public bool AddStatusEffect(StatusEffect newEffect, bool silent = false) | ||||
|         { | ||||
|             // todo: check flags/overwritable and add effect to list | ||||
|             var effect = GetStatusEffectById(newEffect.GetEffectId()); | ||||
|             bool canOverwrite = false; | ||||
|             if (effect != null) | ||||
|             { | ||||
|                 var overwritable = effect.GetOverwritable(); | ||||
|                 canOverwrite = (overwritable == (uint)StatusEffectOverwrite.Always) || | ||||
|                    (overwritable == (uint)StatusEffectOverwrite.GreaterOnly && (effect.GetDurationMs() < newEffect.GetDurationMs() || effect.GetMagnitude() < newEffect.GetMagnitude())) || | ||||
|                    (overwritable == (uint)StatusEffectOverwrite.GreaterOrEqualTo && (effect.GetDurationMs() == newEffect.GetDurationMs() || effect.GetMagnitude() == newEffect.GetMagnitude())); | ||||
|             } | ||||
|  | ||||
|             if (canOverwrite || effects.ContainsKey(effect.GetEffectId())) | ||||
|             { | ||||
|                 if (!silent || (effect.GetFlags() & (uint)StatusEffectFlags.Silent) == 0) | ||||
|                 { | ||||
|                     // todo: send packet to client with effect added message | ||||
|                 } | ||||
|  | ||||
|                 if (canOverwrite) | ||||
|                     effects.Remove(effect.GetEffectId()); | ||||
|  | ||||
|                 effects.Add(newEffect.GetEffectId(), newEffect); | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         public void RemoveStatusEffect(StatusEffect effect, bool silent = false) | ||||
|         { | ||||
|             if (effects.ContainsKey(effect.GetEffectId())) | ||||
|             { | ||||
|                 // send packet to client with effect remove message | ||||
|                 if (!silent || (effect.GetFlags() & (uint)StatusEffectFlags.Silent) == 0) | ||||
|                 { | ||||
|                     // todo: send packet to client with effect added message | ||||
|                 } | ||||
|  | ||||
|                 // function onLose(actor, effec) | ||||
|                 LuaEngine.CallLuaStatusEffectFunction(this.owner, effect, "onLose", this.owner, effect); | ||||
|                 effects.Remove(effect.GetEffectId()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void RemoveStatusEffect(uint effectId, bool silent = false) | ||||
|         { | ||||
|             foreach (var effect in effects.Values) | ||||
|             { | ||||
|                 if (effect.GetEffectId() == effectId) | ||||
|                 { | ||||
|                     RemoveStatusEffect(effect, silent); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public StatusEffect CopyEffect(StatusEffect effect) | ||||
|         { | ||||
|             var newEffect = new StatusEffect(this.owner, effect); | ||||
|             newEffect.SetOwner(this.owner); | ||||
|  | ||||
|             return AddStatusEffect(newEffect) ? newEffect : null; | ||||
|         } | ||||
|  | ||||
|         public bool RemoveStatusEffectsByFlags(uint flags, bool silent = false) | ||||
|         { | ||||
|             // build list of effects to remove | ||||
|             var removeEffects = new List<StatusEffect>(); | ||||
|             foreach (var effect in effects.Values) | ||||
|                 if ((effect.GetFlags() & flags) != 0) | ||||
|                     removeEffects.Add(effect); | ||||
|  | ||||
|             // remove effects from main list | ||||
|             foreach (var effect in removeEffects) | ||||
|                 RemoveStatusEffect(effect, silent); | ||||
|  | ||||
|             // removed an effect with one of these flags | ||||
|             return removeEffects.Count > 0; | ||||
|         } | ||||
|  | ||||
|         public StatusEffect GetStatusEffectById(uint id, byte tier = 0xFF) | ||||
|         { | ||||
|             StatusEffect effect; | ||||
|  | ||||
|             if (effects.TryGetValue(id, out effect) && effect.GetEffectId() == id && (tier != 0xFF ? effect.GetTier() == tier : true)) | ||||
|                 return effect; | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         public List<StatusEffect> GetStatusEffectsByFlag(uint flag) | ||||
|         { | ||||
|             var list = new List<StatusEffect>(); | ||||
|             foreach (var effect in effects.Values) | ||||
|             { | ||||
|                 if ((effect.GetFlags() & flag) > 0) | ||||
|                 { | ||||
|                     list.Add(effect); | ||||
|                 } | ||||
|             } | ||||
|             return list; | ||||
|         } | ||||
|  | ||||
|         public bool HasStatusEffectsByFlag(uint flag) | ||||
|         { | ||||
|             foreach (var effect in effects.Values) | ||||
|             { | ||||
|                 if ((effect.GetFlags() & flag) > 0) | ||||
|                     return true; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public IEnumerable<StatusEffect> GetStatusEffects() | ||||
|         { | ||||
|             return effects.Values; | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user