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)
|
||
|
~~~~~~~~~~~~~~~
|
||
|
|
||
11 months 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
|
||
1 year ago
|
#include "olcPGEX_TransformedView.h"
|
||
11 months ago
|
#include "AdventuresInLestoria.h"
|
||
1 year ago
|
#include "olcUTIL_Camera2D.h"
|
||
1 year ago
|
#include "DamageNumber.h"
|
||
1 year ago
|
#include "Bullet.h"
|
||
1 year ago
|
#include "Ability.h"
|
||
1 year ago
|
#include "Class.h"
|
||
1 year ago
|
#include "Version.h"
|
||
1 year ago
|
#include "TMXParser.h"
|
||
1 year ago
|
#include "TSXParser.h"
|
||
1 year ago
|
#include "Map.h"
|
||
1 year ago
|
#include "DEFINES.h"
|
||
1 year ago
|
#include "util.h"
|
||
1 year ago
|
#include <set>
|
||
|
#include <queue>
|
||
1 year ago
|
#include "Emitter.h"
|
||
1 year ago
|
#include "config.h"
|
||
1 year 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"
|
||
12 months ago
|
#include "MenuItemItemButton.h"
|
||
12 months ago
|
#include "Merchant.h"
|
||
11 months ago
|
#include "SaveFile.h"
|
||
11 months ago
|
#ifndef __EMSCRIPTEN__
|
||
11 months ago
|
#include "discord.h"
|
||
11 months ago
|
#endif
|
||
1 year ago
|
|
||
1 year ago
|
INCLUDE_EMITTER_LIST
|
||
11 months ago
|
INCLUDE_ITEM_CATEGORIES
|
||
1 year ago
|
|
||
1 year ago
|
bool _DEBUG_MAP_LOAD_INFO = false;
|
||
1 year ago
|
//360x240
|
||
1 year ago
|
vi2d WINDOW_SIZE={24*15,24*10};
|
||
1 year ago
|
safemap<std::string,Animate2D::FrameSequence>ANIMATION_DATA;
|
||
1 year ago
|
std::vector<Monster>MONSTER_LIST;
|
||
|
std::vector<MonsterSpawner>SPAWNER_LIST;
|
||
1 year ago
|
std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
|
||
1 year 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;
|
||
1 year ago
|
utils::datafile DATA;
|
||
11 months 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;
|
||
11 months ago
|
#ifndef __EMSCRIPTEN__
|
||
|
::discord::Core*Discord{};
|
||
|
#endif
|
||
1 year ago
|
|
||
11 months ago
|
float AiL::SIZE_CHANGE_SPEED=1;
|
||
1 year ago
|
|
||
11 months ago
|
AiL::AiL()
|
||
1 year ago
|
{
|
||
1 year ago
|
utils::datafile::Read(DATA,"assets/config/configuration.txt");
|
||
|
|
||
1 year ago
|
_DEBUG_MAP_LOAD_INFO=bool("debug_map_load_info"_I);
|
||
|
|
||
1 year ago
|
std::string CONFIG_PATH = "config_path"_S;
|
||
1 year ago
|
|
||
1 year ago
|
std::string GFX_CONFIG = CONFIG_PATH + "gfx_config"_S;
|
||
1 year ago
|
utils::datafile::Read(DATA,GFX_CONFIG);
|
||
1 year ago
|
WINDOW_SIZE={"WINDOW_SIZE"_i[0],"WINDOW_SIZE"_i[1]};
|
||
1 year ago
|
|
||
|
std::string MAP_CONFIG = CONFIG_PATH + "map_config"_S;
|
||
|
utils::datafile::Read(DATA,MAP_CONFIG);
|
||
1 year ago
|
|
||
1 year ago
|
std::string PLAYER_CONFIG = CONFIG_PATH + "player_config"_S;
|
||
|
utils::datafile::Read(DATA,PLAYER_CONFIG);
|
||
|
|
||
1 year 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);
|
||
|
|
||
12 months ago
|
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
|
||
|
utils::datafile::Read(DATA,ITEM_SET_CONFIG);
|
||
|
|
||
11 months ago
|
std::string ITEM_STATS_CONFIG = CONFIG_PATH + "item_stats_config"_S;
|
||
|
utils::datafile::Read(DATA,ITEM_STATS_CONFIG);
|
||
|
|
||
12 months 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;
|
||
|
|
||
12 months ago
|
for(const std::string&cl:DATA.GetProperty("class_list").GetValues()){
|
||
1 year ago
|
std::cout<<cl<<std::endl;
|
||
|
utils::datafile::Read(DATA,CONFIG_PATH + "class_directory"_S + cl + ".txt");
|
||
|
}
|
||
12 months ago
|
|
||
1 year ago
|
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
|
||
11 months ago
|
|
||
|
sAppName = "GAME_NAME"_S;
|
||
|
game=this;
|
||
11 months ago
|
gameStarted=time(NULL);
|
||
1 year ago
|
}
|
||
1 year ago
|
|
||
11 months ago
|
bool AiL::OnUserCreate(){
|
||
1 year ago
|
Font::init();
|
||
|
|
||
1 year ago
|
InitializeDefaultKeybinds();
|
||
1 year ago
|
|
||
|
VisualNovel::Initialize();
|
||
|
|
||
1 year ago
|
InitializeLevels();
|
||
1 year ago
|
|
||
1 year ago
|
//Initialize Camera.
|
||
|
camera=Camera2D{WINDOW_SIZE};
|
||
|
camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow);
|
||
1 year ago
|
camera.SetTarget(player->GetPos());
|
||
1 year ago
|
camera.SetWorldBoundary({0,0},GetCurrentMap().MapSize*GetCurrentMap().TileSize);
|
||
1 year ago
|
camera.EnableWorldBoundary(false);
|
||
11 months ago
|
|
||
|
ItemAttribute::Initialize();
|
||
1 year ago
|
|
||
|
ItemInfo::InitializeItems();
|
||
1 year ago
|
|
||
12 months ago
|
player=std::make_unique<Warrior>();
|
||
|
|
||
11 months 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();
|
||
|
|
||
12 months ago
|
Inventory::AddItem("Minor Health Potion",16);
|
||
1 year ago
|
Inventory::AddItem("Bandages",10);
|
||
11 months ago
|
Inventory::AddItem("Green Slime Remains",40);
|
||
1 year ago
|
Inventory::AddItem("Blue Slime Remains",22);
|
||
12 months ago
|
Inventory::AddItem("Copper Armor");
|
||
12 months ago
|
Inventory::AddItem("Copper Pants");
|
||
11 months ago
|
Inventory::AddItem("Copper Helmet");
|
||
|
Inventory::AddItem("Copper Shoes");
|
||
12 months ago
|
Inventory::AddItem("Shell Helmet");
|
||
|
Inventory::AddItem("Shell Armor");
|
||
11 months ago
|
Inventory::AddItem("Shell Armor");
|
||
|
Inventory::AddItem("Shell Armor");
|
||
12 months ago
|
Inventory::AddItem("Bone Armor");
|
||
12 months ago
|
Inventory::AddItem("Shell Gloves");
|
||
11 months ago
|
Inventory::AddItem("Shell Gloves",3);
|
||
12 months ago
|
Inventory::AddItem("Shell Shoes");
|
||
|
Inventory::AddItem("Bone Pants");
|
||
|
Inventory::AddItem("Bone Gloves");
|
||
11 months ago
|
Inventory::AddItem("Elixir of Bear Strength",3);
|
||
11 months ago
|
Inventory::AddItem("Leather Helmet");
|
||
11 months ago
|
Inventory::AddItem("Leather Pants");
|
||
|
Inventory::AddItem("Leather Gloves");
|
||
|
Inventory::AddItem("Leather Shoes");
|
||
11 months ago
|
Inventory::AddItem("Wooden Sword");
|
||
11 months ago
|
Inventory::AddItem("Laser Sword");
|
||
|
Inventory::AddItem("Shell Sword");
|
||
11 months ago
|
Inventory::AddItem("Ring of the Slime King",3);
|
||
1 year ago
|
|
||
1 year ago
|
LoadLevel(LEVEL_NAMES["starting_map"_S]);
|
||
1 year 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
|
|
||
12 months ago
|
Merchant::Initialize();
|
||
|
|
||
11 months ago
|
Stats::InitializeDamageReductionTable();
|
||
|
|
||
12 months ago
|
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
||
|
|
||
1 year ago
|
ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
|
||
11 months ago
|
#ifndef __EMSCRIPTEN__
|
||
|
SetupDiscord();
|
||
|
#endif
|
||
1 year ago
|
|
||
1 year ago
|
return true;
|
||
|
}
|
||
|
|
||
11 months 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();
|
||
11 months ago
|
#ifndef __EMSCRIPTEN__
|
||
|
if(Discord){
|
||
11 months ago
|
auto result=Discord->RunCallbacks();
|
||
|
if(result!=::discord::Result::Ok){
|
||
|
std::cout<<"Discord Error Code "<<int(result)<<std::endl;
|
||
|
delete Discord;
|
||
|
Discord=nullptr;
|
||
|
}
|
||
11 months ago
|
}
|
||
|
#endif
|
||
1 year ago
|
return !gameEnd;
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
bool AiL::LeftHeld(){
|
||
1 year ago
|
return KEY_LEFT.Held();
|
||
1 year ago
|
}
|
||
11 months ago
|
bool AiL::RightHeld(){
|
||
1 year ago
|
return KEY_RIGHT.Held();
|
||
1 year ago
|
}
|
||
11 months ago
|
bool AiL::UpHeld(){
|
||
1 year ago
|
return KEY_UP.Held();
|
||
1 year ago
|
}
|
||
11 months ago
|
bool AiL::DownHeld(){
|
||
1 year ago
|
return KEY_DOWN.Held();
|
||
1 year ago
|
}
|
||
11 months ago
|
bool AiL::LeftReleased(){
|
||
1 year ago
|
return KEY_LEFT.Released();
|
||
1 year ago
|
}
|
||
11 months ago
|
bool AiL::RightReleased(){
|
||
1 year ago
|
return KEY_RIGHT.Released();
|
||
1 year ago
|
}
|
||
11 months ago
|
bool AiL::UpReleased(){
|
||
1 year ago
|
return KEY_UP.Released();
|
||
1 year ago
|
}
|
||
11 months ago
|
bool AiL::DownReleased(){
|
||
1 year ago
|
return KEY_DOWN.Released();
|
||
1 year ago
|
}
|
||
|
|
||
11 months 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.
|
||
|
|
||
1 year ago
|
bool setIdleAnimation=true;
|
||
1 year ago
|
if(GetKey(F1).bPressed){
|
||
|
ConsoleShow(F1);
|
||
|
}
|
||
1 year ago
|
if(GetMouseWheel()>0){
|
||
1 year ago
|
switch(player->GetClass()){
|
||
1 year ago
|
case WARRIOR:{
|
||
1 year ago
|
ChangePlayerClass(RANGER);
|
||
1 year ago
|
}break;
|
||
|
case RANGER:{
|
||
1 year ago
|
ChangePlayerClass(WIZARD);
|
||
1 year ago
|
}break;
|
||
|
case WIZARD:{
|
||
1 year ago
|
ChangePlayerClass(WARRIOR);
|
||
1 year ago
|
}break;
|
||
|
}
|
||
|
}
|
||
|
if(GetMouseWheel()<0){
|
||
1 year ago
|
switch(player->GetClass()){
|
||
1 year ago
|
case WARRIOR:{
|
||
|
ChangePlayerClass(WIZARD);
|
||
|
}break;
|
||
|
case RANGER:{
|
||
|
ChangePlayerClass(WARRIOR);
|
||
|
}break;
|
||
|
case WIZARD:{
|
||
|
ChangePlayerClass(RANGER);
|
||
|
}break;
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
if(player->GetVelocity()==vf2d{0,0}&&player->CanMove()){
|
||
1 year 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;
|
||
1 year 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"];
|
||
1 year ago
|
}
|
||
|
}
|
||
|
return std::string("NONE");
|
||
|
};
|
||
|
std::string staircaseDirection=GetPlayerStaircaseDirection();
|
||
1 year ago
|
if(RightHeld()){
|
||
1 year ago
|
player->SetX(player->GetX()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.x="Player.MoveSpd"_F;
|
||
1 year ago
|
if(staircaseDirection=="RIGHT"){
|
||
1 year ago
|
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F;
|
||
1 year ago
|
} else
|
||
1 year ago
|
if(staircaseDirection=="LEFT"){
|
||
|
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y="Player.StaircaseClimbSpd"_F;
|
||
|
}
|
||
1 year ago
|
player->SetFacingDirection(RIGHT);
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
1 year ago
|
}
|
||
1 year ago
|
setIdleAnimation=false;
|
||
1 year ago
|
}
|
||
1 year ago
|
if(LeftHeld()){
|
||
1 year ago
|
player->SetX(player->GetX()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.x=-"Player.MoveSpd"_F;
|
||
1 year ago
|
if(staircaseDirection=="RIGHT"){
|
||
1 year ago
|
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y="Player.StaircaseClimbSpd"_F;
|
||
1 year ago
|
} else
|
||
1 year ago
|
if(staircaseDirection=="LEFT"){
|
||
|
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F;
|
||
1 year ago
|
}
|
||
1 year ago
|
if(setIdleAnimation){
|
||
1 year ago
|
player->SetFacingDirection(LEFT);
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
|
setIdleAnimation=false;
|
||
1 year ago
|
}
|
||
1 year ago
|
if(UpHeld()){
|
||
1 year ago
|
player->SetY(player->GetY()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y=-"Player.MoveSpd"_F*fElapsedTime;
|
||
1 year ago
|
if(setIdleAnimation){
|
||
1 year ago
|
player->SetFacingDirection(UP);
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
player->UpdateWalkingAnimation(UP);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
|
setIdleAnimation=false;
|
||
1 year ago
|
}
|
||
1 year ago
|
if(DownHeld()){
|
||
1 year ago
|
player->SetY(player->GetY()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
||
|
player->movementVelocity.y="Player.MoveSpd"_F*fElapsedTime;
|
||
1 year ago
|
if(setIdleAnimation){
|
||
1 year ago
|
player->SetFacingDirection(DOWN);
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
|
setIdleAnimation=false;
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
if(UpReleased()){
|
||
1 year ago
|
player->SetLastReleasedMovementKey(UP);
|
||
1 year ago
|
player->movementVelocity.y=0;
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
if(RightHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
1 year ago
|
} else
|
||
|
if(DownHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
1 year ago
|
} else
|
||
|
if(LeftHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
if(RightReleased()){
|
||
1 year ago
|
player->SetLastReleasedMovementKey(RIGHT);
|
||
1 year ago
|
player->movementVelocity.x=0;
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
if(UpHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(UP);
|
||
1 year ago
|
} else
|
||
|
if(DownHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
1 year ago
|
} else
|
||
|
if(LeftHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
if(LeftReleased()){
|
||
1 year ago
|
player->SetLastReleasedMovementKey(LEFT);
|
||
1 year ago
|
player->movementVelocity.x=0;
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
if(RightHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
1 year ago
|
} else
|
||
|
if(DownHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(DOWN);
|
||
1 year ago
|
} else
|
||
|
if(UpHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(UP);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
if(DownReleased()){
|
||
1 year ago
|
player->SetLastReleasedMovementKey(DOWN);
|
||
1 year ago
|
player->movementVelocity.y=0;
|
||
1 year ago
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||
1 year ago
|
if(RightHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(RIGHT);
|
||
1 year ago
|
} else
|
||
|
if(UpHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(UP);
|
||
1 year ago
|
} else
|
||
|
if(LeftHeld()){
|
||
1 year ago
|
player->UpdateWalkingAnimation(LEFT);
|
||
1 year ago
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
1 year ago
|
if(player->GetState()!=State::NORMAL&&player->GetState()!=State::PREP_CAST){
|
||
1 year ago
|
setIdleAnimation=false;
|
||
|
}
|
||
|
|
||
1 year ago
|
if(setIdleAnimation){
|
||
1 year ago
|
switch(player->GetLastReleasedMovementKey()){
|
||
1 year ago
|
case UP:{
|
||
1 year ago
|
player->UpdateIdleAnimation(UP);
|
||
1 year ago
|
}break;
|
||
|
case DOWN:{
|
||
1 year ago
|
player->UpdateIdleAnimation(DOWN);
|
||
1 year ago
|
}break;
|
||
|
case LEFT:{
|
||
1 year ago
|
player->UpdateIdleAnimation(LEFT);
|
||
1 year ago
|
}break;
|
||
|
case RIGHT:{
|
||
1 year ago
|
player->UpdateIdleAnimation(RIGHT);
|
||
1 year ago
|
}break;
|
||
|
default:{
|
||
1 year ago
|
player->UpdateIdleAnimation(DOWN);
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
|
||
|
if(GetKey(I).bPressed){
|
||
12 months 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
|
}
|
||
11 months ago
|
if(GetKey(L).bHeld){
|
||
|
game->GetPlayer()->AddXP(1);
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::UpdateCamera(float fElapsedTime){
|
||
1 year ago
|
lastWorldShakeAdjust=std::max(0.f,lastWorldShakeAdjust-fElapsedTime);
|
||
1 year ago
|
if(worldShakeTime>0){
|
||
|
worldShakeTime-=fElapsedTime;
|
||
|
if(worldShakeTime<=0){
|
||
|
camera.SetTarget(player->GetPos());
|
||
|
}
|
||
1 year ago
|
if(lastWorldShakeAdjust==0){
|
||
1 year ago
|
lastWorldShakeAdjust=0.02f;
|
||
1 year ago
|
worldShakeVel.x*=-1;
|
||
|
worldShakeVel.y*=-1;
|
||
1 year ago
|
}
|
||
1 year ago
|
worldShake=player->GetPos()+worldShakeVel;
|
||
1 year ago
|
}
|
||
1 year ago
|
camera.Update(fElapsedTime);
|
||
1 year ago
|
view.SetWorldOffset(camera.GetViewPosition());
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::UpdateEffects(float fElapsedTime){
|
||
1 year ago
|
for(auto it=EMITTER_LIST.begin();it!=EMITTER_LIST.end();++it){
|
||
|
auto ptr=(*it).get();
|
||
1 year ago
|
ptr->Update(fElapsedTime);
|
||
1 year ago
|
}
|
||
1 year 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);
|
||
1 year ago
|
}
|
||
1 year 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);
|
||
1 year ago
|
}
|
||
1 year 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
|
|
||
1 year 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();
|
||
1 year ago
|
}
|
||
11 months ago
|
void AiL::UpdateBullets(float fElapsedTime){
|
||
1 year ago
|
for(auto it=BULLET_LIST.begin();it!=BULLET_LIST.end();++it){
|
||
1 year ago
|
Bullet*b=(*it).get();
|
||
1 year ago
|
b->UpdateFadeTime(fElapsedTime);
|
||
1 year ago
|
b->Update(fElapsedTime);
|
||
1 year ago
|
b->animation.UpdateState(b->internal_animState,fElapsedTime);
|
||
1 year ago
|
if(!b->deactivated){
|
||
1 year 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=[&](){
|
||
1 year 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)){
|
||
1 year ago
|
if(!b->hitsMultiple){
|
||
1 year ago
|
if(b->MonsterHit(m)){
|
||
1 year ago
|
b->dead=true;
|
||
1 year ago
|
return false;
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
b->hitList[&m]=true;
|
||
1 year ago
|
}
|
||
|
}
|
||
|
}
|
||
1 year 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)){
|
||
1 year ago
|
if(b->PlayerHit(player.get())){
|
||
1 year ago
|
b->dead=true;
|
||
1 year ago
|
return false;
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year 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;
|
||
1 year ago
|
}
|
||
1 year ago
|
}else{
|
||
1 year ago
|
b->pos+=b->vel*fElapsedTime;
|
||
1 year 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;
|
||
1 year ago
|
continue;
|
||
1 year ago
|
}
|
||
1 year ago
|
b->lifetime-=fElapsedTime;
|
||
|
if(b->lifetime<=0){
|
||
1 year ago
|
b->dead=true;
|
||
1 year ago
|
continue;
|
||
1 year ago
|
}
|
||
1 year ago
|
nextBullet:
|
||
1 year ago
|
while(false);
|
||
1 year ago
|
}
|
||
1 year ago
|
std::erase_if(BULLET_LIST,[](std::unique_ptr<Bullet>&b){return b->dead;});
|
||
1 year ago
|
}
|
||
11 months ago
|
void AiL::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float z){
|
||
1 year ago
|
for(Monster&m:MONSTER_LIST){
|
||
1 year ago
|
if(geom2d::overlaps(geom2d::circle(pos,radius),geom2d::circle(m.GetPos(),12*m.GetSizeMult()))){
|
||
1 year ago
|
m.Hurt(damage,upperLevel,z);
|
||
1 year ago
|
}
|
||
|
}
|
||
|
}
|
||
1 year ago
|
|
||
11 months 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();
|
||
|
|
||
1 year ago
|
Player*pl=GetPlayer();
|
||
1 year ago
|
for(auto it=MONSTER_LIST.begin();it!=MONSTER_LIST.end();++it){
|
||
|
Monster&m=*it;
|
||
1 year ago
|
if(m.GetPos().y<pl->GetPos().y){//This monster renders before the player does (behind the player)
|
||
1 year 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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
1 year 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){
|
||
1 year ago
|
Effect*e=(*it).get();
|
||
|
if(e->OnUpperLevel()){
|
||
|
foregroundEffectsUpper.push_back(e);
|
||
1 year ago
|
}else{
|
||
1 year ago
|
foregroundEffectsLower.push_back(e);
|
||
1 year ago
|
}
|
||
|
}
|
||
|
for(auto it=backgroundEffects.begin();it!=backgroundEffects.end();++it){
|
||
1 year ago
|
Effect*e=(*it).get();
|
||
|
if(e->OnUpperLevel()){
|
||
|
backgroundEffectsUpper.push_back(e);
|
||
1 year ago
|
}else{
|
||
1 year ago
|
backgroundEffectsLower.push_back(e);
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
|
||
|
for(ZoneData&zone:MAP_DATA[GetCurrentLevel()].ZoneData["EndZone"]){
|
||
|
if(zone.isUpper){
|
||
|
upperEndZones.push_back(zone);
|
||
|
}else{
|
||
|
endZones.push_back(zone);
|
||
|
}
|
||
|
}
|
||
|
|
||
1 year 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;});
|
||
|
}
|
||
|
|
||
11 months 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
|
}
|
||
|
}
|
||
|
|
||
11 months 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
|
}
|
||
|
}
|
||
|
|
||
11 months ago
|
void AiL::RenderWorld(float fElapsedTime){
|
||
1 year ago
|
|
||
1 year 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
|
}
|
||
11 months 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;
|
||
|
}
|
||
|
|
||
1 year 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
|
}
|
||
1 year 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});
|
||
1 year ago
|
}
|
||
1 year ago
|
}break;
|
||
|
}
|
||
|
}else{
|
||
|
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth,{float(GetCurrentMap().tilewidth),float(GetCurrentMap().tilewidth)},{100,180,100});
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
if(bridgeLayerFade){
|
||
|
bridgeFadeFactor=std::min(bridgeFadeFactor+fElapsedTime,TileGroup::FADE_TIME);
|
||
|
}else{
|
||
|
bridgeFadeFactor=std::max(bridgeFadeFactor-fElapsedTime,0.f);
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
#pragma endregion
|
||
1 year ago
|
//DrawDecal({0,0},MAP_TILESETS["assets/maps/"+MAP_DATA[LEVEL1].TilesetData[1].data["source"]]->Decal());
|
||
1 year ago
|
|
||
1 year ago
|
for(Monster&m:MONSTER_LIST){
|
||
|
m.strategyDraw(this);
|
||
|
}
|
||
|
|
||
1 year ago
|
if(player->GetZ()>0){
|
||
1 year 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);
|
||
1 year ago
|
}
|
||
1 year ago
|
for(Effect*e:backgroundEffectsLower){
|
||
1 year ago
|
e->rendered=false;
|
||
1 year ago
|
}
|
||
1 year ago
|
for(ZoneData&zone:endZones){
|
||
|
RenderZone(zone.zone);
|
||
|
}
|
||
1 year ago
|
for(int index:dropsBeforeLower){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
1 year ago
|
for(Monster*m:monstersBeforeLower){
|
||
|
m->Draw();
|
||
1 year ago
|
}
|
||
1 year ago
|
if(!player->upperLevel){
|
||
1 year ago
|
RenderPlayer(player->GetPos(),{1,1});
|
||
1 year ago
|
}
|
||
1 year ago
|
for(int index:dropsAfterLower){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
1 year ago
|
for(Monster*m:monstersAfterLower){
|
||
|
m->Draw();
|
||
1 year ago
|
}
|
||
1 year ago
|
for(Bullet*b:bulletsLower){
|
||
1 year ago
|
b->rendered=false;
|
||
1 year ago
|
}
|
||
1 year 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)));
|
||
1 year 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});
|
||
1 year ago
|
} else {
|
||
1 year ago
|
view.DrawDecal(centerPoint,GFX["circle.png"].Decal(),scale,{255,0,0,96});
|
||
1 year ago
|
}
|
||
|
}
|
||
|
};
|
||
|
if(!player->OnUpperLevel()){
|
||
|
RenderPrecastTargetingIndicator();
|
||
1 year ago
|
}
|
||
1 year ago
|
|
||
|
#pragma region Foreground Rendering Preparation
|
||
1 year ago
|
for(TileGroup&group:foregroundTileGroups){
|
||
|
if(view.IsRectVisible(group.GetRange().pos,group.GetRange().size)){
|
||
1 year ago
|
if(geom2d::overlaps(group.GetFadeRange(),player->pos)){
|
||
1 year 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);
|
||
|
}
|
||
1 year 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
|
}
|
||
1 year 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;});
|
||
11 months 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();
|
||
|
|
||
1 year 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){
|
||
1 year 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;
|
||
1 year 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)});
|
||
1 year 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);
|
||
1 year ago
|
}
|
||
|
#endif
|
||
1 year ago
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
#pragma endregion
|
||
1 year ago
|
for(Effect*e:backgroundEffectsUpper){
|
||
1 year ago
|
e->rendered=false;
|
||
1 year ago
|
}
|
||
1 year ago
|
for(ZoneData&zone:upperEndZones){
|
||
|
RenderZone(zone.zone);
|
||
|
}
|
||
1 year ago
|
for(int index:dropsBeforeUpper){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
1 year ago
|
for(Monster*m:monstersBeforeUpper){
|
||
|
m->Draw();
|
||
1 year ago
|
}
|
||
1 year ago
|
if(player->upperLevel){
|
||
1 year ago
|
RenderPlayer(player->GetPos(),{1,1});
|
||
1 year ago
|
}
|
||
1 year ago
|
for(int index:dropsAfterUpper){
|
||
|
ItemDrop::drops[index].Draw();
|
||
|
}
|
||
1 year ago
|
for(Monster*m:monstersAfterUpper){
|
||
|
m->Draw();
|
||
|
}
|
||
|
for(Bullet*b:bulletsUpper){
|
||
1 year ago
|
b->rendered=false;
|
||
1 year ago
|
}
|
||
1 year ago
|
if(player->OnUpperLevel()){
|
||
|
RenderPrecastTargetingIndicator();
|
||
|
}
|
||
1 year ago
|
|
||
|
#pragma region Upper Foreground Rendering Preparation
|
||
1 year ago
|
for(TileGroup&group:upperForegroundTileGroups){
|
||
1 year ago
|
if(view.IsRectVisible(group.GetRange().pos,group.GetRange().size)){
|
||
|
if(geom2d::overlaps(group.GetFadeRange(),player->pos)){
|
||
1 year 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);
|
||
|
}
|
||
1 year 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
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year 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;});
|
||
11 months 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();
|
||
|
}
|
||
|
|
||
1 year 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){
|
||
1 year 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;
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year 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;
|
||
11 months 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
|
}
|
||
1 year 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
|
}
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
Player*AiL::GetPlayer(){
|
||
1 year ago
|
return player.get();
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::RenderHud(){
|
||
1 year ago
|
ItemOverlay::Draw();
|
||
|
|
||
1 year ago
|
RenderCooldowns();
|
||
1 year ago
|
|
||
1 year ago
|
auto RenderCastbar=[&](const CastInfo&cast){
|
||
1 year 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;
|
||
1 year 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;
|
||
1 year ago
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2+90.f,ScreenHeight()-80.f}-vf2d{float(GetTextSizeProp(castTimeDisplay.str()).x),0},castTimeDisplay.str(),WHITE,BLACK);
|
||
11 months 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
|
};
|
||
11 months 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});
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
DrawDecal({2,2},GFX["heart.png"].Decal());
|
||
|
DrawDecal({2,20},GFX["mana.png"].Decal());
|
||
1 year ago
|
std::string text=player->GetHealth()>0?std::to_string(player->GetHealth()):"X";
|
||
|
std::string text_mana=std::to_string(player->GetMana());
|
||
11 months ago
|
DrawShadowStringPropDecal({20,3},text,WHITE,BLACK,{2,2},INFINITE);
|
||
|
DrawShadowStringPropDecal({24,23},text_mana,{192,192,255},BLACK,{1.5f,1.5f},INFINITE);
|
||
1 year ago
|
if(player->notEnoughManaDisplay.second>0){
|
||
|
std::string displayText="Not enough mana for "+player->notEnoughManaDisplay.first+"!";
|
||
1 year ago
|
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)}-GetTextSizeProp(displayText)/2,displayText,DARK_RED,VERY_DARK_RED);
|
||
1 year ago
|
}
|
||
1 year ago
|
if(player->notificationDisplay.second>0){
|
||
|
std::string displayText=player->notificationDisplay.first;
|
||
1 year ago
|
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)-24}-GetTextSizeProp(displayText)/2,displayText,BLUE,VERY_DARK_BLUE);
|
||
1 year ago
|
}
|
||
1 year ago
|
DisplayBossEncounterInfo();
|
||
1 year ago
|
if("debug_player_info"_I){
|
||
1 year ago
|
DrawShadowStringDecal({0,128},player->GetPos().str());
|
||
1 year ago
|
DrawShadowStringDecal({0,136},"Spd: "+std::to_string(player->GetMoveSpdMult()));
|
||
11 months ago
|
DrawShadowStringDecal({0,144},"HP Timer: "+std::to_string(player->hpRecoveryTimer));
|
||
|
DrawShadowStringDecal({0,152},"HP Recovery Amt: "+std::to_string(player->GetHPRecoveryPct()*player->GetMaxHealth()));
|
||
11 months ago
|
if(!ISBLANK(GetLoadoutItem(0))){
|
||
|
DrawShadowStringDecal({0,92},"Loadout Slot 1 Qty: "+std::to_string(GetLoadoutItem(0).lock()->Amt()));
|
||
|
}
|
||
12 months 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
|
}}
|
||
1 year ago
|
|
||
11 months 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){
|
||
11 months 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{
|
||
11 months 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);
|
||
12 months 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){
|
||
11 months 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};
|
||
11 months 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};
|
||
11 months 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
|
}
|
||
|
|
||
11 months ago
|
void AiL::AddEffect(std::unique_ptr<Effect>foreground,std::unique_ptr<Effect> background){
|
||
1 year ago
|
AddEffect(std::move(background),true);
|
||
|
AddEffect(std::move(foreground));
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::AddEffect(std::unique_ptr<Effect> foreground,bool back){
|
||
1 year ago
|
if(back){
|
||
1 year ago
|
backgroundEffectsToBeInserted.push_back(std::move(foreground));
|
||
1 year ago
|
} else {
|
||
1 year ago
|
foregroundEffectsToBeInserted.push_back(std::move(foreground));
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
11 months ago
|
vf2d AiL::GetWorldMousePos(){
|
||
1 year ago
|
return GetMousePos()+view.GetWorldOffset();
|
||
|
}
|
||
|
|
||
11 months ago
|
void AiL::SetupWorldShake(float duration){
|
||
1 year ago
|
worldShakeVel={13,-13};
|
||
1 year ago
|
worldShakeTime=duration;
|
||
1 year ago
|
worldShake=vf2d{player->GetPos()};
|
||
1 year ago
|
camera.SetTarget(worldShake);
|
||
|
}
|
||
|
|
||
1 year ago
|
|
||
11 months ago
|
void AiL::InitializeLevel(std::string mapFile,MapName map){
|
||
1 year ago
|
TMXParser level(mapFile);
|
||
1 year ago
|
|
||
1 year 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){
|
||
1 year 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;
|
||
1 year ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].tileset=r;
|
||
|
MAP_TILESETS["assets/maps/"+baseSourceDir].foregroundTiles=tileset.GetData().ForegroundTileData;
|
||
1 year ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].upperForegroundTiles=tileset.GetData().UpperForegroundTileData;
|
||
1 year ago
|
MAP_TILESETS["assets/maps/"+baseSourceDir].collision=tileset.GetData().CollisionData;
|
||
1 year 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;
|
||
12 months 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();
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year 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){
|
||
11 months 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;
|
||
11 months ago
|
for(std::string spawn:MAP_DATA[map].spawns){
|
||
1 year ago
|
cp.spawns.push_back(spawn);
|
||
|
}
|
||
|
cp.levelDataExists=true;
|
||
|
}
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::LoadLevel(MapName map){
|
||
1 year ago
|
SPAWNER_LIST.clear();
|
||
1 year ago
|
foregroundTileGroups.clear();
|
||
11 months ago
|
upperForegroundTileGroups.clear();
|
||
11 months ago
|
MONSTER_LIST.clear();
|
||
1 year 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");
|
||
11 months ago
|
GetPlayer()->hp=GetPlayer()->GetMaxHealth();
|
||
11 months ago
|
GetPlayer()->mana=GetPlayer()->GetMaxMana();
|
||
11 months ago
|
GetPlayer()->SetState(State::NORMAL);
|
||
|
GetPlayer()->GetCastInfo()={};
|
||
11 months ago
|
GetPlayer()->ResetAccumulatedXP();
|
||
1 year ago
|
|
||
1 year ago
|
#pragma region Monster Spawn Data Setup
|
||
12 months ago
|
for(auto&[key,value]:MAP_DATA[map].SpawnerData){
|
||
|
SpawnerTag&spawnData=MAP_DATA[map].SpawnerData[key];
|
||
11 months ago
|
std::vector<std::pair<std::string,vf2d>>monster_list;
|
||
1 year ago
|
|
||
1 year ago
|
vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2;
|
||
|
for(XMLTag&monster:spawnData.monsters){
|
||
11 months 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;
|
||
11 months 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);
|
||
1 year ago
|
}
|
||
1 year ago
|
};
|
||
11 months 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++;
|
||
1 year 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;});
|
||
1 year 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
|
||
11 months 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
|
||
1 year ago
|
|
||
1 year ago
|
#pragma region Bridge Layer Setup
|
||
|
bridgeLayerIndex=-1;
|
||
12 months ago
|
for(int counter=0;LayerTag&layer:MAP_DATA[map].LayerData){
|
||
1 year ago
|
if(IsBridgeLayer(layer)){
|
||
|
bridgeLayerIndex=counter;
|
||
|
}
|
||
|
counter++;
|
||
1 year ago
|
}
|
||
1 year ago
|
#pragma endregion
|
||
1 year ago
|
|
||
1 year 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);
|
||
1 year ago
|
|
||
1 year ago
|
pathfinder.Initialize();
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
bool AiL::IsUpperForegroundTile(int tileID){
|
||
1 year ago
|
return tileID>=1000000;
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
bool AiL::IsForegroundTile(TilesheetData sheet,int tileID){
|
||
1 year ago
|
return sheet.tileset->foregroundTiles.find(tileID)!=sheet.tileset->foregroundTiles.end();
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
TilesheetData AiL::GetTileSheet(MapName map,int tileID){
|
||
1 year ago
|
std::vector<XMLTag>&tileData=MAP_DATA[map].TilesetData;
|
||
|
if(tileData.size()==1){
|
||
1 year 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};
|
||
1 year 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"])};
|
||
1 year ago
|
}
|
||
|
}
|
||
1 year 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"])};
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
11 months ago
|
bool AiL::HasTileCollision(MapName map,vf2d pos,bool upperLevel){
|
||
1 year ago
|
geom2d::rect<int>collisionRect=GetTileCollision(map,pos,upperLevel);
|
||
1 year ago
|
vi2d collisionRectSnapPos=vi2d{pos/float(game->GetCurrentMap().tilewidth)}*game->GetCurrentMap().tilewidth;
|
||
1 year ago
|
collisionRect.pos+=collisionRectSnapPos;
|
||
|
return geom2d::overlaps(collisionRect,pos);
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
bool AiL::IsBridgeLayer(LayerTag&layer){
|
||
1 year ago
|
return layer.tag.data.find("class")!=layer.tag.data.end()&&layer.tag.data["class"]=="Bridge";
|
||
|
}
|
||
|
|
||
11 months 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;
|
||
1 year 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}};
|
||
1 year ago
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma endregion
|
||
1 year 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;
|
||
1 year 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;
|
||
1 year ago
|
}
|
||
|
return NO_COLLISION;
|
||
|
}
|
||
|
}
|
||
1 year ago
|
geom2d::rect<int>foundRect=NO_COLLISION;
|
||
12 months 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);
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
counter++;
|
||
1 year ago
|
}
|
||
1 year ago
|
return foundRect;
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
MapName AiL::GetCurrentLevel(){
|
||
1 year ago
|
return currentLevel;
|
||
|
}
|
||
|
|
||
11 months ago
|
std::map<std::string,std::vector<ZoneData>>&AiL::GetZoneData(MapName map){
|
||
1 year ago
|
return MAP_DATA[map].ZoneData;
|
||
|
}
|
||
|
|
||
11 months ago
|
void AiL::ChangePlayerClass(Class cl){
|
||
1 year ago
|
Ability itemAbility1=player->useItem1;
|
||
|
Ability itemAbility2=player->useItem2;
|
||
|
Ability itemAbility3=player->useItem3;
|
||
11 months ago
|
uint32_t oldMoney=player->money;
|
||
11 months ago
|
uint8_t level=player->level;
|
||
|
uint8_t levelCap=player->levelCap;
|
||
|
uint32_t totalXPEarned=player->totalXPEarned;
|
||
|
uint32_t currentLevelXP=player->currentLevelXP;
|
||
11 months ago
|
std::set<MenuComponent*>moneyListeners=Player::moneyListeners;
|
||
11 months ago
|
EntityStats previousStats=player->stats;
|
||
1 year ago
|
switch(cl){
|
||
|
case WARRIOR:{
|
||
1 year ago
|
player.reset(NEW Warrior(player.get()));
|
||
1 year ago
|
}break;
|
||
|
case THIEF:{
|
||
1 year ago
|
player.reset(NEW Thief(player.get()));
|
||
1 year ago
|
}break;
|
||
|
case TRAPPER:{
|
||
1 year ago
|
player.reset(NEW Trapper(player.get()));
|
||
1 year ago
|
}break;
|
||
|
case RANGER:{
|
||
1 year ago
|
player.reset(NEW Ranger(player.get()));
|
||
1 year ago
|
}break;
|
||
|
case WIZARD:{
|
||
1 year ago
|
player.reset(NEW Wizard(player.get()));
|
||
1 year ago
|
}break;
|
||
|
case WITCH:{
|
||
1 year ago
|
player.reset(NEW Witch(player.get()));
|
||
1 year ago
|
}break;
|
||
|
}
|
||
11 months ago
|
player->level=level;
|
||
|
player->levelCap=levelCap;
|
||
|
player->totalXPEarned=totalXPEarned;
|
||
|
player->currentLevelXP=currentLevelXP;
|
||
11 months ago
|
player->stats=previousStats;
|
||
11 months ago
|
player->SetBaseStat("Health",DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt());
|
||
|
player->hp=player->GetBaseStat("Health");
|
||
11 months ago
|
player->SetBaseStat("Mana",DATA.GetProperty("Player.BaseMana").GetInt());
|
||
|
player->mana=player->GetBaseStat("Mana");
|
||
11 months 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());
|
||
11 months ago
|
player->money=oldMoney;
|
||
1 year ago
|
sig::Animation::SetupPlayerAnimations();
|
||
1 year ago
|
GetPlayer()->UpdateIdleAnimation(DOWN);
|
||
1 year ago
|
GetPlayer()->SetItem1UseFunc(itemAbility1);
|
||
|
GetPlayer()->SetItem2UseFunc(itemAbility2);
|
||
|
GetPlayer()->SetItem3UseFunc(itemAbility3);
|
||
1 year ago
|
camera.SetTarget(player->GetPos());
|
||
11 months ago
|
Player::moneyListeners=moneyListeners;
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::InitializeClasses(){
|
||
1 year ago
|
Warrior::Initialize();
|
||
|
Thief::Initialize();
|
||
|
Ranger::Initialize();
|
||
|
Trapper::Initialize();
|
||
|
Wizard::Initialize();
|
||
|
Witch::Initialize();
|
||
1 year ago
|
Warrior::InitializeClassAbilities();
|
||
|
Thief::InitializeClassAbilities();
|
||
|
Ranger::InitializeClassAbilities();
|
||
|
Trapper::InitializeClassAbilities();
|
||
|
Wizard::InitializeClassAbilities();
|
||
|
Witch::InitializeClassAbilities();
|
||
|
}
|
||
|
|
||
11 months ago
|
std::string AiL::GetString(std::string key){
|
||
1 year ago
|
return DATA.GetProperty(key).GetString();
|
||
|
}
|
||
|
|
||
11 months ago
|
datafilestringdata AiL::GetStringList(std::string key){
|
||
1 year ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
11 months ago
|
int AiL::GetInt(std::string key){
|
||
1 year ago
|
return DATA.GetProperty(key).GetInt();
|
||
|
}
|
||
|
|
||
11 months ago
|
datafileintdata AiL::GetIntList(std::string key){
|
||
1 year ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
11 months ago
|
float AiL::GetFloat(std::string key){
|
||
1 year ago
|
return float(DATA.GetProperty(key).GetReal());
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
datafilefloatdata AiL::GetFloatList(std::string key){
|
||
1 year ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
11 months ago
|
double AiL::GetDouble(std::string key){
|
||
1 year ago
|
return DATA.GetProperty(key).GetReal();
|
||
|
}
|
||
|
|
||
11 months ago
|
datafiledoubledata AiL::GetDoubleList(std::string key){
|
||
1 year ago
|
return {DATA,key};
|
||
|
}
|
||
|
|
||
1 year ago
|
int main()
|
||
|
{
|
||
1 year ago
|
{
|
||
11 months 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);
|
||
11 months 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
|
||
1 year ago
|
|
||
|
return 0;
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
datafilestringdata operator ""_s(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
1 year ago
|
datafileintdata operator ""_i(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
1 year ago
|
datafilefloatdata operator ""_f(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
1 year ago
|
datafiledoubledata operator ""_d(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return {DATA,std::string(key,len)};
|
||
|
}
|
||
|
|
||
1 year ago
|
Pixel operator ""_Pixel(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year 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))};
|
||
|
}
|
||
|
|
||
1 year ago
|
std::string operator ""_S(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return DATA.GetProperty(std::string(key,len)).GetString();
|
||
|
}
|
||
|
|
||
1 year ago
|
int operator ""_I(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return DATA.GetProperty(std::string(key,len)).GetInt();
|
||
|
}
|
||
|
|
||
1 year ago
|
float operator ""_F(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return float(DATA.GetProperty(std::string(key,len)).GetReal());
|
||
1 year ago
|
}
|
||
|
|
||
1 year ago
|
float operator ""_FRange(const char*key,std::size_t len){
|
||
11 months 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));
|
||
1 year ago
|
}
|
||
11 months ago
|
float operator ""_Pct(long double pct){
|
||
|
return pct/100;
|
||
|
}
|
||
1 year ago
|
|
||
1 year ago
|
double operator ""_D(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return DATA.GetProperty(std::string(key,len)).GetReal();
|
||
1 year ago
|
}
|
||
|
|
||
|
datafile operator ""_A(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
1 year ago
|
return DATA.GetProperty(std::string(key,len));
|
||
|
}
|
||
|
|
||
11 months ago
|
void AiL::OutputDebugInfo(const char*key,std::size_t len){
|
||
1 year 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;
|
||
|
}
|
||
1 year ago
|
}
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
bool AiL::IsReflectiveTile(TilesheetData tileSheet,int tileID){
|
||
1 year ago
|
return tileSheet.tileset->reflectiveData.find(tileID)!=tileSheet.tileset->reflectiveData.end();
|
||
|
}
|
||
|
|
||
11 months ago
|
bool AiL::OnUserDestroy(){
|
||
11 months 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();
|
||
12 months ago
|
for(auto&[key,value]:MAP_DATA){
|
||
|
if(MAP_DATA[key].optimizedTile!=nullptr){
|
||
|
delete MAP_DATA[key].optimizedTile;
|
||
1 year ago
|
}
|
||
|
}
|
||
12 months ago
|
for(auto&[key,value]:MAP_TILESETS){
|
||
|
delete value.tileset;
|
||
1 year ago
|
}
|
||
12 months ago
|
for(auto&[key,value]:GameState::states){
|
||
|
delete value;
|
||
1 year ago
|
}
|
||
1 year ago
|
delete[]pathfinder.nodes;
|
||
|
Menu::CleanupAllMenus();
|
||
12 months ago
|
for(auto&[key,value]:MonsterData::imgs){
|
||
|
delete value;
|
||
1 year ago
|
}
|
||
1 year ago
|
return true;
|
||
|
}
|
||
|
|
||
11 months 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);
|
||
11 months 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
|
}
|
||
|
|
||
11 months ago
|
void AiL::SpawnMonster(vf2d pos,MonsterData&data,bool upperLevel,bool isBossSpawn){
|
||
11 months ago
|
monstersToBeSpawned.push_back(Monster(pos,data,upperLevel,isBossSpawn));
|
||
1 year ago
|
if(isBossSpawn){
|
||
|
totalBossEncounterMobs++;
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
11 months 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
|
}
|
||
|
|
||
11 months 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);
|
||
|
}
|
||
|
|
||
11 months 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
|
}
|
||
|
|
||
11 months ago
|
void AiL::SetBossNameDisplay(std::string name,float time){
|
||
1 year ago
|
bossName=name;
|
||
|
bossDisplayTimer=time;
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
bool AiL::InBossEncounter(){
|
||
1 year ago
|
return bossName!="";
|
||
|
}
|
||
|
|
||
11 months ago
|
void AiL::StartBossEncounter(){
|
||
1 year ago
|
if(!encounterStarted){
|
||
|
encounterStarted=true;
|
||
1 year ago
|
totalDamageDealt=0;
|
||
|
encounterDuration=0.f;
|
||
1 year ago
|
}
|
||
|
}
|
||
|
|
||
11 months 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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
11 months ago
|
void AiL::BossDamageDealt(int damage){
|
||
1 year ago
|
totalDamageDealt+=damage;
|
||
|
}
|
||
|
|
||
11 months 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
|
}
|
||
|
|
||
11 months 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
|
}
|
||
|
|
||
11 months 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;
|
||
12 months 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);
|
||
12 months 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;});
|
||
12 months 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
|
}
|
||
|
|
||
11 months ago
|
MapTag AiL::GetCurrentMap(){
|
||
1 year ago
|
return MAP_DATA[GetCurrentLevel()].MapData;
|
||
1 year ago
|
}
|
||
|
|
||
11 months 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
|
}
|
||
|
|
||
11 months 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));
|
||
11 months 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
|
}
|
||
|
|
||
11 months ago
|
int AiL::GetCurrentChapter(){
|
||
1 year ago
|
return chapter;
|
||
|
}
|
||
|
|
||
11 months ago
|
void AiL::SetChapter(int chapter){
|
||
1 year ago
|
this->chapter=chapter;
|
||
11 months ago
|
for(MenuComponent*component:Menu::chapterListeners){
|
||
|
component->OnChapterUpdate(chapter);
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
11 months 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];
|
||
|
}
|
||
|
|
||
11 months 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){
|
||
11 months ago
|
loadout[slot]=Inventory::CopyItem(itemName)[0];
|
||
11 months 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;
|
||
|
}
|
||
11 months 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};
|
||
11 months ago
|
itemAbility.actionPerformedDuringCast=GetLoadoutItem(slot).lock()->UseDuringCast();
|
||
1 year ago
|
|
||
|
switch(slot){
|
||
|
case 0:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
11 months ago
|
return game->UseLoadoutItem(0);
|
||
1 year ago
|
};
|
||
|
game->GetPlayer()->SetItem1UseFunc(itemAbility);
|
||
11 months 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);
|
||
11 months 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);
|
||
11 months 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!");
|
||
|
}
|
||
|
}
|
||
|
|
||
11 months 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)+").");
|
||
11 months 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
|
}
|
||
|
|
||
11 months 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)+").");
|
||
11 months ago
|
loadout[slot].reset();
|
||
11 months 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={}){
|
||
11 months ago
|
return game->UseLoadoutItem(0);
|
||
11 months ago
|
};
|
||
|
game->GetPlayer()->SetItem1UseFunc(itemAbility);
|
||
11 months ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->SetItem(Item::BLANK);
|
||
11 months ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 1")->UpdateIcon();
|
||
|
}break;
|
||
|
case 1:{
|
||
|
itemAbility.action=[&](Player*p,vf2d pos={}){
|
||
|
return game->UseLoadoutItem(1);
|
||
|
};
|
||
11 months ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 2")->SetItem(Item::BLANK);
|
||
11 months 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);
|
||
11 months ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->SetItem(Item::BLANK);
|
||
11 months ago
|
Component<MenuItemItemButton>(MenuType::ITEM_LOADOUT,"Loadout Item 3")->UpdateIcon();
|
||
|
}break;
|
||
|
}
|
||
1 year ago
|
}
|
||
|
|
||
11 months 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});
|
||
|
}
|
||
|
|
||
11 months ago
|
bool AiL::GamePaused(){
|
||
1 year ago
|
return fadeOutDuration>0;
|
||
1 year ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::EndGame(){
|
||
1 year ago
|
gameEnd=true;
|
||
11 months ago
|
}
|
||
|
|
||
11 months ago
|
#ifndef __EMSCRIPTEN__
|
||
11 months ago
|
::discord::Result AiL::SetupDiscord(){
|
||
11 months ago
|
auto result=::discord::Core::Create(1186719371750555780,DiscordCreateFlags_NoRequireDiscord,&Discord);
|
||
11 months ago
|
if(result==::discord::Result::Ok){
|
||
|
Discord->SetLogHook(
|
||
11 months ago
|
discord::LogLevel::Debug, [](discord::LogLevel level, const char* message) {
|
||
|
std::cerr << "Log(" << static_cast<uint32_t>(level) << "): " << message << "\n";
|
||
|
});
|
||
11 months ago
|
std::cout<<"Connected to Discord!"<<std::endl;
|
||
|
UpdateDiscordStatus("Main Menu",player.get()->GetClassName());
|
||
11 months ago
|
}else{
|
||
|
std::cout<<"Could not connect to Discord. Error Code "<<int(result)<<std::endl;
|
||
11 months ago
|
}
|
||
11 months ago
|
return result;
|
||
11 months ago
|
}
|
||
|
#endif
|
||
11 months ago
|
|
||
11 months ago
|
void AiL::UpdateDiscordStatus(std::string levelName,std::string className){
|
||
11 months ago
|
#ifndef __EMSCRIPTEN__
|
||
|
if(Discord){
|
||
|
::discord::Activity newActivity{};
|
||
|
newActivity.SetDetails(levelName.c_str());
|
||
11 months ago
|
newActivity.SetState(std::format("Level {} {}",player->Level(),className).c_str());
|
||
11 months ago
|
discord::ActivityTimestamps×tamps=newActivity.GetTimestamps();
|
||
|
timestamps.SetStart(gameStarted);
|
||
|
newActivity.SetType(discord::ActivityType::Playing);
|
||
|
discord::ActivityAssets&assets=newActivity.GetAssets();
|
||
11 months ago
|
assets.SetLargeImage("ail_512");
|
||
11 months ago
|
assets.SetLargeText(game->sAppName.c_str());
|
||
11 months ago
|
assets.SetSmallText(std::format("Level {} {}",player->Level(),className).c_str());
|
||
11 months ago
|
|
||
11 months 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){
|
||
11 months 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;
|
||
|
}
|
||
11 months ago
|
});
|
||
11 months ago
|
}else{
|
||
|
if(SetupDiscord()==::discord::Result::Ok){
|
||
|
UpdateDiscordStatus(levelName,className);
|
||
|
}
|
||
11 months ago
|
}
|
||
|
#endif
|
||
11 months ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::InitializePlayerLevelCap(){
|
||
11 months 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;
|
||
11 months ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::ResetGame(){
|
||
11 months ago
|
GameState::ChangeState(States::MAIN_MENU,0.5f);
|
||
11 months 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;
|
||
11 months ago
|
player->SetMoney(100U);
|
||
11 months ago
|
for(int i=0;i<loadout.size();i++){
|
||
|
game->ClearLoadoutItem(i);
|
||
|
}
|
||
11 months ago
|
Unlock::unlocks.clear();
|
||
|
Unlock::Initialize();
|
||
11 months ago
|
State_OverworldMap::SetStageMarker("Stage I-I");
|
||
|
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
|
||
11 months ago
|
SetChapter(1);
|
||
|
SaveFile::SetSaveFileName("");
|
||
11 months ago
|
}
|
||
|
|
||
11 months ago
|
void AiL::OnRequestCompleted(const std::string_view receivedData)const{
|
||
11 months ago
|
responseCallback(receivedData);
|
||
11 months ago
|
}
|
||
|
|
||
|
std::string operator ""_FS(const char*key,std::size_t len){
|
||
11 months ago
|
AiL::OutputDebugInfo(key,len);
|
||
11 months ago
|
return DATA.GetProperty(std::string(key,len)).GetFullString();
|
||
1 year ago
|
}
|