fixed some bugs in new 'g'o system
[k8-i-v-a-n.git] / src / game / items / item_wand.cpp
blob6b20547772f39b63437a83a812076ef8fd9f30da
1 #ifdef HEADER_PHASE
2 ITEM(wand, item)
4 public:
5 virtual truth Apply(character*);
6 virtual void Save(outputfile&) const;
7 virtual void Load(inputfile&);
8 virtual void ChargeFully(character*) { TimesUsed = 0; }
9 virtual truth IsAppliable(ccharacter*) const { return true; }
10 virtual truth IsZappable(ccharacter*) const { return true; }
11 virtual truth IsChargeable(ccharacter*) const { return true; }
12 virtual truth ReceiveDamage(character*, int, int, int);
13 virtual truth Zap(character*, v2, int);
14 virtual void AddInventoryEntry(ccharacter*, festring&, int, truth) const;
15 virtual sLong GetPrice() const;
16 virtual truth IsExplosive() const { return true; }
17 protected:
18 virtual void PostConstruct();
19 void BreakEffect(character*, cfestring&);
20 feuLong GetSpecialParameters() const;
21 int Charges;
22 int TimesUsed;
26 #else
30 sLong wand::GetPrice() const { return Charges > TimesUsed ? item::GetPrice() : 0; }
34 truth wand::Apply(character* Terrorist)
36 if(Terrorist->IsPlayer() && !game::TruthQuestion(CONST_S("Are you sure you want to break ") + GetName(DEFINITE) + "? [y/N]"))
37 return false;
39 if(Terrorist->IsPlayer())
40 ADD_MESSAGE("You bend %s with all your strength.", CHAR_NAME(DEFINITE));
41 else if(Terrorist->CanBeSeenByPlayer())
42 ADD_MESSAGE("%s bends %s with all %s strength.", Terrorist->CHAR_NAME(DEFINITE), CHAR_NAME(INDEFINITE), Terrorist->CHAR_POSSESSIVE_PRONOUN);
44 if(Terrorist->IsPlayer() || Terrorist->CanBeSeenByPlayer())
45 ADD_MESSAGE("%s %s.", CHAR_NAME(DEFINITE), GetBreakMsg().CStr());
47 BreakEffect(Terrorist, CONST_S("killed by ") + GetName(INDEFINITE) + " broken @bk");
48 Terrorist->DexterityAction(5);
49 return true;
54 void wand::Save(outputfile& SaveFile) const
56 item::Save(SaveFile);
57 SaveFile << TimesUsed << Charges;
62 void wand::Load(inputfile& SaveFile)
64 item::Load(SaveFile);
65 SaveFile >> TimesUsed >> Charges;
70 truth wand::ReceiveDamage(character* Damager, int Damage, int Type, int)
72 if(Type & (FIRE|ENERGY|PHYSICAL_DAMAGE) && Damage && (Damage > 125 || !(RAND() % (250 / Damage))))
74 festring DeathMsg = CONST_S("killed by an explosion of ");
75 AddName(DeathMsg, INDEFINITE);
77 if(Damager)
78 DeathMsg << " caused @bk";
80 if(CanBeSeenByPlayer())
81 ADD_MESSAGE("%s %s.", GetExtendedDescription().CStr(), GetBreakMsg().CStr());
83 BreakEffect(Damager, DeathMsg);
84 return true;
87 return false;
92 void wand::PostConstruct()
94 Charges = GetMinCharges() + RAND() % (GetMaxCharges() - GetMinCharges() + 1);
95 TimesUsed = 0;
100 truth wand::Zap(character* Zapper, v2, int Direction)
102 if(Charges <= TimesUsed)
104 ADD_MESSAGE("Nothing happens.");
105 return true;
108 Zapper->EditExperience(PERCEPTION, 150, 1 << 10);
110 beamdata Beam
112 Zapper,
113 CONST_S("killed by ") + GetName(INDEFINITE) + " zapped @bk",
114 Zapper->GetPos(),
115 GetBeamColor(),
116 GetBeamEffect(),
117 Direction,
118 GetBeamRange(),
119 GetSpecialParameters()
122 (GetLevel()->*level::GetBeam(GetBeamStyle()))(Beam);
123 ++TimesUsed;
124 return true;
129 void wand::AddInventoryEntry (ccharacter*, festring& Entry, int, truth ShowSpecialInfo) const { // never piled
130 AddName(Entry, INDEFINITE);
131 if (ShowSpecialInfo) {
132 Entry << " [" << GetWeight();
133 if (TimesUsed == 1) Entry << "g, used 1 time]";
134 else if (TimesUsed) Entry << "g, used " << TimesUsed << " times]";
135 else Entry << "g]";
141 void wand::BreakEffect(character* Terrorist, cfestring& DeathMsg)
143 v2 Pos = GetPos();
144 level* Level = GetLevel();
145 RemoveFromSlot();
146 feuLong StackSize = Level->AddRadiusToSquareStack(Pos, GetBreakEffectRangeSquare());
147 lsquare** SquareStack = Level->GetSquareStack();
148 feuLong c;
150 for(c = 0; c < StackSize; ++c)
151 SquareStack[c]->RemoveFlags(IN_SQUARE_STACK);
153 fearray<lsquare*> Stack(SquareStack, StackSize);
154 (Level->*level::GetBeamEffectVisualizer(GetBeamStyle()))(Stack, GetBeamColor());
156 beamdata Beam
158 Terrorist,
159 DeathMsg,
160 YOURSELF,
161 GetSpecialParameters()
164 for(c = 0; c < Stack.Size; ++c)
165 (Stack[c]->*lsquare::GetBeamEffect(GetBeamEffect()))(Beam);
167 SendToHell();
172 feuLong wand::GetSpecialParameters() const
174 switch(GetConfig())
176 case WAND_OF_MIRRORING:
177 return MIRROR_IMAGE|(1000 << LE_BASE_SHIFT)|(1000 << LE_RAND_SHIFT);
180 return 0;
182 #endif