Page 306 of 400

Re: Ask a simple question, get a simple answer

Posted: Wed May 01, 2019 9:29 am
by Pompidom
I figured it out, I just added the onDie in the monster class of the base trooper class so all different variations of the skeleton trooper model now drop a skeleton corpse on the spot where they perish :)

onDie = function(self)
spawn("dm_floordeco_corpse", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation)
end,

Code: Select all

monsters["skeleton_trooper"] = {
weapons = {
	skullcleave={model="assets/models/items/skeleton_knight_axe.fbx",wtype="axe",offset=vec(0.03,0.17,0.04),rotation=vec(90,0,270),attackPower=15,cooldown=4.5},
	ancient_claymore={model="assets/models/items/claymore.fbx",wtype="sword",offset=vec(0,0.45,-0.03),rotation=vec(270,0,270),attackPower=45,cooldown=5},
	backbiter={model="assets/models/items/backbiter.fbx",wtype="sword",offset=vec(0,0.1,0.03),rotation=vec(90,0,270),attackPower=15,cooldown=3,accuracy=5},
	baton={model="assets/models/items/baton.fbx",wtype="mace",offset=vec(0,0.2,0.06),rotation=vec(90,0,270),attackPower=10,cooldown=4.5},
	bone_blade={model="assets/models/items/bone_blade.fbx",wtype="sword",offset=vec(-0.02,0.1,0.05),rotation=vec(90,0,270),attackPower=25,accuracy=10,cooldown=3.4},
	bone_club={model="assets/models/items/bone_club.fbx",wtype="mace",offset=vec(-0.06,0.1,0.05),rotation=vec(50,-20,270),attackPower=4,cooldown=3},
	cudgel={model="assets/models/items/cudgel.fbx",wtype="mace",offset=vec(-0.08,0.14,0),rotation=vec(180,0,270),attackPower=12,cooldown=5},
	cutlass={model="assets/models/items/cutlass.fbx",wtype="sword",offset=vec(-0.01,0.32,0.03),rotation=vec(90,0,270),attackPower=24,cooldown=3.3},
	dagger={model="assets/models/items/dagger.fbx",wtype="sword",offset=vec(-0.01,0.08,0.03),rotation=vec(90,0,270),attackPower=7,accuracy=5,cooldown=2.5},
	g1_dismantler={model="assets/models/items/dismantler.fbx",wtype="sword",offset=vec(0,0.4,-0.03),rotation=vec(270,0,270),attackPower = 41,cooldown = 4,
		extraComponents = G1_ENHANCED_FX and {
			{
				class = "Light",
				parentNode = "weapon_right",
				offset = vec(0.2, 0.05, 0)+vec(0,0.4,-0.03),
				range = 2,
				color = vec(0.25,0.5,1),
				brightness = 30,
				castShadow = false,
				fillLight = true,
				onUpdate = function(self)
					self:setBrightness((math.noise(Time.currentTime()*13+123)*15+27))
				end,
			},
			{
				class = "Particle",
				parentNode = "weapon_right",
				particleSystem = "g1_dismantler",
				offset = vec(0,0.4,-0.03),
				rotation=vec(270,0,270),
				emitterMesh = "mod_assets/g1/items/Standard/dismantler_emitter.fbx",
			},
		} or nil,
		onAttackHit = function(self, champion)
			if math.random() < 0.25 then 
				local d = spawn("shockburst",party.level,party.x,party.y,party.facing,party.elevation).tiledamager
				d:setAttackPower(30)
			end
		end,
	},
	g1_gladius=G1_MINE_WEAPONS and {model="mod_assets/g1/items/Mine/Gladius.fbx",wtype="sword",offset=vec(0,0.3,-0.03),rotation=vec(270,0,270),attackPower=13,accuracy=5,cooldown=3.6} or nil,
	hand_axe={model="assets/models/items/hand_axe.fbx",wtype="axe",offset=vec(0.02,0.1,0.05),rotation=vec(90,0,270),attackPower=10,cooldown=4.5},
	long_sword={model="assets/models/items/long_sword.fbx",wtype="sword",offset=vec(0,0.4,-0.03),rotation=vec(270,0,270),attackPower=16,cooldown=3.7},
	machete={model="assets/models/items/machete.fbx",wtype="sword",offset=vec(0,0.32,0.03),rotation=vec(90,0,270),attackPower=12,cooldown=4.5},
	-- pierce compensation
	morning_star={model="assets/models/items/morning_star.fbx",wtype="mace",offset=vec(-0.01,0.25,-0.04),rotation=vec(270,0,270),attackPower=25,cooldown=4.5},
	throwing_axe={model="assets/models/items/throwing_axe.fbx",wtype="axe",offset=vec(0.08,0.25,0.05),rotation=vec(90,0,270),attackPower=5,cooldown=3.5},
	torch={model="assets/models/items/torch.fbx",wtype="mace",offset=vec(0,0.25,-0.03),rotation=vec(270,0,270),attackPower=4,cooldown=3,
		extraComponents = {
			{
				class = "Light",
				parentNode = "weapon_right",
				range = 9,
				offset = vec(0,0.65,0.03),
				brightness = 10,
				castShadow = true,
				onUpdate = function(self)
					local noise = math.noise(Time.currentTime()*3 + 123) * 0.5 + 0.9
					self:setBrightness(noise * 10)
				end,
			},
			{
				class = "Particle",
				parentNode = "weapon_right",
				particleSystem = "torch_dynamic",
				offset = vec(0,0.65,0.03),
				rotation = vec(0,0,-50),
			},
		},
	},
	warhammer={model="assets/models/items/warhammer.fbx",wtype="mace",offset=vec(-0.02,0.25,0.05),rotation=vec(90,0,90),attackPower=20,cooldown=4.5},
},

-- XXX: The axe animation has a little clipping with some of these because e.g. the heavy shield is so much larger than the kite shield the standard skeleton trooper has...
shields = {
	skeleton_knight_shield={model = "assets/models/items/skeleton_knight_shield.fbx",offset = vec(0,-0.15,0.07),rotation = vec(90,0,90),evasion=5},

	legionary_shield=G1_STANDARD_ITEMS and {model = "assets/models/items/skeleton_shield.fbx",offset = vec(0,-0.35,0.06),rotation = vec(100,0,270),evasion=5} or nil,
	heavy_shield={model = "mod_assets/g1/monsters/weapon_monsters/heavy_shield_strapless.fbx",offset = vec(0,-0.35,0.06),rotation = vec(100,0,270),evasion=6},
	g1_shield_courage=G1_SHIELDS and {model = "mod_assets/g1/monsters/weapon_monsters/heavy_shield_strapless.fbx",material="heavy_shield_lion",offset = vec(0,-0.35,0.06),rotation = vec(100,0,270),evasion=8} or nil,
	g1_shield_falcon=G1_SHIELDS and {model = "mod_assets/g1/monsters/weapon_monsters/heavy_shield_strapless.fbx",material="heavy_shield_falcon",offset = vec(0,-0.35,0.06),rotation = vec(100,0,270),evasion=12,cooldownMod=1.2} or nil,

	crystal_shield={model = "assets/models/items/crystal_shield.fbx",offset = vec(0.1,-0.2,0.1),rotation = vec(100,0,290),evasion=10},

	round_shield={model = "assets/models/items/small_shield.fbx",offset = vec(0,-0.08,-0.05),rotation = vec(270,0,270),evasion=4},
	g1_shield_winter=G1_SHIELDS and {model = "assets/models/items/small_shield.fbx",material="small_shield_blue",offset = vec(0,-0.08,-0.05),rotation = vec(270,0,270),evasion=6} or nil,
	g1_shield_dragon=G1_SHIELDS and {model = "assets/models/items/small_shield.fbx",material="small_shield_red",offset = vec(0,-0.08,-0.05),rotation = vec(270,0,270),evasion=6,hpMod=30} or nil,

	shield_elements={model = "assets/models/items/shield_elements.fbx",offset = vec(0.04,-0.3,0.1),rotation = vec(90,0,275),evasion=7},
	meteor_shield={model = "assets/models/items/meteor_shield.fbx",offset = vec(0.04,-0.1,0.1),rotation = vec(90,0,275),evasion=7},
	g1_shield_valor={model = "assets/models/items/shield_valor.fbx",offset = vec(0.04,-0.1,0.1),rotation = vec(90,0,275),evasion=10},
}
}

monsters.skeleton_trooper.create = function(weapon,shield,wname,sname,preferredName)

local comps ={
		{
			class = "Model",
			name = "weaponModel",
			parentNode = "weapon_right",
			model = weapon.model,
			offset = weapon.offset,
			rotation = weapon.rotation,
			material = weapon.material,
		},
		{
			class = "Model",
			name = "shieldModel",
			parentNode = "weapon_left",
			model = shield.model,
			offset = shield.offset,
			rotation = shield.rotation,
			material = shield.material,
		},
		{
			class = "Monster",
			meshName = "skeleton_knight_trooper_mesh",
			footstepSound = "skeleton_footstep",
			hitSound = "skeleton_hit",
			dieSound = "skeleton_die",
			hitEffect = "hit_dust",
			capsuleHeight = 0.7,
			capsuleRadius = 0.25,
			collisionRadius = 0.6,
			health = 150+(shield.hpMod or 0),
			immunities = { "poisoned", "sleep", "blinded", "frozen" },
			resistances = {
				["poison"] = "immune",
				["shock"] = "weak",
			},
			traits = { "undead" },
			evasion = SKELETON_TROOPER_BASE_EVASION+shield.evasion,
			protection = 5,
			lootDrop = { 0, wname, 0, sname },
		},
		{
			class = "MonsterAttack",
			name = "basicAttack",
			accuracy = weapon.accuracy,
			attackPower = SKELETON_TROOPER_BASE_ATTACK+weapon.attackPower,
			cooldown = (SKELETON_TROOPER_BASE_COOLDOWN+weapon.cooldown)*(shield.cooldownMod or 1),
			sound = "skeleton_trooper_attack",
			onBeginAction = onBeginActions[weapon.wtype],
			onAttackHit = weapon.onAttackHit,
		},
		{
			class = "MonsterAttack",
			name = "turnAttack",
			accuracy = weapon.accuracy,
			attackPower = SKELETON_TROOPER_BASE_ATTACK+weapon.attackPower,
			cooldown = (SKELETON_TROOPER_BASE_COOLDOWN+weapon.cooldown)*(shield.cooldownMod or 1),
			sound = "skeleton_trooper_attack",
			turnToAttackDirection = true,
			onAttackHit = weapon.onAttackHit,
		},
	}
if weapon.extraComponents then
	for _,c in pairs(weapon.extraComponents) do
		table.insert(comps,c)
	end
end
if shield.extraComponents then
	for _,c in pairs(shield.extraComponents) do
		table.insert(comps,c)
	end
end
defineObject{
	name = preferredName or string.format("skeleton_trooper_%s_%s",wname,sname),
	baseObject = "base_skeleton_trooper_custom_"..weapon.wtype,
	components = comps,
}

end


-- global
function g1_createWeaponMonster(montype,wname,sname,preferredName)
	if not (montype and wname and sname) then
		Console.warn("g1_createWeaponMonster called with invalid arguments (expected string,string,string), aborting")
		return false
	end
	local mon = monsters[montype]
	if not mon then
		Console.warn("g1_createWeaponMonster called with invalid monster type "..mon..", aborting")
		return false
	end
	local weapon = mon.weapons[wname]
	if not weapon then
		Console.warn("g1_createWeaponMonster called with invalid weapon "..wname..", aborting")
	end
	local shield = mon.shields[sname]
	if not shield then
		Console.warn("g1_createWeaponMonster called with invalid shield "..sname..", aborting")
	end
	if not (mon and weapon and shield) then
		return false
	end
	mon.create(weapon,shield,wname,sname,preferredName)
end


end
--------------------------------------------------------------------------------
defineParticleSystem{
	name = "torch_dynamic",
	emitters = {
		-- smoke
		{
			emissionRate = 5,
			emissionTime = 0,
			maxParticles = 50,
			boxMin = {-0.03, -0.03, -0.03},
			boxMax = { 0.03, 0.03,  0.03},
			sprayAngle = {0,30},
			velocity = {0.1,0.5},
			objectSpace = false,
			texture = "assets/textures/particles/smoke_01.tga",
			lifetime = {1,1.75},
			color0 = {0.15, 0.15, 0.15},
			opacity = 1,
			fadeIn = 0.5,
			fadeOut = 0.5,
			size = {0.3, 0.6},
			gravity = {0,0,0},
			airResistance = 0.1,
			rotationSpeed = 0.6,
			blendMode = "Translucent",
		},

		-- flames
		{
			emissionRate = 256,
			emissionTime = 0,
			maxParticles = 512,
			boxMin = {-0.03, -0.03, -0.03},
			boxMax = { 0.03, 0.03,  0.03},
			sprayAngle = {0,10},
			velocity = {0.2, 1},
			objectSpace = false,
			texture = "assets/textures/particles/torch_flame.tga",
			frameRate = 35,
			frameSize = 64,
			frameCount = 16,
			lifetime = {0.25, 0.85},
			colorAnimation = true,
			color0 = {2, 2, 2},
			color1 = {1.0, 1.0, 1.0},
			color2 = {1.0, 0.5, 0.25},
			color3 = {1.0, 0.3, 0.1},
			opacity = 1,
			fadeIn = 0.15,
			fadeOut = 0.3,
			size = {0.01, 0.08},
			gravity = {0,0,0},
			airResistance = 1.0,
			rotationSpeed = 1,
			blendMode = "Additive",
			depthBias = 0.1,
		},
		{
			emissionRate = 32,
			emissionTime = 0,
			maxParticles = 512,
			boxMin = {-0.05, -0.05, -0.05},
			boxMax = { 0.05, 0.05,  0.05},
			sprayAngle = {0,10},
			velocity = {0, 0},
			objectSpace = true,
			texture = "assets/textures/particles/torch_flame.tga",
			frameRate = 35,
			frameSize = 64,
			frameCount = 16,
			lifetime = {0.25, 0.85},
			colorAnimation = true,
			color0 = {2, 2, 2},
			color1 = {1.0, 1.0, 1.0},
			color2 = {1.0, 0.5, 0.25},
			color3 = {1.0, 0.3, 0.1},
			opacity = 1,
			fadeIn = 0.15,
			fadeOut = 0.3,
			size = {0.08, 0.15},
			gravity = {0,0,0},
			airResistance = 1.0,
			rotationSpeed = 1,
			blendMode = "Additive",
			depthBias = 0.3,
		},


		-- glow
		{
			spawnBurst = true,
			emissionRate = 1,
			emissionTime = 0,
			maxParticles = 1,
			boxMin = {0,0,0},
			boxMax = {0,0,0},
			sprayAngle = {0,30},
			velocity = {0,0},
			objectSpace = true,
			texture = "assets/textures/particles/glow.tga",
			lifetime = {1000000, 1000000},
			colorAnimation = false,
			color0 = {0.23, 0.11, 0.08},
			opacity = 1,
			fadeIn = 0.1,
			fadeOut = 0.1,
			size = {2, 2},
			gravity = {0,0,0},
			airResistance = 1,
			rotationSpeed = 0,
			blendMode = "Additive",
			depthBias = 0.5,
		}
	}
}

Re: Ask a simple question, get a simple answer

Posted: Wed May 01, 2019 10:21 am
by bongobeat
hello,

is that possible to make a weapon that can gains xp by killing monsters, and then increase its attackdamage (permanently) on a certain amount of xp gained?

Re: Ask a simple question, get a simple answer

Posted: Wed May 01, 2019 11:11 am
by minmay
bongobeat wrote: Wed May 01, 2019 10:21 am hello,

is that possible to make a weapon that can gains xp by killing monsters, and then increase its attackdamage (permanently) on a certain amount of xp gained?
yes

Re: Ask a simple question, get a simple answer

Posted: Wed May 01, 2019 11:18 am
by Pompidom
An easy method would by an onHit counter where the weapon transitions to a +1/+2/+3/+... version after x amount of successful hits, no idea how to do it properly where the weapon gains experience like a real champion though. I'd love to implement this in my mod as well.

Re: Ask a simple question, get a simple answer

Posted: Wed May 01, 2019 12:47 pm
by Zo Kath Ra
bongobeat wrote: Wed May 01, 2019 10:21 am hello,

is that possible to make a weapon that can gains xp by killing monsters, and then increase its attackdamage (permanently) on a certain amount of xp gained?
MeleeAttackComponent.onPostAttack(self, champion, slot)
only called when you attack an empty tile (?)

ItemActionComponent.onAttack(self, champion, slot, chainIndex)
MeleeAttackComponent.onHitMonster(self, monster, tside, damage, champion)

add two counter components to the weapon:
a) for storing the weapon slot during onAttack()
b) for storing the weapon's xp

How much exp should the weapon gain?
- same amount of xp the champion gains (only when monster dies)
- amount that depends on the damage done, and the monster's exp (every time monster takes damage, even if it doesn't die)

Re: Ask a simple question, get a simple answer

Posted: Wed May 01, 2019 4:09 pm
by bongobeat
Thank you for your answers

I omit something: is this possible as well for any kind of item, like an armor, etc... ?

I have in mind the legendary item (particularly armor) that are in might and magic X, and gain xp (well I don't remember if it was by killing directly monsters or anything else), and can be upgraded a few times.

Re: Ask a simple question, get a simple answer

Posted: Wed May 01, 2019 10:17 pm
by Zo Kath Ra
bongobeat wrote: Wed May 01, 2019 4:09 pm Thank you for your answers

I omit something: is this possible as well for any kind of item, like an armor, etc... ?

I have in mind the legendary item (particularly armor) that are in might and magic X, and gain xp (well I don't remember if it was by killing directly monsters or anything else), and can be upgraded a few times.
Depends on what exactly you want to do.

Armor gains xp every time the champion gains xp?
Then I'd attach a timer to the party.
The timer runs once every frame.
It checks if any champions have gained xp.
If so, the timer distributes the xp gain among the weapons / armor the champion is wearing / wielding.

Re: Ask a simple question, get a simple answer

Posted: Thu May 02, 2019 10:34 am
by bongobeat
yes, stats of the weapon or armor have to changes higher when gaining xp from any monster

Re: Ask a simple question, get a simple answer

Posted: Thu May 02, 2019 11:39 pm
by Zo Kath Ra
bongobeat wrote: Thu May 02, 2019 10:34 am yes, stats of the weapon or armor have to changes higher when gaining xp from any monster
Only xp gains from killing monsters?
(but not from finding secrets or treasures)

Re: Ask a simple question, get a simple answer

Posted: Sat May 04, 2019 6:48 am
by vanblam
In an objects definition how would I go about making it a one time animation and give it a delay before it does its activation on its target?

Here is my objects definition, I just have it set as a lever for now. I need it to animate just once and then activate its selected target (after a delay of about 3 seconds).

Code: Select all

defineObject{
	name = "rc_unique_lever",
	baseObject = "base_wall_decoration",
	components = {
		{
			class = "Model",
			model = "mod_assets/stotp_models/red_cave/env/rc_unique_lever.fbx",
			staticShadow = true,
		},
		{
			class = "Animation",
			animations = {
				activate = "mod_assets/stotp_animations/red_cave/rc_unique_lever_activate.fbx",
				deactivate = "mod_assets/stotp_animations/red_cave/rc_unique_lever_rest.fbx",
			},
			onAnimationEvent = function(self, event)
			if event == "activate" then
			self.go.clickable:disable()
				end
			end,
		},
		{
			class = "Clickable",
			offset = vec(0,1.50,0.5),
			size = vec(0.15, 0.9, 0.4),
			maxDistance = 1,
			debugDraw = true,
		},
		{
			class = "Lever",
			sound = "rc_unique_lever",
		},
		{
			class = "Null",
			onInit = function(self)
				local x = self.go.x
				local y = self.go.y
				local facing = self.go.facing
				local level = self.go.level
				
				local fx,fy = getForward(facing)
				local rx,ry = getForward((facing+1)%4)

				do				
					local x = self.go.x + fx
					local y = self.go.y + fy
					if x >= 0 and y >= 0 and x < 32 and y < 32 then
						self.go.map:setAutomapTile(x, y, 4)	-- rocky wall
					end
				end

				-- destroy all pillars ,slopes and supports
				for yy=0,2 do
					for xx=-1,1 do
						local x = x + rx * xx + fx * yy
						local y = y + ry * xx + fy * yy
						if x >= 0 and y >= 0 and x < 32 and y < 32 then
							for e in self.go.map:entitiesAt(x, y) do
								if e.name == "rc_edge_support_01" 
								or e.name == "rc_edge_support_02" 
								or e.name == "rc_edge_support_03"
								or e.name == "rc_edge_support_04"
								or e.name == "rc_edge_support_01b"
								or e.name == "rc_edge_support_02b"
								or e.name == "rc_edge_support_03b"
								or e.name == "rc_edge_support_04b"
								or e.name == "rc_pillar_01a" 
								or e.name == "rc_pillar_01b" 
								or e.name == "rc_pillar_02a"
								or e.name == "rc_wall_slope"								
								then e:destroy()
								end
							end
						end
					end
				end
			end,
		},
	},
	editorIcon = 92,
	tags = { "shadowgate", "red cave", "vanblam" },
}