405 lines
22 KiB
C++
405 lines
22 KiB
C++
|
//
|
||
|
// 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();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|