Skip to content

Commit

Permalink
Add god mode for player
Browse files Browse the repository at this point in the history
- Add god mode for player in devtool (invisible to all enemy attacks)
- Add keybinding to toggle drawing collision grid info
- Split troubleshoot section in README into seperate md file
- Add keybinding in README
  • Loading branch information
NearHuscarl committed Dec 28, 2018
1 parent 983953f commit 9505b14
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 84 deletions.
114 changes: 51 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,56 @@
# Castlevania

## Project Configuration (Visual studio)

Here are some configurations you may want to change to build the project successfully (using Visual Studio).
Open the project settings by selecting the current project, right click and choose `Properties`

- Convert string in legacy code API: `General` -> `Character Set` -> `Use Unicode Character Set`
- Set C++ standard version to the minimum (C++17): `C/C++` -> `Language` -> `C++ Language Standard` -> `C++17 Standard`
- Enable [native event] _'feature'_: `C/C++` -> `Language` -> `Conformance mode` -> Leave Empty
- To use DirectSound framework: `C/C++` -> `Preprocessor` -> `Preprocessor Definitions` -> Add `_CRT_SECURE_NO_WARNINGS`

Also take a look at the following places and copy from the [sample project] if
there are still errors

- `General` -> `Windows SDK Version` -> Latest Version
- `VC++ Directories` -> `Include Directories`
- `VC++ Directories` -> `Library Directories`

### How to add DirectX SDK to your project

- Step 1: Install DirectX SDK

- Step 2: Go to DirectX SDK installation path

![DirectX_SDK_Path](images/DirectX_SDK_Path.png)

- Step 3: Copy into your game project. Something like this

![SlnTree](images/SlnTree.png)

- Step 4: Reconfigure Include and Library directory to the new relative path

![Include_Header_And_Lib](images/Include_Header_And_Lib.png)

- Step 5: Add those lib files in the Lib folder to Linker input

Go to `Configuration Properties` -> `Linker` -> `Input` -> `Additional Dependencies` and add

```
d3d9.lib;d3dx9.lib;dinput8.lib;dxguid.lib;dsound.lib;dxerr.lib;winmm.lib;%(AdditionalDependencies);legacy_stdio_definitions.lib
```

### How to add third-party dll files

- Go to `Configuration Properties` -> `Build Events` -> `Post-Build Event`
- Add this line in the Command Line

```
XCOPY "$(ProjectDir)\lib\*.dll" "$(TargetDir)" /D /K /Y
```

By default, Visual Studio only copy `*.dll` files in the `$(ProjectDir)`. If you put
them in some subfolder, you have to specify the path manually to that subfolder
(in this case `lib\`) so Visual Studio know where to find and copy them

### Fix linker error when having 2 files with the same name

```
LNK4042: object specified more than once; extras ignored
```

- Go to `Configuration Properties` -> `C/C++` -> `Output Files` -> `Object File Name` -> `$(IntDir)/%(RelativeDir)/`

With the default configuration, Visual will toss all object files into one big folder, leading to name conflict if there are source files with the same name in different folders, replace to `$(IntDir)/%(RelativeDir)/` will put those object files in a mirror source tree, solving name conflicts
A remake of Castlevania NES (Block 01) written in C++ and directx 9

## Controls

| Key | Command |
|----------------|----------------------|
| <kbd>←</kbd> | Walk left |
| <kbd>→</kbd> | Walk right |
| <kbd>↑</kbd> | Go upstairs |
| <kbd>↓</kbd> | Go downstairs / Duck |
| <kbd>z</kbd> | Attack |
| <kbd>x</kbd> | Jump |
| <kbd>c</kbd> | Use subweapon |
| <kbd>Esc</kbd> | Toggle devtool |

### Devtool Control

#### Keyboard

| Key | Command |
|---------------------|--------------------------------|
| <kbd>tab</kbd> | Set category to PLAYER |
| <kbd>q</kbd> | Set category to ENEMY |
| <kbd>w</kbd> | Set category to CONTAINER |
| <kbd>e</kbd> | Set category to POWERUP |
| <kbd>r</kbd> | Set category to WEAPON |
| <kbd>t</kbd> | Set category to EFFECT |
| <kbd>g</kbd> | Toggle drawing grid info |
| <kbd>home</kbd> | Next map |
| <kbd>end</kbd> | Previous map |
| <kbd>1</kbd> | Move player to `Checkpoint` |
| <kbd>2</kbd> | Move player to `Checkpoint_02` |
| <kbd>3</kbd> | Move player to `Checkpoint_03` |
| <kbd>4</kbd> | Move player to `Checkpoint_04` |
| <kbd>5</kbd> | Move player to `Checkpoint_05` |
| <kbd>6</kbd> | Move player to `Checkpoint_06` |
| <kbd>8</kbd> | Add 200 hearts to player |
| <kbd>9</kbd> | Set player health to 1 hp |
| <kbd>0</kbd> | Set player health to full |
| <kbd>Numpad -</kbd> | Kill player |
| <kbd>Numpad +</kbd> | Add 1 live to player |
| <kbd>~</kbd> | Toggle god mode for player |

#### Mouse

| Mouse button | Command |
|------------------------|--------------------------------------|
| <kbd>Scroll up</kbd> | Select to next item |
| <kbd>Scroll down</kbd> | Select to previous item |
| <kbd>Left click</kbd> | Spawn current item at mouse position |
| <kbd>Right click</kbd> | Toggle item facing |

## Development Environment

Expand Down
65 changes: 65 additions & 0 deletions TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Troubleshooting

## Project Configuration (Visual studio)

Here are some configurations you may want to change to build the project successfully (using Visual Studio).
Open the project settings by selecting the current project, right click and choose `Properties`

- Convert string in legacy code API: `General` -> `Character Set` -> `Use Unicode Character Set`
- Set C++ standard version to the minimum (C++17): `C/C++` -> `Language` -> `C++ Language Standard` -> `C++17 Standard`
- Enable [native event] _'feature'_: `C/C++` -> `Language` -> `Conformance mode` -> Leave Empty
- To use DirectSound framework: `C/C++` -> `Preprocessor` -> `Preprocessor Definitions` -> Add `_CRT_SECURE_NO_WARNINGS`

Also take a look at the following places and copy from the [sample project] if
there are still errors

- `General` -> `Windows SDK Version` -> Latest Version
- `VC++ Directories` -> `Include Directories`
- `VC++ Directories` -> `Library Directories`

### How to add DirectX SDK to your project

- Step 1: Install DirectX SDK

- Step 2: Go to DirectX SDK installation path

![DirectX_SDK_Path](images/DirectX_SDK_Path.png)

- Step 3: Copy into your game project. Something like this

![SlnTree](images/SlnTree.png)

- Step 4: Reconfigure Include and Library directory to the new relative path

![Include_Header_And_Lib](images/Include_Header_And_Lib.png)

- Step 5: Add those lib files in the Lib folder to Linker input

Go to `Configuration Properties` -> `Linker` -> `Input` -> `Additional Dependencies` and add

```
d3d9.lib;d3dx9.lib;dinput8.lib;dxguid.lib;dsound.lib;dxerr.lib;winmm.lib;%(AdditionalDependencies);legacy_stdio_definitions.lib
```

### How to add third-party dll files

- Go to `Configuration Properties` -> `Build Events` -> `Post-Build Event`
- Add this line in the Command Line

```
XCOPY "$(ProjectDir)\lib\*.dll" "$(TargetDir)" /D /K /Y
```

By default, Visual Studio only copy `*.dll` files in the `$(ProjectDir)`. If you put
them in some subfolder, you have to specify the path manually to that subfolder
(in this case `lib\`) so Visual Studio know where to find and copy them

### Fix linker error when having 2 files with the same name

```
LNK4042: object specified more than once; extras ignored
```

- Go to `Configuration Properties` -> `C/C++` -> `Output Files` -> `Object File Name` -> `$(IntDir)/%(RelativeDir)/`

With the default configuration, Visual will toss all object files into one big folder, leading to name conflict if there are source files with the same name in different folders, replace to `$(IntDir)/%(RelativeDir)/` will put those object files in a mirror source tree, solving name conflicts
13 changes: 11 additions & 2 deletions src/GameCuaTao/Castlevania/Models/Characters/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ void Player::Throw(std::unique_ptr<RangedWeapon> weapon)

subWeaponCount = MathHelper::Max(--subWeaponCount, 0);


if (data.hearts == 0)
return;

Expand Down Expand Up @@ -508,7 +507,7 @@ void Player::BecomeInvisible()

void Player::TakeDamage(int damage, Direction direction)
{
if (untouchableTimer.IsRunning() || invisibleTimer.IsRunning())
if (untouchableTimer.IsRunning() || invisibleTimer.IsRunning() || godMode)
return;

data.health -= damage;
Expand Down Expand Up @@ -544,6 +543,16 @@ void Player::Die()
SetState(ObjectState::DYING);
}

void Player::ToggleGodMode()
{
godMode = !godMode;

if (godMode)
SendMessageToSystems(GOD_MODE_ACTIVATED);
else
SendMessageToSystems(GOD_MODE_DEACTIVATED);
}

void Player::Revive()
{
data.lives--;
Expand Down
2 changes: 2 additions & 0 deletions src/GameCuaTao/Castlevania/Models/Characters/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ namespace Castlevania
float jumpSpeed;
bool isStopwatchActive;
int subWeaponCount;
bool godMode;

std::unique_ptr<Whip> whip;
std::unique_ptr<RangedWeapon> subWeapon;
Expand All @@ -129,6 +130,7 @@ namespace Castlevania
void TakeDamage(int damage, Direction direction);
void BounceBack(Direction direction); // when simon taking damage
void Die();
void ToggleGodMode();

void UpdateStates();
void OnAttackComplete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ void PlayerRenderingSystem::Receive(int message)
case INVISIBLE_ENDED:
sprite->SetVisibility(true);
break;

case GOD_MODE_ACTIVATED:
case GOD_MODE_DEACTIVATED:
PlayAnimation(sprite->GetCurrentAnimation().GetName());
break;
}
}

Expand Down Expand Up @@ -149,30 +154,35 @@ void PlayerRenderingSystem::UpdateInvisibleRendering()
else
{
if (drawInvisibleEffect)
{
drawInvisibleEffect = false;
PlayAnimation(sprite->GetCurrentAnimation().GetName());
}

sprite->SetVisibility(Stopwatch::Every(1) ? true : false);
}
}

void PlayerRenderingSystem::PlayAnimation(std::string name)
{
if (drawInvisibleEffect)
{
auto invisibleSuffix = "_invisible";

if (EndsWith(name, invisibleSuffix))
return;
auto animationName = name;
auto invisibleSuffix = std::string{ "_invisible" };

sprite->Play(name + invisibleSuffix);
if (drawInvisibleEffect || parent.godMode)
{
if (!EndsWith(animationName, invisibleSuffix))
animationName += invisibleSuffix;
}
else
{
if (name == WALK_ANIMATION)
sprite->PlayCached(name);
else
sprite->Play(name);
if (EndsWith(animationName, invisibleSuffix))
animationName = animationName.substr(0, animationName.size() - invisibleSuffix.size());
}

if (name == WALK_ANIMATION)
sprite->PlayCached(animationName);
else
sprite->Play(animationName);
}

void PlayerRenderingSystem::OnStateChanged()
Expand Down
16 changes: 9 additions & 7 deletions src/GameCuaTao/Castlevania/Models/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@ namespace Castlevania
constexpr auto ATTACK_STATE_CHANGED = 4;
constexpr auto UNTOUCHABLE_ENDED = 5;
constexpr auto INVISIBLE_ENDED = 6;
constexpr auto GOD_MODE_ACTIVATED = 7;
constexpr auto GOD_MODE_DEACTIVATED = 8;

// Whip events
constexpr auto WHIP_UNLEASHED = 7;
constexpr auto WEAPON_WITHDRAWN = 8;
constexpr auto WHIP_UNLEASHED = 9;
constexpr auto WEAPON_WITHDRAWN = 10;

// Enemy events
constexpr auto PLAYER_IN_RANGE = 9;
constexpr auto PLAYER_OUT_OF_RANGE = 10;
constexpr auto ACTIVE_CHANGED = 11;
constexpr auto PLAYER_IN_RANGE = 11;
constexpr auto PLAYER_OUT_OF_RANGE = 12;
constexpr auto ACTIVE_CHANGED = 13;

// GiantBat events
constexpr auto PLAYER_IN_THREAT_ZONE = 12;
constexpr auto PLAYER_IN_THREAT_ZONE = 14;

// WaterArea events
constexpr auto OBJECT_HITS_WATER_SURFACE = 13;
constexpr auto OBJECT_HITS_WATER_SURFACE = 15;
}
7 changes: 7 additions & 0 deletions src/GameCuaTao/Castlevania/Utilities/DevTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ void DevTool::Update(UpdateData &updatData)
SetCategory(WEAPON);
else if (InputHelper::IsKeyDown(DIK_T))
SetCategory(EFFECT);
else if (InputHelper::IsKeyDown(DIK_G))
drawingGridInfo = !drawingGridInfo;

else if (InputHelper::IsKeyDown(DIK_HOME))
NextMap();
Expand Down Expand Up @@ -192,6 +194,8 @@ void DevTool::Update(UpdateData &updatData)
player.Die();
else if (InputHelper::IsKeyDown(DIK_ADD))
player.data.lives++;
else if (InputHelper::IsKeyDown(DIK_GRAVE))
player.ToggleGodMode();

// Update mouse input
if (InputHelper::IsScrollingDown())
Expand Down Expand Up @@ -261,6 +265,9 @@ void DevTool::UpdateEffects(GameTime gameTime)

void DevTool::DrawCollisionGridInfo(SpriteExtensions &spriteBatch)
{
if (!drawingGridInfo)
return;

auto &grid = *stage.grid;

grid.GetCellsFromBoundingBox(camera.GetBounds(), [&](CollisionCell &cell, int col, int row)
Expand Down
3 changes: 2 additions & 1 deletion src/GameCuaTao/Castlevania/Utilities/DevTool.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ namespace Castlevania
private:
using DevToolItems = std::vector<std::pair<std::string, Sprite>>;

bool drawingGridInfo;
std::shared_ptr<SpriteFont> debugFont;

std::unordered_map<std::string, DevToolItems> items;
static int currentItemIndex;
std::string category;
Expand Down

0 comments on commit 9505b14

Please sign in to comment.