]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/domination.c
Added method 0 which uses two cvars g_maplist and g_maplist_index, please test it.
[divverent/nexuiz.git] / qcsrc / gamec / domination.c
1
2 /*
3 Domination as a plugin for netquake mods
4 by LordHavoc (lordhavoc@ghdigital.com)
5
6 How to add domination points to a mod:
7 1. Add this line to progs.src above world.qc:
8 domination.qc
9 2. Comment out all lines in ClientObituary in client.qc that begin with targ.frags  or attacker.frags.
10 3. Add this above worldspawn in world.qc:
11 void() dom_init;
12 4. Add this line to the end of worldspawn in world.qc:
13 dom_init();
14
15 Note: The only teams who can use dom control points are identified by dom_team entities (if none exist these default to red and blue and use only quake models/sounds).
16 */
17
18 void() dom_spawnteams;
19
20 void() dompointthink =
21 {
22         local entity head;
23         self.nextthink = time + 3;
24         if (!self.goalentity.netname)
25                 return;
26         head = find(head, classname, "player");
27         while (head)
28         {
29                 if (head.team == self.goalentity.team)
30                         head.frags = head.frags + 1;
31                 head = find(head, classname, "player");
32         }
33 };
34
35 void() dompointtouch =
36 {
37         local entity head;
38         if (other.classname != "player")
39                 return;
40         if (other.health < 1)
41                 return;
42         // only valid teams can claim it
43         head = find(world, classname, "dom_team");
44         while (head && head.team != other.team)
45                 head = find(head, classname, "dom_team");
46         if (!head || head.netname == "" || head == self.goalentity)
47                 return;
48
49         self.goalentity = head;
50         self.model = head.mdl;
51         self.modelindex = head.dmg;
52         self.skin = head.skin;
53
54         bprint(head.message);
55         bprint("\n");
56
57         if (head.noise != "")
58                 sound(self, CHAN_BODY, head.noise, 1, ATTN_NORM);
59         if (head.noise1 != "")
60                 sound(self, CHAN_VOICE, head.noise1, 1, ATTN_NONE);
61 };
62
63 /*QUAKED dom_team (0 .5 .8) (-16 -16 -24) (16 16 32)
64 Team declaration for Domination gameplay, this allows you to decide what team
65 names and control point models are used in your map.
66
67 Note: If you use dom_team entities you must define at least 3 and only two
68 can have netname set!  The nameless team owns all control points at start.
69
70 Keys:
71 "netname"
72  Name of the team (for example Red, Blue, Green, Yellow, Life, Death, etc)
73 "cnt"
74  Scoreboard color of the team (for example 4 is red and 13 is blue)
75 "model"
76  Model to use for control points owned by this team (for example
77  "progs/b_g_key.mdl" is a gold keycard, and "progs/b_s_key.mdl" is a silver
78  keycard)
79 "skin"
80  Skin of the model to use (for team skins on a single model)
81 "noise"
82  Sound to play when this team captures a point.
83  (this is a localized sound, like a small alarm or other effect)
84 "noise1"
85  Narrator speech to play when this team captures a point.
86  (this is a global sound, like "Red team has captured a control point")
87 "message"
88  Message to show when a team captures a point
89  (for example "Red team has captured a control point", or
90   "The forces of light have captured a mana well")
91 */
92
93 void() dom_team =
94 {
95         precache_model(self.model);
96         if (self.noise != "")
97                 precache_sound(self.noise);
98         if (self.noise1 != "")
99                 precache_sound(self.noise1);
100         self.classname = "dom_team";
101         setmodel(self, self.model);
102         self.mdl = self.model;
103         self.dmg = self.modelindex;
104         self.model = "";
105         self.modelindex = 0;
106         // this would have to be changed if used in quakeworld
107         self.team = self.cnt + 1;
108 };
109
110 void() dom_controlpoint_setup =
111 {
112         local entity head;
113         // find the dom_team representing unclaimed points
114         head = find(world, classname, "dom_team");
115         while(head && head.netname != "")
116                 head = find(head, classname, "dom_team");
117         if (!head)
118                 objerror("no dom_team with netname \"\" found\n");
119
120         // copy important properties from dom_team entity
121         self.goalentity = head;
122         setmodel(self, head.mdl);
123         self.skin = head.skin;
124
125         self.think = dompointthink;
126         self.nextthink = time;
127         self.touch = dompointtouch;
128         self.solid = SOLID_TRIGGER;
129         setsize(self, '-16 -16 -24', '16 16 32');
130         setorigin(self, self.origin);
131         droptofloor(0, 0);
132 };
133
134 /*QUAKED dom_controlpoint (0 .5 .8) (-16 -16 -24) (16 16 32)
135 Control point for Domination gameplay.
136 */
137 void() dom_controlpoint =
138 {
139         self.think = dom_controlpoint_setup;
140         self.nextthink = time + 0.1;
141 };
142
143 // code from here on is just to support maps that don't have control point and team entities
144 void(string teamname, float teamcolor, string pointmodel, float pointskin, string capsound, string capnarration, string capmessage) dom_spawnteam =
145 {
146         local entity oldself;
147         oldself = self;
148         self = spawn();
149         self.classname = "dom_team";
150         self.netname = teamname;
151         self.cnt = teamcolor;
152         self.model = pointmodel;
153         self.skin = pointskin;
154         self.noise = capsound;
155         self.noise1 = capnarration;
156         self.message = capmessage;
157
158         // this code is identical to dom_team
159         setmodel(self, self.model);
160         self.mdl = self.model;
161         self.dmg = self.modelindex;
162         self.model = "";
163         self.modelindex = 0;
164         // this would have to be changed if used in quakeworld
165         self.team = self.cnt + 1;
166
167         //eprint(self);
168         self = oldself;
169 };
170
171 void(vector org) dom_spawnpoint =
172 {
173         local entity oldself;
174         oldself = self;
175         self = spawn();
176         self.classname = "dom_controlpoint";
177         self.think = dom_controlpoint;
178         self.nextthink = time;
179         self.origin = org;
180         dom_controlpoint();
181         self = oldself;
182 };
183
184 void() dom_spawnteams =
185 {
186         // LordHavoc: edit this if you want to change defaults
187         dom_spawnteam("Red", 4, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
188         dom_spawnteam("Blue", 13, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
189         dom_spawnteam("Green", 3, "models/domination/dom_green.md3", 0, "domination/claim.wav", "", "Green team has captured a control point");
190         dom_spawnteam("Yellow", 12, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
191         dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
192 };
193
194 void() dom_delayedinit =
195 {
196         local entity head;
197         // if no teams are found, spawn defaults
198         if (find(world, classname, "dom_team") == world)
199                 dom_spawnteams();
200         // if no control points are found, spawn defaults
201         if (find(world, classname, "dom_controlpoint") == world)
202         {
203                 // here follow default domination points for each map
204                 /*
205                 if (world.model == "maps/e1m1.bsp")
206                 {
207                         dom_spawnpoint('0 0 0');
208                 }
209                 else
210                 */
211                 {
212                         // if no supported map was found, make every deathmatch spawn a point
213                         head = find(world, classname, "info_player_deathmatch");
214                         while (head)
215                         {
216                                 dom_spawnpoint(head.origin);
217                                 head = find(head, classname, "info_player_deathmatch");
218                         }
219                 }
220         }
221 };
222
223 void() dom_init =
224 {
225         local entity e;
226         // we have to precache default models/sounds even if they might not be
227         // used because worldspawn is executed before any other entities are read,
228         // so we don't even know yet if this map is set up for domination...
229         precache_model("models/domination/dom_red.md3");
230         precache_model("models/domination/dom_blue.md3");
231         precache_model("models/domination/dom_green.md3");
232         precache_model("models/domination/dom_yellow.md3");
233         precache_model("models/domination/dom_unclaimed.md3");
234         precache_sound("domination/claim.wav");
235         e = spawn();
236         e.think = dom_delayedinit;
237         e.nextthink = time + 0.1;
238 };
239