Elin Decompiled Documentation EA 23.297 Nightly 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 idSong = "guitar_dusk";
118 break;
119 case "guitar":
120 idSong = "guitar_air";
121 break;
122 case "harp":
123 idSong = "harp_komori";
124 break;
125 case "shield_lute":
126 case "lute":
127 idSong = "guitar_sad";
128 break;
129 case "recorder":
130 idSong = "recorder";
131 break;
132 case "flute":
133 idSong = "flute";
134 break;
135 case "taiko":
136 case "drum":
137 idSong = "taiko";
138 break;
139 case "mokugyo":
140 idSong = "mokugyo";
141 break;
142 case "tambourine":
143 idSong = "tambourine";
144 break;
145 case "mic":
146 idSong = "mic_rachmaninoff";
147 break;
148 case "cello":
149 idSong = "cello_prelude";
150 break;
151 case "koto":
152 idSong = "koto";
153 break;
154 case "instrument_violin":
155 case "panty":
156 idSong = "violin_chaconne";
157 break;
158 case "stradivarius":
159 idSong = "violin_furusato";
160 break;
161 default:
162 idSong = ((EClass.Sound.GetData("Instrument/" + tool.id) is BGMData) ? tool.id : "violin_chaconne");
163 break;
164 }
165 if (owner.IsPC && EClass.player.knownSongs.ContainsKey(idSong))
166 {
167 song = EClass.player.knownSongs[idSong];
168 }
169 if (song == null)
170 {
171 song = new KnownSong();
172 if (owner.IsPC)
173 {
174 EClass.player.knownSongs[idSong] = song;
175 }
176 }
177 playing = new PlayingSong
178 {
179 id = idSong,
180 idTool = tool.id
181 };
182 if (owner.IsPC)
183 {
184 EClass.player.playingSong = playing;
185 }
186 }
187 if (owner.IsPC && EClass.Sound.GetData("Instrument/" + idSong) is BGMData bGMData)
188 {
189 bGMData.song.index = playing.index;
190 }
191 if (Application.isEditor && owner.IsPC)
192 {
193 song.lv += 10;
194 Debug.Log(song.lv);
195 }
196 List<Chara> reacted = new List<Chara>();
197 Progress_Custom progress = new Progress_Custom
198 {
199 maxProgress = 15,
200 cancelWhenMoved = false,
201 showProgress = false,
202 canProgress = () => tool != null && !tool.isDestroyed,
203 onProgressBegin = delegate
204 {
205 owner.Say("music_start", owner, tool);
206 owner.ShowEmo(Emo.happy, 3f, skipSame: false);
207 if (tool != null && tool.ExistsOnMap)
208 {
210 }
211 owner.PlayAnime(AnimeID.PlayMusic);
212 if (owner.IsPC)
213 {
214 bool flag = false;
215 if (playing.mistakes == 0 && (bool)playing.source && playing.source.isPlaying && playing.source.data.name == idSong)
216 {
217 SoundSource soundSource = playing.source;
218 if (Mathf.Abs(soundSource.source.time - (soundSource.data as BGMData).song.parts[playing.index].start) < 2f && playing.source.source.volume >= 0.1f)
219 {
220 soundSource.KeepPlay();
221 flag = true;
222 Debug.Log("keep:" + soundSource.source.time);
223 }
224 else
225 {
226 EClass.Sound.Stop(soundSource.data, 0.1f);
227 }
228 Debug.Log(playing.source);
229 }
230 if (!flag)
231 {
232 playing.source = owner.PlaySound("Instrument/" + idSong);
233 Debug.Log(playing.source);
234 }
235 playing.bgm = playing.source.data as BGMData;
236 BGMData.Part part = playing.bgm.song.parts[playing.index];
237 if (!UISong.Instance)
238 {
239 Util.Instantiate<UISong>("UI/Util/UISong", EClass.ui.rectDynamicEssential);
240 }
242 if (EClass.Sound.currentBGM != null)
243 {
244 float num3 = 0.5f - 0.1f * (float)playing.index;
245 if (num3 < 0f)
246 {
247 num3 = 0f;
248 }
249 if (EClass.Sound.sourceBGM.volume > EClass.Sound.currentBGM.data.volume * num3)
250 {
251 EClass.Sound.sourceBGM.DOFade(EClass.Sound.currentBGM.data.volume * num3, 3f);
252 }
253 SoundManager.jingleTimer = part.duration / playing.bgm.pitch + playing.bgm.song.fadeIn + 2f;
254 }
255 }
256 },
257 onProgress = delegate(Progress_Custom p)
258 {
260 owner.Say(Lang.GetList("music").RandomItem());
261 Msg.SetColor();
262 if (tool.id == "tambourine")
263 {
264 Msg.Say("tambourine");
265 }
266 if (EClass.debug.enable && EClass.pc.job.id == "pianist")
267 {
268 song.lv = 10000;
269 }
270 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))
271 {
273 if (EClass.rnd(2) == 0)
274 {
275 LevelSong(2 + 2 * EClass.rnd(owner.Evalue(1405) + 1));
276 }
277 if (playing.mistakes >= 10)
278 {
279 playing.index = 0;
280 }
281 Cancel();
282 }
283 else
284 {
286 {
287 if (item.conSleep != null && item.ResistLv(957) <= 0)
288 {
289 item.conSleep.Kill();
290 item.ShowEmo(Emo.angry);
291 }
292 }
293 List<Chara> list = owner.pos.ListWitnesses(owner, 4, WitnessType.music);
294 int num = (owner.Evalue(241) + tool?.Evalue(241)).Value * (100 + toolLv) / 100;
295 int num2 = 0;
296 foreach (Chara item2 in list)
297 {
298 if (owner == null)
299 {
300 break;
301 }
302 if (!reacted.Contains(item2) && EClass.rnd(5) == 0)
303 {
304 if (tool != null)
305 {
306 foreach (Element value in tool.elements.dict.Values)
307 {
308 if (value.id == 489 && EClass.rnd(8) == 0)
309 {
310 item2.AddCondition<ConDrunk>();
311 }
312 if (value.source.categorySub == "eleAttack")
313 {
314 item2.ApplyElementEffect(value, value.Value * 10, owner, checkHostileAct: true);
315 }
316 }
317 }
318 if (owner.IsPCParty)
319 {
320 if (item2.interest <= 0 || (EClass._zone is Zone_Music && (item2.IsPCFaction || item2.IsPCFactionMinion)))
321 {
322 continue;
323 }
324 if (!item2.isDrunk)
325 {
326 item2.interest -= EClass.rnd(10);
327 if (item2.interest < 0)
328 {
329 item2.Talk("musicBored");
330 continue;
331 }
332 }
333 }
334 if (EClass.rnd(num2 * num2) <= 30 && item2.pos.FirstChara == item2)
335 {
336 bool isMinion = item2.IsMinion;
337 p.cancelWhenDamaged = false;
338 if (num < item2.LV && EClass.rnd(2) == 0)
339 {
340 reacted.Add(item2);
341 if (!isMinion)
342 {
343 score -= item2.LV / 2 - 10;
344 }
345 if (EClass.rnd(2) == 0)
346 {
347 item2.Talk("musicBad");
348 }
349 else
350 {
351 item2.Say("musicBad", item2, owner);
352 }
353 item2.ShowEmo(Emo.sad);
354 owner.elements.ModExp(241, 10f);
355 if (EClass.rnd(5) == 0)
356 {
357 ThrowReward(item2, punish: true);
358 }
359 num2++;
360 }
361 else if (EClass.rnd(num + 5) > EClass.rnd(item2.LV * 5 + 1))
362 {
363 reacted.Add(item2);
364 if (!isMinion)
365 {
366 score += EClass.rnd(item2.LV / 2 + 5) + 5;
367 }
368 if (EClass.rnd(2) == 0)
369 {
370 item2.Talk("musicGood");
371 }
372 else
373 {
374 item2.Say("musicGood", item2, owner);
375 }
376 item2.ShowEmo(Emo.happy);
377 item2.renderer.PlayAnime((EClass.rnd(2) == 0) ? AnimeID.Jump : AnimeID.Fishing);
378 owner.elements.ModExp(241, EClass._zone.IsUserZone ? 10 : 50);
379 if (!isMinion)
380 {
381 ThrowReward(item2, punish: false);
382 }
383 num2++;
384 }
385 p.cancelWhenDamaged = true;
386 }
387 }
388 }
389 if (owner != null && owner.IsPC && EClass.rnd(80) < num2)
390 {
391 owner.stamina.Mod(-1);
392 }
393 }
394 },
395 onProgressComplete = delegate
396 {
397 if (EClass.rnd(2) == 0)
398 {
399 LevelSong(2);
400 }
401 if ((bool)playing.bgm)
402 {
403 playing.index++;
404 playing.mistakes = 0;
405 if (playing.index >= playing.bgm.song.parts.Count)
406 {
407 playing.index = 0;
408 }
409 playing.bgm.song.index = playing.index;
410 }
411 Evaluate(success: true);
412 }
413 }.SetDuration(26);
414 yield return Do(progress);
415 if (progress.status == Status.Fail)
416 {
417 yield return Cancel();
418 }
419 void LevelSong(int a)
420 {
421 if (a > 0)
422 {
423 song.lv += a + EClass.rnd(2);
424 if (owner == EClass.pc)
425 {
426 Msg.Say("level_song");
427 }
428 }
429 }
430 }
431
432 public void Evaluate(bool success)
433 {
434 if (owner == null || !owner.IsPC)
435 {
436 return;
437 }
438 if (success)
439 {
440 score = score * 110 / 100;
441 }
442 else
443 {
444 score = score / 2 - 20;
445 }
446 int num = Mathf.Clamp(score / 20 + 1, 0, 9);
447 owner.Say(Lang.GetList("music_result")[num]);
448 if (gold > 0)
449 {
450 owner.Say("music_reward", owner, gold.ToString() ?? "");
451 }
452 if (EClass.rnd(3) != 0)
453 {
454 owner.stamina.Mod(-1);
455 }
456 QuestMusic questMusic = EClass.game.quests.Get<QuestMusic>();
457 if (questMusic != null)
458 {
459 questMusic.score += score;
460 questMusic.sumMoney += gold;
461 int num2 = num / 2 - 1;
462 if (num > 0)
463 {
464 SE.Play("clap" + num2);
465 }
466 }
467 }
468
469 public void ThrowReward(Chara c, bool punish)
470 {
471 Thing thing = null;
472 string text = "";
473 int num = 1;
474 bool flag = true;
475 if (punish)
476 {
477 text = ((EClass.rnd(5) == 0) ? "rock" : "pebble");
478 if (EClass.rnd(8) == 0)
479 {
480 text = ((EClass.rnd(3) == 0) ? "water_dirty" : "water");
481 }
482 if (!c.IsPCFactionOrMinion)
483 {
484 thing = c.TryGetThrowable()?.Split(1);
485 }
486 }
487 else if (EClass.rnd(100) == 0 && !EClass._zone.IsUserZone)
488 {
489 text = "ecopo";
490 if (EClass.rnd(4) == 0)
491 {
492 text = "gacha_coin";
493 }
494 if (EClass.rnd(4) == 0)
495 {
496 text = "plat";
497 }
498 if (EClass.rnd(3) == 0)
499 {
500 text = "tomato";
501 }
502 if (EClass.rnd(3) == 0)
503 {
504 text = "casino_coin";
505 }
506 if (owner.IsPC && !EClass._zone.IsInstance)
507 {
508 if (c.LV >= 20 && EClass.rnd(10 * (int)Mathf.Pow(2f, EClass.player.flags.reward_killkill + 1)) == 0)
509 {
510 text = "piano_killkill";
511 punish = true;
512 flag = false;
514 }
515 else if (c.LV >= 40 && EClass.rnd(10 * (int)Mathf.Pow(2f, EClass.player.flags.reward_gould + 1)) == 0)
516 {
517 text = "piano_gould";
518 punish = true;
519 flag = false;
521 }
522 }
523 }
524 else
525 {
526 num = (EClass.rnd(c.LV * 2 + 1) + 1) * (100 + toolLv * 2 + owner.Evalue(1405) * 10) / 100;
527 if (c.IsUnique)
528 {
529 num *= 2;
530 }
531 if (!(EClass._zone is Zone_Music))
532 {
533 if (num > 25)
534 {
535 num /= 2;
536 }
537 if (num > 50)
538 {
539 num /= 2;
540 }
541 if (num > 100)
542 {
543 num /= 2;
544 }
546 {
547 num /= 5;
548 }
549 }
550 if (num < 1)
551 {
552 num = 1;
553 }
554 gold += num;
555 text = "money";
556 }
557 if (!owner.IsPCParty && !punish && text != "money")
558 {
559 return;
560 }
561 if (thing == null)
562 {
563 thing = ThingGen.Create(text, -1, owner.LV).SetNum(num);
564 }
565 ignoreDamage = true;
566 ActThrow.Throw(c, owner.pos, thing, (!punish) ? ThrowMethod.Reward : ThrowMethod.Punish);
567 ignoreDamage = false;
568 if (owner == null || !thing.ExistsOnMap)
569 {
570 return;
571 }
572 if (!owner.IsPC && owner.things.IsFull())
573 {
574 thing.Destroy();
575 }
576 else
577 {
578 if (!owner.IsAliveInCurrentZone)
579 {
580 return;
581 }
582 if (flag)
583 {
584 owner.Pick(thing);
585 }
586 if (thing.id == "money" && !owner.IsPC)
587 {
588 int? obj = ((owner.Evalue(241) + tool?.Evalue(241)) * 10 + 100) / ((owner.IsPCFaction && owner.memberType == FactionMemberType.Default) ? 1 : 10);
589 if (owner.GetCurrency() - obj > 0)
590 {
591 owner.c_allowance += num;
592 owner.ModCurrency(-num);
593 }
594 }
595 }
596 }
597
598 public override void OnCancel()
599 {
600 if (playing != null && (bool)playing.bgm)
601 {
602 playing.bgm.song.Fail(playing.source, playing.bgm);
603 if ((bool)UISong.Instance)
604 {
606 }
607 playing.source = null;
608 SoundManager.jingleTimer = 1f;
609 }
610 Evaluate(success: false);
611 }
612}
AnimeID
Definition: AnimeID.cs:2
Emo
Definition: Emo.cs:2
FactionMemberType
ThrowMethod
Definition: ThrowMethod.cs:2
if(item3.idFile==idFirstFile &&item3.id==idFirstTopic)
Definition: UIBook.cs:627
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:76
bool IsPCFactionOrMinion
Definition: Card.cs:2312
Thing Split(int a)
Definition: Card.cs:3566
ElementContainerCard elements
Definition: Card.cs:42
string id
Definition: Card.cs:36
bool IsUnique
Definition: Card.cs:2129
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:6426
Thing Tool
Definition: Card.cs:2450
Thing AddThing(string id, int lv=-1)
Definition: Card.cs:3180
void Talk(string idTopic, string ref1=null, string ref2=null, bool forceSync=false)
Definition: Card.cs:6986
ICardParent parent
Definition: Card.cs:56
bool ExistsOnMap
Definition: Card.cs:2123
Thing SetNum(int a)
Definition: Card.cs:3577
void ApplyElementEffect(Element e, int eleP, Card origin, bool checkHostileAct=false)
Definition: Card.cs:4955
Point pos
Definition: Card.cs:60
void ShowEmo(Emo _emo=Emo.none, float duration=0f, bool skipSame=true)
Definition: Card.cs:6394
void Destroy()
Definition: Card.cs:5182
ThingContainer things
Definition: Card.cs:39
int Evalue(int ele)
Definition: Card.cs:2611
void PlayAnime(AnimeID id, bool force=false)
Definition: Card.cs:6445
CardRenderer renderer
Definition: Card.cs:62
int LV
Definition: Card.cs:387
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:7104
Definition: Chara.cs:10
Condition AddCondition(string id, int p=100, bool force=false)
Definition: Chara.cs:9474
override bool IsPC
Definition: Chara.cs:626
bool isDrunk
Definition: Chara.cs:126
SourceJob.Row job
Definition: Chara.cs:468
override bool IsPCParty
Definition: Chara.cs:629
int interest
Definition: Chara.cs:319
override bool IsMinion
Definition: Chara.cs:641
override bool IsPCFaction
Definition: Chara.cs:685
Thing TryGetThrowable()
Definition: Chara.cs:7971
override bool IsPCFactionMinion
Definition: Chara.cs:669
Stats stamina
Definition: Chara.cs:1172
override void LookAt(Card c)
Definition: Chara.cs:3602
bool enable
Definition: CoreDebug.cs:286
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:255
SourceElement.Row source
Definition: ELEMENT.cs:278
int Value
Definition: ELEMENT.cs:297
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:6
static string[] GetList(string id)
Definition: Lang.cs:116
List< Chara > ListCharasInCircle(Point center, float radius, bool los=true)
Definition: Map.cs:2291
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:830
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:273
bool IsInstance
Definition: Zone.cs:491