diff --git a/a.out b/a.out index db56a44..2bfb208 100755 Binary files a/a.out and b/a.out differ diff --git a/display.cmi b/display.cmi index 75d0e68..697bffd 100644 Binary files a/display.cmi and b/display.cmi differ diff --git a/display.cmx b/display.cmx index 13c3323..7a6d97a 100644 Binary files a/display.cmx and b/display.cmx differ diff --git a/display.ml b/display.ml index a955a6b..1dcb1bd 100644 --- a/display.ml +++ b/display.ml @@ -21,9 +21,19 @@ let cube_size = 3 ;; let chunk_size = 6 ;; let chunk_size_f = float_of_int chunk_size ;; +(* between 0 (empty) and 100 (full) *) let density = 50 ;; -let speed_multiplier = 1.5 ;; +let speed_multiplier = 0.15 ;; + +(* money money money *) +let coins = ref 0 ;; + +(* player has a cube hitbox with 2*this_value as length *) +let collison_leniency = (float_of_int cube_size) /. 10. ;; + +(* hitbox for coins *) +let coin_magnet_dist = 1. ;; (* -------------------------------------------------------------------------------------------------------- *) @@ -33,7 +43,13 @@ let structure_1_frequency = 2000 ;; (* -------------------------------------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------------------------------------- *) -(* -------------------------------------------------------------------------------------------------------- *) + +type 'a dynamic = {mutable tab : 'a array ; mutable len : int ; mutable memlen : int} ;; + +type pt_3d = {mutable x : float ; mutable y : float ; mutable z : float} ;; +type pt_2d = {mutable x : float ; mutable y : float} ;; + +type coloredCube = {flag : string ; cube : pt_3d array ; red : int ; green : int ; blue : int} ;; (* @@ -143,16 +159,6 @@ let parse_texture filename = let stone = parse_texture "output.txt" ;; -(* ------------------------------------------------------------- *) -(* ------------------------------------------------------------- *) - -type 'a dynamic = {mutable tab : 'a array ; mutable len : int ; mutable memlen : int} ;; - -type pt_3d = {mutable x : float ; mutable y : float ; mutable z : float} ;; -type pt_2d = {mutable x : float ; mutable y : float} ;; - -type coloredCube = {cube : pt_3d array ; red : int ; green : int ; blue : int} ;; - let dyn_create i = {tab = Array.make 25 i ; len = 0 ; memlen = 25} ;; @@ -171,6 +177,23 @@ let dyn_append arr elt = arr.tab.(arr.len) <- elt; arr.len <- arr.len + 1 ;; +let indent arr i alen = + (* elt in place i is deleted *) + (* elt in place alen-1 is duped *) + for j = i to alen -2 do + arr.(j) <- arr.(j+1) + done ;; + +let dyn_remove arr elt = + let found = ref false in + for i = 0 to arr.len -1 do + if not !found && arr.tab.(i) = elt then begin + found := true; + indent arr.tab i arr.len; + arr.len <- arr.len -1 + end + done ;; + (* ------------------------------------------------------------- *) (* ------------------------------------------------------------- *) @@ -742,13 +765,54 @@ done ;; let n_walls = ref (width*height*depth) ;; +let is_string_integer str = + try + for i = 0 to String.length str -1 do + let n = Char.code str.[i] in + if (n <> 0) && (n < 48 || n > 57) then + raise (ReturnBool false) + done; + true + with + | ReturnBool b -> b ;; + +let str_to_int str = + let res = ref 0 in + for i = 0 to String.length str -1 do + let n = Char.code str.[i] in + if n <> 0 then begin + res := !res * 10; + res := !res + n - 48 + end + done; + !res ;; + let is_collision_cube (cam_coords : pt_3d) (cube : pt_3d array) = - cube.(0).x <= (-. cam_coords.x) && - cube.(0).y <= (-. cam_coords.y) && - cube.(0).z <= cam_coords.z && - cube.(6).x >= (-. cam_coords.x) && - cube.(6).y >= (-. cam_coords.y) && - cube.(6).z >= cam_coords.z ;; + cube.(0).x -. collison_leniency <= (-. cam_coords.x) && + cube.(0).y -. collison_leniency <= (-. cam_coords.y) && + cube.(0).z -. collison_leniency <= cam_coords.z && + cube.(6).x +. collison_leniency >= (-. cam_coords.x) && + cube.(6).y +. collison_leniency >= (-. cam_coords.y) && + cube.(6).z +. collison_leniency >= cam_coords.z ;; + +let is_collision_coin (cam_coords : pt_3d) (cube : pt_3d array) = + cube.(0).x -. coin_magnet_dist <= (-. cam_coords.x) && + cube.(0).y -. coin_magnet_dist <= (-. cam_coords.y) && + cube.(0).z -. coin_magnet_dist <= cam_coords.z && + cube.(6).x +. coin_magnet_dist >= (-. cam_coords.x) && + cube.(6).y +. coin_magnet_dist >= (-. cam_coords.y) && + cube.(6).z +. coin_magnet_dist >= cam_coords.z ;; + +let is_collision_cube_bis (cam_coords : pt_3d) (cuube : coloredCube) = + if is_string_integer cuube.flag then + false + else + cuube.cube.(0).x -. collison_leniency <= (-. cam_coords.x) && + cuube.cube.(0).y -. collison_leniency <= (-. cam_coords.y) && + cuube.cube.(0).z -. collison_leniency <= cam_coords.z && + cuube.cube.(6).x +. collison_leniency >= (-. cam_coords.x) && + cuube.cube.(6).y +. collison_leniency >= (-. cam_coords.y) && + cuube.cube.(6).z +. collison_leniency >= cam_coords.z ;; let is_collision (cam_coords : pt_3d) (cubes : pt_3d array array) = let res = ref false in @@ -778,10 +842,18 @@ let is_collision_hash (cam_coords : pt_3d) (cubes : coloredCube dynamic) = for i = 0 to n-1 do if not !res && distances.(i) < 2. then - res := is_collision_cube cam_coords cubes.tab.(i).cube + (*res := is_collision_cube cam_coords cubes.tab.(i).cube*) + res := is_collision_cube_bis cam_coords cubes.tab.(i) done; !res ;; +let rec indent_list (arr : 'a dynamic) lst = match lst with + | [] -> () + | h::t -> + indent arr.tab h arr.len; + arr.len <- arr.len -1; + indent_list arr t ;; + let is_collision_hash_2 (cam_coords : pt_3d) (rcubes : (coloredCube dynamic) option) = match rcubes with | None -> false | Some cubes -> begin @@ -794,10 +866,27 @@ let is_collision_hash_2 (cam_coords : pt_3d) (rcubes : (coloredCube dynamic) opt distances.(i) <- cube_dist cubes.tab.(i).cube; done ; + let to_be_removed = ref [] in + let rem_len = ref 0 in + for i = 0 to n-1 do - if not !res && distances.(i) < 6. then - res := is_collision_cube cam_coords cubes.tab.(i).cube + if is_string_integer cubes.tab.(i).flag then begin + if is_collision_coin cam_coords cubes.tab.(i).cube then begin + let valc = str_to_int cubes.tab.(i).flag in + coins := !coins + valc; + to_be_removed := (i - !rem_len)::(!to_be_removed); + incr rem_len; + (*Printf.printf "%d" valc; + Stdlib.print_endline " "*) + end + end + else if not !res && distances.(i) < chunk_size_f then + (*res := is_collision_cube cam_coords cubes.tab.(i).cube*) + res := is_collision_cube_bis cam_coords cubes.tab.(i) done; + + indent_list cubes !to_be_removed; + !res end ;; @@ -842,8 +931,8 @@ let chunkify_2 laby sz = (*Printf.printf "created cube (%d, %d, %d) (%d)\n" (w*sz) (h*sz) (d*sz) sz; Printf.printf "in chunk (%d, %d, %d)\n" cw ch cd; Stdlib.print_endline " ";*) - let dyna = dyn_create {cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = r; green = g; blue = b} in - dyn_append dyna {cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = r; green = g; blue = b}; + let dyna = dyn_create {flag = "terrain" ; cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = r; green = g; blue = b} in + dyn_append dyna {flag = "terrain" ; cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = r; green = g; blue = b}; Hashtbl.add cubes (cw, ch, cd) dyna end | Some dyna -> begin @@ -851,7 +940,7 @@ let chunkify_2 laby sz = Printf.printf "in chunk (%d, %d, %d)\n" cw ch cd; Stdlib.print_endline " ";*) Hashtbl.remove cubes (cw, ch, cd); - dyn_append dyna {cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = r; green = g; blue = b}; + dyn_append dyna {flag = "terrain" ; cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = r; green = g; blue = b}; Hashtbl.add cubes (cw, ch, cd) dyna end in @@ -913,7 +1002,7 @@ let rec move_cam_hash_2 hash cx cy cz b c =(* Printf.printf "[%b]" b; Stdlib.pri (is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy-1,cz))) || (is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) || (is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1))) - ) then move_cam_hash_2 hash cx cy cz false 'q' + ) then move_cam_hash_2 hash cx cy cz false 'd' | 's' -> camera_xyz.z <- camera_xyz.z -. speed_multiplier *. Float.cos ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); camera_xyz.x <- camera_xyz.x -. speed_multiplier *. Float.sin ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); @@ -960,18 +1049,18 @@ let rec move_cam_hash_2 hash cx cy cz b c =(* Printf.printf "[%b]" b; Stdlib.pri (is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) || (is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1))) ) then move_cam_hash_2 hash cx cy cz false 'p' - | 'a' -> camera_angle_y := !camera_angle_y + 30 - | 'e' -> camera_angle_y := !camera_angle_y - 30 + | 'a' -> camera_angle_y := !camera_angle_y + 1 + | 'e' -> camera_angle_y := !camera_angle_y - 1 | _ -> () ;; let init_chunk_all hash mem ch_x ch_y ch_z = let n_cubes = chunk_size / 3 in - let dyna = dyn_create {cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in + let dyna = dyn_create {flag = "terrain" ; cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in for i = 0 to n_cubes -1 do for j = 0 to n_cubes -1 do for k = 0 to n_cubes -1 do if (Random.int 101) < density then - dyn_append dyna {cube = create_cube (chunk_size*ch_x + cube_size*i) (chunk_size*ch_y + cube_size*j) (chunk_size*ch_z + cube_size*k) cube_size; red = 250; green = 250; blue = 250} + dyn_append dyna {flag = "terrain" ; cube = create_cube (chunk_size*ch_x + cube_size*i) (chunk_size*ch_y + cube_size*j) (chunk_size*ch_z + cube_size*k) cube_size; red = 250; green = 250; blue = 250} done done done; @@ -979,8 +1068,8 @@ let init_chunk_all hash mem ch_x ch_y ch_z = Hashtbl.add hash (ch_x, ch_y, ch_z) dyna ;; let init_full_all hash mem ch_x ch_y ch_z = - let dyna = dyn_create {cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in - dyn_append dyna {cube = create_cube (chunk_size*ch_x) (chunk_size*ch_y) (chunk_size*ch_z) chunk_size; red = 250; green = 32; blue = 32}; + let dyna = dyn_create {flag = "bedrock" ; cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in + dyn_append dyna {flag = "bedrock" ; cube = create_cube (chunk_size*ch_x) (chunk_size*ch_y) (chunk_size*ch_z) chunk_size; red = 250; green = 32; blue = 32}; Hashtbl.add mem (ch_x, ch_y, ch_z) 1; Hashtbl.add hash (ch_x, ch_y, ch_z) dyna ;; @@ -1036,23 +1125,23 @@ let generate_structure_1 hash mem ch_x ch_y ch_z = (* par invariant global, Hashtbl.find_opt hash (chx, chy, chz) = None *) - let empty = dyn_create {cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in + let empty = dyn_create {flag = "struct_1" ; cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in (*dyn_append dyna {cube = create_cube (chunk_size*chx) (chunk_size*chy) (chunk_size*chz) chunk_size; red = 250; green = 32; blue = 32};*) for w = -2 to 2 do for h = -2 to 2 do for d = -2 to 2 do if abs w = 2 || (abs h = 2 && w*d <> 0) || abs d = 2 then begin - let filled = dyn_create {cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in - dyn_append filled {cube = create_cube ((chx+w)*chunk_size) ((chy+h)*chunk_size) ((chz+d)*chunk_size) chunk_size; red = 250; green = 128; blue = 64}; + let filled = dyn_create {flag = "struct_1" ; cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in + dyn_append filled {flag = "struct_1" ; cube = create_cube ((chx+w)*chunk_size) ((chy+h)*chunk_size) ((chz+d)*chunk_size) chunk_size; red = 250; green = 128; blue = 64}; Hashtbl.add hash (chx+w, chy+h, chz+d) filled; end else if w = 0 && h = 0 && d = 0 then begin - let filled = dyn_create {cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in + let filled = dyn_create {flag = "10" ; cube = create_cube 0 0 0 1; red = 33; green = 33; blue = 22} in for i = 0 to chunk_size -1 do for j = 0 to chunk_size -1 do for k = 0 to chunk_size -1 do - dyn_append filled {cube = create_cube (chx*chunk_size+i) (chy*chunk_size+j) (chz*chunk_size+k) 1; red = 250; green = 250; blue = 64}; + dyn_append filled {flag = "10" ; cube = create_cube (chx*chunk_size+i) (chy*chunk_size+j) (chz*chunk_size+k) 1; red = 250; green = 250; blue = 64}; done done done; @@ -1068,9 +1157,9 @@ let generate_structure_1 hash mem ch_x ch_y ch_z = (*Hashtbl.add mem (chx, chy, chz) 2; Hashtbl.add hash (chx, chy, chz) dyna;*) - Printf.printf "Added S1 at (%d, %d, %d)\n" (chx*chunk_size) (chy*chunk_size) (chz*chunk_size); + (*Printf.printf "Added S1 at (%d, %d, %d)\n" (chx*chunk_size) (chy*chunk_size) (chz*chunk_size); Printf.printf "----------- (%d, %d, %d)" chx chy chz; - Stdlib.print_endline " " + Stdlib.print_endline " "*) in for w = -(chunk_dist+3) to (chunk_dist+3) do for h = -(chunk_dist+3) to (chunk_dist+3) do @@ -1149,7 +1238,7 @@ let play_dos laby = let hash = Hashtbl.create 100 in let memory = Hashtbl.create 100 in - let dyna = dyn_create {cube = create_cube 0 0 0 1 ; red = 30 ; green = 30 ; blue = 30} in + let dyna = dyn_create {flag = "spawn" ; cube = create_cube 0 0 0 1 ; red = 30 ; green = 30 ; blue = 30} in Hashtbl.add hash (0, 0, 0) dyna ; Hashtbl.add memory (0, 0, 0) 1; (* @@ -1172,7 +1261,7 @@ let play_dos laby = camera_xyz.z <- 2. ; while true do - if !redraw then begin + if !redraw then begin (* update the display *) auto_synchronize false; open_graph " 1500x1000"; set_color black; @@ -1189,13 +1278,18 @@ let play_dos laby = draw_integer_alignedleft 10 (__height__ - 90) (-int_of_float camera_xyz.y) 25; draw_integer_alignedleft 10 (__height__ - 150) (int_of_float camera_xyz.z) 25; + set_color (rgb 250 250 32); + draw_integer_alignedleft 10 35 !coins 25; + auto_synchronize true; end; redraw := false; let usr_input = get1char_plus () in if usr_input <> '@' then begin - move_cam_hash_2 hash !ch_x !ch_y !ch_z true usr_input; + for i = 0 to 9 do + move_cam_hash_2 hash !ch_x !ch_y !ch_z true usr_input + done; redraw := true end done ; diff --git a/display.o b/display.o index fbd4f2e..043873c 100644 Binary files a/display.o and b/display.o differ diff --git a/flag_list.txt b/flag_list.txt new file mode 100644 index 0000000..000412e --- /dev/null +++ b/flag_list.txt @@ -0,0 +1,7 @@ +----| List of all possible flags for cubes |--- + +"bedrock" : at the top/bottom of the map ; solid, orange wall to prevent player from going too far +"" : coin with its value +"spawn" : spawn chunk ; always has to be empty for the player to spawn +"struct_N" : solid block for structure N +"terrain" : regular terrain piece, usually white/gray \ No newline at end of file