]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/compat/quake3.qc
Merge branch 'master' into terencehill/accuracy_shotgun
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / compat / quake3.qc
1 #include "quake3.qh"
2
3 #include <server/defs.qh>
4 #include <server/miscfunctions.qh>
5 #include <server/items.qh>
6 #include <server/resources.qh>
7 #include <common/weapons/_all.qh>
8
9 spawnfunc(target_items);
10
11 //***********************
12 //QUAKE 3 ENTITIES - So people can play quake3 maps with the xonotic weapons
13 //***********************
14
15 // NOTE: for best experience, you need to swap MGs with SGs in the map or it won't have a MG
16
17 // SG -> SG
18 SPAWNFUNC_ITEM(ammo_shells, ITEM_Shells)
19
20 // MG -> MG
21 SPAWNFUNC_ITEM(ammo_bullets, ITEM_Bullets)
22
23 // GL -> Mortar
24 SPAWNFUNC_ITEM(ammo_grenades, ITEM_Rockets)
25
26 // Mines -> Rockets
27 SPAWNFUNC_WEAPON(weapon_prox_launcher, WEP_MINE_LAYER)
28 SPAWNFUNC_ITEM(ammo_mines, ITEM_Rockets)
29
30 // LG -> Lightning
31 SPAWNFUNC_WEAPON(weapon_lightning, WEP_ELECTRO)
32 SPAWNFUNC_ITEM(ammo_lightning, ITEM_Cells)
33
34 // Plasma -> Hagar
35 SPAWNFUNC_WEAPON(weapon_plasmagun, WEP_HAGAR)
36 SPAWNFUNC_ITEM(ammo_cells, ITEM_Rockets)
37
38 // Rail -> Vortex
39 SPAWNFUNC_WEAPON(weapon_railgun, WEP_VORTEX)
40 SPAWNFUNC_ITEM(ammo_slugs, ITEM_Cells)
41
42 // BFG -> Crylink
43 SPAWNFUNC_WEAPON(weapon_bfg, WEP_CRYLINK)
44 SPAWNFUNC_ITEM(ammo_bfg, ITEM_Cells)
45
46 // grappling hook -> hook
47 SPAWNFUNC_WEAPON(weapon_grapplinghook, WEP_HOOK)
48
49 // RL -> RL
50 SPAWNFUNC_ITEM(ammo_rockets, ITEM_Rockets)
51
52 // Armor
53 SPAWNFUNC_ITEM(item_armor_body, ITEM_ArmorMega)
54 SPAWNFUNC_ITEM(item_armor_combat, ITEM_ArmorBig)
55 SPAWNFUNC_ITEM(item_armor_shard, ITEM_ArmorSmall)
56 SPAWNFUNC_ITEM(item_enviro, ITEM_Shield)
57
58 // medkit -> armor (we have no holdables)
59 SPAWNFUNC_ITEM(holdable_medkit, ITEM_ArmorMega)
60
61 // doubler -> strength
62 SPAWNFUNC_ITEM(item_doubler, ITEM_Strength)
63
64 .float wait;
65 .float delay;
66
67 // weapon remove ent from df
68 void target_init_verify(entity this)
69 {
70         entity trigger, targ;
71         for(trigger = NULL; (trigger = find(trigger, classname, "trigger_multiple")); )
72                 for(targ = NULL; (targ = find(targ, targetname, trigger.target)); )
73                         if (targ.classname == "target_init" || targ.classname == "target_give" || targ.classname == "target_items")
74                         {
75                                 trigger.wait = 0;
76                                 trigger.delay = 0;
77                                 targ.wait = 0;
78                                 targ.delay = 0;
79
80                                 //setsize(targ, trigger.mins, trigger.maxs);
81                                 //setorigin(targ, trigger.origin);
82                                 //remove(trigger);
83                         }
84 }
85
86 void target_init_use(entity this, entity actor, entity trigger)
87 {
88         if (!(this.spawnflags & 1))
89         {
90                 SetResourceAmount(actor, RESOURCE_ARMOR, start_armorvalue);
91                 actor.pauserotarmor_finished = time + autocvar_g_balance_pause_armor_rot;
92         }
93
94         if (!(this.spawnflags & 2))
95         {
96                 SetResourceAmount(actor, RESOURCE_HEALTH, start_health);
97                 actor.pauserothealth_finished = time + autocvar_g_balance_pause_health_rot;
98                 actor.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
99         }
100
101         if (!(this.spawnflags & 4))
102         {
103                 SetResourceAmount(actor, RESOURCE_SHELLS, start_ammo_shells);
104                 SetResourceAmount(actor, RESOURCE_BULLETS, start_ammo_nails);
105                 SetResourceAmount(actor, RESOURCE_ROCKETS, start_ammo_rockets);
106                 SetResourceAmount(actor, RESOURCE_CELLS, start_ammo_cells);
107                 SetResourceAmount(actor, RESOURCE_PLASMA, start_ammo_plasma);
108                 SetResourceAmount(actor, RESOURCE_FUEL, start_ammo_fuel);
109
110                 actor.weapons = start_weapons;
111                 if (this.spawnflags & 32)
112                 {
113                         // TODO
114                 }
115         }
116
117         if (!(this.spawnflags & 8))
118         {
119                 actor.strength_finished = 0;
120                 actor.invincible_finished = 0;
121                 STAT(BUFFS, actor) = 0;
122         }
123
124         if (!(this.spawnflags & 16))
125         {
126                 // We don't have holdables.
127         }
128
129         SUB_UseTargets(this, actor, trigger);
130 }
131
132 spawnfunc(target_init)
133 {
134         this.use = target_init_use;
135         InitializeEntity(this, target_init_verify, INITPRIO_FINDTARGET);
136 }
137
138 // weapon give ent from defrag
139 void target_give_init(entity this)
140 {
141         IL_EACH(g_items, it.targetname == this.target,
142         {
143                 if (it.classname == "weapon_devastator") {
144                         this.ammo_rockets += it.count * WEP_CVAR(devastator, ammo);
145                         this.netname = cons(this.netname, "devastator");
146                 }
147                 else if (it.classname == "weapon_vortex") {
148                         this.ammo_cells += it.count * WEP_CVAR_PRI(vortex, ammo); // WEAPONTODO
149                         this.netname = cons(this.netname, "vortex");
150                 }
151                 else if (it.classname == "weapon_electro") {
152                         this.ammo_cells += it.count * WEP_CVAR_PRI(electro, ammo); // WEAPONTODO
153                         this.netname = cons(this.netname, "electro");
154                 }
155                 else if (it.classname == "weapon_hagar") {
156                         this.ammo_rockets += it.count * WEP_CVAR_PRI(hagar, ammo); // WEAPONTODO
157                         this.netname = cons(this.netname, "hagar");
158                 }
159                 else if (it.classname == "weapon_crylink") {
160                         this.ammo_cells += it.count * WEP_CVAR_PRI(crylink, ammo);
161                         this.netname = cons(this.netname, "crylink");
162                 }
163                 else if (it.classname == "weapon_mortar") {
164                         this.ammo_rockets += it.count * WEP_CVAR_PRI(mortar, ammo); // WEAPONTODO
165                         this.netname = cons(this.netname, "mortar");
166                 }
167                 else if (it.classname == "item_armor_mega")
168                         this.armorvalue = 100;
169                 else if (it.classname == "item_health_mega")
170                         this.health = 200;
171                 //remove(it); // removing ents in init functions causes havoc, workaround:
172         setthink(it, SUB_Remove);
173         it.nextthink = time;
174         });
175         this.spawnflags = 2;
176         this.spawnfunc_checked = true;
177         spawnfunc_target_items(this);
178         InitializeEntity(this, target_init_verify, INITPRIO_FINDTARGET);
179 }
180
181 spawnfunc(target_give)
182 {
183         InitializeEntity(this, target_give_init, INITPRIO_FINDTARGET);
184 }
185
186 //spawnfunc(item_flight)       /* handled by buffs mutator */
187 //spawnfunc(item_haste)        /* handled by buffs mutator */
188 //spawnfunc(item_health)       /* handled in t_quake.qc */
189 //spawnfunc(item_health_large) /* handled in t_items.qc */
190 //spawnfunc(item_health_small) /* handled in t_items.qc */
191 //spawnfunc(item_health_mega)  /* handled in t_items.qc */
192 //spawnfunc(item_invis)        /* handled by buffs mutator */
193 //spawnfunc(item_regen)        /* handled by buffs mutator */
194
195 // CTF spawnfuncs handled in mutators/gamemode_ctf.qc now
196
197 .float notteam;
198 .float notsingle;
199 .float notfree;
200 .float notq3a;
201 .float notta;
202 .string gametype;
203 bool DoesQ3ARemoveThisEntity(entity this)
204 {
205         // Q3 style filters (DO NOT USE, THIS IS COMPAT ONLY)
206
207         if(this.notq3a)
208                 if(!teamplay || g_tdm || g_ctf)
209                         return true;
210
211         if(this.notta)
212                 if (!(!teamplay || g_tdm || g_ctf))
213                         return true;
214
215         if(this.notsingle)
216                 if(maxclients == 1)
217                         return true;
218
219         if(this.notteam)
220                 if(teamplay)
221                         return true;
222
223         if(this.notfree)
224                 if(!teamplay)
225                         return true;
226
227         if(this.gametype)
228         {
229                 string gametypename;
230                 // static char *gametypeNames[] = {"ffa", "tournament", "single", "team", "ctf", "oneflag", "obelisk", "harvester", "teamtournament"}
231                 gametypename = "ffa";
232                 if(teamplay)
233                         gametypename = "team";
234                 if(g_ctf)
235                         gametypename = "ctf";
236                 if(maxclients == 1)
237                         gametypename = "single";
238                 // we do not have the other types (oneflag, obelisk, harvester, teamtournament)
239                 if(strstrofs(this.gametype, gametypename, 0) < 0)
240                         return true;
241         }
242
243         return false;
244 }