summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-06-27 17:04:31 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-06-27 17:04:31 +0000
commit1be101fd1fc43a252cdc4debf475edf0c6dba81b (patch)
tree13e5c780e21268c06bb28c48994f934e906ee62e
parent39e1fb93fe8332c69e55c4364d28091a02d52ad5 (diff)
downloadcrawl-ref-1be101fd1fc43a252cdc4debf475edf0c6dba81b.tar.gz
crawl-ref-1be101fd1fc43a252cdc4debf475edf0c6dba81b.zip
Apply patch by Adam Borowski, introducing new unique enchantress Kirke.
This includes a new transformation TRAN_PIG that the player can not end at will but rather will have to time out. Pigs (or rather hogs) are fast but cannot use any equipment except amulets, or cast spells. If the transformation would cause death by stat loss (due to equipment loss) the player is paralysed instead. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10061 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/abl-show.cc2
-rw-r--r--crawl-ref/source/acr.cc5
-rw-r--r--crawl-ref/source/art-func.h4
-rw-r--r--crawl-ref/source/beam.cc29
-rw-r--r--crawl-ref/source/chardump.cc3
-rw-r--r--crawl-ref/source/clua.cc2
-rw-r--r--crawl-ref/source/dat/database/monspeak.txt31
-rw-r--r--crawl-ref/source/dat/descript/monsters.txt4
-rw-r--r--crawl-ref/source/dungeon.cc7
-rw-r--r--crawl-ref/source/enum.h22
-rw-r--r--crawl-ref/source/fight.cc1
-rw-r--r--crawl-ref/source/misc.cc1
-rw-r--r--crawl-ref/source/mon-data.h12
-rw-r--r--crawl-ref/source/mon-spll.h11
-rw-r--r--crawl-ref/source/monplace.cc4
-rw-r--r--crawl-ref/source/monstuff.cc38
-rw-r--r--crawl-ref/source/mstuff2.cc8
-rw-r--r--crawl-ref/source/output.cc3
-rw-r--r--crawl-ref/source/player.cc13
-rw-r--r--crawl-ref/source/spl-data.h13
-rw-r--r--crawl-ref/source/tilepick.cc1
-rw-r--r--crawl-ref/source/transfor.cc43
-rw-r--r--crawl-ref/source/transfor.h1
23 files changed, 228 insertions, 30 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index 01bf48e49c..d0f3c3624a 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -2164,7 +2164,7 @@ std::vector<talent> your_talents(bool check_confused)
if (player_mutation_level(MUT_SMITE))
_add_talent(talents, ABIL_BOLT_OF_DRAINING, check_confused);
- if (you.duration[DUR_TRANSFORMATION])
+ if (you.duration[DUR_TRANSFORMATION] && you.attribute[ATTR_TRANSFORMATION]!=TRAN_PIG)
_add_talent(talents, ABIL_END_TRANSFORMATION, check_confused);
if (player_mutation_level(MUT_BLINK))
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index a16226327e..835b08cf6f 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -1670,7 +1670,8 @@ void process_command( command_type cmd )
case CMD_CAST_SPELL:
case CMD_FORCE_CAST_SPELL:
- if (player_in_bat_form())
+ if (player_in_bat_form()
+ || you.attribute[ATTR_TRANSFORMATION] == TRAN_PIG)
{
canned_msg(MSG_PRESENT_FORM);
break;
@@ -4077,7 +4078,7 @@ static void _compile_time_asserts()
COMPILE_CHECK(SP_VAMPIRE == 31 , c3);
COMPILE_CHECK(SPELL_DEBUGGING_RAY == 107 , c4);
COMPILE_CHECK(SPELL_PETRIFY == 160 , c5);
- COMPILE_CHECK(NUM_SPELLS == 198 , c6);
+ COMPILE_CHECK(NUM_SPELLS == 199 , c6);
//jmf: NEW ASSERTS: we ought to do a *lot* of these
COMPILE_CHECK(NUM_JOBS < JOB_UNKNOWN , c7);
diff --git a/crawl-ref/source/art-func.h b/crawl-ref/source/art-func.h
index 3cd9976040..e5a54cf691 100644
--- a/crawl-ref/source/art-func.h
+++ b/crawl-ref/source/art-func.h
@@ -408,7 +408,7 @@ static bool _WUCAD_MU_evoke(item_def *item, int* pract, bool* did_work,
///////////////////////////////////////////////////
-// XXX: Always getting maximal vampiric drain is harcoded in
+// XXX: Always getting maximal vampiric drain is hardcoded in
// melee_attack::apply_damage_brand()
static void _VAMPIRES_TOOTH_equip(item_def *item, bool *show_msgs, bool unmeld)
@@ -470,7 +470,7 @@ static void _ZONGULDROK_world_reacts(item_def *item)
did_god_conduct(DID_NECROMANCY, 1);
}
}
-
+
static void _ZONGULDROK_melee_effect(item_def* weapon, actor* attacker,
actor* defender, bool mondied)
{
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index c05e1bf18f..4067b00a24 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -55,6 +55,7 @@ REVISION("$Rev$");
#include "state.h"
#include "stuff.h"
#include "terrain.h"
+#include "transfor.h"
#include "traps.h"
#include "tutorial.h"
#include "view.h"
@@ -3746,6 +3747,15 @@ void bolt::affect_player_enchantment()
obvious_effect = true;
break;
+ case BEAM_PORKALATOR:
+ if (!transform(ench_power, TRAN_PIG, true))
+ {
+ mpr("You feel like a pig.");
+ break;
+ }
+ obvious_effect = true;
+ break;
+
default:
// _All_ enchantments should be enumerated here!
mpr("Software bugs nibble your toes!");
@@ -4528,6 +4538,8 @@ void bolt::affect_monster(monsters* mon)
int beam_hit = hit;
if (mon->invisible() && !this->can_see_invis)
beam_hit /= 2;
+ if (mon->type == MONS_KIRKE) // deflect missiles
+ beam_hit = random2(beam_hit * 2) / 3;
// FIXME We're randomising mon->evasion, which is further
// randomised inside test_beam_hit. This is so we stay close to the 4.0
@@ -4687,6 +4699,13 @@ bool _ench_flavour_affects_monster(beam_type flavour, const monsters* mon)
&& mons_res_cold(mon) <= 0; // can't be hibernated
break;
+ case BEAM_PORKALATOR:
+ rc = (mons_holiness(mon) == MH_NATURAL
+ && mon->type != MONS_HOG) ||
+ (mons_holiness(mon) == MH_DEMONIC
+ && mon->type != MONS_HELL_HOG);
+ break;
+
default:
break;
}
@@ -5003,6 +5022,12 @@ mon_resist_type bolt::apply_enchantment_to_monster(monsters* mon)
}
return (MON_AFFECTED);
+ case BEAM_PORKALATOR:
+ if (monster_polymorph(mon, (mons_holiness(mon)==MH_DEMONIC)?
+ MONS_HELL_HOG : MONS_HOG))
+ obvious_effect = true;
+ return (MON_AFFECTED);
+
default:
break;
}
@@ -5703,6 +5728,7 @@ std::string beam_type_name(beam_type type)
case BEAM_PETRIFY: return("petrify");
case BEAM_BACKLIGHT: return("backlight");
case BEAM_SLEEP: return("sleep");
+ case BEAM_PORKALATOR: return("porkalator");
case BEAM_POTION_BLACK_SMOKE: return("black smoke");
case BEAM_POTION_GREY_SMOKE: return("grey smoke");
case BEAM_POTION_BLUE_SMOKE: return("blue smoke");
@@ -5721,7 +5747,8 @@ std::string beam_type_name(beam_type type)
void clear_zap_info_on_exit()
{
- for (unsigned int i = 0; i < NUM_BEAMS; ++i)
+ const unsigned int zap_size = sizeof(zap_data) / sizeof(zap_info);
+ for (unsigned int i = 0; i < zap_size; ++i)
{
delete zap_data[i].damage;
delete zap_data[i].tohit;
diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc
index e3f62bd2bd..097932a3c0 100644
--- a/crawl-ref/source/chardump.cc
+++ b/crawl-ref/source/chardump.cc
@@ -256,6 +256,9 @@ static void _sdump_transform(dump_params &par)
case TRAN_LICH:
text += "You " + verb + " in lich-form.";
break;
+ case TRAN_PIG:
+ text += "You " + verb + " a filthy swine.";
+ break;
}
text += "\n\n";
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc
index f0f37d7314..e4ded572b4 100644
--- a/crawl-ref/source/clua.cc
+++ b/crawl-ref/source/clua.cc
@@ -752,6 +752,8 @@ static const char *transform_name()
return "dragon";
case TRAN_LICH:
return "lich";
+ case TRAN_PIG:
+ return "pig";
default:
return "";
}
diff --git a/crawl-ref/source/dat/database/monspeak.txt b/crawl-ref/source/dat/database/monspeak.txt
index 6142784c1b..cbb42fb886 100644
--- a/crawl-ref/source/dat/database/monspeak.txt
+++ b/crawl-ref/source/dat/database/monspeak.txt
@@ -1800,6 +1800,37 @@ _Jozef_rare_
@The_monster@ screams @at_foe@, "Die! I've got more contracts today."
## END Jozef ##
%%%%
+# an enchantress, lover of Odysseus
+Kirke
+
+VISUAL:@The_monster@ splashes a potion @at_foe@.
+
+VISUAL:@The_monster@ throws some @strange@ powder @at_foe@.
+
+@The_monster@ says @to_foe@, "Odis was a nice man, you're awful."
+
+@The_monster@ holds her sides and says @to_foe@, "You'll eat dirt beneath my feet."
+
+# "moly" is a magic herb, mentioned only in Kirke's myth (as an antidote to
+# Kirke's potions) and in the English interjection.
+@The_monster@ whispers @to_foe@, "Not even holy moly will save you."
+
+@The_monster@ says, "Can we stop fighting? I have some good wine for you..." @player_only@
+
+@The_monster@ shouts @at_foe@, "You pig! I'll make you look the way you deserve."
+
+@_wizard_common_spell_@
+@_fake_spell_effect_@
+%%%%
+strange
+
+strange
+
+weird
+
+mysterious
+### END Kirke ###
+%%%%
# A powerful sorceress, guarding the ORB
Margery
diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt
index e0c33be01f..5ddb79b85b 100644
--- a/crawl-ref/source/dat/descript/monsters.txt
+++ b/crawl-ref/source/dat/descript/monsters.txt
@@ -172,6 +172,10 @@ Killer Klown
A comical figure full of life and laughter. It looks very happy to see you... but is there a slightly malicious cast to its features? Is that red face paint or something altogether less pleasant?
%%%%
+Kirke
+
+A beautiful enchantress.
+%%%%
Lom Lobon
An ancient and strangely serene demon. It regards you coldly from the huge glowing eye in the centre of its forehead.
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index e48b56ff8d..3ddcd20595 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -3269,19 +3269,20 @@ static monster_type _choose_unique_by_depth(int step)
MONS_SNORG, MONS_ERICA, MONS_JOSEPHINE, MONS_HAROLD,
MONS_ROXANNE, MONS_RUPERT, MONS_NORBERT, MONS_JOZEF,
MONS_AZRAEL, MONS_NESSOS, MONS_AGNES,
- MONS_MAUD, MONS_LOUISE, MONS_NERGALLE, -1);
+ MONS_MAUD, MONS_LOUISE, MONS_NERGALLE, MONS_KIRKE, -1);
break;
case 5: // depth <= 19
ret = random_choose(MONS_SNORG, MONS_LOUISE, MONS_FRANCIS, MONS_FRANCES,
MONS_RUPERT, MONS_WAYNE, MONS_DUANE, MONS_NORRIS,
MONS_AZRAEL, MONS_NESSOS, MONS_NERGALLE,
- MONS_ROXANNE, MONS_SAINT_ROKA, -1);
+ MONS_ROXANNE, MONS_SAINT_ROKA, MONS_KIRKE, -1);
break;
case 6: // depth > 19
default:
ret = random_choose(MONS_FRANCIS, MONS_FRANCES, MONS_WAYNE, MONS_DUANE,
MONS_XTAHUA, MONS_NORRIS, MONS_FREDERICK,
- MONS_MARGERY, MONS_BORIS, MONS_SAINT_ROKA, -1);
+ MONS_MARGERY, MONS_BORIS, MONS_SAINT_ROKA,
+ MONS_KIRKE, -1);
}
return static_cast<monster_type>(ret);
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 42cb62cc1f..67d799ef05 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -235,30 +235,31 @@ enum beam_type // beam[].flavour
BEAM_BLINK,
BEAM_PETRIFY,
BEAM_BACKLIGHT,
- BEAM_SLEEP, // 45
+ BEAM_PORKALATOR, // 45
+ BEAM_SLEEP,
BEAM_LAST_ENCHANTMENT = BEAM_SLEEP,
// new beams for evaporate
BEAM_POTION_STINKING_CLOUD,
BEAM_POTION_POISON,
BEAM_POTION_MIASMA,
- BEAM_POTION_STEAM,
- BEAM_POTION_FIRE, // 50
+ BEAM_POTION_STEAM, // 50
+ BEAM_POTION_FIRE,
BEAM_POTION_COLD,
BEAM_POTION_BLACK_SMOKE,
BEAM_POTION_GREY_SMOKE,
- BEAM_POTION_BLUE_SMOKE,
- BEAM_POTION_PURP_SMOKE, // 55
+ BEAM_POTION_BLUE_SMOKE, // 55
+ BEAM_POTION_PURP_SMOKE,
BEAM_POTION_RANDOM,
BEAM_LAST_REAL = BEAM_POTION_RANDOM,
// For getting the visual effect of a beam.
- BEAM_VISUAL, // 57
+ BEAM_VISUAL,
BEAM_TORMENT_DAMAGE, // Pseudo-beam for damage flavour.
BEAM_FIRST_PSEUDO = BEAM_TORMENT_DAMAGE,
- BEAM_STEAL_FOOD, // 59: Pseudo-beam for harpies stealing food.
+ BEAM_STEAL_FOOD, // 60: Pseudo-beam for harpies stealing food.
NUM_BEAMS
};
@@ -2018,6 +2019,7 @@ enum monster_type // (int) menv[].type
MONS_NESSOS,
MONS_LERNAEAN_HYDRA,
MONS_DISSOLUTION, // 460
+ MONS_KIRKE,
// Testing monsters
MONS_TEST_SPAWNER,
@@ -2222,6 +2224,7 @@ enum mon_spellbook_type
MST_ILSUIW,
MST_PRINCE_RIBBIT, // 145
MST_NESSOS,
+ MST_KIRKE,
MST_GERYON = 150,
MST_DISPATER,
MST_ASMODEUS,
@@ -2808,9 +2811,10 @@ enum spell_type
SPELL_FIRE_BREATH,
SPELL_COLD_BREATH, // 195
SPELL_DRACONIAN_BREATH,
- SPELL_WATER_ELEMENTALS, // 197
+ SPELL_WATER_ELEMENTALS,
+ SPELL_PORKALATOR, // 198
- NUM_SPELLS // 198
+ NUM_SPELLS // 199
};
enum slot_select_mode
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 4f7e94b236..b90eee161f 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -1696,6 +1696,7 @@ int melee_attack::player_weapon_type_modify(int damage)
{
case TRAN_SPIDER:
case TRAN_BAT:
+ case TRAN_PIG:
if (damage < HIT_STRONG)
attack_verb = "bite";
else
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 32b5d1625b..df74fbb252 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -3017,6 +3017,7 @@ std::string your_hand(bool plural)
result = "hand";
break;
case TRAN_SPIDER:
+ case TRAN_PIG:
result = "front leg";
break;
case TRAN_DRAGON:
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index 151693960e..08e1fed7d0 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -4349,6 +4349,18 @@ static monsterentry mondata[] = {
},
{
+ MONS_KIRKE, '@', YELLOW, "Kirke",
+ M_UNIQUE | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS
+ | M_SPEAKS,
+ MR_NO_FLAGS,
+ 550, 15, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
+ { {AT_HIT, AF_PLAIN, 18}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
+ { 16, 0, 0, 110 },
+ 0, 10, MST_KIRKE, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
+ HT_LAND, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM
+},
+
+{
MONS_WAYNE, '@', YELLOW, "Wayne",
M_UNIQUE | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS
| M_EVIL | M_SPEAKS,
diff --git a/crawl-ref/source/mon-spll.h b/crawl-ref/source/mon-spll.h
index 0169a74396..1aa37e5f65 100644
--- a/crawl-ref/source/mon-spll.h
+++ b/crawl-ref/source/mon-spll.h
@@ -1043,6 +1043,17 @@
}
},
+ { MST_KIRKE,
+ {
+ SPELL_PORKALATOR,
+ SPELL_SLOW,
+ SPELL_SUMMON_UGLY_THING,
+ SPELL_SUMMON_ICE_BEAST,
+ SPELL_BACKLIGHT,
+ SPELL_INVISIBILITY
+ }
+ },
+
{ MST_GERYON,
{
SPELL_SUMMON_BEAST,
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index aa5df5c286..726e8b64db 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -1658,9 +1658,11 @@ static band_type _choose_band(int mon_type, int power, int &band_size)
band_size = 2 + random2(3);
break;
+ case MONS_KIRKE:
+ band_size = 3 + random2(5);
case MONS_HOG:
band = BAND_HOGS;
- band_size = 1 + random2(3);
+ band_size += 1 + random2(3);
break;
case MONS_GIANT_MOSQUITO:
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index a7acbe5c0e..310fb9e111 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -58,6 +58,7 @@ REVISION("$Rev$");
#include "state.h"
#include "stuff.h"
#include "terrain.h"
+#include "transfor.h"
#include "traps.h"
#include "tutorial.h"
#include "view.h"
@@ -1068,6 +1069,39 @@ void _monster_die_cloud(const monsters* monster, bool corpse, bool silent,
}
}
+static void _hogs_to_humans()
+{
+ // Simplification: if, in a rare event, another hog which was not created
+ // as a part of Kirke's band happens to be on the level, the player can't
+ // tell them apart anyway.
+ // On the other hand, hogs which left the level are too far away to be
+ // affected by the magic of Kirke's death.
+ int any = 0;
+
+ for (int i = 0; i < MAX_MONSTERS; ++i)
+ {
+ monsters *monster = &menv[i];
+ if (monster->type == MONS_HOG)
+ {
+ monster->type = MONS_HUMAN;
+ monster->attitude = ATT_GOOD_NEUTRAL;
+ monster->flags |= MF_WAS_NEUTRAL;
+ behaviour_event(monster, ME_EVAL);
+
+ any++;
+ }
+ }
+
+ if (any==1)
+ mpr("No longer under Kirke's spell, the hog turns into a human!");
+ else if (any>1)
+ mpr("No longer under Kirke's spell, all hogs revert to their human form!");
+
+ // Revert the player as well.
+ if (you.attribute[ATTR_TRANSFORMATION] == TRAN_PIG)
+ untransform();
+}
+
int monster_die(monsters *monster, killer_type killer,
int killer_index, bool silent, bool wizard)
{
@@ -1678,6 +1712,10 @@ int monster_die(monsters *monster, killer_type killer,
// creation again. -- bwr
you.unique_creatures[monster->type] = false;
}
+ else if (monster->type == MONS_KIRKE && !in_transit)
+ {
+ _hogs_to_humans();
+ }
else if (!mons_is_summoned(monster))
{
if (mons_genus(monster->type) == MONS_MUMMY)
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 38a93a53d0..e9a4d2fd26 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -2057,6 +2057,14 @@ bolt mons_spells( monsters *mons, spell_type spell_cast, int power )
beam.is_beam = true;
break;
+ case SPELL_PORKALATOR:
+ beam.name = "0";
+ beam.type = 0;
+ beam.flavour = BEAM_PORKALATOR;
+ beam.thrower = KILL_MON_MISSILE;
+ beam.is_beam = true;
+ break;
+
default:
if (!is_valid_spell(real_spell))
DEBUGSTR("Invalid spell #%d cast by %s", (int) real_spell,
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index fd2ebd42db..c6371dd018 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -2569,6 +2569,9 @@ std::string _status_mut_abilities()
case TRAN_LICH:
text += "\nYou are in lich-form.";
break;
+ case TRAN_PIG:
+ text += "\nYou are a filthy swine.";
+ break;
}
if ((you.species != SP_VAMPIRE
|| you.attribute[ATTR_TRANSFORMATION] != TRAN_BAT)
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index c04ea520bf..287d8efdf0 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -506,6 +506,8 @@ bool is_player_same_species(const int mon, bool transform)
return (mons_genus(mon) == MONS_WOLF_SPIDER);
case TRAN_DRAGON:
return (mons_genus(mon) == MONS_DRAGON); // Includes all drakes.
+ case TRAN_PIG:
+ return (mons_genus(mon) == MONS_HOG);
default:
break; // Check real (non-transformed) form.
}
@@ -729,8 +731,8 @@ bool you_tran_can_wear(int eq, bool check_mutation)
if (transform == TRAN_NONE || transform == TRAN_LICH)
return (true);
- // Bats cannot wear anything except amulets.
- if (transform == TRAN_BAT && eq != EQ_AMULET)
+ // Bats and pigs cannot wear anything except amulets.
+ if ((transform == TRAN_BAT || transform == TRAN_PIG) && eq != EQ_AMULET)
return (false);
// Everyone else can wear jewellery, at least.
@@ -1966,6 +1968,8 @@ int player_movement_speed(void)
mv = 8;
else if (player_in_bat_form())
mv = 5; // but allowed minimum is six
+ else if (you.attribute[ATTR_TRANSFORMATION] == TRAN_PIG)
+ mv = 7;
// armour
if (player_equip_ego_type( EQ_BOOTS, SPARM_RUNNING ))
@@ -3970,6 +3974,9 @@ void display_char_status()
case TRAN_LICH:
text += "You are in lich-form.";
break;
+ case TRAN_PIG:
+ text += "You are a filthy swine.";
+ break;
}
mpr(text.c_str());
}
@@ -6255,6 +6262,8 @@ std::string player::shout_verb() const
return "hiss";
case TRAN_BAT:
return "squeak";
+ case TRAN_PIG:
+ return "squeal";
default: // depends on SCREAM mutation
int level = player_mutation_level(MUT_SCREAM);
if (level <= 1)
diff --git a/crawl-ref/source/spl-data.h b/crawl-ref/source/spl-data.h
index 99036db9f3..b9e01d3fad 100644
--- a/crawl-ref/source/spl-data.h
+++ b/crawl-ref/source/spl-data.h
@@ -2514,6 +2514,19 @@
},
{
+ SPELL_PORKALATOR, "Porkalator",
+ SPTYP_ENCHANTMENT | SPTYP_TRANSMUTATION,
+ SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
+ 5,
+ 200,
+ LOS_RADIUS, LOS_RADIUS,
+ 0,
+ NULL,
+ true,
+ false
+},
+
+{
SPELL_NO_SPELL, "nonexistent spell",
0,
SPFLAG_TESTING,
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 88636bda76..c4975fafe0 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -2492,6 +2492,7 @@ int tileidx_player(int job)
case '#': ch = TILEP_MONS_VAPOUR; break;
case 'S': ch = TILEP_MONS_LAVA_SNAKE; break;
case 'b': ch = TILEP_MONS_GIANT_BAT; break;
+ case 'h': ch = TILEP_MONS_HOG; break;
}
if (player_is_airborne())
diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc
index 070841ae21..2036d37e0d 100644
--- a/crawl-ref/source/transfor.cc
+++ b/crawl-ref/source/transfor.cc
@@ -56,9 +56,10 @@ bool transform_allows_wearing_item(const item_def& item,
if (item.base_type == OBJ_JEWELLERY)
{
- // Everything but bats can wear all jewellery; bats can
+ // Everything but bats can wear all jewellery; bats and pigs can
// only wear amulets.
- if (transform == TRAN_BAT && !jewellery_is_amulet(item))
+ if ((transform == TRAN_BAT || transform == TRAN_PIG)
+ && !jewellery_is_amulet(item))
rc = false;
}
else
@@ -78,6 +79,7 @@ bool transform_allows_wearing_item(const item_def& item,
// Some can't wear anything.
case TRAN_DRAGON:
case TRAN_BAT:
+ case TRAN_PIG:
rc = false;
break;
@@ -470,6 +472,8 @@ size_type player::transform_size(int psize) const
case TRAN_SPIDER:
case TRAN_BAT:
return SIZE_TINY;
+ case TRAN_PIG:
+ return SIZE_SMALL;
case TRAN_ICE_BEAST:
return SIZE_LARGE;
case TRAN_DRAGON:
@@ -530,8 +534,11 @@ bool transform(int pow, transformation_type which_trans, bool force,
{
if (just_check)
return (true);
-
- mpr("You extend your transformation's duration.");
+
+ if (which_trans==TRAN_PIG)
+ mpr("You feel you'll be a pig longer.");
+ else
+ mpr("You extend your transformation's duration.");
you.duration[DUR_TRANSFORMATION] += random2(pow);
if (you.duration[DUR_TRANSFORMATION] > 100)
@@ -541,7 +548,7 @@ bool transform(int pow, transformation_type which_trans, bool force,
}
else
{
- if (!force)
+ if (!force && which_trans!=TRAN_PIG)
mpr("You cannot extend your transformation any further!");
return (false);
}
@@ -589,7 +596,7 @@ bool transform(int pow, transformation_type which_trans, bool force,
std::set<equipment_type> rem_stuff = _init_equipment_removal(which_trans);
- if (_check_for_cursed_equipment(rem_stuff, which_trans, force))
+ if (_check_for_cursed_equipment(rem_stuff, which_trans, force) && which_trans!=TRAN_PIG)
return (_abort_or_fizzle(just_check));
int str = 0, dex = 0, symbol = '@', colour = LIGHTGREY, xhp = 0, dur = 0;
@@ -673,14 +680,28 @@ bool transform(int pow, transformation_type which_trans, bool force,
msg = "You turn into a bat.";
break;
+ case TRAN_PIG:
+ tran_name = "pig";
+ symbol = 'h';
+ colour = RED;
+ dur = pow;
+ msg = "You have been turned into a pig!";
+ break;
+
case TRAN_NONE:
case NUM_TRANSFORMATIONS:
break;
}
- if (check_transformation_stat_loss(rem_stuff, force,
- std::max(-str, 0), std::max(-dex, 0)))
- {
+ if (check_transformation_stat_loss(rem_stuff, force || which_trans == TRAN_PIG,
+ std::max(-str, 0), std::max(-dex,0)))
+ { // would have died to stat loss
+ if (which_trans == TRAN_PIG)
+ { // no easy way around this!
+ mpr("A dreadful feeling locks you in place!");
+ if (you.duration[DUR_PARALYSIS]<10)
+ you.duration[DUR_PARALYSIS]=10;
+ }
return (_abort_or_fizzle(just_check));
}
@@ -879,6 +900,10 @@ void untransform(bool skip_wielding)
you.is_undead = US_ALIVE;
break;
+ case TRAN_PIG:
+ mpr( "Your transformation has ended.", MSGCH_DURATION );
+ break;
+
default:
break;
}
diff --git a/crawl-ref/source/transfor.h b/crawl-ref/source/transfor.h
index 5dff88bcfa..681f1e84f9 100644
--- a/crawl-ref/source/transfor.h
+++ b/crawl-ref/source/transfor.h
@@ -25,6 +25,7 @@ enum transformation_type
TRAN_DRAGON, // 5
TRAN_LICH,
TRAN_BAT,
+ TRAN_PIG,
NUM_TRANSFORMATIONS // must remain last member {dlb}
};