UFO: Alien Invasion
Loading...
Searching...
No Matches
cp_alien_interest.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "../../cl_shared.h"
27#include "cp_campaign.h"
28#include "cp_alien_interest.h"
29#include "save/save_interest.h"
30
37{
38 ccs.lastInterestIncreaseDelay = 0;
39 ccs.lastMissionSpawnedDelay = 0;
40 ccs.overallInterest = ccs.curCampaign->initialInterest;
41
42 for (int i = 0; i < INTERESTCATEGORY_MAX; i++)
43 ccs.interest[i] = 0;
44 ccs.interest[INTERESTCATEGORY_RECON] = ccs.curCampaign->initialInterest;
45}
46
53void INT_ChangeIndividualInterest (float interestFactor, interestCategory_t category)
54{
55 if (category == INTERESTCATEGORY_MAX) {
56 cgi->Com_Printf("CP_ChangeIndividualInterest: Unsupported value of category\n");
57 return;
58 }
59
60 if (interestFactor > 0.0f) {
61 const int gain = (int) (interestFactor * ccs.overallInterest);
62 const int diff = ccs.overallInterest - ccs.interest[category];
63 /* Fraction of individual interest that will be won if
64 * individal interest becomes higher than overall interest. 0 means no increase */
65 const float slowerIncreaseFraction = 0.5f;
66 /* Value increases: interestFactor is taken from the overall interest value
67 * But it increase slower if the individual interest becomes higher than the overall interest value */
68 if (diff > gain)
69 /* Final value of individual interest is below overall interest */
70 ccs.interest[category] += gain;
71 else if (diff > 0)
72 /* Initial value of individual interest is below overall interest */
73 ccs.interest[category] = ccs.overallInterest + (int) (slowerIncreaseFraction * (gain - diff));
74 else
75 /* Final value of individual interest is above overall interest */
76 ccs.interest[category] += (int) (slowerIncreaseFraction * gain);
77 } else {
78 /* Value decreases: interestFactor is taken from the individual interest value */
79 ccs.interest[category] += (int) (interestFactor * ccs.interest[category]);
80 if (ccs.interest[category] < 0) {
81 /* this may be reached if interestFactor is below -1 */
82 ccs.interest[category] = 0;
83 }
84 }
85}
86
93{
94 /* Adjust interest increase rate by difficulty. */
95 const int delayBetweenIncrease = HOURS_PER_ONE_INTEREST - campaign->difficulty;
96
97 ccs.lastInterestIncreaseDelay++;
98
99 if (ccs.lastInterestIncreaseDelay > delayBetweenIncrease) {
100 ccs.overallInterest++;
101 ccs.lastInterestIncreaseDelay %= delayBetweenIncrease;
102 }
103}
104
109bool INT_SaveXML (xmlNode_t* parent)
110{
111 xmlNode_t* interestsNode = cgi->XML_AddNode(parent, SAVE_INTERESTS);
112
113 cgi->XML_AddShortValue(interestsNode, SAVE_INTERESTS_LASTINCREASEDELAY, ccs.lastInterestIncreaseDelay);
114 cgi->XML_AddShortValue(interestsNode, SAVE_INTERESTS_LASTMISSIONSPAWNEDDELAY, ccs.lastMissionSpawnedDelay);
115 cgi->XML_AddShortValue(interestsNode, SAVE_INTERESTS_OVERALL, ccs.overallInterest);
116 cgi->Com_RegisterConstList(saveInterestConstants);
117 for (int i = 0; i < INTERESTCATEGORY_MAX; i++) {
118 xmlNode_t* interestNode = cgi->XML_AddNode(interestsNode, SAVE_INTERESTS_INTEREST);
119 cgi->XML_AddString(interestNode, SAVE_INTERESTS_ID, cgi->Com_GetConstVariable(SAVE_INTERESTCAT_NAMESPACE, i));
120 cgi->XML_AddShort(interestNode, SAVE_INTERESTS_VAL, ccs.interest[i]);
121 }
122 cgi->Com_UnregisterConstList(saveInterestConstants);
123 return true;
124}
125
130bool INT_LoadXML (xmlNode_t* parent)
131{
132 xmlNode_t* node;
133 xmlNode_t* interestsNode = cgi->XML_GetNode(parent, SAVE_INTERESTS);
134
135 ccs.lastInterestIncreaseDelay = cgi->XML_GetInt(interestsNode, SAVE_INTERESTS_LASTINCREASEDELAY, 0);
136 ccs.lastMissionSpawnedDelay = cgi->XML_GetInt(interestsNode, SAVE_INTERESTS_LASTMISSIONSPAWNEDDELAY, 0);
137 ccs.overallInterest = cgi->XML_GetInt(interestsNode, SAVE_INTERESTS_OVERALL, 0);
138
139 cgi->Com_RegisterConstList(saveInterestConstants);
140 for (node = cgi->XML_GetNode(interestsNode, SAVE_INTERESTS_INTEREST); node;
141 node = cgi->XML_GetNextNode(node, interestsNode, SAVE_INTERESTS_INTEREST)) {
142 const char* categoryId = cgi->XML_GetString(node, SAVE_INTERESTS_ID);
143 int cat;
144
145 if (!cgi->Com_GetConstInt(categoryId, (int*) &cat)) {
146 cgi->Com_Printf("Invalid interest category '%s'\n", categoryId);
147 continue;
148 }
149 ccs.interest[cat]= cgi->XML_GetInt(node, SAVE_INTERESTS_VAL, 0);
150 }
151 cgi->Com_UnregisterConstList(saveInterestConstants);
152
153 return true;
154}
155
156#ifdef DEBUG
160const char* INT_InterestCategoryToName (interestCategory_t category)
161{
162 switch (category) {
164 return "None";
166 return "Recon mission";
168 return "Terror mission";
170 return "Base attack";
173 return "Building Base or Subverting Government";
175 return "Supply base";
177 return "XVI propagation";
180 return "Interception";
182 return "Harvest";
184 return "Alien base discovered";
186 return "Rescue mission";
188 return "UFO-Carrier";
190 return "Unknown mission category";
191 }
192
193 /* Can't reach this point */
194 return "INVALID";
195}
196
201static void INT_AlienInterestList_f (void)
202{
203 cgi->Com_Printf("Overall interest: %i\n", ccs.overallInterest);
204 cgi->Com_Printf("Individual interest:\n");
206 cgi->Com_Printf("...%i. %s -- %i\n", i, INT_InterestCategoryToName((interestCategory_t)i), ccs.interest[i]);
207}
208
213static void INT_SetAlienInterest_f (void)
214{
215 if (cgi->Cmd_Argc() < 2) {
216 cgi->Com_Printf("Usage: %s <interestlevel>\n", cgi->Cmd_Argv(0));
217 return;
218 }
219
220 const int interest = atoi(cgi->Cmd_Argv(1));
221 ccs.overallInterest = std::max(0, interest);
222}
223#endif
224
225static const cmdList_t debugInterestCmds[] = {
226#ifdef DEBUG
227 {"debug_interestlist", INT_AlienInterestList_f, "Debug function to show alien interest values"},
228 {"debug_interestset", INT_SetAlienInterest_f, "Set overall interest level."},
229#endif
230 {nullptr, nullptr, nullptr}
231};
232
236{
237 cgi->Cmd_TableAddList(debugInterestCmds);
238}
239
243void INT_Shutdown (void)
244{
245 cgi->Cmd_TableRemoveList(debugInterestCmds);
246}
Share stuff between the different cgame implementations.
bool INT_LoadXML(xmlNode_t *parent)
Load callback for savegames in XML Format.
void INT_InitStartup(void)
Init actions for alien interests-subsystem.
void INT_Shutdown(void)
Closing actions for alien interests-subsystem.
void INT_IncreaseAlienInterest(const campaign_t *campaign)
Increase alien overall interest.
void INT_ChangeIndividualInterest(float interestFactor, interestCategory_t category)
Change individual interest value.
static const cmdList_t debugInterestCmds[]
bool INT_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
void INT_ResetAlienInterest(void)
Initialize alien interest values and mission cycle.
Alien interest header.
interestCategory_t
@ INTERESTCATEGORY_BASE_ATTACK
@ INTERESTCATEGORY_INTERCEPTBOMBING
@ INTERESTCATEGORY_NONE
@ INTERESTCATEGORY_ALIENBASE
@ INTERESTCATEGORY_BUILDING
@ INTERESTCATEGORY_MAX
@ INTERESTCATEGORY_SUBVERT
@ INTERESTCATEGORY_SUPPLY
@ INTERESTCATEGORY_RECON
@ INTERESTCATEGORY_UFOCARRIER
@ INTERESTCATEGORY_XVI
@ INTERESTCATEGORY_TERROR_ATTACK
@ INTERESTCATEGORY_INTERCEPT
@ INTERESTCATEGORY_RESCUE
@ INTERESTCATEGORY_HARVEST
ccs_t ccs
Header file for single player campaign control.
#define HOURS_PER_ONE_INTEREST
The amount of time (in hours) it takes for the interest to increase by 1. Is later affected by diffic...
Definition cp_campaign.h:67
const cgame_import_t * cgi
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
QGL_EXTERN GLint i
Definition r_gl.h:113
XML tag constants for savegame.
static const constListEntry_t saveInterestConstants[]
#define SAVE_INTERESTS_VAL
#define SAVE_INTERESTS_LASTINCREASEDELAY
#define SAVE_INTERESTS_OVERALL
#define SAVE_INTERESTCAT_NAMESPACE
#define SAVE_INTERESTS_ID
#define SAVE_INTERESTS
#define SAVE_INTERESTS_LASTMISSIONSPAWNEDDELAY
#define SAVE_INTERESTS_INTEREST
signed int difficulty
#define xmlNode_t
Definition xml.h:24