1use theframework::prelude::*;
2
3#[derive(Clone, PartialEq, Debug)]
5pub enum AssignmentOp {
6 Assign,
7 AddAssign,
8 SubtractAssign,
9 MultiplyAssign,
10 DivideAssign,
11}
12
13impl AssignmentOp {
14 pub fn describe(&self) -> &str {
15 match self {
16 AssignmentOp::Assign => "=",
17 AssignmentOp::AddAssign => "+=",
18 AssignmentOp::SubtractAssign => "-=",
19 AssignmentOp::MultiplyAssign => "*=",
20 AssignmentOp::DivideAssign => "/=",
21 }
22 }
23
24 pub fn to_index(&self) -> i32 {
25 match self {
26 AssignmentOp::Assign => 0,
27 AssignmentOp::AddAssign => 1,
28 AssignmentOp::SubtractAssign => 2,
29 AssignmentOp::MultiplyAssign => 3,
30 AssignmentOp::DivideAssign => 4,
31 }
32 }
33
34 pub fn from_index(idx: i32) -> Option<Self> {
35 match idx {
36 0 => Some(AssignmentOp::Assign),
37 1 => Some(AssignmentOp::AddAssign),
38 2 => Some(AssignmentOp::SubtractAssign),
39 3 => Some(AssignmentOp::MultiplyAssign),
40 4 => Some(AssignmentOp::DivideAssign),
41 _ => None,
42 }
43 }
44}
45
46#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
47pub enum ArithmeticOp {
48 Add,
49 Subtract,
50 Multiply,
51 Divide,
52}
53
54impl ArithmeticOp {
55 pub fn from_index(idx: usize) -> Option<Self> {
56 match idx {
57 0 => Some(ArithmeticOp::Add),
58 1 => Some(ArithmeticOp::Subtract),
59 2 => Some(ArithmeticOp::Multiply),
60 3 => Some(ArithmeticOp::Divide),
61 _ => None,
62 }
63 }
64
65 pub fn to_index(&self) -> usize {
66 match self {
67 ArithmeticOp::Add => 0,
68 ArithmeticOp::Subtract => 1,
69 ArithmeticOp::Multiply => 2,
70 ArithmeticOp::Divide => 3,
71 }
72 }
73
74 pub fn to_string(&self) -> &'static str {
75 match self {
76 ArithmeticOp::Add => "+",
77 ArithmeticOp::Subtract => "-",
78 ArithmeticOp::Multiply => "*",
79 ArithmeticOp::Divide => "/",
80 }
81 }
82}
83
84#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
85pub enum ComparisonOp {
86 Equal,
87 NotEqual,
88 LessEqual,
89 GreaterEqual,
90 Less,
91 Greater,
92}
93impl ComparisonOp {
94 pub fn from_index(idx: usize) -> Option<Self> {
95 match idx {
96 0 => Some(ComparisonOp::Equal),
97 1 => Some(ComparisonOp::NotEqual),
98 2 => Some(ComparisonOp::LessEqual),
99 3 => Some(ComparisonOp::GreaterEqual),
100 4 => Some(ComparisonOp::Less),
101 5 => Some(ComparisonOp::Greater),
102 _ => None,
103 }
104 }
105
106 pub fn to_index(&self) -> usize {
107 match self {
108 ComparisonOp::Equal => 0,
109 ComparisonOp::NotEqual => 1,
110 ComparisonOp::LessEqual => 2,
111 ComparisonOp::GreaterEqual => 3,
112 ComparisonOp::Less => 4,
113 ComparisonOp::Greater => 5,
114 }
115 }
116 pub fn to_string(&self) -> &'static str {
117 match self {
118 ComparisonOp::Equal => "==",
119 ComparisonOp::NotEqual => "!=",
120 ComparisonOp::LessEqual => "<=",
121 ComparisonOp::GreaterEqual => ">=",
122 ComparisonOp::Less => "<",
123 ComparisonOp::Greater => ">",
124 }
125 }
126}
127
128#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
129pub enum Cell {
130 ConstructAssignBlock,
131 ConstructColorAssignBlock,
132 ConstructIfBlock,
133
134 Empty,
135 Variable(String),
136 Integer(String),
137 Float(String),
138 Str(String),
139 Boolean(bool),
140 Assignment,
141 Comparison(ComparisonOp),
142 Arithmetic(ArithmeticOp),
143 If,
144 Else,
145 PaletteColor(u8),
146 Value(String),
147
148 Action,
150 AddItem,
151 BlockEvents,
152 CastSpell,
153 ClearAudio,
154 ClearTarget,
155 CloseIn,
156 DealDamage,
157 Drop,
158 DropItems,
159 EntitiesInRadius,
160 Equip,
161 GetAttr,
162 GetAttrOf,
163 GetEntityAttr,
164 Goto,
165 Id,
166 Intent,
167 InventoryItems,
168 InventoryItemsOf,
169 Message,
170 Say,
171 NotifyIn,
172 OfferInventory,
173 Patrol,
174 PlayAudio,
175 Random,
176 RandomWalk,
177 RandomWalkInSector,
178 SetAttr,
179 SetAudioBusVolume,
180 SetEmitLight,
181 SetPlayerCamera,
182 SetProximityTracking,
183 SetTarget,
184 SetTile,
185 Take,
186 Target,
187 HasTarget,
188 Teleport,
189 ToggleAttr,
190 TookDamage,
191
192 Abs,
194 Atan,
195 Atan2,
196 Ceil,
197 Clamp,
198 Cos,
199 Cross,
200 Degrees,
201 Dot,
202 Exp,
203 Floor,
204 Fract,
205 Length,
206 Log,
207 Max,
208 Min,
209 Mix,
210 Mod,
211 Normalize,
212 Pow,
213 Radians,
214 Rand,
215 Rotate2d,
216 Sign,
217 Sin,
218 Smoothstep,
219 Sample,
220 SampleNormal,
221 Textures(String),
222 Sqrt,
223 Step,
224 Tan,
225
226 LeftParent,
227 RightParent,
228}
229
230#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
231pub enum CellRole {
232 None,
233 Operator,
234 Value,
235 Function,
236 Event,
237}
238
239impl CellRole {
240 pub fn to_color(&self) -> [u8; 4] {
241 match self {
242 CellRole::None => [180, 180, 180, 255],
243 CellRole::Operator => [200, 195, 150, 255],
244 CellRole::Value => [160, 185, 160, 255],
245 CellRole::Function => [160, 175, 190, 255],
246 CellRole::Event => [195, 170, 150, 255],
247 }
248 }
249}
250
251use Cell::*;
252
253impl Cell {
254 pub fn description(&self) -> &'static str {
255 match self {
256 Cell::ConstructAssignBlock => "Var = ..",
257 Cell::ConstructColorAssignBlock => "Color = ..",
258 Cell::ConstructIfBlock => "If .. == ..",
259
260 Cell::Empty => "Empty",
261 Cell::Variable(_) => "Variable",
262 Cell::Integer(_) => "Integer",
263 Cell::Float(_) => "Float",
264 Cell::Str(_) => "String",
265 Cell::Boolean(_) => "Boolean",
266 Cell::Assignment => "Assignment",
267 Cell::Comparison(_) => "Comparison",
268 Cell::Arithmetic(_) => "Arithmetic",
269 Cell::If => "If",
270 Cell::Else => "Else",
271 Cell::PaletteColor(_) => "Palette Color",
272 Cell::Value(_) => "Value",
273
274 Cell::Action => "Action",
275 Cell::AddItem => "Add Item",
276 Cell::BlockEvents => "Block Events",
277 Cell::CastSpell => "Cast Spell",
278 Cell::ClearAudio => "Clear Audio",
279 Cell::ClearTarget => "Clear Target",
280 Cell::CloseIn => "Close In",
281 Cell::DealDamage => "Deal Damage",
282 Cell::Drop => "Drop",
283 Cell::DropItems => "Drop Items",
284 Cell::EntitiesInRadius => "Entities in Radius",
285 Cell::Equip => "Equip",
286 Cell::GetAttr => "Get Attribute",
287 Cell::GetAttrOf => "Get Attribute Of",
288 Cell::GetEntityAttr => "Get Attribute Of",
289 Cell::Goto => "Goto",
290 Cell::Id => "Id",
291 Cell::Intent => "Intent",
292 Cell::InventoryItems => "Inventory Items",
293 Cell::InventoryItemsOf => "Inventory Items Of",
294 Cell::Message => "Message",
295 Cell::Say => "Say",
296 Cell::NotifyIn => "Notify In",
297 Cell::OfferInventory => "Offer Inventory",
298 Cell::Patrol => "Patrol",
299 Cell::PlayAudio => "Play Audio",
300 Cell::Random => "Random Number",
301 Cell::RandomWalk => "Random Walk",
302 Cell::RandomWalkInSector => "Random Walk In Sector",
303 Cell::SetAttr => "Set Attribute",
304 Cell::SetAudioBusVolume => "Set Audio Bus Volume",
305 Cell::SetEmitLight => "Set Emit Light",
306 Cell::SetPlayerCamera => "Set Player Camera",
307 Cell::SetProximityTracking => "Set Proximity Tracking",
308 Cell::SetTarget => "Set Target",
309 Cell::SetTile => "Set Tile",
310 Cell::Take => "Take",
311 Cell::Target => "Target",
312 Cell::HasTarget => "Has Target",
313 Cell::Teleport => "Teleport",
314 Cell::ToggleAttr => "Toggle Attr",
315 Cell::TookDamage => "Took Damage",
316
317 Cell::Abs => "Abs",
318 Cell::Atan => "Atan",
319 Cell::Atan2 => "Atan2",
320 Cell::Ceil => "Ceil",
321 Cell::Clamp => "Clamp",
322 Cell::Cos => "Cos",
323 Cell::Cross => "Cross",
324 Cell::Degrees => "Degrees",
325 Cell::Dot => "Dot",
326 Cell::Exp => "Exp",
327 Cell::Floor => "Floor",
328 Cell::Fract => "Fract",
329 Cell::Length => "Length",
330 Cell::Log => "Log",
331 Cell::Max => "Max",
332 Cell::Min => "Min",
333 Cell::Mix => "Mix",
334 Cell::Mod => "Mod",
335 Cell::Normalize => "Normalize",
336 Cell::Pow => "Pow",
337 Cell::Radians => "Radians",
338 Cell::Rand => "Rand",
339 Cell::Rotate2d => "Rotate2d",
340 Cell::Sign => "Sign",
341 Cell::Sin => "Sin",
342 Cell::Smoothstep => "Smoothstep",
343 Cell::Sample => "Sample",
344 Cell::SampleNormal => "Sample Normal",
345 Cell::Textures(_) => "Texture",
346 Cell::Sqrt => "Sqrt",
347 Cell::Step => "Step",
348 Cell::Tan => "Tan",
349
350 Cell::LeftParent => "Left Parenthesis",
351 Cell::RightParent => "Right Parenthesis",
352 }
353 }
354 pub fn from_str(s: &str) -> Option<Self> {
355 match s {
356 "Var = .." => Some(Cell::ConstructAssignBlock),
357 "Color = .." => Some(Cell::ConstructColorAssignBlock),
358 "If .. == .." => Some(Cell::ConstructIfBlock),
359
360 "Empty" => Some(Cell::Empty),
361 "Variable" => Some(Cell::Variable("Unnamed".into())),
362 "Integer" => Some(Cell::Integer("0".into())),
363 "Float" => Some(Cell::Float("0.0".into())),
364 "String" => Some(Cell::Str("".into())),
365 "Boolean" => Some(Cell::Boolean(true)),
366 "Assignment" => Some(Cell::Assignment),
367 "Comparison" => Some(Cell::Comparison(ComparisonOp::Equal)),
368 "Arithmetic" => Some(Cell::Arithmetic(ArithmeticOp::Add)),
369 "If" => Some(Cell::If),
370 "Else" => Some(Cell::Else),
371 "Palette Color" => Some(Cell::PaletteColor(0)),
372 "Value" => Some(Cell::Value("1".to_string())),
373
374 "action" => Some(Cell::Action),
375 "add_item" => Some(Cell::AddItem),
376 "block_events" => Some(Cell::BlockEvents),
377 "cast_spell" => Some(Cell::CastSpell),
378 "clear_audio" => Some(Cell::ClearAudio),
379 "clear_target" => Some(Cell::ClearTarget),
380 "close_in" => Some(Cell::CloseIn),
381 "deal_damage" => Some(Cell::DealDamage),
382 "drop" => Some(Cell::Drop),
383 "drop_items" => Some(Cell::DropItems),
384 "entities_in_radius" => Some(Cell::EntitiesInRadius),
385 "equip" => Some(Cell::Equip),
386 "get_attr" => Some(Cell::GetAttr),
387 "get_attr_of" => Some(Cell::GetAttrOf),
388 "goto" => Some(Cell::Goto),
389 "id" => Some(Cell::Id),
390 "intent" => Some(Cell::Intent),
391 "inventory_items" => Some(Cell::InventoryItems),
392 "inventory_items_of" => Some(Cell::InventoryItemsOf),
393 "message" => Some(Cell::Message),
394 "say" => Some(Cell::Say),
395 "notify_in" => Some(Cell::NotifyIn),
396 "offer_inventory" => Some(Cell::OfferInventory),
397 "patrol" => Some(Cell::Patrol),
398 "play_audio" => Some(Cell::PlayAudio),
399 "random" => Some(Cell::Random),
400 "random_walk" => Some(Cell::RandomWalk),
401 "random_walk_in_sector" => Some(Cell::RandomWalkInSector),
402 "set_attr" => Some(Cell::SetAttr),
403 "set_audio_bus_volume" => Some(Cell::SetAudioBusVolume),
404 "set_emit_light" => Some(Cell::SetEmitLight),
405 "set_player_camera" => Some(Cell::SetPlayerCamera),
406 "set_proximity_tracking" => Some(Cell::SetProximityTracking),
407 "set_target" => Some(Cell::SetTarget),
408 "set_tile" => Some(Cell::SetTile),
409 "take" => Some(Cell::Take),
410 "target" => Some(Cell::Target),
411 "has_target" => Some(Cell::HasTarget),
412 "teleport" => Some(Cell::Teleport),
413 "toggle_attr" => Some(Cell::ToggleAttr),
414 "took_damage" => Some(Cell::TookDamage),
415
416 "abs" => Some(Cell::Abs),
417 "atan" => Some(Cell::Atan),
418 "atan2" => Some(Cell::Atan2),
419 "ceil" => Some(Cell::Ceil),
420 "clamp" => Some(Cell::Clamp),
421 "cos" => Some(Cell::Cos),
422 "cross" => Some(Cell::Cross),
423 "degrees" => Some(Cell::Degrees),
424 "dot" => Some(Cell::Dot),
425 "exp" => Some(Cell::Exp),
426 "floor" => Some(Cell::Floor),
427 "fract" => Some(Cell::Fract),
428 "length" => Some(Cell::Length),
429 "log" => Some(Cell::Log),
430 "max" => Some(Cell::Max),
431 "min" => Some(Cell::Min),
432 "mix" => Some(Cell::Mix),
433 "mod" => Some(Cell::Mod),
434 "normalize" => Some(Cell::Normalize),
435 "pow" => Some(Cell::Pow),
436 "radians" => Some(Cell::Radians),
437 "rand" => Some(Cell::Rand),
438 "rotate2d" => Some(Cell::Rotate2d),
439 "sample" => Some(Cell::Sample),
440 "sample_normal" => Some(Cell::SampleNormal),
441 "textures" => Some(Cell::Textures("value".into())),
442 "sign" => Some(Cell::Sign),
443 "sin" => Some(Cell::Sin),
444 "smoothstep" => Some(Cell::Smoothstep),
445 "sqrt" => Some(Cell::Sqrt),
446 "step" => Some(Cell::Step),
447 "tan" => Some(Cell::Tan),
448
449 _ => None,
450 }
451 }
452
453 pub fn to_string(&self) -> String {
454 match &self {
455 Variable(var_name) => {
456 if var_name == "myself" {
457 "id()".to_string()
458 } else {
459 var_name.clone()
460 }
461 }
462 Integer(value) | Float(value) => value.clone(),
463 Boolean(value) => {
464 if *value {
465 "true".into()
466 } else {
467 "false".into()
468 }
469 }
470 Str(value) => {
471 if value.contains("\"") {
472 value.clone()
473 } else {
474 format!("\"{}\"", value)
475 }
476 }
477 PaletteColor(idx) => {
478 format!("palette({})", idx)
479 }
480 Value(value) => value.clone(),
481
482 Assignment => "=".into(),
483 Comparison(op) => op.to_string().to_string(),
484 Arithmetic(op) => op.to_string().to_string(),
485 If => "if".into(),
486 Else => "else".into(),
487
488 Action => "action".into(),
489 AddItem => "add_item".into(),
490 BlockEvents => "block_events".into(),
491 CastSpell => "cast_spell".into(),
492 ClearAudio => "clear_audio".into(),
493 ClearTarget => "clear_target".into(),
494 CloseIn => "close_in".into(),
495 DealDamage => "deal_damage".into(),
496 Drop => "drop".into(),
497 DropItems => "drop_items".into(),
498 EntitiesInRadius => "entities_in_radius".into(),
499 Equip => "equip".into(),
500 GetAttr => "get_attr".into(),
501 GetAttrOf => "get_attr_of".into(),
502 Goto => "goto".into(),
503 Id => "id".into(),
504 Intent => "intent".into(),
505 InventoryItems => "inventory_items".into(),
506 InventoryItemsOf => "inventory_items_of".into(),
507 Message => "message".into(),
508 Say => "say".into(),
509 NotifyIn => "notify_in".into(),
510 OfferInventory => "offer_inventory".into(),
511 Patrol => "patrol".into(),
512 PlayAudio => "play_audio".into(),
513 Random => "random".into(),
514 RandomWalk => "random_walk".into(),
515 RandomWalkInSector => "random_walk_in_sector".into(),
516 SetAttr => "set_attr".into(),
517 SetAudioBusVolume => "set_audio_bus_volume".into(),
518 SetEmitLight => "set_emit_light".into(),
519 SetPlayerCamera => "set_player_camera".into(),
520 SetProximityTracking => "set_proximity_tracking".into(),
521 SetTarget => "set_target".into(),
522 SetTile => "set_tile".into(),
523 Take => "take".into(),
524 Target => "target".into(),
525 HasTarget => "has_target".into(),
526 Teleport => "teleport".into(),
527 ToggleAttr => "toggle_attr".into(),
528 TookDamage => "took_damage".into(),
529
530 Abs => "abs".into(),
531 Atan => "atan".into(),
532 Atan2 => "atan2".into(),
533 Ceil => "ceil".into(),
534 Clamp => "clamp".into(),
535 Cos => "cos".into(),
536 Cross => "cross".into(),
537 Degrees => "degrees".into(),
538 Dot => "dot".into(),
539 Exp => "exp".into(),
540 Floor => "floor".into(),
541 Fract => "fract".into(),
542 Length => "length".into(),
543 Log => "log".into(),
544 Max => "max".into(),
545 Min => "min".into(),
546 Mix => "mix".into(),
547 Mod => "mod".into(),
548 Normalize => "normalize".into(),
549 Pow => "pow".into(),
550 Radians => "radians".into(),
551 Rand => "rand".into(),
552 Rotate2d => "rotate2d".into(),
553 Sample => "sample".into(),
554 SampleNormal => "sample_normal".into(),
555 Textures(name) => format!("\"{}\"", name),
556 Sign => "sign".into(),
557 Sin => "sin".into(),
558 Smoothstep => "smoothstep".into(),
559 Sqrt => "sqrt".into(),
560 Step => "step".into(),
561 Tan => "tan".into(),
562
563 LeftParent => "(".into(),
564 RightParent => ")".into(),
565 _ => "".into(),
566 }
567 }
568
569 pub fn status(&self) -> String {
570 match &self {
571 Action => "Player based action.".into(),
572 AddItem => "Add an item to the inventory of the current entity.".into(),
573 BlockEvents => "Block specific events for a period of in-game minutes for the current entity or item.".into(),
574 CastSpell => "Cast a spell template towards a target entity or position: cast_spell(template, target[, success_pct]).".into(),
575 ClearAudio => "Stop currently playing audio on a bus, or all buses if omitted.".into(),
576 ClearTarget => "Clear current target for the current entity or item.".into(),
577 CloseIn => "Close in to the target entities within the given radius and speed.".into(),
578 DealDamage => "Deal damage. Use deal_damage(amount) for current target, or deal_damage(target, amount).".into(),
579 Drop => "Drop the item of the given ID for the current entity.".into(),
580 DropItems => "Drop all or filtered items for the current entity.".into(),
581 EntitiesInRadius => {
582 "Returns a list of entity IDs in the radius of the current entity or item.".into()
583 }
584 GetAttr => "Get an attribute of the current entity or item.".into(),
585 GetAttrOf => "Get an attribute of the given entity or item.".into(),
586 Goto => "Go to a sector using pathfinding.".into(),
587 Id => "Returns the ID of the current entity or item.".into(),
588 Intent=> "Player intent. Only applicable during for user events.".into(),
589 InventoryItems => {
590 "Returns a list of item IDs of the inventory of the current entity.".into()
591 }
592 InventoryItemsOf => "Returns a list of item IDs of the item with the given ID.".into(),
593 Message => "Send a message to an entity.".into(),
594 Say => "Display speech above an entity in the game view (optional category).".into(),
595 NotifyIn => "Send the given event after the given amount of in-game minutes.".into(),
596 OfferInventory => "Offer the inventory for sale to the given entity.".into(),
597 Patrol => "Patrol using attributes.route (patrol(wait, speed)).".into(),
598 PlayAudio => "Play an audio asset: play_audio(name, bus, gain, looping).".into(),
599 Random => "Generate a random number within an open range.".into(),
600 RandomWalk => "Randomly walk.".into(),
601 RandomWalkInSector => "Randomly walk in the entities current sector.".into(),
602 SetAttr => "Set an attribute of the current entity or item.".into(),
603 SetAudioBusVolume => "Set volume for an audio bus.".into(),
604 SetEmitLight => "Set the light emission state of the current entity or item.".into(),
605 SetPlayerCamera => {
606 "Sets the player camera: '2d', 'iso' or 'firstp'.".into()
607 }
608 SetProximityTracking => {
609 "Enable / disable tracking of entities for the current entity or item.".into()
610 }
611 SetTarget => "Set current target entity ID for the current entity or item.".into(),
612 SetTile => "Set the tile ID for the current entity or item.".into(),
613 Take => "Take the item with the given ID.".into(),
614 Target => "Get current target entity ID.".into(),
615 HasTarget => "Returns true if a valid current target is set.".into(),
616 Teleport => "Teleport to a sector. Optionally in another region.".into(),
617 ToggleAttr => "Toggles a boolean attribute of the current entity or item.".into(),
618 TookDamage => "Takes damage.".into(),
619
620 Abs => "Absolute value of x.".into(),
621 Atan => "Arc tangent of y/x (single-arg).".into(),
622 Atan2 => "Arc tangent of y/x using signs of both to determine quadrant.".into(),
623 Ceil => "Ceiling: round x up to the next integer.".into(),
624 Clamp => "Clamp x to the range [min, max].".into(),
625 Cos => "Cosine of angle (radians).".into(),
626 Cross => "3D cross product.".into(),
627 Degrees => "Convert radians to degrees.".into(),
628 Dot => "Dot product.".into(),
629 Exp => "Exponential e^x.".into(),
630 Floor => "Floor: round x down to the previous integer.".into(),
631 Fract => "Fractional part of x.".into(),
632 Length => "Vector length / magnitude.".into(),
633 Log => "Natural logarithm.".into(),
634 Max => "Component-wise maximum of x and y.".into(),
635 Min => "Component-wise minimum of x and y.".into(),
636 Mix => "Linear interpolation: mix(a, b, t).".into(),
637 Mod => "Remainder of x/y with sign of x.".into(),
638 Normalize => "Normalize a vector to unit length.".into(),
639 Pow => "Power: x^y.".into(),
640 Radians => "Convert degrees to radians.".into(),
641 Rand => "Random number in [0,1).".into(),
642 Rotate2d => "Rotate a 2D vector by an angle (in degrees).".into(),
643 Sign => "Sign of x (-1, 0, or 1) component-wise.".into(),
644 Sin => "Sine of angle (radians).".into(),
645 Smoothstep => "Hermite smooth interpolation between edge0 and edge1.".into(),
646 Sqrt => "Square root.".into(),
647 Step => "Step function: 0 if x < edge, else 1.".into(),
648 Tan => "Tangent of angle (radians).".into(),
649 Sample => "Sample a noise or pattern texture.".into(),
650 SampleNormal => "Sample the normal of a noise or pattern texture.".into(),
651
652 _ => "".into(),
653 }
654 }
655
656 pub fn role(&self) -> CellRole {
657 match &self {
658 Variable(_) | Integer(_) | Float(_) | Str(_) | Boolean(_) | Textures(_) | Value(_)
659 | PaletteColor(_) => CellRole::Value,
660 Assignment | Comparison(_) | If | Else | Arithmetic(_) => CellRole::Operator,
661 Empty => CellRole::None,
662
663 _ => CellRole::Function,
664 }
665 }
666}