Skip to content

Commit c3c346a

Browse files
MatusGuyrustyboxVankata453
authored
Item Pocket (#3070)
Original description by MatusGuy: The Item Pocket allows you to save a powerup for later use. If you collect a flower while having a bonus greater than GROWUP_BONUS, that flower gets equipped and the old flower gets stored in the top left corner of the screen. Now, the player can press the new ITEM control (usually Select/Back or Left Shift) to use the stored flower by throwing it up and catching it. This pull request replaces the powerup stacking feature because this new solution is much more balanced. It also limits the amount of concurrent players to 4. * aeiou * add item pocket input * item pocket workie * item pocket hud * lifesaver texture Co-authored-by: [email protected] * item pocket bare minimum * god fujjgking damngit * THINGS * pepsi pocket Co-authored-by: RustyBox <[email protected]> * this is for the good of the item economy * more bugs fickesed * powerup stacking is gone * editor * fix ci * setting wip * item pocket setting complete * agjhag * tdjyfjgfjgf * bitch * the anticheat mechanism * omfg * wip [ci skip] * wip again [ci skip] * script * augh squirrel thing * Apply suggestions from code review Co-authored-by: Vankata453 <[email protected]> * Fix being unable to spawn player [ci skip] * Remove code duplication in `MultiplayerPlayerMenu`, do not remove players from status [ci skip] * Fix scripting documentation consistency with function * wip script item pocket * chagne docs * fix duo player bug weird strange weird * Scripting docs: Full stops [ci skip] * Fix `BonusType` enum descriptions for scripting documentation [ci skip] --------- Co-authored-by: MatusGuy <[email protected]> Co-authored-by: RustyBox <[email protected]> Co-authored-by: Vankata453 <[email protected]>
1 parent 72684dc commit c3c346a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+782
-537
lines changed
30.7 KB
Loading

src/badguy/badguy.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ HitResponse
617617
BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
618618
{
619619
if (is_frozen()) {
620-
if (bullet.get_type() == FIRE_BONUS) {
620+
if (bullet.get_type() == BONUS_FIRE) {
621621
// Fire bullet thaws frozen badguys.
622622
unfreeze();
623623
bullet.remove_me();
@@ -629,7 +629,7 @@ BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
629629
}
630630
}
631631
else if (is_ignited()) {
632-
if (bullet.get_type() == ICE_BONUS) {
632+
if (bullet.get_type() == BONUS_ICE) {
633633
// Ice bullets extinguish ignited badguys.
634634
extinguish();
635635
bullet.remove_me();
@@ -640,13 +640,13 @@ BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
640640
return FORCE_MOVE;
641641
}
642642
}
643-
else if (bullet.get_type() == FIRE_BONUS && is_flammable()) {
643+
else if (bullet.get_type() == BONUS_FIRE && is_flammable()) {
644644
// Fire bullets ignite flammable badguys.
645645
ignite();
646646
bullet.remove_me();
647647
return ABORT_MOVE;
648648
}
649-
else if (bullet.get_type() == ICE_BONUS && is_freezable()) {
649+
else if (bullet.get_type() == BONUS_ICE && is_freezable()) {
650650
// Ice bullets freeze freezable badguys.
651651
freeze();
652652
bullet.remove_me();

src/badguy/boss.cpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,19 @@ namespace
3131
Boss::Boss(const ReaderMapping& reader, const std::string& sprite_name, int layer) :
3232
BadGuy(reader, sprite_name, layer),
3333
m_lives(),
34+
m_max_lives(),
3435
m_pinch_lives(),
3536
m_hud_head(),
3637
m_hud_icon(),
3738
m_pinch_mode(),
3839
m_pinch_activation_script()
3940
{
4041
reader.get("lives", m_lives, DEFAULT_LIVES);
41-
reader.get("pinch-lives", m_pinch_lives, DEFAULT_PINCH_LIVES);
42+
m_max_lives = m_lives;
43+
4244
m_countMe = true;
4345

46+
reader.get("pinch-lives", m_pinch_lives, DEFAULT_PINCH_LIVES);
4447
reader.get("pinch-activation-script", m_pinch_activation_script, "");
4548
}
4649

@@ -70,9 +73,13 @@ Boss::draw_hit_points(DrawingContext& context)
7073
context.set_translation(Vector(0, 0));
7174
context.transform().scale = 1.f;
7275

76+
float startpos = (context.get_width() - static_cast<float>((m_hud_head->get_width() * m_max_lives))) / 2;
7377
for (int i = 0; i < m_lives; ++i)
7478
{
75-
context.color().draw_surface(m_hud_head, Vector(BORDER_X + (static_cast<float>(i * m_hud_head->get_width())), BORDER_Y + 1), LAYER_HUD);
79+
context.color().draw_surface(m_hud_head,
80+
Vector(BORDER_X + (startpos + static_cast<float>(i * m_hud_head->get_width())),
81+
BORDER_Y + 1),
82+
LAYER_HUD);
7683
}
7784

7885
context.pop_transform();
@@ -86,15 +93,15 @@ Boss::get_settings()
8693

8794
result.add_text("hud-icon", &m_hud_icon, "hud-icon", "images/creatures/yeti/hudlife.png", OPTION_HIDDEN);
8895
result.add_int(_("Lives"), &m_lives, "lives", DEFAULT_LIVES);
89-
90-
/* l10n: Pinch Mode refers to a particular boss mode that gets
91-
activated once the boss has lost the specified amounts of lives.
96+
97+
/* l10n: Pinch Mode refers to a particular boss mode that gets
98+
activated once the boss has lost the specified amounts of lives.
9299
This setting specifies how many lives need to be spent until pinch
93100
mode is activated. */
94101
result.add_int(_("Lives to Pinch Mode"), &m_pinch_lives, "pinch-lives", DEFAULT_PINCH_LIVES);
95102

96-
/* l10n: Pinch Mode refers to a particular boss mode that gets
97-
activated once the boss has lost the specified amounts of lives.
103+
/* l10n: Pinch Mode refers to a particular boss mode that gets
104+
activated once the boss has lost the specified amounts of lives.
98105
This setting specifies the squirrel script that gets run to activate boss mode. */
99106
result.add_script(_("Pinch Mode Activation Script"), &m_pinch_activation_script, "pinch-activation-script");
100107

src/badguy/boss.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Boss : public BadGuy
3737

3838
protected:
3939
int m_lives;
40+
int m_max_lives;
4041
int m_pinch_lives;
4142
SurfacePtr m_hud_head;
4243
std::string m_hud_icon;

src/badguy/snowman.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Snowman::loose_head()
5454
HitResponse
5555
Snowman::collision_bullet(Bullet& bullet, const CollisionHit& hit)
5656
{
57-
if (bullet.get_type() == FIRE_BONUS) {
57+
if (bullet.get_type() == BONUS_FIRE) {
5858
// Fire bullets destroy snowman's body.
5959
Vector snowball_pos = get_pos();
6060
// Hard-coded values from sprites.

src/badguy/stalactite.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Stalactite::collision_bullet(Bullet& bullet, const CollisionHit& hit)
147147
timer.start(SHAKE_TIME);
148148
state = STALACTITE_SHAKING;
149149
bullet.remove_me();
150-
if (bullet.get_type() == FIRE_BONUS)
150+
if (bullet.get_type() == BONUS_FIRE)
151151
SoundManager::current()->play("sounds/sizzle.ogg", get_pos());
152152
SoundManager::current()->play("sounds/cracking.wav", get_pos());
153153
}

src/control/controller.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const char* g_control_names[] = {
2727
"down",
2828
"jump",
2929
"action",
30+
"item",
3031
"start",
3132
"escape",
3233
"menu-select",

src/control/controller.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum class Control {
2929

3030
JUMP,
3131
ACTION,
32+
ITEM,
3233

3334
START,
3435
ESCAPE,

src/control/game_controller_manager.cpp

+8-27
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "supertux/globals.hpp"
2525
#include "supertux/game_session.hpp"
2626
#include "supertux/savegame.hpp"
27-
#include "supertux/sector.hpp"
2827
#include "util/log.hpp"
2928

3029
GameControllerManager::GameControllerManager(InputManager* parent) :
@@ -84,7 +83,7 @@ GameControllerManager::process_button_event(const SDL_ControllerButtonEvent& ev)
8483
break;
8584

8685
case SDL_CONTROLLER_BUTTON_BACK:
87-
set_control(Control::CONSOLE, ev.state);
86+
set_control(Control::ITEM, ev.state);
8887
break;
8988

9089
case SDL_CONTROLLER_BUTTON_GUIDE:
@@ -205,6 +204,9 @@ GameControllerManager::process_axis_event(const SDL_ControllerAxisEvent& ev)
205204
void
206205
GameControllerManager::on_controller_added(int joystick_index)
207206
{
207+
if (!m_parent->can_add_user())
208+
return;
209+
208210
if (!SDL_IsGameController(joystick_index))
209211
{
210212
log_warning << "joystick is not a game controller, ignoring: " << joystick_index << std::endl;
@@ -240,16 +242,7 @@ GameControllerManager::on_controller_added(int joystick_index)
240242

241243
if (GameSession::current() && !GameSession::current()->get_savegame().is_title_screen() && id != 0)
242244
{
243-
auto& sector = GameSession::current()->get_current_sector();
244-
auto& player_status = GameSession::current()->get_savegame().get_player_status();
245-
246-
if (player_status.m_num_players <= id)
247-
player_status.add_player();
248-
249-
// ID = 0 is impossible, so no need to write `(id == 0) ? "" : ...`
250-
auto& player = sector.add<Player>(player_status, "Tux" + std::to_string(id + 1), id);
251-
252-
player.multiplayer_prepare_spawn();
245+
GameSession::current()->on_player_added(id);
253246
}
254247
}
255248
}
@@ -272,22 +265,10 @@ GameControllerManager::on_controller_removed(int instance_id)
272265
m_game_controllers.erase(it);
273266

274267
if (m_parent->m_use_game_controller && g_config->multiplayer_auto_manage_players
275-
&& deleted_player_id != 0 && !m_parent->m_uses_keyboard[deleted_player_id])
268+
&& deleted_player_id != 0 && !m_parent->m_uses_keyboard[deleted_player_id] &&
269+
GameSession::current())
276270
{
277-
// Sectors in worldmaps have no Player's of that class.
278-
if (Sector::current() && Sector::current()->get_object_count<Player>() > 0)
279-
{
280-
auto players = Sector::current()->get_objects_by_type<Player>();
281-
auto it_players = players.begin();
282-
283-
while (it_players != players.end())
284-
{
285-
if (it_players->get_id() == deleted_player_id)
286-
it_players->remove_me();
287-
288-
it_players++;
289-
}
290-
}
271+
GameSession::current()->on_player_removed(deleted_player_id);
291272
}
292273
}
293274
else

src/control/input_manager.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "control/keyboard_manager.hpp"
2424
#include "util/log.hpp"
2525

26+
static constexpr int MAX_PLAYERS = 4;
27+
2628
InputManager::InputManager(KeyboardConfig& keyboard_config,
2729
JoystickConfig& joystick_config) :
2830
m_controllers(),
@@ -51,6 +53,12 @@ InputManager::get_controller(int player_id)
5153
return *m_controllers[player_id];
5254
}
5355

56+
bool
57+
InputManager::can_add_user() const
58+
{
59+
return get_num_users() < MAX_PLAYERS;
60+
}
61+
5462
void
5563
InputManager::use_game_controller(bool v)
5664
{
@@ -139,6 +147,9 @@ InputManager::process_event(const SDL_Event& event)
139147
void
140148
InputManager::push_user()
141149
{
150+
if (!can_add_user())
151+
return;
152+
142153
m_controllers.push_back(std::make_unique<Controller>());
143154
}
144155

src/control/input_manager.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class InputManager final : public Currenton<InputManager>
5959
Controller& get_controller(int player_id = 0);
6060

6161
int get_num_users() const { return static_cast<int>(m_controllers.size()); }
62-
62+
bool can_add_user() const;
6363
void push_user();
6464
void pop_user();
6565

src/control/joystick_config.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ JoystickConfig::JoystickConfig() :
3838
bind_joybutton(0, 4, Control::PEEK_LEFT);
3939
bind_joybutton(0, 5, Control::PEEK_RIGHT);
4040
bind_joybutton(0, 6, Control::START);
41+
bind_joybutton(0, 7, Control::ITEM);
4142

4243
// Default joystick axis configuration
4344
bind_joyaxis(0, -1, Control::LEFT);

src/control/joystick_manager.cpp

+8-26
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include "supertux/globals.hpp"
2727
#include "supertux/game_session.hpp"
2828
#include "supertux/savegame.hpp"
29-
#include "supertux/sector.hpp"
3029
#include "util/log.hpp"
3130

3231
JoystickManager::JoystickManager(InputManager* parent_,
@@ -55,6 +54,10 @@ void
5554
JoystickManager::on_joystick_added(int joystick_index)
5655
{
5756
log_debug << "on_joystick_added(): " << joystick_index << std::endl;
57+
58+
if (!parent->can_add_user())
59+
return;
60+
5861
SDL_Joystick* joystick = SDL_JoystickOpen(joystick_index);
5962
if (!joystick)
6063
{
@@ -96,16 +99,7 @@ JoystickManager::on_joystick_added(int joystick_index)
9699

97100
if (GameSession::current() && !GameSession::current()->get_savegame().is_title_screen() && id != 0)
98101
{
99-
auto& sector = GameSession::current()->get_current_sector();
100-
auto& player_status = GameSession::current()->get_savegame().get_player_status();
101-
102-
if (player_status.m_num_players <= id)
103-
player_status.add_player();
104-
105-
// ID = 0 is impossible, so no need to write `(id == 0) ? "" : ...`
106-
auto& player = sector.add<Player>(player_status, "Tux" + std::to_string(id + 1), id);
107-
108-
player.multiplayer_prepare_spawn();
102+
GameSession::current()->on_player_added(id);
109103
}
110104
}
111105
}
@@ -129,22 +123,10 @@ JoystickManager::on_joystick_removed(int instance_id)
129123
joysticks.erase(it);
130124

131125
if (!parent->m_use_game_controller && g_config->multiplayer_auto_manage_players
132-
&& deleted_player_id != 0 && !parent->m_uses_keyboard[deleted_player_id])
126+
&& deleted_player_id != 0 && !parent->m_uses_keyboard[deleted_player_id] &&
127+
GameSession::current())
133128
{
134-
// Sectors in worldmaps have no Player's of that class
135-
if (Sector::current() && Sector::current()->get_object_count<Player>() > 0)
136-
{
137-
auto players = Sector::current()->get_objects_by_type<Player>();
138-
auto it_players = players.begin();
139-
140-
while (it_players != players.end())
141-
{
142-
if (it_players->get_id() == deleted_player_id)
143-
it_players->remove_me();
144-
145-
it_players++;
146-
}
147-
}
129+
GameSession::current()->on_player_removed(deleted_player_id);
148130
}
149131
}
150132
else

src/control/keyboard_config.cpp

+2-14
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ KeyboardConfig::KeyboardConfig() :
3434
Control::RIGHT,
3535
Control::JUMP,
3636
Control::ACTION,
37+
Control::ITEM,
3738
Control::PEEK_LEFT,
3839
Control::PEEK_RIGHT,
3940
Control::PEEK_UP,
@@ -51,6 +52,7 @@ KeyboardConfig::KeyboardConfig() :
5152
m_keymap[SDLK_DOWN] = {0, Control::DOWN};
5253
m_keymap[SDLK_SPACE] = {0, Control::JUMP};
5354
m_keymap[SDLK_LCTRL] = {0, Control::ACTION};
55+
m_keymap[SDLK_LSHIFT] = {0, Control::ITEM};
5456
m_keymap[SDLK_ESCAPE] = {0, Control::ESCAPE};
5557
m_keymap[SDLK_p] = {0, Control::START};
5658
m_keymap[SDLK_PAUSE] = {0, Control::START};
@@ -64,20 +66,6 @@ KeyboardConfig::KeyboardConfig() :
6466
m_keymap[SDLK_F1] = {0, Control::CHEAT_MENU};
6567
m_keymap[SDLK_F2] = {0, Control::DEBUG_MENU};
6668
m_keymap[SDLK_BACKSPACE] = {0, Control::REMOVE};
67-
68-
m_keymap[SDLK_a] = {1, Control::LEFT};
69-
m_keymap[SDLK_d] = {1, Control::RIGHT};
70-
m_keymap[SDLK_w] = {1, Control::UP};
71-
m_keymap[SDLK_s] = {1, Control::DOWN};
72-
m_keymap[SDLK_e] = {1, Control::JUMP};
73-
m_keymap[SDLK_q] = {1, Control::ACTION};
74-
75-
m_keymap[SDLK_j] = {2, Control::LEFT};
76-
m_keymap[SDLK_l] = {2, Control::RIGHT};
77-
m_keymap[SDLK_i] = {2, Control::UP};
78-
m_keymap[SDLK_k] = {2, Control::DOWN};
79-
m_keymap[SDLK_o] = {2, Control::JUMP};
80-
m_keymap[SDLK_u] = {2, Control::ACTION};
8169
}
8270

8371
void

0 commit comments

Comments
 (0)