lib/html: implement the tag list as an hashset instead of a array.
[nit.git] / contrib / tinks / src / game / players.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Player related and tank spawning logic
16 module players is serialize
17
18 import tanks
19
20 redef class TGame
21
22 # All the known players in the game
23 var players = new Array[Player]
24
25 redef fun do_turn
26 do
27 var turn = super
28 for player in players do
29 player.do_turn turn
30 end
31 return turn
32 end
33 end
34
35 redef class TTurn
36
37 # Range around the center of the world (0, 0) where a tank can spawn
38 var spawn_range = 256.0
39
40 # Spawn a new tank for `player`
41 fun spawn_tank(player: Player)
42 do
43 var pos = new Pos(spawn_range.rand, spawn_range.rand)
44 var tank = new Tank(game.story.tanks.rand, pos, 2.0*pi.rand)
45
46 if tank.next_move_collisions(self).not_empty then
47 # Clear the way
48 game.world.explode(self, pos, 3)
49 end
50
51 add new TankSpawnEvent(tank, player)
52 end
53 end
54
55 # A player in the game
56 class Player
57 super TTurnable
58
59 # Queue of orders to apply at the end of the turn
60 var orders = new Array[TOrder]
61
62 # The tank controlled by this player, if any
63 var tank: nullable Tank = null
64
65 # Index of the "unique" player stencil applied on all its tanks
66 var stencil_index: Int do
67 var counter = once new Ref[Int](0)
68 var val = counter.item
69 counter.item = (counter.item+1) % 4
70 return val
71 end
72
73 redef fun do_turn(turn)
74 do
75 # Apply orders if they are legal
76 for order in orders do
77 if order.is_legal(turn.game, self) then
78 order.apply turn
79 else print "Server Warning: Order {order} is now illegal"
80 end
81
82 orders.clear
83 end
84 end
85
86 redef class Tank
87 # The player controlling this tank, if any
88 var player: nullable Player = null
89 end
90
91 redef class TOrder
92
93 # Is this order (still) legal?
94 #
95 # This is executed client-side.
96 fun is_legal(game: TGame, issed_by: Player): Bool do return true
97 end
98
99 redef abstract class TankOrder
100 redef fun is_legal(game, issed_by) do return issed_by == tank.player
101 end
102
103 # A request to spawn a new tank
104 class SpawnTankOrder
105 super TOrder
106
107 # Requester
108 var player: Player
109
110 redef fun is_legal(turn, issed_by) do return issed_by == player and player.tank == null
111
112 redef fun apply(turn)
113 do
114 turn.spawn_tank player
115 end
116 end
117
118 # A new tank appeared
119 class TankSpawnEvent
120 super TEvent
121
122 # The new tank
123 var tank: Tank
124
125 # The `tank` owner
126 var player: nullable Player
127
128 redef fun apply(game)
129 do
130 var player = player
131 if player != null then player.tank = tank
132 tank.player = player
133 game.tanks.add tank
134 end
135 end
136
137 redef class TankDeathEvent
138
139 redef fun apply(game)
140 do
141 super
142
143 # `player` has no tank anymore
144 var player = tank.player
145 if player != null then
146 player.tank = null
147 end
148 end
149 end