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