ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_range.C
Revision: 1.28
Committed: Sun Jul 1 05:00:19 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_2, rel-2_3
Changes since 1.27: +10 -11 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# Content
1 /*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 */
23
24 /* This file deals with range related commands (casting, shooting,
25 * throwing, etc.
26 */
27
28 #include <global.h>
29 #include <sproto.h>
30 #include <spells.h>
31 #include <skills.h>
32 #include <commands.h>
33
34 int
35 command_invoke (object *op, char *params)
36 {
37 return command_cast_spell (op, params, 'i');
38 }
39
40 int
41 command_cast (object *op, char *params)
42 {
43 return command_cast_spell (op, params, 'c');
44 }
45
46 int
47 command_prepare (object *op, char *params)
48 {
49 return command_cast_spell (op, params, 'p');
50 }
51
52 /* Shows all spells that op knows. If params is supplied, the must match
53 * that. Given there is more than one skill, we can't supply break
54 * them down to cleric/wizardry.
55 */
56 static void
57 show_matching_spells (object *op, char *params)
58 {
59 object *spell;
60 char spell_sort[NROFREALSPELLS][MAX_BUF], tmp[MAX_BUF], *cp;
61 int num_found = 0, i;
62
63 /* We go and see what spells the player has. We put them
64 * into the spell_sort array so that we can sort them -
65 * we prefix the skill in the name so that the sorting
66 * works better.
67 */
68 for (spell = op->inv; spell; spell = spell->below)
69 {
70 /* If it is a spell, and no params are passed, or they
71 * match the name, process this spell.
72 */
73 if (spell->type == SPELL && (!params || !strncmp (params, spell->name, strlen (params))))
74 {
75 if (spell->path_attuned & op->path_denied)
76 {
77 sprintf (spell_sort[num_found++], "%s:%-22s %3s %3s", spell->skill ? &spell->skill : "generic", &spell->name, "den", "den");
78 }
79 else
80 {
81 sprintf (spell_sort[num_found++],
82 "%s:%-22s %3d %3d", spell->skill ? &spell->skill : "generic",
83 &spell->name, spell->level, SP_level_spellpoint_cost (op, spell, SPELL_HIGHEST));
84 }
85 }
86 }
87
88 if (!num_found)
89 {
90 /* If a matching string was passed along, now try it without that
91 * string. It is odd to do something like 'cast trans',
92 * and it say you have no spells, when really, you do, but just
93 * nothing that matches.
94 */
95 if (params)
96 show_matching_spells (op, NULL);
97 else
98 new_draw_info (NDI_UNIQUE, 0, op, "You know no spells");
99 }
100 else
101 {
102 /* Note in the code below that we make some
103 * presumptions that there will be a colon in the
104 * string. given the code above, this is always
105 * the case.
106 */
107 qsort (spell_sort, num_found, MAX_BUF, (int (*)(const void *, const void *)) std::strcmp);
108 strcpy (tmp, "asdfg"); /* Dummy string so initial compare fails */
109 for (i = 0; i < num_found; i++)
110 {
111 /* Different skill name, so print banner */
112 if (strncmp (tmp, spell_sort[i], strlen (tmp)))
113 {
114 strcpy (tmp, spell_sort[i]);
115 cp = strchr (tmp, ':');
116 *cp = '\0';
117 new_draw_info (NDI_UNIQUE, 0, op, "");
118 new_draw_info_format (NDI_UNIQUE, 0, op, "%s spells %.*s [lvl] [sp]", tmp, 12 - strlen (tmp), " ");
119 }
120 new_draw_info (NDI_UNIQUE, 0, op, strchr (spell_sort[i], ':') + 1);
121 }
122 }
123 }
124
125 /* sets up to cast a spell. op is the caster, params is the spell name,
126 * and command is the first letter of the spell type (c=cast, i=invoke,
127 * p=prepare). Invoke casts a spell immediately, where as cast (and I believe
128 * prepare) just set up the range type.
129 */
130 int
131 command_cast_spell (object *op, char *params, char command)
132 {
133 int castnow = 0;
134 char *cp;
135 object *spob;
136
137 if (command == 'i')
138 castnow = 1;
139
140 /* Remove control of the golem */
141 if (object *golem = op->contr->golem)
142 golem->destroy ();
143
144 if (params)
145 {
146 int spellnumber = 0;
147
148 if ((spellnumber = atoi (params)))
149 for (spob = op->inv; spob && spob->count != spellnumber; spob = spob->below)
150 /* nop */;
151 else
152 spob = lookup_spell_by_name (op, params);
153
154 if (spob && spob->type == SPELL)
155 {
156 /* Now grab any extra data, if there is any. Forward pass
157 * any 'of' delimiter
158 */
159 if (spellnumber)
160 {
161 /* if we passed a number, the options start at the second word */
162 cp = strchr (params, ' ');
163 if (cp)
164 {
165 cp++;
166 if (!strncmp (cp, "of ", 3))
167 cp += 3;
168 }
169 }
170 else if (strlen (params) > strlen (spob->name))
171 {
172 cp = params + strlen (spob->name);
173 *cp = 0;
174 cp++;
175 if (!strncmp (cp, "of ", 3))
176 cp += 3;
177 }
178 else
179 cp = NULL;
180
181 if (!spob->skill)
182 {
183 new_draw_info_format (NDI_UNIQUE, 0, op, "%s is a weird spell, please report it to the dungeon master!", &spob->name);
184 LOG (llevError, "spell without skill found: %s", spob->debug_desc ());
185 return 1;
186 }
187
188 object *skill = find_skill_by_name (op, spob->skill);
189
190 if (!skill)
191 {
192 new_draw_info_format (NDI_UNIQUE, 0, op, "You need the skill %s to cast %s!", &spob->skill, &spob->name);
193 return 1;
194 }
195
196 if (castnow)
197 cast_spell (op, op, op->facing, spob, cp);
198 else
199 {
200 op->change_weapon (op->contr->ranged_ob = spob);
201
202 assign (op->contr->spellparam, cp ? cp : "");
203 new_draw_info_format (NDI_UNIQUE, 0, op, "You ready the spell %s", &spob->name);
204 }
205
206 return 0;
207 } /* else fall through to below and print spells */
208 } /* params supplied */
209
210 /* We get here if cast was given without options or we could not find
211 * the requested spell. List all the spells the player knows.
212 */
213 new_draw_info (NDI_UNIQUE, 0, op, "Cast what spell? Choose one of:");
214 show_matching_spells (op, params);
215
216 return 1;
217 }
218
219 /**************************************************************************/
220
221 void
222 change_spell (object *op, char k)
223 {
224 if (op->contr->combat_ob == op->current_weapon)
225 {
226 if (op->contr->ranged_ob)
227 op->change_weapon (op->contr->ranged_ob);
228 }
229 else if (op->contr->ranged_ob == op->current_weapon)
230 {
231 if (op->contr->combat_ob)
232 op->change_weapon (op->contr->combat_ob);
233 }
234
235 //TODO: maybe switch to golem, if any?
236 }
237
238 int
239 command_rotateshoottype (object *op, char *params)
240 {
241 if (!params)
242 change_spell (op, '+');
243 else
244 change_spell (op, params[0]);
245
246 return 0;
247 }