2003-07-28 01:44:38 +00:00
|
|
|
/* Copyright (C) 1994-2003 Revolution Software Ltd
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* $Header$
|
|
|
|
*/
|
|
|
|
|
2003-07-28 03:12:49 +00:00
|
|
|
#include "stdafx.h"
|
2003-10-04 08:07:03 +00:00
|
|
|
#include "bs2/console.h"
|
|
|
|
#include "bs2/debug.h"
|
|
|
|
#include "bs2/defs.h"
|
|
|
|
#include "bs2/events.h"
|
|
|
|
#include "bs2/interpreter.h"
|
|
|
|
#include "bs2/logic.h"
|
|
|
|
#include "bs2/memory.h"
|
|
|
|
#include "bs2/object.h"
|
|
|
|
#include "bs2/sync.h"
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-04 00:52:27 +00:00
|
|
|
namespace Sword2 {
|
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
_event_unit event_list[MAX_events];
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-26 10:07:18 +00:00
|
|
|
void Init_event_system(void) {
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
2003-09-02 09:54:42 +00:00
|
|
|
//denotes free slot
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = 0;
|
2003-09-02 09:54:42 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-05 15:28:15 +00:00
|
|
|
#ifdef _SWORD2_DEBUG
|
2003-09-02 09:54:42 +00:00
|
|
|
uint32 CountEvents(void) {
|
|
|
|
uint32 count = 0;
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id)
|
2003-07-28 01:44:38 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
return count;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-10-05 15:28:15 +00:00
|
|
|
#endif
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnRequestSpeech(int32 *params) {
|
2003-09-20 13:11:15 +00:00
|
|
|
// change current script - must be followed by a TERMINATE script
|
2003-09-02 09:54:42 +00:00
|
|
|
// directive
|
2003-09-20 13:11:15 +00:00
|
|
|
|
|
|
|
// params: 0 id of target to catch the event and startup speech
|
|
|
|
// servicing
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int i;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == (uint32) params[0])
|
2003-07-28 01:44:38 +00:00
|
|
|
break;
|
2003-09-02 09:54:42 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (!event_list[i].id)
|
2003-07-28 01:44:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (i == MAX_events)
|
|
|
|
Con_fatal_error("fnSetEvent out of event slots");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-10 16:14:52 +00:00
|
|
|
// found that slot
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-10 16:14:52 +00:00
|
|
|
// id of person to stop
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = params[0];
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-10-10 16:14:52 +00:00
|
|
|
// full script id to interact with - megas run their own 7th script
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].interact_id = (params[0] * 65536) + 6;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-26 10:07:18 +00:00
|
|
|
void Set_player_action_event(uint32 id, uint32 interact_id) {
|
2003-10-18 08:11:50 +00:00
|
|
|
int i;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == id)
|
2003-07-28 01:44:38 +00:00
|
|
|
break;
|
2003-09-02 09:54:42 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (!event_list[i].id)
|
2003-07-28 01:44:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (i == MAX_events)
|
2003-07-28 01:44:38 +00:00
|
|
|
Con_fatal_error("Set_event out of event slots");
|
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// found that slot
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-05 15:28:15 +00:00
|
|
|
// id of person to stop
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = id;
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-10-05 15:28:15 +00:00
|
|
|
// full script id of action script number 2
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].interact_id = (interact_id * 65536) + 2;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnSetPlayerActionEvent(int32 *params) {
|
2003-09-02 09:54:42 +00:00
|
|
|
// we want to intercept the player character and have him interact
|
|
|
|
// with an object - from script this code is the same as the mouse
|
|
|
|
// engine calls when you click on an object - here, a third party
|
|
|
|
// does the clicking IYSWIM
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// note - this routine used CUR_PLAYER_ID as the target
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 13:11:15 +00:00
|
|
|
// params: 0 id to interact with
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// search for an existing event or a slot
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int i;
|
2003-09-02 09:54:42 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == CUR_PLAYER_ID)
|
2003-07-28 01:44:38 +00:00
|
|
|
break;
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (!event_list[i].id)
|
|
|
|
break;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (i == MAX_events)
|
2003-07-28 01:44:38 +00:00
|
|
|
Con_fatal_error("Set_event out of event slots");
|
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// found that slot
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// id of person to stop
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = CUR_PLAYER_ID;
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// full script id of action script number 2
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].interact_id = (params[0] * 65536) + 2;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnSendEvent(int32 *params) {
|
2003-09-02 09:54:42 +00:00
|
|
|
// we want to intercept the player character and have him interact
|
|
|
|
// with an object - from script
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 13:11:15 +00:00
|
|
|
// params: 0 id to recieve event
|
|
|
|
// 1 script to run
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// search for an existing event or a slot
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int i;
|
2003-09-02 09:54:42 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == (uint32) params[0])
|
2003-07-28 01:44:38 +00:00
|
|
|
break;
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (!event_list[i].id)
|
|
|
|
break;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
if (i == MAX_events)
|
|
|
|
Con_fatal_error("fnSendEvent out of event slots");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// found that slot
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// id of person to stop
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = params[0];
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
//full script id
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].interact_id = params[1];
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnCheckEventWaiting(int32 *params) {
|
2003-09-02 09:54:42 +00:00
|
|
|
// returns yes/no in RESULT
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
// params: none
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
RESULT = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == ID) {
|
2003-09-02 09:54:42 +00:00
|
|
|
RESULT = 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
// like fnCheckEventWaiting, but starts the event rather than setting RESULT
|
|
|
|
// to 1
|
2003-09-02 09:54:42 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnCheckForEvent(int32 *params) {
|
|
|
|
// params: none
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == ID) {
|
2003-07-28 01:44:38 +00:00
|
|
|
// start the event
|
2003-09-02 09:54:42 +00:00
|
|
|
// run 3rd script of target object on level 1
|
2003-10-18 08:11:50 +00:00
|
|
|
logicOne(event_list[i].interact_id);
|
2003-09-02 09:54:42 +00:00
|
|
|
// clear the event slot
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = 0;
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_TERMINATE;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-02 09:54:42 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
// combination of fnPause and fnCheckForEvent
|
2003-07-28 01:44:38 +00:00
|
|
|
// - ie. does a pause, but also checks for event each cycle
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnPauseForEvent(int32 *params) {
|
2003-07-28 01:44:38 +00:00
|
|
|
// returns yes/no in RESULT
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
// params: 0 pointer to object's logic structure
|
|
|
|
// 1 number of game-cycles to pause
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
Object_logic *ob_logic = (Object_logic *)params[0];
|
|
|
|
|
|
|
|
// first, check for an event
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == ID) {
|
2003-09-02 09:54:42 +00:00
|
|
|
// reset the 'looping' flag
|
|
|
|
ob_logic->looping = 0;
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// start the event
|
2003-09-02 09:54:42 +00:00
|
|
|
// run 3rd script of target object on level 1
|
2003-10-18 08:11:50 +00:00
|
|
|
logicOne(event_list[i].interact_id);
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// clear the event slot
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = 0;
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_TERMINATE;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
// no event, so do the fnPause bit
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// start the pause
|
|
|
|
if (ob_logic->looping == 0) {
|
2003-07-28 01:44:38 +00:00
|
|
|
ob_logic->looping = 1;
|
2003-09-02 09:54:42 +00:00
|
|
|
// no. of game cycles
|
|
|
|
ob_logic->pause = params[1];
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// if non-zero
|
|
|
|
if (ob_logic->pause) {
|
|
|
|
// decrement the pause count
|
|
|
|
ob_logic->pause--;
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// drop out of script, but call this again next cycle
|
|
|
|
return IR_REPEAT;
|
|
|
|
} else {
|
|
|
|
// pause count is zerp
|
2003-07-28 01:44:38 +00:00
|
|
|
ob_logic->looping = 0;
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// continue script
|
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-10 16:14:52 +00:00
|
|
|
bool Check_event_waiting(void) {
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == ID)
|
2003-10-10 16:14:52 +00:00
|
|
|
return true;
|
2003-09-20 13:11:15 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-10 16:14:52 +00:00
|
|
|
return false;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-02 09:54:42 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnClearEvent(int32 *params) {
|
|
|
|
// params: none
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == ID) {
|
2003-09-02 09:54:42 +00:00
|
|
|
//clear the slot
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = 0;
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 13:11:15 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_CONT;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-26 10:07:18 +00:00
|
|
|
void Start_event(void) {
|
2003-10-18 08:11:50 +00:00
|
|
|
// call this from stuff like fnWalk
|
2003-09-02 09:54:42 +00:00
|
|
|
// you must follow with a return IR_TERMINATE
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == ID) {
|
2003-09-02 09:54:42 +00:00
|
|
|
// run 3rd script of target object on level 1
|
2003-10-18 08:11:50 +00:00
|
|
|
g_logic.logicOne(event_list[i].interact_id);
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
//clear the slot
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2003-09-20 13:11:15 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// oh dear - stop the system
|
2003-07-28 01:44:38 +00:00
|
|
|
Con_fatal_error("Start_event can't find event for id %d", ID);
|
|
|
|
}
|
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
int32 Logic::fnStartEvent(int32 *params) {
|
|
|
|
// params: none
|
|
|
|
|
|
|
|
for (int i = 0; i < MAX_events; i++)
|
|
|
|
if (event_list[i].id == ID) {
|
2003-09-02 09:54:42 +00:00
|
|
|
// run 3rd script of target object on level 1
|
2003-10-18 08:11:50 +00:00
|
|
|
logicOne(event_list[i].interact_id);
|
2003-09-20 13:11:15 +00:00
|
|
|
|
2003-09-02 09:54:42 +00:00
|
|
|
// clear the slot
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = 0;
|
2003-09-02 09:54:42 +00:00
|
|
|
return IR_TERMINATE;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-26 10:07:18 +00:00
|
|
|
// oh dear - stop the system
|
2003-10-18 08:11:50 +00:00
|
|
|
Con_fatal_error("fnStartEvent can't find event for id %d", ID);
|
2003-10-10 16:14:52 +00:00
|
|
|
return 0; // never called - but lets stop them bloody errors
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-26 10:07:18 +00:00
|
|
|
void Kill_all_ids_events(uint32 id) {
|
2003-10-18 08:11:50 +00:00
|
|
|
for (int i = 0; i < MAX_events; i++) {
|
|
|
|
if (event_list[i].id == id) {
|
2003-09-02 09:54:42 +00:00
|
|
|
// clear the slot
|
2003-10-18 08:11:50 +00:00
|
|
|
event_list[i].id = 0;
|
2003-09-02 09:54:42 +00:00
|
|
|
}
|
2003-09-20 13:11:15 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-10-04 00:52:27 +00:00
|
|
|
|
|
|
|
} // End of namespace Sword2
|