diff options
author | DShaligram <DShaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-15 17:48:19 +0000 |
---|---|---|
committer | DShaligram <DShaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-15 17:48:19 +0000 |
commit | 03945879dafaf9f02c365ad1a800308b78f095aa (patch) | |
tree | 8f5f4e90a739b06f2c7e051e0efbee9a61a463d5 | |
parent | 0d9cfab608b3ed662b6fc687ba94008e623088d1 (diff) | |
download | crawl-ref-03945879dafaf9f02c365ad1a800308b78f095aa.tar.gz crawl-ref-03945879dafaf9f02c365ad1a800308b78f095aa.zip |
r30@calamity: dshaligram | 2006-08-15 23:20:36 +051800
Added curare-tipped needles (Erik), fixed temporary branding bugginess,
rearranged spells in spell-level order in spellbooks.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup@18 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/source/acr.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/beam.cc | 87 | ||||
-rw-r--r-- | crawl-ref/source/command.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 19 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 5 | ||||
-rw-r--r-- | crawl-ref/source/hiscores.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 36 | ||||
-rw-r--r-- | crawl-ref/source/itemname.cc | 9 | ||||
-rw-r--r-- | crawl-ref/source/libw32c.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/misc.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 17 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/newgame.cc | 1 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/player.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/spells2.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/spl-book.cc | 18 |
18 files changed, 196 insertions, 61 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 953ed0d1a1..7f0f4d5125 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -1920,7 +1920,8 @@ static void input(void) break; case SPWPN_DISTORTION: strcat( info, " seems straighter." ); - miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, "a distortion effect" ); + // [dshaligram] Makes the brand unusable + // miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, "a distortion effect" ); break; default: strcat(info, " seems inexplicably less special."); diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 9bbead8675..8c4ea84d6a 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1975,6 +1975,56 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) return (MON_AFFECTED); } // end mons_ench_f2() +// degree is ignored. +static void slow_monster(monsters *mon, int degree) +{ + bolt beam; + beam.flavour = BEAM_SLOW; + mons_ench_f2(mon, beam); +} + +// Returns true if the curare killed the monster. +bool curare_hits_monster( const bolt &beam, + monsters *monster, + bool fromPlayer, + int levels ) +{ + const bool res_poison = mons_res_poison(monster); + bool mondied = false; + + poison_monster(monster, fromPlayer, levels, false); + + if (!mons_res_asphyx(monster)) + { + int hurted = roll_dice(2, 6); + + // Note that the hurtage is halved by poison resistance. + if (res_poison) + hurted /= 2; + + if (hurted) + { + simple_monster_message(monster, " appears to choke."); + if ((monster->hit_points -= hurted) < 1) + { + const int thrower = YOU_KILL(beam.thrower) ? + KILL_YOU_MISSILE : KILL_MON_MISSILE; + monster_die(monster, thrower, beam.beam_source); + mondied = true; + } + } + + if (!mondied) + slow_monster(monster, levels); + } + + // Deities take notice. + if (fromPlayer) + did_god_conduct( DID_POISON, 5 + random2(3) ); + + return (mondied); +} + // actually poisons a monster (w/ message) void poison_monster( struct monsters *monster, bool fromPlayer, int levels, bool force ) @@ -2938,6 +2988,11 @@ static void affect_items(struct bolt &beam, int x, int y) } } +static int beam_ouch_agent(const bolt &beam) +{ + return YOU_KILL(beam.thrower)? 0 : beam.beam_source; +} + // A little helper function to handle the calling of ouch()... static void beam_ouch( int dam, struct bolt &beam ) { @@ -3283,6 +3338,14 @@ static int affect_player( struct bolt &beam ) } } + if (strstr(beam.beam_name, "curare")) + { + if (random2(100) < 90 - (3 * player_AC())) + { + curare_hits_player( beam_ouch_agent(beam), 1 + random2(3) ); + } + } + // sticky flame if (strcmp(beam.beam_name, "sticky flame") == 0 && (you.species != SP_MOTTLED_DRACONIAN @@ -3508,29 +3571,16 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) if (nasty_beam(mon, beam)) { - bool annoyed = false; - if (YOU_KILL(beam.thrower)) { if (mons_friendly(mon)) - { did_god_conduct( DID_ATTACK_FRIEND, 5 ); - if (hurt_final > mon->hit_dice / 3) - annoyed = true; - } - else - { - annoyed = true; - } if (mons_holiness( mon ) == MH_HOLY) did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice ); } - if (annoyed) - { - behaviour_event(mon, ME_ANNOY, beam_source(beam) ); - } + behaviour_event(mon, ME_ANNOY, beam_source(beam) ); } // explosions always 'hit' @@ -3625,7 +3675,14 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) } } - if (mons_is_mimic( mon->type )) + bool wake_mimic = true; + if (strstr(beam.beam_name, "curare")) + { + if (curare_hits_monster( beam, mon, YOU_KILL(beam.thrower), 2 )) + wake_mimic = false; + } + + if (wake_mimic && mons_is_mimic( mon->type )) mimic_alert(mon); } diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 145edf2e77..eb2bc068d2 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -64,7 +64,7 @@ static const char *features[] = { void version(void) { - mpr( "This is Dungeon Crawl Stone Soup " VERSION " (Last build " BUILD_DATE ")." ); + mpr( "This is Dungeon Crawl Stone Soup " VERSION " (" BUILD_DATE ")." ); std::string feats = "Features: "; for (int i = 1, size = sizeof features / sizeof *features; i < size; ++i) diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index d7d51abacb..eaeed683ff 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -148,6 +148,12 @@ static int vault_grid( int level_number, int vx, int vy, int altar_count, static int pick_an_altar(void); static void place_altar(void); +static bool got_curare_roll(const int item_level) +{ + return one_chance_in(item_level > 27? 2 : + item_level < 2 ? 8 : + (45 - item_level) / 9); +} /* ************************************************** @@ -1366,7 +1372,11 @@ int items( int allow_uniques, // not just true-false, if (mitm[p].sub_type == MI_NEEDLE && (item_level == MAKE_GOOD_ITEM || !one_chance_in(5))) { - set_item_ego_type( mitm[p], OBJ_MISSILES, SPMSL_POISONED_II ); + const int pois = + item_level == MAKE_GOOD_ITEM || + got_curare_roll(item_level) + ? SPMSL_CURARE : SPMSL_POISONED_II; + set_item_ego_type( mitm[p], OBJ_MISSILES, pois ); } else { @@ -2569,7 +2579,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes { case MONS_KOBOLD: // a few of the smarter kobolds have blowguns. - if (one_chance_in(15) && level_number > 1) + if (one_chance_in(10) && level_number > 1) { mitm[bp].base_type = OBJ_WEAPONS; mitm[bp].sub_type = WPN_BLOWGUN; @@ -3163,7 +3173,10 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes // monsters will always have poisoned needles -- otherwise // they are just going to behave badly --GDL if (xitt == MI_NEEDLE) - set_item_ego_type(mitm[thing_created], OBJ_MISSILES, SPMSL_POISONED); + set_item_ego_type(mitm[thing_created], OBJ_MISSILES, + got_curare_roll(give_level)? + SPMSL_CURARE + : SPMSL_POISONED); mitm[thing_created].x = 0; mitm[thing_created].y = 0; diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index c59fee8efa..0fa37aa2cc 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -1376,6 +1376,8 @@ enum KILLBY KILLED_BY_SOMETHING, KILLED_BY_FALLING_DOWN_STAIRS, KILLED_BY_ACID, + KILLED_BY_CURARE, + NUM_KILLBY }; @@ -2584,7 +2586,8 @@ enum SPECIAL_MISSILES // to separate from weapons in general {dlb} SPMSL_FLAME, // 1 SPMSL_ICE, // 2 SPMSL_POISONED, // 3 - from poison_ammo() enchantment {dlb} - SPMSL_POISONED_II // 4 + SPMSL_POISONED_II, // 4 + SPMSL_CURARE // 5 }; enum SPECIAL_ROOMS diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc index ab84678410..9bbd391d41 100644 --- a/crawl-ref/source/hiscores.cc +++ b/crawl-ref/source/hiscores.cc @@ -325,6 +325,10 @@ void hiscores_format_single(char *buf, struct scorefile_entry &se) break; */ + case KILLED_BY_CURARE: + strcat( buf, " asphyxiated"); + break; + case KILLED_BY_LAVA: if (se.race == SP_MUMMY) strcat( buf, " turned to ash by lava" ); @@ -713,6 +717,10 @@ int hiscores_format_single_long( char *buf, struct scorefile_entry &se, } break; + case KILLED_BY_CURARE: + strcat(buf, "Asphyxiated"); + break; + case KILLED_BY_LAVA: if (se.race == SP_MUMMY) strcat( buf, "Turned to ash by lava" ); @@ -1670,6 +1678,8 @@ static void hs_search_death(char *inbuf, struct scorefile_entry &se) se.death_type = KILLED_BY_BEAM; else if (strstr(inbuf, "took a swim in molten lava") != NULL) se.death_type = KILLED_BY_LAVA; + else if (strstr(inbuf, "asphyxiated")) + se.death_type = KILLED_BY_CURARE; else if (strstr(inbuf, "soaked and fell apart") != NULL) { se.death_type = KILLED_BY_WATER; diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index a2dbfe1fdd..2307435db5 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -1199,18 +1199,8 @@ static void throw_it(struct bolt &pbolt, int throw_2) bool launched = false; // item is launched bool thrown = false; // item is sensible thrown 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); - - char str_pass[ ITEMNAME_SIZE ]; - mpr( STD_DIRECTION_PROMPT, MSGCH_PROMPT ); - message_current_target(); - direction( thr, DIR_NONE, TARG_ENEMY ); if (!thr.isValid) @@ -1221,6 +1211,23 @@ static void throw_it(struct bolt &pbolt, int throw_2) return; } + // Must unwield before fire_beam() makes a copy in order to remove things + // like temporary branding. -- bwr + if (throw_2 == you.equip[EQ_WEAPON] && you.inv[throw_2].quantity == 1) + { + unwield_item( throw_2 ); + you.equip[EQ_WEAPON] = -1; + canned_msg( MSG_EMPTY_HANDED ); + } + + // 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); + + char str_pass[ ITEMNAME_SIZE ]; + if (you.conf) { thr.isTarget = true; @@ -1713,15 +1720,6 @@ static void throw_it(struct bolt &pbolt, int throw_2) mpr( info, MSGCH_DIAGNOSTICS ); #endif - // Must unwield before fire_beam() makes a copy in order to remove things - // like temporary branding. -- bwr - if (throw_2 == you.equip[EQ_WEAPON] && you.inv[throw_2].quantity == 1) - { - unwield_item( throw_2 ); - you.equip[EQ_WEAPON] = -1; - canned_msg( MSG_EMPTY_HANDED ); - } - // create message if (launched) strcpy(info, "You shoot "); diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 43c782bbb5..9d9955cb51 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -819,6 +819,11 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], { strncat( buff, (terse) ? "poison " : "poisoned ", ITEMNAME_SIZE ); } + + if (brand == SPMSL_CURARE) + { + strncat( buff, (terse) ? "curare " : "curare-tipped ", ITEMNAME_SIZE); + } if (item_ident( item, ISFLAG_KNOW_PLUSES )) { @@ -862,7 +867,9 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], (brand == SPMSL_ICE) ? ((terse) ? " (ice)" : " of ice") : (brand == SPMSL_NORMAL) ? "" : (brand == SPMSL_POISONED) ? "" : - (brand == SPMSL_POISONED_II) ? "" : " (buggy)", ITEMNAME_SIZE ); + (brand == SPMSL_POISONED_II) ? "" : + (brand == SPMSL_CURARE) ? "" : + " (buggy)", ITEMNAME_SIZE ); } break; diff --git a/crawl-ref/source/libw32c.cc b/crawl-ref/source/libw32c.cc index 8426b82b53..975e14e641 100644 --- a/crawl-ref/source/libw32c.cc +++ b/crawl-ref/source/libw32c.cc @@ -338,7 +338,7 @@ void init_libw32c(void) } GetConsoleTitle( oldTitle, 78 ); - SetConsoleTitle( "Crawl " VERSION ); + SetConsoleTitle( "Crawl Stone Soup " VERSION ); init_colors(oldTitle); diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 24445e241f..e349621b61 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -355,6 +355,27 @@ void in_a_cloud(void) return; } // end in_a_cloud() +void curare_hits_player(int agent, int degree) +{ + const bool res_poison = player_res_poison(); + + poison_player(degree); + + if (!player_res_asphyx()) + { + int hurted = roll_dice(2, 6); + // Note that the hurtage is halved by poison resistance. + if (res_poison) + hurted /= 2; + + if (hurted) + { + mpr("You feel difficulty breathing."); + ouch( hurted, agent, KILLED_BY_CURARE, "curare-induced apnoea" ); + } + potion_effect(POT_SLOWING, 2 + random2(4 + degree)); + } +} void merfolk_start_swimming(void) { diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index d444764b4b..dee5163d6a 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -135,4 +135,6 @@ bool grid_destroys_items( unsigned char grid ); const char *grid_item_destruction_message( unsigned char grid ); +void curare_hits_player(int agent, int degree); + #endif diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 7f1c28f148..73e10916af 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -143,7 +143,7 @@ void mons_init(FixedVector < unsigned short, 1000 > &colour) //return (monsterentry *) 0; // return value should not matter here {dlb} } // end mons_init() -unsigned long mons_class_resist(int mc) +unsigned long get_mons_class_resists(int mc) { return (smc->resists); } @@ -445,7 +445,7 @@ int mons_res_elec( struct monsters *mon ) /* this is a variable, not a player_xx() function, so can be above 1 */ int u = 0; - if (mons_class_resist(MR_RES_ELEC)) + if (mons_class_resist( mon->type, MR_RES_ELEC)) u++; // don't bother checking equipment if the monster can't use it @@ -465,12 +465,19 @@ int mons_res_elec( struct monsters *mon ) return (u); } // end mons_res_elec() +bool mons_res_asphyx( const monsters *mon ) +{ + const int holiness = mons_holiness( mon->type ); + return (holiness == MH_UNDEAD + || holiness == MH_DEMONIC + || holiness == MH_NONLIVING); +} int mons_res_poison( struct monsters *mon ) { int mc = mon->type; - int u = 0, f = mons_class_resist(mc); + int u = 0, f = get_mons_class_resists(mc); if (f & MR_RES_POISON) u++; @@ -510,7 +517,7 @@ int mons_res_fire( struct monsters *mon ) if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON) return (ghost.values[ GVAL_RES_FIRE ]); - int u = 0, f = mons_class_resist(mc); + int u = 0, f = get_mons_class_resists(mc); // no Big Prize (tm) here either if you set all three flags. It's a pity uh? // @@ -558,7 +565,7 @@ int mons_res_cold( struct monsters *mon ) if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON) return (ghost.values[ GVAL_RES_COLD ]); - int u = 0, f = mons_class_resist(mc); + int u = 0, f = get_mons_class_resists(mc); // Note that natural monster resistance is two levels, this is duplicate // the fact that having this flag used to be a lot better than armour diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 7a4b37a14b..c22b1a0442 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -277,6 +277,8 @@ int mons_res_poison( struct monsters *mon ); int mons_res_negative_energy( struct monsters *mon ); +bool mons_res_asphyx( const monsters *mon ); + // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc index fd54adede1..5c24984a06 100644 --- a/crawl-ref/source/newgame.cc +++ b/crawl-ref/source/newgame.cc @@ -1422,6 +1422,7 @@ bool class_allowed( unsigned char speci, int char_class ) case SP_HUMAN: case SP_DEMIGOD: case SP_DEMONSPAWN: + case SP_GHOUL: return true; } return false; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index f14274f2a8..5a4edebd21 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -810,6 +810,24 @@ int player_res_electricity(bool calc_unid) return (re); } // end player_res_electricity() +// Does the player resist asphyxiation? +bool player_res_asphyx() +{ + // The undead are immune to asphyxiation, or so we'll assume. + if (you.is_undead) + return (true); + + switch (you.attribute[ATTR_TRANSFORMATION]) + { + case TRAN_LICH: + case TRAN_STATUE: + case TRAN_SERPENT_OF_HELL: + case TRAN_AIR: + return (true); + } + return (false); +} + // funny that no races are susceptible to poisons {dlb} int player_res_poison(bool calc_unid) { diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index ff7c06835a..4b2feced38 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -171,6 +171,8 @@ int player_res_poison(bool calc_unid = true); int player_res_magic(void); +bool player_res_asphyx(); + /* *********************************************************************** * called from: beam - chardump - fight - misc - output * *********************************************************************** */ diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 3f4ccaf418..b8bb4a78d4 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -620,6 +620,9 @@ bool brand_weapon(int which_brand, int power) strcat( info, coinflip() ? " oddly." : " strangely." ); duration_affected = 5; + // [dshaligram] Clamping power to 2. + power = 2; + // This brand is insanely powerful, this isn't even really // a start to balancing it, but it needs something. -- bwr // [dshaligram] At level 7 it's costly enough to experiment diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index c6cd3cb185..f162e31cfe 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -145,8 +145,8 @@ static int spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] = SPELL_CONDENSATION_SHIELD, SPELL_BOLT_OF_COLD, SPELL_OZOCUBUS_REFRIGERATION, - SPELL_MASS_SLEEP, SPELL_SIMULACRUM, + SPELL_MASS_SLEEP, SPELL_NO_SPELL, }, @@ -332,15 +332,10 @@ static int spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] = SPELL_BACKLIGHT, SPELL_REPEL_MISSILES, SPELL_SLEEP, -#ifdef USE_SILENCE_CODE - SPELL_SILENCE, -#endif SPELL_CONFUSE, SPELL_ENSLAVEMENT, + SPELL_SILENCE, SPELL_INVISIBILITY, -#ifndef USE_SILENCE_CODE - SPELL_NO_SPELL, -#endif SPELL_NO_SPELL, }, // 27 - Book of Demonology -- Vehumet special @@ -383,19 +378,14 @@ static int spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] = // 29 - Book of the Sky {0, -#ifdef USE_SILENCE_CODE - SPELL_SILENCE, -#endif SPELL_SUMMON_ELEMENTAL, SPELL_INSULATION, SPELL_AIRSTRIKE, SPELL_FLY, + SPELL_SILENCE, SPELL_DEFLECT_MISSILES, SPELL_LIGHTNING_BOLT, SPELL_CONJURE_BALL_LIGHTNING, -#ifndef USE_SILENCE_CODE - SPELL_NO_SPELL, -#endif }, // 30 - Book of Divinations @@ -411,11 +401,11 @@ static int spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] = }, // 31 - Book of the Warp {0, - SPELL_CONTROLLED_BLINK, SPELL_BANISHMENT, SPELL_WARP_BRAND, SPELL_DISPERSAL, SPELL_PORTAL, + SPELL_CONTROLLED_BLINK, SPELL_NO_SPELL, SPELL_NO_SPELL, SPELL_NO_SPELL, |