Back to the Korax Forum Archives


Forum

Fri, 06 Feb 2009 13:46:21

Crimson Wizard

I want to discuss our spell system here, in terms of "internal technique". SpellItem class was introduced by Firebrand. If I understood that correct, it acts like an Inventory item that can persist in single instance only and casts some spell when "used"; is this right? Then, SpellInstance class is a base class for a spell... instance, that was already cast and that persist in world for some time, or peforms some complex set of actions and therefore implemented in separate class. Firebrand, I noticed that you added SpiritPowerRequired flag to SpellInstance; maybe it means that spell casting requires spirit power; but I don't think it should be there, because SpellInstance is something that is already created and acting, it cannot be "used", with spirit power or any other power. How to use both these classes in conjunction? I believe that when needed SpellItem should spawn SpellInstance on activation. That's how it fits for player. I am not sure monsters should use same way, unless you want them use mana exactly the way player does. For example, DarkAdvisor simply spawns spell instances in one of his methods during "casting" state. But this question is opened.
Fri, 06 Feb 2009 14:50:03

RambOrc

There are at least two kind of spells in KRPG, offensive spells that work the same way as weapons, and utility spells that work differently. Offensive spells are assigned to keybindings the same way weapons are, i.e. you activate one and when you press fire that one is cast and uses a certain amount of mana of a certain color. These spells are meant to be used many times in a row, like firing a weapon consecutively. Technically offensive spells, melee weapons, ranged weapons and spells inscribed into a staff/wand all work the same way. Utility spells are cast by pressing a certain key or by selecting one from an inventory-like system or by selecting one from a spellbook (exact system to be determined). These spells are meant to be cast occasionally, not several times in quick succession.
Fri, 06 Feb 2009 14:57:30

Crimson Wizard

Well, offensive spells should be implemented as weapon classes then, rather then Spell Items, I guess. Still, they can spawn SpellInstances if this would be ever needed.
Fri, 06 Feb 2009 17:13:57

Firebrand

[quote="Crimson Wizard":rk144zvd]SpellItem class was introduced by Firebrand. If I understood that correct, it acts like an Inventory item that can persist in single instance only and casts some spell when "used"; is this right? Exactly, these are used to be stored on both the spell book and the 'active' spell bar <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. [quote="Crimson Wizard":rk144zvd]Then, SpellInstance class is a base class for a spell... instance, that was already cast and that persist in world for some time, or peforms some complex set of actions and therefore implemented in separate class. Yes, that's good too. [quote="Crimson Wizard":rk144zvd]Firebrand, I noticed that you added SpiritPowerRequired flag to SpellInstance; maybe it means that spell casting requires spirit power; but I don't think it should be there, because SpellInstance is something that is already created and acting, it cannot be "used", with spirit power or any other power. Maybe you are right here too, but then how can we define if the spell uses spirit power or some kind of charge? Or maybe I should ask, what are the main sources of power for spells? [quote="Crimson Wizard":rk144zvd]How to use both these classes in conjunction? I believe that when needed SpellItem should spawn SpellInstance on activation. That's how it fits for player. I am not sure monsters should use same way, unless you want them use mana exactly the way player does. For example, DarkAdvisor simply spawns spell instances in one of his methods during "casting" state. But this question is opened. I was thinking that monsters should have a limited number of 'spirit power' or number of times they can use spells, whatever suits the best for you here is fine IMO. The same would go for inventory, but we won't discuss that on this thread <!-- s;) --><img src="{SMILIES_PATH}/orc9.gif" alt=";)" title="Wink" /><!-- s;) -->.
Fri, 06 Feb 2009 18:47:36

Crimson Wizard

[quote="Firebrand":1tpm7u39] [quote="Crimson Wizard":1tpm7u39]Firebrand, I noticed that you added SpiritPowerRequired flag to SpellInstance; maybe it means that spell casting requires spirit power; but I don't think it should be there, because SpellInstance is something that is already created and acting, it cannot be "used", with spirit power or any other power. Maybe you are right here too, but then how can we define if the spell uses spirit power or some kind of charge? If you mean that spell is draining spirit power continously while working - then it should stay, only I think it would be better to use different variables to determine power costs, butthis may be changed in future. If you were refering to a simply limited duration, this can be easily set after SpellInstance spawn using exisiting LifeDuration property. [quote="Firebrand":1tpm7u39] Or maybe I should ask, what are the main sources of power for spells? Eh, are you asking me? Because I don't know anything except what was written in the concept document. [quote="Firebrand":1tpm7u39] [quote="Crimson Wizard":1tpm7u39]How to use both these classes in conjunction? I believe that when needed SpellItem should spawn SpellInstance on activation. That's how it fits for player. I am not sure monsters should use same way, unless you want them use mana exactly the way player does. For example, DarkAdvisor simply spawns spell instances in one of his methods during "casting" state. But this question is opened. I was thinking that monsters should have a limited number of 'spirit power' or number of times they can use spells, whatever suits the best for you here is fine IMO. Hmm, if you set the problem up this way, I'd say it should depend on monster. I would vote for monsters having 2 properties: max mana (or spirit power if you like) and rate of power regeneration. Low class monsters may have their regeneration very low or zero even (this will work like limited times of use), and bosses probably high speed regeneration. I suggest we should determine this soon, before any more monsters with magic abilities are created. And also this means I'll have to partially rewrite Dark Advisor's spellcasting.
Sat, 07 Feb 2009 02:04:39

Firebrand

[quote="Crimson Wizard":15kcaud6]If you mean that spell is draining spirit power continuously while working - then it should stay, only I think it would be better to use different variables to determine power costs, but this may be changed in future. That's what I meant, so we can leave it as it is for now and make some change if it's needed in the future. [quote="Crimson Wizard":15kcaud6]Eh, are you asking me? Because I don't know anything except what was written in the concept document. No, I guess it's clear enough that spritual power and mana are going to be the main two sources of power for spells now <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. [quote="Crimson Wizard":15kcaud6]Hmm, if you set the problem up this way, I'd say it should depend on monster. I would vote for monsters having 2 properties: max mana (or spirit power if you like) and rate of power regeneration. Yes, I agree with this, let's just have one counter for spirit power and a regeneration rate for it, setting them accordingly for monsters as needed <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. Now, I was thinking on something else, we could define what items/spells monsters carry on with them in their default properties (pretty much as it is done with players), where they have a default inventory and they execute an GiveDefaultInventory method or something like that, what do you think of this?
Sat, 07 Feb 2009 03:18:42

Crimson Wizard

[quote="Firebrand":e4pfva2j] Now, I was thinking on something else, we could define what items/spells monsters carry on with them in their default properties (pretty much as it is done with players), where they have a default inventory and they execute an GiveDefaultInventory method or something like that, what do you think of this? I suggest giving starting inventory in a method, with some randomization; like some monsters have different amount of items and some do not have all of possible item/spells (if we talk about basic spells, not the boss level ones).
Sat, 07 Feb 2009 11:16:51

RambOrc

If you are already planning inventory for monsters: I recall in Stonekeep that there was a guy who mid-fight ran to a secret stash in the room, opened it and got food out of it, eat it and healed himself up. If you knew about it, you could position yourself to block his way to the stash, kill him, and the food was there in the stash for you to pick up.
Sat, 07 Feb 2009 14:09:55

Crimson Wizard

[quote="RambOrc":2hxvmuul]If you are already planning inventory for monsters: I recall in Stonekeep that there was a guy who mid-fight ran to a secret stash in the room, opened it and got food out of it, eat it and healed himself up. If you knew about it, you could position yourself to block his way to the stash, kill him, and the food was there in the stash for you to pick up. This reminds me, should monsters pikcup items that they can use?
Sat, 07 Feb 2009 14:35:30

RambOrc

Certain unimportant types, why not? Just not valuable or rare things. Also, this could be reserved for smarter versions of monsters, not the lower ranks of a type.
Sat, 07 Feb 2009 23:15:09

Firebrand

I wouln't like that, but it's just my opinion, I don't think that's needed.
Sat, 07 Feb 2009 23:48:51

Crimson Wizard

[quote="Firebrand":3afko5vi]I wouln't like that, but it's just my opinion, I don't think that's needed. Well, I also have some doubts about this; primarily because it makes it incomprehensible why haven't they took items earlier, before they met player. Maybe if we want some particular monsters have more items we may use ACS command to give them what they need.
Sun, 08 Feb 2009 03:47:41

Firebrand

I don't see the need of that neither, since we can assign their inventory initially after spawning them to maps, we can easily add an extra parameter that defines how many of which item(s) the monster will have <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->.
Sun, 08 Feb 2009 10:59:07

RambOrc

For future reference: if I say "why not?", that means feel free to either implement or not implement a feature, I have no strong feelings either way. <!-- s;) --><img src="{SMILIES_PATH}/orc9.gif" alt=";)" title="Wink" /><!-- s;) -->
Sun, 08 Feb 2009 15:46:13

Crimson Wizard

[quote="Firebrand":26rncykm]I don't see the need of that neither, since we can assign their inventory initially after spawning them to maps, we can easily add an extra parameter that defines how many of which item(s) the monster will have <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. What parameter are you talking about? And what if I want to add something non-default?
Sun, 08 Feb 2009 16:12:11

Firebrand

[quote="Crimson Wizard":2nca0k3z]What parameter are you talking about? It's not yet implemented, but I was thinking on adding something similar to the default inventory like for the players, but instead of giving every item on the default inventory we would give the items enumerated there randomly (and random quantities/uses for them), hope this is more clear now <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. [quote="Crimson Wizard":2nca0k3z]And what if I want to add something non-default? I would like to ask, giving something for using or something for dropping when enemies die? If it's the first possibility, then we would simply use the GiveInventory ACS special already implemented in the engine, if it's the second one, then we could make the enemy spawn the item by executing an ACS script <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->.
Sun, 08 Feb 2009 18:15:41

RambOrc

In Heretic, some monsters dropped ammo or items now and then, and Heretic didn't have ACS. Isn't this code still in the Hexen code?
Sun, 08 Feb 2009 18:36:20

Firebrand

Yep, it's still there, I forgot about that, and that's the easiest way of doing it <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->.
Mon, 09 Feb 2009 00:11:40

Crimson Wizard

[quote="Firebrand":n2a8nkp4][quote="Crimson Wizard":n2a8nkp4]What parameter are you talking about? It's not yet implemented, but I was thinking on adding something similar to the default inventory like for the players, but instead of giving every item on the default inventory we would give the items enumerated there randomly (and random quantities/uses for them), hope this is more clear now <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. Actually it is more unclear now. I was wondering about how these "parameters" should be set for a monster placed on map. Or shouldn't they? [quote="Firebrand":n2a8nkp4][quote="Crimson Wizard":n2a8nkp4]And what if I want to add something non-default? I would like to ask, giving something for using or something for dropping when enemies die? I was thinking that monster drops his whole inventory in death...
Mon, 09 Feb 2009 15:56:15

Firebrand

[quote="Crimson Wizard":3v5x7avf]Actually it is more unclear now. I was wondering about how these "parameters" should be set for a monster placed on map. Or shouldn't they? For ease of implementation, it shouldn't be set, we can define a min and max parameter of how many items of a powerup the monster will have and this can be decided randomly using the same method I mentioned <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. But we could define a special argument and set it up on a map editor, but IMO it would make it too complex to set up monsters. [quote="Crimson Wizard":3v5x7avf]I was thinking that monster drops his whole inventory in death... This can be done by modifying the existing methods in progs, but it would be a bit unbalanced IMO.
Mon, 09 Feb 2009 16:16:04

RambOrc

Drop tables should be simple and consistent, e.g. a centaur has a 1 in 4 chance to drop a silver bar and a 1 in 8 chance to drop a gold bar and they are exclusive, i.e. rolling an 8-sided dice if it's 1 or 2 it drops a silver bar, if it's 3 it drops a gold bar, if it's 4, 5, 6, 7 or 8 it drops nothing. That would basically mean that killing a dozen centaurs would net you a few silver bars and maybe a gold bar. Crazy drop tables with dozens of items on them and very low drop chances like in Diablo II or World of Warcraft are made for highly repetitive games with constant monster respawns. KRPG is a single player game with very few respawns (in many maps, none at all), meaning if certain monsters have a low chance of dropping something good, players will just save before killing it and reload 100x til the desired item drops. Definitely not fun. For the same reason, nothing really good should be from killing monsters. All cool stuff like new weapons, spells, powerups, chests of gold etc. should be placed on the map in a way that the player has to kill a number of monsters and for exceptionally good items a boss monster, so that if you progress in the story line and thus defeat certain bosses, you are guaranteed to get the most important weapons/spells/whatever. Nothing good should ever be dropped through a random number generator (RNG). Dropping items from monsters would be just an RPG touch, not a necessity to kill endlessly monsters for. Basic DOOM engine stuff like ammo and health will be placed the classic way, i.e. floating all around the map. The money that monsters drop can be used to buy more health potions or ammo if you are short on them, and you can sell health potions to the vendors if you acquire more than you use.
Mon, 09 Feb 2009 16:51:01

Crimson Wizard

Well, that's all is fair enouph and reasonable, although I was wondering if an Ettin Fletchetter may have a chance to drop a fletchette sometimes, for example. I think we should commence writing some rouph table of iventory owned/dropped for each monster, since we already have number of new monsters, and all original Hexen ones, so we may test how all this works.
Mon, 09 Feb 2009 17:00:15

RambOrc

How about every monster family drops one certain thing (or max two), the higher tier the monster within the family, the higher chance to drop it? Like the original ettin has a 10% chance to drop a silver bar, the grenadier like 20%, the commander like 50%?
Mon, 09 Feb 2009 17:05:09

Firebrand

This sounds interesting, I like the idea of higher ranks of the same family of monsters increasing chances of dropping stuff <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->. I also agree with CW, we need to create a rough table of what monsters can drop to implement it to the game, it will make it easier to code and modify in case something is needed.
Mon, 09 Feb 2009 18:06:00

RambOrc

First thing is to determine what monsters can drop at all. I vote: - silver bars - gold bars (or whatever kind of money thing we include in KRGP)
Mon, 09 Feb 2009 20:36:27

Crimson Wizard

What about making rare chance some particular monsters drop their ammunition (the ones that is usable for player ofc). Like Ettin Grenadier can sometimes drop Flechette, and Commander can drop green mana (his weapon is analogue of the Hammer of Retribution which uses green mana). [quote="RambOrc":1jm5qhzg]First thing is to determine what monsters can drop at all. maybe.. - mana from those who use magic/magical weapons - health vials/quartz flasks from toupher monsters.
Thu, 12 Feb 2009 14:22:41

Crimson Wizard

Hm, the discussion turned to monster inventory somehow... Anyway, I wanted to explain some things about SpellInstance and ActorConditions here, i.e. about how to code them (I believe Firebrand will want to read this <!-- s:) --><img src="{SMILIES_PATH}/orc2.gif" alt=":)" title="Smile" /><!-- s:) -->) SpellInstance is a base class for the spell thinkers, i.e. spells that were cast and act for some time on their own (it's like 'fire & forget'). SpellInstance itself does not do much, but it provides some properties to customize spell a little. [u:3f5gkksv]AInstigator[/u:3f5gkksv] reference points to an actor which shot the spell; [u:3f5gkksv]bIsNegative[/u:3f5gkksv] and [u:3f5gkksv]bIsMagic[/u:3f5gkksv] flags allow to set spell personality, first is self-explanatory, second allows to mark that this is not actually a magic spell, but rather some kind of natural factor; they are not used anywhere at the moment, but could become useful if we desire to impement something like 'Dispell Magic' for example. [u:3f5gkksv]Level[/u:3f5gkksv] determines power of this exactly spell instance (not the spell in general). It is up to you (if you create a new type of spell) to decide how it is used in determining spell effeciency (if use it at all). [u:3f5gkksv]LifeDuration[/u:3f5gkksv] is very important, it determines how much time spell instance exists. [u:3f5gkksv]LifeTime[/u:3f5gkksv] is set equal to LifeDuration as soon as spell activates and ticks away. If LifeDuration is 0, spell instance has no time limit. LifeDuration is set in real time (seconds). [u:3f5gkksv]SpiritPowerDrain[/u:3f5gkksv] property alows to set an amount of spirit power (mana) drained from AInstigator each [u:3f5gkksv]SPDrainDelay[/u:3f5gkksv] seconds. If SpiritPowerDrain is 0, no sp drained. How does SpellInstance work? First of all, being Thinker, SI has [u:3f5gkksv]Tick[/u:3f5gkksv] method; however it is not recommended to override it in child classes (if you do, don't forget to call parent's Tick before anything else). Instead, if you need some actions to perform from time to time, use [u:3f5gkksv]Do[/u:3f5gkksv] method. If something should happen on spell activation, override [u:3f5gkksv]Activate[/u:3f5gkksv] method (as with Tick, do not forget to call parent's Acivate, for it initializes lifetime); then if something should happen before spell dies, override [u:3f5gkksv]Deactivate[/u:3f5gkksv] method (calling parent method is not necessary here). How does SpellInstance is being created? As a Thinker, it is allocated using Spawn method (usually Level.Spawn, if you call it from some actor's method). It should be set up after then. In following sample a GoldenStorm is being cast by Dark Advisor (check BlackBishop.vc):
SpellGoldenStorm SGS = SpellGoldenStorm(Level.Spawn(SpellGoldenStorm));
if (SGS)
{
	SGS.AInstigator = self;
	SGS.Level = 7;
	SGS.LifeDuration = 24.0;
	SGS.Origin = Target.Origin;
	SGS.Target = Target;
	SGS.Activate();
}
Here you may see that some standart properties of SpellInstance are set as well as some properties specific for that spell. (SpellGoldenStorm is not a direct child of SpellInstance, but a child of SpellPointBased; SpellPointBased is a child of SpelInstance and a parent for spells that are targetted somehow to some particular point of map or target actor's position)
Thu, 12 Feb 2009 14:52:45

Crimson Wizard

ActorCondition is a child class of SpellInstance and a parent class for the layed spells, i.e. spells that are layed on actors and 'hang' on them, doing something. It adds some extra properties to be set: [u:156vf87z]ARecepient[/u:156vf87z] - an actor which has the spell layed on him (but it is not necessary that he gets all the effects!) [u:156vf87z]CastMessage[/u:156vf87z] - a text that appears on actor's HUD when this spell is being layed on him (this works for players only, ofc) [u:156vf87z]MaxAccumulatedLifePerLevel[/u:156vf87z] - an interesting property, it determines what happens if same spell is cast on actor while he has it still layed on himself. Normally that will increase spell's LifeTime. MaxAccumulatedLifePerLevel determines how many lifetime can be accumulated that way (it depends on spell level). If MaxAccumulatedLifePerLevel = 0, this spell cannot accumulate lifetime (i.e. nothing will happen). MaxAccumulatedLifePerLevel < 0 means unlimited accumulation. Finally, [u:156vf87z]CShift*[/u:156vf87z] properties control visual effect (palette flash) player gets when the spell is layed on him: [u:156vf87z]CShiftOperation[/u:156vf87z] determines the binary operation used, it can be CSHIFT_OP_NONE (no effect at all, default), CSHIFT_OP_SET (just sets effect, overwriting anything else), CSHIFT_OP_OR (adds colours using '|' operator) and CSHIFT_OP_AND (adds colours using '&' operator). [u:156vf87z]CShift[/u:156vf87z] stores colour value. Set it using this formula: CShift = RGBA(R, G, B, Amount). [u:156vf87z]bCShiftFadeOverTime[/u:156vf87z] makes colour effect gradually fade away as spell looses its lifetime. [u:156vf87z]bCShiftFadeBeforeDeath[/u:156vf87z] makes colour effect fade away only when spell is about to die (useful to make player aware that spell wears off some time before it happens). ActorCondition can be spawned same way as SpellInstance, but that's usually not recommended, becuase it has to have strong contact with recepient; for example it must dispell automaticlaly when recepient dies. So, normally you should use Actor::CastCondition method. It stores AC created in a special array for that actor, and also handles spell accumulation properly. In following example Berserk SpellItem casts Berserk ActorCondition on item owner:
Actor(Owner.Player.MO).CastCondition(
			ACSpellBerserk,				// condition class
			false,						// not accumulative
			Actor(Owner.Player.MO),		// instigator (caster)
			1,							// spell level (should be calculated somehow?)
										// duration
			(1.0 + itof(Player(Owner.Player).sp_power) * 80.0) / 35.0
			);
Along with Do, Activated and Deactivated methods, that can be useful for ActorCondition, it introduces couple of more methods that you may override in your spells. [u:156vf87z]CanBeCastUpon[/u:156vf87z] method makes a check if this AC can be cast on an actor given. When overriding yo may want to call parent's CanBeCastUpon before making any other checks and continue only if parent's returned TRUE (it checks actor's Health > 0). What else can be checked here? For example ACPoisoned has this check:
bool CanBeCastUpon(Actor recepient)
{
	return recepient.Health > 0 && recepient.bLiving;
}
In other words it can be cast only on those actors with bLiving flag set. [u:156vf87z]Notify[/u:156vf87z] method can be important for some spells. It is called by actor to notify his Conditions about something happened. Commonly it notifies them about his own death. ACSpellManaBurn extends this method to damage actor only when he uses mana to attack:
switch (notification)
{
case ActorCondition::notify_ManaUsed:
	bDoDamage = true;
	AccumulatedDamage += param;
	break;
default:
	::Notify(notification, E, param);
}
Thu, 12 Feb 2009 15:59:51

Firebrand

Good work with these explanations, they are clear enough for me now <!-- s;) --><img src="{SMILIES_PATH}/orc9.gif" alt=";)" title="Wink" /><!-- s;) -->, thanks!

Back to the Korax Forum Archives