The open source repository for the action RPG game in development by Sig Productions titled 'Adventures in Lestoria'!
https://forums.lestoria.net
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2574 lines
96 KiB
2574 lines
96 KiB
1 year ago
|
#pragma region License
|
||
1 year ago
|
/*
|
||
|
License (OLC-3)
|
||
|
~~~~~~~~~~~~~~~
|
||
|
|
||
1 year ago
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||
1 year ago
|
|
||
|
Redistribution and use in source and binary forms, with or without modification,
|
||
|
are permitted provided that the following conditions are met:
|
||
|
|
||
|
1. Redistributions or derivations of source code must retain the above copyright
|
||
|
notice, this list of conditions and the following disclaimer.
|
||
|
|
||
|
2. Redistributions or derivative works in binary form must reproduce the above
|
||
|
copyright notice. This list of conditions and the following disclaimer must be
|
||
|
reproduced in the documentation and/or other materials provided with the distribution.
|
||
|
|
||
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
||
|
be used to endorse or promote products derived from this software without specific
|
||
|
prior written permission.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
|
SUCH DAMAGE.
|
||
1 year ago
|
|
||
|
Portions of this software are copyright © 2023 The FreeType
|
||
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||
|
All rights reserved.
|
||
1 year ago
|
*/
|
||
1 year ago
|
#pragma endregion
|
||
2 years ago
|
#include "olcPGEX_TransformedView.h"
|
||
1 year ago
|
#include "AdventuresInLestoria.h"
|
||
2 years ago
|
#include "olcUTIL_Camera2D.h"
|
||
2 years ago
|
#include "DamageNumber.h"
|
||
2 years ago
|
#include "Bullet.h"
|
||
2 years ago
|
#include "Ability.h"
|
||
2 years ago
|
#include "Class.h"
|
||
2 years ago
|
#include "Version.h"
|
||
2 years ago
|
#include "TMXParser.h"
|
||
2 years ago
|
#include "TSXParser.h"
|
||
2 years ago
|
#include "Map.h"
|
||
2 years ago
|
#include "DEFINES.h"
|
||
1 year ago
|
#include "util.h"
|
||
2 years ago
|
#include <set>
|
||
|
#include <queue>
|
||
2 years ago
|
#include "Emitter.h"
|
||
2 years ago
|
#include "config.h"
|
||
2 years ago
|
#include "safemap.h"
|
||
1 year ago
|
#include "Key.h"
|
||
1 year ago
|
#include "Menu.h"
|
||
1 year ago
|
#include "GameState.h"
|
||
1 year ago
|
#include "Item.h"
|
||
1 year ago
|
#include "Toggleable.h"
|
||
1 year ago
|
#include "Unlock.h"
|
||
|
#include "State_OverworldMap.h"
|
||
1 year ago
|
#include "Test.h"
|
||
1 year ago
|
#include "ItemDrop.h"
|
||
1 year ago
|
#include "VisualNovel.h"
|
||
1 year ago
|
#include "util.h"
|
||
1 year ago
|
#include "olcPGEX_TTF.h"
|
||
1 year ago
|
#include "MenuItemItemButton.h"
|
||
1 year ago
|
#include "Merchant.h"
|
||
1 year ago
|
#include "SaveFile.h"
|
||
1 year ago
|
#ifndef __EMSCRIPTEN__
|
||
1 year ago
|
#include "discord.h"
|
||
1 year ago
|
#endif
|
||
2 years ago
|
|
||
2 years ago
|
INCLUDE_EMITTER_LIST
|
||
1 year ago
|
INCLUDE_ITEM_CATEGORIES
|
||
2 years ago
|
|
||
1 year ago
|
bool _DEBUG_MAP_LOAD_INFO = false;
|
||
1 year ago
|
//360x240
|
||
2 years ago
|
vi2d WINDOW_SIZE={24*15,24*10};
|
||
2 years ago
|
safemap<std::string,Animate2D::FrameSequence>ANIMATION_DATA;
|
||
2 years ago
|
std::vector<Monster>MONSTER_LIST;
|
||
|
std::vector<MonsterSpawner>SPAWNER_LIST;
|
||
2 years ago
|
std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
|
||
2 years ago
|
std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
|
||
1 year ago
|
safemap<std::string,Renderable>GFX;
|
||
1 year ago
|
safemap<std::string,MapName>LEVEL_NAMES;
|
||
2 years ago
|
utils::datafile DATA;
|
||
1 year ago
|
AiL*game;
|
||
|
InputGroup AiL::KEY_LEFT;
|
||
|
InputGroup AiL::KEY_RIGHT;
|
||
|
InputGroup AiL::KEY_UP;
|
||
|
InputGroup AiL::KEY_DOWN;
|
||
|
InputGroup AiL::KEY_ATTACK;
|
||
|
InputGroup AiL::KEY_CONFIRM;
|
||
|
InputGroup AiL::KEY_MENU;
|
||
1 year ago
|
#ifndef __EMSCRIPTEN__
|
||
|
::discord::Core*Discord{};
|
||
|
#endif
|
||
2 years ago
|
|
||
1 year ago
|
float AiL::SIZE_CHANGE_SPEED=1;
|
||
1 year ago
|
|
||
1 year ago
|
AiL::AiL()
|
||
2 years ago
|
{
|
||
2 years ago
|
utils::datafile::Read(DATA,"assets/config/configuration.txt");
|
||
|
|
||
1 year ago
|
_DEBUG_MAP_LOAD_INFO=bool("debug_map_load_info"_I);
|
||
|
|
||
2 years ago
|
std::string CONFIG_PATH = "config_path"_S;
|
||
2 years ago
|
|
||
2 years ago
|
std::string GFX_CONFIG = CONFIG_PATH + "gfx_config"_S;
|
||
2 years ago
|
utils::datafile::Read(DATA,GFX_CONFIG);
|
||
2 years ago
|
WINDOW_SIZE={"WINDOW_SIZE"_i[0],"WINDOW_SIZE"_i[1]};
|
||
2 years ago
|
|
||
|
std::string MAP_CONFIG = CONFIG_PATH + "map_config"_S;
|
||
|
utils::datafile::Read(DATA,MAP_CONFIG);
|
||
2 years ago
|
|
||
2 years ago
|
std::string PLAYER_CONFIG = CONFIG_PATH + "player_config"_S;
|
||
|
utils::datafile::Read(DATA,PLAYER_CONFIG);
|
||
|
|
||
2 years ago
|
std::string MONSTERS_CONFIG = CONFIG_PATH + "monsters_config"_S;
|
||
|
utils::datafile::Read(DATA,MONSTERS_CONFIG);
|
||
|
|
||
|
std::string MONSTERSTRATEGIES_CONFIG = CONFIG_PATH + "monsterstrategies_config"_S;
|
||
|
utils::datafile::Read(DATA,MONSTERSTRATEGIES_CONFIG);
|
||
|
|
||
1 year ago
|
std::string THEMES_CONFIG = CONFIG_PATH + "themes_config"_S;
|
||
|
utils::datafile::Read(DATA,THEMES_CONFIG);
|
||
|
|
||
1 year ago
|
std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S;
|
||
|
utils::datafile::Read(DATA,ITEM_CONFIG);
|
||
|
|
||
1 year ago
|
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
|
||
|
utils::datafile::Read(DATA,ITEM_SET_CONFIG);
|
||
|
|
||
1 year ago
|
std::string ITEM_STATS_CONFIG = CONFIG_PATH + "item_stats_config"_S;
|
||
|
utils::datafile::Read(DATA,ITEM_STATS_CONFIG);
|
||
|
|
||
1 year ago
|
for(auto&[key,value]:DATA.GetProperty("ItemConfiguration").GetKeys()){
|
||
|
std::string config = DATA["ItemConfiguration"][key].GetString();
|
||
1 year ago
|
utils::datafile::Read(DATA,CONFIG_PATH + "item_directory"_S + config);
|
||
|
}
|
||
|
|
||
1 year ago
|
DEBUG_PATHFINDING="debug_pathfinding"_I;
|
||
|
|
||
1 year ago
|
for(const std::string&cl:DATA.GetProperty("class_list").GetValues()){
|
||
2 years ago
|
std::cout<<cl<<std::endl;
|
||
|
utils::datafile::Read(DATA,CONFIG_PATH + "class_directory"_S + cl + ".txt");
|
||
|
}
|
||
1 year ago
|
|
||
2 years ago
|
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
|
||
1 year ago
|
|
||
|
sAppName = "GAME_NAME"_S;
|
||
|
game=this;
|
||
1 year ago
|
gameStarted=time(NULL);
|
||
2 years ago
|
}
|
||
2 years ago
|
|
||
1 year ago
|
bool AiL::OnUserCreate(){
|
||
1 year ago
|
Font::init();
|
||
|
|
||
1 year ago
|
InitializeDefaultKeybinds();
|
||
1 year ago
|
|
||
|
VisualNovel::Initialize();
|
||
|
|
||
1 year ago
|
InitializeLevels();
|
||
2 years ago
|
|
||
2 years ago
|
//Initialize Camera.
|
||
|
camera=Camera2D{WINDOW_SIZE};
|
||
|
camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow);
|
||
2 years ago
|
camera.SetTarget(player->GetPos());
|
||
1 year ago
|
camera.SetWorldBoundary({0,0},GetCurrentMap().MapSize*GetCurrentMap().TileSize);
|
||
2 years ago
|
camera.EnableWorldBoundary(false);
|
||
1 year ago
|
|
||
|
ItemAttribute::Initialize();
|
||
1 year ago
|
|
||
|
ItemInfo::InitializeItems();
|
||
1 year ago
|
|
||
1 year ago
|
player=std::make_unique<Warrior>();
|
||
|
|
||
1 year ago
|
InitializePlayerLevelCap();
|
||
|
|
||
1 year ago
|
InitializeGraphics();
|
||
1 year ago
|
InitializeClasses();
|
||
1 year ago
|
|
||
1 year ago
|
Monster::InitializeStrategies();
|
||
|
//Animations
|
||
|
sig::Animation::InitializeAnimations();
|
||
|
MonsterData::InitializeMonsterData();
|
||
|
|
||
|
sig::Animation::SetupPlayerAnimations();
|
||
|
view=TileTransformedView{GetScreenSize(),{1,1}};
|
||
|
|
||
1 year ago
|
Menu::InitializeMenus();
|
||
|
|
||
1 year ago
|
Inventory::AddItem("Minor Health Potion",16);
|
||
1 year ago
|
Inventory::AddItem("Bandages",10);
|
||
1 year ago
|
Inventory::AddItem("Green Slime Remains",40);
|
||
1 year ago
|
Inventory::AddItem("Blue Slime Remains",22);
|
||
1 year ago
|
Inventory::AddItem("Copper Armor");
|
||
1 year ago
|
Inventory::AddItem("Copper Pants");
|
||
1 year ago
|
Inventory::AddItem("Copper Helmet");
|
||
|
Inventory::AddItem("Copper Shoes");
|
||
1 year ago
|
Inventory::AddItem("Shell Helmet");
|
||
|
Inventory::AddItem("Shell Armor");
|
||
1 year ago
|
Inventory::AddItem("Shell Armor");
|
||
|
Inventory::AddItem("Shell Armor");
|
||
1 year ago
|
Inventory::AddItem("Bone Armor");
|
||
1 year ago
|
Inventory::AddItem("Shell Gloves");
|
||
1 year ago
|
Inventory::AddItem("Shell Gloves",3);
|
||
1 year ago
|
Inventory::AddItem("Shell Shoes");
|
||
|
Inventory::AddItem("Bone Pants");
|
||
|
Inventory::AddItem("Bone Gloves");
|
||
1 year ago
|
Inventory::AddItem("Elixir of Bear Strength",3);
|
||
1 year ago
|
Inventory::AddItem("Leather Helmet");
|
||
1 year ago
|
Inventory::AddItem("Leather Pants");
|
||
|
Inventory::AddItem("Leather Gloves");
|
||
|
Inventory::AddItem("Leather Shoes");
|
||
1 year ago
|
Inventory::AddItem("Wooden Sword");
|
||
1 year ago
|
Inventory::AddItem("Laser Sword");
|
||
|
Inventory::AddItem("Shell Sword");
|
||
1 year ago
|
Inventory::AddItem("Ring of the Slime King",3);
|
||
1 year ago
|
|
||
1 year ago
|
LoadLevel(LEVEL_NAMES["starting_map"_S]);
|
||
2 years ago
|
ChangePlayerClass(WARRIOR);
|
||
1 year ago
|
|
||
1 year ago
|
GameState::Initialize();
|
||
1 year ago
|
|
||
1 year ago
|
Unlock::Initialize();
|
||
1 year ago
|
ItemDrop::Initialize();
|
||
1 year ago
|
|
||
1 year ago
|
Merchant::Initialize();
|
||
|
|
||
1 year ago
|
Stats::InitializeDamageReductionTable();
|
||
|
|
||
1 year ago
|
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
||
|
|
||
1 year ago
|
ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
|
||
1 year ago
|
#ifndef __EMSCRIPTEN__
|
||
|
SetupDiscord();
|
||
|
#endif
|
||
1 year ago
|
|
||
2 years ago
|
return true;
|
||
|
}
|
||
|
|
||
1 year ago
|
bool AiL::OnUserUpdate(float fElapsedTime){
|
||
1 year ago
|
levelTime+=fElapsedTime;
|
||
1 year ago
|
if(!GamePaused()){
|
||
|
GameState::STATE->OnUserUpdate(this);
|
||
|
}
|
||
1 year ago
|
RenderWorld(GetElapsedTime());
|
||
1 year ago
|
GameState::STATE->Draw(this);
|
||
1 year ago
|
RenderMenu();
|
||
1 year ago
|
RenderFadeout();
|
||
1 year ago
|
RenderVersionInfo();
|
||
1 year ago
|
#ifndef __EMSCRIPTEN__
|
||
|
if(Discord){
|
||
1 year ago
|
auto result=Discord->RunCallbacks();
|
||
|
if(result!=::discord::Result::Ok){
|
||
|
std::cout<<"Discord Error Code "<<int(result)<<std::endl;
|
||
|
delete Discord;
|
||
|
Discord=nullptr;
|
||
|
}
|
||
1 year ago
|
}
|
||
|
#endif
|
||
1 year ago
|
return !gameEnd;
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
bool AiL::LeftHeld(){
|
||
1 year ago
|
return KEY_LEFT.Held();
|
||
2 years ago
|
}
|
||
1 year ago
|
bool AiL::RightHeld(){
|
||
1 year ago
|
return KEY_RIGHT.Held();
|
||
2 years ago
|
}
|
||
1 year ago
|
bool AiL::UpHeld(){
|
||
1 year ago
|
return KEY_UP.Held();
|
||
2 years ago
|
}
|
||
1 year ago
|
bool AiL::DownHeld(){
|
||
1 year ago
|
return KEY_DOWN.Held();
|
||
2 years ago
|
}
|
||
1 year ago
|
bool AiL::LeftReleased(){
|
||
1 year ago
|
return KEY_LEFT.Released();
|
||
2 years ago
|
}
|
||
1 year ago
|
bool AiL::RightReleased(){
|
||
1 year ago
|
return KEY_RIGHT.Released();
|
||
2 years ago
|
}
|
||
1 year ago
|
bool AiL::UpReleased(){
|
||
1 year ago
|
return KEY_UP.Released();
|
||
2 years ago
|
}
|
||
1 year ago
|
bool AiL::DownReleased(){
|
||
1 year ago
|
return KEY_DOWN.Released();
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::HandleUserInput(float fElapsedTime){
|
||
1 year ago
|
if(!Menu::stack.empty())return; //A window being opened means there's no user input allowed.
|
||
|
|
||
2 years ago
|
bool setIdleAnimation=true;
|
||
2 years ago
|
if(GetKey(F1).bPressed){
|
||
|
ConsoleShow(F1);
|
||
|
}
|
||
2 years ago
|
if(GetMouseWheel()>0){
|
||
2 years ago
|
switch(player->GetClass()){
|
||
2 years ago
|
case WARRIOR:{
|
||
2 years ago
|
ChangePlayerClass(RANGER);
|
||
2 years ago
|
}break;
|
||
|
case RANGER:{
|
||
2 years ago
|
ChangePlayerClass(WIZARD);
|
||
2 years ago
|
}break;
|
||
|
case WIZARD:{
|
||
2 years ago
|
ChangePlayerClass(WARRIOR);
|
||
2 years ago
|
}break;
|
||
|
}
|
||
|
}
|
||
|
if(GetMouseWheel()<0){
|
||
2 years ago
|
switch(player->GetClass()){
|
||
1 year ago
|
case WARRIOR:{
|
||
|
ChangePlayerClass(WIZARD);
|
||
|
}break;
|
||
|
case RANGER:{
|
||
|
ChangePlayerClass(WARRIOR);
|
||
|
}break;
|
||
|
case WIZARD:{
|
||
|
ChangePlayerClass(RANGER);
|
||
|
}break;
|
||
2 years ago
|
}
|
||
|
}
|
||
2 years ago
|
if(player->GetVelocity()==vf2d{0,0}&&player->CanMove()){
|
||
2 years ago
|
auto GetPlayerStaircaseDirection=[&](){
|
||
|
for(LayerTag&layer:MAP_DATA[GetCurrentLevel()].LayerData){
|
||
1 year ago
|
int truncatedPlayerX=int(player->GetX())/game->GetCurrentMap().tilewidth;
|
||
|
int truncatedPlayerY=int(player->GetY())/game->GetCurrentMap().tilewidth;
|
||
2 years ago
|
int tileID=layer.tiles[truncatedPlayerY][truncatedPlayerX];
|
||
|
TilesheetData dat=GetTileSheet(GetCurrentLevel(),tileID);
|
||
1 year ago
|
if (dat.tileset->staircaseTiles.find(tileID)!=dat.tileset->staircaseTiles.end()){
|
||
|
return dat.tileset->staircaseTiles[tileID].data["value"];
|
||
2 years ago
|
}
|
||
|
}
|
||
|
return std::string("NONE");
|
||
|
};
|
||
|
std::string staircaseDirection=GetPlayerStaircaseDirection();
|
||
2 years ago
|
if(RightHeld()){
|
||
2 years ago
|
player->SetX(player->GetX()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.x="Player.MoveSpd"_F;
|
||
2 years ago
|
if(staircaseDirection=="RIGHT"){
|
||
2 years ago
|
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F;
|
||
2 years ago
|
} else
|
||
2 years ago
|
if(staircaseDirection=="LEFT"){
|
||
|
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y="Player.StaircaseClimbSpd"_F;
|
||
|
}
|
||
2 years ago
|
player->SetFacingDirection(RIGHT);
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
2 years ago
|
}
|
||
2 years ago
|
setIdleAnimation=false;
|
||
2 years ago
|
}
|
||
2 years ago
|
if(LeftHeld()){
|
||
2 years ago
|
player->SetX(player->GetX()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.x=-"Player.MoveSpd"_F;
|
||
2 years ago
|
if(staircaseDirection=="RIGHT"){
|
||
2 years ago
|
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y="Player.StaircaseClimbSpd"_F;
|
||
2 years ago
|
} else
|
||
2 years ago
|
if(staircaseDirection=="LEFT"){
|
||
|
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F;
|
||
2 years ago
|
}
|
||
2 years ago
|
if(setIdleAnimation){
|
||
2 years ago
|
player->SetFacingDirection(LEFT);
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
|
setIdleAnimation=false;
|
||
2 years ago
|
}
|
||
2 years ago
|
if(UpHeld()){
|
||
2 years ago
|
player->SetY(player->GetY()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y=-"Player.MoveSpd"_F*fElapsedTime;
|
||
2 years ago
|
if(setIdleAnimation){
|
||
2 years ago
|
player->SetFacingDirection(UP);
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
player->UpdateWalkingAnimation(UP);
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
|
setIdleAnimation=false;
|
||
2 years ago
|
}
|
||
2 years ago
|
if(DownHeld()){
|
||
2 years ago
|
player->SetY(player->GetY()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y="Player.MoveSpd"_F*fElapsedTime;
|
||
2 years ago
|
if(setIdleAnimation){
|
||
2 years ago
|
player->SetFacingDirection(DOWN);
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
|
setIdleAnimation=false;
|
||
2 years ago
|
}
|
||
|
}
|
||
2 years ago
|
if(UpReleased()){
|
||
2 years ago
|
player->SetLastReleasedMovementKey(UP);
|
||
2 years ago
|
player->movementVelocity.y=0;
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
if(RightHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
2 years ago
|
} else
|
||
|
if(DownHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
2 years ago
|
} else
|
||
|
if(LeftHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
if(RightReleased()){
|
||
2 years ago
|
player->SetLastReleasedMovementKey(RIGHT);
|
||
2 years ago
|
player->movementVelocity.x=0;
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
if(UpHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(UP);
|
||
2 years ago
|
} else
|
||
|
if(DownHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
2 years ago
|
} else
|
||
|
if(LeftHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
if(LeftReleased()){
|
||
2 years ago
|
player->SetLastReleasedMovementKey(LEFT);
|
||
2 years ago
|
player->movementVelocity.x=0;
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
if(RightHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
2 years ago
|
} else
|
||
|
if(DownHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
2 years ago
|
} else
|
||
|
if(UpHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(UP);
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
if(DownReleased()){
|
||
2 years ago
|
player->SetLastReleasedMovementKey(DOWN);
|
||
2 years ago
|
player->movementVelocity.y=0;
|
||
2 years ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
2 years ago
|
if(RightHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
2 years ago
|
} else
|
||
|
if(UpHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(UP);
|
||
2 years ago
|
} else
|
||
|
if(LeftHeld()){
|
||
2 years ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
2 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
2 years ago
|
if(player->GetState()!=State::NORMAL&&player->GetState()!=State::PREP_CAST){
|
||
2 years ago
|
setIdleAnimation=false;
|
||
|
}
|
||
|
|
||
2 years ago
|
if(setIdleAnimation){
|
||
2 years ago
|
switch(player->GetLastReleasedMovementKey()){
|
||
2 years ago
|
case UP:{
|
||
2 years ago
|
player->UpdateIdleAnimation(UP);
|
||
2 years ago
|
}break;
|
||
|
case DOWN:{
|
||
2 years ago
|
player->UpdateIdleAnimation(DOWN);
|
||
2 years ago
|
}break;
|
||
|
case LEFT:{
|
||
2 years ago
|
player->UpdateIdleAnimation(LEFT);
|
||
2 years ago
|
}break;
|
||
|
case RIGHT:{
|
||
2 years ago
|
player->UpdateIdleAnimation(RIGHT);
|
||
2 years ago
|
}break;
|
||
|
default:{
|
||
2 years ago
|
player->UpdateIdleAnimation(DOWN);
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
|
}
|
||
1 year ago
|
|
||
|
if(GetKey(I).bPressed){
|
||
1 year ago
|
Menu::OpenMenu(INVENTORY_CONSUMABLES);
|
||
1 year ago
|
}
|
||
1 year ago
|
if(GetKey(O).bPressed){
|
||
1 year ago
|
ItemDrop::SpawnItem(&ITEM_DATA.at("Green Slime Remains"),player->GetPos(),player->OnUpperLevel());
|
||
1 year ago
|
}
|
||
1 year ago
|
if(GetKey(L).bHeld){
|
||
|
game->GetPlayer()->AddXP(1);
|
||
|
}
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::UpdateCamera(float fElapsedTime){
|
||
2 years ago
|
lastWorldShakeAdjust=std::max(0.f,lastWorldShakeAdjust-fElapsedTime);
|
||
1 year ago
|
if(worldShakeTime>0){
|
||
|
worldShakeTime-=fElapsedTime;
|
||
|
if(worldShakeTime<=0){
|
||
|
camera.SetTarget(player->GetPos());
|
||
|
}
|
||
2 years ago
|
if(lastWorldShakeAdjust==0){
|
||
1 year ago
|
lastWorldShakeAdjust=0.02f;
|
||
2 years ago
|
worldShakeVel.x*=-1;
|
||
|
worldShakeVel.y*=-1;
|
||
2 years ago
|
}
|
||
1 year ago
|
worldShake=player->GetPos()+worldShakeVel;
|
||
2 years ago
|
}
|
||
2 years ago
|
camera.Update(fElapsedTime);
|
||
2 years ago
|
view.SetWorldOffset(camera.GetViewPosition());
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::UpdateEffects(float fElapsedTime){
|
||
2 years ago
|
for(auto it=EMITTER_LIST.begin();it!=EMITTER_LIST.end();++it){
|
||
|
auto ptr=(*it).get();
|
||
1 year ago
|
ptr->Update(fElapsedTime);
|
||
2 years ago
|
}
|
||
2 years ago
|
for(std::vector<std::unique_ptr<Effect>>::iterator it=backgroundEffects.begin();it!=backgroundEffects.end();++it){
|
||
|
Effect*e=(*it).get();
|
||
1 year ago
|
e->Update(fElapsedTime);
|
||
2 years ago
|
}
|
||
2 years ago
|
for(std::vector<std::unique_ptr<Effect>>::iterator it=foregroundEffects.begin();it!=foregroundEffects.end();++it){
|
||
|
Effect*e=(*it).get();
|
||
1 year ago
|
e->Update(fElapsedTime);
|
||
2 years ago
|
}
|
||
2 years ago
|
|
||
1 year ago
|
std::erase_if(EMITTER_LIST,[](std::unique_ptr<Emitter>&e){return e->dead;});
|
||
|
std::erase_if(backgroundEffects,[](std::unique_ptr<Effect>&e){return e->dead;});
|
||
|
std::erase_if(foregroundEffects,[](std::unique_ptr<Effect>&e){return e->dead;});
|
||
1 year ago
|
std::erase_if(DAMAGENUMBER_LIST,[](std::shared_ptr<DamageNumber>&n){return n->lifeTime>1;});
|
||
1 year ago
|
|
||
2 years ago
|
for(auto it=foregroundEffectsToBeInserted.begin();it!=foregroundEffectsToBeInserted.end();++it){
|
||
|
foregroundEffects.push_back(std::move(*it));
|
||
|
}
|
||
|
for(auto it=backgroundEffectsToBeInserted.begin();it!=backgroundEffectsToBeInserted.end();++it){
|
||
|
backgroundEffects.push_back(std::move(*it));
|
||
|
}
|
||
|
foregroundEffectsToBeInserted.clear();
|
||
|
backgroundEffectsToBeInserted.clear();
|
||
2 years ago
|
}
|
||
1 year ago
|
void AiL::UpdateBullets(float fElapsedTime){
|
||
2 years ago
|
for(auto it=BULLET_LIST.begin();it!=BULLET_LIST.end();++it){
|
||
2 years ago
|
Bullet*b=(*it).get();
|
||
2 years ago
|
b->UpdateFadeTime(fElapsedTime);
|
||
2 years ago
|
b->Update(fElapsedTime);
|
||
2 years ago
|
b->animation.UpdateState(b->internal_animState,fElapsedTime);
|
||
2 years ago
|
if(!b->deactivated){
|
||
2 years ago
|
float totalDistance=(b->vel*fElapsedTime).mag();
|
||
1 year ago
|
int iterations=int(std::max(1.f,(b->vel*fElapsedTime).mag()));
|
||
1 year ago
|
int totalIterations=iterations;
|
||
|
vf2d finalBulletPos=b->pos+b->vel*fElapsedTime;
|
||
|
const auto CollisionCheck=[&](){
|
||
2 years ago
|
if(b->friendly){
|
||
|
for(Monster&m:MONSTER_LIST){
|
||
|
if(geom2d::overlaps(geom2d::circle(m.GetPos(),12*m.GetSizeMult()),geom2d::circle(b->pos,b->radius))){
|
||
1 year ago
|
if(b->hitList.find(&m)==b->hitList.end()&&m.Hurt(b->damage,b->OnUpperLevel(),0)){
|
||
2 years ago
|
if(!b->hitsMultiple){
|
||
2 years ago
|
if(b->MonsterHit(m)){
|
||
1 year ago
|
b->dead=true;
|
||
1 year ago
|
return false;
|
||
2 years ago
|
}
|
||
|
}
|
||
2 years ago
|
b->hitList[&m]=true;
|
||
2 years ago
|
}
|
||
|
}
|
||
|
}
|
||
2 years ago
|
} else {
|
||
|
if(geom2d::overlaps(geom2d::circle(player->GetPos(),12*player->GetSizeMult()/2),geom2d::circle(b->pos,b->radius))){
|
||
1 year ago
|
if(player->Hurt(b->damage,b->OnUpperLevel(),0)){
|
||
2 years ago
|
if(b->PlayerHit(player.get())){
|
||
1 year ago
|
b->dead=true;
|
||
1 year ago
|
return false;
|
||
2 years ago
|
}
|
||
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
1 year ago
|
return true;
|
||
|
};
|
||
|
|
||
|
while(iterations>0){
|
||
|
iterations--;
|
||
|
b->pos+=(b->vel*fElapsedTime)/float(totalIterations);
|
||
|
if(!CollisionCheck()){
|
||
|
goto nextBullet;
|
||
|
}
|
||
|
}
|
||
|
b->pos=finalBulletPos;
|
||
|
if(!CollisionCheck()){
|
||
|
goto nextBullet;
|
||
2 years ago
|
}
|
||
1 year ago
|
}else{
|
||
2 years ago
|
b->pos+=b->vel*fElapsedTime;
|
||
2 years ago
|
}
|
||
1 year ago
|
if(b->pos.x+b->radius<view.GetWorldTL().x-WINDOW_SIZE.x||b->pos.x-b->radius>view.GetWorldBR().x+WINDOW_SIZE.x||b->pos.y+b->radius<view.GetWorldTL().y-WINDOW_SIZE.y||b->pos.y-b->radius>view.GetWorldBR().y+WINDOW_SIZE.y){
|
||
1 year ago
|
b->dead=true;
|
||
2 years ago
|
continue;
|
||
2 years ago
|
}
|
||
2 years ago
|
b->lifetime-=fElapsedTime;
|
||
|
if(b->lifetime<=0){
|
||
1 year ago
|
b->dead=true;
|
||
2 years ago
|
continue;
|
||
2 years ago
|
}
|
||
1 year ago
|
nextBullet:
|
||
1 year ago
|
while(false);
|
||
2 years ago
|
}
|
||
1 year ago
|
std::erase_if(BULLET_LIST,[](std::unique_ptr<Bullet>&b){return b->dead;});
|
||
2 years ago
|
}
|
||
1 year ago
|
void AiL::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float z){
|
||
2 years ago
|
for(Monster&m:MONSTER_LIST){
|
||
2 years ago
|
if(geom2d::overlaps(geom2d::circle(pos,radius),geom2d::circle(m.GetPos(),12*m.GetSizeMult()))){
|
||
1 year ago
|
m.Hurt(damage,upperLevel,z);
|
||
2 years ago
|
}
|
||
|
}
|
||
|
}
|
||
2 years ago
|
|
||
1 year ago
|
void AiL::PopulateRenderLists(){
|
||
1 year ago
|
monstersBeforeLower.clear();
|
||
|
monstersAfterLower.clear();
|
||
|
monstersBeforeUpper.clear();
|
||
|
monstersAfterUpper.clear();
|
||
|
bulletsLower.clear();
|
||
|
bulletsUpper.clear();
|
||
|
backgroundEffectsLower.clear();
|
||
|
backgroundEffectsUpper.clear();
|
||
|
foregroundEffectsLower.clear();
|
||
|
foregroundEffectsUpper.clear();
|
||
1 year ago
|
endZones.clear();
|
||
|
upperEndZones.clear();
|
||
1 year ago
|
dropsBeforeLower.clear();
|
||
|
dropsAfterLower.clear();
|
||
|
dropsBeforeUpper.clear();
|
||
|
dropsAfterUpper.clear();
|
||
1 year ago
|
|
||
1 year ago
|
tilePreparationList.clear();
|
||
|
tileForegroundList.clear();
|
||
|
|
||
2 years ago
|
Player*pl=GetPlayer();
|
||
2 years ago
|
for(auto it=MONSTER_LIST.begin();it!=MONSTER_LIST.end();++it){
|
||
|
Monster&m=*it;
|
||
2 years ago
|
if(m.GetPos().y<pl->GetPos().y){//This monster renders before the player does (behind the player)
|
||
2 years ago
|
if(m.OnUpperLevel()){
|
||
|
monstersBeforeUpper.push_back(&m);
|
||
|
}else{
|
||
|
monstersBeforeLower.push_back(&m);
|
||
|
}
|
||
|
} else {//This monster renders after the player does (in front of the player)
|
||
|
if(m.OnUpperLevel()){
|
||
|
monstersAfterUpper.push_back(&m);
|
||
|
}else{
|
||
|
monstersAfterLower.push_back(&m);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
1 year ago
|
for(int i=0;i<ItemDrop::drops.size();i++){
|
||
|
ItemDrop&drop=ItemDrop::drops[i];
|
||
|
if(drop.GetPos().y<pl->GetPos().y){//This item drop renders before the player does (behind the player)
|
||
|
if(drop.OnUpperLevel()){
|
||
|
dropsBeforeUpper.push_back(i);
|
||
|
}else{
|
||
|
dropsBeforeLower.push_back(i);
|
||
|
}
|
||
|
} else {//This item drop renders after the player does (in front of the player)
|
||
|
if(drop.OnUpperLevel()){
|
||
|
dropsAfterUpper.push_back(i);
|
||
|
}else{
|
||
|
dropsAfterLower.push_back(i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
2 years ago
|
for(auto it=BULLET_LIST.begin();it!=BULLET_LIST.end();++it){
|
||
|
Bullet*b=(*it).get();
|
||
|
if(b->OnUpperLevel()){
|
||
|
bulletsUpper.push_back(b);
|
||
|
}else{
|
||
|
bulletsLower.push_back(b);
|
||
|
}
|
||
|
}
|
||
|
for(auto it=foregroundEffects.begin();it!=foregroundEffects.end();++it){
|
||
2 years ago
|
Effect*e=(*it).get();
|
||
|
if(e->OnUpperLevel()){
|
||
|
foregroundEffectsUpper.push_back(e);
|
||
2 years ago
|
}else{
|
||
2 years ago
|
foregroundEffectsLower.push_back(e);
|
||
2 years ago
|
}
|
||
|
}
|
||
|
for(auto it=backgroundEffects.begin();it!=backgroundEffects.end();++it){
|
||
2 years ago
|
Effect*e=(*it).get();
|
||
|
if(e->OnUpperLevel()){
|
||
|
backgroundEffectsUpper.push_back(e);
|
||
2 years ago
|
}else{
|
||
2 years ago
|
backgroundEffectsLower.push_back(e);
|
||
2 years ago
|
}
|
||
|
}
|
||
1 year ago
|
|
||
|
for(ZoneData&zone:MAP_DATA[GetCurrentLevel()].ZoneData["EndZone"]){
|
||
|
if(zone.isUpper){
|
||
|
upperEndZones.push_back(zone);
|
||
|
}else{
|
||
|
endZones.push_back(zone);
|
||
|
}
|
||
|
}
|
||
|
|
||
2 years ago
|
std::sort(monstersBeforeUpper.begin(),monstersBeforeUpper.end(),[](Monster*m1,Monster*m2){return m1->GetPos().y<m2->GetPos().y;});
|
||
|
std::sort(monstersBeforeLower.begin(),monstersBeforeLower.end(),[](Monster*m1,Monster*m2){return m1->GetPos().y<m2->GetPos().y;});
|
||
|
std::sort(monstersAfterUpper.begin(),monstersAfterUpper.end(),[](Monster*m1,Monster*m2){return m1->GetPos().y<m2->GetPos().y;});
|
||
|
std::sort(monstersAfterLower.begin(),monstersAfterLower.end(),[](Monster*m1,Monster*m2){return m1->GetPos().y<m2->GetPos().y;});
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos){
|
||
1 year ago
|
if(tileSheet.tileset->animationData.count(tileSheetIndex)){
|
||
1 year ago
|
int animationDuration_ms=int(tileSheet.tileset->animationData[tileSheetIndex].size()*"animation_tile_precision"_I);
|
||
|
int animatedIndex=tileSheet.tileset->animationData[tileSheetIndex][size_t(fmod(levelTime*1000.f,animationDuration_ms)/"animation_tile_precision"_I)];
|
||
1 year ago
|
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
|
||
1 year ago
|
int tileSheetX=animatedIndex%tileSheetWidth;
|
||
|
int tileSheetY=animatedIndex/tileSheetWidth;
|
||
1 year ago
|
view.DrawPartialDecal(pos*game->GetCurrentMap().tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)},tileSheet.tileset->tileset->Decal(),vi2d{tileSheetX,tileSheetY}*tileSheet.tileset->tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)});
|
||
1 year ago
|
}else{
|
||
1 year ago
|
view.DrawPartialDecal(pos*game->GetCurrentMap().tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)},tileSheet.tileset->tileset->Decal(),tileSheetPos*tileSheet.tileset->tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)});
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::RenderTile(TileRenderData&tileSheet,Pixel col){
|
||
1 year ago
|
if(tileSheet.tileSheet.tileset->animationData.count(tileSheet.tileID%1000000)){
|
||
1 year ago
|
int animationDuration_ms=int(tileSheet.tileSheet.tileset->animationData[tileSheet.tileID%1000000].size()*"animation_tile_precision"_I);
|
||
|
int animatedIndex=tileSheet.tileSheet.tileset->animationData[tileSheet.tileID%1000000][size_t(fmod(levelTime*1000.f,animationDuration_ms)/"animation_tile_precision"_I)];
|
||
1 year ago
|
int tileSheetWidth=tileSheet.tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileSheet.tileset->tilewidth;
|
||
1 year ago
|
int tileSheetX=animatedIndex%tileSheetWidth;
|
||
|
int tileSheetY=animatedIndex/tileSheetWidth;
|
||
1 year ago
|
view.DrawPartialDecal(tileSheet.pos,{float(tileSheet.tileSheet.tileset->tilewidth),float(tileSheet.tileSheet.tileset->tileheight)},tileSheet.tileSheet.tileset->tileset->Decal(),vi2d{tileSheetX,tileSheetY},{float(tileSheet.tileSheet.tileset->tilewidth),float(tileSheet.tileSheet.tileset->tileheight)},col);
|
||
1 year ago
|
}else{
|
||
1 year ago
|
view.DrawPartialDecal(tileSheet.pos,{float(tileSheet.tileSheet.tileset->tilewidth),float(tileSheet.tileSheet.tileset->tileheight)},tileSheet.tileSheet.tileset->tileset->Decal(),tileSheet.tileSheetPos,{float(tileSheet.tileSheet.tileset->tilewidth),float(tileSheet.tileSheet.tileset->tileheight)},col);
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::RenderWorld(float fElapsedTime){
|
||
1 year ago
|
|
||
2 years ago
|
LayerTag*bridgeLayer=nullptr;
|
||
|
bool bridgeLayerFade=false;
|
||
1 year ago
|
Player*pl=GetPlayer();
|
||
|
|
||
|
PopulateRenderLists();
|
||
|
|
||
|
auto RenderPlayer=[&](vf2d pos,vf2d scale){
|
||
|
vf2d playerScale=vf2d(player->GetSizeMult(),player->GetSizeMult());
|
||
|
int count=0;
|
||
|
for(vf2d&pos:player->ghostPositions){
|
||
|
view.DrawPartialRotatedDecal(pos,player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale,{0,0,0,uint8_t(float(count)/player->RETREAT_GHOST_FRAMES*255)});
|
||
|
count++;
|
||
|
}
|
||
|
if(player->teleportAnimationTimer>0){
|
||
1 year ago
|
playerScale.x=120*float(abs(pow(player->teleportAnimationTimer-0.175f,3)));
|
||
|
pos=player->teleportStartPosition.lerp(player->teleportTarget,(0.35f-player->teleportAnimationTimer)/0.35f);
|
||
1 year ago
|
}
|
||
1 year ago
|
const std::vector<Buff>attackBuffs=player->GetStatBuffs({"Attack","Attack %"});
|
||
|
view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,attackBuffs.size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*attackBuffs[0].duration))),uint8_t(255*abs(sin(1.4*attackBuffs[0].duration)))}:WHITE);
|
||
1 year ago
|
SetDecalMode(DecalMode::NORMAL);
|
||
1 year ago
|
if(player->GetState()==State::BLOCK){
|
||
|
view.DrawDecal(player->GetPos()-vf2d{12,12},GFX["block.png"].Decal());
|
||
|
}
|
||
1 year ago
|
};
|
||
|
|
||
1 year ago
|
auto RenderZone=[&](geom2d::rect<int>&zone){
|
||
|
game->SetDecalMode(DecalMode::ADDITIVE);
|
||
1 year ago
|
Pixel ringColor={128,128,128,uint8_t(abs(sin(game->levelTime))*255)};
|
||
|
Decal*ringDecal=GFX["finishring_green.png"].Decal();
|
||
1 year ago
|
if(!player->IsOutOfCombat()){
|
||
|
game->SetDecalMode(DecalMode::NORMAL);
|
||
|
ringColor.r=ringColor.g=ringColor.b=64;
|
||
1 year ago
|
ringDecal=GFX["finishring.png"].Decal();
|
||
1 year ago
|
}
|
||
1 year ago
|
view.DrawDecal(zone.pos,ringDecal,vf2d(zone.size)/vf2d(GFX["finishring.png"].Sprite()->Size()),ringColor);
|
||
1 year ago
|
game->SetDecalMode(DecalMode::NORMAL);
|
||
|
};
|
||
|
|
||
1 year ago
|
enum class RenderMode{
|
||
|
REFLECTIVE_TILES,
|
||
|
NORMAL_TILES,
|
||
|
EMPTY_TILES,
|
||
|
};
|
||
|
|
||
|
reflectionUpdateTimer-=fElapsedTime;
|
||
|
if(reflectionUpdateTimer<=0){
|
||
|
reflectionStepTime+="water_reflection_time_step"_F;
|
||
|
reflectionUpdateTimer="water_reflection_update_time"_F;
|
||
|
}
|
||
|
|
||
2 years ago
|
#pragma region Basic Tile Layer Rendering
|
||
1 year ago
|
FillRectDecal({0,0},GetScreenSize(),{100,180,100});
|
||
1 year ago
|
for(RenderMode mode=RenderMode::REFLECTIVE_TILES;mode<=RenderMode::EMPTY_TILES;mode=RenderMode(int(mode)+1)){
|
||
|
if(mode==RenderMode::NORMAL_TILES){
|
||
|
SetDecalMode(DecalMode::ADDITIVE);
|
||
|
float reflectionHeight=(float(player->GetFrame().GetSourceRect().size.y)-8)*player->GetSizeMult();
|
||
|
float reflectionBottom=player->GetPos().y+reflectionHeight;
|
||
1 year ago
|
float cutOff=reflectionBottom-GetCurrentMap().height*GetCurrentMap().tileheight;
|
||
1 year ago
|
float multiplierX=0.9f;
|
||
1 year ago
|
multiplierX*=(1-abs(sin(reflectionStepTime))*"water_reflection_scale_factor"_F);
|
||
1 year ago
|
multiplierX*=(1-abs(cos(1.5f*reflectionStepTime))*"water_reflection_scale_factor"_F);
|
||
1 year ago
|
float reflectionRatioX=abs(sin(reflectionStepTime))*"water_reflection_scale_factor"_F;
|
||
|
RenderPlayer(player->GetPos()+vf2d{reflectionRatioX*player->GetFrame().GetSourceRect().size.x,float(player->GetFrame().GetSourceRect().size.y)-8}*player->GetSizeMult(),{multiplierX,-1});
|
||
|
for(Monster&m:MONSTER_LIST){
|
||
|
m.DrawReflection(reflectionRatioX,multiplierX);
|
||
|
}
|
||
1 year ago
|
SetDecalMode(DecalMode::NORMAL);
|
||
|
}
|
||
1 year ago
|
if(GetCurrentMap().optimized){
|
||
1 year ago
|
view.FillRectDecal(-WINDOW_SIZE,vf2d{float(GetCurrentMap().width),float(GetCurrentMap().height)}*float(GetCurrentMap().tilewidth)+vf2d{WINDOW_SIZE}*2,{100,180,100});
|
||
1 year ago
|
view.DrawDecal({0,0},MAP_DATA[GetCurrentLevel()].optimizedTile->Decal());
|
||
|
}else{
|
||
|
for (int x = view.GetTopLeftTile().x/GetCurrentMap().tilewidth-1; x <= view.GetBottomRightTile().x/GetCurrentMap().tilewidth; x++){
|
||
|
for (int y = view.GetTopLeftTile().y/GetCurrentMap().tilewidth-1; y <= view.GetBottomRightTile().y/GetCurrentMap().tilewidth; y++){
|
||
|
if(x>=0&&x<GetCurrentMap().width&&y>=0&&y<GetCurrentMap().height){
|
||
|
switch(mode){
|
||
|
case RenderMode::NORMAL_TILES:{
|
||
|
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||
|
if(IsBridgeLayer(layer)){
|
||
|
bridgeLayer=&layer;
|
||
|
if(!bridgeLayerFade&&!player->upperLevel){
|
||
|
int tileID=layer.tiles[y][x]-1;
|
||
|
if(tileID!=-1){
|
||
|
int playerXTruncated=int(player->GetPos().x)/GetCurrentMap().tilewidth;
|
||
|
int playerYTruncated=int(player->GetPos().y)/GetCurrentMap().tilewidth;
|
||
|
if(playerXTruncated==x&&playerYTruncated==y){
|
||
|
bridgeLayerFade=true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
int tileID=layer.tiles[y][x]-1;
|
||
|
if(tileID!=-1){
|
||
|
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||
|
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
|
||
|
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
|
||
|
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||
|
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||
|
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||
|
if(!IsForegroundTile(tileSheet,tileSheetIndex)&&!IsUpperForegroundTile(tileSheetIndex)&&!IsReflectiveTile(tileSheet,tileSheetIndex)){
|
||
|
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
|
||
|
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
|
||
|
if("debug_collision_boxes"_I){
|
||
|
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
|
||
|
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
|
||
|
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128});
|
||
|
view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY);
|
||
|
}
|
||
1 year ago
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
1 year ago
|
}break;
|
||
|
case RenderMode::REFLECTIVE_TILES:{
|
||
|
visibleTiles.insert({x,y});
|
||
|
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||
|
int tileID=layer.tiles[y][x]-1;
|
||
|
if(tileID!=-1){
|
||
|
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||
|
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
|
||
|
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
|
||
|
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||
|
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||
|
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||
|
if(IsReflectiveTile(tileSheet,tileSheetIndex)){
|
||
|
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
|
||
|
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
|
||
|
}
|
||
1 year ago
|
if("debug_collision_boxes"_I){
|
||
|
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
|
||
|
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
|
||
1 year ago
|
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128});
|
||
|
view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
2 years ago
|
}
|
||
|
}
|
||
1 year ago
|
}break;
|
||
|
case RenderMode::EMPTY_TILES:{
|
||
|
if(visibleTiles.count({x,y})){
|
||
|
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth,{float(GetCurrentMap().tilewidth),float(GetCurrentMap().tilewidth)},{100,180,100});
|
||
2 years ago
|
}
|
||
1 year ago
|
}break;
|
||
|
}
|
||
|
}else{
|
||
|
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth,{float(GetCurrentMap().tilewidth),float(GetCurrentMap().tilewidth)},{100,180,100});
|
||
2 years ago
|
}
|
||
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
if(bridgeLayerFade){
|
||
|
bridgeFadeFactor=std::min(bridgeFadeFactor+fElapsedTime,TileGroup::FADE_TIME);
|
||
|
}else{
|
||
|
bridgeFadeFactor=std::max(bridgeFadeFactor-fElapsedTime,0.f);
|
||
|
}
|
||
1 year ago
|
}
|
||
2 years ago
|
#pragma endregion
|
||
2 years ago
|
//DrawDecal({0,0},MAP_TILESETS["assets/maps/"+MAP_DATA[LEVEL1].TilesetData[1].data["source"]]->Decal());
|
||
2 years ago
|
|
||
1 year ago
|
for(Monster&m:MONSTER_LIST){
|
||
|
m.strategyDraw(this);
|
||
|
}
|
||
|
|
||
2 years ago
|
if(player->GetZ()>0){
|
||
2 years ago
|
vf2d shadowScale=vf2d{8*player->GetSizeMult()/3.f,1}/std::max(1.f,player->GetZ()/24);
|
||
1 year ago
|
view.DrawDecal(player->GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*player->GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
|
||
2 years ago
|
}
|
||
2 years ago
|
for(Effect*e:backgroundEffectsLower){
|
||
1 year ago
|
e->rendered=false;
|
||
2 years ago
|
}
|
||
1 year ago
|
for(ZoneData&zone:endZones){
|
||
|
RenderZone(zone.zone);
|
||
|
}
|
||
1 year ago
|
for(int index:dropsBeforeLower){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
2 years ago
|
for(Monster*m:monstersBeforeLower){
|
||
|
m->Draw();
|
||
2 years ago
|
}
|
||
2 years ago
|
if(!player->upperLevel){
|
||
1 year ago
|
RenderPlayer(player->GetPos(),{1,1});
|
||
2 years ago
|
}
|
||
1 year ago
|
for(int index:dropsAfterLower){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
2 years ago
|
for(Monster*m:monstersAfterLower){
|
||
|
m->Draw();
|
||
2 years ago
|
}
|
||
2 years ago
|
for(Bullet*b:bulletsLower){
|
||
1 year ago
|
b->rendered=false;
|
||
2 years ago
|
}
|
||
2 years ago
|
auto RenderPrecastTargetingIndicator=[&](){
|
||
|
if(player->GetState()==State::PREP_CAST){
|
||
|
float precastSize=GetPlayer()->castPrepAbility->precastInfo.size;
|
||
|
float precastRange=GetPlayer()->castPrepAbility->precastInfo.range;
|
||
|
vf2d scale=vf2d{precastSize,precastSize}*2/3.f;
|
||
1 year ago
|
vf2d centerPoint=GetWorldMousePos()-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
|
||
1 year ago
|
float distance=float(sqrt(pow(player->GetX()-GetWorldMousePos().x,2)+pow(player->GetY()-GetWorldMousePos().y,2)));
|
||
2 years ago
|
if(distance>precastRange){//Clamp the distance.
|
||
|
vf2d pointToCursor = {GetWorldMousePos().x-player->GetX(),GetWorldMousePos().y-player->GetY()};
|
||
|
pointToCursor=pointToCursor.norm()*precastRange;
|
||
1 year ago
|
vf2d centerPoint=player->GetPos()+pointToCursor-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
|
||
|
view.DrawDecal(centerPoint,GFX["circle.png"].Decal(),scale,{255,0,0,96});
|
||
2 years ago
|
} else {
|
||
1 year ago
|
view.DrawDecal(centerPoint,GFX["circle.png"].Decal(),scale,{255,0,0,96});
|
||
2 years ago
|
}
|
||
|
}
|
||
|
};
|
||
|
if(!player->OnUpperLevel()){
|
||
|
RenderPrecastTargetingIndicator();
|
||
2 years ago
|
}
|
||
1 year ago
|
|
||
|
#pragma region Foreground Rendering Preparation
|
||
2 years ago
|
for(TileGroup&group:foregroundTileGroups){
|
||
|
if(view.IsRectVisible(group.GetRange().pos,group.GetRange().size)){
|
||
2 years ago
|
if(geom2d::overlaps(group.GetFadeRange(),player->pos)){
|
||
2 years ago
|
group.playerBehind=true;
|
||
|
group.fadeFactor=std::min(group.fadeFactor+fElapsedTime,TileGroup::FADE_TIME);
|
||
|
} else {
|
||
|
group.playerBehind=false;
|
||
|
group.fadeFactor=std::max(group.fadeFactor-fElapsedTime,0.f);
|
||
|
}
|
||
2 years ago
|
for(TileRenderData&tile:group.GetTiles()){
|
||
1 year ago
|
tile.tileOpacity=group.fadeFactor;
|
||
|
if(tile.tileSheet.tileset->collision.find(tile.tileID)!=tile.tileSheet.tileset->collision.end()){
|
||
|
tilePreparationList.push_back(&tile);
|
||
|
}else{
|
||
|
tileForegroundList.push_back(&tile);
|
||
1 year ago
|
}
|
||
2 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
1 year ago
|
|
||
|
std::sort(tilePreparationList.begin(),tilePreparationList.end(),[](TileRenderData*tile1,TileRenderData*tile2){return tile1->pos.y<tile2->pos.y||tile1->pos.y==tile2->pos.y&&tile1->layerID<tile2->layerID;});
|
||
1 year ago
|
std::sort(tileForegroundList.begin(),tileForegroundList.end(),[](TileRenderData*tile1,TileRenderData*tile2){return tile1->layerID<tile2->layerID;});
|
||
1 year ago
|
|
||
|
#pragma region Foreground Rendering w/Depth
|
||
|
int tilePrevY=0;
|
||
|
for(TileRenderData*tile:tilePreparationList){
|
||
|
tilePrevY=tile->pos.y+12;
|
||
|
#pragma region Depth Ordered Rendering
|
||
|
for(Effect*e:backgroundEffectsLower){
|
||
|
if(!e->rendered&&e->pos.y<tilePrevY){
|
||
|
e->rendered=true;
|
||
|
e->Draw();
|
||
|
}
|
||
|
}
|
||
|
for(Bullet*b:bulletsLower){
|
||
|
if(!b->rendered&&b->pos.y<tilePrevY){
|
||
|
b->rendered=true;
|
||
|
b->Draw();
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||
|
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
|
||
|
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
|
||
|
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
|
||
|
distToPlayer/=4;
|
||
|
if(distToPlayer<1){distToPlayer=1;}
|
||
|
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
|
||
|
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
#pragma region Remaining Bullet and Effect Rendering
|
||
|
for(Effect*e:backgroundEffectsLower){
|
||
|
if(!e->rendered){
|
||
|
e->Draw();
|
||
|
}
|
||
|
}
|
||
|
for(Bullet*b:bulletsLower){
|
||
|
if(!b->rendered){
|
||
|
b->Draw();
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
#pragma region Permanent Foreground Rendering
|
||
|
for(TileRenderData*tile:tileForegroundList){
|
||
|
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||
|
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
|
||
|
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
|
||
|
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
|
||
|
distToPlayer/=4;
|
||
|
if(distToPlayer<1){distToPlayer=1;}
|
||
|
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
|
||
|
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
for(Effect*e:foregroundEffectsLower){
|
||
|
e->Draw();
|
||
|
}
|
||
|
|
||
|
tilePreparationList.clear();
|
||
|
tileForegroundList.clear();
|
||
|
|
||
2 years ago
|
#pragma region Bridge Layer Rendering
|
||
|
if(bridgeLayer!=nullptr){
|
||
1 year ago
|
for (int x = view.GetTopLeftTile().x/game->GetCurrentMap().tilewidth-1; x <= view.GetBottomRightTile().x/game->GetCurrentMap().tilewidth; x++){
|
||
|
for (int y = view.GetTopLeftTile().y/game->GetCurrentMap().tilewidth-1; y <= view.GetBottomRightTile().y/game->GetCurrentMap().tilewidth; y++){
|
||
1 year ago
|
if(x>=0&&x<GetCurrentMap().width&&y>=0&&y<GetCurrentMap().height){
|
||
2 years ago
|
int tileID=bridgeLayer->tiles[y][x]-1;
|
||
|
if(tileID!=-1){
|
||
|
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||
1 year ago
|
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
|
||
|
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
|
||
2 years ago
|
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||
|
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||
|
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||
1 year ago
|
view.DrawPartialDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)},tileSheet.tileset->tileset->Decal(),vi2d{tileSheetX,tileSheetY}*game->GetCurrentMap().tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)},{255,255,255,uint8_t(255-bridgeFadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||
2 years ago
|
#ifdef DEBUG_COLLISIONS
|
||
|
if(tileSheet.tileset.collision.find(tileSheetIndex)!=tileSheet.tileset.collision.end()){
|
||
|
geom2d::rect<int>collision=tileSheet.tileset.collision[tileSheetIndex].collision;
|
||
1 year ago
|
view.FillRectDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128});
|
||
|
view.DrawRectDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth+collision.pos,collision.size,GREY);
|
||
2 years ago
|
}
|
||
|
#endif
|
||
2 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
#pragma endregion
|
||
2 years ago
|
for(Effect*e:backgroundEffectsUpper){
|
||
1 year ago
|
e->rendered=false;
|
||
2 years ago
|
}
|
||
1 year ago
|
for(ZoneData&zone:upperEndZones){
|
||
|
RenderZone(zone.zone);
|
||
|
}
|
||
1 year ago
|
for(int index:dropsBeforeUpper){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
2 years ago
|
for(Monster*m:monstersBeforeUpper){
|
||
|
m->Draw();
|
||
2 years ago
|
}
|
||
2 years ago
|
if(player->upperLevel){
|
||
1 year ago
|
RenderPlayer(player->GetPos(),{1,1});
|
||
2 years ago
|
}
|
||
1 year ago
|
for(int index:dropsAfterUpper){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
2 years ago
|
for(Monster*m:monstersAfterUpper){
|
||
|
m->Draw();
|
||
|
}
|
||
|
for(Bullet*b:bulletsUpper){
|
||
1 year ago
|
b->rendered=false;
|
||
2 years ago
|
}
|
||
2 years ago
|
if(player->OnUpperLevel()){
|
||
|
RenderPrecastTargetingIndicator();
|
||
|
}
|
||
1 year ago
|
|
||
|
#pragma region Upper Foreground Rendering Preparation
|
||
2 years ago
|
for(TileGroup&group:upperForegroundTileGroups){
|
||
1 year ago
|
if(view.IsRectVisible(group.GetRange().pos,group.GetRange().size)){
|
||
|
if(geom2d::overlaps(group.GetFadeRange(),player->pos)){
|
||
2 years ago
|
group.playerBehind=true;
|
||
|
group.fadeFactor=std::min(group.fadeFactor+fElapsedTime,TileGroup::FADE_TIME);
|
||
|
} else {
|
||
|
group.playerBehind=false;
|
||
|
group.fadeFactor=std::max(group.fadeFactor-fElapsedTime,0.f);
|
||
|
}
|
||
2 years ago
|
for(TileRenderData&tile:group.GetTiles()){
|
||
1 year ago
|
tile.tileOpacity=group.fadeFactor;
|
||
|
if(tile.tileSheet.tileset->collision.find(tile.tileID)!=tile.tileSheet.tileset->collision.end()){
|
||
|
tilePreparationList.push_back(&tile);
|
||
|
}else{
|
||
|
tileForegroundList.push_back(&tile);
|
||
|
}
|
||
2 years ago
|
}
|
||
1 year ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
#pragma endregion
|
||
1 year ago
|
|
||
|
std::sort(tilePreparationList.begin(),tilePreparationList.end(),[](TileRenderData*tile1,TileRenderData*tile2){return tile1->pos.y<tile2->pos.y||tile1->pos.y==tile2->pos.y&&tile1->layerID<tile2->layerID;});
|
||
1 year ago
|
std::sort(tileForegroundList.begin(),tileForegroundList.end(),[](TileRenderData*tile1,TileRenderData*tile2){return tile1->pos.y<tile2->pos.y||tile1->pos.y==tile2->pos.y&&tile1->layerID<tile2->layerID;});
|
||
1 year ago
|
|
||
|
#pragma region Upper Foreground Rendering w/Depth
|
||
|
tilePrevY=0;
|
||
|
for(TileRenderData*tile:tilePreparationList){
|
||
|
tilePrevY=tile->pos.y+12;
|
||
|
#pragma region Depth Ordered Upper Rendering
|
||
|
for(Effect*e:backgroundEffectsUpper){
|
||
|
if(!e->rendered&&e->pos.y<tilePrevY){
|
||
|
e->rendered=true;
|
||
|
e->Draw();
|
||
|
}
|
||
|
}
|
||
|
for(Bullet*b:bulletsUpper){
|
||
|
if(!b->rendered&&b->pos.y<tilePrevY){
|
||
|
b->rendered=true;
|
||
|
b->Draw();
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||
|
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
|
||
|
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
|
||
|
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
|
||
|
distToPlayer/=4;
|
||
|
if(distToPlayer<1){distToPlayer=1;}
|
||
|
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
|
||
|
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
#pragma region Remaining Upper Bullet and Effect Rendering
|
||
|
for(Effect*e:backgroundEffectsUpper){
|
||
|
if(!e->rendered){
|
||
|
e->Draw();
|
||
|
}
|
||
|
}
|
||
|
for(Bullet*b:bulletsUpper){
|
||
|
if(!b->rendered){
|
||
|
b->Draw();
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
#pragma region Permanent Upper Foreground Rendering
|
||
|
for(TileRenderData*tile:tileForegroundList){
|
||
|
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
|
||
|
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
|
||
|
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
|
||
|
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
|
||
|
distToPlayer/=4;
|
||
|
if(distToPlayer<1){distToPlayer=1;}
|
||
|
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
|
||
|
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
for(Effect*e:foregroundEffectsUpper){
|
||
|
e->Draw();
|
||
|
}
|
||
|
|
||
2 years ago
|
for(std::vector<std::shared_ptr<DamageNumber>>::iterator it=DAMAGENUMBER_LIST.begin();it!=DAMAGENUMBER_LIST.end();++it){
|
||
|
DamageNumber*dn=(*it).get();
|
||
|
if(dn->pauseTime>0){
|
||
|
dn->pauseTime-=fElapsedTime;
|
||
|
} else{
|
||
|
dn->lifeTime+=fElapsedTime;
|
||
1 year ago
|
if(dn->lifeTime<=1){
|
||
2 years ago
|
if(dn->lifeTime<DamageNumber::MOVE_UP_TIME){
|
||
1 year ago
|
if(dn->invertedDirection){
|
||
1 year ago
|
dn->pos.y+=40*fElapsedTime;
|
||
1 year ago
|
}else{
|
||
|
dn->pos.y-=20*fElapsedTime;
|
||
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
1 year ago
|
switch(dn->type){
|
||
|
case HEALTH_LOSS:{
|
||
|
std::string text=std::to_string(dn->damage);
|
||
|
if(!dn->friendly){
|
||
|
view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,DARK_RED);
|
||
|
}else{
|
||
|
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,RED,VERY_DARK_GREY);
|
||
|
}
|
||
|
}break;
|
||
|
case HEALTH_GAIN:{
|
||
|
std::string text="+"+std::to_string(dn->damage);
|
||
|
if(!dn->friendly){
|
||
|
view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,DARK_GREEN);
|
||
|
}else{
|
||
|
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,GREEN,VERY_DARK_GREY);
|
||
|
}
|
||
|
}break;
|
||
|
case MANA_GAIN:{
|
||
|
std::string text="+"+std::to_string(dn->damage);
|
||
|
if(dn->friendly){
|
||
|
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLUE,VERY_DARK_GREY);
|
||
|
}
|
||
|
}break;
|
||
|
case INTERRUPT:{
|
||
|
std::string text="Interrupted!";
|
||
|
if(dn->friendly){
|
||
|
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLACK,VERY_DARK_GREY,{0.5,1});
|
||
|
}
|
||
|
}break;
|
||
1 year ago
|
case CRIT:{
|
||
|
std::string text=std::to_string(dn->damage);
|
||
|
if(!dn->friendly){
|
||
|
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,YELLOW,DARK_YELLOW);
|
||
|
}else{
|
||
|
view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLACK);
|
||
|
}
|
||
|
}break;
|
||
1 year ago
|
}
|
||
2 years ago
|
}
|
||
1 year ago
|
|
||
|
if(DEBUG_PATHFINDING){
|
||
|
std::vector<vf2d>pathing=game->pathfinder.Solve_AStar(player.get()->GetPos(),GetWorldMousePos(),8,player.get()->OnUpperLevel());
|
||
|
for(vf2d&square:pathing){
|
||
1 year ago
|
view.FillRectDecal(square*float(game->GetCurrentMap().tilewidth),{float(game->GetCurrentMap().tilewidth),float(game->GetCurrentMap().tilewidth)},DARK_GREEN);
|
||
1 year ago
|
}
|
||
|
}
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
Player*AiL::GetPlayer(){
|
||
2 years ago
|
return player.get();
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::RenderHud(){
|
||
1 year ago
|
ItemOverlay::Draw();
|
||
|
|
||
1 year ago
|
RenderCooldowns();
|
||
1 year ago
|
|
||
1 year ago
|
auto RenderCastbar=[&](const CastInfo&cast){
|
||
2 years ago
|
FillRectDecal(vf2d{ScreenWidth()/2-92.f,ScreenHeight()-90.f},{184,20},BLACK);
|
||
|
FillRectDecal(vf2d{ScreenWidth()/2-90.f,ScreenHeight()-88.f},{180,16},DARK_GREY);
|
||
1 year ago
|
float timer=cast.castTimer;
|
||
|
float totalTime=cast.castTotalTime;
|
||
|
std::string castText=cast.name;
|
||
2 years ago
|
GradientFillRectDecal(vf2d{ScreenWidth()/2-90.f,ScreenHeight()-88.f},{(timer/totalTime)*180,16},{247,125,37},{247,125,37},{247,184,37},{247,184,37});
|
||
|
std::stringstream castTimeDisplay;
|
||
|
castTimeDisplay<<std::fixed<<std::setprecision(1)<<timer;
|
||
2 years ago
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2+90.f,ScreenHeight()-80.f}-vf2d{float(GetTextSizeProp(castTimeDisplay.str()).x),0},castTimeDisplay.str(),WHITE,BLACK);
|
||
1 year ago
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2.f-GetTextSizeProp(castText).x*2/2,ScreenHeight()-64.f},castText,WHITE,BLACK,{2,3},std::numeric_limits<float>::max(),2.f);
|
||
1 year ago
|
};
|
||
1 year ago
|
|
||
1 year ago
|
if(GetPlayer()->GetCastInfo().castTimer>0){
|
||
|
RenderCastbar(GetPlayer()->GetCastInfo());
|
||
|
}else
|
||
|
if(GetPlayer()->GetEndZoneStandTime()>0){
|
||
|
RenderCastbar(CastInfo{"Exiting Level...",GetPlayer()->GetEndZoneStandTime(),"Player.End Zone Wait Time"_F});
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
DrawDecal({2,2},GFX["heart.png"].Decal());
|
||
|
DrawDecal({2,20},GFX["mana.png"].Decal());
|
||
2 years ago
|
std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X";
|
||
|
std::string text_mana=std::to_string(player->GetMana());
|
||
1 year ago
|
DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2},INFINITE);
|
||
|
DrawShadowStringPropDecal({24,23},text_mana,{192,192,255},BLACK,{1.5f,1.5f},INFINITE);
|
||
2 years ago
|
if(player->notEnoughManaDisplay.second>0){
|
||
|
std::string displayText="Not enough mana for "+player->notEnoughManaDisplay.first+"!";
|
||
2 years ago
|
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)}-GetTextSizeProp(displayText)/2,displayText,DARK_RED,VERY_DARK_RED);
|
||
2 years ago
|
}
|
||
2 years ago
|
if(player->notificationDisplay.second>0){
|
||
|
std::string displayText=player->notificationDisplay.first;
|
||
2 years ago
|
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)-24}-GetTextSizeProp(displayText)/2,displayText,BLUE,VERY_DARK_BLUE);
|
||
2 years ago
|
}
|
||
1 year ago
|
DisplayBossEncounterInfo();
|
||
2 years ago
|
if("debug_player_info"_I){
|
||
2 years ago
|
DrawShadowStringDecal({0,128},player->GetPos().str());
|
||
2 years ago
|
DrawShadowStringDecal({0,136},"Spd: "+std::to_string(player->GetMoveSpdMult()));
|
||
1 year ago
|
DrawShadowStringDecal({0,144},"HP Timer: "+std::to_string(player->hpRecoveryTimer));
|
||
|
DrawShadowStringDecal({0,152},"HP Recovery Amt: "+std::to_string(player->GetHPRecoveryPct()*player->GetMaxHealth()));
|
||
1 year ago
|
if(!ISBLANK(GetLoadoutItem(0))){
|
||
|
DrawShadowStringDecal({0,92},"Loadout Slot 1 Qty: "+std::to_string(GetLoadoutItem(0).lock()->Amt()));
|
||
|
}
|
||
1 year ago
|
DrawShadowStringDecal({0,1},"Selection: "+Menu::menus[INVENTORY_CONSUMABLES]->selection.str());
|
||
|
DrawShadowStringDecal({0,12},"Button Hold Time: "+std::to_string(Menu::menus[INVENTORY_CONSUMABLES]->buttonHoldTime));
|
||
1 year ago
|
}}
|
||
2 years ago
|
|
||
1 year ago
|
void AiL::RenderCooldowns(){
|
||
1 year ago
|
std::vector<Ability>cooldowns{
|
||
|
player->GetAbility1(),
|
||
|
player->GetAbility2(),
|
||
|
player->GetAbility3(),
|
||
|
player->GetAbility4(),
|
||
|
};
|
||
|
|
||
1 year ago
|
const auto DrawCooldown=[&](vf2d pos,Ability&a,int loadoutSlot=-1/*Set to 0-2 to get an item slot rendered instead*/){
|
||
|
bool circle=loadoutSlot==-1;
|
||
1 year ago
|
if(a.name!="???"){
|
||
|
if(a.cooldown>0.1){
|
||
1 year ago
|
vf2d iconScale={1,1};
|
||
1 year ago
|
if(loadoutSlot!=-1)iconScale={0.7f,0.7f};
|
||
1 year ago
|
DrawRotatedDecal(pos+vf2d{12,12},GFX[a.icon].Decal(),0,{12,12},iconScale,{255,255,255,64});
|
||
|
if(circle){
|
||
1 year ago
|
DrawPie(pos+vf2d{12,12},12,360-(a.cooldown/a.GetCooldownTime())*360,PixelLerp(a.barColor1,a.barColor2,(a.cooldown/a.GetCooldownTime())));
|
||
1 year ago
|
}else{
|
||
1 year ago
|
DrawSquarePie(pos+vf2d{12,12},10,360-(a.cooldown/a.GetCooldownTime())*360,PixelLerp(a.barColor1,a.barColor2,(a.cooldown/a.GetCooldownTime())));
|
||
1 year ago
|
}
|
||
1 year ago
|
std::stringstream cooldownTimeDisplay;
|
||
|
cooldownTimeDisplay<<std::fixed<<std::setprecision(1)<<a.cooldown;
|
||
|
DrawShadowStringPropDecal(pos+vf2d{12,12}-vf2d{float(GetTextSizeProp(cooldownTimeDisplay.str()).x*0.5),float(GetTextSizeProp(cooldownTimeDisplay.str()).y*1)}/2,cooldownTimeDisplay.str(),WHITE,BLACK,{0.5,1});
|
||
1 year ago
|
}else{
|
||
1 year ago
|
vf2d iconScale={1,1};
|
||
1 year ago
|
if(loadoutSlot!=-1)iconScale={0.7f,0.7f};
|
||
1 year ago
|
DrawRotatedDecal(pos+vf2d{12,12},GFX[a.icon].Decal(),0,{12,12},iconScale,WHITE);
|
||
1 year ago
|
}
|
||
1 year ago
|
|
||
1 year ago
|
Decal*overlayIcon=GFX["skill_overlay_icon.png"].Decal();
|
||
|
if(!circle)overlayIcon=GFX["square_skill_overlay_icon.png"].Decal();
|
||
|
DrawDecal(pos,overlayIcon);
|
||
1 year ago
|
if(a.input->Held()){
|
||
|
if(circle){
|
||
|
DrawPie(pos+vf2d{12,12},12,0,{255,255,255,64});
|
||
|
}else{
|
||
|
DrawSquarePie(pos+vf2d{12,12},10,0,{255,255,255,64});
|
||
|
}
|
||
|
}
|
||
1 year ago
|
|
||
1 year ago
|
Pixel shortNameCol=BLUE,manaCostShadowCol=DARK_BLUE,keyDisplayCol=YELLOW;
|
||
1 year ago
|
if(player->GetMana()<a.manaCost){
|
||
1 year ago
|
Decal*overlayOverlayIcon=GFX["skill_overlay_icon_overlay.png"].Decal();
|
||
|
if(!circle)overlayOverlayIcon=GFX["square_skill_overlay_icon_empty.png"].Decal();
|
||
|
DrawDecal(pos,overlayOverlayIcon,{1,1},DARK_RED);
|
||
1 year ago
|
shortNameCol=RED;
|
||
|
manaCostShadowCol=DARK_RED;
|
||
1 year ago
|
keyDisplayCol=RED;
|
||
1 year ago
|
}else
|
||
|
if(a.cooldown>0){
|
||
|
shortNameCol=GREY;
|
||
|
manaCostShadowCol=DARK_GREY;
|
||
1 year ago
|
keyDisplayCol=GREY;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
if(loadoutSlot!=-1){
|
||
1 year ago
|
const std::weak_ptr<Item>loadoutItem=GetLoadoutItem(loadoutSlot);
|
||
|
if(!loadoutItem.expired()&&loadoutItem.lock()->it!=nullptr){
|
||
|
uint32_t itemAmt=loadoutItem.lock()->Amt();
|
||
|
if(itemAmt>0){
|
||
|
std::string amtString="x"+std::to_string(itemAmt);
|
||
|
vf2d qtySize=vf2d{GetTextSize(amtString)}*vf2d{0.5f,0.75f};
|
||
|
DrawShadowStringDecal(pos+vf2d{20,20}-qtySize/2,amtString,WHITE,BLACK,{0.5f,0.75f});
|
||
|
}else{
|
||
|
DrawDecal(pos,GFX["square_skill_overlay_icon_empty.png"].Decal(),{1,1},DARK_RED);
|
||
|
shortNameCol=RED;
|
||
|
manaCostShadowCol=DARK_RED;
|
||
|
keyDisplayCol=RED;
|
||
|
}
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
if(a.manaCost>0){
|
||
1 year ago
|
vf2d manaCostSize=vf2d{GetTextSize(std::to_string(a.manaCost))}*vf2d{0.5f,0.75f};
|
||
|
DrawShadowStringDecal(pos+vf2d{20,4}-manaCostSize/2,std::to_string(a.manaCost),{192,192,255},manaCostShadowCol,{0.5f,0.75f});
|
||
1 year ago
|
}
|
||
1 year ago
|
|
||
1 year ago
|
vf2d keyDisplaySize=vf2d{GetTextSize(a.input->GetDisplayName())}*vf2d{0.5f,0.5f};
|
||
1 year ago
|
DrawShadowStringDecal(pos+vf2d{12,-2}-keyDisplaySize/2,a.input->GetDisplayName(),keyDisplayCol,BLACK,{0.5f,0.5f},std::numeric_limits<float>::max(),1);
|
||
1 year ago
|
|
||
1 year ago
|
vf2d shortNameSize=vf2d{GetTextSize(a.shortName)}*vf2d{0.5f,0.75f};
|
||
1 year ago
|
DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,{255,255,255,230},{0.5f,0.75f});
|
||
1 year ago
|
}
|
||
|
};
|
||
|
|
||
|
vf2d iconPos={8.f,float(ScreenHeight()-32)};
|
||
|
for(Ability&a:cooldowns){
|
||
|
if(a.name!="???"){
|
||
|
DrawCooldown(iconPos,a);
|
||
|
iconPos+={32,0};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DrawCooldown({float(ScreenWidth()-32),float(ScreenHeight()-32)},player->GetRightClickAbility());
|
||
1 year ago
|
|
||
|
for(int i=-1;i<2;i++){
|
||
|
int loadoutSlot=i+1;//0-2
|
||
|
|
||
|
Ability*a=&GetPlayer()->useItem1;
|
||
|
if(loadoutSlot==1){a=&GetPlayer()->useItem2;}else
|
||
|
if(loadoutSlot==2){a=&GetPlayer()->useItem3;}
|
||
|
DrawCooldown({float(ScreenWidth()/2+i*26-12),float(ScreenHeight()-26)},*a,loadoutSlot);
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::AddEffect(std::unique_ptr<Effect>foreground,std::unique_ptr<Effect> background){
|
||
2 years ago
|
AddEffect(std::move(background),true);
|
||
|
AddEffect(std::move(foreground));
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::AddEffect(std::unique_ptr<Effect> foreground,bool back){
|
||
2 years ago
|
if(back){
|
||
2 years ago
|
backgroundEffectsToBeInserted.push_back(std::move(foreground));
|
||
2 years ago
|
} else {
|
||
2 years ago
|
foregroundEffectsToBeInserted.push_back(std::move(foreground));
|
||
2 years ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
vf2d AiL::GetWorldMousePos(){
|
||
2 years ago
|
return GetMousePos()+view.GetWorldOffset();
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::SetupWorldShake(float duration){
|
||
1 year ago
|
worldShakeVel={13,-13};
|
||
2 years ago
|
worldShakeTime=duration;
|
||
1 year ago
|
worldShake=vf2d{player->GetPos()};
|
||
2 years ago
|
camera.SetTarget(worldShake);
|
||
|
}
|
||
|
|
||
2 years ago
|
|
||
1 year ago
|
void AiL::InitializeLevel(std::string mapFile,MapName map){
|
||
2 years ago
|
TMXParser level(mapFile);
|
||
2 years ago
|
|
||
2 years ago
|
size_t slashMarker = mapFile.find_last_of('/');
|
||
|
std::string baseDir=mapFile.substr(0,slashMarker+1);
|
||
|
MAP_DATA[map]=level.GetData();
|
||
|
for(XMLTag&tag:MAP_DATA[map].TilesetData){
|
||
2 years ago
|
size_t slashMarkerSourceDir = tag.data["source"].find_last_of('/');
|
||
|
std::string baseSourceDir=tag.data["source"].substr(slashMarkerSourceDir+1);
|
||
|
if(MAP_TILESETS.find("assets/maps/"+baseSourceDir)==MAP_TILESETS.end()){
|
||
|
TSXParser tileset(baseDir+tag.data["source"]);
|
||
1 year ago
|
Renderable*r=NEW Renderable();
|
||
1 year ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].tilewidth=tileset.GetData().tilewidth;
|
||
|
MAP_TILESETS["assets/maps/"+baseSourceDir].tileheight=tileset.GetData().tileheight;
|
||
2 years ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].tileset=r;
|
||
|
MAP_TILESETS["assets/maps/"+baseSourceDir].foregroundTiles=tileset.GetData().ForegroundTileData;
|
||
2 years ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].upperForegroundTiles=tileset.GetData().UpperForegroundTileData;
|
||
2 years ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].collision=tileset.GetData().CollisionData;
|
||
2 years ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].staircaseTiles=tileset.GetData().StaircaseData;
|
||
1 year ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].animationData=tileset.GetData().AnimationData;
|
||
1 year ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].reflectiveData=tileset.GetData().ReflectiveData;
|
||
1 year ago
|
std::cout<<"assets/maps/"+baseSourceDir<<" Animation Data Size: "<<MAP_TILESETS["assets/maps/"+baseSourceDir].animationData.size()<<std::endl;
|
||
1 year ago
|
std::string mapPath="assets/maps/"+tileset.GetData().ImageData.data["source"];
|
||
|
if(std::filesystem::exists(mapPath)){
|
||
|
r->Load(mapPath);
|
||
|
}else{
|
||
|
std::cout<<"WARNING! "<<mapPath<<" does not exist, auto-generating mock-up texture"<<std::endl;
|
||
|
r->Create(tileset.GetData().imagewidth,tileset.GetData().imageheight);
|
||
|
SetDrawTarget(r->Sprite());
|
||
|
int tileXCount=tileset.GetData().imagewidth/tileset.GetData().tilewidth;
|
||
|
int tileYCount=tileset.GetData().imageheight/tileset.GetData().tileheight;
|
||
|
vi2d tileSize={tileset.GetData().tilewidth,tileset.GetData().tileheight};
|
||
|
|
||
|
const int colorCombinations=255*6;
|
||
|
|
||
|
for(int y=0;y<tileYCount;y++){
|
||
|
for(int x=0;x<tileXCount;x++){
|
||
|
int colorCycleIndex=(y*255+x)%colorCombinations;
|
||
|
Pixel tileCol=WHITE;
|
||
|
if(colorCycleIndex<255){
|
||
|
tileCol={uint8_t(colorCycleIndex%255),0,0};
|
||
|
}else
|
||
|
if(colorCycleIndex<255*2){
|
||
|
tileCol={0,uint8_t(colorCycleIndex%255),0};
|
||
|
}else
|
||
|
if(colorCycleIndex<255*3){
|
||
|
tileCol={0,0,uint8_t(colorCycleIndex%255)};
|
||
|
}else
|
||
|
if(colorCycleIndex<255*4){
|
||
|
tileCol={uint8_t(colorCycleIndex%255),uint8_t(colorCycleIndex%255),0};
|
||
|
}else
|
||
|
if(colorCycleIndex<255*5){
|
||
|
tileCol={0,uint8_t(colorCycleIndex%255),uint8_t(colorCycleIndex%255)};
|
||
|
}else{
|
||
|
tileCol={uint8_t(colorCycleIndex%255),0,uint8_t(colorCycleIndex%255)};
|
||
|
}
|
||
|
FillRect(vi2d{x,y}*tileSize,tileSize,tileCol);
|
||
|
DrawRect(vi2d{x,y}*tileSize,tileSize,GREY);
|
||
|
DrawString(vi2d{x,y}*tileSize+vi2d{1,1},std::to_string(y*255+x),DARK_GREY);
|
||
|
}
|
||
|
}
|
||
|
SetDrawTarget(nullptr);
|
||
|
r->Decal()->Update();
|
||
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
1 year ago
|
|
||
|
if(MAP_DATA[map].MapData.optimized){
|
||
|
std::cout<<"Generating optimized map for Map "<<map<<std::endl;
|
||
1 year ago
|
MAP_DATA[map].optimizedTile=NEW Renderable();
|
||
1 year ago
|
MAP_DATA[map].optimizedTile->Create(MAP_DATA[map].MapData.width*MAP_DATA[map].MapData.tilewidth,MAP_DATA[map].MapData.height*MAP_DATA[map].MapData.tileheight);
|
||
|
SetDrawTarget(MAP_DATA[map].optimizedTile->Sprite());
|
||
|
Pixel::Mode prevMode=GetPixelMode();
|
||
|
SetPixelMode(Pixel::Mode::MASK);
|
||
|
Clear(BLANK);
|
||
|
for(int y=0;y<MAP_DATA[map].MapData.height;y++){
|
||
|
for(int x=0;x<MAP_DATA[map].MapData.width;x++){
|
||
|
for(auto&layer:MAP_DATA[map].LayerData){
|
||
|
int tileID=layer.tiles[y][x]-1;
|
||
|
if(tileID!=-1){
|
||
|
TilesheetData tileSheet=GetTileSheet(map,tileID);
|
||
|
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
|
||
|
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
|
||
|
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||
|
int tileSheetX=tileSheetIndex%tileSheetWidth;
|
||
|
int tileSheetY=tileSheetIndex/tileSheetWidth;
|
||
|
vi2d pos=vi2d{x,y}*tileSheet.tileset->tilewidth;
|
||
|
DrawPartialSprite(pos,tileSheet.tileset->tileset->Sprite(),vi2d{tileSheetX,tileSheetY}*tileSheet.tileset->tilewidth,{tileSheet.tileset->tilewidth,tileSheet.tileset->tileheight});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
SetPixelMode(prevMode);
|
||
|
MAP_DATA[map].optimizedTile->Decal()->Update();
|
||
|
SetDrawTarget(nullptr);
|
||
|
std::cout<<" Clearing Layer Data..."<<std::endl;
|
||
|
MAP_DATA[map].LayerData.clear();
|
||
|
}
|
||
1 year ago
|
|
||
|
for(ConnectionPoint&cp:State_OverworldMap::connections){
|
||
1 year ago
|
if(cp.levelDataExists)continue;
|
||
1 year ago
|
if(VisualNovel::storyLevelData.count(cp.map)){ //Visual novel story data for story levels.
|
||
|
cp.levelDataExists=true;
|
||
|
}
|
||
1 year ago
|
if(LEVEL_NAMES.count(cp.map)&&&MapHelper::MapFromString(cp.map)==&MAP_DATA[map]){
|
||
1 year ago
|
MAP_DATA[map].name=cp.name;
|
||
1 year ago
|
for(std::string spawn:MAP_DATA[map].spawns){
|
||
1 year ago
|
cp.spawns.push_back(spawn);
|
||
|
}
|
||
|
cp.levelDataExists=true;
|
||
|
}
|
||
|
}
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::LoadLevel(MapName map){
|
||
2 years ago
|
SPAWNER_LIST.clear();
|
||
2 years ago
|
foregroundTileGroups.clear();
|
||
1 year ago
|
upperForegroundTileGroups.clear();
|
||
1 year ago
|
MONSTER_LIST.clear();
|
||
2 years ago
|
currentLevel=map;
|
||
1 year ago
|
levelTime=0;
|
||
1 year ago
|
bossName="";
|
||
|
encounterDuration=0;
|
||
|
totalDamageDealt=0;
|
||
|
encounterStarted=false;
|
||
|
totalBossEncounterMobs=0;
|
||
1 year ago
|
Inventory::Clear("Monster Loot");
|
||
|
Inventory::Clear("Stage Loot");
|
||
1 year ago
|
GetPlayer()->hp=GetPlayer()->GetMaxHealth();
|
||
1 year ago
|
GetPlayer()->mana=GetPlayer()->GetMaxMana();
|
||
1 year ago
|
GetPlayer()->SetState(State::NORMAL);
|
||
|
GetPlayer()->GetCastInfo()={};
|
||
1 year ago
|
GetPlayer()->ResetAccumulatedXP();
|
||
2 years ago
|
|
||
1 year ago
|
#pragma region Monster Spawn Data Setup
|
||
1 year ago
|
for(auto&[key,value]:MAP_DATA[map].SpawnerData){
|
||
|
SpawnerTag&spawnData=MAP_DATA[map].SpawnerData[key];
|
||
1 year ago
|
std::vector<std::pair<std::string,vf2d>>monster_list;
|
||
2 years ago
|
|
||
1 year ago
|
vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2;
|
||
|
for(XMLTag&monster:spawnData.monsters){
|
||
1 year ago
|
std::string monsterName=monster.GetString("value");
|
||
|
monster_list.push_back({monsterName,{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}});
|
||
1 year ago
|
}
|
||
1 year ago
|
SPAWNER_LIST.push_back(MonsterSpawner{{spawnData.ObjectData.GetFloat("x"),spawnData.ObjectData.GetFloat("y")},spawnerRadius*2,monster_list,spawnData.upperLevel,spawnData.bossNameDisplay});
|
||
1 year ago
|
}
|
||
|
#pragma endregion
|
||
|
|
||
|
#pragma region Identify Upper Foreground Tiles
|
||
|
auto GetUpperZones=[&](){
|
||
|
for(auto&zoneSet:MAP_DATA[map].ZoneData){
|
||
|
if(zoneSet.first=="UpperZone"){ //We are interested in all upper zones.
|
||
|
return zoneSet.second;
|
||
|
}
|
||
|
}
|
||
1 year ago
|
return std::vector<ZoneData>{};
|
||
1 year ago
|
};
|
||
1 year ago
|
for(ZoneData&zone:GetUpperZones()){
|
||
|
int zoneX=zone.zone.pos.x/game->GetCurrentMap().tilewidth; //snap to grid
|
||
|
int zoneY=zone.zone.pos.y/game->GetCurrentMap().tilewidth;
|
||
|
int zoneW=zone.zone.right().start.x/game->GetCurrentMap().tilewidth-zoneX;
|
||
|
int zoneH=zone.zone.bottom().start.y/game->GetCurrentMap().tilewidth-zoneY;
|
||
1 year ago
|
for(int x=zoneX;x<zoneX+zoneW;x++){
|
||
|
for(int y=zoneY;y<zoneY+zoneH;y++){
|
||
|
for(LayerTag&layer:MAP_DATA[map].LayerData){
|
||
|
int tile=layer.tiles[y][x]-1;
|
||
|
TilesheetData tileSheet=GetTileSheet(currentLevel,tile);
|
||
|
int tileSheetIndex=tile-(tileSheet.firstgid-1);
|
||
|
if(IsForegroundTile(tileSheet,tileSheetIndex)){
|
||
|
layer.tiles[y][x]+=1000000;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
|
|
||
|
#pragma region Foreground and Upper Foreground Tile Fade Group Setup
|
||
|
std::set<vi2d>foregroundTilesAdded,upperForegroundTilesAdded;
|
||
1 year ago
|
for(int x=0;x<GetCurrentMap().width;x++){
|
||
|
for(int y=0;y<GetCurrentMap().height;y++){
|
||
1 year ago
|
int layerID=0;
|
||
|
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
|
||
|
int tileID=layer.tiles[y][x]-1;
|
||
|
if(tileID!=-1){
|
||
|
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
|
||
1 year ago
|
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
|
||
|
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
|
||
1 year ago
|
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||
|
int realTileSheetIndex=(tileID%1000000)-(tileSheet.firstgid-1);
|
||
|
int tileSheetX=realTileSheetIndex%tileSheetWidth;
|
||
|
int tileSheetY=realTileSheetIndex/tileSheetWidth;
|
||
1 year ago
|
int checkTileIndex=tileID;
|
||
|
int checkTileID=tileSheetIndex;
|
||
1 year ago
|
#pragma region TileGroupShenanigans
|
||
|
auto SetupTileGroups=[&](std::function<bool(TilesheetData,int)>IsForeground,TileRenderData tile,std::set<vi2d>&foregroundTilesIncluded,std::vector<TileGroup>&groups){
|
||
|
if(foregroundTilesIncluded.find({x,y})==foregroundTilesIncluded.end()&&IsForeground(tileSheet,tileSheetIndex)){
|
||
|
std::queue<vi2d>tileGroupChecks;
|
||
|
TileGroup group;
|
||
|
foregroundTilesIncluded.insert({x,y});
|
||
|
group.InsertTile(tile);
|
||
|
if(x>0&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{-1,0})==foregroundTilesIncluded.end())tileGroupChecks.push({x-1,y});
|
||
1 year ago
|
if(x<GetCurrentMap().width-1&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{1,0})==foregroundTilesIncluded.end())tileGroupChecks.push({x+1,y});
|
||
1 year ago
|
if(y>0&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{0,-1})==foregroundTilesIncluded.end())tileGroupChecks.push({x,y-1});
|
||
1 year ago
|
if(y<GetCurrentMap().height-1&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{0,1})==foregroundTilesIncluded.end())tileGroupChecks.push({x,y+1});
|
||
1 year ago
|
auto IterateThroughOtherLayers=[&](vi2d pos,bool loopAll=false){
|
||
|
int layer2ID=0;
|
||
|
bool hadForeground=false;
|
||
|
for(LayerTag&layer2:MAP_DATA[currentLevel].LayerData){
|
||
|
if(!loopAll&&&layer==&layer2){layer2ID++;continue;};
|
||
|
int tileID=layer2.tiles[pos.y][pos.x]-1;
|
||
|
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID%1000000);
|
||
1 year ago
|
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
|
||
|
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
|
||
1 year ago
|
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||
|
int realTileSheetIndex=(tileID%1000000)-(tileSheet.firstgid-1);
|
||
|
int tileSheetX=realTileSheetIndex%tileSheetWidth;
|
||
|
int tileSheetY=realTileSheetIndex/tileSheetWidth;
|
||
1 year ago
|
TileRenderData tile={tileSheet,vi2d{pos.x,pos.y}*game->GetCurrentMap().tilewidth,vi2d{tileSheetX,tileSheetY}*game->GetCurrentMap().tilewidth,realTileSheetIndex,layer2ID};
|
||
1 year ago
|
if(IsForeground(tileSheet,tileSheetIndex)){
|
||
|
foregroundTilesIncluded.insert({pos.x,pos.y});
|
||
|
group.InsertTile(tile);
|
||
|
hadForeground=true;
|
||
|
}
|
||
|
layer2ID++;
|
||
1 year ago
|
}
|
||
1 year ago
|
return hadForeground;
|
||
|
};
|
||
|
IterateThroughOtherLayers({x,y});
|
||
|
while(!tileGroupChecks.empty()){
|
||
|
vi2d&pos=tileGroupChecks.front();
|
||
|
if(IterateThroughOtherLayers(pos,true)){
|
||
|
foregroundTilesIncluded.insert({pos.x,pos.y}); //Regardless of if we found a foreground tile or not, we need to add this to not get stuck in an infinite loop.
|
||
|
vi2d targetPos=pos+vi2d{-1,0};
|
||
|
if(pos.x>0&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||
|
targetPos=pos+vi2d{1,0};
|
||
1 year ago
|
if(pos.x<GetCurrentMap().width-1&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||
1 year ago
|
targetPos=pos+vi2d{0,-1};
|
||
|
if(pos.y>0&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||
|
targetPos=pos+vi2d{0,1};
|
||
1 year ago
|
if(pos.y<GetCurrentMap().height-1&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||
1 year ago
|
}
|
||
|
tileGroupChecks.pop();
|
||
1 year ago
|
}
|
||
1 year ago
|
groups.push_back(group);
|
||
2 years ago
|
}
|
||
1 year ago
|
};
|
||
1 year ago
|
TileRenderData tile={tileSheet,vi2d{x,y}*game->GetCurrentMap().tilewidth,vi2d{tileSheetX,tileSheetY}*game->GetCurrentMap().tilewidth,realTileSheetIndex,layerID};
|
||
1 year ago
|
SetupTileGroups([&](TilesheetData sheet,int tileID){return IsForegroundTile(sheet,tileID);},tile,foregroundTilesAdded,foregroundTileGroups);
|
||
|
SetupTileGroups([&](TilesheetData sheet,int tileID){return IsUpperForegroundTile(tileID);},tile,upperForegroundTilesAdded,upperForegroundTileGroups);
|
||
|
#pragma endregion
|
||
|
}
|
||
|
layerID++;
|
||
2 years ago
|
}
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
for(TileGroup&group:foregroundTileGroups){
|
||
|
std::sort(group.GetTiles().begin(),group.GetTiles().end(),[](TileRenderData&t1,TileRenderData&t2){return t1.layerID<t2.layerID;});
|
||
2 years ago
|
}
|
||
1 year ago
|
for(TileGroup&group:upperForegroundTileGroups){
|
||
|
std::sort(group.GetTiles().begin(),group.GetTiles().end(),[](TileRenderData&t1,TileRenderData&t2){return t1.layerID<t2.layerID;});
|
||
1 year ago
|
}
|
||
1 year ago
|
#pragma endregion
|
||
1 year ago
|
|
||
|
#pragma region Foreground and Upper Foreground Tile Fade Group Individual Object Grouping Splitting
|
||
|
auto SplitUp=[&](std::vector<TileGroup>&group){
|
||
|
std::multimap<vi2d,TileRenderData>data;
|
||
|
using TileDataGroup=std::multimap<vi2d,TileRenderData>; //See below.
|
||
|
std::vector<TileDataGroup>splitUpData; //This stores every tile group with tiles as a multi map.
|
||
|
std::set<vi2d>iteratedTiles;
|
||
|
for(TileGroup&group:group){
|
||
|
for(TileRenderData&tile:group.GetTiles()){
|
||
|
data.insert({tile.pos,tile});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
auto IsAdjacent=[](int tile1,int tile2,int tileSheetWidth){
|
||
|
return abs(tile1-tile2)==1||abs(tile1-tile2)>=tileSheetWidth-1&&abs(tile1-tile2)<=tileSheetWidth+1;
|
||
|
};
|
||
|
for(auto&[key,tile]:data){
|
||
|
if(iteratedTiles.count(key))continue;
|
||
|
vi2d loc=key;
|
||
|
auto loc_tiles=data.equal_range(loc);
|
||
|
for(auto&it=loc_tiles.first;it!=loc_tiles.second;++it){ //For each tile that exists at this position...
|
||
|
TileRenderData&tile=(*it).second;
|
||
|
bool groupFound=false;
|
||
|
for(TileDataGroup&group:splitUpData){ //See if this position can fit into any existing tile groups
|
||
|
for(int y=-24;y<=24;y+=24){
|
||
|
for(int x=-24;x<=24;x+=24){
|
||
|
if(x!=0||y!=0){ //Check every adjacent location for a possible adjacent tile.
|
||
|
vi2d checkOffset=loc+vi2d{x,y};
|
||
|
auto find_tiles=group.equal_range(checkOffset);//Each tile group consists of tiles that may be adjacent to us. Find all tiles that are adjacent to us in this tile group.
|
||
|
for(auto&it=find_tiles.first;it!=find_tiles.second;++it){
|
||
|
//These are all tiles that were found adjacent to the location we are checking for. See if they match a potential group.
|
||
|
TileRenderData&foundTile=(*it).second;
|
||
|
if(tile.tileSheet.tileset==foundTile.tileSheet.tileset){ //Let's first see if they are even in the same tileset.
|
||
|
//Let's get how many tiles wide this tile sheet is.
|
||
|
int tileWidth=tile.tileSheet.tileset->tilewidth;
|
||
|
int tileSheetWidth=tile.tileSheet.tileset->tileset->Sprite()->width/tileWidth;
|
||
|
if(IsAdjacent(tile.tileID,foundTile.tileID,tileSheetWidth)){
|
||
|
group.insert({loc,tile});//We add this tile to the group! It is adjacent!
|
||
|
groupFound=true;
|
||
|
goto groupIterationDone;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
groupIterationDone:
|
||
|
if(!groupFound){
|
||
|
splitUpData.push_back({});
|
||
|
splitUpData.back().insert({loc,tile}); //Since we could not find a group to fit in, we had to start a brand new group.
|
||
|
}
|
||
|
}
|
||
|
iteratedTiles.insert(loc);
|
||
|
}
|
||
|
group.clear();
|
||
|
for(auto&split:splitUpData){
|
||
|
TileGroup newGroup;
|
||
|
for(auto&[key,value]:split){
|
||
|
newGroup.InsertTile(value);
|
||
|
}
|
||
|
group.push_back(newGroup);
|
||
|
}
|
||
|
};
|
||
|
SplitUp(foregroundTileGroups);
|
||
|
SplitUp(upperForegroundTileGroups);
|
||
|
#pragma endregion
|
||
2 years ago
|
|
||
1 year ago
|
#pragma region Bridge Layer Setup
|
||
|
bridgeLayerIndex=-1;
|
||
1 year ago
|
for(int counter=0;LayerTag&layer:MAP_DATA[map].LayerData){
|
||
1 year ago
|
if(IsBridgeLayer(layer)){
|
||
|
bridgeLayerIndex=counter;
|
||
|
}
|
||
|
counter++;
|
||
2 years ago
|
}
|
||
1 year ago
|
#pragma endregion
|
||
2 years ago
|
|
||
2 years ago
|
player->upperLevel=false; //Assume player starts on lower level.
|
||
|
player->SetPos(MAP_DATA[map].MapData.playerSpawnLocation);
|
||
1 year ago
|
|
||
|
vf2d cameraStartPos=player->GetPos()+vf2d(-24*6,0);
|
||
1 year ago
|
camera.MoveCamera(cameraStartPos);
|
||
2 years ago
|
|
||
2 years ago
|
pathfinder.Initialize();
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
bool AiL::IsUpperForegroundTile(int tileID){
|
||
1 year ago
|
return tileID>=1000000;
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
bool AiL::IsForegroundTile(TilesheetData sheet,int tileID){
|
||
1 year ago
|
return sheet.tileset->foregroundTiles.find(tileID)!=sheet.tileset->foregroundTiles.end();
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
TilesheetData AiL::GetTileSheet(MapName map,int tileID){
|
||
2 years ago
|
std::vector<XMLTag>&tileData=MAP_DATA[map].TilesetData;
|
||
|
if(tileData.size()==1){
|
||
2 years ago
|
size_t slashMarkerSourceDir = tileData[0].data["source"].find_last_of('/');
|
||
|
std::string baseSourceDir=tileData[0].data["source"].substr(slashMarkerSourceDir+1);
|
||
1 year ago
|
return {&MAP_TILESETS["assets/maps/"+baseSourceDir],1};
|
||
2 years ago
|
} else {
|
||
|
for (int i=1;i<tileData.size();i++){
|
||
1 year ago
|
if(tileID%1000000<stoi(tileData[i].data["firstgid"])-1){
|
||
1 year ago
|
size_t slashMarkerSourceDir = tileData[size_t(i-1)].data["source"].find_last_of('/');
|
||
|
std::string baseSourceDir=tileData[size_t(i-1)].data["source"].substr(slashMarkerSourceDir+1);
|
||
1 year ago
|
return {&MAP_TILESETS["assets/maps/"+baseSourceDir],stoi(tileData[i-1].data["firstgid"])};
|
||
2 years ago
|
}
|
||
|
}
|
||
2 years ago
|
size_t slashMarkerSourceDir = tileData[tileData.size()-1].data["source"].find_last_of('/');
|
||
|
std::string baseSourceDir=tileData[tileData.size()-1].data["source"].substr(slashMarkerSourceDir+1);
|
||
1 year ago
|
return {&MAP_TILESETS["assets/maps/"+baseSourceDir],stoi(tileData[tileData.size()-1].data["firstgid"])};
|
||
2 years ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
bool AiL::HasTileCollision(MapName map,vf2d pos,bool upperLevel){
|
||
2 years ago
|
geom2d::rect<int>collisionRect=GetTileCollision(map,pos,upperLevel);
|
||
1 year ago
|
vi2d collisionRectSnapPos=vi2d{pos/float(game->GetCurrentMap().tilewidth)}*game->GetCurrentMap().tilewidth;
|
||
2 years ago
|
collisionRect.pos+=collisionRectSnapPos;
|
||
|
return geom2d::overlaps(collisionRect,pos);
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
bool AiL::IsBridgeLayer(LayerTag&layer){
|
||
2 years ago
|
return layer.tag.data.find("class")!=layer.tag.data.end()&&layer.tag.data["class"]=="Bridge";
|
||
|
}
|
||
|
|
||
1 year ago
|
geom2d::rect<int>AiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
|
||
1 year ago
|
if(pos.x<0||pos.y<0||pos.x>=GetCurrentMap().width*game->GetCurrentMap().tilewidth||pos.y>=GetCurrentMap().height*game->GetCurrentMap().tilewidth)return NO_COLLISION;
|
||
2 years ago
|
#pragma region Lower Bridge Collision Check
|
||
|
if(!upperLevel){ //We are looking for lower bridge collisions.
|
||
1 year ago
|
for(ZoneData&zone:MAP_DATA[map].ZoneData["LowerBridgeCollision"]){
|
||
|
if(geom2d::contains(zone.zone,pos)){
|
||
1 year ago
|
return {{0,0},{game->GetCurrentMap().tilewidth,game->GetCurrentMap().tilewidth}};
|
||
2 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
2 years ago
|
//The logic here is, if there's a tile on the bridge, we respect that tile instead if we're on the upper level. So we don't check other layers when we are on the upper level and there is a tile below us.
|
||
|
if(upperLevel&&bridgeLayerIndex!=-1){
|
||
1 year ago
|
int tileID=MAP_DATA[map].LayerData[bridgeLayerIndex].tiles[int(pos.y)/game->GetCurrentMap().tilewidth][int(pos.x)/game->GetCurrentMap().tilewidth]-1;
|
||
2 years ago
|
if(tileID!=-1){
|
||
1 year ago
|
if (GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){
|
||
|
return GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
|
||
2 years ago
|
}
|
||
|
return NO_COLLISION;
|
||
|
}
|
||
|
}
|
||
1 year ago
|
geom2d::rect<int>foundRect=NO_COLLISION;
|
||
1 year ago
|
for(int counter=0;LayerTag&layer:MAP_DATA[map].LayerData){
|
||
1 year ago
|
//auto HasNoClass=[&](){return layer.tag.data.find("class")==layer.tag.data.end();};
|
||
|
if(counter!=bridgeLayerIndex){
|
||
1 year ago
|
int tileID=layer.tiles[int(pos.y)/game->GetCurrentMap().tilewidth][int(pos.x)/game->GetCurrentMap().tilewidth]-1;
|
||
1 year ago
|
if(tileID!=-1&&GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){
|
||
|
geom2d::rect<int>collisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
|
||
1 year ago
|
if(foundRect.pos==NO_COLLISION.pos&&foundRect.size==NO_COLLISION.size){
|
||
|
foundRect=collisionRect;
|
||
|
}else{
|
||
1 year ago
|
//When we find another rectangle in the same square, we expand it to consume the area, whichever tile creates a larger surface or the combination of the two.
|
||
1 year ago
|
foundRect.pos.x=std::min(foundRect.pos.x,collisionRect.pos.x);
|
||
|
foundRect.pos.y=std::min(foundRect.pos.y,collisionRect.pos.y);
|
||
|
foundRect.size.x=std::max(foundRect.size.x,collisionRect.size.x);
|
||
|
foundRect.size.y=std::max(foundRect.size.y,collisionRect.size.y);
|
||
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
counter++;
|
||
2 years ago
|
}
|
||
1 year ago
|
return foundRect;
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
MapName AiL::GetCurrentLevel(){
|
||
2 years ago
|
return currentLevel;
|
||
|
}
|
||
|
|
||
1 year ago
|
std::map<std::string,std::vector<ZoneData>>&AiL::GetZoneData(MapName map){
|
||
2 years ago
|
return MAP_DATA[map].ZoneData;
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::ChangePlayerClass(Class cl){
|
||
1 year ago
|
Ability itemAbility1=player->useItem1;
|
||
|
Ability itemAbility2=player->useItem2;
|
||
|
Ability itemAbility3=player->useItem3;
|
||
1 year ago
|
uint32_t oldMoney=player->money;
|
||
1 year ago
|
uint8_t level=player->level;
|
||
|
uint8_t levelCap=player->levelCap;
|
||
|
uint32_t totalXPEarned=player->totalXPEarned;
|
||
|
uint32_t currentLevelXP=player->currentLevelXP;
|
||
1 year ago
|
std::set<MenuComponent*>moneyListeners=Player::moneyListeners;
|
||
1 year ago
|
EntityStats previousStats=player->stats;
|
||
2 years ago
|
switch(cl){
|
||
|
case WARRIOR:{
|
||
1 year ago
|
player.reset(NEW Warrior(player.get()));
|
||
2 years ago
|
}break;
|
||
|
case THIEF:{
|
||
1 year ago
|
player.reset(NEW Thief(player.get()));
|
||
2 years ago
|
}break;
|
||
|
case TRAPPER:{
|
||
1 year ago
|
player.reset(NEW Trapper(player.get()));
|
||
2 years ago
|
}break;
|
||
|
case RANGER:{
|
||
1 year ago
|
player.reset(NEW Ranger(player.get()));
|
||
2 years ago
|
}break;
|
||
|
case WIZARD:{
|
||
1 year ago
|
player.reset(NEW Wizard(player.get()));
|
||
2 years ago
|
}break;
|
||
|
case WITCH:{
|
||
1 year ago
|
player.reset(NEW Witch(player.get()));
|
||
2 years ago
|
}break;
|
||
|
}
|
||
1 year ago
|
player->level=level;
|
||
|
player->levelCap=levelCap;
|
||
|
player->totalXPEarned=totalXPEarned;
|
||
|
player->currentLevelXP=currentLevelXP;
|
||
1 year ago
|
player->stats=previousStats;
|
||
1 year ago
|
player->SetBaseStat("Health",DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt());
|
||
|
player->hp=player->GetBaseStat("Health");
|
||
1 year ago
|
player->SetBaseStat("Mana",DATA.GetProperty("Player.BaseMana").GetInt());
|
||
|
player->mana=player->GetBaseStat("Mana");
|
||
1 year ago
|
player->SetBaseStat("Attack",DATA.GetProperty(player->GetClassName()+".BaseAtk").GetInt());
|
||
1 year ago
|
player->hpGrowthRate=float(DATA.GetProperty(player->GetClassName()+".HealthGrowthRate").GetReal());
|
||
|
player->atkGrowthRate=float(DATA.GetProperty(player->GetClassName()+".AtkGrowthRate").GetReal());
|
||
1 year ago
|
player->money=oldMoney;
|
||
2 years ago
|
sig::Animation::SetupPlayerAnimations();
|
||
2 years ago
|
GetPlayer()->UpdateIdleAnimation(DOWN);
|
||
1 year ago
|
GetPlayer()->SetItem1UseFunc(itemAbility1);
|
||
|
GetPlayer()->SetItem2UseFunc(itemAbility2);
|
||
|
GetPlayer()->SetItem3UseFunc(itemAbility3);
|
||
1 year ago
|
camera.SetTarget(player->GetPos());
|
||
1 year ago
|
Player::moneyListeners=moneyListeners;
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::InitializeClasses(){
|
||
2 years ago
|
Warrior::Initialize();
|
||
|
Thief::Initialize();
|
||
|
Ranger::Initialize();
|
||
|
Trapper::Initialize();
|
||
|
Wizard::Initialize();
|
||
|
Witch::Initialize();
|
||
2 years ago
|
Warrior::InitializeClassAbilities();
|
||
|
Thief::InitializeClassAbilities();
|
||
|
Ranger::InitializeClassAbilities();
|
||
|
Trapper::InitializeClassAbilities();
|
||
|
Wizard::InitializeClassAbilities();
|
||
|
Witch::InitializeClassAbilities();
|
||
|
}
|
||
|
|
||
1 year ago
|
std::string AiL::GetString(std::string key){
|
||
2 years ago
|
return DATA.GetProperty(key).GetString();
|
||
|
}
|
||
|
|
||
1 year ago
|
datafilestringdata AiL::GetStringList(std::string key){
|
||
2 years ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
1 year ago
|
int AiL::GetInt(std::string key){
|
||
2 years ago
|
return DATA.GetProperty(key).GetInt();
|
||
|
}
|
||
|
|
||
1 year ago
|
datafileintdata AiL::GetIntList(std::string key){
|
||
2 years ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
1 year ago
|
float AiL::GetFloat(std::string key){
|
||
1 year ago
|
return float(DATA.GetProperty(key).GetReal());
|
||
2 years ago
|
}
|
||
|
|
||
1 year ago
|
datafilefloatdata AiL::GetFloatList(std::string key){
|
||
2 years ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
1 year ago
|
double AiL::GetDouble(std::string key){
|
||
2 years ago
|
return DATA.GetProperty(key).GetReal();
|
||
|
}
|
||
|
|
||
1 year ago
|
datafiledoubledata AiL::GetDoubleList(std::string key){
|
||
2 years ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
2 years ago
|
int main()
|
||
|
{
|
||
1 year ago
|
{
|
||
1 year ago
|
AiL demo;
|
||
1 year ago
|
if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4))
|
||
|
demo.Start();
|
||
|
}
|
||
|
|
||
1 year ago
|
#ifdef _DEBUG
|
||
|
HANDLE hLogFile;
|
||
|
hLogFile = CreateFile(L"assets/memoryleak.txt", GENERIC_WRITE,
|
||
|
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
|
||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
_CrtSetReportMode(_CRT_WARN,_CRTDBG_MODE_FILE);
|
||
|
_CrtSetReportFile(_CRT_WARN,hLogFile);
|
||
|
_CrtDumpMemoryLeaks();
|
||
|
CloseHandle(hLogFile);
|
||
|
|
||
|
std::ifstream file("assets/memoryleak.txt");
|
||
|
bool leaked=false;
|
||
|
while(file.good()){
|
||
|
std::string line;
|
||
|
std::getline(file,line);
|
||
1 year ago
|
if(line.find("AiL\\")!=std::string::npos){
|
||
1 year ago
|
if(!leaked){
|
||
|
leaked=true;
|
||
|
std::cout<<std::endl<<std::endl<<std::endl<<"Memory leak detected!"<<std::endl;
|
||
|
}
|
||
|
std::cout<<line<<std::endl;
|
||
|
std::getline(file,line);
|
||
|
std::cout<<line<<std::endl;
|
||
|
}
|
||
|
}
|
||
1 year ago
|
if(leaked)ERR("")
|
||
1 year ago
|
#endif
|
||
2 years ago
|
|
||
|
return 0;
|
||
2 years ago
|
}
|
||
|
|
||
2 years ago
|
datafilestringdata operator ""_s(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
2 years ago
|
datafileintdata operator ""_i(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
2 years ago
|
datafilefloatdata operator ""_f(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
2 years ago
|
datafiledoubledata operator ""_d(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
2 years ago
|
Pixel operator ""_Pixel(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return {uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(0)),uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(1)),uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(2)),uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(3))};
|
||
|
}
|
||
|
|
||
2 years ago
|
std::string operator ""_S(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return DATA.GetProperty(std::string(key,len)).GetString();
|
||
|
}
|
||
|
|
||
2 years ago
|
int operator ""_I(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return DATA.GetProperty(std::string(key,len)).GetInt();
|
||
|
}
|
||
|
|
||
2 years ago
|
float operator ""_F(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return float(DATA.GetProperty(std::string(key,len)).GetReal());
|
||
2 years ago
|
}
|
||
|
|
||
2 years ago
|
float operator ""_FRange(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return float(util::random(float(DATA.GetProperty(std::string(key,len)).GetReal(1)-DATA.GetProperty(std::string(key,len)).GetReal(0)))+DATA.GetProperty(std::string(key,len)).GetReal(0));
|
||
2 years ago
|
}
|
||
1 year ago
|
float operator ""_Pct(long double pct){
|
||
|
return pct/100;
|
||
|
}
|
||
2 years ago
|
|
||
2 years ago
|
double operator ""_D(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
2 years ago
|
return DATA.GetProperty(std::string(key,len)).GetReal();
|
||
2 years ago
|
}
|
||
|
|
||
|
datafile operator ""_A(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return DATA.GetProperty(std::string(key,len));
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::OutputDebugInfo(const char*key,std::size_t len){
|
||
2 years ago
|
if(utils::datafile::DEBUG_ACCESS_OPTIONS){
|
||
1 year ago
|
std::string k=std::string(key);
|
||
|
if(!k.starts_with("debug_")){
|
||
|
std::cout<<"Reading "<<k<<std::endl;
|
||
|
}
|
||
2 years ago
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
bool AiL::IsReflectiveTile(TilesheetData tileSheet,int tileID){
|
||
1 year ago
|
return tileSheet.tileset->reflectiveData.find(tileID)!=tileSheet.tileset->reflectiveData.end();
|
||
|
}
|
||
|
|
||
1 year ago
|
bool AiL::OnUserDestroy(){
|
||
1 year ago
|
if(GameState::STATE!=GameState::states[States::MAIN_MENU]){ //If we're on the main menu, we don't have a save file loaded. So we would skip saving the game.
|
||
|
SaveFile::SaveGame();
|
||
|
}
|
||
1 year ago
|
GFX.Reset();
|
||
1 year ago
|
for(auto&[key,value]:MAP_DATA){
|
||
|
if(MAP_DATA[key].optimizedTile!=nullptr){
|
||
|
delete MAP_DATA[key].optimizedTile;
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
for(auto&[key,value]:MAP_TILESETS){
|
||
|
delete value.tileset;
|
||
1 year ago
|
}
|
||
1 year ago
|
for(auto&[key,value]:GameState::states){
|
||
|
delete value;
|
||
1 year ago
|
}
|
||
1 year ago
|
delete[]pathfinder.nodes;
|
||
|
Menu::CleanupAllMenus();
|
||
1 year ago
|
for(auto&[key,value]:MonsterData::imgs){
|
||
|
delete value;
|
||
1 year ago
|
}
|
||
1 year ago
|
return true;
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::InitializeLevels(){
|
||
1 year ago
|
#define INITLEVEL(map) \
|
||
1 year ago
|
LEVEL_NAMES[#map]=map; \
|
||
|
InitializeLevel("map_path"_S + "Levels."#map ## _S,map);
|
||
1 year ago
|
|
||
|
INITLEVEL(WORLD_MAP);
|
||
|
INITLEVEL(CAMPAIGN_1_1);
|
||
|
INITLEVEL(BOSS_1);
|
||
|
INITLEVEL(CAMPAIGN_1_2);
|
||
1 year ago
|
INITLEVEL(CAMPAIGN_1_3);
|
||
|
INITLEVEL(CAMPAIGN_1_4);
|
||
|
INITLEVEL(CAMPAIGN_1_5);
|
||
1 year ago
|
|
||
1 year ago
|
Test::RunMapTests();
|
||
|
|
||
1 year ago
|
LEVEL_NAMES.SetInitialized();
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::SpawnMonster(vf2d pos,MonsterData&data,bool upperLevel,bool isBossSpawn){
|
||
1 year ago
|
monstersToBeSpawned.push_back(Monster(pos,data,upperLevel,isBossSpawn));
|
||
1 year ago
|
if(isBossSpawn){
|
||
|
totalBossEncounterMobs++;
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::DrawPie(vf2d center,float radius,float degreesCut,Pixel col){
|
||
1 year ago
|
DrawPolygonDecal(nullptr,circleCooldownPoints,circleCooldownPoints,std::max(1,int(degreesCut/4)),center,radius,col);
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::DrawSquarePie(vf2d center,float radius,float degreesCut,Pixel col){
|
||
1 year ago
|
DrawPolygonDecal(nullptr,squareCircleCooldownPoints,squareCircleCooldownPoints,std::max(1,int(degreesCut/4)),center,radius,col);
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::InitializeDefaultKeybinds(){
|
||
1 year ago
|
Player::KEY_ABILITY1.AddKeybind({KEY,Q});
|
||
|
Player::KEY_ABILITY2.AddKeybind({KEY,E});
|
||
|
Player::KEY_ABILITY3.AddKeybind({KEY,R});
|
||
|
Player::KEY_ABILITY4.AddKeybind({KEY,F});
|
||
|
Player::KEY_DEFENSIVE.AddKeybind({MOUSE,Mouse::RIGHT});
|
||
1 year ago
|
Player::KEY_ITEM1.AddKeybind({KEY,K1});
|
||
|
Player::KEY_ITEM2.AddKeybind({KEY,K2});
|
||
|
Player::KEY_ITEM3.AddKeybind({KEY,K3});
|
||
1 year ago
|
KEY_ATTACK.AddKeybind({MOUSE,Mouse::LEFT});
|
||
|
KEY_LEFT.AddKeybind({KEY,LEFT});
|
||
|
KEY_LEFT.AddKeybind({KEY,A});
|
||
|
KEY_RIGHT.AddKeybind({KEY,RIGHT});
|
||
|
KEY_RIGHT.AddKeybind({KEY,D});
|
||
|
KEY_UP.AddKeybind({KEY,UP});
|
||
|
KEY_UP.AddKeybind({KEY,W});
|
||
|
KEY_DOWN.AddKeybind({KEY,DOWN});
|
||
|
KEY_DOWN.AddKeybind({KEY,S});
|
||
1 year ago
|
KEY_CONFIRM.AddKeybind({MOUSE,Mouse::LEFT});
|
||
|
KEY_CONFIRM.AddKeybind({KEY,ENTER});
|
||
1 year ago
|
KEY_MENU.AddKeybind({KEY,ESCAPE});
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::SetBossNameDisplay(std::string name,float time){
|
||
1 year ago
|
bossName=name;
|
||
|
bossDisplayTimer=time;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
bool AiL::InBossEncounter(){
|
||
1 year ago
|
return bossName!="";
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::StartBossEncounter(){
|
||
1 year ago
|
if(!encounterStarted){
|
||
|
encounterStarted=true;
|
||
1 year ago
|
totalDamageDealt=0;
|
||
|
encounterDuration=0.f;
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::DisplayBossEncounterInfo(){
|
||
1 year ago
|
if(bossDisplayTimer>0){
|
||
|
std::string displayText="- "+bossName+" -";
|
||
|
|
||
|
uint8_t alpha=0;
|
||
|
if(bossDisplayTimer>4){
|
||
|
alpha=uint8_t((5-bossDisplayTimer)*255);
|
||
|
}else
|
||
|
if(bossDisplayTimer>1){
|
||
|
alpha=255;
|
||
|
}else{
|
||
|
alpha=uint8_t((bossDisplayTimer)*255);
|
||
|
}
|
||
|
vf2d textScale={3,5};
|
||
|
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/2)}-vf2d{GetTextSizeProp(displayText)}*textScale/2,displayText,{252, 186, 3, alpha},{128,0,0,alpha},textScale,2);
|
||
|
}
|
||
|
if(InBossEncounter()){
|
||
|
Pixel displayCol=totalBossEncounterMobs==0?Pixel{224, 133, 29}:WHITE;
|
||
|
std::string timeDisplay=util::timerStr(encounterDuration);
|
||
|
vf2d timerTextSize=GetTextSizeProp(timeDisplay);
|
||
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()-2-timerTextSize.x,2+10*0},timeDisplay,displayCol);
|
||
|
vf2d displayTextSize=GetTextSizeProp(bossName);
|
||
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()-2-displayTextSize.x,2+10*1},bossName,displayCol);
|
||
|
if(encounterDuration>=1){
|
||
|
std::string dpsText="DPS: "+std::to_string(int(totalDamageDealt/encounterDuration));
|
||
|
vf2d dpsDisplayTextSize=GetTextSizeProp(dpsText);
|
||
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()-2-dpsDisplayTextSize.x,2+10*2},dpsText,displayCol);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
1 year ago
|
void AiL::BossDamageDealt(int damage){
|
||
1 year ago
|
totalDamageDealt+=damage;
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::ReduceBossEncounterMobCount(){
|
||
1 year ago
|
totalBossEncounterMobs--;
|
||
|
if(totalBossEncounterMobs<0){
|
||
1 year ago
|
ERR("WARNING! Boss Encounter mob count is less than zero, THIS SHOULD NOT BE HAPPENING!");
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::RenderMenu(){
|
||
1 year ago
|
if(!GamePaused()&&Menu::stack.size()>0){
|
||
1 year ago
|
Menu::stack.back()->Update(this);
|
||
|
}
|
||
|
if(Menu::stack.size()>0){
|
||
1 year ago
|
for(Menu*menu:Menu::stack){
|
||
1 year ago
|
if(menu->cover)FillRectDecal({0,0},WINDOW_SIZE,{0,0,0,uint8_t(255*0.4)});
|
||
1 year ago
|
menu->Draw(this);
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::InitializeGraphics(){
|
||
1 year ago
|
circleCooldownPoints.push_back({0,0});
|
||
1 year ago
|
squareCircleCooldownPoints.push_back({0,0});
|
||
1 year ago
|
for(int i=0;i<=360;i+=4){
|
||
1 year ago
|
float angle=util::degToRad(float(i))-PI/2;
|
||
1 year ago
|
if(i==0){circleCooldownPoints.push_back(vf2d{cos(angle),sin(angle)});}
|
||
1 year ago
|
circleCooldownPoints.push_back(vf2d{cos(angle),sin(angle)});
|
||
1 year ago
|
vf2d point=vf2d{cos(angle),sin(angle)}*sqrt(2.1f);
|
||
|
point.x=std::clamp(point.x,-1.f,1.f);
|
||
|
point.y=std::clamp(point.y,-1.f,1.f);
|
||
1 year ago
|
if(i==0){squareCircleCooldownPoints.push_back(point);}
|
||
1 year ago
|
squareCircleCooldownPoints.push_back(point);
|
||
1 year ago
|
}
|
||
|
|
||
|
for(auto&val:DATA["Images"].GetKeys()){
|
||
|
std::string key=val.first;
|
||
1 year ago
|
std::string imgFile=DATA["Images"][key].GetString(0);
|
||
1 year ago
|
std::cout<<"Loading image "+imgFile+"..."<<std::endl;
|
||
1 year ago
|
bool filtering=false;
|
||
|
bool clamping=false;
|
||
|
if(DATA["Images"][key].GetValueCount()>1){
|
||
|
filtering=bool(DATA["Images"][key].GetInt(1));
|
||
|
}
|
||
|
if(DATA["Images"][key].GetValueCount()>2){
|
||
|
clamping=bool(DATA["Images"][key].GetInt(2));
|
||
|
}
|
||
|
if(!GFX.count(imgFile)&&GFX[imgFile].Load("GFX_Prefix"_S+imgFile,nullptr,filtering,clamping)!=rcode::OK){
|
||
1 year ago
|
ERR(" WARNING! Failed to load "+imgFile+"!")
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
//Specifically split up the 9 patch image into multiple pieces for each theme.
|
||
1 year ago
|
const auto&unordered_map=DATA["Themes"].GetKeys();
|
||
|
std::vector<std::pair<std::string,size_t>>mappedKeys;
|
||
|
mappedKeys.reserve(unordered_map.size());
|
||
|
for(auto&key:unordered_map){
|
||
|
mappedKeys.push_back(key);
|
||
|
}
|
||
|
std::sort(mappedKeys.begin(),mappedKeys.end(),[](std::pair<std::string,size_t>&key1,std::pair<std::string,size_t>&key2){return key1.second<key2.second;});
|
||
1 year ago
|
for(auto&[key,value]:mappedKeys){
|
||
|
std::string themeName=key;
|
||
1 year ago
|
std::string imgPath=DATA["Themes"][themeName]["filename"].GetString();
|
||
1 year ago
|
Renderable&img=GFX["theme_img_directory"_S+imgPath+".png"];
|
||
|
img.Load("GFX_Prefix"_S+"theme_img_directory"_S+imgPath+".png");
|
||
|
Renderable&sourceImg=img;
|
||
1 year ago
|
Pixel::Mode prevMode=GetPixelMode();
|
||
|
SetPixelMode(Pixel::Mode::MASK);
|
||
|
for(int x=0;x<3;x++){
|
||
|
for(int y=0;y<3;y++){
|
||
1 year ago
|
std::string patchKey=themeName+"_"+std::to_string(x)+std::to_string(y)+".png";
|
||
|
Renderable&patchImg=GFX[patchKey];
|
||
|
patchImg.Create("Interface.9PatchSize"_i[0],"Interface.9PatchSize"_i[1],false,false);
|
||
|
SetDrawTarget(patchImg.Sprite());
|
||
1 year ago
|
Clear(BLANK);
|
||
1 year ago
|
DrawPartialSprite({0,0},sourceImg.Sprite(),{x*"Interface.9PatchSize"_i[0],y*"Interface.9PatchSize"_i[1]},{"Interface.9PatchSize"_i[0],"Interface.9PatchSize"_i[1]});
|
||
|
patchImg.Decal()->Update();
|
||
1 year ago
|
SetDrawTarget(nullptr);
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
SetPixelMode(prevMode);
|
||
1 year ago
|
|
||
1 year ago
|
std::cout<<"Theme "<<themeName<<" Loaded."<<std::endl;
|
||
1 year ago
|
|
||
|
if(DATA["Themes"][themeName].HasProperty("CustomBack")){
|
||
|
std::string backPath=DATA["Themes"][themeName]["CustomBack"].GetString();
|
||
|
std::cout<<" Custom background detected, Loading "<<backPath<<"..."<<std::endl;
|
||
|
if(!GFX.count(backPath)){
|
||
|
Renderable&background=GFX[backPath];
|
||
|
background.Load("GFX_Prefix"_S+backPath,nullptr,false,false);
|
||
|
}
|
||
|
Menu::themes[themeName]=Theme{themeName,imgPath,bool(DATA["Themes"][themeName]["Tiled"].GetInt()),DATA["Themes"][themeName]["ButtonColor"].GetPixel(),DATA["Themes"][themeName]["HighlightColor"].GetPixel(),GFX.at(backPath).Decal()};
|
||
|
}else{
|
||
|
Menu::themes[themeName]=Theme{themeName,imgPath,bool(DATA["Themes"][themeName]["Tiled"].GetInt()),DATA["Themes"][themeName]["ButtonColor"].GetPixel(),DATA["Themes"][themeName]["HighlightColor"].GetPixel()};
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
for(std::string img:VisualNovel::graphicsToLoad){
|
||
|
Renderable&image=GFX[img];
|
||
|
image.Load("GFX_Prefix"_S+img);
|
||
|
}
|
||
|
std::cout<<VisualNovel::graphicsToLoad.size()<<" images for visual novel engine have been loaded."<<std::endl;
|
||
|
|
||
1 year ago
|
Menu::themes.SetInitialized();
|
||
|
std::cout<<Menu::themes.size()<<" themes have been loaded."<<std::endl;
|
||
1 year ago
|
GFX.SetInitialized();
|
||
|
std::cout<<GFX.size()<<" images have been loaded."<<std::endl;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
MapTag AiL::GetCurrentMap(){
|
||
1 year ago
|
return MAP_DATA[GetCurrentLevel()].MapData;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::ValidateGameStatus(){
|
||
1 year ago
|
if(IToggleable::uninitializedToggleGroupItems.size()>0){
|
||
|
for(IToggleable*item:IToggleable::uninitializedToggleGroupItems){
|
||
|
std::cout<<"\tUninitialized Toggle Item Ptr: 0x"<<std::hex<<item<<std::endl;
|
||
|
}
|
||
1 year ago
|
ERR("Error TOGGLE!!! Please turn on debug_toggleable_items in configuration.txt and re-run the program to see which toggleable item did not properly get a toggleable group set.");
|
||
1 year ago
|
}
|
||
1 year ago
|
if(Unlock::unlocks.size()==0){
|
||
1 year ago
|
ERR("WARNING! There are no unlocks set! This was probably not intentional! It means no areasa on the overworld are accessible!");
|
||
1 year ago
|
}
|
||
|
if(!Unlock::IsUnlocked(State_OverworldMap::GetCurrentConnectionPoint())){
|
||
1 year ago
|
ERR("WARNING! The current connection point is not unlocked! This is not supposed to be happening.")
|
||
1 year ago
|
}
|
||
1 year ago
|
if(ItemDrop::gravity!="ItemDrop.Item Drop Gravity"_F){
|
||
|
ERR("WARNING! Gravity constant for item drops was not initialized to "<<"Item Drop Gravity"_F<<". Actual value: "<<ItemDrop::gravity);
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::RenderVersionInfo(){
|
||
1 year ago
|
std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD));
|
||
1 year ago
|
DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4f,versionStr,WHITE,BLACK,{0.4f,0.4f},std::numeric_limits<float>::max(),0.4f);
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
int AiL::GetCurrentChapter(){
|
||
1 year ago
|
return chapter;
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::SetChapter(int chapter){
|
||
1 year ago
|
this->chapter=chapter;
|
||
1 year ago
|
for(MenuComponent*component:Menu::chapterListeners){
|
||
|
component->OnChapterUpdate(chapter);
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
const std::weak_ptr<Item>AiL::GetLoadoutItem(int slot){
|
||
1 year ago
|
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
|
||
|
return loadout[slot];
|
||
|
}
|
||
|
|
||
1 year ago
|
void AiL::SetLoadoutItem(int slot,std::string itemName){
|
||
1 year ago
|
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
|
||
|
if(Inventory::GetItemCount(itemName)>0){
|
||
1 year ago
|
loadout[slot]=Inventory::CopyItem(itemName)[0];
|
||
1 year ago
|
GetLoadoutItem(slot).lock()->amt=std::min((uint32_t)"Player.Item Loadout Limit"_I,GetLoadoutItem(slot).lock()->Amt()); //We are only allowed to have up to 10 maximum of an item on a journey.
|
||
1 year ago
|
InputGroup*inputGroup=nullptr;
|
||
|
switch(slot){
|
||
|
case 0:{
|
||
|
inputGroup=&Player::KEY_ITEM1;
|
||
|
}break;
|
||
|
case 1:{
|
||
|
inputGroup=&Player::KEY_ITEM2;
|
||
|
}break;
|
||
|
case 2:{
|
||
|
inputGroup=&Player::KEY_ITEM3;
|
||
|
}break;
|
||
|
}
|
||
1 year ago
|
Ability itemAbility{itemName,"","","Item.Item Cooldown Time"_F,0,inputGroup,"items/"+itemName+".png",VERY_DARK_RED,DARK_RED,PrecastData{GetLoadoutItem(slot).lock()->CastTime(),0,0},true};
|
||
1 year ago
|
itemAbility.actionPerformedDuringCast=GetLoadoutItem(slot).lock()->UseDuringCast();
|
||
1 year ago
|
|
||
|
switch(slot){
|
||
|
case 0:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
1 year ago
|
return game->UseLoadoutItem(0);
|
||
1 year ago
|
};
|
||
|
game->GetPlayer()->SetItem1UseFunc(itemAbility);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->SetItem(loadout[slot]);
|
||
1 year ago
|
}break;
|
||
|
case 1:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
1 year ago
|
return game->UseLoadoutItem(1);
|
||
1 year ago
|
};
|
||
|
game->GetPlayer()->SetItem2UseFunc(itemAbility);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 2")->SetItem(loadout[slot]);
|
||
1 year ago
|
}break;
|
||
|
case 2:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
1 year ago
|
return game->UseLoadoutItem(2);
|
||
1 year ago
|
};
|
||
|
game->GetPlayer()->SetItem3UseFunc(itemAbility);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->SetItem(loadout[slot]);
|
||
1 year ago
|
}break;
|
||
|
}
|
||
|
|
||
1 year ago
|
}else{
|
||
|
ERR("Trying to set item "+itemName+" in Loadout slot "+std::to_string(slot)+" when said item does not exist in our inventory!");
|
||
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
bool AiL::UseLoadoutItem(int slot){
|
||
1 year ago
|
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
|
||
1 year ago
|
if(GetLoadoutItem(slot).lock()->Amt()>0){
|
||
|
Inventory::UseItem(GetLoadoutItem(slot).lock()->ActualName());
|
||
|
GetLoadoutItem(slot).lock()->amt--;
|
||
1 year ago
|
return true;
|
||
1 year ago
|
}
|
||
1 year ago
|
return false;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::ClearLoadoutItem(int slot){
|
||
1 year ago
|
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
|
||
1 year ago
|
loadout[slot].reset();
|
||
1 year ago
|
InputGroup*inputGroup=nullptr;
|
||
|
switch(slot){
|
||
|
case 0:{
|
||
|
inputGroup=&Player::KEY_ITEM1;
|
||
|
}break;
|
||
|
case 1:{
|
||
|
inputGroup=&Player::KEY_ITEM2;
|
||
|
}break;
|
||
|
case 2:{
|
||
|
inputGroup=&Player::KEY_ITEM3;
|
||
|
}break;
|
||
|
}
|
||
|
Ability itemAbility{"???","","",0,0,inputGroup,""};
|
||
|
switch(slot){
|
||
|
case 0:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
1 year ago
|
return game->UseLoadoutItem(0);
|
||
1 year ago
|
};
|
||
|
game->GetPlayer()->SetItem1UseFunc(itemAbility);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->SetItem(Item::BLANK);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->UpdateIcon();
|
||
|
}break;
|
||
|
case 1:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
|
return game->UseLoadoutItem(1);
|
||
|
};
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 2")->SetItem(Item::BLANK);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 2")->UpdateIcon();
|
||
|
}break;
|
||
|
case 2:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
|
return game->UseLoadoutItem(2);
|
||
|
};
|
||
|
game->GetPlayer()->SetItem3UseFunc(itemAbility);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->SetItem(Item::BLANK);
|
||
1 year ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->UpdateIcon();
|
||
|
}break;
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::RenderFadeout(){
|
||
1 year ago
|
uint8_t alpha=0;
|
||
|
if(fadeOutDuration>0){
|
||
|
fadeOutDuration=std::max(0.f,fadeOutDuration-GetElapsedTime());
|
||
|
if(fadeOutDuration==0){
|
||
|
GameState::_ChangeState(transitionState);
|
||
|
}
|
||
|
alpha=uint8_t(util::lerp(0,255,1-(fadeOutDuration/fadeOutTotalTime)));
|
||
|
}else
|
||
|
if(fadeInDuration>0){
|
||
|
fadeInDuration=std::max(0.f,fadeInDuration-GetElapsedTime());
|
||
|
alpha=uint8_t(util::lerp(255,0,1-(fadeInDuration/fadeOutTotalTime)));
|
||
|
}
|
||
|
FillRectDecal({0,0},GetScreenSize(),{0,0,0,alpha});
|
||
|
}
|
||
|
|
||
1 year ago
|
bool AiL::GamePaused(){
|
||
1 year ago
|
return fadeOutDuration>0;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::EndGame(){
|
||
1 year ago
|
gameEnd=true;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
#ifndef __EMSCRIPTEN__
|
||
1 year ago
|
::discord::Result AiL::SetupDiscord(){
|
||
1 year ago
|
auto result=::discord::Core::Create(1186719371750555780,DiscordCreateFlags_NoRequireDiscord,&Discord);
|
||
1 year ago
|
if(result==::discord::Result::Ok){
|
||
|
Discord->SetLogHook(
|
||
1 year ago
|
discord::LogLevel::Debug, [](discord::LogLevel level, const char* message) {
|
||
|
std::cerr << "Log(" << static_cast<uint32_t>(level) << "): " << message << "\n";
|
||
|
});
|
||
1 year ago
|
std::cout<<"Connected to Discord!"<<std::endl;
|
||
|
UpdateDiscordStatus("Main Menu",player.get()->GetClassName());
|
||
1 year ago
|
}else{
|
||
|
std::cout<<"Could not connect to Discord. Error Code "<<int(result)<<std::endl;
|
||
1 year ago
|
}
|
||
1 year ago
|
return result;
|
||
1 year ago
|
}
|
||
|
#endif
|
||
1 year ago
|
|
||
1 year ago
|
void AiL::UpdateDiscordStatus(std::string levelName,std::string className){
|
||
1 year ago
|
#ifndef __EMSCRIPTEN__
|
||
|
if(Discord){
|
||
|
::discord::Activity newActivity{};
|
||
|
newActivity.SetDetails(levelName.c_str());
|
||
1 year ago
|
newActivity.SetState(std::format("Level {} {}",player->Level(),className).c_str());
|
||
1 year ago
|
discord::ActivityTimestamps×tamps=newActivity.GetTimestamps();
|
||
|
timestamps.SetStart(gameStarted);
|
||
|
newActivity.SetType(discord::ActivityType::Playing);
|
||
|
discord::ActivityAssets&assets=newActivity.GetAssets();
|
||
1 year ago
|
assets.SetLargeImage("ail_512");
|
||
1 year ago
|
assets.SetLargeText(game->sAppName.c_str());
|
||
1 year ago
|
assets.SetSmallText(std::format("Level {} {}",player->Level(),className).c_str());
|
||
1 year ago
|
|
||
1 year ago
|
if(levelName!="Main Menu"){
|
||
|
std::for_each(className.begin(),className.end(),[](char&c){c=std::tolower(c);});
|
||
|
assets.SetSmallImage(("nico-"+className+"_512").c_str());
|
||
|
}
|
||
|
Discord->ActivityManager().UpdateActivity(newActivity,[](::discord::Result result){
|
||
1 year ago
|
if(result==::discord::Result::Ok){
|
||
|
std::cout<<"Discord Activity successfully updated!"<<std::endl;
|
||
|
}else{
|
||
|
std::cout<<"Could not update Discord Activity. Error Code "<<int(result)<<std::endl;
|
||
|
}
|
||
1 year ago
|
});
|
||
1 year ago
|
}else{
|
||
|
if(SetupDiscord()==::discord::Result::Ok){
|
||
|
UpdateDiscordStatus(levelName,className);
|
||
|
}
|
||
1 year ago
|
}
|
||
|
#endif
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::InitializePlayerLevelCap(){
|
||
1 year ago
|
while(DATA["PlayerXP"].HasProperty(std::format("LEVEL[{}]",player->levelCap+1))){
|
||
|
player->levelCap++;
|
||
|
}
|
||
|
if(player->levelCap<=1)ERR("Could not detect level cap properly!")
|
||
|
std::cout<<"Level cap detected as "<<int(player->levelCap)<<std::endl;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::ResetGame(){
|
||
1 year ago
|
GameState::ChangeState(States::MAIN_MENU,0.5f);
|
||
1 year ago
|
for(int i=int(EquipSlot::HELMET);i<=int(EquipSlot::RING2);i<<=1){
|
||
|
Inventory::UnequipItem(EquipSlot(i));
|
||
|
}
|
||
|
for(auto&[cat,items]:ITEM_CATEGORIES){
|
||
|
Inventory::Clear(cat);
|
||
|
}
|
||
|
player->level=1;
|
||
|
player->stats.Reset();
|
||
|
player->ResetAccumulatedXP();
|
||
|
player->totalXPEarned=0;
|
||
1 year ago
|
player->SetMoney(100U);
|
||
1 year ago
|
for(int i=0;i<loadout.size();i++){
|
||
|
game->ClearLoadoutItem(i);
|
||
|
}
|
||
1 year ago
|
Unlock::unlocks.clear();
|
||
|
Unlock::Initialize();
|
||
1 year ago
|
State_OverworldMap::SetStageMarker("Stage I-I");
|
||
|
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
|
||
1 year ago
|
SetChapter(1);
|
||
|
SaveFile::SetSaveFileName("");
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
void AiL::OnRequestCompleted(const std::string_view receivedData)const{
|
||
1 year ago
|
responseCallback(receivedData);
|
||
1 year ago
|
}
|
||
|
|
||
|
std::string operator ""_FS(const char*key,std::size_t len){
|
||
1 year ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return DATA.GetProperty(std::string(key,len)).GetFullString();
|
||
2 years ago
|
}
|