View Full Version: Item making

ivan >>Programming >>Item making


<< Prev | Next >>

Atomic- 04-04-2005
Item making
Posting here because this could be a tad spoily: I've been poking at item/material codes, and am wondering a few things: What file is used for special effects/tags (e.g. for stat-boost foods, and weapons that have special effects)? OK, there were other things but I forgot them. :P I've been trying to make a "shield of acid" (at Ighalli's suggestion), which would have a MainMaterial of steel etc and a SecondaryMaterial of some sort of acid, and that would harm people when I blocked an attack (or if they had a weapon, could damage/destroy the weapon). A few pointers would be appriciated.

Ighalli- 04-04-2005

I havent coded anything besides god type stuff, so I could be wrong. But it looks like you need to do the .dat file thing (which I left out here). Then you need to use a GetSpecialFlag command on the item. These go at the top of gear.cpp int flamingsword::GetSpecialFlags() const { return meleeweapon::GetSpecialFlags()|ST_FLAME_1; } Later on in gear.cpp there are sections like so: truth flamingsword::HitEffect(character* Enemy, character* Hitter, v2 HitPos, int BodyPartIndex, int Direction, truth BlockedByArmour) { truth BaseSuccess = meleeweapon::HitEffect(Enemy, Hitter, HitPos, BodyPartIndex, Direction, BlockedByArmour); if(Enemy->IsEnabled() && RAND() & 1) { if(Enemy->IsPlayer() || Hitter->IsPlayer() || Enemy->CanBeSeenByPlayer() || Hitter->CanBeSeenByPlayer()) ADD_MESSAGE("%s sword burns %s.", Hitter->CHAR_POSSESSIVE_PRONOUN, Enemy->CHAR_DESCRIPTION(DEFINITE)); return Enemy->ReceiveBodyPartDamage(Hitter, 3 + (RAND() & 3), FIRE, BodyPartIndex, Direction) || BaseSuccess; } else return BaseSuccess; } In gear.h there is something like this for every item: ITEM(flamingsword, meleeweapon) { public: virtual truth HitEffect(character*, character*, v2, int, int, truth); virtual int GetSpecialFlags() const; }; You'll need to make one of each of those. It looks like only ego weapons are working at the moment, but I imagine you could change that too. Or just brute force flaming hammers, maces, 2-h swords, etc etc. I think I picked up all the pieces, but we'll hopefully hear from Holy or Hexi to set us straight.

holybanana- 04-06-2005

The GetSpecialFlags() only affects the outlook of the item, not its effects. It's poorly named; eg. GetSpecialDrawFlags() would be better. ST_FLAME_1 means a flame is generated rising from pixels which represent the first material in the item's picture. When you add special weapons, HitEffect is the main function to override. However, when doing a special shield you'll have to hack more, since we haven't yet done any and so you can't copy code quite as easily from elsewhere. You probably shouldn't try to add a second material to it, since you want to derive it from shield, not from materialcontainer (the base for cans, bottles, mines etc. which have two materials) or meleeweapon (which also have two materials). You could of course copypaste a lot of code from either of those classes to yours and get the second material working, but it probably isn't worth it. I suggest you use a single material and add a special function which is called when the shield blocks an attack. The most important blocking function is int character::CheckForBlockWithArm(character* Enemy, item* Weapon, arm* Arm, double WeaponToHitValue, int Damage, int Success, int Type) { // lots of code here } in char.cpp. You'll want to add a call to a virtual function of the blocking item here, since there's none currently. Something like Blocker->BlockEffect(this, Enemy, Weapon); could be fine (add more parameters if you need them, as there are a lot of variables which may be of help). Then add virtual void BlockEffect(character*, character*, item*) { } to class item in item.h and virtual void BlockEffect(character*, character*, item*); to your class in gear.h and void acidshield::BlockEffect(character* Blocker, character* Hitter, item* Weapon) { // your special effect } to gear.cpp. Start with something simple, like splashing sulphuric acid at the Hitter and his Weapon (remember to check the pointer isn't zero, for instance if Hitter is unarmed). There's a SpillFluid function in characters and items, you can find how they work from their definition or their use in eg. the rain or fountain code. When this works, you can try to produce more complicated effects. I apologize there is far too little comments in the code, so it may be a little hard to understand at places. :oops:

Atomic- 04-06-2005

*sigh* I was hoping there would be a way to do it w/o mucking in anything more than the .dat files, as I have yet to successfully compile IVAN from source. Ah well. Thanks for the tips, if I ever get IVAN to compile I'll try to code my acid shield in... Splashing sulpheric acid on their weapon sounds like it could work. Although, wouldn't that then mean that when they actually hit me it would acidize me? *shrug* Oh well. Such are the dangers of using a shield coated in acid.

holybanana- 04-06-2005

Yeah, some acid enters your body each time you are hit, and will do constant damage there for some time until vanishing, unless you have resistance. :twisted: A wonderful idea in fact, I love this kind of double-edged sword items (eg. Turox, thunder hammer...), if you do it I'll add it in the game. :lol:

Atomic- 04-06-2005

Shweeeet... I'll get crackin tonight then. :P I'll sacrifice FFX game time to make something for a game...

Ighalli- 04-07-2005

I'm trying to make the poisoned dagger and a few other items myself, but I need some help. I want to make it so that whenever the item has Be() called it adds a very small amount of fluid (a gram or so). I've been staring at the code for awhile now, but I can't make much sense of the way fluids are currently added. Could you give me a few pointers Holy?? heres what I did so far in gear.h ITEM(daggerofvenom, meleeweapon) { public: virtual void Be(); } then in gear.cpp i want to add soemthing to the effect of: void daggerofvenom::Be() { meleeweapon::Be(); add a tiny bit of fluid <-- this is what I'm having trouble with if (item totally saturated) spill on players arm or the floor & remove some fluid } Thanks a ton!

holybanana- 04-07-2005

First you must ensure the Be function is always called by modifying class daggerofvenom: ITEM(daggerofvenom, meleeweapon) { public: virtual void Be(); protected: virtual truth CalculateHasBe() const { return true; } } Normally CalculateHasBe() checks if the entity is a mirror item or if some material needs a Be-function, for instance if it's rotting slowly. There's no need to add the entity to IVAN's global entity pool if such is not the case; it'd be a waste of clock ticks to run a Be() which does nothing for every granite wall in the level, for instance. There's a SpillFluid function declared for items: virtual void SpillFluid(character*, liquid*, int = 0); defined as: void item::SpillFluid(character*, liquid* Liquid, int SquareIndex) { // something } That character* is the spiller. It's reserved for future, 0 means no spiller. SquareIndex is only necessary for items larger than one tile, for instance Elpuri's corpse. So if you want to spill poison with a volume of X cubic centimeters, do this in the Be(): SpillFluid(0, liquid::Spawn(POISON_LIQUID, X)); SpillFluid might have problems adding the liquid to the dagger's image if X is too small, as there might be right shifts and other calculations which are rounded down. If such problems occur, consider the following alternative: if(!RAND_N(N)) SpillFluid(0, liquid::Spawn(POISON_LIQUID, N * X)); Where N is an integer. Hmm. I wonder which way would be the best to check if there's too much liquid, and drop some... At least something like this should work: fluidvector FluidVector; FillFluidVector(FluidVector); for(uint c = 0; c < FluidVector.size(); ++c) { liquid* L = FluidVector[c]->GetLiquid(); if(L->GetVolume() >= Y) // define yourself Y = limit volume { long Z = ??? // define yourself Z = how much to drop if(!game::IsInWilderness()) GetLSquareUnder()->SpillFluid(0, L->SpawnMoreLiquid(Z)); L->EditVolume(-Z); } } (If always Z < Y, this is actually not the optimal loop, but the fastest solution crashes if Z >= Y and a fluid is removed because of this, so you should probably play safe.) If you really like to drop the poison to the arm, it would probably be easiest to do like this: if((*Slot)->IsGearSlot()) static_cast<gearslot*>(*Slot)->GetBodyPart()->SpillFluid(0, L->SpawnMoreLiquid(Z)); I don't guarantee that any of this actually works, since I tested nothing. :? May Valpurus be with you when compiling!

Atomic- 04-07-2005

This reminds me of something: could objects/characters that are "covered in fluid" actually drip that fluid onto the ground as they move? The animations show it dripping off, so...

holybanana- 04-07-2005

That would be most consistent, we'll do it eventually.

Ighalli- 04-07-2005

Thanks for the help Holy! My new dagger of venom is working now (but needs balanced). I'm gonna make at least 2 more items and then I'll send you guys some code!

Ighalli- 04-09-2005

OK, the program refuses to use Be on the weapons unless it already wanted to use it in the first place. Ommel tooth versions work, but other materials don't. I think it comes down to this function: truth meleeweapon::CalculateHasBe() const { return LifeExpectancy || (MainMaterial && MainMaterial->HasBe()) || (SecondaryMaterial && SecondaryMaterial->GetVolume() && SecondaryMaterial->HasBe()); } I did include protected: virtual truth CalculateHasBe() const { return true; } in the gear.h, but it looks like the melee weapon CalculateHasBe is overriding that one. Any suggestion for modifying that main CalculateHasBe function?

holybanana- 04-10-2005

Naah, it can't override your function. However, it seems CalculateHasBe() only ensures the item isn't disabled by material changes etc. So the initial enabling must be done manually be adding a constructor: ITEM(daggerofvenom, meleeweapon) { public: daggerofvenom() { Enable(); } virtual void Be(); protected: virtual truth CalculateHasBe() const { return true; } }

Atomic- 04-12-2005

Another item I'm thinking about making are a pair of gauntlets. Well, not really a pair, but two different gauntlets, that are made as singular items. I still havn't made that acid shield yet. But, I'm going to put my thoughts on these two gauntlets down so I don't forget them, and if someone else thinks they're cool and wants to code them theirselves I won't stop them. Fist of Flames: Artifact Resist Fire 30 Adds a little fire damage to melee attacks with that arm Adds lots of fire damage (plus normal damage) to unarmed melee attacks with that arm Chance to cause a small but powerful explosion when attacking unarmed ASTR +2 (+1 per enchantment) Made of "Red Steel" (basically, a harder/lighter form of meteoric steel, only red) Fist of Storms: Artifact Resist Electricity 30 Adds a little electricity damage to melee attacks with that arm Adds lots of electricity damage (plus normal damage) to unarmed melee attacks with that arm Chance to spit out a powerful lightning bolt when attacking unarmed DEX +2 (+1 per enchantment) Made of "White Steel" (same as Red Steel, except white)

blob- 04-12-2005

They seem really powerful. isnt resist 30 too much ?

Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.