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