diff --git a/Scripts/Python/plasma/Plasma.py b/Scripts/Python/plasma/Plasma.py index 19901433fa..53f2f4110f 100644 --- a/Scripts/Python/plasma/Plasma.py +++ b/Scripts/Python/plasma/Plasma.py @@ -43,7 +43,7 @@ from __future__ import annotations from PlasmaConstants import * -from typing import Callable, Optional, Tuple, Union +from typing import Callable, Iterable, Optional, Tuple, Union def PtAcceptInviteInGame(friendName,inviteKey): """Sends a VaultTask to the server to perform the invite""" @@ -306,6 +306,14 @@ def PtFileExists(filename): """Returns true if the specified file exists""" pass +def PtFindImage(name: str) -> Iterable[ptImage]: + """Find an already loaded image by name""" + ... + +def PtFindLayer(name: str, age: str = "", page: str = "") -> Optional[ptLayer]: + """Find a layer by name""" + ... + def PtFindSceneobject(name,ageName): """This will try to find a sceneobject based on its name and what age its in - it will return a ptSceneObject if found- if not found then a NameError exception will happen""" @@ -5271,6 +5279,24 @@ def saveAsJPEG(self,filename,quality=75): """Saves this image to disk as a JPEG file""" pass +class ptImageLibMod: + """Plasma ImageLibraryModifier class""" + def __init__(self,imlkey): + """None""" + pass + + def getImage(imageName): + """Returns the named image, if present""" + pass + + def getImages(): + """Returns a tuple of ptImages""" + pass + + def getNames(): + """Returns a tuple of the image names""" + pass + class ptInputInterface: """Plasma input interface class""" def __init__(self): @@ -5391,6 +5417,20 @@ def writeKeyMap(self): """Forces write of the keymap file""" pass +class ptLayer: + """Plasma Layer class""" + def __init__(self,layerKey): + """None""" + pass + + def getTexture(self) -> ptImage: + """Returns the image texture of the layer""" + ... + + def setTexture(self, image: ptImage) -> None: + """Sets the texture of the layer""" + ... + class ptMarkerMgr: """Marker manager accessor class""" def __init__(self): @@ -6066,6 +6106,10 @@ def getPythonMods(self): """Returns list of ptKeys of the python modifiers attached to this sceneobject""" pass + def getImageLibMods(self): + """Returns list of ptKeys of the image library modifiers attached to this sceneobject""" + pass + def getResponderState(self): """Return the responder state (if we are a responder)""" pass diff --git a/Scripts/Python/plasma/PlasmaTypes.py b/Scripts/Python/plasma/PlasmaTypes.py index abbcd6becd..960a9e85c3 100644 --- a/Scripts/Python/plasma/PlasmaTypes.py +++ b/Scripts/Python/plasma/PlasmaTypes.py @@ -895,6 +895,18 @@ def __setvalue__(self,value): self.shader = ptGrassShader(value) self.value = self.shader +# a Layer attribute +class ptAttribLayer(ptAttribute): + def __init__(self,id,name=None): + ptAttribute.__init__(self,id,name) + self.value = None + self.layer = None + def getdef(self): + return (self.id, self.name, 25) + def __setvalue__(self,value): + self.layer = ptLayer(value) + self.value = self.layer + # # ptModifier - class for creating a Plasma modifier, such as a responder diff --git a/Scripts/Python/stupStartUp.py b/Scripts/Python/stupStartUp.py index cbde12715b..e507344a60 100644 --- a/Scripts/Python/stupStartUp.py +++ b/Scripts/Python/stupStartUp.py @@ -48,11 +48,15 @@ launch start up sequence """ +import random + from Plasma import * from PlasmaTypes import * # define the attributes that will be entered in max Camera = ptAttribSceneobject(1, "Camera") +BGObj = ptAttribSceneobject(2, "Background Object") +BGLayer = ptAttribLayer(3, "Background Image Layer") #==================================== @@ -104,3 +108,20 @@ def OnServerInitComplete(self): PtShowDialog("GUIDialog04b") else: PtShowDialog("GUIDialog06") + + self.randomizeBackground() + + + ########################### + def randomizeBackground(self): + if not BGObj.sceneobject or not BGLayer.layer: + PtDebugPrint("stupStartUp: Missing ptAttribs for randomized backgrounds. Leaving default...") + return + + # Get the first available ImageLibModifier on our Background SceneObject + if ilm := next(iter(BGObj.sceneobject.getImageLibMods()), None): + # Choose a random image from the available images + bgChoice = random.choice(ilm.getImages()) + # Update the Background Layer's texture to our chosen image + BGLayer.layer.setTexture(bgChoice) + PtDebugPrint("stupStartUp: Background has been randomized.") diff --git a/Sources/MaxPlugin/MaxComponent/plAutoUIBase.cpp b/Sources/MaxPlugin/MaxComponent/plAutoUIBase.cpp index 7eb0122add..136707001f 100644 --- a/Sources/MaxPlugin/MaxComponent/plAutoUIBase.cpp +++ b/Sources/MaxPlugin/MaxComponent/plAutoUIBase.cpp @@ -375,6 +375,18 @@ void plAutoUIBase::AddPickGrassComponentButton(int16_t id, const ST::string& scr fParams.push_back(param); } +void plAutoUIBase::AddPickLayerButton(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set vstates) +{ + ST::string scriptNameNew = !scriptName.empty() ? scriptName : IMakeScriptName(name); + + fDesc->AddParam(id, ST2M(scriptNameNew), TYPE_REFTARG, 0, 0, + p_end, + p_end); + plAutoUIParam* param = new plPickMaterialButtonParam(id, name); + param->SetVisInfo(vid, std::move(vstates)); + fParams.push_back(param); +} + INT_PTR CALLBACK plAutoUIBase::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { plAutoUIBase *pthis = nullptr; diff --git a/Sources/MaxPlugin/MaxComponent/plAutoUIBase.h b/Sources/MaxPlugin/MaxComponent/plAutoUIBase.h index c0115262b7..7d08ea7ae9 100644 --- a/Sources/MaxPlugin/MaxComponent/plAutoUIBase.h +++ b/Sources/MaxPlugin/MaxComponent/plAutoUIBase.h @@ -120,6 +120,7 @@ class plAutoUIBase void AddDropDownList(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set vstates, std::vector options); void AddPickGrassComponentButton(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set vstates); + void AddPickLayerButton(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set vstates); void CreateAutoRollup(IParamBlock2 *pb); void DestroyAutoRollup(); diff --git a/Sources/MaxPlugin/MaxComponent/plAutoUIParams.h b/Sources/MaxPlugin/MaxComponent/plAutoUIParams.h index 1323308651..a36b5477dc 100644 --- a/Sources/MaxPlugin/MaxComponent/plAutoUIParams.h +++ b/Sources/MaxPlugin/MaxComponent/plAutoUIParams.h @@ -92,6 +92,7 @@ class plAutoUIParam kTypeClusterComponent, kTypeMaterialAnimation, kTypeGrassComponent, + kTypeLayer }; plAutoUIParam(ParamID id, ST::string name); diff --git a/Sources/MaxPlugin/MaxComponent/plPythonFileComponent.cpp b/Sources/MaxPlugin/MaxComponent/plPythonFileComponent.cpp index 6bdcad6cdd..aa37845a20 100644 --- a/Sources/MaxPlugin/MaxComponent/plPythonFileComponent.cpp +++ b/Sources/MaxPlugin/MaxComponent/plPythonFileComponent.cpp @@ -80,6 +80,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plAvatar/plSwimRegion.h" #include "plSurface/plGrassShaderMod.h" #include "plGrassComponent.h" +#include "plSurface/plLayer.h" #include "plMessageBox/hsMessageBox.h" @@ -990,6 +991,21 @@ bool plPythonFileComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) } } break; + case plAutoUIParam::kTypeLayer: + { + int numKeys = param->GetCount(pb); + for (int i = 0; i < numKeys; i++) + { + plKey key = param->GetKey(pb, i); + // make sure we got a key and that it is a plLayer + if (key && plLayer::ConvertNoRef(key->GetObjectPtr())) + { + pyParam.SetToLayer(key); + mod->AddParameter(pyParam); + } + } + } + break; } } diff --git a/Sources/MaxPlugin/MaxMain/plPythonMgr.cpp b/Sources/MaxPlugin/MaxMain/plPythonMgr.cpp index 990c9dddcb..8cdd847468 100644 --- a/Sources/MaxPlugin/MaxMain/plPythonMgr.cpp +++ b/Sources/MaxPlugin/MaxMain/plPythonMgr.cpp @@ -180,7 +180,8 @@ enum ParamTypes kTypeSwimCurrentInterface, // 21 kTypeClusterComponent, // 22 kTypeMaterialAnimation, // 23 - kTypeGrassComponent, // 24 + kTypeGrassComponent, // 24 + kTypeLayer, // 25 }; bool IGetTupleInt(PyObject *tuple, int pos, int& val) @@ -451,6 +452,9 @@ bool plPythonMgr::IQueryPythonFile(const ST::string& fileName) case kTypeGrassComponent: IAddGrassComponent(autoUI, ret, paramName, paramID, ddlParamID, vec); break; + case kTypeLayer: + IAddLayerComponent(autoUI, ret, paramName, paramID, ddlParamID, vec); + break; } } } @@ -624,6 +628,11 @@ void plPythonMgr::IAddGrassComponent(plAutoUIBlock *autoUI, PyObject *objTuple, autoUI->AddPickGrassComponentButton(id, {}, paramName, vid, std::move(vstates)); } +void plPythonMgr::IAddLayerComponent(plAutoUIBlock* autoUI, PyObject* objTuple, const ST::string& paramName, int id, int vid, std::unordered_set vstates) +{ + autoUI->AddPickLayerButton(id, {}, paramName, vid, std::move(vstates)); +} + void plPythonMgr::LoadPythonFiles() { plFileName clientPath = plMaxConfig::GetClientPath(false, true); diff --git a/Sources/MaxPlugin/MaxMain/plPythonMgr.h b/Sources/MaxPlugin/MaxMain/plPythonMgr.h index eff45edb57..6b7dded958 100644 --- a/Sources/MaxPlugin/MaxMain/plPythonMgr.h +++ b/Sources/MaxPlugin/MaxMain/plPythonMgr.h @@ -81,6 +81,7 @@ class plPythonMgr void IAddClusterComponent(plAutoUIBlock *autoUI, PyObject *tuple, const ST::string& paramName, int id, int vid, std::unordered_set vstates); void IAddMaterialAnimation(plAutoUIBlock *autoUI, PyObject *tuple, const ST::string& paramName, int id, int vid, std::unordered_set vstates); void IAddGrassComponent(plAutoUIBlock *autoUI, PyObject *objTuple, const ST::string& paramName, int id, int vid, std::unordered_set vstates); + void IAddLayerComponent(plAutoUIBlock *autoUI, PyObject *objTuple, const ST::string& paramName, int id, int vid, std::unordered_set vstates); public: static plPythonMgr& Instance(); diff --git a/Sources/Plasma/FeatureLib/pfPython/CMakeLists.txt b/Sources/Plasma/FeatureLib/pfPython/CMakeLists.txt index 22d2052066..38041ecb9f 100644 --- a/Sources/Plasma/FeatureLib/pfPython/CMakeLists.txt +++ b/Sources/Plasma/FeatureLib/pfPython/CMakeLists.txt @@ -51,9 +51,11 @@ set(pfPython_SOURCES pyGUIPopUpMenu.cpp pyGUISkin.cpp pyImage.cpp + pyImageLibMod.cpp pyJournalBook.cpp pyKey.cpp pyKeyMap.cpp + pyLayer.cpp pyMarkerMgr.cpp pyMatrix44.cpp pyMoviePlayer.cpp @@ -142,9 +144,11 @@ set(pfPython_HEADERS pyGUIPopUpMenu.h pyGUISkin.h pyImage.h + pyImageLibMod.h pyJournalBook.h pyKey.h pyKeyMap.h + pyLayer.h pyMarkerMgr.h pyMatrix44.h pyMoviePlayer.h @@ -229,9 +233,11 @@ set(pfPython_GLUE pyGUIPopUpMenuGlue.cpp pyGUISkinGlue.cpp pyImageGlue.cpp + pyImageLibModGlue.cpp pyJournalBookGlue.cpp pyKeyGlue.cpp pyKeyMapGlue.cpp + pyLayerGlue.cpp pyMarkerMgrGlue.cpp pyMatrix44Glue.cpp pyMoviePlayerGlue.cpp @@ -294,6 +300,7 @@ target_link_libraries( plGImage plGLight plInputCore + plSurface plModifier plNetClient plNetClientComm diff --git a/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp b/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp index d2456a31fd..703d86b15f 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp @@ -155,6 +155,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pyJournalBook.h" #include "pyKeyMap.h" +#include "pyImageLibMod.h" +#include "pyLayer.h" #include "pyStream.h" #include "pyMoviePlayer.h" @@ -1037,6 +1039,7 @@ void PythonInterface::AddPlasmaMethods(PyObject* m) pyGUIDialog::AddPlasmaMethods(m); pyImage::AddPlasmaMethods(m); pyJournalBook::AddPlasmaMethods(m); + pyLayer::AddPlasmaMethods(m); pySDLModifier::AddPlasmaMethods(m); pySpawnPointInfo::AddPlasmaMethods(m); } @@ -1079,8 +1082,10 @@ void PythonInterface::AddPlasmaClasses(PyObject* plasmaMod) pyDniInfoSource::AddPlasmaClasses(plasmaMod); pyDynamicText::AddPlasmaClasses(plasmaMod); pyImage::AddPlasmaClasses(plasmaMod); + pyImageLibMod::AddPlasmaClasses(plasmaMod); pyJournalBook::AddPlasmaClasses(plasmaMod); pyKeyMap::AddPlasmaClasses(plasmaMod); + pyLayer::AddPlasmaClasses(plasmaMod); pyMarkerMgr::AddPlasmaClasses(plasmaMod); pyMoviePlayer::AddPlasmaClasses(plasmaMod); pyNetLinkingMgr::AddPlasmaClasses(plasmaMod); diff --git a/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp b/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp index 0265b3ba9a..cf42517051 100644 --- a/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp @@ -561,6 +561,7 @@ void plPythonFileMod::AddTarget(plSceneObject* sobj) case plPythonParameter::kClusterComponentList: case plPythonParameter::kMaterialAnimation: case plPythonParameter::kGrassShaderComponent: + case plPythonParameter::kLayer: if (parameter.fObjectKey) { // create pyKey for the object value = pyKey::New(parameter.fObjectKey); diff --git a/Sources/Plasma/FeatureLib/pfPython/plPythonParameter.h b/Sources/Plasma/FeatureLib/pfPython/plPythonParameter.h index 3afc1de9cc..7aa1a786c0 100644 --- a/Sources/Plasma/FeatureLib/pfPython/plPythonParameter.h +++ b/Sources/Plasma/FeatureLib/pfPython/plPythonParameter.h @@ -88,6 +88,7 @@ typedef struct plPythonParameter kClusterComponentList, kMaterialAnimation, kGrassShaderComponent, + kLayer, kNone }; @@ -204,6 +205,9 @@ typedef struct plPythonParameter case kGrassShaderComponent: SetToGrassShaderComponent(other.fObjectKey); break; + case kLayer: + SetToLayer(other.fObjectKey); + break; } return *this; } @@ -347,6 +351,12 @@ typedef struct plPythonParameter fValueType = kGrassShaderComponent; fObjectKey = std::move(key); } + void SetToLayer(plKey key) + { + SetToNone(); + fValueType = kLayer; + fObjectKey = std::move(key); + } // read and write routines for export and reading in at runtime void Read(hsStream *stream, hsResMgr* mgr) @@ -404,6 +414,7 @@ typedef struct plPythonParameter case kClusterComponentList: case kMaterialAnimation: case kGrassShaderComponent: + case kLayer: fObjectKey = mgr->ReadKey(stream); break; } @@ -455,6 +466,7 @@ typedef struct plPythonParameter case kClusterComponentList: case kMaterialAnimation: case kGrassShaderComponent: + case kLayer: mgr->WriteKey(stream, fObjectKey); break; diff --git a/Sources/Plasma/FeatureLib/pfPython/pyImage.cpp b/Sources/Plasma/FeatureLib/pfPython/pyImage.cpp index 4ba2c0d012..43b291fb33 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pyImage.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/pyImage.cpp @@ -42,6 +42,9 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pyImage.h" +#include +#include + #include #include "hsResMgr.h" @@ -52,6 +55,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plGImage/plJPEG.h" #include "plGImage/plMipmap.h" #include "plGImage/plPNG.h" +#include "plResMgr/plKeyFinder.h" #include "pyColor.h" #include "pyGeometry3.h" @@ -201,6 +205,23 @@ void pyImage::SaveAsPNG(const plFileName& fileName, const std::multimapGetImage(), textFields); } +PyObject* pyImage::Find(const ST::string& name) +{ + std::vector foundKeys; + plKeyFinder::Instance().ReallyStupidSubstringSearch(name, plMipmap::Index(), foundKeys); + // Remove anything that isn't loaded - they aren't useful in Python code + std::remove_if( + foundKeys.begin(), + foundKeys.end(), + [](const plKey& key) { return key->ObjectIsLoaded() == nullptr; } + ); + + PyObject* tup = PyTuple_New(foundKeys.size()); + for (size_t i = 0; i < foundKeys.size(); ++i) + PyTuple_SET_ITEM(tup, i, pyImage::New(foundKeys[i])); + return tup; +} + PyObject* pyImage::LoadJPEGFromDisk(const plFileName& filename, uint16_t width, uint16_t height) { plMipmap* theMipmap = plJPEG::Instance().ReadFromFile(filename); diff --git a/Sources/Plasma/FeatureLib/pfPython/pyImage.h b/Sources/Plasma/FeatureLib/pfPython/pyImage.h index 73fe2559e4..3dac7ce584 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pyImage.h +++ b/Sources/Plasma/FeatureLib/pfPython/pyImage.h @@ -150,6 +150,8 @@ class pyImage uint32_t GetHeight(); // returns the height of the image void SaveAsJPEG(const plFileName& fileName, uint8_t quality = 75); void SaveAsPNG(const plFileName& fileName, const std::multimap& textFields = std::multimap()); + + static PyObject* Find(const ST::string& name); static PyObject* LoadJPEGFromDisk(const plFileName& filename, uint16_t width, uint16_t height); // returns pyImage static PyObject* LoadPNGFromDisk(const plFileName& filename, uint16_t width, uint16_t height); // returns pyImage #endif diff --git a/Sources/Plasma/FeatureLib/pfPython/pyImageGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/pyImageGlue.cpp index a0183fc0f0..b6d1fd5f29 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pyImageGlue.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/pyImageGlue.cpp @@ -252,6 +252,17 @@ void pyImage::AddPlasmaClasses(PyObject *m) } #ifndef BUILDING_PYPLASMA +PYTHON_GLOBAL_METHOD_DEFINITION(PtFindImage, args, "Params: name\nFind an already loaded image by name.") +{ + ST::string name; + if (!PyArg_ParseTuple(args, "O&", PyUnicode_STStringConverter, &name)) { + PyErr_SetString(PyExc_TypeError, "PtFindImage expects a string"); + PYTHON_RETURN_ERROR; + } + + return pyImage::Find(name); +} + PYTHON_GLOBAL_METHOD_DEFINITION(PtLoadJPEGFromDisk, args, "Params: filename,width,height\nThe image will be resized to fit the width and height arguments. Set to 0 if resizing is not desired.\nReturns a pyImage of the specified file.") { plFileName filename; @@ -283,6 +294,7 @@ void pyImage::AddPlasmaMethods(PyObject* m) { #ifndef BUILDING_PYPLASMA PYTHON_START_GLOBAL_METHOD_TABLE(ptImage) + PYTHON_GLOBAL_METHOD(PtFindImage) PYTHON_GLOBAL_METHOD(PtLoadJPEGFromDisk) PYTHON_GLOBAL_METHOD(PtLoadPNGFromDisk) PYTHON_END_GLOBAL_METHOD_TABLE(m, ptImage) diff --git a/Sources/Plasma/FeatureLib/pfPython/pyImageLibMod.cpp b/Sources/Plasma/FeatureLib/pfPython/pyImageLibMod.cpp new file mode 100644 index 0000000000..4d1c7ae2f5 --- /dev/null +++ b/Sources/Plasma/FeatureLib/pfPython/pyImageLibMod.cpp @@ -0,0 +1,105 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 3 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, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#include +#include "pyKey.h" +#include "hsResMgr.h" + +#include "pnKeyedObject/plUoid.h" +#include "pyImage.h" +#include "pyImageLibMod.h" + + +void pyImageLibMod::setKey(pyKey& ilmKey) // only for python glue, do NOT call +{ + if (fModifier && fModifierKey) + fModifierKey->UnRefObject(); + + fModifier = nullptr; + fModifierKey = ilmKey.getKey(); +} + +PyObject* pyImageLibMod::GetImage(const ST::string& name) const +{ + plBitmap* image; + + if (fModifier) + image = fModifier->GetImage(name); + else + image = plImageLibMod::ConvertNoRef(fModifierKey->ObjectIsLoaded())->GetImage(name); + + if (image) + return pyImage::New(plMipmap::ConvertNoRef(image)); + + PYTHON_RETURN_NONE; +} + +std::vector pyImageLibMod::GetImages() const +{ + std::vector imageList; + plImageLibMod* mod; + + if (fModifier) + mod = fModifier; + else + mod = plImageLibMod::ConvertNoRef(fModifierKey->ObjectIsLoaded()); + + imageList.reserve(mod->GetImages().size()); + for (const auto& image : mod->GetImages()) { + if (image) + imageList.push_back(pyImage::New(plMipmap::ConvertNoRef(image))); + } + + return imageList; +} + +std::vector pyImageLibMod::GetImageNames() const +{ + plImageLibMod* mod; + + if (fModifier) + mod = fModifier; + else + mod = plImageLibMod::ConvertNoRef(fModifierKey->ObjectIsLoaded()); + + return mod->GetImageNames(); +} diff --git a/Sources/Plasma/FeatureLib/pfPython/pyImageLibMod.h b/Sources/Plasma/FeatureLib/pfPython/pyImageLibMod.h new file mode 100644 index 0000000000..39d7e3ab7f --- /dev/null +++ b/Sources/Plasma/FeatureLib/pfPython/pyImageLibMod.h @@ -0,0 +1,124 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 3 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, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#ifndef pyImageLibMod_h +#define pyImageLibMod_h + +///////////////////////////////////////////////////////////////////////////// +// +// NAME: pyImageLibMod +// +// PURPOSE: Class wrapper for Python to a plImageLib Modifier +// + +#include "pyGlueHelpers.h" + +#include "plModifier/plImageLibMod.h" + +class plKey; +class pyImage; + +class pyImageLibMod +{ +protected: + plKey fModifierKey; + plImageLibMod* fModifier; + + // For python glue only, do NOT call + pyImageLibMod() + : fModifierKey(), fModifier() + { } + + // Constructor from C++ + pyImageLibMod(plKey ilmKey) + : fModifierKey(std::move(ilmKey)), fModifier() + { } + + // Constructor from C++ ... uses pointer instead of plKey + pyImageLibMod(plImageLibMod* ilm) + : fModifierKey(ilm->GetKey()), fModifier(ilm) + { + if (fModifierKey) + fModifierKey->RefObject(); + } + +public: + ~pyImageLibMod() + { + if (fModifier && fModifierKey) + fModifierKey->UnRefObject(); + } + + // required functions for PyObject interoperability + PYTHON_CLASS_NEW_FRIEND(ptImageLibMod); + static PyObject* New(plImageLibMod* ilm); + static PyObject* New(plKey ilmKey); + static PyObject* New(pyKey& ilmKey); + PYTHON_CLASS_CHECK_DEFINITION; // returns true if the PyObject is a pyImageLibMod object + PYTHON_CLASS_CONVERT_FROM_DEFINITION(pyImageLibMod); // converts a PyObject to a pyImageLibMod (throws error if not correct type) + + static void AddPlasmaClasses(PyObject* m); + static void AddPlasmaMethods(PyObject* m); + + void setKey(pyKey& ilmKey); + + // override the equals to operator + bool operator==(const pyImageLibMod& mod) const + { + // only thing that needs testing is the plKey, which is unique for all + if (fModifierKey == ((pyImageLibMod&)mod).GetKey() ) + return true; + else + return false; + } + bool operator!=(const pyImageLibMod& mod) const { return !(mod == *this); } + + // for C++ access + plKey GetKey() const { return fModifier ? fModifier->GetKey() : fModifierKey; } + + // for python access + PyObject* GetImage(const ST::string& name) const; + std::vector GetImageNames() const; + std::vector GetImages() const; +}; + +#endif // pyImageLibMod_h diff --git a/Sources/Plasma/FeatureLib/pfPython/pyImageLibModGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/pyImageLibModGlue.cpp new file mode 100644 index 0000000000..cf14b0f674 --- /dev/null +++ b/Sources/Plasma/FeatureLib/pfPython/pyImageLibModGlue.cpp @@ -0,0 +1,150 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 3 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, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + + +#include +#include "pyKey.h" + +#include "pyImageLibMod.h" +#include "pyImage.h" +#include "plGImage/plMipmap.h" + +// glue functions +PYTHON_CLASS_DEFINITION(ptImageLibMod, pyImageLibMod); + +PYTHON_DEFAULT_NEW_DEFINITION(ptImageLibMod, pyImageLibMod) +PYTHON_DEFAULT_DEALLOC_DEFINITION(ptImageLibMod) + +PYTHON_INIT_DEFINITION(ptImageLibMod, args, keywords) +{ + PyObject* keyObj = nullptr; + if (!PyArg_ParseTuple(args, "O", &keyObj)) + { + PyErr_SetString(PyExc_TypeError, "__init__ expects a ptKey"); + PYTHON_RETURN_INIT_ERROR; + } + if (!pyKey::Check(keyObj)) + { + PyErr_SetString(PyExc_TypeError, "__init__ expects a ptKey"); + PYTHON_RETURN_INIT_ERROR; + } + pyKey* key = pyKey::ConvertFrom(keyObj); + self->fThis->setKey(*key); + PYTHON_RETURN_INIT_OK; +} + +PYTHON_METHOD_DEFINITION(ptImageLibMod, getImage, args) +{ + ST::string name; + if (!PyArg_ParseTuple(args, "O&", PyUnicode_STStringConverter, &name)) { + PyErr_SetString(PyExc_TypeError, "getImage expects an image name"); + PYTHON_RETURN_ERROR; + } + + return self->fThis->GetImage(name); +} + +PYTHON_METHOD_DEFINITION_NOARGS(ptImageLibMod, getImages) +{ + const std::vector imageList = self->fThis->GetImages(); + PyObject* retVal = PyTuple_New(imageList.size()); + for (size_t curKey = 0; curKey < imageList.size(); curKey++) + PyTuple_SET_ITEM(retVal, curKey, imageList[curKey]); + return retVal; +} + +PYTHON_METHOD_DEFINITION_NOARGS(ptImageLibMod, getNames) +{ + std::vector nameList = self->fThis->GetImageNames(); + PyObject* retVal = PyTuple_New(nameList.size()); + for (size_t curKey = 0; curKey < nameList.size(); curKey++) + PyTuple_SET_ITEM(retVal, curKey, PyUnicode_FromSTString(nameList[curKey])); + return retVal; +} + +PYTHON_START_METHODS_TABLE(ptImageLibMod) + PYTHON_METHOD(ptImageLibMod, getImage, "Params: name\nReturns the ptImage with the specified name"), + PYTHON_METHOD_NOARGS(ptImageLibMod, getImages, "Returns a tuple of the library's ptImages"), + PYTHON_METHOD_NOARGS(ptImageLibMod, getNames, "Returns the list of image names"), +PYTHON_END_METHODS_TABLE; + +// Type structure definition +PLASMA_DEFAULT_TYPE(ptImageLibMod, "Params: ilmKey\nPlasma image library modifier class"); + +// required functions for PyObject interoperability +PyObject* pyImageLibMod::New(plImageLibMod* ilm) +{ + ptImageLibMod* newObj = (ptImageLibMod*)ptImageLibMod_type.tp_new(&ptImageLibMod_type, nullptr, nullptr); + newObj->fThis->fModifier = ilm; + newObj->fThis->fModifierKey = ilm->GetKey(); + if (ilm->GetKey()) + newObj->fThis->fModifierKey->RefObject(); + return (PyObject*)newObj; +} + +PyObject* pyImageLibMod::New(plKey ilmKey) +{ + ptImageLibMod* newObj = (ptImageLibMod*)ptImageLibMod_type.tp_new(&ptImageLibMod_type, nullptr, nullptr); + newObj->fThis->fModifierKey = std::move(ilmKey); + return (PyObject*)newObj; +} + +PyObject* pyImageLibMod::New(pyKey& ilmKey) +{ + ptImageLibMod* newObj = (ptImageLibMod*)ptImageLibMod_type.tp_new(&ptImageLibMod_type, nullptr, nullptr); + newObj->fThis->fModifierKey = ilmKey.getKey(); + return (PyObject*)newObj; +} + +PYTHON_CLASS_CHECK_IMPL(ptImageLibMod, pyImageLibMod) +PYTHON_CLASS_CONVERT_FROM_IMPL(ptImageLibMod, pyImageLibMod) + +/////////////////////////////////////////////////////////////////////////// +// +// AddPlasmaClasses - the python module definitions +// +void pyImageLibMod::AddPlasmaClasses(PyObject* m) +{ + PYTHON_CLASS_IMPORT_START(m); + PYTHON_CLASS_IMPORT(m, ptImageLibMod); + PYTHON_CLASS_IMPORT_END(m); +} diff --git a/Sources/Plasma/FeatureLib/pfPython/pyLayer.cpp b/Sources/Plasma/FeatureLib/pfPython/pyLayer.cpp new file mode 100644 index 0000000000..9ecc390758 --- /dev/null +++ b/Sources/Plasma/FeatureLib/pfPython/pyLayer.cpp @@ -0,0 +1,96 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 3 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, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#include +#include "pyKey.h" +#include "hsResMgr.h" + +#include "pyLayer.h" +#include "pyImage.h" + +#include "plMessage/plLayRefMsg.h" +#include "plResMgr/plKeyFinder.h" + +void pyLayer::setKey(pyKey& layerKey) // only for python glue, do NOT call +{ + if (fLayer && fLayerKey) + fLayerKey->UnRefObject(); + + fLayer = nullptr; + fLayerKey = layerKey.getKey(); +} + +plLayer* pyLayer::GetLayer() const +{ + if (fLayer) + return fLayer; + return plLayer::ConvertNoRef(fLayerKey->ObjectIsLoaded()); +} + +void pyLayer::SetTexture(plBitmap* image) +{ + plLayer* layer = GetLayer(); + + if (image) { + plLayRefMsg* refMsg = new plLayRefMsg(fLayerKey, plRefMsg::kOnReplace, 0, plLayRefMsg::kTexture); + hsgResMgr::ResMgr()->AddViaNotify(image->GetKey(), refMsg, plRefFlags::kActiveRef); + } +} + +PyObject* pyLayer::GetTexture() const +{ + plLayer* layer = GetLayer(); + + plMipmap* mm = plMipmap::ConvertNoRef(layer->GetTexture()); + if (mm) + return pyImage::New(mm); + + PYTHON_RETURN_NONE; +} + +PyObject* pyLayer::Find(const ST::string& name, const ST::string& age, const ST::string& page) +{ + plKey foundKey = plKeyFinder::Instance().StupidSearch(age, page, plLayer::Index(), name); + if (foundKey) + return pyLayer::New(std::move(foundKey)); + PYTHON_RETURN_NONE; +} diff --git a/Sources/Plasma/FeatureLib/pfPython/pyLayer.h b/Sources/Plasma/FeatureLib/pfPython/pyLayer.h new file mode 100644 index 0000000000..3768ba387c --- /dev/null +++ b/Sources/Plasma/FeatureLib/pfPython/pyLayer.h @@ -0,0 +1,128 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 3 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, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#ifndef pyLayer_h +#define pyLayer_h + +///////////////////////////////////////////////////////////////////////////// +// +// NAME: pyLayer +// +// PURPOSE: Class wrapper for Python to a plLayer +// + +#include + +#include "pyGlueHelpers.h" +#include "pnKeyedObject/plKey.h" + +#include "plSurface/plLayer.h" + +class plBitmap; + +class pyLayer +{ +protected: + plKey fLayerKey; + plLayer* fLayer; + + // For python glue only, do NOT call + pyLayer() + : fLayerKey(), fLayer() + { } + + // Constructor from C++ + pyLayer(plKey layerkey) + : fLayerKey(std::move(layerkey)), fLayer() + { } + + // Constructor from C++ ... uses pointer instead of plKey + pyLayer(plLayer* layer) + : fLayerKey(layer->GetKey()), fLayer(layer) + { + if (fLayerKey) + fLayerKey->RefObject(); + } + +public: + ~pyLayer() + { + if (fLayer && fLayerKey) + fLayerKey->UnRefObject(); + } + + // required functions for PyObject interoperability + PYTHON_CLASS_NEW_FRIEND(ptLayer); + static PyObject* New(plLayer* layer); + static PyObject* New(plKey layerKey); + static PyObject* New(pyKey& layerKey); + PYTHON_CLASS_CHECK_DEFINITION; // returns true if the PyObject is a pyLayer object + PYTHON_CLASS_CONVERT_FROM_DEFINITION(pyLayer); // converts a PyObject to a pyLayer (throws error if not correct type) + + static void AddPlasmaClasses(PyObject* m); + static void AddPlasmaMethods(PyObject* m); + + void setKey(pyKey& layerKey); + + // override the equals to operator + bool operator==(const pyLayer& layer) const + { + // only thing that needs testing is the plKey, which is unique for all + if (fLayerKey == ((pyLayer&)layer).GetKey()) + return true; + else + return false; + } + bool operator!=(const pyLayer& layer) const { return !(layer == *this); } + + // For C++ access + plKey GetKey() const { return fLayer ? fLayer->GetKey() : fLayerKey; } + plLayer* GetLayer() const; + + // For Python access + void SetTexture(plBitmap* image); + PyObject* GetTexture() const; + + static PyObject* Find(const ST::string& name, const ST::string& age, const ST::string& page); +}; + +#endif // pyLayer_h diff --git a/Sources/Plasma/FeatureLib/pfPython/pyLayerGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/pyLayerGlue.cpp new file mode 100644 index 0000000000..dccdcffd31 --- /dev/null +++ b/Sources/Plasma/FeatureLib/pfPython/pyLayerGlue.cpp @@ -0,0 +1,170 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 3 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, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#include +#include "pyKey.h" + +#include "pyLayer.h" +#include "pyImage.h" + +// glue functions +PYTHON_CLASS_DEFINITION(ptLayer, pyLayer); + +PYTHON_DEFAULT_NEW_DEFINITION(ptLayer, pyLayer) +PYTHON_DEFAULT_DEALLOC_DEFINITION(ptLayer) + +PYTHON_INIT_DEFINITION(ptLayer, args, keywords) +{ + PyObject* keyObj = nullptr; + if (!PyArg_ParseTuple(args, "O", &keyObj)) + { + PyErr_SetString(PyExc_TypeError, "__init__ expects a ptKey"); + PYTHON_RETURN_INIT_ERROR; + } + if (!pyKey::Check(keyObj)) + { + PyErr_SetString(PyExc_TypeError, "__init__ expects a ptKey"); + PYTHON_RETURN_INIT_ERROR; + } + pyKey* key = pyKey::ConvertFrom(keyObj); + self->fThis->setKey(*key); + PYTHON_RETURN_INIT_OK; +} + +PYTHON_METHOD_DEFINITION_NOARGS(ptLayer, getTexture) +{ + return self->fThis->GetTexture(); +} + +PYTHON_METHOD_DEFINITION(ptLayer, setTexture, args) +{ + PyObject* imageObj; + if (!PyArg_ParseTuple(args, "O", &imageObj)) { + PyErr_SetString(PyExc_TypeError, "setTexture expects a ptImage"); + PYTHON_RETURN_ERROR; + } + if (!pyImage::Check(imageObj)) { + PyErr_SetString(PyExc_TypeError, "setTexture expects a ptImage"); + PYTHON_RETURN_ERROR; + } + + self->fThis->SetTexture(pyImage::ConvertFrom(imageObj)->GetImage()); + PYTHON_RETURN_NONE; +} + +PYTHON_START_METHODS_TABLE(ptLayer) + PYTHON_METHOD_NOARGS(ptLayer, getTexture, "Returns the image texture of the layer"), + PYTHON_METHOD(ptLayer, setTexture, "Params: image\nSets the ptImage texture of the layer"), +PYTHON_END_METHODS_TABLE; + +// Type structure definition +#define ptLayer_AS_NUMBER PYTHON_NO_AS_NUMBER +#define ptLayer_AS_SEQUENCE PYTHON_NO_AS_SEQUENCE +#define ptLayer_AS_MAPPING PYTHON_NO_AS_MAPPING +#define ptLayer_STR PYTHON_NO_STR +#define ptLayer_GETATTRO PYTHON_NO_GETATTRO +#define ptLayer_SETATTRO PYTHON_NO_SETATTRO +#define ptLayer_RICH_COMPARE PYTHON_NO_RICH_COMPARE +#define ptLayer_GETSET PYTHON_NO_GETSET +#define ptLayer_BASE PYTHON_NO_BASE +PLASMA_CUSTOM_TYPE(ptLayer, "Params: layerKey\nPlasma layer class"); + +// required functions for PyObject interoperability +PyObject* pyLayer::New(plLayer* layer) +{ + ptLayer* newObj = (ptLayer*)ptLayer_type.tp_new(&ptLayer_type, nullptr, nullptr); + newObj->fThis->fLayer = layer; + newObj->fThis->fLayerKey = layer->GetKey(); + if (layer->GetKey()) + newObj->fThis->fLayerKey->RefObject(); + return (PyObject*)newObj; +} + +PyObject* pyLayer::New(plKey layerKey) +{ + ptLayer* newObj = (ptLayer*)ptLayer_type.tp_new(&ptLayer_type, nullptr, nullptr); + newObj->fThis->fLayerKey = std::move(layerKey); + return (PyObject*)newObj; +} + +PyObject* pyLayer::New(pyKey& layerKey) +{ + ptLayer* newObj = (ptLayer*)ptLayer_type.tp_new(&ptLayer_type, nullptr, nullptr); + newObj->fThis->fLayerKey = layerKey.getKey(); + return (PyObject*)newObj; +} + +PYTHON_CLASS_CHECK_IMPL(ptLayer, pyLayer) +PYTHON_CLASS_CONVERT_FROM_IMPL(ptLayer, pyLayer) + +/////////////////////////////////////////////////////////////////////////// +// +// AddPlasmaClasses - the python module definitions +// +void pyLayer::AddPlasmaClasses(PyObject* m) +{ + PYTHON_CLASS_IMPORT_START(m); + PYTHON_CLASS_IMPORT(m, ptLayer); + PYTHON_CLASS_IMPORT_END(m); +} + +PYTHON_GLOBAL_METHOD_DEFINITION_WKEY(PtFindLayer, args, kwds, "Params: name\nFind a layer by name.") +{ + const char* kwdlist[]{"name", "age", "page", nullptr}; + ST::string name, age, page; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&", const_cast(kwdlist), + PyUnicode_STStringConverter, &name, + PyUnicode_STStringConverter, &age, + PyUnicode_STStringConverter, &page)) { + PyErr_SetString(PyExc_TypeError, "PtFindLayer expects a string and two optional strings"); + PYTHON_RETURN_ERROR; + } + + return pyLayer::Find(name, age, page); +} + +void pyLayer::AddPlasmaMethods(PyObject* m) +{ + PYTHON_START_GLOBAL_METHOD_TABLE(ptLayer) + PYTHON_GLOBAL_METHOD_WKEY(PtFindLayer) + PYTHON_END_GLOBAL_METHOD_TABLE(m, ptLayer) +} diff --git a/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp b/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp index f09b4d5ef6..a04bc39325 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp @@ -59,6 +59,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plModifier/plResponderModifier.h" #include "pfCamera/plCameraModifier.h" +#include "pyImageLibMod.h" +#include "pySceneObject.h" #include "cyAvatar.h" #include "cyDraw.h" @@ -68,6 +70,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pyGeometry3.h" #include "pyGlueHelpers.h" #include "pyMatrix44.h" +#include "plModifier/plResponderModifier.h" +#include "plModifier/plImageLibMod.h" void pySceneObject::IAddObjKeyToAll(const plKey& key) { @@ -815,15 +819,34 @@ std::vector pySceneObject::GetPythonMods() { for (size_t i = 0; i < obj->GetNumModifiers(); i++) { - const plPythonFileMod* resp = plPythonFileMod::ConvertNoRef(obj->GetModifier(i)); - if (resp) - pyPL.push_back(pyKey::New(resp->GetKey())); + const plPythonFileMod* pfm = plPythonFileMod::ConvertNoRef(obj->GetModifier(i)); + if (pfm) + pyPL.push_back(pyKey::New(pfm->GetKey())); } } } return pyPL; } +std::vector pySceneObject::GetImageLibMods() +{ + std::vector pyPL; + if (!fSceneObjects.empty()) + { + // get the object pointer of just the first one in the list + // (We really can't tell which one the user is thinking of if they are + // referring to multiple objects, so the first one in the list will do.) + plSceneObject* obj = plSceneObject::ConvertNoRef(fSceneObjects[0]->ObjectIsLoaded()); + if (obj) + { + const plImageLibMod* ilm = plImageLibMod::ConvertNoRef(obj->GetModifierByType(plImageLibMod::Index())); + if (ilm) + pyPL.push_back(pyImageLibMod::New(ilm->GetKey())); + } + } + return pyPL; +} + void pySceneObject::Animate() { plSceneObject* obj = plSceneObject::ConvertNoRef(fSceneObjects[0]->ObjectIsLoaded()); diff --git a/Sources/Plasma/FeatureLib/pfPython/pySceneObject.h b/Sources/Plasma/FeatureLib/pfPython/pySceneObject.h index 7a311994e6..fe29c16378 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pySceneObject.h +++ b/Sources/Plasma/FeatureLib/pfPython/pySceneObject.h @@ -116,6 +116,7 @@ class pySceneObject ST::string GetName(); std::vector GetResponders(); // pyKey list std::vector GetPythonMods(); // pyKey list + std::vector GetImageLibMods(); // pyKey list // // deteremine if this object (or the first object in the list) // ...is locally owned diff --git a/Sources/Plasma/FeatureLib/pfPython/pySceneObjectGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/pySceneObjectGlue.cpp index 83260e154c..fdaacdce0e 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pySceneObjectGlue.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/pySceneObjectGlue.cpp @@ -180,6 +180,15 @@ PYTHON_METHOD_DEFINITION_NOARGS(ptSceneobject, getPythonMods) return retVal; } +PYTHON_METHOD_DEFINITION_NOARGS(ptSceneobject, getImageLibMods) +{ + std::vector vecList = self->fThis->GetImageLibMods(); + PyObject* retVal = PyTuple_New(vecList.size()); + for (int curKey = 0; curKey < vecList.size(); curKey++) + PyTuple_SET_ITEM(retVal, curKey, vecList[curKey]); + return retVal; +} + PYTHON_METHOD_DEFINITION_NOARGS(ptSceneobject, isLocallyOwned) { PYTHON_RETURN_BOOL(self->fThis->IsLocallyOwned()); @@ -483,6 +492,7 @@ PYTHON_START_METHODS_TABLE(ptSceneobject) "- If there are more than one sceneobject attached, return just the first one"), PYTHON_METHOD_NOARGS(ptSceneobject, getResponders, "Returns list of ptKeys of the responders attached to this sceneobject"), PYTHON_METHOD_NOARGS(ptSceneobject, getPythonMods, "Returns list of ptKeys of the python modifiers attached to this sceneobject"), + PYTHON_METHOD_NOARGS(ptSceneobject, getImageLibMods, "Returns list of ptKeys of the image library modifiers attached to this sceneobject"), PYTHON_METHOD_NOARGS(ptSceneobject, isLocallyOwned, "Returns true(1) if this object is locally owned by this client\n" "or returns false(0) if it is not or don't know"), diff --git a/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.cpp b/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.cpp index 955d70d760..f6abe84857 100644 --- a/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.cpp +++ b/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.cpp @@ -49,13 +49,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "hsStream.h" #include "hsResMgr.h" -plImageLibMod::plImageLibMod() -{ -} - -plImageLibMod::~plImageLibMod() -{ -} bool plImageLibMod::MsgReceive(plMessage* msg) { @@ -97,3 +90,23 @@ void plImageLibMod::Write(hsStream* stream, hsResMgr* mgr) for (plBitmap* image : fImages) mgr->WriteKey(stream, image->GetKey()); } + +plBitmap* plImageLibMod::GetImage(const ST::string& imageName) const +{ + auto findIt = std::find_if(fImages.begin(), fImages.end(), [&imageName](plBitmap* x) { return x->GetKeyName() == imageName; }); + if (findIt != fImages.end()) + return *findIt; + return nullptr; +} + +std::vector plImageLibMod::GetImageNames() const +{ + std::vector names; + names.reserve(fImages.size()); + + for (const auto& image : fImages) { + if (image) + names.emplace_back(image->GetKeyName()); + } + return names; +} diff --git a/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.h b/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.h index 50e9418f02..305c6a6b0b 100644 --- a/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.h +++ b/Sources/Plasma/PubUtilLib/plModifier/plImageLibMod.h @@ -58,8 +58,7 @@ class plImageLibMod : public plSingleModifier bool IEval(double secs, float del, uint32_t dirty) override { return false; } public: - plImageLibMod(); - virtual ~plImageLibMod(); + plImageLibMod() {}; CLASSNAME_REGISTER( plImageLibMod ); GETINTERFACE_ANY( plImageLibMod, plSingleModifier ); @@ -75,6 +74,9 @@ class plImageLibMod : public plSingleModifier }; size_t GetNumImages() const { return fImages.size(); } + plBitmap* GetImage(const ST::string&) const; + std::vector GetImages() const { return fImages; } + std::vector GetImageNames() const; }; #endif // plImageLibMod_inc