ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_range.C
Revision: 1.55
Committed: Sat Nov 17 23:40:03 2018 UTC (5 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.54: +1 -0 lines
Log Message:
copyright update 2018

File Contents

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