read Blackboard data correctly from the SFC file, and construct a BlackboardPart...
[openc2e.git] / caosVM_compound.cpp
blob442485be814392fb35377eab2dab8b7db01a1f48
1 /*
2 * caosVM_compound.cpp
3 * openc2e
5 * Created by Alyssa Milburn on Mon May 31 2004.
6 * Copyright (c) 2004 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
20 #include "caosVM.h"
21 #include "CompoundAgent.h"
22 #include "CameraPart.h"
23 #include "openc2e.h"
24 #include "World.h"
25 #include "Engine.h"
27 /**
28 PART (command) part_id (integer)
29 %status maybe
30 %pragma variants c1 c2 cv c3 sm
32 Sets the part number of the TARGeted compound agent or vehicle to work on (ANIM/POSE use this,
33 amongst other commands).
35 void caosVM::c_PART() {
36 VM_VERIFY_SIZE(1)
37 VM_PARAM_INTEGER(part_id)
39 caos_assert((part_id >= 0) || (part_id == -1));
40 part = part_id;
43 /**
44 PART (integer) part_id (integer)
45 %status maybe
47 Returns 1 if the given part number exists on the target agent, or 0 if otherwise.
49 void caosVM::v_PART() {
50 VM_PARAM_INTEGER(part_id)
52 caos_assert(part_id >= 0); // TODO: should we do this?
53 valid_agent(targ);
54 if (targ->part(part_id))
55 result.setInt(1);
56 else
57 result.setInt(0);
60 /**
61 NEW: PART (command) part (integer) x (integer) y (integer) first_image (integer) plane (integer)
62 %status maybe
63 %pragma variants c1 c2
65 void caosVM::c_NEW_PART() {
66 VM_PARAM_INTEGER(plane)
67 VM_PARAM_INTEGER(first_image)
68 VM_PARAM_INTEGER(y)
69 VM_PARAM_INTEGER(x)
70 VM_PARAM_INTEGER(partno)
72 caos_assert(partno >= 0 && partno <= 9);
73 valid_agent(targ);
74 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
75 caos_assert(a);
77 CompoundPart *p = new DullPart(a, partno, a->getSpriteFile(), a->getFirstImage() + first_image, x, y, plane);
78 a->addPart(p);
80 part = partno;
83 /**
84 PAT: DULL (command) part (integer) sprite (string) first_image (integer) x (integer) y (integer) plane (integer)
85 %status maybe
86 %pragma variants cv c3
88 Adds a new 'dull' part to the TARGed compound agent/vehicle which does nothing but display an image.
89 Part ID numbers begin at 1. x/y/plane are relative to the agent you're working on.
91 void caosVM::c_PAT_DULL() {
92 VM_VERIFY_SIZE(6)
93 VM_PARAM_INTEGER(plane)
94 // TODO: should x/y be int? original docs say 'decimal'
95 VM_PARAM_INTEGER(y)
96 VM_PARAM_INTEGER(x)
97 VM_PARAM_INTEGER(first_image)
98 VM_PARAM_STRING(sprite)
99 VM_PARAM_INTEGER(part)
101 caos_assert(part >= 0);
102 valid_agent(targ);
103 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
104 caos_assert(a);
106 CompoundPart *p = new DullPart(a, part, sprite, first_image, x, y, plane);
107 a->addPart(p);
111 PAT: BUTT (command) part (integer) sprite (string) first_image (integer) image_count (integer) x (integer) y (integer) plane (integer) hoveranim (byte-string) messageid (integer) option (integer)
112 %status maybe
114 Adds a new 'button' part to the TARGed compound agent/vehicle.
115 Part ID numbers begin at 1. x/y/plane are relative to the agent you're working on.
116 'hoveranim' is the animation to use when the part is mouse-overed - see ANIM for details.
117 'messageid' is the message sent when the button is clicked - _p1_ of the message is set to the part number.
118 If option is 1, mouseclicks/hovers only apply to non-transparent areas. otherwise, option should be 0.
120 void caosVM::c_PAT_BUTT() {
121 VM_VERIFY_SIZE(10)
122 VM_PARAM_INTEGER(option)
123 VM_PARAM_INTEGER(messageid)
124 VM_PARAM_BYTESTR(hoveranim)
125 VM_PARAM_INTEGER(plane)
126 // TODO: should x/y be int? original docs say 'decimal'
127 VM_PARAM_INTEGER(y)
128 VM_PARAM_INTEGER(x)
129 VM_PARAM_INTEGER(image_count)
130 VM_PARAM_INTEGER(first_image)
131 VM_PARAM_STRING(sprite)
132 VM_PARAM_INTEGER(part)
134 caos_assert(part >= 0);
135 // caos_assert((option == 0) || (option == 1)); .. I've seen '1000' and '255' used, so, gah. TODO: make sure all non-zero values are identical
136 valid_agent(targ);
137 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
138 caos_assert(a);
140 // TODO TODO TODO we don't take image_count!!
141 CompoundPart *p = new ButtonPart(a, part, sprite, first_image, x, y, plane, hoveranim, messageid, option);
142 a->addPart(p);
146 PAT: FIXD (command) part (integer) sprite (string) first_image (integer) x (integer) y (integer) plane (integer) fontsprite (string)
147 %status maybe
149 Adds a new 'fixed' text part to the TARGed compound agent/vehicle,
150 Part ID numbers begin at 1. x/y/plane are relative to the agent you're working on.
151 The 'first_image' frame of the given sprite file will be used underneath the text, which is set with PTXT.
153 void caosVM::c_PAT_FIXD() {
154 VM_PARAM_STRING(fontsprite)
155 VM_PARAM_INTEGER(plane)
156 // TODO: should x/y be int? original docs say 'decimal'
157 VM_PARAM_INTEGER(y)
158 VM_PARAM_INTEGER(x)
159 VM_PARAM_INTEGER(first_image)
160 VM_PARAM_STRING(sprite)
161 VM_PARAM_INTEGER(part)
163 caos_assert(part >= 0);
164 valid_agent(targ);
165 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
166 caos_assert(a);
168 CompoundPart *p = new FixedTextPart(a, part, sprite, first_image, x, y, plane, fontsprite);
169 a->addPart(p);
173 PAT: TEXT (command) part (integer) sprite (string) first_image (integer) x (integer) y (integer) plane (integer) message_id (integer) fontsprite (string)
174 %status maybe
176 Adds a new text entry part to the TARGed compound agent/vehicle.
177 Part ID numbers begin at 1. x/y/plane are relative to the agent you're working on.
178 The 'first_image' frame of the given sprite file will be used underneath the text. The part will
179 gain the focus when FCUS is called or when it is clicked. A message of the given type will be sent.
181 void caosVM::c_PAT_TEXT() {
182 VM_PARAM_STRING(fontsprite)
183 VM_PARAM_INTEGER(message_id)
184 VM_PARAM_INTEGER(plane)
185 // TODO: should x/y be int? original docs say 'decimal'
186 VM_PARAM_INTEGER(y)
187 VM_PARAM_INTEGER(x)
188 VM_PARAM_INTEGER(first_image)
189 VM_PARAM_STRING(sprite)
190 VM_PARAM_INTEGER(part)
192 caos_assert(part >= 0);
193 valid_agent(targ);
194 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
195 caos_assert(a);
197 CompoundPart *p = new TextEntryPart(a, part, sprite, first_image, x, y, plane, message_id, fontsprite);
198 a->addPart(p);
202 PAT: CMRA (command) part (integer) sprite (string) first_image (integer) x (integer) y (integer) plane (integer) viewwidth (integer) viewheight (integer) camerawidth (integer) cameraheight(integer)
203 %status maybe
205 void caosVM::c_PAT_CMRA() {
206 VM_PARAM_INTEGER(cameraheight)
207 VM_PARAM_INTEGER(camerawidth)
208 VM_PARAM_INTEGER(viewheight)
209 VM_PARAM_INTEGER(viewwidth)
210 VM_PARAM_INTEGER(plane)
211 // TODO: should x/y be int? original docs say 'decimal'
212 VM_PARAM_INTEGER(y)
213 VM_PARAM_INTEGER(x)
214 VM_PARAM_INTEGER(first_image)
215 VM_PARAM_STRING(sprite)
216 VM_PARAM_INTEGER(part)
218 caos_assert(part >= 0);
219 valid_agent(targ);
220 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
221 caos_assert(a);
223 CompoundPart *p = new CameraPart(a, part, sprite, first_image, x, y, plane, viewwidth, viewheight, camerawidth, cameraheight);
224 a->addPart(p);
228 PAT: GRPH (command) part (integer) sprite (string) first_image (integer) x (integer) y (integer) plane (integer) numvalues (integer)
229 %status maybe
233 void caosVM::c_PAT_GRPH() {
234 VM_PARAM_INTEGER(numvalues)
235 VM_PARAM_INTEGER(plane)
236 // TODO: should x/y be int? original docs say 'decimal'
237 VM_PARAM_INTEGER(y)
238 VM_PARAM_INTEGER(x)
239 VM_PARAM_INTEGER(first_image)
240 VM_PARAM_STRING(sprite)
241 VM_PARAM_INTEGER(part)
243 caos_assert(part >= 0);
244 valid_agent(targ);
245 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
246 caos_assert(a);
248 CompoundPart *p = new GraphPart(a, part, sprite, first_image, x, y, plane, numvalues);
249 a->addPart(p);
253 PAT: KILL (command) part (integer)
254 %status maybe
256 Kills the specified part of the TARGed compound agent or vehicle.
258 void caosVM::c_PAT_KILL() {
259 VM_VERIFY_SIZE(1)
260 VM_PARAM_INTEGER(part)
262 caos_assert(part > 0);
263 valid_agent(targ);
264 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
265 caos_assert(a);
266 if (!a->part(part)) return; // Edynn does PAT: KILL on nonexistant parts
268 a->delPart(part);
272 PAT: MOVE (command) part (integer) x (integer) y (integer)
273 %status maybe
275 move the compound part specified to the new relative position specified
277 void caosVM::c_PAT_MOVE() {
278 // TODO: should x/y be int? original docs say 'decimal'
279 VM_PARAM_INTEGER(y)
280 VM_PARAM_INTEGER(x)
281 VM_PARAM_INTEGER(part)
283 valid_agent(targ);
284 CompoundAgent *a = dynamic_cast<CompoundAgent *>(targ.get());
285 caos_assert(a);
286 CompoundPart *p = a->part(part);
287 caos_assert(p);
289 p->x = x;
290 p->y = y;
294 FCUS (command)
295 %status maybe
297 Focus the current targeted part, which must be a PAT: TEXT.
298 If the target is null, then the current part will be unfocused.
300 void caosVM::c_FCUS() {
301 VM_VERIFY_SIZE(0)
303 if (!targ)
304 world.setFocus(0);
305 else {
306 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
307 caos_assert(c);
308 TextEntryPart *p = dynamic_cast<TextEntryPart *>(c->part(part));
309 caos_assert(p);
310 world.setFocus(p);
315 FRMT (command) left_margin (integer) top_margin (integer) right_margin (integer) button_margin (integer) line_spacing (integer) char_spacing (integer) justification (integer)
316 %status maybe
318 Alters the appearance of the target text part. The spacing values and margins are to be specified in
319 pixels. Justification can be 0 for left, 1 for right, 2 for center, 4 for bottom, 8 for middle or 16
320 for 'last page scroll' (TODO?), and you can add these together (except 0/1 are mutually exclusive, obviously).
322 void caosVM::c_FRMT() {
323 VM_PARAM_INTEGER(justification)
324 VM_PARAM_INTEGER(char_spacing)
325 VM_PARAM_INTEGER(line_spacing)
326 VM_PARAM_INTEGER(bottom_margin)
327 VM_PARAM_INTEGER(right_margin)
328 VM_PARAM_INTEGER(top_margin)
329 VM_PARAM_INTEGER(left_margin)
331 valid_agent(targ);
332 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
333 caos_assert(c);
334 TextPart *p = dynamic_cast<TextPart *>(c->part(part));
335 caos_assert(p);
337 horizontalalign h;
338 if ((justification & 3) == 1) h = rightalign;
339 else if ((justification & 3) == 2) h = centeralign;
340 else h = leftalign;
342 verticalalign v;
343 if ((justification & 12) == 4) v = bottom;
344 else if ((justification & 12) == 8) v = middle;
345 else v = top; // TODO: i haven't verified this is the correct fallback - fuzzie
347 if (char_spacing == 1) char_spacing = 0; // TODO: horrible hack to try and fix issues
349 p->setFormat(left_margin, top_margin, right_margin, bottom_margin, line_spacing, char_spacing, h, v, (justification & 16));
353 PTXT (command) text (string)
354 %status maybe
356 Sets the text displayed in the current text part.
358 void caosVM::c_PTXT() {
359 VM_PARAM_STRING(text)
361 valid_agent(targ);
362 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
363 caos_assert(c);
364 TextPart *p = dynamic_cast<TextPart *>(c->part(part));
365 caos_assert(p);
367 p->setText(text);
371 PTXT (string)
372 %status maybe
374 Returns the text displayed in the current text part.
376 void caosVM::v_PTXT() {
377 valid_agent(targ);
378 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
379 caos_assert(c);
380 TextPart *p = dynamic_cast<TextPart *>(c->part(part));
381 caos_assert(p);
383 result.setString(p->getText());
387 PNXT (integer) previous_part (integer)
388 %status maybe
390 Returns the next part of the TARG compound agent or vehicle, (or -1 if you have reached the end, or
391 the first part if you go past -1).
393 void caosVM::v_PNXT() {
394 VM_PARAM_INTEGER(previous_part)
396 valid_agent(targ);
397 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
399 if (!c) { // handle non-compound agents
400 if (previous_part == -1)
401 result.setInt(0);
402 else
403 result.setInt(-1);
404 return;
407 // TODO: this might not be the best way to do this..
408 CompoundPart *curpart = 0;
410 for (std::vector<CompoundPart *>::iterator x = c->parts.begin(); x != c->parts.end(); x++) {
411 unsigned int i = (*x)->id;
412 if ((int)i > previous_part)
413 if (!curpart || i < curpart->id)
414 curpart = *x;
417 if (curpart) result.setInt(curpart->id);
418 else result.setInt(-1);
422 PAGE (command) page (integer)
423 %status maybe
425 Sets the zero-based page number of the current text part. This must be less than NPGS.
427 void caosVM::c_PAGE() {
428 VM_PARAM_INTEGER(page)
430 valid_agent(targ);
431 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
432 caos_assert(c);
433 CompoundPart *p = c->part(part);
434 caos_assert(p);
435 FixedTextPart *t = dynamic_cast<FixedTextPart *>(p);
436 caos_assert(t);
438 t->setPage(page);
442 PAGE (integer)
443 %status maybe
445 Returns the zero-based page number of the current text part.
447 void caosVM::v_PAGE() {
448 valid_agent(targ);
449 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
450 caos_assert(c);
451 CompoundPart *p = c->part(part);
452 caos_assert(p);
453 FixedTextPart *t = dynamic_cast<FixedTextPart *>(p);
454 caos_assert(t);
456 result.setInt(t->getPage());
460 NPGS (integer)
461 %status maybe
463 Returns the number of pages for the current text part.
465 void caosVM::v_NPGS() {
466 valid_agent(targ);
467 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
468 caos_assert(c);
469 CompoundPart *p = c->part(part);
470 caos_assert(p);
471 FixedTextPart *t = dynamic_cast<FixedTextPart *>(p);
472 caos_assert(t);
474 result.setInt(t->noPages());
478 GRPV (command) line (integer) value (float)
479 %status stub
481 Add the given value to the given line on a graph.
483 void caosVM::c_GRPV() {
484 VM_PARAM_FLOAT(value)
485 VM_PARAM_INTEGER(line)
487 valid_agent(targ);
488 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
489 caos_assert(c);
490 CompoundPart *p = c->part(part);
491 caos_assert(p);
492 GraphPart *t = dynamic_cast<GraphPart *>(p);
493 caos_assert(t);
495 // TODO
499 GRPL (command) red (integer) green (integer) blue (integer) min (float) max (float)
500 %status stub
502 Add a new line to a graph created with PAT: GRPH with the given
503 characteristics.
505 void caosVM::c_GRPL() {
506 VM_PARAM_FLOAT(max)
507 VM_PARAM_FLOAT(min)
508 VM_PARAM_INTEGER(blue)
509 VM_PARAM_INTEGER(green)
510 VM_PARAM_INTEGER(red)
512 valid_agent(targ);
513 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
514 caos_assert(c);
515 CompoundPart *p = c->part(part);
516 caos_assert(p);
517 GraphPart *t = dynamic_cast<GraphPart *>(p);
518 caos_assert(t);
520 // TODO
524 BBD: WORD (command) index (integer) id (integer) text (string)
525 %status stub
526 %pragma variants c1 c2
528 Change the word at index to target blackboard, setting to the provided id and text.
530 void caosVM::c_BBD_WORD() {
531 VM_PARAM_STRING(text)
532 VM_PARAM_INTEGER(id)
533 VM_PARAM_INTEGER(index)
535 if (engine.version == 1) {
536 caos_assert(index < 16);
537 } else {
538 caos_assert(index < 48);
541 valid_agent(targ);
542 // TODO
546 BBD: SHOW (command) show (integer)
547 %status stub
548 %pragma variants c1 c2
550 If show is 1, draw the current text onto part 0 of the target blackboard. If 0,
551 remove it from the blackboard.
553 void caosVM::c_BBD_SHOW() {
554 VM_PARAM_INTEGER(show)
556 valid_agent(targ);
557 // TODO
561 BBD: EMIT (command) audible (integer)
562 %status stub
563 %pragma variants c1 c2
565 Broadcast the current word of the target blackboard. If audible is 1, broadcast
566 to all nearby creatures. If 0, broadcast to all creatures looking at it.
568 void caosVM::c_BBD_EMIT() {
569 VM_PARAM_INTEGER(audible)
571 valid_agent(targ);
572 // TODO
576 BBD: EDIT (command) allow (integer)
577 %status stub
578 %pragma variants c1
580 If allow is 1, switch target blackboard into editing mode, give it focus. If it
581 is 0, remove focus from target blackboard.
583 void caosVM::c_BBD_EDIT() {
584 VM_PARAM_INTEGER(allow)
586 valid_agent(targ);
587 // TODO
591 BBD: VOCB (command) blackboardstart (integer) globalstart (integer) count (integer)
592 %status stub
593 %pragma variants c2
595 Copy count words into the blackboard word list from the global word list.
597 void caosVM::c_BBD_VOCB() {
598 VM_PARAM_INTEGER(count)
599 VM_PARAM_INTEGER(globalstart)
600 VM_PARAM_INTEGER(blackboardstart)
602 valid_agent(targ);
603 // TODO
607 NEW: BBTX (command) part (integer) x (integer) y (integer) width (integer)
608 %status stub
609 %pragma variants c2
611 Create a new C2 text part for a compound bubble object. Text will wrap as required to fit width.
613 void caosVM::c_NEW_BBTX() {
614 VM_PARAM_INTEGER(width)
615 VM_PARAM_INTEGER(y)
616 VM_PARAM_INTEGER(x)
617 VM_PARAM_INTEGER(part)
619 valid_agent(targ);
620 // TODO
624 BBTX (command) part (integer) stringindex (integer)
625 %status stub
626 %pragma variants c2
628 void caosVM::c_BBTX() {
629 VM_PARAM_INTEGER(stringindex)
630 VM_PARAM_INTEGER(part)
632 valid_agent(targ);
633 // TODO
637 SPOT (command) spotno (integer) left (integer) top (integer) right (integer) bottom (integer)
638 %status maybe
639 %pragma variants c1 c2
641 void caosVM::c_SPOT() {
642 VM_PARAM_INTEGER(bottom)
643 VM_PARAM_INTEGER(right)
644 VM_PARAM_INTEGER(top)
645 VM_PARAM_INTEGER(left)
646 VM_PARAM_INTEGER(spotno)
648 valid_agent(targ);
649 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
650 caos_assert(c);
652 c->setHotspotLoc(spotno, left, top, right, bottom);
656 KNOB (command) function (integer) spotno (integer)
657 %status maybe
658 %pragma variants c1 c2
660 void caosVM::c_KNOB() {
661 VM_PARAM_INTEGER(spotno)
662 VM_PARAM_INTEGER(function)
664 valid_agent(targ);
665 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
666 caos_assert(c);
668 c->setHotspotFunc(function, spotno);
672 KMSG (command) function (integer) flags (integer) message (integer)
673 %status maybe
674 %pragma variants c2
676 void caosVM::c_KMSG() {
677 VM_PARAM_INTEGER(message)
678 VM_PARAM_INTEGER(flags)
679 VM_PARAM_INTEGER(function)
681 valid_agent(targ);
682 CompoundAgent *c = dynamic_cast<CompoundAgent *>(targ.get());
683 caos_assert(c);
685 c->setHotspotFuncDetails(function, message, flags);
689 BBLE (command) text (string) ticks (integer) type (integer) track (integer)
690 %status stub
691 %pragma variants c2
693 Display the given text for the given number of ticks, in a bubble (type is 0 for speech or 1 for thought).
695 void caosVM::c_BBLE() {
696 VM_PARAM_INTEGER(track)
697 VM_PARAM_INTEGER(type)
698 VM_PARAM_INTEGER(ticks)
699 VM_PARAM_STRING(text)
701 // TODO
705 BBFD (command) part (integer) red (integer) green (integer) blue (integer)
706 %status stub
707 %pragma variants c2
709 void caosVM::c_BBFD() {
710 VM_PARAM_INTEGER(blue)
711 VM_PARAM_INTEGER(green)
712 VM_PARAM_INTEGER(red)
713 VM_PARAM_INTEGER(part)
715 valid_agent(targ);
716 // TODO
719 /* vim: set noet: */