Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
campaign.qc
Go to the documentation of this file.
1#include "campaign.qh"
2
4#include <common/mapinfo.qh>
5#include <common/stats.qh>
7#include <server/cheats.qh>
9#include <server/world.qh>
10
11// campaign cvars:
12// _campaign_index: index of CURRENT map
13// _campaign_name: name of the current campaign
14// g_campaign(name)_index: index of current LAST map (saved)
15// g_campaign_skill: bot skill offset
16
20//float checkrules_equality;
21
22float CampaignBailout(string s)
23{
24 cvar_set("g_campaign", "0");
25 LOG_INFO("^4campaign initialization failed: ", s);
27 error("CAMPAIGN FAIL AHAHAHAHAHAHAHAHAH))");
28 return 1;
29}
30
32{
33 string thismapname, wantedmapname;
34 thismapname = GetMapname();
35 wantedmapname = campaign_gametype[0];
36 if(MapInfo_CurrentGametype() != MapInfo_Type_FromString(wantedmapname, false, false))
37 return CampaignBailout("wrong gametype!");
38 wantedmapname = campaign_mapname[0];
39 if(wantedmapname != thismapname)
40 return CampaignBailout(strcat("wrong map: ", wantedmapname, " != ", thismapname));
41 return 0;
42}
43
45{
46 return campaign_level + 1;
47}
48
50{
51 float baseskill;
54 campaign_index_var = strzone(strcat("g_campaign", campaign_name, "_index"));
56
57 if(campaign_entries < 1)
58 {
59 CampaignBailout("unknown map");
60 return;
61 }
62
64 {
67 CampaignBailout("JOLLY CHEATS AHAHAHAHAHAHAH))");
68 return;
69 }
70
72 campaign_forcewin = false;
73
74 cvar_set("sv_public", "0");
75 cvar_set("pausable", "1");
76
77 string cvar_campaignwrapper_list = strcat("; ", campaign_mutators[0], "; ");
78 int argc = tokenizebyseparator(cvar_campaignwrapper_list, "; ");
79 if(argc > 0)
80 {
81 for(int j = 0; j < argc; ++j)
82 {
83 string arg = argv(j);
84 if(arg == "") continue;
86 }
87 }
88
89 cvar_settemp("g_campaign", "1");
90 cvar_settemp("g_dm", "0");
91 cvar_settemp("skill", ftos(baseskill));
92 cvar_settemp("bot_number", ftos(campaign_bots[0]));
93
95
97 return;
98}
99
101{
102 // now some sanity checks
103 if(Campaign_Invalid())
104 return;
106 {
107 cvar_set("fraglimit", "0");
108 cvar_set("leadlimit", "0");
109 cvar_set("timelimit", "0.01");
110 }
111 else
112 {
113 // "default" uses implicit values, "" or "0" means no limit
115 if(argv(0) != "default") {
116 cvar_set("fraglimit", argv(0));
117 }
118 if(argv(1) != "default") {
119 cvar_set("leadlimit", argv(1));
120 }
121 if(campaign_timelimit[0] != "default") {
122 cvar_set("timelimit", campaign_timelimit[0]);
123 }
124 }
125}
126
127void CampaignSaveCvar(string cvarname, float value)
128{
129 float fh;
130 float len;
131 string contents;
132 string l;
133
134 registercvar(cvarname, ftos(value));
135 cvar_set(cvarname, ftos(value));
136 // note: cvarname must be remembered
137
138 fh = fopen("campaign.cfg", FILE_READ);
139 contents = "";
140 if(fh >= 0)
141 {
142 while((l = fgets(fh)))
143 {
144 len = tokenize_console(l);
145 if(len != 3)
146 continue;
147 if(argv(0) != "set")
148 continue;
149 if(argv(1) == cvarname)
150 continue;
151 contents = strcat(contents, "set ", argv(1), " ", argv(2), "\n");
152 }
153 fclose(fh);
154 }
155 contents = strcat(contents, "set ", cvarname, " ", ftos(value), "\n");
156 fh = fopen("campaign.cfg", FILE_WRITE);
157 if(fh >= 0)
158 {
159 fputs(fh, contents);
160 }
161 else
162 {
163 error("Cannot write to campaign file");
164 }
165}
166
168{
169 int won = 0;
170 int lost = 0;
171 string savevar;
172
174 if(it.winning)
175 won += 1;
176 else
177 lost += 1;
178 });
179
181 {
182 campaign_won = 1;
183 bprint("Campaign test run, advancing level.\n");
184 }
185 else if(campaign_forcewin)
186 {
187 campaign_won = 1;
188 bprint("The current level has been WON.\n");
189 }
190 else if(won == 1 && lost == 0 && checkrules_equality == 0)
191 {
192 if(autocvar_timelimit != 0 && autocvar_fraglimit != 0 && time > autocvar_timelimit * 60) // checks if the timelimit has expired.
193 {
194 campaign_won = 0;
195 bprint("Time's up! The current level has been LOST.\n");
196 // sound!
197 }
198 else
199 {
200 campaign_won = 1;
201 bprint("The current level has been WON.\n");
202 // sound!
203 }
204 }
205 else if(autocvar_timelimit != 0 && time > autocvar_timelimit * 60)
206 {
207 campaign_won = 0;
208 bprint("Time's up! The current level has been LOST.\n");
209 // sound!
210 }
211 else
212 {
213 campaign_won = 0;
214 bprint("The current level has been LOST.\n");
215 // sound!
216 }
217
219 {
221 {
222 if(campaign_entries < 2)
223 {
224 // I have won
225 savevar = strcat("g_campaign", campaign_name, "_won");
226 CampaignSaveCvar(savevar, 1);
227 // advance level (for menu to show it right)
229 }
230 else
231 {
232 // advance level
234 }
235 }
236 }
237}
238
240{
241 // NOTE: campaign_won is 0 or 1, that is, points to the next level
242
244 {
245 // last map won!
246 LOG_DEBUG("^2test run: campaign looks GOOD");
247 localcmd("togglemenu 1\n");
249 return;
250 }
251
256 campaign_name = "";
257}
258
259
260
261void CampaignLevelWarp(float n)
262{
263 if(n < 0)
264 n = campaign_level + 1;
266 CampaignFile_Load(n, 1);
268 CampaignSetup(0);
269 else
270 error("Sorry, cheater. You are NOT WELCOME.");
272}
273
string campaign_mutators[CAMPAIGN_MAX_ENTRIES]
string campaign_name
float campaign_bots[CAMPAIGN_MAX_ENTRIES]
float campaign_botskill[CAMPAIGN_MAX_ENTRIES]
void CampaignFile_Unload()
string campaign_gametype[CAMPAIGN_MAX_ENTRIES]
string campaign_fraglimit[CAMPAIGN_MAX_ENTRIES]
string campaign_mapname[CAMPAIGN_MAX_ENTRIES]
void CampaignSetup(int n)
int campaign_entries
float CampaignFile_Load(float offset, float entries)
string campaign_timelimit[CAMPAIGN_MAX_ENTRIES]
float cheatcount_total
Definition cheats.qh:10
int autocvar_sv_cheats
Definition cheats.qh:5
#define IS_PLAYER(s)
Definition player.qh:243
#define autocvar_timelimit
Definition stats.qh:92
#define autocvar_fraglimit
Definition stats.qh:90
float cvar_settemp(string tmp_cvar, string tmp_value)
Definition util.qc:811
string mapname
const float FILE_READ
const float FILE_WRITE
float time
#define tokenize_console
#define tokenizebyseparator
string GetMapname()
#define LOG_INFO(...)
Definition log.qh:65
#define LOG_DEBUG(...)
Definition log.qh:80
void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s, float recurse)
Definition mapinfo.qc:667
Gametype MapInfo_CurrentGametype()
Definition mapinfo.qc:1490
void MapInfo_SwitchGameType(Gametype t)
Definition mapinfo.qc:1518
Gametype MapInfo_Type_FromString(string gtype, bool dowarn, bool is_q3compat)
Definition mapinfo.qc:621
#define MAPINFO_SETTEMP_ACL_USER
Definition mapinfo.qh:236
float registercvar(string name, string value, float flags)
void localcmd(string command,...)
void cvar_set(string name, string value)
string fgets(float fhandle)
void fclose(float fhandle)
void fputs(float fhandle, string s)
float cvar(string name)
float fopen(string filename, float mode)
void bprint(string text,...)
void strunzone(string s)
string ftos(float f)
string strzone(string s)
string argv(float n)
float max(float f,...)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define error
Definition pre.qh:6
float campaign_won
Definition campaign.qc:18
void CampaignPostIntermission()
Definition campaign.qc:239
string campaign_index_var
Definition campaign.qc:19
void CampaignSaveCvar(string cvarname, float value)
Definition campaign.qc:127
float Campaign_Invalid()
Definition campaign.qc:31
void CampaignPostInit()
Definition campaign.qc:100
void CampaignLevelWarp(float n)
Definition campaign.qc:261
void CampaignPreInit()
Definition campaign.qc:49
void CampaignPreIntermission()
Definition campaign.qc:167
float CampaignBailout(string s)
Definition campaign.qc:22
int Campaign_GetLevelNum()
Definition campaign.qc:44
float campaign_level
Definition campaign.qc:17
int autocvar_g_campaign_skill
Definition campaign.qh:8
string autocvar__campaign_name
Definition campaign.qh:5
int autocvar__campaign_index
Definition campaign.qh:4
bool autocvar__campaign_testrun
Definition campaign.qh:3
bool campaign_forcewin
Definition campaign.qh:28
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:50
float checkrules_equality
Definition world.qh:35