source: 2015/24/ohjaajat/Dungeon/Dungeon/Dungeon/Dungeon.cs @ 6046

Revision 6046, 28.1 KB checked in by sieerinn, 4 years ago (diff)
RevLine 
[5927]1using System;
2using System.Linq;
3using System.Collections.Generic;
4using Jypeli;
5using Jypeli.Assets;
6using Jypeli.Controls;
7using Jypeli.Effects;
8using Jypeli.Widgets;
9using Point = Microsoft.Xna.Framework.Point;
10
[6005]11/* Tässä on jotain dokumentaation tapaista:
12 *
13 * Layerit
14 *   3 - Kaivuunuoli ja partikkeliefektit
15 *   2 - Partikkelien varjot
16 *   1 - Huoneiden katto
17 *   0 - Huoneiden seinät ja barbaarit
18 *  -1 - Päivitykset
19 *  -2 - Huone (eli lattiat siis)
[6046]20 * 
21 * Ideoita:
22 *  - Pahempia vihollisia, joihin ei tehoa piikkiansat
23 *    vaan pitää ostaa kalliimpia ansoja niitä varten.
[6005]24*/
25
26/// <summary>
27/// Päivitys joka voi olla huoneessa.
28/// </summary>
[6034]29public abstract class Upgrade : GameObject
[6005]30{
31    public int Price { get; set; }
32
[6040]33    protected Upgrade()
[6005]34        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
35    {
36    }
37
38    /// <summary>
39    /// Tätä kutsutaan kun päivitys on rakennettu huoneeseen.
40    /// </summary>
41    public virtual void Built(Dungeon peli) { }
[6035]42
43    /// <summary>
[6042]44    /// Tätä kutsutaan kun barbaari tulee kylään.
[6035]45    /// </summary>
46    public virtual void Invasion(Dungeon peli, Barbaari barbaari, Room huone) { }
[6042]47
48    /// <summary>
49    /// Kutsutaan joka syklin alussa.
50    /// </summary>
51    public virtual void SykliPaivitys() { }
[6005]52}
53
54class TrapUpgrade : Upgrade
55{
56    public int Damage { get; set; }
[6035]57
[6043]58    public bool Active
59    {
[6042]60        get { return LatausMittari.Value == LatausMittari.MaxValue; }
61    }
62
63    // Jos täynnä, niin ansa on aktiivinen.
64    public IntMeter LatausMittari { get; set; }
65
66    public TrapUpgrade()
67    {
68        LatausMittari = new IntMeter(4, 0, 4);
69        LatausMittari.UpperLimit += delegate
70        {
71            // Askelletaan vikasta framesta ekaan.
72            Animation.Step();
73        };
74    }
75
[6035]76    public override void Invasion(Dungeon peli, Barbaari barbaari, Room huone)
77    {
[6042]78        if (!Active) return;
79
[6036]80        peli.barbaarit.Remove(barbaari);
[6042]81        barbaari.Destroy();
[6037]82        peli.Splatter(huone.Position);
[6039]83
[6042]84        // Barbaarin tappo pudottaa latausmittarin nollaan.
85        LatausMittari.Value = LatausMittari.MinValue;
[6039]86
[6042]87        Animation.StopOnLastFrame = true;
88        Animation.Start(1);
89    }
90
91    public override void SykliPaivitys()
92    {
93        base.SykliPaivitys();
94        if (LatausMittari.Value < LatausMittari.MaxValue)
[6039]95        {
[6043]96            LatausMittari.Value++;
[6039]97        }
[6035]98    }
[6005]99}
100
101class CultureUpgrade : Upgrade
102{
103    // Tämän päivityksen antama kultuurin määrä.
104    public IntMeter Culture { get; set; }
105
106    // Label joka näyttää päivityksen antaman kultuurin määrän.
107    public Label KultuuriNaytto { get; set; }
108
109    public override void Built(Dungeon peli)
110    {
111        base.Built(peli);
112
113        Culture = new IntMeter(0, 0, 1000);
114
115        // Luodaan kultuurin ilmaisin.
116        KultuuriNaytto = new Label("asd");
117        KultuuriNaytto.TextColor = Color.HotPink;
118        KultuuriNaytto.Color = Color.Black;
[6045]119        KultuuriNaytto.Position = peli.Camera.WorldToScreen(this.Position + new Vector(0, Dungeon.RUUDUN_KOKO * 0.5));
[6005]120        KultuuriNaytto.BindTo(Culture);
121        peli.Add(KultuuriNaytto);
122
123        // Näytetään kultuurin määrä kun hiiri on päivityksen päällä.
124        var kuuntelija = peli.Mouse.ListenMovement(0.1, _ => KultuuriNaytto.IsVisible = peli.Mouse.IsCursorOn(this), null);
125
126        this.Destroyed += delegate
127        {
128            KultuuriNaytto.Destroy();
129            kuuntelija.Destroy();
130        };
131    }
[6035]132
133    public override void Invasion(Dungeon peli, Barbaari barbaari, Room huone)
134    {
135        this.Destroy();
[6042]136        huone.Upgrade = null;
137        if (peli.KultuuriHuoneidenPaikat().Count < 1)
[6035]138        {
139            peli.LopetaPeli();
140        }
141    }
[6005]142}
143
[6034]144public class Room : GameObject
[5927]145{
146    // Sijainti pelin ruudukossa.
147    public Point Location { get; set; }
148
149    // Päällä näkyvä "katto" kun huone ei ole vielä kaivettu.
150    public GameObject Roof { get; set; }
151
152    // Neljä seinää, jotka on GameObjekteja.
153    public Dictionary<Direction, GameObject> Walls { get; set; }
154
[6005]155    // Huoneen sisältämä päivitys.
156    public Upgrade Upgrade { get; set; }
[5966]157
[5927]158    private bool dug; // Onko huone kaivettu?
159    public bool Dug
160    {
161        get { return dug; }
162        set
163        {
164            dug = value;
165            Roof.IsVisible = !Dug;
166        }
167    }
168
169    public Room(Point paikka)
170        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
171    {
172        Walls = new Dictionary<Direction, GameObject>();
173        Location = paikka;
174    }
175}
176
[6007]177public class Barbaari : GameObject
178{
[6031]179    public List<Point> Reitti { get; set; }
[6035]180
[6042]181    public Point Kohde { get; set; }
[6040]182
183    public Point Location { get; set; }
184
[6007]185    public Barbaari(double width, double height)
[6035]186        : base(width, height)
[6031]187    {
188        Reitti = new List<Point>();
189    }
[6007]190}
191
[5927]192public class Dungeon : PhysicsGame
193{
194    public const int RUUDUN_KOKO = 64;
195
[5966]196    #region Kuvat
[5927]197    Image lattiaKuva = LoadImage("floor");
198    Image seinaKuva = LoadImage("wall");
199    Image reikaSeinaKuva = LoadImage("wallhole");
200    Image kiviKuva = LoadImage("rock");
[6034]201    Image[] kultuuriKuvat = LoadImages("nyan", "es", "spurdo");
[6035]202    Image[] ansaKuvat = LoadImages((from i in Enumerable.Range(1, 7) select String.Format("piikit{0:0000}", i)).ToArray());
[5970]203    Image[] vihuKuvat = LoadImages((from i in Enumerable.Range(1, 10) select String.Format("v{0:0000}", i)).ToArray());
[6040]204    Image partikkeliKuva = LoadImage("partikkeli");
[6038]205    Image taideVeri = LoadImage("taideveri");
[5970]206    #endregion
[5927]207
[6040]208    int[] hinnat = { 100, 200, 300, 100 };
[6046]209    int[] ansaHinnat = { 400 };
[6039]210    private int barbaariMaara = 2;
[5966]211
[6041]212    private Label kierrosIlmaisin;
213    private bool kierrosKaynnissa;
214    public bool KierrosKaynnissa
215    {
216        get
217        {
218            return kierrosKaynnissa;
219        }
220        set
221        {
222            kierrosKaynnissa = value;
223            kierrosIlmaisin.Text = "Vaihe: " + (kierrosKaynnissa ? "Barbaari-invaasio" : "Rakennusvaihe");
224        }
225    }
[6039]226
[5927]227    Room[,] huoneet;
[6042]228    //public List<Room> kohteet = new List<Room>();
[6036]229    public List<Barbaari> barbaarit = new List<Barbaari>();
[5966]230    Room spawn;
231    Timer barbaariAjastin = new Timer();
[6005]232    Upgrade ostamassa;
[5927]233    Point digStart; // Huoneen sijainti, josta kaivuu aloitetaan.
234    bool digging = false;
235
[5967]236    GameObject digArrow;
237    GameObject digArrowHead;
238
[6039]239    IntMeter kultuuri = new IntMeter(1000, 0, 2000);
[5966]240
[6034]241    const int VAAKA_HUONEET = 12;
242    const int PYSTY_HUONEET = 8;
[5966]243
[6005]244    // Paljonko peliruudukko on siirtynyt origosta.
[6045]245    Vector huoneSiirtyma = new Vector(-200, 0);
[6005]246
[5927]247    public override void Begin()
248    {
[6045]249        //SetWindowSize(1024, 768);
250
[5927]251        ClearAll();
[5966]252        Kontrollit();
253        UlkoAsuRoskaa();
254        Kauppa();
[5968]255        Nuoli();
[5927]256
257        // Luodaan huoneet ruutuihin.
[6034]258        huoneet = new Room[VAAKA_HUONEET, PYSTY_HUONEET];
[5927]259        foreach (var paikka in RuutujenPaikat())
260        {
261            var huone = CreateRoom(paikka);
262            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, () => RoomPressed(huone), null);
263            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Released, () => RoomReleased(huone), null);
264            huoneet[paikka.X, paikka.Y] = huone;
265        }
266
[5965]267        LuoSpawn();
268
[6042]269        Timer sykliAjastin = new Timer { Interval = 1.0 };
[6031]270        sykliAjastin.Timeout += Sykli;
271        sykliAjastin.Start();
272
[6040]273        barbaariAjastin.Timeout += LuoBarbaareja;
[5966]274        barbaariAjastin.Interval = 3;
[6045]275
276        Level.Width = 1300;
277        Camera.ZoomToLevel();
[5966]278    }
279
[5968]280    void Nuoli()
[5966]281    {
[5968]282        digArrow = new GameObject(5, 5);
283        digArrowHead = new GameObject(15, 15);
284        digArrowHead.Shape = Shape.Triangle;
285        digArrowHead.IsVisible = digArrow.IsVisible = false;
286        Add(digArrow, 3);
287        Add(digArrowHead, 3);
288    }
[5966]289
[5968]290    void UlkoAsuRoskaa()
291    {
[5966]292        Level.Background.Color = Color.Black;
293
[6041]294        kierrosIlmaisin = new Label("asd");
295        kierrosIlmaisin.TextColor = Color.White;
296        kierrosIlmaisin.Y = Screen.Top - 150;
297        Add(kierrosIlmaisin);
298        KierrosKaynnissa = KierrosKaynnissa; // Aiheuttaa labelin päivittymisen.
299
[5966]300        Label rahat = new Label();
[6039]301        rahat.BindTo(kultuuri);
[6045]302        rahat.Position = new Vector(Screen.Right - 200, Screen.Bottom + 50);
303        //rahat.Position = new Vector(Level.Right + Level.Width * 0.2, Level.Bottom + Level.Height * 0.1);
[5966]304        rahat.TextColor = Color.White;
305        rahat.IntFormatString = "Käytettävää kulttuuria: {0:D3}";
306        Add(rahat);
307    }
308
[6035]309    public void LopetaPeli()
310    {
311        ClearAll();
312        GameObject spurdo = new GameObject(Screen.Width, Screen.Height);
313        spurdo.Image = kultuuriKuvat[2];
314        Add(spurdo);
315
316        Label havisit = new Label("Hävisit muuten belin");
317        havisit.Color = Color.HotPink;
318        havisit.Size = new Vector(300, 300);
319        havisit.Position = new Vector(Level.Right - havisit.Width * 0.5, Level.Top - havisit.Height * 0.5);
320        Add(havisit);
321    }
322
[5966]323    void Kauppa()
324    {
[6005]325        for (int i = 0; i < kultuuriKuvat.Length; i++)
[5966]326        {
[6005]327            PushButton kuva = new PushButton(kultuuriKuvat[i]);
328            kuva.Size = new Vector(1, 1) * RUUDUN_KOKO;
[6045]329            kuva.X = Window.ClientBounds.Width / 2 - 200;
330            kuva.Y = Window.ClientBounds.Height / 2 - (100 + RUUDUN_KOKO * i);
331            //kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - (i * RUUDUN_KOKO)));
332            //kuva.Position = new Vector(Window.ClientBounds.Right, 0);
[6005]333            Add(kuva);
334
335            int indeksi = i; // Alla oleva delegaatti vaatii uuden indeksi muuttujan toimiakseen.
336            kuva.Clicked += delegate
337            {
338                ostamassa = LuoKultuuriPaivitys(kultuuriKuvat[indeksi], hinnat[indeksi]);
339            };
340
[6040]341            Add(new Label
342            {
343                Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0),
344                TextColor = Color.White,
345                Text = hinnat[i].ToString()
346            });
[6035]347        }
[6034]348
[6040]349        for (int i = 0; i < 1; i++)
[6035]350        {
[6036]351            PushButton kuva = new PushButton(ansaKuvat[i]);
[6035]352            kuva.Size = new Vector(1, 1) * RUUDUN_KOKO;
[6036]353            kuva.Color = Color.Gray;
[6045]354            kuva.X = Window.ClientBounds.Width / 2 - 200;
355            kuva.Y = Window.ClientBounds.Height / 2 - (100 + RUUDUN_KOKO * (kultuuriKuvat.Count() + i));
356            //kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - ((kultuuriKuvat.Count() + i) * RUUDUN_KOKO)));
[6035]357            Add(kuva);
[6036]358
359            int indeksi = i;
360            kuva.Clicked += delegate
361            {
[6043]362                ostamassa = LuoAnsaPaivitys(ansaKuvat[ansaKuvat.Length - 1], ansaHinnat[indeksi]);
[6036]363            };
364
[6040]365            Add(new Label
366            {
367                Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0),
368                TextColor = Color.White,
[6043]369                Text = ansaHinnat[i].ToString()
[6040]370            });
[5966]371        }
372    }
373
[6036]374    Upgrade LuoAnsaPaivitys(Image kuva, int hinta)
375    {
[6040]376        return new TrapUpgrade
377        {
378            Image = kuva,
379            Size = new Vector(0.5, 0.5) * RUUDUN_KOKO,
380            Price = hinta,
381            Animation = new Animation(ansaKuvat)
382        };
[6036]383    }
384
[6005]385    Upgrade LuoKultuuriPaivitys(Image kuva, int hinta)
386    {
[6040]387        return new CultureUpgrade
388        {
389            Image = kuva,
390            Size = new Vector(0.5, 0.5) * RUUDUN_KOKO,
391            Price = hinta
392        };
[6005]393    }
394
[5966]395    void LuoBarbaareja()
396    {
[6007]397        Barbaari barbaari = new Barbaari(RUUDUN_KOKO * 0.4, RUUDUN_KOKO * 0.4);
[5966]398        barbaari.Color = Color.Red;
399        barbaari.Position = spawn.Position;
[6040]400        barbaari.Animation = new Animation(vihuKuvat) { FPS = 10 };
[5970]401        barbaari.Animation.Start();
[6034]402        barbaari.Location = spawn.Location;
[5966]403        Add(barbaari);
[6031]404        barbaarit.Add(barbaari);
[6007]405
406        EtsiBarbaarinReitti(barbaari);
[5966]407    }
408
[6007]409    void EtsiBarbaarinReitti(Barbaari barbaari)
410    {
[6042]411        var kohteet = KultuuriHuoneidenPaikat();
[6034]412        barbaari.Kohde = kohteet[RandomGen.NextInt(kohteet.Count)];
[6042]413        barbaari.Reitti = FindPath(barbaari.Kohde, (barbaari.Location.Equals(spawn.Location)) ? spawn.Location : barbaari.Location);
[6031]414    }
[6007]415
[6042]416    public List<Point> KultuuriHuoneidenPaikat()
417    {
418        return RuutujenPaikat().Select(GetRoom).Where(r => r.Upgrade != null && r.Upgrade is CultureUpgrade).Select(r => r.Location).ToList();
419    }
420
[6031]421    void Sykli()
422    {
[6042]423        // Päivitetään huoneiden päivityksiä.
424        RuutujenPaikat().Select(GetRoom).Where(r => r.Upgrade != null).ToList().ForEach(r => r.Upgrade.SykliPaivitys());
425
426        // Päivitetään barbaareja.
[6031]427        foreach (var barbaari in barbaarit)
428        {
429            if (barbaari.Reitti.Count == 0)
430            {
[6042]431                EtsiBarbaarinReitti(barbaari);  //Etsitään uusi reitti poiston sijaan.
432                continue;
[6031]433            }
434
435            Point seuraavaPaikka = barbaari.Reitti[0];
436            barbaari.Reitti.RemoveAt(0);
[6040]437            Barbaari b = barbaari;
438            barbaari.MoveTo(huoneet[seuraavaPaikka.X, seuraavaPaikka.Y].Position, 100, () => SyklinPaatteeksi(b, seuraavaPaikka));
[6031]439        }
[6041]440
441        // Tarkistetaan onko barbaariaalto jo ohi.
442        if (KierrosKaynnissa && barbaarit.Count == 0 && barbaariAjastin.Times == barbaariAjastin.Times.MinValue)
443        {
444            KierrosKaynnissa = false;
[6043]445
446            // Annetaan pelaajalle kultuuripisteet.
447            foreach (var huone in KultuuriHuoneidenPaikat().Select(GetRoom))
448            {
449                CultureUpgrade upg = huone.Upgrade as CultureUpgrade;
450                if (upg == null)
451                    continue;
[6045]452
[6043]453                kultuuri.Value += upg.Culture;
454                Label ilmoitus = new Label("+" + upg.Culture);
455                ilmoitus.TextColor = Color.HotPink;
456                ilmoitus.Color = Color.Black;
457                ilmoitus.Position = Camera.WorldToScreen(huone.Position);
458                Add(ilmoitus);
459
460                double kohdeY = ilmoitus.Y + 50;
461                var liikutusAjastin = new Timer();
462                liikutusAjastin.Interval = 0.02;
463                liikutusAjastin.Timeout += delegate
464                {
[6045]465                    ilmoitus.Y += (kohdeY - ilmoitus.Y) * 0.05;
[6043]466                };
467                liikutusAjastin.Start();
468
469                ilmoitus.LifetimeLeft = TimeSpan.FromSeconds(2.0);
470                ilmoitus.Destroyed += liikutusAjastin.Stop;
471            }
[6041]472        }
[6007]473    }
474
[6031]475    void SyklinPaatteeksi(Barbaari barbaari, Point uusiPaikka)
476    {
477        // Barbaari saapui juuri uusiPaikka kohdassa olevaan huoneeseen.
478        // Tässä pitäisi katsoa mitä huoneessa tapahtuu.
[6034]479        barbaari.Location = uusiPaikka;
480
481        Room huone = huoneet[uusiPaikka.X, uusiPaikka.Y];
482
[6035]483        if (huone.Upgrade != null)
[6034]484        {
[6035]485            huone.Upgrade.Invasion(this, barbaari, huone);
[6034]486        }
[6031]487    }
488
[5966]489    void Kontrollit()
490    {
491        IsMouseVisible = true;
[5927]492        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
493        Keyboard.Listen(Key.F1, ButtonState.Pressed, Begin, null);
[5966]494
495        Keyboard.Listen(Key.Space, ButtonState.Pressed, SeuraavaAalto, "Anna kivan barbaariaallon tulla");
[5927]496    }
497
[5966]498    void SeuraavaAalto()
499    {
[6046]500        if (KultuuriHuoneidenPaikat().Count == 0 || KierrosKaynnissa) return;
[6040]501
502        barbaariAjastin.Start(barbaariMaara);
503        barbaariMaara += 2;
[6041]504        KierrosKaynnissa = true;
[5966]505    }
506
[5965]507    void LuoSpawn()
508    {
[5966]509        spawn = huoneet[(int)(huoneet.GetLength(0) * 0.5), 0];
510        spawn.Dug = true;
[5965]511
[6005]512        Direction oviSuunta = Direction.Down;
[5966]513        spawn.Walls[oviSuunta].Image = reikaSeinaKuva;
514
515        Light valo = new Light();
516        valo.Position = spawn.Position;
517        valo.Intensity = 1;
518        valo.Distance = 40;
519        Add(valo);
[5965]520    }
521
[5927]522    void RoomPressed(Room huone)
523    {
524        digStart = huone.Location;
525        digging = true;
[5967]526        digArrowHead.IsVisible = digArrow.IsVisible = true;
[5927]527    }
528
529    void RoomReleased(Room kohdeHuone)
530    {
531        digging = false;
[5967]532        digArrowHead.IsVisible = digArrow.IsVisible = false;
[6040]533        if (!CanDig()) return;
[6035]534
[6040]535        int dx = kohdeHuone.Location.X - digStart.X;
536        int dy = kohdeHuone.Location.Y - digStart.Y;
537        Point[] kaivettavatPaikat = RuudutSuoralta(digStart, dx, dy).ToArray();
538        for (int i = 0; i < kaivettavatPaikat.Length - 1; i++)
539        {
540            Dig(GetRoom(kaivettavatPaikat[i]), GetRoom(kaivettavatPaikat[i + 1]));
[5927]541        }
[6040]542
543        // Päivitetään huoneiden kultuuri-infot.
544        PaivitaHuoneidenKultuurit();
[5927]545    }
546
[6006]547    void Dig(Room alku, Room kohde)
548    {
549        // Hienot partikkeliefektit.
550        if (!alku.Dug)
551            LuoKiviPartikkelit(alku.Position);
552        if (!kohde.Dug)
553            LuoKiviPartikkelit(kohde.Position);
554
555        // Merkataan huoneet kaivetuksi.
556        alku.Dug = kohde.Dug = true;
557
558        // Reiät seinään.
559        Direction oviSuunta = (kohde.Position - alku.Position).Angle.MainDirection;
560        Direction toinenOviSuunta = Direction.Inverse(oviSuunta);
561        alku.Walls[oviSuunta].Image = reikaSeinaKuva;
562        kohde.Walls[toinenOviSuunta].Image = reikaSeinaKuva;
563    }
564
[5927]565    Room CreateRoom(Point paikka)
566    {
567        Room huone = new Room(paikka);
568        huone.Image = lattiaKuva;
569        huone.Position = new Vector(paikka.X - huoneet.GetLength(0) / 2, paikka.Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
[6005]570        huone.Position += huoneSiirtyma;
[5927]571        foreach (var suunta in Suunnat())
572            huone.Walls[suunta] = CreateWall(huone.Position, suunta);
[6005]573        Add(huone, -2);
[5927]574        huone.Roof = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
575        huone.Roof.Image = kiviKuva;
576        huone.Roof.Position = huone.Position;
[5967]577        Add(huone.Roof, 1);
[5966]578
[6005]579        Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, AsetaPaivitys, "Asetetaan ostettu päivitys paikoilleen", huone);
[6040]580        Mouse.Listen(MouseButton.Right, ButtonState.Pressed, delegate { ostamassa = null; }, "Perutaan ostos");
[6035]581        Mouse.ListenOn(huone, MouseButton.Right, ButtonState.Pressed, PoistaPaivitys, "Poistetaan asetettu päivitys", huone);
[5966]582
[5927]583        return huone;
584    }
585
[6035]586    private void PoistaPaivitys(Room huone)
587    {
588        if (huone.Upgrade != null)
589        {
590            huone.Upgrade.Destroy();
591        }
592    }
593
[6005]594    void AsetaPaivitys(Room huone)
[5966]595    {
[6039]596        if (ostamassa != null && huone.Dug && kultuuri.Value >= ostamassa.Price)
[5966]597        {
[6039]598            kultuuri.Value -= ostamassa.Price;
[6005]599
600            // Lisätään päivitys huoneeseen.
601            huone.Upgrade = ostamassa;
602            Add(huone.Upgrade, -1);
603            huone.Upgrade.Position = huone.Position;
604            huone.Upgrade.Built(this);
605
606            ostamassa = null;
607            PaivitaHuoneenKultuuri(huone);
[5966]608        }
609    }
610
[6005]611    void PaivitaHuoneidenKultuurit()
612    {
[6040]613        RuutujenPaikat().Select(GetRoom).ToList().ForEach(PaivitaHuoneenKultuuri); // :D ;___;; MIKSI <- koska pystyn
[6005]614    }
615
616    void PaivitaHuoneenKultuuri(Room room)
617    {
618        if (room != null && room.Upgrade != null && room.Upgrade is CultureUpgrade)
619        {
620            var upg = room.Upgrade as CultureUpgrade;
621
622            List<Point> polku = FindPath(room.Location, spawn.Location);
[6043]623            upg.Culture.Value = Math.Max(0, 150 - 5 * polku.Count);
[6005]624        }
625    }
626
[5927]627    GameObject CreateWall(Vector paikka, Direction suunta)
628    {
[5964]629        GameObject wall = new GameObject(RUUDUN_KOKO + 2, RUUDUN_KOKO + 2);
[5927]630        wall.Position = paikka;
631        wall.Image = seinaKuva;
632        wall.Angle = suunta.Angle;
[5967]633        Add(wall, 0);
[5927]634        return wall;
635    }
636
637    bool CanDig()
638    {
639        Room kohdeHuone = GetRoom(MuunnaJypelista(Mouse.PositionOnWorld));
[5967]640        if (kohdeHuone == null)
641        {
642            return false;
643        }
[6006]644
[5927]645        int dx = Math.Abs(kohdeHuone.Location.X - digStart.X);
646        int dy = Math.Abs(kohdeHuone.Location.Y - digStart.Y);
[6006]647        return (dx > 0 && dy == 0) || (dy > 0 && dx == 0);
[5927]648    }
649
[5967]650    #region Reitinlöytö
651
[5969]652    List<Point> FindPath(Point alku, Point loppu)
[5967]653    {
[5969]654        if (GetRoom(alku) == null || GetRoom(loppu) == null)
655            return new List<Point>();
656
[5967]657        bool[,] walkable = new bool[huoneet.GetLength(0), huoneet.GetLength(1)];
658        foreach (var paikka in RuutujenPaikat())
659        {
660            walkable[paikka.X, paikka.Y] = huoneet[paikka.X, paikka.Y].Dug;
661        }
[6007]662        var finder = new AStar.PathFinder(new AStar.SearchParameters(loppu, alku, walkable), OviTarkistus);
[5969]663        return finder.FindPath();
[5967]664    }
665
[5969]666    bool OviTarkistus(Point a, Point b)
667    {
668        Room ra = GetRoom(a);
669        Room rb = GetRoom(b);
670        Direction suunta = (new Vector(b.X, b.Y) - new Vector(a.X, a.Y)).Angle.MainDirection;
671        if (ra != null && rb != null)
672        {
673            return ra.Walls[suunta].Image == reikaSeinaKuva && rb.Walls[Direction.Inverse(suunta)].Image == reikaSeinaKuva;
674        }
675        return false;
676    }
677
[5967]678    #endregion
679
[5927]680    #region Extra Juttuja
681
682    IEnumerable<Direction> Suunnat()
683    {
684        yield return Direction.Left;
685        yield return Direction.Right;
686        yield return Direction.Up;
687        yield return Direction.Down;
688    }
689
690    IEnumerable<Point> RuutujenPaikat()
691    {
692        return from y in Enumerable.Range(0, huoneet.GetLength(1))
693               from x in Enumerable.Range(0, huoneet.GetLength(0))
694               select new Point(x, y);
695    }
696
[6006]697    /// <summary>
698    /// Palauttaa ruutuja suoralta pätkältä dx ja dy verran alkaen pisteestä "alku".
699    /// dx tai dy pitää olla nolla.
700    /// </summary>
701    IEnumerable<Point> RuudutSuoralta(Point alku, int dx, int dy)
702    {
703        if (dx != 0)
704        {
705            for (int i = 0; i < Math.Abs(dx) + 1; i++)
706            {
707                yield return new Point(alku.X + i * Math.Sign(dx), alku.Y);
708            }
709            yield break;
710        }
711        if (dy != 0)
712        {
713            for (int i = 0; i < Math.Abs(dy) + 1; i++)
714            {
715                yield return new Point(alku.X, alku.Y + i * Math.Sign(dy));
716            }
717        }
718    }
719
[5927]720    Room GetRoom(Point paikka)
721    {
722        if (paikka.X >= 0 && paikka.X < huoneet.GetLength(0) && paikka.Y >= 0 && paikka.Y < huoneet.GetLength(1))
723        {
724            return huoneet[paikka.X, paikka.Y];
725        }
726        return null;
727    }
728
729    /// <summary>
730    /// Muuntaa Jypeli-koordinaatin peliruudukon koordinaatiksi.
731    /// </summary>
732    Point MuunnaJypelista(Vector paikka)
733    {
[6005]734        Vector siirrettyOrigo = (paikka - huoneSiirtyma) + RUUDUN_KOKO * (0.5 * new Vector(huoneet.GetLength(0), huoneet.GetLength(1)) + new Vector(0.5, 0.5));
[5927]735        Vector wtf = new Vector(siirrettyOrigo.X < 0 ? -1 : 0, siirrettyOrigo.Y < 0 ? -1 : 0);
736        Vector valmis = wtf + siirrettyOrigo / RUUDUN_KOKO;
737        return new Point((int)valmis.X, (int)valmis.Y);
738    }
739
[6041]740    public void LuoLentavaPartikkeli(Vector alkupaikka, Image kuva, double koko, int maara, bool veri = false)
[6005]741    {
742        // Feikki 3D partikkeli juttu.
743        // Heittää ilmaan GameObjekteja joiden alla on varjo.
[6040]744
745        // VAROITUS: SISÄLTÄÄ JÄRKYTTÄVÄÄ KOODIA
746
747        for (int i = 0; i < maara; i++)
[6005]748        {
[6040]749            GameObject partikkeli = new GameObject(koko, koko);
750            partikkeli.Image = kuva;
751            partikkeli.Position = alkupaikka + RandomGen.NextVector(0.0, RUUDUN_KOKO * 0.4);
752            Add(partikkeli, 3);
[6005]753
[6040]754            GameObject varjo = new GameObject(koko, koko / 2.0);
755            varjo.Position = partikkeli.Position;
[6005]756            varjo.Shape = Shape.Circle;
757            varjo.Color = Color.Lerp(Color.Black, Color.Transparent, 0.5);
758            Add(varjo, 2);
759
[6040]760            Vector paikka = partikkeli.Position;
[6005]761            Vector nopeus = RandomGen.NextVector(0.2, 3.0);
762            nopeus.Y *= 0.3;
763            double g = -0.2; // painovoima
764            double z = 0.0; // sijainti z-akselilla
765            double vz = RandomGen.NextDouble(3.5, 4.5); // nopeus z-akselilla
766            double angularVelocity = RandomGen.NextDouble(-1.0, 1.0) * 8;
767
[6040]768            var verenLuontiAjastin = veri ? new Timer() : null;
769
770            var ajastin = new Timer();
[6005]771            ajastin.Interval = 0.02;
772            ajastin.Timeout += delegate
773            {
774                vz += g;
775                z += vz;
776                paikka += nopeus;
[6040]777                partikkeli.Position = paikka + new Vector(0.0, 1.0) * z;
778                partikkeli.Angle += Angle.FromDegrees(angularVelocity);
[6005]779                varjo.Position = paikka;
780
781                if (z < 0.0)
782                {
783                    ajastin.Stop();
[6040]784                    partikkeli.Destroy();
[6005]785                    varjo.Destroy();
[6040]786                    if (verenLuontiAjastin != null)
787                        verenLuontiAjastin.Stop();
[6005]788                }
789            };
790            ajastin.Start();
791
[6040]792            if (verenLuontiAjastin != null)
793            {
794                verenLuontiAjastin.Interval = 0.1;
795                verenLuontiAjastin.Timeout += delegate
796                {
797                    GameObject veriPartikkeli = new GameObject(3, 3);
798                    veriPartikkeli.Color = Color.DarkRed;
799                    Add(veriPartikkeli, 2);
[6037]800
[6040]801                    Vector veriPaikka = paikka;
802                    double veriZ = z;
803                    double veriVz = 0.0;
[6037]804
[6040]805                    var veriPaivitysAjastin = new Timer();
806                    veriPaivitysAjastin.Interval = 0.02;
807                    veriPaivitysAjastin.Timeout += delegate
808                    {
809                        veriVz += g;
810                        veriZ += veriVz;
[6041]811                        veriPartikkeli.Position = veriPaikka + new Vector(0.0, 1.0) * veriZ;
[6037]812
[6040]813                        if (veriZ < 0.0)
814                        {
815                            veriPaivitysAjastin.Stop();
816                            veriPartikkeli.Destroy();
817                        }
818                    };
819                    veriPaivitysAjastin.Start();
820                };
821                verenLuontiAjastin.Start();
822            }
[6037]823        }
824    }
825
[6040]826    void LuoKiviPartikkelit(Vector alkupaikka)
827    {
828        LuoLentavaPartikkeli(alkupaikka, partikkeliKuva, 25, 6);
829    }
830
831    public void Splatter(Vector alkupaikka)
832    {
833        LuoLentavaPartikkeli(alkupaikka, taideVeri, 8, 10, true);
834    }
835
[6005]836    protected override void Update(Time time)
837    {
838        if (digging)
839        {
840            Color vari = CanDig() ? Color.White : Color.Red;
841            Vector alku = huoneet[digStart.X, digStart.Y].Position;
842            Vector loppu = Mouse.PositionOnWorld;
843            Vector suunta = loppu - alku;
844            double pituus = suunta.Magnitude;
845            if (pituus <= 2) pituus = 2;
846
847            digArrow.Color = vari;
848            digArrow.Position = alku + suunta * 0.5;
849            digArrow.Angle = suunta.Angle;
850            digArrow.Width = pituus;
851
852            digArrowHead.Color = vari;
853            digArrowHead.Position = alku + suunta;
854            digArrowHead.Angle = suunta.Angle - Angle.FromDegrees(90);
855        }
856
857        base.Update(time);
858    }
859
[6045]860    /*
[6005]861    protected override void Paint(Canvas canvas)
862    {
863        canvas.BrushColor = Color.Purple;
864
865        var points = FindPath(new Point(6, 0), MuunnaJypelista(Mouse.PositionOnWorld));
866        for (int i = 0; i < points.Count - 1; i++)
867        {
868            Vector v = huoneSiirtyma + new Vector(points[i].X - huoneet.GetLength(0) / 2, points[i].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
869            Vector v2 = huoneSiirtyma + new Vector(points[i + 1].X - huoneet.GetLength(0) / 2, points[i + 1].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
870            canvas.DrawLine(v, v2);
871        }
872
873        base.Paint(canvas);
874    }
[6045]875    */
[6005]876
[5927]877    #endregion
878}
Note: See TracBrowser for help on using the repository browser.