AI Switcher

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
Xanathar
Posts: 629
Joined: Sun Apr 15, 2012 10:19 am
Location: Torino, Italy
Contact:

AI Switcher

Post by Xanathar »

Hi all
here is the first release of the AI switcher : http://grimrock.nexusmods.com/mods/254/

Demo in this post from Leki: viewtopic.php?f=14&t=5230&start=100#p58291

Sample dungeon contained in zip, with web and poison shooting spider - really almost the same AI code of Leki ancient ghoul, put on a spider to give you an example :)

Sorry but now I'm in a hurry, later today I'll update this post with more details :oops: I wanted to release it, however, as I'm not so sure I'm able to do it later ;)


Readme.txt dumped here in a hurry:

SETUP
=====

0) unzip or copy the ai folder in your mod directory.

IF YOU'RE USING LOG FRAMEWORK OR GRIMWIDGETS:
--------------------------------------------
1) You must be on the latest version of Log Framework
2) In init.lua, immediately *after* the import of grimwidgets/framework line add:

import "mod_assets/ai/aiswitcher.lua"


IF YOU'RE NOT USING LOG FRAMEWORK OR GRIMWIDGETS:
-------------------------------------------------
1) At the beginning of init.lua, immediately after either the 'import "assets/scripts/standard_assets.lua"' line add:

import "mod_assets/ai/aiswitcher.lua"

2) After this, add a scripting entity to your dungeon with this code:

spawn("aiswitcher_engine", 1, 1, 1, 1):open()



Either way... You're Done :)



DEFINING MONSTERS
=================
To define a monster for AI switching, use defineAiSwitchMonster instead of defineObject.
You need to change the monster definition this way:

1) All hooks must be strings containing code, instead of functions. In 99% of the cases you just need to add [[ before the code and ]] after (but before the comma).
2) You need a new "brains" subtable which will contain the alternate definitions. You can override every property in brains (as a handy helper, if you override the animations, these will be merged with the original definition).
3) Each element of the "brains" subtable must contain a "condition". Condion can be a function in string form or a table of <condition-name>, <minvalue>, <maxvalue>. condition-name can as now be "distance" to check the distance of the monster to the party, "directdistance", which checks the distance but only if the monster is in the same row or column of the party, and "health" which checks the monster health. If a function in string form is specified, the function receives the monster as an argument and should return true when the condition is satisfied.
4) Elements of "brains" are always checked in sequence (so the first satisfied condition wins). If no condition is satisfied, the default is the brain of the monster (the one outside the brains table).
5) Do NOT add items to monsters with AI switch using the standard editor, as those are lost after an AI change.

EXTRA-HOOKS
===========
A couple of extra hooks are provided for the modder convenience at the monster declaration level:
- onAiSwitch(self, oldindex, newindex): Happens when the AI is about to be switched. oldindex and newindex are indices in the brains array, with 0 being the one of the outer (default) brain.
- onPartyProjectileHit: same as party.onProjectileHit. This is included here, as a lot of monster customizations involve
shooting a projectile as a form of attack


Example:

Code: Select all

defineAiSwitchMonster{
	name = "spider",
	class = "Monster",
	model = "assets/models/monsters/spider.fbx",
	meshName = "spider_mesh",
	animations = {
		idle = "assets/animations/monsters/spider/spider_idle.fbx",
		moveForward = "assets/animations/monsters/spider/spider_walk.fbx",
		turnLeft = "assets/animations/monsters/spider/spider_turn_left.fbx",
		turnRight = "assets/animations/monsters/spider/spider_turn_right.fbx",
		attack = "assets/animations/monsters/spider/spider_bite.fbx",
		getHitFrontLeft = "assets/animations/monsters/spider/spider_get_hit_front_left.fbx",
		getHitFrontRight = "assets/animations/monsters/spider/spider_get_hit_front_right.fbx",
		getHitBack = "assets/animations/monsters/spider/spider_get_hit_back.fbx",
		getHitLeft = "assets/animations/monsters/spider/spider_get_hit_left.fbx",
		getHitRight = "assets/animations/monsters/spider/spider_get_hit_right.fbx",
		fall = "assets/animations/monsters/spider/spider_get_hit_front_left.fbx",
	},
	moveSound = "spider_walk",
	attackSound = "spider_attack",
	hitSound = "spider_hit",
	dieSound = "spider_die",
	hitEffect = "hit_goo",
	capsuleHeight = 0.2,
	capsuleRadius = 0.8,
	health = 160,
	sight = 6,
	attackPower = 23,
	accuracy = 10,
	movementCoolDown = 1,
	noRecoilInterval = { 0.1, 0.4 },
	exp = 175,
	healthIncrement = 30,
	attackPowerIncrement = 5,
	brain = "Melee",
	onDealDamage = [[function(self, champion, damage)
		if math.random() <= 0.3 then
			champion:setConditionCumulative("poison", 30)
		end
	end]],
	onDamage = [[function(self, amount, typed)
		if (typed == "poison") then
			return false
		end
	end]],	
	
	brains = 
	{
		{	-- will change to this brain when the monster is in line with the party, with distance equal to 2
			condition = { "directdistance", 2, 2 },
			animations = { attack = "mod_assets/animations/spider_shoot.fbx" },
			rangedAttack = "poison_bolt",
			brain = "Ranged",
			
			-- override ranged attack for this monster! Note the hook is a string
			onRangedAttack = [[function(self)
				local x, z = getForward(self.facing)
				shootProjectile("spider_web", self.level, self.x, self.y, self.facing, 9.0, 7.0, 0.1, -x, 0.7, z, 10, self, true);
				return false;
			end]],
			onPartyProjectileHit = [[function(champ, proj, damage, damtype)
				if (proj.name == "spider_web") then
					champ:setConditionCumulative("paralyzed", 60);
				end
			end]],					
		},
		{	-- will change to this brain when the monster is distance 2 to infinite from the party
			condition = { "distance", 2, 99999 },
			animations = { attack = "mod_assets/animations/spider_shoot.fbx" },
			rangedAttack = "poison_bolt",
			brain = "Ranged",
		},	
	},	
}

defineAnimationEvent{
	animation = "mod_assets/animations/spider_shoot.fbx",
	event = "ranged_attack",
	frame = 12,
}

cloneObject {
	name = "spider_web",
	baseObject = "rock",
	-- change the model here!
}
Waking Violet (Steam, PS4, PSVita, Switch) : http://www.wakingviolet.com

The Sunset Gate [MOD]: viewtopic.php?f=14&t=5563

My preciousss: http://www.moonsharp.org
User avatar
Leki
Posts: 550
Joined: Wed Sep 12, 2012 3:49 pm

Re: AI Switcher

Post by Leki »

File on Nexus does not published m8.
I'm the Gate I'm the Key.
Dawn of Lore
User avatar
odinsballs
Posts: 288
Joined: Thu Dec 20, 2012 4:25 pm
Location: south of heaven

Re: AI Switcher

Post by odinsballs »

Leki wrote:File on Nexus does not published m8.
nexus is set up in a way that you can upload the files and make all read me's and then hit publish file (so i wager xanathar forgot to hit the publish button wich then makes file visible in download list)
User avatar
Xanathar
Posts: 629
Joined: Sun Apr 15, 2012 10:19 am
Location: Torino, Italy
Contact:

Re: AI Switcher

Post by Xanathar »

Ok I'm an idiot.. me and Nexus are in a complicated relationship :lol:
Now it should work.

Just another point I kinda forgot in the worst announcement ever: if you are a framework user, the sentence "1) You must be on the latest version of Log Framework" might actually mean "the next version jkos is going to release when he can" :D (sorry jkos, I totally forgot that wasn't a public version yet).
Waking Violet (Steam, PS4, PSVita, Switch) : http://www.wakingviolet.com

The Sunset Gate [MOD]: viewtopic.php?f=14&t=5563

My preciousss: http://www.moonsharp.org
User avatar
Xanathar
Posts: 629
Joined: Sun Apr 15, 2012 10:19 am
Location: Torino, Italy
Contact:

Re: AI Switcher

Post by Xanathar »

Hi all,
I have a number of requests for little demos of this, if anyone has spare time :)
  • A "web" projectile and, maybe, a web particle screen effect (like the fireball one but suggesting a web thrown to the party)
  • Two retextured spiders, one "natural" the other more with vivid colors (this second for a phase spider concept)
  • Any one humanoid monster (skeleton, ogre, warden, what you want) retextured and positioned as a statue (texture and 1 frame fixed animation in a statue like position)
I think they would make nice concepts (not original at all I admit, these were discussed a lot in these forums :) ), but I have no skills on those areas (or, well, very little skills :) ).
Waking Violet (Steam, PS4, PSVita, Switch) : http://www.wakingviolet.com

The Sunset Gate [MOD]: viewtopic.php?f=14&t=5563

My preciousss: http://www.moonsharp.org
User avatar
Damonya
Posts: 134
Joined: Thu Feb 28, 2013 1:16 pm
Location: France
Contact:

Re: AI Switcher

Post by Damonya »

I like your job
SpoilerShow
First spider (red)
Model = http://www.meteobell.com/Divers/JDR/Gri ... _low.model
Texture = http://www.meteobell.com/Divers/JDR/Gri ... l2_dif.dds

Second spider (green)
Model = http://www.meteobell.com/Divers/JDR/Gri ... dium.model
Texture = http://www.meteobell.com/Divers/JDR/Gri ... l3_dif.dds

Code: Select all

defineMaterial{
	name = "spider_low",
	diffuseMap = "mod_assets/textures/spider_level2_dif.tga",
	specularMap = "assets/textures/monsters/spider_spec.tga",
	normalMap = "assets/textures/monsters/spider_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}


defineMaterial{
	name = "spider_medium",
	diffuseMap = "mod_assets/textures/spider_level3_dif.tga",
	specularMap = "assets/textures/monsters/spider_spec.tga",
	normalMap = "assets/textures/monsters/spider_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}

--Spider LVL 2
cloneObject{
	name = "spider_low",
	baseObject = "spider",
	model = "mod_assets/models/spider_low.fbx",
	exp = 200,
	health = 190,
	attackPower = 28,
	
}
--Spider LVL 3
cloneObject{
	name = "spider_medium",
	baseObject = "spider",
	model = "mod_assets/models/spider_medium.fbx",
	exp = 225,
	health = 220,
	attackPower = 33,
	
}

Spider_web_rock
Model = http://www.meteobell.com/Divers/JDR/Gri ... _web.model

Code: Select all

defineMaterial{
	name = "spider_web_rock",
	diffuseMap = "assets/textures/props/spider_webs_dif.tga",
	specularMap = "assets/textures/items/rock_spec.tga",
	doubleSided = true,
	lighting = false,
	alphaTest = false,
	blendMode = "Translucent",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineObject{
		name = "spider_web",
		class = "Item",
		uiName = "Spider Web",
		model = "mod_assets/models/spider_web.fbx",							
		skill = "throwing_weapons",
		ammoType = "rock",
		throwingWeapon = true,
		gfxIndex = 45,
		attackPower = 5,
		coolDownTime = 4,
		attackMethod = "throwAttack",
		attackSound = "swipe",
		impactSound = "impact_blunt",
		stackable = true,
		projectileRotationSpeed = 10,
		projectileRotationZ = -30,
		weight = 1.0,

}
Change like you want the spider_web feature. Here it's like a rock with only the web texture. It's not perfect. I did it very quickly. We can do better
Orwak - MOD - Beta version 1.0
User avatar
Xanathar
Posts: 629
Joined: Sun Apr 15, 2012 10:19 am
Location: Torino, Italy
Contact:

Re: AI Switcher

Post by Xanathar »

Wow that was QUICK!

Thanks!
Waking Violet (Steam, PS4, PSVita, Switch) : http://www.wakingviolet.com

The Sunset Gate [MOD]: viewtopic.php?f=14&t=5563

My preciousss: http://www.moonsharp.org
User avatar
Damonya
Posts: 134
Joined: Thu Feb 28, 2013 1:16 pm
Location: France
Contact:

Re: AI Switcher

Post by Damonya »

Yes very quickly. Maybe, someone will do better.

For your web particle screen effect. Try this:
SpoilerShow

Code: Select all

  defineParticleSystem{
name = "web",
emitters = {
{
emissionRate = 10,
emissionTime = 5,
maxParticles = 100,
boxMin = {-1, 0,-1},
boxMax = { 1, 0, 1},
sprayAngle = {0,0},
velocity = {0,0},
texture = "assets/textures/props/spider_webs_dif.tga",
lifetime = {10,20},
color0 = {1, 1, 1},
opacity = 0.9,
fadeIn = 0.5,
fadeOut = 7,
size = {0,5, 1},
gravity = {0,0,0},
airResistance = 0.1,
rotationSpeed = 0,
blendMode = "Translucent",
objectSpace = false,
}
}
} 

defineObject{
name = "spider_web_emitter",
class = "LightSource",
lightPosition = vec(1.2, 0.2, 0),
lightRange = 6,
lightColor = vec(1, 1, 1),
brightness = 0,
castShadow = true,
particleSystem = "web",
placement = "floor",
editorIcon = 88,
}
For humanoid monster, I've never done it, so someone else.
Orwak - MOD - Beta version 1.0
Grimfan
Posts: 369
Joined: Wed Jan 02, 2013 7:48 am

Re: AI Switcher

Post by Grimfan »

This is simply brilliant Xanathar (and Leki). While I won't be implementing this in my upcoming mod (playtesting it now) I certainly will be using this in the future (unless AH implements something like this in LOG2 before I can conclude my next one that is).

Still, crazy good work! :)
User avatar
Xanathar
Posts: 629
Joined: Sun Apr 15, 2012 10:19 am
Location: Torino, Italy
Contact:

Re: AI Switcher

Post by Xanathar »

Thanks Grimfan! :)

And using Damonya assets, I've uploaded to the Nexus page a new version of the sample dungeon with a more badass version of the shooting spider :)
Waking Violet (Steam, PS4, PSVita, Switch) : http://www.wakingviolet.com

The Sunset Gate [MOD]: viewtopic.php?f=14&t=5563

My preciousss: http://www.moonsharp.org
Post Reply