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(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
;
78 fxqueue
->AddEffect( fx
);
81 //adding a pulse effect for weapons (PST)
82 //if it is an equipping effect block
83 if ((usage
==-1) && (WieldColor
!=0xffff)) {
84 if (Flags
&IE_ITEM_PULSATING
) {
85 Effect
*tmp
= BuildGlowEffect(WieldColor
);
87 tmp
->InventorySlot
= invslot
;
89 fxqueue
->AddEffect( tmp
);
97 /** returns the average damage this weapon would cause */
98 int Item::GetDamagePotential(bool ranged
, ITMExtHeader
*&header
) const
100 header
= GetWeaponHeader(ranged
);
102 return header
->DiceThrown
*(header
->DiceSides
+1)/2+header
->DamageBonus
;
107 int Item::GetWeaponHeaderNumber(bool ranged
) const
109 for(int ehc
=0; ehc
<ExtHeaderCount
; ehc
++) {
110 ITMExtHeader
*ext_header
= GetExtHeader(ehc
);
111 if (ext_header
->Location
!=ITEM_LOC_WEAPON
) {
114 unsigned char AType
= ext_header
->AttackType
;
116 if ((AType
!=ITEM_AT_PROJECTILE
) && (AType
!=ITEM_AT_BOW
) ) {
120 if (AType
!=ITEM_AT_MELEE
) {
126 return 0xffff; //invalid extheader number
129 int Item::GetEquipmentHeaderNumber(int cnt
) const
131 for(int ehc
=0; ehc
<ExtHeaderCount
; ehc
++) {
132 ITMExtHeader
*ext_header
= GetExtHeader(ehc
);
133 if (ext_header
->Location
!=ITEM_LOC_EQUIPMENT
) {
136 if (ext_header
->AttackType
!=ITEM_AT_MAGIC
) {
146 return 0xffff; //invalid extheader number
149 ITMExtHeader
*Item::GetWeaponHeader(bool ranged
) const
151 //start from the beginning
152 return GetExtHeader(GetWeaponHeaderNumber(ranged
)) ;
155 int Item::UseCharge(ieWord
*Charges
, int header
, bool expend
) const
157 ITMExtHeader
*ieh
= GetExtHeader(header
);
159 int type
= ieh
->ChargeDepletion
;
162 if ((header
>=CHARGE_COUNTERS
) || (header
<0/*weapon header*/)) {
165 ccount
=Charges
[header
];
167 //if the item started from 0 charges, then it isn't depleting
168 if (ieh
->Charges
==0) {
172 Charges
[header
] = --ccount
;
178 if (type
== CHG_NONE
) {
184 //returns a projectile loaded with the effect queue
185 Projectile
*Item::GetProjectile(ieDwordSigned invslot
, int header
, int miss
) const
187 ITMExtHeader
*eh
= GetExtHeader(header
);
191 ieDword idx
= eh
->ProjectileAnimation
;
192 Projectile
*pro
= core
->GetProjectileServer()->GetProjectileByIndex(idx
);
197 usage
= GetWeaponHeaderNumber(header
==-2) ;
199 EffectQueue
*fx
= GetEffectBlock(usage
, invslot
, idx
);
205 //this is the implementation of the weapon glow effect in PST
206 static EffectRef glow_ref
={"Color:PulseRGB",NULL
,-1};
207 //this type of colour uses PAL32, a PST specific palette
209 static Color ActorColor
[PALSIZE
];
211 Effect
*Item::BuildGlowEffect(int gradient
) const
213 //palette entry to to RGB conversion
214 core
->GetPalette( gradient
, PALSIZE
, ActorColor
);
215 ieDword rgb
= (ActorColor
[16].r
<<16) | (ActorColor
[16].g
<<8) | ActorColor
[16].b
;
216 ieDword location
= 0;
218 Effect
*fx
= EffectQueue::CreateEffect(glow_ref
, rgb
, location
|(speed
<<16), FX_DURATION_INSTANT_WHILE_EQUIPPED
);
222 unsigned int Item::GetCastingDistance(int idx
) const
224 ITMExtHeader
*seh
= GetExtHeader(idx
);
226 printMessage("Item", "Cannot retrieve item header!!! ",RED
);
227 printf("required header: %d, maximum: %d\n", idx
, (int) ExtHeaderCount
);
230 return (unsigned int) seh
->Range
;