forked from Benjamin-Dobell/ge_tts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHandZone.ttslua
153 lines (125 loc) · 6.2 KB
/
HandZone.ttslua
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
local ObjectUtils = require('ge_tts.ObjectUtils')
local TableUtils = require('ge_tts.TableUtils')
local Zone = require('ge_tts.Zone')
---@class ge_tts__HandZone : ge_tts__Zone
---@shape ge_tts__HandZone_SavedState : ge_tts__Zone_SavedState
---@field ownerColor tts__PlayerHandColor
---@field handIndex number
---@param owner tts__Player
---@param handIndex number
---@return tts__Vector, tts__Vector, tts__Vector
local function zoneParameters(owner, handIndex)
local handTransform = owner.getHandTransform(handIndex)
return handTransform.position, handTransform.rotation, handTransform.scale
end
---@class ge_tts__static_HandZone : ge_tts__static_Zone
---@overload fun(owner: tts__Player): ge_tts__HandZone
---@overload fun(owner: tts__Player, handIndex: nil | number): ge_tts__HandZone
---@overload fun(savedState: ge_tts__HandZone_SavedState): ge_tts__HandZone
---@overload fun(ownerOrSavedState: tts__Player | ge_tts__HandZone_SavedState, nilOrHandIndex: nil | number): ge_tts__HandZone
local HandZone = {}
HandZone.TYPE = 'HandZone'
setmetatable(HandZone, TableUtils.merge(getmetatable(Zone), {
---@param ownerOrSavedState tts__Player | ge_tts__HandZone_SavedState
---@param nilOrHandIndex nil | number @TTS player hand index, defaults to 1.
__call = function(_, ownerOrSavedState, nilOrHandIndex)
local isSavedState = HandZone.isSavedState(ownerOrSavedState)
local self = --[[---@type ge_tts__HandZone]] (
isSavedState and Zone(--[[---@type ge_tts__HandZone_SavedState]] ownerOrSavedState)
or Zone(zoneParameters(--[[---@type tts__Player]] ownerOrSavedState, --[[---@not nil]] nilOrHandIndex))
)
---@type tts__Player
local owner
---@type number
local handIndex
---@return tts__Player
function self.getOwner()
return owner
end
---@return number
function self.getHandIndex()
return handIndex
end
function self.getType()
return HandZone.TYPE
end
local superOnEnter = self.onEnter
--- Called when a TTS object enters this HandZone.
---@param object tts__Object
function self.onEnter(object)
superOnEnter(object)
if not self.isObjectOccupying(object) and TableUtils.find(owner.getHandObjects(handIndex), object) then
self.onDrop(owner.color, object)
end
end
--- Called when a player attempts to drop an object within this zone. The return value
--- indicates whether the zone wishes to accept, reject or ignore the object being dropped.
---@param colorName tts__PlayerColor @Color of the TTS player that dropped the TTS object.
---@param object tts__Object
---@return ge_tts__Zone_FilterResult
function self.filterObject(colorName, object)
return object.use_hands and HandZone.FilterResult.ACCEPT or HandZone.FilterResult.IGNORE
end
local superDrop = self.drop
--- Can be called to dynamically drop (deal) a TTS object into this HandZone. Works for containers or objects with `use_hands` enabled.
---@param colorName string @Color of the TTS player that should be deemed responsible for having dropped the TTS object.
---@param object tts__Object @The object that will be dropped.
function self.drop(colorName, object)
local isContainer = ObjectUtils.isContainerTag(object.tag)
self.deal(colorName, object, isContainer and object.getQuantity() or 1)
end
--- Same as onDrop except that we provide a count which is the maximum number of objects dealt from a container.
---@param colorName string @Color of the TTS player that should be deemed responsible for having dropped the TTS object.
---@param object tts__Object @The object that will be dropped.
function self.deal(colorName, object, count)
local isContainer = ObjectUtils.isContainerTag(object.tag)
if isContainer then
-- The deal API doesn't do what we want, so we need to do our best to mimic it with takeObject
local quantity = math.min(count, object.getQuantity())
for _ = 1, quantity do
local takenObject = object.takeObject({
callback_function = function(spawnedObject)
if self.isObjectOccupying(spawnedObject) then
spawnedObject.use_hands = true
spawnedObject.deal(1, --[[---@type tts__PlayerHandColor]] owner.color, handIndex)
end
end,
})
superDrop(colorName, --[[---@not nil]] takenObject)
end
else
if object.spawning then
-- Unlike setPositionSmooth, deal does not work on objects that are in the process of spawning.
Wait.condition(function()
if self.isObjectOccupying(object) then
object.use_hands = true
object.deal(1, --[[---@type tts__PlayerHandColor]] owner.color, handIndex)
end
end, function() return object ~= nil and not object.spawning end)
else
object.deal(1, --[[---@type tts__PlayerHandColor]] owner.color, handIndex)
end
superDrop(colorName, object)
end
end
local superSave = self.save
---@return ge_tts__HandZone_SavedState
function self.save()
return --[[---@type ge_tts__HandZone_SavedState]] TableUtils.merge(superSave(), {
ownerColor = owner.color,
handIndex = handIndex,
})
end
if isSavedState then
local data = --[[---@type ge_tts__HandZone_SavedState]] ownerOrSavedState
owner = Player[data.ownerColor]
handIndex = data.handIndex
else
owner = --[[---@type tts__Player]] ownerOrSavedState
handIndex = nilOrHandIndex or 1
end
return self
end,
__index = Zone,
}))
return HandZone