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