1 //=============================================================================
2 //
3 // Adventure Game Studio (AGS)
4 //
5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
6 // The full list of copyright holders can be found in the Copyright.txt
7 // file, which is part of this source code distribution.
8 //
9 // The AGS source code is provided under the Artistic License 2.0.
10 // A copy of this license can be found in the file License.txt and at
11 // http://www.opensource.org/licenses/artistic-license-2.0.php
12 //
13 //=============================================================================
14 //
15 // AGS Character functions
16 //
17 //=============================================================================
18
19 #include "ac/character.h"
20 #include "ac/common.h"
21 #include "ac/gamesetupstruct.h"
22 #include "ac/roomstruct.h"
23 #include "ac/view.h"
24 #include "ac/display.h"
25 #include "ac/draw.h"
26 #include "ac/event.h"
27 #include "ac/game.h"
28 #include "ac/global_audio.h"
29 #include "ac/global_character.h"
30 #include "ac/global_game.h"
31 #include "ac/global_object.h"
32 #include "ac/global_region.h"
33 #include "ac/global_room.h"
34 #include "ac/global_translation.h"
35 #include "ac/gui.h"
36 #include "ac/lipsync.h"
37 #include "ac/mouse.h"
38 #include "ac/object.h"
39 #include "ac/overlay.h"
40 #include "ac/path.h"
41 #include "ac/properties.h"
42 #include "ac/screenoverlay.h"
43 #include "ac/string.h"
44 #include "ac/system.h"
45 #include "ac/viewframe.h"
46 #include "ac/walkablearea.h"
47 #include "gui/guimain.h"
48 #include "ac/route_finder.h"
49 #include "ac/gamestate.h"
50 #include "debug/debug_log.h"
51 #include "main/game_run.h"
52 #include "main/update.h"
53 #include "ac/spritecache.h"
54 #include "util/string_utils.h"
55 #include <math.h>
56 #include "gfx/graphicsdriver.h"
57 #include "platform/base/override_defines.h"
58 #include "script/runtimescriptvalue.h"
59 #include "ac/dynobj/cc_character.h"
60 #include "ac/dynobj/cc_inventory.h"
61 #include "script/script_runtime.h"
62 #include "gfx/gfx_def.h"
63
64 using namespace AGS::Common;
65
66 extern GameSetupStruct game;
67 extern int displayed_room,starting_room;
68 extern roomstruct thisroom;
69 extern MoveList *mls;
70 extern ViewStruct*views;
71 extern RoomObject*objs;
72 extern int spritewidth[MAX_SPRITES],spriteheight[MAX_SPRITES];
73 extern ScriptInvItem scrInv[MAX_INV];
74 extern SpriteCache spriteset;
75 extern ScreenOverlay screenover[MAX_SCREEN_OVERLAYS];
76 extern Bitmap *walkable_areas_temp;
77 extern IGraphicsDriver *gfxDriver;
78 extern Bitmap **actsps;
79 extern int offsetx, offsety;
80 extern int is_text_overlay;
81 extern int said_speech_line;
82 extern int numscreenover;
83 extern int said_text;
84 extern int our_eip;
85 extern int update_music_at;
86 extern int current_screen_resolution_multiplier;
87 extern int cur_mode;
88 extern int screen_is_dirty;
89 extern CCCharacter ccDynamicCharacter;
90 extern CCInventory ccDynamicInv;
91
92 //--------------------------------
93
94
95 CharacterExtras *charextra;
96 CharacterInfo*playerchar;
97 int32_t _sc_PlayerCharPtr = 0;
98 int char_lowest_yp;
99
100 // Sierra-style speech settings
101 int face_talking=-1,facetalkview=0,facetalkwait=0,facetalkframe=0;
102 int facetalkloop=0, facetalkrepeat = 0, facetalkAllowBlink = 1;
103 int facetalkBlinkLoop = 0;
104 CharacterInfo *facetalkchar = NULL;
105 // Do override default portrait position during QFG4-style speech overlay update
106 bool facetalk_qfg4_override_placement_x = false;
107 bool facetalk_qfg4_override_placement_y = false;
108
109 // lip-sync speech settings
110 int loops_per_character, text_lips_offset, char_speaking = -1;
111 int char_thinking = -1;
112 const char *text_lips_text = NULL;
113 SpeechLipSyncLine *splipsync = NULL;
114 int numLipLines = 0, curLipLine = -1, curLipLinePhoneme = 0;
115
116 // **** CHARACTER: FUNCTIONS ****
117
Character_AddInventory(CharacterInfo * chaa,ScriptInvItem * invi,int addIndex)118 void Character_AddInventory(CharacterInfo *chaa, ScriptInvItem *invi, int addIndex) {
119 int ee;
120
121 if (invi == NULL)
122 quit("!AddInventoryToCharacter: invalid invnetory number");
123
124 int inum = invi->id;
125
126 if (chaa->inv[inum] >= 32000)
127 quit("!AddInventory: cannot carry more than 32000 of one inventory item");
128
129 chaa->inv[inum]++;
130
131 int charid = chaa->index_id;
132
133 if (game.options[OPT_DUPLICATEINV] == 0) {
134 // Ensure it is only in the list once
135 for (ee = 0; ee < charextra[charid].invorder_count; ee++) {
136 if (charextra[charid].invorder[ee] == inum) {
137 // They already have the item, so don't add it to the list
138 if (chaa == playerchar)
139 run_on_event (GE_ADD_INV, RuntimeScriptValue().SetInt32(inum));
140 return;
141 }
142 }
143 }
144 if (charextra[charid].invorder_count >= MAX_INVORDER)
145 quit("!Too many inventory items added, max 500 display at one time");
146
147 if ((addIndex == SCR_NO_VALUE) ||
148 (addIndex >= charextra[charid].invorder_count) ||
149 (addIndex < 0)) {
150 // add new item at end of list
151 charextra[charid].invorder[charextra[charid].invorder_count] = inum;
152 }
153 else {
154 // insert new item at index
155 for (ee = charextra[charid].invorder_count - 1; ee >= addIndex; ee--)
156 charextra[charid].invorder[ee + 1] = charextra[charid].invorder[ee];
157
158 charextra[charid].invorder[addIndex] = inum;
159 }
160 charextra[charid].invorder_count++;
161 guis_need_update = 1;
162 if (chaa == playerchar)
163 run_on_event (GE_ADD_INV, RuntimeScriptValue().SetInt32(inum));
164
165 }
166
Character_AddWaypoint(CharacterInfo * chaa,int x,int y)167 void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) {
168
169 if (chaa->room != displayed_room)
170 quit("!MoveCharacterPath: specified character not in current room");
171
172 // not already walking, so just do a normal move
173 if (chaa->walking <= 0) {
174 Character_Walk(chaa, x, y, IN_BACKGROUND, ANYWHERE);
175 return;
176 }
177
178 MoveList *cmls = &mls[chaa->walking % TURNING_AROUND];
179 if (cmls->numstage >= MAXNEEDSTAGES)
180 quit("!MoveCharacterPath: move is too complex, cannot add any further paths");
181
182 cmls->pos[cmls->numstage] = (x << 16) + y;
183 // They're already walking there anyway
184 if (cmls->pos[cmls->numstage] == cmls->pos[cmls->numstage - 1])
185 return;
186
187 calculate_move_stage (cmls, cmls->numstage-1);
188 cmls->numstage ++;
189
190 }
191
Character_Animate(CharacterInfo * chaa,int loop,int delay,int repeat,int blocking,int direction)192 void Character_Animate(CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction) {
193
194 if (direction == FORWARDS)
195 direction = 0;
196 else if (direction == BACKWARDS)
197 direction = 1;
198 else
199 quit("!Character.Animate: Invalid DIRECTION parameter");
200
201 animate_character(chaa, loop, delay, repeat, 0, direction);
202
203 if ((blocking == BLOCKING) || (blocking == 1))
204 GameLoopUntilEvent(UNTIL_SHORTIS0,(long)&chaa->animating);
205 else if ((blocking != IN_BACKGROUND) && (blocking != 0))
206 quit("!Character.Animate: Invalid BLOCKING parameter");
207 }
208
Character_ChangeRoomAutoPosition(CharacterInfo * chaa,int room,int newPos)209 void Character_ChangeRoomAutoPosition(CharacterInfo *chaa, int room, int newPos)
210 {
211 if (chaa->index_id != game.playercharacter)
212 {
213 quit("!Character.ChangeRoomAutoPosition can only be used with the player character.");
214 }
215
216 new_room_pos = newPos;
217
218 if (new_room_pos == 0) {
219 // auto place on other side of screen
220 if (chaa->x <= thisroom.left + 10)
221 new_room_pos = 2000;
222 else if (chaa->x >= thisroom.right - 10)
223 new_room_pos = 1000;
224 else if (chaa->y <= thisroom.top + 10)
225 new_room_pos = 3000;
226 else if (chaa->y >= thisroom.bottom - 10)
227 new_room_pos = 4000;
228
229 if (new_room_pos < 3000)
230 new_room_pos += chaa->y;
231 else
232 new_room_pos += chaa->x;
233 }
234 NewRoom(room);
235 }
236
Character_ChangeRoom(CharacterInfo * chaa,int room,int x,int y)237 void Character_ChangeRoom(CharacterInfo *chaa, int room, int x, int y) {
238 Character_ChangeRoomSetLoop(chaa, room, x, y, SCR_NO_VALUE);
239 }
240
Character_ChangeRoomSetLoop(CharacterInfo * chaa,int room,int x,int y,int direction)241 void Character_ChangeRoomSetLoop(CharacterInfo *chaa, int room, int x, int y, int direction) {
242
243 if (chaa->index_id != game.playercharacter) {
244 // NewRoomNPC
245 if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) {
246 chaa->x = x;
247 chaa->y = y;
248 if (direction != SCR_NO_VALUE && direction>=0) chaa->loop = direction;
249 }
250 chaa->prevroom = chaa->room;
251 chaa->room = room;
252
253 debug_script_log("%s moved to room %d, location %d,%d, loop %d",
254 chaa->scrname, room, chaa->x, chaa->y, chaa->loop);
255
256 return;
257 }
258
259 if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) {
260 new_room_pos = 0;
261
262 if (loaded_game_file_version <= kGameVersion_272)
263 {
264 // Set position immediately on 2.x.
265 chaa->x = x;
266 chaa->y = y;
267 }
268 else
269 {
270 // don't check X or Y bounds, so that they can do a
271 // walk-in animation if they want
272 new_room_x = x;
273 new_room_y = y;
274 if (direction != SCR_NO_VALUE) new_room_loop = direction;
275 }
276 }
277
278 NewRoom(room);
279 }
280
281
Character_ChangeView(CharacterInfo * chap,int vii)282 void Character_ChangeView(CharacterInfo *chap, int vii) {
283 vii--;
284
285 if ((vii < 0) || (vii >= game.numviews))
286 quit("!ChangeCharacterView: invalid view number specified");
287
288 // if animating, but not idle view, give warning message
289 if ((chap->flags & CHF_FIXVIEW) && (chap->idleleft >= 0))
290 debug_script_warn("Warning: ChangeCharacterView was used while the view was fixed - call ReleaseCharView first");
291
292 // if the idle animation is playing we should release the view
293 if ( chap->idleleft < 0) {
294 Character_UnlockView(chap);
295 chap->idleleft = chap->idletime;
296 }
297
298 debug_script_log("%s: Change view to %d", chap->scrname, vii+1);
299 chap->defview = vii;
300 chap->view = vii;
301 chap->animating = 0;
302 chap->frame = 0;
303 chap->wait = 0;
304 chap->walkwait = 0;
305 charextra[chap->index_id].animwait = 0;
306 FindReasonableLoopForCharacter(chap);
307 }
308
309 enum DirectionalLoop
310 {
311 kDirLoop_Down = 0,
312 kDirLoop_Left = 1,
313 kDirLoop_Right = 2,
314 kDirLoop_Up = 3,
315 kDirLoop_DownRight = 4,
316 kDirLoop_UpRight = 5,
317 kDirLoop_DownLeft = 6,
318 kDirLoop_UpLeft = 7,
319
320 kDirLoop_Default = kDirLoop_Down,
321 kDirLoop_LastOrthogonal = kDirLoop_Up,
322 kDirLoop_Last = kDirLoop_UpLeft,
323 };
324
325 // Internal direction-facing functions
326
GetDirectionalLoop(CharacterInfo * chinfo,int x_diff,int y_diff)327 DirectionalLoop GetDirectionalLoop(CharacterInfo *chinfo, int x_diff, int y_diff)
328 {
329 DirectionalLoop next_loop = kDirLoop_Left; // NOTE: default loop was Left for some reason
330
331 const ViewStruct &chview = views[chinfo->view];
332 const bool new_version = loaded_game_file_version > kGameVersion_272;
333 const bool has_down_loop = ((chview.numLoops > kDirLoop_Down) && (chview.loops[kDirLoop_Down].numFrames > 0));
334 const bool has_up_loop = ((chview.numLoops > kDirLoop_Up) && (chview.loops[kDirLoop_Up].numFrames > 0));
335 // NOTE: 3.+ games required left & right loops to be present at all times
336 const bool has_left_loop = new_version ||
337 ((chview.numLoops > kDirLoop_Left) && (chview.loops[kDirLoop_Left].numFrames > 0));
338 const bool has_right_loop = new_version ||
339 ((chview.numLoops > kDirLoop_Right) && (chview.loops[kDirLoop_Right].numFrames > 0));
340 const bool has_diagonal_loops = useDiagonal(chinfo) == 0; // NOTE: useDiagonal returns 0 for "true"
341
342 const bool want_horizontal = (abs(y_diff) < abs(x_diff)) ||
343 new_version && (!has_down_loop || !has_up_loop) ||
344 // NOTE: <= 2.72 games switch to horizontal loops only if both vertical ones are missing
345 !new_version && (!has_down_loop && !has_up_loop);
346 if (want_horizontal)
347 {
348 const bool want_diagonal = has_diagonal_loops && (abs(y_diff) > abs(x_diff) / 2);
349 if (!has_left_loop && !has_right_loop)
350 {
351 next_loop = kDirLoop_Down;
352 }
353 else if (has_right_loop && (x_diff > 0))
354 {
355 next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpRight : kDirLoop_DownRight) :
356 kDirLoop_Right;
357 }
358 else if (has_left_loop && (x_diff <= 0))
359 {
360 next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpLeft : kDirLoop_DownLeft) :
361 kDirLoop_Left;
362 }
363 }
364 else
365 {
366 const bool want_diagonal = has_diagonal_loops && (abs(x_diff) > abs(y_diff) / 2);
367 if (y_diff > 0 || !has_up_loop)
368 {
369 next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_DownLeft : kDirLoop_DownRight) :
370 kDirLoop_Down;
371 }
372 else
373 {
374 next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_UpLeft : kDirLoop_UpRight) :
375 kDirLoop_Up;
376 }
377 }
378 return next_loop;
379 }
380
FaceDirectionalLoop(CharacterInfo * char1,int direction,int blockingStyle)381 void FaceDirectionalLoop(CharacterInfo *char1, int direction, int blockingStyle)
382 {
383 // Change facing only if the desired direction is different
384 if (direction != char1->loop)
385 {
386 if ((game.options[OPT_TURNTOFACELOC] != 0) &&
387 (in_enters_screen == 0))
388 {
389 const int no_diagonal = useDiagonal (char1);
390 const int highestLoopForTurning = no_diagonal != 1 ? kDirLoop_Last : kDirLoop_LastOrthogonal;
391 if ((char1->loop <= highestLoopForTurning))
392 {
393 // Turn to face new direction
394 Character_StopMoving(char1);
395 if (char1->on == 1)
396 {
397 // only do the turning if the character is not hidden
398 // (otherwise GameLoopUntilEvent will never return)
399 start_character_turning (char1, direction, no_diagonal);
400
401 if ((blockingStyle == BLOCKING) || (blockingStyle == 1))
402 GameLoopUntilEvent(UNTIL_MOVEEND, (long) &char1->walking);
403 }
404 else
405 char1->loop = direction;
406 }
407 else
408 char1->loop = direction;
409 }
410 else
411 char1->loop = direction;
412 }
413
414 char1->frame = 0;
415 }
416
FaceLocationXY(CharacterInfo * char1,int xx,int yy,int blockingStyle)417 void FaceLocationXY(CharacterInfo *char1, int xx, int yy, int blockingStyle)
418 {
419 debug_script_log("%s: Face location %d,%d", char1->scrname, xx, yy);
420
421 const int diffrx = xx - char1->x;
422 const int diffry = yy - char1->y;
423
424 if ((diffrx == 0) && (diffry == 0)) {
425 // FaceLocation called on their current position - do nothing
426 return;
427 }
428
429 FaceDirectionalLoop(char1, GetDirectionalLoop(char1, diffrx, diffry), blockingStyle);
430 }
431
432 // External direction-facing functions with validation
433
Character_FaceDirection(CharacterInfo * char1,int direction,int blockingStyle)434 void Character_FaceDirection(CharacterInfo *char1, int direction, int blockingStyle)
435 {
436 if (char1 == NULL)
437 quit("!FaceDirection: invalid character specified");
438
439 if (direction != SCR_NO_VALUE)
440 {
441 if (direction < 0 || direction > kDirLoop_Last)
442 quit("!FaceDirection: invalid direction specified");
443
444 FaceDirectionalLoop(char1, direction, blockingStyle);
445 }
446 }
447
Character_FaceLocation(CharacterInfo * char1,int xx,int yy,int blockingStyle)448 void Character_FaceLocation(CharacterInfo *char1, int xx, int yy, int blockingStyle)
449 {
450 if (char1 == NULL)
451 quit("!FaceLocation: invalid character specified");
452
453 FaceLocationXY(char1, xx, yy, blockingStyle);
454 }
455
Character_FaceObject(CharacterInfo * char1,ScriptObject * obj,int blockingStyle)456 void Character_FaceObject(CharacterInfo *char1, ScriptObject *obj, int blockingStyle) {
457 if (obj == NULL)
458 quit("!FaceObject: invalid object specified");
459
460 FaceLocationXY(char1, objs[obj->id].x, objs[obj->id].y, blockingStyle);
461 }
462
Character_FaceCharacter(CharacterInfo * char1,CharacterInfo * char2,int blockingStyle)463 void Character_FaceCharacter(CharacterInfo *char1, CharacterInfo *char2, int blockingStyle) {
464 if (char2 == NULL)
465 quit("!FaceCharacter: invalid character specified");
466
467 if (char1->room != char2->room)
468 quit("!FaceCharacter: characters are in different rooms");
469
470 FaceLocationXY(char1, char2->x, char2->y, blockingStyle);
471 }
472
Character_FollowCharacter(CharacterInfo * chaa,CharacterInfo * tofollow,int distaway,int eagerness)473 void Character_FollowCharacter(CharacterInfo *chaa, CharacterInfo *tofollow, int distaway, int eagerness) {
474
475 if ((eagerness < 0) || (eagerness > 250))
476 quit("!FollowCharacterEx: invalid eagerness: must be 0-250");
477
478 if ((chaa->index_id == game.playercharacter) && (tofollow != NULL) &&
479 (tofollow->room != chaa->room))
480 quit("!FollowCharacterEx: you cannot tell the player character to follow a character in another room");
481
482 if (tofollow != NULL) {
483 debug_script_log("%s: Start following %s (dist %d, eager %d)", chaa->scrname, tofollow->scrname, distaway, eagerness);
484 }
485 else {
486 debug_script_log("%s: Stop following other character", chaa->scrname);
487 }
488
489 if ((chaa->following >= 0) &&
490 (chaa->followinfo == FOLLOW_ALWAYSONTOP)) {
491 // if this character was following always-on-top, its baseline will
492 // have been changed, so release it.
493 chaa->baseline = -1;
494 }
495
496 if (tofollow == NULL)
497 chaa->following = -1;
498 else
499 chaa->following = tofollow->index_id;
500
501 chaa->followinfo=(distaway << 8) | eagerness;
502
503 chaa->flags &= ~CHF_BEHINDSHEPHERD;
504
505 // special case for Always On Other Character
506 if (distaway == FOLLOW_ALWAYSONTOP) {
507 chaa->followinfo = FOLLOW_ALWAYSONTOP;
508 if (eagerness == 1)
509 chaa->flags |= CHF_BEHINDSHEPHERD;
510 }
511
512 if (chaa->animating & CHANIM_REPEAT)
513 debug_script_warn("Warning: FollowCharacter called but the sheep is currently animating looped. It may never start to follow.");
514
515 }
516
Character_IsCollidingWithChar(CharacterInfo * char1,CharacterInfo * char2)517 int Character_IsCollidingWithChar(CharacterInfo *char1, CharacterInfo *char2) {
518 if (char2 == NULL)
519 quit("!AreCharactersColliding: invalid char2");
520
521 if (char1->room != char2->room) return 0; // not colliding
522
523 if ((char1->y > char2->y - 5) && (char1->y < char2->y + 5)) ;
524 else return 0;
525
526 int w1 = divide_down_coordinate(GetCharacterWidth(char1->index_id));
527 int w2 = divide_down_coordinate(GetCharacterWidth(char2->index_id));
528
529 int xps1=char1->x - w1/2;
530 int xps2=char2->x - w2/2;
531
532 if ((xps1 >= xps2 - w1) & (xps1 <= xps2 + w2)) return 1;
533 return 0;
534 }
535
Character_IsCollidingWithObject(CharacterInfo * chin,ScriptObject * objid)536 int Character_IsCollidingWithObject(CharacterInfo *chin, ScriptObject *objid) {
537 if (objid == NULL)
538 quit("!AreCharObjColliding: invalid object number");
539
540 if (chin->room != displayed_room)
541 return 0;
542 if (objs[objid->id].on != 1)
543 return 0;
544
545 Bitmap *checkblk = GetObjectImage(objid->id, NULL);
546 int objWidth = checkblk->GetWidth();
547 int objHeight = checkblk->GetHeight();
548 int o1x = objs[objid->id].x;
549 int o1y = objs[objid->id].y - divide_down_coordinate(objHeight);
550
551 Bitmap *charpic = GetCharacterImage(chin->index_id, NULL);
552
553 int charWidth = charpic->GetWidth();
554 int charHeight = charpic->GetHeight();
555 int o2x = chin->x - divide_down_coordinate(charWidth) / 2;
556 int o2y = chin->get_effective_y() - 5; // only check feet
557
558 if ((o2x >= o1x - divide_down_coordinate(charWidth)) &&
559 (o2x <= o1x + divide_down_coordinate(objWidth)) &&
560 (o2y >= o1y - 8) &&
561 (o2y <= o1y + divide_down_coordinate(objHeight))) {
562 // the character's feet are on the object
563 if (game.options[OPT_PIXPERFECT] == 0)
564 return 1;
565 // check if they're on a transparent bit of the object
566 int stxp = multiply_up_coordinate(o2x - o1x);
567 int styp = multiply_up_coordinate(o2y - o1y);
568 int maskcol = checkblk->GetMaskColor ();
569 int maskcolc = charpic->GetMaskColor ();
570 int thispix, thispixc;
571 // check each pixel of the object along the char's feet
572 for (int i = 0; i < charWidth; i += get_fixed_pixel_size(1)) {
573 for (int j = 0; j < get_fixed_pixel_size(6); j += get_fixed_pixel_size(1)) {
574 thispix = my_getpixel(checkblk, i + stxp, j + styp);
575 thispixc = my_getpixel(charpic, i, j + (charHeight - get_fixed_pixel_size(5)));
576
577 if ((thispix != -1) && (thispix != maskcol) &&
578 (thispixc != -1) && (thispixc != maskcolc))
579 return 1;
580 }
581 }
582
583 }
584 return 0;
585 }
586
Character_IsInteractionAvailable(CharacterInfo * cchar,int mood)587 bool Character_IsInteractionAvailable(CharacterInfo *cchar, int mood) {
588
589 play.check_interaction_only = 1;
590 RunCharacterInteraction(cchar->index_id, mood);
591 int ciwas = play.check_interaction_only;
592 play.check_interaction_only = 0;
593 return (ciwas == 2);
594 }
595
Character_LockView(CharacterInfo * chap,int vii)596 void Character_LockView(CharacterInfo *chap, int vii) {
597 Character_LockViewEx(chap, vii, STOP_MOVING);
598 }
599
Character_LockViewEx(CharacterInfo * chap,int vii,int stopMoving)600 void Character_LockViewEx(CharacterInfo *chap, int vii, int stopMoving) {
601
602 if ((vii < 1) || (vii > game.numviews)) {
603 char buffer[150];
604 sprintf (buffer, "!SetCharacterView: invalid view number (You said %d, max is %d)", vii, game.numviews);
605 quit(buffer);
606 }
607 vii--;
608
609 debug_script_log("%s: View locked to %d", chap->scrname, vii+1);
610 if (chap->idleleft < 0) {
611 Character_UnlockView(chap);
612 chap->idleleft = chap->idletime;
613 }
614 if (stopMoving != KEEP_MOVING)
615 {
616 Character_StopMoving(chap);
617 }
618 chap->view=vii;
619 chap->animating=0;
620 FindReasonableLoopForCharacter(chap);
621 chap->frame=0;
622 chap->wait=0;
623 chap->flags|=CHF_FIXVIEW;
624 chap->pic_xoffs = 0;
625 chap->pic_yoffs = 0;
626 }
627
Character_LockViewAligned(CharacterInfo * chap,int vii,int loop,int align)628 void Character_LockViewAligned(CharacterInfo *chap, int vii, int loop, int align) {
629 Character_LockViewAlignedEx(chap, vii, loop, align, STOP_MOVING);
630 }
631
Character_LockViewAlignedEx(CharacterInfo * chap,int vii,int loop,int align,int stopMoving)632 void Character_LockViewAlignedEx(CharacterInfo *chap, int vii, int loop, int align, int stopMoving) {
633 if (chap->view < 0)
634 quit("!SetCharacterLoop: character has invalid old view number");
635
636 int sppic = views[chap->view].loops[chap->loop].frames[chap->frame].pic;
637 int leftSide = multiply_up_coordinate(chap->x) - spritewidth[sppic] / 2;
638
639 Character_LockViewEx(chap, vii, stopMoving);
640
641 if ((loop < 0) || (loop >= views[chap->view].numLoops))
642 quit("!SetCharacterViewEx: invalid loop specified");
643
644 chap->loop = loop;
645 chap->frame = 0;
646 int newpic = views[chap->view].loops[chap->loop].frames[chap->frame].pic;
647 int newLeft = multiply_up_coordinate(chap->x) - spritewidth[newpic] / 2;
648 int xdiff = 0;
649
650 if (align == SCALIGN_LEFT)
651 xdiff = leftSide - newLeft;
652 else if (align == SCALIGN_CENTRE)
653 xdiff = 0;
654 else if (align == SCALIGN_RIGHT)
655 xdiff = (leftSide + spritewidth[sppic]) - (newLeft + spritewidth[newpic]);
656 else
657 quit("!SetCharacterViewEx: invalid alignment type specified");
658
659 chap->pic_xoffs = xdiff;
660 chap->pic_yoffs = 0;
661 }
662
Character_LockViewFrame(CharacterInfo * chaa,int view,int loop,int frame)663 void Character_LockViewFrame(CharacterInfo *chaa, int view, int loop, int frame) {
664 Character_LockViewFrameEx(chaa, view, loop, frame, STOP_MOVING);
665 }
666
Character_LockViewFrameEx(CharacterInfo * chaa,int view,int loop,int frame,int stopMoving)667 void Character_LockViewFrameEx(CharacterInfo *chaa, int view, int loop, int frame, int stopMoving) {
668
669 Character_LockViewEx(chaa, view, stopMoving);
670
671 view--;
672 if ((loop < 0) || (loop >= views[view].numLoops))
673 quit("!SetCharacterFrame: invalid loop specified");
674 if ((frame < 0) || (frame >= views[view].loops[loop].numFrames))
675 quit("!SetCharacterFrame: invalid frame specified");
676
677 chaa->loop = loop;
678 chaa->frame = frame;
679 }
680
Character_LockViewOffset(CharacterInfo * chap,int vii,int xoffs,int yoffs)681 void Character_LockViewOffset(CharacterInfo *chap, int vii, int xoffs, int yoffs) {
682 Character_LockViewOffsetEx(chap, vii, xoffs, yoffs, STOP_MOVING);
683 }
684
Character_LockViewOffsetEx(CharacterInfo * chap,int vii,int xoffs,int yoffs,int stopMoving)685 void Character_LockViewOffsetEx(CharacterInfo *chap, int vii, int xoffs, int yoffs, int stopMoving) {
686 Character_LockViewEx(chap, vii, stopMoving);
687
688 if ((current_screen_resolution_multiplier == 1) && (game.IsHiRes())) {
689 // running a 640x400 game at 320x200, adjust
690 xoffs /= 2;
691 yoffs /= 2;
692 }
693 else if ((current_screen_resolution_multiplier > 1) && (!game.IsHiRes())) {
694 // running a 320x200 game at 640x400, adjust
695 xoffs *= 2;
696 yoffs *= 2;
697 }
698
699 chap->pic_xoffs = xoffs;
700 chap->pic_yoffs = yoffs;
701 }
702
Character_LoseInventory(CharacterInfo * chap,ScriptInvItem * invi)703 void Character_LoseInventory(CharacterInfo *chap, ScriptInvItem *invi) {
704
705 if (invi == NULL)
706 quit("!LoseInventoryFromCharacter: invalid invnetory number");
707
708 int inum = invi->id;
709
710 if (chap->inv[inum] > 0)
711 chap->inv[inum]--;
712
713 if ((chap->activeinv == inum) & (chap->inv[inum] < 1)) {
714 chap->activeinv = -1;
715 if ((chap == playerchar) && (GetCursorMode() == MODE_USE))
716 set_cursor_mode(0);
717 }
718
719 int charid = chap->index_id;
720
721 if ((chap->inv[inum] == 0) || (game.options[OPT_DUPLICATEINV] > 0)) {
722 int xx,tt;
723 for (xx = 0; xx < charextra[charid].invorder_count; xx++) {
724 if (charextra[charid].invorder[xx] == inum) {
725 charextra[charid].invorder_count--;
726 for (tt = xx; tt < charextra[charid].invorder_count; tt++)
727 charextra[charid].invorder[tt] = charextra[charid].invorder[tt+1];
728 break;
729 }
730 }
731 }
732 guis_need_update = 1;
733
734 if (chap == playerchar)
735 run_on_event (GE_LOSE_INV, RuntimeScriptValue().SetInt32(inum));
736 }
737
Character_PlaceOnWalkableArea(CharacterInfo * chap)738 void Character_PlaceOnWalkableArea(CharacterInfo *chap)
739 {
740 if (displayed_room < 0)
741 quit("!Character.PlaceOnWalkableArea: no room is currently loaded");
742
743 find_nearest_walkable_area(&chap->x, &chap->y);
744 }
745
Character_RemoveTint(CharacterInfo * chaa)746 void Character_RemoveTint(CharacterInfo *chaa) {
747
748 if (chaa->flags & (CHF_HASTINT | CHF_HASLIGHT)) {
749 debug_script_log("Un-tint %s", chaa->scrname);
750 chaa->flags &= ~(CHF_HASTINT | CHF_HASLIGHT);
751 }
752 else {
753 debug_script_warn("Character.RemoveTint called but character was not tinted");
754 }
755 }
756
Character_GetHasExplicitTint(CharacterInfo * ch)757 int Character_GetHasExplicitTint(CharacterInfo *ch)
758 {
759 return ch->has_explicit_tint() || ((game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v341) && ch->has_explicit_light());
760 }
761
Character_Say(CharacterInfo * chaa,const char * text)762 void Character_Say(CharacterInfo *chaa, const char *text) {
763 _DisplaySpeechCore(chaa->index_id, text);
764 }
765
Character_SayAt(CharacterInfo * chaa,int x,int y,int width,const char * texx)766 void Character_SayAt(CharacterInfo *chaa, int x, int y, int width, const char *texx) {
767
768 DisplaySpeechAt(x, y, width, chaa->index_id, (char*)texx);
769 }
770
Character_SayBackground(CharacterInfo * chaa,const char * texx)771 ScriptOverlay* Character_SayBackground(CharacterInfo *chaa, const char *texx) {
772
773 int ovltype = DisplaySpeechBackground(chaa->index_id, (char*)texx);
774 int ovri = find_overlay_of_type(ovltype);
775 if (ovri<0)
776 quit("!SayBackground internal error: no overlay");
777
778 // Convert the overlay ID to an Overlay object
779 ScriptOverlay *scOver = new ScriptOverlay();
780 scOver->overlayId = ovltype;
781 scOver->borderHeight = 0;
782 scOver->borderWidth = 0;
783 scOver->isBackgroundSpeech = 1;
784 int handl = ccRegisterManagedObject(scOver, scOver);
785 screenover[ovri].associatedOverlayHandle = handl;
786
787 return scOver;
788 }
789
Character_SetAsPlayer(CharacterInfo * chaa)790 void Character_SetAsPlayer(CharacterInfo *chaa) {
791
792 // Set to same character, so ignore.
793 // But only on versions > 2.61. The relevant entry in the 2.62 changelog is:
794 // - Fixed SetPlayerCharacter to do nothing at all if you pass the current
795 // player character to it (previously it was resetting the inventory layout)
796 if ((loaded_game_file_version > kGameVersion_261) && (game.playercharacter == chaa->index_id))
797 return;
798
799 setup_player_character(chaa->index_id);
800
801 //update_invorder();
802
803 debug_script_log("%s is new player character", playerchar->scrname);
804
805 // Within game_start, return now
806 if (displayed_room < 0)
807 return;
808
809 // Ignore invalid room numbers for the character and just place him in
810 // the current room for 2.x. Following script calls to NewRoom() will
811 // make sure this still works as intended.
812 if ((loaded_game_file_version <= kGameVersion_272) && (playerchar->room < 0))
813 playerchar->room = displayed_room;
814
815 if (displayed_room != playerchar->room)
816 NewRoom(playerchar->room);
817 else // make sure it doesn't run the region interactions
818 play.player_on_region = GetRegionAt (playerchar->x, playerchar->y);
819
820 if ((playerchar->activeinv >= 0) && (playerchar->inv[playerchar->activeinv] < 1))
821 playerchar->activeinv = -1;
822
823 // They had inv selected, so change the cursor
824 if (cur_mode == MODE_USE) {
825 if (playerchar->activeinv < 0)
826 SetNextCursor ();
827 else
828 SetActiveInventory (playerchar->activeinv);
829 }
830
831 }
832
833
Character_SetIdleView(CharacterInfo * chaa,int iview,int itime)834 void Character_SetIdleView(CharacterInfo *chaa, int iview, int itime) {
835
836 if (iview == 1)
837 quit("!SetCharacterIdle: view 1 cannot be used as an idle view, sorry.");
838
839 // if an idle anim is currently playing, release it
840 if (chaa->idleleft < 0)
841 Character_UnlockView(chaa);
842
843 chaa->idleview = iview - 1;
844 // make sure they don't appear idle while idle anim is disabled
845 if (iview < 1)
846 itime = 10;
847 chaa->idletime = itime;
848 chaa->idleleft = itime;
849
850 // if not currently animating, reset the wait counter
851 if ((chaa->animating == 0) && (chaa->walking == 0))
852 chaa->wait = 0;
853
854 if (iview >= 1) {
855 debug_script_log("Set %s idle view to %d (time %d)", chaa->scrname, iview, itime);
856 }
857 else {
858 debug_script_log("%s idle view disabled", chaa->scrname);
859 }
860 if (chaa->flags & CHF_FIXVIEW) {
861 debug_script_warn("SetCharacterIdle called while character view locked with SetCharacterView; idle ignored");
862 debug_script_log("View locked, idle will not kick in until Released");
863 }
864 // if they switch to a swimming animation, kick it off immediately
865 if (itime == 0)
866 charextra[chaa->index_id].process_idle_this_time = 1;
867
868 }
869
Character_GetHasExplicitLight(CharacterInfo * ch)870 bool Character_GetHasExplicitLight(CharacterInfo *ch)
871 {
872 return ch->has_explicit_light();
873 }
874
Character_GetLightLevel(CharacterInfo * ch)875 int Character_GetLightLevel(CharacterInfo *ch)
876 {
877 return ch->has_explicit_light() ? charextra[ch->index_id].tint_light : 0;
878 }
879
Character_SetLightLevel(CharacterInfo * chaa,int light_level)880 void Character_SetLightLevel(CharacterInfo *chaa, int light_level)
881 {
882 light_level = Math::Clamp(-100, 100, light_level);
883
884 charextra[chaa->index_id].tint_light = light_level;
885 chaa->flags &= ~CHF_HASTINT;
886 chaa->flags |= CHF_HASLIGHT;
887 }
888
Character_GetTintRed(CharacterInfo * ch)889 int Character_GetTintRed(CharacterInfo *ch)
890 {
891 return ch->has_explicit_tint() ? charextra[ch->index_id].tint_r : 0;
892 }
893
Character_GetTintGreen(CharacterInfo * ch)894 int Character_GetTintGreen(CharacterInfo *ch)
895 {
896 return ch->has_explicit_tint() ? charextra[ch->index_id].tint_g : 0;
897 }
898
Character_GetTintBlue(CharacterInfo * ch)899 int Character_GetTintBlue(CharacterInfo *ch)
900 {
901 return ch->has_explicit_tint() ? charextra[ch->index_id].tint_b : 0;
902 }
903
Character_GetTintSaturation(CharacterInfo * ch)904 int Character_GetTintSaturation(CharacterInfo *ch)
905 {
906 return ch->has_explicit_tint() ? charextra[ch->index_id].tint_level : 0;
907 }
908
Character_GetTintLuminance(CharacterInfo * ch)909 int Character_GetTintLuminance(CharacterInfo *ch)
910 {
911 return ch->has_explicit_tint() ? ((charextra[ch->index_id].tint_light * 10) / 25) : 0;
912 }
913
Character_SetOption(CharacterInfo * chaa,int flag,int yesorno)914 void Character_SetOption(CharacterInfo *chaa, int flag, int yesorno) {
915
916 if ((yesorno < 0) || (yesorno > 1))
917 quit("!SetCharacterProperty: last parameter must be 0 or 1");
918
919 if (flag & CHF_MANUALSCALING) {
920 // backwards compatibility fix
921 Character_SetIgnoreScaling(chaa, yesorno);
922 }
923 else {
924 chaa->flags &= ~flag;
925 if (yesorno)
926 chaa->flags |= flag;
927 }
928
929 }
930
Character_SetSpeed(CharacterInfo * chaa,int xspeed,int yspeed)931 void Character_SetSpeed(CharacterInfo *chaa, int xspeed, int yspeed) {
932
933 if ((xspeed == 0) || (xspeed > 50) || (yspeed == 0) || (yspeed > 50))
934 quit("!SetCharacterSpeedEx: invalid speed value");
935 if (chaa->walking)
936 quit("!SetCharacterSpeedEx: cannot change speed while walking");
937
938 chaa->walkspeed = xspeed;
939
940 if (yspeed == xspeed)
941 chaa->walkspeed_y = UNIFORM_WALK_SPEED;
942 else
943 chaa->walkspeed_y = yspeed;
944 }
945
946
Character_StopMoving(CharacterInfo * charp)947 void Character_StopMoving(CharacterInfo *charp) {
948
949 int chaa = charp->index_id;
950 if (chaa == play.skip_until_char_stops)
951 EndSkippingUntilCharStops();
952
953 if (charextra[chaa].xwas != INVALID_X) {
954 charp->x = charextra[chaa].xwas;
955 charp->y = charextra[chaa].ywas;
956 charextra[chaa].xwas = INVALID_X;
957 }
958 if ((charp->walking > 0) && (charp->walking < TURNING_AROUND)) {
959 // if it's not a MoveCharDirect, make sure they end up on a walkable area
960 if ((mls[charp->walking].direct == 0) && (charp->room == displayed_room))
961 Character_PlaceOnWalkableArea(charp);
962
963 debug_script_log("%s: stop moving", charp->scrname);
964
965 charp->idleleft = charp->idletime;
966 // restart the idle animation straight away
967 charextra[chaa].process_idle_this_time = 1;
968 }
969 if (charp->walking) {
970 // If the character is currently moving, stop them and reset their frame
971 charp->walking = 0;
972 if ((charp->flags & CHF_MOVENOTWALK) == 0)
973 charp->frame = 0;
974 }
975 }
976
Character_Tint(CharacterInfo * chaa,int red,int green,int blue,int opacity,int luminance)977 void Character_Tint(CharacterInfo *chaa, int red, int green, int blue, int opacity, int luminance) {
978 if ((red < 0) || (green < 0) || (blue < 0) ||
979 (red > 255) || (green > 255) || (blue > 255) ||
980 (opacity < 0) || (opacity > 100) ||
981 (luminance < 0) || (luminance > 100))
982 quit("!Character.Tint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100");
983
984 debug_script_log("Set %s tint RGB(%d,%d,%d) %d%%", chaa->scrname, red, green, blue, opacity);
985
986 charextra[chaa->index_id].tint_r = red;
987 charextra[chaa->index_id].tint_g = green;
988 charextra[chaa->index_id].tint_b = blue;
989 charextra[chaa->index_id].tint_level = opacity;
990 charextra[chaa->index_id].tint_light = (luminance * 25) / 10;
991 chaa->flags &= ~CHF_HASLIGHT;
992 chaa->flags |= CHF_HASTINT;
993 }
994
Character_Think(CharacterInfo * chaa,const char * text)995 void Character_Think(CharacterInfo *chaa, const char *text) {
996 _DisplayThoughtCore(chaa->index_id, text);
997 }
998
Character_UnlockView(CharacterInfo * chaa)999 void Character_UnlockView(CharacterInfo *chaa) {
1000 Character_UnlockViewEx(chaa, STOP_MOVING);
1001 }
1002
Character_UnlockViewEx(CharacterInfo * chaa,int stopMoving)1003 void Character_UnlockViewEx(CharacterInfo *chaa, int stopMoving) {
1004 if (chaa->flags & CHF_FIXVIEW) {
1005 debug_script_log("%s: Released view back to default", chaa->scrname);
1006 }
1007 chaa->flags &= ~CHF_FIXVIEW;
1008 chaa->view = chaa->defview;
1009 chaa->frame = 0;
1010 if (stopMoving != KEEP_MOVING)
1011 {
1012 Character_StopMoving(chaa);
1013 }
1014 if (chaa->view >= 0) {
1015 int maxloop = views[chaa->view].numLoops;
1016 if (((chaa->flags & CHF_NODIAGONAL)!=0) && (maxloop > 4))
1017 maxloop = 4;
1018 FindReasonableLoopForCharacter(chaa);
1019 }
1020 chaa->animating = 0;
1021 chaa->idleleft = chaa->idletime;
1022 chaa->pic_xoffs = 0;
1023 chaa->pic_yoffs = 0;
1024 // restart the idle animation straight away
1025 charextra[chaa->index_id].process_idle_this_time = 1;
1026
1027 }
1028
1029
Character_Walk(CharacterInfo * chaa,int x,int y,int blocking,int direct)1030 void Character_Walk(CharacterInfo *chaa, int x, int y, int blocking, int direct)
1031 {
1032 walk_or_move_character(chaa, x, y, blocking, direct, true);
1033 }
1034
Character_Move(CharacterInfo * chaa,int x,int y,int blocking,int direct)1035 void Character_Move(CharacterInfo *chaa, int x, int y, int blocking, int direct)
1036 {
1037 walk_or_move_character(chaa, x, y, blocking, direct, false);
1038 }
1039
Character_WalkStraight(CharacterInfo * chaa,int xx,int yy,int blocking)1040 void Character_WalkStraight(CharacterInfo *chaa, int xx, int yy, int blocking) {
1041
1042 if (chaa->room != displayed_room)
1043 quit("!MoveCharacterStraight: specified character not in current room");
1044
1045 Character_StopMoving(chaa);
1046 int movetox = xx, movetoy = yy;
1047
1048 wallscreen = prepare_walkable_areas(chaa->index_id);
1049
1050 int fromXLowres = convert_to_low_res(chaa->x);
1051 int fromYLowres = convert_to_low_res(chaa->y);
1052 int toXLowres = convert_to_low_res(xx);
1053 int toYLowres = convert_to_low_res(yy);
1054
1055 if (!can_see_from(fromXLowres, fromYLowres, toXLowres, toYLowres)) {
1056 movetox = convert_back_to_high_res(lastcx);
1057 movetoy = convert_back_to_high_res(lastcy);
1058 }
1059
1060 walk_character(chaa->index_id, movetox, movetoy, 1, true);
1061
1062 if ((blocking == BLOCKING) || (blocking == 1))
1063 GameLoopUntilEvent(UNTIL_MOVEEND,(long)&chaa->walking);
1064 else if ((blocking != IN_BACKGROUND) && (blocking != 0))
1065 quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND");
1066
1067 }
1068
Character_RunInteraction(CharacterInfo * chaa,int mood)1069 void Character_RunInteraction(CharacterInfo *chaa, int mood) {
1070
1071 RunCharacterInteraction(chaa->index_id, mood);
1072 }
1073
1074
1075
1076 // **** CHARACTER: PROPERTIES ****
1077
Character_GetProperty(CharacterInfo * chaa,const char * property)1078 int Character_GetProperty(CharacterInfo *chaa, const char *property) {
1079
1080 return get_int_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property);
1081
1082 }
Character_GetPropertyText(CharacterInfo * chaa,const char * property,char * bufer)1083 void Character_GetPropertyText(CharacterInfo *chaa, const char *property, char *bufer) {
1084 get_text_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property, bufer);
1085 }
Character_GetTextProperty(CharacterInfo * chaa,const char * property)1086 const char* Character_GetTextProperty(CharacterInfo *chaa, const char *property) {
1087 return get_text_property_dynamic_string(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property);
1088 }
1089
Character_SetProperty(CharacterInfo * chaa,const char * property,int value)1090 bool Character_SetProperty(CharacterInfo *chaa, const char *property, int value)
1091 {
1092 return set_int_property(play.charProps[chaa->index_id], property, value);
1093 }
1094
Character_SetTextProperty(CharacterInfo * chaa,const char * property,const char * value)1095 bool Character_SetTextProperty(CharacterInfo *chaa, const char *property, const char *value)
1096 {
1097 return set_text_property(play.charProps[chaa->index_id], property, value);
1098 }
1099
Character_GetActiveInventory(CharacterInfo * chaa)1100 ScriptInvItem* Character_GetActiveInventory(CharacterInfo *chaa) {
1101
1102 if (chaa->activeinv <= 0)
1103 return NULL;
1104
1105 return &scrInv[chaa->activeinv];
1106 }
1107
Character_SetActiveInventory(CharacterInfo * chaa,ScriptInvItem * iit)1108 void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem* iit) {
1109 guis_need_update = 1;
1110
1111 if (iit == NULL) {
1112 chaa->activeinv = -1;
1113
1114 if (chaa->index_id == game.playercharacter) {
1115
1116 if (GetCursorMode()==MODE_USE)
1117 set_cursor_mode(0);
1118 }
1119 return;
1120 }
1121
1122 if (chaa->inv[iit->id] < 1)
1123 quit("!SetActiveInventory: character doesn't have any of that inventory");
1124
1125 chaa->activeinv = iit->id;
1126
1127 if (chaa->index_id == game.playercharacter) {
1128 // if it's the player character, update mouse cursor
1129 update_inv_cursor(iit->id);
1130 set_cursor_mode(MODE_USE);
1131 }
1132 }
1133
Character_GetAnimating(CharacterInfo * chaa)1134 int Character_GetAnimating(CharacterInfo *chaa) {
1135 if (chaa->animating)
1136 return 1;
1137 return 0;
1138 }
1139
Character_GetAnimationSpeed(CharacterInfo * chaa)1140 int Character_GetAnimationSpeed(CharacterInfo *chaa) {
1141 return chaa->animspeed;
1142 }
1143
Character_SetAnimationSpeed(CharacterInfo * chaa,int newval)1144 void Character_SetAnimationSpeed(CharacterInfo *chaa, int newval) {
1145
1146 chaa->animspeed = newval;
1147 }
1148
Character_GetBaseline(CharacterInfo * chaa)1149 int Character_GetBaseline(CharacterInfo *chaa) {
1150
1151 if (chaa->baseline < 1)
1152 return 0;
1153
1154 return chaa->baseline;
1155 }
1156
Character_SetBaseline(CharacterInfo * chaa,int basel)1157 void Character_SetBaseline(CharacterInfo *chaa, int basel) {
1158
1159 chaa->baseline = basel;
1160 }
1161
Character_GetBlinkInterval(CharacterInfo * chaa)1162 int Character_GetBlinkInterval(CharacterInfo *chaa) {
1163
1164 return chaa->blinkinterval;
1165 }
1166
Character_SetBlinkInterval(CharacterInfo * chaa,int interval)1167 void Character_SetBlinkInterval(CharacterInfo *chaa, int interval) {
1168
1169 if (interval < 0)
1170 quit("!SetCharacterBlinkView: invalid blink interval");
1171
1172 chaa->blinkinterval = interval;
1173
1174 if (chaa->blinktimer > 0)
1175 chaa->blinktimer = chaa->blinkinterval;
1176 }
1177
Character_GetBlinkView(CharacterInfo * chaa)1178 int Character_GetBlinkView(CharacterInfo *chaa) {
1179
1180 return chaa->blinkview + 1;
1181 }
1182
Character_SetBlinkView(CharacterInfo * chaa,int vii)1183 void Character_SetBlinkView(CharacterInfo *chaa, int vii) {
1184
1185 if (((vii < 2) || (vii > game.numviews)) && (vii != -1))
1186 quit("!SetCharacterBlinkView: invalid view number");
1187
1188 chaa->blinkview = vii - 1;
1189 }
1190
Character_GetBlinkWhileThinking(CharacterInfo * chaa)1191 int Character_GetBlinkWhileThinking(CharacterInfo *chaa) {
1192 if (chaa->flags & CHF_NOBLINKANDTHINK)
1193 return 0;
1194 return 1;
1195 }
1196
Character_SetBlinkWhileThinking(CharacterInfo * chaa,int yesOrNo)1197 void Character_SetBlinkWhileThinking(CharacterInfo *chaa, int yesOrNo) {
1198 chaa->flags &= ~CHF_NOBLINKANDTHINK;
1199 if (yesOrNo == 0)
1200 chaa->flags |= CHF_NOBLINKANDTHINK;
1201 }
1202
Character_GetBlockingHeight(CharacterInfo * chaa)1203 int Character_GetBlockingHeight(CharacterInfo *chaa) {
1204
1205 return chaa->blocking_height;
1206 }
1207
Character_SetBlockingHeight(CharacterInfo * chaa,int hit)1208 void Character_SetBlockingHeight(CharacterInfo *chaa, int hit) {
1209
1210 chaa->blocking_height = hit;
1211 }
1212
Character_GetBlockingWidth(CharacterInfo * chaa)1213 int Character_GetBlockingWidth(CharacterInfo *chaa) {
1214
1215 return chaa->blocking_width;
1216 }
1217
Character_SetBlockingWidth(CharacterInfo * chaa,int wid)1218 void Character_SetBlockingWidth(CharacterInfo *chaa, int wid) {
1219
1220 chaa->blocking_width = wid;
1221 }
1222
Character_GetDiagonalWalking(CharacterInfo * chaa)1223 int Character_GetDiagonalWalking(CharacterInfo *chaa) {
1224
1225 if (chaa->flags & CHF_NODIAGONAL)
1226 return 0;
1227 return 1;
1228 }
1229
Character_SetDiagonalWalking(CharacterInfo * chaa,int yesorno)1230 void Character_SetDiagonalWalking(CharacterInfo *chaa, int yesorno) {
1231
1232 chaa->flags &= ~CHF_NODIAGONAL;
1233 if (!yesorno)
1234 chaa->flags |= CHF_NODIAGONAL;
1235 }
1236
Character_GetClickable(CharacterInfo * chaa)1237 int Character_GetClickable(CharacterInfo *chaa) {
1238
1239 if (chaa->flags & CHF_NOINTERACT)
1240 return 0;
1241 return 1;
1242 }
1243
Character_SetClickable(CharacterInfo * chaa,int clik)1244 void Character_SetClickable(CharacterInfo *chaa, int clik) {
1245
1246 chaa->flags &= ~CHF_NOINTERACT;
1247 // if they don't want it clickable, set the relevant bit
1248 if (clik == 0)
1249 chaa->flags |= CHF_NOINTERACT;
1250 }
1251
Character_GetID(CharacterInfo * chaa)1252 int Character_GetID(CharacterInfo *chaa) {
1253
1254 return chaa->index_id;
1255
1256 }
1257
Character_GetFrame(CharacterInfo * chaa)1258 int Character_GetFrame(CharacterInfo *chaa) {
1259 return chaa->frame;
1260 }
1261
Character_SetFrame(CharacterInfo * chaa,int newval)1262 void Character_SetFrame(CharacterInfo *chaa, int newval) {
1263 chaa->frame = newval;
1264 }
1265
Character_GetIdleView(CharacterInfo * chaa)1266 int Character_GetIdleView(CharacterInfo *chaa) {
1267
1268 if (chaa->idleview < 1)
1269 return -1;
1270
1271 return chaa->idleview + 1;
1272 }
1273
Character_GetIInventoryQuantity(CharacterInfo * chaa,int index)1274 int Character_GetIInventoryQuantity(CharacterInfo *chaa, int index) {
1275 if ((index < 1) || (index >= game.numinvitems))
1276 quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index);
1277
1278 return chaa->inv[index];
1279 }
1280
Character_HasInventory(CharacterInfo * chaa,ScriptInvItem * invi)1281 int Character_HasInventory(CharacterInfo *chaa, ScriptInvItem *invi)
1282 {
1283 if (invi == NULL)
1284 quit("!Character.HasInventory: NULL inventory item supplied");
1285
1286 return (chaa->inv[invi->id] > 0) ? 1 : 0;
1287 }
1288
Character_SetIInventoryQuantity(CharacterInfo * chaa,int index,int quant)1289 void Character_SetIInventoryQuantity(CharacterInfo *chaa, int index, int quant) {
1290 if ((index < 1) || (index >= game.numinvitems))
1291 quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index);
1292
1293 if ((quant < 0) || (quant > 32000))
1294 quitprintf("!Character.InventoryQuantity: invalid quantity %d", quant);
1295
1296 chaa->inv[index] = quant;
1297 }
1298
Character_GetIgnoreLighting(CharacterInfo * chaa)1299 int Character_GetIgnoreLighting(CharacterInfo *chaa) {
1300
1301 if (chaa->flags & CHF_NOLIGHTING)
1302 return 1;
1303 return 0;
1304 }
1305
Character_SetIgnoreLighting(CharacterInfo * chaa,int yesorno)1306 void Character_SetIgnoreLighting(CharacterInfo *chaa, int yesorno) {
1307
1308 chaa->flags &= ~CHF_NOLIGHTING;
1309 if (yesorno)
1310 chaa->flags |= CHF_NOLIGHTING;
1311 }
1312
Character_GetIgnoreScaling(CharacterInfo * chaa)1313 int Character_GetIgnoreScaling(CharacterInfo *chaa) {
1314
1315 if (chaa->flags & CHF_MANUALSCALING)
1316 return 1;
1317 return 0;
1318 }
1319
Character_SetIgnoreScaling(CharacterInfo * chaa,int yesorno)1320 void Character_SetIgnoreScaling(CharacterInfo *chaa, int yesorno) {
1321
1322 if (yesorno) {
1323 // when setting IgnoreScaling to 1, should reset zoom level
1324 // like it used to in pre-2.71
1325 charextra[chaa->index_id].zoom = 100;
1326 }
1327 Character_SetManualScaling(chaa, yesorno);
1328 }
1329
Character_SetManualScaling(CharacterInfo * chaa,int yesorno)1330 void Character_SetManualScaling(CharacterInfo *chaa, int yesorno) {
1331
1332 chaa->flags &= ~CHF_MANUALSCALING;
1333 if (yesorno)
1334 chaa->flags |= CHF_MANUALSCALING;
1335 }
1336
Character_GetIgnoreWalkbehinds(CharacterInfo * chaa)1337 int Character_GetIgnoreWalkbehinds(CharacterInfo *chaa) {
1338
1339 if (chaa->flags & CHF_NOWALKBEHINDS)
1340 return 1;
1341 return 0;
1342 }
1343
Character_SetIgnoreWalkbehinds(CharacterInfo * chaa,int yesorno)1344 void Character_SetIgnoreWalkbehinds(CharacterInfo *chaa, int yesorno) {
1345
1346 chaa->flags &= ~CHF_NOWALKBEHINDS;
1347 if (yesorno)
1348 chaa->flags |= CHF_NOWALKBEHINDS;
1349 }
1350
Character_GetMovementLinkedToAnimation(CharacterInfo * chaa)1351 int Character_GetMovementLinkedToAnimation(CharacterInfo *chaa) {
1352
1353 if (chaa->flags & CHF_ANTIGLIDE)
1354 return 1;
1355 return 0;
1356 }
1357
Character_SetMovementLinkedToAnimation(CharacterInfo * chaa,int yesorno)1358 void Character_SetMovementLinkedToAnimation(CharacterInfo *chaa, int yesorno) {
1359
1360 chaa->flags &= ~CHF_ANTIGLIDE;
1361 if (yesorno)
1362 chaa->flags |= CHF_ANTIGLIDE;
1363 }
1364
Character_GetLoop(CharacterInfo * chaa)1365 int Character_GetLoop(CharacterInfo *chaa) {
1366 return chaa->loop;
1367 }
1368
Character_SetLoop(CharacterInfo * chaa,int newval)1369 void Character_SetLoop(CharacterInfo *chaa, int newval) {
1370 if ((newval < 0) || (newval >= views[chaa->view].numLoops))
1371 quit("!Character.Loop: invalid loop number for this view");
1372
1373 chaa->loop = newval;
1374
1375 if (chaa->frame >= views[chaa->view].loops[chaa->loop].numFrames)
1376 chaa->frame = 0;
1377 }
1378
Character_GetMoving(CharacterInfo * chaa)1379 int Character_GetMoving(CharacterInfo *chaa) {
1380 if (chaa->walking)
1381 return 1;
1382 return 0;
1383 }
1384
Character_GetDestinationX(CharacterInfo * chaa)1385 int Character_GetDestinationX(CharacterInfo *chaa) {
1386 if (chaa->walking) {
1387 MoveList *cmls = &mls[chaa->walking % TURNING_AROUND];
1388 return cmls->pos[cmls->numstage - 1] >> 16;
1389 }
1390 else
1391 return chaa->x;
1392 }
1393
Character_GetDestinationY(CharacterInfo * chaa)1394 int Character_GetDestinationY(CharacterInfo *chaa) {
1395 if (chaa->walking) {
1396 MoveList *cmls = &mls[chaa->walking % TURNING_AROUND];
1397 return cmls->pos[cmls->numstage - 1] & 0xFFFF;
1398 }
1399 else
1400 return chaa->y;
1401 }
1402
Character_GetName(CharacterInfo * chaa)1403 const char* Character_GetName(CharacterInfo *chaa) {
1404 return CreateNewScriptString(chaa->name);
1405 }
1406
Character_SetName(CharacterInfo * chaa,const char * newName)1407 void Character_SetName(CharacterInfo *chaa, const char *newName) {
1408 strncpy(chaa->name, newName, 40);
1409 chaa->name[39] = 0;
1410 }
1411
Character_GetNormalView(CharacterInfo * chaa)1412 int Character_GetNormalView(CharacterInfo *chaa) {
1413 return chaa->defview + 1;
1414 }
1415
Character_GetPreviousRoom(CharacterInfo * chaa)1416 int Character_GetPreviousRoom(CharacterInfo *chaa) {
1417 return chaa->prevroom;
1418 }
1419
Character_GetRoom(CharacterInfo * chaa)1420 int Character_GetRoom(CharacterInfo *chaa) {
1421 return chaa->room;
1422 }
1423
1424
Character_GetScaleMoveSpeed(CharacterInfo * chaa)1425 int Character_GetScaleMoveSpeed(CharacterInfo *chaa) {
1426
1427 if (chaa->flags & CHF_SCALEMOVESPEED)
1428 return 1;
1429 return 0;
1430 }
1431
Character_SetScaleMoveSpeed(CharacterInfo * chaa,int yesorno)1432 void Character_SetScaleMoveSpeed(CharacterInfo *chaa, int yesorno) {
1433
1434 if ((yesorno < 0) || (yesorno > 1))
1435 quit("Character.ScaleMoveSpeed: value must be true or false (1 or 0)");
1436
1437 chaa->flags &= ~CHF_SCALEMOVESPEED;
1438 if (yesorno)
1439 chaa->flags |= CHF_SCALEMOVESPEED;
1440 }
1441
Character_GetScaleVolume(CharacterInfo * chaa)1442 int Character_GetScaleVolume(CharacterInfo *chaa) {
1443
1444 if (chaa->flags & CHF_SCALEVOLUME)
1445 return 1;
1446 return 0;
1447 }
1448
Character_SetScaleVolume(CharacterInfo * chaa,int yesorno)1449 void Character_SetScaleVolume(CharacterInfo *chaa, int yesorno) {
1450
1451 if ((yesorno < 0) || (yesorno > 1))
1452 quit("Character.ScaleVolume: value must be true or false (1 or 0)");
1453
1454 chaa->flags &= ~CHF_SCALEVOLUME;
1455 if (yesorno)
1456 chaa->flags |= CHF_SCALEVOLUME;
1457 }
1458
Character_GetScaling(CharacterInfo * chaa)1459 int Character_GetScaling(CharacterInfo *chaa) {
1460 return charextra[chaa->index_id].zoom;
1461 }
1462
Character_SetScaling(CharacterInfo * chaa,int zoomlevel)1463 void Character_SetScaling(CharacterInfo *chaa, int zoomlevel) {
1464
1465 if ((chaa->flags & CHF_MANUALSCALING) == 0)
1466 quit("!Character.Scaling: cannot set property unless ManualScaling is enabled");
1467 if ((zoomlevel < 5) || (zoomlevel > 200))
1468 quit("!Character.Scaling: scaling level must be between 5 and 200%");
1469
1470 charextra[chaa->index_id].zoom = zoomlevel;
1471 }
1472
Character_GetSolid(CharacterInfo * chaa)1473 int Character_GetSolid(CharacterInfo *chaa) {
1474
1475 if (chaa->flags & CHF_NOBLOCKING)
1476 return 0;
1477 return 1;
1478 }
1479
Character_SetSolid(CharacterInfo * chaa,int yesorno)1480 void Character_SetSolid(CharacterInfo *chaa, int yesorno) {
1481
1482 chaa->flags &= ~CHF_NOBLOCKING;
1483 if (!yesorno)
1484 chaa->flags |= CHF_NOBLOCKING;
1485 }
1486
Character_GetSpeaking(CharacterInfo * chaa)1487 int Character_GetSpeaking(CharacterInfo *chaa) {
1488 if (get_character_currently_talking() == chaa->index_id)
1489 return 1;
1490
1491 return 0;
1492 }
1493
Character_GetSpeechColor(CharacterInfo * chaa)1494 int Character_GetSpeechColor(CharacterInfo *chaa) {
1495
1496 return chaa->talkcolor;
1497 }
1498
Character_SetSpeechColor(CharacterInfo * chaa,int ncol)1499 void Character_SetSpeechColor(CharacterInfo *chaa, int ncol) {
1500
1501 chaa->talkcolor = ncol;
1502 }
1503
Character_SetSpeechAnimationDelay(CharacterInfo * chaa,int newDelay)1504 void Character_SetSpeechAnimationDelay(CharacterInfo *chaa, int newDelay)
1505 {
1506 if (game.options[OPT_GLOBALTALKANIMSPD] != 0)
1507 quit("!Character.SpeechAnimationDelay cannot be set when global speech animation speed is enabled");
1508
1509 chaa->speech_anim_speed = newDelay;
1510 }
1511
Character_GetSpeechView(CharacterInfo * chaa)1512 int Character_GetSpeechView(CharacterInfo *chaa) {
1513
1514 return chaa->talkview + 1;
1515 }
1516
Character_SetSpeechView(CharacterInfo * chaa,int vii)1517 void Character_SetSpeechView(CharacterInfo *chaa, int vii) {
1518 if (vii == -1) {
1519 chaa->talkview = -1;
1520 return;
1521 }
1522
1523 if ((vii < 1) || (vii > game.numviews))
1524 quit("!SetCharacterSpeechView: invalid view number");
1525
1526 chaa->talkview = vii - 1;
1527 }
1528
Character_GetThinking(CharacterInfo * chaa)1529 bool Character_GetThinking(CharacterInfo *chaa)
1530 {
1531 return char_thinking == chaa->index_id;
1532 }
1533
Character_GetThinkingFrame(CharacterInfo * chaa)1534 int Character_GetThinkingFrame(CharacterInfo *chaa)
1535 {
1536 if (char_thinking == chaa->index_id)
1537 return chaa->thinkview > 0 ? chaa->frame : -1;
1538
1539 quit("!Character.ThinkingFrame: character is not currently thinking");
1540 return -1;
1541 }
1542
Character_GetThinkView(CharacterInfo * chaa)1543 int Character_GetThinkView(CharacterInfo *chaa) {
1544
1545 return chaa->thinkview + 1;
1546 }
1547
Character_SetThinkView(CharacterInfo * chaa,int vii)1548 void Character_SetThinkView(CharacterInfo *chaa, int vii) {
1549 if (((vii < 2) || (vii > game.numviews)) && (vii != -1))
1550 quit("!SetCharacterThinkView: invalid view number");
1551
1552 chaa->thinkview = vii - 1;
1553 }
1554
Character_GetTransparency(CharacterInfo * chaa)1555 int Character_GetTransparency(CharacterInfo *chaa) {
1556
1557 return GfxDef::LegacyTrans255ToTrans100(chaa->transparency);
1558 }
1559
Character_SetTransparency(CharacterInfo * chaa,int trans)1560 void Character_SetTransparency(CharacterInfo *chaa, int trans) {
1561
1562 if ((trans < 0) || (trans > 100))
1563 quit("!SetCharTransparent: transparency value must be between 0 and 100");
1564
1565 chaa->transparency = GfxDef::Trans100ToLegacyTrans255(trans);
1566 }
1567
Character_GetTurnBeforeWalking(CharacterInfo * chaa)1568 int Character_GetTurnBeforeWalking(CharacterInfo *chaa) {
1569
1570 if (chaa->flags & CHF_NOTURNING)
1571 return 0;
1572 return 1;
1573 }
1574
Character_SetTurnBeforeWalking(CharacterInfo * chaa,int yesorno)1575 void Character_SetTurnBeforeWalking(CharacterInfo *chaa, int yesorno) {
1576
1577 chaa->flags &= ~CHF_NOTURNING;
1578 if (!yesorno)
1579 chaa->flags |= CHF_NOTURNING;
1580 }
1581
Character_GetView(CharacterInfo * chaa)1582 int Character_GetView(CharacterInfo *chaa) {
1583 return chaa->view + 1;
1584 }
1585
Character_GetWalkSpeedX(CharacterInfo * chaa)1586 int Character_GetWalkSpeedX(CharacterInfo *chaa) {
1587 return chaa->walkspeed;
1588 }
1589
Character_GetWalkSpeedY(CharacterInfo * chaa)1590 int Character_GetWalkSpeedY(CharacterInfo *chaa) {
1591 if (chaa->walkspeed_y != UNIFORM_WALK_SPEED)
1592 return chaa->walkspeed_y;
1593
1594 return chaa->walkspeed;
1595 }
1596
Character_GetX(CharacterInfo * chaa)1597 int Character_GetX(CharacterInfo *chaa) {
1598 return chaa->x;
1599 }
1600
Character_SetX(CharacterInfo * chaa,int newval)1601 void Character_SetX(CharacterInfo *chaa, int newval) {
1602 chaa->x = newval;
1603 }
1604
Character_GetY(CharacterInfo * chaa)1605 int Character_GetY(CharacterInfo *chaa) {
1606 return chaa->y;
1607 }
1608
Character_SetY(CharacterInfo * chaa,int newval)1609 void Character_SetY(CharacterInfo *chaa, int newval) {
1610 chaa->y = newval;
1611 }
1612
Character_GetZ(CharacterInfo * chaa)1613 int Character_GetZ(CharacterInfo *chaa) {
1614 return chaa->z;
1615 }
1616
Character_SetZ(CharacterInfo * chaa,int newval)1617 void Character_SetZ(CharacterInfo *chaa, int newval) {
1618 chaa->z = newval;
1619 }
1620
1621 extern int char_speaking;
1622
Character_GetSpeakingFrame(CharacterInfo * chaa)1623 int Character_GetSpeakingFrame(CharacterInfo *chaa) {
1624
1625 if ((face_talking >= 0) && (facetalkrepeat))
1626 {
1627 if (facetalkchar->index_id == chaa->index_id)
1628 {
1629 return facetalkframe;
1630 }
1631 }
1632 else if (char_speaking >= 0)
1633 {
1634 if (char_speaking == chaa->index_id)
1635 {
1636 return chaa->frame;
1637 }
1638 }
1639
1640 quit("!Character.SpeakingFrame: character is not currently speaking");
1641 return -1;
1642 }
1643
1644 //=============================================================================
1645
1646 // order of loops to turn character in circle from down to down
1647 int turnlooporder[8] = {0, 6, 1, 7, 3, 5, 2, 4};
1648
walk_character(int chac,int tox,int toy,int ignwal,bool autoWalkAnims)1649 void walk_character(int chac,int tox,int toy,int ignwal, bool autoWalkAnims) {
1650 CharacterInfo*chin=&game.chars[chac];
1651 if (chin->room!=displayed_room)
1652 quit("!MoveCharacter: character not in current room");
1653
1654 chin->flags &= ~CHF_MOVENOTWALK;
1655
1656 int toxPassedIn = tox, toyPassedIn = toy;
1657 int charX = convert_to_low_res(chin->x);
1658 int charY = convert_to_low_res(chin->y);
1659 tox = convert_to_low_res(tox);
1660 toy = convert_to_low_res(toy);
1661
1662 if ((tox == charX) && (toy == charY)) {
1663 StopMoving(chac);
1664 debug_script_log("%s already at destination, not moving", chin->scrname);
1665 return;
1666 }
1667
1668 if ((chin->animating) && (autoWalkAnims))
1669 chin->animating = 0;
1670
1671 if (chin->idleleft < 0) {
1672 ReleaseCharacterView(chac);
1673 chin->idleleft=chin->idletime;
1674 }
1675 // stop them to make sure they're on a walkable area
1676 // but save their frame first so that if they're already
1677 // moving it looks smoother
1678 int oldframe = chin->frame;
1679 int waitWas = 0, animWaitWas = 0;
1680 // if they are currently walking, save the current Wait
1681 if (chin->walking)
1682 {
1683 waitWas = chin->walkwait;
1684 animWaitWas = charextra[chac].animwait;
1685 }
1686
1687 StopMoving (chac);
1688 chin->frame = oldframe;
1689 // use toxPassedIn cached variable so the hi-res co-ordinates
1690 // are still displayed as such
1691 debug_script_log("%s: Start move to %d,%d", chin->scrname, toxPassedIn, toyPassedIn);
1692
1693 int move_speed_x = chin->walkspeed;
1694 int move_speed_y = chin->walkspeed;
1695
1696 if (chin->walkspeed_y != UNIFORM_WALK_SPEED)
1697 move_speed_y = chin->walkspeed_y;
1698
1699 if ((move_speed_x == 0) && (move_speed_y == 0)) {
1700 debug_script_warn("Warning: MoveCharacter called for '%s' with walk speed 0", chin->name);
1701 }
1702
1703 set_route_move_speed(move_speed_x, move_speed_y);
1704 set_color_depth(8);
1705 int mslot=find_route(charX, charY, tox, toy, prepare_walkable_areas(chac), chac+CHMLSOFFS, 1, ignwal);
1706 set_color_depth(game.GetColorDepth());
1707 if (mslot>0) {
1708 chin->walking = mslot;
1709 mls[mslot].direct = ignwal;
1710
1711 if ((game.options[OPT_NATIVECOORDINATES] != 0) &&
1712 game.IsHiRes())
1713 {
1714 convert_move_path_to_high_res(&mls[mslot]);
1715 }
1716 // cancel any pending waits on current animations
1717 // or if they were already moving, keep the current wait -
1718 // this prevents a glitch if MoveCharacter is called when they
1719 // are already moving
1720 if (autoWalkAnims)
1721 {
1722 chin->walkwait = waitWas;
1723 charextra[chac].animwait = animWaitWas;
1724
1725 if (mls[mslot].pos[0] != mls[mslot].pos[1]) {
1726 fix_player_sprite(&mls[mslot],chin);
1727 }
1728 }
1729 else
1730 chin->flags |= CHF_MOVENOTWALK;
1731 }
1732 else if (autoWalkAnims) // pathfinder couldn't get a route, stand them still
1733 chin->frame = 0;
1734 }
1735
find_looporder_index(int curloop)1736 int find_looporder_index (int curloop) {
1737 int rr;
1738 for (rr = 0; rr < 8; rr++) {
1739 if (turnlooporder[rr] == curloop)
1740 return rr;
1741 }
1742 return 0;
1743 }
1744
1745 // returns 0 to use diagonal, 1 to not
useDiagonal(CharacterInfo * char1)1746 int useDiagonal (CharacterInfo *char1) {
1747 if ((views[char1->view].numLoops < 8) || ((char1->flags & CHF_NODIAGONAL)!=0))
1748 return 1;
1749 // If they have just provided standing frames for loops 4-7, to
1750 // provide smoother turning
1751 if (views[char1->view].loops[4].numFrames < 2)
1752 return 2;
1753 return 0;
1754 }
1755
1756 // returns 1 normally, or 0 if they only have horizontal animations
hasUpDownLoops(CharacterInfo * char1)1757 int hasUpDownLoops(CharacterInfo *char1) {
1758 // if no loops in the Down animation
1759 // or no loops in the Up animation
1760 if ((views[char1->view].loops[0].numFrames < 1) ||
1761 (views[char1->view].numLoops < 4) ||
1762 (views[char1->view].loops[3].numFrames < 1))
1763 {
1764 return 0;
1765 }
1766
1767 return 1;
1768 }
1769
start_character_turning(CharacterInfo * chinf,int useloop,int no_diagonal)1770 void start_character_turning (CharacterInfo *chinf, int useloop, int no_diagonal) {
1771 // work out how far round they have to turn
1772 int fromidx = find_looporder_index (chinf->loop);
1773 int toidx = find_looporder_index (useloop);
1774 //Display("Curloop: %d, needloop: %d",chinf->loop, useloop);
1775 int ii, go_anticlock = 0;
1776 // work out whether anticlockwise is quicker or not
1777 if ((toidx > fromidx) && ((toidx - fromidx) > 4))
1778 go_anticlock = 1;
1779 if ((toidx < fromidx) && ((fromidx - toidx) < 4))
1780 go_anticlock = 1;
1781 // strip any current turning_around stages
1782 chinf->walking = chinf->walking % TURNING_AROUND;
1783 if (go_anticlock)
1784 chinf->walking += TURNING_BACKWARDS;
1785 else
1786 go_anticlock = -1;
1787
1788 // Allow the diagonal frames just for turning
1789 if (no_diagonal == 2)
1790 no_diagonal = 0;
1791
1792 for (ii = fromidx; ii != toidx; ii -= go_anticlock) {
1793 if (ii < 0)
1794 ii = 7;
1795 if (ii >= 8)
1796 ii = 0;
1797 if (ii == toidx)
1798 break;
1799 if ((turnlooporder[ii] >= 4) && (no_diagonal > 0))
1800 continue;
1801 if (views[chinf->view].loops[turnlooporder[ii]].numFrames < 1)
1802 continue;
1803 if (turnlooporder[ii] < views[chinf->view].numLoops)
1804 chinf->walking += TURNING_AROUND;
1805 }
1806
1807 }
1808
fix_player_sprite(MoveList * cmls,CharacterInfo * chinf)1809 void fix_player_sprite(MoveList*cmls,CharacterInfo*chinf) {
1810 const fixed xpmove = cmls->xpermove[cmls->onstage];
1811 const fixed ypmove = cmls->ypermove[cmls->onstage];
1812
1813 // if not moving, do nothing
1814 if ((xpmove == 0) && (ypmove == 0))
1815 return;
1816
1817 const int useloop = GetDirectionalLoop(chinf, xpmove, ypmove);
1818
1819 if ((game.options[OPT_ROTATECHARS] == 0) || ((chinf->flags & CHF_NOTURNING) != 0)) {
1820 chinf->loop = useloop;
1821 return;
1822 }
1823 if ((chinf->loop > kDirLoop_LastOrthogonal) && ((chinf->flags & CHF_NODIAGONAL)!=0)) {
1824 // They've just been playing an animation with an extended loop number,
1825 // so don't try and rotate using it
1826 chinf->loop = useloop;
1827 return;
1828 }
1829 if ((chinf->loop >= views[chinf->view].numLoops) ||
1830 (views[chinf->view].loops[chinf->loop].numFrames < 1) ||
1831 (hasUpDownLoops(chinf) == 0)) {
1832 // Character is not currently on a valid loop, so don't try to rotate
1833 // eg. left/right only view, but current loop 0
1834 chinf->loop = useloop;
1835 return;
1836 }
1837 const int no_diagonal = useDiagonal (chinf);
1838 start_character_turning (chinf, useloop, no_diagonal);
1839 }
1840
1841 // Check whether two characters have walked into each other
has_hit_another_character(int sourceChar)1842 int has_hit_another_character(int sourceChar) {
1843
1844 // if the character who's moving doesn't Bitmap *, don't bother checking
1845 if (game.chars[sourceChar].flags & CHF_NOBLOCKING)
1846 return -1;
1847
1848 for (int ww = 0; ww < game.numcharacters; ww++) {
1849 if (game.chars[ww].on != 1) continue;
1850 if (game.chars[ww].room != displayed_room) continue;
1851 if (ww == sourceChar) continue;
1852 if (game.chars[ww].flags & CHF_NOBLOCKING) continue;
1853
1854 if (is_char_on_another (sourceChar, ww, NULL, NULL)) {
1855 // we are now overlapping character 'ww'
1856 if ((game.chars[ww].walking) &&
1857 ((game.chars[ww].flags & CHF_AWAITINGMOVE) == 0))
1858 return ww;
1859 }
1860
1861 }
1862 return -1;
1863 }
1864
1865 // Does the next move from the character's movelist.
1866 // Returns 1 if they are now waiting for another char to move,
1867 // otherwise returns 0
doNextCharMoveStep(CharacterInfo * chi,int & char_index,CharacterExtras * chex)1868 int doNextCharMoveStep (CharacterInfo *chi, int &char_index, CharacterExtras *chex) {
1869 int ntf=0, xwas = chi->x, ywas = chi->y;
1870
1871 if (do_movelist_move(&chi->walking,&chi->x,&chi->y) == 2)
1872 {
1873 if ((chi->flags & CHF_MOVENOTWALK) == 0)
1874 fix_player_sprite(&mls[chi->walking], chi);
1875 }
1876
1877 ntf = has_hit_another_character(char_index);
1878 if (ntf >= 0) {
1879 chi->walkwait = 30;
1880 if (game.chars[ntf].walkspeed < 5)
1881 chi->walkwait += (5 - game.chars[ntf].walkspeed) * 5;
1882 // we are now waiting for the other char to move, so
1883 // make sure he doesn't stop for us too
1884
1885 chi->flags |= CHF_AWAITINGMOVE;
1886
1887 if ((chi->flags & CHF_MOVENOTWALK) == 0)
1888 {
1889 chi->frame = 0;
1890 chex->animwait = chi->walkwait;
1891 }
1892
1893 if ((chi->walking < 1) || (chi->walking >= TURNING_AROUND)) ;
1894 else if (mls[chi->walking].onpart > 0) {
1895 mls[chi->walking].onpart --;
1896 chi->x = xwas;
1897 chi->y = ywas;
1898 }
1899 debug_script_log("%s: Bumped into %s, waiting for them to move", chi->scrname, game.chars[ntf].scrname);
1900 return 1;
1901 }
1902 return 0;
1903 }
1904
find_nearest_walkable_area_within(int * xx,int * yy,int range,int step)1905 int find_nearest_walkable_area_within(int *xx, int *yy, int range, int step)
1906 {
1907 int ex, ey, nearest = 99999, thisis, nearx = 0, neary = 0;
1908 int startx = 0, starty = 14;
1909 int roomWidthLowRes = convert_to_low_res(thisroom.width);
1910 int roomHeightLowRes = convert_to_low_res(thisroom.height);
1911 int xwidth = roomWidthLowRes, yheight = roomHeightLowRes;
1912
1913 int xLowRes = convert_to_low_res(xx[0]);
1914 int yLowRes = convert_to_low_res(yy[0]);
1915 int rightEdge = convert_to_low_res(thisroom.right);
1916 int leftEdge = convert_to_low_res(thisroom.left);
1917 int topEdge = convert_to_low_res(thisroom.top);
1918 int bottomEdge = convert_to_low_res(thisroom.bottom);
1919
1920 // tweak because people forget to move the edges sometimes
1921 // if the player is already over the edge, ignore it
1922 if (xLowRes >= rightEdge) rightEdge = roomWidthLowRes;
1923 if (xLowRes <= leftEdge) leftEdge = 0;
1924 if (yLowRes >= bottomEdge) bottomEdge = roomHeightLowRes;
1925 if (yLowRes <= topEdge) topEdge = 0;
1926
1927 if (range > 0)
1928 {
1929 startx = xLowRes - range;
1930 starty = yLowRes - range;
1931 xwidth = startx + range * 2;
1932 yheight = starty + range * 2;
1933 if (startx < 0) startx = 0;
1934 if (starty < 10) starty = 10;
1935 if (xwidth > roomWidthLowRes) xwidth = roomWidthLowRes;
1936 if (yheight > roomHeightLowRes) yheight = roomHeightLowRes;
1937 }
1938
1939 for (ex = startx; ex < xwidth; ex += step) {
1940 for (ey = starty; ey < yheight; ey += step) {
1941 // non-walkalbe, so don't go here
1942 if (thisroom.walls->GetPixel(ex,ey) == 0) continue;
1943 // off a screen edge, don't move them there
1944 if ((ex <= leftEdge) || (ex >= rightEdge) ||
1945 (ey <= topEdge) || (ey >= bottomEdge))
1946 continue;
1947 // otherwise, calculate distance from target
1948 thisis=(int) ::sqrt((double)((ex - xLowRes) * (ex - xLowRes) + (ey - yLowRes) * (ey - yLowRes)));
1949 if (thisis<nearest) { nearest=thisis; nearx=ex; neary=ey; }
1950 }
1951 }
1952 if (nearest < 90000)
1953 {
1954 xx[0] = convert_back_to_high_res(nearx);
1955 yy[0] = convert_back_to_high_res(neary);
1956 return 1;
1957 }
1958
1959 return 0;
1960 }
1961
find_nearest_walkable_area(int * xx,int * yy)1962 void find_nearest_walkable_area (int *xx, int *yy) {
1963
1964
1965 int pixValue = thisroom.walls->GetPixel(convert_to_low_res(xx[0]), convert_to_low_res(yy[0]));
1966 // only fix this code if the game was built with 2.61 or above
1967 if (pixValue == 0 || (loaded_game_file_version >= kGameVersion_261 && pixValue < 1))
1968 {
1969 // First, check every 2 pixels within immediate area
1970 if (!find_nearest_walkable_area_within(xx, yy, 20, 2))
1971 {
1972 // If not, check whole screen at 5 pixel intervals
1973 find_nearest_walkable_area_within(xx, yy, -1, 5);
1974 }
1975 }
1976
1977 }
1978
FindReasonableLoopForCharacter(CharacterInfo * chap)1979 void FindReasonableLoopForCharacter(CharacterInfo *chap) {
1980
1981 if (chap->loop >= views[chap->view].numLoops)
1982 chap->loop=kDirLoop_Default;
1983 if (views[chap->view].numLoops < 1)
1984 quitprintf("!View %d does not have any loops", chap->view + 1);
1985
1986 // if the current loop has no frames, find one that does
1987 if (views[chap->view].loops[chap->loop].numFrames < 1)
1988 {
1989 for (int i = 0; i < views[chap->view].numLoops; i++)
1990 {
1991 if (views[chap->view].loops[i].numFrames > 0) {
1992 chap->loop = i;
1993 break;
1994 }
1995 }
1996 }
1997
1998 }
1999
walk_or_move_character(CharacterInfo * chaa,int x,int y,int blocking,int direct,bool isWalk)2000 void walk_or_move_character(CharacterInfo *chaa, int x, int y, int blocking, int direct, bool isWalk)
2001 {
2002 if (chaa->on != 1)
2003 quit("!MoveCharacterBlocking: character is turned off and cannot be moved");
2004
2005 if ((direct == ANYWHERE) || (direct == 1))
2006 walk_character(chaa->index_id, x, y, 1, isWalk);
2007 else if ((direct == WALKABLE_AREAS) || (direct == 0))
2008 walk_character(chaa->index_id, x, y, 0, isWalk);
2009 else
2010 quit("!Character.Walk: Direct must be ANYWHERE or WALKABLE_AREAS");
2011
2012 if ((blocking == BLOCKING) || (blocking == 1))
2013 GameLoopUntilEvent(UNTIL_MOVEEND,(long)&chaa->walking);
2014 else if ((blocking != IN_BACKGROUND) && (blocking != 0))
2015 quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND");
2016
2017 }
2018
is_valid_character(int newchar)2019 int is_valid_character(int newchar) {
2020 if ((newchar < 0) || (newchar >= game.numcharacters)) return 0;
2021 return 1;
2022 }
2023
wantMoveNow(CharacterInfo * chi,CharacterExtras * chex)2024 int wantMoveNow (CharacterInfo *chi, CharacterExtras *chex) {
2025 // check most likely case first
2026 if ((chex->zoom == 100) || ((chi->flags & CHF_SCALEMOVESPEED) == 0))
2027 return 1;
2028
2029 // the % checks don't work when the counter is negative, so once
2030 // it wraps round, correct it
2031 while (chi->walkwaitcounter < 0) {
2032 chi->walkwaitcounter += 12000;
2033 }
2034
2035 // scaling 170-200%, move 175% speed
2036 if (chex->zoom >= 170) {
2037 if ((chi->walkwaitcounter % 4) >= 1)
2038 return 2;
2039 else
2040 return 1;
2041 }
2042 // scaling 140-170%, move 150% speed
2043 else if (chex->zoom >= 140) {
2044 if ((chi->walkwaitcounter % 2) == 1)
2045 return 2;
2046 else
2047 return 1;
2048 }
2049 // scaling 115-140%, move 125% speed
2050 else if (chex->zoom >= 115) {
2051 if ((chi->walkwaitcounter % 4) >= 3)
2052 return 2;
2053 else
2054 return 1;
2055 }
2056 // scaling 80-120%, normal speed
2057 else if (chex->zoom >= 80)
2058 return 1;
2059 // scaling 60-80%, move 75% speed
2060 if (chex->zoom >= 60) {
2061 if ((chi->walkwaitcounter % 4) >= 1)
2062 return -1;
2063 else if (chex->xwas != INVALID_X) {
2064 // move the second half of the movement to make it smoother
2065 chi->x = chex->xwas;
2066 chi->y = chex->ywas;
2067 chex->xwas = INVALID_X;
2068 }
2069 }
2070 // scaling 30-60%, move 50% speed
2071 else if (chex->zoom >= 30) {
2072 if ((chi->walkwaitcounter % 2) == 1)
2073 return -1;
2074 else if (chex->xwas != INVALID_X) {
2075 // move the second half of the movement to make it smoother
2076 chi->x = chex->xwas;
2077 chi->y = chex->ywas;
2078 chex->xwas = INVALID_X;
2079 }
2080 }
2081 // scaling 0-30%, move 25% speed
2082 else {
2083 if ((chi->walkwaitcounter % 4) >= 3)
2084 return -1;
2085 if (((chi->walkwaitcounter % 4) == 1) && (chex->xwas != INVALID_X)) {
2086 // move the second half of the movement to make it smoother
2087 chi->x = chex->xwas;
2088 chi->y = chex->ywas;
2089 chex->xwas = INVALID_X;
2090 }
2091
2092 }
2093
2094 return 0;
2095 }
2096
setup_player_character(int charid)2097 void setup_player_character(int charid) {
2098 game.playercharacter = charid;
2099 playerchar = &game.chars[charid];
2100 _sc_PlayerCharPtr = ccGetObjectHandleFromAddress((char*)playerchar);
2101 if (loaded_game_file_version < kGameVersion_270) {
2102 ccAddExternalDynamicObject("player", playerchar, &ccDynamicCharacter);
2103 }
2104 }
2105
animate_character(CharacterInfo * chap,int loopn,int sppd,int rept,int noidleoverride,int direction)2106 void animate_character(CharacterInfo *chap, int loopn,int sppd,int rept, int noidleoverride, int direction) {
2107
2108 if ((chap->view < 0) || (chap->view > game.numviews)) {
2109 quitprintf("!AnimateCharacter: you need to set the view number first\n"
2110 "(trying to animate '%s' using loop %d. View is currently %d).",chap->name,loopn,chap->view+1);
2111 }
2112 debug_script_log("%s: Start anim view %d loop %d, spd %d, repeat %d", chap->scrname, chap->view+1, loopn, sppd, rept);
2113 if ((chap->idleleft < 0) && (noidleoverride == 0)) {
2114 // if idle view in progress for the character (and this is not the
2115 // "start idle animation" animate_character call), stop the idle anim
2116 Character_UnlockView(chap);
2117 chap->idleleft=chap->idletime;
2118 }
2119 if ((loopn < 0) || (loopn >= views[chap->view].numLoops))
2120 quit("!AnimateCharacter: invalid loop number specified");
2121 Character_StopMoving(chap);
2122 chap->animating=1;
2123 if (rept) chap->animating |= CHANIM_REPEAT;
2124 if (direction) chap->animating |= CHANIM_BACKWARDS;
2125
2126 chap->animating|=((sppd << 8) & 0xff00);
2127 chap->loop=loopn;
2128
2129 if (direction) {
2130 chap->frame = views[chap->view].loops[loopn].numFrames - 1;
2131 }
2132 else
2133 chap->frame=0;
2134
2135 chap->wait = sppd + views[chap->view].loops[loopn].frames[chap->frame].speed;
2136 CheckViewFrameForCharacter(chap);
2137 }
2138
CheckViewFrameForCharacter(CharacterInfo * chi)2139 void CheckViewFrameForCharacter(CharacterInfo *chi) {
2140
2141 int soundVolume = SCR_NO_VALUE;
2142
2143 if (chi->flags & CHF_SCALEVOLUME) {
2144 // adjust the sound volume using the character's zoom level
2145 int zoom_level = charextra[chi->index_id].zoom;
2146 if (zoom_level == 0)
2147 zoom_level = 100;
2148
2149 soundVolume = zoom_level;
2150
2151 if (soundVolume < 0)
2152 soundVolume = 0;
2153 if (soundVolume > 100)
2154 soundVolume = 100;
2155 }
2156
2157 CheckViewFrame(chi->view, chi->loop, chi->frame, soundVolume);
2158 }
2159
GetCharacterImage(int charid,int * isFlipped)2160 Bitmap *GetCharacterImage(int charid, int *isFlipped)
2161 {
2162 if (!gfxDriver->HasAcceleratedStretchAndFlip())
2163 {
2164 if (actsps[charid + MAX_INIT_SPR] != NULL)
2165 {
2166 // the actsps image is pre-flipped, so no longer register the image as such
2167 if (isFlipped)
2168 *isFlipped = 0;
2169 return actsps[charid + MAX_INIT_SPR];
2170 }
2171 }
2172 CharacterInfo*chin=&game.chars[charid];
2173 int sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic;
2174 return spriteset[sppic];
2175 }
2176
GetCharacterAtLocation(int xx,int yy)2177 CharacterInfo *GetCharacterAtLocation(int xx, int yy) {
2178 int hsnum = GetCharacterAt(xx, yy);
2179 if (hsnum < 0)
2180 return NULL;
2181 return &game.chars[hsnum];
2182 }
2183
2184 extern int char_lowest_yp, obj_lowest_yp;
2185
is_pos_on_character(int xx,int yy)2186 int is_pos_on_character(int xx,int yy) {
2187 int cc,sppic,lowestyp=0,lowestwas=-1;
2188 for (cc=0;cc<game.numcharacters;cc++) {
2189 if (game.chars[cc].room!=displayed_room) continue;
2190 if (game.chars[cc].on==0) continue;
2191 if (game.chars[cc].flags & CHF_NOINTERACT) continue;
2192 if (game.chars[cc].view < 0) continue;
2193 CharacterInfo*chin=&game.chars[cc];
2194
2195 if ((chin->view < 0) ||
2196 (chin->loop >= views[chin->view].numLoops) ||
2197 (chin->frame >= views[chin->view].loops[chin->loop].numFrames))
2198 {
2199 continue;
2200 }
2201
2202 sppic=views[chin->view].loops[chin->loop].frames[chin->frame].pic;
2203 int usewid = charextra[cc].width;
2204 int usehit = charextra[cc].height;
2205 if (usewid==0) usewid=spritewidth[sppic];
2206 if (usehit==0) usehit=spriteheight[sppic];
2207 int xxx = chin->x - divide_down_coordinate(usewid) / 2;
2208 int yyy = chin->get_effective_y() - divide_down_coordinate(usehit);
2209
2210 int mirrored = views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE;
2211 Bitmap *theImage = GetCharacterImage(cc, &mirrored);
2212
2213 if (is_pos_in_sprite(xx,yy,xxx,yyy, theImage,
2214 divide_down_coordinate(usewid),
2215 divide_down_coordinate(usehit), mirrored) == FALSE)
2216 continue;
2217
2218 int use_base = chin->get_baseline();
2219 if (use_base < lowestyp) continue;
2220 lowestyp=use_base;
2221 lowestwas=cc;
2222 }
2223 char_lowest_yp = lowestyp;
2224 return lowestwas;
2225 }
2226
get_char_blocking_rect(int charid,int * x1,int * y1,int * width,int * y2)2227 void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2) {
2228 CharacterInfo *char1 = &game.chars[charid];
2229 int cwidth, fromx;
2230
2231 if (char1->blocking_width < 1)
2232 cwidth = divide_down_coordinate(GetCharacterWidth(charid)) - 4;
2233 else
2234 cwidth = char1->blocking_width;
2235
2236 fromx = char1->x - cwidth/2;
2237 if (fromx < 0) {
2238 cwidth += fromx;
2239 fromx = 0;
2240 }
2241 if (fromx + cwidth >= convert_back_to_high_res(walkable_areas_temp->GetWidth()))
2242 cwidth = convert_back_to_high_res(walkable_areas_temp->GetWidth()) - fromx;
2243
2244 if (x1)
2245 *x1 = fromx;
2246 if (width)
2247 *width = cwidth;
2248 if (y1)
2249 *y1 = char1->get_blocking_top();
2250 if (y2)
2251 *y2 = char1->get_blocking_bottom();
2252 }
2253
2254 // Check whether the source char has walked onto character ww
is_char_on_another(int sourceChar,int ww,int * fromxptr,int * cwidptr)2255 int is_char_on_another (int sourceChar, int ww, int*fromxptr, int*cwidptr) {
2256
2257 int fromx, cwidth;
2258 int y1, y2;
2259 get_char_blocking_rect(ww, &fromx, &y1, &cwidth, &y2);
2260
2261 if (fromxptr)
2262 fromxptr[0] = fromx;
2263 if (cwidptr)
2264 cwidptr[0] = cwidth;
2265
2266 // if the character trying to move is already on top of
2267 // this char somehow, allow them through
2268 if ((sourceChar >= 0) &&
2269 // x/width are left and width co-ords, so they need >= and <
2270 (game.chars[sourceChar].x >= fromx) &&
2271 (game.chars[sourceChar].x < fromx + cwidth) &&
2272 // y1/y2 are the top/bottom co-ords, so they need >= / <=
2273 (game.chars[sourceChar].y >= y1 ) &&
2274 (game.chars[sourceChar].y <= y2 ))
2275 return 1;
2276
2277 return 0;
2278 }
2279
my_getpixel(Bitmap * blk,int x,int y)2280 int my_getpixel(Bitmap *blk, int x, int y) {
2281 if ((x < 0) || (y < 0) || (x >= blk->GetWidth()) || (y >= blk->GetHeight()))
2282 return -1;
2283
2284 // strip the alpha channel
2285 // TODO: is there a way to do this vtable thing with Bitmap?
2286 BITMAP *al_bmp = (BITMAP*)blk->GetAllegroBitmap();
2287 return al_bmp->vtable->getpixel(al_bmp, x, y) & 0x00ffffff;
2288 }
2289
check_click_on_character(int xx,int yy,int mood)2290 int check_click_on_character(int xx,int yy,int mood) {
2291 int lowestwas=is_pos_on_character(xx,yy);
2292 if (lowestwas>=0) {
2293 RunCharacterInteraction (lowestwas, mood);
2294 return 1;
2295 }
2296 return 0;
2297 }
2298
_DisplaySpeechCore(int chid,const char * displbuf)2299 void _DisplaySpeechCore(int chid, const char *displbuf) {
2300 if (displbuf[0] == 0) {
2301 // no text, just update the current character who's speaking
2302 // this allows the portrait side to be switched with an empty
2303 // speech line
2304 play.swap_portrait_lastchar = chid;
2305 return;
2306 }
2307
2308 // adjust timing of text (so that DisplaySpeech("%s", str) pauses
2309 // for the length of the string not 2 frames)
2310 int len = (int)strlen(displbuf);
2311 if (len > source_text_length + 3)
2312 source_text_length = len;
2313
2314 DisplaySpeech(displbuf, chid);
2315 }
2316
_DisplayThoughtCore(int chid,const char * displbuf)2317 void _DisplayThoughtCore(int chid, const char *displbuf) {
2318 // adjust timing of text (so that DisplayThought("%s", str) pauses
2319 // for the length of the string not 2 frames)
2320 int len = (int)strlen(displbuf);
2321 if (len > source_text_length + 3)
2322 source_text_length = len;
2323
2324 int xpp = -1, ypp = -1, width = -1;
2325
2326 if ((game.options[OPT_SPEECHTYPE] == 0) || (game.chars[chid].thinkview <= 0)) {
2327 // lucasarts-style, so we want a speech bubble actually above
2328 // their head (or if they have no think anim in Sierra-style)
2329 width = multiply_up_coordinate(play.speech_bubble_width);
2330 xpp = (multiply_up_coordinate(game.chars[chid].x) - offsetx) - width / 2;
2331 if (xpp < 0)
2332 xpp = 0;
2333 // -1 will automatically put it above the char's head
2334 ypp = -1;
2335 }
2336
2337 _displayspeech ((char*)displbuf, chid, xpp, ypp, width, 1);
2338 }
2339
_displayspeech(const char * texx,int aschar,int xx,int yy,int widd,int isThought)2340 void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int isThought) {
2341 if (!is_valid_character(aschar))
2342 quit("!DisplaySpeech: invalid character");
2343
2344 CharacterInfo *speakingChar = &game.chars[aschar];
2345 if ((speakingChar->view < 0) || (speakingChar->view >= game.numviews))
2346 quit("!DisplaySpeech: character has invalid view");
2347
2348 if (is_text_overlay > 0)
2349 quit("!DisplaySpeech: speech was already displayed (nested DisplaySpeech, perhaps room script and global script conflict?)");
2350
2351 EndSkippingUntilCharStops();
2352
2353 said_speech_line = 1;
2354
2355 int aa;
2356 if (play.bgspeech_stay_on_display == 0) {
2357 // remove any background speech
2358 for (aa=0;aa<numscreenover;aa++) {
2359 if (screenover[aa].timeout > 0) {
2360 remove_screen_overlay(screenover[aa].type);
2361 aa--;
2362 }
2363 }
2364 }
2365 said_text = 1;
2366
2367 // the strings are pre-translated
2368 //texx = get_translation(texx);
2369 our_eip=150;
2370
2371 int isPause = 1;
2372 // if the message is all .'s, don't display anything
2373 for (aa = 0; texx[aa] != 0; aa++) {
2374 if (texx[aa] != '.') {
2375 isPause = 0;
2376 break;
2377 }
2378 }
2379
2380 play.messagetime = GetTextDisplayTime(texx);
2381 play.speech_in_post_state = false;
2382
2383 if (isPause) {
2384 if (update_music_at > 0)
2385 update_music_at += play.messagetime;
2386 GameLoopUntilEvent(UNTIL_INTISNEG,(long)&play.messagetime);
2387 return;
2388 }
2389
2390 int textcol = speakingChar->talkcolor;
2391
2392 // if it's 0, it won't be recognised as speech
2393 if (textcol == 0)
2394 textcol = 16;
2395
2396 int allowShrink = 0;
2397 int bwidth = widd;
2398 if (bwidth < 0)
2399 bwidth = play.viewport.GetWidth()/2 + play.viewport.GetWidth()/4;
2400
2401 our_eip=151;
2402
2403 int useview = speakingChar->talkview;
2404 if (isThought) {
2405 useview = speakingChar->thinkview;
2406 // view 0 is not valid for think views
2407 if (useview == 0)
2408 useview = -1;
2409 // speech bubble can shrink to fit
2410 allowShrink = 1;
2411 if (speakingChar->room != displayed_room) {
2412 // not in room, centre it
2413 xx = -1;
2414 yy = -1;
2415 }
2416 }
2417
2418 if (useview >= game.numviews)
2419 quitprintf("!Character.Say: attempted to use view %d for animation, but it does not exist", useview + 1);
2420
2421 int tdxp = xx,tdyp = yy;
2422 int oldview=-1, oldloop = -1;
2423 int ovr_type = 0;
2424
2425 text_lips_offset = 0;
2426 text_lips_text = texx;
2427
2428 Bitmap *closeupface=NULL;
2429 if (texx[0]=='&') {
2430 // auto-speech
2431 int igr=atoi(&texx[1]);
2432 while ((texx[0]!=' ') & (texx[0]!=0)) texx++;
2433 if (texx[0]==' ') texx++;
2434 if (igr <= 0)
2435 quit("DisplaySpeech: auto-voice symbol '&' not followed by valid integer");
2436
2437 text_lips_text = texx;
2438
2439 if (play_speech(aschar,igr)) {
2440 if (play.want_speech == 2)
2441 texx = " "; // speech only, no text.
2442 }
2443 }
2444 if (game.options[OPT_SPEECHTYPE] == 3)
2445 remove_screen_overlay(OVER_COMPLETE);
2446 our_eip=1500;
2447
2448 if (game.options[OPT_SPEECHTYPE] == 0)
2449 allowShrink = 1;
2450
2451 if (speakingChar->idleleft < 0) {
2452 // if idle anim in progress for the character, stop it
2453 ReleaseCharacterView(aschar);
2454 // speakingChar->idleleft = speakingChar->idletime;
2455 }
2456
2457 bool overlayPositionFixed = false;
2458 int charFrameWas = 0;
2459 int viewWasLocked = 0;
2460 if (speakingChar->flags & CHF_FIXVIEW)
2461 viewWasLocked = 1;
2462
2463 /*if ((speakingChar->room == displayed_room) ||
2464 ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) ) {*/
2465
2466 if (speakingChar->room == displayed_room) {
2467 // If the character is in this room, go for it - otherwise
2468 // run the "else" clause which does text in the middle of
2469 // the screen.
2470 our_eip=1501;
2471 if (tdxp < 0)
2472 tdxp = multiply_up_coordinate(speakingChar->x) - offsetx;
2473 if (tdxp < 2)
2474 tdxp=2;
2475
2476 if (speakingChar->walking)
2477 StopMoving(aschar);
2478
2479 // save the frame we need to go back to
2480 // if they were moving, this will be 0 (because we just called
2481 // StopMoving); otherwise, it might be a specific animation
2482 // frame which we should return to
2483 if (viewWasLocked)
2484 charFrameWas = speakingChar->frame;
2485
2486 // if the current loop doesn't exist in talking view, use loop 0
2487 if (speakingChar->loop >= views[speakingChar->view].numLoops)
2488 speakingChar->loop = 0;
2489
2490 if ((speakingChar->view < 0) ||
2491 (speakingChar->loop >= views[speakingChar->view].numLoops) ||
2492 (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1))
2493 {
2494 quitprintf("Unable to display speech because the character %s has an invalid view frame (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame);
2495 }
2496
2497 our_eip=1504;
2498
2499 if (tdyp < 0)
2500 {
2501 int sppic = views[speakingChar->view].loops[speakingChar->loop].frames[0].pic;
2502 tdyp = multiply_up_coordinate(speakingChar->get_effective_y()) - offsety - get_fixed_pixel_size(5);
2503 if (charextra[aschar].height < 1)
2504 tdyp -= spriteheight[sppic];
2505 else
2506 tdyp -= charextra[aschar].height;
2507 // if it's a thought, lift it a bit further up
2508 if (isThought)
2509 tdyp -= get_fixed_pixel_size(10);
2510 }
2511
2512 our_eip=1505;
2513 if (tdyp < 5)
2514 tdyp=5;
2515
2516 tdxp=-tdxp; // tell it to centre it
2517 our_eip=152;
2518
2519 if ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) {
2520 // Sierra-style close-up portrait
2521
2522 if (play.swap_portrait_lastchar != aschar) {
2523 // if the portraits are set to Alternate, OR they are
2524 // set to Left but swap_portrait has been set to 1 (the old
2525 // method for enabling it), then swap them round
2526 if ((game.options[OPT_PORTRAITSIDE] == PORTRAIT_ALTERNATE) ||
2527 ((game.options[OPT_PORTRAITSIDE] == 0) &&
2528 (play.swap_portrait_side > 0))) {
2529
2530 if (play.swap_portrait_side == 2)
2531 play.swap_portrait_side = 1;
2532 else
2533 play.swap_portrait_side = 2;
2534 }
2535
2536 if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION) {
2537 // Portrait side based on character X-positions
2538 if (play.swap_portrait_lastchar < 0) {
2539 // No previous character been spoken to
2540 // therefore, assume it's the player
2541 if(game.playercharacter != aschar && game.chars[game.playercharacter].room == speakingChar->room && game.chars[game.playercharacter].on == 1)
2542 play.swap_portrait_lastchar = game.playercharacter;
2543 else
2544 // The player's not here. Find another character in this room
2545 // that it could be
2546 for (int ce = 0; ce < game.numcharacters; ce++) {
2547 if ((game.chars[ce].room == speakingChar->room) &&
2548 (game.chars[ce].on == 1) &&
2549 (ce != aschar)) {
2550 play.swap_portrait_lastchar = ce;
2551 break;
2552 }
2553 }
2554 }
2555
2556 if (play.swap_portrait_lastchar >= 0) {
2557 // if this character is right of the one before, put the
2558 // portrait on the right
2559 if (speakingChar->x > game.chars[play.swap_portrait_lastchar].x)
2560 play.swap_portrait_side = -1;
2561 else
2562 play.swap_portrait_side = 0;
2563 }
2564 }
2565 play.swap_portrait_lastlastchar = play.swap_portrait_lastchar;
2566 play.swap_portrait_lastchar = aschar;
2567 }
2568 else
2569 // If the portrait side is based on the character's X position and the same character is
2570 // speaking, compare against the previous *previous* character to see where the speech should be
2571 if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION && play.swap_portrait_lastlastchar >= 0) {
2572 if (speakingChar->x > game.chars[play.swap_portrait_lastlastchar].x)
2573 play.swap_portrait_side = -1;
2574 else
2575 play.swap_portrait_side = 0;
2576 }
2577
2578 // Determine whether to display the portrait on the left or right
2579 int portrait_on_right = 0;
2580
2581 if (game.options[OPT_SPEECHTYPE] == 3)
2582 { } // always on left with QFG-style speech
2583 else if ((play.swap_portrait_side == 1) ||
2584 (play.swap_portrait_side == -1) ||
2585 (game.options[OPT_PORTRAITSIDE] == PORTRAIT_RIGHT))
2586 portrait_on_right = 1;
2587
2588
2589 int bigx=0,bigy=0,kk;
2590 ViewStruct*viptr=&views[useview];
2591 for (kk = 0; kk < viptr->loops[0].numFrames; kk++)
2592 {
2593 int tw = spritewidth[viptr->loops[0].frames[kk].pic];
2594 if (tw > bigx) bigx=tw;
2595 tw = spriteheight[viptr->loops[0].frames[kk].pic];
2596 if (tw > bigy) bigy=tw;
2597 }
2598
2599 // if they accidentally used a large full-screen image as the sierra-style
2600 // talk view, correct it
2601 if ((game.options[OPT_SPEECHTYPE] != 3) && (bigx > play.viewport.GetWidth() - get_fixed_pixel_size(50)))
2602 bigx = play.viewport.GetWidth() - get_fixed_pixel_size(50);
2603
2604 if (widd > 0)
2605 bwidth = widd - bigx;
2606
2607 our_eip=153;
2608 int ovr_yp = get_fixed_pixel_size(20);
2609 int view_frame_x = 0;
2610 int view_frame_y = 0;
2611 facetalk_qfg4_override_placement_x = false;
2612 facetalk_qfg4_override_placement_y = false;
2613
2614 if (game.options[OPT_SPEECHTYPE] == 3) {
2615 // QFG4-style whole screen picture
2616 closeupface = BitmapHelper::CreateBitmap(play.viewport.GetWidth(), play.viewport.GetHeight(), spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth());
2617 closeupface->Clear(0);
2618 if (xx < 0 && play.speech_portrait_placement)
2619 {
2620 facetalk_qfg4_override_placement_x = true;
2621 view_frame_x = play.speech_portrait_x;
2622 }
2623 if (yy < 0 && play.speech_portrait_placement)
2624 {
2625 facetalk_qfg4_override_placement_y = true;
2626 view_frame_y = play.speech_portrait_y;
2627 }
2628 else
2629 {
2630 view_frame_y = play.viewport.GetHeight()/2 - spriteheight[viptr->loops[0].frames[0].pic]/2;
2631 }
2632 bigx = play.viewport.GetWidth()/2 - get_fixed_pixel_size(20);
2633 ovr_type = OVER_COMPLETE;
2634 ovr_yp = 0;
2635 tdyp = -1; // center vertically
2636 }
2637 else {
2638 // KQ6-style close-up face picture
2639 if (yy < 0 && play.speech_portrait_placement)
2640 {
2641 ovr_yp = play.speech_portrait_y;
2642 }
2643 else if (yy < 0)
2644 ovr_yp = adjust_y_for_guis (ovr_yp);
2645 else
2646 ovr_yp = yy;
2647
2648 closeupface = BitmapHelper::CreateTransparentBitmap(bigx+1,bigy+1,spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth());
2649 ovr_type = OVER_PICTURE;
2650
2651 if (yy < 0)
2652 tdyp = ovr_yp + get_textwindow_top_border_height(play.speech_textwindow_gui);
2653 }
2654 const ViewFrame *vf = &viptr->loops[0].frames[0];
2655 const bool closeupface_has_alpha = (game.spriteflags[vf->pic] & SPF_ALPHACHANNEL) != 0;
2656 DrawViewFrame(closeupface, vf, view_frame_x, view_frame_y);
2657
2658 int overlay_x = get_fixed_pixel_size(10);
2659 if (xx < 0) {
2660 tdxp = bigx + get_textwindow_border_width(play.speech_textwindow_gui) / 2;
2661 if (play.speech_portrait_placement)
2662 {
2663 overlay_x = play.speech_portrait_x;
2664 tdxp += overlay_x + get_fixed_pixel_size(6);
2665 }
2666 else
2667 {
2668 tdxp += get_fixed_pixel_size(16);
2669 }
2670
2671 int maxWidth = (play.viewport.GetWidth() - tdxp) - get_fixed_pixel_size(5) -
2672 get_textwindow_border_width (play.speech_textwindow_gui) / 2;
2673
2674 if (bwidth > maxWidth)
2675 bwidth = maxWidth;
2676 }
2677 else {
2678 tdxp = xx + bigx + get_fixed_pixel_size(8);
2679 overlay_x = xx;
2680 }
2681
2682 // allow the text box to be shrunk to fit the text
2683 allowShrink = 1;
2684
2685 // if the portrait's on the right, swap it round
2686 if (portrait_on_right) {
2687 if ((xx < 0) || (widd < 0)) {
2688 tdxp = get_fixed_pixel_size(9);
2689 if (play.speech_portrait_placement)
2690 {
2691 overlay_x = (play.viewport.GetWidth() - bigx) - play.speech_portrait_x;
2692 int maxWidth = overlay_x - tdxp - get_fixed_pixel_size(9) -
2693 get_textwindow_border_width (play.speech_textwindow_gui) / 2;
2694 if (bwidth > maxWidth)
2695 bwidth = maxWidth;
2696 }
2697 else
2698 {
2699 overlay_x = (play.viewport.GetWidth() - bigx) - get_fixed_pixel_size(5);
2700 }
2701 }
2702 else {
2703 overlay_x = (xx + widd - bigx) - get_fixed_pixel_size(5);
2704 tdxp = xx;
2705 }
2706 tdxp += get_textwindow_border_width(play.speech_textwindow_gui) / 2;
2707 allowShrink = 2;
2708 }
2709 if (game.options[OPT_SPEECHTYPE] == 3)
2710 overlay_x = 0;
2711 face_talking=add_screen_overlay(overlay_x,ovr_yp,ovr_type,closeupface, closeupface_has_alpha);
2712 facetalkframe = 0;
2713 facetalkwait = viptr->loops[0].frames[0].speed + GetCharacterSpeechAnimationDelay(speakingChar);
2714 facetalkloop = 0;
2715 facetalkview = useview;
2716 facetalkrepeat = (isThought) ? 0 : 1;
2717 facetalkBlinkLoop = 0;
2718 facetalkAllowBlink = 1;
2719 if ((isThought) && (speakingChar->flags & CHF_NOBLINKANDTHINK))
2720 facetalkAllowBlink = 0;
2721 facetalkchar = &game.chars[aschar];
2722 if (facetalkchar->blinktimer < 0)
2723 facetalkchar->blinktimer = facetalkchar->blinkinterval;
2724 textcol=-textcol;
2725 overlayPositionFixed = true;
2726 }
2727 else if (useview >= 0) {
2728 // Lucasarts-style speech
2729 our_eip=154;
2730
2731 oldview = speakingChar->view;
2732 oldloop = speakingChar->loop;
2733 speakingChar->animating = 1 | (GetCharacterSpeechAnimationDelay(speakingChar) << 8);
2734 // only repeat if speech, not thought
2735 if (!isThought)
2736 speakingChar->animating |= CHANIM_REPEAT;
2737
2738 speakingChar->view = useview;
2739 speakingChar->frame=0;
2740 speakingChar->flags|=CHF_FIXVIEW;
2741
2742 if (speakingChar->loop >= views[speakingChar->view].numLoops)
2743 {
2744 // current character loop is outside the normal talking directions
2745 speakingChar->loop = 0;
2746 }
2747
2748 facetalkBlinkLoop = speakingChar->loop;
2749
2750 if ((speakingChar->loop >= views[speakingChar->view].numLoops) ||
2751 (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1))
2752 {
2753 quitprintf("!Unable to display speech because the character %s has an invalid speech view (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame);
2754 }
2755
2756 // set up the speed of the first frame
2757 speakingChar->wait = GetCharacterSpeechAnimationDelay(speakingChar) +
2758 views[speakingChar->view].loops[speakingChar->loop].frames[0].speed;
2759
2760 if (widd < 0) {
2761 bwidth = play.viewport.GetWidth()/2 + play.viewport.GetWidth()/6;
2762 // If they are close to the screen edge, make the text narrower
2763 int relx = multiply_up_coordinate(speakingChar->x) - offsetx;
2764 if ((relx < play.viewport.GetWidth() / 4) || (relx > play.viewport.GetWidth() - (play.viewport.GetWidth() / 4)))
2765 bwidth -= play.viewport.GetWidth() / 5;
2766 }
2767 /* this causes the text to bob up and down as they talk
2768 tdxp = OVR_AUTOPLACE;
2769 tdyp = aschar;*/
2770 if (!isThought) // set up the lip sync if not thinking
2771 char_speaking = aschar;
2772
2773 }
2774 }
2775 else
2776 allowShrink = 1;
2777
2778 // it wants the centred position, so make it so
2779 if ((xx >= 0) && (tdxp < 0))
2780 tdxp -= widd / 2;
2781
2782 // if they used DisplaySpeechAt, then use the supplied width
2783 if ((widd > 0) && (isThought == 0))
2784 allowShrink = 0;
2785
2786 if (isThought)
2787 char_thinking = aschar;
2788
2789 our_eip=155;
2790 _display_at(tdxp,tdyp,bwidth,texx,0,textcol, isThought, allowShrink, overlayPositionFixed);
2791 our_eip=156;
2792 if ((play.in_conversation > 0) && (game.options[OPT_SPEECHTYPE] == 3))
2793 closeupface = NULL;
2794 if (closeupface!=NULL)
2795 remove_screen_overlay(ovr_type);
2796 screen_is_dirty = 1;
2797 face_talking = -1;
2798 facetalkchar = NULL;
2799 our_eip=157;
2800 if (oldview>=0) {
2801 speakingChar->flags &= ~CHF_FIXVIEW;
2802 if (viewWasLocked)
2803 speakingChar->flags |= CHF_FIXVIEW;
2804 speakingChar->view=oldview;
2805
2806 // Don't reset the loop in 2.x games
2807 if (loaded_game_file_version > kGameVersion_272)
2808 speakingChar->loop = oldloop;
2809
2810 speakingChar->animating=0;
2811 speakingChar->frame = charFrameWas;
2812 speakingChar->wait=0;
2813 speakingChar->idleleft = speakingChar->idletime;
2814 // restart the idle animation straight away
2815 charextra[aschar].process_idle_this_time = 1;
2816 }
2817 char_speaking = -1;
2818 char_thinking = -1;
2819 stop_speech();
2820 }
2821
get_character_currently_talking()2822 int get_character_currently_talking() {
2823 if ((face_talking >= 0) && (facetalkrepeat))
2824 return facetalkchar->index_id;
2825 else if (char_speaking >= 0)
2826 return char_speaking;
2827
2828 return -1;
2829 }
2830
DisplaySpeech(const char * texx,int aschar)2831 void DisplaySpeech(const char*texx, int aschar) {
2832 _displayspeech (texx, aschar, -1, -1, -1, 0);
2833 }
2834
2835 // Calculate which frame of the loop to use for this character of
2836 // speech
GetLipSyncFrame(const char * curtex,int * stroffs)2837 int GetLipSyncFrame (const char *curtex, int *stroffs) {
2838 /*char *frameletters[MAXLIPSYNCFRAMES] =
2839 {"./,/ ", "A", "O", "F/V", "D/N/G/L/R", "B/P/M",
2840 "Y/H/K/Q/C", "I/T/E/X/th", "U/W", "S/Z/J/ch", NULL,
2841 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};*/
2842
2843 int bestfit_len = 0, bestfit = game.default_lipsync_frame;
2844 for (int aa = 0; aa < MAXLIPSYNCFRAMES; aa++) {
2845 char *tptr = game.lipSyncFrameLetters[aa];
2846 while (tptr[0] != 0) {
2847 int lenthisbit = strlen(tptr);
2848 if (strchr(tptr, '/'))
2849 lenthisbit = strchr(tptr, '/') - tptr;
2850
2851 if ((strnicmp (curtex, tptr, lenthisbit) == 0) && (lenthisbit > bestfit_len)) {
2852 bestfit = aa;
2853 bestfit_len = lenthisbit;
2854 }
2855 tptr += lenthisbit;
2856 while (tptr[0] == '/')
2857 tptr++;
2858 }
2859 }
2860 // If it's an unknown character, use the default frame
2861 if (bestfit_len == 0)
2862 bestfit_len = 1;
2863 *stroffs += bestfit_len;
2864 return bestfit;
2865 }
2866
update_lip_sync(int talkview,int talkloop,int * talkframeptr)2867 int update_lip_sync(int talkview, int talkloop, int *talkframeptr) {
2868 int talkframe = talkframeptr[0];
2869 int talkwait = 0;
2870
2871 // lip-sync speech
2872 const char *nowsaying = &text_lips_text[text_lips_offset];
2873 // if it's an apostraphe, skip it (we'll, I'll, etc)
2874 if (nowsaying[0] == '\'') {
2875 text_lips_offset++;
2876 nowsaying++;
2877 }
2878
2879 if (text_lips_offset >= (int)strlen(text_lips_text))
2880 talkframe = 0;
2881 else {
2882 talkframe = GetLipSyncFrame (nowsaying, &text_lips_offset);
2883 if (talkframe >= views[talkview].loops[talkloop].numFrames)
2884 talkframe = 0;
2885 }
2886
2887 talkwait = loops_per_character + views[talkview].loops[talkloop].frames[talkframe].speed;
2888
2889 talkframeptr[0] = talkframe;
2890 return talkwait;
2891 }
2892
2893 //=============================================================================
2894 //
2895 // Script API Functions
2896 //
2897 //=============================================================================
2898
2899 #include "debug/out.h"
2900 #include "script/script_api.h"
2901 #include "script/script_runtime.h"
2902 #include "ac/dynobj/scriptstring.h"
2903
2904 extern ScriptString myScriptStringImpl;
2905
2906 // void | CharacterInfo *chaa, ScriptInvItem *invi, int addIndex
Sc_Character_AddInventory(void * self,const RuntimeScriptValue * params,int32_t param_count)2907 RuntimeScriptValue Sc_Character_AddInventory(void *self, const RuntimeScriptValue *params, int32_t param_count)
2908 {
2909 API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_AddInventory, ScriptInvItem);
2910 }
2911
2912 // void | CharacterInfo *chaa, int x, int y
Sc_Character_AddWaypoint(void * self,const RuntimeScriptValue * params,int32_t param_count)2913 RuntimeScriptValue Sc_Character_AddWaypoint(void *self, const RuntimeScriptValue *params, int32_t param_count)
2914 {
2915 API_OBJCALL_VOID_PINT2(CharacterInfo, Character_AddWaypoint);
2916 }
2917
2918 // void | CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction
Sc_Character_Animate(void * self,const RuntimeScriptValue * params,int32_t param_count)2919 RuntimeScriptValue Sc_Character_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count)
2920 {
2921 API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Animate);
2922 }
2923
2924 // void | CharacterInfo *chaa, int room, int x, int y
Sc_Character_ChangeRoom(void * self,const RuntimeScriptValue * params,int32_t param_count)2925 RuntimeScriptValue Sc_Character_ChangeRoom(void *self, const RuntimeScriptValue *params, int32_t param_count)
2926 {
2927 API_OBJCALL_VOID_PINT3(CharacterInfo, Character_ChangeRoom);
2928 }
2929
Sc_Character_ChangeRoomSetLoop(void * self,const RuntimeScriptValue * params,int32_t param_count)2930 RuntimeScriptValue Sc_Character_ChangeRoomSetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count)
2931 {
2932 API_OBJCALL_VOID_PINT4(CharacterInfo, Character_ChangeRoomSetLoop);
2933 }
2934
2935 // void | CharacterInfo *chaa, int room, int newPos
Sc_Character_ChangeRoomAutoPosition(void * self,const RuntimeScriptValue * params,int32_t param_count)2936 RuntimeScriptValue Sc_Character_ChangeRoomAutoPosition(void *self, const RuntimeScriptValue *params, int32_t param_count)
2937 {
2938 API_OBJCALL_VOID_PINT2(CharacterInfo, Character_ChangeRoomAutoPosition);
2939 }
2940
2941 // void | CharacterInfo *chap, int vii
Sc_Character_ChangeView(void * self,const RuntimeScriptValue * params,int32_t param_count)2942 RuntimeScriptValue Sc_Character_ChangeView(void *self, const RuntimeScriptValue *params, int32_t param_count)
2943 {
2944 API_OBJCALL_VOID_PINT(CharacterInfo, Character_ChangeView);
2945 }
2946
2947 // void | CharacterInfo *char1, CharacterInfo *char2, int blockingStyle
Sc_Character_FaceCharacter(void * self,const RuntimeScriptValue * params,int32_t param_count)2948 RuntimeScriptValue Sc_Character_FaceCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count)
2949 {
2950 API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceCharacter, CharacterInfo);
2951 }
2952
2953 // void | CharacterInfo *char1, int direction, int blockingStyle
Sc_Character_FaceDirection(void * self,const RuntimeScriptValue * params,int32_t param_count)2954 RuntimeScriptValue Sc_Character_FaceDirection(void *self, const RuntimeScriptValue *params, int32_t param_count)
2955 {
2956 API_OBJCALL_VOID_PINT2(CharacterInfo, Character_FaceDirection);
2957 }
2958
2959 // void | CharacterInfo *char1, int xx, int yy, int blockingStyle
Sc_Character_FaceLocation(void * self,const RuntimeScriptValue * params,int32_t param_count)2960 RuntimeScriptValue Sc_Character_FaceLocation(void *self, const RuntimeScriptValue *params, int32_t param_count)
2961 {
2962 API_OBJCALL_VOID_PINT3(CharacterInfo, Character_FaceLocation);
2963 }
2964
2965 // void | CharacterInfo *char1, ScriptObject *obj, int blockingStyle
Sc_Character_FaceObject(void * self,const RuntimeScriptValue * params,int32_t param_count)2966 RuntimeScriptValue Sc_Character_FaceObject(void *self, const RuntimeScriptValue *params, int32_t param_count)
2967 {
2968 API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceObject, ScriptObject);
2969 }
2970
2971 // void | CharacterInfo *chaa, CharacterInfo *tofollow, int distaway, int eagerness
Sc_Character_FollowCharacter(void * self,const RuntimeScriptValue * params,int32_t param_count)2972 RuntimeScriptValue Sc_Character_FollowCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count)
2973 {
2974 API_OBJCALL_VOID_POBJ_PINT2(CharacterInfo, Character_FollowCharacter, CharacterInfo);
2975 }
2976
2977 // int (CharacterInfo *chaa, const char *property)
Sc_Character_GetProperty(void * self,const RuntimeScriptValue * params,int32_t param_count)2978 RuntimeScriptValue Sc_Character_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count)
2979 {
2980 API_OBJCALL_INT_POBJ(CharacterInfo, Character_GetProperty, const char);
2981 }
2982
2983 // void (CharacterInfo *chaa, const char *property, char *bufer)
Sc_Character_GetPropertyText(void * self,const RuntimeScriptValue * params,int32_t param_count)2984 RuntimeScriptValue Sc_Character_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count)
2985 {
2986 API_OBJCALL_VOID_POBJ2(CharacterInfo, Character_GetPropertyText, const char, char);
2987 }
2988
2989 // const char* (CharacterInfo *chaa, const char *property)
Sc_Character_GetTextProperty(void * self,const RuntimeScriptValue * params,int32_t param_count)2990 RuntimeScriptValue Sc_Character_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count)
2991 {
2992 API_OBJCALL_OBJ_POBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetTextProperty, const char);
2993 }
2994
Sc_Character_SetProperty(void * self,const RuntimeScriptValue * params,int32_t param_count)2995 RuntimeScriptValue Sc_Character_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count)
2996 {
2997 API_OBJCALL_BOOL_POBJ_PINT(CharacterInfo, Character_SetProperty, const char);
2998 }
2999
Sc_Character_SetTextProperty(void * self,const RuntimeScriptValue * params,int32_t param_count)3000 RuntimeScriptValue Sc_Character_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count)
3001 {
3002 API_OBJCALL_BOOL_POBJ2(CharacterInfo, Character_SetTextProperty, const char, const char);
3003 }
3004
3005 // int (CharacterInfo *chaa, ScriptInvItem *invi)
Sc_Character_HasInventory(void * self,const RuntimeScriptValue * params,int32_t param_count)3006 RuntimeScriptValue Sc_Character_HasInventory(void *self, const RuntimeScriptValue *params, int32_t param_count)
3007 {
3008 API_OBJCALL_INT_POBJ(CharacterInfo, Character_HasInventory, ScriptInvItem);
3009 }
3010
3011 // int (CharacterInfo *char1, CharacterInfo *char2)
Sc_Character_IsCollidingWithChar(void * self,const RuntimeScriptValue * params,int32_t param_count)3012 RuntimeScriptValue Sc_Character_IsCollidingWithChar(void *self, const RuntimeScriptValue *params, int32_t param_count)
3013 {
3014 API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithChar, CharacterInfo);
3015 }
3016
3017 // int (CharacterInfo *chin, ScriptObject *objid)
Sc_Character_IsCollidingWithObject(void * self,const RuntimeScriptValue * params,int32_t param_count)3018 RuntimeScriptValue Sc_Character_IsCollidingWithObject(void *self, const RuntimeScriptValue *params, int32_t param_count)
3019 {
3020 API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithObject, ScriptObject);
3021 }
3022
Sc_Character_IsInteractionAvailable(void * self,const RuntimeScriptValue * params,int32_t param_count)3023 RuntimeScriptValue Sc_Character_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count)
3024 {
3025 API_OBJCALL_BOOL_PINT(CharacterInfo, Character_IsInteractionAvailable);
3026 }
3027
3028 // void (CharacterInfo *chap, int vii)
Sc_Character_LockView(void * self,const RuntimeScriptValue * params,int32_t param_count)3029 RuntimeScriptValue Sc_Character_LockView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3030 {
3031 API_OBJCALL_VOID_PINT(CharacterInfo, Character_LockView);
3032 }
3033
3034 // void (CharacterInfo *chap, int vii, int stopMoving)
Sc_Character_LockViewEx(void * self,const RuntimeScriptValue * params,int32_t param_count)3035 RuntimeScriptValue Sc_Character_LockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count)
3036 {
3037 API_OBJCALL_VOID_PINT2(CharacterInfo, Character_LockViewEx);
3038 }
3039
3040 // void (CharacterInfo *chap, int vii, int loop, int align)
Sc_Character_LockViewAligned(void * self,const RuntimeScriptValue * params,int32_t param_count)3041 RuntimeScriptValue Sc_Character_LockViewAligned(void *self, const RuntimeScriptValue *params, int32_t param_count)
3042 {
3043 API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewAligned);
3044 }
3045
3046 // void (CharacterInfo *chap, int vii, int loop, int align, int stopMoving)
Sc_Character_LockViewAlignedEx(void * self,const RuntimeScriptValue * params,int32_t param_count)3047 RuntimeScriptValue Sc_Character_LockViewAlignedEx(void *self, const RuntimeScriptValue *params, int32_t param_count)
3048 {
3049 API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewAlignedEx);
3050 }
3051
3052 // void (CharacterInfo *chaa, int view, int loop, int frame)
Sc_Character_LockViewFrame(void * self,const RuntimeScriptValue * params,int32_t param_count)3053 RuntimeScriptValue Sc_Character_LockViewFrame(void *self, const RuntimeScriptValue *params, int32_t param_count)
3054 {
3055 API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewFrame);
3056 }
3057
3058 // void (CharacterInfo *chaa, int view, int loop, int frame, int stopMoving)
Sc_Character_LockViewFrameEx(void * self,const RuntimeScriptValue * params,int32_t param_count)3059 RuntimeScriptValue Sc_Character_LockViewFrameEx(void *self, const RuntimeScriptValue *params, int32_t param_count)
3060 {
3061 API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewFrameEx);
3062 }
3063
3064 // void (CharacterInfo *chap, int vii, int xoffs, int yoffs)
Sc_Character_LockViewOffset(void * self,const RuntimeScriptValue * params,int32_t param_count)3065 RuntimeScriptValue Sc_Character_LockViewOffset(void *self, const RuntimeScriptValue *params, int32_t param_count)
3066 {
3067 API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewOffset);
3068 }
3069
3070 // void (CharacterInfo *chap, int vii, int xoffs, int yoffs, int stopMoving)
Sc_Character_LockViewOffsetEx(void * self,const RuntimeScriptValue * params,int32_t param_count)3071 RuntimeScriptValue Sc_Character_LockViewOffsetEx(void *self, const RuntimeScriptValue *params, int32_t param_count)
3072 {
3073 API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewOffsetEx);
3074 }
3075
3076 // void (CharacterInfo *chap, ScriptInvItem *invi)
Sc_Character_LoseInventory(void * self,const RuntimeScriptValue * params,int32_t param_count)3077 RuntimeScriptValue Sc_Character_LoseInventory(void *self, const RuntimeScriptValue *params, int32_t param_count)
3078 {
3079 API_OBJCALL_VOID_POBJ(CharacterInfo, Character_LoseInventory, ScriptInvItem);
3080 }
3081
3082 // void (CharacterInfo *chaa, int x, int y, int blocking, int direct)
Sc_Character_Move(void * self,const RuntimeScriptValue * params,int32_t param_count)3083 RuntimeScriptValue Sc_Character_Move(void *self, const RuntimeScriptValue *params, int32_t param_count)
3084 {
3085 API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Move);
3086 }
3087
3088 // void (CharacterInfo *chap)
Sc_Character_PlaceOnWalkableArea(void * self,const RuntimeScriptValue * params,int32_t param_count)3089 RuntimeScriptValue Sc_Character_PlaceOnWalkableArea(void *self, const RuntimeScriptValue *params, int32_t param_count)
3090 {
3091 API_OBJCALL_VOID(CharacterInfo, Character_PlaceOnWalkableArea);
3092 }
3093
3094 // void (CharacterInfo *chaa)
Sc_Character_RemoveTint(void * self,const RuntimeScriptValue * params,int32_t param_count)3095 RuntimeScriptValue Sc_Character_RemoveTint(void *self, const RuntimeScriptValue *params, int32_t param_count)
3096 {
3097 API_OBJCALL_VOID(CharacterInfo, Character_RemoveTint);
3098 }
3099
3100 // void (CharacterInfo *chaa, int mood)
Sc_Character_RunInteraction(void * self,const RuntimeScriptValue * params,int32_t param_count)3101 RuntimeScriptValue Sc_Character_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count)
3102 {
3103 API_OBJCALL_VOID_PINT(CharacterInfo, Character_RunInteraction);
3104 }
3105
3106 // void (CharacterInfo *chaa, const char *texx, ...)
Sc_Character_Say(void * self,const RuntimeScriptValue * params,int32_t param_count)3107 RuntimeScriptValue Sc_Character_Say(void *self, const RuntimeScriptValue *params, int32_t param_count)
3108 {
3109 API_OBJCALL_SCRIPT_SPRINTF(Character_Say, 1);
3110 Character_Say((CharacterInfo*)self, scsf_buffer);
3111 return RuntimeScriptValue((int32_t)0);
3112 }
3113
3114 // void (CharacterInfo *chaa, int x, int y, int width, const char *texx)
Sc_Character_SayAt(void * self,const RuntimeScriptValue * params,int32_t param_count)3115 RuntimeScriptValue Sc_Character_SayAt(void *self, const RuntimeScriptValue *params, int32_t param_count)
3116 {
3117 API_OBJCALL_VOID_PINT3_POBJ(CharacterInfo, Character_SayAt, const char);
3118 }
3119
3120 // ScriptOverlay* (CharacterInfo *chaa, const char *texx)
Sc_Character_SayBackground(void * self,const RuntimeScriptValue * params,int32_t param_count)3121 RuntimeScriptValue Sc_Character_SayBackground(void *self, const RuntimeScriptValue *params, int32_t param_count)
3122 {
3123 API_OBJCALL_OBJAUTO_POBJ(CharacterInfo, ScriptOverlay, Character_SayBackground, const char);
3124 }
3125
3126 // void (CharacterInfo *chaa)
Sc_Character_SetAsPlayer(void * self,const RuntimeScriptValue * params,int32_t param_count)3127 RuntimeScriptValue Sc_Character_SetAsPlayer(void *self, const RuntimeScriptValue *params, int32_t param_count)
3128 {
3129 API_OBJCALL_VOID(CharacterInfo, Character_SetAsPlayer);
3130 }
3131
3132 // void (CharacterInfo *chaa, int iview, int itime)
Sc_Character_SetIdleView(void * self,const RuntimeScriptValue * params,int32_t param_count)3133 RuntimeScriptValue Sc_Character_SetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3134 {
3135 API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIdleView);
3136 }
3137
Sc_Character_HasExplicitLight(void * self,const RuntimeScriptValue * params,int32_t param_count)3138 RuntimeScriptValue Sc_Character_HasExplicitLight(void *self, const RuntimeScriptValue *params, int32_t param_count)
3139 {
3140 API_OBJCALL_BOOL(CharacterInfo, Character_GetHasExplicitLight);
3141 }
3142
Sc_Character_GetLightLevel(void * self,const RuntimeScriptValue * params,int32_t param_count)3143 RuntimeScriptValue Sc_Character_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count)
3144 {
3145 API_OBJCALL_INT(CharacterInfo, Character_GetLightLevel);
3146 }
3147
Sc_Character_SetLightLevel(void * self,const RuntimeScriptValue * params,int32_t param_count)3148 RuntimeScriptValue Sc_Character_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count)
3149 {
3150 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLightLevel);
3151 }
3152
Sc_Character_GetTintBlue(void * self,const RuntimeScriptValue * params,int32_t param_count)3153 RuntimeScriptValue Sc_Character_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count)
3154 {
3155 API_OBJCALL_INT(CharacterInfo, Character_GetTintBlue);
3156 }
3157
Sc_Character_GetTintGreen(void * self,const RuntimeScriptValue * params,int32_t param_count)3158 RuntimeScriptValue Sc_Character_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count)
3159 {
3160 API_OBJCALL_INT(CharacterInfo, Character_GetTintGreen);
3161 }
3162
Sc_Character_GetTintRed(void * self,const RuntimeScriptValue * params,int32_t param_count)3163 RuntimeScriptValue Sc_Character_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count)
3164 {
3165 API_OBJCALL_INT(CharacterInfo, Character_GetTintRed);
3166 }
3167
Sc_Character_GetTintSaturation(void * self,const RuntimeScriptValue * params,int32_t param_count)3168 RuntimeScriptValue Sc_Character_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count)
3169 {
3170 API_OBJCALL_INT(CharacterInfo, Character_GetTintSaturation);
3171 }
3172
Sc_Character_GetTintLuminance(void * self,const RuntimeScriptValue * params,int32_t param_count)3173 RuntimeScriptValue Sc_Character_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count)
3174 {
3175 API_OBJCALL_INT(CharacterInfo, Character_GetTintLuminance);
3176 }
3177
3178 /*
3179 RuntimeScriptValue Sc_Character_SetOption(void *self, const RuntimeScriptValue *params, int32_t param_count)
3180 {
3181 }
3182 */
3183
3184 // void (CharacterInfo *chaa, int xspeed, int yspeed)
Sc_Character_SetSpeed(void * self,const RuntimeScriptValue * params,int32_t param_count)3185 RuntimeScriptValue Sc_Character_SetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count)
3186 {
3187 API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetSpeed);
3188 }
3189
3190 // void (CharacterInfo *charp)
Sc_Character_StopMoving(void * self,const RuntimeScriptValue * params,int32_t param_count)3191 RuntimeScriptValue Sc_Character_StopMoving(void *self, const RuntimeScriptValue *params, int32_t param_count)
3192 {
3193 API_OBJCALL_VOID(CharacterInfo, Character_StopMoving);
3194 }
3195
3196 // void (CharacterInfo *chaa, const char *texx, ...)
Sc_Character_Think(void * self,const RuntimeScriptValue * params,int32_t param_count)3197 RuntimeScriptValue Sc_Character_Think(void *self, const RuntimeScriptValue *params, int32_t param_count)
3198 {
3199 API_OBJCALL_SCRIPT_SPRINTF(Character_Think, 1);
3200 Character_Think((CharacterInfo*)self, scsf_buffer);
3201 return RuntimeScriptValue((int32_t)0);
3202 }
3203
3204 //void (CharacterInfo *chaa, int red, int green, int blue, int opacity, int luminance)
Sc_Character_Tint(void * self,const RuntimeScriptValue * params,int32_t param_count)3205 RuntimeScriptValue Sc_Character_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count)
3206 {
3207 API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Tint);
3208 }
3209
3210 // void (CharacterInfo *chaa)
Sc_Character_UnlockView(void * self,const RuntimeScriptValue * params,int32_t param_count)3211 RuntimeScriptValue Sc_Character_UnlockView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3212 {
3213 API_OBJCALL_VOID(CharacterInfo, Character_UnlockView);
3214 }
3215
3216 // void (CharacterInfo *chaa, int stopMoving)
Sc_Character_UnlockViewEx(void * self,const RuntimeScriptValue * params,int32_t param_count)3217 RuntimeScriptValue Sc_Character_UnlockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count)
3218 {
3219 API_OBJCALL_VOID_PINT(CharacterInfo, Character_UnlockViewEx);
3220 }
3221
3222 // void (CharacterInfo *chaa, int x, int y, int blocking, int direct)
Sc_Character_Walk(void * self,const RuntimeScriptValue * params,int32_t param_count)3223 RuntimeScriptValue Sc_Character_Walk(void *self, const RuntimeScriptValue *params, int32_t param_count)
3224 {
3225 API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Walk);
3226 }
3227
3228 // void (CharacterInfo *chaa, int xx, int yy, int blocking)
Sc_Character_WalkStraight(void * self,const RuntimeScriptValue * params,int32_t param_count)3229 RuntimeScriptValue Sc_Character_WalkStraight(void *self, const RuntimeScriptValue *params, int32_t param_count)
3230 {
3231 API_OBJCALL_VOID_PINT3(CharacterInfo, Character_WalkStraight);
3232 }
3233
3234 // CharacterInfo *(int xx, int yy)
Sc_GetCharacterAtLocation(const RuntimeScriptValue * params,int32_t param_count)3235 RuntimeScriptValue Sc_GetCharacterAtLocation(const RuntimeScriptValue *params, int32_t param_count)
3236 {
3237 API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtLocation);
3238 }
3239
3240 // ScriptInvItem* (CharacterInfo *chaa)
Sc_Character_GetActiveInventory(void * self,const RuntimeScriptValue * params,int32_t param_count)3241 RuntimeScriptValue Sc_Character_GetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count)
3242 {
3243 API_OBJCALL_OBJ(CharacterInfo, ScriptInvItem, ccDynamicInv, Character_GetActiveInventory);
3244 }
3245
3246 // void (CharacterInfo *chaa, ScriptInvItem* iit)
Sc_Character_SetActiveInventory(void * self,const RuntimeScriptValue * params,int32_t param_count)3247 RuntimeScriptValue Sc_Character_SetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count)
3248 {
3249 API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetActiveInventory, ScriptInvItem);
3250 }
3251
3252 // int (CharacterInfo *chaa)
Sc_Character_GetAnimating(void * self,const RuntimeScriptValue * params,int32_t param_count)3253 RuntimeScriptValue Sc_Character_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count)
3254 {
3255 API_OBJCALL_INT(CharacterInfo, Character_GetAnimating);
3256 }
3257
3258 // int (CharacterInfo *chaa)
Sc_Character_GetAnimationSpeed(void * self,const RuntimeScriptValue * params,int32_t param_count)3259 RuntimeScriptValue Sc_Character_GetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count)
3260 {
3261 API_OBJCALL_INT(CharacterInfo, Character_GetAnimationSpeed);
3262 }
3263
3264 // void (CharacterInfo *chaa, int newval)
Sc_Character_SetAnimationSpeed(void * self,const RuntimeScriptValue * params,int32_t param_count)3265 RuntimeScriptValue Sc_Character_SetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count)
3266 {
3267 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetAnimationSpeed);
3268 }
3269
3270 // int (CharacterInfo *chaa)
Sc_Character_GetBaseline(void * self,const RuntimeScriptValue * params,int32_t param_count)3271 RuntimeScriptValue Sc_Character_GetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count)
3272 {
3273 API_OBJCALL_INT(CharacterInfo, Character_GetBaseline);
3274 }
3275
3276 // void (CharacterInfo *chaa, int basel)
Sc_Character_SetBaseline(void * self,const RuntimeScriptValue * params,int32_t param_count)3277 RuntimeScriptValue Sc_Character_SetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count)
3278 {
3279 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBaseline);
3280 }
3281
3282 // int (CharacterInfo *chaa)
Sc_Character_GetBlinkInterval(void * self,const RuntimeScriptValue * params,int32_t param_count)3283 RuntimeScriptValue Sc_Character_GetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count)
3284 {
3285 API_OBJCALL_INT(CharacterInfo, Character_GetBlinkInterval);
3286 }
3287
3288 // void (CharacterInfo *chaa, int interval)
Sc_Character_SetBlinkInterval(void * self,const RuntimeScriptValue * params,int32_t param_count)3289 RuntimeScriptValue Sc_Character_SetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count)
3290 {
3291 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkInterval);
3292 }
3293
3294 // int (CharacterInfo *chaa)
Sc_Character_GetBlinkView(void * self,const RuntimeScriptValue * params,int32_t param_count)3295 RuntimeScriptValue Sc_Character_GetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3296 {
3297 API_OBJCALL_INT(CharacterInfo, Character_GetBlinkView);
3298 }
3299
3300 // void (CharacterInfo *chaa, int vii)
Sc_Character_SetBlinkView(void * self,const RuntimeScriptValue * params,int32_t param_count)3301 RuntimeScriptValue Sc_Character_SetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3302 {
3303 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkView);
3304 }
3305
3306 // int (CharacterInfo *chaa)
Sc_Character_GetBlinkWhileThinking(void * self,const RuntimeScriptValue * params,int32_t param_count)3307 RuntimeScriptValue Sc_Character_GetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3308 {
3309 API_OBJCALL_INT(CharacterInfo, Character_GetBlinkWhileThinking);
3310 }
3311
3312 // void (CharacterInfo *chaa, int yesOrNo)
Sc_Character_SetBlinkWhileThinking(void * self,const RuntimeScriptValue * params,int32_t param_count)3313 RuntimeScriptValue Sc_Character_SetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3314 {
3315 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkWhileThinking);
3316 }
3317
3318 // int (CharacterInfo *chaa)
Sc_Character_GetBlockingHeight(void * self,const RuntimeScriptValue * params,int32_t param_count)3319 RuntimeScriptValue Sc_Character_GetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count)
3320 {
3321 API_OBJCALL_INT(CharacterInfo, Character_GetBlockingHeight);
3322 }
3323
3324 // void (CharacterInfo *chaa, int hit)
Sc_Character_SetBlockingHeight(void * self,const RuntimeScriptValue * params,int32_t param_count)3325 RuntimeScriptValue Sc_Character_SetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count)
3326 {
3327 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingHeight);
3328 }
3329
3330 // int (CharacterInfo *chaa)
Sc_Character_GetBlockingWidth(void * self,const RuntimeScriptValue * params,int32_t param_count)3331 RuntimeScriptValue Sc_Character_GetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count)
3332 {
3333 API_OBJCALL_INT(CharacterInfo, Character_GetBlockingWidth);
3334 }
3335
3336 // void (CharacterInfo *chaa, int wid)
Sc_Character_SetBlockingWidth(void * self,const RuntimeScriptValue * params,int32_t param_count)3337 RuntimeScriptValue Sc_Character_SetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count)
3338 {
3339 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingWidth);
3340 }
3341
3342 // int (CharacterInfo *chaa)
Sc_Character_GetClickable(void * self,const RuntimeScriptValue * params,int32_t param_count)3343 RuntimeScriptValue Sc_Character_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count)
3344 {
3345 API_OBJCALL_INT(CharacterInfo, Character_GetClickable);
3346 }
3347
3348 // void (CharacterInfo *chaa, int clik)
Sc_Character_SetClickable(void * self,const RuntimeScriptValue * params,int32_t param_count)3349 RuntimeScriptValue Sc_Character_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count)
3350 {
3351 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetClickable);
3352 }
3353
3354 // int (CharacterInfo *chaa)
Sc_Character_GetDiagonalWalking(void * self,const RuntimeScriptValue * params,int32_t param_count)3355 RuntimeScriptValue Sc_Character_GetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3356 {
3357 API_OBJCALL_INT(CharacterInfo, Character_GetDiagonalWalking);
3358 }
3359
3360 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetDiagonalWalking(void * self,const RuntimeScriptValue * params,int32_t param_count)3361 RuntimeScriptValue Sc_Character_SetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3362 {
3363 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetDiagonalWalking);
3364 }
3365
3366 // int (CharacterInfo *chaa)
Sc_Character_GetFrame(void * self,const RuntimeScriptValue * params,int32_t param_count)3367 RuntimeScriptValue Sc_Character_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count)
3368 {
3369 API_OBJCALL_INT(CharacterInfo, Character_GetFrame);
3370 }
3371
3372 // void (CharacterInfo *chaa, int newval)
Sc_Character_SetFrame(void * self,const RuntimeScriptValue * params,int32_t param_count)3373 RuntimeScriptValue Sc_Character_SetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count)
3374 {
3375 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetFrame);
3376 }
3377
Sc_Character_GetHasExplicitTint(void * self,const RuntimeScriptValue * params,int32_t param_count)3378 RuntimeScriptValue Sc_Character_GetHasExplicitTint(void *self, const RuntimeScriptValue *params, int32_t param_count)
3379 {
3380 API_OBJCALL_INT(CharacterInfo, Character_GetHasExplicitTint);
3381 }
3382
3383 // int (CharacterInfo *chaa)
Sc_Character_GetID(void * self,const RuntimeScriptValue * params,int32_t param_count)3384 RuntimeScriptValue Sc_Character_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count)
3385 {
3386 API_OBJCALL_INT(CharacterInfo, Character_GetID);
3387 }
3388
3389 // int (CharacterInfo *chaa)
Sc_Character_GetIdleView(void * self,const RuntimeScriptValue * params,int32_t param_count)3390 RuntimeScriptValue Sc_Character_GetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3391 {
3392 API_OBJCALL_INT(CharacterInfo, Character_GetIdleView);
3393 }
3394
3395 // int (CharacterInfo *chaa, int index)
Sc_Character_GetIInventoryQuantity(void * self,const RuntimeScriptValue * params,int32_t param_count)3396 RuntimeScriptValue Sc_Character_GetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count)
3397 {
3398 API_OBJCALL_INT_PINT(CharacterInfo, Character_GetIInventoryQuantity);
3399 }
3400
3401 // void (CharacterInfo *chaa, int index, int quant)
Sc_Character_SetIInventoryQuantity(void * self,const RuntimeScriptValue * params,int32_t param_count)3402 RuntimeScriptValue Sc_Character_SetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count)
3403 {
3404 API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIInventoryQuantity);
3405 }
3406
3407 // int (CharacterInfo *chaa)
Sc_Character_GetIgnoreLighting(void * self,const RuntimeScriptValue * params,int32_t param_count)3408 RuntimeScriptValue Sc_Character_GetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count)
3409 {
3410 API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreLighting);
3411 }
3412
3413 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetIgnoreLighting(void * self,const RuntimeScriptValue * params,int32_t param_count)3414 RuntimeScriptValue Sc_Character_SetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count)
3415 {
3416 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreLighting);
3417 }
3418
3419 // int (CharacterInfo *chaa)
Sc_Character_GetIgnoreScaling(void * self,const RuntimeScriptValue * params,int32_t param_count)3420 RuntimeScriptValue Sc_Character_GetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count)
3421 {
3422 API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreScaling);
3423 }
3424
3425 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetIgnoreScaling(void * self,const RuntimeScriptValue * params,int32_t param_count)3426 RuntimeScriptValue Sc_Character_SetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count)
3427 {
3428 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreScaling);
3429 }
3430
3431 // int (CharacterInfo *chaa)
Sc_Character_GetIgnoreWalkbehinds(void * self,const RuntimeScriptValue * params,int32_t param_count)3432 RuntimeScriptValue Sc_Character_GetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count)
3433 {
3434 API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreWalkbehinds);
3435 }
3436
3437 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetIgnoreWalkbehinds(void * self,const RuntimeScriptValue * params,int32_t param_count)3438 RuntimeScriptValue Sc_Character_SetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count)
3439 {
3440 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreWalkbehinds);
3441 }
3442
3443 // int (CharacterInfo *chaa)
Sc_Character_GetLoop(void * self,const RuntimeScriptValue * params,int32_t param_count)3444 RuntimeScriptValue Sc_Character_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count)
3445 {
3446 API_OBJCALL_INT(CharacterInfo, Character_GetLoop);
3447 }
3448
3449 // void (CharacterInfo *chaa, int newval)
Sc_Character_SetLoop(void * self,const RuntimeScriptValue * params,int32_t param_count)3450 RuntimeScriptValue Sc_Character_SetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count)
3451 {
3452 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLoop);
3453 }
3454
3455 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetManualScaling(void * self,const RuntimeScriptValue * params,int32_t param_count)3456 RuntimeScriptValue Sc_Character_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count)
3457 {
3458 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetManualScaling);
3459 }
3460
3461 // int (CharacterInfo *chaa)
Sc_Character_GetMovementLinkedToAnimation(void * self,const RuntimeScriptValue * params,int32_t param_count)3462 RuntimeScriptValue Sc_Character_GetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count)
3463 {
3464 API_OBJCALL_INT(CharacterInfo, Character_GetMovementLinkedToAnimation);
3465 }
3466
3467 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetMovementLinkedToAnimation(void * self,const RuntimeScriptValue * params,int32_t param_count)3468 RuntimeScriptValue Sc_Character_SetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count)
3469 {
3470 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetMovementLinkedToAnimation);
3471 }
3472
3473 // int (CharacterInfo *chaa)
Sc_Character_GetMoving(void * self,const RuntimeScriptValue * params,int32_t param_count)3474 RuntimeScriptValue Sc_Character_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count)
3475 {
3476 API_OBJCALL_INT(CharacterInfo, Character_GetMoving);
3477 }
3478
3479 // int (CharacterInfo *chaa)
Sc_Character_GetDestinationX(void * self,const RuntimeScriptValue * params,int32_t param_count)3480 RuntimeScriptValue Sc_Character_GetDestinationX(void *self, const RuntimeScriptValue *params, int32_t param_count)
3481 {
3482 API_OBJCALL_INT(CharacterInfo, Character_GetDestinationX);
3483 }
3484
3485 // int (CharacterInfo *chaa)
Sc_Character_GetDestinationY(void * self,const RuntimeScriptValue * params,int32_t param_count)3486 RuntimeScriptValue Sc_Character_GetDestinationY(void *self, const RuntimeScriptValue *params, int32_t param_count)
3487 {
3488 API_OBJCALL_INT(CharacterInfo, Character_GetDestinationY);
3489 }
3490
3491 // const char* (CharacterInfo *chaa)
Sc_Character_GetName(void * self,const RuntimeScriptValue * params,int32_t param_count)3492 RuntimeScriptValue Sc_Character_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count)
3493 {
3494 API_OBJCALL_OBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetName);
3495 }
3496
3497 // void (CharacterInfo *chaa, const char *newName)
Sc_Character_SetName(void * self,const RuntimeScriptValue * params,int32_t param_count)3498 RuntimeScriptValue Sc_Character_SetName(void *self, const RuntimeScriptValue *params, int32_t param_count)
3499 {
3500 API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetName, const char);
3501 }
3502
3503 // int (CharacterInfo *chaa)
Sc_Character_GetNormalView(void * self,const RuntimeScriptValue * params,int32_t param_count)3504 RuntimeScriptValue Sc_Character_GetNormalView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3505 {
3506 API_OBJCALL_INT(CharacterInfo, Character_GetNormalView);
3507 }
3508
3509 // int (CharacterInfo *chaa)
Sc_Character_GetPreviousRoom(void * self,const RuntimeScriptValue * params,int32_t param_count)3510 RuntimeScriptValue Sc_Character_GetPreviousRoom(void *self, const RuntimeScriptValue *params, int32_t param_count)
3511 {
3512 API_OBJCALL_INT(CharacterInfo, Character_GetPreviousRoom);
3513 }
3514
3515 // int (CharacterInfo *chaa)
Sc_Character_GetRoom(void * self,const RuntimeScriptValue * params,int32_t param_count)3516 RuntimeScriptValue Sc_Character_GetRoom(void *self, const RuntimeScriptValue *params, int32_t param_count)
3517 {
3518 API_OBJCALL_INT(CharacterInfo, Character_GetRoom);
3519 }
3520
3521 // int (CharacterInfo *chaa)
Sc_Character_GetScaleMoveSpeed(void * self,const RuntimeScriptValue * params,int32_t param_count)3522 RuntimeScriptValue Sc_Character_GetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count)
3523 {
3524 API_OBJCALL_INT(CharacterInfo, Character_GetScaleMoveSpeed);
3525 }
3526
3527 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetScaleMoveSpeed(void * self,const RuntimeScriptValue * params,int32_t param_count)3528 RuntimeScriptValue Sc_Character_SetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count)
3529 {
3530 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleMoveSpeed);
3531 }
3532
3533 // int (CharacterInfo *chaa)
Sc_Character_GetScaleVolume(void * self,const RuntimeScriptValue * params,int32_t param_count)3534 RuntimeScriptValue Sc_Character_GetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count)
3535 {
3536 API_OBJCALL_INT(CharacterInfo, Character_GetScaleVolume);
3537 }
3538
3539 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetScaleVolume(void * self,const RuntimeScriptValue * params,int32_t param_count)3540 RuntimeScriptValue Sc_Character_SetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count)
3541 {
3542 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleVolume);
3543 }
3544
3545 // int (CharacterInfo *chaa)
Sc_Character_GetScaling(void * self,const RuntimeScriptValue * params,int32_t param_count)3546 RuntimeScriptValue Sc_Character_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count)
3547 {
3548 API_OBJCALL_INT(CharacterInfo, Character_GetScaling);
3549 }
3550
3551 // void (CharacterInfo *chaa, int zoomlevel)
Sc_Character_SetScaling(void * self,const RuntimeScriptValue * params,int32_t param_count)3552 RuntimeScriptValue Sc_Character_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count)
3553 {
3554 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaling);
3555 }
3556
3557 // int (CharacterInfo *chaa)
Sc_Character_GetSolid(void * self,const RuntimeScriptValue * params,int32_t param_count)3558 RuntimeScriptValue Sc_Character_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count)
3559 {
3560 API_OBJCALL_INT(CharacterInfo, Character_GetSolid);
3561 }
3562
3563 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetSolid(void * self,const RuntimeScriptValue * params,int32_t param_count)3564 RuntimeScriptValue Sc_Character_SetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count)
3565 {
3566 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSolid);
3567 }
3568
3569 // int (CharacterInfo *chaa)
Sc_Character_GetSpeaking(void * self,const RuntimeScriptValue * params,int32_t param_count)3570 RuntimeScriptValue Sc_Character_GetSpeaking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3571 {
3572 API_OBJCALL_INT(CharacterInfo, Character_GetSpeaking);
3573 }
3574
3575 // int (CharacterInfo *chaa)
Sc_Character_GetSpeakingFrame(void * self,const RuntimeScriptValue * params,int32_t param_count)3576 RuntimeScriptValue Sc_Character_GetSpeakingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count)
3577 {
3578 API_OBJCALL_INT(CharacterInfo, Character_GetSpeakingFrame);
3579 }
3580
3581 // int (CharacterInfo *cha)
Sc_GetCharacterSpeechAnimationDelay(void * self,const RuntimeScriptValue * params,int32_t param_count)3582 RuntimeScriptValue Sc_GetCharacterSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count)
3583 {
3584 API_OBJCALL_INT(CharacterInfo, GetCharacterSpeechAnimationDelay);
3585 }
3586
3587 // void (CharacterInfo *chaa, int newDelay)
Sc_Character_SetSpeechAnimationDelay(void * self,const RuntimeScriptValue * params,int32_t param_count)3588 RuntimeScriptValue Sc_Character_SetSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count)
3589 {
3590 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechAnimationDelay);
3591 }
3592
3593 // int (CharacterInfo *chaa)
Sc_Character_GetSpeechColor(void * self,const RuntimeScriptValue * params,int32_t param_count)3594 RuntimeScriptValue Sc_Character_GetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count)
3595 {
3596 API_OBJCALL_INT(CharacterInfo, Character_GetSpeechColor);
3597 }
3598
3599 // void (CharacterInfo *chaa, int ncol)
Sc_Character_SetSpeechColor(void * self,const RuntimeScriptValue * params,int32_t param_count)3600 RuntimeScriptValue Sc_Character_SetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count)
3601 {
3602 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechColor);
3603 }
3604
3605 // int (CharacterInfo *chaa)
Sc_Character_GetSpeechView(void * self,const RuntimeScriptValue * params,int32_t param_count)3606 RuntimeScriptValue Sc_Character_GetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3607 {
3608 API_OBJCALL_INT(CharacterInfo, Character_GetSpeechView);
3609 }
3610
3611 // void (CharacterInfo *chaa, int vii)
Sc_Character_SetSpeechView(void * self,const RuntimeScriptValue * params,int32_t param_count)3612 RuntimeScriptValue Sc_Character_SetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3613 {
3614 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechView);
3615 }
3616
Sc_Character_GetThinking(void * self,const RuntimeScriptValue * params,int32_t param_count)3617 RuntimeScriptValue Sc_Character_GetThinking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3618 {
3619 API_OBJCALL_BOOL(CharacterInfo, Character_GetThinking);
3620 }
3621
Sc_Character_GetThinkingFrame(void * self,const RuntimeScriptValue * params,int32_t param_count)3622 RuntimeScriptValue Sc_Character_GetThinkingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count)
3623 {
3624 API_OBJCALL_INT(CharacterInfo, Character_GetThinkingFrame);
3625 }
3626
3627 // int (CharacterInfo *chaa)
Sc_Character_GetThinkView(void * self,const RuntimeScriptValue * params,int32_t param_count)3628 RuntimeScriptValue Sc_Character_GetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3629 {
3630 API_OBJCALL_INT(CharacterInfo, Character_GetThinkView);
3631 }
3632
3633 // void (CharacterInfo *chaa, int vii)
Sc_Character_SetThinkView(void * self,const RuntimeScriptValue * params,int32_t param_count)3634 RuntimeScriptValue Sc_Character_SetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3635 {
3636 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetThinkView);
3637 }
3638
3639 // int (CharacterInfo *chaa)
Sc_Character_GetTransparency(void * self,const RuntimeScriptValue * params,int32_t param_count)3640 RuntimeScriptValue Sc_Character_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count)
3641 {
3642 API_OBJCALL_INT(CharacterInfo, Character_GetTransparency);
3643 }
3644
3645 // void (CharacterInfo *chaa, int trans)
Sc_Character_SetTransparency(void * self,const RuntimeScriptValue * params,int32_t param_count)3646 RuntimeScriptValue Sc_Character_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count)
3647 {
3648 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTransparency);
3649 }
3650
3651 // int (CharacterInfo *chaa)
Sc_Character_GetTurnBeforeWalking(void * self,const RuntimeScriptValue * params,int32_t param_count)3652 RuntimeScriptValue Sc_Character_GetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3653 {
3654 API_OBJCALL_INT(CharacterInfo, Character_GetTurnBeforeWalking);
3655 }
3656
3657 // void (CharacterInfo *chaa, int yesorno)
Sc_Character_SetTurnBeforeWalking(void * self,const RuntimeScriptValue * params,int32_t param_count)3658 RuntimeScriptValue Sc_Character_SetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count)
3659 {
3660 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTurnBeforeWalking);
3661 }
3662
3663 // int (CharacterInfo *chaa)
Sc_Character_GetView(void * self,const RuntimeScriptValue * params,int32_t param_count)3664 RuntimeScriptValue Sc_Character_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count)
3665 {
3666 API_OBJCALL_INT(CharacterInfo, Character_GetView);
3667 }
3668
3669 // int (CharacterInfo *chaa)
Sc_Character_GetWalkSpeedX(void * self,const RuntimeScriptValue * params,int32_t param_count)3670 RuntimeScriptValue Sc_Character_GetWalkSpeedX(void *self, const RuntimeScriptValue *params, int32_t param_count)
3671 {
3672 API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedX);
3673 }
3674
3675 // int (CharacterInfo *chaa)
Sc_Character_GetWalkSpeedY(void * self,const RuntimeScriptValue * params,int32_t param_count)3676 RuntimeScriptValue Sc_Character_GetWalkSpeedY(void *self, const RuntimeScriptValue *params, int32_t param_count)
3677 {
3678 API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedY);
3679 }
3680
3681 // int (CharacterInfo *chaa)
Sc_Character_GetX(void * self,const RuntimeScriptValue * params,int32_t param_count)3682 RuntimeScriptValue Sc_Character_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count)
3683 {
3684 API_OBJCALL_INT(CharacterInfo, Character_GetX);
3685 }
3686
3687 // void (CharacterInfo *chaa, int newval)
Sc_Character_SetX(void * self,const RuntimeScriptValue * params,int32_t param_count)3688 RuntimeScriptValue Sc_Character_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count)
3689 {
3690 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetX);
3691 }
3692
3693 // int (CharacterInfo *chaa)
Sc_Character_GetY(void * self,const RuntimeScriptValue * params,int32_t param_count)3694 RuntimeScriptValue Sc_Character_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count)
3695 {
3696 API_OBJCALL_INT(CharacterInfo, Character_GetY);
3697 }
3698
3699 // void (CharacterInfo *chaa, int newval)
Sc_Character_SetY(void * self,const RuntimeScriptValue * params,int32_t param_count)3700 RuntimeScriptValue Sc_Character_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count)
3701 {
3702 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetY);
3703 }
3704
3705 // int (CharacterInfo *chaa)
Sc_Character_GetZ(void * self,const RuntimeScriptValue * params,int32_t param_count)3706 RuntimeScriptValue Sc_Character_GetZ(void *self, const RuntimeScriptValue *params, int32_t param_count)
3707 {
3708 API_OBJCALL_INT(CharacterInfo, Character_GetZ);
3709 }
3710
3711 // void (CharacterInfo *chaa, int newval)
Sc_Character_SetZ(void * self,const RuntimeScriptValue * params,int32_t param_count)3712 RuntimeScriptValue Sc_Character_SetZ(void *self, const RuntimeScriptValue *params, int32_t param_count)
3713 {
3714 API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetZ);
3715 }
3716
3717 //=============================================================================
3718 //
3719 // Exclusive API for Plugins
3720 //
3721 //=============================================================================
3722
3723 // void (CharacterInfo *chaa, const char *texx, ...)
ScPl_Character_Say(CharacterInfo * chaa,const char * texx,...)3724 void ScPl_Character_Say(CharacterInfo *chaa, const char *texx, ...)
3725 {
3726 API_PLUGIN_SCRIPT_SPRINTF(texx);
3727 Character_Say(chaa, scsf_buffer);
3728 }
3729
3730 // void (CharacterInfo *chaa, const char *texx, ...)
ScPl_Character_Think(CharacterInfo * chaa,const char * texx,...)3731 void ScPl_Character_Think(CharacterInfo *chaa, const char *texx, ...)
3732 {
3733 API_PLUGIN_SCRIPT_SPRINTF(texx);
3734 Character_Think(chaa, scsf_buffer);
3735 }
3736
RegisterCharacterAPI()3737 void RegisterCharacterAPI()
3738 {
3739 ccAddExternalObjectFunction("Character::AddInventory^2", Sc_Character_AddInventory);
3740 ccAddExternalObjectFunction("Character::AddWaypoint^2", Sc_Character_AddWaypoint);
3741 ccAddExternalObjectFunction("Character::Animate^5", Sc_Character_Animate);
3742 ccAddExternalObjectFunction("Character::ChangeRoom^3", Sc_Character_ChangeRoom);
3743 ccAddExternalObjectFunction("Character::ChangeRoom^4", Sc_Character_ChangeRoomSetLoop);
3744 ccAddExternalObjectFunction("Character::ChangeRoomAutoPosition^2", Sc_Character_ChangeRoomAutoPosition);
3745 ccAddExternalObjectFunction("Character::ChangeView^1", Sc_Character_ChangeView);
3746 ccAddExternalObjectFunction("Character::FaceCharacter^2", Sc_Character_FaceCharacter);
3747 ccAddExternalObjectFunction("Character::FaceDirection^2", Sc_Character_FaceDirection);
3748 ccAddExternalObjectFunction("Character::FaceLocation^3", Sc_Character_FaceLocation);
3749 ccAddExternalObjectFunction("Character::FaceObject^2", Sc_Character_FaceObject);
3750 ccAddExternalObjectFunction("Character::FollowCharacter^3", Sc_Character_FollowCharacter);
3751 ccAddExternalObjectFunction("Character::GetProperty^1", Sc_Character_GetProperty);
3752 ccAddExternalObjectFunction("Character::GetPropertyText^2", Sc_Character_GetPropertyText);
3753 ccAddExternalObjectFunction("Character::GetTextProperty^1", Sc_Character_GetTextProperty);
3754 ccAddExternalObjectFunction("Character::SetProperty^2", Sc_Character_SetProperty);
3755 ccAddExternalObjectFunction("Character::SetTextProperty^2", Sc_Character_SetTextProperty);
3756 ccAddExternalObjectFunction("Character::HasInventory^1", Sc_Character_HasInventory);
3757 ccAddExternalObjectFunction("Character::IsCollidingWithChar^1", Sc_Character_IsCollidingWithChar);
3758 ccAddExternalObjectFunction("Character::IsCollidingWithObject^1", Sc_Character_IsCollidingWithObject);
3759 ccAddExternalObjectFunction("Character::IsInteractionAvailable^1", Sc_Character_IsInteractionAvailable);
3760 ccAddExternalObjectFunction("Character::LockView^1", Sc_Character_LockView);
3761 ccAddExternalObjectFunction("Character::LockView^2", Sc_Character_LockViewEx);
3762 ccAddExternalObjectFunction("Character::LockViewAligned^3", Sc_Character_LockViewAligned);
3763 ccAddExternalObjectFunction("Character::LockViewAligned^4", Sc_Character_LockViewAlignedEx);
3764 ccAddExternalObjectFunction("Character::LockViewFrame^3", Sc_Character_LockViewFrame);
3765 ccAddExternalObjectFunction("Character::LockViewFrame^4", Sc_Character_LockViewFrameEx);
3766 ccAddExternalObjectFunction("Character::LockViewOffset^3", Sc_Character_LockViewOffset);
3767 ccAddExternalObjectFunction("Character::LockViewOffset^4", Sc_Character_LockViewOffsetEx);
3768 ccAddExternalObjectFunction("Character::LoseInventory^1", Sc_Character_LoseInventory);
3769 ccAddExternalObjectFunction("Character::Move^4", Sc_Character_Move);
3770 ccAddExternalObjectFunction("Character::PlaceOnWalkableArea^0", Sc_Character_PlaceOnWalkableArea);
3771 ccAddExternalObjectFunction("Character::RemoveTint^0", Sc_Character_RemoveTint);
3772 ccAddExternalObjectFunction("Character::RunInteraction^1", Sc_Character_RunInteraction);
3773 ccAddExternalObjectFunction("Character::Say^101", Sc_Character_Say);
3774 ccAddExternalObjectFunction("Character::SayAt^4", Sc_Character_SayAt);
3775 ccAddExternalObjectFunction("Character::SayBackground^1", Sc_Character_SayBackground);
3776 ccAddExternalObjectFunction("Character::SetAsPlayer^0", Sc_Character_SetAsPlayer);
3777 ccAddExternalObjectFunction("Character::SetIdleView^2", Sc_Character_SetIdleView);
3778 ccAddExternalObjectFunction("Character::SetLightLevel^1", Sc_Character_SetLightLevel);
3779 //ccAddExternalObjectFunction("Character::SetOption^2", Sc_Character_SetOption);
3780 ccAddExternalObjectFunction("Character::SetWalkSpeed^2", Sc_Character_SetSpeed);
3781 ccAddExternalObjectFunction("Character::StopMoving^0", Sc_Character_StopMoving);
3782 ccAddExternalObjectFunction("Character::Think^101", Sc_Character_Think);
3783 ccAddExternalObjectFunction("Character::Tint^5", Sc_Character_Tint);
3784 ccAddExternalObjectFunction("Character::UnlockView^0", Sc_Character_UnlockView);
3785 ccAddExternalObjectFunction("Character::UnlockView^1", Sc_Character_UnlockViewEx);
3786 ccAddExternalObjectFunction("Character::Walk^4", Sc_Character_Walk);
3787 ccAddExternalObjectFunction("Character::WalkStraight^3", Sc_Character_WalkStraight);
3788
3789 ccAddExternalStaticFunction("Character::GetAtScreenXY^2", Sc_GetCharacterAtLocation);
3790
3791 ccAddExternalObjectFunction("Character::get_ActiveInventory", Sc_Character_GetActiveInventory);
3792 ccAddExternalObjectFunction("Character::set_ActiveInventory", Sc_Character_SetActiveInventory);
3793 ccAddExternalObjectFunction("Character::get_Animating", Sc_Character_GetAnimating);
3794 ccAddExternalObjectFunction("Character::get_AnimationSpeed", Sc_Character_GetAnimationSpeed);
3795 ccAddExternalObjectFunction("Character::set_AnimationSpeed", Sc_Character_SetAnimationSpeed);
3796 ccAddExternalObjectFunction("Character::get_Baseline", Sc_Character_GetBaseline);
3797 ccAddExternalObjectFunction("Character::set_Baseline", Sc_Character_SetBaseline);
3798 ccAddExternalObjectFunction("Character::get_BlinkInterval", Sc_Character_GetBlinkInterval);
3799 ccAddExternalObjectFunction("Character::set_BlinkInterval", Sc_Character_SetBlinkInterval);
3800 ccAddExternalObjectFunction("Character::get_BlinkView", Sc_Character_GetBlinkView);
3801 ccAddExternalObjectFunction("Character::set_BlinkView", Sc_Character_SetBlinkView);
3802 ccAddExternalObjectFunction("Character::get_BlinkWhileThinking", Sc_Character_GetBlinkWhileThinking);
3803 ccAddExternalObjectFunction("Character::set_BlinkWhileThinking", Sc_Character_SetBlinkWhileThinking);
3804 ccAddExternalObjectFunction("Character::get_BlockingHeight", Sc_Character_GetBlockingHeight);
3805 ccAddExternalObjectFunction("Character::set_BlockingHeight", Sc_Character_SetBlockingHeight);
3806 ccAddExternalObjectFunction("Character::get_BlockingWidth", Sc_Character_GetBlockingWidth);
3807 ccAddExternalObjectFunction("Character::set_BlockingWidth", Sc_Character_SetBlockingWidth);
3808 ccAddExternalObjectFunction("Character::get_Clickable", Sc_Character_GetClickable);
3809 ccAddExternalObjectFunction("Character::set_Clickable", Sc_Character_SetClickable);
3810 ccAddExternalObjectFunction("Character::get_DestinationX", Sc_Character_GetDestinationX);
3811 ccAddExternalObjectFunction("Character::get_DestinationY", Sc_Character_GetDestinationY);
3812 ccAddExternalObjectFunction("Character::get_DiagonalLoops", Sc_Character_GetDiagonalWalking);
3813 ccAddExternalObjectFunction("Character::set_DiagonalLoops", Sc_Character_SetDiagonalWalking);
3814 ccAddExternalObjectFunction("Character::get_Frame", Sc_Character_GetFrame);
3815 ccAddExternalObjectFunction("Character::set_Frame", Sc_Character_SetFrame);
3816 ccAddExternalObjectFunction("Character::get_HasExplicitTint", Sc_Character_GetHasExplicitTint);
3817 ccAddExternalObjectFunction("Character::get_ID", Sc_Character_GetID);
3818 ccAddExternalObjectFunction("Character::get_IdleView", Sc_Character_GetIdleView);
3819 ccAddExternalObjectFunction("Character::geti_InventoryQuantity", Sc_Character_GetIInventoryQuantity);
3820 ccAddExternalObjectFunction("Character::seti_InventoryQuantity", Sc_Character_SetIInventoryQuantity);
3821 ccAddExternalObjectFunction("Character::get_IgnoreLighting", Sc_Character_GetIgnoreLighting);
3822 ccAddExternalObjectFunction("Character::set_IgnoreLighting", Sc_Character_SetIgnoreLighting);
3823 ccAddExternalObjectFunction("Character::get_IgnoreScaling", Sc_Character_GetIgnoreScaling);
3824 ccAddExternalObjectFunction("Character::set_IgnoreScaling", Sc_Character_SetIgnoreScaling);
3825 ccAddExternalObjectFunction("Character::get_IgnoreWalkbehinds", Sc_Character_GetIgnoreWalkbehinds);
3826 ccAddExternalObjectFunction("Character::set_IgnoreWalkbehinds", Sc_Character_SetIgnoreWalkbehinds);
3827 ccAddExternalObjectFunction("Character::get_Loop", Sc_Character_GetLoop);
3828 ccAddExternalObjectFunction("Character::set_Loop", Sc_Character_SetLoop);
3829 ccAddExternalObjectFunction("Character::get_ManualScaling", Sc_Character_GetIgnoreScaling);
3830 ccAddExternalObjectFunction("Character::set_ManualScaling", Sc_Character_SetManualScaling);
3831 ccAddExternalObjectFunction("Character::get_MovementLinkedToAnimation",Sc_Character_GetMovementLinkedToAnimation);
3832 ccAddExternalObjectFunction("Character::set_MovementLinkedToAnimation",Sc_Character_SetMovementLinkedToAnimation);
3833 ccAddExternalObjectFunction("Character::get_Moving", Sc_Character_GetMoving);
3834 ccAddExternalObjectFunction("Character::get_Name", Sc_Character_GetName);
3835 ccAddExternalObjectFunction("Character::set_Name", Sc_Character_SetName);
3836 ccAddExternalObjectFunction("Character::get_NormalView", Sc_Character_GetNormalView);
3837 ccAddExternalObjectFunction("Character::get_PreviousRoom", Sc_Character_GetPreviousRoom);
3838 ccAddExternalObjectFunction("Character::get_Room", Sc_Character_GetRoom);
3839 ccAddExternalObjectFunction("Character::get_ScaleMoveSpeed", Sc_Character_GetScaleMoveSpeed);
3840 ccAddExternalObjectFunction("Character::set_ScaleMoveSpeed", Sc_Character_SetScaleMoveSpeed);
3841 ccAddExternalObjectFunction("Character::get_ScaleVolume", Sc_Character_GetScaleVolume);
3842 ccAddExternalObjectFunction("Character::set_ScaleVolume", Sc_Character_SetScaleVolume);
3843 ccAddExternalObjectFunction("Character::get_Scaling", Sc_Character_GetScaling);
3844 ccAddExternalObjectFunction("Character::set_Scaling", Sc_Character_SetScaling);
3845 ccAddExternalObjectFunction("Character::get_Solid", Sc_Character_GetSolid);
3846 ccAddExternalObjectFunction("Character::set_Solid", Sc_Character_SetSolid);
3847 ccAddExternalObjectFunction("Character::get_Speaking", Sc_Character_GetSpeaking);
3848 ccAddExternalObjectFunction("Character::get_SpeakingFrame", Sc_Character_GetSpeakingFrame);
3849 ccAddExternalObjectFunction("Character::get_SpeechAnimationDelay", Sc_GetCharacterSpeechAnimationDelay);
3850 ccAddExternalObjectFunction("Character::set_SpeechAnimationDelay", Sc_Character_SetSpeechAnimationDelay);
3851 ccAddExternalObjectFunction("Character::get_SpeechColor", Sc_Character_GetSpeechColor);
3852 ccAddExternalObjectFunction("Character::set_SpeechColor", Sc_Character_SetSpeechColor);
3853 ccAddExternalObjectFunction("Character::get_SpeechView", Sc_Character_GetSpeechView);
3854 ccAddExternalObjectFunction("Character::set_SpeechView", Sc_Character_SetSpeechView);
3855 ccAddExternalObjectFunction("Character::get_Thinking", Sc_Character_GetThinking);
3856 ccAddExternalObjectFunction("Character::get_ThinkingFrame", Sc_Character_GetThinkingFrame);
3857 ccAddExternalObjectFunction("Character::get_ThinkView", Sc_Character_GetThinkView);
3858 ccAddExternalObjectFunction("Character::set_ThinkView", Sc_Character_SetThinkView);
3859 ccAddExternalObjectFunction("Character::get_Transparency", Sc_Character_GetTransparency);
3860 ccAddExternalObjectFunction("Character::set_Transparency", Sc_Character_SetTransparency);
3861 ccAddExternalObjectFunction("Character::get_TurnBeforeWalking", Sc_Character_GetTurnBeforeWalking);
3862 ccAddExternalObjectFunction("Character::set_TurnBeforeWalking", Sc_Character_SetTurnBeforeWalking);
3863 ccAddExternalObjectFunction("Character::get_View", Sc_Character_GetView);
3864 ccAddExternalObjectFunction("Character::get_WalkSpeedX", Sc_Character_GetWalkSpeedX);
3865 ccAddExternalObjectFunction("Character::get_WalkSpeedY", Sc_Character_GetWalkSpeedY);
3866 ccAddExternalObjectFunction("Character::get_X", Sc_Character_GetX);
3867 ccAddExternalObjectFunction("Character::set_X", Sc_Character_SetX);
3868 ccAddExternalObjectFunction("Character::get_x", Sc_Character_GetX);
3869 ccAddExternalObjectFunction("Character::set_x", Sc_Character_SetX);
3870 ccAddExternalObjectFunction("Character::get_Y", Sc_Character_GetY);
3871 ccAddExternalObjectFunction("Character::set_Y", Sc_Character_SetY);
3872 ccAddExternalObjectFunction("Character::get_y", Sc_Character_GetY);
3873 ccAddExternalObjectFunction("Character::set_y", Sc_Character_SetY);
3874 ccAddExternalObjectFunction("Character::get_Z", Sc_Character_GetZ);
3875 ccAddExternalObjectFunction("Character::set_Z", Sc_Character_SetZ);
3876 ccAddExternalObjectFunction("Character::get_z", Sc_Character_GetZ);
3877 ccAddExternalObjectFunction("Character::set_z", Sc_Character_SetZ);
3878
3879 ccAddExternalObjectFunction("Character::get_HasExplicitLight", Sc_Character_HasExplicitLight);
3880 ccAddExternalObjectFunction("Character::get_LightLevel", Sc_Character_GetLightLevel);
3881 ccAddExternalObjectFunction("Character::get_TintBlue", Sc_Character_GetTintBlue);
3882 ccAddExternalObjectFunction("Character::get_TintGreen", Sc_Character_GetTintGreen);
3883 ccAddExternalObjectFunction("Character::get_TintRed", Sc_Character_GetTintRed);
3884 ccAddExternalObjectFunction("Character::get_TintSaturation", Sc_Character_GetTintSaturation);
3885 ccAddExternalObjectFunction("Character::get_TintLuminance", Sc_Character_GetTintLuminance);
3886
3887 /* ----------------------- Registering unsafe exports for plugins -----------------------*/
3888
3889 ccAddExternalFunctionForPlugin("Character::AddInventory^2", (void*)Character_AddInventory);
3890 ccAddExternalFunctionForPlugin("Character::AddWaypoint^2", (void*)Character_AddWaypoint);
3891 ccAddExternalFunctionForPlugin("Character::Animate^5", (void*)Character_Animate);
3892 ccAddExternalFunctionForPlugin("Character::ChangeRoom^3", (void*)Character_ChangeRoom);
3893 ccAddExternalFunctionForPlugin("Character::ChangeRoomAutoPosition^2", (void*)Character_ChangeRoomAutoPosition);
3894 ccAddExternalFunctionForPlugin("Character::ChangeView^1", (void*)Character_ChangeView);
3895 ccAddExternalFunctionForPlugin("Character::FaceCharacter^2", (void*)Character_FaceCharacter);
3896 ccAddExternalFunctionForPlugin("Character::FaceDirection^2", (void*)Character_FaceDirection);
3897 ccAddExternalFunctionForPlugin("Character::FaceLocation^3", (void*)Character_FaceLocation);
3898 ccAddExternalFunctionForPlugin("Character::FaceObject^2", (void*)Character_FaceObject);
3899 ccAddExternalFunctionForPlugin("Character::FollowCharacter^3", (void*)Character_FollowCharacter);
3900 ccAddExternalFunctionForPlugin("Character::GetProperty^1", (void*)Character_GetProperty);
3901 ccAddExternalFunctionForPlugin("Character::GetPropertyText^2", (void*)Character_GetPropertyText);
3902 ccAddExternalFunctionForPlugin("Character::GetTextProperty^1", (void*)Character_GetTextProperty);
3903 ccAddExternalFunctionForPlugin("Character::HasInventory^1", (void*)Character_HasInventory);
3904 ccAddExternalFunctionForPlugin("Character::IsCollidingWithChar^1", (void*)Character_IsCollidingWithChar);
3905 ccAddExternalFunctionForPlugin("Character::IsCollidingWithObject^1", (void*)Character_IsCollidingWithObject);
3906 ccAddExternalFunctionForPlugin("Character::LockView^1", (void*)Character_LockView);
3907 ccAddExternalFunctionForPlugin("Character::LockView^2", (void*)Character_LockViewEx);
3908 ccAddExternalFunctionForPlugin("Character::LockViewAligned^3", (void*)Character_LockViewAligned);
3909 ccAddExternalFunctionForPlugin("Character::LockViewAligned^4", (void*)Character_LockViewAlignedEx);
3910 ccAddExternalFunctionForPlugin("Character::LockViewFrame^3", (void*)Character_LockViewFrame);
3911 ccAddExternalFunctionForPlugin("Character::LockViewFrame^4", (void*)Character_LockViewFrameEx);
3912 ccAddExternalFunctionForPlugin("Character::LockViewOffset^3", (void*)Character_LockViewOffset);
3913 ccAddExternalFunctionForPlugin("Character::LockViewOffset^4", (void*)Character_LockViewOffset);
3914 ccAddExternalFunctionForPlugin("Character::LoseInventory^1", (void*)Character_LoseInventory);
3915 ccAddExternalFunctionForPlugin("Character::Move^4", (void*)Character_Move);
3916 ccAddExternalFunctionForPlugin("Character::PlaceOnWalkableArea^0", (void*)Character_PlaceOnWalkableArea);
3917 ccAddExternalFunctionForPlugin("Character::RemoveTint^0", (void*)Character_RemoveTint);
3918 ccAddExternalFunctionForPlugin("Character::RunInteraction^1", (void*)Character_RunInteraction);
3919 ccAddExternalFunctionForPlugin("Character::Say^101", (void*)ScPl_Character_Say);
3920 ccAddExternalFunctionForPlugin("Character::SayAt^4", (void*)Character_SayAt);
3921 ccAddExternalFunctionForPlugin("Character::SayBackground^1", (void*)Character_SayBackground);
3922 ccAddExternalFunctionForPlugin("Character::SetAsPlayer^0", (void*)Character_SetAsPlayer);
3923 ccAddExternalFunctionForPlugin("Character::SetIdleView^2", (void*)Character_SetIdleView);
3924 //ccAddExternalFunctionForPlugin("Character::SetOption^2", (void*)Character_SetOption);
3925 ccAddExternalFunctionForPlugin("Character::SetWalkSpeed^2", (void*)Character_SetSpeed);
3926 ccAddExternalFunctionForPlugin("Character::StopMoving^0", (void*)Character_StopMoving);
3927 ccAddExternalFunctionForPlugin("Character::Think^101", (void*)ScPl_Character_Think);
3928 ccAddExternalFunctionForPlugin("Character::Tint^5", (void*)Character_Tint);
3929 ccAddExternalFunctionForPlugin("Character::UnlockView^0", (void*)Character_UnlockView);
3930 ccAddExternalFunctionForPlugin("Character::UnlockView^1", (void*)Character_UnlockViewEx);
3931 ccAddExternalFunctionForPlugin("Character::Walk^4", (void*)Character_Walk);
3932 ccAddExternalFunctionForPlugin("Character::WalkStraight^3", (void*)Character_WalkStraight);
3933 ccAddExternalFunctionForPlugin("Character::GetAtScreenXY^2", (void*)GetCharacterAtLocation);
3934 ccAddExternalFunctionForPlugin("Character::get_ActiveInventory", (void*)Character_GetActiveInventory);
3935 ccAddExternalFunctionForPlugin("Character::set_ActiveInventory", (void*)Character_SetActiveInventory);
3936 ccAddExternalFunctionForPlugin("Character::get_Animating", (void*)Character_GetAnimating);
3937 ccAddExternalFunctionForPlugin("Character::get_AnimationSpeed", (void*)Character_GetAnimationSpeed);
3938 ccAddExternalFunctionForPlugin("Character::set_AnimationSpeed", (void*)Character_SetAnimationSpeed);
3939 ccAddExternalFunctionForPlugin("Character::get_Baseline", (void*)Character_GetBaseline);
3940 ccAddExternalFunctionForPlugin("Character::set_Baseline", (void*)Character_SetBaseline);
3941 ccAddExternalFunctionForPlugin("Character::get_BlinkInterval", (void*)Character_GetBlinkInterval);
3942 ccAddExternalFunctionForPlugin("Character::set_BlinkInterval", (void*)Character_SetBlinkInterval);
3943 ccAddExternalFunctionForPlugin("Character::get_BlinkView", (void*)Character_GetBlinkView);
3944 ccAddExternalFunctionForPlugin("Character::set_BlinkView", (void*)Character_SetBlinkView);
3945 ccAddExternalFunctionForPlugin("Character::get_BlinkWhileThinking", (void*)Character_GetBlinkWhileThinking);
3946 ccAddExternalFunctionForPlugin("Character::set_BlinkWhileThinking", (void*)Character_SetBlinkWhileThinking);
3947 ccAddExternalFunctionForPlugin("Character::get_BlockingHeight", (void*)Character_GetBlockingHeight);
3948 ccAddExternalFunctionForPlugin("Character::set_BlockingHeight", (void*)Character_SetBlockingHeight);
3949 ccAddExternalFunctionForPlugin("Character::get_BlockingWidth", (void*)Character_GetBlockingWidth);
3950 ccAddExternalFunctionForPlugin("Character::set_BlockingWidth", (void*)Character_SetBlockingWidth);
3951 ccAddExternalFunctionForPlugin("Character::get_Clickable", (void*)Character_GetClickable);
3952 ccAddExternalFunctionForPlugin("Character::set_Clickable", (void*)Character_SetClickable);
3953 ccAddExternalFunctionForPlugin("Character::get_DestinationX", (void*)Character_GetDestinationX);
3954 ccAddExternalFunctionForPlugin("Character::get_DestinationY", (void*)Character_GetDestinationY);
3955 ccAddExternalFunctionForPlugin("Character::get_DiagonalLoops", (void*)Character_GetDiagonalWalking);
3956 ccAddExternalFunctionForPlugin("Character::set_DiagonalLoops", (void*)Character_SetDiagonalWalking);
3957 ccAddExternalFunctionForPlugin("Character::get_Frame", (void*)Character_GetFrame);
3958 ccAddExternalFunctionForPlugin("Character::set_Frame", (void*)Character_SetFrame);
3959 ccAddExternalFunctionForPlugin("Character::get_HasExplicitTint", (void*)Character_GetHasExplicitTint);
3960 ccAddExternalFunctionForPlugin("Character::get_ID", (void*)Character_GetID);
3961 ccAddExternalFunctionForPlugin("Character::get_IdleView", (void*)Character_GetIdleView);
3962 ccAddExternalFunctionForPlugin("Character::geti_InventoryQuantity", (void*)Character_GetIInventoryQuantity);
3963 ccAddExternalFunctionForPlugin("Character::seti_InventoryQuantity", (void*)Character_SetIInventoryQuantity);
3964 ccAddExternalFunctionForPlugin("Character::get_IgnoreLighting", (void*)Character_GetIgnoreLighting);
3965 ccAddExternalFunctionForPlugin("Character::set_IgnoreLighting", (void*)Character_SetIgnoreLighting);
3966 ccAddExternalFunctionForPlugin("Character::get_IgnoreScaling", (void*)Character_GetIgnoreScaling);
3967 ccAddExternalFunctionForPlugin("Character::set_IgnoreScaling", (void*)Character_SetIgnoreScaling);
3968 ccAddExternalFunctionForPlugin("Character::get_IgnoreWalkbehinds", (void*)Character_GetIgnoreWalkbehinds);
3969 ccAddExternalFunctionForPlugin("Character::set_IgnoreWalkbehinds", (void*)Character_SetIgnoreWalkbehinds);
3970 ccAddExternalFunctionForPlugin("Character::get_Loop", (void*)Character_GetLoop);
3971 ccAddExternalFunctionForPlugin("Character::set_Loop", (void*)Character_SetLoop);
3972 ccAddExternalFunctionForPlugin("Character::get_ManualScaling", (void*)Character_GetIgnoreScaling);
3973 ccAddExternalFunctionForPlugin("Character::set_ManualScaling", (void*)Character_SetManualScaling);
3974 ccAddExternalFunctionForPlugin("Character::get_MovementLinkedToAnimation",(void*)Character_GetMovementLinkedToAnimation);
3975 ccAddExternalFunctionForPlugin("Character::set_MovementLinkedToAnimation",(void*)Character_SetMovementLinkedToAnimation);
3976 ccAddExternalFunctionForPlugin("Character::get_Moving", (void*)Character_GetMoving);
3977 ccAddExternalFunctionForPlugin("Character::get_Name", (void*)Character_GetName);
3978 ccAddExternalFunctionForPlugin("Character::set_Name", (void*)Character_SetName);
3979 ccAddExternalFunctionForPlugin("Character::get_NormalView", (void*)Character_GetNormalView);
3980 ccAddExternalFunctionForPlugin("Character::get_PreviousRoom", (void*)Character_GetPreviousRoom);
3981 ccAddExternalFunctionForPlugin("Character::get_Room", (void*)Character_GetRoom);
3982 ccAddExternalFunctionForPlugin("Character::get_ScaleMoveSpeed", (void*)Character_GetScaleMoveSpeed);
3983 ccAddExternalFunctionForPlugin("Character::set_ScaleMoveSpeed", (void*)Character_SetScaleMoveSpeed);
3984 ccAddExternalFunctionForPlugin("Character::get_ScaleVolume", (void*)Character_GetScaleVolume);
3985 ccAddExternalFunctionForPlugin("Character::set_ScaleVolume", (void*)Character_SetScaleVolume);
3986 ccAddExternalFunctionForPlugin("Character::get_Scaling", (void*)Character_GetScaling);
3987 ccAddExternalFunctionForPlugin("Character::set_Scaling", (void*)Character_SetScaling);
3988 ccAddExternalFunctionForPlugin("Character::get_Solid", (void*)Character_GetSolid);
3989 ccAddExternalFunctionForPlugin("Character::set_Solid", (void*)Character_SetSolid);
3990 ccAddExternalFunctionForPlugin("Character::get_Speaking", (void*)Character_GetSpeaking);
3991 ccAddExternalFunctionForPlugin("Character::get_SpeakingFrame", (void*)Character_GetSpeakingFrame);
3992 ccAddExternalFunctionForPlugin("Character::get_SpeechAnimationDelay", (void*)GetCharacterSpeechAnimationDelay);
3993 ccAddExternalFunctionForPlugin("Character::set_SpeechAnimationDelay", (void*)Character_SetSpeechAnimationDelay);
3994 ccAddExternalFunctionForPlugin("Character::get_SpeechColor", (void*)Character_GetSpeechColor);
3995 ccAddExternalFunctionForPlugin("Character::set_SpeechColor", (void*)Character_SetSpeechColor);
3996 ccAddExternalFunctionForPlugin("Character::get_SpeechView", (void*)Character_GetSpeechView);
3997 ccAddExternalFunctionForPlugin("Character::set_SpeechView", (void*)Character_SetSpeechView);
3998 ccAddExternalFunctionForPlugin("Character::get_ThinkView", (void*)Character_GetThinkView);
3999 ccAddExternalFunctionForPlugin("Character::set_ThinkView", (void*)Character_SetThinkView);
4000 ccAddExternalFunctionForPlugin("Character::get_Transparency", (void*)Character_GetTransparency);
4001 ccAddExternalFunctionForPlugin("Character::set_Transparency", (void*)Character_SetTransparency);
4002 ccAddExternalFunctionForPlugin("Character::get_TurnBeforeWalking", (void*)Character_GetTurnBeforeWalking);
4003 ccAddExternalFunctionForPlugin("Character::set_TurnBeforeWalking", (void*)Character_SetTurnBeforeWalking);
4004 ccAddExternalFunctionForPlugin("Character::get_View", (void*)Character_GetView);
4005 ccAddExternalFunctionForPlugin("Character::get_WalkSpeedX", (void*)Character_GetWalkSpeedX);
4006 ccAddExternalFunctionForPlugin("Character::get_WalkSpeedY", (void*)Character_GetWalkSpeedY);
4007 ccAddExternalFunctionForPlugin("Character::get_X", (void*)Character_GetX);
4008 ccAddExternalFunctionForPlugin("Character::set_X", (void*)Character_SetX);
4009 ccAddExternalFunctionForPlugin("Character::get_x", (void*)Character_GetX);
4010 ccAddExternalFunctionForPlugin("Character::set_x", (void*)Character_SetX);
4011 ccAddExternalFunctionForPlugin("Character::get_Y", (void*)Character_GetY);
4012 ccAddExternalFunctionForPlugin("Character::set_Y", (void*)Character_SetY);
4013 ccAddExternalFunctionForPlugin("Character::get_y", (void*)Character_GetY);
4014 ccAddExternalFunctionForPlugin("Character::set_y", (void*)Character_SetY);
4015 ccAddExternalFunctionForPlugin("Character::get_Z", (void*)Character_GetZ);
4016 ccAddExternalFunctionForPlugin("Character::set_Z", (void*)Character_SetZ);
4017 ccAddExternalFunctionForPlugin("Character::get_z", (void*)Character_GetZ);
4018 ccAddExternalFunctionForPlugin("Character::set_z", (void*)Character_SetZ);
4019 }
4020