make wheat an entity
This commit is contained in:
parent
3b2398ee8d
commit
0377fab55b
5 changed files with 58 additions and 49 deletions
|
|
@ -1,12 +1,13 @@
|
||||||
type _ t =
|
type _ t =
|
||||||
| Sheep : int -> [> `S ] t
|
| Sheep : int -> [> `S ] t
|
||||||
| Fairy : int -> [> `F ] t
|
| Fairy : int -> [> `F ] t
|
||||||
|
| Wheat : int -> [> `W ] t
|
||||||
|
|
||||||
(* todo move to State? *)
|
(* todo move to State? *)
|
||||||
type tbl =
|
type tbl =
|
||||||
{ mutable count : int
|
{ mutable count : int
|
||||||
; positions : ([ `S | `F ] t, Map.position) Hashtbl.t
|
; positions : ([ `S | `F | `W ] t, Map.position) Hashtbl.t
|
||||||
; positions' : (int * int, [ `S | `F ] t) Hashtbl.t
|
; positions' : (int * int, [ `S | `F | `W ] t) Hashtbl.t
|
||||||
; manas : ([ `F ] t, int) Hashtbl.t
|
; manas : ([ `F ] t, int) Hashtbl.t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -20,11 +21,13 @@ let init_tbl () =
|
||||||
let pp fmt tbl entity =
|
let pp fmt tbl entity =
|
||||||
let pos = Hashtbl.find tbl.positions entity in
|
let pos = Hashtbl.find tbl.positions entity in
|
||||||
match entity with
|
match entity with
|
||||||
|
| Wheat id -> Format.fprintf fmt "Wheat %d: %a" id Map.pp_position pos
|
||||||
| Sheep id -> Format.fprintf fmt "Sheep %d: %a" id Map.pp_position pos
|
| Sheep id -> Format.fprintf fmt "Sheep %d: %a" id Map.pp_position pos
|
||||||
| Fairy id as fairy ->
|
| Fairy id as fairy ->
|
||||||
let mana = Hashtbl.find tbl.manas fairy in
|
let mana = Hashtbl.find tbl.manas fairy in
|
||||||
Format.fprintf fmt "Fairy %d : mana = %d, %a" id mana Map.pp_position pos
|
Format.fprintf fmt "Fairy %d : mana = %d, %a" id mana Map.pp_position pos
|
||||||
|
|
||||||
|
(* todo refacto make_* , hange to spawn_* ? *)
|
||||||
let make_sheep tbl ~x ~y =
|
let make_sheep tbl ~x ~y =
|
||||||
let entity = Sheep tbl.count in
|
let entity = Sheep tbl.count in
|
||||||
tbl.count <- tbl.count + 1;
|
tbl.count <- tbl.count + 1;
|
||||||
|
|
@ -36,6 +39,17 @@ let make_sheep tbl ~x ~y =
|
||||||
Hashtbl.replace tbl.positions' (pos.x, pos.y) entity;
|
Hashtbl.replace tbl.positions' (pos.x, pos.y) entity;
|
||||||
entity
|
entity
|
||||||
|
|
||||||
|
let make_wheat tbl ~x ~y =
|
||||||
|
let entity = Wheat tbl.count in
|
||||||
|
tbl.count <- tbl.count + 1;
|
||||||
|
let pos =
|
||||||
|
Map.{ x; y; offset_x = 0.; offset_y = 0.; dir = Obj.magic (x * y mod 4) }
|
||||||
|
in
|
||||||
|
(* todo unsafe position could be taken already *)
|
||||||
|
Hashtbl.replace tbl.positions entity pos;
|
||||||
|
Hashtbl.replace tbl.positions' (pos.x, pos.y) entity;
|
||||||
|
entity
|
||||||
|
|
||||||
let make_fairy tbl ~x ~y =
|
let make_fairy tbl ~x ~y =
|
||||||
let entity = Fairy tbl.count in
|
let entity = Fairy tbl.count in
|
||||||
tbl.count <- tbl.count + 1;
|
tbl.count <- tbl.count + 1;
|
||||||
|
|
@ -85,4 +99,4 @@ let set_mana tbl id n = Hashtbl.replace tbl.manas id n
|
||||||
(* todo better name *)
|
(* todo better name *)
|
||||||
let get_entity tbl ~x ~y = Hashtbl.find_opt tbl.positions' (x, y)
|
let get_entity tbl ~x ~y = Hashtbl.find_opt tbl.positions' (x, y)
|
||||||
|
|
||||||
let id = function Sheep id | Fairy id -> id
|
let id = function Sheep id | Fairy id | Wheat id -> id
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,6 @@ let draw_canvas =
|
||||||
| Grass -> grass
|
| Grass -> grass
|
||||||
| Water -> water
|
| Water -> water
|
||||||
| Black -> water
|
| Black -> water
|
||||||
| Wheat -> wheat
|
|
||||||
in
|
in
|
||||||
C2d.draw_image context tile_img ~x:tile_x ~y:tile_y;
|
C2d.draw_image context tile_img ~x:tile_x ~y:tile_y;
|
||||||
begin
|
begin
|
||||||
|
|
@ -97,7 +96,10 @@ let draw_canvas =
|
||||||
| Some e ->
|
| Some e ->
|
||||||
if e <> player then
|
if e <> player then
|
||||||
let tile_img =
|
let tile_img =
|
||||||
match e with Sheep _ -> sheep | Fairy _ -> papy_up
|
match e with
|
||||||
|
| Sheep _ -> sheep
|
||||||
|
| Fairy _ -> papy_up
|
||||||
|
| Wheat _ -> wheat
|
||||||
in
|
in
|
||||||
C2d.draw_image context tile_img ~x:tile_x ~y:tile_y
|
C2d.draw_image context tile_img ~x:tile_x ~y:tile_y
|
||||||
end
|
end
|
||||||
|
|
@ -244,7 +246,7 @@ let rec game_loop state last_auto_update timestamp =
|
||||||
if should_auto_update then timestamp else last_auto_update
|
if should_auto_update then timestamp else last_auto_update
|
||||||
in
|
in
|
||||||
apply_last_key state;
|
apply_last_key state;
|
||||||
let state =
|
|
||||||
(* apply queue of actions *)
|
(* apply queue of actions *)
|
||||||
Queue.iter (State.perform_action state) to_apply_queue;
|
Queue.iter (State.perform_action state) to_apply_queue;
|
||||||
Queue.clear to_apply_queue;
|
Queue.clear to_apply_queue;
|
||||||
|
|
@ -252,8 +254,9 @@ let rec game_loop state last_auto_update timestamp =
|
||||||
Queue.iter (send_action state) input_queue;
|
Queue.iter (send_action state) input_queue;
|
||||||
Queue.clear input_queue;
|
Queue.clear input_queue;
|
||||||
(* state auto update *)
|
(* state auto update *)
|
||||||
if should_auto_update then State.auto_update state else state
|
begin
|
||||||
in
|
if should_auto_update then State.auto_update state
|
||||||
|
end;
|
||||||
G.request_animation_frame (game_loop state last_auto_update)
|
G.request_animation_frame (game_loop state last_auto_update)
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
|
|
|
||||||
22
src/map.ml
22
src/map.ml
|
|
@ -8,7 +8,6 @@ type background =
|
||||||
| Grass
|
| Grass
|
||||||
| Water
|
| Water
|
||||||
| Black
|
| Black
|
||||||
| Wheat
|
|
||||||
|
|
||||||
let pp_dir fmt dir =
|
let pp_dir fmt dir =
|
||||||
let s =
|
let s =
|
||||||
|
|
@ -22,11 +21,7 @@ let pp_dir fmt dir =
|
||||||
|
|
||||||
let pp_background fmt b =
|
let pp_background fmt b =
|
||||||
let s =
|
let s =
|
||||||
match b with
|
match b with Grass -> "Grass" | Water -> "Water" | Black -> "Black"
|
||||||
| Grass -> "Grass"
|
|
||||||
| Water -> "Water"
|
|
||||||
| Black -> "Black"
|
|
||||||
| Wheat -> "Wheat"
|
|
||||||
in
|
in
|
||||||
Format.pp_print_string fmt s
|
Format.pp_print_string fmt s
|
||||||
|
|
||||||
|
|
@ -52,19 +47,6 @@ type t =
|
||||||
let get_tile_kind ~x ~y map =
|
let get_tile_kind ~x ~y map =
|
||||||
try map.tiles.(x).(y) with Invalid_argument _ -> Black
|
try map.tiles.(x).(y) with Invalid_argument _ -> Black
|
||||||
|
|
||||||
let count_wheat map =
|
|
||||||
Array.fold_left
|
|
||||||
(fun count a ->
|
|
||||||
let count' =
|
|
||||||
Array.fold_left
|
|
||||||
(fun count -> function
|
|
||||||
| Wheat -> succ count
|
|
||||||
| Black | Grass | Water -> count )
|
|
||||||
0 a
|
|
||||||
in
|
|
||||||
count + count' )
|
|
||||||
0 map
|
|
||||||
|
|
||||||
let check_move map ({ x; y; _ } as pos) movement_dir =
|
let check_move map ({ x; y; _ } as pos) movement_dir =
|
||||||
let x, y =
|
let x, y =
|
||||||
match movement_dir with
|
match movement_dir with
|
||||||
|
|
@ -76,7 +58,7 @@ let check_move map ({ x; y; _ } as pos) movement_dir =
|
||||||
match get_tile_kind ~x ~y map with
|
match get_tile_kind ~x ~y map with
|
||||||
| (Black | Water) as bg ->
|
| (Black | Water) as bg ->
|
||||||
Error (Format.asprintf "can't move on %a" pp_background bg)
|
Error (Format.asprintf "can't move on %a" pp_background bg)
|
||||||
| Grass | Wheat -> Ok { pos with x; y }
|
| Grass -> Ok { pos with x; y }
|
||||||
|
|
||||||
let n = 50
|
let n = 50
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@ let update_offline_user_state () =
|
||||||
|
|
||||||
let update_online_user_state () =
|
let update_online_user_state () =
|
||||||
Hashtbl.filter_map_inplace
|
Hashtbl.filter_map_inplace
|
||||||
(fun _user_id state -> Some (Shared.State.auto_update state))
|
(fun _user_id state ->
|
||||||
|
Shared.State.auto_update state;
|
||||||
|
Some state )
|
||||||
User.state_ht
|
User.state_ht
|
||||||
|
|
||||||
let to_repeat () =
|
let to_repeat () =
|
||||||
|
|
|
||||||
30
src/state.ml
30
src/state.ml
|
|
@ -39,7 +39,7 @@ end
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
{ map : Map.t
|
{ map : Map.t
|
||||||
; wheat : int
|
; mutable wheat : int
|
||||||
; player : [ `F ] Entity.t
|
; player : [ `F ] Entity.t
|
||||||
; tbl : Entity.tbl
|
; tbl : Entity.tbl
|
||||||
}
|
}
|
||||||
|
|
@ -58,16 +58,16 @@ let init () =
|
||||||
type action =
|
type action =
|
||||||
| Meditate
|
| Meditate
|
||||||
(* TODO some action do not needs to be checked by server *)
|
(* TODO some action do not needs to be checked by server *)
|
||||||
| Move_offset of ([ `S | `F ] Entity.t * Map.dir)
|
| Move_offset of ([ `S | `F | `W ] Entity.t * Map.dir)
|
||||||
| Move of ([ `S | `F ] Entity.t * Map.dir)
|
| Move of ([ `S | `F | `W ] Entity.t * Map.dir)
|
||||||
| Plant_wheat
|
| Plant_wheat
|
||||||
(* TODO: we don't need dir so we should change the type of Map.position *)
|
(* TODO: we don't need dir so we should change the type of Map.position *)
|
||||||
|
|
||||||
(* type for result of action send to the client by the server *)
|
(* type for result of action send to the client by the server *)
|
||||||
type action' =
|
type action' =
|
||||||
| Add_mana of ([ `F ] Entity.t * int)
|
| Add_mana of ([ `F ] Entity.t * int)
|
||||||
| Set_position of ([ `S | `F ] Entity.t * Map.position)
|
| Set_position of ([ `S | `F | `W ] Entity.t * Map.position)
|
||||||
| Set_offset of ([ `S | `F ] Entity.t * (float * float))
|
| Set_offset of ([ `S | `F | `W ] Entity.t * (float * float))
|
||||||
| Spawn_wheat of int * int
|
| Spawn_wheat of int * int
|
||||||
|
|
||||||
let pp_action fmt = function
|
let pp_action fmt = function
|
||||||
|
|
@ -128,11 +128,17 @@ let rec check_action state = function
|
||||||
match Map.get_tile_kind ~x ~y state.map with
|
match Map.get_tile_kind ~x ~y state.map with
|
||||||
| Map.Black -> Error "can't plant wheat in space !"
|
| Map.Black -> Error "can't plant wheat in space !"
|
||||||
| Water -> Error "can't plant wheat in water !"
|
| Water -> Error "can't plant wheat in water !"
|
||||||
| Wheat -> Error "there's already some wheat there !"
|
| Grass -> (
|
||||||
| Grass ->
|
match Entity.get_entity state.tbl ~x ~y with
|
||||||
|
| Some other_entity ->
|
||||||
|
let pp fmt = Entity.pp fmt state.tbl in
|
||||||
|
Error
|
||||||
|
(Format.asprintf "there's already another entity (%a) there !" pp
|
||||||
|
other_entity )
|
||||||
|
| None ->
|
||||||
if Entity.get_mana state.tbl state.player >= plant_wheat_cost then
|
if Entity.get_mana state.tbl state.player >= plant_wheat_cost then
|
||||||
Ok [ Spawn_wheat (x, y); Add_mana (state.player, -plant_wheat_cost) ]
|
Ok [ Spawn_wheat (x, y); Add_mana (state.player, -plant_wheat_cost) ]
|
||||||
else Error "not enough mana..." )
|
else Error "not enough mana..." ) )
|
||||||
|
|
||||||
(* TODO imutable state? *)
|
(* TODO imutable state? *)
|
||||||
let perform_action state = function
|
let perform_action state = function
|
||||||
|
|
@ -141,7 +147,10 @@ let perform_action state = function
|
||||||
Entity.set_mana state.tbl e (old_mana + n)
|
Entity.set_mana state.tbl e (old_mana + n)
|
||||||
| Set_position (e, pos) -> Entity.set_pos state.tbl e pos
|
| Set_position (e, pos) -> Entity.set_pos state.tbl e pos
|
||||||
| Set_offset (e, offset) -> Entity.set_offset state.tbl e offset
|
| Set_offset (e, offset) -> Entity.set_offset state.tbl e offset
|
||||||
| Spawn_wheat (x, y) -> state.map.tiles.(x).(y) <- Map.Wheat
|
| Spawn_wheat (x, y) ->
|
||||||
|
state.wheat <- state.wheat + 1;
|
||||||
|
let _w : [> `W ] Entity.t = Entity.make_wheat state.tbl ~x ~y in
|
||||||
|
()
|
||||||
|
|
||||||
let auto_update state =
|
let auto_update state =
|
||||||
(* mut state *)
|
(* mut state *)
|
||||||
|
|
@ -150,9 +159,8 @@ let auto_update state =
|
||||||
| Error _e -> ()
|
| Error _e -> ()
|
||||||
| Ok actions -> List.iter (perform_action state) actions
|
| Ok actions -> List.iter (perform_action state) actions
|
||||||
end;
|
end;
|
||||||
let count_wheat = Map.count_wheat state.map.tiles in
|
|
||||||
(* TODO simulate animals *)
|
(* TODO simulate animals *)
|
||||||
{ state with wheat = state.wheat + count_wheat }
|
()
|
||||||
|
|
||||||
let auto_update_rate = Time.mk_s 1
|
let auto_update_rate = Time.mk_s 1
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue