void MultiReshape(OBJECT *pMultiObj) { SCNHANDLE hFrame; // validate object pointer assert(pMultiObj >= objectList && pMultiObj <= objectList + NUM_OBJECTS - 1); // get objects current anim frame hFrame = pMultiObj->hShape; if (hFrame != 0 && hFrame != pMultiObj->hMirror) { // a valid shape frame which is different from previous // get pointer to frame const FRAME *pFrame = (const FRAME *)LockMem(hFrame); // update previous pMultiObj->hMirror = hFrame; while (READ_LE_UINT32(pFrame) != 0 && pMultiObj != NULL) { // a normal image - update the current object with this image AnimateObject(pMultiObj, READ_LE_UINT32(pFrame)); // move to next image for this frame pFrame++; // move to next part of object pMultiObj = pMultiObj->pSlave; } // null the remaining object parts while (pMultiObj != NULL) { // set a null image for this object part AnimateObject(pMultiObj, 0); // move to next part of object pMultiObj = pMultiObj->pSlave; } } else if (hFrame == 0) { // update previous pMultiObj->hMirror = hFrame; // null all the object parts while (pMultiObj != NULL) { // set a null image for this object part AnimateObject(pMultiObj, 0); // move to next part of object pMultiObj = pMultiObj->pSlave; } } }
/* * AnimateDescription: Animate bitmap in description dialog. * dt is number of milliseconds since last time animation timer went off. */ void AnimateDescription(int dt) { int old_group; DescDialogStruct *info; object_node *obj; if (hDescDialog == NULL) return; info = (DescDialogStruct *) GetWindowLong(hDescDialog, DWL_USER); obj = info->obj; old_group = obj->animate->group; if (AnimateObject(obj, dt) == True) SendMessage(hDescDialog, BK_ANIMATE, 0, 0); }
/* * Animate player overlays; return True if any was animated. * dt is number of milliseconds since last time animation timer went off. */ Bool AnimatePlayerOverlays(int dt) { int i; Bool need_redraw = False, retval; for (i=0; i < NUM_PLAYER_OVERLAYS; i++) { PlayerOverlay *poverlay = &player.poverlays[i]; if (poverlay->obj == NULL || poverlay->hotspot == 0) continue; retval = AnimateObject(poverlay->obj, dt); need_redraw = need_redraw || retval; // If animation is over, group becomes -1 => we should remove overlay if (poverlay->obj->animate->group == (WORD) -1) poverlay->hotspot = 0; } return need_redraw; }
/* * Animate objects in current room; return True if any was animated. * dt is number of milliseconds since last time animation timer went off. */ Bool AnimateObjects(int dt) { Bool need_redraw = False; list_type l; for (l = current_room.contents; l != NULL; l = l->next) { room_contents_node *r = (room_contents_node *) (l->data); int old_animate = r->obj.animate->animation; need_redraw |= AnimateObject(&r->obj, dt); // If room object animation finished, restore motion animation if appropriate. // (Done after drawing so that last frame of animation not skipped). if (r->obj.animate->animation == ANIMATE_NONE && old_animate != ANIMATE_NONE && r->moving) { RoomObjectSetAnimation(r, True); r->motion.move_animating = True; } } return need_redraw; }
/* * AnimateInventory: Animate inventory items. * dt is number of milliseconds since last time animation timer went off. */ void AnimateInventory(int dt) { Bool need_redraw; int index; list_type l; index = 0; for (l = items; l != NULL; l = l->next) { InvItem *item = (InvItem *) (l->data); need_redraw = AnimateObject(item->obj, dt); if (need_redraw) { // Redraw object on screen if it's visible int row = index / cols; int col = index % cols; if (InventoryItemVisible(row, col)) InventoryDrawSingleItem(item, row - top_row, col); } index++; } }
// the 'cmdsrun' parameter counts how many commands are run. // if a 'Inv Item Was Used' check does not pass, it doesn't count // so cmdsrun remains 0 if no inventory items matched int run_interaction_commandlist (InteractionCommandList *nicl, int *timesrun, int*cmdsrun) { size_t i; if (nicl == NULL) return -1; for (i = 0; i < nicl->Cmds.size(); i++) { cmdsrun[0] ++; int room_was = play.room_changes; switch (nicl->Cmds[i].Type) { case 0: // Do nothing break; case 1: // Run script { TempEip tempip(4001); RuntimeScriptValue rval_null; update_mp3(); if ((strstr(evblockbasename,"character")!=0) || (strstr(evblockbasename,"inventory")!=0)) { // Character or Inventory (global script) const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); // we are already inside the mouseclick event of the script, can't nest calls QueueScriptFunction(kScInstGame, torun); } else { // Other (room script) const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); QueueScriptFunction(kScInstRoom, torun); } update_mp3(); break; } case 2: // Add score (first time) if (timesrun[0] > 0) break; timesrun[0] ++; case 3: // Add score GiveScore (IPARAM1); break; case 4: // Display Message /* if (comprdata<0) display_message_aschar=evb->data[ss];*/ DisplayMessage(IPARAM1); break; case 5: // Play Music PlayMusicResetQueue(IPARAM1); break; case 6: // Stop Music stopmusic (); break; case 7: // Play Sound play_sound (IPARAM1); break; case 8: // Play Flic play_flc_file(IPARAM1, IPARAM2); break; case 9: // Run Dialog { int room_was = play.room_changes; RunDialog(IPARAM1); // if they changed room within the dialog script, // the interaction command list is no longer valid if (room_was != play.room_changes) return -1; } break; case 10: // Enable Dialog Option SetDialogOption (IPARAM1, IPARAM2, 1); break; case 11: // Disable Dialog Option SetDialogOption (IPARAM1, IPARAM2, 0); break; case 12: // Go To Screen Character_ChangeRoomAutoPosition(playerchar, IPARAM1, IPARAM2); return -1; case 13: // Add Inventory add_inventory (IPARAM1); break; case 14: // Move Object MoveObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); // if they want to wait until finished, do so if (IPARAM5) GameLoopUntilEvent(UNTIL_MOVEEND,(long)&objs[IPARAM1].moving); break; case 15: // Object Off ObjectOff (IPARAM1); break; case 16: // Object On ObjectOn (IPARAM1); break; case 17: // Set Object View SetObjectView (IPARAM1, IPARAM2); break; case 18: // Animate Object AnimateObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); break; case 19: // Move Character if (IPARAM4) MoveCharacterBlocking (IPARAM1, IPARAM2, IPARAM3, 0); else MoveCharacter (IPARAM1, IPARAM2, IPARAM3); break; case 20: // If Inventory Item was used if (play.usedinv == IPARAM1) { if (game.options[OPT_NOLOSEINV] == 0) lose_inventory (play.usedinv); if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; } else cmdsrun[0] --; break; case 21: // if player has inventory item if (playerchar->inv[IPARAM1] > 0) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 22: // if a character is moving if (game.chars[IPARAM1].walking) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 23: // if two variables are equal if (IPARAM1 == IPARAM2) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 24: // Stop character walking StopMoving (IPARAM1); break; case 25: // Go to screen at specific co-ordinates NewRoomEx (IPARAM1, IPARAM2, IPARAM3); return -1; case 26: // Move NPC to different room if (!is_valid_character(IPARAM1)) quit("!Move NPC to different room: invalid character specified"); game.chars[IPARAM1].room = IPARAM2; break; case 27: // Set character view SetCharacterView (IPARAM1, IPARAM2); break; case 28: // Release character view ReleaseCharacterView (IPARAM1); break; case 29: // Follow character FollowCharacter (IPARAM1, IPARAM2); break; case 30: // Stop following FollowCharacter (IPARAM1, -1); break; case 31: // Disable hotspot DisableHotspot (IPARAM1); break; case 32: // Enable hotspot EnableHotspot (IPARAM1); break; case 33: // Set variable value get_interaction_variable(nicl->Cmds[i].Data[0].Value)->Value = IPARAM2; break; case 34: // Run animation scAnimateCharacter(IPARAM1, IPARAM2, IPARAM3, 0); GameLoopUntilEvent(UNTIL_SHORTIS0,(long)&game.chars[IPARAM1].animating); break; case 35: // Quick animation SetCharacterView (IPARAM1, IPARAM2); scAnimateCharacter(IPARAM1, IPARAM3, IPARAM4, 0); GameLoopUntilEvent(UNTIL_SHORTIS0,(long)&game.chars[IPARAM1].animating); ReleaseCharacterView (IPARAM1); break; case 36: // Set idle animation SetCharacterIdle (IPARAM1, IPARAM2, IPARAM3); break; case 37: // Disable idle animation SetCharacterIdle (IPARAM1, -1, -1); break; case 38: // Lose inventory item lose_inventory (IPARAM1); break; case 39: // Show GUI InterfaceOn (IPARAM1); break; case 40: // Hide GUI InterfaceOff (IPARAM1); break; case 41: // Stop running more commands return -1; case 42: // Face location FaceLocation (IPARAM1, IPARAM2, IPARAM3); break; case 43: // Pause command processor scrWait (IPARAM1); break; case 44: // Change character view ChangeCharacterView (IPARAM1, IPARAM2); break; case 45: // If player character is if (GetPlayerCharacter() == IPARAM1) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 46: // if cursor mode is if (GetCursorMode() == IPARAM1) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 47: // if player has been to room if (HasBeenToRoom(IPARAM1)) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; default: quit("unknown new interaction command"); break; } // if the room changed within the action, nicl is no longer valid if (room_was != play.room_changes) return -1; } return 0; }
void AboutTimer(HWND hwnd, UINT id) { HWND hwndBitmap; HDC hdc; int i, j, k, x, y; RECT r; PDIB pdib; BYTE *bits, index; object_node *obj; // Copy bits to offscreen area for (i=0; i < scroll_height; i++) { int yBitmap = (scroll_y + i) % DibHeight(credits_pdib); BYTE *pSource = DibPtr(credits_pdib) + (yBitmap * DibWidth(credits_pdib)); BYTE *pDest = gBits + i*DIBWIDTH(gbits_width); memcpy(pDest,pSource,scroll_width); } scroll_y++; if (scroll_y >= DibHeight(credits_pdib)) scroll_y = 0; hwndBitmap = GetDlgItem(hwnd, IDC_SCROLL); hdc = GetDC(hwndBitmap); SelectPalette(hdc, hPal, FALSE); BitBlt(hdc, 0, 0, scroll_width, scroll_height, gDC, 0, 0, SRCCOPY); ReleaseDC(hwndBitmap, hdc); // Draw animated characters r.left = r.top = 0; r.right = gbits_width; r.bottom = gbits_height; FillRect(gDC, &r, GetSysColorBrush(COLOR_3DFACE)); GdiFlush(); hdc = GetDC(hwnd); for (i=0; i < NUM_DUDES; i++) { if (dudes[i].obj != NULL) { obj = dudes[i].obj; if (rand() % 30 == 0) { obj->animate->animation = ANIMATE_ONCE; obj->animate->group = obj->animate->group_low = 3; obj->animate->group_high = 4; obj->animate->group_final = 0; obj->animate->period = obj->animate->tick = 400; if (config.play_sound) { switch (dudes[i].obj->icon_res) { case ABOUT_RSC1: index = 3; break; case ABOUT_RSC2: index = 4; break; case ABOUT_RSC3: index = 5; break; default: index = rand() % num_sounds; break; } SoundPlayFile(sounds[index], SF_RANDOM_PITCH); } } AnimateObject(dudes[i].obj, ABOUT_INTERVAL); pdib = GetObjectPdib(dudes[i].obj->icon_res, dudes[i].angle, dudes[i].obj->animate->group); if (pdib == NULL) continue; bits = DibPtr(pdib); x = dudes[i].x - DibWidth(pdib) / 2; y = DUDE_MAX_HEIGHT - DibHeight(pdib); for (j=0; j < DibHeight(pdib); j++) { for (k=0; k < DibWidth(pdib); k++) { index = *(bits + j * DibWidth(pdib) + k); if (index != TRANSPARENT_INDEX) *(gBits + (j + y) * DIBWIDTH(gbits_width) + x + k) = index; } } } } SelectPalette(hdc, hPal, FALSE); BitBlt(hdc, dude_x, dude_y, DUDE_AREA_WIDTH, DUDE_MAX_HEIGHT, gDC, 0, 0, SRCCOPY); ReleaseDC(hwnd, hdc); }