Certain scripting possibilities?

A place to post your add ons and ideas for them

Moderator: Moderator

Post Reply
Message
Author
Deis
Wayist
Posts: 18
Joined: Sat Nov 08, 2014 11:15 am

Certain scripting possibilities?

#1 Post by Deis »

I am in the beginning steps of planning out a ranger class addon. (I know there already is one, but that one seems very dead which is a shame because it looks funs, and my interpretation of the ranger is a bit different.) I have a bit of experience modding games like Skyrim and Mount and Blade, so I know there are some things that engines do not support. I am not familiar with TOME scripting however and had a few questions about possibilities for talents.

1. I want to create a talent that shoots an enemy and then shows enemies within a radius of the enemy struck.

Something like this,
Does 120,136,150,162,172% weapon damage, view creatures in radius of 2,3,4,5,6 around creature struck for 3 turns.

2. Is it possible to create a stealth talent that increases equilibrium based on how many enemies are in specific radius, reduces equilibrium when there are none, and also checks upon using talents or striking enemies if stealth is broken?

Something like this,
Camoflauge checks your current equilibrium fail chance every turn. Also slightly increases your equilibrium (2, 1.6, 1.2, .8, .5) every turn that there are enemies in view. When you strike or shoot enemies, or use any offensive talent within range of enemies, multiplies your equilibrium fail chance by 3,2.2,1.5,0.8, 0.4 and checks result to see if camoflauge is broken.

3. Where would I find infromation on the various AI packages that can be assigned to summons?


EDIT: :sigh:, of course about a minute after posting I found some tutorials for LUA on the wiki. Will be reading those now xD.

stinkstink
Spiderkin
Posts: 543
Joined: Sat Feb 11, 2012 1:12 am

Re: Certain scripting possibilities?

#2 Post by stinkstink »

Deis wrote:1. I want to create a talent that shoots an enemy and then shows enemies within a radius of the enemy struck.
Should be doable by creating a temporary effect on the user to store a reference to the target, and superloading mod\class\Player.lua playerFOV() to check if the player has the effect and display creatures around the target. You can look at the function to see how things like Track and Arcane Eye are handled to work out how it's done.
2. Is it possible to create a stealth talent that increases equilibrium based on how many enemies are in specific radius, reduces equilibrium when there are none, and also checks upon using talents or striking enemies if stealth is broken?
Also doable. Have a callback in your talent (most likely callbackOnAct if you want it test every time the user acts, or callbackOnActBase if you only want to check it every global turn). For the bits about breaking stealth, poke around in mod\class\Actor.lua breakStealth() for general stealth breaking and mod\class\inferface\Combat.lua attackTarget() for melee-specific stealth failure.

HousePet
Perspiring Physicist
Posts: 6215
Joined: Sun Sep 09, 2012 7:43 am

Re: Certain scripting possibilities?

#3 Post by HousePet »

Deis wrote: I have a bit of experience modding games like Skyrim
My condolences.
Thankfully ToME4 is much easier to mod, and you have direct access to the source code.

Basically, anything is possible.
My feedback meter decays into coding. Give me feedback and I make mods.

Deis
Wayist
Posts: 18
Joined: Sat Nov 08, 2014 11:15 am

Re: Certain scripting possibilities?

#4 Post by Deis »

Thanks for the responses and insight. I have been reading through some of the documentation and browsing through the various talents and had more questions.

1. I am attempting to make a passive that combines bow and sling mastery. However, looking through the code at bow.lua and sling.lua, I don't see where it checks specifically for a bow or sling to be equipped.

2. My addon loads and I can create a character with my class. I have only created two talents, however I'm not seeing any talents present in-game on the character.

3. My addon shows up when in folder form, however when I zip it to a .teaa file, it does not load or show up in the addon list. I set compression to "Store". Not sure what I'm missing there. Forum doesn't seem to allow upload of .teaa files, so I have uploaded it as a 7z in case anyone wants to take a look.
Attachments
tome-ranger.7z
(18.44 KiB) Downloaded 406 times

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

Re: Certain scripting possibilities?

#5 Post by lukep »

1: look at _M:addCombatTraining in Combat.lua for how to do this. IIRC the donator class (forget the name, the dwarf with shields) uses this so you can steal it there.

2: not sure what's happening here.

3: Your file structure goes [zip file] -> [tome-ranger folder] -> [init, data, overload, etc.], and it needs to go [zip file] -> [init, data, overload, etc.].
Some of my tools for helping make talents:
Melee Talent Creator
Annotated Talent Code (incomplete)

HousePet
Perspiring Physicist
Posts: 6215
Joined: Sun Sep 09, 2012 7:43 am

Re: Certain scripting possibilities?

#6 Post by HousePet »

2) You have "gifts/woodland-training" etcetera in you classes categories list but they should be "wild-gift/woodland-training".
My feedback meter decays into coding. Give me feedback and I make mods.

Deis
Wayist
Posts: 18
Joined: Sat Nov 08, 2014 11:15 am

Re: Certain scripting possibilities?

#7 Post by Deis »

Thanks again for the help! I've managed to get talents to show up, got the bow/sling mastery combined and working, and even the dex and wil substitutions. Now to figure out how damage is calculated for skills damage values. I see in the talent descriptions that the min and max values for the skills damage values are set, but I don't see/understand how the per level progression is calculated. I assume that is something I'll need to poke around in the combat.lua for.

Deis
Wayist
Posts: 18
Joined: Sat Nov 08, 2014 11:15 am

Another question...

#8 Post by Deis »

So I am trying to create a sustain identical to Lacerating Strikes. I have even copied over the code from the talent. However, nothing at all happens when I have the sustain activated and strike an opponent. Tried it on many creatures.

The talent is set up to be one of many aspects provided by one talent investment that can be sustained (one at a time).

I have the talent set as such,

Code: Select all

newTalent{
	name = "Natural Adaptation - Ravaging Strikes", short_name = "NA_RAVAGING_STRIKES",
	type = {"wild-gift/other", 1},
	mode = "sustained",
	require = techs_req2,
	points = 5,
	cooldown = 12,
	sustain_equilibrium = 10,
	no_energy = true,
	dont_provide_pool = true,
	tactical = { BUFF = 2 },
	range = 10,

	cutChance = function(self,t) return self:combatTalentLimit(t, 100, 20, 60) end, --Limit < 100%
	do_cut = function(self, t, target, dam)
		if target:canBe("cut") and rng.percent(t.cutChance(self, t)) then
			dam = dam * self:combatTalentWeaponDamage(t, 0.15, 0.35)
			target:setEffect(target.EFF_CUT, 10, {src=self, power=(dam / 10)})
		end
	end,
	cancelAdaptations(self)
	activate = function(self, t)
		return {}
	end,
	deactivate = function(self, t)
		return true
	end,
	info = function(self, t)
		return ([[Rend your foe with every attack you do. All attacks now have a %d%% chance of inflicting an additional %d%% of your attack's damage in Bleeding damage, divided over ten turns.]]):
		format(t.cutChance(self, t), 100 * self:combatTalentWeaponDamage(t, 0.15, 0.35))
	end,
}
And I added this entry in Combat.lua,

Code: Select all

	-- Ravaging Strikes
	if hitted and not target.dead and self:isTalentActive(self.T_NA_RAVAGING_STRIKES) then
		local t = self:getTalentFromId(self.T_NA_RAVAGING_STRIKES)
		t.do_cut(self, t, target, dam)
	end
When I try with

Code: Select all

function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
above the Ravaging Strikes entry I get this error whenever being struck or striking,

Code: Select all

[ATTACK] attacking with innate combat
stack traceback:
	[C]: in function 'error'
	/engine/interface/ActorTalents.lua:248: in function </engine/interface/ActorTalents.lua:232>
Lua Error: /engine/interface/ActorTalents.lua:271: /engine/interface/ActorTalents.lua:248: /engine/interface/ActorTalents.lua:148: /mod/class/interface/Combat.lua:207: bad argument #2 to 'max' (number expected, got nil)
stack traceback:
	[C]: in function 'max'
	/mod/class/interface/Combat.lua:207: in function 'attackTarget'
	/data/talents/misc/misc.lua:75: in function </data/talents/misc/misc.lua:54>
	[C]: in function 'xpcall'
	/engine/interface/ActorTalents.lua:145: in function </engine/interface/ActorTalents.lua:138>
	At [C]:-1 
	At [C]:-1 error
	At /engine/interface/ActorTalents.lua:271 bumpInto
	At /mod/class/Actor.lua:3342 attack
	At /engine/interface/ActorLife.lua:41 check
	At [string "return function(self, x, y, what, ...) local ..."]:1 checkAllEntities
	At /engine/Actor.lua:198 move
	At /mod/class/Actor.lua:1260 move
	At /engine/ai//simple.lua:139 runAI
	At /engine/ai//simple.lua:195 runAI
	At /engine/ai//talented.lua:64 doAI
	At /mod/class/NPC.lua:72 act
	At /engine/GameEnergyBased.lua:126 tickLevel
	At /engine/GameEnergyBased.lua:62 tick
	At /engine/GameTurnBased.lua:46 tick
	At /mod/class/Game.lua:1255 

I'm not sure what I'm missing here and would appreciate any help :?

stinkstink
Spiderkin
Posts: 543
Joined: Sat Feb 11, 2012 1:12 am

Re: Certain scripting possibilities?

#9 Post by stinkstink »

My guess is you're superloading attackTargetWith() and aren't calling the original function in your new code. However, there's a cleaner way to do what you're attempting, using a callback. You can include this bit of code in your talent definition and get the same effect without having to superload anything

Code: Select all

callbackOnMeleeAttack = function(self, t, target, hitted, crit, weapon, damtype, mult, dam)
	if hitted and not target.dead and target:canBe("cut") and rng.percent(t.cutChance(self, t)) then
		local pow = dam * self:combatTalentWeaponDamage(t, 0.15, 0.35)
		target:setEffect("EFF_CUT", 10, {src=self, power=(pow / 10)})
	end
end,
There's a list of available callbacks here, they're great for keeping as much related code as possible in the same place for ease of maintenance. Unfortunately a lot of stuff in the base game was written before they existed, so for beginning modders it can be tough to realize when things might be handled using more modern methods.

Deis
Wayist
Posts: 18
Joined: Sat Nov 08, 2014 11:15 am

Re: Certain scripting possibilities?

#10 Post by Deis »

Thanks! That worked perfectly!

I'm trying to incorporate a callback on another talent (a combination of lacerating strike's chance on hit and cripple's speed debuff.) I think I have the code portion correct, however I keep receiving an error upon trying to start a new game or load a save.

The error is as follows,

Code: Select all

Lua Error: /engine/utils.lua:1782: /data-ranger/talents/gifts/feral-combat.lua:358: 'end' expected (to close 'function' at line 354) near ')'
	At [C]:-1 
	At [C]:-1 error
	At /engine/utils.lua:1782 loadfilemods
	At /engine/interface/ActorTalents.lua:31 loadDefinition
	At /engine/interface/ActorTalents.lua:39 load
	At /data-ranger/talents/talents.lua:123 f
	At /engine/interface/ActorTalents.lua:42 loadDefinition
	At /hooks/ranger/load.lua:10 
	At [string "return function(l, self, data) local ok=false..."]:1 
	At /mod/load.lua:271 
	At [C]:-1 require
	At /engine/Module.lua:160 load
	At /engine/Module.lua:955 instanciate
	At /engine/utils.lua:2197 showMainMenu
	At /engine/init.lua:162 
	At [C]:-1 dofile
	At /loader/init.lua:204 

Code: Select all

newTalent{
	name = "Natural Adaptation - Webbed Mandibles", short_name = "NA_WEBBED_MANDIBLES",
	type = {"wild-gift/other", 1},
	mode = "sustained",
	require = techs_req2,
	points = 5,
	cooldown = 12,
	sustain_equilibrium = 10,
	no_energy = true,
	dont_provide_pool = true,
	tactical = { BUFF = 2 },
	range = 10,

	getSpeedPenalty = function(self, t) return self:combatLimit(self:combatTalentStatDamage(t, "cun", 5, 50), 100, 20, 0, 55.7, 35.7) end, -- Limit < 100%
	slowChance = function(self,t) return self:combatTalentLimit(t, 100, 20, 60) end, --Limit < 100%
	getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 4, 8)) end,
	speed = "weapon",


	callbackOnMeleeAttack = function(self, t, target, hitted, crit, weapon, damtype, mult, dam)
   if hitted and not target.dead and target:canBe("slow") and rng.percent(t.slowChance(self, t)) then
	local speed = t.getSpeedPenalty(self, t) / 100
			target:setEffect(target.EFF_SLOW, t.getDuration(self, t), {speed=speed, apply_power=self:combatAttack()})
		end
	end,

	activate = function(self, t)
	cancelAdaptations(self)
		return {}
	end,
	deactivate = function(self, t)
		return true
	end,

	info = function(self, t)
		local duration = t.getDuration(self, t)
		local speedpen = t.getSpeedPenalty(self, t)
		return ([[Attempt to cripple your foe with every attack you do. All attacks now have a %d%% chance of slowing your opponents for %d turns, causing them to lose %d%% melee, spellcasting and mind speed.]]):
		format(t.slowChance(self, t), duration, speedpen))
	end,
}
Line 354 is the "info = function(self,t)"
Line 358 starts with "format(t.slowChance...."

I've checked a few times, and I don't think I'm missing any ends...

stinkstink
Spiderkin
Posts: 543
Joined: Sat Feb 11, 2012 1:12 am

Re: Certain scripting possibilities?

#11 Post by stinkstink »

You have an extra closing parenthesis in your string format line. Also, a few minor things about that talent:
-There's no resistance stat for slowing, so a canBe("slow") check isn't necessary
-The effect the description mentions (increased energy cost for abilities) is EFF_CRIPPLE; EFF_SLOW reduces global speed, making the target regain energy slower.
-If you're making a group of sustains where only one can be active at a time, you can add a sustain_slots = 'your slot', field to your talent definitions and the game will handle disabling any sustains with that slot whenever you activate one automatically.

Post Reply