Monster Detector

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Monster Detector

Post by minmay »

It would be better to draw arrows on the border of the screen. You can inspect the party's transformation matrix from party:getWorldRotation() to make the arrows point the correct direction relative to the camera.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
GoldenShadowGS
Posts: 168
Joined: Thu Oct 30, 2014 1:56 am

Re: Monster Detector

Post by GoldenShadowGS »

Code: Select all

defineSpell{
	name = "detect_monster",
	uiName = "Monster Detector",
	skill = "earth_magic",
	requirements = {"concentration", 1},
	gesture = 8,
	manaCost = 5,
	icon = 14,
	spellIcon = 13,
	description = "Reveals how many monster are nearby. Every point is Earth Magic increases your maximum detection range.",
	onCast = function(champion, x, y, direction, elevation, skillLevel)
		local monsterNames = {air_elemental = "an Air Elemental", crab = "a Crab", crowern = "a Crowern", dark_acolyte = "a Dark Acolyte", 
		eyctopus = "an Eyectopus", fire_elemental = "a Fire Elemental", fjeld_warg = "a Fjeld Warg", fjeld_warg1 = "a Fjeld Warg",
		fjeld_warg2 = "a Fjeld Warg", forest_ogre = "a Forest Ogre", giant_snake = "a giant Snake", goromorg = "a Goromorg", 
		herder = "a Herder", herder_big = "a big Herder", herder_small = "a small Herder", ice_guardian = "an Ice Guardian", 
		lindworm = "a Lindworm", lizard_ice = "an Ice Lizard", lizard_dark = "a Dark Lizard", lizard_fire= "a Fire Lizard", 
		lizard_green = "a Green Lizard", magma_golem = "a Magma Golem", medusa = "a Medusa", mimic = "a Mimic", 
		mosquito_swarm = "a Swarm of Mosquitos", mummy = "a Mummy", mummy1 = "a Mummy", mummy2 = "a Mummy", mummy3 = "a Mummy", 
		ogre = "a Cave Ogre", rat_swarm = "a Swarm of Rats", ratling = "a Ratling", ratling1 = "a Ratling", ratling2 = "a Ratling", 
		ratling_boss = "a Ratling Clan Chief", sand_warg = "a Sand Warg", scavenger = "a Scavenger", shrakk_torr = "a Shrakk Torr",
		skeleton_archer = "a Skeleton Archer", skeleton_commander = "a Skeleton Commander", skeleton_trooper = "a Skeleton Trooper", 
		skeleton_trooper1 = "a Skeleton Trooper", skeleton_trooper2 = "a Skeleton Trooper", skeleton_warrior = "a Skeleton Warrior",
		slime_green = "a Green Slime", slime_red = "a Red Slime", slime_blue = "a Blue Slime", slime_fire = "a Fire Slime", 
		slime_ice = "an Ice Slime", slime_dark = "a Dark Slime", slime_plasm = "a Plasma Slime",  slime_poison = "a Poison Slime",  
		slime_golden = "a Golden Slime", snail = "a Snail", snail_blue_green = "a Hardshell Snail", snail_green_brown = "a Deep Forest Snail",
		spider = "a Spider", spore_mushroom = "a Mushroom Sporer", summon_stone = "a Summon Stone", swamp_toad = "a Swamp Toad",
		tentacles = "a Pit Tentacle", trickster = "a Trickster", turtle = "a Turtle", turtle_diving = "a Turtle", twigroot = "a Twigroot",
		uggardian = "a Uggardian", undead = "a Zombie", viper_root = "a Viper Root", warden = "a Warden", wizard = "a Wizard", wyvern = "a Wyvern",
		xeloroid = "a Xeloroid", zarchton_diving = "a Zarchton", zarchton = "a Zarchton"}
		local monsterNamesplural = {air_elemental = "Air Elementals", crab = "Crabs", crowern = "Crowerns", dark_acolyte = "Dark Acolytes", 
		eyctopus = "Eyectopuses", fire_elemental = "Fire Elementals", fjeld_warg = "Fjeld Wargs", fjeld_warg1 = "Fjeld Wargs",
		fjeld_warg2 = "Fjeld Wargs", forest_ogre = "Forest Ogres", giant_snake = "giant Snakes", goromorg = "Goromorgs", 
		herder = "Herders", herder_big = "big Herders", herder_small = "small Herders", ice_guardian = "Ice Guardians", 
		lindworm = "Lindworms", lizard_ice = "Ice Lizards", lizard_dark = "Dark Lizards", lizard_fire= "Fire Lizards", 
		lizard_green = "Green Lizards", magma_golem = "Magma Golems", medusa = "Medusas", mimic = "Mimics", 
		mosquito_swarm = "Swarm of Mosquitos", mummy = "Mummies", mummy1 = "Mummies", mummy2 = "Mummies", mummy3 = "Mummies", 
		ogre = "Cave Ogres", rat_swarm = "Swarm of Rats", ratling = "Ratlings", ratling1 = "Ratlings", ratling2 = "Ratlings", 
		ratling_boss = "Ratling Clan Chiefs", sand_warg = "Sand Wargs", scavenger = "Scavengers", shrakk_torr = "Shrakk Torrs",
		skeleton_archer = "Skeleton Archers", skeleton_commander = "Skeleton Commanders", skeleton_trooper = "Skeleton Troopers", 
		skeleton_trooper1 = "Skeleton Troopers", skeleton_trooper2 = "Skeleton Troopers", skeleton_warrior = "Skeleton Warriors",
		slime_green = "Green Slimes", slime_red = "Red Slimes", slime_blue = "Blue Slimes", slime_fire = "Fire Slimes", 
		slime_ice = "Ice Slimes", slime_dark = "Dark Slimes", slime_plasm = "Plasma Slimes",  slime_poison = "Poison Slimes",  
		slime_golden = "Golden Slimes", snail = "Snails", snail_blue_green = "Hardshell Snails", snail_green_brown = "Deep Forest Snails",
		spider = "Spiders", spore_mushroom = "Mushroom Sporers", summon_stone = "Summon Stones", swamp_toad = "Swamp Toads",
		tentacles = "Pit Tentacles", trickster = "Tricksters", turtle = "Turtles", turtle_diving = "Turtles", twigroot = "Twigroots",
		uggardian = "Uggardians", undead = "Zombies", viper_root = "Viper Roots", warden = "Wardens", wizard = "Wizards", wyvern = "Wyverns",
		xeloroid = "Xeloroids", zarchton_diving = "Zarchtons", zarchton = "Zarchtons"}
		local monstertotal = 0
		--max range
		local count = 4 + skillLevel
		local monsterarray = {}
		local monsterdistance = {}
		local maxdist = 0
		--Fill the Monster Array
		for fx = x - count, x + count do
			for fy = y - count, y + count do
				for i in party.map:entitiesAt(fx,fy) do
					if i:getComponent("monster") then
						monstertotal = monstertotal + 1
						local xdist = (x - i.x) * 3
						local ydist = (y - i.y) * 3
						local zdist = (elevation - i.elevation) * 3
						local dist = math.floor(0.5 + math.sqrt(xdist^2 + ydist^2 + zdist^2))
						if i.monster:getGroupSize() > 1 then
							if monstertotal > 1 and i.x == monsterarray[monstertotal - 1].x and i.y == monsterarray[monstertotal - 1].y and i.elevation == monsterarray[monstertotal - 1].elevation then 
								monstertotal = monstertotal - 1
							else
								monsterdistance[i] = dist
							end
						else
							monsterdistance[i] = dist
						end
						if dist > maxdist then
							maxdist = dist
						end
						monsterarray[monstertotal] = i
					end
				end
			end
		end
		local skillcount = 0
		playSound("generic_spell")
		for m = 0, maxdist do
			for k,v in pairs(monsterdistance) do
				if m == v and skillcount < skillLevel then
					local deltax = x - k.x
					local deltay = y - k.y
					local mdir = 0
					local height = ""
					if math.abs(deltax) <= math.abs(deltay) then
						if deltay == 0 then
							mdir = -1
						elseif deltay > 0 then
							mdir = (4 + direction) % 4
						else
							mdir = (6 + direction) % 4
						end
					else
						if deltax == 0 then
							mdir = -1
						elseif deltax > 0 then
							mdir = (5 + direction) % 4
						else
							mdir = (7 + direction) % 4
						end
					end
					if elevation == k.elevation then
						height = ""
					elseif elevation < k.elevation then
						height = ", above you"
					else
						height = ", below you"
					end
					local fdir = ""
					if mdir == -1 then
						fdir = height
					elseif mdir == 0 then
						fdir = ""..height..", in front of the party"
					elseif mdir == 1 then
						fdir = ""..height..", to the left of the party"
					elseif mdir == 2 then
						fdir = ""..height..", behind the party"
					elseif mdir == 3 then
						fdir = ""..height..", to the right of the party"
					end
					if skillLevel < 3 then
						fdir = ""
					end
					skillcount = skillcount + 1
					if k.monster:getGroupSize() <= 1 then
						hudPrint("There is "..monsterNames[k.name].." "..m.." meters away"..fdir..".")
					else
						hudPrint("There is a group of "..k.monster:getGroupSize().." "..monsterNamesplural[k.name].." "..m.." meters away"..fdir..".")
					end
				end
			end
		end
	end,
}
Shows direction now at skill 3
"There is a Crowern 3 meters away, above you, in front of the party."

!!edited to clean up a bit of code.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Monster Detector

Post by akroma222 »

Yup, although I like the added "need compass to assist thing", infront/behind/left/right of party is a better way to do it
Screen effects wise I was just going to shine a warning light for a few seconds

Code: Select all

spawn("detect_monster_light", k.level, k.x, k.y, k.facing, k.elevation)
SpoilerShow

Code: Select all

defineObject{
	name = "detect_monster_light",
	baseObject = "base_spell",
	components = {
		{
			class = "Light",
			color = vec(2.0, 0.4, 0.4),
			brightness = 50,
			range = 8,
			offset = vec(0, 0.2, 0),
			fadeOut = 1.75,
			disableSelf = true,
		},
	},
}
I am not sure how to GUI the arrows onto the screen *yet*
minmay is there a good link with an example u know of?
bongobeat
Posts: 1076
Joined: Thu May 16, 2013 5:58 pm
Location: France

Re: Monster Detector

Post by bongobeat »

GoldenShadowGS wrote:Here is a modified secret detector spell that lists the nearby monsters and how far away they are in the console.

Paste into spells.lua

Code: Select all

defineSpell{
	name = "detect_monster",
	uiName = "Monster Detector",
	skill = "earth_magic",
	requirements = {"concentration", 1},
	gesture = 8,
	manaCost = 5,
	icon = 14,
	spellIcon = 13,
	description = "Reveals how many monster are nearby. Every point is Earth Magic increases your maximum detection range.",
	onCast = function(champion, x, y, direction, elevation, skillLevel)
		local monstertotal = 0
		--max range
		local count = 4 + skillLevel
		local monsterarray = {}
		local monsterdistance = {}
		--Fill the Monster Array
		for fx = x - count, x + count do
			for fy = y - count, y + count do
				for i in party.map:entitiesAt(fx,fy) do
					if i:getComponent("monster") then
						monstertotal = monstertotal + 1
						local xdist = (x - i.x) * 3
						local ydist = (y - i.y) * 3
						local zdist = (elevation - i.elevation) * 3
						local dist = math.floor(0.5 + math.sqrt(xdist^2 + ydist^2 + zdist^2))
						monsterdistance[monstertotal] = dist
						monsterarray[monstertotal] = i
					end
				end
			end
		end
		for i = 1, monstertotal do
			print(monsterarray[i].name, monsterdistance[i])
		end
	end,
}
that's I always says about scripters, you guys are incredible :lol:
anyway, thanks for sharing it.
My asset pack: viewtopic.php?f=22&t=9320

Log1 mod : Toorum Manor: viewtopic.php?f=14&t=5505
Post Reply