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