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