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