Elin Decompiled Documentation EA 23.182 Nightly
Loading...
Searching...
No Matches
ActRanged.cs
Go to the documentation of this file.
1using System.Collections.Generic;
2using System.Linq;
3using UnityEngine;
4
5public class ActRanged : ActThrow
6{
7 public bool IsReload
8 {
9 get
10 {
12 {
13 return !(EClass.player.currentHotItem.Thing.trait is TraitToolRangeCane);
14 }
15 return false;
16 }
17 }
18
20
21 public override int PerformDistance => 99;
22
23 public override string Name
24 {
25 get
26 {
27 if (!IsReload)
28 {
29 return base.Name;
30 }
31 return "ActReload".lang();
32 }
33 }
34
35 public override string GetText(string str = "")
36 {
37 if (!IsReload)
38 {
39 return base.GetText(str);
40 }
41 return Name;
42 }
43
44 public override bool CanPerform()
45 {
47 {
48 return false;
49 }
51 {
52 return false;
53 }
54 if (Act.TC == null)
55 {
56 return Act.CC.CanSeeLos(Act.TP);
57 }
59 {
60 return false;
61 }
62 return Act.CC.CanSeeLos(Act.TC.pos);
63 }
64
65 public override bool Perform()
66 {
67 if (Act.TC == null)
68 {
69 Act.TC = Act.TP.FindAttackTarget();
70 }
71 if (Act.TC != null)
72 {
73 Act.TP.Set(Act.TC.pos);
74 }
76 {
78 {
79 target = Act.TC,
80 range = true
81 });
82 return true;
83 }
85 if (!Act.CC.IsPC)
86 {
88 }
90 if (weapon != null && Act.CC.IsPC && Act.CC.body.IsTooHeavyToEquip(weapon))
91 {
92 Msg.Say("tooHeavyToEquip", weapon);
93 return false;
94 }
95 if (weapon == null || !weapon.CanAutoFire(Act.CC, Act.TC))
96 {
97 return false;
98 }
99 bool flag = weapon.trait is TraitToolRangeGun;
100 bool flag2 = weapon.trait is TraitToolRangeCane;
101 GameSetting.EffectData effectData = EClass.setting.effect.guns.TryGetValue(weapon.id) ?? EClass.setting.effect.guns[flag2 ? "cane" : (flag ? "gun" : "bow")];
102 bool hasHit = false;
103 int numFire = effectData.num;
104 int numFireWithoutDamageLoss = numFire;
105 int num = GetWeaponEnc(602);
106 int drill = GetWeaponEnc(606);
107 int scatter = GetWeaponEnc(607);
108 int chaser = GetWeaponEnc(620);
109 if (num > 0)
110 {
111 numFire += Mathf.Min(num / 10 + ((num % 10 > EClass.rnd(10)) ? 1 : 0), 10);
112 numFireWithoutDamageLoss += num / 100 + ((num % 100 > EClass.rnd(100)) ? 1 : 0);
113 }
114 numFire += Act.CC.Evalue(1652);
115 int num2 = numFire;
116 int num3 = 1 + weapon.material.hardness / 30 + EClass.rnd(3);
117 int num4 = weapon.Evalue(604);
118 if (num4 > 0)
119 {
120 for (int i = 0; i < numFire; i++)
121 {
122 if (Mathf.Sqrt(num4) * 5f + 10f > (float)EClass.rnd(100))
123 {
124 num2--;
125 }
126 }
127 num3 = Mathf.Max(1, num3 * 100 / (100 + num4 * 5));
128 }
129 string missSound = ((weapon.trait is TraitToolRangeGun) ? "miss_bullet" : "miss_arrow");
130 if (weapon.trait is TraitToolRangeCane)
131 {
132 foreach (Element item in weapon.elements.dict.Values.Where((Element e) => e.source.categorySub == "eleAttack"))
133 {
134 num3 += item.source.LV / 15;
135 }
136 if (Act.CC.IsPC)
137 {
138 if (Act.CC.mana.value < num3)
139 {
140 if (!Act.CC.ai.IsNoGoal)
141 {
142 return false;
143 }
145 {
146 ActPlan.warning = true;
147 Dialog.TryWarnMana(delegate
148 {
149 if (Perform())
150 {
152 }
153 });
154 return false;
155 }
156 }
157 EClass.ui.CloseLayers();
158 }
159 }
160 else
161 {
162 if (IsReload)
163 {
164 return TryReload(weapon);
165 }
166 if (weapon.c_ammo <= 0)
167 {
168 if (!TryReload(weapon))
169 {
170 if (Act.CC.IsPC)
171 {
172 EInput.Consume();
173 }
174 return false;
175 }
177 {
178 return true;
179 }
180 }
181 if (Act.CC.HasCondition<ConFear>())
182 {
183 Act.CC.Say("fear", Act.CC, Act.TC);
184 if (Act.CC.IsPC)
185 {
186 EInput.Consume(consumeAxis: true);
187 }
188 return true;
189 }
190 }
191 Act.TC?.Chara?.RequestProtection(Act.CC, delegate(Chara c)
192 {
193 Act.TC = c;
194 });
195 Act.CC.LookAt(Act.TP);
196 int index = 0;
197 Point orgTP = Act.TP.Copy();
198 List<Point> points = new List<Point>();
199 if (drill > 0)
200 {
201 points = EClass._map.ListPointsInLine(Act.CC.pos, Act.TP, drill / 10 + ((drill % 10 > EClass.rnd(10)) ? 1 : 0) + 1);
202 }
203 else if (scatter > 0)
204 {
205 Act.TP.ForeachNeighbor(delegate(Point _p)
206 {
207 points.Add(_p.Copy());
208 });
209 }
211 {
212 EClass.Wait(0.25f, Act.CC);
213 }
214 Shoot(Act.TC, Act.TP);
215 if (points.Count > 0)
216 {
217 Point obj = Act.TP.Copy();
218 foreach (Point item2 in points)
219 {
220 if (!item2.Equals(obj))
221 {
222 Chara firstChara = item2.FirstChara;
223 if ((firstChara == null || firstChara.IsHostile(Act.CC)) && (firstChara != null || scatter != 0))
224 {
225 Shoot(item2.FirstChara, item2);
226 }
227 }
228 }
229 }
230 if (!(weapon.trait is TraitToolRangeCane))
231 {
232 weapon.c_ammo -= num2;
233 if (weapon.ammoData != null)
234 {
235 weapon.ammoData.Num = weapon.c_ammo;
236 }
237 if (weapon.c_ammo <= 0)
238 {
239 weapon.c_ammo = 0;
240 weapon.ammoData = null;
241 }
242 }
243 if (Act.CC.IsPC)
244 {
246 }
247 if (Act.TC != null && !hasHit)
248 {
249 Act.CC.PlaySound(missSound);
250 }
251 if (!Act.CC.isDead)
252 {
253 if (EClass.rnd(2) == 0)
254 {
255 Act.CC.RemoveCondition<ConInvisibility>();
256 }
257 if (weapon.trait is TraitToolRangeCane)
258 {
259 Act.CC.mana.Mod(-num3 * numFire);
260 }
261 }
262 return true;
263 int GetWeaponEnc(int ele)
264 {
265 return weapon.Evalue(ele) + (Act.CC.IsPCFactionOrMinion ? EClass.pc.faction.charaElements.Value(ele) : 0);
266 }
267 void Prepare()
268 {
270 AttackProcess.Current.numFire = numFire;
271 AttackProcess.Current.numFireWithoutDamageLoss = numFireWithoutDamageLoss;
272 AttackProcess.Current.posRangedAnime = Act.TP.Copy();
273 AttackProcess.Current.ignoreAnime = index > 1;
274 AttackProcess.Current.ignoreAttackSound = false;
275 if (drill > 0 && points.Count > 0)
276 {
277 AttackProcess.Current.posRangedAnime = points.LastItem();
278 }
279 else if (scatter > 0)
280 {
281 AttackProcess.Current.ignoreAnime = false;
282 AttackProcess.Current.ignoreAttackSound = index > 1;
283 }
284 }
285 void Shoot(Card _tc, Point _tp)
286 {
287 float dmgMulti = 1f;
288 index++;
289 Act.TC = _tc;
290 Act.TP = _tp;
291 CellEffect effect = Act.TP.cell.effect;
292 if (effect != null && effect.id == 6 && EClass.rnd(2) == 0)
293 {
294 Prepare();
296 Act.CC.PlaySound(missSound);
297 Act.CC.Say("abMistOfDarkness_miss", Act.CC);
298 }
299 else
300 {
301 if (scatter > 0)
302 {
303 dmgMulti = Mathf.Clamp(1.2f - 0.2f * (float)Act.CC.Dist(Act.TP) - (Act.TP.Equals(orgTP) ? 0f : 0.4f), 0.2f, 1f);
304 }
305 for (int j = 0; j < numFire; j++)
306 {
307 Act.TC = _tc;
308 Prepare();
309 if (AttackProcess.Current.Perform(j, hasHit, dmgMulti))
310 {
311 hasHit = true;
312 }
313 else if (chaser > 0)
314 {
315 for (int k = 0; k < 10; k++)
316 {
317 if (chaser > EClass.rnd(4 + (int)Mathf.Pow(4f, k + 2 + j)))
318 {
319 Act.CC.Say("attack_chaser");
320 if (AttackProcess.Current.Perform(j, hasHit, dmgMulti))
321 {
322 hasHit = true;
323 break;
324 }
325 }
326 }
327 }
328 if (Act.TC == null || !Act.TC.IsAliveInCurrentZone)
329 {
330 break;
331 }
332 }
333 if (Act.TC != null)
334 {
336 }
337 }
338 }
339 }
340
341 public static bool TryReload(Thing weapon, Thing ammo = null)
342 {
343 TraitToolRange traitToolRange = weapon.trait as TraitToolRange;
344 if (Act.CC.IsPC)
345 {
347 }
348 if (weapon.ammoData != null)
349 {
350 if (weapon.ammoData.Num > 0)
351 {
352 Act.CC.Pick(weapon.ammoData);
353 }
354 weapon.ammoData = null;
355 }
356 int num = 0;
357 if (ammo == null)
358 {
360 }
361 if (ammo == null)
362 {
363 if (Act.CC.IsPC)
364 {
365 if (!weapon.IsMeleeWithAmmo)
366 {
367 Msg.Say("noAmmo", weapon);
368 }
369 return false;
370 }
371 num = traitToolRange.MaxAmmo;
372 }
373 else
374 {
375 num = Mathf.Min(ammo.Num, traitToolRange.MaxAmmo);
376 Thing thing = ammo.Split(num);
377 Act.CC.Say("takeAmmo", thing);
378 if (thing.GetRootCard() == Act.CC)
379 {
380 thing.parent.RemoveCard(thing);
381 }
382 weapon.ammoData = thing;
383 }
384 weapon.c_ammo = num;
385 int reloadTurn = traitToolRange.ReloadTurn;
386 reloadTurn = reloadTurn * 100 / (100 + Act.CC.Evalue(1652) * 100);
387 if (traitToolRange.NeedReload && reloadTurn > 0)
388 {
389 Act.CC.AddCondition<ConReload>(reloadTurn * 10);
390 }
391 return true;
392 }
393}
virtual bool IsNoGoal
Definition: AIAct.cs:74
override bool Perform()
Definition: ActRanged.cs:65
override string Name
Definition: ActRanged.cs:24
override CursorInfo CursorIcon
Definition: ActRanged.cs:19
override int PerformDistance
Definition: ActRanged.cs:21
static bool TryReload(Thing weapon, Thing ammo=null)
Definition: ActRanged.cs:341
bool IsReload
Definition: ActRanged.cs:8
override string GetText(string str="")
Definition: ActRanged.cs:35
override bool CanPerform()
Definition: ActRanged.cs:44
Thing target
Definition: ActThrow.cs:5
Definition: ACT.cs:62
static Card TC
Definition: ACT.cs:79
static Point TP
Definition: ACT.cs:81
static Chara CC
Definition: ACT.cs:77
void Prepare(Chara _CC, Thing _weapon, Card _TC=null, Point _TP=null, int _attackIndex=0, bool _isThrow=false)
bool Perform(int count, bool hasHit, float dmgMulti=1f, bool maxRoll=false, bool subAttack=false)
static AttackProcess Current
Definition: AttackProcess.cs:8
void PlayRangedAnime(int numFire)
virtual void NextFrame()
Definition: Card.cs:11
virtual Chara Chara
Definition: Card.cs:2032
bool IsRestrainedResident
Definition: Card.cs:2220
bool isRestrained
Definition: Card.cs:552
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:5852
ICardParent parent
Definition: Card.cs:53
Point pos
Definition: Card.cs:57
Trait trait
Definition: Card.cs:51
virtual bool IsAliveInCurrentZone
Definition: Card.cs:2089
Card GetRootCard()
Definition: Card.cs:3324
int Evalue(int ele)
Definition: Card.cs:2533
int Dist(Card c)
Definition: Card.cs:7315
CardRenderer renderer
Definition: Card.cs:59
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:6499
CellEffect effect
Definition: Cell.cs:94
bool IsTooHeavyToEquip(Thing thing)
Definition: CharaBody.cs:156
Definition: Chara.cs:10
CharaBody body
Definition: Chara.cs:94
AIAct ai
Definition: Chara.cs:200
Condition AddCondition(string id, int p=100, bool force=false)
Definition: Chara.cs:8769
Thing FindAmmo(Thing weapon)
Definition: Chara.cs:7415
Faction faction
Definition: Chara.cs:425
override bool IsPC
Definition: Chara.cs:610
bool CanSeeLos(Card c, int dist=-1)
Definition: Chara.cs:1232
bool RequestProtection(Chara attacker, Action< Chara > action)
Definition: Chara.cs:7972
bool HasCondition(string alias)
Definition: Chara.cs:8926
AIAct SetAI(AIAct g)
Definition: Chara.cs:8399
Thing ranged
Definition: Chara.cs:98
Stats mana
Definition: Chara.cs:1136
void DoHostileAction(Card _tg, bool immediate=false)
Definition: Chara.cs:6016
bool IsHostile()
Definition: Chara.cs:6193
bool isDead
Definition: Chara.cs:387
override void LookAt(Card c)
Definition: Chara.cs:3454
bool TryEquipRanged()
Definition: Chara.cs:7445
Thing Pick(Thing t, bool msg=true, bool tryStack=true)
Definition: Chara.cs:4168
new GameConfig game
Definition: CoreConfig.cs:602
bool godMode
Definition: CoreDebug.cs:172
CoreConfig config
Definition: Core.cs:70
static CursorInfo IconRange
Definition: Dialog.cs:7
static bool warned
Definition: Dialog.cs:49
static void TryWarnMana(Action action)
Definition: Dialog.cs:391
Definition: EClass.cs:5
static Core core
Definition: EClass.cs:6
static void Wait(float a, Card c)
Definition: EClass.cs:102
static Map _map
Definition: EClass.cs:18
static int rnd(long a)
Definition: EClass.cs:58
static Player player
Definition: EClass.cs:12
static Chara pc
Definition: EClass.cs:14
static CoreDebug debug
Definition: EClass.cs:48
static UI ui
Definition: EClass.cs:16
static GameSetting setting
Definition: EClass.cs:34
Definition: EInput.cs:8
static void Consume(int _skipFrame)
Definition: EInput.cs:656
int Value(int ele)
ElementContainerFaction charaElements
Definition: FACTION.cs:146
UD_String_EffectData guns
Definition: GameSetting.cs:276
EffectSetting effect
Definition: GameSetting.cs:299
virtual Thing Thing
Definition: HotItem.cs:38
static void SetDirty(Thing t)
List< Point > ListPointsInLine(Point center, Point to, int radius)
Definition: Map.cs:2312
Definition: Msg.cs:5
static string Say(string idLang, string ref1, string ref2=null, string ref3=null, string ref4=null)
Definition: Msg.cs:58
void EndTurn(bool consume=true)
Definition: Player.cs:1984
HotItem currentHotItem
Definition: Player.cs:1020
Definition: Point.cs:9
Point Copy()
Definition: Point.cs:479
Point Set(int _x, int _z)
Definition: Point.cs:491
void ForeachNeighbor(Action< Point > action, bool diagonal=true)
Definition: Point.cs:1377
bool Equals(int _x, int _z)
Definition: Point.cs:940
Card FindAttackTarget()
Definition: Point.cs:1078
Chara FirstChara
Definition: Point.cs:276
Cell cell
Definition: Point.cs:51
virtual void Mod(int a)
Definition: Stats.cs:135
virtual int value
Definition: Stats.cs:56
Definition: Thing.cs:8
virtual bool NeedReload
bool TryGetValue(TKey key, out TValue value)
Definition: UDictionary.cs:178
void RemoveCard(Card c)