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

# User Rev Content
1 elmex 1.1 /*
2 root 1.27 * 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 root 1.28 * 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 root 1.27 *
13 root 1.28 * 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 root 1.27 *
18 root 1.28 * 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 root 1.27 *
21     * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 pippijn 1.15 */
23 elmex 1.1
24     /* This file deals with range related commands (casting, shooting,
25     * throwing, etc.
26     */
27    
28     #include <global.h>
29 root 1.13 #include <sproto.h>
30 elmex 1.1 #include <spells.h>
31     #include <skills.h>
32     #include <commands.h>
33    
34 root 1.5 int
35     command_invoke (object *op, char *params)
36 elmex 1.1 {
37 root 1.5 return command_cast_spell (op, params, 'i');
38 elmex 1.1 }
39    
40 root 1.5 int
41     command_cast (object *op, char *params)
42 elmex 1.1 {
43 root 1.5 return command_cast_spell (op, params, 'c');
44 elmex 1.1 }
45    
46 root 1.5 int
47     command_prepare (object *op, char *params)
48 elmex 1.1 {
49 root 1.5 return command_cast_spell (op, params, 'p');
50 elmex 1.1 }
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 root 1.5 static void
57     show_matching_spells (object *op, char *params)
58 elmex 1.1 {
59 root 1.5 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 root 1.19 for (spell = op->inv; spell; spell = spell->below)
69 root 1.5 {
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 root 1.2 }
85     }
86 elmex 1.1 }
87 root 1.19
88 root 1.5 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 root 1.16 qsort (spell_sort, num_found, MAX_BUF, (int (*)(const void *, const void *)) std::strcmp);
108 root 1.5 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 root 1.2 }
120 root 1.5 new_draw_info (NDI_UNIQUE, 0, op, strchr (spell_sort[i], ':') + 1);
121 root 1.2 }
122 elmex 1.1 }
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 root 1.5 int
131     command_cast_spell (object *op, char *params, char command)
132 elmex 1.1 {
133 root 1.5 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 root 1.20 if (object *golem = op->contr->golem)
142 root 1.18 golem->destroy ();
143 elmex 1.1
144 root 1.18 if (params)
145 root 1.5 {
146     int spellnumber = 0;
147    
148     if ((spellnumber = atoi (params)))
149 root 1.9 for (spob = op->inv; spob && spob->count != spellnumber; spob = spob->below)
150 root 1.6 /* nop */;
151 root 1.5 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 root 1.2 }
169     }
170 root 1.20 else if (strlen (params) > strlen (spob->name))
171 root 1.5 {
172     cp = params + strlen (spob->name);
173     *cp = 0;
174     cp++;
175     if (!strncmp (cp, "of ", 3))
176     cp += 3;
177 root 1.2 }
178 root 1.5 else
179     cp = NULL;
180    
181 root 1.20 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 root 1.5 {
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 root 1.6 cast_spell (op, op, op->facing, spob, cp);
198 root 1.5 else
199     {
200 root 1.26 op->change_weapon (op->contr->ranged_ob = spob);
201 root 1.20
202 root 1.7 assign (op->contr->spellparam, cp ? cp : "");
203 root 1.5 new_draw_info_format (NDI_UNIQUE, 0, op, "You ready the spell %s", &spob->name);
204 root 1.2 }
205 root 1.6
206 root 1.5 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 root 1.22 new_draw_info (NDI_UNIQUE, 0, op, "Cast what spell? Choose one of:");
214 root 1.5 show_matching_spells (op, params);
215 root 1.22
216 root 1.5 return 1;
217 elmex 1.1 }
218    
219     /**************************************************************************/
220    
221 root 1.5 void
222     change_spell (object *op, char k)
223     {
224 root 1.23 if (op->contr->combat_ob == op->current_weapon)
225     {
226     if (op->contr->ranged_ob)
227 root 1.25 op->change_weapon (op->contr->ranged_ob);
228 root 1.23 }
229     else if (op->contr->ranged_ob == op->current_weapon)
230     {
231     if (op->contr->combat_ob)
232 root 1.25 op->change_weapon (op->contr->combat_ob);
233 root 1.23 }
234    
235 root 1.20 //TODO: maybe switch to golem, if any?
236 elmex 1.1 }
237    
238 root 1.5 int
239     command_rotateshoottype (object *op, char *params)
240 elmex 1.1 {
241     if (!params)
242 root 1.5 change_spell (op, '+');
243 elmex 1.1 else
244 root 1.5 change_spell (op, params[0]);
245 root 1.19
246 elmex 1.1 return 0;
247     }