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