Merge branch 'fixes' into main/gingo-test
[ryzomcore.git] / ryzom / common / data_common / r2 / r2_utils.lua
blob0c25ba64c6f6ae75bc61eeeaa687504d02502d7a
1 if r2.Utils == nil
2 then
3 r2.Utils={}
4 end
7 r2.Utils.addReaction = function(this,event,action)
8 local reactions = this.Reactions[event]
9 if reactions == nil
10 then
11 reactions = {}
12 this.Reactions[event]=reactions
13 end
14 table.insert(reactions,action)
15 end
17 ------------------------------------------------------
18 --Create the states and groups to represent:
19 -- -A counter mission
20 -- -The counters used for this mission
21 r2.Utils._obsolete_initCounterStates = function(counter,context)
23 if counter.Class =="Counter"
24 then
26 local pGroup = r2.createPseudoGroup(context)
27 context.RtCounters[counter.InstanceId]=pGroup
29 for k,v in pairs(counter.Counters)
31 Translator.LogicEntityTranslator(v,context)
32 end
33 end
34 end
37 r2.Utils.createGroup = function(x,y,n,base,name,mode)
39 if mode == nil
40 then
41 mode = "circle"
42 end
44 local isGeneric = false
46 if string.find(base, "palette.entities.players.") ~= nil then
47 isGeneric = true
48 end
51 local npcGroup = r2.newComponent("NpcGrpFeature")
52 assert(npcGroup)
53 npcGroup.Name = name
55 if mode == "circle"
56 then
58 local pas = (2 * math.pi)/n
59 local r = (n/(2*math.pi))+2
60 for i=1,n do
61 local npc = nil
62 if ( isGeneric == true) then
63 npc = r2.newComponent("NpcCustom")
64 else
65 npc = r2.newComponent("Npc")
66 end
68 npc.Name = name.."_".."Npc"..i
69 npc.Base = base
70 npc.Position.x = x + (r-1) * math.cos((i-1)*pas)
71 npc.Position.y = y + (r-1) * math.sin((i-1)*pas)
72 npc.Position.z = r2:snapZToGround(npc.Position.x, npc.Position.y)
73 npc.Angle = (i-1)*pas + math.pi
74 table.insert(npcGroup.Components,npc)
75 end
76 end
77 if mode == "line"
78 then
79 local pas = 1
80 for i=1,n do
81 local npc = r2.newComponent("Npc")
82 npc.Name = name.."_".."Npc"..i
83 npc.Base = base
84 npc.Position.x = x + i * pas
85 npc.Position.y = y
86 npc.Position.z = r2:snapZToGround(npc.Position.x, npc.Position.y)
87 npc.Angle = 0
88 table.insert(npcGroup.Components,npc)
89 end
90 end
91 return npcGroup
92 end
94 --region = region to fill
95 --x,y = region's center
96 --r = region's ray
97 --nbPoints = number of points to create the region
98 r2.Utils.createRegion = function(region,x, y, r,nbPoints)
99 region.Points = {}
100 local tmpPositions = region.Points
101 local pas = (2 * math.pi)/nbPoints
102 local Angle = 0
103 while nbPoints ~= 0
105 local tmpVertex = r2.newComponent("RegionVertex")
106 local tmpPosition = r2.newComponent("Position")
107 local sx, sy, sz
108 sx = x + r * math.cos(Angle)
109 sy = y + r * math.sin(Angle)
110 sx, sy, sz = r2:snapPosToGround(sx, sy)
111 tmpPosition.x = sx
112 tmpPosition.y = sy
113 tmpPosition.z = sz
114 tmpVertex.Position = tmpPosition
115 table.insert(tmpPositions, tmpVertex)
116 Angle = Angle + pas
117 nbPoints = nbPoints - 1
121 --region = region to fill
122 --x,y = region's center
123 --r = region's ray
124 --nbPoints = number of points to create the region
125 r2.Utils.createNonDeleteableRegion = function(region,x, y, r,nbPoints)
126 region.Deletable = 0
127 region.Points = {}
128 local tmpPositions = region.Points
129 local pas = (2 * math.pi)/nbPoints
130 local Angle = 0
131 while nbPoints ~= 0
133 local tmpVertex = r2.newComponent("RegionVertex")
134 tmpVertex.Deletable = 0
135 local tmpPosition = r2.newComponent("Position")
136 local sx, sy, sz
137 sx = x + r * math.cos(Angle)
138 sy = y + r * math.sin(Angle)
139 sx, sy, sz = r2:snapPosToGround(sx, sy)
140 tmpPosition.x = sx
141 tmpPosition.y = sy
142 tmpPosition.z = sz
143 tmpVertex.Position = tmpPosition
144 table.insert(tmpPositions, tmpVertex)
145 Angle = Angle + pas
146 nbPoints = nbPoints - 1
150 --region = trigger Zone
151 --x,y = region's center
152 --r = region's ray
153 --nbPoints = number of points to create the region
154 r2.Utils.createTriggerRegion = function(region,x, y, r)
155 return r2.Utils.createNonDeleteableRegion(region, x, y, r, 4)
160 -- Create a Road
161 -- ex local road = createRoad("rout1", { {21570, -1363}, {21570, -1363}, {21570, -1363})
162 r2.Utils.createRoute = function(name, positions)
163 local road = r2.newComponent("Road")
164 local function wp(x, y, z)
165 local wayPoint = r2.newComponent("WayPoint")
166 local pos = r2.newComponent("Position")
167 pos.x = x
168 pos.y = y
169 pos.z = z
170 wayPoint.Position = pos
171 return wayPoint
174 -- road.Base = "palette.geom.road"
175 road.Name = name
176 local tmpPositions = road.Points -- depart a arrivée
178 for index, points in pairs(positions)
180 table.insert(tmpPositions, wp(points[1], points[2], 0))
183 return road
187 --function to set an RtAiState with a npc's behavior
188 r2.Utils.setState = function(context,behavior,rtAiState)
189 local aiMovement = behavior.Type
190 rtAiState.Name = rtAiState.Id .. "|" .. aiMovement
191 rtAiState.AiMovement = aiMovement
192 if (aiMovement == "wander" or aiMovement == "follow_route" or aiMovement == "patrol_route" or aiMovement == "repeat_road") then
193 local id = behavior.ZoneId
194 local zone = context.Components[id]
195 assert( zone ~= nil)
196 local points=zone.Points
197 assert( points ~= nil)
198 local size = table.getn(points)
199 rtAiState.Pts = {}
200 local k,v = next(points, nil)
201 local i = 0
202 while k ~= nil
204 if (k ~= "Keys")
205 then
206 -- replacement for getworldPos
207 assert(v ~= nil)
208 i = i +1
209 rtAiState.Pts[i] = {}
210 -- ??? v.Position.x ??
211 rtAiState.Pts[i].x = r2.getWorldPos(v).x
212 rtAiState.Pts[i].y = r2.getWorldPos(v).y
213 rtAiState.Pts[i].z = r2.getWorldPos(v).z
215 k,v = next(points, k)
217 -- do reverse
218 if (aiMovement == "patrol_route") then
219 i = 0
220 for i = 1, size -1 , 1
222 local first = size - i
223 local last = size + i
225 rtAiState.Pts[last] = {}
226 rtAiState.Pts[last].x = rtAiState.Pts[first].x
227 rtAiState.Pts[last].y = rtAiState.Pts[first].y
228 rtAiState.Pts[last].z = rtAiState.Pts[first].z
230 end
231 if (aiMovement == "patrol_route" or aiMovement == "repeat_road") then
232 rtAiState.AiMovement = "follow_route"
233 local eventHandler = Actions.createEvent("destination_reached", rtAiState.Id ,"")
234 assert( eventHandler ~= nil)
235 local eName = rtAiState.Id .. ":destination_reached"
236 eventHandler.Name=eName
237 table.insert(context.RtAct.Events,eventHandler)
239 local action = Actions.createAction("begin_state", rtAiState.Id)
240 action.Name="begin state " .. rtAiState.Id
241 table.insert(context.RtAct.Actions,action)
242 table.insert(eventHandler.ActionsId,action.Id)
248 r2.Utils.invertRoad = function(road)
249 local road2 = r2.newComponent("Road")
250 local function wp(x, y, z)
251 local wayPoint = r2.newComponent("WayPoint")
252 local pos = r2.newComponent("Position")
253 pos.x = x
254 pos.y = y
255 pos.z = z
256 wayPoint.Position = pos
257 return wayPoint
259 local max = table.getn(road.Points)
261 for i=1,max do
262 local point = road.Points[max-i+1].Position
263 table.insert(road2.Points,wp(point.x,point.y,point.z))
265 return road2
269 r2.Utils.createEntry = function(who,states,event,actions)
270 local entry = r2.newComponent("EventHandlerEntry")
271 entry.Who = who
272 entry.States = states
273 entry.Event = event
274 entry.Actions = actions
275 return entry
278 r2.Utils.createPlace = function(x,y,z,r)
279 local place = r2.newComponent("Place")
280 place.Position.x=x
281 place.Position.y=y
282 place.Position.z=z
283 place.Radius = r
284 return place
287 r2.Utils.searchEntry = function(activity,who,event,state)
288 local max = table.getn(activity.Entries)
289 for i=1, max do
290 local entry = activity.Entries[i]
291 if entry.Who==who and entry.Event == event and (entry.States == state or state=="")
292 then
293 return entry
296 return nil
299 r2.Utils.groupActivities = function(activity1,activity2,event1,state1,event2,state2)
300 local entry
301 entry = r2.Utils.searchEntry(activity1,activity1.Entries[1].Who,event1,state1)
303 if entry == nil
304 then
305 entry = r2.Utils.createEntry(activity1.Entries[1].Who,state1,event1,"begin_state\n"..state2)
306 table.insert(activity1.Entries,entry)
307 else
308 entry.Actions = entry.Actions .. "\nbegin_state\n"..state2
311 entry = r2.Utils.searchEntry(activity2,activity2.Entries[1].Who,event2,state2)
312 if entry == nil
313 then
314 entry = r2.Utils.createEntry(activity2.Entries[1].Who,state2,event2,"begin_state\n"..state1)
315 table.insert(activity2.Entries,entry)
316 else
317 entry.Actions = entry.Actions .. "\nbegin_state\n"..state
321 r2.Utils.evalCost = function(feature)
322 --luaObject(feature)
323 local components = feature.Components
324 --luaObject(components)
325 local cost = 0
326 if components ~= nil
327 then
328 for key,comp in pairs(components)
330 if key~="Keys" and comp.Class == "Npc"
331 then
332 cost = cost + 1
336 return cost
339 r2.Utils.createChatAction = function(who,says,emote,face)
340 local chatStep
342 chatStep = r2.newComponent("ChatAction")
343 chatStep.Who = who
345 if says ~= ""
346 then
347 local entry=r2.registerText(says)
348 chatStep.Says = entry.InstanceId
349 else
350 chatStep.Says = says
353 if face ~="" and face ~=nil
354 then
355 chatStep.Facing = face
358 chatStep.Emote = emote
359 return chatStep
364 --replace each instanceId in the table by the new one
365 r2.Utils.replaceTab = function(this,ttable)
366 for k,v in pairs(this)
368 if k ~="Keys"
369 then
370 this[k]=ttable[this[k]]
374 --call the replace function for each object in the table
375 r2.Utils.callReplace = function(this,ttable)
376 for k,v in pairs(this)
378 if k ~="Keys"
379 then
380 v:replace(ttable)
386 r2.Utils.changeRepere = function(position,center)
387 position.x=position.x - center.x
388 position.y=position.y - center.y
389 position.z = r2:snapZToGround(position.x,position.y)
392 r2.Utils.changeZoneRepere = function(zone,center)
393 for i=1,table.getn(zone.Points)
395 r2.Utils.changeRepere(zone.Points[i])
399 r2.Utils.changeRepereRt = function(npc,center)
400 local x,y
401 local position = npc.Position
402 x = position.x - center.x
403 y = position.y - center.y
404 r2.requestSetNode(position.InstanceId,"x",x)
405 r2.requestSetNode(position.InstanceId,"y",y)
406 r2.requestSetNode(position.InstanceId,"z",r2:snapZToGround(x,y))
409 r2.Utils.setNewGroupCenter = function(group,x,y)
410 local k,v = next(group.Components,nil)
411 local center = r2.newComponent("Position")
412 local first = true
413 center.x = x
414 center.y = y
416 while k~=nil
418 if first == true
419 then
420 first = false
421 local newCenter = {}
422 newCenter.x = -(center.x - v.Position.x)
423 newCenter.y = -(center.y - v.Position.y)
424 center.z = r2:snapZToGround(center.x,center.y)
425 r2.requestSetNode(v.Position.InstanceId,"x",center.x)
426 r2.requestSetNode(v.Position.InstanceId,"y",center.y)
427 r2.requestSetNode(v.Position.InstanceId,"z",r2:snapZToGround(center.x,center.y))
428 center = newCenter
429 else
430 r2.Utils.changeRepereRt(v,center)
432 k,v = next(group.Components,k)
437 -- Obsolete
438 r2.Utils.getRtGroup = function(context,instanceId)
439 debugInfo("Call obsolete function: call r2.Translator.getRtGroup")
440 -- use r2.Translator.getRtGroup instead
441 return r2.Translator.getRtGroup(context, instanceId)
444 r2.Utils.concat = function(text,textSup)
445 if text == ""
446 then
447 return textSup
448 else
449 return text.."\n"..textSup
454 -----------------------------------------------------------
455 --return a string like: "group1:Npc1" for use with actions
456 r2.Utils.getNpcParam = function(npcId, context)
458 assert( type(npcId) == "string")
459 local who = r2:getInstanceFromId(tostring(npcId))
460 -- local group = who:getParentGroup()
461 local rtNpcGrp = context.RtGroups[tostring(npcId)]
462 if rtNpcGrp == nil
463 then
464 debugInfo("Err: unable to know the npc's group name ("..npcId..")")
465 return nil
468 return rtNpcGrp.Name..":"..tostring(who.Name)
473 -- Returns the RtNpcGrp Id for a given instanceId
475 r2.Utils.getRtIdFromInstanceId = function(context, instanceId)
476 assert(instanceId ~= nil and type(instanceId) == "string")
477 local instance = r2:getInstanceFromId(instanceId)
478 assert(instance)
479 return context.RtGroups[instanceId].Id
483 -- vianney tests
484 function r2.testVianney1()
485 r2.requestStartAct(1)
488 function r2.testVianney2()
489 r2.requestStartAct(2)
492 function r2.testVianney3()
493 r2.requestStopAct()
496 function r2:lowerTranslate(uiR2EdStr)
497 return string.lower(i18n.get(uiR2EdStr):toUtf8())