Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
Attackment.cs
浏览该文件的文档.
1using System.Globalization;
2using Engine;
5
6namespace Game {
12 public class Attackment {
13 public Entity Target;
15 protected Random m_random = new();
16
17 public Attackment(Entity target, Entity attacker, Vector3 hitPoint, Vector3 hitDirection, float attackPower) {
18 Target = target;
19 Attacker = attacker;
20 HitPoint = hitPoint;
21 HitDirection = hitDirection;
22 AttackPower = attackPower;
23 ComponentCreature attackerCreature = attacker?.FindComponent<ComponentCreature>();
24 if (attackerCreature != null) {
25 string str = attackerCreature.KillVerbs[m_random.Int(0, attackerCreature.KillVerbs.Count - 1)];
26 string attackerName = attackerCreature.DisplayName;
27 CauseOfDeath = string.Format(LanguageControl.Get("ComponentMiner", 4), LanguageControl.Get("ComponentMiner", str), attackerName);
28 }
29 else {
30 CauseOfDeath = LanguageControl.Get("ComponentMiner", m_random.Int(0, 5) + 5);
31 }
32 ComponentDamage componentDamage = Target.FindComponent<ComponentDamage>();
33 if (componentDamage != null) {
34 AttackSoundName = componentDamage.DamageSoundName;
35 }
36 AttackSoundPitch = m_random.Float(-0.3f, 0.3f);
37 }
38
39 public Attackment(ComponentBody target, Entity attacker, Vector3 hitPoint, Vector3 hitDirection, float attackPower) : this(
40 target.Entity,
41 attacker,
42 hitPoint,
43 hitDirection,
44 attackPower
45 ) { }
46
47 public virtual ComponentBody TargetBody {
48 get => Target.FindComponent<ComponentBody>();
49 set => Target = value.Entity;
50 }
51
54 public float AttackPower;
55 public float? StunTimeSet;
56 public float StunTimeAdd = 0.2f;
57 public float ImpulseFactor = 2f;
58 public string CauseOfDeath;
59 public bool EnableArmorProtection = true;
60 public bool EnableResilienceFactor = true;
61 public bool EnableHitValueParticleSystem = true;
62 public string AttackSoundName = "Audio/Impacts/Body";
63 public float AttackSoundVolume = 1f;
64 public float AttackSoundPitch;
65
71 public virtual float ArmorProtectionDivision { get; set; } = 1f;
72
74
75 public float? m_injuryAmount;
76
81
82 public virtual float CalculateInjuryAmount() {
83 if (m_injuryAmount != null) {
84 return m_injuryAmount.Value;
85 }
86 if (AttackPower <= 0f) {
87 return AttackPower;
88 }
89 float attackPower = AttackPower;
91 ComponentClothing componentClothing = Target.FindComponent<ComponentClothing>();
92 if (componentClothing != null) {
93 attackPower = componentClothing.ApplyArmorProtection(this);
94 }
95 }
97 ComponentFactors componentFactors = Target.FindComponent<ComponentFactors>();
98 if (componentFactors != null) {
99 attackPower /= componentFactors.ResilienceFactor;
100 }
101 }
102 ComponentHealth componentHealth = Target.FindComponent<ComponentHealth>();
103 if (componentHealth != null) {
104 return attackPower / componentHealth.AttackResilience;
105 }
106 ComponentDamage componentDamage = Target.FindComponent<ComponentDamage>();
107 if (componentDamage != null) {
108 return attackPower / componentDamage.AttackResilience;
109 }
110 return -1f;
111 }
112
113 public virtual void AddHitValueParticleSystem(float damage) {
115 return;
116 }
117 ComponentBody attackerBody = Attacker?.FindComponent<ComponentBody>();
118 ComponentPlayer attackerComponentPlayer = Attacker?.FindComponent<ComponentPlayer>();
119 ComponentHealth attackedComponentHealth = Target?.FindComponent<ComponentHealth>();
120 string text2 = (0f - damage).ToString("0", CultureInfo.InvariantCulture);
121 Vector3 hitValueParticleVelocity = Vector3.Zero;
122 if (attackerBody != null) {
123 hitValueParticleVelocity = attackerBody.Velocity;
124 }
125 Color color = attackerComponentPlayer != null && damage > 0f && attackedComponentHealth != null ? Color.White : Color.Transparent;
126 HitValueParticleSystem particleSystem = new(HitPoint + 0.75f * HitDirection, 1f * HitDirection + hitValueParticleVelocity, color, text2);
128 "SetHitValueParticleSystem",
129 modLoader => {
130 modLoader.SetHitValueParticleSystem(particleSystem, this);
131 return false;
132 }
133 );
134 Target?.Project.FindSubsystem<SubsystemParticles>()?.AddParticleSystem(particleSystem);
135 }
136
137 public virtual void ProcessAttackmentToCreature(out float injuryAmount) {
138 ComponentHealth componentHealth = Target.FindComponent<ComponentHealth>();
139 ComponentBody componentBody = Target.FindComponent<ComponentBody>();
140 //ComponentCreature attackerCreature = Attacker?.FindComponent<ComponentCreature>();
141 if (componentHealth == null
142 || componentBody == null) {
143 injuryAmount = 0f;
144 return;
145 }
146 injuryAmount = CalculateInjuryAmount();
147 float healthBeforeAttack = componentHealth.Health;
148 componentHealth.Injure(new AttackInjury(injuryAmount, this));
149 if (injuryAmount > 0f) {
150 if (AttackSoundName != "") {
151 Target.Project.FindSubsystem<SubsystemAudio>()
152 ?.PlayRandomSound(AttackSoundName, AttackSoundVolume, AttackSoundPitch, componentBody.Position, 4f, false);
153 }
154 //显示粒子效果的攻击,不需要一定是玩家攻击
155 float num2 = (healthBeforeAttack - componentHealth.Health) * componentHealth.AttackResilience;
157 }
158 }
159
160 public virtual void ProcessAttackmentToNonCreature(out float injuryAmount) {
161 ComponentDamage componentDamage = Target.FindComponent<ComponentDamage>();
162 ComponentBody componentBody = Target.FindComponent<ComponentBody>();
163 //ComponentCreature attackerCreature = Attacker?.FindComponent<ComponentCreature>();
164 if (componentDamage == null
165 || componentBody == null) {
166 injuryAmount = 0f;
167 return;
168 }
169 injuryAmount = CalculateInjuryAmount();
170 m_injuryAmount = injuryAmount;
171 float hitPointsBeforeAttack = componentDamage.Hitpoints;
172 componentDamage.Damage(injuryAmount);
173 float damage = (hitPointsBeforeAttack - componentDamage.Hitpoints) * componentDamage.AttackResilience;
175 if (injuryAmount > 0f
176 && AttackSoundName != "") {
177 Target.Project.FindSubsystem<SubsystemAudio>()
178 ?.PlayRandomSound(AttackSoundName, AttackSoundVolume, AttackSoundPitch, componentBody.Position, 4f, false);
179 }
180 }
181
182 public virtual bool DisableFriendlyFire() {
183 if (Attacker?.FindComponent<ComponentPlayer>() != null
184 && Target?.FindComponent<ComponentPlayer>() != null
185 && !Target.Project.FindSubsystem<SubsystemGameInfo>(true).WorldSettings.IsFriendlyFireEnabled) {
186 Attacker?.FindComponent<ComponentGui>()?.DisplaySmallMessage(LanguageControl.Get("ComponentMiner", 3), Color.White, true, true);
187 return true;
188 }
189 return false;
190 }
191
192 public virtual void ImpulseTarget() {
193 if (ImpulseFactor <= 0f) {
194 return;
195 }
196 Target.FindComponent<ComponentBody>()
197 .ApplyImpulse(ImpulseFactor * Vector3.Normalize(HitDirection + m_random.Vector3(0.1f) + 0.2f * Vector3.UnitY));
198 }
199
200 public virtual void StunTarget() {
201 if (ImpulseFactor <= 0f) {
202 return;
203 }
204 ComponentLocomotion componentLocomotion = Target.FindComponent<ComponentLocomotion>();
205 if (componentLocomotion != null) {
206 if (StunTimeSet.HasValue)
207 componentLocomotion.StunTime = MathUtils.Max(componentLocomotion.StunTime, StunTimeSet.Value);
208 else
209 componentLocomotion.StunTime += StunTimeAdd;
210 }
211 }
212
213 public virtual void ProcessAttackment() {
214 if (DisableFriendlyFire()) {
215 return;
216 }
218 "ProcessAttackment",
219 loader => {
220 loader.ProcessAttackment(this);
221 return false;
222 }
223 );
224 float injuryAmount = 0f;
225 if (AttackPower > 0f) {
226 ComponentBody componentBody = Target.FindComponent<ComponentBody>();
227 componentBody?.Attacked?.Invoke(this);
228 ComponentHealth componentHealth = Target.FindComponent<ComponentHealth>();
229 if (componentHealth != null) {
230 ProcessAttackmentToCreature(out injuryAmount);
231 }
232 ComponentDamage componentDamage = Target.FindComponent<ComponentDamage>();
233 if (componentDamage != null) {
234 ProcessAttackmentToNonCreature(out injuryAmount);
235 }
236 }
238 "AttackPowerParameter",
239 modloader => {
240 bool reclalculate = false;
241 float stunTimeSet = StunTimeSet ?? -1f;
242#pragma warning disable CS0618
243 modloader.AttackPowerParameter(
244 Target.FindComponent<ComponentBody>(),
245 Attacker?.FindComponent<ComponentCreature>(),
246 HitPoint,
248 ref ImpulseFactor,
249 ref stunTimeSet,
250 ref reclalculate
251 );
252#pragma warning restore CS0618
253 if (stunTimeSet >= 0f) {
254 StunTimeSet = stunTimeSet;
255 }
256 return false;
257 }
258 );
259 if (AllowImpulseAndStunWhenDamageIsZero || injuryAmount > 0f) {
261 StunTarget();
262 }
263 }
264 }
265}
static int Max(int x1, int x2)
virtual bool DisableFriendlyFire()
bool AllowImpulseAndStunWhenDamageIsZero
virtual void ProcessAttackmentToNonCreature(out float injuryAmount)
virtual void StunTarget()
ValuesDictionary DictionaryForOtherMods
模组可以向Dictionary里面添加内容,另一个模组可以从Dictionary读取内容,以实现模组联动效果
bool EnableHitValueParticleSystem
Attackment(ComponentBody target, Entity attacker, Vector3 hitPoint, Vector3 hitDirection, float attackPower)
virtual void ImpulseTarget()
virtual float CalculateInjuryAmount()
virtual float ArmorProtectionDivision
该攻击被护甲结算时,护甲的防御值会除以ArmorProtectionDivision。 例如当ArmorProtectionDivision = 2,模组护甲的ArmorProtection = 150...
Attackment(Entity target, Entity attacker, Vector3 hitPoint, Vector3 hitDirection, float attackPower)
virtual void ProcessAttackment()
virtual ComponentBody TargetBody
virtual void ProcessAttackmentToCreature(out float injuryAmount)
virtual void AddHitValueParticleSystem(float damage)
virtual Action< Attackment > Attacked
float ApplyArmorProtection(float attackPower)
ReadOnlyList< string > KillVerbs
virtual void Damage(float amount)
virtual void Injure(float amount, ComponentCreature attacker, bool ignoreInvulnerability, string cause)
virtual float AttackResilience
攻击抗性
static string Get(string className, int key)
获取在当前语言类名键对应的字符串
Component FindComponent(Type type, string name, bool throwOnError)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static Color Transparent
定义 Color.cs:5
static Color White
static Vector3 Normalize(Vector3 v)
static readonly Vector3 Zero
static readonly Vector3 UnitY