CnC_Remastered_Collection/TIBERIANDAWN/SMUDGE.CPP

405 lines
22 KiB
C++
Raw Permalink Normal View History

//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
/* $Header: F:\projects\c&c\vcs\code\smudge.cpv 2.18 16 Oct 1995 16:52:06 JOE_BOSTIC $ */
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : SMUDGE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : August 9, 1994 *
* *
* Last Update : July 24, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* SmudgeClass::Init -- Initialize the smudge tracking system. *
* SmudgeClass::SmudgeClass -- Constructor for smudge objects. *
* SmudgeClass::operator delete -- Deletes the smudge from the tracking system. *
* SmudgeClass::operator new -- Creator of smudge objects. *
* SmudgeClass::Mark -- Marks a smudge down on the map. *
* SmudgeClass::Read_INI -- Reads smudge data from an INI file. *
* SmudgeClass::Write_INI -- Writes the smudge data to an INI file. *
* SmudgeClass::Disown -- Disowns (removes) a building bib piece. *
* SmudgeClass::Validate -- validates smudge pointer *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "smudge.h"
/*
** This contains the value of the Virtual Function Table Pointer
*/
void * SmudgeClass::VTable;
HousesType SmudgeClass::ToOwn = HOUSE_NONE;
/***********************************************************************************************
* SmudgeClass::Validate -- validates smudge pointer *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = ok, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 08/09/1995 BRR : Created. *
*=============================================================================================*/
#ifdef CHEAT_KEYS
int SmudgeClass::Validate(void) const
{
int num;
num = Smudges.ID(this);
if (num < 0 || num >= SMUDGE_MAX) {
Validate_Error("SMUDGE");
return (0);
}
else
return (1);
}
#else
#define Validate()
#endif
/***********************************************************************************************
* SmudgeClass::operator new -- Creator of smudge objects. *
* *
* This routine will allocate a smudge object from the smudge tracking pool. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a pointer to a newly allocated smudge object. If one couldn't be *
* found, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/01/1994 JLB : Created. *
*=============================================================================================*/
void * SmudgeClass::operator new(size_t )
{
void * ptr = Smudges.Allocate();
if (ptr) {
((SmudgeClass *)ptr)->Set_Active();
}
return(ptr);
}
/***********************************************************************************************
* SmudgeClass::operator delete -- Deletes the smudge from the tracking system. *
* *
* This routine is used to remove the smudge from the tracking system. *
* *
* INPUT: ptr -- Pointer to the smudge to delete. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/01/1994 JLB : Created. *
*=============================================================================================*/
void SmudgeClass::operator delete(void *ptr)
{
if (ptr) {
((SmudgeClass *)ptr)->IsActive = false;
}
Smudges.Free((SmudgeClass *)ptr);
//Map.Validate();
}
/***********************************************************************************************
* SmudgeClass::SmudgeClass -- Constructor for smudge objects. *
* *
* This is the typical constructor for smudge objects. If the position to place the *
* smudge is not given, then the smudge will be initialized in a limbo state. If the *
* smudge is placed on the map, then this operation causes the smudge object itself to be *
* deleted and special map values updated to reflect the presence of a smudge. *
* *
* INPUT: type -- The type of smudge to construct. *
* *
* pos -- The position to place the smudge. If -1, then the smudge is initialized *
* into a limbo state. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/01/1994 JLB : Created. *
*=============================================================================================*/
SmudgeClass::SmudgeClass(SmudgeType type, COORDINATE pos, HousesType house) :
Class(&SmudgeTypeClass::As_Reference(type))
{
if (pos != -1) {
ToOwn = house;
if (!Unlimbo(pos)) {
Delete_This();
}
ToOwn = HOUSE_NONE;
}
}
/***********************************************************************************************
* SmudgeClass::Init -- Initialize the smudge tracking system. *
* *
* This routine is used during the scenario clearing process to initialize the smudge *
* object tracking system to a null state. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/01/1994 JLB : Created. *
*=============================================================================================*/
void SmudgeClass::Init(void)
{
SmudgeClass *ptr;
Smudges.Free_All();
ptr = new SmudgeClass();
VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0];
delete ptr;
}
/***********************************************************************************************
* SmudgeClass::Mark -- Marks a smudge down on the map. *
* *
* This routine will place the smudge on the map. If the map cell allows. *
* *
* INPUT: mark -- The type of marking to perform. Only MARK_DOWN is supported. *
* *
* OUTPUT: bool; Was the smudge marked successfully? Failure occurs if the smudge isn't *
* marked DOWN. *
* *
* WARNINGS: The smudge object is DELETED by this routine. *
* *
* HISTORY: *
* 09/22/1994 JLB : Created. *
* 12/23/1994 JLB : Checks low level legality before proceeding. *
*=============================================================================================*/
bool SmudgeClass::Mark(MarkType mark)
{
Validate();
if (ObjectClass::Mark(mark)) {
if (mark == MARK_DOWN) {
CELL origin = Coord_Cell(Coord);
for (int w = 0; w < Class->Width; w++) {
for (int h = 0; h < Class->Height; h++) {
CELL newcell = origin + w + (h*MAP_CELL_W);
if (Map.In_Radar(newcell)) {
CellClass * cell = &Map[newcell];
if (Class->IsBib) {
cell->Smudge = Class->Type;
cell->SmudgeData = w + (h*Class->Width);
cell->Owner = ToOwn;
} else {
if (cell->Is_Generally_Clear()) {
if (Class->IsCrater && cell->Smudge != SMUDGE_NONE && SmudgeTypeClass::As_Reference(cell->Smudge).IsCrater) {
cell->SmudgeData++;
cell->SmudgeData = (int)MIN((int)cell->SmudgeData, (int)4);
}
if (cell->Smudge == SMUDGE_NONE) {
/*
** Special selection of a crater that starts as close to the
** specified coordinate as possible.
*/
if (Class->IsCrater) {
cell->Smudge = (SmudgeType)(SMUDGE_CRATER1 + CellClass::Spot_Index(Coord));
} else {
cell->Smudge = Class->Type;
}
cell->SmudgeData = 0;
}
}
}
/*
** Flag everything that might be overlapping this cell to redraw itself.
*/
cell->Redraw_Objects();
}
}
}
/*
** Whether it was successful in placing, or not, delete the smudge object. It isn't
** needed once the map has been updated with the proper smudge data.
*/
Delete_This();
return(true);
}
}
return(false);
}
/***********************************************************************************************
* SmudgeClass::Read_INI -- Reads smudge data from an INI file. *
* *
* This routine is used by the scenario loader to read the smudge data in an INI file and *
* create the appropriate smudge objects on the map. *
* *
* INPUT: buffer -- Pointer to the INI file staging buffer. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/01/1994 JLB : Created. *
* 07/24/1995 JLB : Sets the smudge data value as well. *
*=============================================================================================*/
void SmudgeClass::Read_INI(char *buffer)
{
char buf[128]; // Working string staging buffer.
int len = strlen(buffer) + 2;
char * tbuffer = buffer + len;
WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer);
while (*tbuffer != '\0') {
SmudgeType smudge; // Smudge type.
WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer);
smudge = SmudgeTypeClass::From_Name(strtok(buf, ","));
if (smudge != SMUDGE_NONE) {
char * ptr = strtok(NULL, ",");
if (ptr) {
int data = 0;
CELL cell = atoi(ptr);
ptr = strtok(NULL, ",");
if (ptr) data = atoi(ptr);
new SmudgeClass(smudge, Cell_Coord(cell));
if (Map[cell].Smudge == smudge && data) {
Map[cell].SmudgeData = data;
}
}
}
tbuffer += strlen(tbuffer)+1;
}
}
/***********************************************************************************************
* SmudgeClass::Write_INI -- Writes the smudge data to an INI file. *
* *
* This routine is used by the scenario editor to write the smudge data to an INI file. *
* *
* INPUT: buffer -- Pointer to the INI file staging buffer. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/01/1994 JLB : Created. *
* 07/24/1995 JLB : Records the smudge data as well. *
*=============================================================================================*/
void SmudgeClass::Write_INI(char *buffer)
{
char uname[10];
char buf[127];
char *tbuffer; // Accumulation buffer of unit IDs.
/*
** First, clear out all existing template data from the ini file.
*/
tbuffer = buffer + strlen(buffer) + 2;
WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer);
while (*tbuffer != '\0') {
WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer);
tbuffer += strlen(tbuffer)+1;
}
/*
** Find all templates and write them to the file.
*/
for (CELL index = 0; index < MAP_CELL_TOTAL; index++) {
CellClass * ptr;
ptr = &Map[index];
if (ptr->Smudge != SMUDGE_NONE) {
SmudgeTypeClass const * stype = &SmudgeTypeClass::As_Reference(ptr->Smudge);
if (!stype->IsBib) {
sprintf(uname, "%03d", index);
sprintf(buf, "%s,%d,%d", stype->IniName, index, ptr->SmudgeData);
WWWritePrivateProfileString(INI_Name(), uname, buf, buffer);
}
}
}
}
/***********************************************************************************************
* SmudgeClass::Disown -- Disowns (removes) a building bib piece. *
* *
* This routine is used when a building is removed from the game. If there was any bib *
* attached, this routine will be called to disown the cells and remove the bib artwork. *
* *
* INPUT: cell -- The origin cell for this bib removal. *
* *
* OUTPUT: none *
* *
* WARNINGS: This is actually working on a temporary bib object. It is created for the sole *
* purpose of calling this routine. It will be deleted immediately afterward. *
* *
* HISTORY: *
* 07/04/1995 JLB : Created. *
*=============================================================================================*/
void SmudgeClass::Disown(CELL cell)
{
Validate();
if (Class->IsBib) {
for (int w = 0; w < Class->Width; w++) {
for (int h = 0; h < Class->Height; h++) {
CellClass & cellptr = Map[cell + w + (h*MAP_CELL_W)];
if (cellptr.Overlay == OVERLAY_NONE || !OverlayTypeClass::As_Reference(cellptr.Overlay).IsWall) {
cellptr.Smudge = SMUDGE_NONE;
cellptr.SmudgeData = 0;
cellptr.Owner = HOUSE_NONE;
cellptr.Redraw_Objects();
}
}
}
}
}