MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

The role-playing games (I-X) that started it all and the various spin-offs (including Dark Messiah).
Kyurem
Leprechaun
Leprechaun
Posts: 5
Joined: 02 Feb 2022

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Kyurem » 06 Feb 2022, 01:25

Tomsod wrote: 05 Feb 2022, 08:06 Table files like mapstats.txt are in lod archives in the Data directory. You'll need MMArchive or a similar tool to open them. Create DataFiles directory next to Data, extract the txt file there, and then you can edit it. The specific archive depends on the version of Merge you're using, usually it's something.T.lod.
I've successfully found and edited the mapstat.txt. But mapstats only contains maps from the MM8 game. Since I was playing the merge version I thought that maps like New Sorpigal and Harmondale could also be found in that file. I guess the only thing to do is to open every lod file and see if I can find the other mapstats for both Enroth and Antagarich.
Tomsod wrote: 05 Feb 2022, 08:06 Training time is not easily editable. You'd need an assembly patch or perhaps some time-rewinding MMExt hack, and both are evidently not your specialty. Relatedly, I actually intend to make this exact change in the next version of my MM7 mod (I have a very strong opinion that the MM6 way was better here), but I haven't got around to it yet.
Damn I was hoping there was a file that tells the game how many days it takes to train a single level. But I think that's hardcoded. Yeah I understand why people might want to change that. Training 10 levels just to later found out that 3 months have passed. As an MM6 player was not happy with that change.

Thanks a lot, now I can kill the monsters from some areas every couple of months instead of waiting a whole year. I'm RP as a solo bounty hunter (using the worst class in MM7, the ranger) and I was sick of trying to track down my target in an monster-free zone.

UPDATE: After some testing, I discovered that the mapstats.txt inside EnglishT.lod is useless. The merge version uses another mapstat file. The real one is inside mmmergeT.lod which contains the maps from Jadane, Antagarich and Enroth (tested). Remember to make a backup copy before editing files like mapstats.txt.

Kyurem
Leprechaun
Leprechaun
Posts: 5
Joined: 02 Feb 2022

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Kyurem » 07 Feb 2022, 00:32

Hello it's me again.
So, I was trying to create a potion of town portal. I've successfully created a new item ID and entries in POTION.TXT, POTNOTES.TXT, rnditems.txt and Potion settings.txt. Everything works just fine. By mixing shield+orange the character can create this potion called "instant transmission". Sadly this is where I hit the wall. I just can't create the right script for this new potion. (71 is the ID of this new potion, 31 is the ID of the town portal spell)

Code: Select all

evt.PotionEffects[71] = function(IsDrunk, Target, Power)
if IsDrunk then
	evt.CastSpell[31]
	return true
	end
end
Sorry if this code is way simpler than it should be. But have no idea how it really works. I mean, I could probably get it right if I know the code for the potion of haste (or any other potion that cast a spell) and the code or script for the scroll of town portal (so I can see how the game cast that specifc spell).
Anyway, for now the only thing I could do is to edit the potion.txt so I can mix both Shield+Orange into a SCROLL of town portal (you can mix potions to create any item in the game, I found this trick by accident). It's kind of the same thing I want to accomplish but not quite because I want a potion, not a scroll.

Tomsod
Scout
Scout
Posts: 171
Joined: 31 Jul 2020

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Tomsod » 07 Feb 2022, 04:40

This is a common misunderstanding that pops up quite often lately: evt.CastSpell cannot actually cast most spells. It's only limited to a few spells deemed necessary by NWC, like those cast by pedestals, traps, and other scripted events. At least, it is so in vanilla MM6-8; I am no Merge expert. Triggering an arbitrary spell from MMExtension is actually not trivial because the ordinary generic-player-spellcasting function is not hooked. Your best bet is to use actions, like this:

Code: Select all

function add_action(type, info1, info2)
    local len = Game.Actions.length
    if (len < 40) then
        Game.Actions.length = len + 1
        Game.Actions[len].Type = type
        Game.Actions[len].Info1 = info1
        Game.Actions[len].Info2 = info2
    end
end

-- this will simulate casting from a scroll (50% chance to fail)
player = 0 ; pc to "use" the "scroll"
add_action(0x92, 31, player) -- 31 is town portal
if Game.CurrentScreen ~= 0 then add_action(0x71, 0, 0) end -- return to main screen to avoid glitches

-- this will directly call town portal dialog (will never fail)
if Game.CurrentScreen == 0 then add_action(0xc3, 0, 0) end -- do NOT call from inventory etc., can lead to crashes
Maybe the latter one can be modified to work from inventory somehow, but I haven't figured it out. You'll likely need to exit the inventory first (0x71), then call it (0xc3), but 0x71 erases all actions after itself. Maybe use a timer?

cthscr
Blood Fury
Blood Fury
Posts: 456
Joined: 12 Jan 2020

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby cthscr » 07 Feb 2022, 08:36

Perhaps you can just put TP into the spell queue (like Rodril did). See also [MM8-related] https://gitlab.com/cthscr/mmmerge/-/wik ... Spell-proc

Tomsod
Scout
Scout
Posts: 171
Joined: 31 Jul 2020

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Tomsod » 07 Feb 2022, 13:39

cthscr wrote: 07 Feb 2022, 08:36 See also [MM8-related] https://gitlab.com/cthscr/mmmerge/-/wik ... Spell-proc
Oh, so that's what the loop around the spellcasting function does. That's surprisingly convenient, wonder why MMExt hasn't exposed it. Still, without the interface it's a tiny bit more advanced.

User avatar
GrayFace
Round Table Hero
Round Table Hero
Posts: 1644
Joined: 29 Nov 2005

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby GrayFace » 15 Feb 2022, 08:43

Making GM Dagger do +2 damage/skill instead of +1

Code: Select all

function events.CalcStatBonusBySkills(t)
	if t.Result ~= 0 and t.Stat == const.Stats.MeleeDamageBase then  -- t.Result ~= 0 is for speedup
		local sk, mas = SplitSkill(t.Player.Skills[const.Skills.Dagger])
		if mas >= const.GM then
			local it = t.Player:GetActiveItem(const.ItemSlot.MainHand)
			if it and it:T().Skill == const.Skills.Dagger then
				t.Result = t.Result + sk
			end
		end
	end
end
Mareneusz002 wrote: 14 Feb 2022, 06:45would it be possible to make .txt file with things like "+2/skill on GM" or
for example change "+1% chance to stun per skill point." to more % like 2 or 5% chance to stun per skill point?
Nope.
My patches: MM6 MM7 MM8. MMExtension. Tools. Also, I love Knytt Stories and Knytt Underground. I'm also known as sergroj.

Karol
Leprechaun
Leprechaun
Posts: 34
Joined: 02 Jan 2022

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Karol » 17 Mar 2022, 17:46

How to learn to find & edit NPC scripts? I was going through https://grayface.github.io/mm/ext/ref/ but could not solve my problem:

MM7Rev4modR1 Redone is quite strict on 2nd Sorcerer promotion, and I didn't click the right button. Hence I am barred from the 2nd promotion.
The promotion itself, I could possibly edit with Cheat Engine, but I more than that want to visit the dungeon that is dedicated for this quest.

Without actual knowledge, I used random evt. commands from this part and I was able to use the PORTAL near the stables (Home Portal pedestal)

Code: Select all

-- "Spellbinder Promotion"
evt.global[94] = function()
	if evt.Cmp{"QBits", Value = 99} then         -- Chose the path of Light
		evt.SetMessage{Str = 18}         --[[ "Our Diviners have been unable to discover who, or what, caused the unmaking of the Town Portal spell, but they have located the book that was used to accomplish this dastardly deed.  It’s called the Book of UnMakings.  The book was  kept under guard in the Strange Temple here in the Bracada.  However, several years ago, the temple was swallowed up by a terrible tremor that shook the Bracada, and the book went down with it.  This temple is now buried deep within the depths of the land, with no known entrance from the surface.

However, after consulting with Torrent, the Grandmaster of Water Migicks, we have been able to open an astral tunnel into the temple and link it to the Home Portal here in Bracada.  The tunnel is not too stable, and we aren’t sure how long we can keep it open.

If you desire this promotion, you must enter the tunnel, find the Book of UnMakings, and return it to me.  But you must go NOW.  We cannot afford to wait even an hour, lest the tunnel close." ]]
		evt.Set{"QBits", Value = 47}         -- "Recover the Book of Unmakings from the Strange Temple and return it to Thomas Grey in the School of Sorcery."
		evt.SetNPCTopic{NPC = 48, Index = 0, Event = 95}         -- "Thomas Grey" : "We've retrieved the Book of UnMakings!"
	else
		if evt.Cmp{"QBits", Value = 100} then         -- Chose the path of Dark
			evt.SetMessage{Str = 208}         -- "You've chosen Darkness, my students.  I will teach you no more."
		else
			evt.SetMessage{Str = 207}         -- "Archmage training is reserved only for people dedicated to the Path of Light.  Prove to me you have chosen the right way, and I will be proud to be your teacher."
		end
	end
end
I am now in the dungeon... I yet have to find out, if I will be actually promoted to Archmage, after I will return with the book of UnMaking..
Last edited by Karol on 18 Mar 2022, 10:30, edited 1 time in total.

Tomsod
Scout
Scout
Posts: 171
Joined: 31 Jul 2020

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Tomsod » 17 Mar 2022, 21:11

In the original Rev4 you'd just need to reset Thomas Grey's dialogue, which is as simple as

Code: Select all

evt.SetNPCTopic(48, 0, 94)
or, alternatively,

Code: Select all

Game.NPC[48].EventA = 94
. But I don't know how much David has changed, maybe Grey is no longer 48, or the Archmage topic is no longer 94, even the quest itself could've been rewritten. If these commands won't work, try looking for Thomas Grey in npcdata.txt and the first Archmage topic in npctopic.txt and substituting the numbers, or ask David himself for help.

Karol
Leprechaun
Leprechaun
Posts: 34
Joined: 02 Jan 2022

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Karol » 18 Mar 2022, 10:42

Thank you,

Grey is still 48 (well, there is 2nd instance of Grey, but that one is not the actual promoter :)



As for the Archmage topic, I do see "Event=94" so it seems intact as well.

User avatar
DaveHer
Marksman
Marksman
Posts: 434
Joined: 13 Mar 2019

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby DaveHer » 21 Mar 2022, 05:06

Tomsod wrote: 17 Mar 2022, 21:11 In the original Rev4 you'd just need to reset Thomas Grey's dialogue, which is as simple as

Code: Select all

evt.SetNPCTopic(48, 0, 94)
or, alternatively,

Code: Select all

Game.NPC[48].EventA = 94
. But I don't know how much David has changed, maybe Grey is no longer 48, or the Archmage topic is no longer 94, even the quest itself could've been rewritten. If these commands won't work, try looking for Thomas Grey in npcdata.txt and the first Archmage topic in npctopic.txt and substituting the numbers, or ask David himself for help.
Thomas Grey is number 7 in the Npcdata.txt.
David

Karol
Leprechaun
Leprechaun
Posts: 34
Joined: 02 Jan 2022

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Karol » 21 Mar 2022, 11:11

DaveHer wrote: 21 Mar 2022, 05:06 Thomas Grey is number 7 in the Npcdata.txt.
David
Sorry, imgur somehow removed the pic, where I wanted to show, that Thomas Gray has two instances in NPC list (scrubbed from .LOD)
So now I try different provider:
https://ibb.co/9VpSHQq

And using NPC = 48 did work in order to fix my mistake. (also visible in the NPC table picture, that the #7 Gray does not have any starting Even associated, only greetings)

Still, it sometimes becomes quite a headache to move (mental jogging) between the original and Redone differences.

User avatar
DaveHer
Marksman
Marksman
Posts: 434
Joined: 13 Mar 2019

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby DaveHer » 22 Mar 2022, 03:04

Karol wrote: 21 Mar 2022, 11:11
DaveHer wrote: 21 Mar 2022, 05:06 Thomas Grey is number 7 in the Npcdata.txt.
David
Sorry, imgur somehow removed the pic, where I wanted to show, that Thomas Gray has two instances in NPC list (scrubbed from .LOD)
So now I try different provider:
https://ibb.co/9VpSHQq

And using NPC = 48 did work in order to fix my mistake. (also visible in the NPC table picture, that the #7 Gray does not have any starting Even associated, only greetings)

Still, it sometimes becomes quite a headache to move (mental jogging) between the original and Redone differences.
MM7Rev4modR1 was created by Big Daddy Jim and later modified by Maestro. It is very different form the original MM7. They moved a few NPC locations. I just added sprites, icons, bitmaps, textures, quests, and models made with blender. I did not mess with NPCs. That would mess up the game.
David :)

cthscr
Blood Fury
Blood Fury
Posts: 456
Joined: 12 Jan 2020

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby cthscr » 22 Apr 2022, 08:58

MM8, requires MM8Patch 2.5.*
Use at your own risk (seems to work for me with Revamp).

Code: Select all

-- Increase amount of save slots
--do return end

local asmpatch, u4 = mem.asmpatch, mem.u4

local MaxSaveSlots = 0x3C  -- no more than 0x7F

--
asmpatch(0x45C043, "cmp ebx, " .. MaxSaveSlots)

--
asmpatch(0x4CD624, "push " .. (MaxSaveSlots - 10))

--
asmpatch(0x4CDBEC, "push " .. MaxSaveSlots)

--
mem.IgnoreProtection(true)

-- replace 0x6C9B40 -- includes savegame title
--  0x64 * MaxSaveSlots
local buf1 = mem.StaticAlloc(0x64 * MaxSaveSlots)

local ptrs = {0x45C16F+3, 0x45C2FD+1, 0x45C5CB+3, 0x45C719+1, 0x45DBBC+1,
	0x45DC17+2,
	--0x45DFCC+2, -- mmpatch
	0x45E341+1,
	--0x4CD875+1, -- mmpatch
	0x4CD9DF+1,
	--0x4CDB0E+2 -- mmpatch
}
for _, v in pairs(ptrs) do
	mem.u4[v] = buf1
end
u4[0x45DBE0+2] = buf1 + 0x14
u4[0x45DBF2+2] = buf1 + 0x28
u4[0x45DBFD+2] = buf1 + 0x2C
u4[0x45DE13+1] = buf1 + 0x14
u4[0x45DE45+2] = buf1 + 0x28
u4[0x45E326+1] = buf1 + 0x14

-- replace 0x6CAD00
local buf2 = mem.StaticAlloc(4 * MaxSaveSlots)

ptrs = {0x42F2D3+3, 0x433692+3, 0x45C089+1, 0x45C222+3, 0x45C235+3,
	0x45C522+1, 0x45C916+3, 0x45DDA1+3}
for _, v in pairs(ptrs) do
	mem.u4[v] = buf2
end
u4[0x45C083+1] = 4 * MaxSaveSlots
u4[0x45C51C+1] = 4 * MaxSaveSlots

-- replace 0x6CADCC / 0x6CADB8 - savegame filenames list
--  0x118 * MaxSaveSlots
local buf3 = mem.StaticAlloc(0x118 * MaxSaveSlots)

u4[0x45BF68+1] = buf3
u4[0x45BF60+1] = 0x118 * MaxSaveSlots
ptrs = {0x45BF8D+1, 0x45C176+3, 0x45C5D2+3, 0x45C969+2, 0x4CD907+1}
for _, v in pairs(ptrs) do
	mem.u4[v] = buf3 + 0x14
end
-- replace 0x6CC3AC
--  0x6CADCC + 0x118 * MaxSaveSlots
--   0x45C671+3
u4[0x45C671+3] = buf3 + 0x14 + 0x118 * MaxSaveSlots

-- replace 0x6CDEF0
local buf4 = mem.StaticAlloc(0x28 * MaxSaveSlots)

-- 6CDEF0
ptrs = {
	0x4129BF+3,
	0x4129D5+3,
	0x430DE0+1, -- lloyd beacon
	0x4310CF+1, -- lloyd beacon
	0x45BC65+1,
	0x45C09C+1,
	0x45C536+1,
	0x45CE8A+3,
	0x45DCA4+1,
	0x4D176F+3
}
for _, v in pairs(ptrs) do
	mem.u4[v] = buf4
end
u4[0x45C096+1] = 0x28 * MaxSaveSlots
u4[0x45C530+1] = 0x28 * MaxSaveSlots
-- 6CDF14
ptrs = {
	0x4129B0+3,
	0x430D22+3,
	0x430D84+3,
	0x45BC7C+1
}
for _, v in pairs(ptrs) do
	mem.u4[v] = buf4 + 0x24
end
--0x45DCB3+2, -- 6CE210 (cmp,jl,0,20*0x28) 0x40F7F6
u4[0x45DCB3+2] = buf4 + 0x28 * MaxSaveSlots
--0x45BCA5+2, -- 6CE57C (cmp,jl,36,41*0x28) clear
u4[0x45DCB3+2] = buf4 + 0x24 + 0x28 * MaxSaveSlots
-- lloyd beacon
--0x430DEF+2, -- 6CDFB8 (cmp,jl,0,5*0x28) action 181
u4[0x430DEF+2] = buf4 + 0x28 * 5
--0x4310DE+2, -- 6CDFB8 (cmp,jl,0,5*0x28) action 179
u4[0x4310DE+2] = buf4 + 0x28 * 5

mem.IgnoreProtection(false)

User avatar
theorclair
Peasant
Peasant
Posts: 62
Joined: 18 Jun 2013

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby theorclair » 10 May 2022, 01:37

Nirran wrote: 12 Feb 2021, 16:09 hello people :)

were can i find docs on the hooks this mod adds?i wnata change the time of lvl training,it is possible isnt it?

thnx

edit : found it ,yay now training takes 0 time :P
How were you able to do this?

User avatar
Nirran
Leprechaun
Leprechaun
Posts: 22
Joined: 09 Feb 2021

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Nirran » 10 May 2022, 06:33

theorclair wrote: 10 May 2022, 01:37
Nirran wrote: 12 Feb 2021, 16:09 hello people :)

were can i find docs on the hooks this mod adds?i wnata change the time of lvl training,it is possible isnt it?

thnx

edit : found it ,yay now training takes 0 time :P
How were you able to do this?
Hello,

I Altered the training time per learning skills reduction function - it is in scripts/general/Learning.lua

i mearly zeroed the function variables,this may be outdated,since i havent play mm for ages,this is the entire fuction

Code: Select all

local function ReduceTrainingTime()
	-- Ignore MM8 check for maximal amount of level-ups this session
	-- Get training hours to be added in according to Learning mastery
	local NewCode = asmpatch(0x4B3606, [[
	inc dword ptr [eax]
	mov eax, dword ptr [eax]
	nop
	nop
	nop
	nop
	nop
	test edi, edi
	je absolute 0x4B3640
	push eax
	]])

	hook(NewCode + 4, function(d)
		local cur_pl = Game.CurrentPlayer
		local cur_levels = d.eax
		local days, total_levels = 0, 0
		-- Get already spent days during this session for other players
		for k, pl in Party do
			if k ~= cur_pl then
				local levels = u4[0xFFD3AC + k * 4]
				if levels > 0 then
					local _, mastery = SplitSkill(pl.Skills[LEARNING])
					local pl_days = levels * (7 - mastery)
					if pl_days > days then
						days = pl_days
					end
					total_levels = total_levels + levels
				end
			end
		end
		local _, mastery = SplitSkill(Party[cur_pl].Skills[LEARNING])
		local cur_days = cur_levels * (7 - mastery)
		if cur_days > days then
			if cur_levels > 1 then
				-- Check if current player already spent more days than others
				local prev_days = (cur_levels - 1) * (7 - mastery)
				days = max(days, prev_days)
			end
			d.edi = (cur_days - days) * 24
		else
			d.edi = 0
		end
		total_levels = total_levels + cur_levels
		--d.eax = total_levels
		d.ecx = 0 -- Nirran Added
		d.eax = 0 -- Nirran Added
		d.edi = 0 -- Nirran Added
	end)


	-- Ignore extra hours for non first level-up.
	-- Check for next 9 AM to be in 24 hours for first level-up.
	-- ecx - level-ups this sesssion
	-- eax - hours till next dawn
	-- edi - training hours to be added
	asmpatch(0x4B3617, [[
	pop ecx
	cmp ecx, 1
	jle @first
	xor eax, eax
	jmp @std
	@first:
	add eax, 4
	cmp eax, 0x18
	jle @std
	sub eax, 0x18
	@std:
	add eax, edi
	]])
end
Enjoy

edit : forgot to tell you that this is done for might and magic merge mod,ive no idea how to do it from scratch

User avatar
theorclair
Peasant
Peasant
Posts: 62
Joined: 18 Jun 2013

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby theorclair » 10 May 2022, 14:07

Nirran wrote: 10 May 2022, 06:33
theorclair wrote: 10 May 2022, 01:37
Nirran wrote: 12 Feb 2021, 16:09 hello people :)

were can i find docs on the hooks this mod adds?i wnata change the time of lvl training,it is possible isnt it?

thnx

edit : found it ,yay now training takes 0 time :P
How were you able to do this?
Hello,

I Altered the training time per learning skills reduction function - it is in scripts/general/Learning.lua

i mearly zeroed the function variables,this may be outdated,since i havent play mm for ages,this is the entire fuction

Code: Select all

local function ReduceTrainingTime()
	-- Ignore MM8 check for maximal amount of level-ups this session
	-- Get training hours to be added in according to Learning mastery
	local NewCode = asmpatch(0x4B3606, [[
	inc dword ptr [eax]
	mov eax, dword ptr [eax]
	nop
	nop
	nop
	nop
	nop
	test edi, edi
	je absolute 0x4B3640
	push eax
	]])

	hook(NewCode + 4, function(d)
		local cur_pl = Game.CurrentPlayer
		local cur_levels = d.eax
		local days, total_levels = 0, 0
		-- Get already spent days during this session for other players
		for k, pl in Party do
			if k ~= cur_pl then
				local levels = u4[0xFFD3AC + k * 4]
				if levels > 0 then
					local _, mastery = SplitSkill(pl.Skills[LEARNING])
					local pl_days = levels * (7 - mastery)
					if pl_days > days then
						days = pl_days
					end
					total_levels = total_levels + levels
				end
			end
		end
		local _, mastery = SplitSkill(Party[cur_pl].Skills[LEARNING])
		local cur_days = cur_levels * (7 - mastery)
		if cur_days > days then
			if cur_levels > 1 then
				-- Check if current player already spent more days than others
				local prev_days = (cur_levels - 1) * (7 - mastery)
				days = max(days, prev_days)
			end
			d.edi = (cur_days - days) * 24
		else
			d.edi = 0
		end
		total_levels = total_levels + cur_levels
		--d.eax = total_levels
		d.ecx = 0 -- Nirran Added
		d.eax = 0 -- Nirran Added
		d.edi = 0 -- Nirran Added
	end)


	-- Ignore extra hours for non first level-up.
	-- Check for next 9 AM to be in 24 hours for first level-up.
	-- ecx - level-ups this sesssion
	-- eax - hours till next dawn
	-- edi - training hours to be added
	asmpatch(0x4B3617, [[
	pop ecx
	cmp ecx, 1
	jle @first
	xor eax, eax
	jmp @std
	@first:
	add eax, 4
	cmp eax, 0x18
	jle @std
	sub eax, 0x18
	@std:
	add eax, edi
	]])
end
Enjoy

edit : forgot to tell you that this is done for might and magic merge mod,ive no idea how to do it from scratch
Thanks.

Can anyone tell me if this would work in the current game?

User avatar
raekuul
Demon
Demon
Posts: 349
Joined: 05 Jul 2019

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby raekuul » 29 Jun 2022, 14:12

We're working on an MM6 mod and we decided we want unique monsters that drop specific items (like how the Devil of Baa drops the Devil Plans, or how Q drops the Horn of Ros) but we can't find any examples of creating a unique monster that drops a specific item. We are able to create specific monsters, we just haven't been successful in making them carry specific items.

Tomsod
Scout
Scout
Posts: 171
Joined: 31 Jul 2020

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Tomsod » 03 Jul 2022, 06:40

Isn't it just the 'Item' field of the map monster struct? For a vanilla example, see that one quest dragon in the Mire of the Damned.

User avatar
raekuul
Demon
Demon
Posts: 349
Joined: 05 Jul 2019

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby raekuul » 10 Jul 2022, 15:25

(and I'm back again)

So one of the difficulties I've run into is that the MM6 Skill Emphasis Mod changed certain early game monsters to be stronger (since they also appeared in late/endgame dungeons and it was desirable to make them better-suited for the endgame); originally they also replaced their early-game appearances with a suitable monster class via a change to the lodfiles, but I need a solution that doesn't change the lodfiles for compatibility with the randomizer (randomizer patched lods need to come last in the sequence, so changes to lodfiles won't properly make it down the chain; the affected dungeons are SEWER and T1, replacing Priest-type monsters with Monk-type).

I see in the docs that there's Map.Monsters[], is that what I want to look at? (I'm not entirely comfortable yet with how MMExt presents structs for interaction, so code samples would be helpful too)

EDIT: On that note, I'm having issues getting updated item names/notes to show up in-game without resorting to lodfile updating; the lua is as follows: <code removed>
As far as I can tell, it works in the lua debugger but not from the script itself, so there's probably an error that exists between keyboard and chair (most likely related to the if not nil condition)
Yep, it was exactly the `if not var == nil` check - changing it to `if var ~= nil` made it work.

Eksekk
Scout
Scout
Posts: 185
Joined: 19 Jul 2016

Re: MMExtension v2.2 + MMEditor v2.1 Level Editor [June 4, 2019]

Unread postby Eksekk » 11 Jul 2022, 12:59

raekuul wrote: 10 Jul 2022, 15:25 (and I'm back again)

So one of the difficulties I've run into is that the MM6 Skill Emphasis Mod changed certain early game monsters to be stronger (since they also appeared in late/endgame dungeons and it was desirable to make them better-suited for the endgame); originally they also replaced their early-game appearances with a suitable monster class via a change to the lodfiles, but I need a solution that doesn't change the lodfiles for compatibility with the randomizer (randomizer patched lods need to come last in the sequence, so changes to lodfiles won't properly make it down the chain; the affected dungeons are SEWER and T1, replacing Priest-type monsters with Monk-type).

I see in the docs that there's Map.Monsters[], is that what I want to look at? (I'm not entirely comfortable yet with how MMExt presents structs for interaction, so code samples would be helpful too)
Welcome back!
You can modify the monsters directly after loading the map. To do this, create a file with map file name and ".lua" extension in Scripts/Maps, for example oute3.lua, and inside put this code:

Code: Select all

for k, v in Map.Monsters do -- loop over monsters on map, v will become each subsequent monster
	if v.Id == [monster id, check them in monsters.txt file] then
		-- edit monster properties (names are here: <https://grayface.github.io/mm/ext/ref/#structs.MapMonster>, they are similar to those in monsters.txt file), example:
		v.WaterResistance = 100 -- set water res to 100
		v.Fly = false -- can't fly
		v.FullHP, v.HP = 500, 500 -- set max and current HP
		v.EarthResistance = v.EarthResistance + 50 -- increase earth res by 50
	-- optional:
	elseif v.Id == [another id] then
		-- instructions...
	-- more elseifs can follow:
	elseif v.Id == [another id2] then
		-- instructions2...
	-- optional too, happens if no previous conditions matched,
	-- after else you can't use elseif anymore
	else
		-- instructions3...
	-- this is always required
	end
end
You can choose if your script should boost monsters in endgame locations or weaken monsters in starting locations. A convenient way to match all three tiers of monster is to use

Code: Select all

if (Id + 2):div(3) == <compute integer part of (any tier of chosen monster id + 2) / 3> then ...
(without the <>). If you need more help, write here or on MM discord.
raekuul wrote: 10 Jul 2022, 15:25 EDIT: On that note, I'm having issues getting updated item names/notes to show up in-game without resorting to lodfile updating; the lua is as follows: <code removed>
As far as I can tell, it works in the lua debugger but not from the script itself, so there's probably an error that exists between keyboard and chair (most likely related to the if not nil condition)
Yep, it was exactly the `if not var == nil` check - changing it to `if var ~= nil` made it work.
BTW, it didn't work because without parentheses lua applied not to var (not returns only true or false, so the result will never be nil). If you wrote `if not (var == nil)` it would work too. For future reference, for learning basic syntax you can use programming in lua course, one version of which is available online for free or, if you don't have that much time, most basic language/syntax concepts are explained by lua cheatsheets, like this one (I'm not promoting it, this was my first google result for "lua cheat sheet").


Return to “Might and Magic”

Who is online

Users browsing this forum: No registered users and 17 guests