aboutsummaryrefslogtreecommitdiff
path: root/tutorials/tut050_entities.md
blob: f223228269ccbb0ac0ebc2f998f929ca929abab5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# Tut 0x050

## Entities

Usually in addons, you have a dedicated folder for entities, however, that's not the only way to create entities. The canonical way to create entities in artery is to use the ![img](http://wiki.garrysmod.com/favicon.ico)[scripted\_ents.Register](http://wiki.garrysmod.com/page/scripted_ents/Register) function. This allows you to register entities after the gamemode has loaded. If your entities don't derive from artery entities, you can still use the usual entity system by placeing a init.lua, cl\_init.lua, and shared.lua in garrysmod/addons/artery\_rougelite/lua/entities.

Let's make some entities that are commonly found in rougelikes. We'll make:

* Fountain - When you go up to and press E on it, you can drink from it.
* Alter - When you go up to and press E on it, it will remove the "cursed" status that we implemented in @{tut042_too_many_items.md}.
* Chest - When you go up to it and press E, it will display an inventory you can put items into. We'll use this later on.

### Fountain

This one is easy enough. Just make an entity that spawns with a model, and accepts a "Use" input.

garrysmod/addons/artery\_rougelite/data/global/entity\_fountain.txt

	local ENT = scripted_ents.Get("prop_dynamic")
	
	function ENT:Initalize()
		self:SetModel("models/props_c17/fountain_01.mdl")
	end
	
	function ENT:Use()
		print("Mmm... Refreshing!")
	end
	
	scripted_ents.Register(ENT, "artery_fountain")

### Alter

Use mostly the same approach. You can skip this entity if you never went through  @{tut042_too_many_items.md}
garrysmod/addons/artery\_rogelite/data/global/entity\_alter.txt

	local ENT = scripted_ents.Get("prop_dynamic")

	function ENT:Initalize()
		self:SetModel("models/props_junk/wood_crate002a.mdl")
	end

	function ENT:Use(ply)
		--Get all the items the player has that are cursed
		local iscursed = function(item)
			if item.attribute == -1 then -- Item is cursed
				return true
			end
		end
		local to_uncurse_pos = ply:HasItem(iscursed)
		while(to_uncurse_pos) do --Will be nil if we don't have any cursed items
			local item = ply:RemoveItem(to_uncurse_pos)
			item.attribute = nil
			ply:GiveItem(item)
		end
	end
	
	scripted_ents.Register(ENT, "artery_fountain")

It may have been tempting here to just set the item's .attribute in our iscursed() function, since it will be the first place we detect a cursed item. **HOWEVER!** There are a lot of places in Artery that this kind of thing can BREAK other addons. Generally speaking, try not to modify items while they're in an inventory. Remove them, modify them, then add them back.

### Chest

This one is pretty easy, it's really only here to show you how to extend the entities that are already in Artery.

	local ENT = scripted_ents.Get("prop_dynamic")

	DEFINE_BASECLASS("art_chest") -- this defines a local variable called BaseClass

	function ENT:Initalize()
		self:SetModel("models/props_junk/wood_crate002a.mdl")
	end

	function ENT:Use(ply)
		--Get all the items the player has that are cursed
		local iscursed = function(item)
			if item.attribute == -1 then -- Item is cursed
				return true
			end
		end
		local to_uncurse_pos = ply:HasItem(iscursed)
		while(to_uncurse_pos) do --Will be nil if we don't have any cursed items
			local item = ply:RemoveItem(to_uncurse_pos)
			item.attribute = nil
			ply:GiveItem(item)
		end
	end

	scripted_ents.Register(ENT, "artery_fountain")