Not again --- Scripting help required

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
User avatar
Kuningas
Posts: 268
Joined: Wed Apr 11, 2012 10:29 pm
Location: Northern Finland

Not again --- Scripting help required

Post by Kuningas »

I'm thinking we could use a general topic for scripting help, it is getting embarassing making a new topic every day for a new problem...

Alas, I am out of luck again, for the last three hours or so, I've been trying to formulate a script that checks if a champion has a dagger in hand when attacking. I've used a print("check") as a way of testing if it works since I've not yet started scripting the effect I was planning. Currently I am using a party hook onAttack and then getItem(7) to see if the right hand slot has a dagger, and then printing check if it does. (I've treid it with both slots but to no avail) For some unknown to me reason the only result I reached was that if the champion did NOT have a dagger in the mentioned slot, it would print the message. Adding "not" to the script to see if this worked in reverse, showed that it doesn't. With a not, it didn't print anything. Here is the current code, albeit it is already gone through multiple iterations:

Code: Select all

cloneObject{
	name = "party",
	baseObject = "party",
	
	onAttack = function(champion)
		if champion:getItem(7) == dagger then
			print("check")
			else
		print("No dagger")
		end
	end
	}
This code seems to work exactly the opposite from what it should (to me) -- if the item is not a dagger, it prints "check" and if it is, it prints "no dagger".

Sorry again /_\

EDIT: Hmm, it seems there is something very wrong in the way I address the type of item in the hand. It actually prints check when I attack with an empty hand, and no dagger if I attack with any weapon...
BASILEUS
User avatar
Wolfrug
Posts: 55
Joined: Wed Oct 03, 2012 6:56 pm

Re: Not again --- Scripting help required

Post by Wolfrug »

According to the Asset Definition page the onAttack function already knows what weapon the attack is being made by! "The function gets two parameters: the attacking champion and the weapon used to attack."

So it should really just be:

Code: Select all

onAttack = function(champion,weapon)
      if weapon.name == "dagger" then
         print("check")
         else
      print("No dagger")
      end
end

The above will probably crash if you do an unarmed attack though, but that might be avoided by an extra "if not nil" check. Maybe.
Try my Mordor: Depths of Dejenol LoG-ification. Feedback much appreciated!
User avatar
Grimwold
Posts: 511
Joined: Thu Sep 13, 2012 11:45 pm
Location: A Dungeon somewhere in the UK

Re: Not again --- Scripting help required

Post by Grimwold »

looks like you are missing the name portion of getItem.. as below (PS I changed the output to hudPrint because I prefer that way of outputting).

Code: Select all

   onAttack = function(champion)
     if champion:getItem(7).name == "dagger" then
       hudPrint("check")
     else
       hudPrint("No dagger")
     end
   end,
this only checks the left hand... so you would need to modify it to check the right hand.. and it still returns true if I have a dagger in my left hand but attack with a spear in the right.

Also... if I have a dagger as the mouse item and I use it to right-click a spear to attack it crashes the editor!

EDIT... beaten to the punch and by a much more elegant solution.
User avatar
Grimwold
Posts: 511
Joined: Thu Sep 13, 2012 11:45 pm
Location: A Dungeon somewhere in the UK

Re: Not again --- Scripting help required

Post by Grimwold »

Perhaps an even better way to script it would be as follows:

Code: Select all

cloneObject{
   name = "party",
   baseObject = "party",
    onAttack = function(champion,weapon)
      return attack_script.weaponCheck(champion,weapon)
    end
}
Then you can script everything else in a function weaponCheck() in a script entity called attack_script in the dungeon itself.

e.g.

Code: Select all

function weaponCheck(champion,weapon)
  if weapon ~= nil 
  then
    if weapon.name == "dagger" then
      hudPrint("Dagger")
    else
      hudPrint("Non-Dagger Weapon")
    end
  else
    hudPrint("Unarmed")
  end
end
EDIT - modified function above for "Unarmed" check (per Edsploration's notes below)
Last edited by Grimwold on Tue Oct 09, 2012 5:08 pm, edited 2 times in total.
User avatar
Edsploration
Posts: 104
Joined: Wed Sep 19, 2012 4:32 pm

Re: Not again --- Scripting help required

Post by Edsploration »

The word dagger does not automatically refer to any dagger object. What you can use, however, is check the name property which will be the same for any dagger object. The name property is a string.

Code: Select all

champion:getItem(7).name == "dagger"
Now things get a bit tricky because there's one more pitfall you can run into. If there is not an item in slot 7, getItem(7) will not point to any item at all! It will return nil, which is a fancy way to say it returns nothing. Nothing does not have a name property, so basically, the game will crash.

But fear not! We can first check if the item exists (it not nil), and THEN only if it exists we can check if the item's name is "dagger". Like so:

Code: Select all

onAttack = function(champion)
	if champion:getItem(7) ~= nil then
		if champion:getItem(7).name == "dagger" then
			print("It's a dagger!")
		else
			print("Not a dagger...")
		end
	else
		print("No item found. At all.")
	end
end
(~= means is not equal to)

Also, here's an extra tip to help you stretch those debugging muscles:
Use the tostring() function inside of print(). With this you can check what anything is, more or less. For instance you cay use...

Code: Select all

print(tostring(champion:getItem(7)))
...which will be able to tell you if there is something there, if it is a string "dagger", or if it is nil. Basically you can "peak" into what's going on just about anywhere. Without the tostring() function, this code will crash if you check something which is not a string.
Open Project -> Community FrankenDungeon: viewtopic.php?f=14&t=4276
User avatar
Kuningas
Posts: 268
Joined: Wed Apr 11, 2012 10:29 pm
Location: Northern Finland

Re: Not again --- Scripting help required

Post by Kuningas »

Thank you everyone! I had no idea of the .name part, and I was wondering what was causing all the crashes I got.

And the solution was more complex than I could have dreamed, while being simple enough to keep me interested in learning this scripting business. If all goes according to plan fromhere, I'll be sure to show results here or the scripting repository.

Onwards, to the editor!

EDIT: I also actually understood what parameters are, damn! I've been... a fool amongst gentlemen!
BASILEUS
User avatar
crisman
Posts: 305
Joined: Sat Sep 22, 2012 9:23 pm
Location: Italy

Re: Not again --- Scripting help required

Post by crisman »

Ehy, an advice on hooks.
Since bugged hooks on .lua files crash the editor, my suggestion is to make a reference to a function inside the editor, so in case of error, it won't crash but it will warn you inside of the script directly.
When everything is fine you'll copy and paste the script inside the hook, deleting the reference

just an example:

onAttack = function(item, champion)
attackScript.attackFunction(item, champion)
return true
end,

in the editor you need to place a script with an ID of attackScript, which will have a function called attackFunction
function attackFunction(a, b)
--type your script here
end
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Not again --- Scripting help required

Post by akroma222 »

This is very useful! Just what I am after to try and replicate lifeleach effect ;) Ta!
Post Reply