1743 |
namespace |
namespace |
1744 |
{ |
{ |
1745 |
class Burnable : public Item { |
class Burnable : public Item { |
1746 |
CLONEOBJ(Burnable); |
CLONEOBJ(Burnable); |
1747 |
public: |
public: |
1748 |
enum State { IDLE, IGNITE, BURNING, FIREPROOF, ASH }; |
enum State { IDLE, IGNITE, BURNING, FIREPROOF, ASH }; |
1749 |
Burnable( State initstate=IDLE): Item("it-burnable") { |
Burnable( State initstate=IDLE): Item("it-burnable") { |
1750 |
state = initstate; |
state = initstate; |
1751 |
} |
} |
1752 |
private: |
private: |
1753 |
State state; |
State state; |
|
|
|
|
void message(const string &msg, const Value &) { |
|
|
if ((msg == "trigger" || msg == "ignite") && state==IDLE) { |
|
|
state = IGNITE; // start burning |
|
|
init_model(); |
|
|
} else if (msg == "extinguish") { // stop / never start burning |
|
|
state = FIREPROOF; |
|
|
init_model(); |
|
|
} else if (msg == "brush" && (state == ASH || state == FIREPROOF)) { |
|
|
KillItem(get_pos()); // The brush will clean the floor |
|
|
} |
|
|
} |
|
|
|
|
|
void animcb() { |
|
|
GridPos p = get_pos(); |
|
|
if (state == IGNITE || state == BURNING) { |
|
|
bool spread = true; |
|
|
if( Stone *st = GetStone( p)) { |
|
|
if( ! st->is_floating()) |
|
|
spread = false; // only hollow stones allow the fire to spread |
|
|
|
|
|
string model = st->get_kind(); |
|
|
if( model == "st-wood1" || model == "st-wood2") { |
|
|
KillStone( p); // The fire has burnt away the wooden stone |
|
|
spread = true; |
|
|
} |
|
|
} |
|
|
|
|
|
// spread to neighbouring tiles |
|
|
if( spread) { |
|
|
if( DoubleRand(0, 1) > 0.3) ignite (move(p, NORTH)); |
|
|
if( DoubleRand(0, 1) > 0.3) ignite (move(p, EAST)); |
|
|
if( DoubleRand(0, 1) > 0.3) ignite (move(p, SOUTH)); |
|
|
if( DoubleRand(0, 1) > 0.3) ignite (move(p, WEST)); |
|
|
} |
|
|
} |
|
|
if (state == IGNITE) { |
|
|
if( Floor *fl = GetFloor( p)) { // The fire has burnt away the wooden floor |
|
|
string model = fl->get_kind(); |
|
|
if( model == "fl-wood" || model == "fl-stwood") |
|
|
SetFloor( p, MakeFloor("fl-abyss")); |
|
|
} |
|
|
state = BURNING; |
|
|
init_model(); |
|
|
} else if (state == BURNING) { // stop burning after some random time |
|
|
if( DoubleRand(0, 1) > 0.7) |
|
|
state = ASH; |
|
|
else |
|
|
state = BURNING; |
|
|
|
|
|
init_model(); |
|
|
} |
|
|
} |
|
|
void init_model() { |
|
|
switch (state) { |
|
|
case IDLE: set_model("invisible"); break; |
|
|
case IGNITE: set_anim("it-burnable_ignite"); break; |
|
|
case BURNING: set_anim("it-burnable_burning"); break; |
|
|
case FIREPROOF: set_model("it-burnable_fireproof"); break; |
|
|
case ASH: set_model("it-burnable_ash"); break; |
|
|
} |
|
|
} |
|
|
|
|
|
bool actor_hit(Actor *a) { |
|
|
if (state == IGNITE || state == BURNING) |
|
|
SendMessage(a, "shatter"); |
|
|
return false; |
|
|
} |
|
1754 |
|
|
1755 |
void ignite( GridPos p) { |
void message(const string &msg, const Value &) { |
1756 |
bool only_ignite = false; |
if ((msg == "trigger" || msg == "ignite") && state==IDLE) { |
1757 |
|
state = IGNITE; // start burning |
1758 |
if( Stone *st = GetStone( p)) { |
init_model(); |
1759 |
if( ! st->is_floating() && ! st->is_movable()) |
} else if (msg == "extinguish") { // stop / never start burning |
1760 |
return; // Stone does not allow to ignite. |
state = FIREPROOF; |
1761 |
if( st->is_movable()) |
init_model(); |
1762 |
only_ignite = true; // only ignit burnable items |
} else if (msg == "brush" && (state == ASH || state == FIREPROOF)) { |
1763 |
} |
KillItem(get_pos()); // The brush will clean the floor |
1764 |
|
} |
1765 |
if (Item *it = GetItem(p)) { // spread to other items |
} |
1766 |
string model = it->get_kind(); |
|
1767 |
// ignite burnable items |
void animcb() { |
1768 |
if( model=="it-burnable" || model=="it-dynamite" |
GridPos p = get_pos(); |
1769 |
|| model=="it-blackbomb" || model=="it-whitebomb") |
if (state == IGNITE || state == BURNING) { |
1770 |
SendMessage (it, "ignite"); |
bool spread = true; |
1771 |
// cracks are not strong enought |
if( Stone *st = GetStone( p)) { |
1772 |
else if( model=="it-crack") |
if( ! st->is_floating()) |
1773 |
SetItem( p, MakeItem("it-debris")); |
spread = false; // only hollow stones allow the fire to spread |
1774 |
// all other items except some fire-proof ones will burn |
|
1775 |
else if (model != "it-extinguisher" && model != "it-hill" && model != "it-hollow" |
string model = st->get_kind(); |
1776 |
&& model != "it-tinyhill" && model != "it-tinyhollow") { |
if( model == "st-wood1" || model == "st-wood2") { |
1777 |
SetItem( p, MakeItem("it-burnable-ignited")); |
KillStone( p); // The fire has burnt away the wooden stone |
1778 |
//SendMessage (it, "ignite"); |
spread = true; |
1779 |
} |
} |
1780 |
} else if( ! only_ignite){ // spread on the same floor (if stone allows) |
} |
1781 |
if( Floor *fl1 = GetFloor( get_pos())) { |
|
1782 |
string model1 = fl1->get_kind(); |
// spread to neighbouring tiles |
1783 |
if( Floor *fl2 = GetFloor( p)) { |
if( spread) { |
1784 |
string model2 = fl2->get_kind(); |
if( DoubleRand(0, 1) > 0.3) ignite (move(p, NORTH)); |
1785 |
if( model1 == model2) |
if( DoubleRand(0, 1) > 0.3) ignite (move(p, EAST)); |
1786 |
SetItem( p, MakeItem("it-burnable")); |
if( DoubleRand(0, 1) > 0.3) ignite (move(p, SOUTH)); |
1787 |
} |
if( DoubleRand(0, 1) > 0.3) ignite (move(p, WEST)); |
1788 |
} |
} |
1789 |
} |
} |
1790 |
} |
if (state == IGNITE) { |
1791 |
|
if( Floor *fl = GetFloor( p)) { // The fire has burnt away the wooden floor |
1792 |
|
string model = fl->get_kind(); |
1793 |
|
if( model == "fl-wood" || model == "fl-stwood") |
1794 |
|
SetFloor( p, MakeFloor("fl-abyss")); |
1795 |
|
} |
1796 |
|
state = BURNING; |
1797 |
|
init_model(); |
1798 |
|
} else if (state == BURNING) { // stop burning after some random time |
1799 |
|
if( DoubleRand(0, 1) > 0.7) |
1800 |
|
state = ASH; |
1801 |
|
else |
1802 |
|
state = BURNING; |
1803 |
|
|
1804 |
|
init_model(); |
1805 |
|
} |
1806 |
|
} |
1807 |
|
void init_model() { |
1808 |
|
switch (state) { |
1809 |
|
case IDLE: set_model("invisible"); break; |
1810 |
|
case IGNITE: set_anim("it-burnable_ignite"); break; |
1811 |
|
case BURNING: set_anim("it-burnable_burning"); break; |
1812 |
|
case FIREPROOF: set_model("it-burnable_fireproof"); break; |
1813 |
|
case ASH: set_model("it-burnable_ash"); break; |
1814 |
|
} |
1815 |
|
} |
1816 |
|
|
1817 |
|
bool actor_hit(Actor *a) { |
1818 |
|
if (state == IGNITE || state == BURNING) |
1819 |
|
SendMessage(a, "shatter"); |
1820 |
|
return false; |
1821 |
|
} |
1822 |
|
|
1823 |
|
void ignite( GridPos p) { |
1824 |
|
bool only_ignite = false; |
1825 |
|
|
1826 |
|
if( Stone *st = GetStone( p)) { |
1827 |
|
if( ! st->is_floating() && ! st->is_movable()) |
1828 |
|
return; // Stone does not allow to ignite. |
1829 |
|
if( st->is_movable()) |
1830 |
|
only_ignite = true; // only ignit burnable items |
1831 |
|
} |
1832 |
|
|
1833 |
|
if (Item *it = GetItem(p)) { // spread to other items |
1834 |
|
string model = it->get_kind(); |
1835 |
|
// ignite burnable items |
1836 |
|
if( model=="it-burnable" || model=="it-dynamite" |
1837 |
|
|| model=="it-blackbomb" || model=="it-whitebomb") |
1838 |
|
SendMessage (it, "ignite"); |
1839 |
|
// cracks are not strong enought |
1840 |
|
else if( model=="it-crack") |
1841 |
|
SetItem( p, MakeItem("it-debris")); |
1842 |
|
// all other items except some fire-proof ones will burn |
1843 |
|
else if (model != "it-extinguisher" && model != "it-hill" && model != "it-hollow" |
1844 |
|
&& model != "it-tinyhill" && model != "it-tinyhollow") { |
1845 |
|
SetItem( p, MakeItem("it-burnable-ignited")); |
1846 |
|
//SendMessage (it, "ignite"); |
1847 |
|
} |
1848 |
|
} else if (!only_ignite) { // spread on the same floor (if stone allows) |
1849 |
|
if( Floor *fl1 = GetFloor( get_pos())) { |
1850 |
|
string model1 = fl1->get_kind(); |
1851 |
|
if( Floor *fl2 = GetFloor( p)) { |
1852 |
|
string model2 = fl2->get_kind(); |
1853 |
|
if( model1 == model2) |
1854 |
|
SetItem( p, MakeItem("it-burnable")); |
1855 |
|
} |
1856 |
|
} |
1857 |
|
} |
1858 |
|
} |
1859 |
}; |
}; |
1860 |
} |
} |
1861 |
|
|
1907 |
ItemAction |
ItemAction |
1908 |
Extinguisher::activate(Actor *a, GridPos p) |
Extinguisher::activate(Actor *a, GridPos p) |
1909 |
{ |
{ |
1910 |
if( get_load() > 0) { |
if (get_load() > 0) { |
1911 |
extinguish (p); |
extinguish (p); |
1912 |
extinguish (move(p, NORTH)); |
extinguish (move(p, NORTH)); |
1913 |
extinguish (move(p, SOUTH)); |
extinguish (move(p, SOUTH)); |
1914 |
extinguish (move(p, EAST)); |
extinguish (move(p, EAST)); |
1915 |
extinguish (move(p, WEST)); |
extinguish (move(p, WEST)); |
1916 |
if( get_load() > 1) { |
if (get_load() > 1) { |
1917 |
// full extinguisher have a higher range |
// full extinguisher has a larger range |
1918 |
extinguish (move(move(p, NORTH),NORTH)); |
extinguish (move(move(p, NORTH),NORTH)); |
1919 |
extinguish (move(move(p, NORTH),EAST)); |
extinguish (move(move(p, NORTH),EAST)); |
1920 |
extinguish (move(move(p, SOUTH),SOUTH)); |
extinguish (move(move(p, SOUTH),SOUTH)); |
1931 |
if (player::Inventory *inv = player::GetInventory(a)) { |
if (player::Inventory *inv = player::GetInventory(a)) { |
1932 |
inv->redraw(); |
inv->redraw(); |
1933 |
} |
} |
|
|
|
|
//init_model(); |
|
1934 |
} |
} |
1935 |
return ITEM_DROP; |
return ITEM_DROP; |
1936 |
} |
} |