|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00030 #include <global.h> 00031 00042 static int find_spell_byname(object *op, char *params, int options) 00043 { 00044 /* number of spells known by op */ 00045 int numknown; 00046 /* number of spell that is being cast */ 00047 int spnum, match = -1, i; 00048 size_t paramlen = 0; 00049 00050 /* DMs know all spells */ 00051 if (QUERY_FLAG(op, FLAG_WIZ)) 00052 { 00053 numknown = NROFREALSPELLS; 00054 } 00055 else 00056 { 00057 numknown = CONTR(op)->nrofknownspells; 00058 } 00059 00060 for (i = 0; i < numknown; i++) 00061 { 00062 if (QUERY_FLAG(op, FLAG_WIZ)) 00063 { 00064 spnum = i; 00065 } 00066 else 00067 { 00068 spnum = CONTR(op)->known_spells[i]; 00069 } 00070 00071 if (!options) 00072 { 00073 paramlen = strlen(params); 00074 } 00075 00076 if (!strncmp(params, spells[spnum].name, options ? strlen(spells[spnum].name) : paramlen)) 00077 { 00078 /* We already found a match previously - thus params is not 00079 * not unique, so return -2 stating this. */ 00080 if (match >= 0) 00081 { 00082 return -2; 00083 } 00084 else 00085 { 00086 match = spnum; 00087 } 00088 } 00089 } 00090 00091 return match; 00092 } 00093 00099 int command_cast_spell(object *op, char *params) 00100 { 00101 char *cp = NULL; 00102 rangetype orig_rangetype = CONTR(op)->shoottype; 00103 int orig_spn = CONTR(op)->chosen_spell; 00104 /* number of spell that is being cast */ 00105 int spnum = -1, spnum2 = -1, value; 00106 00107 if (!CONTR(op)->nrofknownspells && !QUERY_FLAG(op, FLAG_WIZ)) 00108 { 00109 new_draw_info(0, COLOR_WHITE, op, "You don't know any spells."); 00110 return 0; 00111 } 00112 00113 if (params == NULL) 00114 { 00115 new_draw_info(0, COLOR_WHITE, op, "Cast which spell?"); 00116 return 0; 00117 } 00118 00119 /* This assumes simply that if the name of 00120 * the spell being cast as input by the player is shorter than or 00121 * equal to the length of the spell name, then there is no options 00122 * but if it is longer, then everything after the spell name is 00123 * an option. It determines if the spell name is shorter or 00124 * longer by first iterating through the actual spell names, checking 00125 * to the length of the typed in name. If that fails, then it checks 00126 * to the length of each spell name. If that passes, it assumes that 00127 * anything after the length of the actual spell name is extra options 00128 * typed in by the player (ie: marking rune Hello there) */ 00129 if (((spnum2 = spnum = find_spell_byname(op, params, 0)) < 0) && ((spnum = find_spell_byname(op, params, 1)) >= 0)) 00130 { 00131 params[strlen(spells[spnum].name)] = '\0'; 00132 cp = ¶ms[strlen(spells[spnum].name) + 1]; 00133 00134 if (strncmp(cp, "of ", 3) == 0) 00135 { 00136 cp += 3; 00137 } 00138 } 00139 00140 /* We don't know this spell name */ 00141 if (spnum == -1) 00142 { 00143 new_draw_info_format(0, COLOR_WHITE, op, "You don't know the spell %s.", params); 00144 return 0; 00145 } 00146 00147 CONTR(op)->shoottype = range_magic; 00148 CONTR(op)->chosen_spell = spnum; 00149 00150 if (!check_skill_to_fire(op)) 00151 { 00152 if (!QUERY_FLAG(op, FLAG_WIZ)) 00153 { 00154 CONTR(op)->chosen_spell = orig_spn; 00155 return 0; 00156 } 00157 } 00158 00159 CONTR(op)->chosen_spell = orig_spn; 00160 CONTR(op)->shoottype = orig_rangetype; 00161 00162 /* We still need to wait */ 00163 if (!check_skill_action_time(op, op->chosen_skill)) 00164 { 00165 return 0; 00166 } 00167 00168 value = cast_spell(op, op, op->facing, spnum, 0, CAST_NORMAL, cp); 00169 00170 if (value) 00171 { 00172 CONTR(op)->action_casting = ROUND_TAG + spells[spnum].time; 00173 00174 if (spells[spnum].type == SPELL_TYPE_PRIEST) 00175 { 00176 op->stats.grace -= value; 00177 } 00178 else 00179 { 00180 op->stats.sp -= value; 00181 } 00182 00183 CONTR(op)->action_timer = (float) (CONTR(op)->action_casting - global_round_tag) / (1000000 / MAX_TIME) * 1000.0f; 00184 00185 if (CONTR(op)->last_action_timer > 0) 00186 { 00187 CONTR(op)->action_timer *= -1; 00188 } 00189 } 00190 00191 return 1; 00192 } 00193 00200 int fire_cast_spell(object *op, char *params) 00201 { 00202 char *cp = NULL; 00203 rangetype orig_rangetype = CONTR(op)->shoottype; 00204 int orig_spn = CONTR(op)->chosen_spell; 00205 /* number of spell that is being cast */ 00206 int spnum = -1, spnum2 = -1; 00207 00208 if (!CONTR(op)->nrofknownspells && !QUERY_FLAG(op, FLAG_WIZ)) 00209 { 00210 new_draw_info(0, COLOR_WHITE, op, "You don't know any spells."); 00211 return 0; 00212 } 00213 00214 if (params == NULL) 00215 { 00216 new_draw_info(0, COLOR_WHITE, op, "Cast which spell?"); 00217 return 0; 00218 } 00219 00220 /* This assumes simply that if the name of 00221 * the spell being cast as input by the player is shorter than or 00222 * equal to the length of the spell name, then there is no options 00223 * but if it is longer, then everything after the spell name is 00224 * an option. It determines if the spell name is shorter or 00225 * longer by first iterating through the actual spell names, checking 00226 * to the length of the typed in name. If that fails, then it checks 00227 * to the length of each spell name. If that passes, it assumes that 00228 * anything after the length of the actual spell name is extra options 00229 * typed in by the player (ie: marking rune Hello there) */ 00230 if (((spnum2 = spnum = find_spell_byname(op, params, 0)) < 0) && ((spnum = find_spell_byname(op, params, 1)) >= 0)) 00231 { 00232 params[strlen(spells[spnum].name)] = '\0'; 00233 cp = ¶ms[strlen(spells[spnum].name) + 1]; 00234 00235 if (strncmp(cp, "of ", 3) == 0) 00236 { 00237 cp += 3; 00238 } 00239 } 00240 00241 /* We don't know this spell name */ 00242 if (spnum == -1) 00243 { 00244 new_draw_info_format(0, COLOR_WHITE, op, "You don't know the spell %s.", params); 00245 return 0; 00246 } 00247 00248 CONTR(op)->shoottype = range_magic; 00249 CONTR(op)->chosen_spell = spnum; 00250 00251 if (!QUERY_FLAG(op, FLAG_WIZ)) 00252 { 00253 if (!check_skill_to_fire(op)) 00254 { 00255 CONTR(op)->chosen_spell = orig_spn; 00256 CONTR(op)->shoottype = orig_rangetype; 00257 return 0; 00258 } 00259 } 00260 00261 return 1; 00262 } 00263 00271 int legal_range(object *op, int r) 00272 { 00273 int i; 00274 object *tmp; 00275 00276 switch (r) 00277 { 00278 /* "Nothing" is always legal */ 00279 case range_none: 00280 return 1; 00281 00282 /* Bows */ 00283 case range_bow: 00284 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 00285 { 00286 if (tmp->type == BOW && QUERY_FLAG(tmp, FLAG_APPLIED)) 00287 { 00288 return 1; 00289 } 00290 } 00291 00292 return 0; 00293 00294 /* Cast spells */ 00295 case range_magic: 00296 if (CONTR(op)->nrofknownspells == 0) 00297 { 00298 return 0; 00299 } 00300 00301 for (i = 0; i < CONTR(op)->nrofknownspells; i++) 00302 { 00303 if (CONTR(op)->known_spells[i] == CONTR(op)->chosen_spell) 00304 { 00305 return 1; 00306 } 00307 } 00308 00309 CONTR(op)->chosen_spell = CONTR(op)->known_spells[0]; 00310 return 1; 00311 00312 /* Use wands */ 00313 case range_wand: 00314 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 00315 { 00316 if (tmp->type == WAND && QUERY_FLAG(tmp, FLAG_APPLIED)) 00317 { 00318 return 1; 00319 } 00320 } 00321 00322 return 0; 00323 00324 /* Rod */ 00325 case range_rod: 00326 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 00327 { 00328 if (tmp->type == ROD && QUERY_FLAG(tmp, FLAG_APPLIED)) 00329 { 00330 return 1; 00331 } 00332 } 00333 00334 return 0; 00335 00336 /* Horn */ 00337 case range_horn: 00338 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 00339 { 00340 if (tmp->type == HORN && QUERY_FLAG(tmp, FLAG_APPLIED)) 00341 { 00342 return 1; 00343 } 00344 } 00345 00346 return 0; 00347 00348 /* Use scrolls */ 00349 case range_scroll: 00350 return 0; 00351 00352 case range_skill: 00353 if (op->chosen_skill) 00354 { 00355 return 1; 00356 } 00357 00358 return 0; 00359 } 00360 00361 return 0; 00362 }
1.7.4