forked from teamnwah/openmw-tes3coop
Made the first working Monster script within OpenMW
git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@62 ea6a568a-9f4f-0410-981a-c910a81bb256actorid
parent
3f1aeb3aef
commit
7349221b9c
@ -0,0 +1,70 @@
|
||||
module mscripts.object;
|
||||
|
||||
import monster.monster;
|
||||
import std.stdio;
|
||||
import std.date;
|
||||
|
||||
// Set up the base Monster classes we need in OpenMW
|
||||
void initMonsterScripts()
|
||||
{
|
||||
// Add the script directory
|
||||
MonsterClass.addPath("mscripts/");
|
||||
|
||||
// Make sure the Object class is loaded
|
||||
auto mc = new MonsterClass("Object", "object.mn");
|
||||
|
||||
// Bind various functions
|
||||
mc.bind("print", { print(); });
|
||||
mc.bind("sleep", new IdleSleep);
|
||||
|
||||
// Load and run the test script
|
||||
mc = new MonsterClass("Test");
|
||||
mc.createObject().call("test");
|
||||
}
|
||||
|
||||
// Write a message to screen
|
||||
void print()
|
||||
{
|
||||
AIndex[] args = stack.popAArray();
|
||||
|
||||
foreach(AIndex ind; args)
|
||||
writef("%s ", arrays.getRef(ind).carr);
|
||||
writefln();
|
||||
}
|
||||
|
||||
// Sleep a given amount of time. Currently uses the system clock, but
|
||||
// will later be optimized to use the already existing timing
|
||||
// information from OGRE.
|
||||
class IdleSleep : IdleFunction
|
||||
{
|
||||
long getLong(MonsterObject *mo)
|
||||
{ return *(cast(long*)mo.extra); }
|
||||
void setLong(MonsterObject *mo, long l)
|
||||
{ *(cast(long*)mo.extra) = l; }
|
||||
|
||||
override:
|
||||
bool initiate(MonsterObject *mo)
|
||||
{
|
||||
// Get the parameter
|
||||
double secs = stack.popFloat;
|
||||
|
||||
// Get current time
|
||||
long newTime = getUTCtime();
|
||||
|
||||
// Calculate when we should return
|
||||
newTime += secs*TicksPerSecond;
|
||||
|
||||
// Store it
|
||||
if(mo.extra == null) mo.extra = new long;
|
||||
setLong(mo, newTime);
|
||||
|
||||
// Schedule us
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasFinished(MonsterObject *mo)
|
||||
{
|
||||
// Is it time?
|
||||
return getUTCtime() >= getLong(mo);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// This is the base class of all OpenMW Monster classes.
|
||||
class Object;
|
||||
|
||||
// Sleeps a given amount of time
|
||||
idle sleep(float seconds);
|
||||
|
||||
// Print a message to screen
|
||||
native print(char[][] msg...);
|
@ -0,0 +1,17 @@
|
||||
// A sample class
|
||||
class Test : Object;
|
||||
|
||||
test()
|
||||
{
|
||||
state = printMessage;
|
||||
}
|
||||
|
||||
state printMessage
|
||||
{
|
||||
// This state code will run as long as the object is in this state.
|
||||
begin:
|
||||
sleep(10);
|
||||
print("Howdy from the world of Monster scripts!");
|
||||
print("This script is located in mscripts/test.mn. Check it out!");
|
||||
goto begin;
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.snaptoad.com/
|
||||
|
||||
This file (utfconvert.d) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
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
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
module util.utfconvert;
|
||||
|
||||
import std.utf;
|
||||
|
||||
// A specialized version of std.utf.decode(). It returns a bool rather
|
||||
// than throwing an exception.
|
||||
private bool fdecode(char[] s, inout size_t idx)
|
||||
{
|
||||
size_t len = s.length;
|
||||
dchar V;
|
||||
size_t i = idx;
|
||||
char u = s[i];
|
||||
|
||||
if (u & 0x80)
|
||||
{ uint n;
|
||||
char u2;
|
||||
|
||||
/* The following encodings are valid, except for the 5 and 6 byte
|
||||
* combinations:
|
||||
* 0xxxxxxx
|
||||
* 110xxxxx 10xxxxxx
|
||||
* 1110xxxx 10xxxxxx 10xxxxxx
|
||||
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
*/
|
||||
for (n = 1; ; n++)
|
||||
{
|
||||
if (n > 4)
|
||||
return false; // only do the first 4 of 6 encodings
|
||||
if (((u << n) & 0x80) == 0)
|
||||
{
|
||||
if (n == 1)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Pick off (7 - n) significant bits of B from first byte of octet
|
||||
V = cast(dchar)(u & ((1 << (7 - n)) - 1));
|
||||
|
||||
if (i + (n - 1) >= len)
|
||||
return false; // off end of string
|
||||
|
||||
/* The following combinations are overlong, and illegal:
|
||||
* 1100000x (10xxxxxx)
|
||||
* 11100000 100xxxxx (10xxxxxx)
|
||||
* 11110000 1000xxxx (10xxxxxx 10xxxxxx)
|
||||
* 11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)
|
||||
* 11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
|
||||
*/
|
||||
u2 = s[i + 1];
|
||||
if ((u & 0xFE) == 0xC0 ||
|
||||
(u == 0xE0 && (u2 & 0xE0) == 0x80) ||
|
||||
(u == 0xF0 && (u2 & 0xF0) == 0x80) ||
|
||||
(u == 0xF8 && (u2 & 0xF8) == 0x80) ||
|
||||
(u == 0xFC && (u2 & 0xFC) == 0x80))
|
||||
return false; // overlong combination
|
||||
|
||||
for (uint j = 1; j != n; j++)
|
||||
{
|
||||
u = s[i + j];
|
||||
if ((u & 0xC0) != 0x80)
|
||||
return false; // trailing bytes are 10xxxxxx
|
||||
V = (V << 6) | (u & 0x3F);
|
||||
}
|
||||
if (!isValidDchar(V))
|
||||
return false;
|
||||
i += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
V = cast(dchar) u;
|
||||
i++;
|
||||
}
|
||||
|
||||
idx = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Converts any string to valid UTF8 so it can be safely printed. It
|
||||
// does not translate from other encodings but simply replaces invalid
|
||||
// characters with 'replace'. Does everything in place.
|
||||
char[] makeUTF8(char[] str, char replace = '?')
|
||||
{
|
||||
size_t idx = 0;
|
||||
while(idx < str.length)
|
||||
if(!fdecode(str, idx))
|
||||
str[idx++] = replace;
|
||||
return str;
|
||||
}
|
Loading…
Reference in New Issue