source: 2013/30/MiskaK/MW2(My Warfare 2)/MW2(My Warfare 2)/MW2(My Warfare 2)/MW2_My_Warfare_2_.cs @ 4532

Revision 4532, 105.3 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
1// MY WARFARE 2
2// ohjelmointi: Miska Kananen
3// tekstuurit: Miska Kananen, Leevi Kujanpää, Kalle Pienmäki
4// musiikit: Kalle Pienmäki
5
6using System;
7using System.Collections.Generic;
8using System.Text;
9using Jypeli;
10using Jypeli.Assets;
11using Jypeli.Controls;
12using Jypeli.Effects;
13using Jypeli.Widgets;
14using XnaPathfidingLibrary;
15using My_Warfare_2_Server;
16
17/// @author Miska Kananen
18/// @version 22.6.2013
19///
20/// <summary>
21/// My Warfare 2:n pääluokka. Peli toimii tämän luokan sisällä.
22/// </summary>
23public class MW2_My_Warfare_2_ : PhysicsGame
24{
25    #region attribuutit, kuvat ja äänet
26    #region peliattribuutit
27
28    public static MW2_My_Warfare_2_ Peli { get; private set; }
29    public Pelaaja[] pelaajat = new Pelaaja[Vakiot.PELAAJIEN_MAARA];
30    private List<GameObject> tehosteet = new List<GameObject>();
31    private Kentta KentanOsat { get; set; }
32    private String ValittuKenttaTiedosto { get; set; }
33    private Timer AikaKentanAlusta = new Timer();
34
35    /// <summary>
36    /// Onko klassinen vai satunnainen kenttä.
37    /// </summary>
38    private bool OnkoSatunnaisKentta = false;
39
40    /// <summary>
41    /// Monestako taposta voittaa pelin.
42    /// </summary>
43    public static IntMeter MonestakoVoittaa = new IntMeter(Int32.MaxValue);
44
45    // Tämä attribuuttikönttä POIS
46    Label ammusmittariNäyttö;
47    Label ammusmittariNäyttö2;
48    // -------------------
49
50    static readonly SoundEffect aseTyhjäAani = LoadSoundEffect("dry-fire-gun");
51    static readonly SoundEffect aseLatausAani = LoadSoundEffect("Pump Shotgun");
52    static readonly SoundEffect lippaanPoistoAani = LoadSoundEffect("clip-remove");
53    static readonly SoundEffect hylsynPutoamisAani = LoadSoundEffect("gun_shell_drop");
54    static readonly SoundEffect luotiOsuu = LoadSoundEffect("bullet_hit");
55    static readonly SoundEffect luotiOsuu2 = LoadSoundEffect("bullet_hit2");
56    static readonly SoundEffect luotiOsuu3 = LoadSoundEffect("bullet_hit3");
57    static readonly SoundEffect luotiOsuu4 = LoadSoundEffect("bullet_hit4");
58    static readonly SoundEffect luotiOsuu5 = LoadSoundEffect("bullet_hit5");
59    public static readonly SoundEffect osuma1 = LoadSoundEffect("hit_1");
60
61    private Light valo = new Light();
62    #endregion
63
64    #region Kuvat
65
66    #region asekuvat
67    static readonly Image kranaatinKuva = LoadImage("Kranaatti_F1");
68    static readonly Image pistoolinMaaKuva = LoadImage("GLOCK18_maa");
69    static readonly Image rynkynMaaKuva = LoadImage("AK-74M_maa");
70    static readonly Image pumpparinMaaKuva = LoadImage("REMINGTON870_maa");
71    static readonly Image sawinMaaKuva = LoadImage("M249SAW_maa");
72    static readonly Image singonMaaKuva = LoadImage("RPG-7_maa");
73    static readonly Image snipanMaaKuva = LoadImage("SVDDRAGUNOV_maa");
74    static readonly Image kranaatinMaaKuva = LoadImage("F1FRAG_maa");
75    static readonly Image magnuminMaaKuva = LoadImage("Magnum_maa");
76    #endregion
77
78    #region kentänkuvat
79    // Kentän osat
80    static readonly Image valikonKuva = LoadImage("valikkotausta");
81    static readonly Image valikonPainikeKuva = LoadImage("menu_buttontest");
82    static GameObject menuGradient;
83    static readonly Image kivenKuva = LoadImage("kivi");
84    static readonly Image piikkilankaKuva = LoadImage("piikkilanka");
85    static readonly Image pystypiikkilankaKuva = LoadImage("piikkilankapysty");
86    static readonly Image vaakapuunKuva = LoadImage("puuvaaka");
87    static readonly Image naamioverkonKuva = LoadImage("naamioverkko");
88    static readonly Image pystypuunKuva = LoadImage("puupysty");
89    static readonly Image bussinkuva = LoadImage("bussi");
90    static readonly Image poistuvanseinänKuva = LoadImage("poistuvaseinä");
91    static readonly Image crack1 = LoadImage("crack1");
92    static readonly Image kiviRikki0 = LoadImage("kivirikki0");
93    static readonly Image kiviRikki1 = LoadImage("kivirikki1");
94    static readonly Image kiviRikki2 = LoadImage("kivirikki2");
95    static readonly Image kiviRikki3 = LoadImage("kivirikki3");
96    static readonly Image pystypuuRikki1 = LoadImage("puupystyrikki1");
97    static readonly Image pystypuuRikki2 = LoadImage("puupystyrikki2");
98    static readonly Image edustanKuva = LoadImage("edusta1");
99    static readonly Image seinäSoihdunKuva = LoadImage("seinäsoihtu");
100    static readonly Image valonKuva = LoadImage("valo1");
101    static readonly Image tynnyrinKuva = LoadImage("tynnyri");
102    static readonly Image killballPohja = LoadImage("killball_pohja");
103    static readonly Image killballKeski = LoadImage("killball_keski");
104    static readonly Image killballYla = LoadImage("killball_ylä");
105
106    static readonly Image hudKuva = LoadImage("hudtausta");
107    static readonly Image hudTäysi = LoadImage("hudtaustatäysi");
108    static readonly Image hudKuva2 = LoadImage("hudtausta2");
109    static readonly Image hudTäysi2 = LoadImage("hudtaustatäysi2");
110
111    static readonly Image laatikonKuva = LoadImage("kamaa");
112    static readonly Image laatikkoTyhjä = LoadImage("kamaatyhjä");
113    static readonly Image kamaaNäkymätön = LoadImage("kamaanäkymätön");
114    static readonly Image tyhjä = LoadImage("tyhjä");
115    static readonly Image[] laatikonAnimaatioKuvat = LoadImages("kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa1", "kamaa2", "kamaa3", "kamaa4");
116
117    static readonly Image zombinKuva = LoadImage("zombi");
118    static readonly Image[] zombinKuvat = LoadImages("zombi1", "zombi2", "zombi1", "zombi3");
119    static readonly Image korpinKuva = LoadImage("korppitesti");
120    #endregion
121
122    #region infinitekuvat
123    static readonly Image normaaliZombiKuva = LoadImage("zombi_tavallinen");
124    static readonly Image ampuvaZombiKuva = LoadImage("zombi_ak");
125    static readonly Image[] parasiittienKuvat = LoadImages("Parasiitti1", "Parasiitti2", "Parasiitti3");
126    static readonly Image[] parasiittienPartikkeliKuvat = LoadImages("paras_sirpale1", "paras_sirpale2", "paras_sirpale3", "paras_sirpale4", "paras_sirpale5");
127    #endregion
128
129    #endregion
130
131    #endregion
132
133    #region yleiset toiminnot
134
135    /// <summary>
136    /// Aloitetaan peli luomalla alkuvalikko.
137    /// </summary>
138    public override void Begin()
139    {
140        SoitaMusiikkia(0); // valikkotheme valikkoon
141        LuoAlkuValikko();
142    }
143
144    /// <summary>
145    /// Päivitetään pelaajiin liittyviä asioita.
146    /// </summary>
147    /// <param name="time">Aika pelin alusta ja edellisestä päivityksestä.</param>
148    protected override void Update(Time time)
149    {
150        base.Update(time);
151
152        // Päivitetään pelaajiin liittyviä juttuja.
153        for (int i = 0; i < pelaajat.Length; i++)
154        {
155            if (pelaajat[i] != null)
156            {
157                Vector suunta = (pelaajat[i].tahtain.Position - pelaajat[i].Position).Normalize();
158                pelaajat[i].Angle = suunta.Angle;
159
160                pelaajat[i].elamaPalkki.Position = new Vector(pelaajat[i].X, pelaajat[i].Y + 30);
161                pelaajat[i].infoRuutu.Position = new Vector(pelaajat[i].X, pelaajat[i].Y + 50);
162
163                // Tarkistetaan, ovatko pelaajat sallitun pelialueen ulkopuolella. Ei tarvita kentillä, joissa on piikkilangat reunoina.
164                if (OnkoSatunnaisKentta)
165                {
166                    if (pelaajat[i].Position.X > Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA || pelaajat[i].Position.Y > Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA)
167                    {
168                        pelaajat[i].infoRuutu.Text = String.Format("Palaa taistelukentälle {0:0.00} sekunnin sisällä.", pelaajat[i].aikaPoissaKentalta.Value);
169                        if (pelaajat[i].OllaankoPoissaKentalta == false) pelaajat[i].PoistuttiinKentalta();
170                    }
171                    else if (pelaajat[i].Position.X < Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA || pelaajat[i].Position.Y < Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA)
172                    {
173                        pelaajat[i].infoRuutu.Text = String.Format("Palaa taistelukentälle {0:0.00} sekunnin sisällä.", pelaajat[i].aikaPoissaKentalta.Value);
174                        if (pelaajat[i].OllaankoPoissaKentalta == false) pelaajat[i].PoistuttiinKentalta();
175                    }
176                    else
177                    {
178                        if (pelaajat[i].OllaankoPoissaKentalta == true)
179                        {
180                            pelaajat[i].infoRuutu.Text = "";
181                            pelaajat[i].PalattiinKentalle();
182                        }
183                    }
184                }
185            }
186        }
187    }
188
189    /// <summary>
190    /// Tehdään vahinkoa kohteelle.
191    /// </summary>
192    /// <param name="damagenKohde">Kohde, jota vahingoitetaan.</param>
193    /// <param name="damagenMäärä">Paljonko vahinkoa tehdään.</param>
194    void Damagea(Elava damagenKohde, double damagenMäärä)
195    {
196        damagenKohde.Elamat.Value -= damagenMäärä;
197        GameObject[] effects = Blood.AddNormalBlood(damagenKohde.Position, 3, 0.3);
198        foreach (GameObject blood in effects)
199        {
200            LisaaTehosteObjekti(blood);
201        }
202    }
203
204    /// <summary>
205    /// Tehdään vahinkoa kohteelle.
206    /// </summary>
207    /// <param name="damagenKohde">Kohde, jota vahingoitetaan.</param>
208    /// <param name="damagenMäärä">Paljonko vahinkoa tehdään.</param>
209    void Damagea(Tuhoutuva damagenKohde, double damagenMaara)
210    {
211        damagenKohde.Kesto.Value -= damagenMaara;
212    }
213
214    /// <summary>
215    /// Aloittaa pelin alusta ja palaa päävalikkoon. Poistaa kaiken tähän mennessä tehdyn.
216    /// </summary>
217    void PaaValikkoon()
218    {
219        ClearAll();
220        Camera.Reset();
221        Level.AmbientLight = 0.8;
222        SoitaMusiikkia(0); // valikkotheme valikkoon
223        LuoAlkuValikko(true);
224    }
225
226    /// <summary>
227    /// Kutsutaan, kun toinen pelaaja voittaa pelin.
228    /// </summary>
229    /// <param name="voittanutPelaaja">Pelaaja, joka voitti pelin.</param>
230    void Voitto(Pelaaja voittanutPelaaja)
231    {
232        // MediaPlayer.Play("EPIC VICTORY THEME SONG");
233        PimennaRuutua();
234        MultiSelectWindow voittoIkkuna = new MultiSelectWindow("Pelaaja " + voittanutPelaaja.Numero + " voitti pelin!\n\n" +
235            "Pelaajan 1 tapot: " + pelaajat[0].Tapot + "\n" +
236            "Pelaajan 2 tapot: " + pelaajat[1].Tapot, Color.White, "Päävalikkoon", "Lopeta peli");
237        voittoIkkuna.ItemSelected += delegate(int valinta)
238        {
239            switch (valinta)
240            {
241                case 0:
242                    PaaValikkoon();
243                    break;
244                case 1:
245                    Exit();
246                    break;
247            }
248        };
249        voittoIkkuna.Color = Color.Transparent;
250        voittoIkkuna.BorderColor = Color.Transparent;
251        voittoIkkuna.SelectionColor = Color.Green;
252        voittoIkkuna.DefaultCancel = 0;
253        voittoIkkuna.IsModal = true;
254        Add(voittoIkkuna);
255    }
256
257    /// <summary>
258    /// Kutsutaan, kun Infinite hävitään.
259    /// </summary>
260    /// <param name="havittyPeli">Peli, joka on hävitty.</param>
261    void InfiniteHavio(Infinite havittyPeli)
262    {
263        MediaPlayer.Play("ZombieGameOverFIX");
264        PimennaRuutua();
265        MultiSelectWindow havioIkkuna = new MultiSelectWindow("Peli päättyi!\nVihollisia tapettu " + havittyPeli.VihollisiaTapettu + " kpl.\nAikaa kului " + String.Format("{0:00}", havittyPeli.AikaPelinAlusta.CurrentTime) + " sekuntia.", Color.White, "Päävalikkoon", "Lopeta peli");
266        havioIkkuna.ItemSelected += delegate(int valinta)
267        {
268            switch (valinta)
269            {
270                case 0:
271                    PaaValikkoon();
272                    Infinite.OnkoPeliKaynnissa = false;
273                    break;
274                case 1:
275                    Infinite.OnkoPeliKaynnissa = false;
276                    Exit();
277                    break;
278            }
279        };
280        havioIkkuna.Color = Color.Transparent;
281        havioIkkuna.BorderColor = Color.Transparent;
282        havioIkkuna.SelectionColor = Color.Green;
283        havioIkkuna.DefaultCancel = 0;
284        havioIkkuna.IsModal = true;
285        Add(havioIkkuna);
286
287        havittyPeli.SpawnataankoVihollisia = false;
288
289        foreach (Pelaaja p in pelaajat)
290        {
291            if (p != null && p.Taskulamppu != null) p.Taskulamppu.Destroy();
292        }
293
294        foreach (Vihollinen vihu in havittyPeli.VihollisetKentalla)
295        {
296            vihu.Destroy();
297        }
298    }
299
300    /// <summary>
301    /// Asettaa ikkunan koon halutuksi ja palaa päävalikkoon.
302    /// </summary>
303    /// <param name="leveys">Ikkunan leveys.</param>
304    /// <param name="korkeus">Ikkunan korkeus.</param>
305    void AsetaIkkunanKoko(int leveys, int korkeus)
306    {
307        SetWindowSize(leveys, korkeus);
308        PaaValikkoon();
309    }
310
311    /// <summary>
312    /// Pimennetään ruutua pikku hiljaa.
313    /// </summary>
314    void PimennaRuutua()
315    {
316        Timer ajastin = new Timer();
317        ajastin.Interval = 0.1;
318        ajastin.Timeout += delegate { Level.AmbientLight -= 0.01; };
319        ajastin.Start();
320    }
321
322    /// <summary>
323    /// Soitetaan musiikkia.
324    /// 0:Menu Background Theme
325    /// 1:Dark Lurk
326    /// 2:Zombin taustamusiikki
327    /// 3:OrcsCome
328    /// 4:OrcsCome Special
329    /// 5:MoozE-Radwind
330    /// </summary>
331    /// <param name="valinta">Mikä biisi soitetaan.</param>
332    void SoitaMusiikkia(int valinta)
333    {
334        MediaPlayer.IsRepeating = true;
335        switch (valinta)
336        {
337            case 0:
338                MediaPlayer.Play("Menu_BackGround");
339                break;
340            case 1:
341                MediaPlayer.Play("DarkLurk");
342                break;
343            case 2:
344                MediaPlayer.Play("zombi_taustamusa_1");
345                break;
346            case 3:
347                MediaPlayer.Play("OrcsCome");
348                break;
349            case 4:
350                MediaPlayer.Play("OrcsCome_special");
351                break;
352            case 5:
353                MediaPlayer.Play("03 MoozE - Radwind Pt1");
354                break;
355        }
356    }
357
358    /// <summary>
359    /// Piirretään valojuovia.
360    /// </summary>
361    /// <param name="position">Valojuovan tämänhetkinen sijainti.</param>
362    /// <param name="color">Valojuovan väri.</param>
363    /// <param name="lifetimeInSeconds">Kauanko valojuova pysyy kentällä.</param>
364    void DrawTracers(Vector position, Color color, double lifetimeInSeconds, double brightnessFactor)
365    {
366        color.AlphaComponent = (byte)(32 * brightnessFactor); // 64 toimii
367        GameObject tracer = new GameObject(2, 2);
368        tracer.Shape = Shape.Circle;
369        tracer.Color = color;
370        tracer.Position = position;
371        tracer.MaximumLifetime = TimeSpan.FromSeconds(lifetimeInSeconds);
372        Add(tracer);
373    }
374
375    /// <summary>
376    /// Piirretään valojuovia.
377    /// </summary>
378    /// <param name="tracingObject">Olio, josta valojuovat tulevat.</param>
379    /// <param name="color">Valojuovan väri.</param>
380    /// <param name="lifetimeInSeconds">Kauanko valojuova pysyy kentällä.</param>
381    /// <param name="brightnessFactor">Valojuovan kirkkaus.</param>
382    void DrawTracers(PhysicsObject tracingObject, Color color, double lifetimeInSeconds, double brightnessFactor)
383    {
384        color.AlphaComponent = (byte)(32 * brightnessFactor); // 64 toimii
385        GameObject tracer = new GameObject(60, 2);
386        tracer.Shape = Shape.Circle;
387        tracer.Color = color;
388        tracer.Position = tracingObject.Position;
389        tracer.Angle = tracingObject.Angle;
390        tracer.MaximumLifetime = TimeSpan.FromSeconds(lifetimeInSeconds);
391        Add(tracer);
392    }
393
394    void LisaaTehosteObjekti(GameObject tehoste)
395    {
396        tehosteet.Add(tehoste);
397        if (tehosteet.Count > Vakiot.TEHOSTEOBJEKTIEN_MAX_MAARA)
398        {
399            tehosteet[0].Destroy();
400            tehosteet.RemoveAt(0);
401        }
402
403    }
404
405    #endregion
406
407    #region kenttä
408
409    /// <summary>
410    /// Luodaan kenttä ja kaikki siihen liittyvä, kuten pelaajat.
411    /// </summary>
412    /// <param name="kenttaTyyppi">Kentän luomistapa. 0: kenttä kuvasta, 1: satunnaisgeneroitu kenttä, 2: tyhjä kenttä.</param>
413    /// <param name="pelaajienMaara">Montako pelaajaa peliin tulee.</param>
414    void LuoKentta(int kenttaTyyppi, int pelaajienMaara, bool onkoInfinite)
415    {
416        Mouse.IsCursorVisible = false;
417        bool onkoSandbox = false;
418        AikaKentanAlusta.Reset();
419        AikaKentanAlusta.Start();
420        MessageDisplay.BackgroundColor = Color.Transparent;
421        MessageDisplay.TextColor = Color.White;
422        MessageDisplay.MessageTime = TimeSpan.FromSeconds(1.5);
423        Level.Size = new Vector(Vakiot.KENTAN_LEVEYS * Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_KORKEUS * Vakiot.KENTAN_RUUDUN_KORKEUS);
424        Level.AmbientLight = 0.8;
425        Add(valo);
426        menuGradient.Destroy();
427        menuGradient = null;
428
429        Vector pelaajan1spawni = new Vector(-700.0, 0.0);
430        Vector pelaajan2spawni = new Vector(700.0, 0.0);
431        List<Vector> vaihtoehtoisetSpawnit = new List<Vector>();
432
433        switch (kenttaTyyppi)
434        {
435            case 0:
436                ColorTileMap ruudut = ColorTileMap.FromLevelAsset(ValittuKenttaTiedosto);
437                KentanOsat = new Kentta(ruudut.ColumnCount, ruudut.RowCount, "valekivi");
438
439                ruudut.SetTileMethod(Color.Black, LuoKentanOsa, piikkilankaKuva, "piikkilanka", 5);
440                ruudut.SetTileMethod(Color.Gray, LuoTuhoutuvaKentanOsa, kivenKuva, "kivi", 20, 1.0, 1.0);
441                ruudut.SetTileMethod(Color.DarkRed, LuoLapiMentavaKentanOsa, kivenKuva, "valekivi", 1.0, 1.0);
442                ruudut.SetTileMethod(Color.Orange, LuoTuhoutuvaKentanOsa, pystypuunKuva, "puu", 10, 0.3, 1.0);
443                ruudut.SetTileMethod(Color.Red, LuoKentanOsa, pystypiikkilankaKuva, "piikkilanka", 5);
444                ruudut.SetTileMethod(Color.Brown, LuoTuhoutuvaKentanOsa, vaakapuunKuva, "puu", 10, 1.0, 0.3);
445                ruudut.SetTileMethod(Color.ForestGreen, LuoKentanOsa, naamioverkonKuva, "naamioverkko", 1);
446                ruudut.SetTileMethod(Color.Purple, LuoLaatikko);
447                ruudut.SetTileMethod(Color.Yellow, LuoLapiMentavaKentanOsa, seinäSoihdunKuva, "seinäsoihtu", 1.0, 1.0);
448                ruudut.SetTileMethod(Color.Olive, LuoLapiMentavaKentanOsa, valonKuva, "valo", 6.0, 6.0);
449                ruudut.SetTileMethod(Color.Rose, LuoTynnyri);
450                ruudut.SetTileMethod(Color.BloodRed, delegate(Vector p, double w, double h, IntPoint posInLevel) 
451                { 
452                    if (Infinite.CurrentGame != null)
453                        Infinite.CurrentGame.LisaaFixedSpawni(p);
454                });
455                ruudut.SetTileMethod(Color.BrightGreen, delegate(Vector p, double w, double h, IntPoint posInLevel)
456                {
457                    pelaajan1spawni = p;
458                });
459                ruudut.SetTileMethod(Color.Azure, delegate(Vector p, double w, double h, IntPoint posInLevel)
460                {
461                    pelaajan2spawni = p;
462                });
463                ruudut.SetTileMethod(Color.Gold, delegate(Vector p, double w, double h, IntPoint posInLevel) 
464                {
465                    vaihtoehtoisetSpawnit.Add(p);             
466                });
467
468                //ruudut.Optimize(Color.Gray);
469                ruudut.Execute(50, 50);
470                LuoPilvet((onkoInfinite && pelaajienMaara == 1));
471
472                break;
473            case 1:
474                string[] satunnaisKenttäTiedosto = LuoSatunnainenKenttäTiedosto(Vakiot.KENTAN_LEVEYS, Vakiot.KENTAN_KORKEUS);
475                TileMap satunnaisKenttä = TileMap.FromStringArray(satunnaisKenttäTiedosto);
476                satunnaisKenttä.SetTileMethod('1', LuoTuhoutuvaKentanOsa, kivenKuva, "kivi", 20, 1.0, 1.0);
477                satunnaisKenttä.Optimize();
478                satunnaisKenttä.Execute(Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_RUUDUN_KORKEUS);
479
480                string[] pickupTiedosto = LuoSatunnainenPickupTiedosto(satunnaisKenttäTiedosto, Vakiot.PICKUPIEN_MAARA);
481                TileMap pickupit = TileMap.FromStringArray(pickupTiedosto);
482                pickupit.SetTileMethod('1', LuoKerattavaEsine);
483                pickupit.Execute(Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_RUUDUN_KORKEUS);
484                LuoPilvet(false);
485                break;
486            case 2:
487                onkoSandbox = true;
488                break;
489        }
490
491        #region pelaajien spawnaus ja asettelu
492
493        bool kaytetaankoTaskuLamppua = false;
494
495        if (onkoInfinite)
496        {
497            if (pelaajienMaara == 1) kaytetaankoTaskuLamppua = true;
498        }
499
500        pelaajat[0] = LuoPelaaja(pelaajan1spawni, 43.5, 21.75, 1, Aseet.pelaaja1pistooliKuva, Color.Green, AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta, new Vector(Screen.Left + 130, Screen.Top - 70), kaytetaankoTaskuLamppua);
501        Add(pelaajat[0], 1);
502        pelaajat[0].SpawnausPaikat.AddRange(vaihtoehtoisetSpawnit);
503
504        AmmusMittari();
505        pelaajat[1] = LuoPelaaja(pelaajan2spawni, 43.5, 21.75, 2, Aseet.pelaaja2pistooliKuva, Color.Red, AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta, new Vector(Screen.Right - 130, Screen.Top - 70), kaytetaankoTaskuLamppua);
506        pelaajat[1].SpawnausPaikat.AddRange(vaihtoehtoisetSpawnit);
507
508
509        if (!onkoInfinite)
510        {
511            pelaajat[0].Voitti += Voitto;
512            pelaajat[0].Kuoli += delegate { pelaajat[1].Tapot.Value++; };
513            pelaajat[1].Voitti += Voitto;
514            pelaajat[1].Kuoli += delegate { pelaajat[0].Tapot.Value++; };
515        }
516
517        if (pelaajienMaara == 2)
518        {
519            Add(pelaajat[1], 1);
520            pelaajat[1].tahtain.Position = pelaajat[1].Position + new Vector(-200.0, 0.0);
521            Camera.Follow(pelaajat[0], pelaajat[1]);
522            AmmusMittari2();
523        }
524        else
525        {
526            Camera.Zoom(1);
527            Camera.Follow(pelaajat[0]);
528            pelaajat[1].elamaPalkki.IsVisible = false;
529            pelaajat[1].tahtain.IsVisible = false;
530            pelaajat[1].ValittuAseNaytto.IsVisible = false;
531            pelaajat[1].TappojenMaaraNaytto.IsVisible = false;
532        }
533
534        if (onkoSandbox) // laitetaan kaikki aseet, loputtomat ammukset ja loputtomat kranaatit
535        {
536            for (int i = 0; i < pelaajat.Length; i++)
537            {
538                pelaajat[i].LisaaAse(Aseet.LuoRynkky());
539                pelaajat[i].LisaaAse(Aseet.LuoMinigun());
540                pelaajat[i].LisaaAse(Aseet.LuoHaulikko());
541                pelaajat[i].LisaaAse(Aseet.LuoMagnum());
542                pelaajat[i].LisaaAse(Aseet.LuoSnipa());
543                pelaajat[i].LisaaAse(Aseet.LuoSinko());
544                pelaajat[i].LisaaAse(Aseet.LuoVarsijousi());
545                pelaajat[i].LisaaAse(Aseet.LuoOhjus());
546                pelaajat[i].LisaaAse(Aseet.LuoBinaryRifle());
547                pelaajat[i].LisaaAse(Aseet.LuoVintorez());
548                pelaajat[i].LisaaAse(Aseet.LuoAutomaattiHaulikko());
549
550                for (int j = 0; j < pelaajat[i].Aseet.Count; j++)
551                {
552                    pelaajat[i].Aseet[j].Ammo.MaxValue = Int32.MaxValue;
553                    pelaajat[i].Aseet[j].Ammo.Value = Int32.MaxValue;
554                    pelaajat[i].Aseet[j].MaxAmmo.MaxValue = Int32.MaxValue;
555                    pelaajat[i].Aseet[j].MaxAmmo.Value = Int32.MaxValue;
556
557                    pelaajat[i].KranaattienMaara = Int32.MaxValue;
558                }
559                ammusmittariNäyttö.IsVisible = false;
560                if (ammusmittariNäyttö2 != null)
561                    ammusmittariNäyttö2.IsVisible = false;
562            }
563        }
564        #endregion
565
566    }
567
568    /// <summary>
569    /// Luodaan kenttä onlinepelille.
570    /// </summary>
571    /// <param name="pelaajat">Pelaajat pelissä.</param>
572    /// <param name="kenttaTyyppi">Kentän tyyppi. 0: klassinen mäppi, 1: satunnaisgeneroitu mäppi, 2: tyhjä mäppi.</param>
573    void LuoOnlineKentta(List<Player> onlinePelaajat, int kenttaTyyppi)
574    {
575        Level.Background.Image = null;
576        Mouse.IsCursorVisible = false;
577        AikaKentanAlusta.Reset();
578        AikaKentanAlusta.Start();
579        MessageDisplay.BackgroundColor = Color.Transparent;
580        MessageDisplay.TextColor = Color.White;
581        MessageDisplay.MessageTime = TimeSpan.FromSeconds(1.5);
582        Level.Size = new Vector(Vakiot.KENTAN_LEVEYS * Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_KORKEUS * Vakiot.KENTAN_RUUDUN_KORKEUS);
583        Level.AmbientLight = 0.8;
584        Add(valo);
585
586        foreach (Player pelaaja in onlinePelaajat)
587        {
588            Pelaaja p = new Pelaaja(43.5, 21.75, false, false);
589            p.Position = pelaaja.Position;
590            p.Angle = pelaaja.Angle;
591            p.Velocity = pelaaja.Velocity;
592            p.Elamat.Value = pelaaja.Health;
593            Add(p);
594            OnlineGame.PhysicalPlayers.Add(p);
595        }
596
597        pelaajat[0] = LuoPelaaja(new Vector(0.0, 0.0), 43.5, 21.75, 1, Aseet.pelaaja1pistooliKuva, Color.Green, AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta, new Vector(Screen.Left + 130, Screen.Top - 70), false); // false = onko taskulamppua
598        Add(pelaajat[0], 1);
599        AmmusMittari();
600        ClearControls();
601        AsetaOhjaimet();
602        SoitaMusiikkia(4); // OrcsCome Special nettipeliin
603    }
604
605    #region satunnaisgeneraatio
606
607    /// <summary>
608    /// Luodaan kentälle kerättävä esine.
609    /// </summary>
610    /// <param name="mikaLuodaan">Mikä esine luodaan, välillä 0..6.
611    /// (0:Pistooli, 1:Rynkky, 2:Haulikko, 3:Minigun, 4:Varsijousi, 5:Snipa, 6:Sinko, 7:Kranaatti)</param>
612    /// <param name="paikka">Paikka, johon esine luodaan.</param>
613    void LuoKerattavaEsine(Vector paikka, double leveys, double korkeus, IntPoint posInLevel)
614    {
615        int mikaLuodaan = RandomGen.NextIntWithProbabilities(0.20, 0.15, 0.10, 0.10, 0.10, 0.10, 0.05, 0.05, 0.15);
616        switch (mikaLuodaan)
617        {
618            // Pistooli
619            case 0:
620                Kerattava pistooli = LuoKerattava(paikka, Aseet.LuoPistooli(), pistoolinMaaKuva, 0.5);
621                pistooli.Kerattiin += JotainKerattiin;
622                Add(pistooli);
623                break;
624
625            // Rynkky
626            case 1:
627                Kerattava rynkky = LuoKerattava(paikka, Aseet.LuoRynkky(), rynkynMaaKuva);
628                rynkky.Kerattiin += JotainKerattiin;
629                Add(rynkky);
630                break;
631
632            // Haulikko
633            case 2:
634                Kerattava haulikko = LuoKerattava(paikka, Aseet.LuoHaulikko(), pumpparinMaaKuva);
635                haulikko.Kerattiin += JotainKerattiin;
636                Add(haulikko);
637                break;
638            case 3:
639                Kerattava magnum = LuoKerattava(paikka, Aseet.LuoMagnum(), magnuminMaaKuva);
640                magnum.Kerattiin += JotainKerattiin;
641                Add(magnum);
642                break;
643
644            // Minigun
645            case 4:
646                Kerattava minigun = LuoKerattava(paikka, Aseet.LuoMinigun(), sawinMaaKuva);
647                minigun.Kerattiin += JotainKerattiin;
648                Add(minigun);
649                break;
650
651            // Varsijousi
652            case 5:
653                /*Kerattava varsijousi = LuoKerattava(paikka, Aseet.LuoVarsijousi(), new Image(512, 512, Color.White));
654                varsijousi.Kerattiin += JotainKerattiin;
655                Add(varsijousi);*/
656                break;
657            // Snipa
658            case 6:
659                Kerattava snipa = LuoKerattava(paikka, Aseet.LuoSnipa(), snipanMaaKuva);
660                snipa.Kerattiin += JotainKerattiin;
661                Add(snipa);
662                break;
663
664            // Sinko
665            case 7:
666                Kerattava sinko = LuoKerattava(paikka, Aseet.LuoSinko(), singonMaaKuva);
667                sinko.Kerattiin += JotainKerattiin;
668                Add(sinko);
669                break;
670
671            case 8:
672                Kerattava kranaatti = LuoKerattava(paikka, 1, kranaatinMaaKuva, 0.8);
673                kranaatti.Kerattiin += JotainKerattiin;
674                Add(kranaatti);
675                break;
676            case 9:
677                /*Kerattava vintorez = LuoKerattava(paikka, Aseet.LuoVintorez(), vintorezMaaKuva);
678                vintorez.Kerattiin += JotainKerattiin;
679                Add(vintorez);*/
680                break;
681        }
682    }
683
684    /// <summary>
685    /// Luodaan kerättävä esine.
686    /// </summary>
687    /// <param name="paikka">Esineen paikka.</param>
688    /// <param name="mitaKerattiin">Mitä esineestä saa.</param>
689    /// <param name="kuva">Esineen kuva. Voi olla null.</param>
690    /// <param name="kuvanKoonMuutosKerroin">Paljonko kuvan kokoa muutetaan piirrettäessä. 1.0 ei tee mitään, suurempi kasvattaa ja pienempi pienentää.</param>
691    /// <returns>Esine.</returns>
692    Kerattava LuoKerattava(Vector paikka, object mitaKerattiin, Image kuva, double kuvanKoonMuutosKerroin = 1.0)
693    {
694        Kerattava k = new Kerattava(kuva.Width / 8 * kuvanKoonMuutosKerroin, kuva.Height / 8 * kuvanKoonMuutosKerroin, mitaKerattiin, paikka);
695        if (kuva != null)
696            k.Image = kuva;
697        return k;
698    }
699
700    /// <summary>
701    /// Kutsutaan, kun pelaaja törmää kerättävään esineeseen.
702    /// </summary>
703    /// <param name="p">Pelaaja, joka törmäsi.</param>
704    /// <param name="keratty">Se, mitä pelaaja sai kerättävästä esineestä.</param>
705    void JotainKerattiin(Pelaaja p, object keratty)
706    {
707        if (keratty is Ase)
708        {
709            Ase a = keratty as Ase;
710            if (!p.OnkoPelaajallaAse(a.Tag.ToString())) p.LisaaAse(a);
711            else
712            {
713                for (int i = 0; i < p.Aseet.Count; i++)
714                {
715                    if (p.Aseet[i].Tag.ToString() == a.Tag.ToString()) p.Aseet[i].MaxAmmo.Value += p.Aseet[i].Ammo.MaxValue; // jos pelaajalla on jo ase, annetaan aseeseen lippaallinen ammuksia
716                }
717            }
718        }
719        if (keratty is Int32)
720        {
721            p.KranaattienMaara++;
722        }
723    }
724
725    /// <summary>
726    /// Luodaan satunnainen String-taulukko nollista ja ykkösistä, jota voidaan käyttää kentän luontiin.
727    /// </summary>
728    /// <param name="leveys">Kentän leveys.</param>
729    /// <param name="korkeus">Kentän korkeus.</param>
730    /// <returns>Kenttä binäärimuodossa.</returns>
731    String[] LuoSatunnainenKenttäTiedosto(int leveys, int korkeus)
732    {
733        const int ARVOTTAVIA_SUKUPOLVIA = 2;
734        int[,] kentanArvot = new int[leveys, korkeus];
735        for (int i = 0; i < kentanArvot.GetLength(0); i++)
736        {
737            for (int j = 0; j < kentanArvot.GetLength(1); j++)
738            {
739                kentanArvot[i, j] = RandomGen.NextIntWithProbabilities(0.1);
740            }
741        }
742        int[,] kenttaLukuina = GameOfLife.ArvoSukupolvia(kentanArvot, leveys, korkeus, ARVOTTAVIA_SUKUPOLVIA);
743        String[] tulos = TaulukkoStringiksi(kenttaLukuina);
744        return tulos;
745    }
746
747    /// <summary>
748    /// Muunnetaan kaksiulotteinen int-taulukko string-taulukoksi.
749    /// </summary>
750    /// <param name="taulukko">Alkuperäinen int-taulukko.</param>
751    /// <returns>Int-taulukko string-taulukkona.</returns>
752    String[] TaulukkoStringiksi(int[,] taulukko)
753    {
754        String[] tulos = new String[taulukko.GetLength(1)];
755        for (int rivi = 0; rivi < taulukko.GetLength(0); rivi++)
756        {
757            for (int sarake = 0; sarake < taulukko.GetLength(1); sarake++)
758            {
759                tulos[rivi] += taulukko[rivi, sarake];
760            }
761        }
762        return tulos;
763    }
764
765    /// <summary>
766    /// Palauttaa string-lukutaulukon muunnettuna 2D-int-taulukoksi. Taulukon rivien pitää
767    /// olla samanpituisia.
768    /// </summary>
769    /// <param name="taulukko">Muunnettava taulukko.</param>
770    /// <returns>Taulukko int-muodossa.<returns>
771    int[,] TaulukkoIntiksi(String[] taulukko)
772    {
773        int[,] tulos = new int[taulukko.Length, taulukko[0].Length];
774        for (int rivi = 0; rivi < taulukko.Length; rivi++)
775        {
776            for (int sarake = 0; sarake < taulukko[0].Length; sarake++)
777            {
778                tulos[rivi, sarake] = int.Parse(taulukko[rivi][sarake].ToString());
779            }
780        }
781        return tulos;
782    }
783
784    /// <summary>
785    /// Muuntaa int-taulukon bool-taulukoksi. Luvusta 0 tulee true, muista false.
786    /// </summary>
787    /// <param name="taulukkoIntina">Muunnettava taulukko.</param>
788    /// <returns>Taulukko boolina.</returns>
789    bool[,] TaulukkoBooliksi(int[,] taulukkoIntina)
790    {
791        bool[,] tulos = new bool[taulukkoIntina.GetLength(0), taulukkoIntina.GetLength(1)];
792        for (int i = 0; i < taulukkoIntina.GetLength(0); i++)
793        {
794            for (int j = 0; j < taulukkoIntina.GetLength(1); j++)
795            {
796                if (taulukkoIntina[i, j] == 0) tulos[i, j] = true;
797                else tulos[i, j] = false;
798            }
799        }
800        return tulos;
801    }
802
803    /// <summary>
804    /// Palauttaa int-taulukon, jonka alkioiden arvot voivat olla VAIN 0 tai 1 käännettynä siten, että alkioiden
805    /// arvot ovat päinvastaiset.
806    /// </summary>
807    /// <param name="taulukko">Käännettävä taulukko.</param>
808    /// <returns>Käännetty taulukko.</returns>
809    int[,] KaannaTaulukko(int[,] taulukko)
810    {
811        for (int i = 0; i < taulukko.GetLength(0); i++)
812        {
813            for (int j = 0; j < taulukko.GetLength(1); j++)
814            {
815                if (taulukko[i, j] == 0) taulukko[i, j] = 1;
816                else taulukko[i, j] = 0;
817            }
818        }
819        return taulukko;
820    }
821
822    /// <summary>
823    /// Palauttaa niiden taulukon alkioiden indeksit, joissa on etsittävä luku.
824    /// </summary>
825    /// <param name="taulukko">Taulukko, josta lukua etsitään.</param>
826    /// <param name="mitäEtsitään">Mitä lukua etsitään.</param>
827    /// <returns>Indeksit vektorilistana.</returns>
828    List<Vector> TaulukonAlkioidenIndeksit(int[,] taulukko, int mitäEtsitään)
829    {
830        List<Vector> indeksit = new List<Vector>();
831        for (int i = 0; i < taulukko.GetLength(0); i++)
832        {
833            for (int j = 0; j < taulukko.GetLength(1); j++)
834            {
835                if (taulukko[i, j] == mitäEtsitään) indeksit.Add(new Vector(i, j));
836            }
837        }
838        return indeksit;
839    }
840
841    /// <summary>
842    /// Luodaan tiedosto pickupien luontia varten siten, ettei pickupeja mene seinien päälle.
843    /// </summary>
844    /// <param name="kentanKiinteatOsat">Kentän seinät.</param>
845    /// <returns>String-taulukko, jossa on pickupien paikat.</returns>
846    String[] LuoSatunnainenPickupTiedosto(String[] kentanKiinteatOsat, int pickupienMaara)
847    {
848        int[,] pickupienPaikat = new int[kentanKiinteatOsat.Length, kentanKiinteatOsat[0].Length];
849
850        // Ne paikat, jotka ovat tyhjiä kenttägeneraation jäljiltä.
851        int[,] pickupienMahdollisetPaikat = TaulukkoIntiksi(kentanKiinteatOsat);
852        pickupienMahdollisetPaikat = KaannaTaulukko(pickupienMahdollisetPaikat);
853        List<Vector> indeksitJoissaOnTyhjää = TaulukonAlkioidenIndeksit(pickupienMahdollisetPaikat, 1);
854
855        for (int i = 0; i < pickupienMaara; i++)
856        {
857            Vector paikka = RandomGen.SelectOne<Vector>(indeksitJoissaOnTyhjää);
858            int x = (int)paikka.X;
859            int y = (int)paikka.Y;
860            pickupienPaikat[x, y] = 1;
861        }
862        String[] pickupienPaikatStringinä = TaulukkoStringiksi(pickupienPaikat);
863        return pickupienPaikatStringinä;
864    }
865    #endregion
866
867    #region kentän osat
868
869    /// <summary>
870    /// Luo staattisen kentän osan, joka voi tuhoutua.
871    /// </summary>
872    /// <param name="paikka">Kappaleen paikka.</param>
873    /// <param name="leveys">Kappaleen leveys.</param>
874    /// <param name="korkeus">Kappaleen korkeus.</param>
875    /// <param name="kuva">Kappaleen kuva.</param>
876    /// <param name="tag">Kappaleen tagi.</param>
877    /// <param name="kesto">Kappaleen kesto.</param>
878    public void LuoTuhoutuvaKentanOsa(Vector paikka, double leveys, double korkeus, IntPoint positionInLevelArray, Image kuva, string tag, int kesto, double leveydenKerroin, double korkeudenKerroin)
879    {
880        Tuhoutuva kentanosa = new Tuhoutuva(leveys * leveydenKerroin, korkeus * korkeudenKerroin, kesto);
881        kentanosa.Position = paikka;
882        kentanosa.MakeStatic();
883        kentanosa.Image = kuva;
884        kentanosa.Tag = tag;
885        kentanosa.CollisionIgnoreGroup = 1;
886        kentanosa.PositionInLevelArray = positionInLevelArray;
887        kentanosa.Kesto.LowerLimit += delegate {
888            KentanOsat.TuhoaSeina(kentanosa.PositionInLevelArray.X, kentanosa.PositionInLevelArray.Y);
889            kentanosa.Destroy();
890        };
891        Add(kentanosa);
892
893        KentanOsat.LisaaSeina(positionInLevelArray.X, positionInLevelArray.Y, kentanosa);
894    }
895
896    /// <summary>
897    /// Luo staattisen kentän osan, joka ei voi tuhoutua.
898    /// </summary>
899    /// <param name="paikka">Kappaleen paikka.</param>
900    /// <param name="leveys">Kappaleen leveys.</param>
901    /// <param name="korkeus">Kappaleen korkeus.</param>
902    /// <param name="kuva">Kappaleen kuva.</param>
903    /// <param name="tag">Kappaleen tagi.</param>
904    /// <param name="collisionIgnoreGroup">Kappaleen törmäysryhmä.</param>
905    void LuoKentanOsa(Vector paikka, double leveys, double korkeus, IntPoint positionInLevelArray, Image kuva, string tag, int collisionIgnoreGroup)
906    {
907        PhysicsObject kentanosa = new PhysicsObject(leveys, korkeus);
908        kentanosa.Position = paikka;
909        kentanosa.MakeStatic();
910        kentanosa.Image = kuva;
911        kentanosa.Tag = tag;
912        kentanosa.CollisionIgnoreGroup = collisionIgnoreGroup;
913        kentanosa.PositionInLevelArray = positionInLevelArray;
914        Add(kentanosa);
915
916        KentanOsat.LisaaSeina(positionInLevelArray.X, positionInLevelArray.Y, kentanosa);
917    }
918
919    /// <summary>
920    /// Luo liikkumattoman kentän osan, johon ei voi törmätä.
921    /// </summary>
922    /// <param name="paikka">Kappaleen paikka.</param>
923    /// <param name="leveys">Kappaleen leveys.</param>
924    /// <param name="korkeus">Kappaleen korkeus.</param>
925    /// <param name="kuva">Kappaleen kuva.</param>
926    /// <param name="tag">Kappaleen tagi.</param>
927    void LuoLapiMentavaKentanOsa(Vector paikka, double leveys, double korkeus, IntPoint positionInLevelArray, Image kuva, string tag, double leveydenKerroin, double korkeudenKerroin)
928    {
929        GameObject kentanosa = new GameObject(leveys * leveydenKerroin, korkeus * korkeudenKerroin);
930        kentanosa.Image = kuva;
931        kentanosa.Tag = tag;
932        kentanosa.Position = paikka;
933        kentanosa.PositionInLevelArray = positionInLevelArray;
934        Add(kentanosa, -1);
935
936        KentanOsat.LisaaSeina(positionInLevelArray.X, positionInLevelArray.Y, kentanosa);
937    }
938
939    /// <summary>
940    /// Luodaan liikkuva kentän osa.
941    /// </summary>
942    /// <param name="paikka">Paikka.</param>
943    /// <param name="leveys">Leveys.</param>
944    /// <param name="korkeus">Korkeus.</param>
945    /// <param name="kuva">Kuva.</param>
946    /// <param name="tag">Tagi.</param>
947    /// <param name="shape">Muoto.</param>
948    /// <returns>Kentän osa.</returns>
949    PhysicsObject LuoLiikkuvaKentanOsa(Vector paikka, double leveys, double korkeus, Image kuva, string tag, Shape shape)
950    {
951        PhysicsObject kentanosa = new PhysicsObject(leveys, korkeus);
952        kentanosa.Position = paikka;
953        kentanosa.Tag = tag;
954        if (kuva != null) kentanosa.Image = kuva;
955        kentanosa.Shape = shape;
956        Add(kentanosa);
957        return kentanosa;
958    }
959
960    /// <summary>
961    /// Luodaan räjähtävä tynnyri.
962    /// </summary>
963    /// <param name="paikka">Tynnyrin paikka.</param>
964    /// <param name="leveys">Tynnyrin leveys.</param>
965    /// <param name="korkeus">Tynnyrin korkeus.</param>
966    void LuoTynnyri(Vector paikka, double leveys, double korkeus, IntPoint posInLevel)
967    {
968        Tuhoutuva tynnyri = new Tuhoutuva(leveys / 1.5, korkeus / 1.5, 1);
969        tynnyri.Image = tynnyrinKuva;
970        tynnyri.Position = paikka;
971        tynnyri.Shape = Shape.Circle;
972        //tynnyri.Mass = 600;
973        tynnyri.LinearDamping = 0.90;
974        tynnyri.AngularDamping = 0.90;
975        tynnyri.Angle = RandomGen.NextAngle();
976        tynnyri.Kesto.LowerLimit += delegate
977        {
978            Partikkelit.AddExplosionEffect(tynnyri.Position, 600);
979            //Flame f = Partikkelit.CreateFlames(tynnyri.Position, 30);
980            //Add(f);
981
982            Explosion rajahdys = new Explosion(200);
983            rajahdys.Position = tynnyri.Position;
984            rajahdys.Image = tyhjä;
985            rajahdys.Sound = Aseet.singonAani;
986            rajahdys.Force = 400;
987            rajahdys.Speed = 1000;
988            rajahdys.ShockwaveColor = Color.Black;
989            rajahdys.ShockwaveReachesObject += delegate(IPhysicsObject paineaallonKohde, Vector shokki) { RajahdysOsuu(paineaallonKohde, shokki, tynnyri.Position, Aseet.SINGON_MAKSIMI_DAMAGE); };
990            Add(rajahdys);
991            tynnyri.Destroy();
992        };
993        Add(tynnyri);
994        //tynnyri.Hit(RandomGen.NextVector(100.0, 1000.0));
995    }
996
997    /// <summary>
998    /// Luodaan kentän päälle pilviä, jotka liikkuvat hiljalleen.
999    /// </summary>
1000    void LuoPilvet(bool onkoInfinite)
1001    {
1002        GameObject pilvet = new GameObject(8192, 8192);
1003        if (onkoInfinite) pilvet.Image = LoadImage("himmeatpilvet");
1004        else pilvet.Image = LoadImage("pilvet2");
1005        pilvet.Tag = "pilvet";
1006        Add(pilvet, 2);
1007        Layers[2].RelativeTransition = new Vector(2.0, 2.0);
1008        RandomMoverBrain rb = new RandomMoverBrain(0.3);
1009        pilvet.Brain = rb;
1010        rb.WanderRadius = 1000;
1011        rb.ChangeMovementSeconds = 10.0;
1012        rb.TurnWhileMoving = false;
1013    }
1014
1015    /// <summary>
1016    /// Luodaan laatikko, josta voi kerätä kamaa.
1017    /// </summary>
1018    /// <param name="paikka">Laatikon paikka.</param>
1019    /// <param name="leveys">Laatikon leveys.</param>
1020    /// <param name="korkeus">Laatikon korkeus.</param>
1021    void LuoLaatikko(Vector paikka, double leveys, double korkeus, IntPoint posInLevel)
1022    {
1023        Laatikko laatikko = new Laatikko(leveys, korkeus);
1024        laatikko.Animation = new Animation(laatikonAnimaatioKuvat);
1025        laatikko.Animation.Start();
1026        laatikko.MakeStatic();
1027        laatikko.Animation.FPS = 10;
1028        laatikko.Position = paikka;
1029        laatikko.Tag = "laatikko";
1030        AddCollisionHandler(laatikko, AnnaKamaa);
1031        Add(laatikko);
1032    }
1033
1034    void LuoKillBall(Vector paikka)
1035    {
1036        PhysicsObject killball = LuoLiikkuvaKentanOsa(paikka, 200.0, 200.0, killballPohja, "killball", Shape.Circle);
1037        killball.AngularDamping = 1.0;
1038        killball.AngularVelocity = 5.0;
1039
1040        PhysicsObject killballKeskiOsa = new PhysicsObject(200.0, 200.0);
1041        killballKeskiOsa.Image = killballKeski;
1042        killballKeskiOsa.MakeStatic();
1043        killballKeskiOsa.Shape = Shape.Circle;
1044        killballKeskiOsa.AngularDamping = 1.0;
1045        killballKeskiOsa.AngularVelocity = -6.0;
1046        killball.Add(killballKeskiOsa);
1047
1048        PhysicsObject killballYlaOsa = new PhysicsObject(200.0, 200.0);
1049        killballYlaOsa.Image = killballYla;
1050        killballYlaOsa.MakeStatic();
1051        killballYlaOsa.Shape = Shape.Circle;
1052        killballYlaOsa.AngularDamping = 1.0;
1053        killballYlaOsa.AngularVelocity = 8.0;
1054        killballKeskiOsa.Add(killballYlaOsa);
1055
1056        AddCollisionHandler<PhysicsObject, Pelaaja>(
1057            killball, delegate(PhysicsObject kb, Pelaaja pelaaja)
1058        {
1059            Damagea(pelaaja, 20);
1060            PlaySound("KillBall_Kill");
1061        });
1062    }
1063    #endregion
1064
1065    #endregion
1066
1067    #region valikot
1068    /// <summary>
1069    /// Luodaan pelille alkuvalikko.
1070    /// </summary>
1071    /// <param name="isEverythingCleared">Jos kutsutaan ClearAllin jälkeen.</param>
1072    void LuoAlkuValikko(bool isEverythingCleared = false)
1073    {
1074        MW2_My_Warfare_2_.Peli = this;
1075        AsetustenKaytto.LataaAsetukset();
1076        Infinite.OnkoPeliKaynnissa = false;
1077        AnimatedMultiSelectWindow valikko = new AnimatedMultiSelectWindow("MY WARFARE 2", valikonPainikeKuva,
1078        "Uusi peli", "Multiplayer", "Asetukset", "Lopeta peli");
1079        valikko.ItemSelected += PainettiinAlkuValikonNappia;
1080        valikko.Color = Color.Transparent;
1081        valikko.BorderColor = Color.Transparent;
1082        valikko.MovementSpeed = 450;
1083        Level.Background.Image = valikonKuva;
1084        Level.BackgroundColor = Color.Black;
1085        Level.AmbientLight = 1.0;
1086        valikko.DefaultCancel = 4;
1087        Add(valikko);
1088
1089        if (menuGradient == null || menuGradient.IsDestroyed || !menuGradient.IsAddedToGame || isEverythingCleared) // jos null tai poistettu pelistä tai jos tullaan ClearAllin kautta
1090        {
1091            menuGradient = new GameObject(1920, 1080);
1092            menuGradient.Image = LoadImage("menu_gradient");
1093            Add(menuGradient);
1094        }
1095    }
1096
1097    /// <summary>
1098    /// Alkuvalikon nappien painalluksen käsittely.
1099    /// </summary>
1100    /// <param name="valinta">Painettu nappi.</param>
1101    void PainettiinAlkuValikonNappia(int valinta)
1102    {
1103        switch (valinta)
1104        {
1105            case 0:
1106                LuoPelimuodonValintaValikko();
1107                break;
1108            case 1:
1109                LuoOnlineValikko();
1110                break;
1111            case 2:
1112                LuoAsetusIkkuna();
1113                break;
1114            case 3:
1115                Exit();
1116                break;
1117        }
1118    }
1119
1120    void LuoOnlineValikko()
1121    {
1122        AnimatedMultiSelectWindow onlineValikko = new AnimatedMultiSelectWindow("Valitse pelimuoto", valikonPainikeKuva, "Liity peliin", "Syötä IP", "Syötä portti", "Syötä salasana", "Takaisin");
1123        onlineValikko.ItemSelected += PainettiinOnlineValikonNappia;
1124        onlineValikko.Color = Color.Transparent;
1125        onlineValikko.BorderColor = Color.Transparent;
1126        Level.Background.Image = valikonKuva;
1127        Level.BackgroundColor = Color.Black;
1128        onlineValikko.DefaultCancel = 2;
1129        //onlineValikko.Position = new Vector(0, Screen.Top - 100);
1130        Add(onlineValikko);
1131
1132    }
1133
1134    void PainettiinOnlineValikonNappia(int valinta)
1135    {
1136        switch (valinta)
1137        {
1138            case 0:
1139                OnlineGame.JoinGame(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(OnlineGame.ServerIP.ToString()), OnlineGame.ServerPort));
1140                LuoOnlineKentta(OnlineGame.CurrentGame.ConnectedPlayers, 2);
1141
1142                break;
1143            case 1:
1144                InputWindow ipIkkuna = new InputWindow("Syötä serverin IP:");
1145                ipIkkuna.Color = Color.Transparent;
1146                ipIkkuna.InputBox.BorderColor = Color.Green;
1147                ipIkkuna.InputBox.Cursor.Color = Color.Green;
1148                ipIkkuna.MaxCharacters = 15;
1149                ipIkkuna.OKButton.Clicked += delegate
1150                {
1151                    OnlineGame.ServerIP.Clear();
1152                    OnlineGame.ServerIP.Append(ipIkkuna.InputBox.Text);
1153                    LuoOnlineValikko();
1154                };
1155                Add(ipIkkuna);
1156                break;
1157            case 2:
1158                InputWindow porttiIkkuna = new InputWindow("Syötä serverin portti:");
1159                porttiIkkuna.Color = Color.Transparent;
1160                porttiIkkuna.InputBox.BorderColor = Color.Green;
1161                porttiIkkuna.InputBox.Cursor.Color = Color.Green;
1162                porttiIkkuna.MaxCharacters = 5;
1163                porttiIkkuna.OKButton.Clicked += delegate
1164                {
1165                    OnlineGame.ServerPort = int.Parse(porttiIkkuna.InputBox.Text);
1166                    LuoOnlineValikko();
1167                };
1168                Add(porttiIkkuna);
1169
1170                break;
1171            case 3:
1172                InputWindow salasanaIkkuna = new InputWindow("Syötä serverin portti:");
1173                salasanaIkkuna.Color = Color.Transparent;
1174                salasanaIkkuna.InputBox.BorderColor = Color.Green;
1175                salasanaIkkuna.InputBox.Cursor.Color = Color.Green;
1176                salasanaIkkuna.OKButton.Clicked += delegate
1177                {
1178                    OnlineGame.ServerPassword.Clear();
1179                    OnlineGame.ServerPassword.Append(salasanaIkkuna.InputBox.Text);
1180                    LuoOnlineValikko();
1181                };
1182                Add(salasanaIkkuna);
1183                break;
1184            case 4:
1185                LuoAlkuValikko();
1186                break;
1187        }
1188    }
1189
1190    /// <summary>
1191    /// Asetukset, kuten fullscreen-valinta, antialiasing ja resoluutio.
1192    /// </summary>
1193    void LuoAsetusIkkuna()
1194    {
1195        AsetustenKaytto.LataaAsetukset();
1196        Mouse.IsCursorVisible = true;
1197        MultiSelectWindow paluu = new MultiSelectWindow("Asetukset", "Tallenna ja palaa päävalikkoon", "Palauta oletusasetukset");
1198        paluu.ItemSelected += delegate(int valinta)
1199        {
1200            switch (valinta)
1201            {
1202                case 0:
1203                    AsetustenKaytto.TallennaAsetukset();
1204                    PaaValikkoon();
1205                    break;
1206                case 1:
1207                    AsetustenKaytto.PalautaOletusAsetukset();
1208                    AsetustenKaytto.TallennaAsetukset();
1209                    PaaValikkoon();
1210                    break;
1211            }
1212        };
1213        paluu.Color = Color.Transparent;
1214        paluu.BorderColor = Color.Transparent;
1215        paluu.SelectionColor = Color.Green;
1216        Level.Background.Image = valikonKuva;
1217        Level.BackgroundColor = Color.Black;
1218        paluu.DefaultCancel = 0;
1219        paluu.Position = new Vector(0, Screen.Top - 100);
1220        Add(paluu);
1221
1222        OnOffButton fullscreenNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoFullscreen);
1223        fullscreenNappi.Position = new Vector(0.0, paluu.Y - 100);
1224        Add(fullscreenNappi);
1225        fullscreenNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoFullscreen = fullscreenNappi.IsPressed; this.IsFullScreen = AsetustenKaytto.Asetukset.OnkoFullscreen; };
1226
1227        Label fullscreenTeksti = new Label("Fullscreen:");
1228        fullscreenTeksti.Position = new Vector(fullscreenNappi.X - 100, fullscreenNappi.Y);
1229        Add(fullscreenTeksti);
1230
1231        OnOffButton antialiasingNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoAntialiasing);
1232        antialiasingNappi.Position = new Vector(0.0, fullscreenNappi.Y - 50);
1233        Add(antialiasingNappi);
1234        antialiasingNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoAntialiasing = antialiasingNappi.IsPressed; Game.SmoothTextures = AsetustenKaytto.Asetukset.OnkoAntialiasing; };
1235
1236        Label antialiasingTeksti = new Label("Antialiasing:");
1237        antialiasingTeksti.Position = new Vector(antialiasingNappi.X - 100, antialiasingNappi.Y);
1238        Add(antialiasingTeksti);
1239
1240        Label resoluutiotOtsikko = new Label("Resoluutio:");
1241        resoluutiotOtsikko.Position = new Vector(antialiasingTeksti.X, antialiasingTeksti.Y - 50);
1242        Add(resoluutiotOtsikko);
1243
1244        PushButton resoluutio800x600 = new PushButton(20, 20);
1245        resoluutio800x600.Position = new Vector(100.0, resoluutiotOtsikko.Y - 50);
1246        Add(resoluutio800x600);
1247        resoluutio800x600.Clicked += delegate { AsetaIkkunanKoko(800, 600); };
1248
1249        Label resoluutio800x600Teksti = new Label("800 x 600");
1250        resoluutio800x600Teksti.Position = new Vector(resoluutio800x600.X - 100, resoluutio800x600.Y);
1251        Add(resoluutio800x600Teksti);
1252
1253        PushButton resoluutio1024x768 = new PushButton(20, 20);
1254        resoluutio1024x768.Position = new Vector(100.0, resoluutio800x600.Y - 50);
1255        Add(resoluutio1024x768);
1256        resoluutio1024x768.Clicked += delegate { AsetaIkkunanKoko(1024, 768); };
1257
1258        Label resoluutio1024x768Teksti = new Label("1024 x 768");
1259        resoluutio1024x768Teksti.Position = new Vector(resoluutio1024x768.X - 100, resoluutio1024x768.Y);
1260        Add(resoluutio1024x768Teksti);
1261
1262        PushButton resoluutio1280x1024 = new PushButton(20, 20);
1263        resoluutio1280x1024.Position = new Vector(100.0, resoluutio1024x768.Y - 50);
1264        Add(resoluutio1280x1024);
1265        resoluutio1280x1024.Clicked += delegate { AsetaIkkunanKoko(1280, 1024); };
1266
1267        Label resoluutio1280x1024Teksti = new Label("1280 x 1024");
1268        resoluutio1280x1024Teksti.Position = new Vector(resoluutio1280x1024.X - 100, resoluutio1280x1024.Y);
1269        Add(resoluutio1280x1024Teksti);
1270
1271        PushButton resoluutio1600x1200 = new PushButton(20, 20);
1272        resoluutio1600x1200.Position = new Vector(100.0, resoluutio1280x1024.Y - 50);
1273        Add(resoluutio1600x1200);
1274        resoluutio1600x1200.Clicked += delegate { AsetaIkkunanKoko(1600, 1200); };
1275
1276        Label resoluutio1600x1200Teksti = new Label("1600 x 1200");
1277        resoluutio1600x1200Teksti.Position = new Vector(resoluutio1600x1200.X - 100, resoluutio1600x1200.Y);
1278        Add(resoluutio1600x1200Teksti);
1279
1280        PushButton resoluutio1920x1080 = new PushButton(20, 20);
1281        resoluutio1920x1080.Position = new Vector(100.0, resoluutio1600x1200.Y - 50);
1282        Add(resoluutio1920x1080);
1283        resoluutio1920x1080.Clicked += delegate { AsetaIkkunanKoko(1920, 1080); };
1284
1285        Label resoluutio1920x1080Teksti = new Label("1920 x 1080");
1286        resoluutio1920x1080Teksti.Position = new Vector(resoluutio1920x1080.X - 100, resoluutio1920x1080.Y);
1287        Add(resoluutio1920x1080Teksti);
1288
1289        OnOffButton pelaaja1LaserNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta);
1290        pelaaja1LaserNappi.Position = new Vector(0.0, resoluutio1920x1080.Y - 50);
1291        Add(pelaaja1LaserNappi);
1292        pelaaja1LaserNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta = !AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta; };
1293
1294        Label pelaaja1LaserTeksti = new Label("Pelaajan 1 lasertähtäin:");
1295        pelaaja1LaserTeksti.Position = new Vector(pelaaja1LaserNappi.X - 150, pelaaja1LaserNappi.Y);
1296        Add(pelaaja1LaserTeksti);
1297
1298        OnOffButton pelaaja2LaserNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta);
1299        pelaaja2LaserNappi.Position = new Vector(0.0, pelaaja1LaserNappi.Y - 50);
1300        Add(pelaaja2LaserNappi);
1301        pelaaja2LaserNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta = !AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta; };
1302
1303        Label pelaaja2LaserTeksti = new Label("Pelaajan 2 lasertähtäin:");
1304        pelaaja2LaserTeksti.Position = new Vector(pelaaja2LaserNappi.X - 150, pelaaja2LaserNappi.Y);
1305        Add(pelaaja2LaserTeksti);
1306
1307        PushButton kayttajaNimiNappi = new PushButton("Muuta");
1308        kayttajaNimiNappi.Color = Color.Green;
1309        kayttajaNimiNappi.Position = new Vector(0.0, pelaaja2LaserNappi.Position.Y - 50);
1310        kayttajaNimiNappi.Clicked += delegate
1311        {
1312            InputWindow kayttajanimiIkkuna = new InputWindow("");
1313            kayttajanimiIkkuna.Color = Color.Transparent;
1314            kayttajanimiIkkuna.InputBox.BorderColor = Color.Green;
1315            kayttajanimiIkkuna.InputBox.Text = AsetustenKaytto.Asetukset.KayttajaNimi;
1316            kayttajanimiIkkuna.InputBox.Cursor.Color = Color.Green;
1317            kayttajanimiIkkuna.Position = new Vector(0.0, kayttajaNimiNappi.Y - 50);
1318            kayttajanimiIkkuna.OKButton.Color = Color.Green;
1319            kayttajanimiIkkuna.OKButton.Clicked += delegate
1320            {
1321                AsetustenKaytto.Asetukset.KayttajaNimi = kayttajanimiIkkuna.InputBox.Text;
1322                AsetustenKaytto.TallennaAsetukset();
1323                LuoAsetusIkkuna();
1324            };
1325            Add(kayttajanimiIkkuna);
1326        };
1327        Add(kayttajaNimiNappi);
1328
1329        Label kayttajanimiTeksti = new Label("Käyttäjänimi: ");
1330        kayttajanimiTeksti.Position = new Vector(kayttajaNimiNappi.X - 150, kayttajaNimiNappi.Y);
1331        Add(kayttajanimiTeksti);
1332    }
1333
1334    /// <summary>
1335    /// Pelimuotovalikon luonti.
1336    /// </summary>
1337    void LuoPelimuodonValintaValikko()
1338    {
1339        AnimatedMultiSelectWindow pelimuotoValikko = new AnimatedMultiSelectWindow("Valitse pelimuoto", valikonPainikeKuva, "Deathmatch", "Infinite", "Sandbox", "Takaisin");
1340        pelimuotoValikko.ItemSelected += PainettiinPelimuotoValikonNappia;
1341        pelimuotoValikko.Color = Color.Transparent;
1342        pelimuotoValikko.BorderColor = Color.Transparent;
1343        Level.Background.Image = valikonKuva;
1344        Level.BackgroundColor = Color.Black;
1345        pelimuotoValikko.DefaultCancel = 2;
1346        Add(pelimuotoValikko);
1347    }
1348
1349    /// <summary>
1350    /// Pelimuotovalikon nappien painalluksen käsittely.
1351    /// </summary>
1352    /// <param name="valinta">Painettu nappi.</param>
1353    void PainettiinPelimuotoValikonNappia(int valinta)
1354    {
1355        switch (valinta)
1356        {
1357            case 0:
1358                LuoPelinKustomointiIkkuna();
1359                break;
1360            case 1:
1361                LuoInfinitevalikko();
1362                break;
1363            case 2:
1364                Level.Background.Image = null;
1365                ValittuKenttaTiedosto = "kenttä2"; // turha
1366                LuoKentta(2, 2, false);
1367                OnkoSatunnaisKentta = false;
1368                ClearControls();
1369                AsetaOhjaimet();
1370                AsetaSandboxOhjaimet();
1371                SoitaMusiikkia(3); // Sandbox: vanha OrcsCome
1372                break;
1373            case 3:
1374                LuoAlkuValikko();
1375                break;
1376        }
1377    }
1378
1379    /// <summary>
1380    /// Pelin kustomointi-ikkunan luonti.
1381    /// </summary>
1382    void LuoPelinKustomointiIkkuna()
1383    {
1384        List<Widget> ikkunanKomponentit = new List<Widget>();
1385
1386        MultiSelectWindow valikko = new MultiSelectWindow("Pelin kustomointi", "Klassinen mäppi", "Satunnaisgeneroitu mäppi", "Takaisin");
1387        valikko.ItemSelected += delegate(int valinta) { PainettiinPelinKustomointiIkkunanNappia(valinta, ikkunanKomponentit); };
1388        valikko.Color = Color.Transparent;
1389        valikko.SelectionColor = Color.Green;
1390        valikko.BorderColor = Color.Transparent;
1391        Level.Background.Image = valikonKuva;
1392        Level.BackgroundColor = Color.Black;
1393        valikko.DefaultCancel = 2;
1394        valikko.Position = new Vector(0.0, Screen.Top - valikko.Height);
1395        Add(valikko);
1396
1397        MonestakoVoittaa = new IntMeter(5, 1, 100);
1398
1399        Slider tapotJoillaVoittaa = new Slider(300.0, 20.0);
1400        tapotJoillaVoittaa.Position = new Vector(valikko.X, valikko.Y - 200);
1401        Add(tapotJoillaVoittaa);
1402        tapotJoillaVoittaa.BorderColor = Color.Transparent;
1403        tapotJoillaVoittaa.Color = Color.Transparent;
1404        tapotJoillaVoittaa.Knob.Color = Color.Green;
1405        tapotJoillaVoittaa.Track.Color = Color.DarkGreen;
1406        tapotJoillaVoittaa.BindTo(MonestakoVoittaa);
1407        ikkunanKomponentit.Add(tapotJoillaVoittaa);
1408
1409        Label tapotJoillaVoittaaOtsikko = new Label("Tappoja voittoon:");
1410        tapotJoillaVoittaaOtsikko.Position = new Vector(tapotJoillaVoittaa.X - tapotJoillaVoittaa.Width, tapotJoillaVoittaa.Y);
1411        Add(tapotJoillaVoittaaOtsikko);
1412        ikkunanKomponentit.Add(tapotJoillaVoittaaOtsikko);
1413
1414        Label tapotJoillaVoittaaNaytto = new Label();
1415        tapotJoillaVoittaaNaytto.BindTo(MonestakoVoittaa);
1416        tapotJoillaVoittaaNaytto.Position = new Vector(tapotJoillaVoittaa.X + tapotJoillaVoittaa.Width / 1.5, tapotJoillaVoittaa.Y);
1417        Add(tapotJoillaVoittaaNaytto);
1418        ikkunanKomponentit.Add(tapotJoillaVoittaaNaytto);
1419    }
1420
1421    /// <summary>
1422    /// Handleri pelin kustomointinäytön napeille.
1423    /// </summary>
1424    /// <param name="valinta">Valittu nappi.</param>
1425    /// <param name="poistettavatIkkunanKomponentit">Mitkä kaikki poistetaan, kun nappia painetaan.</param>
1426    void PainettiinPelinKustomointiIkkunanNappia(int valinta, List<Widget> poistettavatIkkunanKomponentit)
1427    {
1428        foreach (Widget ikkunanKomponentti in poistettavatIkkunanKomponentit)
1429        {
1430            ikkunanKomponentti.Destroy();
1431        }
1432
1433       
1434
1435        switch (valinta)
1436        {
1437            case 0:
1438                Level.Background.Image = null;
1439                ValittuKenttaTiedosto = "kenttä2"; // kenttä2
1440                LuoKentta(0, 2, false);
1441                ClearControls();
1442                AsetaOhjaimet();
1443                SoitaMusiikkia(1); // DarkLurk deathmatchiin
1444                //Level.Background.Image = LoadImage("Pohja_testi");
1445                break;
1446            case 1:
1447                Level.Background.Image = null;
1448                ValittuKenttaTiedosto = "kenttä2";
1449                LuoKentta(1, 2, false);
1450                OnkoSatunnaisKentta = true;
1451                ClearControls();
1452                AsetaOhjaimet();
1453                SoitaMusiikkia(1); // DarkLurk deathmatchiin
1454                break;
1455            case 2:
1456                LuoPelimuodonValintaValikko();
1457                break;
1458        }
1459    }
1460
1461    /// <summary>
1462    /// Infinitevalikon luonti.
1463    /// </summary>
1464    void LuoInfinitevalikko()
1465    {
1466        List<Widget> ikkunanKomponentit = new List<Widget>();
1467        IntMeter monestakoHaviaa = new IntMeter(1, 0, 100);
1468        Level.Background.Image = null;
1469        MultiSelectWindow infinitevalikko = new MultiSelectWindow("Valitse pelaajien määrä", "Yksinpeli", "Moninpeli", "Takaisin");
1470        infinitevalikko.ItemSelected += delegate(int valinta) { PainettiinInfiniteMenunNappia(valinta, monestakoHaviaa.Value, ikkunanKomponentit); };
1471        infinitevalikko.Color = Color.Transparent;
1472        infinitevalikko.SelectionColor = Color.Green;
1473        infinitevalikko.BorderColor = Color.Transparent;
1474        infinitevalikko.Position = new Vector(0.0, Screen.Top - infinitevalikko.Height);
1475        Level.Background.Image = valikonKuva;
1476        infinitevalikko.DefaultCancel = 2;
1477        Add(infinitevalikko);
1478
1479        Slider kuolematJoillaHaviaa = new Slider(300.0, 20.0);
1480        kuolematJoillaHaviaa.Position = new Vector(infinitevalikko.X, infinitevalikko.Y - 200);
1481        Add(kuolematJoillaHaviaa);
1482        kuolematJoillaHaviaa.BorderColor = Color.Transparent;
1483        kuolematJoillaHaviaa.Color = Color.Transparent;
1484        kuolematJoillaHaviaa.Knob.Color = Color.Green;
1485        kuolematJoillaHaviaa.Track.Color = Color.DarkGreen;
1486        kuolematJoillaHaviaa.BindTo(monestakoHaviaa);
1487        ikkunanKomponentit.Add(kuolematJoillaHaviaa);
1488
1489        Label kuolematJoillaHaviaaOtsikko = new Label("Respauksia käytössä:");
1490        kuolematJoillaHaviaaOtsikko.Position = new Vector(kuolematJoillaHaviaa.X - kuolematJoillaHaviaa.Width, kuolematJoillaHaviaa.Y);
1491        Add(kuolematJoillaHaviaaOtsikko);
1492        ikkunanKomponentit.Add(kuolematJoillaHaviaaOtsikko);
1493
1494        Label kuolematJoillaHaviaaNaytto = new Label();
1495        kuolematJoillaHaviaaNaytto.BindTo(monestakoHaviaa);
1496        kuolematJoillaHaviaaNaytto.Position = new Vector(kuolematJoillaHaviaa.X + kuolematJoillaHaviaa.Width / 1.5, kuolematJoillaHaviaa.Y);
1497        Add(kuolematJoillaHaviaaNaytto);
1498        ikkunanKomponentit.Add(kuolematJoillaHaviaaNaytto);
1499
1500    }
1501
1502    /// <summary>
1503    /// Infinitevalikon napin painalluksen käsittely.
1504    /// </summary>
1505    /// <param name="valinta">Mitä painettiin.</param>
1506    /// <param name="monestakoPoikki">Monestako peli menee poikki.</param>
1507    /// <param name="poistettavatJutut">Pitä poistetaan, kun nappia painetaan.</param>
1508    void PainettiinInfiniteMenunNappia(int valinta, int monestakoPoikki, List<Widget> poistettavatJutut)
1509    {
1510        foreach (Widget poistettava in poistettavatJutut)
1511        {
1512            poistettava.Destroy();
1513        }
1514
1515        switch (valinta)
1516        {
1517            case 0: // Infiniten yksinpeli
1518                Level.Background.Image = null;
1519                ValittuKenttaTiedosto = "Minium"; // zombimäppi1
1520                ClearControls();
1521                SoitaMusiikkia(4); // OrcsCome Special
1522                AloitaInfiniteGame(1, 0, monestakoPoikki);
1523                AsetaOhjaimet();
1524                break;
1525
1526            case 1: // Infiniten kaksinpeli
1527                Level.Background.Image = null;
1528                ValittuKenttaTiedosto = "Minium";
1529                ClearControls();
1530                SoitaMusiikkia(4); // OrcsCome Special
1531                AloitaInfiniteGame(2, 0, monestakoPoikki);
1532                AsetaOhjaimet();
1533                break;
1534            case 2:
1535                LuoPelimuodonValintaValikko();
1536                break;
1537        }
1538    }
1539
1540    /// <summary>
1541    /// Luodaan pausevalikko.
1542    /// </summary>
1543    void LuoPauseValikko()
1544    {
1545        IsPaused = true;
1546        MultiSelectWindow valikko = new MultiSelectWindow("TAUKO", "Takaisin peliin", "Päävalikkoon", "Poistu pelistä");
1547        valikko.ItemSelected += PainettiinPauseValikonNappia;
1548        valikko.Color = Color.Transparent;
1549        valikko.BorderColor = Color.Transparent;
1550        valikko.SelectionColor = Color.Green;
1551        valikko.DefaultCancel = 0;
1552        Add(valikko);
1553    }
1554
1555    /// <summary>
1556    /// Pausevalikon nappien painalluksen käsittely.
1557    /// </summary>
1558    /// <param name="valinta">Painettu nappi.</param>
1559    void PainettiinPauseValikonNappia(int valinta)
1560    {
1561        switch (valinta)
1562        {
1563            case 0:
1564                IsPaused = false;
1565                break;
1566            case 1:
1567                IsPaused = false;
1568                PaaValikkoon();
1569                break;
1570            case 2:
1571                Exit();
1572                break;
1573        }
1574    }
1575
1576    #endregion
1577
1578    #region infinite
1579
1580    /// <summary>
1581    /// Aloitetaan uusi Infinite-peli.
1582    /// </summary>
1583    /// <param name="pelaajienMaara">Montako pelaajaa peliin tulee.</param>
1584    /// <param name="kenttaTyyppi">Millaista kenttää käytetään.</param>
1585    /// <param name="monestakoRespauksestaPoikki">Monestako respauksesta peli menee poikki.-</param>
1586    void AloitaInfiniteGame(int pelaajienMaara, int kenttaTyyppi, int monestakoRespauksestaPoikki)
1587    {
1588        Infinite infinite = new Infinite(monestakoRespauksestaPoikki);
1589        LuoKentta(kenttaTyyppi, pelaajienMaara, true);
1590        LuoVihollistenMallineet(infinite);
1591        infinite.PeliPaattyi += InfiniteHavio;
1592        infinite.VihollistenSpawnausAjastin.Timeout += delegate { SpawnaaInfinitenVihollisia(infinite); };
1593        foreach (Pelaaja p in pelaajat)
1594        {
1595            p.Kuoli += infinite.PelaajaKuoli;
1596        }
1597
1598        if (kenttaTyyppi == 0)
1599        {
1600            infinite.KaytetaankoFixedSpawneja = true;
1601            //AsetaFixedSpawnitInfiniteen(infinite);
1602        }
1603        Level.AmbientLight = 0.4;
1604        if (pelaajienMaara == 1) Level.AmbientLight = 0.7; // koska taskulamppu
1605    }
1606
1607    /// <summary>
1608    /// Luodaan Infinitessä käytettävien vihollisten mallineet
1609    /// ja annetaan ne Infinite-pelimuodon spawnauslistaan.
1610    /// </summary>
1611    /// <param name="peli">Peli, johon viholliset lisätään.</param>
1612    void LuoVihollistenMallineet(Infinite peli)
1613    {
1614        // Tavallinen zombi
1615        Vihollinen zombi = new Vihollinen(normaaliZombiKuva.Width / 1.2, normaaliZombiKuva.Height / 1.2, normaaliZombiKuva, 20, 4, 100, pelaajat, false, false, this, peli);
1616        peli.LisaaVihollinenPeliin(zombi);
1617
1618        // Zombi, jolla on ase
1619        /*Vihollinen ampuvaZombi = new Vihollinen(ampuvaZombiKuva.Width / 1.2, ampuvaZombiKuva.Height / 1.2, ampuvaZombiKuva, 20, 4, 100, pelaajat, true, false, this, peli);
1620        ampuvaZombi.AmpumisTarkkuus = 6.0;
1621        ampuvaZombi.EtaisyysJoltaAmpuu = 300.0;
1622        ampuvaZombi.ValittuAse = Aseet.LuoRynkky();
1623        ampuvaZombi.ValittuAse.AanenVoimakkuus = 0.5;
1624        ampuvaZombi.TodennakoisyysSpawnata = 0.3;
1625        peli.LisaaVihollinenPeliin(ampuvaZombi);*/
1626
1627        // Itsetuhoinen parasiitti
1628        /*Vihollinen parasiitti = new Vihollinen(10, 10, RandomGen.SelectOne<Image>(parasiittienKuvat), 1, 2, 200, pelaajat, false, true, this);
1629        parasiitti.KuolemaEfektinPartikkeliKuva = RandomGen.SelectOne<Image>(parasiittienPartikkeliKuvat);
1630        peli.LisaaVihollinenPeliin(parasiitti); */
1631    }
1632
1633    /// <summary>
1634    /// Spawnataan viholliset Infiniten spawnauslistasta.
1635    /// </summary>
1636    /// <param name="peli">Peli, jonka spawnauslistasta viholliset spawnataan.</param>
1637    void SpawnaaInfinitenVihollisia(Infinite peli)
1638    {
1639        foreach (Vihollinen vihu in peli.TallaSpawnauskerrallaSpawnattavatViholliset)
1640        {
1641            vihu.Destroyed += delegate { peli.VihollisiaTapettu.Value++; };
1642            Add(vihu);
1643            if (peli.KaytetaankoFixedSpawneja && peli.VihollistenFixedSpawnit.Count != 0) vihu.Position = RandomGen.SelectOne<Vector>(peli.VihollistenFixedSpawnit);
1644            else vihu.Position = ArvoSpawnausPaikkaKentanLaidoilta(Vakiot.PALJONKO_VIHOLLISET_SPAWNAAVAT_KENTAN_RAJOJEN_ULKOPUOLELLE);
1645            peli.VihollisetKentalla.Add(vihu);
1646        }
1647    }
1648
1649    /// <summary>
1650    /// Arvotaan satunnainen paikka kentän rajojen ulkopuolelta.
1651    /// </summary>
1652    /// <param name="paljonkoLaitojenUlkopuolelle">Paljonko paikka tulee kentän rajojen ulkopuolelle.</param>
1653    /// <returns>Satunnainen paikka kentän laidoilta.</returns>
1654    Vector ArvoSpawnausPaikkaKentanLaidoilta(double paljonkoLaitojenUlkopuolelle)
1655    {
1656        //Arvotaan satunnainen vektori kentän joka laidalle, ja arvotaan joku niistä
1657        Vector[] vaihtoehdot = new Vector[4];
1658        vaihtoehdot[0] = RandomGen.NextVector(Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA - paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA,
1659            Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA - paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA); // vasen reuna
1660
1661        vaihtoehdot[1] = RandomGen.NextVector(Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA + paljonkoLaitojenUlkopuolelle,
1662            Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA + paljonkoLaitojenUlkopuolelle); // yläreuna
1663
1664        vaihtoehdot[2] = RandomGen.NextVector(Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA + paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA,
1665            Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA + paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA); // oikea reuna
1666
1667        vaihtoehdot[3] = RandomGen.NextVector(Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA - paljonkoLaitojenUlkopuolelle,
1668            Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA - paljonkoLaitojenUlkopuolelle); // alareuna
1669        return RandomGen.SelectOne<Vector>(vaihtoehdot); // palautetaan yksi neljästä
1670    }
1671
1672    /// <summary>
1673    /// Asetetaan Infiniten fixed-spawnit normimäppiä varten.
1674    /// </summary>
1675    /// <param name="peli"></param>
1676    void AsetaFixedSpawnitInfiniteen(Infinite peli)
1677    {
1678        peli.VihollistenFixedSpawnit.Add(new Vector(0, -900));
1679        peli.VihollistenFixedSpawnit.Add(new Vector(960, -270));
1680        peli.VihollistenFixedSpawnit.Add(new Vector(-960, -270));
1681        peli.VihollistenFixedSpawnit.Add(new Vector(0, 1640));
1682        peli.VihollistenFixedSpawnit.Add(new Vector(1300, 920));
1683        peli.VihollistenFixedSpawnit.Add(new Vector(-1300, 920));
1684    }
1685
1686    #endregion
1687
1688    #region pelaaja
1689
1690    /// <summary>
1691    /// Luodaan uusi pelaaja.
1692    /// </summary>
1693    /// <param name="paikka">Paikka, johon pelaaja luodaan ja johon se respawnaa.</param>
1694    /// <param name="leveys">Pelaajan leveys.</param>
1695    /// <param name="korkeus">Pelaajan korkeus.</param>
1696    /// <param name="numero">Pelaajan numero.</param>
1697    /// <param name="kuva">Pelaajan kuva.</param>
1698    /// <param name="kamanVari">Pelaajaan viittaavien objektien väri.</param>
1699    /// <param name="kaytetaankoLaseria">Onko pelaajalla lasertähtäin vai tavallinen piste.</param>
1700    /// <param name="hudinPaikka">Pelaajan HUD:in paikka.</param>
1701    /// <returns>Pelaaja.</returns>
1702    public Pelaaja LuoPelaaja(Vector paikka, double leveys, double korkeus, int numero, Image kuva, Color kamanVari, bool kaytetaankoLaseria, Vector hudinPaikka, bool kaytetaankoTaskulamppua)
1703    {
1704        Pelaaja pelaaja = new Pelaaja(leveys, korkeus, kaytetaankoLaseria, kaytetaankoTaskulamppua); // true: käytetäänkö taskulamppua
1705        pelaaja.CanRotate = false;
1706        pelaaja.Tag = "pelaaja";
1707        pelaaja.LisaaAse(Aseet.LuoPistooli());
1708        pelaaja.LisaaAse(Aseet.LuoNyrkki());
1709        pelaaja.Position = paikka;
1710        pelaaja.SpawnausPaikat.Add(paikka);
1711        pelaaja.Numero = numero;
1712        pelaaja.Image = kuva;
1713        pelaaja.LinearDamping = 0.80;
1714        pelaaja.objektienVari = kamanVari;
1715        pelaaja.elamaPalkki.BarColor = pelaaja.objektienVari;
1716        pelaaja.tahtain = LuoTähtäin(pelaaja.objektienVari);
1717        pelaaja.ValittuAseNaytto = LuoAseNäyttö(hudinPaikka);
1718        pelaaja.ValittuAseNaytto.Text = pelaaja.ValittuAse.AseenNimi;
1719        pelaaja.TappojenMaaraNaytto = LuoTappoNaytto(pelaaja.ValittuAseNaytto.Position);
1720        if (kaytetaankoLaseria)
1721        {
1722            pelaaja.kaytetaankoPalloTahtainta = false;
1723            //pelaaja.tahtain.IsVisible = false;
1724            //AxleJoint aj = new AxleJoint(pelaaja.tahtain, pelaaja);
1725            //aj.Softness = 2;
1726            //Add(aj);
1727        }
1728        return pelaaja;
1729    }
1730
1731    /// <summary>
1732    /// Liikutetaan pelaajaa määrättyyn suuntaan näppäimistöllä.
1733    /// </summary>
1734    /// <param name="pelaaja">Pelaaja, jota liikutetaan.</param>
1735    /// <param name="suunta">Suunta, johon pelaajaa liikutetaan.</param>
1736    void LiikutaPelaajaa(Pelaaja pelaaja, Vector suunta)
1737    {
1738        pelaaja.Move(suunta * pelaaja.Nopeus);
1739    }
1740
1741    /// <summary>
1742    /// Liikutetaan pelaajaa määrättyyn suuntaan Xbox-ohjaimella.
1743    /// </summary>
1744    /// <param name="pelaaja">Pelaaja, jota liikutetaan.</param>
1745    /// <param name="tatinTila">Xbox-ohjaimen analogitatin asento.</param>
1746    void LiikutaPelaajaaPadilla(AnalogState tatinTila, Pelaaja pelaaja)
1747    {
1748        Vector tatinAsento = tatinTila.StateVector;
1749        pelaaja.Move(tatinAsento * pelaaja.Nopeus);
1750        pelaaja.tahtain.Move(tatinAsento * pelaaja.Nopeus);
1751    }
1752
1753    // Tässä kohdassa (LiikutaTahtainta, LiikutaTahtaintaPadilla) ongelmana samat parametrit, mutta eri sisältö.
1754
1755    /// <summary>
1756    /// Liikutetaan pelaajan tähtäintä hiirellä.
1757    /// </summary>
1758    /// <param name="hiirenTila">Ei käytössä, pakollinen parametri.</param>
1759    /// <param name="pelaaja">Pelaaja, jonka tähtäintä liikutetaan.</param>
1760    void LiikutaTahtainta(AnalogState hiirenTila, Pelaaja pelaaja)
1761    {
1762        pelaaja.tahtain.X = Mouse.PositionOnWorld.X;
1763        pelaaja.tahtain.Y = Mouse.PositionOnWorld.Y;
1764    }
1765
1766    /// <summary>
1767    /// Liikutetaan pelaajan tähtäintä Xbox-ohjaimella.
1768    /// </summary>
1769    /// <param name="pelaaja">Pelaaja, jonka tähtäintä liikutetaan.</param>
1770    /// <param name="tatinTila">Xbox-ohjaimen analogitatin asento.</param>
1771    void LiikutaTahtaintaPadilla(AnalogState tatinTila, Pelaaja pelaaja)
1772    {
1773        pelaaja.tahtain.Move(tatinTila.StateVector * 1500);
1774    }
1775
1776    /// <summary>
1777    /// Luodaan uusi tähtäin.
1778    /// </summary>
1779    /// <param name="vari">Tähtäimen väri.</param>
1780    /// <returns>Tähtäin.</returns>
1781    PhysicsObject LuoTähtäin(Color vari)
1782    {
1783        PhysicsObject tähtäin = new PhysicsObject(10.0, 10.0);
1784        tähtäin.Shape = Shape.Circle;
1785        tähtäin.Color = vari;
1786        tähtäin.IgnoresCollisionResponse = true;
1787        tähtäin.IgnoresExplosions = true;
1788        tähtäin.IgnoresPhysicsLogics = true;
1789        tähtäin.LinearDamping = 0.60;
1790        Add(tähtäin, 3);
1791        return tähtäin;
1792    }
1793
1794    Label LuoTappoNaytto(Vector ylemmanHudinOsanPaikka)
1795    {
1796        Label tapponaytto = new Label("Tappoja: 0");
1797        tapponaytto.TextColor = Color.White;
1798        tapponaytto.BorderColor = Color.Transparent;
1799        tapponaytto.Position = ylemmanHudinOsanPaikka - new Vector(0.0, 60.0);
1800        Add(tapponaytto);
1801        return tapponaytto;
1802    }
1803
1804    #endregion
1805
1806    #region aseiden toiminnot
1807
1808    /// <summary>
1809    /// Ammutaan pelaajan kulloinkin valittuna olevalla aseella ja
1810    /// luodaan ammukselle törmäyksenkäsittelijät.
1811    /// </summary>
1812    /// <param name="pelaaja">Pelaaja, jonka aseella ammutaan.</param>
1813    /// <param name="overridesIsReady">Annetaan aseen ampua, vaikka se ei oikeasti voisi. Jos true, ääntä ei toisteta.</param>
1814    void Ammu(Pelaaja pelaaja, bool overridesIsReady = false)
1815    {
1816        // pari tarpeellista tarkistusta
1817        if (!pelaaja.IsAddedToGame) return;
1818        if (pelaaja.ValittuAse == null) return;
1819        if (pelaaja.LadataankoAsetta) return;
1820
1821        //pelaaja.ValittuAse.IsReady = true;
1822        PhysicsObject ammus = pelaaja.ValittuAse.Shoot(overridesIsReady);
1823        if (ammus == null) return;
1824
1825        // laitetaan ammus satunnaiseen suuntaan aseen hajoaman mukaan
1826        Vector random = RandomGen.NextVector(pelaaja.ValittuAse.AseenHajoama.X, pelaaja.ValittuAse.AseenHajoama.Y);
1827        if (pelaaja == pelaajat[0])
1828        {
1829            ammusmittariNäyttö.Text = pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString();
1830            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö.Text = "";
1831            if (pelaaja.ValittuAse.HyokkaysAnimaatio1 != null)
1832            {
1833                pelaajat[0].Animation = pelaaja.ValittuAse.HyokkaysAnimaatio1;
1834                pelaajat[0].Animation.Start(1);
1835            }
1836        }
1837
1838        if (pelaaja == pelaajat[1])
1839        {
1840            ammusmittariNäyttö2.Text = pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString();
1841            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö2.Text = "";
1842            if (pelaaja.ValittuAse.HyokkaysAnimaatio2 != null)
1843            {
1844                pelaajat[1].Animation = pelaaja.ValittuAse.HyokkaysAnimaatio2;
1845                pelaajat[1].Animation.Start(1);
1846            }
1847        }
1848
1849        ammus.Hit(random);
1850        ammus.CollisionIgnoreGroup = 4;
1851        ammus.Tag = "ammus";
1852        ammus.LinearDamping = 0.99;
1853        ammus.Size = new Vector(pelaaja.ValittuAse.luodinKuva.Width, pelaaja.ValittuAse.luodinKuva.Height);
1854        ammus.Color = Color.White;
1855        ammus.Mass = 0.01;
1856        ammus.CanRotate = false;
1857
1858        // jos on meleease, ei näytetä ammusta
1859        if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammus.IsVisible = false;
1860
1861        // muuten ammutaan hylsy ja laitetaan luodille oikea kuva
1862        else
1863        {
1864            if (pelaaja.ValittuAse.TuleekoHylsya)
1865                Hylsy(pelaaja, pelaaja.ValittuAse.hylsynKuva);
1866            ammus.Image = pelaaja.ValittuAse.luodinKuva;
1867        }
1868
1869        if (pelaaja.ValittuAse.UsesTracers)
1870        {
1871            ammus.IsUpdated = true;
1872            ammus.NeedsUpdateCall = true;
1873            Color c;
1874            if (pelaaja.ValittuAse.OverrideTracerColor != Color.Transparent)
1875                c = pelaaja.ValittuAse.OverrideTracerColor;
1876            else c = pelaaja.objektienVari;
1877            ammus.Updated += delegate(PhysicsObject o) { DrawTracers(o, c, pelaaja.ValittuAse.TracerLength, pelaaja.ValittuAse.TracerBrightness); };
1878        }
1879
1880        if (pelaaja.ValittuAse.IsHoming)
1881        {
1882            ammus.IsUpdated = true;
1883            ammus.NeedsUpdateCall = true;
1884            if (pelaaja == pelaajat[0])
1885                ammus.Updated += delegate(PhysicsObject o) { HakeuduKohteeseen(o, pelaajat[1], 750); };
1886            else
1887                ammus.Updated += delegate(PhysicsObject o) { HakeuduKohteeseen(o, pelaajat[0], 750); };
1888
1889        }
1890
1891        if (pelaaja.ValittuAse.LapaiseekoMateriaaleja)
1892        {
1893            ammus.IgnoresCollisionResponse = true;
1894            ammus.Collided += delegate
1895            {
1896                Timer.SingleShot(pelaaja.ValittuAse.AseenLapaisy, delegate { ammus.IgnoresCollisionResponse = false; });
1897            };
1898        }
1899
1900        AddCollisionHandler<PhysicsObject, Pelaaja>(
1901            ammus, delegate(PhysicsObject a, Pelaaja kohdepelaaja)
1902            {
1903                Damagea(kohdepelaaja, pelaaja.ValittuAse.TuhovoimaElaviaVastaan);
1904                Partikkelit.AddParticleEffect(Partikkelit.VeriPartikkelit, new Vector(a.X, a.Y), 40);
1905                osuma1.Play();
1906                if (ammus != null) ammus.Destroy();
1907            });
1908
1909        AddCollisionHandler<PhysicsObject, Vihollinen>(
1910            ammus, delegate(PhysicsObject a, Vihollinen kohde)
1911            {
1912                Damagea(kohde, pelaaja.ValittuAse.TuhovoimaElaviaVastaan);
1913                Partikkelit.AddParticleEffect(Partikkelit.VeriPartikkelit, new Vector(a.X, a.Y), 40);
1914                osuma1.Play();
1915                if (ammus != null) ammus.Destroy();
1916            });
1917
1918        AddCollisionHandler<PhysicsObject, Tuhoutuva>(
1919            ammus, delegate(PhysicsObject a, Tuhoutuva tuhoutuva)
1920        {
1921            if (tuhoutuva.IsStatic)
1922            {
1923                //GameObject luodinJalki = new GameObject(12, 13);
1924                //luodinJalki.Image = crack1;
1925                //luodinJalki.Position = a.Position;
1926                //luodinJalki.Angle = RandomGen.NextAngle();
1927                //Add(luodinJalki, 1);
1928                //LisaaTehosteObjekti(luodinJalki);
1929                //tuhoutuva.Destroyed += delegate
1930                //{
1931                //    luodinJalki.Destroy();
1932                //    tehosteet.Remove(luodinJalki);
1933                //};
1934            }
1935
1936            if (pelaaja.ValittuAse.HaviaakoAmmusOsumasta && ammus.IgnoresCollisionResponse == false)
1937            {
1938                a.Destroy();
1939                a.NeedsUpdateCall = false;
1940                switch (RandomGen.NextInt(0, 5))
1941                {
1942                    case 0:
1943                        luotiOsuu.Play();
1944                        break;
1945                    case 1:
1946                        luotiOsuu2.Play();
1947                        break;
1948                    case 2:
1949                        luotiOsuu3.Play();
1950                        break;
1951                    case 3:
1952                        luotiOsuu4.Play();
1953                        break;
1954                    case 4:
1955                        luotiOsuu5.Play();
1956                        break;
1957                }
1958            }
1959            else if (ammus.IgnoresCollisionResponse == true) // ei tuhota
1960            {
1961                switch (RandomGen.NextInt(0, 5))
1962                {
1963                    case 0:
1964                        luotiOsuu.Play();
1965                        break;
1966                    case 1:
1967                        luotiOsuu2.Play();
1968                        break;
1969                    case 2:
1970                        luotiOsuu3.Play();
1971                        break;
1972                    case 3:
1973                        luotiOsuu4.Play();
1974                        break;
1975                    case 4:
1976                        luotiOsuu5.Play();
1977                        break;
1978                }
1979            }
1980            else
1981            {
1982                a.Velocity = new Vector(0.0, 0.0);
1983                a.IgnoresCollisionResponse = true;
1984            }
1985            //tuhoutuva.Kesto.Value -= pelaaja.ValittuAse.TuhovoimaTuhoutuviaVastaan;
1986            Damagea(tuhoutuva, pelaaja.ValittuAse.TuhovoimaTuhoutuviaVastaan);
1987        });
1988
1989        AddCollisionHandler<PhysicsObject, Tuhoutuva>(
1990            ammus, "kivi", delegate(PhysicsObject a, Tuhoutuva kivi)
1991            {
1992                Partikkelit.AddParticleEffect(Partikkelit.KiviPartikkelit, new Vector(a.X, a.Y), 30);
1993                Partikkelit.AddParticleEffect(Partikkelit.KipinaPartikkelit, new Vector(a.X, a.Y), 5);
1994            });
1995
1996        AddCollisionHandler<PhysicsObject, Tuhoutuva>(
1997            ammus, "puu", delegate(PhysicsObject a, Tuhoutuva puu)
1998            {
1999                Partikkelit.AddParticleEffect(Partikkelit.PuuPartikkelit, new Vector(a.X, a.Y), 40);
2000            });
2001        AddCollisionHandler<PhysicsObject, PhysicsObject>(
2002            ammus, "piikkilanka", delegate(PhysicsObject a, PhysicsObject piikkilanka)
2003            {
2004                Partikkelit.AddParticleEffect(Partikkelit.KipinaPartikkelit, new Vector(a.X, a.Y), 40);
2005                //ammus.Destroy();
2006            });
2007        AddCollisionHandler<PhysicsObject, PhysicsObject>(
2008            ammus, delegate(PhysicsObject a, PhysicsObject kohde)
2009            {
2010                if (ammus.IgnoresCollisionResponse == false) a.Destroy();
2011                a.NeedsUpdateCall = false;
2012            });
2013
2014    }
2015
2016    /// <summary>
2017    /// Ammutaan haulikkotyyppisellä aseella.
2018    /// </summary>
2019    /// <param name="pelaaja">Pelaaja, jonka aseella ammutaan.</param>
2020    /// <param name="ammustenMaara">Montako ammusta ammutaan.</param>
2021    void AmmuHaulikolla(Pelaaja pelaaja, int ammustenMaara)
2022    {
2023        if (!pelaaja.ValittuAse.IsReady) return;
2024
2025        pelaaja.ValittuAse.AttackSound.Play();
2026        pelaaja.ValittuAse.Ammo.Value--;
2027        Hylsy(pelaaja, pelaaja.ValittuAse.hylsynKuva);
2028
2029        for (int i = 0; i < ammustenMaara; i++)
2030        {
2031            Ammu(pelaaja, true);
2032        }
2033    }
2034
2035    /// <summary>
2036    /// Ladataan pelaajan kulloinkin valittuna oleva ase.
2037    /// </summary>
2038    /// <param name="pelaaja">Pelaaja, jonka ase ladataan.</param>
2039    void Lataa(Pelaaja pelaaja)
2040    {
2041        // Ammo.Value == valitun aseen senhetkinen lippaassa oleva ammusmäärä
2042        // Ammo.MaxValue == valitun aseen maksimimäärä ammuksia lippaassa
2043        // MaxAmmo.Value == valitun aseen kokonaisammusten maksimimäärä
2044
2045        // jos ammukset täynnä, ei tehdä mitään
2046        if (pelaaja.ValittuAse.Ammo.Value == pelaaja.ValittuAse.Ammo.MaxValue)
2047        {
2048            pelaaja.LadataankoAsetta = false;
2049            return;
2050        }
2051
2052        // montako ammusta on käytetty lippaasta
2053        int lippaastaKaytettyjaAmmuksia = pelaaja.ValittuAse.Ammo.MaxValue - pelaaja.ValittuAse.Ammo.Value;
2054        aseLatausAani.Play();
2055        if (pelaaja.ValittuAse.MaxAmmo.Value >= pelaaja.ValittuAse.Ammo.MaxValue) pelaaja.ValittuAse.Ammo.Value = pelaaja.ValittuAse.Ammo.MaxValue;
2056        else pelaaja.ValittuAse.Ammo.Value = pelaaja.ValittuAse.MaxAmmo.Value;
2057
2058        pelaaja.ValittuAse.MaxAmmo.Value -= lippaastaKaytettyjaAmmuksia;
2059
2060        if (pelaaja == pelaajat[0])
2061        {
2062            ammusmittariNäyttö.Text = pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString();
2063        }
2064        if (pelaaja == pelaajat[1])
2065        {
2066            ammusmittariNäyttö2.Text = pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString();
2067        }
2068        pelaaja.LadataankoAsetta = false;
2069    }
2070
2071    /// <summary>
2072    /// Luo hylsyn pelaajan ampuessa ja lisää sen hylsyt-taulukkoon.
2073    /// </summary>
2074    /// <param name="pelaaja">Pelaaja, jonka aseesta hylsy lentää.</param>
2075    void Hylsy(Pelaaja pelaaja, Image hylsynkuva)
2076    {
2077        PhysicsObject hylsy = new PhysicsObject(2, 5);
2078        hylsy.Image = hylsynkuva;
2079        hylsy.Position = pelaaja.Position + Vector.FromLengthAndAngle(15, pelaaja.Angle + Angle.FromDegrees(-90));
2080        hylsy.LinearDamping = 0.93;
2081        hylsy.Mass = 0.5;
2082        hylsy.Angle = pelaaja.Angle + Angle.FromDegrees(90);
2083        hylsy.AngularVelocity = RandomGen.NextDouble(-20.0, 20.0);
2084        hylsy.AngularDamping = 0.97;
2085        Add(hylsy, -3);
2086
2087        hylsy.MaximumLifetime = TimeSpan.FromSeconds(1.5);
2088        hylsy.Destroying += delegate
2089        {
2090            GameObject fakeHylsy = new GameObject(hylsy.Width, hylsy.Height); // samanlainen GameObject-hylsy samaan paikkaan lagin vähentämiseksi
2091            fakeHylsy.Image = hylsynkuva;
2092            fakeHylsy.Position = hylsy.Position;
2093            fakeHylsy.Angle = hylsy.Angle;
2094            Add(fakeHylsy, -1);
2095            LisaaTehosteObjekti(fakeHylsy);
2096        };
2097
2098        hylsy.Hit(Vector.FromLengthAndAngle(RandomGen.NextInt(150, 300), pelaaja.Angle + Angle.FromDegrees(RandomGen.NextDouble(-95, -85))));
2099        AddCollisionHandler(hylsy, HylsyOsuu);
2100        Timer.SingleShot(0.5, delegate { hylsynPutoamisAani.Play(0.7, 0.0, 0.0); });
2101    }
2102
2103    /// <summary>
2104    /// CollisionHandleri hylsylle. Soitetaan kilahdusääni, jos hylsy osuu seinään.
2105    /// </summary>
2106    /// <param name="hylsy">Hylsy.</param>
2107    /// <param name="kohde">Kohde, johon hylsy osuu.</param>
2108    void HylsyOsuu(PhysicsObject hylsy, PhysicsObject kohde)
2109    {
2110        if (kohde is Tuhoutuva)
2111            hylsynPutoamisAani.Play(0.7, 0.0, 0.0);
2112    }
2113
2114    /// <summary>
2115    /// Heitetään kranaatti, jos pelaaja on lisätty ruudulle ja pelaajalla on kranaatteja jäljellä.
2116    /// </summary>
2117    /// <param name="pelaaja">Pelaaja, joka heittää kranaatin.</param>
2118    void HeitaKranaatti(Pelaaja pelaaja)
2119    {
2120        if (!pelaaja.IsAddedToGame || pelaaja.KranaattienMaara <= 0) return;
2121        const double KRANAATIN_NOPEUS = 25000;
2122        Grenade kranaatti = new Grenade(3.0, TimeSpan.FromSeconds(1.5));
2123        kranaatti.LinearDamping = 0.95;
2124        kranaatti.AngularVelocity = RandomGen.NextDouble(-5.0, 5.0);
2125        kranaatti.AngularDamping = 0.97;
2126        kranaatti.Image = kranaatinKuva;
2127        kranaatti.Explosion.Image = null;
2128        kranaatti.Explosion.ShockwaveColor = Color.Black;
2129        kranaatti.Explosion.IsShockwaveVisible = false;
2130        kranaatti.Explosion.Sound = Aseet.singonAani;
2131        kranaatti.Explosion.Speed = 2000;
2132        kranaatti.Explosion.MaxRadius = 500;
2133        kranaatti.Explosion.ShockwaveReachesObject += delegate(IPhysicsObject kohde, Vector shokki) { RajahdysOsuu(kohde, shokki, kranaatti.Position, Aseet.KRANAATIN_MAKSIMI_DAMAGE); };
2134        kranaatti.Destroying += delegate
2135        {
2136            Partikkelit.AddExplosionEffect(kranaatti.Position, 800);
2137            valo.Position = kranaatti.Position;
2138            valo.Intensity = 2.0;
2139            valo.Distance = 100;
2140            Timer.SingleShot(0.2, delegate { valo.Intensity = 1.5; });
2141            Timer.SingleShot(0.3, delegate { valo.Intensity = 1.0; });
2142            Timer.SingleShot(0.4, delegate { valo.Intensity = 0.5; });
2143            Timer.SingleShot(0.5, delegate { valo.Intensity = 0.0; });
2144        };
2145        kranaatti.IsUpdated = true;
2146        kranaatti.NeedsUpdateCall = true;
2147        kranaatti.Updated += delegate(PhysicsObject p) { DrawTracers(kranaatti.Position, Color.Orange, 0.30, 3); };
2148        pelaaja.Throw(kranaatti, Angle.FromDegrees(0), KRANAATIN_NOPEUS, 0, 0);
2149        pelaaja.KranaattienMaara--;
2150    }
2151
2152    /// <summary>
2153    /// Annetaan pelaajalle kamaa pelaajan törmätessä laatikkoon.
2154    /// </summary>
2155    /// <param name="laatikko">Laatikko, johon törmätään.</param>
2156    /// <param name="kohde">Pelaaja, joka törmää.</param>
2157    void AnnaKamaa(PhysicsObject laatikko, PhysicsObject kohde)
2158    {
2159        if (kohde.Tag.ToString() == "pelaaja")
2160        {
2161            Pelaaja pelaaja = (kohde as Pelaaja);
2162            Laatikko laat = (laatikko as Laatikko);
2163            Func<Ase>[] aseidenLuontimetodit = { Aseet.LuoRynkky, Aseet.LuoHaulikko, Aseet.LuoMinigun, Aseet.LuoSnipa, Aseet.LuoSinko, /*Aseet.LuoVarsijousi,*/ Aseet.LuoMagnum, Aseet.LuoVintorez };
2164
2165            if (laat.OnkoKäytössä == false)
2166            {
2167                //Ei voi ottaa kamaa käytetystä laatikosta
2168                return;
2169            }
2170            for (int i = 0; i < aseidenLuontimetodit.Length; i++)
2171            {
2172                Ase ase = aseidenLuontimetodit[i]();
2173                if (!pelaaja.OnkoPelaajallaAse(ase.Tag.ToString()))
2174                {
2175                    if (AikaKentanAlusta.SecondCounter.Value > ase.aikaJolloinVoiLuoda)
2176                    {
2177                        pelaaja.LisaaAse(ase);
2178                        MessageDisplay.Add("Pelaaja " + pelaaja.Numero + " sai aseen: " + ase.AseenNimi);
2179                        return;
2180                    }
2181                }
2182            }
2183            Ase satunnainenPelaajanAse;
2184            do
2185                satunnainenPelaajanAse = RandomGen.SelectOne<Ase>(pelaaja.Aseet);
2186            while (satunnainenPelaajanAse.OnkoMeleeAse);
2187
2188            satunnainenPelaajanAse.MaxAmmo.Value = satunnainenPelaajanAse.MaxAmmo.MaxValue;
2189            MessageDisplay.Add("Pelaaja " + pelaaja.Numero + " sai ammuksia aseeseen: " + satunnainenPelaajanAse.AseenNimi);
2190            pelaaja.KranaattienMaara++;
2191            MessageDisplay.Add("Pelaaja " + pelaaja.Numero + " sai kranaatin.");
2192
2193            laatikko.Image = kamaaNäkymätön;
2194            laatikko.IgnoresCollisionResponse = true;
2195            laat.OnkoKäytössä = false;
2196            laat.LaatikonAika.Start();
2197        }
2198    }
2199
2200    /// <summary>
2201    /// Luodaan näyttö, joka näyttää valitun aseen nimen.
2202    /// </summary>
2203    /// <param name="paikka">Näytön paikka.</param>
2204    /// <returns>Näyttö.</returns>
2205    Label LuoAseNäyttö(Vector paikka)
2206    {
2207        Label asenäyttö = new Label();
2208        Add(asenäyttö);
2209        //asenäyttö.X = Screen.Left + 130;
2210        //asenäyttö.Y = Screen.Top - 70;
2211        asenäyttö.Position = paikka;
2212        asenäyttö.TextColor = Color.White;
2213        asenäyttö.BorderColor = Color.Transparent;
2214        return asenäyttö;
2215    }
2216
2217    /// <summary>
2218    /// Luodaan pelaajan 1 ammusmittari.
2219    /// </summary>
2220    void AmmusMittari()
2221    {
2222        IntMeter ammusmittari = new IntMeter(0);
2223        ammusmittariNäyttö = new Label(
2224        pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString());
2225        ammusmittariNäyttö.X = Screen.Left + 125;
2226        ammusmittariNäyttö.Y = Screen.Top - 100;
2227        ammusmittariNäyttö.TextColor = Jypeli.Color.White;
2228        ammusmittariNäyttö.BorderColor = Jypeli.Color.Transparent;
2229        Add(ammusmittariNäyttö);
2230    }
2231
2232    /// <summary>
2233    /// Luodaan pelaajan 2 ammusmittari.
2234    /// </summary>
2235    void AmmusMittari2()
2236    {
2237        IntMeter ammusmittari2 = new IntMeter(0);
2238        ammusmittariNäyttö2 = new Label(pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString());
2239        ammusmittariNäyttö2.X = Screen.Right - 125;
2240        ammusmittariNäyttö2.Y = Screen.Top - 100;
2241        ammusmittariNäyttö2.TextColor = Jypeli.Color.White;
2242        ammusmittariNäyttö2.BorderColor = Jypeli.Color.Transparent;
2243        Add(ammusmittariNäyttö2);
2244    }
2245
2246    /// <summary>
2247    /// Vaihdetaan asetta ja pelaajan kuvaa.
2248    /// </summary>
2249    /// <param name="pelaaja">Pelaaja, jonka asetta vaihdetaan.</param>
2250    /// <param name="vaihtosuunta">Suunta, johon aselistaa pyöritetään.</param>
2251    void VaihdaAsetta(Pelaaja pelaaja, int vaihtosuunta = 0)
2252    {
2253        if (pelaaja.AseidenMaara < 1) return;
2254        pelaaja.VaihdaAse(Mouse.WheelChange);
2255        pelaaja.VaihdaAse(vaihtosuunta);
2256
2257        if (pelaaja == pelaajat[0])
2258        {
2259            pelaaja.Image = pelaaja.ValittuAse.Pelaajan1AseKuva;
2260            ammusmittariNäyttö.Text = pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString();
2261            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö.Text = "";
2262            pelaaja.ValittuAseNaytto.Text = pelaaja.ValittuAse.AseenNimi;
2263        }
2264
2265        if (pelaaja == pelaajat[1])
2266        {
2267            pelaaja.Image = pelaaja.ValittuAse.Pelaajan2AseKuva;
2268            ammusmittariNäyttö2.Text = pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString();
2269            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö2.Text = "";
2270            pelaaja.ValittuAseNaytto.Text = pelaaja.ValittuAse.AseenNimi;
2271        }
2272        pelaaja.ValittuAse.IsVisible = false;
2273    }
2274
2275    /// <summary>
2276    /// Ohjataan hakeutuvaa esinettä kohteeseen.
2277    /// </summary>
2278    /// <param name="hakeutuva">Hakeutuva esine.</param>
2279    /// <param name="kohde">Kohde, jota kohti hakeudutaan.</param>
2280    void HakeuduKohteeseen(PhysicsObject hakeutuva, PhysicsObject kohde, double nopeus)
2281    {
2282        if (hakeutuva.Brain.Owner != null) return;
2283
2284        FollowerBrain fb = new FollowerBrain(kohde);
2285        fb.Speed = nopeus;
2286        fb.TurnWhileMoving = true;
2287        hakeutuva.Brain = fb;
2288    }
2289
2290    #endregion
2291
2292    #region ohjaimet
2293
2294    /// <summary>
2295    /// Asetetaan ohjaimet.
2296    /// </summary>
2297    void AsetaOhjaimet()
2298    {
2299        // Pelaajan 1 ohjaimet
2300        Keyboard.Listen(Key.Escape, Jypeli.ButtonState.Pressed, LuoPauseValikko, "Lopeta peli");
2301        Keyboard.Listen(Key.W, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(0.0, 1.0));
2302        Keyboard.Listen(Key.S, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(0.0, -1.0));
2303        Keyboard.Listen(Key.A, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(-1.0, 0.0));
2304        Keyboard.Listen(Key.D, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(1.0, 0.0));
2305        Keyboard.Listen(Key.R, Jypeli.ButtonState.Pressed, delegate
2306        {
2307            lippaanPoistoAani.Play();
2308            pelaajat[0].LadataankoAsetta = true;
2309            if (pelaajat[0].ValittuAse.LatausAnimaatio1 != null)
2310            {
2311                pelaajat[0].Animation = new Animation(pelaajat[0].ValittuAse.LatausAnimaatio1);
2312                pelaajat[0].Animation.Start(1);
2313                pelaajat[0].Animation.FPS = pelaajat[0].Animation.FrameCount / pelaajat[0].ValittuAse.LataukseenKuluvaAika;
2314            }
2315            Timer.SingleShot(pelaajat[0].ValittuAse.LataukseenKuluvaAika, delegate { Lataa(pelaajat[0]); });
2316        }, null);
2317        Keyboard.Listen(Key.LeftShift, Jypeli.ButtonState.Pressed, delegate { pelaajat[0].Nopeus = 450.0; ;}, null);
2318        Keyboard.Listen(Key.LeftShift, Jypeli.ButtonState.Released, delegate { pelaajat[0].Nopeus = 300.0; ;}, null);
2319        Mouse.ListenWheel(delegate { VaihdaAsetta(pelaajat[0]); }, null);
2320        Mouse.Listen(MouseButton.Left, Jypeli.ButtonState.Down, delegate {
2321            if (pelaajat[0].ValittuAse.BulletsPerShot != 1) AmmuHaulikolla(pelaajat[0], pelaajat[0].ValittuAse.BulletsPerShot);
2322            else Ammu(pelaajat[0]);
2323        }, null);
2324        Mouse.Listen(MouseButton.Right, Jypeli.ButtonState.Pressed, HeitaKranaatti, null, pelaajat[0]);
2325        Mouse.ListenMovement(0.1, LiikutaTahtainta, null, pelaajat[0]);
2326
2327        Keyboard.Listen(Key.RightControl, ButtonState.Pressed, delegate { MessageDisplay.Add(pelaajat[0].Position.ToString()); }, null);
2328
2329        // Pelaajan 2 ohjaimet
2330        ControllerOne.ListenAnalog(AnalogControl.LeftStick, 0.1, LiikutaPelaajaaPadilla, null, pelaajat[1]);
2331        ControllerOne.Listen(Button.LeftStick, Jypeli.ButtonState.Pressed, delegate { pelaajat[1].Nopeus = 450.0; }, null);
2332        ControllerOne.Listen(Button.LeftStick, Jypeli.ButtonState.Released, delegate { pelaajat[1].Nopeus = 300.0; }, null);
2333        ControllerOne.ListenAnalog(AnalogControl.RightStick, 0.1, LiikutaTahtaintaPadilla, null, pelaajat[1]);
2334        ControllerOne.Listen(Button.RightTrigger, Jypeli.ButtonState.Down, delegate{
2335            if (pelaajat[1].ValittuAse.BulletsPerShot != 1) AmmuHaulikolla(pelaajat[1], pelaajat[1].ValittuAse.BulletsPerShot);
2336            else Ammu(pelaajat[1]);
2337        }, null);
2338        ControllerOne.Listen(Button.LeftTrigger, Jypeli.ButtonState.Pressed, HeitaKranaatti, null, pelaajat[1]);
2339        ControllerOne.Listen(Button.LeftShoulder, Jypeli.ButtonState.Pressed, delegate { VaihdaAsetta(pelaajat[1], -1); }, null);
2340        ControllerOne.Listen(Button.RightShoulder, Jypeli.ButtonState.Pressed, delegate { VaihdaAsetta(pelaajat[1], 1); }, null);
2341        ControllerOne.Listen(Button.X, Jypeli.ButtonState.Pressed, delegate
2342        {
2343            lippaanPoistoAani.Play(); pelaajat[1].LadataankoAsetta = true;
2344            if (pelaajat[1].ValittuAse.LatausAnimaatio1 != null)
2345            {
2346                pelaajat[1].Animation = new Animation(pelaajat[1].ValittuAse.LatausAnimaatio2);
2347                pelaajat[1].Animation.Start(1);
2348                pelaajat[1].Animation.FPS = pelaajat[1].Animation.FrameCount / pelaajat[1].ValittuAse.LataukseenKuluvaAika;
2349            }
2350            Timer.SingleShot(pelaajat[1].ValittuAse.LataukseenKuluvaAika, delegate { Lataa(pelaajat[1]); });
2351        }, null);
2352        ControllerOne.Listen(Button.A, Jypeli.ButtonState.Pressed, delegate { pelaajat[1].tahtain.Position = pelaajat[1].Position; }, null);
2353    }
2354
2355    /// <summary>
2356    /// Otetaan käyttöön sandbox-lisäohjaimet.
2357    /// </summary>
2358    void AsetaSandboxOhjaimet()
2359    {
2360        Keyboard.Listen(Key.Space, ButtonState.Pressed, delegate { LuoTuhoutuvaKentanOsa(pelaajat[0].tahtain.Position, 50, 50, null, kivenKuva, "kivi", 20, 1.0, 1.0); }, null);
2361        Keyboard.Listen(Key.K, ButtonState.Pressed, delegate { LuoKillBall(pelaajat[0].tahtain.Position); }, null);
2362        Keyboard.Listen(Key.T, ButtonState.Pressed, delegate { LuoTynnyri(pelaajat[0].tahtain.Position, 50.0, 50.0, null); }, null);
2363        ControllerOne.Listen(Button.B, ButtonState.Pressed, delegate { LuoTuhoutuvaKentanOsa(pelaajat[1].tahtain.Position, 50, 50, null, kivenKuva, "kivi", 20, 1.0, 1.0); }, null);
2364    }
2365
2366    #endregion
2367
2368    #region aseiden osumat
2369
2370    /// <summary>
2371    /// Kutsutaan, kun singon raketti osuu johonkin.
2372    /// </summary>
2373    /// <param name="ammus">Ammus, joka osuu.</param>
2374    /// <param name="kohde">Kohde, johon osutaan.</param>
2375    public void SingonAmmusRajahtaa(PhysicsObject ammus, PhysicsObject kohde)
2376    {
2377        Explosion sinkopaineaalto = new Explosion(200);
2378        sinkopaineaalto.Position = ammus.Position;
2379        sinkopaineaalto.Image = tyhjä;
2380        sinkopaineaalto.Sound = null;
2381        sinkopaineaalto.Force = 400;
2382        sinkopaineaalto.Speed = 1000;
2383        sinkopaineaalto.ShockwaveColor = Color.Black;
2384        sinkopaineaalto.ShockwaveReachesObject += delegate(IPhysicsObject paineaallonKohde, Vector shokki) { RajahdysOsuu(paineaallonKohde, shokki, ammus.Position, Aseet.SINGON_MAKSIMI_DAMAGE); };
2385
2386        Add(sinkopaineaalto);
2387        Aseet.singonAani.Play();
2388
2389        Partikkelit.AddParticleEffect(Partikkelit.RajahdysPartikkelit1, new Vector(kohde.X, kohde.Y), 500);
2390        Partikkelit.AddParticleEffect(Partikkelit.RajahdysPartikkelit2, new Vector(kohde.X, kohde.Y), 300);
2391        ammus.Destroy();
2392
2393        valo.Position = ammus.Position;
2394        valo.Intensity = 2.0;
2395        valo.Distance = 100;
2396        Timer.SingleShot(0.2, delegate { valo.Intensity = 1.5; });
2397        Timer.SingleShot(0.3, delegate { valo.Intensity = 1.0; });
2398        Timer.SingleShot(0.4, delegate { valo.Intensity = 0.5; });
2399        Timer.SingleShot(0.5, delegate { valo.Intensity = 0.0; });
2400    }
2401
2402    /// <summary>
2403    /// Lasketaan räjähdyksen aiheuttama vahinko etäisyyden mukaan.
2404    /// </summary>
2405    /// <param name="rajahdyksenKeskiPiste">Räjähdyksen keskipiste.</param>
2406    /// <param name="kohde">Kohde, johon räjähdys osuu.</param>
2407    /// <param name="maksimivahinko">Vahinko, jonka räjähdys tekee nollapisteessä.</param>
2408    /// <param name="nopeusJollaVahinkoVahenee">Nopeus, jolla räjähdyksen vahinko vähenee etäisyyden kasvaessa. Suurempi luku hidastaa, pienempi nopeuttaa.</param>
2409    /// <returns>Vahinko.</returns>
2410    double LaskeRajahdyksenDamage(Vector rajahdyksenKeskiPiste, Vector kohde, double maksimivahinko, double nopeusJollaVahinkoVahenee)
2411    {
2412        double pisteidenEtaisyys = Vector.Distance(rajahdyksenKeskiPiste, kohde) / nopeusJollaVahinkoVahenee;
2413        double damage = maksimivahinko - pisteidenEtaisyys;
2414        if (damage < 0) return 0;
2415        return damage;
2416    }
2417
2418    /// <summary>
2419    /// Törmäyksenkuuntelija räjähdyksille.
2420    /// </summary>
2421    /// <param name="kohde">Kohde, johon räjähdys osuu.</param>
2422    /// <param name="shokki">Pakollinen parametri.</param>
2423    void RajahdysOsuu(IPhysicsObject kohde, Vector shokki, Vector rajahdyksenAlkamisPiste, double maksimivahinko)
2424    {
2425        double todellinenVahinko = LaskeRajahdyksenDamage(rajahdyksenAlkamisPiste, kohde.Position, maksimivahinko, 8);
2426        if (todellinenVahinko == 0) return;
2427
2428        if (kohde is Tuhoutuva)
2429        {
2430            //Partikkelit.AddParticleEffect(Partikkelit.KiviHajoaa, new Vector(kohde.X, kohde.Y), 50);
2431            //Partikkelit.AddParticleEffect(Partikkelit.PuuHajoaa, new Vector(kohde.X, kohde.Y), 50);
2432            if (kohde != null) Damagea(kohde as Tuhoutuva, todellinenVahinko);
2433        }
2434
2435        if (kohde is Elava)
2436        {
2437            Elava kohdePelaaja = kohde as Elava;
2438            Partikkelit.AddParticleEffect(Partikkelit.VeriPartikkelit, new Vector(kohde.X, kohde.Y), 40);
2439            GameObject[] effects = Blood.AddNormalBlood(kohde.Position, 3, 0.3);
2440            foreach (GameObject blood in effects)
2441            {
2442                LisaaTehosteObjekti(blood);
2443            }
2444            Damagea(kohdePelaaja, todellinenVahinko);
2445        }
2446    }
2447    #endregion
2448}
Note: See TracBrowser for help on using the repository browser.