--- deliantra/server/server/spell_attack.C 2010/01/19 16:13:05 1.95 +++ deliantra/server/server/spell_attack.C 2016/11/16 22:14:06 1.113 @@ -1,24 +1,24 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. - * - * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team - * Copyright (©) 2002-2003,2007 Mark Wedel & Crossfire Development Team - * Copyright (©) 1992,2007 Frank Tore Johansen - * + * + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 2002-2003 Mark Wedel & Crossfire Development Team + * Copyright (©) 1992 Frank Tore Johansen + * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the Affero GNU General Public License * and the GNU General Public License along with this program. If not, see * . - * + * * The authors can be reached via e-mail to */ @@ -61,7 +61,7 @@ int num_sections = 1; /* don't move DM */ - if (QUERY_FLAG (tmp, FLAG_WIZ)) + if (tmp->flag [FLAG_WIZ]) return; /* don't move parts of objects */ @@ -69,7 +69,7 @@ continue; /* don't move floors or immobile objects */ - if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) || (!QUERY_FLAG (tmp, FLAG_ALIVE) && QUERY_FLAG (tmp, FLAG_NO_PICK))) + if (tmp->flag [FLAG_IS_FLOOR] || (!tmp->flag [FLAG_ALIVE] && tmp->flag [FLAG_NO_PICK])) continue; /* count the object's sections */ @@ -95,7 +95,7 @@ * I don't see us doing anything useful with that information * right now. */ - move_object (tmp, absdir (op->stats.sp)); + tmp->move (absdir (op->stats.sp)); } } @@ -196,7 +196,7 @@ */ if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)) || ((mflags & P_IS_ALIVE) && reflwall (m, x, y, op))) { - if (!QUERY_FLAG (op, FLAG_REFLECTING)) + if (!op->flag [FLAG_REFLECTING]) return; /* Since walls don't run diagonal, if the bolt is in @@ -296,7 +296,7 @@ tmp->stats.Con = spob->stats.Con; tmp->direction = dir; - if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) + if (tmp->flag [FLAG_IS_TURNABLE]) SET_ANIMATION (tmp, dir); tmp->set_owner (op); @@ -318,7 +318,7 @@ if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) { - if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) + if (!tmp->flag [FLAG_REFLECTING]) { tmp->drop_and_destroy (); return 0; @@ -523,14 +523,14 @@ for (tmp = op->ms ().bot; tmp; tmp = tmp->above) { - if (QUERY_FLAG (tmp, FLAG_ALIVE)) + if (tmp->flag [FLAG_ALIVE]) { dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); // TODO: can't understand the following if's if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) { - if (!QUERY_FLAG (op, FLAG_REMOVED)) + if (!op->flag [FLAG_REMOVED]) { op->destroy (); return; @@ -642,7 +642,7 @@ tmp->dam_modifier = spob->stats.food + SP_level_dam_adjust (caster, spob); tmp->direction = dir; - if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) + if (tmp->flag [FLAG_IS_TURNABLE]) SET_ANIMATION (tmp, dir); tmp->set_owner (op); @@ -677,7 +677,7 @@ if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) { - if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) + if (!tmp->flag [FLAG_REFLECTING]) { tmp->destroy (); return 0; @@ -731,7 +731,7 @@ } /* lava saves it's life, but not yours :) */ - if (QUERY_FLAG (op, FLAG_LIFESAVE)) + if (op->flag [FLAG_LIFESAVE]) { hit_map (op, 0, op->attacktype, 0); return; @@ -822,9 +822,9 @@ if (!spell->other_arch) return 0; - if (op->type == PLAYER && QUERY_FLAG (op, FLAG_UNDEAD) && op->attacktype & AT_TURN_UNDEAD) + if (op->type == PLAYER && op->flag [FLAG_UNDEAD] && op->attacktype & AT_TURN_UNDEAD) { - new_draw_info (NDI_UNIQUE, 0, op, "Your undead nature prevents you from turning undead!"); + op->failmsg ("Your undead nature prevents you from turning undead!"); return 0; } @@ -998,7 +998,7 @@ if (op->skill && op->skill != tmp->skill) tmp->skill = op->skill; - if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) + if (tmp->flag [FLAG_IS_TURNABLE]) SET_ANIMATION (tmp, i); op->map->insert (tmp, op->x + freearr_x[i], op->y + freearr_x[i], op); @@ -1027,7 +1027,7 @@ { if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK)) { - new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); + op->failmsg ("There is something in the way."); return 0; } } @@ -1091,14 +1091,14 @@ if (mflags & P_IS_ALIVE) for (target = GET_MAP_OB (mp, x, y); target; target = target->above) - if (QUERY_FLAG (target, FLAG_MONSTER)) + if (target->flag [FLAG_MONSTER]) return target; } return NULL; } -/* cast_smite_arch() - the priest points to a creature and causes +/* cast_smite_spell() - the priest points to a creature and causes * a 'godly curse' to decend. * usual params - * op = player @@ -1111,9 +1111,7 @@ { object *effect, *target; object *god = find_god (determine_god (op)); - int range; - range = spell->range + SP_level_range_adjust (caster, spell); target = get_pointed_target (op, dir, 50, spell->stats.grace ? SPELL_GRACE : SPELL_MANA); /* Bunch of conditions for casting this spell. Note that only @@ -1131,7 +1129,7 @@ || (god && target->title == god->name) || (god && target->race.contains (god->race))) { - new_draw_info (NDI_UNIQUE, 0, op, "Your request is unheeded."); + op->failmsg ("Your request is unheeded."); return 0; } @@ -1149,7 +1147,7 @@ new_draw_info_format (NDI_UNIQUE, 0, op, "%s answers your call!", (const char *)determine_god (op)); else { - new_draw_info (NDI_UNIQUE, 0, op, "Your request is ignored."); + op->failmsg ("Your request is ignored."); return 0; } } @@ -1163,7 +1161,7 @@ effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell); /* casting death spells at undead isn't a good thing */ - if (QUERY_FLAG (target, FLAG_UNDEAD)) + if (target->flag [FLAG_UNDEAD]) { if (random_roll (0, 2, op, PREFER_LOW)) { @@ -1266,10 +1264,10 @@ if (op->path_denied & PATH_LIGHT) return 0; - object *tmp = get_archetype (FORCE_NAME); - tmp->speed = 0.01; + object *tmp = archetype::get (FORCE_NAME); + tmp->set_speed (0.01); tmp->stats.food = time; - SET_FLAG (tmp, FLAG_IS_USED_UP); + tmp->set_flag (FLAG_IS_USED_UP); tmp->set_glow_radius (min (MAX_LIGHT_RADIUS, radius)); tmp = insert_ob_in_ob (tmp, op); @@ -1288,21 +1286,8 @@ bool friendly = op->flag [FLAG_FRIENDLY] || op->is_player (); - /* destruction doesn't use another spell object, so we need - * update op's skill pointer so that exp is properly awarded. - */ - const shstr skill = op->skill; - - if (caster == op) - op->skill = spell_ob->skill; - else if (caster->skill) - op->skill = caster->skill; - else - op->skill = 0; - - op->change_skill (find_skill_by_name (op, op->skill)); - - unordered_mapwalk (op, -range, -range, range, range) + dynbuf buf; + unordered_mapwalk (buf, op, -range, -range, range, range) { mapspace &ms = m->at (nx, ny); @@ -1335,7 +1320,6 @@ } } - op->skill = skill; return 1; } @@ -1353,7 +1337,7 @@ tmp = get_pointed_target (op, (dir == 0) ? op->direction : dir, spell_ob->range, SPELL_GRACE); if (!tmp) { - new_draw_info (NDI_UNIQUE, 0, op, "There is no one in that direction to curse."); + op->failmsg ("There is no one in that direction to curse."); return 0; } @@ -1378,7 +1362,7 @@ if (!force) { - force = get_archetype (FORCE_NAME); + force = archetype::get (FORCE_NAME); force->subtype = FORCE_CHANGE_ABILITY; if (spell_ob->race) @@ -1406,9 +1390,9 @@ } force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; - force->speed = 1.f; force->speed_left = -1.f; - SET_FLAG (force, FLAG_APPLIED); + force->set_speed (1.f); + force->set_flag (FLAG_APPLIED); if (god) { @@ -1471,12 +1455,13 @@ else race = spell->race; - unordered_mapwalk (op, -range, -range, range, range) + dynbuf buf; + unordered_mapwalk (buf, op, -range, -range, range, range) { mapspace &ms = m->at (nx, ny); /* If there is nothing living on this space, no need to go further */ - if (!ms.flags () & P_IS_ALIVE) + if (!(ms.flags () & P_IS_ALIVE)) continue; // players can only affect spaces that they can actually see @@ -1500,7 +1485,7 @@ if (race && head->race && !strstr (race, head->race)) continue; - if (QUERY_FLAG (head, FLAG_UNDEAD) && !QUERY_FLAG (spell, FLAG_UNDEAD)) + if (head->flag [FLAG_UNDEAD] && !spell->flag [FLAG_UNDEAD]) continue; /* Now do a bunch of stuff related to saving throws */ @@ -1552,38 +1537,38 @@ done_one = 0; /* aggravation */ - if (QUERY_FLAG (spell, FLAG_MONSTER)) + if (spell->flag [FLAG_MONSTER]) { - CLEAR_FLAG (head, FLAG_SLEEP); + head->clr_flag (FLAG_SLEEP); remove_friendly_object (head); done_one = 1; head->enemy = op; } /* calm monsters */ - if (QUERY_FLAG (spell, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (head, FLAG_UNAGGRESSIVE)) + if (spell->flag [FLAG_UNAGGRESSIVE] && !head->flag [FLAG_UNAGGRESSIVE]) { - SET_FLAG (head, FLAG_UNAGGRESSIVE); + head->set_flag (FLAG_UNAGGRESSIVE); head->enemy = NULL; done_one = 1; } /* berserk monsters */ - if (QUERY_FLAG (spell, FLAG_BERSERK) && !QUERY_FLAG (head, FLAG_BERSERK)) + if (spell->flag [FLAG_BERSERK] && !head->flag [FLAG_BERSERK]) { - SET_FLAG (head, FLAG_BERSERK); + head->set_flag (FLAG_BERSERK); done_one = 1; } /* charm */ - if (QUERY_FLAG (spell, FLAG_NO_ATTACK) && !QUERY_FLAG (head, FLAG_FRIENDLY)) + if (spell->flag [FLAG_NO_ATTACK] && !head->flag [FLAG_FRIENDLY]) { INVOKE_OBJECT (KILL, head, ARG_OBJECT (caster)); /* Prevent uncontrolled outbreaks of self replicating monsters. Typical use case is charm, go somwhere, use aggravation to make hostile. This could lead to fun stuff like mice outbreak in bigworld and server crawl. */ - CLEAR_FLAG (head, FLAG_GENERATOR); + head->clr_flag (FLAG_GENERATOR); head->set_owner (op); set_spell_skill (op, caster, spell, head); add_friendly_object (head); @@ -1887,14 +1872,14 @@ if (mflags & P_OUT_OF_MAP) { - new_draw_info (NDI_UNIQUE, 0, op, "Nothing is there."); + op->failmsg ("Nothing is there."); return 0; } if (mflags & P_IS_ALIVE && spell->attacktype) { for (target = GET_MAP_OB (m, x, y); target; target = target->above) - if (QUERY_FLAG (target, FLAG_MONSTER)) + if (target->flag [FLAG_MONSTER]) { /* oky doky. got a target monster. Lets make a blinding attack */ if (target->head) @@ -1908,7 +1893,7 @@ /* no live target, perhaps a wall is in the way? */ if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y))) { - new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); + op->failmsg ("Something is in the way."); return 0; } } @@ -1988,7 +1973,7 @@ { /* search this square for a victim */ for (walk = GET_MAP_OB (m, x, y); walk; walk = walk->above) - if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER)) + if (walk->flag [FLAG_MONSTER] || (walk->type == PLAYER)) { /* found a victim */ object *disease = spell->other_arch->instance (); @@ -1998,59 +1983,32 @@ disease->level = casting_level (caster, spell); /* do level adjustments */ - if (disease->stats.wc) - disease->stats.wc += dur_mod / 2; - - if (disease->magic > 0) - disease->magic += dur_mod / 8; - - if (disease->stats.maxhp > 0) - disease->stats.maxhp += dur_mod; - - if (disease->stats.maxgrace > 0) - disease->stats.maxgrace += dur_mod; - - if (disease->stats.dam) - { - if (disease->stats.dam > 0) - disease->stats.dam += dam_mod; - else - disease->stats.dam -= dam_mod; - } + if (disease->stats.wc ) disease->stats.wc += dur_mod / 2; + if (disease->magic > 0) disease->magic += dur_mod / 8; + if (disease->stats.maxhp > 0) disease->stats.maxhp += dur_mod; + if (disease->stats.maxgrace > 0) disease->stats.maxgrace += dur_mod; if (disease->last_sp) { disease->last_sp -= 2 * dam_mod; + if (disease->last_sp < 1) disease->last_sp = 1; } - if (disease->stats.maxsp) - { - if (disease->stats.maxsp > 0) - disease->stats.maxsp += dam_mod; - else - disease->stats.maxsp -= dam_mod; - } - - if (disease->stats.ac) - disease->stats.ac += dam_mod; - - if (disease->last_eat) - disease->last_eat -= dam_mod; - - if (disease->stats.hp) - disease->stats.hp -= dam_mod; - - if (disease->stats.sp) - disease->stats.sp -= dam_mod; + if (disease->stats.dam ) disease->stats.dam += copysignl (disease->stats.dam , dam_mod); + if (disease->stats.maxsp) disease->stats.maxsp += copysignl (disease->stats.maxsp, dam_mod); + if (disease->stats.ac ) disease->stats.ac += dam_mod; + if (disease->last_eat ) disease->last_eat -= dam_mod; + if (disease->stats.hp ) disease->stats.hp -= dam_mod; + if (disease->stats.sp ) disease->stats.sp -= dam_mod; if (infect_object (walk, disease, 1)) { - new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name); + op->statusmsg (format ("You inflict %s on %s!", &disease->name, &walk->name)); disease->destroy (); /* don't need this one anymore */ - walk->map->insert (get_archetype (shstr_detect_magic), x, y, op); + walk->map->insert (archetype::get (shstr_detect_magic), x, y, op); return 1; }