worshipping an appropriate god. I'm simply reusing dolorous unchivalric methods here. :) Also, don't prompt for harmless beams.
Still TODO: Make the message differentiate between target and obstacles, and clean up the code a bit.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5193 c06c8d41-db1a-0410-9941-cceddc491573
3EUPIYJNWOMOQBP2Z5SGSMWK453BXJD6KL2WFTR3NM565MEBYASAC
FLAGBNUNSIQNFDN53CDWABJRTTFWDL4PG34AI474ZKPXDEPYHOAQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
NCSALY7HYRVCKTPS5TWZBRE2C3OCANYU3LBPIZ4RRVEI6GOZL2EQC
5BYWI6JJMVTQLCOMPHQNSFC2HW5LYGYFBHBIOU7D4T4B2AIUZV4AC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
7EI4HMXZ7TAWZKFZG2SXHDAX3FWFBCZLUAKOALPRFF72FS7NKVBQC
7Q33YEI26IBNMOJEG2PMW7ULDJBXU4SRA3ZIPHBUFUXXM2VUTBPQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
6GDKXNFXPKQ6AVNOSMJECN7CLELM2KCMVRM2A7BARLK2NNILN6SAC
KHHAE5ZK7ITEZVMMUKYROKECLE2RU5ZU5OQ4Z4XSRQXE2R65O67AC
CIPVRZGLOZHCERK6YPOBV3P2E4IAB4H6D5EHLRQE2O5E4P4VCBUAC
5FBOE2QNRLKUNOP54CZD6LFAMM7LX6NNLHJRJHRDDIUTQ7J723DQC
QCUMH3C7GXV7ZW444WT5SFAXQOJKJSE2YCQCEHMRYXCWF4QI7UMAC
GT7BSR54BVJKHUCLEBTELGBMNBFFDQW52EVC4XKVEMUVG2UGZMDAC
4GGNXCX2CLKWQZIZT543LXFFKFRD4PY5XPJFLGWKW4ACKYZNLVPQC
QUBQZMAVSWJ7JVOL7CBSOXBEVW2WYK2MDFA2JCZWX62R2GEKP3ZQC
5V47S4NNTHWTSAHV3YLO2VGH7JTUIYJ3GBPDN5ZM4UQALT2ZEXDQC
ASLW3Z5PAVZSWJEMMMVZT226P44EKSAD47QS72JIFJESAI3RPN3AC
RMCZDJKEYYT6TTZNJGBVZTG74CVLF72NWKON6IJ2HNTCA23INPJQC
UZ5623MOLKBTGBSRBJ4OBOEI4IEZSPV3NCV2DRMUZ3CHHJQVHIIAC
W74555HMPXUQ72AGKBXC5P3STMMX5DZAW6ZESUDLNVJBCAG43PLAC
72CQFK27NR37P2WQ32U4PEXXKMRIO7JEMJN2ZCPNVPZMT7UPFJJAC
G3HJCS277WA2VONPOJW6FAOQO7VHMSMLXZWYIXKFE4N4Y3OV7UZAC
RBKHIKKQ5LSNWJA7ZIJ6B7HF36UA6LPZLVEWOJ3X5CUSQUOJGFZQC
4UXFU3FZOCBSLDQ4S7MJKAE2H7VUHCNRDQMIY6NJ3PHYXWNGISDQC
KBNY5FWKTEAKABFCLPC3QFKFSVZKAGXINPCIFV6WDSWFO4VCKNTAC
PR42BCP5BPRFD2MP5H6CIJP7E57Q6TKL6SOXZWFKMFVR2OZWHT7AC
DKRSOHZXL6EPSLKOKHF7GJXSZEJVY7CXGACSHWLM5B5FTRETWWCAC
5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC
KAOE5HB3THUKVGFZRO5EZESHEB3Q34WUO5DFMLWIKOBF47LZTIYAC
QNKMXCJSGRBEPE6ZNPEXU5EQIOME6EI4DECVC56GLOBCMGWWE6MQC
25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC
DUBEHQIQABGLXLFIVZ6WXBMFGLFKFRBOCK5LZ6ECUSRM3V2V35NAC
7YUGK5Q64KG5O7GJGTUBRRLHAHBCJ5YOE23YUPT6UBKUSB67CYAQC
5K2ANIEXD3CPJM4XNKNPZINP2G4NT7SJBKRN62WNBUKJXFERTILQC
RCPQNIRPR3NQXEMVLBAQW6657UJFIP43N54UJVEZHJH22OH4UQIQC
MG6LLF3XYCOEBQRX7TJ4MUTKM3IROYWUMZGCMYVW4TGDG36CJMJQC
C5U3HSOOQ7BKXKXIDS7MLVXUKDTHAWJ5NXNX6YDXTM3GWY5UWX4QC
MFCHFDPW4YX4QZWUOJIT3UG6OHIJPWZRXLYZQCSAUQFCEPYOYHEAC
6PAG7GHXHIYXJPPTEK4KZQZT4CL2SJDAGTVIUDB4KK66PVSTWUMAC
BTO5WE4OEK64DZQVNYLOESM74KKQNE7KSNMQVF5UDB26OBKP7ORQC
2SNCC2NXKFVBYTWH7THU2QELHONTOBRNCWH6FWYORKKCWZAXTTVAC
// Making a copy of the item: changed only for venom launchers
item_def item = you.inv[throw_2];
item.quantity = 1;
item.slot = index_to_letter(item.link);
// Get the ammo/weapon type. Convenience.
const object_class_type wepClass = item.base_type;
const int wepType = item.sub_type;
// figure out if we're thrown or launched
const launch_retval projected = is_launched(&you, you.weapon(), item);
pbolt.name = item.name(DESC_PLAIN, false, false, false);
pbolt.thrower = KILL_YOU_MISSILE;
pbolt.source_x = you.x_pos;
pbolt.source_y = you.y_pos;
pbolt.colour = item.colour;
pbolt.flavour = BEAM_MISSILE;
pbolt.aux_source.clear();
// pbolt.range is set below
if (projected)
{
if (wepType == MI_LARGE_ROCK)
{
pbolt.range = 1 + random2( you.strength / 5 );
pbolt.rangeMax = you.strength / 5;
if (you.can_throw_rocks())
{
pbolt.range += random_range(4, 7);
pbolt.rangeMax += 7;
}
if (pbolt.rangeMax > 12)
{
pbolt.rangeMax = 12;
if (pbolt.range > 12)
pbolt.range = 12;
}
}
else if (wepType == MI_THROWING_NET)
{
pbolt.rangeMax = pbolt.range = 2 + player_size(PSIZE_BODY);
}
else
{
pbolt.rangeMax = pbolt.range = 12;
}
}
else
{
// Range based on mass & strength, between 1 and 9.
pbolt.range = you.strength - item_mass(item) / 10 + 3;
if (pbolt.range < 1)
pbolt.range = 1;
if (pbolt.range > 9)
pbolt.range = 9;
pbolt.rangeMax = pbolt.range;
}
pbolt.is_beam = false;
pbolt.beam_source = 0;
pbolt.can_see_invis = player_see_invis();
pbolt.smart_monster = true;
pbolt.attitude = ATT_FRIENDLY;
pbolt.is_tracer = true;
// init tracer variables
pbolt.foe_count = pbolt.fr_count = 0;
pbolt.foe_power = pbolt.fr_power = 0;
pbolt.fr_helped = pbolt.fr_hurt = 0;
pbolt.foe_helped = pbolt.foe_hurt = 0;
pbolt.foe_ratio = 100;
// Don't do the tracing when confused.
if (!you.duration[DUR_CONF])
fire_beam(pbolt);
// Should only happen if the player answered 'n' to one of those
// "Fire through friendly?" prompts.
if (pbolt.fr_count > 0)
{
canned_msg(MSG_OK);
you.turn_is_over = false;
return (false);
}
// Now start real firing!
origin_set_unknown(item);
// Making a copy of the item: changed only for venom launchers
item_def item = you.inv[throw_2];
item.quantity = 1;
item.slot = index_to_letter(item.link);
origin_set_unknown(item);
if (item.base_type == OBJ_POTIONS
&& (item.sub_type == POT_BLOOD
|| item.sub_type == POT_BLOOD_COAGULATED)
&& you.inv[throw_2].quantity > 1)
if (is_blood_potion(item) && you.inv[throw_2].quantity > 1)
pbolt.source_x = you.x_pos;
pbolt.source_y = you.y_pos;
pbolt.colour = item.colour;
pbolt.name = item.name(DESC_PLAIN, false, false, false);
pbolt.thrower = KILL_YOU_MISSILE;
pbolt.aux_source.clear();
// get the ammo/weapon type. Convenience.
const object_class_type wepClass = item.base_type;
const int wepType = item.sub_type;
// get the launcher class,type. Convenience.
// Get the launcher class,type. Convenience.
returning = ((get_weapon_brand(item) == SPWPN_RETURNING ||
get_ammo_brand(item) == SPMSL_RETURNING) && !teleport);
returning = (!teleport && (get_weapon_brand(item) == SPWPN_RETURNING
|| get_ammo_brand(item) == SPMSL_RETURNING));
if (wepType == MI_LARGE_ROCK)
{
pbolt.range = 1 + random2( you.strength / 5 );
if (you.can_throw_rocks())
pbolt.range += random_range(4, 7);
if (pbolt.range > 12)
pbolt.range = 12;
pbolt.rangeMax = pbolt.range;
}
else if (wepType == MI_THROWING_NET)
if (wepType != MI_LARGE_ROCK && wepType != MI_THROWING_NET)
pbolt.rangeMax = pbolt.range = 2 + player_size(PSIZE_BODY);
}
else
{
pbolt.range = 12;
pbolt.rangeMax = 12;
// range based on mass & strength, between 1 and 9
pbolt.range = you.strength - item_mass(item) / 10 + 3;
if (pbolt.range < 1)
pbolt.range = 1;
if (pbolt.range > 9)
pbolt.range = 9;
// set max range equal to range for this
pbolt.rangeMax = pbolt.range;
// last updated 19apr2001 {gdl}
/* ***********************************************************************
* called from: beam
* *********************************************************************** */
bool nasty_beam( monsters *mon, struct bolt &beam );
bool nice_beam( monsters *mon, struct bolt &beam );
// The others are handled here.
switch (beam.flavour)
{
case BEAM_DIGGING:
return (true);
// Cleansing flame doesn't affect player's followers.
case BEAM_HOLY:
return (mons_is_holy(mon)
|| is_good_god(you.religion)
&& ( is_follower(mon) || mons_neutral(mon) ));
case BEAM_STEAM:
return (mons_res_steam(mon) >= 3);
case BEAM_FIRE:
return (mons_res_fire(mon) >= 3);
case BEAM_COLD:
return (mons_res_cold(mon) >= 3);
case BEAM_MIASMA:
case BEAM_NEG:
return (mons_res_negative_energy(mon) >= 3);
case BEAM_ELECTRICITY:
return (mons_res_elec(mon) >= 3);
case BEAM_POISON:
return (mons_res_poison(mon) >= 3);
case BEAM_ACID:
return (mons_res_acid(mon) >= 3);
default:
return (false);
}
}
static bool _stop_unchivalric_attack(monsters *mon)
{
const bool wontAttack = mons_wont_attack(mon);
const bool isFriendly = mons_friendly(mon);
const bool isNeutral = mons_neutral(mon);
const bool isUnchivalric = is_unchivalric_attack(&you, mon, mon);
const bool isHoly = mons_is_holy(mon);
if (wontAttack
|| is_good_god(you.religion) && (isNeutral || isHoly)
|| you.religion == GOD_SHINING_ONE && isUnchivalric)
{
snprintf(info, INFO_SIZE, "Really fire through this "
"%s%s%screature?",
(isUnchivalric) ? "helpless "
: "",
(isFriendly) ? "friendly " :
(wontAttack) ? "non-hostile " :
(isNeutral) ? "neutral "
: "",
(isHoly) ? "holy "
: "");
if (!yesno(info, true, 'n'))
return (true);
}
return (false);
}
const int mons_type = menv[tid].type;
const int thrower = YOU_KILL(beam.thrower)? KILL_YOU_MISSILE
: KILL_MON_MISSILE;
const int mons_type = menv[tid].type;
const int thrower = YOU_KILL(beam.thrower) ? KILL_YOU_MISSILE
: KILL_MON_MISSILE;
// check can see other monster
if (!beam.can_see_invis && menv[tid].invisible())
// Can we see this monster?
if (!beam.can_see_invis && menv[tid].invisible()
|| thrower == KILL_YOU_MISSILE && !see_grid(mon->x, mon->y))