Jump to content

Change drop of Monster


Recommended Posts

The problem here, is that the goblin actually has a spear in his hand. This is different to most monsters, which have a "virtual"/fake weapon, which isn't actually equipped, but acts as a sort of innate attack "item". Look at the prefab for Clockwork Knights for an example. These goblins actually receive a spear and it is equipped on them manually in their initialization function. This is why the spear drops from them every time, since monsters always drop what they have in their hands. This make this problem a bit harder to fix.

The first thing you'll want to do, is to destroy the spear in their hands when they die. For this, you can listen for the event "death" on the goblin inst, and trigger some code that destroys the spear they have in their hands.

Then, to add/change their loot table, you'll have to add some loot to their lootdropper component. It doesn't look like anything is added to it in their initialization function, but the component is definitely attached to them. The file you're probably going to interact with, is the lootdropper,lua. You're not going to change it, but you can change the loot dropped by prefabs which have it on. So, you can do an AddPrefabPostInit for the goblins, where you somehow react to their death, by destroying the spear they have before they actually die, AND add some loot to their lootdropper component, for example by using the lootdropper:AddChanceLoot or lootdropper:AddRandomLoot functions.

Edited by Ultroman
Link to comment
Share on other sites

On 15.12.2018 at 10:29 PM, Ultroman said:

by destroying the spear they have before they actually die, AND add some loot to their lootdropper component, for example by using the lootdropper:AddChanceLoot or lootdropper:AddRandomLoot functions.

Where i can find this functions is their any docu? How can i finde this function for Listing to an event or destroying an item

I added 

local function OnDeath(inst, data)
	inst.components.inventory:Equip()
end

and this but i think i´m on a totally wrong way 
 

local function fn()
	local inst = CreateEntity()
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddMiniMapEntity()
	inst.entity:AddSoundEmitter()
	inst.entity:AddDynamicShadow()
	inst.entity:AddNetwork()
	
	...

	inst.OnBuilt = linkToBuilder
	
	inst:ListenForEvent("attacked", OnAttacked)  
	inst:ListenForEvent("onattackother", OnAttackOther)
	inst:ListenForEvent("death",OnDeath)

	return inst

 

Edited by BlueJelly
Link to comment
Share on other sites

Your listenforevent is perfect. Your OnDeath makes no sense. You're trying to unequip, not equip. I don't have time this week to write long-winded answers, so I'll just say: find scripts.zip in the game files, unzip it, and look at how inventory.lua and inventoryitem.lua work together. You'll figure it out. Same with lootdropper. In your fn() just call inst.components.lootdropper:AddChanceLoot or inst.components.lootdropper:AddRandomLoot with the variables for the function you want. lootdropper.lua has all the answers.

Edited by Ultroman
Link to comment
Share on other sites

I found 

Inventory:RemoveItemBySlot(slot)

and 

Inventory:RemoveItem(item, wholestack)

but i can not find information what wholestack parameter or the slot parameter takes

 

tried this as my on death method but dosen't work

local function OnDeath(inst, data)
    inst.components.Inventory:RemoveItem( inst.goblinweapon )
end

 

I also tried:

local function OnDeath(inst, data)
    inst.components.inventory:RemoveItemBySlot(EQUIPSLOTS.HANDS)
end

but nothing hapend

Edited by BlueJelly
Link to comment
Share on other sites

There is actually an Unequip function in the inventory.lua. It just takes the equipment slot and a boolean of whether the item slipped or not. It returns the item.

local equippedItem = inst.components.inventory:Unequip(GLOBAL.EQUIPSLOTS.HANDS, false)
if equippedItem ~= nil then
    equippedItem:Remove()
end

 

Link to comment
Share on other sites

still drops the spear 

local function OnDeath(inst, data)
	local equippedItem = inst.components.inventory:Unequip(EQUIPSLOTS.HANDS, false)
	if equippedItem ~= nil then
    equippedItem:Remove()
	end
end

could this be the Problem?
 

local function fn()
	...
		
	inst:AddComponent("inventory")
	inst.goblinweapon = SpawnPrefab("spear")
	
	if inst.goblinweapon ~= nil then 
		inst.components.inventory:Equip( inst.goblinweapon )
	end
	
	...
	
	return inst
end

can I add a variable which i change to true in the onDeath  function so he don´t equip a new spear after removing the old one ?

Link to comment
Share on other sites

but..the fn() runs when the goblin is being spawned. That code is what makes him have a spear in the first place.

Since the goblin seems to have his weapon directly referenced on his instance, you can also try:

if inst.goblinweapon ~= nil then
	inst.goblinweapon:Remove()
end

But if I were you, I would insert a line in your OnDeath function, to make sure it's even being called.

print("GOBLIN IS DEAD")

Then go kill a goblin, and exit the game. Open all your server and client logs in a text editor, and search for GOBLIN IS DEAD in them.

Link to comment
Share on other sites

This works fine for me 

local function OnDeath(inst, data)
	print("GOBLIN IS DEAD")
	if inst.goblinweapon ~= nil then
	inst.goblinweapon:Remove()
	print("No more weapon")
	end
end

but my loot isn´t working until now:

	local randomloot = inst.components.lootdropper:PickRandomLoot()
	inst.components.lootdropper:AddRandomLoot(randomloot,1)

i know this can not work after i printed randomloot and saw it is nil but is there a different way to generate totally random loot ?

Edited by BlueJelly
Link to comment
Share on other sites

Ah, you DO have a loot table now. I see. Then it's probably fine.

Your error is now in your stategraph. Apparently nothing to do with your loot stuff. You're just trying to access a component that isn't there. Why are you trying to access the goblinweapon's replica? Look, I don't know much about these networking things. They confuse the **** out of me. But one way to test what's going on, would be to print some debug lines.

local function DropAndSwitch(inst)
	if inst.goblinweapon.replica then print("Goblin weapon has a replica") end
	if inst.goblinweapon.replica and inst.goblinweapon.replica.equippable then print("Goblin weapon has a replica equippable") end
	if inst.goblinweapon.equippable then print("Goblin weapon has a non-replica equippable") end
    local goblinweaponslot = inst.goblinweapon.replica.equippable:EquipSlot()
    local inventory = inst.components.inventory
    local currentitem = inventory:GetEquippedItem(goblinweaponslot)
    inventory:DropItem(currentitem)
    inventory:Equip(inst.goblinweapon)
end

Now, I'm not sure about this, but I THINK you need to differentiate between accessing the replica equippable (on clients) and the non-replica equippable (on the server). But I am not sure at all. All I know is, Wilson has separate stategraphs for working on the server and on the client. Maybe you just don't need to have replica in there.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...