/* * InterfaceAction: User wants to perform given action. Return True iff * action should be passed along for further processing. */ Bool InterfaceAction(int action, void *action_data) { POINT mouse; AREA a; room_contents_node *r; static int lastRestWarning = 0; if ((pinfo.resting || cinfo->effects->paralyzed) && (IsMoveAction(action) || IsAttackAction(action))) { // debug(("Can't do while resting\n")); return False; } switch (action) { case A_TARGETCLEAR: case A_TARGETSELF: case A_TARGETNEXT: case A_TARGETPREVIOUS: case A_ATTACK: UserAreaRedraw(); return True; break; case A_FORWARDFAST: // If too tired, don't run if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_FORWARD, NULL); return False; } break; case A_BACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_BACKWARD, NULL); return False; } break; case A_SLIDELEFTFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFT, NULL); return False; } break; case A_SLIDERIGHTFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHT, NULL); return False; } break; case A_SLIDELEFTFORWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFTFORWARD, NULL); return False; } break; case A_SLIDELEFTBACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDELEFTBACKWARD, NULL); return False; } break; case A_SLIDERIGHTFORWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHTFORWARD, NULL); return False; } break; case A_SLIDERIGHTBACKWARDFAST: if (pinfo.vigor < MIN_VIGOR) { PerformAction(A_SLIDERIGHTBACKWARD, NULL); return False; } break; case A_CAST: UserCastSpell(); return False; case A_CASTSPELL: // action_data is pointer to spell if (GetPlayer()->viewID && (GetPlayer()->viewID != GetPlayer()->id)) { if (!(GetPlayer()->viewFlags & REMOTE_VIEW_CAST)) { GameMessage(GetString(hInst, IDS_SPELLPARALYZED)); return False; } } if (cinfo->effects->paralyzed) { GameMessage(GetString(hInst, IDS_SPELLPARALYZED)); return False; } if (pinfo.resting) { GameMessage(GetString(hInst, IDS_SPELLRESTING)); return False; } SpellCast((spell *) action_data); return False; case A_GO: if (pinfo.resting) return False; break; case A_ENDDRAG: // action_data is ID of object being dragged // See if user dragged object to inventory InventoryGetArea(&a); GetCursorPos(&mouse); ScreenToClient(cinfo->hMain, &mouse); if (!IsInArea(&a, mouse.x, mouse.y)) break; r = GetRoomObjectById((ID) action_data); if (r == NULL) break; // If a non-gettable container, try to get contents if ((r->obj.flags & OF_CONTAINER) && !(r->obj.flags & OF_GETTABLE)) RequestObjectContents((ID) action_data); else RequestPickup((ID) action_data); break; case A_TABFWD: return InterfaceTab((int) action_data, True); case A_TABBACK: return InterfaceTab((int) action_data, False); } return True; }
/* * HandleKeys: Check state of keyboard and perform actions that correspond * to keys that are down. */ void HandleKeys(Bool poll) { Bool norepeat; BYTE keys[NUM_KEYS]; int action, i, j; DWORD now; int actions[MAX_ACTIONS]; // Holds actions we've already done int num_actions; // Number of valid entries in actions Bool moved, turned, already_done; KeyTable table; void *action_data; list_type l; /* If main window no longer has the focus, don't read keyboard */ if (GetFocus() != hMain) return; now = timeGetTime(); num_actions = 0; GetKeyboardState(keys); // Go through all key tables that match the current state for (l = key_tables; l != NULL; l = l->next) { KeyTableListEntry *entry; entry = (KeyTableListEntry *) (l->data); if (entry->state != GameGetState()) continue; table = entry->table; /* Perform action for ALL keys that are down; this allows multiple arrow keys to work */ /* First, mark all actions that correspond to keys that are down */ norepeat = False; moved = turned = False; for (i = 1; i < NUM_KEYS; i++) { if (!IsDown(keys[i])) continue; action = TranslateKey(i, table, &action_data); if (action == A_NOACTION) continue; // Don't constantly toggle tab or mouselook if key held down. if ((IsTabAction(action) || IsMouseLookAction(action)) && poll) continue; // Perform action at most once already_done = False; for (j=0; j < num_actions; j++) if (actions[j] == action) already_done = True; if (already_done || num_actions == MAX_ACTIONS) continue; actions[num_actions++] = action; /* Only repeat for moving actions and a few others */ if (!RepeatAction(action)) if (now - last_norepeat_time >= KEY_NOREPEAT_INTERVAL) norepeat = True; else continue; // Action retried too soon if (IsMoveAction(action)) if (moved) continue; else { int tempKey = i; int tempAction; moved = True; for (; tempKey < NUM_KEYS; tempKey++) { if (!IsDown(keys[tempKey])) continue; tempAction = TranslateKey(tempKey, table, &action_data); if (IsMoveAction(tempAction)) { switch (action) { case A_FORWARD: switch(tempAction) { case A_SLIDELEFT: action = A_SLIDELEFTFORWARD; tempKey = NUM_KEYS; break; case A_SLIDERIGHT: action = A_SLIDERIGHTFORWARD; tempKey = NUM_KEYS; break; } case A_FORWARDFAST: switch(tempAction) { case A_SLIDELEFTFAST: action = A_SLIDELEFTFORWARDFAST; tempKey = NUM_KEYS; break; case A_SLIDERIGHTFAST: action = A_SLIDERIGHTFORWARDFAST; tempKey = NUM_KEYS; break; } break; case A_BACKWARD: switch(tempAction) { case A_SLIDELEFT: action = A_SLIDELEFTBACKWARD; tempKey = NUM_KEYS; break; case A_SLIDERIGHT: action = A_SLIDERIGHTBACKWARD; tempKey = NUM_KEYS; break; } case A_BACKWARDFAST: switch(tempAction) { case A_SLIDELEFTFAST: action = A_SLIDELEFTBACKWARDFAST; tempKey = NUM_KEYS; break; case A_SLIDERIGHTFAST: action = A_SLIDERIGHTBACKWARDFAST; tempKey = NUM_KEYS; break; } break; case A_SLIDELEFT: switch(tempAction) { case A_FORWARD: action = A_SLIDELEFTFORWARD; tempKey = NUM_KEYS; break; case A_BACKWARD: action = A_SLIDELEFTBACKWARD; tempKey = NUM_KEYS; break; } break; case A_SLIDELEFTFAST: switch(tempAction) { case A_FORWARDFAST: action = A_SLIDELEFTFORWARDFAST; tempKey = NUM_KEYS; break; case A_BACKWARDFAST: action = A_SLIDELEFTBACKWARDFAST; tempKey = NUM_KEYS; break; } break; case A_SLIDERIGHT: switch(tempAction) { case A_FORWARD: action = A_SLIDERIGHTFORWARD; tempKey = NUM_KEYS; break; case A_BACKWARD: action = A_SLIDERIGHTBACKWARD; tempKey = NUM_KEYS; break; } break; case A_SLIDERIGHTFAST: switch(tempAction) { case A_FORWARDFAST: action = A_SLIDERIGHTFORWARDFAST; tempKey = NUM_KEYS; break; case A_BACKWARDFAST: action = A_SLIDERIGHTBACKWARDFAST; tempKey = NUM_KEYS; break; } break; } } } } if (IsTurnAction(action)) if (turned) continue; else turned = True; // If we're doing a non-repeat action, remember the time so that we don't repeat it if (norepeat) last_norepeat_time = now; PerformAction(action, action_data); } } }