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