slightly smarter stack selection lists
[k8-i-v-a-n.git] / src / game / items / lockableitem_itemcontainer.cpp
blobbf19612ca778e17686eb04c2a66110755231d4bc
1 #ifdef HEADER_PHASE
2 ITEM(itemcontainer, lockableitem)
4 public:
5 itemcontainer();
6 itemcontainer(const itemcontainer&);
7 virtual ~itemcontainer();
9 virtual truth Open(character*);
10 virtual void Load(inputfile&);
11 virtual void Save(outputfile&) const;
12 virtual truth Polymorph(character*, stack*);
13 virtual void CalculateVolumeAndWeight();
14 virtual truth ContentsCanBeSeenBy(ccharacter*) const;
15 virtual sLong GetTruePrice() const;
16 virtual truth ReceiveDamage(character*, int, int, int);
17 virtual void DrawContents(ccharacter*);
18 virtual truth Apply(character* Applier) { return Open(Applier); }
19 virtual truth IsAppliable(ccharacter*) const { return true; }
20 virtual void SetItemsInside(const fearray<contentscript<item> >&, int);
21 virtual truth AllowContentEmitation() const { return false; }
22 virtual truth IsDestroyable(ccharacter*) const;
23 virtual int GetOfferValue(int) const;
24 virtual void SortAllItems(const sortdata&) const;
25 virtual void PreProcessForBone();
26 virtual void PostProcessForBone();
27 virtual void FinalProcessForBone();
28 virtual material* RemoveMaterial(material*);
29 virtual void SetLifeExpectancy(int, int);
30 virtual void CalculateEnchantment();
31 virtual int GetTeleportPriority() const;
32 virtual void SetParameters(int);
33 virtual void Disappear();
34 virtual stack* GetContained() const { return Contained; }
35 virtual truth IsLockableContainer () const override { return true; }
36 protected:
37 virtual col16 GetMaterialColorB(int) const;
38 virtual void PostConstruct();
39 stack* Contained;
43 #else
47 col16 itemcontainer::GetMaterialColorB(int) const { return MakeRGB16(80, 80, 80); }
51 itemcontainer::itemcontainer()
53 Contained = new stack(0, this, HIDDEN);
58 void itemcontainer::PostConstruct()
60 lockableitem::PostConstruct();
61 SetIsLocked(RAND_N(3));
62 sLong ItemNumber = RAND() % (GetMaxGeneratedContainedItems() + 1);
64 for(int c = 0; c < ItemNumber; ++c)
66 item* NewItem = protosystem::BalancedCreateItem(0);
67 sLong Volume = NewItem->GetVolume();
69 if(NewItem->HandleInPairs())
70 Volume <<= 1;
72 if(NewItem->CanBeGeneratedInContainer()
73 && (GetStorageVolume() - GetContained()->GetVolume()) >= Volume)
75 GetContained()->AddItem(NewItem);
76 NewItem->SpecialGenerationHandler();
78 else
79 delete NewItem;
84 truth itemcontainer::Open (character *Opener) {
85 if (IsLocked()) {
86 ADD_MESSAGE("%s seems to be locked.", CHAR_NAME(DEFINITE));
87 return false;
89 festring Question = CONST_S("Do you want to \1Gt\2ake something from or \1Gp\2ut something in this container?");
90 truth Success = false;
91 switch (game::KeyQuestion(Question, /*KEY_ESC*/REQUIRES_ANSWER, 5, 't', 'p', 'T', 'P', KEY_ESC)) {
92 case 't': case 'T': Success = GetContained()->TakeSomethingFrom(Opener, GetName(DEFINITE)); break;
93 case 'p': case 'P': Success = GetContained()->PutSomethingIn(Opener, GetName(DEFINITE), GetStorageVolume(), GetID()); break;
94 default: return false;
96 if (Success) Opener->DexterityAction(Opener->OpenMultiplier()*5);
97 return Success;
101 void itemcontainer::Save(outputfile& SaveFile) const
103 lockableitem::Save(SaveFile);
104 Contained->Save(SaveFile);
109 void itemcontainer::Load(inputfile& SaveFile)
111 lockableitem::Load(SaveFile);
112 Contained->Load(SaveFile);
117 truth itemcontainer::Polymorph(character* Polymorpher, stack* CurrentStack)
119 GetContained()->MoveItemsTo(CurrentStack);
120 item::Polymorph(Polymorpher, CurrentStack);
121 return true;
126 itemcontainer::~itemcontainer()
128 delete Contained;
133 void itemcontainer::CalculateVolumeAndWeight()
135 item::CalculateVolumeAndWeight();
136 Volume += Contained->GetVolume();
137 Weight += Contained->GetWeight();
142 truth itemcontainer::ContentsCanBeSeenBy(ccharacter* Viewer) const
144 return GetMainMaterial()->IsTransparent() && CanBeSeenBy(Viewer);
149 itemcontainer::itemcontainer(const itemcontainer& Container) : mybase(Container)
151 Contained = new stack(0, this, HIDDEN);
152 CalculateAll();
157 sLong itemcontainer::GetTruePrice() const
159 return GetContained()->GetTruePrice() + item::GetTruePrice();
164 truth itemcontainer::ReceiveDamage (character *Damager, int Damage, int Type, int) {
165 if (Type & (PHYSICAL_DAMAGE|SOUND|ENERGY)) {
166 Contained->ReceiveDamage(Damager, Damage/GetDamageDivider(), Type);
167 int SV = Max(GetStrengthValue(), 1);
168 if (IsLocked() && Damage > SV && RAND()%(100*Damage/SV) >= 100) {
169 SetIsLocked(false);
170 SetConfig((GetConfig()&~LOCK_BITS)|BROKEN_LOCK);
171 if (CanBeSeenByPlayer()) ADD_MESSAGE("The %s's lock shatters to pieces.", GetNameSingular().CStr());
172 return true;
174 if (Damager && Damager->IsPlayer()) ADD_MESSAGE("THUMP!");
176 return false;
181 void itemcontainer::DrawContents(ccharacter* Char)
183 festring Topic = CONST_S("Contents of your ") + GetName(UNARTICLED);
184 GetContained()->DrawContents(Char, Topic, NO_SELECT);
186 for(stackiterator i = GetContained()->GetBottom(); i.HasItem(); ++i)
187 i->DrawContents(Char);
192 void itemcontainer::SetItemsInside(const fearray<contentscript<item> >& ItemArray, int SpecialFlags)
194 GetContained()->Clean();
196 for(uInt c1 = 0; c1 < ItemArray.Size; ++c1)
197 if(ItemArray[c1].IsValid())
199 const interval* TimesPtr = ItemArray[c1].GetTimes();
200 int Times = TimesPtr ? TimesPtr->Randomize() : 1;
202 for(int c2 = 0; c2 < Times; ++c2)
204 item* Item = ItemArray[c1].Instantiate(SpecialFlags);
206 if(Item)
208 Contained->AddItem(Item);
209 Item->SpecialGenerationHandler();
217 int itemcontainer::GetOfferValue(int Receiver) const
219 int Sum = 0;
221 for(int c = 0; c < GetContained()->GetItems(); ++c)
222 Sum += GetContained()->GetItem(c)->GetOfferValue(Receiver);
224 return item::GetOfferValue(Receiver) + Sum;
229 truth itemcontainer::IsDestroyable(ccharacter* Char) const
231 for(int c = 0; c < GetContained()->GetItems(); ++c)
232 if(!GetContained()->GetItem(c)->IsDestroyable(Char))
233 return false;
235 return true;
240 void itemcontainer::SortAllItems(const sortdata& SortData) const
242 item::SortAllItems(SortData);
244 if(SortData.Recurse)
245 GetContained()->SortAllItems(SortData);
250 void itemcontainer::PreProcessForBone()
252 item::PreProcessForBone();
253 Contained->PreProcessForBone();
258 void itemcontainer::PostProcessForBone()
260 item::PostProcessForBone();
261 Contained->PostProcessForBone();
266 void itemcontainer::FinalProcessForBone()
268 item::FinalProcessForBone();
269 Contained->FinalProcessForBone();
274 material* itemcontainer::RemoveMaterial(material* Material)
276 Contained->MoveItemsTo(GetSlot());
277 return item::RemoveMaterial(Material);
282 void itemcontainer::SetLifeExpectancy(int Base, int RandPlus)
284 LifeExpectancy = RandPlus > 1 ? Base + RAND_N(RandPlus) : Base;
285 Enable();
286 Contained->SetLifeExpectancy(Base, RandPlus);
291 void itemcontainer::CalculateEnchantment()
293 Contained->CalculateEnchantments();
298 int itemcontainer::GetTeleportPriority() const
300 sLong Priority = item::GetTeleportPriority();
302 for(stackiterator i = Contained->GetBottom(); i.HasItem(); ++i)
303 Priority += i->GetTeleportPriority();
305 return Priority;
310 void itemcontainer::SetParameters(int Param)
312 SetIsLocked(Param & LOCKED);
317 void itemcontainer::Disappear()
319 Contained->MoveItemsTo(GetSlot());
320 item::Disappear();
322 #endif