ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_range.C
(Generate patch)

Comparing deliantra/server/server/c_range.C (file contents):
Revision 1.2 by root, Tue Aug 29 08:01:37 2006 UTC vs.
Revision 1.12 by root, Tue Dec 12 21:39:57 2006 UTC

1/*
2 * static char *rcsid_c_range_c =
3 * "$Id: c_range.C,v 1.2 2006/08/29 08:01:37 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29/* This file deals with range related commands (casting, shooting, 24/* This file deals with range related commands (casting, shooting,
30 * throwing, etc. 25 * throwing, etc.
31 */ 26 */
32 27
33#include <global.h> 28#include <global.h>
34#ifndef __CEXTRACT__ 29#ifndef __CEXTRACT__
35#include <sproto.h> 30# include <sproto.h>
36#endif 31#endif
37#include <spells.h> 32#include <spells.h>
38#include <skills.h> 33#include <skills.h>
39#include <newclient.h> 34#include <newclient.h>
40#include <commands.h> 35#include <commands.h>
41 36
42 37int
43int command_invoke(object *op, char *params) 38command_invoke (object *op, char *params)
44{ 39{
45 return command_cast_spell(op, params, 'i'); 40 return command_cast_spell (op, params, 'i');
46} 41}
47 42
43int
48int command_cast(object *op, char *params) 44command_cast (object *op, char *params)
49{ 45{
50 return command_cast_spell(op, params, 'c'); 46 return command_cast_spell (op, params, 'c');
51} 47}
52 48
49int
53int command_prepare(object *op, char *params) 50command_prepare (object *op, char *params)
54{ 51{
55 return command_cast_spell(op, params, 'p'); 52 return command_cast_spell (op, params, 'p');
56} 53}
57 54
58/* Shows all spells that op knows. If params is supplied, the must match 55/* Shows all spells that op knows. If params is supplied, the must match
59 * that. Given there is more than one skill, we can't supply break 56 * that. Given there is more than one skill, we can't supply break
60 * them down to cleric/wizardry. 57 * them down to cleric/wizardry.
61 */ 58 */
59static void
62static void show_matching_spells(object *op, char *params) 60show_matching_spells (object *op, char *params)
63{ 61{
64 object *spell; 62 object *spell;
65 char spell_sort[NROFREALSPELLS][MAX_BUF], tmp[MAX_BUF], *cp; 63 char spell_sort[NROFREALSPELLS][MAX_BUF], tmp[MAX_BUF], *cp;
66 int num_found=0, i; 64 int num_found = 0, i;
67 65
68 /* We go and see what spells the player has. We put them 66 /* We go and see what spells the player has. We put them
69 * into the spell_sort array so that we can sort them - 67 * into the spell_sort array so that we can sort them -
70 * we prefix the skill in the name so that the sorting 68 * we prefix the skill in the name so that the sorting
71 * works better. 69 * works better.
72 */ 70 */
73 for (spell=op->inv; spell!=NULL; spell=spell->below) { 71 for (spell = op->inv; spell != NULL; spell = spell->below)
72 {
74 /* If it is a spell, and no params are passed, or they 73 /* If it is a spell, and no params are passed, or they
75 * match the name, process this spell. 74 * match the name, process this spell.
76 */ 75 */
77 if (spell->type == SPELL &&
78 (!params || !strncmp(params, spell->name, strlen(params)))) { 76 if (spell->type == SPELL && (!params || !strncmp (params, spell->name, strlen (params))))
77 {
79 if (spell->path_attuned & op->path_denied) { 78 if (spell->path_attuned & op->path_denied)
79 {
80 sprintf (spell_sort[num_found++], "%s:%-22s %3s %3s", spell->skill ? &spell->skill : "generic", &spell->name, "den", "den");
81 }
82 else
83 {
80 sprintf(spell_sort[num_found++], 84 sprintf (spell_sort[num_found++],
81 "%s:%-22s %3s %3s", spell->skill?spell->skill:"generic",
82 spell->name, "den", "den");
83 } else {
84 sprintf(spell_sort[num_found++],
85 "%s:%-22s %3d %3d", spell->skill?spell->skill:"generic", 85 "%s:%-22s %3d %3d", spell->skill ? &spell->skill : "generic",
86 spell->name, spell->level,
87 SP_level_spellpoint_cost(op,spell, SPELL_HIGHEST)); 86 &spell->name, spell->level, SP_level_spellpoint_cost (op, spell, SPELL_HIGHEST));
88 } 87 }
89 } 88 }
90 } 89 }
91 if (!num_found) { 90 if (!num_found)
91 {
92 /* If a matching string was passed along, now try it without that 92 /* If a matching string was passed along, now try it without that
93 * string. It is odd to do something like 'cast trans', 93 * string. It is odd to do something like 'cast trans',
94 * and it say you have no spells, when really, you do, but just 94 * and it say you have no spells, when really, you do, but just
95 * nothing that matches. 95 * nothing that matches.
96 */ 96 */
97 if (params) 97 if (params)
98 show_matching_spells(op, NULL); 98 show_matching_spells (op, NULL);
99 else 99 else
100 new_draw_info(NDI_UNIQUE, 0, op, "You know no spells"); 100 new_draw_info (NDI_UNIQUE, 0, op, "You know no spells");
101 } else { 101 }
102 else
103 {
102 /* Note in the code below that we make some 104 /* Note in the code below that we make some
103 * presumptions that there will be a colon in the 105 * presumptions that there will be a colon in the
104 * string. given the code above, this is always 106 * string. given the code above, this is always
105 * the case. 107 * the case.
106 */ 108 */
107 qsort(spell_sort, num_found, MAX_BUF, (int (*)(const void*, const void*))strcmp); 109 qsort (spell_sort, num_found, MAX_BUF, (int (*)(const void *, const void *)) strcmp);
108 strcpy(tmp,"asdfg"); /* Dummy string so initial compare fails */ 110 strcpy (tmp, "asdfg"); /* Dummy string so initial compare fails */
109 for (i=0; i<num_found; i++) { 111 for (i = 0; i < num_found; i++)
112 {
110 /* Different skill name, so print banner */ 113 /* Different skill name, so print banner */
111 if (strncmp(tmp, spell_sort[i], strlen(tmp))) { 114 if (strncmp (tmp, spell_sort[i], strlen (tmp)))
115 {
112 strcpy(tmp, spell_sort[i]); 116 strcpy (tmp, spell_sort[i]);
113 cp = strchr(tmp, ':'); 117 cp = strchr (tmp, ':');
114 *cp = '\0'; 118 *cp = '\0';
115 new_draw_info(NDI_UNIQUE, 0, op, ""); 119 new_draw_info (NDI_UNIQUE, 0, op, "");
116 new_draw_info_format(NDI_UNIQUE, 0,op,"%s spells %.*s [lvl] [sp]", 120 new_draw_info_format (NDI_UNIQUE, 0, op, "%s spells %.*s [lvl] [sp]", tmp, 12 - strlen (tmp), " ");
117 tmp, 12-strlen(tmp), " ");
118 } 121 }
119 new_draw_info(NDI_UNIQUE, 0, op, strchr(spell_sort[i], ':') + 1); 122 new_draw_info (NDI_UNIQUE, 0, op, strchr (spell_sort[i], ':') + 1);
120 } 123 }
121 } 124 }
122} 125}
123
124
125 126
126/* sets up to cast a spell. op is the caster, params is the spell name, 127/* sets up to cast a spell. op is the caster, params is the spell name,
127 * and command is the first letter of the spell type (c=cast, i=invoke, 128 * and command is the first letter of the spell type (c=cast, i=invoke,
128 * p=prepare). Invoke casts a spell immediately, where as cast (and I believe 129 * p=prepare). Invoke casts a spell immediately, where as cast (and I believe
129 * prepare) just set up the range type. 130 * prepare) just set up the range type.
130 */ 131 */
131 132int
132int command_cast_spell (object *op, char *params, char command) 133command_cast_spell (object *op, char *params, char command)
133{ 134{
134 int castnow=0; 135 int castnow = 0;
135 char *cp; 136 char *cp;
136 object *spob; 137 object *spob;
137 138
138 if (command=='i') castnow = 1; 139 if (command == 'i')
140 castnow = 1;
139 141
140 /* Remove control of the golem */ 142 /* Remove control of the golem */
141 if(op->contr->ranges[range_golem]!=NULL) { 143 if (op->contr->ranges[range_golem])
142 if (op->contr->golem_count == op->contr->ranges[range_golem]->count) { 144 {
143 remove_friendly_object(op->contr->ranges[range_golem]); 145 op->contr->ranges[range_golem]->destroy ();
144 remove_ob(op->contr->ranges[range_golem]);
145 free_object(op->contr->ranges[range_golem]);
146 }
147 op->contr->ranges[range_golem]=NULL; 146 op->contr->ranges[range_golem] = 0;
148 op->contr->golem_count = 0;
149 } 147 }
150 148
151 if(params!=NULL) { 149 if (params != NULL)
150 {
152 int spellnumber = 0; 151 int spellnumber = 0;
152
153 if (spellnumber = atoi(params)) 153 if ((spellnumber = atoi (params)))
154 for (spob = op->inv; spob && spob->count != spellnumber; spob=spob->below); 154 for (spob = op->inv; spob && spob->count != spellnumber; spob = spob->below)
155 /* nop */;
156 else
155 else spob = lookup_spell_by_name(op, params); 157 spob = lookup_spell_by_name (op, params);
156 158
157 if (spob && spob->type == SPELL) { 159 if (spob && spob->type == SPELL)
160 {
158 /* Now grab any extra data, if there is any. Forward pass 161 /* Now grab any extra data, if there is any. Forward pass
159 * any 'of' delimiter 162 * any 'of' delimiter
160 */ 163 */
161 if (spellnumber) { 164 if (spellnumber)
165 {
162 /* if we passed a number, the options start at the second word */ 166 /* if we passed a number, the options start at the second word */
163 cp = strchr(params, ' '); 167 cp = strchr (params, ' ');
164 if (cp) { 168 if (cp)
169 {
165 cp++; 170 cp++;
166 if (!strncmp(cp, "of ", 3)) cp+=3; 171 if (!strncmp (cp, "of ", 3))
172 cp += 3;
167 } 173 }
168 } 174 }
169 else if (strlen(params) > strlen(spob->name)) { 175 else if (strlen (params) > (size_t) strlen (spob->name))
176 {
170 cp = params + strlen(spob->name); 177 cp = params + strlen (spob->name);
171 *cp = 0; 178 *cp = 0;
172 cp++; 179 cp++;
173 if (!strncmp(cp, "of ", 3)) cp+=3; 180 if (!strncmp (cp, "of ", 3))
181 cp += 3;
182 }
174 } else 183 else
175 cp = NULL; 184 cp = NULL;
176 185
177 if (spob->skill && !find_skill_by_name(op, spob->skill)) { 186 if (spob->skill && !find_skill_by_name (op, spob->skill))
178 new_draw_info_format(NDI_UNIQUE, 0, op, 187 {
179 "You need the skill %s to cast %s!", 188 new_draw_info_format (NDI_UNIQUE, 0, op, "You need the skill %s to cast %s!", &spob->skill, &spob->name);
180 spob->skill, spob->name);
181 return 1; 189 return 1;
190 }
191
192 if (castnow)
193 cast_spell (op, op, op->facing, spob, cp);
194 else
182 } 195 {
183
184 if (castnow) {
185 cast_spell(op,op,op->facing,spob,cp);
186 } else {
187 op->contr->ranges[range_magic] = spob; 196 op->contr->ranges[range_magic] = spob;
188 op->contr->shoottype = range_magic; 197 op->contr->shoottype = range_magic;
189 if(cp != NULL) { 198 assign (op->contr->spellparam, cp ? cp : "");
190 strncpy(op->contr->spellparam, cp, MAX_BUF); 199 new_draw_info_format (NDI_UNIQUE, 0, op, "You ready the spell %s", &spob->name);
191 op->contr->spellparam[MAX_BUF-1] = '\0';
192 } else {
193 op->contr->spellparam[0] = '\0';
194 } 200 }
195 new_draw_info_format(NDI_UNIQUE, 0, op, 201
196 "You ready the spell %s", spob->name);
197 }
198 return 0; 202 return 0;
199 } /* else fall through to below and print spells */ 203 } /* else fall through to below and print spells */
200 } /* params supplied */ 204 } /* params supplied */
201 205
202 /* We get here if cast was given without options or we could not find 206 /* We get here if cast was given without options or we could not find
203 * the requested spell. List all the spells the player knows. 207 * the requested spell. List all the spells the player knows.
204 */ 208 */
205 new_draw_info(NDI_UNIQUE, 0,op,"Cast what spell? Choose one of:"); 209 new_draw_info (NDI_UNIQUE, 0, op, "Cast what spell? Choose one of:");
206 show_matching_spells(op, params); 210 show_matching_spells (op, params);
207 return 1; 211 return 1;
208} 212}
209 213
210/**************************************************************************/ 214/**************************************************************************/
211 215
212/* Returns TRUE if the range specified (int r) is legal - that is, 216/* Returns TRUE if the range specified (int r) is legal - that is,
214 * return 0 if there is no item of that range type that is usable. 218 * return 0 if there is no item of that range type that is usable.
215 * This function could probably be simplified, eg, everything 219 * This function could probably be simplified, eg, everything
216 * should index into the ranges[] array. 220 * should index into the ranges[] array.
217 */ 221 */
218 222
223int
219int legal_range(object *op,int r) { 224legal_range (object *op, int r)
225{
220 226
221 switch(r) { 227 switch (r)
228 {
222 case range_none: /* "Nothing" is always legal */ 229 case range_none: /* "Nothing" is always legal */
223 return 1; 230 return 1;
231
224 case range_bow: 232 case range_bow:
225 case range_misc: 233 case range_misc:
226 case range_magic: /* cast spells */ 234 case range_magic: /* cast spells */
227 if (op->contr->ranges[r]) return 1; 235 return !!op->contr->ranges[r];
228 else return 0;
229 236
230 case range_golem: /* Use scrolls */ 237 case range_golem: /* Use scrolls */
231 if (op->contr->ranges[range_golem] && 238 return !!op->contr->ranges[range_golem];
232 op->contr->ranges[range_golem]->count == op->contr->golem_count)
233 return 1;
234 else
235 return 0;
236 239
237 case range_skill: 240 case range_skill:
238 if (op->chosen_skill) 241 return !!op->chosen_skill;
239 return 1;
240 else
241 return 0;
242 } 242 }
243
243 /* No match above, must not be valid */ 244 /* No match above, must not be valid */
244 return 0; 245 return 0;
245} 246}
246 247
248void
247void change_spell(object *op,char k) { 249change_spell (object *op, char k)
250{
248 251
252 do
249 do { 253 {
250 op->contr->shoottype = (rangetype) (op->contr->shoottype + ((k == '+') ? 1 : -1)); 254 op->contr->shoottype = (rangetype) (op->contr->shoottype + ((k == '+') ? 1 : -1));
251 if(op->contr->shoottype >= range_size) 255 if (op->contr->shoottype >= range_size)
252 op->contr->shoottype = range_none; 256 op->contr->shoottype = range_none;
253 else if (op->contr->shoottype <= range_bottom) 257 else if (op->contr->shoottype <= range_bottom)
254 op->contr->shoottype = (rangetype)(range_size-1); 258 op->contr->shoottype = (rangetype) (range_size - 1);
259 }
255 } while (!legal_range(op,op->contr->shoottype)); 260 while (!legal_range (op, op->contr->shoottype));
256 261
257 /* Legal range has already checked that we have an appropriate item 262 /* Legal range has already checked that we have an appropriate item
258 * that uses the slot, so we don't need to be too careful about 263 * that uses the slot, so we don't need to be too careful about
259 * checking the status of the object. 264 * checking the status of the object.
260 */ 265 */
261 switch(op->contr->shoottype) { 266 switch (op->contr->shoottype)
267 {
262 case range_none: 268 case range_none:
263 new_draw_info(NDI_UNIQUE, 0,op, "No ranged attack chosen."); 269 new_draw_info (NDI_UNIQUE, 0, op, "No ranged attack chosen.");
264 break; 270 break;
265 271
266 case range_golem: 272 case range_golem:
267 new_draw_info(NDI_UNIQUE, 0,op, "You regain control of your golem."); 273 new_draw_info (NDI_UNIQUE, 0, op, "You regain control of your golem.");
268 break; 274 break;
269 275
270 case range_bow: 276 case range_bow:
271 new_draw_info_format(NDI_UNIQUE, 0,op, "Switched to %s and %s.", query_name(op->contr->ranges[range_bow]), 277 new_draw_info_format (NDI_UNIQUE, 0, op, "Switched to %s and %s.", query_name (op->contr->ranges[range_bow]),
272 op->contr->ranges[range_bow]->race ? op->contr->ranges[range_bow]->race : "nothing"); 278 op->contr->ranges[range_bow]->race ? &op->contr->ranges[range_bow]->race : "nothing");
273 break; 279 break;
274 280
275 case range_magic: 281 case range_magic:
276 new_draw_info_format(NDI_UNIQUE, 0,op,"Switched to spells (%s).", 282 new_draw_info_format (NDI_UNIQUE, 0, op, "Switched to spells (%s).", &op->contr->ranges[range_magic]->name);
277 op->contr->ranges[range_magic]->name);
278 break; 283 break;
279 284
280 case range_misc: 285 case range_misc:
281 new_draw_info_format(NDI_UNIQUE, 0,op, "Switched to %s.", query_base_name(op->contr->ranges[range_misc], 0)); 286 new_draw_info_format (NDI_UNIQUE, 0, op, "Switched to %s.", query_base_name (op->contr->ranges[range_misc], 0));
282 break; 287 break;
283 288
284 case range_skill: 289 case range_skill:
285 new_draw_info_format(NDI_UNIQUE, 0,op, "Switched to skill: %s", op->chosen_skill ? 290 new_draw_info_format (NDI_UNIQUE, 0, op, "Switched to skill: %s", op->chosen_skill ? &op->chosen_skill->name : "none");
286 op->chosen_skill->name : "none");
287 break; 291 break;
288 292
289 default: 293 default:
290 break; 294 break;
291 } 295 }
292} 296}
293 297
294 298
299int
295int command_rotateshoottype (object *op, char *params) 300command_rotateshoottype (object *op, char *params)
296{ 301{
297 if (!params) 302 if (!params)
298 change_spell(op,'+'); 303 change_spell (op, '+');
299 else 304 else
300 change_spell(op, params[0]); 305 change_spell (op, params[0]);
301 return 0; 306 return 0;
302} 307}
303

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines