mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-12 08:00:55 +02:00
Added the ability to place new light objects in the world, lights don't work yet.
This commit is contained in:
+2
-2
@@ -631,7 +631,7 @@ set(src_redalert
|
||||
./redalert/mapscript.cpp
|
||||
./redalert/txtprnt.cpp
|
||||
./redalert/tilesetxml.cpp
|
||||
"redalert/sidebareditor.cpp")
|
||||
"redalert/sidebareditor.cpp" "redalert/light.cpp")
|
||||
|
||||
set(src_external
|
||||
#glew
|
||||
@@ -731,7 +731,7 @@ if (UNIX)
|
||||
add_definitions(-D RA_AF -DCHEAT_KEYS -DIMGUI_IMPL_OPENGL_LOADER_GLEW -DSCENARIO_EDITOR -DTRUE_FALSE_DEFINED -DENGLISH -D_USRDLL -DREDALERT_EXPORTS)
|
||||
endif(UNIX)
|
||||
|
||||
add_executable(RedAlert ${src_io} ${src_win32lib} ${src_redalert} ${src_external})
|
||||
add_executable(RedAlert ${src_io} ${src_win32lib} ${src_redalert} ${src_external} "redalert/light.cpp")
|
||||
|
||||
if (MSVC)
|
||||
set_target_properties(RedAlert PROPERTIES OUTPUT_NAME "RedAlert" LINK_FLAGS "/PDB:\"RedAlert.pdb\" /SUBSYSTEM:WINDOWS" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../" )
|
||||
|
||||
@@ -2230,6 +2230,8 @@ ObjectClass * DisplayClass::Cell_Object(CELL cell, int x, int y) const
|
||||
HidPage.Unlock();
|
||||
}
|
||||
|
||||
lightManager.RenderLights();
|
||||
|
||||
#ifndef WIN32
|
||||
/*
|
||||
** Once the icons are drawn, duplicate the bottom line of the screen into the phantom
|
||||
|
||||
@@ -234,6 +234,7 @@ struct NoInitClass {
|
||||
#include "crcstraw.h"
|
||||
#include "shastraw.h"
|
||||
#include "rndstraw.h"
|
||||
#include "light.h"
|
||||
|
||||
// Should be part of WWLIB.H. This is used in JSHELL.CPP.
|
||||
typedef struct {
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
// light.cpp
|
||||
//
|
||||
|
||||
#include "function.h"
|
||||
#include "image.h"
|
||||
|
||||
void Light_t::PlaceLight(int screenx, int screeny) {
|
||||
isPending = false;
|
||||
COORDINATE lightCoord;
|
||||
|
||||
CellClass::ConvertIsoCoordsToScreen(screenx, screeny);
|
||||
|
||||
position = Map.Closest_Free_Spot(Map.Pixel_To_Coord(screenx, screeny));
|
||||
}
|
||||
|
||||
bool Light_t::GetRenderPosition(int& x, int& y) {
|
||||
Map.Coord_To_Pixel(position, x, y);
|
||||
CellClass::ConvertCoordsToIsometric(x, y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LightManager lightManager;
|
||||
|
||||
LightManager::LightManager() {
|
||||
FreeAllLights();
|
||||
}
|
||||
|
||||
void LightManager::Init(void) {
|
||||
lightEditorIcon = Image_LoadImage("ui/edwin/lightbulb.png");
|
||||
}
|
||||
|
||||
void LightManager::RenderLights(void) {
|
||||
for(int i = 0; i < MAX_WORLD_LIGHTS; i++) {
|
||||
if (!lights[i].active) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!lights[i].isPending) {
|
||||
int screenx, screeny;
|
||||
lights[i].GetRenderPosition(screenx, screeny);
|
||||
GL_RenderImage(lightEditorIcon, screenx, screeny, 30, 30);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LightManager::FreeAllLights(void) {
|
||||
memset(lights, 0, sizeof(lights));
|
||||
}
|
||||
|
||||
Light_t* LightManager::AllocateLight(void) {
|
||||
for(int i = 0; i < MAX_WORLD_LIGHTS; i++) {
|
||||
if(!lights[i].active) {
|
||||
lights[i].active = true;
|
||||
lights[i].lightNum = i;
|
||||
return &lights[i];
|
||||
}
|
||||
}
|
||||
|
||||
assert(!"Too many lights in the scene!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Light_t *LightManager::PlaceLight(char *name, int x, int y, float r, float g, float b, float radius, LightType_t type) {
|
||||
Light_t* light = AllocateLight();
|
||||
|
||||
if(!light) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(name == NULL) {
|
||||
sprintf(light->name, "light%d", light->lightNum);
|
||||
}
|
||||
else {
|
||||
strcpy(light->name, name);
|
||||
}
|
||||
light->position = XYP_Coord(x, y);
|
||||
light->color.x = r;
|
||||
light->color.y = g;
|
||||
light->color.z = b;
|
||||
light->radius = radius;
|
||||
light->type = type;
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
void LightManager::FreeLight(Light_t* light) {
|
||||
light->active = false;
|
||||
}
|
||||
|
||||
void LightManager::Write_Scenerio_Lights(CCINIClass* ini) {
|
||||
ini->Clear("Lights");
|
||||
|
||||
// Write out the lights.
|
||||
for (int i = 0; i < MAX_WORLD_LIGHTS; i++) {
|
||||
if (lights[i].active == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
char name[256];
|
||||
sprintf(buffer, "%s,%d,%f,%f,%f,%f,%d", lights[i].name, lights[i].position, lights[i].color.x, lights[i].color.y, lights[i].color.z, lights[i].radius, lights[i].type);
|
||||
sprintf(name, "%d", i);
|
||||
ini->Put_String("Lights",name,buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void LightManager::Read_Scenerio_Lights(CCINIClass* ini) {
|
||||
char buf[2048];
|
||||
|
||||
int len = ini->Entry_Count("Lights");
|
||||
for (int index = 0; index < len; index++) {
|
||||
char const* entry = ini->Get_Entry("Lights", index);
|
||||
|
||||
/*
|
||||
** Get a lighting entry.
|
||||
*/
|
||||
ini->Get_String("Lights", entry, NULL, buf, sizeof(buf));
|
||||
Light_t* light = AllocateLight();
|
||||
strcpy(light->name, strtok(buf, ","));
|
||||
light->position = atoi(strtok(NULL, ","));
|
||||
light->color.x = atof(strtok(NULL, ","));
|
||||
light->color.y = atof(strtok(NULL, ","));
|
||||
light->color.z = atof(strtok(NULL, ","));
|
||||
light->radius = atof(strtok(NULL, ","));
|
||||
light->type = (LightType_t)atoi(strtok(NULL, ","));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// light.h
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include "vectormath.h"
|
||||
|
||||
class CCINIClass;
|
||||
struct Image_t;
|
||||
|
||||
#define MAX_WORLD_LIGHTS 6556
|
||||
|
||||
enum LightType_t {
|
||||
LIGHT_AMBIENT = 0,
|
||||
LIGHT_POINT,
|
||||
LIGHT_SPOT
|
||||
};
|
||||
|
||||
class Light_t {
|
||||
friend class LightManager;
|
||||
public:
|
||||
int GetLightNum(void) { return lightNum; }
|
||||
void PlaceLight(int screenx, int screeny);
|
||||
bool GetRenderPosition(int& x, int& y);
|
||||
|
||||
char name[512];
|
||||
unsigned long position;
|
||||
float3 color;
|
||||
float radius;
|
||||
bool isPending;
|
||||
LightType_t type;
|
||||
protected:
|
||||
int lightNum;
|
||||
bool active;
|
||||
};
|
||||
|
||||
class LightManager {
|
||||
public:
|
||||
LightManager();
|
||||
|
||||
void Init(void);
|
||||
|
||||
Light_t* AllocateLight(void);
|
||||
Light_t* PlaceLight(char *name, int x, int y, float r, float g, float b, float radius, LightType_t type);
|
||||
|
||||
void FreeLight(Light_t* light);
|
||||
void FreeAllLights(void);
|
||||
|
||||
void Read_Scenerio_Lights(CCINIClass* ini);
|
||||
void Write_Scenerio_Lights(CCINIClass* ini);
|
||||
public:
|
||||
Image_t* GetLightEditorIcon(void) { return lightEditorIcon; }
|
||||
void RenderLights(void);
|
||||
private:
|
||||
Light_t lights[MAX_WORLD_LIGHTS];
|
||||
int numLights;
|
||||
Image_t* lightEditorIcon;
|
||||
};
|
||||
|
||||
extern LightManager lightManager;
|
||||
+61
-34
@@ -107,6 +107,7 @@ MapEditClass::MapEditClass(void)
|
||||
// ScenVar = SCEN_VAR_A;
|
||||
LastHouse = HOUSE_GOOD;
|
||||
GrabbedObject = 0;
|
||||
GrabbedLight = nullptr;
|
||||
Scen.Waypoint[WAYPT_HOME] = 0;
|
||||
CurrentCell = 0;
|
||||
CurTeam = NULL;
|
||||
@@ -545,25 +546,33 @@ void MapEditClass::AI(KeyNumType & input, int x, int y)
|
||||
|
||||
rc = Mouse_Moved();
|
||||
if (Keyboard->Down(KN_LMOUSE) && rc) {
|
||||
|
||||
/*
|
||||
** "Paint" mode: place current object, and restart placement
|
||||
*/
|
||||
if (PendingObject) {
|
||||
Flag_To_Redraw(true);
|
||||
if (Place_Object() == 0) {
|
||||
Changed = 1;
|
||||
Start_Placement();
|
||||
}
|
||||
} else {
|
||||
|
||||
if (GrabbedLight)
|
||||
{
|
||||
GrabbedLight->PlaceLight(Get_Mouse_X(), Get_Mouse_Y());
|
||||
GrabbedLight = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
** Move the currently-grabbed object
|
||||
** "Paint" mode: place current object, and restart placement
|
||||
*/
|
||||
if (GrabbedObject) {
|
||||
GrabbedObject->Mark(MARK_CHANGE);
|
||||
if (Move_Grabbed_Object() == 0) {
|
||||
if (PendingObject) {
|
||||
Flag_To_Redraw(true);
|
||||
if (Place_Object() == 0) {
|
||||
Changed = 1;
|
||||
Start_Placement();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
** Move the currently-grabbed object
|
||||
*/
|
||||
if (GrabbedObject) {
|
||||
GrabbedObject->Mark(MARK_CHANGE);
|
||||
if (Move_Grabbed_Object() == 0) {
|
||||
Changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1466,27 +1475,40 @@ bool MapEditClass::Mouse_Moved(void)
|
||||
const ObjectTypeClass * objtype = NULL;
|
||||
bool retcode = false;
|
||||
|
||||
/*
|
||||
** Return if no motion
|
||||
*/
|
||||
if (old_mx == Get_Mouse_X() && old_my == Get_Mouse_Y()) {
|
||||
return(false);
|
||||
if (GrabbedLight != NULL)
|
||||
{
|
||||
GL_RenderImage(lightManager.GetLightEditorIcon(), Get_Mouse_X(), Get_Mouse_Y(), 32, 32);
|
||||
old_mx = Get_Mouse_X();
|
||||
old_my = Get_Mouse_Y();
|
||||
old_zonecell = ZoneCell;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
** Get a ptr to ObjectTypeClass
|
||||
*/
|
||||
if (PendingObject) {
|
||||
objtype = PendingObject;
|
||||
} else {
|
||||
if (GrabbedObject) {
|
||||
objtype = &GrabbedObject->Class_Of();
|
||||
} else {
|
||||
old_mx = Get_Mouse_X();
|
||||
old_my = Get_Mouse_Y();
|
||||
old_zonecell = ZoneCell;
|
||||
else
|
||||
{
|
||||
/*
|
||||
** Return if no motion
|
||||
*/
|
||||
if (old_mx == Get_Mouse_X() && old_my == Get_Mouse_Y()) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Get a ptr to ObjectTypeClass
|
||||
*/
|
||||
if (PendingObject) {
|
||||
objtype = PendingObject;
|
||||
}
|
||||
else {
|
||||
if (GrabbedObject) {
|
||||
objtype = &GrabbedObject->Class_Of();
|
||||
}
|
||||
else {
|
||||
old_mx = Get_Mouse_X();
|
||||
old_my = Get_Mouse_Y();
|
||||
old_zonecell = ZoneCell;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1659,6 +1681,11 @@ void MapEditClass::Main_Menu(void)
|
||||
process = false;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
GrabbedLight = lightManager.PlaceLight(NULL, 0, 0, 1.0f, 1.0f, 1.0f, 100, LIGHT_POINT);
|
||||
GrabbedLight->isPending = true;
|
||||
break;
|
||||
|
||||
/*
|
||||
** Test-drive this scenario
|
||||
*/
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
#include <vector>
|
||||
#include "sidebareditor.h"
|
||||
|
||||
class Light_t;
|
||||
|
||||
/*
|
||||
** This is the maximum # of ObjectTypeClasses the editor has to deal with.
|
||||
*/
|
||||
@@ -270,6 +272,8 @@ class MapEditClass : public MouseClass
|
||||
//int LastChoice; // index of item user picked last
|
||||
HousesType LastHouse; // house of last item picked
|
||||
|
||||
Light_t *GrabbedLight;
|
||||
|
||||
/*
|
||||
** Variables for grabbing/moving objects
|
||||
*/
|
||||
|
||||
@@ -820,6 +820,8 @@ void Clear_Scenario(void)
|
||||
{
|
||||
// TCTCTC -- possibly just use in-place new of scenario object?
|
||||
|
||||
lightManager.FreeAllLights();
|
||||
|
||||
Scen.MissionTimer = 0;
|
||||
Scen.MissionTimer.Stop();
|
||||
Scen.Timer = 0;
|
||||
@@ -2289,6 +2291,8 @@ bool Read_Scenario_INI(char * fname, bool )
|
||||
Scen.IsMoneyTiberium = ini.Get_Bool(BASIC, "FillSilos", Scen.IsMoneyTiberium);
|
||||
Scen.Percent = ini.Get_Int(BASIC, "Percent", Scen.Percent);
|
||||
|
||||
lightManager.Read_Scenerio_Lights(&ini);
|
||||
|
||||
/*
|
||||
** Read in the specific information for each of the house types. This creates
|
||||
** the houses of different types.
|
||||
@@ -2659,6 +2663,7 @@ void Write_Scenario_INI(char * fname)
|
||||
ini.Put_Bool(BASIC, "TruckCrate", Scen.IsTruckCrate);
|
||||
ini.Put_Int(BASIC, "Percent", Scen.Percent);
|
||||
|
||||
lightManager.Write_Scenerio_Lights(&ini);
|
||||
HouseClass::Write_INI(ini);
|
||||
TeamTypeClass::Write_INI(ini);
|
||||
TriggerTypeClass::Write_INI(ini);
|
||||
|
||||
@@ -57,7 +57,8 @@ void SidebarEditor::draw_it(void) {
|
||||
if (ImGui::MenuItem("Scenario Options")) { mainmenu_selection = 5; }
|
||||
if (ImGui::MenuItem("AI Options")) { mainmenu_selection = 6; }
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Objects"))
|
||||
{
|
||||
Debug_LockScroll = true;
|
||||
@@ -65,6 +66,13 @@ void SidebarEditor::draw_it(void) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Lights"))
|
||||
{
|
||||
Debug_LockScroll = true;
|
||||
if (ImGui::MenuItem("Add Light")) { mainmenu_selection = 8; }
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Run"))
|
||||
{
|
||||
Debug_LockScroll = true;
|
||||
|
||||
@@ -859,6 +859,8 @@ void Create_Main_Window ( HANDLE instance , int command_show , int width , int h
|
||||
io.Fonts->AddFontFromFileTTF("fonts/Arial.ttf", 16.0f);
|
||||
|
||||
ImGui_NewFrame();
|
||||
|
||||
lightManager.Init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user