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