Skip to content

Intrinsics mod #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: noobhack-0.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions noobhack/game/brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@

import re

from noobhack import ui
import vt102

from noobhack.game.graphics import ibm
from noobhack.game import shops, status, intrinsics, sounds, dungeon
from noobhack.game.events import dispatcher

import intrinsicsC

class Brain:
"""
GrraaAAaaaAaaaa... braaaAAaaains...
Expand Down Expand Up @@ -53,12 +58,12 @@ def _dispatch_level_feature_events(self, data):
if match is not None:
dispatcher.dispatch("level-feature", feature)

def _dispatch_intrinsic_events(self, data):
for name, messages in intrinsics.messages.iteritems():
for message, value in messages.iteritems():
match = re.search(message, data, re.I | re.M)
if match is not None:
dispatcher.dispatch("intrinsic", name, value)
def _dispatch_intrinsic_events(self, data):
intrinsicsResult = intrinsicsC.DispatchIntrinsics(
intrinsics.messages, self.term.display)

for name, value in intrinsicsResult.items():
dispatcher.dispatch("intrinsic", name, value)

def _dispatch_status_events(self, data):
"""
Expand Down
178 changes: 178 additions & 0 deletions noobhack/game/cpp/intrinsics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#include <Python.h>

#include <boost/regex.hpp>

#include <string>
#include <sstream>
#include <vector>

using namespace std;

namespace
{
static bool firstTime = true;

struct TextSearchItem
{
TextSearchItem()
{}

TextSearchItem(const string& name, const wstring& searchTerm, bool result)
: name_(name),
searchTerm_(searchTerm),
result_(result)
{}

string name_;
wstring searchTerm_;
bool result_; // intrinsic/status enabled or disabled
};

typedef vector<TextSearchItem> TextSearchItems;
static TextSearchItems searchItems;

string ToStr(PyObject* pyOb)
{
// is type-check needed?
return PyString_AsString(pyOb);
}

wstring ToWStr(PyObject* pyOb)
{
// is type-check needed?
const string str = PyString_AsString(pyOb);
return wstring(str.begin(), str.end());
}

bool ToBool(PyObject* pyOb)
{
// if PyBool_check(pyOb) ... is type-check needed?
return Py_True == pyOb;
}

static void ParseDictionary(PyObject* dictionary)
{
firstTime = false; // we don't want to do this again...

PyObject *keys = PyDict_Keys(dictionary);
for(int i = 0; i < PyList_Size(keys); ++i)
{
PyObject* pyItemName = PyList_GetItem(keys, i);
const string itemName = ToStr(pyItemName);

PyObject *itemSearchTerms = PyDict_GetItem(dictionary, pyItemName);
if(!PyDict_Check(itemSearchTerms))
{
continue;
}

PyObject *subKeys = PyDict_Keys(itemSearchTerms);

for(int j = 0; j < PyList_Size(subKeys); ++j)
{
PyObject* pySearchTerm = PyList_GetItem(subKeys, j);

const wstring wsSearchTerm = ToWStr(pySearchTerm);
bool searchTermValue = ToBool(PyDict_GetItem(itemSearchTerms, pySearchTerm));

searchItems.push_back(TextSearchItem(itemName, wsSearchTerm, searchTermValue));
}
}
}
}

static PyObject* DispatchIntrinsics(PyObject *self, PyObject* args)
{
if(PyTuple_Size(args) != 2)
{
return PyDict_New();
}

if(firstTime)
{
PyObject *dictionary = PyTuple_GetItem(args, 0);
// is type-check needed?
if(PyDict_Check(dictionary))
{
ParseDictionary(dictionary);
}
else
{
return NULL;
}
}

typedef pair<string, bool> StdResult;
typedef vector< StdResult > StdResults;
StdResults stdResults;

PyObject *messageData = PyTuple_GetItem(args, 1);
// is type-check needed?
if(PyList_Check(messageData))
{
int listSize = PyList_Size(messageData);

wostringstream lines;

for(int i=0 ; i < listSize ; ++i)
{
PyObject* line = PyList_GetItem(messageData, i);
if(!PyUnicode_Check(line))
{
continue;
}

const wstring wsLine( reinterpret_cast< wchar_t* >( PyUnicode_AS_UNICODE(line) ) );
lines << wsLine;

if(wsLine == L"")
{
continue;
}
}

const wstring fullScreenData = lines.str();

for(TextSearchItems::const_iterator it = searchItems.begin();
it != searchItems.end();
++it)
{
if(boost::regex_search(fullScreenData, boost::wregex(it->searchTerm_)))
{
const string name(it->name_);
const wstring wsName(name.begin(), name.end());

if(it->result_)
{
stdResults.push_back( StdResult(it->name_, true) );
}
else
{
stdResults.push_back( StdResult(it->name_, false) );
}
}
}

}

PyObject* pyResults = PyDict_New();
for(StdResults::const_iterator it = stdResults.begin(); it != stdResults.end(); ++it)
{
const string name(it->first);
PyDict_SetItem(pyResults, PyString_FromString(name.c_str()), it->second ? Py_True : Py_False);
}
return pyResults;
}


static PyMethodDef IntrinsicsMethods[] =
{
{"DispatchIntrinsics", DispatchIntrinsics, METH_VARARGS, "Figure out Intrinsics changed..."},
{NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC initintrinsicsC()
{
(void) Py_InitModule("intrinsicsC", IntrinsicsMethods);
}

52 changes: 26 additions & 26 deletions noobhack/game/intrinsics.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
messages = {
"Warning": {
"You feel sensitive!":True,
"You feel less sensitive!":False,
"You feel sensitive":True,
"You feel less sensitive":False,
},
"Shock resistance": {
"Your health currently feels amplified!":True,
"You feel insulated!":True,
"Your health currently feels amplified":True,
"You feel insulated":True,
"You are shock resistant":True,
"You feel grounded in reality.":True,
"You feel grounded in reality":True,
"You feel conductive":False
},
"Fire resistance": {
"You be chillin'.":True,
"You feel cool!":True,
"You be chillin'":True,
"You feel cool":True,
"You are fire resistant":True,
"You feel a momentary chill.":True,
"You feel warmer!":False
"You feel a momentary chill":True,
"You feel warmer":False
},
"Cold resistance": {
"You are cold resistant":True,
"You feel warm!":True,
"You feel full of hot air.":True,
"You feel cooler!":False
"You feel warm":True,
"You feel full of hot air":True,
"You feel cooler":False
},
"Disintegration resist.": {
"Disintegration resist": {
"You are disintegration-resistant":True,
"You feel very firm.":True,
"You feel totally together, man.":True
"You feel very firm":True,
"You feel totally together, man":True
},
"Poison resistance": {
"You are poison resistant":True,
"You feel( especially)? (healthy)|(hardy)":True,
"You feel a little sick!":False
"You feel a little sick":False
},
"Sleep resistance": {
"You are sleep resistant":True,
"You feel( wide)? awake":True,
"You feel tired!":False
"You feel tired":False
},
"Aggravate monster": {
"You feel that monsters are aware of your presence":True,
Expand All @@ -46,22 +46,22 @@
"You feel vulnerable":False
},
"Invisible": {
"You feel hidden!":True
"You feel hidden":True
},
"See invisible": {
"You see an image of someone stalking you.":True,
"You see an image of someone stalking you":True,
"You feel transparent":True,
"You feel very self-conscious":True,
"Your vision becomes clear":True
},
"Searching": {
"You feel perceptive!":True
"You feel perceptive":True
},
"Speed": {
"You feel quick!":True,
"You feel yourself speed up.":True, # speed boots put on (want this here?)!
"You feel yourself slow down.":False, # speed boots removed (want this here?)!
"You feel slow!":False
"You feel quick":True,
"You feel yourself speed up":True, # speed boots put on (want this here?)!
"You feel yourself slow down":False, # speed boots removed (want this here?)!
"You feel slow":False
},
"Teleportitis": {
"You feel very jumpy":True,
Expand All @@ -70,9 +70,9 @@
},
"Teleport control": {
"You feel in control of yourself":True,
"You feel controlled!":True,
"You feel controlled":True,
"You feel centered in your personal space":True,
"You feel less jumpy":False
"You feel less jumpy":False
},
"Telepathy": {
"You feel in touch with the cosmos":True,
Expand Down
9 changes: 7 additions & 2 deletions scripts/noobhack
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import optparse

import cPickle as pickle

#import profile

import cProfile

import vt102

from noobhack import ui, telnet, process, proxy
Expand Down Expand Up @@ -314,9 +318,10 @@ class Noobhack:

if __name__ == "__main__":
locale.setlocale(locale.LC_ALL, "")

hack = Noobhack()
try:
curses.wrapper(hack.run)
# profile.run('curses.wrapper(hack.run); print')
cProfile.run('curses.wrapper(hack.run)', "noobhack.trace")
except IOError, exit_message:
print exit_message
11 changes: 9 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from distutils.core import setup
from distutils.core import setup, Extension

intrinsicsModule = Extension('intrinsicsC',
sources = ['noobhack/game/cpp/intrinsics.cpp'],
libraries = ['boost_regex'])

setup(
name="noobhack",
Expand All @@ -11,5 +15,8 @@
requires=["vt102 (>=0.3.2)"],
packages=["noobhack", "noobhack.game"],
scripts=["scripts/noobhack"],
license="Lesser General Public License v3.0"
license="Lesser General Public License v3.0",
ext_modules=[intrinsicsModule], #Extension('intrinsicsC', ['noobhack/game/cpp/intrinsics.cpp'])],
)


Loading