3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
13 /* Compiled through itemset.cpp */
15 void meleeweapon::SetSecondaryMaterial(material
* What
, int SpecialFlags
) { SetMaterial(SecondaryMaterial
, What
, GetDefaultSecondaryVolume(), SpecialFlags
); }
16 void meleeweapon::ChangeSecondaryMaterial(material
* What
, int SpecialFlags
) { ChangeMaterial(SecondaryMaterial
, What
, GetDefaultSecondaryVolume(), SpecialFlags
); }
17 void meleeweapon::InitMaterials(material
* M1
, material
* M2
, truth CUP
) { ObjectInitMaterials(MainMaterial
, M1
, GetDefaultMainVolume(), SecondaryMaterial
, M2
, GetDefaultSecondaryVolume(), CUP
); }
18 double meleeweapon::GetTHVBonus() const { return Enchantment
* .5; }
19 double meleeweapon::GetDamageBonus() const { return Enchantment
; }
20 col16
meleeweapon::GetDripColor() const { return Fluid
[0]->GetLiquid()->GetColor(); }
21 truth
meleeweapon::IsDippable(ccharacter
*) const { return !Fluid
; }
22 truth
meleeweapon::AllowRegularColors() const { return SecondaryMaterial
->GetVolume(); }
23 v2
meleeweapon::GetWieldedBitmapPos(int I
) const { return SecondaryMaterial
->GetVolume() ? item::GetWieldedBitmapPos(I
) : v2(160, 128); }
24 void meleeweapon::InitMaterials(const materialscript
* M
, const materialscript
* S
, truth CUP
) { InitMaterials(M
->Instantiate(), S
->Instantiate(), CUP
); }
26 col16
justifier::GetOutlineColor(int) const { return MakeRGB16(0, 255, 0); }
28 col16
neercseulb::GetOutlineColor(int) const { return MakeRGB16(255, 0, 0); }
30 int flamingsword::GetSpecialFlags() const { return meleeweapon::GetSpecialFlags()|ST_FLAME_1
; }
32 col16
gorovitsweapon::GetOutlineColor(int) const { return MakeRGB16(255, 0, 0); }
34 int thunderhammer::GetSpecialFlags() const { return !IsBroken() ? meleeweapon::GetSpecialFlags()|ST_LIGHTNING
: meleeweapon::GetSpecialFlags(); }
36 int armor::GetCarryingBonus() const { return Enchantment
<< 1; }
37 double armor::GetTHVBonus() const { return Enchantment
* .5; }
38 double armor::GetDamageBonus() const { return Enchantment
; }
40 sLong
bodyarmor::GetPrice() const { return (armor::GetPrice() << 3) + GetEnchantedPrice(Enchantment
); }
41 truth
bodyarmor::IsInCorrectSlot(int I
) const { return I
== BODY_ARMOR_INDEX
; }
42 cfestring
& bodyarmor::GetNameSingular() const { return GetMainMaterial()->GetFlexibility() >= 5 ? item::GetFlexibleNameSingular() : item::GetNameSingular(); }
43 cchar
* bodyarmor::GetBreakVerb() const { return GetMainMaterial()->GetFlexibility() >= 5 ? "is torn apart" : "breaks"; }
45 col16
goldeneagleshirt::GetOutlineColor(int) const { return MakeRGB16(0, 255, 255); }
47 sLong
cloak::GetPrice() const { return armor::GetPrice() * 10 + GetEnchantedPrice(Enchantment
); }
48 truth
cloak::IsInCorrectSlot(int I
) const { return I
== CLOAK_INDEX
; }
49 col16
cloak::GetMaterialColorB(int) const { return MakeRGB16(111, 64, 37); }
50 cchar
* cloak::GetBreakVerb() const { return GetMainMaterial()->GetFlexibility() >= 5 ? "is torn apart" : "breaks"; }
51 truth
cloak::ReceiveDamage(character
* Damager
, int Damage
, int Type
, int Dir
) { return armor::ReceiveDamage(Damager
, Damage
>> 1, Type
, Dir
); }
52 int cloak::GetSpecialFlags() const { return ST_CLOAK
; }
54 sLong
boot::GetPrice() const { return armor::GetPrice() / 5 + GetEnchantedPrice(Enchantment
); }
55 truth
boot::IsInCorrectSlot(int I
) const { return I
== RIGHT_BOOT_INDEX
|| I
== LEFT_BOOT_INDEX
; }
57 sLong
gauntlet::GetPrice() const { return armor::GetPrice() / 3 + GetEnchantedPrice(Enchantment
); }
58 truth
gauntlet::IsInCorrectSlot(int I
) const { return I
== RIGHT_GAUNTLET_INDEX
|| I
== LEFT_GAUNTLET_INDEX
; }
60 sLong
belt::GetPrice() const { return armor::GetPrice() * 5 + GetEnchantedPrice(Enchantment
); }
61 truth
belt::IsInCorrectSlot(int I
) const { return I
== BELT_INDEX
; }
63 truth
ring::IsInCorrectSlot(int I
) const { return I
== RIGHT_RING_INDEX
|| I
== LEFT_RING_INDEX
; }
64 col16
ring::GetMaterialColorB(int) const { return MakeRGB16(200, 200, 200); }
66 truth
amulet::IsInCorrectSlot(int I
) const { return I
== AMULET_INDEX
; }
67 col16
amulet::GetMaterialColorB(int) const { return MakeRGB16(111, 64, 37); }
69 truth
helmet::IsGorovitsFamilyRelic() const { return GetConfig() == GOROVITS_FAMILY_GAS_MASK
; }
70 sLong
helmet::GetPrice() const { return armor::GetPrice() + GetEnchantedPrice(Enchantment
); }
71 truth
helmet::IsInCorrectSlot(int I
) const { return I
== HELMET_INDEX
; }
72 col16
helmet::GetMaterialColorB(int) const { return GetConfig() != GOROVITS_FAMILY_GAS_MASK
? (GetConfig() & ~BROKEN
) ? MakeRGB16(140, 70, 70) : MakeRGB16(111, 64, 37) : MakeRGB16(0, 40, 0); }
73 col16
helmet::GetMaterialColorC(int) const { return MakeRGB16(180, 200, 180); }
75 int wondersmellstaff::GetClassAnimationFrames() const { return !IsBroken() ? 128 : 1; }
77 truth
meleeweapon::HitEffect(character
* Enemy
, character
*, v2
, int BodyPartIndex
, int, truth BlockedByArmour
)
79 if(!BlockedByArmour
&& Fluid
)
81 truth Success
= false;
82 fluidvector FluidVector
;
83 FillFluidVector(FluidVector
);
85 for(uInt c
= 0; c
< FluidVector
.size(); ++c
)
86 if(FluidVector
[c
]->Exists()
87 && FluidVector
[c
]->GetLiquid()->HitEffect(Enemy
, Enemy
->GetBodyPart(BodyPartIndex
)))
96 void meleeweapon::DipInto(liquid
* Liquid
, character
* Dipper
)
98 if(Dipper
->IsPlayer())
99 ADD_MESSAGE("%s is now covered with %s.", CHAR_NAME(DEFINITE
), Liquid
->GetName(false, false).CStr());
101 SpillFluid(Dipper
, Liquid
);
102 Dipper
->DexterityAction(10);
105 truth
pickaxe::Apply(character
* User
)
109 ADD_MESSAGE("%s is totally broken.",CHAR_NAME(DEFINITE
));
113 int Dir
= game::DirectionQuestion(CONST_S("What direction do you want to dig? [press a direction key]"), false);
115 v2 Temp
= game::GetMoveVector(Dir
);
116 v2 ToBeDug
= User
->GetPos() + Temp
;
117 if(Dir
== DIR_ERROR
|| !GetArea()->IsValidPos(ToBeDug
))
120 lsquare
* Square
= GetNearLSquare(ToBeDug
);
121 olterrain
* Terrain
= Square
->GetOLTerrain();
125 ADD_MESSAGE("Nothing to dig there!");
129 if(Square
->CanBeDug())
131 if(Terrain
->CanBeDestroyed())
132 if(Terrain
->GetMainMaterial()->CanBeDug(GetMainMaterial()))
134 int RoomNumber
= Square
->GetRoomIndex();
136 if(!RoomNumber
|| Square
->GetLevel()->GetRoom(RoomNumber
)->CheckDestroyTerrain(User
))
138 User
->SwitchToDig(this, ToBeDug
);
139 User
->DexterityAction(5);
146 ADD_MESSAGE("%s is too hard to dig with %s.", Square
->GetOLTerrain()->CHAR_NAME(DEFINITE
), CHAR_NAME(INDEFINITE
));
148 ADD_MESSAGE(Terrain
->GetDigMessage().CStr());
154 sLong
meleeweapon::GetPrice() const
156 double WeaponStrengthModifier
= GetFormModifier() * GetMainMaterial()->GetStrengthValue();
157 WeaponStrengthModifier
*= WeaponStrengthModifier
;
158 WeaponStrengthModifier
*= GetMainMaterial()->GetWeight();
159 WeaponStrengthModifier
*= Max((10 + Enchantment
) * 0.1, 0.1);
160 return sLong(WeaponStrengthModifier
/ (20000000.0 * sqrt(GetWeight())))
161 + GetEnchantedPrice(Enchantment
);
164 int whip::GetFormModifier() const
166 return item::GetFormModifier() * GetMainMaterial()->GetFlexibility();
169 truth
pickaxe::IsAppliable(ccharacter
* Who
) const
171 return Who
->CanWield();
174 void meleeweapon::Save(outputfile
& SaveFile
) const
176 item::Save(SaveFile
);
177 SaveFile
<< Enchantment
;
178 SaveFile
<< SecondaryMaterial
;
181 void meleeweapon::Load(inputfile
& SaveFile
)
183 item::Load(SaveFile
);
184 SaveFile
>> Enchantment
;
185 LoadMaterial(SaveFile
, SecondaryMaterial
);
188 material
* meleeweapon::GetMaterial(int I
) const
190 return !I
? MainMaterial
: SecondaryMaterial
;
193 col16
meleeweapon::GetMaterialColorB(int) const
195 return SecondaryMaterial
->GetVolume() ? SecondaryMaterial
->GetColor() : TRANSPARENT_COLOR
;
198 alpha
meleeweapon::GetAlphaB(int) const
200 return SecondaryMaterial
->GetAlpha();
203 truth
flamingsword::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
205 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
207 if(Enemy
->IsEnabled() && RAND() & 1)
211 if(Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
212 ADD_MESSAGE("%s sword burns %s.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
216 if(Enemy
->IsPlayer() || Enemy
->CanBeSeenByPlayer())
217 ADD_MESSAGE("The sword burns %s.", Enemy
->CHAR_DESCRIPTION(DEFINITE
));
220 return Enemy
->ReceiveBodyPartDamage(Hitter
, 3 + (RAND() & 3), FIRE
, BodyPartIndex
, Direction
) || BaseSuccess
;
226 truth
mjolak::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
228 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
230 if(!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 3))
234 if(Hitter
->IsPlayer())
235 game::DoEvilDeed(10);
237 if(Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
238 ADD_MESSAGE("A burst of %s Mjolak's unholy energy fries %s.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
242 if(Enemy
->IsPlayer() || Enemy
->CanBeSeenByPlayer())
243 ADD_MESSAGE("A burst of Mjolak's unholy energy fries %s.", Enemy
->CHAR_DESCRIPTION(DEFINITE
));
246 return Enemy
->ReceiveBodyPartDamage(Hitter
, 5 + (RAND() % 6), ENERGY
, BodyPartIndex
, Direction
) || BaseSuccess
;
252 truth
vermis::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
254 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
256 if(!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5))
260 if(Enemy
->IsPlayer() || Enemy
->CanBeSeenByPlayer())
261 ADD_MESSAGE("%s Vermis sends %s on a sudden journey.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
265 if(Enemy
->IsPlayer() || Enemy
->CanBeSeenByPlayer())
266 ADD_MESSAGE("Vermis sends %s on a sudden journey.", Enemy
->CHAR_DESCRIPTION(DEFINITE
));
269 Enemy
->TeleportRandomly();
276 truth
turox::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
278 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
280 if(!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5))
284 if(Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
285 ADD_MESSAGE("%s smash%s %s with the full force of Turox.", Hitter
->CHAR_PERSONAL_PRONOUN
, Hitter
->IsPlayer() ? "" : "es", Enemy
->CHAR_DESCRIPTION(DEFINITE
));
289 if(Enemy
->IsPlayer() || Enemy
->CanBeSeenByPlayer())
290 ADD_MESSAGE("Turox is smashed against %s with full force.", Enemy
->CHAR_DESCRIPTION(DEFINITE
));
293 if(GetSquareUnder()->CanBeSeenByPlayer(true))
294 ADD_MESSAGE("A magical explosion is triggered!");
296 Enemy
->GetLevel()->Explosion(Hitter
, CONST_S("burned @bkp Turox's explosion"), HitPos
, 10 + RAND() % 100);
303 truth
whipofthievery::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
305 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
307 if(Enemy
->IsEnabled() && Hitter
&& CleptiaHelps(Enemy
, Hitter
))
309 if(Hitter
->IsPlayer())
311 game::DoEvilDeed(10);
312 game::GetGod(CLEPTIA
)->AdjustRelation(10);
315 if(Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
316 ADD_MESSAGE("%s whip asks for the help of Cleptia as it steals %s %s.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->GetMainWielded()->CHAR_NAME(UNARTICLED
));
318 Enemy
->GetMainWielded()->MoveTo(GetLSquareUnder()->GetStack());
325 meleeweapon::~meleeweapon()
327 delete SecondaryMaterial
;
330 meleeweapon::meleeweapon(const meleeweapon
& MW
) : mybase(MW
), Enchantment(MW
.Enchantment
)
332 CopyMaterial(MW
.SecondaryMaterial
, SecondaryMaterial
);
335 truth
whipofthievery::CleptiaHelps(ccharacter
* Enemy
, ccharacter
* Hitter
) const
337 if(Enemy
->IsImmuneToWhipOfThievery() || !Enemy
->GetMainWielded() || GetMainMaterial()->GetFlexibility() <= 5)
340 if(Hitter
->IsPlayer())
342 if(game::GetGod(CLEPTIA
)->GetRelation() < 0)
345 return !RAND_N(10 - game::GetGod(CLEPTIA
)->GetRelation() / 200);
351 void meleeweapon::AddInventoryEntry(ccharacter
* Viewer
, festring
& Entry
, int, truth ShowSpecialInfo
) const // never piled
353 AddName(Entry
, INDEFINITE
);
357 Entry
<< " [" << GetWeight() << "g, DAM " << GetBaseMinDamage() << '-' << GetBaseMaxDamage();
358 Entry
<< ", " << GetBaseToHitValueDescription();
360 if(!IsBroken() && !IsWhip())
361 Entry
<< ", " << GetStrengthValueDescription();
363 int CWeaponSkillLevel
= Viewer
->GetCWeaponSkillLevel(this);
364 int SWeaponSkillLevel
= Viewer
->GetSWeaponSkillLevel(this);
366 if(CWeaponSkillLevel
|| SWeaponSkillLevel
)
367 Entry
<< ", skill " << CWeaponSkillLevel
<< '/' << SWeaponSkillLevel
;
373 void meleeweapon::SignalSpoil (material
*Material
) {
374 if (!Exists()) return;
375 if (Material
== MainMaterial
) {
376 if (CanBeSeenByPlayer()) {
377 if (SecondaryMaterial
->GetVolume()) ADD_MESSAGE("The edge of %s spoils.", GetExtendedDescription().CStr());
378 else ADD_MESSAGE("%s spoils.", GetExtendedDescription().CStr());
380 RemoveMainMaterial();
382 if (CanBeSeenByPlayer()) ADD_MESSAGE("The handle of %s spoils", GetExtendedDescription().CStr());
383 delete RemoveSecondaryMaterial();
387 void meleeweapon::AddPostFix(festring
& String
, int Case
) const
389 item::AddPostFix(String
, Case
);
393 String
<< " covered with ";
394 fluid::AddFluidInfo(Fluid
[0], String
);
398 String
<< " +" << Enchantment
;
399 else if(Enchantment
< 0)
400 String
<< ' ' << Enchantment
;
403 void meleeweapon::Be()
407 if(Exists() && SecondaryMaterial
->GetVolume())
408 SecondaryMaterial
->Be(ItemFlags
);
411 sLong
whipofthievery::GetPrice() const
413 /* If intact but not flexible enough to work, special thievery bonus must be removed */
415 return GetMainMaterial()->GetFlexibility() > 5 || IsBroken() ? whip::GetPrice() : whip::GetPrice() - item::GetPrice();
418 int meleeweapon::GetSparkleFlags() const
420 return (MainMaterial
->IsSparkling() ? SPARKLING_A
|(SecondaryMaterial
->GetVolume() ? SPARKLING_C
: 0) : 0)
421 | (SecondaryMaterial
->IsSparkling() ? SPARKLING_B
: 0);
424 void meleeweapon::SetEnchantment(int Amount
)
426 Enchantment
= Amount
;
427 SignalEnchantmentChange();
430 void meleeweapon::EditEnchantment(int Amount
)
432 Enchantment
+= Amount
;
433 SignalEnchantmentChange();
436 int meleeweapon::GetStrengthValue() const
438 return Max
<int>(sLong(GetStrengthModifier()) * GetMainMaterial()->GetStrengthValue() / 2000 + Enchantment
, 0);
441 void meleeweapon::PostConstruct()
443 Enchantment
= GetBaseEnchantment();
446 int meleeweapon::GetSpoilLevel() const
448 int MainSpoilLevel
= MainMaterial
->GetSpoilLevel();
450 if(SecondaryMaterial
->GetVolume())
451 return Max(MainSpoilLevel
, SecondaryMaterial
->GetSpoilLevel());
453 return MainSpoilLevel
;
456 truth
neercseulb::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
458 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
460 if(!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5))
462 if(Hitter
->IsPlayer())
463 game::DoEvilDeed(10);
465 if(Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
466 ADD_MESSAGE("%s Neerc Se-ulb's life-draining energies swallow %s!", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
468 return Enemy
->ReceiveBodyPartDamage(Hitter
, 10 + (RAND() % 11), DRAIN
, BodyPartIndex
, Direction
) || BaseSuccess
;
474 truth
thunderhammer::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
476 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
478 if(!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5))
480 if(Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
481 ADD_MESSAGE("%s hammer shoots a lightning bolt at %s!", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
486 CONST_S("electrocuted @bkp thunder hammer"),
495 GetLevel()->LightningBeam(Beam
);
502 truth
thunderhammer::ReceiveDamage(character
* Damager
, int Damage
, int Type
, int Dir
)
504 return Type
& ELECTRICITY
? false : meleeweapon::ReceiveDamage(Damager
, Damage
, Type
, Dir
);
507 sLong
armor::GetPrice() const
509 double StrengthValue
= GetStrengthValue();
510 return sLong(StrengthValue
* StrengthValue
* StrengthValue
* 20 / sqrt(GetWeight()));
513 int belt::GetFormModifier() const
515 return item::GetFormModifier() * GetMainMaterial()->GetFlexibility();
518 void armor::AddInventoryEntry(ccharacter
*, festring
& Entry
, int Amount
, truth ShowSpecialInfo
) const
521 AddName(Entry
, INDEFINITE
);
524 Entry
<< Amount
<< ' ';
525 AddName(Entry
, PLURAL
);
529 Entry
<< " [" << GetWeight() * Amount
<< "g, AV " << GetStrengthValue() << ']';
532 void shield::AddInventoryEntry(ccharacter
* Viewer
, festring
& Entry
, int, truth ShowSpecialInfo
) const // never piled
534 AddName(Entry
, INDEFINITE
);
538 Entry
<< " [" << GetWeight() << "g, " << GetBaseBlockValueDescription();
541 Entry
<< ", " << GetStrengthValueDescription();
543 int CWeaponSkillLevel
= Viewer
->GetCWeaponSkillLevel(this);
544 int SWeaponSkillLevel
= Viewer
->GetSWeaponSkillLevel(this);
546 if(CWeaponSkillLevel
|| SWeaponSkillLevel
)
547 Entry
<< ", skill " << CWeaponSkillLevel
<< '/' << SWeaponSkillLevel
;
553 truth
armor::CanBePiledWith(citem
* Item
, ccharacter
* Viewer
) const
555 return item::CanBePiledWith(Item
, Viewer
) && Enchantment
== static_cast<const armor
*>(Item
)->Enchantment
;
558 sLong
shield::GetPrice() const /* temporary... */
560 double StrengthValue
= GetStrengthValue();
561 return sLong(sqrt(GetBaseBlockValue()) * StrengthValue
* StrengthValue
) + item::GetPrice();
564 void armor::Save(outputfile
& SaveFile
) const
566 item::Save(SaveFile
);
567 SaveFile
<< Enchantment
;
570 void armor::Load(inputfile
& SaveFile
)
572 item::Load(SaveFile
);
573 SaveFile
>> Enchantment
;
576 void armor::AddPostFix(festring
& String
, int Case
) const
578 item::AddPostFix(String
, Case
);
582 String
<< " covered with ";
583 fluid::AddFluidInfo(Fluid
[0], String
);
587 String
<< " +" << Enchantment
;
588 else if(Enchantment
< 0)
589 String
<< ' ' << Enchantment
;
592 void armor::SetEnchantment(int Amount
)
594 Enchantment
= Amount
;
595 SignalEnchantmentChange();
598 void armor::EditEnchantment(int Amount
)
600 Enchantment
+= Amount
;
601 SignalEnchantmentChange();
604 int armor::GetStrengthValue() const
606 return Max
<sLong
>(sLong(GetStrengthModifier()) * GetMainMaterial()->GetStrengthValue() / 2000 + Enchantment
, 0);
609 void armor::PostConstruct()
611 Enchantment
= GetBaseEnchantment();
614 int armor::GetInElasticityPenalty(int Attribute
) const
616 return Attribute
* GetInElasticityPenaltyModifier() / (GetMainMaterial()->GetFlexibility() * 100);
619 void meleeweapon::GenerateMaterials()
621 int Chosen
= RandomizeMaterialConfiguration();
622 const fearray
<sLong
>& MMC
= GetMainMaterialConfig();
623 InitMaterial(MainMaterial
,
624 MAKE_MATERIAL(MMC
.Data
[MMC
.Size
== 1 ? 0 : Chosen
]),
625 GetDefaultMainVolume());
626 const fearray
<sLong
>& SMC
= GetSecondaryMaterialConfig();
627 InitMaterial(SecondaryMaterial
,
628 MAKE_MATERIAL(SMC
.Data
[SMC
.Size
== 1 ? 0 : Chosen
]),
629 GetDefaultSecondaryVolume());
632 truth
chameleonwhip::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
634 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
636 if(!IsBroken() && Enemy
->IsEnabled() && ScabiesHelps(Enemy
, Hitter
))
638 if(Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
639 ADD_MESSAGE("%s whip asks for the help of Scabies as it polymorphs %s.", Hitter
->CHAR_PERSONAL_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
641 if(Hitter
->IsPlayer())
643 game::DoEvilDeed(20);
644 game::GetGod(SCABIES
)->AdjustRelation(10);
647 int CurrentDanger
= int(Enemy
->GetRelativeDanger(PLAYER
) * 1000);
648 Enemy
->PolymorphRandomly(CurrentDanger
/ 4, Min(CurrentDanger
, 999999), 100 + RAND() % 400);
655 truth
chameleonwhip::ScabiesHelps(ccharacter
* Enemy
, ccharacter
* Hitter
) const
657 if(!Enemy
->IsPolymorphable())
660 if(Hitter
->IsPlayer())
662 if(game::GetGod(SCABIES
)->GetRelation() < 0)
665 return !(RAND() % (20 - game::GetGod(SCABIES
)->GetRelation() / 150));
668 return !(RAND() % 20);
671 alpha
justifier::GetOutlineAlpha(int Frame
) const
674 return 50 + (Frame
* (31 - Frame
) >> 1);
677 alpha
neercseulb::GetOutlineAlpha(int Frame
) const
680 return 50 + (Frame
* (31 - Frame
) >> 1);
683 alpha
gorovitsweapon::GetOutlineAlpha(int Frame
) const
686 return 50 + (Frame
* (31 - Frame
) >> 1);
689 alpha
goldeneagleshirt::GetOutlineAlpha(int Frame
) const
692 return 50 + (Frame
* (31 - Frame
) >> 1);
695 alpha
wondersmellstaff::GetOutlineAlpha(int Frame
) const
700 return Frame
* (31 - Frame
) >> 1;
706 col16
wondersmellstaff::GetOutlineColor(int Frame
) const
709 switch((Frame
&127) >> 5)
712 case 1: return GREEN
;
714 case 3: return YELLOW
;
717 return TRANSPARENT_COLOR
;
720 truth
wondersmellstaff::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
722 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
724 if(!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5))
729 int Amount
= 250 / Enemy
->GetSquaresUnder();
731 for(int c
= 0; c
< Enemy
->GetSquaresUnder(); ++c
)
733 lsquare
* Square
= Enemy
->GetLSquareUnder(c
);
735 if(Square
->IsFlyable())
737 Square
->AddSmoke(gas::Spawn(EVIL_WONDER_STAFF_VAPOUR
, Amount
));
739 if(!Seen
&& Square
->CanBeSeenByPlayer())
745 ADD_MESSAGE("Strange red smoke billows out of %s staff.", Hitter
->CHAR_POSSESSIVE_PRONOUN
);
749 /* Can a multitiled creature ever be the hitter? */
751 lsquare
* Square
= Hitter
->GetLSquareUnder();
753 if(Square
->IsFlyable())
755 if(Square
->CanBeSeenByPlayer())
756 ADD_MESSAGE("Strange blue smoke billows out of %s staff.", Hitter
->CHAR_POSSESSIVE_PRONOUN
);
758 Square
->AddSmoke(gas::Spawn(GOOD_WONDER_STAFF_VAPOUR
, 100));
768 truth
bodyarmor::AddAdjective(festring
& String
, truth Articled
) const
775 if(GetMainMaterial()->GetFlexibility() >= 5)
787 truth
cloak::AddAdjective(festring
& String
, truth Articled
) const
794 if(GetMainMaterial()->GetFlexibility() >= 5)
806 int meleeweapon::GetRustDataB() const
808 return SecondaryMaterial
->GetRustData();
811 void meleeweapon::TryToRust(sLong LiquidModifier
)
813 item::TryToRust(LiquidModifier
);
815 if(SecondaryMaterial
->GetVolume() && SecondaryMaterial
->TryToRust(LiquidModifier
))
816 SecondaryMaterial
->SetRustLevel(SecondaryMaterial
->GetRustLevel() + 1);
819 material
* meleeweapon::GetConsumeMaterial(ccharacter
* Consumer
, materialpredicate Predicate
) const
821 if((SecondaryMaterial
->*Predicate
)()
822 && SecondaryMaterial
->GetVolume()
823 && Consumer
->CanConsume(SecondaryMaterial
))
824 return SecondaryMaterial
;
826 return item::GetConsumeMaterial(Consumer
, Predicate
);
829 material
* meleeweapon::RemoveMaterial(material
* Material
)
831 if(Material
== MainMaterial
)
832 return RemoveMainMaterial();
834 return RemoveSecondaryMaterial();
837 material
* meleeweapon::RemoveMainMaterial()
839 truth Equipped
= PLAYER
->Equips(this);
841 if(SecondaryMaterial
->GetVolume())
843 item
* Lump
= SecondaryMaterial
->CreateNaturalForm(SecondaryMaterial
->GetVolume());
844 DonateFluidsTo(Lump
);
852 game::AskForEscPress(CONST_S("Equipment destroyed!"));
858 material
* meleeweapon::RemoveSecondaryMaterial()
860 SecondaryMaterial
->SetVolume(0);
866 RedistributeFluids();
868 SendNewDrawAndMemorizedUpdateRequest();
874 pixelpredicate
meleeweapon::GetFluidPixelAllowedPredicate() const
876 if(SecondaryMaterial
->GetVolume())
877 return &rawbitmap::IsTransparent
;
879 return &rawbitmap::IsMaterialColor1
;
882 void meleeweapon::CalculateEmitation()
884 Emitation
= GetBaseEmitation();
887 game::CombineLights(Emitation
, MainMaterial
->GetEmitation());
889 if(SecondaryMaterial
->GetVolume())
890 game::CombineLights(Emitation
, SecondaryMaterial
->GetEmitation());
893 truth
meleeweapon::CalculateHasBe() const
895 return LifeExpectancy
896 || (MainMaterial
&& MainMaterial
->HasBe())
897 || (SecondaryMaterial
898 && SecondaryMaterial
->GetVolume()
899 && SecondaryMaterial
->HasBe());
902 void decosadshirt::Be()
904 if(PLAYER
->Equips(this))
910 decosadshirt::decosadshirt() : EquippedTicks(0)
915 void decosadshirt::Save(outputfile
& SaveFile
) const
917 bodyarmor::Save(SaveFile
);
918 SaveFile
<< EquippedTicks
;
921 void decosadshirt::Load(inputfile
& SaveFile
)
923 bodyarmor::Load(SaveFile
);
924 SaveFile
>> EquippedTicks
;
928 item
* meleeweapon::Fix()
930 SecondaryMaterial
->SetVolumeNoSignals(GetDefaultSecondaryVolume());
934 sLong
meleeweapon::GetMaterialPrice() const
936 return MainMaterial
->GetRawPrice() + SecondaryMaterial
->GetRawPrice();
939 void meleeweapon::CalculateEnchantment()
941 Enchantment
-= femath::LoopRoll(game::GetCurrentLevel()->GetEnchantmentMinusChance(), 5);
942 Enchantment
+= femath::LoopRoll(game::GetCurrentLevel()->GetEnchantmentPlusChance(), 5);
943 Enchantment
-= femath::LoopRoll(GetEnchantmentMinusChance(), 5);
944 Enchantment
+= femath::LoopRoll(GetEnchantmentPlusChance(), 5);
947 void armor::CalculateEnchantment()
949 Enchantment
-= femath::LoopRoll(game::GetCurrentLevel()->GetEnchantmentMinusChance(), 5);
950 Enchantment
+= femath::LoopRoll(game::GetCurrentLevel()->GetEnchantmentPlusChance(), 5);
951 Enchantment
-= femath::LoopRoll(GetEnchantmentMinusChance(), 5);
952 Enchantment
+= femath::LoopRoll(GetEnchantmentPlusChance(), 5);
955 col16
meleeweapon::GetMaterialColorC(int Frame
) const
957 return SecondaryMaterial
->GetVolume() ? GetMaterialColorA(Frame
) : TRANSPARENT_COLOR
;
960 void daggerofvenom::Be()
964 if(Exists() && !IsBroken() && (*Slot
)->IsGearSlot() && !RAND_N(10))
966 fluidvector FluidVector
;
967 FillFluidVector(FluidVector
);
970 for(uInt c
= 0; c
< FluidVector
.size(); ++c
)
972 liquid
* L
= FluidVector
[c
]->GetLiquid();
973 Volume
+= L
->GetVolume(); //I imagine that there is a function I don't know to do this...
977 SpillFluid(0, liquid::Spawn(POISON_LIQUID
, 10));
981 truth
weepblade::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
983 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
985 if(Enemy
->IsEnabled() && !(RAND_N(3)))
987 if(Enemy
->IsPlayer() || Hitter
->IsPlayer()
988 || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
989 ADD_MESSAGE("%s weeping blade spills acid on %s.",
990 Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
991 Enemy
->SpillFluid(PLAYER
, liquid::Spawn(SULPHURIC_ACID
, 25+RAND()%25));
998 void acidshield::BlockEffect(character
* Blocker
, character
* Attacker
, item
* Weapon
, int Type
)
1000 /*k8 int CheckAttackType = 0;*/
1007 Weapon
->SpillFluid(Blocker
, liquid::Spawn(SULPHURIC_ACID
, 200 + RAND() % 51));
1008 ADD_MESSAGE("%s is completely doused in sulpheric acid!", Attacker
->CHAR_DESCRIPTION(DEFINITE
));
1013 if(RAND_2
&& Weapon
)
1015 Weapon
->SpillFluid(Blocker
, liquid::Spawn(SULPHURIC_ACID
, 20 + RAND() % 41));
1016 ADD_MESSAGE("%s weapon is splashed with acid from the shield!", Attacker
->CHAR_POSSESSIVE_PRONOUN
);
1021 Attacker
->SpillFluid(Blocker
, liquid::Spawn(SULPHURIC_ACID
, 5 + RAND() % 11));
1022 ADD_MESSAGE("%s is splashed with acid!", Attacker
->CHAR_DESCRIPTION(DEFINITE
));
1028 Attacker
->SpillFluid(Blocker
, liquid::Spawn(SULPHURIC_ACID
, 25 + RAND() % 26));
1029 ADD_MESSAGE("%s is splashed with acid from the shield!", Attacker
->CHAR_DESCRIPTION(DEFINITE
));
1035 void wondersmellstaff::Break(character
* Who
, int Much
)
1037 /*k8: material* GasMaterial = GetSecondaryMaterial(); */
1038 GetLevel()->GasExplosion(gas::Spawn(GOOD_WONDER_STAFF_VAPOUR
, 100), GetLSquareUnder());
1040 if(CanBeSeenByPlayer())
1042 ADD_MESSAGE("%s unleashes a puff of a wonderous gas.", CHAR_NAME(DEFINITE
));
1045 meleeweapon::Break(Who
,Much
);
1049 truth
vacuumblade::HitEffect (character
*Enemy
, character
*Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
) {
1050 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1051 if (!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 2)) {
1053 if (Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
1054 ADD_MESSAGE("%s blade creates a wind vortex cutting %s.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1056 if (Enemy
->IsPlayer() || Enemy
->CanBeSeenByPlayer())
1057 ADD_MESSAGE("The blade creates a wind vortex cutting %s.", Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1059 return Enemy
->ReceiveBodyPartDamage(Hitter
, 6 + (RAND() % 6), ENERGY
, BodyPartIndex
, Direction
) || BaseSuccess
;
1065 col16
masamune::GetOutlineColor (int) const { return MakeRGB16(0, 0, 255); }
1067 alpha
masamune::GetOutlineAlpha (int Frame
) const {
1069 return 50+(Frame
*(31-Frame
)>>1);
1072 truth
masamune::HitEffect (character
*Enemy
, character
*Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
) {
1073 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1074 if (!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 4)) {
1075 if (Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
1076 ADD_MESSAGE("%s Masamune's slash cuts %s so deep you thought it was cut in half for a moment.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1077 return Enemy
->ReceiveBodyPartDamage(Hitter
, 4 + (RAND() % 4), PHYSICAL_DAMAGE
, BodyPartIndex
, Direction
) || BaseSuccess
;
1082 truth
zulfiqar::HitEffect (character
*Enemy
, character
*Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
) {
1083 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1084 if (!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 3)) {
1085 if (Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
1086 ADD_MESSAGE("%s Zulfiqar's slash deeply cuts %s.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1087 return Enemy
->ReceiveBodyPartDamage(Hitter
, 4 + (RAND() % 5), PHYSICAL_DAMAGE
, BodyPartIndex
, Direction
) || BaseSuccess
;
1092 truth
tipswordofpenetration::HitEffect (character
*Enemy
, character
*Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
) {
1093 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1094 if (!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 3)) {
1095 if (Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
1096 ADD_MESSAGE("%s tip sword's slash penetrates %s.", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1097 return Enemy
->ReceiveBodyPartDamage(Hitter
, 2 + (RAND() % 5), PHYSICAL_DAMAGE
, BodyPartIndex
, Direction
) || BaseSuccess
;
1103 col16
loricatushammer::GetOutlineColor (int) const { return MakeRGB16(0, 0, 255); }
1105 alpha
loricatushammer::GetOutlineAlpha (int Frame
) const {
1107 return 50 + (Frame
* (31 - Frame
) >> 1);
1111 col16
belderiver::GetOutlineColor (int) const { return MakeRGB16(180, 50, 50); }
1113 alpha
belderiver::GetOutlineAlpha (int Frame
) const {
1115 return 50 + (Frame
* (31 - Frame
) >> 1);
1119 col16
demonhead::GetOutlineColor (int) const { return MakeRGB16(255, 0, 0); }
1121 alpha
demonhead::GetOutlineAlpha (int Frame
) const {
1123 return 50 + (Frame
* (31 - Frame
) >> 1);
1127 col16
muramasa::GetOutlineColor (int) const { return MakeRGB16(255, 0, 0); }
1129 alpha
muramasa::GetOutlineAlpha (int Frame
) const {
1131 return 50 + (Frame
* (31 - Frame
) >> 1);
1134 truth
muramasa::HitEffect (character
*Enemy
, character
*Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
) {
1135 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1136 if (!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5)) {
1137 if (Hitter
->IsPlayer()) game::DoEvilDeed(10);
1138 if (Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
1139 ADD_MESSAGE("%s Muramasa's life-draining energies swallow %s!", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1140 return Enemy
->ReceiveBodyPartDamage(Hitter
, 10 + (RAND() % 11), DRAIN
, BodyPartIndex
, Direction
) || BaseSuccess
;
1146 int smite::GetSpecialFlags() const {
1147 return !IsBroken() ? meleeweapon::GetSpecialFlags()|ST_LIGHTNING
: meleeweapon::GetSpecialFlags();
1150 truth
smite::HitEffect (character
*Enemy
, character
*Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
) {
1151 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1152 if (!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5)) {
1153 if (Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
1154 ADD_MESSAGE("%s mace named Smite shoots a lightning bolt at %s!", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1157 CONST_S("electrocuted @bkp mace named Smite"),
1165 GetLevel()->LightningBeam(Beam
);
1171 truth
smite::ReceiveDamage (character
*Damager
, int Damage
, int Type
, int Dir
) {
1172 return Type
& ELECTRICITY
? false : meleeweapon::ReceiveDamage(Damager
, Damage
, Type
, Dir
);
1176 col16
goldenjaguarshirt::GetOutlineColor (int) const { return MakeRGB16(255, 255, 128); }
1178 alpha
goldenjaguarshirt::GetOutlineAlpha (int Frame
) const {
1180 return 50 + (Frame
* (31 - Frame
) >> 1);
1184 col16
kawai::GetOutlineColor (int) const { return MakeRGB16(255, 0, 0); }
1186 alpha
kawai::GetOutlineAlpha (int Frame
) const {
1188 return 50 + (Frame
* (31 - Frame
) >> 1);
1191 truth
kawai::HitEffect (character
*Enemy
, character
*Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
) {
1192 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1193 if (!IsBroken() && Enemy
->IsEnabled() && !(RAND() % 5)) {
1194 if (Hitter
->IsPlayer()) game::DoEvilDeed(10);
1195 if (Enemy
->IsPlayer() || Hitter
->IsPlayer() || Enemy
->CanBeSeenByPlayer() || Hitter
->CanBeSeenByPlayer())
1196 ADD_MESSAGE("%s Kawai's life-draining energies swallow %s!", Hitter
->CHAR_POSSESSIVE_PRONOUN
, Enemy
->CHAR_DESCRIPTION(DEFINITE
));
1197 return Enemy
->ReceiveBodyPartDamage(Hitter
, 10 + (RAND() % 11), DRAIN
, BodyPartIndex
, Direction
) || BaseSuccess
;
1203 int eptyron::GetClassAnimationFrames() const { return !IsBroken() ? 128 : 1; }
1205 //Entropyaxe code begins
1207 /** Whatever is not commented below, is stuff that works */
1209 truth
eptyron::HitEffect(character
* Enemy
, character
* Hitter
, v2 HitPos
, int BodyPartIndex
, int Direction
, truth BlockedByArmour
)
1211 truth BaseSuccess
= meleeweapon::HitEffect(Enemy
, Hitter
, HitPos
, BodyPartIndex
, Direction
, BlockedByArmour
);
1215 if(!IsBroken() && Enemy
->IsEnabled() && Enemy
->IsHumanoid() /*&& !(RAND() % 2)*/)
1217 //bodypart* BodyPartThatWasHit = Enemy -> GetBodyPart(BodyPartIndex);
1218 item
* MainArmor
= 0;
1220 switch(BodyPartIndex
)
1223 MainArmor
= Enemy
->GetEquipment(BODY_ARMOR_INDEX
);
1226 MainArmor
= Enemy
->GetEquipment(HELMET_INDEX
);
1228 case RIGHT_ARM_INDEX
:
1229 MainArmor
= Enemy
->GetEquipment(RIGHT_GAUNTLET_INDEX
);
1230 //BodyPartThatWasHit = Enemy -> GetBodyPart(BodyPartIndex);
1232 case LEFT_ARM_INDEX
:
1233 MainArmor
= Enemy
->GetEquipment(LEFT_GAUNTLET_INDEX
);
1234 //BodyPartThatWasHit = Enemy -> GetBodyPart(BodyPartIndex);
1237 MainArmor
= Enemy
->GetEquipment(BELT_INDEX
);
1239 case RIGHT_LEG_INDEX
:
1240 MainArmor
= Enemy
->GetEquipment(RIGHT_BOOT_INDEX
);
1241 //BodyPartThatWasHit = Enemy -> GetBodyPart(BodyPartIndex);
1243 case LEFT_LEG_INDEX
:
1244 MainArmor
= Enemy
->GetEquipment(LEFT_BOOT_INDEX
);
1245 //BodyPartThatWasHit = Enemy -> GetBodyPart(BodyPartIndex);
1251 material
* OldMaterial
= MainArmor
->GetMainMaterial();
1252 int OldModifier
= OldMaterial
->GetHardenModifier(MainArmor
);
1253 materialvector MaterialVector
;
1254 protosystem::CreateEveryMaterial(MaterialVector
);
1255 truth Changed
= false;
1256 int * CandidateMaterialIndex
;
1257 CandidateMaterialIndex
= new int[MaterialVector
.size()];
1260 MainArmor
->AddName(Desc
, UNARTICLED
);
1262 for(unsigned int c
= 0; c
< MaterialVector
.size(); ++c
)
1264 if((MaterialVector
[c
]->GetCommonFlags() & CAN_BE_WISHED
)
1265 && (MaterialVector
[c
]->GetConsumeType() & OldMaterial
->GetConsumeType()) )
1267 material
* Material
= MaterialVector
[c
];
1269 if(Material
->GetHardenModifier(MainArmor
) < OldModifier
1270 /*&& Material->GetRawPrice() < OldMaterial->GetRawPrice()*/
1271 && ((Material
->GetCommonFlags() & IS_VALUABLE
) == (OldMaterial
->GetCommonFlags() & IS_VALUABLE
)) //Hint: ie only valuable can entropy to valuable, and non-valuable to non-valuable
1272 && ( 10*(1 + OldMaterial
->GetIntelligenceRequirement() - Material
->GetIntelligenceRequirement()) < (Hitter
->GetAttribute(INTELLIGENCE
))*(Hitter
->GetSWeaponSkillLevel(this)) ) )
1274 CandidateMaterialIndex
[Index
++] = c
;
1280 int Chosen
= CandidateMaterialIndex
[(RAND() % Index
)];
1281 material
* ChosenMaterial
= MaterialVector
[Chosen
];
1282 MainArmor
->ChangeMainMaterial(ChosenMaterial
->SpawnMore());
1283 if(ChosenMaterial
!= NONE
)
1285 if(Hitter
->IsPlayer())
1287 ADD_MESSAGE("%s's %s softens into %s!", Enemy
->CHAR_DESCRIPTION(DEFINITE
), Desc
.CStr() , ChosenMaterial
->GetName(false, false).CStr());
1290 ADD_MESSAGE("Your %s softens into %s!", Desc
.CStr(), ChosenMaterial
->GetName(false, false).CStr());
1298 delete[] CandidateMaterialIndex
;
1300 for(unsigned int c
= 0; c
< MaterialVector
.size(); ++c
) delete MaterialVector
[c
];
1302 if(Hitter
->IsPlayer())
1304 ADD_MESSAGE("%s's %s vibrates slightly but remains unchanged.", Enemy
->CHAR_DESCRIPTION(DEFINITE
), MainArmor
->CHAR_NAME(UNARTICLED
) );
1307 ADD_MESSAGE("Your %s vibrates slightly but remains unchanged.", MainArmor
->CHAR_NAME(UNARTICLED
) );
1312 /*this bit softens enemy limbs!!! but pictures do not update :( */
1313 //if(BodyPartThatWasHit && !(Enemy -> BodyPartIsVital(BodyPartIndex)) )
1315 // material* OldMaterial = BodyPartThatWasHit->GetMainMaterial();
1316 // int OldModifier = OldMaterial->GetHardenModifier(BodyPartThatWasHit);
1317 // materialvector MaterialVector;
1318 // protosystem::CreateEveryMaterial(MaterialVector);
1319 // truth Changed = false;
1321 //// for(c = 0; c < MaterialVector.size(); ++c)
1323 // if(MaterialVector[c]->GetCommonFlags() & CAN_BE_WISHED)
1325 // material* Material = MaterialVector[c];
1327 //// if(Material->GetHardenModifier(BodyPartThatWasHit) < OldModifier
1328 // /*&& !RAND_N(Max(Material->GetIntelligenceRequirement() - 15, 1))*/)
1330 // BodyPartThatWasHit->ChangeMainMaterial(Material->SpawnMore());
1331 // if(Hitter->IsPlayer())
1333 // ADD_MESSAGE("%s %s softens into %s!", Enemy->CHAR_POSSESSIVE_PRONOUN, BodyPartThatWasHit->GetBodyPartName().CStr() , Material->GetName(false, false).CStr());
1336 // ADD_MESSAGE("Your %s softens into %s!", BodyPartThatWasHit->GetBodyPartName().CStr(), Material->GetName(false, false).CStr());
1342 // for(c = 0; c < MaterialVector.size(); ++c)
1343 // delete MaterialVector[c];
1345 // if(Hitter->IsPlayer())
1347 // ADD_MESSAGE("%s %s vibrates slightly but remains unchanged.", Enemy->CHAR_POSSESSIVE_PRONOUN, BodyPartThatWasHit->GetBodyPartName().CStr() );
1350 // ADD_MESSAGE("Your %s vibrates slightly but remains unchanged.", BodyPartThatWasHit->GetBodyPartName().CStr() );
1356 ////if(BlockedByArmour)
1360 // if(MainArmor->IsMaterialChangeable())
1363 // MainArmor->AddName(Desc, UNARTICLED);
1364 // Desc << " is transformed";
1366 // switch(RAND() % 3)
1369 // MainArmor->ChangeMainMaterial(MAKE_MATERIAL(CLOTH));
1372 // MainArmor->ChangeMainMaterial(MAKE_MATERIAL(PLANT_FIBER));
1375 // MainArmor->ChangeMainMaterial(MAKE_MATERIAL(PARCHMENT));
1378 // if(Hitter->IsPlayer())
1380 // ADD_MESSAGE("%s's %s", Enemy->CHAR_DESCRIPTION(DEFINITE), Desc.CStr());
1383 // ADD_MESSAGE("Your %s", Desc.CStr());
1386 // ADD_MESSAGE("%s's %s emits a strange light but remain unchanged.", Enemy->CHAR_DESCRIPTION(DEFINITE), MainArmor->CHAR_NAME(DEFINITE));
1391 //if(BodyPartThatWasHit && !(Enemy -> BodyPartIsVital(BodyPartIndex)) )
1393 // if(BodyPartThatWasHit->IsMaterialChangeable())
1395 // if(Hitter->IsPlayer())
1397 // ADD_MESSAGE("%s's %s softens into banana flesh.", Enemy->CHAR_DESCRIPTION(DEFINITE), BodyPartThatWasHit->GetBodyPartName().CStr() );
1400 // ADD_MESSAGE("Your %s softens into banana flesh.", BodyPartThatWasHit->GetBodyPartName().CStr() );
1402 // BodyPartThatWasHit->ChangeMainMaterial(MAKE_MATERIAL(BANANA_FLESH));
1405 // ADD_MESSAGE("%s's %s emits a strange light but remains unchanged.", Enemy->CHAR_DESCRIPTION(DEFINITE), BodyPartThatWasHit->GetBodyPartName().CStr() );
1412 void eptyron::BlockEffect(character
* Blocker
, character
* Attacker
, item
* Weapon
, int Type
)
1418 if(Weapon
&& !(Weapon
->IsWhip()))
1420 material
* OldMaterial
= Weapon
->GetMainMaterial();
1421 int OldModifier
= OldMaterial
->GetHardenModifier(Weapon
);
1422 materialvector MaterialVector
;
1423 protosystem::CreateEveryMaterial(MaterialVector
);
1424 truth Changed
= false;
1425 int * CandidateMaterialIndex
;
1426 CandidateMaterialIndex
= new int[MaterialVector
.size()];
1429 Weapon
->AddName(Desc
, UNARTICLED
);
1431 for(unsigned int c
= 0; c
< MaterialVector
.size(); ++c
)
1433 if((MaterialVector
[c
]->GetCommonFlags() & CAN_BE_WISHED
)
1434 && (MaterialVector
[c
]->GetConsumeType() & OldMaterial
->GetConsumeType()) )
1436 material
* Material
= MaterialVector
[c
];
1438 if(Material
->GetHardenModifier(Weapon
) < OldModifier
1439 && Material
->GetRawPrice() < OldMaterial
->GetRawPrice()
1440 && ((Material
->GetCommonFlags() & IS_VALUABLE
) == (OldMaterial
->GetCommonFlags() & IS_VALUABLE
)) //ie only valuable can entropy to valuable, and non-valuable to non-valuable
1441 && ( 10*(1 + OldMaterial
->GetIntelligenceRequirement() - Material
->GetIntelligenceRequirement()) < (Blocker
->GetAttribute(INTELLIGENCE
))*(Blocker
->GetSWeaponSkillLevel(this)) ) )
1443 CandidateMaterialIndex
[Index
++] = c
;
1449 int Chosen
= CandidateMaterialIndex
[(RAND() % Index
)];
1450 material
* ChosenMaterial
= MaterialVector
[Chosen
];
1451 Weapon
->ChangeMainMaterial(ChosenMaterial
->SpawnMore());
1452 if(ChosenMaterial
!= NONE
)
1454 if(Blocker
->IsPlayer())
1456 ADD_MESSAGE("%s's %s softens into %s!", Attacker
->CHAR_DESCRIPTION(DEFINITE
), Desc
.CStr() , ChosenMaterial
->GetName(false, false).CStr());
1459 ADD_MESSAGE("Your %s softens into %s!", Desc
.CStr(), ChosenMaterial
->GetName(false, false).CStr());
1467 delete[] CandidateMaterialIndex
;
1469 for(unsigned int c
= 0; c
< MaterialVector
.size(); ++c
) delete MaterialVector
[c
];
1471 if(Blocker
->IsPlayer())
1473 ADD_MESSAGE("%s's %s vibrates slightly but remains unchanged.", Attacker
->CHAR_DESCRIPTION(DEFINITE
), Weapon
->CHAR_NAME(UNARTICLED
) );
1476 ADD_MESSAGE("Your %s vibrates slightly but remains unchanged.", Weapon
->CHAR_NAME(UNARTICLED
) );
1484 //Entropyaxe code ends
1486 alpha
eptyron::GetOutlineAlpha(int Frame
) const
1491 return Frame
* (31 - Frame
) >> 1;
1497 col16
eptyron::GetOutlineColor(int Frame
) const
1500 switch((Frame
&127) >> 5)
1502 case 0: return BLUE
;
1503 case 1: return GREEN
;
1505 case 3: return YELLOW
;
1508 return TRANSPARENT_COLOR
;
1512 int taiaha::GetClassAnimationFrames() const { return !IsBroken() ? 128 : 1; }
1516 truth
taiaha::Zap(character
* Zapper
, v2
, int Direction
)
1518 if(Charges
<= TimesUsed
)
1520 ADD_MESSAGE("Nothing happens.");
1524 Zapper
->EditExperience(PERCEPTION
, 150, 1 << 10);
1525 int TaiahaBeamEffect
= RAND() & 3;
1527 beamdata Beam
// Just hard-code this
1530 CONST_S("killed by ") + GetName(INDEFINITE
) + " zapped @bk",
1532 GREEN
, //was GetBeamColor()
1533 TaiahaBeamEffect
? ((RAND() & 2) ? BEAM_FIRE_BALL
: BEAM_STRIKE
) : BEAM_LIGHTNING
, //was GetBeamEffect()
1535 15, // 10 is the lowest beamrange out of the three
1536 0 //was GetSpecialParameters()
1539 (GetLevel()->*level::GetBeam(!TaiahaBeamEffect
))(Beam
); // BeamStyle = !TaiahaBeamEffect;
1544 void taiaha::AddInventoryEntry(ccharacter
* Viewer
, festring
& Entry
, int, truth ShowSpecialInfo
) const // never piled
1546 AddName(Entry
, INDEFINITE
);
1550 Entry
<< " [" << GetWeight() << "g, DAM " << GetBaseMinDamage() << '-' << GetBaseMaxDamage();
1551 Entry
<< ", " << GetBaseToHitValueDescription();
1553 if(!IsBroken() && !IsWhip())
1554 Entry
<< ", " << GetStrengthValueDescription();
1556 int CWeaponSkillLevel
= Viewer
->GetCWeaponSkillLevel(this);
1557 int SWeaponSkillLevel
= Viewer
->GetSWeaponSkillLevel(this);
1559 if(CWeaponSkillLevel
|| SWeaponSkillLevel
)
1560 Entry
<< ", skill " << CWeaponSkillLevel
<< '/' << SWeaponSkillLevel
;
1563 Entry
<< ", zapped 1 time]";
1565 Entry
<< ", zapped " << TimesUsed
<< " times]";
1571 void taiaha::BreakEffect(character
* Terrorist
, cfestring
& DeathMsg
)
1574 level
* Level
= GetLevel();
1576 ulong StackSize
= Level
->AddRadiusToSquareStack(Pos
, 2); //hardcode, default is 2 for most wands, but zero for fireballs
1577 lsquare
** SquareStack
= Level
->GetSquareStack();
1580 for(c
= 0; c
< StackSize
; ++c
)
1581 SquareStack
[c
]->RemoveFlags(IN_SQUARE_STACK
);
1583 fearray
<lsquare
*> Stack(SquareStack
, StackSize
);
1584 (Level
->*level::GetBeamEffectVisualizer(PARTICLE_BEAM
))(Stack
, YELLOW
); //beamstyle
1591 0 //was GetSpecialParameters()
1594 for(c
= 0; c
< Stack
.Size
; ++c
)
1595 (Stack
[c
]->*lsquare::GetBeamEffect(BEAM_FIRE_BALL
))(Beam
); // beam effect
1597 SendToHell(); //removes the taiaha from existence
1600 void taiaha::Save(outputfile
& SaveFile
) const
1602 item::Save(SaveFile
);
1603 SaveFile
<< TimesUsed
<< Charges
;
1604 SaveFile
<< Enchantment
;
1605 SaveFile
<< SecondaryMaterial
;
1606 //meleeweapon::Save(SaveFile);
1609 void taiaha::Load(inputfile
& SaveFile
)
1611 item::Load(SaveFile
);
1612 SaveFile
>> TimesUsed
>> Charges
;
1613 SaveFile
>> Enchantment
;
1614 LoadMaterial(SaveFile
, SecondaryMaterial
);
1615 //meleeweapon::Load(SaveFile);
1618 truth
taiaha::ReceiveDamage(character
* Damager
, int Damage
, int Type
, int)
1620 if(Type
& (FIRE
|ENERGY
|PHYSICAL_DAMAGE
) && Damage
&& (Damage
> 125 || !(RAND() % (250 / Damage
))))
1622 festring DeathMsg
= CONST_S("killed by an explosion of ");
1623 AddName(DeathMsg
, INDEFINITE
);
1626 DeathMsg
<< " caused @bk";
1628 if(CanBeSeenByPlayer())
1629 ADD_MESSAGE("%s %s.", GetExtendedDescription().CStr(), GetBreakMsg().CStr());
1631 BreakEffect(Damager
, DeathMsg
);
1638 void taiaha::PostConstruct()
1640 Charges
= GetMinCharges() + RAND() % (GetMaxCharges() - GetMinCharges() + 1);
1642 meleeweapon::PostConstruct();
1645 alpha
taiaha::GetOutlineAlpha(int Frame
) const
1650 return Frame
* (31 - Frame
) >> 1;
1656 col16
taiaha::GetOutlineColor(int Frame
) const
1659 switch((Frame
&127) >> 5)
1661 case 0: return BLUE
;
1662 case 1: return GREEN
;
1664 case 3: return YELLOW
;
1667 return TRANSPARENT_COLOR
;