Added code for locked doors, picking locks etc...
I dont know how to submit for CVS, so ill put it here (hope thats ok)
changes are to CVS code current as of june 11, 10pm CST (/zone/doors.h) new code at line 33 //used_pawn int16 GetKeyItem() {return keyitem;} int16 GetLockpick() {return lockpick;} // (/zone/client_process.cpp) new code at line 4904 //used_pawn: Locked doors! Rogue friendly too =) //TODO: add check for other lockpick items if((currentdoor->GetKeyItem()==0) || (currentdoor->GetKeyItem()==this->GetItemAt(0))) { if(!currentdoor->IsDoorOpen()) { currentdoor->HandleClick(this); md->action = 0x02; } else { currentdoor->HandleClick(this); md->action = 0x03; } } else { if((this->GetItemAt(0)==13010)&&(this->GetSkill(35)>0)) { if(rand()%100<2)this->SetSkill(35,this->GetSkill(35)+1); if(rand()%currentdoor->GetLockpick()<=this->GetSkill(35)) { if(!currentdoor->IsDoorOpen()) { currentdoor->HandleClick(this); md->action = 0x02; } else { currentdoor->HandleClick(this); md->action = 0x03; } Message(4,"You picked the lock!"); } else { Message(4,"Your skill is not high enough for this door."); } } else { Message(4,"It's locked and you don't have the key!"); } } //end used_pawn (/zone/client_process.cpp) old code to be replaced at line 4904 if(!currentdoor->IsDoorOpen()) { currentdoor->HandleClick(this); md->action = 0x02; } else { currentdoor->HandleClick(this); md->action = 0x03; } sorry, my tabs didnt copy/paste =( it works very well,has chance of success if skill to low on pick locks, has messages (close as i remember to eqlive) and skill increases for pick locks (chance for increase is 1% per attempt, may need adjusted) not sure if i need to check if client is a rogue/bard (it ignores picking locks if skill = 0 ) i dont know if i need to check for maxskill on pick locks or not (i assumed the setskill() handles this, please let me know if i assumed wrong) Also, i dont remember what all items can be used for picking locks so only the basic lockpicks are valid EDIT: edited to reflect errors i had made in the post |
Post diffs if you can..
line33 in zone.h is around the zonepoint struct, im assuming you want these functions to be in the public section of the zone class... And in client process, i cant tell if you replaced exisitng funcitons, or completely new.. Please post the changed .cpp files, or diffs, or EXACT instructions. I'll merge in what I see in COMMENTS. Also, whats int16 GetKeyItem() {return keyitem;} int16 GetLockpick() {return lockpick;} You dont define keyitem or lockpick anywhere, so until those are defined, those are unknown variables.... |
Quote:
...keyitem and lockpick are variables in the doors header file. (I think he ment doors.h instead of zone.h --- but maybe I am wrong) ********************************************* EDIT ********************************************* Please note give all credit to used_pawn for the initial code - I'm just bored right now and thought I'd add some to the code provided. The following code takes his code where it checks for if the client is holding the key for the door/object on the cursor and checks if the skill of the client is greater than zero ... also the end of his code (your sniplet used_pawn ) opens the door anyways ... which should be enclosed inside a pair of {}'s where it checks for a successful lock pick or if the client actually has the key ... but here is the code ... else if( this->GetClass() == 8 || this->GetClass() == 9 ) //: Check if the class is a bard or a rogue { int16 Cursor_Item = this->GetItemAt(0); int16 Gloves_Item = this->GetItemAt(12); // Glove/hand slot bool Has_LockPicks = false; float Skill_Mod = 0.0f; float Final_PickSkill = 0.0f; if(Cursor_Item == 13010) // Normal Lockpicks - no skill mod Has_LockPicks = true; else if(Cursor_Item == 16865 ) // Mechanical(spelt Mechanized in the db) lockpicks ...3% skill mod { Skill_Mod = 0.03f; Has_LockPicks = true; } if( Gloves_Item == 19702 ) // Gloves of the brood - 3% skill mod Skill_Mod = 0.03f; if( Has_LockPicks == true ) { Final_PickSkill = Skill_Mod * (GetSkill(35)); if( Final_PickSkill > currentdoor->LockPick() ) { this->Message(4, "You have successfully picked the pick!"); if(!currentdoor->IsDoorOpen()) { currentdoor->HandleClick(this); md->action = 0x02; } else { currentdoor->HandleClick(this); md->action = 0x03; } int8 action = md->action; entity_list.QueueClients(this,outapp,false); delete outapp; if(currentdoor->GetTriggerDoorID() != 0) { Doors* triggerdoor = entity_list.FindDoor(currentdoor->GetTriggerDoorID()); if(triggerdoor) { if(!triggerdoor->IsDoorOpen()) { triggerdoor->HandleClick(this); action = 0x02; } else { triggerdoor->HandleClick(this); action = 0x03; } outapp = new APPLAYER(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; md->doorid = triggerdoor->GetDoorID(); md->action = action; entity_list.QueueClients(this,outapp,false); delete outapp; } } } // Chance to increase the skill if it is not maxxed if( this->GetSkill(35) < this->MaxSkill(35) ) { sint16 Chance = 1; // 1% chance to increase the skill (not sure if this is right..) if (rand()%100 == Chance) SetSkill(skillid,GetSkill(35)+1); } } } |
hehe, ah what things i do when im up too late at night...
yes, i meant doors.h, dont know what my eyes were doin also, the section new code is to replace the section old code in client_process (not merge in ahead of it as it is in the CVS) sorry i really have no idea how to do a diff file. good stuff zern...i didnt handle everything, seems you caught the rest, far as i can tell all in all, I just wanted locked doors, hehe adding fixes and zerns suggestions to code, will submit in a bit thanks for all feedback! |
Well just use the CODE tags, file, line number, 1-3 lines before your changes and 1-3 after for ever change and we can easily go through and find what you mean.
|
OK.. got my groove on now..here is the 'final' version
complete with lockpick items suggested by zern and their skill mods again, sorry about my original post, guess i shouldn't do that when im up past my bed time, hehe (/zone/doors.h) new code at line 33 //used_pawn int16 GetKeyItem() {return keyitem;} int16 GetLockpick() {return lockpick;} // (/zone/client_process.cpp) line 4904 REPLACE this section: if(!currentdoor->IsDoorOpen()) { currentdoor->HandleClick(this); md->action = 0x02; } else { currentdoor->HandleClick(this); md->action = 0x03; } with this: //used_pawn: Locked doors! Rogue friendly too =) if((currentdoor->GetKeyItem()==0) || (currentdoor->GetKeyItem()==this->GetItemAt(0))) { //door not locked, or door is locked & client is using key if(!currentdoor->IsDoorOpen()) { currentdoor->HandleClick(this); md->action = 0x02; } else { currentdoor->HandleClick(this); md->action = 0x03; } } else { //door is locked, client is NOT using key if(this->GetSkill(35)>0) //no need to check for class, only bard/rogue will (should) have picklocks skill > 0, allows GM's to picklocks also { bool has_lockpicks=false; float modskill=0.0f; if(this->GetItemAt(0)==13010) //lockpicks { modskill=this->GetSkill(35); //no skill mod has_lockpicks=true; } if ((this->GetItemAt(0)==16865)||(this->GetItemAt(12)==19702)) //mechanized lockpicks and gloves of the brood { modskill=0.3f*this->GetSkill(35)+this->GetSkill(35); //3% skill mod has_lockpicks=true; } if(has_lockpicks) { if(rand()%100<2)this->SetSkill(35,this->GetSkill(35)+1); //1% chance skill increase if((float)(rand()%currentdoor->GetLockpick())<=modskill) { if(!currentdoor->IsDoorOpen()) { currentdoor->HandleClick(this); md->action = 0x02; } else { currentdoor->HandleClick(this); md->action = 0x03; } Message(4,"You picked the lock!"); } else { Message(4,"Your skill is not high enough for this door."); } } else { Message(4,"It's locked and you don't have the key!"); } } } //end used_pawn |
EDIT: double posted, oops, deleting
|
Quote:
Don't worry, we all do it :P - see I even forgot to take the skill of the PickLock_Mod, multiply it by the PickLock_SKill then add that result the original skill value to get the final value. lol :) oh well. Good job again. -David |
Looks good, I'll try to get this in for you guys tonight. Good work !
|
Ahh...never done
After some research on the web, talking to a couple EQlive'ers and some thought, I have some updates coming. a few items im working on: 1. no skill checks/messages while door is opening/closing =) 2. locked door triggers (ie. the paineel rock trigger for the elevator) 3. chances of opening/skill point increase closer to EQlive (i guess there is always a chance of failure) 4. researching if there was a trivial message for doors hopefully I will be done with these soon! |
Stupid question, but if you code the items based on values from the database. If those items were changed because they aren't using the default database, doesn't that brake the code?
Let me rephrase that, I see that it doesn't break it. But if they aren't where they should be how do we get them back if the item database is changed? New database flag? /hides |
Instead of checking for item numbers, the item type should include a value for lockpicks. For skill mods I know that information is in there too. That way it is based on the actual item stats like it should.
I think: skill skillModId skillModPercent Are the item properties you want |
Ok, merged the last set into CVS. Check it out and certify please.
|
Quote:
Ok, as for item skill, skillmod etc. instead of using item number, I must say you guys are correct, and I am working on that very thing in my update. |
That was from my original attempt to add it when you listed the wrong header. Its been removed in the dev-cvs.
|
update is finished, will post later today or tomorrow (have to go to work)
all equiped items and item on cursor checked for lockpick skill/ skill mod skill point increase use learning curve like eqlive no skill increase while charmed (unlikely, but hey...) only tries to unlock a closed door =) should work with triggered doors, teleport door objects etc... |
found an error in the item_struct table, some values were mis-aligned, so I fixed it
to avoid confusion this time, I just copied the whole function containing changes ************************************************** ******************************** ../common/eq_packet_structs.h : line 974 ************************************************** ******************************** struct Item_Struct { /*0000*/ char name[64]; // Name of item /*0064*/ char lore[80]; // Lore text /*0144*/ char idfile[6]; // This is the filename of the item graphic when held/worn. /*0150*/ sint16 flag; /*0152*/ uint8 unknown0150[22]; // Placeholder /*0174*/ uint8 weight; // Weight of item /*0175*/ sint8 nosave; // Nosave flag 1=normal, 0=nosave, -1=spell? /*0176*/ sint8 nodrop; // Nodrop flag 1=normal, 0=nodrop, -1=?? /*0177*/ uint8 size; // Size of item /*0178*/ int8 type; /*0179*/ uint8 unknown0178; // ***Placeholder /*0180*/ uint16 item_nr; // Unique Item number /*0182*/ uint16 icon_nr; // Icon Number /*0184*/ sint16 equipSlot; // Current Equip slot /*0186*/ uint8 unknwn0186[2]; // Equip slot cont.? /*0188*/ uint32 equipableSlots; // Slots where this item goes /*0192*/ sint32 cost; // Item cost in copper /*0196*/ uint8 unknown0196[32]; // ***Placeholder union { struct { // 0228- have different meanings depending on flags /*0228*/ sint8 STR; // Strength /*0229*/ sint8 STA; // Stamina /*0230*/ sint8 CHA; // Charisma /*0231*/ sint8 DEX; // Dexterity /*0232*/ sint8 INT; // Intelligence /*0233*/ sint8 AGI; // Agility /*0234*/ sint8 WIS; // Wisdom /*0235*/ sint8 MR; // Magic Resistance /*0236*/ sint8 FR; // Fire Resistance /*0237*/ sint8 CR; // Cold Resistance /*0238*/ sint8 DR; // Disease Resistance /*0239*/ sint8 PR; // Poison Resistance /*0240*/ sint16 HP; // Hitpoints /*0242*/ sint16 MANA; // Mana /*0244*/ sint16 AC; // Armor Class /*0246*/ uint8 MaxCharges; // Maximum number of charges, for rechargable? (Sept 25, 2002) /*0247*/ sint8 GMFlag; // GM flag 0 - normal item, -1 - gm item (Sept 25, 2002) /*0248*/ uint8 light; // Light effect of this item /*0249*/ uint8 delay; // Weapon Delay /*0250*/ uint8 damage; // Weapon Damage /*0251*/ sint8 effecttype0; // 0=combat, 1=click anywhere w/o class check, 2=latent/worn, 3=click anywhere EXPENDABLE, 4=click worn, 5=click anywhere w/ class check, -1=no effect /*0252*/ uint8 range; // Range of weapon /*0253*/ uint8 skill; // Skill of this weapon, refer to weaponskill chart /*0254*/ sint8 magic; // Magic flag // 00 (0000) = ??? // 01 (0001) = magic // 12 (1100) = ??? // 14 (1110) = ??? // 15 (1111) = ??? /*0255*/ sint8 level0; // Casting level /*0256*/ uint8 material; // Material? /*0257*/ uint8 unknown0257[3]; // ***Placeholder /*0260*/ uint32 color; // Amounts of RGB in original color /*0264*/ uint8 unknown0264[2]; // ***Placeholder (Asiel: Has to do with Diety, will unwrap later) /*0266*/ uint16 spellId0; // SpellID of special effect /*0268*/ uint16 classes; // Classes that can use this item /*0270*/ uint8 unknown0270[2]; // ***Placeholder union { struct { /*0272*/ uint16 races; // Races that can use this item /*0274*/ sint8 unknown0274[2]; // ***Placeholder /*0276*/ sint8 stackable; // 1= stackable, 3 = normal, 0 = ? (not stackable) } normal; }; /*0277*/ uint8 level; // Casting level union // 0278 has different meanings depending on an stackable { /*0278*/ sint8 number; // Number of items in stack /*0278*/ int8 charges; // Number of charges (-1 = unlimited) }; /*0279*/ sint8 effecttype; // 0=combat, 1=click anywhere w/o class check, 2=latent/worn, 3=click anywhere EXPENDABLE, 4=click worn, 5=click anywhere w/ class check, -1=no effect /*0280*/ uint16 spellId; // spellId of special effect /*0282*/ uint8 unknown0282[10]; // ***Placeholder 0288 /*0292*/ uint32 casttime; // Cast time of clicky item in miliseconds //used_pawn // /*0296*/uint8 unknown0296[16]; // ***Placeholder // skillModId and skillModPercent placement was off by +2 bytes /*0296*/ uint8 unknown0296[14]; // ***Placeholder /*0310*/ uint16 skillModId; /*0312*/ sint16 skillModPercent; /*0314*/ uint8 unknown0314[2]; //put here to align back up // /*0316*/ sint16 BaneDMGRace; /*0318*/ sint16 BaneDMGBody; // 1 Humanoid, 2 Lycanthrope, 3 Undead, 4 Giant, 5 Construct, 6 Extraplanar, 7 Magical /*0320*/ uint8 BaneDMG; /*0321*/ uint8 unknown0321[3]; /*0324*/ uint8 RecLevel; // max should be 65 /*0325*/ uint8 RecSkill; // Max should be 252 /*0326*/ uint8 unknown0326[2]; /*0328*/ uint8 ElemDmgType; // 1 Magic, 2 Fire, 3 Cold, 4 Poison, 5 Disease /*0329*/ uint8 ElemDmg; /*0330*/ uint8 unknown0330[22]; /*0352*/ uint8 ReqLevel; // Required level /*0353*/ uint8 unknown0353[5]; /*0358*/ int16 focusspellId; } common; ************************************************** ******************************** ../zone/doors.h : line 10 ************************************************** ******************************** class Doors : public Entity { public: Doors(const Door* door); ~Doors(); bool IsDoor() { return true; } void HandleClick(Client* sender); bool Process(); int8 GetDoorID() { return door_id; } int32 GetDoorDBID() { return db_id; } int32 GetGuildID() { return guildid; } int8 GetOpenType() { return opentype; } char* GetDoorName() { return door_name; } float GetX() { return pos_x; } float GetY() { return pos_y; } float GetZ() { return pos_z; } float GetHeading() { return heading; } bool IsDoorOpen() { return isopen; } int8 GetTriggerDoorID() { return trigger_door; } int8 GetTriggerType() { return trigger_type; } //used_pawn int16 GetKeyItem() {return keyitem;} int16 GetLockpick() {return lockpick;} // void SetGuildID(int32 guild_id) { guildid = guild_id; } int32 GetEntityID() { return entity_id; } void SetEntityID(int32 entity) { entity_id = entity; } void DumpDoor(); float GetDestX() { return dest_x; } float GetDestY() { return dest_y; } float GetDestZ() { return dest_z; } float GetDestHeading() { return dest_heading; } private: int32 db_id; int8 door_id; char zone_name[16]; char door_name[16]; float pos_x; float pos_y; float pos_z; float heading; int8 opentype; int32 guildid; int16 lockpick; int16 keyitem; int8 trigger_door; int8 trigger_type; int16 liftheight; int32 entity_id; bool isopen; Timer* close_timer; char dest_zone[16]; float dest_x; float dest_y; float dest_z; float dest_heading; }; ************************************************** ******************************** ../zone/client_process.cpp : line 4855 from function : Client::HandlePacket() ************************************************** ******************************** case OP_ClickDoor: { ClickDoor_Struct* cd = (ClickDoor_Struct*)app->pBuffer; Doors* currentdoor = entity_list.FindDoor(cd->doorid); if(!currentdoor) { Message(0,"Unable to find door, please notify a GM (DoorID: %i).",cd->doorid); break; } if (IsSettingGuildDoor) { if (database.SetGuildDoor(cd->doorid,SetGuildDoorID,zone->GetShortName())) { //cout << SetGuildDoorID << endl; if (SetGuildDoorID) { Message(4,"This is now a guilddoor of '%s'",guilds[SetGuildDoorID].name); currentdoor->SetGuildID(SetGuildDoorID); } else { Message(4,"Guildoor deleted"); currentdoor->SetGuildID(0); } } else Message(4,"Failed to edit guilddoor!"); IsSettingGuildDoor = false; break; } if (cd->doorid >= 128) { if(!database.CheckGuildDoor(cd->doorid,GuildEQID(),zone->GetShortName())) { // heh hope grammer on this is right lol this->Message(4,"A magic barrier protects this hall against intruders!"); break; } else this->Message(4,"The magic barrier disappears and you open the door!"); } APPLAYER* outapp = new APPLAYER(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; md->doorid = cd->doorid; if(currentdoor->GetTriggerType() == 255) // this object isnt triggered { delete outapp; break; } //used_pawn: Locked doors! Bard/Rogue friendly too =) bool openit=false; if(!currentdoor->IsDoorOpen()) //only locked if door is closed { //check if door locked & if client is using key if((currentdoor->GetKeyItem()==0)||(currentdoor->GetKeyItem()==this->GetItemAt(0))) openit=true; else { //door is locked, client is NOT using key int pl_skill=this->GetSkill(PICK_LOCK); bool has_lockpicks=false; int modskill=pl_skill; //no need to check for class, only bard/rogue will (should) have picklocks skill > 0, allows GM's to picklocks also if(pl_skill>0) //check if lockpicking is one of players skill { //it is, check for lockpick items const Item_Struct* pl_item = 0; int slot = 0; int temp = 0; for (slot=0;slot<22;slot++) //cursor slot & worn items slots { pl_item=0; pl_item=database.GetItem(this->GetItemAt(slot)); if(pl_item) { //two ways lockpicks are flagged in db if(pl_item->common.skill==12) has_lockpicks=true; //cout << pl_item->common.skillModId << ":" << pl_item->common.skillModPercent << endl; if(pl_item->common.skillModId==PICK_LOCK) { temp=(pl_item->common.skillModPercent*pl_skill+pl_skill*100)/100; if (temp>modskill) modskill=temp; //use item with highest skill mod has_lockpicks=true; } } } } if(has_lockpicks) { //lock is trivial at door_skill+1 int door_skill=currentdoor->GetLockpick(); if(door_skill<modskill) { if(rand()%100>1) //always small chance of fail { openit=true; Message(MT_Skills,"This lock is trivial for your skill."); Message(MT_Skills,"You have picked the lock!"); } else Message(MT_Skills,"You have failed to pick the lock!"); } else { //can only have up to 5*level+5 skill points in MOST abilities //can only gain up to level of door_skill+1 (up to trivial) if((this->GetLevel()*5+5)>pl_skill) { if(!IsAIControlled()) //not while charmed { //learning curve function, very close to EQlive if((rand()%(door_skill/2+1)+rand()%(door_skill/2+1))<modskill) this->SetSkill(PICK_LOCK,pl_skill+1); } } if(rand()%door_skill<modskill) { openit=true; Message(MT_Skills,"You have picked the lock!"); } else Message(MT_Skills,"You lack the skills necessary to pick this lock."); } } else Message(MT_Skills,"It's locked and you don't have the key!"); } if(openit) { //all rules handled...open the door! currentdoor->HandleClick(this); md->action = 0x02; } } else { //no key needed to shut a door... currentdoor->HandleClick(this); md->action = 0x03; } //END used_pawn int8 action = md->action; entity_list.QueueClients(this,outapp,false); delete outapp; if(currentdoor->GetTriggerDoorID() != 0) { Doors* triggerdoor = entity_list.FindDoor(currentdoor->GetTriggerDoorID()); if(triggerdoor) { if(!triggerdoor->IsDoorOpen()) { triggerdoor->HandleClick(this); //md->action = 0x02; } else { triggerdoor->HandleClick(this); //md->action = 0x03; } outapp = new APPLAYER(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer; md->doorid = triggerdoor->GetDoorID(); md->action = action; entity_list.QueueClients(this,outapp,false); delete outapp; } } break; } ************************************************** ***************************** enjoy! |
Since your working on doors, could you look into the lift height? While lifts can be set to move, the height isn't being affected by the DB entry.
|
Quote:
|
I hate to be impatient, but has any devs noticed my big update to locked doors?
I imagine so, but I dont see any CVS updates. Just curious. |
Yes, i noticed... I started to merge it in, but BP and I had some discussions on it so I decided to hold off a bit.. He has some other ideas for it's implementation...
|
Groovy. :D
|
Ok first off the item struct isn't wrong, just most of us have old struct format items lurking around. You can test this by looking at say your mechanical lockpicks in game notice the skill mod doesn't show? Now try a more recent item, 24602 for instance will show it's skill mod.
Now doors wheee! Ok i just got done moveing all the door code to the ::HandleClick() function. Changes include, locked doors without a key item assigned (lockpick=skill,keyitem=0) locked doors that can not be picked (lockpick=0,keyitem=item_nr) check the cursored item for lock pick skill skill mods are handled inside GetSkill() Use IncreaseSkill() for skill ups TODO: Use the fancy(not acurate atm) check skill increase function Keyring (bleh) Point out anything you fixed above i missed please =) |
well right on! Guess there was a few things I didnt remember (liked unpickable doors etc..)
if you mean my code with those fixes/extras then that sounds like the ticket (course I was done before, so any add-ons are good to me hehe) |
All times are GMT -4. The time now is 11:39 PM. |
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.