Actions lasting more than 1 round

Moderator: Moderator

Post Reply
Message
Author
Kemsha
Higher
Posts: 58
Joined: Thu Aug 26, 2010 3:46 pm

Actions lasting more than 1 round

#1 Post by Kemsha »

Hi all,

I was wondering if there's an (easy) way to code actions that last more than 1 round.
For instance, a talent that you have to concentrate 2 rounds and on the third it takes effect.

The way I see it, there are several choices while your are concentrating (or aiming or preparing or whatever)

1) Anything that would break running stops the preparation
2) You're asked if you want to stop or keep concentrating
3) You can't do nothing until the action is done

It would open the way for several interisting choices like:
- Aim for 2 rounds than shoot for +x damage
- Gain momentum for 1 round then make a melee attack for +x damage
- reloading your weapon takes 3 rounds

It could bring problems for moving targets but you could simply stop the action if your target breaks LOS

I couldn't remember anything already created like that, so maybe that's my answer
So... can it be done?


Thanks

darkgod
Master of Eyal
Posts: 10751
Joined: Wed Jul 24, 2002 9:26 pm
Location: Angolwen
Contact:

Re: Actions lasting more than 1 round

#2 Post by darkgod »

Actions that interrupt like run/rest, yes check out how diggers work.
Actions that take multiple turns and are not interuptable: call actor:useEnergy(game.energy_to_act * X)
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)

marvalis
Uruivellas
Posts: 683
Joined: Sun Sep 05, 2010 5:11 am

Re: Actions lasting more than 1 round

#3 Post by marvalis »

Just a general remark: I like skill the best that work over multiple turns and allow you to position while using them.

For example, a channeled spell that allows you to move but not take any other action (no attacking, no casting, no equipment swapping or picking up items).

Maybe it could be set up as a temporary effect called 'channeling' that prevents all actions except movement, and triggers the effect when it runs out.

Actions that take more than one turn are dangerous if you cannot take any actions. They function as a X-turn stun (the old stun, not the new one). Even two turns can be dangerous: The skeleton hits you, the skeleton hits you, you are dead.

Frumple
Sher'Tul Godslayer
Posts: 1517
Joined: Sat May 15, 2010 9:17 pm

Re: Actions lasting more than 1 round

#4 Post by Frumple »

I'd think it'd be pretty easy to have a multi-turn status effect that prevents you from doing anything but moving, and then does something else when that effect ends. It'd be kinda' like tying disarmed and silence into a temporary psionic aura/shield, and then having it spike when the shield wore out. Vaguely staring at the code seems to suggest it'd be at least possible to basically do exactly that -- have a talent that prevented non-movement actions for a few turns and then did something interesting.

lukep
Sher'Tul Godslayer
Posts: 1712
Joined: Mon Mar 14, 2011 10:32 am
Location: Canada

Re: Actions lasting more than 1 round

#5 Post by lukep »

I would look at movement infusions, psionic auras, and maybe meditation/spacetime tuning, and build out from there. Alternatively, you could check out gather the threads for a different way of doing something like that.
Some of my tools for helping make talents:
Melee Talent Creator
Annotated Talent Code (incomplete)

edge2054
Retired Ninja
Posts: 3756
Joined: Fri May 28, 2010 4:38 pm

Re: Actions lasting more than 1 round

#6 Post by edge2054 »

Yeah, to reiterate what's already been said. A two turn cast that is interpretable can be done easily as a timed effect that breaks on whatever you want the break conditions to be.

Just have it set to do 'blah' when the required number of turns is done (I'd build a timer right into the timed effect and have it count down on time_out then have the time_out effect actually trigger what ever you want your talent to do once the timer was at the right spot) then set up your break conditions in Actor (on move, on talent use, on damage are easy ones).

Kemsha
Higher
Posts: 58
Joined: Thu Aug 26, 2010 3:46 pm

Re: Actions lasting more than 1 round

#7 Post by Kemsha »

Ok, so I began with something simple, aim for a few turns then fire.
Using the diggers code as base:

Code: Select all

	action = function(self, t)
		local targets = self:archeryAcquireTargets(nil, {one_shot=true})
		if not targets then return end
		local wait = function()
			local co = coroutine.running()
			local ok = false
			self:restInit( t.aim_time(self,t), "aiming", "aimed", function(cnt, max)
				if cnt > max then ok = true end
				coroutine.resume(co)
			end)
			coroutine.yield()
			if not ok then
				game.logPlayer(who, "You have been interrupted!")
				return false
			end
			return true
		end
		if wait() then
			res = self:archeryShoot(targets, t, nil, {mult=self:combatTalentWeaponDamage(t, 1.1, 2.2)})
		end
		
		return true
	end,
It doesn't work the way I wanted. After the waiting time, the arrow doesn't move, only after I do something.
Also, I get interrupted if a monster moves, not very nice.

If I understood correctly, it's the yield routine that determines when my action is interrupted, is that right? Where is it coded?

Maybe I should do as a timed effect like you said, keeping line of sight and allowing move (maybe a slower move), where should I start?

I know programing but no LUA so most of what I do is copying code but I'm getting better... I think. One of the things that sometimes troubles me is finding where something is coded (too many files to look)

edge2054
Retired Ninja
Posts: 3756
Joined: Fri May 28, 2010 4:38 pm

Re: Actions lasting more than 1 round

#8 Post by edge2054 »

I have no idea how diggers work but I can try to walk you through how to do it with a timed effect.

Here's an excerpt from a timed effect and talent that's in the SVN that causes an effect after so many turns. For your purposes you'd want to add some break effects in class/actor (look for step up to get an idea how that's done) to remove the effect early if the character tries to do anything else.

From data/timed_effects (note this is in the SVN)

Code: Select all

	on_timeout = function(self, eff)
		self.worm_rot_timer = self.worm_rot_timer - 1  -- our timer count here
		-- burst and spawn a worm mass
		if self.worm_rot_timer == 0 then  -- and the trigger when it hits 0
			DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.burst, {from_disease=true})
			local t = eff.src:getTalentFromId(eff.src.T_WORM_ROT)
			t.spawn_carrion_worm(eff.src, self, t)
			game.logSeen(self, "#LIGHT_RED#A carrion worm mass bursts out of %s!", self.name:capitalize())
			self:removeEffect(self.EFF_WORM_ROT)
		end
	end,
	activate = function(self, eff)
		self.worm_rot_timer = 5 -- start our timer here
	end,
	deactivate = function(self, eff)
		self.worm_rot_timer = nil -- make sure the timer is removed when the effect is
	end,
}
And from the talent info (something similar is in data\talents\spells\air in the thunderstorm function, though it's called differently).

Code: Select all

	spawn_carrion_worm = function (self, target, t)
		local x, y = util.findFreeGrid(target.x, target.y, 10, true, {[Map.ACTOR]=true})
		if not x then
			return
		end
		
		local worm = {type="vermin", subtype="worms", name="carrion worm mass", number=1, hasxp=false}
		local m = game.zone:makeEntity(game.level, "actor", worm, nil, true)
		m:resolve()
		m.faction = self.faction
		
		game.zone:addEntity(game.level, m, "actor", x, y)
	end,	
Note that this is kinda a bad example for what you're specifically trying to do. But it should be a start. You can't really copy and paste this since you're wanting to fire on something after X turns rather then summon an enemy. But you can see in the timed effect how it has a delayed damage effect (when the worm mass spawns). Something similar could be done as a projectile. In the case of my example changing the self.x, self.y to eff.src.x and eff.src.y would cause the projector to originate from the caster rather then the person with the timed effect. I'd probably call it in the timed effect and put the projector code in the talent itself so you can pull the targeting information from there (hit, bolt, etc.)

Kemsha
Higher
Posts: 58
Joined: Thu Aug 26, 2010 3:46 pm

Re: Actions lasting more than 1 round

#9 Post by Kemsha »

Ok, I think I got it.

If I undestood correctly, I can have a timed effect "Aiming" that fires a shot when it ends.
So I could have a talent that selects a target, then sets this condition. And the shooting part is coded on the talent, right?

I'll give it another try, thanks a lot

edge2054
Retired Ninja
Posts: 3756
Joined: Fri May 28, 2010 4:38 pm

Re: Actions lasting more than 1 round

#10 Post by edge2054 »

Yeah, that's how I would do it. There's other ways and probably a better way but this should give you something to work with.

Note that I use timers inside the timed effect rather then just on deactivate, because the deactivate condition is what's called when the effect is removed. Kinda confusing but say you wanted early movement to break your effect or say something clears the effect mid cast (or say timeless increases the timer on the effect), you'd end up with the duration of your Aim effect being extended or going off early.

Post Reply