2c7cd5b5845f28e65c5030871c45cbcae65e82b4
[nit.git] / contrib / tinks / src / game / powerups.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 # Support for pickable powerups (only health for now)
16 module powerups is serialize
17
18 import tanks
19
20 # A powerup item
21 class Powerup
22 super Feature
23 redef type R: PowerupRule
24 end
25
26 # Metadata of a powerup item
27 class PowerupRule
28 super FeatureRule
29
30 # Restore all health when picked up
31 var restore_health: Bool
32 end
33
34 redef class Story
35 # A powerup that restores all health
36 var health = new PowerupRule(self, 2, true)
37
38 # All `PowerupRule` in this story
39 var powerups: Array[PowerupRule] = [health]
40 end
41
42 redef class Tank
43
44 redef fun destroy(turn)
45 do
46 super
47
48 # Put a random powerup at the center of the old tank
49 var pos = new Pos(pos.x.floor+0.5, pos.y.floor+0.5)
50 var powerup = new Powerup(turn.game.story.powerups.rand, pos)
51 turn.add new FeatureChangeEvent(powerup, pos)
52
53 # Add some debris around it
54 var forward = new Pos((pos.x+heading.cos*1.1).floor+0.5, (pos.y+heading.sin*1.1).floor+0.5)
55 var backward = new Pos((pos.x-heading.cos*1.1).floor+0.5, (pos.y-heading.sin*1.1).floor+0.5)
56 turn.add new FeatureChangeEvent(new Feature(turn.game.story.debris, forward), forward)
57 turn.add new FeatureChangeEvent(new Feature(turn.game.story.debris, backward), backward)
58 end
59
60 # Intercept collision detection of "absorb" powerups
61 #
62 # This is a wee bit hackish.
63 # The collision detection on tank move can return a max of 4 items (1 per side).
64 # If there is powerups, they may have hidden other features.
65 # This could cause the tank to move over a feature and get stuck.
66 # This is not a big problem as the tank can open fire to liberate itself,
67 # or even simply go back as the speed is static.
68 redef fun next_move_collisions(turn)
69 do
70 var collisions = super
71 if collisions.is_empty then return collisions
72
73 for coll in collisions do if not coll isa Powerup then
74 # An unavoidable collision
75 return collisions
76 end
77
78 # Only powerups! absorb them
79 for powerup in collisions do
80 if powerup isa Powerup then
81 turn.add new FeatureChangeEvent(null, powerup.pos)
82
83 if powerup.rule.restore_health then
84 turn.add new TankHealthChange(self, rule.max_health)
85 end
86 end
87 end
88
89 return new HashSet[Feature]
90 end
91 end