Weapon Type Auto-Detection

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Message
Author
User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Weapon Type Auto-Detection

#1 Post by Bill D Cat » Sat Jul 11, 2015 10:17 pm

I was wondering if the bot can detect what type of weapon the player has equipped in main hand, off hand and ranged slots. This could help in reducing errors during combat, and save a little time between skill usage. For example, when playing a Scout/X class combo and you switch to X/Scout and forget to equip a bow or crossbow (or don't yet have one for whatever reason) you could then avoid using scout ranged attacks. This of course would only really be an issue if you preset your character's profile to include SHOT or VAMPIRE ARROWS for the off-class. Warriors would benefit as well when having to use Tactical Attack (2H) or Thunder (1H).

I have a simple RoM macro I built into one of my personal add-ons that will report the current weapon skill level for each slot as well as the weapon type. This could be modified and used in the in-game functions file, or code could be added directly into the bot to achieve the same goal.

Code: Select all

-- Prints the player's current equipped weapon skills to the local chat window.
function GetWeaponSkill()
  local WSlots = {"MainHandSlot","SecondaryHandSlot","RangedSlot"}
  local WSlotNames = {"Main Hand","Off Hand","Ranged"}
  local WSkills = {"Unarmed","Sword","Dagger","Wand","Axe","Bludgeon","2-H Sword","Staff","2-H Axe","2-H Hammer","Polearm","Bow","Crossbow","Gun"}
  local WSkillNames = {"Unarmed","1-H Sword","Dagger","Wand","Axe","1-H Hammer","2-H Sword","Staff","2-H Axe","2-H Hammer","Polearm","Bow","Crossbow","Gun"}
  for k = 1, 3 do
    local id, id2, id3 = GetInventorySlotInfo(WSlots[k])
    if id ~= nil and GetInventoryItemTexture("player",id) then
      OTCGetDataTooltip:SetInventoryItem("player", id)
      OTCGetDataTooltip:Hide()  
      for i = 2, 8 do
        leftSide = getglobal("OTCGetDataTooltipTextLeft" .. i)
        leftText = ""
        if leftSide:IsVisible() then
          leftText = leftSide:GetText()
        end
        if left == nil then
          left = ""
        end
        CurrWeap = 0
        for j = 1, 13 do
          if string.find(leftText, WSkills[j]) ~= nil then
            CurrWeap = j
          end
        end 
        if CurrWeap > 0 then
          for a,b in pairs(PRACTICEDFRAME_ITEMS) do
            if a == CurrWeap then
              local CurrSkill, _, MaxSkill = GetPlayerSkilled(b)
              CurrLvl = math.floor(CurrSkill)
              local PctLvl = math.floor((CurrSkill - CurrLvl)*10000+0.5)/100
              Msg(WSlotNames[k].." Skill: "..WSkillNames[CurrWeap].." = "..CurrLvl.."/"..MaxSkill.." ("..PctLvl.."%)")
            end  
          end
        end
      end
    end
  end
end

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Weapon Type Auto-Detection

#2 Post by rock5 » Sun Jul 12, 2015 2:29 am

Of course the bot gets items types as part of the item class. That includes equipped items. Plus it has some functions to help. eg.

Code: Select all

local ammo = equipment:findItem("ammunition")
if ammo:isType("Arrows") then
    ---
elseif ammo:isType("Projectiles") then
    ---
end
Note: findItem for the equipment class is a bit different than other containers. With other classes findItem accepts the name as the first argument and a range as the second argument. equipment only accept the 'range' as the first argument. The 'ranges' for the equipment class are the names of the slots. I don't think they are recorded anywhere but you can find them in the getInventoryRange function in the inventory.lua file around line 725.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
BlubBlab
Posts: 948
Joined: Fri Nov 30, 2012 11:33 pm
Location: My little Pony cafe

Re: Weapon Type Auto-Detection

#3 Post by BlubBlab » Sun Jul 12, 2015 3:10 am

Yeah I did that too in my userfunction.
You should note that :isType() takes a language specific string. Which can by found in the itemtypestable in the directory cache
Jack-of-all-trades, but master-of-only of a few :D

My Reps:
https://github.com/BlubBlab/Micromacro-with-OpenCV (My version of MM2 with OpenCV and for MS Visual Studio)
https://github.com/BlubBlab/rom-bot (rombot with no stop WP and advanced human emulation mode and some other extensions)
https://github.com/BlubBlab/Micromacro-2-Bot-Framework ( A work in progress )
My Tools : viewtopic.php?f=10&t=6226

User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: Weapon Type Auto-Detection

#4 Post by Bill D Cat » Sun Jul 12, 2015 8:33 am

Okay, I was just curious since I noticed the bot would try to use Tactical Attack with a 1 handed weapon, and Thunder with a 2 handed weapon. Rogues would get stuck spamming Shadowstab because they were using a sword and not a dagger and so the bleed wasn't being applied. Mostly in that case due to new dwarf or elf rogues not getting a dagger to turn into their +8 weapon when starting out. Human rogues get a starting dagger.

I guess it's not that big of an issue, since you usually won't die because a few skills fail to cast. But on the other hand, anything to make the bot smarter about it's skill usage can't hurt.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Weapon Type Auto-Detection

#5 Post by rock5 » Mon Jul 13, 2015 2:12 am

Yeah so the problem is not identifying the weapon but identifying the requirements for the skills. So far weapon requirements have not been found in the skills memory structure. It's certainly not part of the SKILLUSES values which are used to test skill requirements for power, projectile, arrow and item requirements. We could just add a value to the skills database but that would be tedious. And given that most people would just make sure to only include skills in their profile that match their preferred weapon type, there is no real need.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: Weapon Type Auto-Detection

#6 Post by Bill D Cat » Mon Jul 13, 2015 6:38 am

Skills that have some type of equipment requirement:

Rogue:
Shadowstab needs a dagger for bleed effect

Warrior:
Tactical Attack needs 2 handed weapon
Thunder needs 1 handed weapon
Slash needs axe or sword for bleed effect
Mooncleave needs 2 handed weapon

Scout:
Shot needs a ranged weapon
Vampire Arrows needs a ranged weapon
etc.

Knight:
Shield of Atonement needs a shield equipped
Shield of Discipline needs a shield equipped
Whirlwind Shield needs a shield equipped
Shield of Valor needs a shield equipped
Truth Shield Bash needs a shield equipped

Overall, not that many skills other than Scout that require a certain equipment configuration to be used. In the case of the Rogue, it can potentially not use Low Blow or Wound Attack because the effects aren't proccing to trigger them.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Weapon Type Auto-Detection

#7 Post by rock5 » Mon Jul 13, 2015 7:32 am

I don't know if you should be including skills that can still be used even though the wrong weapon is equipped such as Shadowstab. Just because you don't have a dagger equipped doesn't mean you shouldn't use the skill. And does that list include all elite skills? I don't like the idea of adding it. It's too messy. Now if we ever found that info in memory then we could test for it without having to add stuff to the skills.xml database.

In regards to Shadowstab, Low Blow and Wound Attack combo. I believe the bot has no buff requirements for those skills. So they should work such as they are. If you have the expertise to customize your profile to test for the buffs then you have the expertise to add a check for the weapon, if you want to be that fussy.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: Weapon Type Auto-Detection

#8 Post by Bill D Cat » Mon Jul 13, 2015 7:44 am

If memory serves me (I'm at work at the moment) the Low Blow and Wound Attack skills each do have a requirement in the skills.lua database for the Bleed and Grevious Wound buffs. So they don't get triggered by the bot unless it finds them.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Weapon Type Auto-Detection

#9 Post by rock5 » Mon Jul 13, 2015 8:17 am

I'm looking at it now.

Code: Select all

	<skill name="ROGUE_LOW_BLOW" 						id="490323" range="50"	type="damage"		casttime="0"	cooldown="0"	target="enemy" />
	<skill name="ROGUE_WOUND_ATTACK" 					id="490313" range="50"	type="damage"		casttime="0"	cooldown="6"	target="enemy" />
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: Weapon Type Auto-Detection

#10 Post by Bill D Cat » Mon Jul 13, 2015 9:45 am

I think I copied the skills.lua data from the Rogue Rotation thread. So at least for my characters it has buff requirements for those skills. The release version of the bot won't have them. I will just work on something that checks for required equipment for my own use.

dx876234
Posts: 188
Joined: Sat Jul 24, 2010 6:13 am

Re: Weapon Type Auto-Detection

#11 Post by dx876234 » Mon Jul 13, 2015 1:35 pm

Requirements for skills are locate just before the cooldown in memory, addresses.skillRemainingCooldown_offset points to
MagicColdownBaseStruct.Time so addresses.skillRemainingCooldown_offset - 0x10 should point to the MagicNeedStruct
which specifies dependency where Type field is type of dependency and Value is additional data such as distance.

Best regards
DX

Code: Select all

struct MagicNeedStruct
{
	MagicSpellNeedTypeENUM	        Type;		//需求類型
	int						Value;		//值
};

struct MagicColdownBaseStruct
{
	//一般的Coldown
	MagicColdownClassENUM		Class;
	int							Type;
	int							Time;	//(秒)
	//下次可失法的時間
	int							TimeAllMagic;		
};

enum MagicSpellNeedTypeENUM
{
	EM_MagicSpellNeedType_None						,	//無需求
	EM_MagicSpellNeedType_Weapon					,	//需求 自己裝 武器
	EM_MagicSpellNeedType_EQ						,	//需求 自己裝 裝備
	EM_MagicSpellNeedType_Suit						,	//需求 自己裝 套裝
	EM_MagicSpellNeedType_Buf						,	//需求 自己有 法術Buf
	EM_MagicSpellNeedType_Buf_Target				,	//需求 目標有 法術Buf
	EM_MagicSpellNeedType_NoBuf						,	//需求 自己沒有 法術Buf
	EM_MagicSpellNeedType_NoBuf_Target				,	//需求 目標沒有 法術Buf
	EM_MagicSpellNeedType_WeaponType_Unarmed		,	//需求 自己裝 武器類型 空手
	EM_MagicSpellNeedType_WeaponType_Blade      	,	//需求 自己裝 武器類型 單手劍
	EM_MagicSpellNeedType_WeaponType_Dagger     	,	//需求 自己裝 武器類型 匕首
	EM_MagicSpellNeedType_WeaponType_Wand       	,	//需求 自己裝 武器類型 權杖
	EM_MagicSpellNeedType_WeaponType_Axe        	,	//需求 自己裝 武器類型 單手斧
	EM_MagicSpellNeedType_WeaponType_Bludgeon   	,	//需求 自己裝 武器類型 鎚棍棒
	EM_MagicSpellNeedType_WeaponType_Claymore   	,	//需求 自己裝 武器類型 雙手劍
	EM_MagicSpellNeedType_WeaponType_Staff      	,	//需求 自己裝 武器類型 杖
	EM_MagicSpellNeedType_WeaponType_2H_Axe     	,	//需求 自己裝 武器類型 雙手斧
	EM_MagicSpellNeedType_WeaponType_2H_Hammer  	,	//需求 自己裝 武器類型 雙手鎚
	EM_MagicSpellNeedType_WeaponType_Polearm		,	//需求 自己裝 武器類型 槍(長矛)
	EM_MagicSpellNeedType_WeaponType_SwordType  	,	//需求 自己裝 武器類型 劍類(單雙手)
	EM_MagicSpellNeedType_WeaponType_AxeType    	,	//需求 自己裝 武器類型 斧類(單雙手)
	EM_MagicSpellNeedType_WeaponType_Shield			,	//需求 自己裝 武器類型 盾
	EM_MagicSpellNeedType_Distance					,	//需求 距離目標
	EM_MagicSpellNeedType_NotAttak					,	//需求 自己非戰鬥
	EM_MagicSpellNeedType_Attack					,	//需求 自己戰鬥
	EM_MagicSpellNeedType_Critical					,	//需求 自己爆擊
	EM_MagicSpellNeedType_BeCritical				,	//需求 自己被爆擊
	EM_MagicSpellNeedType_Dodge						,	//需求 自己閃避
	EM_MagicSpellNeedType_BeDodge					,	//需求 自己被閃避
	EM_MagicSpellNeedType_Miss						,	//需求 自己Miss
	EM_MagicSpellNeedType_Parry						,	//需求 自己格擋
	EM_MagicSpellNeedType_BeParry					,	//需求 自己被格擋
	EM_MagicSpellNeedType_NotAttack_Target			,	//需求 目標非戰鬥
	EM_MagicSpellNeedType_Attack_Target				,	//需求 目標戰鬥	
	EM_MagicSpellNeedType_SelfHp_Smaller_Percent	,	//需求 HP百分比小於
	EM_MagicSpellNeedType_SelfHp_Greater_Percent	,	//需求 HP百分比大於
	EM_MagicSpellNeedType_Self_Job					,	//需求 職業
	EM_MagicSpellNeedType_WeaponType_LongDistWeapon	,	//需求 自己裝 武器類型 長距離武器
	EM_MagicSpellNeedType_WeaponType_2H_Weapon		,	//需求 自己裝 武器類型 雙手武器
	EM_MagicSpellNeedType_WeaponType_Hammer			,	//需求 自己裝 武器類型 鎚類(單雙手)
	EM_MagicSpellNeedType_BuffGroup					,	//需求 自己擁有某 Buff Group
	EM_MagicSpellNeedType_ShieldBlock				,	//需求 自己盾擋
	EM_MagicSpellNeedType_BeShieldBlock				,	//需求 自己被盾擋
	EM_MagicSpellNeedType_WeaponType_1H_Weapon		,	//需求 自己裝 武器類型 單手武器
	EM_MagicSpellNeedType_NoBuffGroup				,	//需求 自己沒有某 Buff Group
	EM_MagicSpellNeedType_TargetBuffGroup			,	//需求 目標擁有某 Buff Group
	EM_MagicSpellNeedType_TargetNoBuffGroup			,	//需求 目標沒有某 Buff Group
	EM_MagicSpellNeedType_MagicCritical				,	//需求 自己爆擊
	EM_MagicSpellNeedType_BeMagicCritical			,	//需求 自己被爆擊
	EM_MagicSpellNeedType_Self_MainJob				,	//需求 主職業
	EM_MagicSpellNeedType_Self_SoulPoint			,	//需求 靈魂值

};

User avatar
BlubBlab
Posts: 948
Joined: Fri Nov 30, 2012 11:33 pm
Location: My little Pony cafe

Re: Weapon Type Auto-Detection

#12 Post by BlubBlab » Mon Jul 13, 2015 1:54 pm

Wow you have access to ROM's source code :D
Jack-of-all-trades, but master-of-only of a few :D

My Reps:
https://github.com/BlubBlab/Micromacro-with-OpenCV (My version of MM2 with OpenCV and for MS Visual Studio)
https://github.com/BlubBlab/rom-bot (rombot with no stop WP and advanced human emulation mode and some other extensions)
https://github.com/BlubBlab/Micromacro-2-Bot-Framework ( A work in progress )
My Tools : viewtopic.php?f=10&t=6226

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Weapon Type Auto-Detection

#13 Post by rock5 » Tue Jul 14, 2015 12:13 am

I'm not sure I understand it. addresses.skillRemainingCooldown_offset - 0x10 = 0xD4. That allows for 4 ints. So I see the following ints at BaseItemAddress + 0xD4 [tr][tdspan=5][b]2 Handed skills[/b][/tdspan][/tr] [tr][td]Tactical Attack[/td][td]0[/td][td]0[/td][td]0[/td][td]1[/td][/tr] [tr][td]Moon Cleave[/td][td]0[/td][td]0[/td][td]0[/td][td]1[/td][/tr] [tr][tdspan=5][b]1 Handed skill[/b][/tdspan][/tr] [tr][td]Thunder[/td][td]501503[/td][td]43[/td][td]0[/td][td]1[/td][/tr] [tr][tdspan=5][b]shield skills[/b][/tdspan][/tr] [tr][td]Shield of Valor[/td][td]0[/td][td]0[/td][td]0[/td][td]1[/td][/tr] [tr][td]Truth Shield Bash[/td][td]0[/td][td]0[/td][td]0[/td][td]1[/td][/tr] [tr][td]Whirlwind Shield[/td][td]0[/td][td]0[/td][td]0[/td][td]1[/td][/tr]So what do those numbers mean in regards to the above info? Doesn't look informative.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

dx876234
Posts: 188
Joined: Sat Jul 24, 2010 6:13 am

Re: Weapon Type Auto-Detection

#14 Post by dx876234 » Tue Jul 14, 2015 11:51 am

Hmm I might have been a little to quick on posting that one, looking into it again.

Btw, while looking I found a skill that doesn't get enabled, the KNIGHT_SHIELD_OF_DISCIPLINE is not available as GetIdName(490169) doesn't return the name, is this my client/bot setup or a bug? Could you test a simple print(GetIdName(490169))?

-dx

dx876234
Posts: 188
Joined: Sat Jul 24, 2010 6:13 am

Re: Weapon Type Auto-Detection

#15 Post by dx876234 » Tue Jul 14, 2015 1:36 pm

Okey, I've looked at a Warrior, Tactical Attack and Thunder and found the following list which seems pretty correct to me.
Perhaps the issue was that the MagicNeedStruct is actually a small table MagicNeedStruct[2]...

-dx

Code: Select all

Tactical Attack BaseItemAddress + offset

0xd0	Type = 38		// EM_MagicSpellNeedType_WeaponType_2H_Weapon
0xd4	Value = 0
0xd8	Type = 0		// EM_MagicSpellNeedType_None
0xdc	Value = 0
0xe8	Time = 5		// Cooldown of TA

Thunder BaseItemAddress + offset

0xd0	Type = 5		// EM_MagicSpellNeedType_Buf
0xd4	Value = 501503	// Weakened buff ID
0xd8	Type = 43		// EM_MagicSpellNeedType_WeaponType_1H_Weapon
0xdc	Value = 0
0xe8	Time = 15		// Cooldown of Thunder

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Weapon Type Auto-Detection

#16 Post by rock5 » Wed Jul 15, 2015 7:54 am

Interesting, In addresses.lua there is

Code: Select all

	skillRequiredEffectFlag_offset = 0xD0,
	skillRequiredEffect_offset = 0xD4,
	skillRequiredEffectsStart_offset = 0x190,
I'm not sure what they mean as I can't find any other reference to them but it looks like the skill effects have been found before.

So you are saying it is a table of 4 int values starting at 0xD0? Looks good.

Code: Select all

Command> function effects(name) print(unpack(memoryReadBatch(getProc(),FindSkill
BookSkill(name).BaseItemAddress+0xd0,"iiii"))) end
Command> effects("Tactical Attack")
38      0       0       0
Command> effects("Moon Cleave")
38      0       0       0
Command> effects("Shield of Discipline")
21      0       0       0
Command> effects("Whirlwind Shield")
21      0       0       0
Command> effects("Shield of Valor")
21      0       0       0
Now I see where that ENUM table comes into play. These all make sense now. So only 2 requirements possible per skill?

I'll think about whether I'll do something with it.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

dx876234
Posts: 188
Joined: Sat Jul 24, 2010 6:13 am

Re: Weapon Type Auto-Detection

#17 Post by dx876234 » Wed Jul 15, 2015 1:26 pm

Yes, I only found two requirements per skill, seems this is hardcoded into the structure.

Seems the skillRequiredEffectFlag_offset/skillRequiredEffect_offset was an early attempt to check the same thing.

-dx

noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Weapon Type Auto-Detection

#18 Post by noobbotter » Wed Jul 15, 2015 4:40 pm

Any chance that it would be possible to write a value into memory to effectively remove a requirement to use a skill?

User avatar
BlubBlab
Posts: 948
Joined: Fri Nov 30, 2012 11:33 pm
Location: My little Pony cafe

Re: Weapon Type Auto-Detection

#19 Post by BlubBlab » Wed Jul 15, 2015 4:49 pm

I think you must try to find it out.
Jack-of-all-trades, but master-of-only of a few :D

My Reps:
https://github.com/BlubBlab/Micromacro-with-OpenCV (My version of MM2 with OpenCV and for MS Visual Studio)
https://github.com/BlubBlab/rom-bot (rombot with no stop WP and advanced human emulation mode and some other extensions)
https://github.com/BlubBlab/Micromacro-2-Bot-Framework ( A work in progress )
My Tools : viewtopic.php?f=10&t=6226

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Weapon Type Auto-Detection

#20 Post by rock5 » Thu Jul 16, 2015 2:22 am

It's easy enough for me to test so I thought I'd give it a go.

Doesn't work. I tried removing the shield requirement from a knights skills. When I did so the icon on the action bar became available but I still got the "Shield must be equipped" message when I tried to use it.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 0 guests