Subversion Repositories forest

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
rem Nightmare Forest
2
rem   by Daniel Marschall
3
 
4
rem ToDo:
5
rem   Nebel-Himmel-Probleme
6
rem   DynArray
7
rem   Steifen am Boden
8
rem   Radar wackelt
9
rem   Verifizieren der Dateien
10
rem   :startgame weglassen
11
rem   Streifen am Boden und am Himmel...
12
rem   Baum teiltransparenz
13
rem   Radar lieber als Matrix. Viele Probleme wie z.B. mit Skorpion transparenz
14
rem   Unscharfes Radar, Radar ganz dyn. zeichnen? Rader stay on top
15
rem   Menü: musik aus --> an: loop von position 0!
16
rem   Horizont machen...
17
rem breitbild
18
rem mausumkehrung einstellbar
19
rem 	die gegner kommen erst nach einer bestimmten zeit. spawnen weit weg vom spieler
20
rem stars.bmp (5000px) braucht lange zum laden. 1000px ist verpixelt
21
 
22
// Read configuration
23
open to read 1, "config.txt"
24
read string 1, dummy$ : rem header
25
framerate = fileReadInt(1)
26
clockSpeedFactor = fileReadInt(1)
27
clockBlinksPerSecond = fileReadInt(1)
28
clockShowSeconds = fileReadInt(1)
29
beginClockSeconds = fileReadInt(1)
30
enemyRotateSmoothness = fileReadInt(1)
31
maxRunEnergy = fileReadInt(1)
32
waterLevel = fileReadInt(1)
33
waterMovement = fileReadInt(1)
34
sound3dVolumeCor = fileReadInt(1)
35
invertMouse = fileReadInt(1)
36
test = fileReadInt(1)
37
camerarange = fileReadInt(1)
38
close file 1
39
 
40
rem SCHEISSE! bei 3000 ist die framerate total am arsch! was mach ich nur?
41
rem #constant cMaxTrees 3000
42
#constant cMaxTrees 200
43
 
44
#constant cMapSizeX 10000
45
#constant cMapSizeZ 10000
46
#constant idxMonsterBase 1000
47
 
48
#constant cMaxEnemies 20   : rem todo: 0 heißt 1 , das ist verwirrend
49
 
50
rem Setup & Startbildschirm
51
if check display mode( desktop width(), desktop height(), screen depth() ) then set display mode desktop width(), desktop height(), screen depth()
52
hide mouse
53
 
54
randomize timer()
55
 
56
Sync On
57
Sync Rate framerate
58
 
59
load bitmap "bitmap\titlescreen.jpg"
60
 
61
gosub _menu
62
 
63
_startgame:
64
 
65
ink rgb(255, 230, 0), 0
66
load bitmap "bitmap\titlescreen.jpg"
67
text 28, 550, "Level wird geladen..."
68
 
69
sync
70
 
71
rem Setup
72
Set camera range 1, camerarange
73
Autocam off
74
 
75
runEnergy# = maxRunEnergy
76
clockSeconds = beginClockSeconds
77
 
78
gosub _create_floor
79
gosub _create_sky
80
gosub _create_trees
81
gosub _draw_trees
82
gosub _create_water
83
gosub _create_radar
84
 
85
rem Bildschirm neu aufbauen
86
cls
87
sync
88
 
89
rem Lichtversuch
90
make light 1
91
 
92
rem Radar vorbereiten
93
radarpointcolor = 150
94
 
95
gosub _create_enemies
96
gosub _setupClock
97
 
98
Rem Forest atmo
99
load sound "sound\forestbg.wav", 1
100
loop sound 1
101
 
102
load sound "music\pause.wav", 5
103
 
104
load sound "sound\walk.wav", 10
105
 
106
rem Pause Menu
107
load image "bitmap\titlescreen.jpg",95
108
sprite 95,0,0,95
109
set sprite 95, 1, 0
110
hide sprite 95
111
 
112
rem Hauptschleife
113
do
114
    Disable EscapeKey
115
    gosub _handle_weather
116
    gosub _handle_player
117
    gosub _handle_radar
118
    gosub _handle_enemies
119
    gosub _handleClock
120
    if EscapeKey() = 1
121
        repeat
122
            sync
123
        until not (EscapeKey() = 1)
124
        gosub _pausemenu
125
    endif
126
    sync
127
loop
128
 
129
_pausemenu:
130
rem TODO: geht nicht
131
rem    show sprite 95
132
rem    load bitmap "bitmap\titlescreen.jpg",0
133
    gosub _stop_game_sounds
134
    loop sound 5
135
    repeat
136
        text 28, 550, "Pause. ESC=Weiter. Runter=Ende."
137
        sync
138
 
139
        if DownKey() = 1
140
            goto _exit
141
        ENDIF
142
    UNTIL EscapeKey() = 1
143
    repeat
144
        sync
145
    until not (EscapeKey() = 1)
146
    stop sound 5
147
    loop sound 1
148
    hide sprite 95
149
 
150
    rem TODO: das bringt nix. wenn man die maus bewegt, wird nach der pause die kamera gescrollt
151
    set cursor 0, 0
152
return
153
 
154
_handle_weather:
155
   rem Wetter
156
 
157
   color ambient light rgb(64,64,128)
158
rem   set ambient light 1
159
set ambient light 50
160
   if fog available() = 1
161
      fog on
162
      fog distance 600
163
      fog color rgb(0, 0, 0)
164
   endif
165
 
166
 
167
   if test = 1
168
        SET MATRIX WIREFRAME ON 1
169
        SET MATRIX WIREFRAME ON 3
170
    endif
171
 
172
 
173
 
174
   rem test
175
   remstart
176
   xx = xx - 1
177
   if xx <= 0 then xx = 100
178
 
179
   set object specular 126, 0
180
   SET OBJECT SPECULAR POWER 126,xx
181
 
182
   set object specular 127, 0
183
   SET OBJECT SPECULAR POWER 127,xx
184
   remend
185
 
186
rem   fade object 126, xx
187
rem   fade object 127, xx
188
 
189
 
190
   rem test trees
191
   remstart
192
       pX# = Camera Position X()
193
    pZ# = Camera Position Z()
194
 
195
        eX# = Object Position X(126)
196
        eZ# = Object Position Z(126)
197
 
198
        deltaX# = pX#-eX#
199
        deltaZ# = pZ#-eZ#
200
 
201
                aa# = atanfull(deltaX#, deltaZ#)
202
                 rotate object 126, 0, aa#, 0
203
remend
204
 
205
 
206
    rem Stars are moving
207
    scroll object texture 2, 0.00002, 0
208
 
209
 
210
 
211
    rem TODO: doch lieber eine plane mit scroll object texture?
212
    rem man kann "fog" einschalten, aber "ambient light" (problem) ausmachen per set object
213
    if waterMovement > 0
214
        if waterdir=0
215
            watermov=watermov+1
216
            if watermov=waterMovement
217
                waterdir=1
218
            endif
219
        ENDIF
220
        if waterdir=1
221
            watermov=watermov-1
222
            if watermov=-1
223
                waterdir=0
224
            endif
225
        ENDIF
226
    endif
227
    position matrix 3, watermov, waterLevel, watermov
228
return
229
 
230
_handle_enemies:
231
    pX# = Camera Position X()
232
    pZ# = Camera Position Z()
233
 
234
    for t = 0 to cMaxEnemies
235
        eX# = Object Position X(idxMonsterBase+t)
236
        eY# = Object Position Y(idxMonsterBase+t)
237
        eZ# = Object Position Z(idxMonsterBase+t)
238
 
239
        eRX# = Object Angle X(idxMonsterBase+t)
240
        eRY# = Object Angle Y(idxMonsterBase+t)
241
        eRZ# = Object Angle Z(idxMonsterBase+t)
242
 
243
        deltaX# = pX#-eX#
244
        deltaZ# = pZ#-eZ#
245
 
246
        rem TODO: cor file
247
        yPosOffset# = 20
248
 
249
        dist# = sqrt( deltaX#*deltaX# + deltaZ#*deltaZ# )
250
 
251
        if clockSeconds > 1
252
            if not sound playing(idxMonsterBase+t)
253
                set sound volume idxMonsterBase+t, 0
254
 
255
                rem TODO: beliebiges startoffset?
256
                loop sound idxMonsterBase+t
257
            endif
258
        endif
259
 
260
        rem The mixing of 3dsound is bullshit (too loud from far distance, and not very loud on close distance),
261
        rem so we mix the volume ourself
262
        if sound3dVolumeCor>0 and dist#<sound3dVolumeCor then set sound volume idxMonsterBase+t, (1-(dist#/sound3dVolumeCor))*100
263
 
264
        if dist# > 10 : rem <-- at least a distance of 10 so that atanfull() does not bug, when deltas becomes 0
265
            if dist# < enemyAwarenessRadius(t)
266
                enemyAngle(t) = atanfull(deltaX#, deltaZ#)
267
                enemyAngle(t) = WrapValue(enemyAngle(t)+180)
268
                enemyCurSpeed(t) = enemyMaxSpeed(t)
269
            else
270
                if enemyWalkTimeout(t) <= 0
271
                    enemyWalkTimeout(t) = RndBetween(enemyWalkTimeoutMin(t), enemyWalkTimeoutMax(t))
272
                    enemyAngle(t) = RndBetween(0,359)
273
                    enemyCurSpeed(t) = RndBetween(0, enemyMaxSpeed(t))
274
                ENDIF
275
                enemyWalkTimeout(t) = enemyWalkTimeout(t) - 1
276
            endif
277
 
278
            if enemyCurSpeed(t) = 0
279
                gosub scorpChangeToIdle
280
            else
281
                gosub scorpChangeToWalk
282
                rem TODO: also make animation slower/faster
283
            endif
284
 
285
            a# = WrapValue(enemyAngle(t) + 180)
286
            XTest# = Newxvalue(eX#, a#, enemyCurSpeed(t))
287
            ZTest# = Newzvalue(eZ#, a#, enemyCurSpeed(t))
288
            if XTest# > 0 and XTest# < cMapSizeX then eX# = XTest#
289
            if ZTest# > 0 and ZTest# < cMapSizeZ then eZ# = ZTest#
290
            if XTest# <= 0 or XTest# >= cMapSizeX or ZTest# <= 0 or ZTest# >= cMapSizeZ
291
                rem Kehrtwende, um den Kartenrand zu verlassen
292
                enemyAngle(t) = WrapValue(enemyAngle(t)+180)
293
                enemyWalkTimeout(t) = RndBetween(enemyWalkTimeoutMin(t), enemyWalkTimeoutMax(t))
294
                enemyCurSpeed(t) = RndBetween(0, enemyMaxSpeed(t))
295
            endif
296
 
297
            eY# = floorHeight#(eX#, eZ#) + yPosOffset#
298
            Position Object idxMonsterBase+t, eX#, eY#, eZ#
299
            Position Sound idxMonsterBase+t, eX#, eY#, eZ#
300
 
301
            eRY# = smoothRotate#(eRY#, enemyAngle(t), enemyRotateSmoothness)
302
            rotate object idxMonsterBase+t, eRX#, eRY#, eRZ#
303
        endif
304
    next
305
return
306
 
307
_handle_player:
308
   set cursor 0, 0
309
   oldcAY# = cAY#
310
   oldcAX# = cAX#
311
 
312
   X# = camera position x()
313
   Y# = camera position y()
314
   Z# = camera position z()
315
 
316
   if invertMouse = 1
317
       cAX# = WrapValue(cAX# - MousemoveY() * 0.2)
318
   else
319
       cAX# = WrapValue(cAX# + MousemoveY() * 0.2)
320
   endif
321
   cAY# = WrapValue(cAY# + MousemoveX() * 0.2)
322
   cAZ# = Camera angle Z()   
323
 
324
   rem Sprungroutine
325
   jumpBoost = 1
326
   if sprungdelay > 0 then dec sprungdelay
327
   if MouseClick() = 2 and sprung = 0 and sprungrev = 0 and sprungdelay = 0 and obentimer = 0 then sprung = sprung + 5
328
   if sprung > 0
329
     if sprungrev = 0
330
       if obentimer = 0
331
         if sprung < 70 then sprung = sprung + 5
332
         if sprung > 69 then sprung = sprung + 2
333
       endif
334
       if sprung > 79 and obentimer < 5 then obentimer = obentimer + 1
335
       if obentimer > 2
336
         obentimer = 0
337
         sprungrev = 1
338
       endif
339
     else
340
       if sprungrev = 1
341
         sprung = sprung - 5
342
         if sprung < 1
343
           sprungrev = 0
344
           sprung = 0
345
           sprungdelay = 15
346
         endif
347
       endif
348
     endif
349
   endif
350
 
351
    rem Laufen
352
    speedboost# = 1
353
 
354
    if upPressed()+downPressed()+leftPressed()+rightPressed() = 0
355
        runEnergy# = runEnergy# + 2
356
        stop sound 10
357
    else
358
        if not sound playing(10) then loop sound 10
359
        energyChanged = 0
360
        if ShiftKey()+ControlKey() = 1 : rem shift+control at the same time = walk normal
361
            rem TODO: es ruckelt trotzdem noch
362
            if ControlKey()=1 and runEnergy#>0 : rem Energy >1 , damit es nicht ruckelt (run-walk-run-walk-run-walk) . 3 = walk regain
363
                speedboost# = 2
364
                runEnergy# = runEnergy# - 1
365
                energyChanged = 1
366
            endif
367
            if ShiftKey()=1
368
                speedboost# = 0.5
369
                runEnergy# = runEnergy# + 0.5
370
                energyChanged = 1
371
            endif
372
        endif
373
        if not energyChanged then runEnergy# = runEnergy# + 1
374
        if upPressed()
375
            XTest# = Newxvalue(X#, cAY#, 7*speedboost#)
376
            ZTest# = Newzvalue(Z#, cAY#, 7*speedboost#)
377
            if XTest# > 0 and XTest# < cMapSizeX then X# = XTest#
378
            if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest#
379
        endif
380
        if downPressed()
381
            XTest# = Newxvalue(X#, Wrapvalue(cAY# - 180), 5*(speedboost#/2))
382
            ZTest# = Newzvalue(Z#, Wrapvalue(cAY# - 180), 5*(speedboost#/2))
383
            if XTest# > 0 and XTest# < cMapSizeX then X# = XTest#
384
            if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest#
385
        endif
386
        if leftPressed()
387
            XTest# = Newxvalue(X#, Wrapvalue(cAY# - 90), 5*(speedboost#/1.3))
388
            ZTest# = Newzvalue(Z#, Wrapvalue(cAY# - 90), 5*(speedboost#/1.3))
389
            if XTest# > 0 and XTest# < cMapSizeX then X# = XTest#
390
            if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest#
391
        endif
392
        if rightPressed()
393
            XTest# = Newxvalue(X#, Wrapvalue(cAY# + 90), 5*(speedboost#/1.3))
394
            ZTest# = Newzvalue(Z#, Wrapvalue(cAY# + 90), 5*(speedboost#/1.3))
395
            if XTest# > 0 and XTest# < cMapSizeX then X# = XTest#
396
            if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest#
397
        endif
398
    endif
399
    if runEnergy# > maxRunEnergy then runEnergy# = maxRunEnergy
400
    print "Run energy: ", runEnergy#
401
 
402
    Rem Rotate camera
403
    cTestX# = WrapValue(cAX# - 180)
404
    if cTestX# > 225 then cAX# = 45
405
    if cTestX# < 135 then cAX# = 315
406
    YRotate camera CurveAngle(cAY#, oldcAY#, 24)
407
    XRotate camera CurveAngle(cAX#, oldcAX#, 24)
408
 
409
    Rem Position Camera
410
    Y# = floorHeight#(X#, Z#) + 85 + sprung*jumpBoost
411
    Position Camera X#, Y#, Z#
412
 
413
    Rem Position Listener
414
    Position Listener X#, Y#, Z#
415
    Rotate Listener 0, cAY#, 0
416
 
417
    rem Sky sphere follows player
418
    position object 2, X#, Y#, Z#
419
 
420
    rem zrotate object 51, cAY#
421
return
422
 
423
_fademenu:
424
   if fade > 100 then fadedir = 0
425
   if fade < 50 then fadedir = 1
426
   if fadedir = 1
427
      fade = fade + 2.5
428
   else
429
      fade = fade - 2.5
430
   endif
431
   rem Beleuchtet
432
   ink rgb(255, fade, 0), 0
433
   set text font "Tahoma"
434
   set text size 26
435
   if menu = 1
436
     if pos = 1 then text 260, 255, "Neues Spiel starten"
437
     if pos = 2 then text 260, 285, "Spiel laden"
438
     if pos = 3 then text 260, 315, "Einstellungen"
439
     if pos = 4 then text 260, 345, "Spiel beenden"
440
   endif
441
   if menu = 3
442
     if pos = 1
443
        if sound = 1 then text 260, 255, "Ton: An"
444
        if sound = 0 then text 260, 255, "Ton: Aus"
445
     endif
446
     if pos = 2
447
        if music = 1 then text 260, 285, "Musik: An"
448
        if music = 0 then text 260, 285, "Musik: Aus"
449
     endif
450
     if pos = 3 then text 260, 315, "Hauptmenü"
451
   endif
452
   rem Normal
453
   ink rgb(255, 230, 0), 0
454
   if menu = 1
455
     if pos <> 1 then text 260, 255, "Neues Spiel starten"
456
     if pos <> 2 then text 260, 285, "Spiel laden"
457
     if pos <> 3 then text 260, 315, "Einstellungen"
458
     if pos <> 4 then text 260, 345, "Spiel beenden"
459
   endif
460
   if menu = 3
461
     if pos <> 1
462
        if sound = 1 then text 260, 255, "Ton: An"
463
        if sound = 0 then text 260, 255, "Ton: Aus"
464
     endif
465
     if pos <> 2
466
        if music = 1 then text 260, 285, "Musik: An"
467
        if music = 0 then text 260, 285, "Musik: Aus"
468
     endif
469
     if pos <> 3 then text 260, 315, "Hauptmenü"
470
   endif
471
   sync
472
return
473
 
474
_handle_radar:
475
   rem Leuchtpunkt
476
   if radarpointrev = 0
477
     inc radarpointcolor, 3
478
   else
479
     dec radarpointcolor, 3
480
   endif
481
   if radarpointcolor > 255
482
     radarpointrev = 1
483
     radarpointcolor = 254
484
   endif
485
   if radarpointcolor < 150
486
     radarpointrev = 0
487
     radarpointcolor = 149
488
   endif
489
   rem Bäume
490
    for t = 0 to cMaxTrees
491
     x = (baumx(t) / 62.5) + 7.5
492
     y = screen height() - 7.5 - (baumz(t) / 62.5)
493
     rem ink rgb(0, radarpointcolor, 0), 0
494
     ink rgb(0, 50, 0), 0
495
     circle x, y, 1
496
     circle x, y, 0
497
   next i
498
   rem Player
499
   x = (X# / 62.5) + 7.5
500
   y = screen height() - 7.5 - (Z# / 62.5)
501
   ink rgb(0, 0, radarpointcolor), 0
502
   circle x, y, 1
503
   circle x, y, 0
504
   rem Enemies
505
   for t = 0 to cMaxEnemies
506
       x = (object position x(idxMonsterBase+t) / 62.5) + 7.5
507
       y = screen height() - 7.5 - (object position z(idxMonsterBase+t) / 62.5)
508
       ink rgb(radarpointcolor, 0, 0), 0
509
       circle x, y, 1
510
       circle x, y, 0
511
   next
512
return
513
 
514
_draw_trees:
515
    // TODO: mit clone object arbeiten?
516
    load image "bitmap\tree.bmp", 4
517
    make object plain 52, 200, 400
518
    make mesh from object 52, 52
519
    add limb 52, 1, 52
520
    rotate limb 52, 1, 0, 90, 0
521
    make mesh from object 52, 52
522
    delete object 52
523
 
524
    // Methode 1: 1 Baum = 1 Object
525
    for t = 0 to cMaxTrees
526
       make object 1500+t, 52, 4
527
       rx = baumx(t)
528
       rz = baumz(t)
529
       position object 1500+t, rx, floorHeight#(rx, rz)+190, rz
530
      set object 1500+t, 1, 1, 0
531
    next t
532
 
533
    // Methode 2: Alle Bäume = 1 Objekt
534
    remstart
535
    make object 52, 52, 0 : rem TODO: da ist ein baum an offset 0,0,0
536
    for t = 0 to cMaxTrees
537
       add limb 52, t+1, 52
538
       rx = baumx(t)
539
       rz = baumz(t)
540
       offset limb 52, t, rx, floorHeight#(rx, rz), rz
541
    next t
542
    make mesh from object 52, 52
543
    delete object 52
544
    make object 52, 52, 4
545
    position object 52, 0, 190, 0
546
    set object 52, 1, 1, 0
547
    remend
548
 
549
 
550
    rem test todo
551
 
552
    rx = 500
553
    rz = 500
554
    load image "bitmap\dark-forest.jpg", 127
555
     MAKE OBJECT BOX  127, 500, 350, 500
556
         position object 127, rx, floorHeight#(rx,rz)+175, rz
557
rem    set object 127, 1, 0, 0, 0, 0, 1, 0
558
    texture object 127, 127
559
 
560
    rx = 1700
561
    rz = 500
562
    load image "bitmap\dark-forest2.jpg", 126
563
     MAKE OBJECT CYLINDER 126, 350
564
     scale object 126, 180, 100, 180 : rem percent!
565
         position object 126, rx, floorHeight#(rx,rz)+150, rz
566
    set object 126, 1, 0, 0, 0, 0, 1, 0 
567
rem    texture object 126, 126
568
 
569
 
570
 
571
 
572
 
573
    rem Make flat mesh piece
574
    make object plain 998,300,300
575
    hide object 998
576
    make mesh from object 1,998
577
    delete object 998
578
 
579
 
580
 
581
    rem const
582
    h=-40
583
    li=0
584
 
585
    end_x = 400
586
    end_y = 400
587
 
588
    for i = 0 to 10
589
        w = RndBetween(150,250)
590
        a = a + RndBetween(-80,80)
591
        start_x = end_x
592
        start_y = end_y  
593
        center_x = start_x + (w/2) * cos(a)
594
        center_y = start_y + (w/2) * sin(a)
595
        end_x = start_x + w * cos(a)
596
        end_y = start_y + w * sin(a)
597
        li=li+1
598
        add limb 126,li,1
599
        rotate limb 126, li, 0, -a, 0
600
        offset limb 126,li,center_x,floorHeight#(center_x,center_y)+h,center_y
601
    next
602
 
603
    set object cull 126, 0 
604
    set object ambient 126, 0   
605
    texture object 126, 126
606
 
607
return
608
 
609
_create_trees:
610
    dim baumx(cMaxTrees)
611
    dim baumz(cMaxTrees)
612
    for t = 0 to cMaxTrees
613
        repeat
614
            x = rnd(cMapSizeX)
615
            z = rnd(cMapSizeZ)
616
            ok = 1
617
            if isInCircle(x,z,5000,5000,2000) then ok=0 : rem TODO: später für büschel anwenden
618
        until ok=1
619
        baumx(t) = x
620
        baumz(t) = z
621
    NEXT
622
return
623
 
624
_menu:
625
  load bitmap "bitmap\titlescreen.jpg"
626
  set text font "times"
627
  set text size 27
628
  fade = 100
629
  pos = 1
630
  menu = 1
631
  sound = 1
632
  do
633
     gosub _fademenu
634
     if ( downkey() = 1 and pos < 4 and menu = 1 ) or ( downkey() = 1 and pos < 3 and menu = 3 )
635
       inc pos
636
       while downkey() = 1
637
          gosub _fademenu
638
       endwhile
639
     endif
640
     if upkey() = 1 and pos > 1
641
       dec pos
642
       while upkey() = 1
643
          gosub _fademenu
644
       endwhile
645
     endif
646
     if returnkey() = 1
647
       if menu = 1
648
          if pos = 1 then gosub _startgame
649
          if pos = 2
650
            rem load bitmap "bitmap\titlescreen.jpg"
651
            rem menu = 2
652
            rem pos = 1
653
          endif
654
          if pos = 3
655
            load bitmap "bitmap\titlescreen.jpg"
656
            menu = 3
657
            pos = 1
658
          endif
659
          if pos = 4 then end
660
       else
661
         if menu = 3
662
            if pos = 1
663
              if sound = 1
664
                sound = 0
665
              else
666
                sound = 1
667
              endif
668
              load bitmap "bitmap\titlescreen.jpg"
669
            endif
670
            if pos = 2
671
              if music = 1
672
                music = 0
673
              else
674
                music = 1
675
              endif
676
              load bitmap "bitmap\titlescreen.jpg"
677
            endif
678
            if pos = 3
679
              load bitmap "bitmap\titlescreen.jpg"
680
              menu = 1
681
              pos = 1
682
            endif
683
         endif
684
       endif
685
       while returnkey() = 1
686
          gosub _fademenu
687
       endwhile
688
     endif
689
  loop
690
return
691
 
692
_create_enemies:
693
    dim enemySpeed(cMaxEnemies)
694
    dim enemyDir(cMaxEnemies)
695
    dim enemyWalkTimeout(cMaxEnemies)
696
    dim enemyWalkTimeoutMin(cMaxEnemies)
697
    dim enemyWalkTimeoutMax(cMaxEnemies)
698
    dim enemyAwarenessRadius(cMaxEnemies)
699
    dim enemyCurSpeed(cMaxEnemies)
700
    dim enemyMaxSpeed(cMaxEnemies)
701
    dim enemyAngle(cMaxEnemies)
702
    dim enemyCurrentAnim(cMaxEnemies)
703
    for t = 0 to cMaxEnemies
704
        if t=0        
705
            Load 3Dsound "test.wav",idxMonsterBase+t
706
        else
707
            Clone Sound idxMonsterBase+t, idxMonsterBase
708
        endif
709
 
710
        x# = RndBetween(1000, 9000)
711
        z# = RndBetween(1000, 9000)
712
        enemyAwarenessRadius(t) = RndBetween(600, 1300)
713
        enemyMaxSpeed(t) = RndBetween(1, 4)
714
        enemyWalkTimeoutMin(t) = 200
715
        enemyWalkTimeoutMax(t) = 300
716
 
717
        if t = 0
718
            animScorpIdleStart = 0
719
            Load object "obj\scorpion\ScorpIdle.x", idxMonsterBase+t
720
            animScorpIdleEnd = total object frames(idxMonsterBase+t)
721
 
722
            animScorpWalkStart = animScorpIdleEnd+1
723
            Append object "obj\scorpion\ScorpWalk.x", idxMonsterBase+t, animScorpWalkStart
724
            animScorpWalkEnd = total object frames(idxMonsterBase+t)
725
        else
726
            Clone Object idxMonsterBase+t, idxMonsterBase        
727
        endif
728
 
729
        y# = floorHeight#(x#, z#) : rem TODO  + yPosOffset#
730
        position object idxMonsterBase+t, x#, y#, z#
731
        Position Sound idxMonsterBase+t, x#, y#, z#
732
 
733
        fix object pivot idxMonsterBase+t
734
        gosub scorpChangeToWalk
735
        set object collision on idxMonsterBase+t
736
    NEXT
737
return
738
 
739
scorpChangeToIdle:
740
    rem TODO: smoothness (interpolation)
741
    if enemyCurrentAnim(t) <> 1
742
        loop object idxMonsterBase+t, animScorpIdleStart, animScorpIdleEnd
743
        enemyCurrentAnim(t) = 1
744
    endif
745
return
746
 
747
scorpChangeToWalk:
748
    rem TODO: smoothness (interpolation)
749
    if enemyCurrentAnim(t) <> 2
750
        loop object idxMonsterBase+t, animScorpWalkStart, animScorpWalkEnd
751
        enemyCurrentAnim(t) = 2
752
    endif
753
return
754
 
755
_setupClock:
756
    set text font "arial" : set text size 30 : set text transparent
757
 
758
    // Session variables
759
    clockTickCounter=0
760
    clockCurrentMidDot=0
761
    clockTicksPerSecond = framerate
762
return
763
 
764
_handleClock:
765
    if mod(clockTickCounter*clockBlinksPerSecond, clockTicksPerSecond) = 0
766
        clockCurrentMidDot = 1 - clockCurrentMidDot
767
    endif
768
 
769
    if mod(clockTickCounter*clockSpeedFactor, clockTicksPerSecond) = 0
770
        clockSeconds = clockSeconds + 1
771
    endif
772
 
773
    gosub _printClock
774
 
775
    clockTickCounter = clockTickCounter + 1
776
RETURN
777
 
778
_create_water:
779
    remstart
780
    make object plain 3, 20000, 20000
781
    load image "bitmap\GM01B02.bmp", 3
782
    texture object 3, 3
783
    position object 3, 0, waterLevel, 0
784
    xrotate object 3, 90
785
    set object light 3, 1
786
    ghost object on 3
787
    remend
788
 
789
 
790
    remstart
791
    make object plain 3, 10000, 10000
792
    load image "bitmap\GM01B02a.bmp",3
793
    texture object 3, 3
794
    xrotate object 3, 90
795
    position object 3, 5000,waterLevel, 5000
796
    set object ambient 3,0
797
    ghost object on 3
798
    remend
799
 
800
 
801
    remstart
802
    rem TODO: geht nicht zusammen mit fog
803
    make object plain 3, 10000, 10000
804
    load image "bitmap\GM01B02c.bmp", 3
805
    texture object 3, 3
806
    xrotate object 3, 90
807
    position object 3, 5000, waterLevel, 5000
808
    set object ambient 3, 0
809
    rem set object ambient 3, 1
810
    rem ghost object on 3
811
    remend
812
 
813
 
814
    make matrix 3, cMapSizeX+2*waterMovement, cMapSizeZ+2*waterMovement, 15, 15
815
    load image "bitmap\water.bmp", 3
816
    prepare matrix texture 3, 3, 1, 1
817
    fill matrix 3, 0, 1
818
    position matrix 3, 0, waterLevel, 0
819
    ghost matrix on 3
820
    set matrix 3, 0, 0, 1, 1, 1, 1, 1
821
    update matrix 3
822
return
823
 
824
_create_floor:
825
    rem Boden
826
    make matrix 1, cMapSizeX, cMapSizeZ, 15, 15
827
 
828
    load image "bitmap\forest_floor_texture.jpg", 1
829
    prepare matrix texture 1, 1, 1, 1
830
    fill matrix 1, 0, 1
831
    set matrix 1, 0, 0, 1, 1, 1, 1, 1
832
    randomize matrix 1, 130
833
 
834
    rem TEST
835
    rem TODO: aber man kann 40,40 nicht updaten?!
836
    set matrix height 1, 10, 10, 1000
837
 
838
    update matrix 1
839
 
840
    remstart
841
    currentmatrix=1
842
    for z=1 to 20
843
       for x=1 to 20
844
 
845
          rem Get matrix heights
846
          rem print x, " - ", z
847
          rem sync
848
          rem sleep 100
849
 
850
          h8#=get matrix height(currentmatrix,x,z-1)
851
          h4#=get matrix height(currentmatrix,x-1,z)
852
          h#=get matrix height(currentmatrix,x,z)
853
          h2#=get matrix height(currentmatrix,x,z)
854
 
855
          rem Calculate projected angle X using heights
856
          x1#=(x-1)*25.0 : y1#=h#
857
          x2#=(x+0)*25.0 : y2#=h4#
858
          dx#=x2#-x1#
859
          dy#=y2#-y1#
860
          ax#=atanfull(dx#,dy#)
861
          ax#=wrapvalue(90-ax#)
862
 
863
          rem Calculate projected angle Z using heights
864
          z1#=(z-1)*25.0 : y1#=h2#
865
          z2#=(z+0)*25.0 : y2#=h8#
866
          dz#=z2#-z1#
867
          dy#=y2#-y1#
868
          az#=atanfull(dz#,dy#)
869
          az#=wrapvalue(90-az#)
870
 
871
          rem Make normal from projected angle
872
          nx#=sin(ax#)
873
          ny#=cos(ax#)
874
          nz#=sin(az#)
875
 
876
          rem Setting matrix normal for smoothness
877
          set matrix normal currentmatrix,x,z,nx#,ny#,nz#
878
 
879
       next x
880
    next z
881
    update matrix currentmatrix
882
    remend
883
return
884
 
885
_create_sky:
886
    if test = 1 
887
        load image "bitmap\tree.bmp", 2
888
    else
889
       load image "bitmap\stars.bmp", 2
890
    endif
891
 
892
    make object sphere 2, (landsize * 2) - 500
893
 
894
rem    make object sphere 2, -4000
895
 
896
    set object collision off 2
897
    rem scale object 2, 2000, 750, 2000
898
    scale object 2, 600, 120, 600
899
    set object 2, 1, 0, 0, 0, 0, 1, 1
900
    texture object 2, 2
901
rem    fade object 2, 0
902
    backdrop off
903
 
904
    if test = 1
905
        backdrop on
906
        set object wireframe 2, 1
907
    endif
908
return
909
 
910
_create_radar:
911
    rem Karte - Abstand zur Kamera: 1.1
912
    remstart
913
    load image "map\ST01L01a.bmp", 5
914
    make object plain 51, 0.352, 0.352
915
    lock object on 51
916
    position object 51, -0.6908, -0.4675, 1.1
917
    ghost object on 51
918
    texture object 51, 5
919
    remend
920
 
921
    rem Karte - Abstand zur Kamera: 1.5
922
    load image "map\ST01L01a.bmp", 5
923
    make object plain 51, 0.48, 0.48
924
    lock object on 51
925
    position object 51, -0.942, -0.6375, 1.5
926
    ghost object on 51
927
    texture object 51, 5
928
return
929
 
930
_printClock:
931
    if clockCurrentMidDot = 0
932
        middle$ = " "
933
    else
934
        middle$ = ":"
935
    endif
936
    min = clockSeconds/60
937
    hours = min/60
938
    if clockShowSeconds
939
        secsText$ = middle$+TwoDigit$(mod(clockSeconds,60))
940
    else
941
        secsText$ = ""
942
    endif
943
    print "Time: ", TwoDigit$(mod(hours,24)), middle$, TwoDigit$(mod(min,60)), secsText$
944
return
945
 
946
rem Rotate smooth, and rotate in the direction with the lowest distance
947
rem "turn object left" ist das kommando
948
function smoothRotate#(von#, nach#, smoothness)
949
    if (von# > 270) and (nach# < 90)
950
        ret# = WrapValue(von# + (360 - von# + nach#)/smoothness)
951
    else
952
        if (von# < 90) and (nach# > 270)
953
            ret# = WrapValue(von# - (360 - nach# + von#)/smoothness)
954
        else
955
            ret# = von# + (nach# - von#)/smoothness
956
        endif
957
    endif
958
endfunction ret#
959
 
960
function floorHeight#(X#, Z#)
961
    rem TODO: implement water
962
    ret# = Get Ground Height(1, X#, Z#)
963
ENDFUNCTION ret#
964
 
965
function upPressed()
966
    ret = UpKey()=1 or keystate(17)=1 or joystick up()=1
967
ENDFUNCTION ret
968
 
969
function leftPressed()
970
    ret = LeftKey()=1 or keystate(30)=1 or joystick left()=1
971
ENDFUNCTION ret
972
 
973
function rightPressed()
974
    ret = RightKey()=1 or keystate(32)=1 or joystick right()=1
975
ENDFUNCTION ret
976
 
977
function downPressed()
978
    ret = DownKey()=1 or keystate(31)=1 or joystick down()=1
979
ENDFUNCTION ret
980
 
981
function TwoDigit$(value)
982
    if value < 10
983
        ret$ = "0"+STR$(value)
984
    else
985
        ret$ = STR$(value)
986
    ENDIF
987
ENDFUNCTION ret$
988
 
989
function mod(num,modulus)
990
   value=num-((num/modulus)*modulus)
991
endfunction value
992
 
993
function fileReadInt(fileNum)
994
    read string 1, s$
995
    ret=val(s$)
996
ENDFUNCTION ret
997
 
998
function RndBetween(a,b)
999
    ret = a+Rnd(b-a)
1000
ENDFUNCTION ret
1001
 
1002
function isInCircle(pX#,pY#,cX#,cY#,cR#)
1003
    ret = sqrt( (pX#-cX#)*(pX#-cX#) + (pY#-cY#)*(pY#-cY#) ) <= cR#
1004
ENDFUNCTION ret
1005
 
1006
_stop_game_sounds:
1007
    Stop Sound 1  : rem sound\forestbg.wav
1008
    Stop Sound 5  : rem music\pause.wav
1009
    Stop Sound 10 : rem sound\walk.wav
1010
    for t = 0 to cMaxEnemies
1011
        Stop Sound idxMonsterBase+t
1012
    next t
1013
return
1014
 
1015
_exit:
1016
    exit