Page 2 of 4

Re: Having some trouble with shootProjectile

Posted: Wed Nov 26, 2014 7:12 pm
by Prozail
AndakRainor wrote:Do you know how to delay and move the start positions of multiple projectiles to recreate the meteor spell ?
My code has a SetWorldPosition, if you spawn several, just set different positions. Delaying them is a bit tricker but im sure it can be done either through chaining spells, or with delayCall somehow.

Also for the problem with throwing rocks and arrows, this has not yet been solved.. I'm still at the "Item is not flying" error...(I've gone through pretty much all of the ingame lua, and it's just not done in LoG2.)

I've had an idea to create an arrow-shooting dummy-monster, kindof like the spore_mushroom.

Re: Having some trouble with shootProjectile

Posted: Sun Dec 07, 2014 4:25 pm
by spikedsynapse
Has anyone figured this out yet?

To me this is kind of a staple of classic dungeon crawls.

Re: Having some trouble with shootProjectile

Posted: Mon Dec 08, 2014 1:40 am
by MrChoke
spikedsynapse wrote:Has anyone figured this out yet?

To me this is kind of a staple of classic dungeon crawls.
Prozail's reply in this thread does work. I think it is the way to do it with Grimrock 2. My guess is shootProjectile() needs to get removed from the scripting reference.

Re: Having some trouble with shootProjectile

Posted: Wed Dec 10, 2014 9:25 am
by Prozail
I tried a different approach to the fire-an-arrow problem, and tried to make it into a spell...

It sortof works.. but there are a few issues as to what it actually hits...

Code: Select all


defineObject{
	name = "projectile_arrow_hit",
	baseObject = "base_spell",
	components = {
		{
			class = "Particle",
			particleSystem = "hit_dust",
			destroyObject = true,
		},
	},
}

defineObject{
   name ="projectile_arrow",
   baseObject = "base_spell",
   components = {
		{
			class = "Model",
			model = "assets/models/items/arrow.fbx",
			rotation = vec(0,90,0)
		},
		{
			class = "Projectile",
			spawnOffsetY = 1.15,
			velocity = 15.0,
			radius = 0.1,
			hitEffect = "projectile_arrow_hit",
			onProjectileHit = function(self, what, entity)
				print("onHit",self,what,entity)
				self.go:spawn("arrow")
				if entity and entity.name == "party" then
					local r = math.random(1,4)
					entity.party:getChampionByOrdinal(r):damage(rollDamage(10),"physical")
				end
			end
		}
	},
}

Re: Having some trouble with shootProjectile

Posted: Wed Dec 10, 2014 6:50 pm
by Aisuu
I got it working like this. Only issue is with impact sound. Its same, whether it hit party or wall.
SpoilerShow

Code: Select all

defineObject{
   name ="projectile_arrow",
   baseObject = "base_spell",
   components = {
      {
         class = "Model",
         model = "assets/models/items/arrow.fbx",
         rotation = vec(0,90,0)
      },
      {
         class = "Projectile",
         spawnOffsetY = 1.15,
         velocity = 15.0,
         radius = 0.1,
         hitEffect = "projectile_arrow_hit",
      },
		{
			class = "Sound",
			name = "launchSound",
			sound = "swipe_bow",
		}
   },
}

defineObject{
   name = "projectile_arrow_hit",
   baseObject = "base_spell",
   components = {
	  {
			class = "TileDamager",
			attackPower = 10,
			damageType = "physical",
			screenEffect = "damage_screen",
			sound = "projectile_hit_party",
		}
   },
}

Re: Having some trouble with shootProjectile

Posted: Wed Dec 10, 2014 7:19 pm
by QuintinStone
Haha! I went the same route and made it a spell! :lol:

Code: Select all

defineObject{
	name = "dart_spell",
	baseObject = "base_spell",
	components = {
		{
			class = "Model",
			model = "assets/models/items/blowpipe_dart.fbx",
			rotation = vec(0, 90, 0),
		},
		{
			class = "Projectile",
			spawnOffsetY = 1.15,
			velocity = 20,
			radius = 0.1,
			onProjectileHit = function(self, what, entity)
				-- if what ~= nil then
					-- hudPrint("Hit " .. what)
				-- end
				-- if entity ~= nil then
					-- hudPrint("Entity " .. entity.name)
				-- end
				local damage = 15
				if entity == party then
					-- hudPrint("Hit the party!")
					local i = math.random(1,4)
					local champ = party.party:getChampionByOrdinal(i)
					champ:playDamageSound()
					champ:damage(rollDamage(damage), "physical")
					if math.random() < 0.5 then
						champ:setCondition("poison")
					end
				elseif entity == nil then
					playSound("impact_arrow")
				elseif entity.monster ~= nil then
					-- hudPrint("Hit monster")
					damageTile(entity.level, entity.x, entity.y, 0, entity.elevation, DamageFlags.Impact, "poison", rollDamage(damage))
					if math.random() < 0.9 then
						entity.monster:setCondition("poisoned")
					end
				else
					playSound("impact_arrow")
				end
				self.go:spawn("dart")
			end
		},
	},
}

Re: Having some trouble with shootProjectile

Posted: Thu Dec 18, 2014 4:51 pm
by AndakRainor
I copied your examples to make a spell launching multiple falling rocks in front of the party. There still is one thing I don't know how to implement, how would you use the delayedCall function in this code to avoid throwing all rocks at the same time ? The syntax I used isn't working at all...

Code: Select all

defineObject{
   name = "rock_fall_spell",
   baseObject = "base_spell",
   components = {
      {
         class = "Model",
         model = "assets/models/items/rock.fbx",
         rotation = vec(0, 0, 0),
      },
      {
         class = "Projectile",
         spawnOffsetY = 3,
         velocity = 0,
         gravity = 10,
         radius = 0.1,
         onProjectileHit = function(self, what, entity)
            local damage = 15
            if entity == party then
               -- hudPrint("Hit the party!")
               local i = math.random(1,4)
               local champ = party.party:getChampionByOrdinal(i)
               champ:playDamageSound()
               champ:damage(rollDamage(damage), "physical")
            elseif entity == nil then
               playSound("impact_blunt")
            elseif entity.monster ~= nil then
               -- hudPrint("Hit monster")
               damageTile(entity.level, entity.x, entity.y, 0, entity.elevation, DamageFlags.Impact, "physical", rollDamage(damage))
            else
               playSound("impact_blunt")
            end
            --self.go:spawn("rock")
         end
      },
   },
}

defineSpell{
   name = "test",
   uiName = "Test",
   skill = "concentration",
   requirements = {"concentration", 1},
   gesture = 2,
   manaCost = 0,
   icon = 72,
   spellIcon = 13,
   description = "Throws something",
   onCast = function(champion, x, y, direction, elevation, skillLevel)
      if direction == 0 then y = y-1 else if direction == 1 then x = x+1 else if direction == 2 then y = y+1 else x = x-1 end end end
      local function rock_fall()
        spawn("rock_fall_spell",party.level,x-0.5+math.random(),y-0.5+math.random(),direction,elevation)
      end
      for i = 0, 5, 1 do
        --delayedCall("rock_fall", i, "rock_fall")
        rock_fall()
      end
   end
}

Re: Having some trouble with shootProjectile

Posted: Thu Dec 18, 2014 5:06 pm
by MrChoke
AndakRainor wrote:I copied your examples to make a spell launching multiple falling rocks in front of the party. There still is one thing I don't know how to implement, how would you use the delayedCall function in this code to avoid throwing all rocks at the same time ? The syntax I used isn't working at all...

Code: Select all

defineObject{
   name = "rock_fall_spell",
   baseObject = "base_spell",
   components = {
      {
         class = "Model",
         model = "assets/models/items/rock.fbx",
         rotation = vec(0, 0, 0),
      },
      {
         class = "Projectile",
         spawnOffsetY = 3,
         velocity = 0,
         gravity = 10,
         radius = 0.1,
         onProjectileHit = function(self, what, entity)
            local damage = 15
            if entity == party then
               -- hudPrint("Hit the party!")
               local i = math.random(1,4)
               local champ = party.party:getChampionByOrdinal(i)
               champ:playDamageSound()
               champ:damage(rollDamage(damage), "physical")
            elseif entity == nil then
               playSound("impact_blunt")
            elseif entity.monster ~= nil then
               -- hudPrint("Hit monster")
               damageTile(entity.level, entity.x, entity.y, 0, entity.elevation, DamageFlags.Impact, "physical", rollDamage(damage))
            else
               playSound("impact_blunt")
            end
            --self.go:spawn("rock")
         end
      },
   },
}

defineSpell{
   name = "test",
   uiName = "Test",
   skill = "concentration",
   requirements = {"concentration", 1},
   gesture = 2,
   manaCost = 0,
   icon = 72,
   spellIcon = 13,
   description = "Throws something",
   onCast = function(champion, x, y, direction, elevation, skillLevel)
      if direction == 0 then y = y-1 else if direction == 1 then x = x+1 else if direction == 2 then y = y+1 else x = x-1 end end end
      local function rock_fall()
        spawn("rock_fall_spell",party.level,x-0.5+math.random(),y-0.5+math.random(),direction,elevation)
      end
      for i = 0, 5, 1 do
        --delayedCall("rock_fall", i, "rock_fall")
        rock_fall()
      end
   end
}
The definition of delayedCall isn't worded very well in the scripting reference, nor does it have all the parameters you can pass. It says:

delayedCall(receiver, delay, msg)

receiver = The name of the script where the "delay" function resides
delay = The time to wait in seconds. You can use tenths of seconds too (i.e. 2.5).
msg = The name of the function. It must exits in the script you reference in parameter 1

Also, you can specify any number of additional parameters after these and these parameters will be passed to the delay function. The only limit is they must be basic LUA types (no game objects will work).

Re: Having some trouble with shootProjectile

Posted: Thu Dec 18, 2014 5:21 pm
by AndakRainor
So, here my function is local :

Code: Select all

local function rock_fall()
   spawn("rock_fall_spell",party.level,x-0.5+math.random(),y-0.5+math.random(),direction,elevation)
end
What would be the correct values for the receiver and msg parameters in this situation ?
Should I avoid using a local function ?
Where should I put the code of that function instead, and what would then be the correct values for the delayCall parameters ?

Re: Having some trouble with shootProjectile

Posted: Thu Dec 18, 2014 9:55 pm
by AndakRainor
Ok I found how to use delayCall properly :
the function goes into a script entity named script_center

Code: Select all

function rockFall(x, y, direction, elevation)
  spawn("rock_fall_spell",party.level,x-0.3+0.6*math.random(),y-0.3+0.6*math.random(),direction,elevation)
end
the object definition for the falling rock (multiple impacts sounds are a little annoying, what would you suggest for the sound?)

Code: Select all

defineObject{
   name = "rock_fall_spell",
   baseObject = "base_spell",
   components = {
      {
         class = "Model",
         model = "assets/models/items/rock.fbx",
         rotation = vec(0, 0, 0),
      },
      {
         class = "Projectile",
         spawnOffsetY = 3,
         velocity = 0,
         gravity = 10,
         radius = 0.1,
         onProjectileHit = function(self, what, entity)
            local damage = 5
            if entity == party then
               -- hudPrint("Hit the party!")
               local i = math.random(1,4)
               local champ = party.party:getChampionByOrdinal(i)
               champ:playDamageSound()
               champ:damage(rollDamage(damage), "physical")
            elseif entity == nil then
               --playSound("impact_generic")
            elseif entity.monster ~= nil then
               -- hudPrint("Hit monster")
               damageTile(entity.level, entity.x, entity.y, 0, entity.elevation, DamageFlags.Impact, "physical", rollDamage(damage))
            else
               --playSound("impact_generic")
            end
            --self.go:spawn("rock")
         end
      },
   },
}
and the spell definition :

Code: Select all

defineSpell{
   name = "test",
   uiName = "Test",
   skill = "concentration",
   requirements = {"concentration", 1},
   gesture = 2,
   manaCost = 0,
   icon = 72,
   spellIcon = 13,
   description = "Throws something",
   onCast = function(champion, x, y, direction, elevation, skillLevel)
      if direction == 0 then y = y-1 else if direction == 1 then x = x+1 else if direction == 2 then y = y+1 else x = x-1 end end end
      playSound("serpent_staff_launch")
      local power = champion:getCurrentStat("willpower")*skillLevel/5
      for i = 0, power, 1 do
        delayedCall("script_center", 3*i/power, "rockFall", x, y, direction, elevation)
      end
   end
}
I just noticed that the party doesn't get XP when killing a monster with this spell, do you have any idea why ?