1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 // This class represents the .itm (item) files of the engine
22 // Items are all the weapons, armor, carriable quest objects, etc.
28 #include "Interface.h"
29 #include "Projectile.h"
30 #include "ProjectileServer.h"
32 ITMExtHeader::ITMExtHeader(void)
37 ITMExtHeader::~ITMExtHeader(void)
45 equipping_features
= NULL
;
50 //core->FreeITMExt( ext_headers, equipping_features );
51 delete [] ext_headers
;
52 delete [] equipping_features
;
55 //-1 will return equipping feature block
56 //otherwise returns the n'th feature block
57 EffectQueue
*Item::GetEffectBlock(Scriptable
*self
, const Point
&pos
, int usage
, ieDwordSigned invslot
, ieDword pro
) const
62 if (usage
>=ExtHeaderCount
) {
66 features
= ext_headers
[usage
].features
;
67 count
= ext_headers
[usage
].FeatureCount
;
69 features
= equipping_features
;
70 count
= EquippingFeatureCount
;
72 EffectQueue
*fxqueue
= new EffectQueue();
74 for (int i
=0;i
<count
;i
++) {
75 Effect
*fx
= features
+i
;
76 fx
->InventorySlot
= invslot
;
77 //this is not coming from the item header, but from the recharge flags
78 fx
->SourceFlags
= ext_headers
[usage
].RechargeFlags
;
79 if (fx
->Target
!= FX_TARGET_SELF
) {
81 fxqueue
->AddEffect( fx
);
83 Actor
*target
= (self
->Type
==ST_ACTOR
)?(Actor
*) self
:NULL
;
88 core
->ApplyEffect(fx
, target
, self
);
93 //adding a pulse effect for weapons (PST)
94 //if it is an equipping effect block
95 if ((usage
==-1) && (WieldColor
!=0xffff)) {
96 if (Flags
&IE_ITEM_PULSATING
) {
97 Effect
*tmp
= BuildGlowEffect(WieldColor
);
99 tmp
->InventorySlot
= invslot
;
101 fxqueue
->AddEffect( tmp
);
109 /** returns the average damage this weapon would cause */
110 int Item::GetDamagePotential(bool ranged
, ITMExtHeader
*&header
) const
112 header
= GetWeaponHeader(ranged
);
114 return header
->DiceThrown
*(header
->DiceSides
+1)/2+header
->DamageBonus
;
119 int Item::GetWeaponHeaderNumber(bool ranged
) const
121 for(int ehc
=0; ehc
<ExtHeaderCount
; ehc
++) {
122 ITMExtHeader
*ext_header
= GetExtHeader(ehc
);
123 if (ext_header
->Location
!=ITEM_LOC_WEAPON
) {
126 unsigned char AType
= ext_header
->AttackType
;
128 if ((AType
!=ITEM_AT_PROJECTILE
) && (AType
!=ITEM_AT_BOW
) ) {
132 if (AType
!=ITEM_AT_MELEE
) {
138 return 0xffff; //invalid extheader number
141 int Item::GetEquipmentHeaderNumber(int cnt
) const
143 for(int ehc
=0; ehc
<ExtHeaderCount
; ehc
++) {
144 ITMExtHeader
*ext_header
= GetExtHeader(ehc
);
145 if (ext_header
->Location
!=ITEM_LOC_EQUIPMENT
) {
148 if (ext_header
->AttackType
!=ITEM_AT_MAGIC
) {
158 return 0xffff; //invalid extheader number
161 ITMExtHeader
*Item::GetWeaponHeader(bool ranged
) const
163 //start from the beginning
164 return GetExtHeader(GetWeaponHeaderNumber(ranged
)) ;
167 int Item::UseCharge(ieWord
*Charges
, int header
, bool expend
) const
169 ITMExtHeader
*ieh
= GetExtHeader(header
);
171 int type
= ieh
->ChargeDepletion
;
174 if ((header
>=CHARGE_COUNTERS
) || (header
<0/*weapon header*/)) {
177 ccount
=Charges
[header
];
179 //if the item started from 0 charges, then it isn't depleting
180 if (ieh
->Charges
==0) {
184 Charges
[header
] = --ccount
;
190 if (type
== CHG_NONE
) {
196 //returns a projectile loaded with the effect queue
197 Projectile
*Item::GetProjectile(Scriptable
*self
, int header
, const Point
&target
, ieDwordSigned invslot
, int miss
) const
199 ITMExtHeader
*eh
= GetExtHeader(header
);
203 ieDword idx
= eh
->ProjectileAnimation
;
204 Projectile
*pro
= core
->GetProjectileServer()->GetProjectileByIndex(idx
);
209 usage
= GetWeaponHeaderNumber(header
==-2);
211 EffectQueue
*fx
= GetEffectBlock(self
, target
, usage
, invslot
, idx
);
217 //this is the implementation of the weapon glow effect in PST
218 static EffectRef glow_ref
={"Color:PulseRGB",NULL
,-1};
219 //this type of colour uses PAL32, a PST specific palette
221 static Color ActorColor
[PALSIZE
];
223 Effect
*Item::BuildGlowEffect(int gradient
) const
225 //palette entry to to RGB conversion
226 core
->GetPalette( gradient
, PALSIZE
, ActorColor
);
227 ieDword rgb
= (ActorColor
[16].r
<<16) | (ActorColor
[16].g
<<8) | ActorColor
[16].b
;
228 ieDword location
= 0;
230 Effect
*fx
= EffectQueue::CreateEffect(glow_ref
, rgb
, location
|(speed
<<16), FX_DURATION_INSTANT_WHILE_EQUIPPED
);
234 unsigned int Item::GetCastingDistance(int idx
) const
236 ITMExtHeader
*seh
= GetExtHeader(idx
);
238 printMessage("Item", "Cannot retrieve item header!!! ",RED
);
239 printf("required header: %d, maximum: %d\n", idx
, (int) ExtHeaderCount
);
242 return (unsigned int) seh
->Range
;