mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-28 17:56:37 +00:00 
			
		
		
		
	Merged pull request #1572
This commit is contained in:
		
						commit
						f62df90960
					
				
					 9 changed files with 108 additions and 64 deletions
				
			
		
							
								
								
									
										42
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| # use the official gcc image, based on debian | ||||
| # can use verions as well, like gcc:5.2 | ||||
| # see https://hub.docker.com/_/gcc/ | ||||
| image: gcc | ||||
| 
 | ||||
| cache: | ||||
|   key: apt-cache | ||||
|   paths: | ||||
|   - apt-cache/ | ||||
| 
 | ||||
| before_script: | ||||
|   - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR | ||||
|   - apt-get update -yq  | ||||
|   - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt4-dev libopenal-dev libopenscenegraph-3.4-dev libunshield-dev libtinyxml-dev | ||||
| # - apt-get install -y libmygui-dev libbullet-dev  # to be updated to latest below because stretch is too old | ||||
|   - curl http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet-dev_2.87+dfsg-2_amd64.deb -o libbullet-dev_2.87+dfsg-2_amd64.deb | ||||
|   - curl http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet2.87_2.87+dfsg-2_amd64.deb -o libbullet2.87_2.87+dfsg-2_amd64.deb | ||||
|   - curl http://ftp.us.debian.org/debian/pool/main/m/mygui/libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb -o libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb | ||||
|   - curl http://ftp.us.debian.org/debian/pool/main/m/mygui/libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb -o libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb | ||||
|   - curl http://ftp.us.debian.org/debian/pool/main/m/mygui/libmygui-dev_3.2.2+dfsg-1_amd64.deb -o libmygui-dev_3.2.2+dfsg-1_amd64.deb | ||||
|   - dpkg --ignore-depends=libmygui.ogreplatform0debian1v5 -i *.deb  | ||||
| 
 | ||||
| build: | ||||
|   stage: build | ||||
|   script:  | ||||
|     - nproc | ||||
|     - mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../ | ||||
|     - make -j2 | ||||
|     - DESTDIR=artifacts make install | ||||
|   artifacts: | ||||
|     paths: | ||||
|       - build/artifacts/ | ||||
|   # depending on your build setup it's most likely a good idea to cache outputs to reduce the build time | ||||
|   cache: | ||||
|     paths: | ||||
|       - "*.o" | ||||
| 
 | ||||
| # run tests using the binary built before | ||||
| test: | ||||
|   stage: test | ||||
|   script: | ||||
|     - ls | ||||
|  | @ -24,6 +24,7 @@ | |||
|     Bug #4429: [Windows] Error on build INSTALL.vcxproj project (debug) with cmake 3.7.2 | ||||
|     Bug #4432: Guards behaviour is incorrect if they do not have AI packages | ||||
|     Bug #4433: Guard behaviour is incorrect with Alarm = 0 | ||||
|     Bug #4454: AI opens doors too slow | ||||
|     Feature #3276: Editor: Search- Show number of (remaining) search results and indicate a search without any results | ||||
|     Feature #4324: Add CFBundleIdentifier in Info.plist to allow for macOS function key shortcuts | ||||
|     Feature #4345: Add equivalents for the command line commands to Launcher | ||||
|  |  | |||
|  | @ -139,24 +139,21 @@ namespace MWClass | |||
|         const std::string trapActivationSound = "Disarm Trap Fail"; | ||||
| 
 | ||||
|         MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); | ||||
|         const MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player); | ||||
|         MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player); | ||||
| 
 | ||||
|         bool isLocked = ptr.getCellRef().getLockLevel() > 0; | ||||
|         bool isTrapped = !ptr.getCellRef().getTrap().empty(); | ||||
|         bool hasKey = false; | ||||
|         std::string keyName; | ||||
| 
 | ||||
|         // make key id lowercase
 | ||||
|         std::string keyId = ptr.getCellRef().getKey(); | ||||
|         Misc::StringUtils::lowerCaseInPlace(keyId); | ||||
|         for (MWWorld::ConstContainerStoreIterator it = invStore.cbegin(); it != invStore.cend(); ++it) | ||||
|         const std::string keyId = ptr.getCellRef().getKey(); | ||||
|         if (!keyId.empty()) | ||||
|         { | ||||
|             std::string refId = it->getCellRef().getRefId(); | ||||
|             Misc::StringUtils::lowerCaseInPlace(refId); | ||||
|             if (refId == keyId) | ||||
|             MWWorld::Ptr keyPtr = invStore.search(keyId); | ||||
|             if (!keyPtr.isEmpty()) | ||||
|             { | ||||
|                 hasKey = true; | ||||
|                 keyName = it->getClass().getName(*it); | ||||
|                 keyName = keyPtr.getClass().getName(keyPtr); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -114,7 +114,7 @@ namespace MWClass | |||
|         const std::string lockedSound = "LockedDoor"; | ||||
|         const std::string trapActivationSound = "Disarm Trap Fail"; | ||||
| 
 | ||||
|         const MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); | ||||
|         MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); | ||||
| 
 | ||||
|         bool isLocked = ptr.getCellRef().getLockLevel() > 0; | ||||
|         bool isTrapped = !ptr.getCellRef().getTrap().empty(); | ||||
|  | @ -135,21 +135,14 @@ namespace MWClass | |||
|             animation->addSpellCastGlow(effect, 1); // 1 second glow to match the time taken for a door opening or closing
 | ||||
|         } | ||||
| 
 | ||||
|         // make key id lowercase
 | ||||
|         std::string keyId = ptr.getCellRef().getKey(); | ||||
|         const std::string keyId = ptr.getCellRef().getKey(); | ||||
|         if (!keyId.empty()) | ||||
|         { | ||||
|             Misc::StringUtils::lowerCaseInPlace(keyId); | ||||
|             for (MWWorld::ConstContainerStoreIterator it = invStore.cbegin(); it != invStore.cend(); ++it) | ||||
|             MWWorld::Ptr keyPtr = invStore.search(keyId); | ||||
|             if (!keyPtr.isEmpty()) | ||||
|             { | ||||
|                 std::string refId = it->getCellRef().getRefId(); | ||||
|                 Misc::StringUtils::lowerCaseInPlace(refId); | ||||
|                 if (refId == keyId) | ||||
|                 { | ||||
|                     hasKey = true; | ||||
|                     keyName = it->getClass().getName(*it); | ||||
|                     break; | ||||
|                 } | ||||
|                 hasKey = true; | ||||
|                 keyName = keyPtr.getClass().getName(keyPtr); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -120,6 +120,9 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const ESM::Pathgr | |||
| 
 | ||||
|     if (!isDestReached && mTimer > AI_REACTION_TIME) | ||||
|     { | ||||
|         if (actor.getClass().isBipedal(actor)) | ||||
|             openDoors(actor); | ||||
| 
 | ||||
|         bool wasShortcutting = mIsShortcutting; | ||||
|         bool destInLOS = false; | ||||
| 
 | ||||
|  | @ -209,41 +212,10 @@ void MWMechanics::AiPackage::evadeObstacles(const MWWorld::Ptr& actor, float dur | |||
|     // first check if obstacle is a door
 | ||||
|     static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); | ||||
| 
 | ||||
|     MWWorld::Ptr door = getNearbyDoor(actor, distance); | ||||
|     if (door != MWWorld::Ptr() && actor.getClass().isBipedal(actor)) | ||||
|     const MWWorld::Ptr door = getNearbyDoor(actor, distance); | ||||
|     if (!door.isEmpty() && actor.getClass().isBipedal(actor)) | ||||
|     { | ||||
|         // note: AiWander currently does not open doors
 | ||||
|         if (getTypeId() != TypeIdWander && !door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == 0) | ||||
|         { | ||||
|             if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0 )) | ||||
|             { | ||||
|                 MWBase::Environment::get().getWorld()->activate(door, actor); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             std::string keyId = door.getCellRef().getKey(); | ||||
|             if (keyId.empty()) | ||||
|                 return; | ||||
| 
 | ||||
|             bool hasKey = false; | ||||
|             const MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); | ||||
| 
 | ||||
|             // make key id lowercase
 | ||||
|             Misc::StringUtils::lowerCaseInPlace(keyId); | ||||
|             for (MWWorld::ConstContainerStoreIterator it = invStore.cbegin(); it != invStore.cend(); ++it) | ||||
|             { | ||||
|                 std::string refId = it->getCellRef().getRefId(); | ||||
|                 Misc::StringUtils::lowerCaseInPlace(refId); | ||||
|                 if (refId == keyId) | ||||
|                 { | ||||
|                     hasKey = true; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (hasKey) | ||||
|                 MWBase::Environment::get().getWorld()->activate(door, actor); | ||||
|         } | ||||
|         openDoors(actor); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|  | @ -251,6 +223,35 @@ void MWMechanics::AiPackage::evadeObstacles(const MWWorld::Ptr& actor, float dur | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) | ||||
| { | ||||
|     static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); | ||||
| 
 | ||||
|     const MWWorld::Ptr door = getNearbyDoor(actor, distance); | ||||
|     if (door == MWWorld::Ptr()) | ||||
|         return; | ||||
| 
 | ||||
|     // note: AiWander currently does not open doors
 | ||||
|     if (getTypeId() != TypeIdWander && !door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == 0) | ||||
|     { | ||||
|         if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0 )) | ||||
|         { | ||||
|             MWBase::Environment::get().getWorld()->activate(door, actor); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const std::string keyId = door.getCellRef().getKey(); | ||||
|         if (keyId.empty()) | ||||
|             return; | ||||
| 
 | ||||
|         MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); | ||||
|         MWWorld::Ptr keyPtr = invStore.search(keyId); | ||||
| 
 | ||||
|         if (!keyPtr.isEmpty()) | ||||
|             MWBase::Environment::get().getWorld()->activate(door, actor); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const MWMechanics::PathgridGraph& MWMechanics::AiPackage::getPathGridGraph(const MWWorld::CellStore *cell) | ||||
| { | ||||
|     const ESM::CellId& id = cell->getCell()->getCellId(); | ||||
|  |  | |||
|  | @ -123,6 +123,7 @@ namespace MWMechanics | |||
|             virtual bool doesPathNeedRecalc(const ESM::Pathgrid::Point& newDest, const MWWorld::CellStore* currentCell); | ||||
| 
 | ||||
|             void evadeObstacles(const MWWorld::Ptr& actor, float duration, const ESM::Position& pos); | ||||
|             void openDoors(const MWWorld::Ptr& actor); | ||||
| 
 | ||||
|             const PathgridGraph& getPathGridGraph(const MWWorld::CellStore* cell); | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,13 +26,13 @@ namespace MWMechanics | |||
| 
 | ||||
|     bool proximityToDoor(const MWWorld::Ptr& actor, float minDist) | ||||
|     { | ||||
|         if(getNearbyDoor(actor, minDist)!=MWWorld::Ptr()) | ||||
|             return true; | ||||
|         else | ||||
|         if(getNearbyDoor(actor, minDist).isEmpty()) | ||||
|             return false; | ||||
|         else | ||||
|             return true; | ||||
|     } | ||||
| 
 | ||||
|     MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist) | ||||
|     const MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist) | ||||
|     { | ||||
|         MWWorld::CellStore *cell = actor.getCell(); | ||||
| 
 | ||||
|  | @ -50,6 +50,16 @@ namespace MWMechanics | |||
|             const MWWorld::LiveCellRef<ESM::Door>& ref = *it; | ||||
| 
 | ||||
|             osg::Vec3f doorPos(ref.mData.getPosition().asVec3()); | ||||
| 
 | ||||
|             // FIXME: cast
 | ||||
|             const MWWorld::Ptr doorPtr = MWWorld::Ptr(&const_cast<MWWorld::LiveCellRef<ESM::Door> &>(ref), actor.getCell()); | ||||
| 
 | ||||
|             int doorState = doorPtr.getClass().getDoorState(doorPtr); | ||||
|             float doorRot = ref.mData.getPosition().rot[2] - doorPtr.getCellRef().getPosition().rot[2]; | ||||
| 
 | ||||
|             if (doorState != 0 || doorRot != 0) | ||||
|                 continue; // the door is already opened/opening
 | ||||
| 
 | ||||
|             doorPos.z() = 0; | ||||
| 
 | ||||
|             float angle = std::acos(actorDir * (doorPos - pos) / (actorDir.length() * (doorPos - pos).length())); | ||||
|  | @ -62,8 +72,7 @@ namespace MWMechanics | |||
|             if ((pos - doorPos).length2() > minDist*minDist) | ||||
|                 continue; | ||||
| 
 | ||||
|             // FIXME cast
 | ||||
|             return MWWorld::Ptr(&const_cast<MWWorld::LiveCellRef<ESM::Door> &>(ref), actor.getCell()); // found, stop searching
 | ||||
|             return doorPtr; // found, stop searching
 | ||||
|         } | ||||
| 
 | ||||
|         return MWWorld::Ptr(); // none found
 | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ namespace MWMechanics | |||
| 
 | ||||
|     /// Returns door pointer within range. No guarantee is given as to which one
 | ||||
|     /** \return Pointer to the door, or NULL if none exists **/ | ||||
|     MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist); | ||||
|     const MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist); | ||||
| 
 | ||||
|     class ObstacleCheck | ||||
|     { | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ namespace | |||
|         for (typename MWWorld::CellRefList<T>::List::iterator iter (list.mList.begin()); | ||||
|              iter!=list.mList.end(); ++iter) | ||||
|         { | ||||
|             if (Misc::StringUtils::ciEqual(iter->mBase->mId, id2)) | ||||
|             if (Misc::StringUtils::ciEqual(iter->mBase->mId, id2) && iter->mData.getCount()) | ||||
|             { | ||||
|                 MWWorld::Ptr ptr (&*iter, 0); | ||||
|                 ptr.setContainerStore (store); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue