restructure codebase according to vcproj filters

This commit is contained in:
Tropical
2026-03-30 09:50:58 -05:00
parent d5cf90c713
commit 451682693e
3015 changed files with 46858 additions and 54635 deletions

View File

@@ -0,0 +1,47 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
#include "AreaConstraint.h"
#include "../../../../../Minecraft.World/net/minecraft/world/phys/AABB.h"
AreaConstraint::AreaConstraint(int descriptionId, double x0, double y0,
double z0, double x1, double y1, double z1,
bool contains /*= true*/,
bool restrictsMovement /*=true*/)
: TutorialConstraint(descriptionId) {
messageArea = AABB(x0 + 2, y0 + 2, z0 + 2, x1 - 2, y1 - 2, z1 - 2);
movementArea = AABB(x0, y0, z0, x1, y1, z1);
this->contains = contains;
m_restrictsMovement = restrictsMovement;
}
bool AreaConstraint::isConstraintSatisfied(int iPad) {
Minecraft* minecraft = Minecraft::GetInstance();
// TODO: check if this can be elided
Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1);
return messageArea.contains(ipad_player) == contains;
}
bool AreaConstraint::isConstraintRestrictive(int iPad) {
return m_restrictsMovement;
}
bool AreaConstraint::canMoveToPosition(double xo, double yo, double zo,
double xt, double yt, double zt) {
if (!m_restrictsMovement) return true;
Vec3 targetPos(xt, yt, zt);
Minecraft* minecraft = Minecraft::GetInstance();
if (movementArea.contains(targetPos) == contains) {
return true;
}
Vec3 origPos(xo, yo, zo);
double currDist = origPos.distanceTo(&movementArea);
double targetDist = targetPos.distanceTo(&movementArea);
return targetDist < currDist;
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include "TutorialConstraint.h"
class AABB;
class AreaConstraint : public TutorialConstraint {
private:
AABB movementArea;
AABB messageArea;
bool contains; // If true we must stay in this area, if false must stay out
// of this area
bool m_restrictsMovement;
public:
virtual ConstraintType getType() { return e_ConstraintArea; }
AreaConstraint(int descriptionId, double x0, double y0, double z0,
double x1, double y1, double z1, bool contains = true,
bool restrictsMovement = true);
virtual bool isConstraintSatisfied(int iPad);
virtual bool isConstraintRestrictive(int iPad);
virtual bool canMoveToPosition(double xo, double yo, double zo, double xt,
double yt, double zt);
};

View File

@@ -0,0 +1,158 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../Tutorial.h"
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/net.minecraft.world.level.h"
#include "ChangeStateConstraint.h"
#include "../../../../../Minecraft.World/net/minecraft/world/phys/AABB.h"
#include "../../../../net/minecraft/client/multiplayer/ClientConnection.h"
#include "../../../../../Minecraft.World/net/minecraft/network/packet/net.minecraft.network.packet.h"
ChangeStateConstraint::ChangeStateConstraint(
Tutorial* tutorial, eTutorial_State targetState,
eTutorial_State sourceStates[], std::size_t sourceStatesCount, double x0,
double y0, double z0, double x1, double y1, double z1,
bool contains /*= true*/, bool changeGameMode /*= false*/,
GameType* targetGameMode /*= 0*/)
: TutorialConstraint(-1) {
movementArea = AABB(x0, y0, z0, x1, y1, z1);
this->contains = contains;
m_changeGameMode = changeGameMode;
m_targetGameMode = targetGameMode;
m_changedFromGameMode = 0;
m_tutorial = tutorial;
m_targetState = targetState;
m_sourceStatesCount = sourceStatesCount;
m_bHasChanged = false;
m_changedFromState = e_Tutorial_State_None;
m_bComplete = false;
m_sourceStates = new eTutorial_State[m_sourceStatesCount];
for (unsigned int i = 0; i < m_sourceStatesCount; i++) {
m_sourceStates[i] = sourceStates[i];
}
}
ChangeStateConstraint::~ChangeStateConstraint() {
if (m_sourceStatesCount > 0) delete[] m_sourceStates;
}
void ChangeStateConstraint::tick(int iPad) {
if (m_bComplete) return;
if (m_tutorial->isStateCompleted(m_targetState)) {
Minecraft* minecraft = Minecraft::GetInstance();
if (m_changeGameMode) {
unsigned int playerPrivs =
minecraft->localplayers[iPad]->getAllPlayerGamePrivileges();
Player::setPlayerGamePrivilege(
playerPrivs, Player::ePlayerGamePrivilege_CreativeMode,
m_changedFromGameMode == GameType::CREATIVE);
unsigned int originalPrivileges =
minecraft->localplayers[iPad]->getAllPlayerGamePrivileges();
if (originalPrivileges != playerPrivs) {
// Send update settings packet to server
Minecraft* pMinecraft = Minecraft::GetInstance();
std::shared_ptr<MultiplayerLocalPlayer> player =
minecraft->localplayers[iPad];
if (player != nullptr && player->connection &&
player->connection->getNetworkPlayer() != nullptr) {
player->connection->send(
std::shared_ptr<PlayerInfoPacket>(new PlayerInfoPacket(
player->connection->getNetworkPlayer()
->GetSmallId(),
-1, playerPrivs)));
}
}
}
m_bComplete = true;
return;
}
bool inASourceState = false;
Minecraft* minecraft = Minecraft::GetInstance();
for (std::size_t i = 0; i < m_sourceStatesCount; ++i) {
if (m_sourceStates[i] == m_tutorial->getCurrentState()) {
inASourceState = true;
break;
}
}
// TODO: check if this can be elided
Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1);
if (!m_bHasChanged && inASourceState &&
movementArea.contains(ipad_player) == contains) {
m_bHasChanged = true;
m_changedFromState = m_tutorial->getCurrentState();
m_tutorial->changeTutorialState(m_targetState);
if (m_changeGameMode) {
if (minecraft->localgameModes[iPad] != nullptr) {
m_changedFromGameMode =
minecraft->localplayers[iPad]->abilities.instabuild
? GameType::CREATIVE
: GameType::SURVIVAL;
unsigned int playerPrivs =
minecraft->localplayers[iPad]->getAllPlayerGamePrivileges();
Player::setPlayerGamePrivilege(
playerPrivs, Player::ePlayerGamePrivilege_CreativeMode,
m_targetGameMode == GameType::CREATIVE);
unsigned int originalPrivileges =
minecraft->localplayers[iPad]->getAllPlayerGamePrivileges();
if (originalPrivileges != playerPrivs) {
// Send update settings packet to server
Minecraft* pMinecraft = Minecraft::GetInstance();
std::shared_ptr<MultiplayerLocalPlayer> player =
minecraft->localplayers[iPad];
if (player != nullptr && player->connection &&
player->connection->getNetworkPlayer() != nullptr) {
player->connection->send(
std::shared_ptr<PlayerInfoPacket>(
new PlayerInfoPacket(
player->connection->getNetworkPlayer()
->GetSmallId(),
-1, playerPrivs)));
}
}
}
}
} else if (m_bHasChanged &&
movementArea.contains(ipad_player) != contains) {
m_bHasChanged = false;
m_tutorial->changeTutorialState(m_changedFromState);
if (m_changeGameMode) {
unsigned int playerPrivs =
minecraft->localplayers[iPad]->getAllPlayerGamePrivileges();
Player::setPlayerGamePrivilege(
playerPrivs, Player::ePlayerGamePrivilege_CreativeMode,
m_changedFromGameMode == GameType::CREATIVE);
unsigned int originalPrivileges =
minecraft->localplayers[iPad]->getAllPlayerGamePrivileges();
if (originalPrivileges != playerPrivs) {
// Send update settings packet to server
Minecraft* pMinecraft = Minecraft::GetInstance();
std::shared_ptr<MultiplayerLocalPlayer> player =
minecraft->localplayers[iPad];
if (player != nullptr && player->connection &&
player->connection->getNetworkPlayer() != nullptr) {
player->connection->send(
std::shared_ptr<PlayerInfoPacket>(new PlayerInfoPacket(
player->connection->getNetworkPlayer()
->GetSmallId(),
-1, playerPrivs)));
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "../TutorialEnum.h"
#include "TutorialConstraint.h"
#include <cstddef>
class AABB;
class Tutorial;
class GameType;
class ChangeStateConstraint : public TutorialConstraint {
private:
AABB movementArea;
bool contains; // If true we must stay in this area, if false must stay out
// of this area
bool m_changeGameMode;
GameType* m_targetGameMode;
GameType* m_changedFromGameMode;
eTutorial_State m_targetState;
eTutorial_State* m_sourceStates;
std::size_t m_sourceStatesCount;
bool m_bHasChanged;
eTutorial_State m_changedFromState;
bool m_bComplete;
Tutorial* m_tutorial;
public:
virtual ConstraintType getType() { return e_ConstraintChangeState; }
ChangeStateConstraint(Tutorial* tutorial, eTutorial_State targetState,
eTutorial_State sourceStates[],
std::size_t sourceStatesCount, double x0, double y0,
double z0, double x1, double y1, double z1,
bool contains = true, bool changeGameMode = false,
GameType* targetGameMode = nullptr);
~ChangeStateConstraint();
virtual void tick(int iPad);
};

View File

@@ -0,0 +1,18 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "InputConstraint.h"
bool InputConstraint::isMappingConstrained(int iPad, int mapping) {
// If it's a menu button, then we ignore all inputs
if ((m_inputMapping == mapping) || (mapping < ACTION_MAX_MENU)) {
return true;
}
// Otherwise see if they map to the same actual button
unsigned char layoutMapping = InputManager.GetJoypadMapVal(iPad);
// 4J HEG - Replaced the equivalance test with bitwise AND, important in
// some mapping configurations (e.g. when comparing two action map values
// and one has extra buttons mapped)
return (InputManager.GetGameJoypadMaps(layoutMapping, m_inputMapping) &
InputManager.GetGameJoypadMaps(layoutMapping, mapping)) > 0;
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "TutorialConstraint.h"
class InputConstraint : public TutorialConstraint {
private:
int m_inputMapping; // Should be one of the EControllerActions
public:
virtual ConstraintType getType() { return e_ConstraintInput; }
InputConstraint(int mapping)
: TutorialConstraint(-1), m_inputMapping(mapping) {}
virtual bool isMappingConstrained(int iPad, int mapping);
};

View File

@@ -0,0 +1,49 @@
#pragma once
// 4J Stu - An abstract class that represents a constraint on what the user is
// able to do
class TutorialConstraint {
private:
int descriptionId;
bool m_deleteOnDeactivate;
bool m_queuedForRemoval;
public:
enum ConstraintType {
e_ConstraintInput = 0, // Constraint on controller input
e_ConstraintArea,
e_ConstraintAllInput,
e_ConstraintXuiInput,
e_ConstraintChangeState,
};
TutorialConstraint(int descriptionId)
: descriptionId(descriptionId),
m_deleteOnDeactivate(false),
m_queuedForRemoval(false) {}
virtual ~TutorialConstraint() {}
int getDescriptionId() { return descriptionId; }
virtual ConstraintType getType() = 0;
virtual void tick(int iPad) {}
virtual bool isConstraintSatisfied(int iPad) { return true; }
virtual bool isConstraintRestrictive(int iPad) { return true; }
virtual bool isMappingConstrained(int iPad, int mapping) { return false; }
virtual bool isXuiInputConstrained(int vk) { return false; }
void setDeleteOnDeactivate(bool deleteOnDeactivated) {
m_deleteOnDeactivate = deleteOnDeactivated;
}
bool getDeleteOnDeactivate() { return m_deleteOnDeactivate; }
void setQueuedForRemoval(bool queued) { m_queuedForRemoval = queued; }
bool getQueuedForRemoval() { return m_queuedForRemoval; }
virtual bool canMoveToPosition(double xo, double yo, double zo, double xt,
double yt, double zt) {
return true;
}
};

View File

@@ -0,0 +1,5 @@
#pragma once
#include "TutorialConstraint.h"
#include "AreaConstraint.h"
#include "ChangeStateConstraint.h"
#include "InputConstraint.h"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Tutorial.h"
#define FULL_TUTORIAL_PROGRESS_2_X_2_Crafting 1
#define FULL_TUTORIAL_PROGRESS_3_X_3_Crafting 2
#define FULL_TUTORIAL_PROGRESS_CRAFT_FURNACE 4
#define FULL_TUTORIAL_PROGRESS_USE_FURNACE 8
#define EXTENDED_TUTORIAL_PROGRESS_USE_BREWING_STAND 16
class FullTutorial : public Tutorial {
private:
bool m_isTrial;
char m_progressFlags;
bool m_completedStates[e_Tutorial_State_Max];
public:
FullTutorial(int iPad, bool isTrial = false);
virtual bool isStateCompleted(eTutorial_State state);
virtual void setStateCompleted(eTutorial_State state);
};

View File

@@ -0,0 +1,15 @@
#include "../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../net/minecraft/client/Minecraft.h"
#include "FullTutorial.h"
#include "FullTutorialMode.h"
FullTutorialMode::FullTutorialMode(int iPad, Minecraft* minecraft,
ClientConnection* connection)
: TutorialMode(iPad, minecraft, connection) {
tutorial = new FullTutorial(iPad);
minecraft->playerStartedTutorial(iPad);
}
bool FullTutorialMode::isTutorial() {
return !tutorial->m_fullTutorialComplete;
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "TutorialMode.h"
class FullTutorialMode : public TutorialMode {
public:
FullTutorialMode(int iPad, Minecraft* minecraft,
ClientConnection* connection);
virtual bool isImplemented() { return true; }
virtual bool isTutorial();
};

View File

@@ -0,0 +1,41 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
#include "AreaHint.h"
#include "../../../../../Minecraft.World/net/minecraft/world/phys/AABB.h"
#include "../Tutorial.h"
AreaHint::AreaHint(eTutorial_Hint id, Tutorial* tutorial,
eTutorial_State displayState, eTutorial_State completeState,
int descriptionId, double x0, double y0, double z0,
double x1, double y1, double z1, bool allowFade /*= false*/,
bool contains /*= true*/)
: TutorialHint(id, tutorial, descriptionId, e_Hint_Area, allowFade) {
area = AABB(x0, y0, z0, x1, y1, z1);
this->contains = contains;
m_displayState = displayState;
m_completeState = completeState;
}
int AreaHint::tick() {
Minecraft* minecraft = Minecraft::GetInstance();
Vec3 player_pos = minecraft->player->getPos(1);
if ((m_displayState == e_Tutorial_State_Any ||
m_tutorial->getCurrentState() == m_displayState) &&
m_hintNeeded && area.contains(player_pos) == contains) {
if (m_completeState == e_Tutorial_State_None) {
m_hintNeeded = false;
} else if (m_tutorial->isStateCompleted(m_completeState)) {
m_hintNeeded = false;
return -1;
}
return m_descriptionId;
} else {
return -1;
}
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include "TutorialHint.h"
class AABB;
class AreaHint : public TutorialHint {
private:
AABB area;
bool contains; // If true we must stay in this area, if false must stay out
// of this area
// Only display the hint if the game is in this state
eTutorial_State m_displayState;
// Only display the hint if this state is not completed
eTutorial_State m_completeState;
public:
AreaHint(eTutorial_Hint id, Tutorial* tutorial,
eTutorial_State displayState, eTutorial_State completeState,
int descriptionId, double x0, double y0, double z0, double x1,
double y1, double z1, bool allowFade = true, bool contains = true);
virtual int tick();
};

View File

@@ -0,0 +1,64 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/net.minecraft.world.level.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/tile/net.minecraft.world.level.tile.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/net.minecraft.world.item.h"
#include "../../../../../Minecraft.World/net/minecraft/world/entity/net.minecraft.world.entity.h"
#include "../Tutorial.h"
#include "DiggerItemHint.h"
DiggerItemHint::DiggerItemHint(eTutorial_Hint id, Tutorial* tutorial,
int descriptionId, int items[],
unsigned int itemsLength)
: TutorialHint(id, tutorial, descriptionId, e_Hint_DiggerItem) {
m_iItemsCount = itemsLength;
m_iItems = new int[m_iItemsCount];
for (unsigned int i = 0; i < m_iItemsCount; i++) {
m_iItems[i] = items[i];
}
tutorial->addMessage(IDS_TUTORIAL_HINT_ATTACK_WITH_TOOL, true);
}
int DiggerItemHint::startDestroyBlock(std::shared_ptr<ItemInstance> item,
Tile* tile) {
if (item != nullptr) {
bool itemFound = false;
for (unsigned int i = 0; i < m_iItemsCount; i++) {
if (item->id == m_iItems[i]) {
itemFound = true;
break;
}
}
if (itemFound) {
float speed = item->getDestroySpeed(tile);
if (speed == 1) {
// Display hint
return m_descriptionId;
}
}
}
return -1;
}
int DiggerItemHint::attack(std::shared_ptr<ItemInstance> item,
std::shared_ptr<Entity> entity) {
if (item != nullptr) {
bool itemFound = false;
for (unsigned int i = 0; i < m_iItemsCount; i++) {
if (item->id == m_iItems[i]) {
itemFound = true;
break;
}
}
if (itemFound) {
// It's also possible that we could hit TileEntities (eg falling
// sand) so don't want to give this hint then
if (entity->instanceof(eTYPE_MOB)) {
return IDS_TUTORIAL_HINT_ATTACK_WITH_TOOL;
} else {
return -1;
}
}
}
return -1;
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "TutorialHint.h"
class DiggerItem;
class Level;
class DiggerItemHint : public TutorialHint {
private:
int* m_iItems;
unsigned int m_iItemsCount;
public:
DiggerItemHint(eTutorial_Hint id, Tutorial* tutorial, int descriptionId,
int items[], unsigned int itemsLength);
virtual int startDestroyBlock(std::shared_ptr<ItemInstance> item,
Tile* tile);
virtual int attack(std::shared_ptr<ItemInstance> item,
std::shared_ptr<Entity> entity);
};

View File

@@ -0,0 +1,24 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../Tutorial.h"
#include "LookAtEntityHint.h"
LookAtEntityHint::LookAtEntityHint(eTutorial_Hint id, Tutorial* tutorial,
int descriptionId, int titleId,
eINSTANCEOF type)
: TutorialHint(id, tutorial, descriptionId, e_Hint_LookAtEntity) {
m_type = type;
m_titleId = titleId;
}
bool LookAtEntityHint::onLookAtEntity(eINSTANCEOF type) {
if (m_type == type) {
// Display hint
Tutorial::PopupMessageDetails* message =
new Tutorial::PopupMessageDetails();
message->m_messageId = m_descriptionId;
message->m_titleId = m_titleId;
message->m_delay = true;
return m_tutorial->setMessage(this, message);
}
return false;
}

View File

@@ -0,0 +1,21 @@
#pragma once
// using namespace std;
#include "../../../../../Minecraft.World/ConsoleJavaLibs/Class.h"
#include "TutorialHint.h"
class ItemInstance;
class LookAtEntityHint : public TutorialHint {
private:
eINSTANCEOF m_type;
int m_titleId;
public:
LookAtEntityHint(eTutorial_Hint id, Tutorial* tutorial, int descriptionId,
int titleId, eINSTANCEOF type);
// TODO: 4jcraft added, this was not implemented
~LookAtEntityHint() {};
virtual bool onLookAtEntity(eINSTANCEOF type);
};

View File

@@ -0,0 +1,59 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/net.minecraft.world.item.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/tile/net.minecraft.world.level.tile.h"
#include "../Tutorial.h"
#include "LookAtTileHint.h"
LookAtTileHint::LookAtTileHint(eTutorial_Hint id, Tutorial* tutorial,
int tiles[], unsigned int tilesLength,
int iconOverride /*= -1*/, int iData /* = -1 */,
int iDataOverride /*= -1*/)
: TutorialHint(id, tutorial, -1, e_Hint_LookAtTile) {
m_iTilesCount = tilesLength;
// TODO: 4jcraft: allocating but never freeing mem, leak
m_iTiles = new int[m_iTilesCount];
for (unsigned int i = 0; i < m_iTilesCount; i++) {
m_iTiles[i] = tiles[i];
}
m_iconOverride = iconOverride;
m_iData = iData;
m_iDataOverride = iDataOverride;
}
bool LookAtTileHint::onLookAt(int id, int iData) {
if (id > 0 && id < 256 && (m_iData == -1 || m_iData == iData)) {
bool itemFound = false;
for (unsigned int i = 0; i < m_iTilesCount; i++) {
if (id == m_iTiles[i]) {
itemFound = true;
break;
}
}
if (itemFound) {
// Display hint
Tutorial::PopupMessageDetails* message =
new Tutorial::PopupMessageDetails();
message->m_delay = true;
if (m_iconOverride >= 0) {
message->m_icon = m_iconOverride;
} else if (m_iconOverride == -2) {
message->m_icon = TUTORIAL_NO_ICON;
} else {
message->m_icon = id;
}
// 4J-JEV: Moved to keep data override even if we're overriding the
// icon as well.
message->m_iAuxVal =
(m_iDataOverride > -1) ? m_iDataOverride : iData;
message->m_messageId = Item::items[id]->getUseDescriptionId();
message->m_titleId =
Item::items[id]->getDescriptionId(message->m_iAuxVal);
return m_tutorial->setMessage(this, message);
}
}
return false;
}

View File

@@ -0,0 +1,24 @@
#pragma once
// using namespace std;
#include "TutorialHint.h"
class ItemInstance;
class LookAtTileHint : public TutorialHint {
private:
int* m_iTiles;
unsigned int m_iTilesCount;
int m_iconOverride;
int m_iData;
int m_iDataOverride;
public:
LookAtTileHint(eTutorial_Hint id, Tutorial* tutorial, int tiles[],
unsigned int tilesLength, int iconOverride = -1,
int iData = -1, int iDataOverride = -1);
// TODO: 4jcraft, added, destructor was never implemented
~LookAtTileHint() {};
virtual bool onLookAt(int id, int iData = 0);
};

View File

@@ -0,0 +1,39 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/net.minecraft.world.item.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/tile/net.minecraft.world.level.tile.h"
#include "../Tutorial.h"
#include "TakeItemHint.h"
TakeItemHint::TakeItemHint(eTutorial_Hint id, Tutorial* tutorial, int items[],
unsigned int itemsLength)
: TutorialHint(id, tutorial, -1, e_Hint_TakeItem) {
m_iItemsCount = itemsLength;
m_iItems = new int[m_iItemsCount];
for (unsigned int i = 0; i < m_iItemsCount; i++) {
m_iItems[i] = items[i];
}
}
bool TakeItemHint::onTake(std::shared_ptr<ItemInstance> item) {
if (item != nullptr) {
bool itemFound = false;
for (unsigned int i = 0; i < m_iItemsCount; i++) {
if (item->id == m_iItems[i]) {
itemFound = true;
break;
}
}
if (itemFound) {
// Display hint
Tutorial::PopupMessageDetails* message =
new Tutorial::PopupMessageDetails();
message->m_messageId = item->getUseDescriptionId();
message->m_titleId = item->getDescriptionId();
message->m_icon = item->id;
message->m_delay = true;
return m_tutorial->setMessage(this, message);
}
}
return false;
}

View File

@@ -0,0 +1,20 @@
#pragma once
// using namespace std;
#include "TutorialHint.h"
class ItemInstance;
class TakeItemHint : public TutorialHint {
private:
int* m_iItems;
unsigned int m_iItemsCount;
public:
TakeItemHint(eTutorial_Hint id, Tutorial* tutorial, int items[],
unsigned int itemsLength);
// TODO: 4jcraft, added, it was never implemented
virtual ~TakeItemHint() {};
virtual bool onTake(std::shared_ptr<ItemInstance> item);
};

View File

@@ -0,0 +1,117 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/net.minecraft.world.level.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/tile/net.minecraft.world.level.tile.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/net.minecraft.world.item.h"
#include "../Tutorial.h"
#include "TutorialHint.h"
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
TutorialHint::TutorialHint(eTutorial_Hint id, Tutorial* tutorial,
int descriptionId, eHintType type,
bool allowFade /*= true*/)
: m_id(id),
m_tutorial(tutorial),
m_descriptionId(descriptionId),
m_type(type),
m_counter(0),
m_lastTile(nullptr),
m_hintNeeded(true),
m_allowFade(allowFade) {
tutorial->addMessage(descriptionId, type != e_Hint_NoIngredients);
}
int TutorialHint::startDestroyBlock(std::shared_ptr<ItemInstance> item,
Tile* tile) {
int returnVal = -1;
switch (m_type) {
case e_Hint_HoldToMine:
if (tile == m_lastTile && m_hintNeeded) {
++m_counter;
if (m_counter > TUTORIAL_HINT_MAX_MINE_REPEATS) {
returnVal = m_descriptionId;
}
} else {
m_counter = 0;
}
m_lastTile = tile;
break;
default:
break;
}
return returnVal;
}
int TutorialHint::destroyBlock(Tile* tile) {
int returnVal = -1;
switch (m_type) {
case e_Hint_HoldToMine:
if (tile == m_lastTile && m_counter > 0) {
m_hintNeeded = false;
}
break;
default:
break;
}
return returnVal;
}
int TutorialHint::attack(std::shared_ptr<ItemInstance> item,
std::shared_ptr<Entity> entity) {
/*
switch(m_type)
{
default:
return -1;
}
*/
return -1;
}
int TutorialHint::createItemSelected(std::shared_ptr<ItemInstance> item,
bool canMake) {
int returnVal = -1;
switch (m_type) {
case e_Hint_NoIngredients:
if (!canMake) returnVal = m_descriptionId;
break;
default:
break;
}
return returnVal;
}
int TutorialHint::itemDamaged(std::shared_ptr<ItemInstance> item) {
int returnVal = -1;
switch (m_type) {
case e_Hint_ToolDamaged:
returnVal = m_descriptionId;
break;
default:
break;
}
return returnVal;
}
bool TutorialHint::onTake(std::shared_ptr<ItemInstance> item) { return false; }
bool TutorialHint::onLookAt(int id, int iData) { return false; }
bool TutorialHint::onLookAtEntity(eINSTANCEOF type) { return false; }
int TutorialHint::tick() {
int returnVal = -1;
switch (m_type) {
case e_Hint_SwimUp:
if (Minecraft::GetInstance()
->localplayers[m_tutorial->getPad()]
->isUnderLiquid(Material::water))
returnVal = m_descriptionId;
break;
default:
break;
}
return returnVal;
}

View File

@@ -0,0 +1,56 @@
#pragma once
// using namespace std;
#include "../TutorialEnum.h"
#define TUTORIAL_HINT_MAX_MINE_REPEATS 20
class Level;
class Tutorial;
class TutorialHint {
public:
enum eHintType {
e_Hint_DiggerItem,
e_Hint_HoldToMine,
e_Hint_NoIngredients,
e_Hint_ToolDamaged,
e_Hint_TakeItem,
e_Hint_Area,
e_Hint_LookAtTile,
e_Hint_LookAtEntity,
e_Hint_SwimUp,
};
protected:
eHintType m_type;
int m_descriptionId;
Tutorial* m_tutorial;
eTutorial_Hint m_id;
int m_counter;
Tile* m_lastTile;
bool m_hintNeeded;
bool m_allowFade;
public:
TutorialHint(eTutorial_Hint id, Tutorial* tutorial, int descriptionId,
eHintType type, bool allowFade = true);
virtual ~TutorialHint() {}
eTutorial_Hint getId() { return m_id; }
virtual int startDestroyBlock(std::shared_ptr<ItemInstance> item,
Tile* tile);
virtual int destroyBlock(Tile* tile);
virtual int attack(std::shared_ptr<ItemInstance> item,
std::shared_ptr<Entity> entity);
virtual int createItemSelected(std::shared_ptr<ItemInstance> item,
bool canMake);
virtual int itemDamaged(std::shared_ptr<ItemInstance> item);
virtual bool onTake(std::shared_ptr<ItemInstance> item);
virtual bool onLookAt(int id, int iData = 0);
virtual bool onLookAtEntity(eINSTANCEOF type);
virtual int tick();
virtual bool allowFade() { return m_allowFade; }
};

View File

@@ -0,0 +1,7 @@
#pragma once
#include "AreaHint.h"
#include "DiggerItemHint.h"
#include "LookAtTileHint.h"
#include "TakeItemHint.h"
#include "LookAtEntityHint.h"

View File

@@ -0,0 +1,58 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../Tutorial.h"
#include "AreaTask.h"
AreaTask::AreaTask(eTutorial_State state, Tutorial* tutorial,
std::vector<TutorialConstraint*>* inConstraints,
int descriptionId, EAreaTaskCompletionStates completionState)
: TutorialTask(tutorial, descriptionId, false, inConstraints, false, false,
false) {
m_tutorialState = state;
if (m_tutorialState == e_Tutorial_State_Gameplay) {
enableConstraints(true);
}
m_completionState = completionState;
}
bool AreaTask::isCompleted() {
if (bIsCompleted) return true;
bool complete = false;
switch (m_completionState) {
case eAreaTaskCompletion_CompleteOnConstraintsSatisfied: {
bool allSatisfied = true;
for (auto it = constraints.begin(); it != constraints.end(); ++it) {
TutorialConstraint* constraint = *it;
if (!constraint->isConstraintSatisfied(tutorial->getPad())) {
allSatisfied = false;
break;
}
}
complete = allSatisfied;
} break;
case eAreaTaskCompletion_CompleteOnActivation:
complete = bHasBeenActivated;
break;
};
bIsCompleted = complete;
return complete;
}
void AreaTask::setAsCurrentTask(bool active) {
TutorialTask::setAsCurrentTask(active);
if (m_completionState ==
eAreaTaskCompletion_CompleteOnConstraintsSatisfied) {
enableConstraints(active);
}
}
void AreaTask::onStateChange(eTutorial_State newState) {
if (m_completionState == eAreaTaskCompletion_CompleteOnActivation) {
if (m_tutorialState == newState) {
enableConstraints(true);
} else if (m_tutorialState != e_Tutorial_State_Gameplay) {
// enableConstraints(false);
}
}
}

View File

@@ -0,0 +1,27 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
// A task that creates an maintains an area constraint until it is activated
class AreaTask : public TutorialTask {
public:
enum EAreaTaskCompletionStates {
eAreaTaskCompletion_CompleteOnActivation,
eAreaTaskCompletion_CompleteOnConstraintsSatisfied,
};
private:
EAreaTaskCompletionStates m_completionState;
eTutorial_State m_tutorialState;
public:
AreaTask(eTutorial_State state, Tutorial* tutorial,
std::vector<TutorialConstraint*>* inConstraints,
int descriptionId = -1,
EAreaTaskCompletionStates completionState =
eAreaTaskCompletion_CompleteOnActivation);
virtual bool isCompleted();
virtual void setAsCurrentTask(bool active = true);
virtual void onStateChange(eTutorial_State newState);
};

View File

@@ -0,0 +1,129 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include <string>
#include <unordered_map>
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
#include "../Tutorial.h"
#include "../Constraints/TutorialConstraints.h"
#include "ChoiceTask.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/material/Material.h"
ChoiceTask::ChoiceTask(
Tutorial* tutorial, int descriptionId, int promptId /*= -1*/,
bool requiresUserInput /*= false*/, int iConfirmMapping /*= 0*/,
int iCancelMapping /*= 0*/,
eTutorial_CompletionAction cancelAction /*= e_Tutorial_Completion_None*/,
ETelemetryChallenges telemetryEvent /*= eTelemetryTutorial_NoEvent*/)
: TutorialTask(tutorial, descriptionId, false, nullptr, true, false,
false) {
if (requiresUserInput == true) {
constraints.push_back(new InputConstraint(iConfirmMapping));
constraints.push_back(new InputConstraint(iCancelMapping));
}
m_iConfirmMapping = iConfirmMapping;
m_iCancelMapping = iCancelMapping;
m_bConfirmMappingComplete = false;
m_bCancelMappingComplete = false;
m_cancelAction = cancelAction;
m_promptId = promptId;
tutorial->addMessage(m_promptId);
m_eTelemetryEvent = telemetryEvent;
}
bool ChoiceTask::isCompleted() {
Minecraft* pMinecraft = Minecraft::GetInstance();
if (m_bConfirmMappingComplete || m_bCancelMappingComplete) {
sendTelemetry();
enableConstraints(false, true);
return true;
}
if (ui.GetMenuDisplayed(tutorial->getPad())) {
// If a menu is displayed, then we use the handleUIInput to complete the
// task
} else {
// If the player is under water then allow all keypresses so they can
// jump out
if (pMinecraft->localplayers[tutorial->getPad()]->isUnderLiquid(
Material::water))
return false;
if (!m_bConfirmMappingComplete &&
InputManager.GetValue(pMinecraft->player->GetXboxPad(),
m_iConfirmMapping) > 0) {
m_bConfirmMappingComplete = true;
}
if (!m_bCancelMappingComplete &&
InputManager.GetValue(pMinecraft->player->GetXboxPad(),
m_iCancelMapping) > 0) {
m_bCancelMappingComplete = true;
}
}
if (m_bConfirmMappingComplete || m_bCancelMappingComplete) {
sendTelemetry();
enableConstraints(false, true);
}
return m_bConfirmMappingComplete || m_bCancelMappingComplete;
}
eTutorial_CompletionAction ChoiceTask::getCompletionAction() {
if (m_bCancelMappingComplete) {
return m_cancelAction;
} else {
return e_Tutorial_Completion_None;
}
}
int ChoiceTask::getPromptId() {
if (m_bShownForMinimumTime)
return m_promptId;
else
return -1;
}
void ChoiceTask::setAsCurrentTask(bool active /*= true*/) {
enableConstraints(active);
TutorialTask::setAsCurrentTask(active);
}
void ChoiceTask::handleUIInput(int iAction) {
if (bHasBeenActivated && m_bShownForMinimumTime) {
if (iAction == m_iConfirmMapping) {
m_bConfirmMappingComplete = true;
} else if (iAction == m_iCancelMapping) {
m_bCancelMappingComplete = true;
}
}
}
void ChoiceTask::sendTelemetry() {
Minecraft* pMinecraft = Minecraft::GetInstance();
if (m_eTelemetryEvent != eTelemetryChallenges_Unknown) {
bool firstPlay = true;
// We only store first play for some of the events
switch (m_eTelemetryEvent) {
case eTelemetryTutorial_TrialStart:
firstPlay =
!tutorial->getCompleted(eTutorial_Telemetry_TrialStart);
tutorial->setCompleted(eTutorial_Telemetry_TrialStart);
break;
case eTelemetryTutorial_Halfway:
firstPlay =
!tutorial->getCompleted(eTutorial_Telemetry_Halfway);
tutorial->setCompleted(eTutorial_Telemetry_Halfway);
break;
default:
break;
};
TelemetryManager->RecordEnemyKilledOrOvercome(
pMinecraft->player->GetXboxPad(), 0, 0, 0, 0, 0, 0,
m_eTelemetryEvent);
}
}

View File

@@ -0,0 +1,32 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
// Information messages with a choice
class ChoiceTask : public TutorialTask {
private:
int m_iConfirmMapping, m_iCancelMapping;
bool m_bConfirmMappingComplete, m_bCancelMappingComplete;
eTutorial_CompletionAction m_cancelAction;
ETelemetryChallenges m_eTelemetryEvent;
bool CompletionMaskIsValid();
public:
ChoiceTask(
Tutorial* tutorial, int descriptionId, int promptId = -1,
bool requiresUserInput = false, int iConfirmMapping = 0,
int iCancelMapping = 0,
eTutorial_CompletionAction cancelAction = e_Tutorial_Completion_None,
ETelemetryChallenges telemetryEvent = eTelemetryChallenges_Unknown);
virtual bool isCompleted();
virtual eTutorial_CompletionAction getCompletionAction();
virtual int getPromptId();
virtual void setAsCurrentTask(bool active = true);
virtual void handleUIInput(int iAction);
private:
void sendTelemetry();
};

View File

@@ -0,0 +1,30 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/ItemInstance.h"
#include "CompleteUsingItemTask.h"
CompleteUsingItemTask::CompleteUsingItemTask(Tutorial* tutorial,
int descriptionId, int itemIds[],
unsigned int itemIdsLength,
bool enablePreCompletion)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, nullptr) {
m_iValidItemsA = new int[itemIdsLength];
for (int i = 0; i < itemIdsLength; i++) {
m_iValidItemsA[i] = itemIds[i];
}
m_iValidItemsCount = itemIdsLength;
}
CompleteUsingItemTask::~CompleteUsingItemTask() { delete[] m_iValidItemsA; }
bool CompleteUsingItemTask::isCompleted() { return bIsCompleted; }
void CompleteUsingItemTask::completeUsingItem(
std::shared_ptr<ItemInstance> item) {
if (!hasBeenActivated() && !isPreCompletionEnabled()) return;
for (int i = 0; i < m_iValidItemsCount; i++) {
if (item->id == m_iValidItemsA[i]) {
bIsCompleted = true;
break;
}
}
}

View File

@@ -0,0 +1,21 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
class Level;
class CompleteUsingItemTask : public TutorialTask {
private:
int* m_iValidItemsA;
int m_iValidItemsCount;
bool completed;
public:
CompleteUsingItemTask(Tutorial* tutorial, int descriptionId, int itemIds[],
unsigned int itemIdsLength,
bool enablePreCompletion = false);
virtual ~CompleteUsingItemTask();
virtual bool isCompleted();
virtual void completeUsingItem(std::shared_ptr<ItemInstance> item);
};

View File

@@ -0,0 +1,120 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include <string>
#include <unordered_map>
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
#include "../Tutorial.h"
#include "../Constraints/TutorialConstraints.h"
#include "ControllerTask.h"
ControllerTask::ControllerTask(Tutorial* tutorial, int descriptionId,
bool enablePreCompletion, bool showMinimumTime,
int mappings[], unsigned int mappingsLength,
int iCompletionMaskA[],
int iCompletionMaskACount,
int iSouthpawMappings[],
unsigned int uiSouthpawMappingsCount)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, nullptr,
showMinimumTime) {
for (unsigned int i = 0; i < mappingsLength; ++i) {
constraints.push_back(new InputConstraint(mappings[i]));
completedMappings[mappings[i]] = false;
}
if (uiSouthpawMappingsCount > 0) m_bHasSouthpaw = true;
for (unsigned int i = 0; i < uiSouthpawMappingsCount; ++i) {
southpawCompletedMappings[iSouthpawMappings[i]] = false;
}
m_iCompletionMaskA = new int[iCompletionMaskACount];
for (int i = 0; i < iCompletionMaskACount; i++) {
m_iCompletionMaskA[i] = iCompletionMaskA[i];
}
m_iCompletionMaskACount = iCompletionMaskACount;
m_uiCompletionMask = 0;
// If we don't want to be able to complete it early..then assume we want the
// constraints active
// if( !enablePreCompletion )
// enableConstraints( true );
m_initialized = false; // we can set yaw + pitch on the first tick
}
ControllerTask::~ControllerTask() { delete[] m_iCompletionMaskA; }
bool ControllerTask::isCompleted() {
if (bIsCompleted) return true;
Minecraft* pMinecraft = Minecraft::GetInstance();
// mouse look check
if (!m_initialized) {
m_lastYaw = pMinecraft->player->yRot;
m_lastPitch = pMinecraft->player->xRot;
m_initialized = true;
} else {
float deltaYaw = fabs(pMinecraft->player->yRot - m_lastYaw);
float deltaPitch = fabs(pMinecraft->player->xRot - m_lastPitch);
m_lastYaw = pMinecraft->player->yRot;
m_lastPitch = pMinecraft->player->xRot;
const float LOOK_THRESHOLD = 0.1f;
if (deltaYaw > LOOK_THRESHOLD || deltaPitch > LOOK_THRESHOLD)
return true;
}
// check for controller button input
bool bAllComplete = true;
int iCurrent = 0;
if (m_bHasSouthpaw && app.GetGameSettings(pMinecraft->player->GetXboxPad(),
eGameSetting_ControlSouthPaw)) {
for (auto it = southpawCompletedMappings.begin();
it != southpawCompletedMappings.end(); ++it) {
if (!it->second) {
if (InputManager.GetValue(pMinecraft->player->GetXboxPad(),
it->first) > 0) {
it->second = true;
m_uiCompletionMask |= 1 << iCurrent;
} else {
bAllComplete = false;
}
}
iCurrent++;
}
} else {
for (auto it = completedMappings.begin(); it != completedMappings.end();
++it) {
if (!it->second) {
if (InputManager.GetValue(pMinecraft->player->GetXboxPad(),
it->first) > 0) {
it->second = true;
m_uiCompletionMask |= 1 << iCurrent;
} else {
bAllComplete = false;
}
}
iCurrent++;
}
}
// completion mask check
if (m_iCompletionMaskA && CompletionMaskIsValid())
bIsCompleted = true;
else
bIsCompleted = bAllComplete;
return bIsCompleted;
}
bool ControllerTask::CompletionMaskIsValid() {
for (int i = 0; i < m_iCompletionMaskACount; i++) {
if (m_uiCompletionMask == m_iCompletionMaskA[i]) return true;
}
return false;
}
void ControllerTask::setAsCurrentTask(bool active /*= true*/) {
TutorialTask::setAsCurrentTask(active);
enableConstraints(!active);
}

View File

@@ -0,0 +1,33 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
// 4J Stu - Tasks that involve using the controller
class ControllerTask : public TutorialTask {
private:
std::unordered_map<int, bool> completedMappings;
std::unordered_map<int, bool> southpawCompletedMappings;
bool m_bHasSouthpaw;
unsigned int m_uiCompletionMask;
int* m_iCompletionMaskA;
int m_iCompletionMaskACount;
bool CompletionMaskIsValid();
// Mouse tracking for tutorial look-around task
float m_lastYaw;
float m_lastPitch;
bool m_initialized = false;
public:
ControllerTask(Tutorial* tutorial, int descriptionId,
bool enablePreCompletion, bool showMinimumTime,
int mappings[], unsigned int mappingsLength,
int iCompletionMaskA[] = nullptr,
int iCompletionMaskACount = 0,
int iSouthpawMappings[] = nullptr,
unsigned int uiSouthpawMappingsCount = 0);
~ControllerTask();
virtual bool isCompleted();
virtual void setAsCurrentTask(bool active = true);
};

View File

@@ -0,0 +1,66 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "CraftTask.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/net.minecraft.world.item.h"
CraftTask::CraftTask(
int itemId, int auxValue, int quantity, Tutorial* tutorial,
int descriptionId, bool enablePreCompletion /*= true*/,
std::vector<TutorialConstraint*>* inConstraints /*= nullptr*/,
bool bShowMinimumTime /*=false*/, bool bAllowFade /*=true*/,
bool m_bTaskReminders /*=true*/)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, inConstraints,
bShowMinimumTime, bAllowFade, m_bTaskReminders),
m_quantity(quantity),
m_count(0) {
m_numItems = 1;
m_items = new int[1];
m_items[0] = itemId;
m_auxValues = new int[1];
m_auxValues[0] = auxValue;
}
CraftTask::CraftTask(
int* items, int* auxValues, int numItems, int quantity, Tutorial* tutorial,
int descriptionId, bool enablePreCompletion /*= true*/,
std::vector<TutorialConstraint*>* inConstraints /*= nullptr*/,
bool bShowMinimumTime /*=false*/, bool bAllowFade /*=true*/,
bool m_bTaskReminders /*=true*/)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, inConstraints,
bShowMinimumTime, bAllowFade, m_bTaskReminders),
m_quantity(quantity),
m_count(0) {
m_numItems = numItems;
m_items = new int[m_numItems];
m_auxValues = new int[m_numItems];
for (int i = 0; i < m_numItems; ++i) {
m_items[i] = items[i];
m_auxValues[i] = auxValues[i];
}
}
CraftTask::~CraftTask() {
delete[] m_items;
delete[] m_auxValues;
}
void CraftTask::onCrafted(std::shared_ptr<ItemInstance> item) {
#ifndef _CONTENT_PACKAGE
wprintf(L"CraftTask::onCrafted - %ls\n", item->toString().c_str());
#endif
bool itemFound = false;
for (int i = 0; i < m_numItems; ++i) {
if (m_items[i] == item->id &&
(m_auxValues[i] == -1 || m_auxValues[i] == item->getAuxValue())) {
itemFound = true;
break;
}
}
if (itemFound) {
++m_count;
}
if (m_count >= m_quantity) {
bIsCompleted = true;
}
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include "TutorialTask.h"
class CraftTask : public TutorialTask {
public:
CraftTask(int itemId, int auxValue, int quantity, Tutorial* tutorial,
int descriptionId, bool enablePreCompletion = true,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool m_bTaskReminders = true);
CraftTask(int* items, int* auxValues, int numItems, int quantity,
Tutorial* tutorial, int descriptionId,
bool enablePreCompletion = true,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool m_bTaskReminders = true);
~CraftTask();
virtual bool isCompleted() { return bIsCompleted; }
virtual void onCrafted(std::shared_ptr<ItemInstance> item);
private:
int* m_items;
int* m_auxValues;
int m_numItems;
int m_quantity;
int m_count;
};

View File

@@ -0,0 +1,27 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/effect/net.minecraft.world.effect.h"
#include "EffectChangedTask.h"
EffectChangedTask::EffectChangedTask(Tutorial* tutorial, int descriptionId,
MobEffect* effect, bool apply,
bool enablePreCompletion,
bool bShowMinimumTime, bool bAllowFade,
bool bTaskReminders)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, nullptr,
bShowMinimumTime, bAllowFade, bTaskReminders) {
m_effect = effect;
m_apply = apply;
}
bool EffectChangedTask::isCompleted() { return bIsCompleted; }
void EffectChangedTask::onEffectChanged(MobEffect* effect,
bool bRemoved /*=false*/) {
if (effect == m_effect) {
if (m_apply == !bRemoved) {
bIsCompleted = true;
} else {
bIsCompleted = false;
}
}
}

View File

@@ -0,0 +1,20 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
class MobEffect;
class EffectChangedTask : public TutorialTask {
private:
MobEffect* m_effect;
bool m_apply;
public:
EffectChangedTask(Tutorial* tutorial, int descriptionId, MobEffect* effect,
bool apply = true, bool enablePreCompletion = true,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool bTaskReminders = true);
virtual bool isCompleted();
virtual void onEffectChanged(MobEffect* effect, bool bRemoved = false);
};

View File

@@ -0,0 +1,20 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../Tutorial.h"
#include "FullTutorialActiveTask.h"
FullTutorialActiveTask::FullTutorialActiveTask(
Tutorial* tutorial,
eTutorial_CompletionAction completeAction /*= e_Tutorial_Completion_None*/)
: TutorialTask(tutorial, -1, false, nullptr, false, false, false) {
m_completeAction = completeAction;
}
bool FullTutorialActiveTask::isCompleted() { return bHasBeenActivated; }
eTutorial_CompletionAction FullTutorialActiveTask::getCompletionAction() {
if (tutorial->m_fullTutorialComplete) {
return m_completeAction;
} else {
return e_Tutorial_Completion_None;
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
// Information messages with a choice
class FullTutorialActiveTask : public TutorialTask {
private:
eTutorial_CompletionAction m_completeAction;
bool CompletionMaskIsValid();
public:
FullTutorialActiveTask(
Tutorial* tutorial,
eTutorial_CompletionAction completeAction = e_Tutorial_Completion_None);
virtual bool isCompleted();
virtual eTutorial_CompletionAction getCompletionAction();
};

View File

@@ -0,0 +1,47 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include <string>
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../Tutorial.h"
#include "../../../../../Minecraft.World/net/minecraft/world/entity/animal/EntityHorse.h"
#include "HorseChoiceTask.h"
HorseChoiceTask::HorseChoiceTask(Tutorial* tutorial, int iDescHorse,
int iDescDonkey, int iDescMule, int iPromptId,
bool requiresUserInput, int iConfirmMapping,
int iCancelMapping,
eTutorial_CompletionAction cancelAction,
ETelemetryChallenges telemetryEvent)
: ChoiceTask(tutorial, -1, iPromptId, requiresUserInput, iConfirmMapping,
iCancelMapping, cancelAction, telemetryEvent) {
m_eHorseType = -1;
m_iDescMule = iDescMule;
m_iDescDonkey = iDescDonkey;
m_iDescHorse = iDescHorse;
}
int HorseChoiceTask::getDescriptionId() {
switch (m_eHorseType) {
case EntityHorse::TYPE_HORSE:
return m_iDescHorse;
case EntityHorse::TYPE_DONKEY:
return m_iDescDonkey;
case EntityHorse::TYPE_MULE:
return m_iDescMule;
default:
return -1;
}
return -1;
}
void HorseChoiceTask::onLookAtEntity(std::shared_ptr<Entity> entity) {
if ((m_eHorseType < 0) && entity->instanceof(eTYPE_HORSE)) {
std::shared_ptr<EntityHorse> horse =
std::dynamic_pointer_cast<EntityHorse>(entity);
if (horse->isAdult()) m_eHorseType = horse->getType();
}
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include "ChoiceTask.h"
// Same as choice task, but switches description based on horse type.
class HorseChoiceTask : public ChoiceTask {
protected:
int m_eHorseType;
int m_iDescHorse, m_iDescDonkey, m_iDescMule;
public:
HorseChoiceTask(
Tutorial* tutorial, int iDescHorse, int iDescDonkey, int iDescMule,
int iPromptId = -1, bool requiresUserInput = false,
int iConfirmMapping = 0, int iCancelMapping = 0,
eTutorial_CompletionAction cancelAction = e_Tutorial_Completion_None,
ETelemetryChallenges telemetryEvent = eTelemetryChallenges_Unknown);
virtual int getDescriptionId();
virtual void onLookAtEntity(std::shared_ptr<Entity> entity);
};

View File

@@ -0,0 +1,126 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include <string>
#include <unordered_map>
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
#include "../Tutorial.h"
#include "../Constraints/TutorialConstraints.h"
#include "InfoTask.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/material/Material.h"
InfoTask::InfoTask(
Tutorial* tutorial, int descriptionId, int promptId /*= -1*/,
bool requiresUserInput /*= false*/, int iMapping /*= 0*/,
ETelemetryChallenges telemetryEvent /*= eTelemetryTutorial_NoEvent*/)
: TutorialTask(tutorial, descriptionId, false, nullptr, true, false,
false) {
if (requiresUserInput == true) {
constraints.push_back(new InputConstraint(iMapping));
}
completedMappings[iMapping] = false;
m_promptId = promptId;
tutorial->addMessage(m_promptId);
m_eTelemetryEvent = telemetryEvent;
}
bool InfoTask::isCompleted() {
if (bIsCompleted) return true;
if (tutorial->m_hintDisplayed) return false;
if (!bHasBeenActivated || !m_bShownForMinimumTime) return false;
bool bAllComplete = true;
Minecraft* pMinecraft = Minecraft::GetInstance();
// If the player is under water then allow all keypresses so they can jump
// out
if (pMinecraft->localplayers[tutorial->getPad()]->isUnderLiquid(
Material::water))
return false;
if (ui.GetMenuDisplayed(tutorial->getPad())) {
// If a menu is displayed, then we use the handleUIInput to complete the
// task
bAllComplete = true;
for (auto it = completedMappings.begin(); it != completedMappings.end();
++it) {
bool current = (*it).second;
if (!current) {
bAllComplete = false;
break;
}
}
} else {
int iCurrent = 0;
for (auto it = completedMappings.begin(); it != completedMappings.end();
++it) {
bool current = (*it).second;
if (!current) {
if (InputManager.GetValue(pMinecraft->player->GetXboxPad(),
(*it).first) > 0) {
(*it).second = true;
bAllComplete = true;
} else {
bAllComplete = false;
}
}
iCurrent++;
}
}
if (bAllComplete == true) {
sendTelemetry();
enableConstraints(false, true);
}
bIsCompleted = bAllComplete;
return bAllComplete;
}
int InfoTask::getPromptId() {
if (m_bShownForMinimumTime)
return m_promptId;
else
return -1;
}
void InfoTask::setAsCurrentTask(bool active /*= true*/) {
enableConstraints(active);
TutorialTask::setAsCurrentTask(active);
}
void InfoTask::handleUIInput(int iAction) {
if (bHasBeenActivated) {
for (auto it = completedMappings.begin(); it != completedMappings.end();
++it) {
if (iAction == (*it).first) {
(*it).second = true;
}
}
}
}
void InfoTask::sendTelemetry() {
Minecraft* pMinecraft = Minecraft::GetInstance();
if (m_eTelemetryEvent != eTelemetryChallenges_Unknown) {
bool firstPlay = true;
// We only store first play for some of the events
switch (m_eTelemetryEvent) {
case eTelemetryTutorial_Complete:
firstPlay =
!tutorial->getCompleted(eTutorial_Telemetry_Complete);
tutorial->setCompleted(eTutorial_Telemetry_Complete);
break;
default:
break;
};
TelemetryManager->RecordEnemyKilledOrOvercome(
pMinecraft->player->GetXboxPad(), 0, 0, 0, 0, 0, 0,
m_eTelemetryEvent);
}
}

View File

@@ -0,0 +1,27 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
// Information messages
class InfoTask : public TutorialTask {
private:
std::unordered_map<int, bool> completedMappings;
ETelemetryChallenges m_eTelemetryEvent;
bool CompletionMaskIsValid();
public:
InfoTask(
Tutorial* tutorial, int descriptionId, int promptId = -1,
bool requiresUserInput = false, int iMapping = 0,
ETelemetryChallenges telemetryEvent = eTelemetryChallenges_Unknown);
virtual bool isCompleted();
virtual int getPromptId();
virtual void setAsCurrentTask(bool active = true);
virtual void handleUIInput(int iAction);
private:
void sendTelemetry();
};

View File

@@ -0,0 +1,15 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "PickupTask.h"
void PickupTask::onTake(std::shared_ptr<ItemInstance> item,
unsigned int invItemCountAnyAux,
unsigned int invItemCountThisAux) {
if (item->id == m_itemId) {
if (m_auxValue == -1 && invItemCountAnyAux >= m_quantity) {
bIsCompleted = true;
} else if (m_auxValue == item->getAuxValue() &&
invItemCountThisAux >= m_quantity) {
bIsCompleted = true;
}
}
}

View File

@@ -0,0 +1,31 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
class ItemInstance;
class PickupTask : public TutorialTask {
public:
PickupTask(int itemId, unsigned int quantity, int auxValue,
Tutorial* tutorial, int descriptionId,
bool enablePreCompletion = true,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool m_bTaskReminders = true)
: TutorialTask(tutorial, descriptionId, enablePreCompletion,
inConstraints, bShowMinimumTime, bAllowFade,
m_bTaskReminders),
m_itemId(itemId),
m_quantity(quantity),
m_auxValue(auxValue) {}
virtual bool isCompleted() { return bIsCompleted; }
virtual void onTake(std::shared_ptr<ItemInstance> item,
unsigned int invItemCountAnyAux,
unsigned int invItemCountThisAux);
private:
int m_itemId;
unsigned int m_quantity;
int m_auxValue;
};

View File

@@ -0,0 +1,212 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "ProcedureCompoundTask.h"
ProcedureCompoundTask::~ProcedureCompoundTask() {
for (auto it = m_taskSequence.begin(); it < m_taskSequence.end(); ++it) {
delete (*it);
}
}
void ProcedureCompoundTask::AddTask(TutorialTask* task) {
if (task != nullptr) {
m_taskSequence.push_back(task);
}
}
int ProcedureCompoundTask::getDescriptionId() {
if (bIsCompleted) return -1;
// Return the id of the first task not completed
int descriptionId = -1;
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (!task->isCompleted()) {
task->setAsCurrentTask(true);
descriptionId = task->getDescriptionId();
break;
} else if (task->getCompletionAction() ==
e_Tutorial_Completion_Complete_State) {
bIsCompleted = true;
break;
}
}
return descriptionId;
}
int ProcedureCompoundTask::getPromptId() {
if (bIsCompleted) return -1;
// Return the id of the first task not completed
int promptId = -1;
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (!task->isCompleted()) {
promptId = task->getPromptId();
break;
}
}
return promptId;
}
bool ProcedureCompoundTask::isCompleted() {
// Return whether all tasks are completed
bool allCompleted = true;
bool isCurrentTask = true;
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (allCompleted && isCurrentTask) {
if (task->isCompleted()) {
if (task->getCompletionAction() ==
e_Tutorial_Completion_Complete_State) {
allCompleted = true;
break;
}
} else {
task->setAsCurrentTask(true);
allCompleted = false;
isCurrentTask = false;
}
} else if (!allCompleted) {
task->setAsCurrentTask(false);
}
}
if (allCompleted) {
// Disable all constraints
itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
task->enableConstraints(false);
}
}
bIsCompleted = allCompleted;
return allCompleted;
}
void ProcedureCompoundTask::onCrafted(std::shared_ptr<ItemInstance> item) {
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
task->onCrafted(item);
}
}
void ProcedureCompoundTask::handleUIInput(int iAction) {
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
task->handleUIInput(iAction);
}
}
void ProcedureCompoundTask::setAsCurrentTask(bool active /*= true*/) {
bool allCompleted = true;
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (allCompleted && !task->isCompleted()) {
task->setAsCurrentTask(true);
allCompleted = false;
} else if (!allCompleted) {
task->setAsCurrentTask(false);
}
}
}
bool ProcedureCompoundTask::ShowMinimumTime() {
if (bIsCompleted) return false;
bool showMinimumTime = false;
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (!task->isCompleted()) {
showMinimumTime = task->ShowMinimumTime();
break;
}
}
return showMinimumTime;
}
bool ProcedureCompoundTask::hasBeenActivated() {
if (bIsCompleted) return true;
bool hasBeenActivated = false;
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (!task->isCompleted()) {
hasBeenActivated = task->hasBeenActivated();
break;
}
}
return hasBeenActivated;
}
void ProcedureCompoundTask::setShownForMinimumTime() {
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (!task->isCompleted()) {
task->setShownForMinimumTime();
break;
}
}
}
bool ProcedureCompoundTask::AllowFade() {
if (bIsCompleted) return true;
bool allowFade = true;
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
if (!task->isCompleted()) {
allowFade = task->AllowFade();
break;
}
}
return allowFade;
}
void ProcedureCompoundTask::useItemOn(Level* level,
std::shared_ptr<ItemInstance> item, int x,
int y, int z, bool bTestUseOnly) {
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
task->useItemOn(level, item, x, y, z, bTestUseOnly);
}
}
void ProcedureCompoundTask::useItem(std::shared_ptr<ItemInstance> item,
bool bTestUseOnly) {
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
task->useItem(item, bTestUseOnly);
}
}
void ProcedureCompoundTask::onTake(std::shared_ptr<ItemInstance> item,
unsigned int invItemCountAnyAux,
unsigned int invItemCountThisAux) {
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
task->onTake(item, invItemCountAnyAux, invItemCountThisAux);
}
}
void ProcedureCompoundTask::onStateChange(eTutorial_State newState) {
auto itEnd = m_taskSequence.end();
for (auto it = m_taskSequence.begin(); it < itEnd; ++it) {
TutorialTask* task = *it;
task->onStateChange(newState);
}
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include "TutorialTask.h"
// A tutorial task that requires each of the task to be completed in order until
// the last one is complete. If an earlier task that was complete is now not
// complete then it's hint should be shown.
class ProcedureCompoundTask : public TutorialTask {
public:
ProcedureCompoundTask(Tutorial* tutorial)
: TutorialTask(tutorial, -1, false, nullptr, false, true, false) {}
~ProcedureCompoundTask();
void AddTask(TutorialTask* task);
virtual int getDescriptionId();
virtual int getPromptId();
virtual bool isCompleted();
virtual void onCrafted(std::shared_ptr<ItemInstance> item);
virtual void handleUIInput(int iAction);
virtual void setAsCurrentTask(bool active = true);
virtual bool ShowMinimumTime();
virtual bool hasBeenActivated();
virtual void setShownForMinimumTime();
virtual bool AllowFade();
virtual void useItemOn(Level* level, std::shared_ptr<ItemInstance> item,
int x, int y, int z, bool bTestUseOnly = false);
virtual void useItem(std::shared_ptr<ItemInstance> item,
bool bTestUseOnly = false);
virtual void onTake(std::shared_ptr<ItemInstance> item,
unsigned int invItemCountAnyAux,
unsigned int invItemCountThisAux);
virtual void onStateChange(eTutorial_State newState);
private:
std::vector<TutorialTask*> m_taskSequence;
};

View File

@@ -0,0 +1,15 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "ProgressFlagTask.h"
bool ProgressFlagTask::isCompleted() {
switch (m_type) {
case e_Progress_Set_Flag:
(*flags) |= m_mask;
bIsCompleted = true;
break;
case e_Progress_Flag_On:
bIsCompleted = ((*flags) & m_mask) == m_mask;
break;
}
return bIsCompleted;
}

View File

@@ -0,0 +1,27 @@
#pragma once
// using namespace std;
#include "../Tutorial.h"
#include "TutorialTask.h"
class ProgressFlagTask : public TutorialTask {
public:
enum EProgressFlagType {
e_Progress_Set_Flag,
e_Progress_Flag_On,
};
private:
char* flags; // Not a member of this object
char m_mask;
EProgressFlagType m_type;
public:
ProgressFlagTask(char* flags, char mask, EProgressFlagType type,
Tutorial* tutorial)
: TutorialTask(tutorial, -1, false, nullptr),
flags(flags),
m_mask(mask),
m_type(type) {}
virtual bool isCompleted();
};

View File

@@ -0,0 +1,27 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include <string>
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../Tutorial.h"
#include "../../../../../Minecraft.World/net/minecraft/world/entity/animal/EntityHorse.h"
#include "RideEntityTask.h"
RideEntityTask::RideEntityTask(const int eType, Tutorial* tutorial,
int descriptionId, bool enablePreCompletion,
std::vector<TutorialConstraint*>* inConstraints,
bool bShowMinimumTime, bool bAllowFade,
bool bTaskReminders)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, inConstraints,
bShowMinimumTime, bAllowFade, bTaskReminders),
m_eType(eType) {}
bool RideEntityTask::isCompleted() { return bIsCompleted; }
void RideEntityTask::onRideEntity(std::shared_ptr<Entity> entity) {
if (entity->instanceof((eINSTANCEOF)m_eType)) {
bIsCompleted = true;
}
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "TutorialTask.h"
class Level;
// 4J-JEV: Tasks that involve riding an entity.
class RideEntityTask : public TutorialTask {
protected:
const int m_eType;
public:
RideEntityTask(const int eTYPE, Tutorial* tutorial, int descriptionId,
bool enablePreCompletion = false,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool bTaskReminders = true);
virtual bool isCompleted();
virtual void onRideEntity(std::shared_ptr<Entity> entity);
};

View File

@@ -0,0 +1,27 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../net/minecraft/client/Minecraft.h"
#include "../../../../net/minecraft/client/player/LocalPlayer.h"
#include "../../../../net/minecraft/stats/StatsCounter.h"
#include "../../../../../Minecraft.World/net/minecraft/stats/net.minecraft.stats.h"
#include "StatTask.h"
StatTask::StatTask(Tutorial* tutorial, int descriptionId,
bool enablePreCompletion, Stat* stat, int variance /*= 1*/)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, nullptr) {
this->stat = stat;
Minecraft* minecraft = Minecraft::GetInstance();
targetValue =
minecraft->stats[ProfileManager.GetPrimaryPad()]->getTotalValue(stat) +
variance;
}
bool StatTask::isCompleted() {
if (bIsCompleted) return true;
Minecraft* minecraft = Minecraft::GetInstance();
bIsCompleted =
minecraft->stats[ProfileManager.GetPrimaryPad()]->getTotalValue(stat) >=
(unsigned int)targetValue;
return bIsCompleted;
}

View File

@@ -0,0 +1,19 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
class Stat;
// 4J Stu - Tutorial tasks that can use the current stat trackin code. This is
// things like blocks mined/items crafted.
class StatTask : public TutorialTask {
private:
Stat* stat;
int targetValue;
public:
StatTask(Tutorial* tutorial, int descriptionId, bool enablePreCompletion,
Stat* stat, int variance = 1);
virtual bool isCompleted();
};

View File

@@ -0,0 +1,28 @@
#pragma once
// using namespace std;
#include "../Tutorial.h"
#include "TutorialTask.h"
class StateChangeTask : public TutorialTask {
private:
eTutorial_State m_state;
public:
StateChangeTask(eTutorial_State state, Tutorial* tutorial,
int descriptionId = -1, bool enablePreCompletion = false,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool m_bTaskReminders = true)
: TutorialTask(tutorial, descriptionId, enablePreCompletion,
inConstraints, bShowMinimumTime, bAllowFade,
m_bTaskReminders),
m_state(state) {}
virtual bool isCompleted() { return bIsCompleted; }
virtual void onStateChange(eTutorial_State newState) {
if (newState == m_state) {
bIsCompleted = true;
}
}
};

View File

@@ -0,0 +1,74 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../Tutorial.h"
#include "../Constraints/TutorialConstraints.h"
#include "TutorialTask.h"
TutorialTask::TutorialTask(Tutorial* tutorial, int descriptionId,
bool enablePreCompletion,
std::vector<TutorialConstraint*>* inConstraints,
bool bShowMinimumTime, bool bAllowFade,
bool bTaskReminders)
: tutorial(tutorial),
descriptionId(descriptionId),
m_promptId(-1),
enablePreCompletion(enablePreCompletion),
areConstraintsEnabled(false),
bIsCompleted(false),
bHasBeenActivated(false),
m_bAllowFade(bAllowFade),
m_bTaskReminders(bTaskReminders),
m_bShowMinimumTime(bShowMinimumTime),
m_bShownForMinimumTime(false) {
if (inConstraints != nullptr) {
for (auto it = inConstraints->begin(); it < inConstraints->end();
++it) {
TutorialConstraint* constraint = *it;
constraints.push_back(constraint);
}
delete inConstraints;
}
tutorial->addMessage(descriptionId);
}
TutorialTask::~TutorialTask() {
enableConstraints(false);
for (auto it = constraints.begin(); it < constraints.end(); ++it) {
TutorialConstraint* constraint = *it;
if (constraint->getQueuedForRemoval()) {
constraint->setDeleteOnDeactivate(true);
} else {
delete constraint;
}
}
}
void TutorialTask::taskCompleted() {
if (areConstraintsEnabled == true) enableConstraints(false);
}
void TutorialTask::enableConstraints(bool enable,
bool delayRemove /*= false*/) {
if (!enable && (areConstraintsEnabled || !delayRemove)) {
// Remove
for (auto it = constraints.begin(); it != constraints.end(); ++it) {
TutorialConstraint* constraint = *it;
// app.DebugPrintf(">>>>>>>> %i\n", constraints.size());
tutorial->RemoveConstraint(constraint, delayRemove);
}
areConstraintsEnabled = false;
} else if (!areConstraintsEnabled && enable) {
// Add
for (auto it = constraints.begin(); it != constraints.end(); ++it) {
TutorialConstraint* constraint = *it;
tutorial->AddConstraint(constraint);
}
areConstraintsEnabled = true;
}
}
void TutorialTask::setAsCurrentTask(bool active /*= true*/) {
bHasBeenActivated = active;
}

View File

@@ -0,0 +1,81 @@
#pragma once
// using namespace std;
#include "../TutorialEnum.h"
class Level;
class Tutorial;
class TutorialConstraint;
class MobEffect;
// A class that represents each individual task in the tutorial.
//
// Members:
// enablePreCompletion - If this is true, then the player can complete this
// task out of sequence.
// This stops us asking them to do
// things they have already done
// constraints - A list of constraints which can be activated
// (as a whole).
// If they are active, then the
// constraints are removed when the task is completed
// areConstraintsEnabled- A flag which records whether or not we have added the
// constraints to the tutorial
class TutorialTask {
protected:
int descriptionId;
int m_promptId;
Tutorial* tutorial;
bool enablePreCompletion;
bool bHasBeenActivated;
bool m_bAllowFade;
bool m_bTaskReminders;
bool m_bShowMinimumTime;
protected:
bool bIsCompleted;
bool m_bShownForMinimumTime;
std::vector<TutorialConstraint*> constraints;
bool areConstraintsEnabled;
public:
TutorialTask(Tutorial* tutorial, int descriptionId,
bool enablePreCompletion,
std::vector<TutorialConstraint*>* inConstraints,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool bTaskReminders = true);
virtual ~TutorialTask();
virtual int getDescriptionId() { return descriptionId; }
virtual int getPromptId() { return m_promptId; }
virtual bool isCompleted() = 0;
virtual eTutorial_CompletionAction getCompletionAction() {
return e_Tutorial_Completion_None;
}
virtual bool isPreCompletionEnabled() { return enablePreCompletion; }
virtual void taskCompleted();
virtual void enableConstraints(bool enable, bool delayRemove = false);
virtual void setAsCurrentTask(bool active = true);
virtual void setShownForMinimumTime() { m_bShownForMinimumTime = true; }
virtual bool hasBeenActivated() { return bHasBeenActivated; }
virtual bool AllowFade() { return m_bAllowFade; }
bool TaskReminders() { return m_bTaskReminders; }
virtual bool ShowMinimumTime() { return m_bShowMinimumTime; }
virtual void useItemOn(Level* level, std::shared_ptr<ItemInstance> item,
int x, int y, int z, bool bTestUseOnly = false) {}
virtual void useItem(std::shared_ptr<ItemInstance> item,
bool bTestUseOnly = false) {}
virtual void completeUsingItem(std::shared_ptr<ItemInstance> item) {}
virtual void handleUIInput(int iAction) {}
virtual void onCrafted(std::shared_ptr<ItemInstance> item) {}
virtual void onTake(std::shared_ptr<ItemInstance> item,
unsigned int invItemCountAnyAux,
unsigned int invItemCountThisAux) {}
virtual void onStateChange(eTutorial_State newState) {}
virtual void onEffectChanged(MobEffect* effect, bool bRemoved = false) {}
virtual void onLookAtEntity(std::shared_ptr<Entity> entity) {}
virtual void onRideEntity(std::shared_ptr<Entity> entity) {}
};

View File

@@ -0,0 +1,19 @@
#pragma once
#include "StatTask.h"
#include "CraftTask.h"
#include "PickupTask.h"
#include "UseTileTask.h"
#include "UseItemTask.h"
#include "InfoTask.h"
#include "ControllerTask.h"
#include "ProcedureCompoundTask.h"
#include "XuiCraftingTask.h"
#include "StateChangeTask.h"
#include "ChoiceTask.h"
#include "HorseChoiceTask.h"
#include "RideEntityTask.h"
#include "FullTutorialActiveTask.h"
#include "AreaTask.h"
#include "ProgressFlagTask.h"
#include "CompleteUsingItemTask.h"
#include "EffectChangedTask.h"

View File

@@ -0,0 +1,23 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/entity/Entity.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/Level.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/ItemInstance.h"
#include "UseItemTask.h"
UseItemTask::UseItemTask(const int itemId, Tutorial* tutorial,
int descriptionId, bool enablePreCompletion,
std::vector<TutorialConstraint*>* inConstraints,
bool bShowMinimumTime, bool bAllowFade,
bool bTaskReminders)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, inConstraints,
bShowMinimumTime, bAllowFade, bTaskReminders),
itemId(itemId) {}
bool UseItemTask::isCompleted() { return bIsCompleted; }
void UseItemTask::useItem(std::shared_ptr<ItemInstance> item,
bool bTestUseOnly) {
if (bTestUseOnly) return;
if (item->id == itemId) bIsCompleted = true;
}

View File

@@ -0,0 +1,22 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
class Level;
// 4J Stu - Tasks that involve placing a tile
class UseItemTask : public TutorialTask {
private:
const int itemId;
public:
UseItemTask(const int itemId, Tutorial* tutorial, int descriptionId,
bool enablePreCompletion = false,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool bTaskReminders = true);
virtual bool isCompleted();
virtual void useItem(std::shared_ptr<ItemInstance> item,
bool bTestUseOnly = false);
};

View File

@@ -0,0 +1,45 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/entity/Entity.h"
#include "../../../../../Minecraft.World/net/minecraft/world/level/Level.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/ItemInstance.h"
#include "UseTileTask.h"
UseTileTask::UseTileTask(const int tileId, int x, int y, int z,
Tutorial* tutorial, int descriptionId,
bool enablePreCompletion,
std::vector<TutorialConstraint*>* inConstraints,
bool bShowMinimumTime, bool bAllowFade,
bool bTaskReminders)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, inConstraints,
bShowMinimumTime, bAllowFade, bTaskReminders),
x(x),
y(y),
z(z),
tileId(tileId) {
useLocation = true;
}
UseTileTask::UseTileTask(const int tileId, Tutorial* tutorial,
int descriptionId, bool enablePreCompletion,
std::vector<TutorialConstraint*>* inConstraints,
bool bShowMinimumTime, bool bAllowFade,
bool bTaskReminders)
: TutorialTask(tutorial, descriptionId, enablePreCompletion, inConstraints,
bShowMinimumTime, bAllowFade, bTaskReminders),
tileId(tileId) {
useLocation = false;
}
bool UseTileTask::isCompleted() { return bIsCompleted; }
void UseTileTask::useItemOn(Level* level, std::shared_ptr<ItemInstance> item,
int x, int y, int z, bool bTestUseOnly) {
if (bTestUseOnly) return;
if (!enablePreCompletion && !bHasBeenActivated) return;
if (!useLocation || (x == this->x && y == this->y && z == this->z)) {
int t = level->getTile(x, y, z);
if (t == tileId) bIsCompleted = true;
}
}

View File

@@ -0,0 +1,31 @@
#pragma once
// using namespace std;
#include "TutorialTask.h"
class Level;
// 4J Stu - Tasks that involve using a tile, with or without an item. e.g.
// Opening a chest
class UseTileTask : public TutorialTask {
private:
int x, y, z;
const int tileId;
bool useLocation;
bool completed;
public:
UseTileTask(const int tileId, int x, int y, int z, Tutorial* tutorial,
int descriptionId, bool enablePreCompletion = false,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool bTaskReminders = true);
UseTileTask(const int tileId, Tutorial* tutorial, int descriptionId,
bool enablePreCompletion = false,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool bTaskReminders = true);
virtual bool isCompleted();
virtual void useItemOn(Level* level, std::shared_ptr<ItemInstance> item,
int x, int y, int z, bool bTestUseOnly = false);
};

View File

@@ -0,0 +1,31 @@
#include "../../../../../Minecraft.World/Header Files/stdafx.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/ItemInstance.h"
#include "../../UI/UI.h"
#include "../Tutorial.h"
#include "XuiCraftingTask.h"
bool XuiCraftingTask::isCompleted() {
// This doesn't seem to work
// IUIScene_CraftingMenu *craftScene =
// reinterpret_cast<IUIScene_CraftingMenu *>(tutorial->getScene());
UIScene_CraftingMenu* craftScene =
reinterpret_cast<UIScene_CraftingMenu*>(tutorial->getScene());
bool completed = false;
switch (m_type) {
case e_Crafting_SelectGroup:
if (craftScene != nullptr &&
craftScene->getCurrentGroup() == m_group) {
completed = true;
}
break;
case e_Crafting_SelectItem:
if (craftScene != nullptr && craftScene->isItemSelected(m_item)) {
completed = true;
}
break;
}
return completed;
}

View File

@@ -0,0 +1,43 @@
#pragma once
#include "TutorialTask.h"
#include "../../../../../Minecraft.World/net/minecraft/world/item/crafting/Recipy.h"
class XuiCraftingTask : public TutorialTask {
public:
enum eCraftingTaskType {
e_Crafting_SelectGroup,
e_Crafting_SelectItem,
};
// Select group
XuiCraftingTask(Tutorial* tutorial, int descriptionId,
Recipy::_eGroupType groupToSelect,
bool enablePreCompletion = false,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool m_bTaskReminders = true)
: TutorialTask(tutorial, descriptionId, enablePreCompletion,
inConstraints, bShowMinimumTime, bAllowFade,
m_bTaskReminders),
m_group(groupToSelect),
m_type(e_Crafting_SelectGroup) {}
// Select Item
XuiCraftingTask(Tutorial* tutorial, int descriptionId, int itemId,
bool enablePreCompletion = false,
std::vector<TutorialConstraint*>* inConstraints = nullptr,
bool bShowMinimumTime = false, bool bAllowFade = true,
bool m_bTaskReminders = true)
: TutorialTask(tutorial, descriptionId, enablePreCompletion,
inConstraints, bShowMinimumTime, bAllowFade,
m_bTaskReminders),
m_item(itemId),
m_type(e_Crafting_SelectItem) {}
virtual bool isCompleted();
private:
eCraftingTaskType m_type;
Recipy::_eGroupType m_group;
int m_item;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
#pragma once
// using namespace std;
#include "Tasks/TutorialTask.h"
#include "Constraints/TutorialConstraint.h"
#include "Hints/TutorialHint.h"
#include "TutorialMessage.h"
#include "TutorialEnum.h"
#include <cstdint>
// #define TUTORIAL_HINT_DELAY_TIME 14000 // How long we should wait from
// displaying one hint to the next #define TUTORIAL_DISPLAY_MESSAGE_TIME 7000
// #define TUTORIAL_MINIMUM_DISPLAY_MESSAGE_TIME 2000
// #define TUTORIAL_REMINDER_TIME (TUTORIAL_DISPLAY_MESSAGE_TIME + 20000)
// #define TUTORIAL_CONSTRAINT_DELAY_REMOVE_TICKS 15
//
// // 0-24000
// #define TUTORIAL_FREEZE_TIME_VALUE 8000
class Level;
class CXuiScene;
class Tutorial {
public:
class PopupMessageDetails {
public:
int m_messageId;
int m_promptId;
int m_titleId;
std::wstring m_messageString;
std::wstring m_promptString;
std::wstring m_titleString;
int m_icon;
int m_iAuxVal;
bool m_allowFade;
bool m_isReminder;
bool m_replaceCurrent;
bool m_forceDisplay;
bool m_delay;
PopupMessageDetails() {
m_messageId = -1;
m_promptId = -1;
m_titleId = -1;
m_messageString = L"";
m_promptString = L"";
m_titleString = L"";
m_icon = TUTORIAL_NO_ICON;
m_iAuxVal = 0;
m_allowFade = true;
m_isReminder = false;
m_replaceCurrent = false;
m_forceDisplay = false;
m_delay = false;
}
bool isSameContent(PopupMessageDetails* other);
};
private:
static int m_iTutorialHintDelayTime;
static int m_iTutorialDisplayMessageTime;
static int m_iTutorialMinimumDisplayMessageTime;
static int m_iTutorialExtraReminderTime;
static int m_iTutorialReminderTime;
static int m_iTutorialConstraintDelayRemoveTicks;
static int m_iTutorialFreezeTimeValue;
eTutorial_State m_CurrentState;
bool m_hasStateChanged;
bool m_bSceneIsSplitscreen;
bool m_bHasTickedOnce;
int m_firstTickTime;
protected:
std::unordered_map<int, TutorialMessage*> messages;
std::vector<TutorialConstraint*> m_globalConstraints;
std::vector<TutorialConstraint*> constraints[e_Tutorial_State_Max];
std::vector<std::pair<TutorialConstraint*, unsigned char> >
constraintsToRemove[e_Tutorial_State_Max];
std::vector<TutorialTask*>
tasks; // We store a copy of the tasks for the main gameplay tutorial
// so that we could display an overview menu
std::vector<TutorialTask*> activeTasks[e_Tutorial_State_Max];
std::vector<TutorialHint*> hints[e_Tutorial_State_Max];
TutorialTask* currentTask[e_Tutorial_State_Max];
TutorialConstraint* currentFailedConstraint[e_Tutorial_State_Max];
bool m_freezeTime;
bool m_timeFrozen;
// D3DXVECTOR3 m_OriginalPosition;
public:
std::uint32_t lastMessageTime;
std::uint32_t m_lastHintDisplayedTime;
private:
PopupMessageDetails* m_lastMessage;
eTutorial_State m_lastMessageState;
unsigned int m_iTaskReminders;
bool m_allowShow;
public:
bool m_hintDisplayed;
private:
bool hasRequestedUI;
bool uiTempDisabled;
UIScene* m_UIScene;
int m_iPad;
public:
bool m_allTutorialsComplete;
bool m_fullTutorialComplete;
bool m_isFullTutorial;
public:
Tutorial(int iPad, bool isFullTutorial = false);
virtual ~Tutorial();
void tick();
int getPad() { return m_iPad; }
virtual bool isStateCompleted(eTutorial_State state);
virtual void setStateCompleted(eTutorial_State state);
bool isHintCompleted(eTutorial_Hint hint);
void setHintCompleted(eTutorial_Hint hint);
void setHintCompleted(TutorialHint* hint);
// completableId will be either a eTutorial_State value or eTutorial_Hint
void setCompleted(int completableId);
bool getCompleted(int completableId);
void changeTutorialState(eTutorial_State newState,
UIScene* scene = nullptr);
bool isSelectedItemState();
bool setMessage(PopupMessageDetails* message);
bool setMessage(TutorialHint* hint, PopupMessageDetails* message);
bool setMessage(const std::wstring& message, int icon, int auxValue);
void showTutorialPopup(bool show);
void useItemOn(Level* level, std::shared_ptr<ItemInstance> item, int x,
int y, int z, bool bTestUseOnly = false);
void useItemOn(std::shared_ptr<ItemInstance> item,
bool bTestUseOnly = false);
void completeUsingItem(std::shared_ptr<ItemInstance> item);
void startDestroyBlock(std::shared_ptr<ItemInstance> item, Tile* tile);
void destroyBlock(Tile* tile);
void attack(std::shared_ptr<Player> player, std::shared_ptr<Entity> entity);
void itemDamaged(std::shared_ptr<ItemInstance> item);
void handleUIInput(int iAction);
void createItemSelected(std::shared_ptr<ItemInstance> item, bool canMake);
void onCrafted(std::shared_ptr<ItemInstance> item);
void onTake(std::shared_ptr<ItemInstance> item,
unsigned int invItemCountAnyAux,
unsigned int invItemCountThisAux);
void onSelectedItemChanged(std::shared_ptr<ItemInstance> item);
void onLookAt(int id, int iData = 0);
void onLookAtEntity(std::shared_ptr<Entity> entity);
void onRideEntity(std::shared_ptr<Entity> entity);
void onEffectChanged(MobEffect* effect, bool bRemoved = false);
bool canMoveToPosition(double xo, double yo, double zo, double xt,
double yt, double zt);
bool isInputAllowed(int mapping);
void AddGlobalConstraint(TutorialConstraint* c);
void AddConstraint(TutorialConstraint* c);
void RemoveConstraint(TutorialConstraint* c, bool delayedRemove = false);
void addTask(eTutorial_State state, TutorialTask* t);
void addHint(eTutorial_State state, TutorialHint* h);
void addMessage(int messageId, bool limitRepeats = false,
unsigned char numRepeats = TUTORIAL_MESSAGE_DEFAULT_SHOW);
int GetTutorialDisplayMessageTime() {
return m_iTutorialDisplayMessageTime;
}
// Only for the main gameplay tutorial
std::vector<TutorialTask*>* getTasks();
unsigned int getCurrentTaskIndex();
UIScene* getScene() { return m_UIScene; }
eTutorial_State getCurrentState() { return m_CurrentState; }
// These are required so that we have a consistent mapping of the completion
// bits stored in the profile data
static void staticCtor();
static std::vector<int> s_completableTasks;
static void debugResetPlayerSavedProgress(int iPad);
};

View File

@@ -0,0 +1,361 @@
#pragma once
#include <cstdint>
typedef struct {
std::uint16_t index;
std::uint32_t diffsSize;
std::uint8_t* diffs;
std::uint32_t lastByteChanged;
} TutorialDiff_Chunk;
typedef struct {
std::uint32_t diffCount;
TutorialDiff_Chunk* diffs;
} TutorialDiff_File;
#define TUTORIAL_NO_TEXT -1
#define TUTORIAL_NO_ICON -1
// If you want to make these bigger, be aware that that will affect what is
// stored after the tutorial data in the profile data See Xbox_App.h for the
// struct
#define TUTORIAL_PROFILE_STORAGE_BITS 512
#define TUTORIAL_PROFILE_STORAGE_BYTES (TUTORIAL_PROFILE_STORAGE_BITS / 8)
// 4J Stu - The total number of eTutorial_State and eTutorial_Hint must be less
// than 512, as we only have 512 bits of profile data to flag whether or not the
// player has seen them In general a block or tool will have one each. We have a
// state if we need more than one message, or a hint if just once message will
// suffice Tasks added here should also be added in the Tutorial::staticCtor()
// if you wish to store completion in the profile data
enum eTutorial_State {
e_Tutorial_State_Any = -2,
e_Tutorial_State_None = -1,
e_Tutorial_State_Gameplay = 0,
e_Tutorial_State_Inventory_Menu,
e_Tutorial_State_2x2Crafting_Menu,
e_Tutorial_State_3x3Crafting_Menu,
e_Tutorial_State_Furnace_Menu,
e_Tutorial_State_Riding_Minecart,
e_Tutorial_State_Riding_Boat,
e_Tutorial_State_Fishing,
e_Tutorial_State_Bed,
e_Tutorial_State_Container_Menu,
e_Tutorial_State_Trap_Menu,
e_Tutorial_State_Redstone_And_Piston,
e_Tutorial_State_Portal,
e_Tutorial_State_Creative_Inventory_Menu, // Added TU5
e_Tutorial_State_Food_Bar, // Added TU5
e_Tutorial_State_CreativeMode, // Added TU7
e_Tutorial_State_Brewing,
e_Tutorial_State_Brewing_Menu,
e_Tutorial_State_Enchanting,
e_Tutorial_State_Enchanting_Menu,
e_Tutorial_State_Farming,
e_Tutorial_State_Breeding,
e_Tutorial_State_Golem,
e_Tutorial_State_Trading,
e_Tutorial_State_Trading_Menu,
e_Tutorial_State_Anvil,
e_Tutorial_State_Anvil_Menu,
e_Tutorial_State_Enderchests,
e_Tutorial_State_Horse,
e_Tutorial_State_Horse_Menu,
e_Tutorial_State_Hopper,
e_Tutorial_State_Hopper_Menu,
e_Tutorial_State_Beacon,
e_Tutorial_State_Beacon_Menu,
e_Tutorial_State_Fireworks,
e_Tutorial_State_Fireworks_Menu,
e_Tutorial_State_Max
};
// Hints added here should also be added in the Tutorial::staticCtor() if you
// wish to store completion in the profile data
enum eTutorial_Hint {
e_Tutorial_Hint_Always_On = e_Tutorial_State_Max,
e_Tutorial_Hint_Hold_To_Mine,
e_Tutorial_Hint_Tool_Damaged,
e_Tutorial_Hint_Swim_Up,
e_Tutorial_Hint_Unused_2,
e_Tutorial_Hint_Unused_3,
e_Tutorial_Hint_Unused_4,
e_Tutorial_Hint_Unused_5,
e_Tutorial_Hint_Unused_6,
e_Tutorial_Hint_Unused_7,
e_Tutorial_Hint_Unused_8,
e_Tutorial_Hint_Unused_9,
e_Tutorial_Hint_Unused_10,
e_Tutorial_Hint_Rock,
e_Tutorial_Hint_Stone,
e_Tutorial_Hint_Planks,
e_Tutorial_Hint_Sapling,
e_Tutorial_Hint_Unbreakable,
e_Tutorial_Hint_Water,
e_Tutorial_Hint_Lava,
e_Tutorial_Hint_Sand,
e_Tutorial_Hint_Gravel,
e_Tutorial_Hint_Gold_Ore,
e_Tutorial_Hint_Iron_Ore,
e_Tutorial_Hint_Coal_Ore,
e_Tutorial_Hint_Tree_Trunk,
e_Tutorial_Hint_Leaves,
e_Tutorial_Hint_Glass,
e_Tutorial_Hint_Lapis_Ore,
e_Tutorial_Hint_Lapis_Block,
e_Tutorial_Hint_Dispenser,
e_Tutorial_Hint_Sandstone,
e_Tutorial_Hint_Note_Block,
e_Tutorial_Hint_Powered_Rail,
e_Tutorial_Hint_Detector_Rail,
e_Tutorial_Hint_Tall_Grass,
e_Tutorial_Hint_Wool,
e_Tutorial_Hint_Flower,
e_Tutorial_Hint_Mushroom,
e_Tutorial_Hint_Gold_Block,
e_Tutorial_Hint_Iron_Block,
e_Tutorial_Hint_Stone_Slab,
e_Tutorial_Hint_Red_Brick,
e_Tutorial_Hint_Tnt,
e_Tutorial_Hint_Bookshelf,
e_Tutorial_Hint_Moss_Stone,
e_Tutorial_Hint_Obsidian,
e_Tutorial_Hint_Torch,
e_Tutorial_Hint_MobSpawner,
e_Tutorial_Hint_Chest,
e_Tutorial_Hint_Redstone,
e_Tutorial_Hint_Diamond_Ore,
e_Tutorial_Hint_Diamond_Block,
e_Tutorial_Hint_Crafting_Table,
e_Tutorial_Hint_Crops,
e_Tutorial_Hint_Farmland,
e_Tutorial_Hint_Furnace,
e_Tutorial_Hint_Sign,
e_Tutorial_Hint_Door_Wood,
e_Tutorial_Hint_Ladder,
e_Tutorial_Hint_Stairs_Stone,
e_Tutorial_Hint_Rail,
e_Tutorial_Hint_Lever,
e_Tutorial_Hint_PressurePlate,
e_Tutorial_Hint_Door_Iron,
e_Tutorial_Hint_Redstone_Ore,
e_Tutorial_Hint_Redstone_Torch,
e_Tutorial_Hint_Button,
e_Tutorial_Hint_Snow,
e_Tutorial_Hint_Ice,
e_Tutorial_Hint_Cactus,
e_Tutorial_Hint_Clay,
e_Tutorial_Hint_Sugarcane,
e_Tutorial_Hint_Record_Player,
e_Tutorial_Hint_Pumpkin,
e_Tutorial_Hint_Hell_Rock,
e_Tutorial_Hint_Hell_Sand,
e_Tutorial_Hint_Glowstone,
e_Tutorial_Hint_Portal,
e_Tutorial_Hint_Pumpkin_Lit,
e_Tutorial_Hint_Cake,
e_Tutorial_Hint_Redstone_Repeater,
e_Tutorial_Hint_Trapdoor,
e_Tutorial_Hint_Piston,
e_Tutorial_Hint_Sticky_Piston,
e_Tutorial_Hint_Monster_Stone_Egg,
e_Tutorial_Hint_Stone_Brick_Smooth,
e_Tutorial_Hint_Huge_Mushroom,
e_Tutorial_Hint_Iron_Fence,
e_Tutorial_Hint_Thin_Glass,
e_Tutorial_Hint_Melon,
e_Tutorial_Hint_Vine,
e_Tutorial_Hint_Fence_Gate,
e_Tutorial_Hint_Mycel,
e_Tutorial_Hint_Water_Lily,
e_Tutorial_Hint_Nether_Brick,
e_Tutorial_Hint_Nether_Fence,
e_Tutorial_Hint_Nether_Stalk,
e_Tutorial_Hint_Enchant_Table,
e_Tutorial_Hint_Brewing_Stand,
e_Tutorial_Hint_Cauldron,
e_Tutorial_Hint_End_Portal,
e_Tutorial_Hint_End_Portal_Frame,
e_Tutorial_Hint_Squid,
e_Tutorial_Hint_Cow,
e_Tutorial_Hint_Sheep,
e_Tutorial_Hint_Chicken,
e_Tutorial_Hint_Pig,
e_Tutorial_Hint_Wolf,
e_Tutorial_Hint_Creeper,
e_Tutorial_Hint_Skeleton,
e_Tutorial_Hint_Spider,
e_Tutorial_Hint_Zombie,
e_Tutorial_Hint_Pig_Zombie,
e_Tutorial_Hint_Ghast,
e_Tutorial_Hint_Slime,
e_Tutorial_Hint_Enderman,
e_Tutorial_Hint_Silverfish,
e_Tutorial_Hint_Cave_Spider,
e_Tutorial_Hint_MushroomCow,
e_Tutorial_Hint_SnowMan,
e_Tutorial_Hint_IronGolem,
e_Tutorial_Hint_EnderDragon,
e_Tutorial_Hint_Blaze,
e_Tutorial_Hint_Lava_Slime,
e_Tutorial_Hint_Ozelot,
e_Tutorial_Hint_Villager,
e_Tutorial_Hint_Wither,
e_Tutorial_Hint_Witch,
e_Tutorial_Hint_Bat,
e_Tutorial_Hint_Horse,
e_Tutorial_Hint_Item_Shovel,
e_Tutorial_Hint_Item_Hatchet,
e_Tutorial_Hint_Item_Pickaxe,
e_Tutorial_Hint_Item_Flint_And_Steel,
e_Tutorial_Hint_Item_Apple,
e_Tutorial_Hint_Item_Bow,
e_Tutorial_Hint_Item_Arrow,
e_Tutorial_Hint_Item_Coal,
e_Tutorial_Hint_Item_Diamond,
e_Tutorial_Hint_Item_Iron_Ingot,
e_Tutorial_Hint_Item_Gold_Ingot,
e_Tutorial_Hint_Item_Sword,
e_Tutorial_Hint_Item_Stick,
e_Tutorial_Hint_Item_Bowl,
e_Tutorial_Hint_Item_Mushroom_Stew,
e_Tutorial_Hint_Item_String,
e_Tutorial_Hint_Item_Feather,
e_Tutorial_Hint_Item_Sulphur,
e_Tutorial_Hint_Item_Hoe,
e_Tutorial_Hint_Item_Seeds,
e_Tutorial_Hint_Item_Wheat,
e_Tutorial_Hint_Item_Bread,
e_Tutorial_Hint_Item_Helmet,
e_Tutorial_Hint_Item_Chestplate,
e_Tutorial_Hint_Item_Leggings,
e_Tutorial_Hint_Item_Boots,
e_Tutorial_Hint_Item_Flint,
e_Tutorial_Hint_Item_Porkchop_Raw,
e_Tutorial_Hint_Item_Porkchop_Cooked,
e_Tutorial_Hint_Item_Painting,
e_Tutorial_Hint_Item_Apple_Gold,
e_Tutorial_Hint_Item_Sign,
e_Tutorial_Hint_Item_Door_Wood,
e_Tutorial_Hint_Item_Bucket_Empty,
e_Tutorial_Hint_Item_Bucket_Water,
e_Tutorial_Hint_Item_Bucket_Lava,
e_Tutorial_Hint_Item_Minecart,
e_Tutorial_Hint_Item_Saddle,
e_Tutorial_Hint_Item_Door_Iron,
e_Tutorial_Hint_Item_Redstone,
e_Tutorial_Hint_Item_Snowball,
e_Tutorial_Hint_Item_Boat,
e_Tutorial_Hint_Item_Leather,
e_Tutorial_Hint_Item_Milk,
e_Tutorial_Hint_Item_Brick,
e_Tutorial_Hint_Item_Clay,
e_Tutorial_Hint_Item_Reeds,
e_Tutorial_Hint_Item_Paper,
e_Tutorial_Hint_Item_Book,
e_Tutorial_Hint_Item_Slimeball,
e_Tutorial_Hint_Item_Minecart_Chest,
e_Tutorial_Hint_Item_Minecart_Furnace,
e_Tutorial_Hint_Item_Egg,
e_Tutorial_Hint_Item_Compass,
e_Tutorial_Hint_Item_Clock,
e_Tutorial_Hint_Item_Yellow_Dust,
e_Tutorial_Hint_Item_Fish_Raw,
e_Tutorial_Hint_Item_Fish_Cooked,
e_Tutorial_Hint_Item_Dye_Powder,
e_Tutorial_Hint_Item_Bone,
e_Tutorial_Hint_Item_Sugar,
e_Tutorial_Hint_Item_Cake,
e_Tutorial_Hint_Item_Diode,
e_Tutorial_Hint_Item_Cookie,
e_Tutorial_Hint_Item_Map,
e_Tutorial_Hint_Item_Record,
e_Tutorial_Hint_White_Stone,
e_Tutorial_Hint_Dragon_Egg,
e_Tutorial_Hint_RedstoneLamp,
e_Tutorial_Hint_Cocoa,
e_Tutorial_Hint_EmeraldOre,
e_Tutorial_Hint_EmeraldBlock,
e_Tutorial_Hint_EnderChest,
e_Tutorial_Hint_TripwireSource,
e_Tutorial_Hint_Tripwire,
e_Tutorial_Hint_CobblestoneWall,
e_Tutorial_Hint_Flowerpot,
e_Tutorial_Hint_Anvil,
e_Tutorial_Hint_QuartzOre,
e_Tutorial_Hint_QuartzBlock,
e_Tutorial_Hint_WoolCarpet,
e_Tutorial_Hint_Potato,
e_Tutorial_Hint_Carrot,
e_Tutorial_Hint_CommandBlock,
e_Tutorial_Hint_Beacon,
e_Tutorial_Hint_Activator_Rail,
e_Tutorial_Hint_RedstoneBlock,
e_Tutorial_Hint_DaylightDetector,
e_Tutorial_Hint_Dropper,
e_Tutorial_Hint_Hopper,
e_Tutorial_Hint_Comparator,
e_Tutorial_Hint_ChestTrap,
e_Tutorial_Hint_HayBlock,
e_Tutorial_Hint_ClayHardened,
e_Tutorial_Hint_ClayHardenedColored,
e_Tutorial_Hint_CoalBlock,
e_Tutorial_Hint_Item_Max,
};
// We store the first time that we complete these tasks to be used in telemetry
enum eTutorial_Telemetry {
eTutorial_Telemetry_None = e_Tutorial_Hint_Item_Max,
eTutorial_Telemetry_TrialStart,
eTutorial_Telemetry_Halfway,
eTutorial_Telemetry_Complete,
eTutorial_Telemetry_Unused_1,
eTutorial_Telemetry_Unused_2,
eTutorial_Telemetry_Unused_3,
eTutorial_Telemetry_Unused_4,
eTutorial_Telemetry_Unused_5,
eTutorial_Telemetry_Unused_6,
eTutorial_Telemetry_Unused_7,
eTutorial_Telemetry_Unused_8,
eTutorial_Telemetry_Unused_9,
eTutorial_Telemetry_Unused_10,
};
enum eTutorial_CompletionAction {
e_Tutorial_Completion_None,
e_Tutorial_Completion_Complete_State, // This will make the current
// tutorial state complete
e_Tutorial_Completion_Complete_State_Gameplay_Constraints, // This will
// make the
// current
// tutorial
// state
// complete, and
// move the
// delayed
// constraints
// to the
// gameplay
// state
e_Tutorial_Completion_Jump_To_Last_Task,
};

View File

@@ -0,0 +1,22 @@
#include "../../../../Minecraft.World/Header Files/stdafx.h"
#include "TutorialMessage.h"
TutorialMessage::TutorialMessage(
int messageId, bool limitRepeats /*= false*/,
unsigned char numRepeats /*= TUTORIAL_MESSAGE_DEFAULT_SHOW*/)
: messageId(messageId),
limitRepeats(limitRepeats),
numRepeats(numRepeats),
timesShown(0) {}
bool TutorialMessage::canDisplay() {
return !limitRepeats || (timesShown < numRepeats);
}
const wchar_t* TutorialMessage::getMessageForDisplay() {
if (!canDisplay()) return L"";
if (limitRepeats) ++timesShown;
return app.GetString(messageId);
}

View File

@@ -0,0 +1,20 @@
#pragma once
// The default number of times any message should be shown
#define TUTORIAL_MESSAGE_DEFAULT_SHOW 3
class TutorialMessage {
private:
int messageId;
bool limitRepeats;
unsigned char numRepeats;
unsigned char timesShown;
uint32_t lastDisplayed;
public:
TutorialMessage(int messageId, bool limitRepeats = false,
unsigned char numRepeats = TUTORIAL_MESSAGE_DEFAULT_SHOW);
bool canDisplay();
const wchar_t* getMessageForDisplay();
};

View File

@@ -0,0 +1,110 @@
#include "../../../../Minecraft.World/Header Files/stdafx.h"
#include <memory>
#include "../../../net/minecraft/client/Minecraft.h"
#include "../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
#include "../../../net/minecraft/client/multiplayer/MultiPlayerLevel.h"
#include "../../../../Minecraft.World/net/minecraft/world/entity/player/Inventory.h"
#include "../../../../Minecraft.World/net/minecraft/world/item/net.minecraft.world.item.h"
#include "../../../../Minecraft.World/net/minecraft/world/level/net.minecraft.world.level.h"
#include "../../../../Minecraft.World/net/minecraft/world/level/tile/net.minecraft.world.level.tile.h"
#include "TutorialMode.h"
TutorialMode::TutorialMode(int iPad, Minecraft* minecraft,
ClientConnection* connection)
: MultiPlayerGameMode(minecraft, connection), m_iPad(iPad) {}
TutorialMode::~TutorialMode() {
if (tutorial != nullptr) delete tutorial;
}
void TutorialMode::startDestroyBlock(int x, int y, int z, int face) {
if (!tutorial->m_allTutorialsComplete) {
int t = minecraft->level->getTile(x, y, z);
tutorial->startDestroyBlock(minecraft->player->inventory->getSelected(),
Tile::tiles[t]);
}
MultiPlayerGameMode::startDestroyBlock(x, y, z, face);
}
bool TutorialMode::destroyBlock(int x, int y, int z, int face) {
if (!tutorial->m_allTutorialsComplete) {
int t = minecraft->level->getTile(x, y, z);
tutorial->destroyBlock(Tile::tiles[t]);
}
std::shared_ptr<ItemInstance> item = minecraft->player->getSelectedItem();
int damageBefore;
if (item != nullptr) {
damageBefore = item->getDamageValue();
}
bool changed = MultiPlayerGameMode::destroyBlock(x, y, z, face);
if (!tutorial->m_allTutorialsComplete) {
if (item != nullptr && item->isDamageableItem()) {
int max = item->getMaxDamage();
int damageNow = item->getDamageValue();
if (damageNow > damageBefore && damageNow > (max / 2)) {
tutorial->itemDamaged(item);
}
}
}
return changed;
}
void TutorialMode::tick() {
MultiPlayerGameMode::tick();
if (!tutorial->m_allTutorialsComplete) tutorial->tick();
/*
if( tutorial.m_allTutorialsComplete && (tutorial.lastMessageTime +
m_iTutorialDisplayMessageTime) < GetTickCount() )
{
// Exit tutorial
minecraft->gameMode = new SurvivalMode( this );
delete this;
}
*/
}
bool TutorialMode::useItemOn(std::shared_ptr<Player> player, Level* level,
std::shared_ptr<ItemInstance> item, int x, int y,
int z, int face, Vec3* hit, bool bTestUseOnly,
bool* pbUsedItem) {
bool haveItem = false;
int itemCount = 0;
if (!tutorial->m_allTutorialsComplete) {
tutorial->useItemOn(level, item, x, y, z, bTestUseOnly);
if (!bTestUseOnly) {
if (item != nullptr) {
haveItem = true;
itemCount = item->count;
}
}
}
bool result = MultiPlayerGameMode::useItemOn(
player, level, item, x, y, z, face, hit, bTestUseOnly, pbUsedItem);
if (!bTestUseOnly) {
if (!tutorial->m_allTutorialsComplete) {
if (result && haveItem && itemCount > item->count) {
tutorial->useItemOn(item);
}
}
}
return result;
}
void TutorialMode::attack(std::shared_ptr<Player> player,
std::shared_ptr<Entity> entity) {
if (!tutorial->m_allTutorialsComplete) tutorial->attack(player, entity);
MultiPlayerGameMode::attack(player, entity);
}
bool TutorialMode::isInputAllowed(int mapping) {
return tutorial->m_allTutorialsComplete ||
tutorial->isInputAllowed(mapping);
}

View File

@@ -0,0 +1,33 @@
#pragma once
// using namespace std;
#include "../../../net/minecraft/client/multiplayer/MultiPlayerGameMode.h"
#include "Tutorial.h"
class TutorialMode : public MultiPlayerGameMode {
protected:
Tutorial* tutorial;
int m_iPad;
// Function to make this an abstract class
virtual bool isImplemented() = 0;
public:
TutorialMode(int iPad, Minecraft* minecraft, ClientConnection* connection);
virtual ~TutorialMode();
virtual void startDestroyBlock(int x, int y, int z, int face);
virtual bool destroyBlock(int x, int y, int z, int face);
virtual void tick();
virtual bool useItemOn(std::shared_ptr<Player> player, Level* level,
std::shared_ptr<ItemInstance> item, int x, int y,
int z, int face, Vec3* hit,
bool bTestUseOnly = false,
bool* pbUsedItem = nullptr);
virtual void attack(std::shared_ptr<Player> player,
std::shared_ptr<Entity> entity);
virtual bool isInputAllowed(int mapping);
Tutorial* getTutorial() { return tutorial; }
};