Elin Decompiled Documentation EA 23.333 Myaightly Patch 1
Loading...
Searching...
No Matches
AI_PlayMusic.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using DG.Tweening;
4using UnityEngine;
5
6public class AI_PlayMusic : AIAct
7{
8 public static bool keepPlaying;
9
10 public static Thing playingTool;
11
12 public Thing tool;
13
14 public static bool ignoreDamage;
15
17
18 public int score;
19
20 public int gold;
21
22 public int toolLv;
23
24 public override bool ShowProgress => false;
25
26 public override bool CancelWhenDamaged => !ignoreDamage;
27
28 public override TargetType TargetType
29 {
30 get
31 {
32 if (tool != null && tool != EClass.pc.Tool)
33 {
34 return TargetType.Any;
35 }
36 return TargetType.Self;
37 }
38 }
39
40 public static void CancelKeepPlaying()
41 {
42 if (keepPlaying)
43 {
44 SE.CancelAction();
45 keepPlaying = false;
46 playingTool = null;
47 }
48 }
49
50 public override IEnumerable<Status> Run()
51 {
52 if (tool == null)
53 {
54 tool = (owner.IsPC ? owner.Tool : owner.things.Find<TraitToolMusic>());
55 }
56 if (tool == null && !owner.IsPCFaction && EClass.rnd(20) == 0)
57 {
59 }
60 if (tool == null)
61 {
62 yield return Cancel();
63 }
64 if (tool.parent is Zone)
65 {
66 yield return DoGoto(tool.pos, tool.pos.IsBlocked ? 1 : 0);
67 }
69 {
70 keepPlaying = true;
72 EInput.Consume(consumeAxis: true, 10);
73 }
74 toolLv = 1;
75 string idSong = null;
76 KnownSong song = null;
77 playing = null;
78 score = 40;
79 gold = 0;
81 {
83 idSong = EClass.player.playingSong.id;
85 }
86 if (playing == null)
87 {
88 switch (tool.id)
89 {
90 case "sax":
91 case "trumpet":
92 idSong = "trumpet_practice";
93 break;
94 case "piano_gould":
95 idSong = "piano_gould";
96 break;
97 case "piano_killkill":
98 case "piano2":
99 idSong = "piano_neko";
100 break;
101 case "piano":
102 idSong = "piano_kanon";
103 break;
104 case "harpsichord":
105 idSong = "harpsichord_goldberg";
106 break;
107 case "guitar_ash":
108 idSong = "guitar_caccini";
109 break;
110 case "ocarina":
111 idSong = "ocarina_lulu";
112 break;
113 case "harmonica":
114 idSong = "harmonica_kumi";
115 break;
116 case "guitar_efrond":
117 case "guitar_elec":
118 idSong = "guitar_dusk";
119 break;
120 case "guitar":
121 idSong = "guitar_air";
122 break;
123 case "harp":
124 idSong = "harp_komori";
125 break;
126 case "shield_lute":
127 case "lute":
128 idSong = "guitar_sad";
129 break;
130 case "recorder":
131 idSong = "recorder";
132 break;
133 case "flute":
134 idSong = "flute";
135 break;
136 case "taiko":
137 case "drum":
138 idSong = "taiko";
139 break;
140 case "mokugyo":
141 idSong = "mokugyo";
142 break;
143 case "tambourine":
144 idSong = "tambourine";
145 break;
146 case "mic":
147 idSong = "mic_rachmaninoff";
148 break;
149 case "cello":
150 idSong = "cello_prelude";
151 break;
152 case "koto":
153 idSong = "koto";
154 break;
155 case "instrument_violin":
156 case "panty":
157 idSong = "violin_chaconne";
158 break;
159 case "stradivarius":
160 idSong = "violin_furusato";
161 break;
162 default:
163 idSong = ((EClass.Sound.GetData("Instrument/" + tool.id) is BGMData) ? tool.id : "violin_chaconne");
164 break;
165 }
166 if (owner.IsPC && EClass.player.knownSongs.ContainsKey(idSong))
167 {
168 song = EClass.player.knownSongs[idSong];
169 }
170 if (song == null)
171 {
172 song = new KnownSong();
173 if (owner.IsPC)
174 {
175 EClass.player.knownSongs[idSong] = song;
176 }
177 }
178 playing = new PlayingSong
179 {
180 id = idSong,
181 idTool = tool.id
182 };
183 if (owner.IsPC)
184 {
185 EClass.player.playingSong = playing;
186 }
187 }
188 if (owner.IsPC && EClass.Sound.GetData("Instrument/" + idSong) is BGMData bGMData)
189 {
190 bGMData.song.index = playing.index;
191 }
192 if (Application.isEditor && owner.IsPC)
193 {
194 song.lv += 10;
195 Debug.Log(song.lv);
196 }
197 List<Chara> reacted = new List<Chara>();
198 Progress_Custom progress = new Progress_Custom
199 {
200 maxProgress = 15,
201 cancelWhenMoved = false,
202 showProgress = false,
203 canProgress = () => tool != null && !tool.isDestroyed,
204 onProgressBegin = delegate
205 {
206 owner.Say("music_start", owner, tool);
207 owner.ShowEmo(Emo.happy, 3f, skipSame: false);
208 if (tool != null && tool.ExistsOnMap)
209 {
211 }
212 owner.PlayAnime(AnimeID.PlayMusic);
213 if (owner.IsPC)
214 {
215 bool flag = false;
216 if (playing.mistakes == 0 && (bool)playing.source && playing.source.isPlaying && playing.source.data.name == idSong)
217 {
218 SoundSource soundSource = playing.source;
219 if (Mathf.Abs(soundSource.source.time - (soundSource.data as BGMData).song.parts[playing.index].start) < 2f && playing.source.source.volume >= 0.1f)
220 {
221 soundSource.KeepPlay();
222 flag = true;
223 Debug.Log("keep:" + soundSource.source.time);
224 }
225 else
226 {
227 EClass.Sound.Stop(soundSource.data, 0.1f);
228 }
229 Debug.Log(playing.source);
230 }
231 if (!flag)
232 {
233 playing.source = owner.PlaySound("Instrument/" + idSong);
234 Debug.Log(playing.source);
235 }
236 playing.bgm = playing.source.data as BGMData;
237 BGMData.Part part = playing.bgm.song.parts[playing.index];
238 if (!UISong.Instance)
239 {
240 Util.Instantiate<UISong>("UI/Util/UISong", EClass.ui.rectDynamicEssential);
241 }
243 if (EClass.Sound.currentBGM != null)
244 {
245 float num3 = 0.5f - 0.1f * (float)playing.index;
246 if (num3 < 0f)
247 {
248 num3 = 0f;
249 }
250 if (EClass.Sound.sourceBGM.volume > EClass.Sound.currentBGM.data.volume * num3)
251 {
252 EClass.Sound.sourceBGM.DOFade(EClass.Sound.currentBGM.data.volume * num3, 3f);
253 }
254 SoundManager.jingleTimer = part.duration / playing.bgm.pitch + playing.bgm.song.fadeIn + 2f;
255 }
256 }
257 },
258 onProgress = delegate(Progress_Custom p)
259 {
261 owner.Say(Lang.GetList("music").RandomItem());
262 Msg.SetColor();
263 if (tool.id == "tambourine")
264 {
265 Msg.Say("tambourine");
266 }
267 if (EClass.debug.enable && EClass.pc.job.id == "pianist")
268 {
269 song.lv = 10000;
270 }
271 if (p.progress > 2 && (EClass.rnd(100 + 50 * owner.Evalue(1405)) == 0 || EClass.rnd(4 + (int)MathF.Max(0f, song.lv - playing.index * 25 - playing.index * playing.index / 2)) == 0))
272 {
274 if (EClass.rnd(2) == 0)
275 {
276 LevelSong(2 + 2 * EClass.rnd(owner.Evalue(1405) + 1));
277 }
278 if (playing.mistakes >= 10)
279 {
280 playing.index = 0;
281 }
282 Cancel();
283 }
284 else
285 {
287 {
288 if (item.conSleep != null && item.ResistLv(957) <= 0)
289 {
290 item.conSleep.Kill();
291 item.ShowEmo(Emo.angry);
292 }
293 }
294 List<Chara> list = owner.pos.ListWitnesses(owner, 4, WitnessType.music);
295 int num = (owner.Evalue(241) + tool?.Evalue(241)).Value * (100 + toolLv) / 100;
296 int num2 = 0;
297 foreach (Chara item2 in list)
298 {
299 if (owner == null)
300 {
301 break;
302 }
303 if (!reacted.Contains(item2) && EClass.rnd(5) == 0)
304 {
305 if (tool != null)
306 {
307 foreach (Element value in tool.elements.dict.Values)
308 {
309 if (value.id == 489 && EClass.rnd(8) == 0)
310 {
311 item2.AddCondition<ConDrunk>();
312 }
313 if (value.source.categorySub == "eleAttack")
314 {
315 item2.ApplyElementEffect(value, value.Value * 10, owner, checkHostileAct: true);
316 }
317 }
318 }
319 if (owner.IsPCParty)
320 {
321 if (item2.interest <= 0 || (EClass._zone is Zone_Music && (item2.IsPCFaction || item2.IsPCFactionMinion)))
322 {
323 continue;
324 }
325 if (!item2.isDrunk)
326 {
327 item2.interest -= EClass.rnd(10);
328 if (item2.interest < 0)
329 {
330 item2.Talk("musicBored");
331 continue;
332 }
333 }
334 }
335 if (EClass.rnd(num2 * num2) <= 30 && item2.pos.FirstChara == item2)
336 {
337 bool isMinion = item2.IsMinion;
338 p.cancelWhenDamaged = false;
339 if (num < item2.LV && EClass.rnd(2) == 0)
340 {
341 reacted.Add(item2);
342 if (!isMinion)
343 {
344 score -= item2.LV / 2 - 10;
345 }
346 if (EClass.rnd(2) == 0)
347 {
348 item2.Talk("musicBad");
349 }
350 else
351 {
352 item2.Say("musicBad", item2, owner);
353 }
354 item2.ShowEmo(Emo.sad);
355 owner.elements.ModExp(241, 10f);
356 if (EClass.rnd(5) == 0)
357 {
358 ThrowReward(item2, punish: true);
359 }
360 num2++;
361 }
362 else if (EClass.rnd(num + 5) > EClass.rnd(item2.LV * 5 + 1))
363 {
364 reacted.Add(item2);
365 if (!isMinion)
366 {
367 score += EClass.rnd(item2.LV / 2 + 5) + 5;
368 }
369 if (EClass.rnd(2) == 0)
370 {
371 item2.Talk("musicGood");
372 }
373 else
374 {
375 item2.Say("musicGood", item2, owner);
376 }
377 item2.ShowEmo(Emo.happy);
378 item2.renderer.PlayAnime((EClass.rnd(2) == 0) ? AnimeID.Jump : AnimeID.Fishing);
379 owner.elements.ModExp(241, EClass._zone.IsUserZone ? 10 : 50);
380 if (!isMinion)
381 {
382 ThrowReward(item2, punish: false);
383 }
384 num2++;
385 }
386 p.cancelWhenDamaged = true;
387 }
388 }
389 }
390 if (owner != null && owner.IsPC && EClass.rnd(80) < num2)
391 {
392 owner.stamina.Mod(-1);
393 }
394 }
395 },
396 onProgressComplete = delegate
397 {
398 if (EClass.rnd(2) == 0)
399 {
400 LevelSong(2);
401 }
402 if ((bool)playing.bgm)
403 {
404 playing.index++;
405 playing.mistakes = 0;
406 if (playing.index >= playing.bgm.song.parts.Count)
407 {
408 playing.index = 0;
409 }
410 playing.bgm.song.index = playing.index;
411 }
412 Evaluate(success: true);
413 }
414 }.SetDuration(26);
415 yield return Do(progress);
416 if (progress.status == Status.Fail)
417 {
418 yield return Cancel();
419 }
420 void LevelSong(int a)
421 {
422 if (a > 0)
423 {
424 song.lv += a + EClass.rnd(2);
425 if (owner == EClass.pc)
426 {
427 Msg.Say("level_song");
428 }
429 }
430 }
431 }
432
433 public void Evaluate(bool success)
434 {
435 if (owner == null || !owner.IsPC)
436 {
437 return;
438 }
439 if (success)
440 {
441 score = score * 110 / 100;
442 }
443 else
444 {
445 score = score / 2 - 20;
446 }
447 int num = Mathf.Clamp(score / 20 + 1, 0, 9);
448 owner.Say(Lang.GetList("music_result")[num]);
449 if (gold > 0)
450 {
451 owner.Say("music_reward", owner, gold.ToString() ?? "");
452 }
453 if (EClass.rnd(3) != 0)
454 {
455 owner.stamina.Mod(-1);
456 }
457 QuestMusic questMusic = EClass.game.quests.Get<QuestMusic>();
458 if (questMusic != null)
459 {
460 questMusic.score += score;
461 questMusic.sumMoney += gold;
462 int num2 = num / 2 - 1;
463 if (num > 0)
464 {
465 SE.Play("clap" + num2);
466 }
467 }
468 }
469
470 public void ThrowReward(Chara c, bool punish)
471 {
472 Thing thing = null;
473 string text = "";
474 int num = 1;
475 bool flag = true;
476 if (punish)
477 {
478 text = ((EClass.rnd(5) == 0) ? "rock" : "pebble");
479 if (EClass.rnd(8) == 0)
480 {
481 text = ((EClass.rnd(3) == 0) ? "water_dirty" : "water");
482 }
483 if (!c.IsPCFactionOrMinion)
484 {
485 thing = c.TryGetThrowable()?.Split(1);
486 }
487 }
488 else if (EClass.rnd(100) == 0 && !EClass._zone.IsUserZone)
489 {
490 text = "ecopo";
491 if (EClass.rnd(4) == 0)
492 {
493 text = "gacha_coin";
494 }
495 if (EClass.rnd(4) == 0)
496 {
497 text = "plat";
498 }
499 if (EClass.rnd(3) == 0)
500 {
501 text = "tomato";
502 }
503 if (EClass.rnd(3) == 0)
504 {
505 text = "casino_coin";
506 }
507 if (owner.IsPC && !EClass._zone.IsInstance)
508 {
509 if (c.LV >= 20 && EClass.rnd(10 * (int)Mathf.Pow(2f, EClass.player.flags.reward_killkill + 1)) == 0)
510 {
511 text = "piano_killkill";
512 punish = true;
513 flag = false;
515 }
516 else if (c.LV >= 40 && EClass.rnd(10 * (int)Mathf.Pow(2f, EClass.player.flags.reward_gould + 1)) == 0)
517 {
518 text = "piano_gould";
519 punish = true;
520 flag = false;
522 }
523 }
524 }
525 else
526 {
527 num = (EClass.rnd(c.LV * 2 + 1) + 1) * (100 + toolLv * 2 + owner.Evalue(1405) * 10) / 100;
528 if (c.IsUnique)
529 {
530 num *= 2;
531 }
532 if (!(EClass._zone is Zone_Music))
533 {
534 if (num > 25)
535 {
536 num /= 2;
537 }
538 if (num > 50)
539 {
540 num /= 2;
541 }
542 if (num > 100)
543 {
544 num /= 2;
545 }
547 {
548 num /= 5;
549 }
550 }
551 if (num < 1)
552 {
553 num = 1;
554 }
555 gold += num;
556 text = "money";
557 }
558 if (!owner.IsPCParty && !punish && text != "money")
559 {
560 return;
561 }
562 if (thing == null)
563 {
564 thing = ThingGen.Create(text, -1, owner.LV).SetNum(num);
565 }
566 ignoreDamage = true;
567 ActThrow.Throw(c, owner.pos, thing, (!punish) ? ThrowMethod.Reward : ThrowMethod.Punish);
568 ignoreDamage = false;
569 if (owner == null || !thing.ExistsOnMap)
570 {
571 return;
572 }
573 if (!owner.IsPC && owner.things.IsFull())
574 {
575 thing.Destroy();
576 }
577 else
578 {
579 if (!owner.IsAliveInCurrentZone)
580 {
581 return;
582 }
583 if (flag)
584 {
585 owner.Pick(thing);
586 }
587 if (thing.id == "money" && !owner.IsPC)
588 {
589 int? obj = ((owner.Evalue(241) + tool?.Evalue(241)) * 10 + 100) / ((owner.IsPCFaction && owner.memberType == FactionMemberType.Default) ? 1 : 10);
590 if (owner.GetCurrency() - obj > 0)
591 {
592 owner.c_allowance += num;
593 owner.ModCurrency(-num);
594 }
595 }
596 }
597 }
598
599 public override void OnCancel()
600 {
601 if (playing != null && (bool)playing.bgm)
602 {
603 playing.bgm.song.Fail(playing.source, playing.bgm);
604 if ((bool)UISong.Instance)
605 {
607 }
608 playing.source = null;
609 SoundManager.jingleTimer = 1f;
610 }
611 Evaluate(success: false);
612 }
613}
AnimeID
Definition: AnimeID.cs:2
if(!match.Success)
Emo
Definition: Emo.cs:2
FactionMemberType
ThrowMethod
Definition: ThrowMethod.cs:2
WitnessType
Definition: WitnessType.cs:2
Definition: AIAct.cs:6
Status Do(AIAct _seq, Func< Status > _onChildFail=null)
Definition: AIAct.cs:430
virtual Status Cancel()
Definition: AIAct.cs:305
new Chara owner
Definition: AIAct.cs:14
Status
Definition: AIAct.cs:8
Status DoGoto(Point pos, int dist=0, bool ignoreConnection=false, Func< Status > _onChildFail=null)
Definition: AIAct.cs:446
int progress
Definition: AIProgress.cs:5
override bool CancelWhenDamaged
Definition: AI_PlayMusic.cs:26
override bool ShowProgress
Definition: AI_PlayMusic.cs:24
static Thing playingTool
Definition: AI_PlayMusic.cs:10
override IEnumerable< Status > Run()
Definition: AI_PlayMusic.cs:50
void ThrowReward(Chara c, bool punish)
static bool keepPlaying
Definition: AI_PlayMusic.cs:8
static void CancelKeepPlaying()
Definition: AI_PlayMusic.cs:40
override void OnCancel()
void Evaluate(bool success)
PlayingSong playing
Definition: AI_PlayMusic.cs:16
static bool ignoreDamage
Definition: AI_PlayMusic.cs:14
static EffectIRenderer Throw(Card c, Point p, Thing t, ThrowMethod method=ThrowMethod.Default, float failChance=0f)
Definition: ActThrow.cs:97
void PlayAnime(AnimeID id, bool force)
bool isDestroyed
Definition: Card.cs:78
bool IsPCFactionOrMinion
Definition: Card.cs:2342
Thing Split(int a)
Definition: Card.cs:3662
ElementContainerCard elements
Definition: Card.cs:42
string id
Definition: Card.cs:36
bool IsUnique
Definition: Card.cs:2143
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:6626
Thing Tool
Definition: Card.cs:2480
Thing AddThing(string id, int lv=-1)
Definition: Card.cs:3277
void Talk(string idTopic, string ref1=null, string ref2=null, bool forceSync=false)
Definition: Card.cs:7186
ICardParent parent
Definition: Card.cs:56
bool ExistsOnMap
Definition: Card.cs:2137
Thing SetNum(int a)
Definition: Card.cs:3673
void ApplyElementEffect(Element e, int eleP, Card origin, bool checkHostileAct=false)
Definition: Card.cs:5077
Point pos
Definition: Card.cs:60
void ShowEmo(Emo _emo=Emo.none, float duration=0f, bool skipSame=true)
Definition: Card.cs:6594
void Destroy()
Definition: Card.cs:5305
ThingContainer things
Definition: Card.cs:39
int Evalue(int ele)
Definition: Card.cs:2704
void PlayAnime(AnimeID id, bool force=false)
Definition: Card.cs:6645
CardRenderer renderer
Definition: Card.cs:64
int LV
Definition: Card.cs:389
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:7304
Definition: Chara.cs:10
Condition AddCondition(string id, int p=100, bool force=false)
Definition: Chara.cs:9798
override bool IsPC
Definition: Chara.cs:630
bool isDrunk
Definition: Chara.cs:126
SourceJob.Row job
Definition: Chara.cs:470
override bool IsPCParty
Definition: Chara.cs:633
int interest
Definition: Chara.cs:321
override bool IsMinion
Definition: Chara.cs:645
override bool IsPCFaction
Definition: Chara.cs:689
Thing TryGetThrowable()
Definition: Chara.cs:8193
override bool IsPCFactionMinion
Definition: Chara.cs:673
Stats stamina
Definition: Chara.cs:1205
override void LookAt(Card c)
Definition: Chara.cs:3775
bool enable
Definition: CoreDebug.cs:301
Definition: EClass.cs:6
static Game game
Definition: EClass.cs:9
static Zone _zone
Definition: EClass.cs:21
static Map _map
Definition: EClass.cs:19
static int rnd(long a)
Definition: EClass.cs:59
static Player player
Definition: EClass.cs:13
static Chara pc
Definition: EClass.cs:15
static CoreDebug debug
Definition: EClass.cs:49
static SoundManager Sound
Definition: EClass.cs:47
static UI ui
Definition: EClass.cs:17
Definition: EInput.cs:8
static void Consume(int _skipFrame)
Definition: EInput.cs:667
void ModExp(int ele, float a, bool chain=false)
Dictionary< int, Element > dict
int id
Definition: ELEMENT.cs:259
SourceElement.Row source
Definition: ELEMENT.cs:282
int Value
Definition: ELEMENT.cs:301
ConfigPreference preference
Definition: Game.cs:97
Config config
Definition: Game.cs:219
QuestManager quests
Definition: Game.cs:183
int lv
Definition: KnownSong.cs:6
Definition: Lang.cs:7
static string[] GetList(string id)
Definition: Lang.cs:113
List< Chara > ListCharasInCircle(Point center, float radius, bool los=true)
Definition: Map.cs:2350
Color Ono
Definition: MsgColors.cs:13
Definition: Msg.cs:5
static MsgColors colors
Definition: Msg.cs:20
static string Say(string idLang, string ref1, string ref2=null, string ref3=null, string ref4=null)
Definition: Msg.cs:58
static void SetColor()
Definition: Msg.cs:22
int reward_killkill
Definition: Player.cs:724
int reward_gould
Definition: Player.cs:712
Flags flags
Definition: Player.cs:1161
Dictionary< string, KnownSong > knownSongs
Definition: Player.cs:1113
PlayingSong playingSong
Definition: Player.cs:1291
SoundSource source
Definition: PlayingSong.cs:13
string idTool
Definition: PlayingSong.cs:5
BGMData bgm
Definition: PlayingSong.cs:11
string id
Definition: PlayingSong.cs:3
int mistakes
Definition: PlayingSong.cs:9
List< Chara > ListWitnesses(Chara criminal, int radius=4, WitnessType type=WitnessType.crime, Chara target=null)
Definition: Point.cs:835
bool IsBlocked
Definition: Point.cs:363
Quest Get(string id)
virtual void Mod(int a)
Definition: Stats.cs:135
static TargetTypeSelf Self
Definition: TargetType.cs:7
static TargetTypeAny Any
Definition: TargetType.cs:5
Thing Find(int uid)
static Thing Create(string id, int idMat=-1, int lv=-1)
Definition: ThingGen.cs:53
Definition: Thing.cs:8
Definition: UISong.cs:5
void Kill()
Definition: UISong.cs:69
void SetSong(SoundSource _source, BGMData _bgm, BGMData.Part _part)
Definition: UISong.cs:29
static UISong Instance
Definition: UISong.cs:6
Definition: Zone.cs:12
virtual bool IsUserZone
Definition: Zone.cs:275
bool IsInstance
Definition: Zone.cs:493