Safariminer 527b73afb5 rebase
2025-09-19 14:33:07 -04:00

469 lines
19 KiB
C++

#include "Map.h"
#include <raylib.h>
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include "Skybox.h"
#include <raymath.h>
#include "rlgl.h"
#include <map>
#include "Fonts.h"
#include "Camera.h"
#include "Chai.h"
#define RLIGHTS_IMPLEMENTATION
#include "rlights.h"
#include "titles.h"
#include "Engine.h"
#include <filesystem>
#include "cameraextern.h"
std::string currMapName;
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured
void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color); // Draw cube with a region of a texture
std::map<std::string, Texture2D> mapTextures;
std::map<std::string, Texture2D> mapSprites;
Shader lightingShader;
std::string MassShoot::Maps::Map::GetMapName() {
return currMapName;
}
std::vector<BoundingBox> upgradeTriggers;
std::vector<std::string> upgradeTriggersNames;
bool loadedSound = false;
Sound upgradeSound;
LOADING_FUNC MassShoot::Maps::Map::LoadMap(std::string mapName)
{
if (!loadedSound) {
upgradeSound = LoadSound("massshoot/sounds/upgrade.mp3");
loadedSound = true;
}
#ifdef LIGHTING_ENABLED
lights.clear();
if (lightingShader.id != NULL) UnloadShader(lightingShader);
lightingShader = LoadShader("massshoot/shaders/lighting.vs",
"massshoot/shaders/lighting.fs");
// Get some required lightingShader locations
lightingShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(lightingShader, "viewPos");
// NOTE: "matModel" location name is automatically assigned on lightingShader loading,
// no need to get the location again if using that uniform name
//lightingShader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(lightingShader, "matModel");
// Ambient light level (some basic lighting)
int ambientLoc = GetShaderLocation(lightingShader, "ambient");
float basicLight[4] = { 0.1f, 0.1f, 0.1f, 1.0f };
SetShaderValue(lightingShader, ambientLoc, basicLight, SHADER_UNIFORM_VEC4);
std::ifstream lightsfile("massshoot/maps/" + mapName + "/lighting.txt");
int xlights, ylights, zlights, rlights, glights, blights, alights;
while (lightsfile >> xlights >> ylights >> zlights >> rlights >> glights >> blights >> alights)
{
Light light = CreateLight(LIGHT_POINT, { (float)xlights, (float)ylights, (float)zlights}, Vector3Zero(), {(unsigned char)rlights, (unsigned char)glights, (unsigned char)blights, (unsigned char)alights}, lightingShader);
lights.push_back(light);
}
lightsfile.close();
#endif
std::ifstream textureData("massshoot/maps/" + mapName + "/textures.txt");
std::string textureName, texturePath;
collisions.clear();
triggers.clear();
triggerMaps.clear();
upgradeTriggers.clear();
textures.clear();
sprites.clear();
billboards.clear();
// textures.clear();
while (textureData >> textureName >> texturePath) {
// MassShoot::Skybox::LoadSkybox(line);
if (mapTextures.find(textureName) != mapTextures.end()) {
UnloadTexture(mapTextures.at(textureName));
mapTextures.erase(textureName);
}
mapTextures.insert_or_assign(textureName, LoadTexture(texturePath.c_str()));
}
textureData.close();
std::ifstream spritesData("massshoot/maps/" + mapName + "/sprites.txt");
// textures.clear();
while (spritesData >> textureName >> texturePath) {
// MassShoot::Skybox::LoadSkybox(line);
if (mapSprites.find(textureName) != mapSprites.end()) {
UnloadTexture(mapSprites.at(textureName));
mapSprites.erase(textureName);
}
mapSprites.insert_or_assign(textureName, LoadTexture(texturePath.c_str()));
}
spritesData.close();
std::ifstream mapfile("massshoot/maps/" + mapName + "/map.txt");
float x1, y1, z1, x2, y2, z2;
while (mapfile >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> textureName)
{
BoundingBox newBox;
newBox.min = { (float)x1, (float)y1, (float)z1 };
newBox.max = { (float)x2, (float)y2, (float)z2 };
collisions.push_back(newBox);
textures.push_back(textureName);
}
mapfile.close();
std::ifstream upgradefiles("massshoot/maps/" + mapName + "/upgrades.txt");
while (upgradefiles >> x1 >> y1 >> z1 >> textureName)
{
BoundingBox newBox;
newBox.min = { (float)x1-1, (float)y1-1, (float)z1-1 };
newBox.max = { (float)x1+1, (float)y1+1, (float)z1+1 };
upgradeTriggers.push_back(newBox);
upgradeTriggersNames.push_back(textureName);
}
upgradefiles.close();
std::ifstream triggerData("massshoot/maps/" + mapName + "/triggers.txt");
// float x1, y1, z1, x2, y2, z2;
std::string mapTrigName;
while (triggerData >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> mapTrigName)
{
BoundingBox newBox;
newBox.min = { (float)x1, (float)y1, (float)z1 };
newBox.max = { (float)x2, (float)y2, (float)z2 };
triggers.push_back(newBox);
triggerMaps.push_back(mapTrigName);
}
triggerData.close();
std::ifstream skyboxData("massshoot/maps/" + mapName + "/skybox.txt");
std::string line;
while (std::getline(skyboxData, line)) {
MassShoot::Skybox::LoadSkybox(line);
}
for (int i = 0; i < collisions.size(); i++) {
printf("%f, %f, %f | %f, %f, %f\n",
collisions.at(i).min.x,
collisions.at(i).min.y,
collisions.at(i).min.z,
collisions.at(i).max.x,
collisions.at(i).max.y,
collisions.at(i).max.z
);
}
std::string spritename;
std::ifstream billboardsData("massshoot/maps/" + mapName + "/billboards.txt");
// float x1, y1, z1, x2, y2, z2;
while (billboardsData >> x1 >> y1 >> z1 >> spritename)
{
Vector3 newvec = { x1, y1, z1 };
billboards.push_back(newvec);
sprites.push_back(spritename);
}
triggerData.close();
skyboxData.close();
shaded = std::filesystem::exists("massshoot/maps/" + mapName + "/pleaseshademap");
std::ifstream titlefile("massshoot/maps/" + mapName + "/title.txt");
std::getline(titlefile, title);
std::getline(titlefile, subtitle);
titlefile.close();
MassShoot::StoryTools::LaunchTitle(title, subtitle);
MassShoot::Engine::Log(2, TextFormat("Title: %s\nSubtitle: %s\n\n", title.c_str(), subtitle.c_str()), nullptr);
}
LIGHTING_FUNC MassShoot::Maps::Map::UpdateLighting(Vector3 cameraPosition) {
#ifdef LIGHTING_ENABLED
float cameraPos[3] = { cameraPosition.x, cameraPosition.y, cameraPosition.z };
SetShaderValue(lightingShader, lightingShader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
// Update light values (actually, only enable/disable them)
// for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
for (int i = 0; i < lights.size(); i++) {
UpdateLightValues(lightingShader, lights.at(i));
}
#endif
}
RENDERING_FUNC MassShoot::Maps::Map::RenderBillboards() {
for (int i = 0; i < billboards.size(); i++) {
DrawBillboard(camera, mapSprites.at(sprites.at(i)), billboards.at(i), 10.0f, WHITE);
}
}
RENDERING_FUNC MassShoot::Maps::Map::RenderBoxes()
{
// BeginShaderMode(lightingShader);
for (int i = 0; i < collisions.size(); i++) {
// DrawBoundingBox(collisions.at(i), BLACK);
Vector3 size = { 0 };
size.x = fabsf(collisions.at(i).max.x - collisions.at(i).min.x);
size.y = fabsf(collisions.at(i).max.y - collisions.at(i).min.y);
size.z = fabsf(collisions.at(i).max.z - collisions.at(i).min.z);
Vector3 center = { collisions.at(i).min.x + size.x / 2.0f, collisions.at(i).min.y + size.y / 2.0f, collisions.at(i).min.z + size.z / 2.0f };
// int color = 255 / collisions.size() * i; {255, (unsigned char)color, 0, 255}
if(textures.at(i) != "invis")
DrawCubeTexture(mapTextures.at(textures.at(i)), center, size.x, size.y, size.z, WHITE);
}
for (int i = 0; i < upgradeTriggers.size(); i++) {
DrawCube(upgradeTriggers.at(i).min, 1, 1, 1, PURPLE);
}
// EndShaderMode();
#ifdef LIGHTING_ENABLED
for (int l = 0; l < lights.size(); l++) {
DrawSphere(lights.at(l).position, 2, lights.at(l).color);
}
#endif
}
PHYSICS_BOOL MassShoot::Maps::Map::IsColliding(BoundingBox box)
{
for (int i = 0; i < collisions.size(); i++) {
if (CheckCollisionBoxes(collisions.at(i), box)) {
// printf("%i\n", i);
return true;
}
}
return false;
}
BoundingBox GenerateBoundingBox(Vector3 center, int margin, int height) {
BoundingBox box;
box.min.x = center.x - (margin / 2);
box.max.x = center.x + (margin / 2);
box.min.y = center.y - (height / 2);
box.max.y = center.y + (height / 2);
box.min.z = center.z - (margin / 2);
box.max.z = center.z + (margin / 2);
return box;
}
MassShoot::Maps::CollideCollAdvancedResult MassShoot::Maps::Map::CollideCollAdvanced(Vector3 newbox, Vector3 oldbox, int margin, int height)
{
MassShoot::Maps::CollideCollAdvancedResult result = { oldbox };
if (!IsColliding(GenerateBoundingBox({ oldbox.x, oldbox.y, newbox.z }, margin, height))) result = { oldbox.x, oldbox.y, newbox.z };
if (!IsColliding(GenerateBoundingBox({ oldbox.x, newbox.y, oldbox.z }, margin, height))) result = { oldbox.x, newbox.y, oldbox.z };
if (!IsColliding(GenerateBoundingBox({ oldbox.x, newbox.y, newbox.z }, margin, height))) result = { oldbox.x, newbox.y, newbox.z };
if (!IsColliding(GenerateBoundingBox({ newbox.x, oldbox.y, oldbox.z }, margin, height))) result = { newbox.x, oldbox.y, oldbox.z };
if (!IsColliding(GenerateBoundingBox({ newbox.x, oldbox.y, newbox.z }, margin, height))) result = { newbox.x, oldbox.y, newbox.z };
if (!IsColliding(GenerateBoundingBox({ newbox.x, newbox.y, oldbox.z }, margin, height))) result = { newbox.x, newbox.y, oldbox.z };
return result;
}
PHYSICS_FUNC MassShoot::Maps::Map::CheckForTriggers(BoundingBox box)
{
for (int i = 0; i < triggers.size(); i++) {
if (CheckCollisionBoxes(triggers.at(i), box)) {
DrawTextEx(textFont, TextFormat("PRESS E TO GO TO %s", triggerMaps.at(i).c_str()), {(float)GetScreenWidth()/2-180, (float)GetScreenHeight() / 2 +140}, 40, 0, WHITE);
if (IsKeyPressed(KEY_E)) {
DrawRectangle(0, 0, 300, 70, { 150,150,150,150 });
MassShoot::Camera::InitCamera();
std::cout << triggerMaps.at(i);
DrawTextEx(smallFont, "LOADING...", { 0,0 }, 60, 0, WHITE);
LoadMap(triggerMaps.at(i));
}
}
}
}
SCRIPTING_FUNC MassShoot::Weapons::WeaponSuite::CheckForUpgradeTriggers()
{
for (int i = 0; i < upgradeTriggers.size(); i++) {
if (CheckCollisionBoxes(upgradeTriggers.at(i), MassShoot::Camera::GetCollider())) {
DrawTextEx(textFont, "PRESS E TO GRAB", { (float)GetScreenWidth() / 2 - 180, (float)GetScreenHeight() / 2 + 140 }, 40, 0, WHITE);
if (IsKeyPressed(KEY_E)) {
std::string info, script;
int key;
std::ifstream infoData("massshoot/upgrades/" + upgradeTriggersNames.at(i) + "/info.txt");
while (std::getline(infoData, info)) {
// truc
}
infoData.close();
std::ifstream scriptData("massshoot/upgrades/" + upgradeTriggersNames.at(i) + "/script.chai");
std::string scriptline;
while (std::getline(scriptData, scriptline)) {
script = script + "\n" + scriptline;
}
scriptData.close();
std::ifstream keyData("massshoot/upgrades/" + upgradeTriggersNames.at(i) + "/key.txt");
while (keyData >> key) {
printf("New Key: %i\n", key);
}
keyData.close();
MassShoot::Weapons::WeaponUpgrade newUpgrade;
newUpgrade.keyID = key;
newUpgrade.name = info;
newUpgrade.script = script;
upgrades.push_back(newUpgrade);
PlaySound(upgradeSound);
upgradeTriggers.erase(upgradeTriggers.begin()+i);
upgradeTriggersNames.erase(upgradeTriggersNames.begin() + i);
}
}
}
}
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color)
{
float x = position.x;
float y = position.y;
float z = position.z;
// Set desired texture to be enabled while drawing following vertex data
rlSetTexture(texture.id);
// Vertex data transformation can be defined with the commented lines,
// but in this example we calculate the transformed vertex data directly when calling rlVertex3f()
//rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
//rlTranslatef(2.0f, 0.0f, 0.0f);
//rlRotatef(45, 0, 1, 0);
//rlScalef(2.0f, 2.0f, 2.0f);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width / 2, y - height / 2, z + length / 2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width / 2, y - height / 2, z + length / 2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width / 2, y + height / 2, z + length / 2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width / 2, y + height / 2, z + length / 2); // Top Left Of The Texture and Quad
// Back Face
rlNormal3f(0.0f, 0.0f, -1.0f); // Normal Pointing Away From Viewer
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width / 2, y - height / 2, z - length / 2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width / 2, y + height / 2, z - length / 2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width / 2, y + height / 2, z - length / 2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width / 2, y - height / 2, z - length / 2); // Bottom Left Of The Texture and Quad
// Top Face
rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width / 2, y + height / 2, z - length / 2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width / 2, y + height / 2, z + length / 2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width / 2, y + height / 2, z + length / 2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width / 2, y + height / 2, z - length / 2); // Top Right Of The Texture and Quad
// Bottom Face
rlNormal3f(0.0f, -1.0f, 0.0f); // Normal Pointing Down
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width / 2, y - height / 2, z - length / 2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width / 2, y - height / 2, z - length / 2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width / 2, y - height / 2, z + length / 2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width / 2, y - height / 2, z + length / 2); // Bottom Right Of The Texture and Quad
// Right face
rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width / 2, y - height / 2, z - length / 2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width / 2, y + height / 2, z - length / 2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width / 2, y + height / 2, z + length / 2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width / 2, y - height / 2, z + length / 2); // Bottom Left Of The Texture and Quad
// Left Face
rlNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width / 2, y - height / 2, z - length / 2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width / 2, y - height / 2, z + length / 2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width / 2, y + height / 2, z + length / 2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width / 2, y + height / 2, z - length / 2); // Top Left Of The Texture and Quad
rlEnd();
//rlPopMatrix();
rlSetTexture(0);
}
// Draw cube with texture piece applied to all faces
void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color)
{
float x = position.x;
float y = position.y;
float z = position.z;
float texWidth = (float)texture.width;
float texHeight = (float)texture.height;
// Set desired texture to be enabled while drawing following vertex data
rlSetTexture(texture.id);
// We calculate the normalized texture coordinates for the desired texture-source-rectangle
// It means converting from (tex.width, tex.height) coordinates to [0.0f, 1.0f] equivalent
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front face
rlNormal3f(0.0f, 0.0f, 1.0f);
rlTexCoord2f(source.x / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x - width / 2, y - height / 2, z + length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x + width / 2, y - height / 2, z + length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, source.y / texHeight);
rlVertex3f(x + width / 2, y + height / 2, z + length / 2);
rlTexCoord2f(source.x / texWidth, source.y / texHeight);
rlVertex3f(x - width / 2, y + height / 2, z + length / 2);
// Back face
rlNormal3f(0.0f, 0.0f, -1.0f);
rlTexCoord2f((source.x + source.width) / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x - width / 2, y - height / 2, z - length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, source.y / texHeight);
rlVertex3f(x - width / 2, y + height / 2, z - length / 2);
rlTexCoord2f(source.x / texWidth, source.y / texHeight);
rlVertex3f(x + width / 2, y + height / 2, z - length / 2);
rlTexCoord2f(source.x / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x + width / 2, y - height / 2, z - length / 2);
// Top face
rlNormal3f(0.0f, 1.0f, 0.0f);
rlTexCoord2f(source.x / texWidth, source.y / texHeight);
rlVertex3f(x - width / 2, y + height / 2, z - length / 2);
rlTexCoord2f(source.x / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x - width / 2, y + height / 2, z + length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x + width / 2, y + height / 2, z + length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, source.y / texHeight);
rlVertex3f(x + width / 2, y + height / 2, z - length / 2);
// Bottom face
rlNormal3f(0.0f, -1.0f, 0.0f);
rlTexCoord2f((source.x + source.width) / texWidth, source.y / texHeight);
rlVertex3f(x - width / 2, y - height / 2, z - length / 2);
rlTexCoord2f(source.x / texWidth, source.y / texHeight);
rlVertex3f(x + width / 2, y - height / 2, z - length / 2);
rlTexCoord2f(source.x / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x + width / 2, y - height / 2, z + length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x - width / 2, y - height / 2, z + length / 2);
// Right face
rlNormal3f(1.0f, 0.0f, 0.0f);
rlTexCoord2f((source.x + source.width) / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x + width / 2, y - height / 2, z - length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, source.y / texHeight);
rlVertex3f(x + width / 2, y + height / 2, z - length / 2);
rlTexCoord2f(source.x / texWidth, source.y / texHeight);
rlVertex3f(x + width / 2, y + height / 2, z + length / 2);
rlTexCoord2f(source.x / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x + width / 2, y - height / 2, z + length / 2);
// Left face
rlNormal3f(-1.0f, 0.0f, 0.0f);
rlTexCoord2f(source.x / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x - width / 2, y - height / 2, z - length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, (source.y + source.height) / texHeight);
rlVertex3f(x - width / 2, y - height / 2, z + length / 2);
rlTexCoord2f((source.x + source.width) / texWidth, source.y / texHeight);
rlVertex3f(x - width / 2, y + height / 2, z + length / 2);
rlTexCoord2f(source.x / texWidth, source.y / texHeight);
rlVertex3f(x - width / 2, y + height / 2, z - length / 2);
rlEnd();
rlSetTexture(0);
}