Elin Decompiled Documentation EA 23.223 Nyaightly
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 bool isRocket = weapon.trait is TraitToolRangeGunRocket;
102 GameSetting.EffectData effectData = EClass.setting.effect.guns.TryGetValue(weapon.id) ?? EClass.setting.effect.guns[flag2 ? "cane" : (flag ? "gun" : "bow")];
103 bool hasHit = false;
104 int numFire = effectData.num;
105 int numFireWithoutDamageLoss = numFire;
106 int num = GetWeaponEnc(602);
107 int drill = GetWeaponEnc(606);
108 int scatter = GetWeaponEnc(607);
109 int chaser = GetWeaponEnc(620);
110 if (num > 0)
111 {
112 numFire += Mathf.Min(num / 10 + ((num % 10 > EClass.rnd(10)) ? 1 : 0), 10);
113 numFireWithoutDamageLoss += num / 100 + ((num % 100 > EClass.rnd(100)) ? 1 : 0);
114 }
115 numFire += Act.CC.Evalue(1652);
116 int num2 = numFire;
117 int num3 = 1 + weapon.material.hardness / 30 + EClass.rnd(3);
118 int num4 = weapon.Evalue(604);
119 if (num4 > 0)
120 {
121 for (int i = 0; i < numFire; i++)
122 {
123 if (Mathf.Sqrt(num4) * 5f + 10f > (float)EClass.rnd(100))
124 {
125 num2--;
126 }
127 }
128 num3 = Mathf.Max(1, num3 * 100 / (100 + num4 * 5));
129 }
130 string missSound = ((weapon.trait is TraitToolRangeGun) ? "miss_bullet" : "miss_arrow");
131 if (weapon.trait is TraitToolRangeCane)
132 {
133 foreach (Element item in weapon.elements.dict.Values.Where((Element e) => e.source.categorySub == "eleAttack"))
134 {
135 num3 += item.source.LV / 15;
136 }
137 if (Act.CC.IsPC)
138 {
139 if (Act.CC.mana.value < num3)
140 {
141 if (!Act.CC.ai.IsNoGoal)
142 {
143 return false;
144 }
146 {
147 ActPlan.warning = true;
148 Dialog.TryWarnMana(delegate
149 {
150 if (Perform())
151 {
153 }
154 });
155 return false;
156 }
157 }
158 EClass.ui.CloseLayers();
159 }
160 }
161 else
162 {
163 if (IsReload)
164 {
165 return TryReload(weapon);
166 }
167 if (weapon.c_ammo <= 0)
168 {
169 if (!TryReload(weapon))
170 {
171 if (Act.CC.IsPC)
172 {
173 EInput.Consume();
174 }
175 return false;
176 }
178 {
179 return true;
180 }
181 }
182 if (Act.CC.HasCondition<ConFear>())
183 {
184 Act.CC.Say("fear", Act.CC, Act.TC);
185 if (Act.CC.IsPC)
186 {
187 EInput.Consume(consumeAxis: true);
188 }
189 return true;
190 }
191 }
192 Act.TC?.Chara?.RequestProtection(Act.CC, delegate(Chara c)
193 {
194 Act.TC = c;
195 });
196 Act.CC.LookAt(Act.TP);
197 int index = 0;
198 Point orgTP = Act.TP.Copy();
199 List<Point> points = new List<Point>();
200 if (drill > 0)
201 {
202 points = EClass._map.ListPointsInLine(Act.CC.pos, Act.TP, drill / 10 + ((drill % 10 > EClass.rnd(10)) ? 1 : 0) + 1);
203 }
204 else if (scatter > 0)
205 {
206 Act.TP.ForeachNeighbor(delegate(Point _p)
207 {
208 points.Add(_p.Copy());
209 });
210 }
212 {
213 EClass.Wait(0.25f, Act.CC);
214 }
215 Shoot(Act.TC, Act.TP, subAttack: false);
216 if (points.Count > 0)
217 {
218 Point obj = Act.TP.Copy();
219 foreach (Point item2 in points)
220 {
221 if (item2.Equals(obj))
222 {
223 continue;
224 }
225 Chara firstChara = item2.FirstChara;
226 if (firstChara != null && !firstChara.IsHostile(Act.CC))
227 {
228 continue;
229 }
230 if (scatter > 0)
231 {
232 if (EClass.rnd(EClass.rnd(100) + 1) > scatter)
233 {
234 continue;
235 }
236 }
237 else if (firstChara == null)
238 {
239 continue;
240 }
241 Shoot(item2.FirstChara ?? item2.FindThing<TraitTrainingDummy>()?.owner, item2, subAttack: true);
242 }
243 }
244 if (!(weapon.trait is TraitToolRangeCane))
245 {
246 weapon.c_ammo -= num2;
247 if (weapon.ammoData != null)
248 {
249 weapon.ammoData.Num = weapon.c_ammo;
250 }
251 if (weapon.c_ammo <= 0)
252 {
253 weapon.c_ammo = 0;
254 weapon.ammoData = null;
255 }
256 }
257 if (Act.CC.IsPC)
258 {
260 }
261 if (Act.TC != null && !hasHit)
262 {
263 Act.CC.PlaySound(missSound);
264 }
265 if (!Act.CC.isDead)
266 {
267 if (EClass.rnd(2) == 0)
268 {
269 Act.CC.RemoveCondition<ConInvisibility>();
270 }
271 if (weapon.trait is TraitToolRangeCane)
272 {
273 Act.CC.mana.Mod(-num3 * numFire);
274 }
275 }
276 return true;
277 int GetWeaponEnc(int ele)
278 {
279 return weapon.Evalue(ele) + (Act.CC.IsPCFactionOrMinion ? EClass.pc.faction.charaElements.Value(ele) : 0);
280 }
281 void Prepare()
282 {
284 AttackProcess.Current.numFire = numFire;
285 AttackProcess.Current.numFireWithoutDamageLoss = numFireWithoutDamageLoss;
286 AttackProcess.Current.posRangedAnime = Act.TP.Copy();
287 AttackProcess.Current.ignoreAnime = index > 1;
288 AttackProcess.Current.ignoreAttackSound = false;
289 if (drill > 0 && points.Count > 0)
290 {
291 AttackProcess.Current.posRangedAnime = points.LastItem();
292 }
293 else if (scatter > 0)
294 {
295 AttackProcess.Current.ignoreAnime = false;
296 AttackProcess.Current.ignoreAttackSound = index > 1;
297 }
298 }
299 void Shoot(Card _tc, Point _tp, bool subAttack)
300 {
301 float dmgMulti = 1f;
302 index++;
303 Act.TC = _tc;
304 Act.TP = _tp;
305 CellEffect effect = Act.TP.cell.effect;
306 if (effect != null && effect.id == 6 && EClass.rnd(2) == 0)
307 {
308 Prepare();
310 Act.CC.PlaySound(missSound);
311 Act.CC.Say("abMistOfDarkness_miss", Act.CC);
312 }
313 else
314 {
315 if (scatter > 0)
316 {
317 dmgMulti = Mathf.Clamp(1.2f - 0.2f * (float)Act.CC.Dist(Act.TP) - (Act.TP.Equals(orgTP) ? 0f : 0.4f), 0.2f, 1f);
318 }
319 for (int j = 0; j < numFire; j++)
320 {
321 Act.TC = _tc;
322 Card tC = Act.TC;
323 Chara cC = Act.CC;
324 Point point = Act.TP.Copy();
325 if (isRocket && EClass.rnd(3) == 0)
326 {
328 }
329 Prepare();
330 int num5 = 0;
331 if (weapon.trait is TraitToolRangeGunEnergy && Act.TC != null && Act.TC.isChara && Act.TC.HasElement(383))
332 {
333 if (weapon.id == "gun_laser")
334 {
335 num5 = 50;
336 }
337 num5 += Mathf.Max(25 * Act.TC.PER / Mathf.Max(1, Act.CC.PER), 50);
338 if (Act.CC.IsPowerful)
339 {
340 num5 /= 2;
341 }
342 }
343 if (num5 > EClass.rnd(100))
344 {
345 List<Chara> list = Act.TC.pos.ListCharasInRadius(Act.TC.Chara, Act.TC.GetSightRadius(), (Chara c) => c.IsHostile(Act.TC.Chara));
346 Chara chara = ((list.Count > 0) ? list.RandomItem() : Act.CC?.Chara);
347 Act.TC.Say((Act.TC.isChara && Act.TC.Chara.IsHostile()) ? "attack_reflect_enemy" : "attack_reflect");
348 Act.TC.PlaySound("attack_gun_laser_parry");
350 AttackProcess.Current.CC = Act.TC?.Chara;
351 AttackProcess.Current.TC = chara;
353 AttackProcess.Current.posRangedAnime = chara.pos;
354 AttackProcess.Current.Perform(j, hasHit, chara.IsPCFactionOrMinion ? 0.1f : 2.5f, maxRoll: true, subAttack: true);
355 }
356 else if (AttackProcess.Current.Perform(j, hasHit, dmgMulti, maxRoll: false, subAttack))
357 {
358 hasHit = true;
359 }
360 else if (chaser > 0)
361 {
362 for (int k = 0; k < 10; k++)
363 {
364 if (chaser > EClass.rnd(4 + (int)Mathf.Pow(4f, k + 2 + j)))
365 {
366 Act.CC.Say(Act.CC.IsHostile() ? "attack_chaser_enemy" : "attack_chaser");
367 if (AttackProcess.Current.Perform(j, hasHit, dmgMulti, maxRoll: false, subAttack))
368 {
369 hasHit = true;
370 break;
371 }
372 }
373 }
374 }
375 if (isRocket)
376 {
377 ActEffect.ProcAt(EffectId.Rocket, AttackProcess.Current.GetRocketPower(), BlessedState.Normal, Act.CC, null, Act.TP, isNeg: true, new ActRef
378 {
379 origin = Act.CC.Chara,
380 refThing = weapon,
381 aliasEle = "eleImpact"
382 });
383 }
384 Act.TC = tC;
385 Act.CC = cC;
386 Act.TP.Set(point);
387 if (!isRocket && (Act.TC == null || !Act.TC.IsAliveInCurrentZone))
388 {
389 break;
390 }
391 }
392 if (Act.TC != null)
393 {
395 }
396 }
397 }
398 }
399
400 public static bool TryReload(Thing weapon, Thing ammo = null)
401 {
402 TraitToolRange traitToolRange = weapon.trait as TraitToolRange;
403 if (Act.CC.IsPC)
404 {
406 }
407 if (weapon.ammoData != null)
408 {
409 if (weapon.ammoData.Num > 0)
410 {
411 Act.CC.Pick(weapon.ammoData);
412 }
413 weapon.ammoData = null;
414 }
415 int num = 0;
416 if (ammo == null)
417 {
419 }
420 if (ammo == null)
421 {
422 if (Act.CC.IsPC && !traitToolRange.AutoRefillAmmo)
423 {
424 if (!weapon.IsMeleeWithAmmo)
425 {
426 Msg.Say("noAmmo", weapon);
427 }
428 return false;
429 }
430 num = traitToolRange.MaxAmmo;
431 }
432 else
433 {
434 num = Mathf.Min(ammo.Num, traitToolRange.MaxAmmo);
435 Thing thing = ammo.Split(num);
436 Act.CC.Say("takeAmmo", thing);
437 if (thing.GetRootCard() == Act.CC)
438 {
439 thing.parent.RemoveCard(thing);
440 }
441 weapon.ammoData = thing;
442 }
443 weapon.c_ammo = num;
444 int reloadTurn = traitToolRange.ReloadTurn;
445 reloadTurn = reloadTurn * 100 / (100 + Act.CC.Evalue(1652) * 100);
446 if (traitToolRange.NeedReload && reloadTurn > 0)
447 {
448 Act.CC.AddCondition<ConReload>(reloadTurn * 10);
449 }
450 return true;
451 }
452}
BlessedState
Definition: BlessedState.cs:2
EffectId
Definition: EffectId.cs:2
virtual bool IsNoGoal
Definition: AIAct.cs:74
static void ProcAt(EffectId id, int power, BlessedState state, Card cc, Card tc, Point tp, bool isNeg, ActRef actRef=default(ActRef))
Definition: ActEffect.cs:440
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:400
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
int GetRocketPower()
void PlayRangedAnime(int numFire, float delay=0f)
virtual void NextFrame()
Definition: Card.cs:11
bool IsPCFactionOrMinion
Definition: Card.cs:2260
virtual Chara Chara
Definition: Card.cs:2058
int GetSightRadius()
Definition: Card.cs:6259
bool IsRestrainedResident
Definition: Card.cs:2246
bool HasElement(int ele, int req=1)
Definition: Card.cs:5787
bool isRestrained
Definition: Card.cs:566
int PER
Definition: Card.cs:2327
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:6009
ICardParent parent
Definition: Card.cs:55
Point pos
Definition: Card.cs:59
Trait trait
Definition: Card.cs:53
bool IsPowerful
Definition: Card.cs:2082
virtual bool IsAliveInCurrentZone
Definition: Card.cs:2115
virtual bool isChara
Definition: Card.cs:2071
Card GetRootCard()
Definition: Card.cs:3356
int Evalue(int ele)
Definition: Card.cs:2559
int Dist(Card c)
Definition: Card.cs:7504
CardRenderer renderer
Definition: Card.cs:61
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:6661
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:8990
Thing FindAmmo(Thing weapon)
Definition: Chara.cs:7613
Faction faction
Definition: Chara.cs:425
override bool IsPC
Definition: Chara.cs:610
bool CanSeeLos(Card c, int dist=-1)
Definition: Chara.cs:1244
bool RequestProtection(Chara attacker, Action< Chara > action)
Definition: Chara.cs:8170
bool HasCondition(string alias)
Definition: Chara.cs:9147
AIAct SetAI(AIAct g)
Definition: Chara.cs:8620
Thing ranged
Definition: Chara.cs:98
Stats mana
Definition: Chara.cs:1148
void DoHostileAction(Card _tg, bool immediate=false)
Definition: Chara.cs:6214
bool IsHostile()
Definition: Chara.cs:6391
bool isDead
Definition: Chara.cs:387
override void LookAt(Card c)
Definition: Chara.cs:3501
bool TryEquipRanged()
Definition: Chara.cs:7643
Thing Pick(Thing t, bool msg=true, bool tryStack=true)
Definition: Chara.cs:4231
new GameConfig game
Definition: CoreConfig.cs:605
bool godMode
Definition: CoreDebug.cs:173
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:2326
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:2061
HotItem currentHotItem
Definition: Player.cs:1097
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:1385
List< Chara > ListCharasInRadius(Chara cc, int dist, Func< Chara, bool > func, bool onlyVisible=true)
Definition: Point.cs:1208
bool Equals(int _x, int _z)
Definition: Point.cs:948
Card FindAttackTarget()
Definition: Point.cs:1086
Chara FirstChara
Definition: Point.cs:276
Cell cell
Definition: Point.cs:51
Thing FindThing(Func< Thing, bool > func)
Definition: Point.cs:1128
Point GetRandomNeighbor()
Definition: Point.cs:747
virtual void Mod(int a)
Definition: Stats.cs:135
virtual int value
Definition: Stats.cs:56
Definition: Thing.cs:8
virtual bool AutoRefillAmmo
virtual bool NeedReload
Card owner
Definition: Trait.cs:27
bool TryGetValue(TKey key, out TValue value)
Definition: UDictionary.cs:178
void RemoveCard(Card c)
Definition: ActRef.cs:2