initial commit - getting at TSkill structs
This commit is contained in:
commit
717f5cd9da
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.vscode
|
||||
bin
|
||||
build
|
||||
local
|
||||
*.log
|
||||
9
TODO.md
Normal file
9
TODO.md
Normal file
@ -0,0 +1,9 @@
|
||||
## TODO NEXT
|
||||
- ALL TSkill structures
|
||||
- TSkillBase
|
||||
- TCreature
|
||||
- TPlayer
|
||||
- TNonPlayer
|
||||
|
||||
## Estimate
|
||||
The decompiled file has ~115K lines of C. If we take ~15K lines to be rubbish, this can be round to ~100K. Considering a low estimate of 200 lines per day, the whole process could take up to 500 days which is quite a bit but not impossible. Now considering a high estimate of 1K lines per day, it could take 100 days which is also quite a bit.
|
||||
25
build.bat
Normal file
25
build.bat
Normal file
@ -0,0 +1,25 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
pushd %~dp0
|
||||
del /q .\build\*
|
||||
mkdir .\build
|
||||
pushd .\build
|
||||
|
||||
set OUTPUTEXE=out.exe
|
||||
set OUTPUTPDB=out.pdb
|
||||
set INSTALLDIR=..\bin
|
||||
|
||||
set SRC="../src/creature.cc" "../src/main.cc"
|
||||
cl -W3 -WX -Zi -we4244 -we4456 -we4457 -wd4996 -std:c++14 -utf-8 -MP8 -DBUILD_DEBUG=1 -DARCH_X64=1 -D_CRT_SECURE_NO_WARNINGS=1 -Fe:"%OUTPUTEXE%" -Fd:"%OUTPUTPDB%" %* %SRC% /link -subsystem:console -incremental:no -opt:ref -dynamicbase "ws2_32.lib"
|
||||
|
||||
if errorlevel 1 exit /b errorlevel
|
||||
|
||||
mkdir "%INSTALLDIR%"
|
||||
copy /Y "%OUTPUTEXE%" "%INSTALLDIR%"
|
||||
copy /Y "%OUTPUTPDB%" "%INSTALLDIR%"
|
||||
|
||||
popd
|
||||
popd
|
||||
|
||||
endlocal
|
||||
605
reference/enums.hh
Normal file
605
reference/enums.hh
Normal file
@ -0,0 +1,605 @@
|
||||
|
||||
enum CreatureType: int {
|
||||
PLAYER=0,
|
||||
MONSTER=1,
|
||||
NPC=2
|
||||
};
|
||||
|
||||
enum CONNECTIONSTATE: int {
|
||||
CONNECTION_FREE=0,
|
||||
CONNECTION_ASSIGNED=1,
|
||||
CONNECTION_CONNECTED=2,
|
||||
CONNECTION_LOGIN=3,
|
||||
CONNECTION_GAME=4,
|
||||
CONNECTION_DEAD=5,
|
||||
CONNECTION_LOGOUT=6,
|
||||
CONNECTION_DISCONNECTED=7
|
||||
};
|
||||
|
||||
enum KNOWNCREATURESTATE: int {
|
||||
KNOWNCREATURE_FREE=0,
|
||||
KNOWNCREATURE_UPTODATE=1,
|
||||
KNOWNCREATURE_OUTDATED=2
|
||||
};
|
||||
|
||||
enum ToDoType: int {
|
||||
TDWait=0,
|
||||
TDGo=1,
|
||||
TDRotate=2,
|
||||
TDMove=3,
|
||||
TDTrade=4,
|
||||
TDUse=5,
|
||||
TDTurn=6,
|
||||
TDAttack=7,
|
||||
TDTalk=8,
|
||||
TDChangeState=9
|
||||
};
|
||||
|
||||
enum GAMESTATE: int {
|
||||
GAME_STARTING=0,
|
||||
GAME_RUNNING=1,
|
||||
GAME_CLOSING=2,
|
||||
GAME_ENDING=3
|
||||
};
|
||||
|
||||
enum STATE: int {
|
||||
SLEEPING=0,
|
||||
IDLE=1,
|
||||
UNDERATTACK=2,
|
||||
TALKING=3,
|
||||
LEAVING=4,
|
||||
ATTACKING=5,
|
||||
PANIC=6
|
||||
};
|
||||
|
||||
enum SpellShapeType: int {
|
||||
SHAPE_ACTOR=0,
|
||||
SHAPE_VICTIM=1,
|
||||
SHAPE_ORIGIN=2,
|
||||
SHAPE_DESTINATION=3,
|
||||
SHAPE_ANGLE=4
|
||||
};
|
||||
|
||||
enum SpellImpactType: int {
|
||||
IMPACT_DAMAGE=0,
|
||||
IMPACT_FIELD=1,
|
||||
IMPACT_HEALING=2,
|
||||
IMPACT_SPEED=3,
|
||||
IMPACT_DRUNKEN=4,
|
||||
IMPACT_STRENGTH=5,
|
||||
IMPACT_OUTFIT=6,
|
||||
IMPACT_SUMMON=7
|
||||
};
|
||||
|
||||
enum RESULT: int {
|
||||
ERROR=-1,
|
||||
NOERROR=0,
|
||||
NOTACCESSIBLE=1,
|
||||
NOTMOVABLE=2,
|
||||
NOTTAKABLE=3,
|
||||
NOROOM=4,
|
||||
OUTOFRANGE=5,
|
||||
OUTOFHOME=6,
|
||||
CANNOTTHROW=7,
|
||||
TOOHEAVY=8,
|
||||
CROSSREFERENCE=9,
|
||||
CONTAINERFULL=10,
|
||||
WRONGPOSITION=11,
|
||||
WRONGPOSITION2=12,
|
||||
WRONGCLOTHES=13,
|
||||
HANDSNOTFREE=14,
|
||||
HANDBLOCKED=15,
|
||||
ONEWEAPONONLY=16,
|
||||
NOMATCH=17,
|
||||
NOTCUMULABLE=18,
|
||||
TOOMANYPARTS=19,
|
||||
EMPTYCONTAINER=20,
|
||||
SPLITOBJECT=21,
|
||||
NOKEYMATCH=22,
|
||||
UPSTAIRS=23,
|
||||
DOWNSTAIRS=24,
|
||||
CREATURENOTEXISTING=25,
|
||||
PLAYERNOTEXISTING=26,
|
||||
PLAYERNOTONLINE=27,
|
||||
NAMEAMBIGUOUS=28,
|
||||
NOTUSABLE=29,
|
||||
FEDUP=30,
|
||||
DESTROYED=31,
|
||||
SPELLUNKNOWN=32,
|
||||
LOWMAGICLEVEL=33,
|
||||
MAGICITEM=34,
|
||||
NOTENOUGHMANA=35,
|
||||
NOSKILL=36,
|
||||
TARGETLOST=37,
|
||||
OUTOFAMMO=38,
|
||||
NOCREATURE=39,
|
||||
TOOLONG=40,
|
||||
TARGETOUTOFRANGE=41,
|
||||
TARGETHIDDEN=42,
|
||||
ATTACKNOTALLOWED=43,
|
||||
NOWAY=44,
|
||||
LOGINERROR=45,
|
||||
LOGINABORT=46,
|
||||
PROTECTIONZONE=47,
|
||||
ENTERPROTECTIONZONE=48,
|
||||
EXHAUSTED=49,
|
||||
NOTINVITED=50,
|
||||
NOPREMIUMACCOUNT=51,
|
||||
MOVENOTPOSSIBLE=52,
|
||||
ALREADYTRADING=53,
|
||||
PARTNERTRADING=54,
|
||||
TOOMANYOBJECTS=55,
|
||||
TOOMANYSLAVES=56,
|
||||
NOTTURNABLE=57,
|
||||
SECUREMODE=58,
|
||||
NOTENOUGHSOULPOINTS=59,
|
||||
LOWLEVEL=60
|
||||
};
|
||||
|
||||
enum ActionType: int {
|
||||
ACTION_CREATEONMAP=0,
|
||||
ACTION_CREATE=1,
|
||||
ACTION_MONSTERONMAP=2,
|
||||
ACTION_MONSTER=3,
|
||||
ACTION_EFFECTONMAP=4,
|
||||
ACTION_EFFECT=5,
|
||||
ACTION_TEXTONMAP=6,
|
||||
ACTION_TEXT=7,
|
||||
ACTION_CHANGEONMAP=8,
|
||||
ACTION_CHANGE=9,
|
||||
ACTION_CHANGEREL=10,
|
||||
ACTION_SETATTRIBUTE=11,
|
||||
ACTION_CHANGEATTRIBUTE=12,
|
||||
ACTION_SETQUESTVALUE=13,
|
||||
ACTION_DAMAGE=14,
|
||||
ACTION_SETSTART=15,
|
||||
ACTION_WRITENAME=16,
|
||||
ACTION_WRITETEXT=17,
|
||||
ACTION_LOGOUT=18,
|
||||
ACTION_MOVEALLONMAP=19,
|
||||
ACTION_MOVEALL=20,
|
||||
ACTION_MOVEALLREL=21,
|
||||
ACTION_MOVETOPONMAP=22,
|
||||
ACTION_MOVETOP=23,
|
||||
ACTION_MOVETOPREL=24,
|
||||
ACTION_MOVE=25,
|
||||
ACTION_MOVEREL=26,
|
||||
ACTION_RETRIEVE=27,
|
||||
ACTION_DELETEALLONMAP=28,
|
||||
ACTION_DELETETOPONMAP=29,
|
||||
ACTION_DELETEONMAP=30,
|
||||
ACTION_DELETE=31,
|
||||
ACTION_DELETEININVENTORY=32,
|
||||
ACTION_DESCRIPTION=33,
|
||||
ACTION_LOADDEPOT=34,
|
||||
ACTION_SAVEDEPOT=35,
|
||||
ACTION_SENDMAIL=36,
|
||||
ACTION_NOP=37
|
||||
};
|
||||
|
||||
enum ModifierType: int {
|
||||
MODIFIER_NORMAL=0,
|
||||
MODIFIER_INVERT=1,
|
||||
MODIFIER_TRUE=2
|
||||
};
|
||||
|
||||
enum ConditionType: int {
|
||||
CONDITION_ISPOSITION=0,
|
||||
CONDITION_ISTYPE=1,
|
||||
CONDITION_ISCREATURE=2,
|
||||
CONDITION_ISPLAYER=3,
|
||||
CONDITION_HASFLAG=4,
|
||||
CONDITION_HASTYPEATTRIBUTE=5,
|
||||
CONDITION_HASINSTANCEATTRIBUTE=6,
|
||||
CONDITION_HASTEXT=7,
|
||||
CONDITION_ISPEACEFUL=8,
|
||||
CONDITION_MAYLOGOUT=9,
|
||||
CONDITION_HASPROFESSION=10,
|
||||
CONDITION_HASLEVEL=11,
|
||||
CONDITION_HASRIGHT=12,
|
||||
CONDITION_HASQUESTVALUE=13,
|
||||
CONDITION_TESTSKILL=14,
|
||||
CONDITION_COUNTOBJECTS=15,
|
||||
CONDITION_COUNTOBJECTSONMAP=16,
|
||||
CONDITION_ISOBJECTTHERE=17,
|
||||
CONDITION_ISCREATURETHERE=18,
|
||||
CONDITION_ISPLAYERTHERE=19,
|
||||
CONDITION_ISOBJECTININVENTORY=20,
|
||||
CONDITION_ISPROTECTIONZONE=21,
|
||||
CONDITION_ISHOUSE=22,
|
||||
CONDITION_ISHOUSEOWNER=23,
|
||||
CONDITION_ISDRESSED=24,
|
||||
CONDITION_RANDOM=25
|
||||
};
|
||||
|
||||
enum INSTANCEATTRIBUTE: int {
|
||||
CONTENT=0,
|
||||
CHESTQUESTNUMBER=1,
|
||||
AMOUNT=2,
|
||||
KEYNUMBER=3,
|
||||
KEYHOLENUMBER=4,
|
||||
DOORLEVEL=5,
|
||||
DOORQUESTNUMBER=6,
|
||||
DOORQUESTVALUE=7,
|
||||
CHARGES=8,
|
||||
TEXTSTRING=9,
|
||||
EDITOR=10,
|
||||
CONTAINERLIQUIDTYPE=11,
|
||||
POOLLIQUIDTYPE=12,
|
||||
ABSTELEPORTDESTINATION=13,
|
||||
RESPONSIBLE=14,
|
||||
REMAININGEXPIRETIME=15,
|
||||
SAVEDEXPIRETIME=16,
|
||||
REMAININGUSES=17
|
||||
};
|
||||
|
||||
enum TYPEATTRIBUTE: int {
|
||||
WAYPOINTS=0,
|
||||
CAPACITY=1,
|
||||
CHANGETARGET=2,
|
||||
KEYDOORTARGET=3,
|
||||
NAMEDOORTARGET=4,
|
||||
LEVELDOORTARGET=5,
|
||||
QUESTDOORTARGET=6,
|
||||
NUTRITION=7,
|
||||
INFORMATIONTYPE=8,
|
||||
FONTSIZE=9,
|
||||
MAXLENGTH=10,
|
||||
MAXLENGTHONCE=11,
|
||||
SOURCELIQUIDTYPE=12,
|
||||
ABSTELEPORTEFFECT=13,
|
||||
RELTELEPORTDISPLACEMENT=14,
|
||||
RELTELEPORTEFFECT=15,
|
||||
AVOIDDAMAGETYPES=16,
|
||||
MINIMUMLEVEL=17,
|
||||
PROFESSIONS=18,
|
||||
WEIGHT=19,
|
||||
ROTATETARGET=20,
|
||||
DESTROYTARGET=21,
|
||||
BODYPOSITION=22,
|
||||
SKILLNUMBER=23,
|
||||
SKILLMODIFICATION=24,
|
||||
PROTECTIONDAMAGETYPES=25,
|
||||
DAMAGEREDUCTION=26,
|
||||
BRIGHTNESS=27,
|
||||
LIGHTCOLOR=28,
|
||||
CORPSETYPE=29,
|
||||
TOTALEXPIRETIME=30,
|
||||
EXPIRETARGET=31,
|
||||
TOTALUSES=32,
|
||||
WEAROUTTARGET=33,
|
||||
WEAPONTYPE=34,
|
||||
WEAPONATTACKVALUE=35,
|
||||
WEAPONDEFENDVALUE=36,
|
||||
SHIELDDEFENDVALUE=37,
|
||||
BOWRANGE=38,
|
||||
BOWAMMOTYPE=39,
|
||||
THROWRANGE=40,
|
||||
THROWATTACKVALUE=41,
|
||||
THROWDEFENDVALUE=42,
|
||||
THROWMISSILE=43,
|
||||
THROWSPECIALEFFECT=44,
|
||||
THROWEFFECTSTRENGTH=45,
|
||||
THROWFRAGILITY=46,
|
||||
WANDRANGE=47,
|
||||
WANDMANACONSUMPTION=48,
|
||||
WANDATTACKSTRENGTH=49,
|
||||
WANDATTACKVARIATION=50,
|
||||
WANDDAMAGETYPE=51,
|
||||
WANDMISSILE=52,
|
||||
AMMOTYPE=53,
|
||||
AMMOATTACKVALUE=54,
|
||||
AMMOMISSILE=55,
|
||||
AMMOSPECIALEFFECT=56,
|
||||
AMMOEFFECTSTRENGTH=57,
|
||||
ARMORVALUE=58,
|
||||
ELEVATION=59,
|
||||
DISGUISETARGET=60,
|
||||
MEANING=61
|
||||
};
|
||||
|
||||
enum FLAG: int {
|
||||
BANK=0,
|
||||
CLIP=1,
|
||||
BOTTOM=2,
|
||||
TOP=3,
|
||||
CONTAINER=4,
|
||||
CHEST=5,
|
||||
CUMULATIVE=6,
|
||||
USEEVENT=7,
|
||||
CHANGEUSE=8,
|
||||
FORCEUSE=9,
|
||||
MULTIUSE=10,
|
||||
DISTUSE=11,
|
||||
MOVEMENTEVENT=12,
|
||||
COLLISIONEVENT=13,
|
||||
SEPARATIONEVENT=14,
|
||||
KEY=15,
|
||||
KEYDOOR=16,
|
||||
NAMEDOOR=17,
|
||||
LEVELDOOR=18,
|
||||
QUESTDOOR=19,
|
||||
BED=20,
|
||||
FOOD=21,
|
||||
RUNE=22,
|
||||
INFORMATION=23,
|
||||
TEXT=24,
|
||||
WRITE=25,
|
||||
WRITEONCE=26,
|
||||
LIQUIDCONTAINER=27,
|
||||
LIQUIDSOURCE=28,
|
||||
LIQUIDPOOL=29,
|
||||
TELEPORTABSOLUTE=30,
|
||||
TELEPORTRELATIVE=31,
|
||||
UNPASS=32,
|
||||
UNMOVE=33,
|
||||
UNTHROW=34,
|
||||
UNLAY=35,
|
||||
AVOID=36,
|
||||
MAGICFIELD=37,
|
||||
RESTRICTLEVEL=38,
|
||||
RESTRICTPROFESSION=39,
|
||||
TAKE=40,
|
||||
HANG=41,
|
||||
HOOKSOUTH=42,
|
||||
HOOKEAST=43,
|
||||
ROTATE=44,
|
||||
DESTROY=45,
|
||||
CLOTHES=46,
|
||||
SKILLBOOST=47,
|
||||
PROTECTION=48,
|
||||
LIGHT=49,
|
||||
ROPESPOT=50,
|
||||
CORPSE=51,
|
||||
EXPIRE=52,
|
||||
EXPIRESTOP=53,
|
||||
WEAROUT=54,
|
||||
WEAPON=55,
|
||||
SHIELD=56,
|
||||
BOW=57,
|
||||
THROW=58,
|
||||
WAND=59,
|
||||
AMMO=60,
|
||||
ARMOR=61,
|
||||
HEIGHT=62,
|
||||
DISGUISE=63,
|
||||
SHOWDETAIL=64,
|
||||
SPECIALOBJECT=65
|
||||
};
|
||||
|
||||
enum SPECIALMEANING: int {
|
||||
MONEY_ONE=1,
|
||||
MONEY_HUNDRED=2,
|
||||
MONEY_TENTHOUSAND=3,
|
||||
INVENTORY_RIGHTHAND=10,
|
||||
INVENTORY_LEFTHAND=11,
|
||||
INVENTORY_BODY_MALE=12,
|
||||
INVENTORY_BODY_FEMALE=13,
|
||||
INVENTORY_CONTAINER=14,
|
||||
INVENTORY_FOOD=15,
|
||||
DEPOT_LOCKER=20,
|
||||
DEPOT_CHEST=21,
|
||||
PARCEL_NEW=22,
|
||||
PARCEL_STAMPED=23,
|
||||
PARCEL_LABEL=24,
|
||||
LETTER_NEW=25,
|
||||
LETTER_STAMPED=26,
|
||||
BLOOD_SPLASH=30,
|
||||
BLOOD_POOL=31,
|
||||
RUNE_BLANK=40,
|
||||
MAGICFIELD_FIRE_DANGEROUS=41,
|
||||
MAGICFIELD_FIRE_HARMLESS=42,
|
||||
MAGICFIELD_POISON_DANGEROUS=43,
|
||||
MAGICFIELD_POISON_HARMLESS=44,
|
||||
MAGICFIELD_ENERGY_DANGEROUS=45,
|
||||
MAGICFIELD_ENERGY_HARMLESS=46,
|
||||
MAGICFIELD_MAGICWALL=47,
|
||||
MAGICFIELD_RUSHWOOD=48
|
||||
};
|
||||
|
||||
enum RIGHT: int {
|
||||
PREMIUM_ACCOUNT=0,
|
||||
NOTATION=1,
|
||||
NAMELOCK=2,
|
||||
STATEMENT_REPORT=3,
|
||||
BANISHMENT=4,
|
||||
FINAL_WARNING=5,
|
||||
IP_BANISHMENT=6,
|
||||
KICK=7,
|
||||
HOME_TELEPORT=8,
|
||||
GAMEMASTER_BROADCAST=9,
|
||||
ANONYMOUS_BROADCAST=10,
|
||||
NO_BANISHMENT=11,
|
||||
ALLOW_MULTICLIENT=12,
|
||||
LOG_COMMUNICATION=13,
|
||||
READ_GAMEMASTER_CHANNEL=14,
|
||||
READ_TUTOR_CHANNEL=15,
|
||||
HIGHLIGHT_HELP_CHANNEL=16,
|
||||
SEND_BUGREPORTS=17,
|
||||
NAME_INSULTING=18,
|
||||
NAME_SENTENCE=19,
|
||||
NAME_NONSENSICAL_LETTERS=20,
|
||||
NAME_BADLY_FORMATTED=21,
|
||||
NAME_NO_PERSON=22,
|
||||
NAME_CELEBRITY=23,
|
||||
NAME_COUNTRY=24,
|
||||
NAME_FAKE_IDENTITY=25,
|
||||
NAME_FAKE_POSITION=26,
|
||||
STATEMENT_INSULTING=27,
|
||||
STATEMENT_SPAMMING=28,
|
||||
STATEMENT_ADVERT_OFFTOPIC=29,
|
||||
STATEMENT_ADVERT_MONEY=30,
|
||||
STATEMENT_NON_ENGLISH=31,
|
||||
STATEMENT_CHANNEL_OFFTOPIC=32,
|
||||
STATEMENT_VIOLATION_INCITING=33,
|
||||
CHEATING_BUG_ABUSE=34,
|
||||
CHEATING_GAME_WEAKNESS=35,
|
||||
CHEATING_MACRO_USE=36,
|
||||
CHEATING_MODIFIED_CLIENT=37,
|
||||
CHEATING_HACKING=38,
|
||||
CHEATING_MULTI_CLIENT=39,
|
||||
CHEATING_ACCOUNT_TRADING=40,
|
||||
CHEATING_ACCOUNT_SHARING=41,
|
||||
GAMEMASTER_THREATENING=42,
|
||||
GAMEMASTER_PRETENDING=43,
|
||||
GAMEMASTER_INFLUENCE=44,
|
||||
GAMEMASTER_FALSE_REPORTS=45,
|
||||
KILLING_EXCESSIVE_UNJUSTIFIED=46,
|
||||
DESTRUCTIVE_BEHAVIOUR=47,
|
||||
SPOILING_AUCTION=48,
|
||||
INVALID_PAYMENT=49,
|
||||
TELEPORT_TO_CHARACTER=50,
|
||||
TELEPORT_TO_MARK=51,
|
||||
TELEPORT_VERTICAL=52,
|
||||
TELEPORT_TO_COORDINATE=53,
|
||||
LEVITATE=54,
|
||||
SPECIAL_MOVEUSE=55,
|
||||
MODIFY_GOSTRENGTH=56,
|
||||
SHOW_COORDINATE=57,
|
||||
RETRIEVE=58,
|
||||
ENTER_HOUSES=59,
|
||||
OPEN_NAMEDOORS=60,
|
||||
INVULNERABLE=61,
|
||||
UNLIMITED_MANA=62,
|
||||
KEEP_INVENTORY=63,
|
||||
ALL_SPELLS=64,
|
||||
UNLIMITED_CAPACITY=65,
|
||||
ZERO_CAPACITY=66,
|
||||
ATTACK_EVERYWHERE=67,
|
||||
NO_ATTACK=68,
|
||||
NO_RUNES=69,
|
||||
NO_LOGOUT_BLOCK=70,
|
||||
GAMEMASTER_OUTFIT=71,
|
||||
ILLUMINATE=72,
|
||||
CHANGE_PROFESSION=73,
|
||||
IGNORED_BY_MONSTERS=74,
|
||||
SHOW_KEYHOLE_NUMBERS=75,
|
||||
CREATE_OBJECTS=76,
|
||||
CREATE_MONEY=77,
|
||||
CREATE_MONSTERS=78,
|
||||
CHANGE_SKILLS=79,
|
||||
CLEANUP_FIELDS=80,
|
||||
NO_STATISTICS=81
|
||||
};
|
||||
|
||||
enum TWriterThreadReplyType: int {
|
||||
REPLY_BROADCAST=0,
|
||||
REPLY_DIRECT=1,
|
||||
REPLY_LOGOUT=2
|
||||
};
|
||||
|
||||
enum TWriterThreadOrderType: int {
|
||||
ORDER_TERMINATE=0,
|
||||
ORDER_LOGOUT=1,
|
||||
ORDER_PLAYERLIST=2,
|
||||
ORDER_KILLSTATISTICS=3,
|
||||
ORDER_PUNISHMENT=4,
|
||||
ORDER_CHARACTERDEATH=5,
|
||||
ORDER_ADDBUDDY=6,
|
||||
ORDER_REMOVEBUDDY=7,
|
||||
ORDER_DECREMENTISONLINE=8,
|
||||
ORDER_SAVEPLAYERDATA=9
|
||||
};
|
||||
|
||||
enum TALK_MODE: int {
|
||||
TALK_SAY=1,
|
||||
TALK_WHISPER=2,
|
||||
TALK_YELL=3,
|
||||
TALK_PRIVATE_MESSAGE=4,
|
||||
TALK_CHANNEL_CALL=5,
|
||||
TALK_GAMEMASTER_REQUEST=6,
|
||||
TALK_GAMEMASTER_ANSWER=7,
|
||||
TALK_PLAYER_ANSWER=8,
|
||||
TALK_GAMEMASTER_BROADCAST=9,
|
||||
TALK_GAMEMASTER_CHANNELCALL=10,
|
||||
TALK_GAMEMASTER_MESSAGE=11,
|
||||
TALK_HIGHLIGHT_CHANNELCALL=12,
|
||||
TALK_ANONYMOUS_BROADCAST=13,
|
||||
TALK_ANONYMOUS_CHANNELCALL=14,
|
||||
TALK_ANONYMOUS_MESSAGE=15,
|
||||
TALK_ANIMAL_LOW=16,
|
||||
TALK_ANIMAL_LOUD=17,
|
||||
TALK_ADMIN_MESSAGE=18,
|
||||
TALK_EVENT_MESSAGE=19,
|
||||
TALK_LOGIN_MESSAGE=20,
|
||||
TALK_STATUS_MESSAGE=21,
|
||||
TALK_INFO_MESSAGE=22,
|
||||
TALK_FAILURE_MESSAGE=23
|
||||
};
|
||||
|
||||
enum CHANNEL: int {
|
||||
GUILD_CHANNEL=0,
|
||||
GAMEMASTER_CHANNEL=1,
|
||||
TUTOR_CHANNEL=2,
|
||||
REQUEST_QUEUE=3,
|
||||
GAME_CHANNEL=4,
|
||||
TRADE_CHANNEL=5,
|
||||
REALLIFE_CHANNEL=6,
|
||||
HELP_CHANNEL=7
|
||||
};
|
||||
|
||||
enum EventType: int {
|
||||
EVENT_USE=0,
|
||||
EVENT_MULTIUSE=1,
|
||||
EVENT_MOVEMENT=2,
|
||||
EVENT_COLLISION=3,
|
||||
EVENT_SEPARATION=4
|
||||
};
|
||||
|
||||
enum ParameterType: int {
|
||||
PARAMETER_OBJECT=0,
|
||||
PARAMETER_TYPE=1,
|
||||
PARAMETER_FLAG=2,
|
||||
PARAMETER_TYPEATTRIBUTE=3,
|
||||
PARAMETER_INSTANCEATTRIBUTE=4,
|
||||
PARAMETER_COORDINATE=5,
|
||||
PARAMETER_VECTOR=6,
|
||||
PARAMETER_RIGHT=7,
|
||||
PARAMETER_SKILL=8,
|
||||
PARAMETER_NUMBER=9,
|
||||
PARAMETER_TEXT=10,
|
||||
PARAMETER_COMPARISON=11
|
||||
};
|
||||
|
||||
enum TReaderThreadOrderType: int {
|
||||
ORDER_TERMINATE=0,
|
||||
ORDER_LOADSECTOR=1,
|
||||
ORDER_LOADCHARACTER=2
|
||||
};
|
||||
|
||||
enum TReaderThreadReplyType: int {
|
||||
REPLY_SECTORDATA=0,
|
||||
REPLY_CHARACTERDATA=1
|
||||
};
|
||||
|
||||
enum TOKEN: int {
|
||||
ENDOFFILE=0,
|
||||
IDENTIFIER=1,
|
||||
NUMBER=2,
|
||||
STRING=3,
|
||||
BYTES=4,
|
||||
COORDINATE=5,
|
||||
SPECIAL=6
|
||||
};
|
||||
|
||||
enum SITUATION: int {
|
||||
DEFAULT=0,
|
||||
ADDRESS=1,
|
||||
ADDRESSQUEUE=2,
|
||||
BUSY=3,
|
||||
VANISH=4
|
||||
};
|
||||
|
||||
enum BloodType: int {
|
||||
BT_BLOOD=0,
|
||||
BT_SLIME=1,
|
||||
BT_BONES=2,
|
||||
BT_FIRE=3,
|
||||
BT_ENERGY=4
|
||||
};
|
||||
|
||||
enum TWorldType: int {
|
||||
NORMAL=0,
|
||||
NON_PVP=1,
|
||||
PVP_ENFORCED=2
|
||||
};
|
||||
115412
reference/game.c
Normal file
115412
reference/game.c
Normal file
File diff suppressed because it is too large
Load Diff
1712
reference/types.hh
Normal file
1712
reference/types.hh
Normal file
File diff suppressed because it is too large
Load Diff
429
src/creature.cc
Normal file
429
src/creature.cc
Normal file
@ -0,0 +1,429 @@
|
||||
#include "creature.hh"
|
||||
#include "enums.hh"
|
||||
|
||||
// TSkill REGULAR FUNCTIONS
|
||||
//==============================================================================
|
||||
TSkill::TSkill(int SkNr, TCreature *Master){
|
||||
this->Reset();
|
||||
this->SkNr = (uint16)SkNr;
|
||||
this->Master = Master;
|
||||
}
|
||||
|
||||
int TSkill::Get(void){
|
||||
int Value = this->Act;
|
||||
if(Value < this->Min)
|
||||
Value = this->Min;
|
||||
Value += this->MDAct + this->DAct;
|
||||
return Value;
|
||||
}
|
||||
|
||||
int TSkill::GetProgress(void){
|
||||
int Result = 0;
|
||||
if(this->NextLevel > this->LastLevel){
|
||||
Result = (this->NextLevel - this->Exp) * 100 / (this->NextLevel - this->LastLevel);
|
||||
|
||||
// TODO(fusion): This feels too much for reporting a mostly *impossible* error.
|
||||
if(Result < 0 || Result > 100){
|
||||
error("TSkill::GetProgress: Berechnungsfehler Exp %d, Last %d, Next %d, Prozent %d.\n",
|
||||
this->Exp, this->LastLevel, this->NextLevel, Result);
|
||||
|
||||
const char *MasterName = "(Unknown";
|
||||
if(this->Master != NULL){
|
||||
MasterName = this->Master->Name;
|
||||
}
|
||||
error("# Spieler %s - Skill %d\n", MasterName, this->SkNr);
|
||||
Result = 0;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void TSkill::Check(void){
|
||||
if(this->Act > this->Max){
|
||||
this->Act = this->Max;
|
||||
}
|
||||
}
|
||||
|
||||
void TSkill::Change(int Amount){
|
||||
this->Set(this->Act + Amount);
|
||||
|
||||
// TODO(fusion): Probably `TSkill::Check` inlined? It doesn't make a whole
|
||||
// lot of sense because `TSkill::Set` also checks the value. Maybe a custom
|
||||
// version of it does something differently?
|
||||
if(this->Act > this->Max){
|
||||
this->Act = this->Max;
|
||||
}
|
||||
}
|
||||
|
||||
void TSkill::SetMDAct(int MDAct){
|
||||
this->MDAct = MDAct;
|
||||
if(this->SkNr == 4 && this->Master && this->Master->Type == PLAYER){
|
||||
// TODO(fusion): Same as `TSkill::Process`.
|
||||
((TPlayer*)this->Master)->CheckState();
|
||||
}
|
||||
}
|
||||
|
||||
void TSkill::Load(int Act, int Max, int Min, int DAct, int MDAct,
|
||||
int Cycle, int MaxCycle, int Count, int MaxCount, int AddLevel,
|
||||
int Exp, int FactorPercent, int NextLevel, int Delta){
|
||||
this->Act = Act;
|
||||
this->Max = Max;
|
||||
this->Min = Min;
|
||||
this->DAct = DAct;
|
||||
this->MDAct = MDAct;
|
||||
this->Cycle = Cycle;
|
||||
this->MaxCycle = MaxCycle;
|
||||
this->Count = Count;
|
||||
this->MaxCount = MaxCount;
|
||||
this->AddLevel = AddLevel;
|
||||
this->Exp = Exp;
|
||||
this->FactorPercent = FactorPercent;
|
||||
this->NextLevel = NextLevel;
|
||||
this->Delta = Delta;
|
||||
|
||||
// TODO(fusion): Shouldn't we also do the same for `NextLevel`?
|
||||
this->LastLevel = this->GetExpForLevel(Act);
|
||||
|
||||
TCreature *Master = this->Master;
|
||||
if(Master && Cycle != 0){
|
||||
int SkNr = this->SkNr;
|
||||
if(SkNr >= NARRAY(Master->Skills)){
|
||||
error("TSkillBase::SetTimer: Ungueltige SkNr: %d\n", SkNr);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(fusion): I'm not entirely sure wtf is going on here.
|
||||
TSkill *Other = Master->Skills[SkNr];
|
||||
Master->DelTimer(SkNr);
|
||||
if(Other->SetTimer(Cycle, Count, MaxCount, FactorPercent)){
|
||||
Master->TimerList[Master->FirstFreeTimer] = Other;
|
||||
Master->FirstFreeTimer += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TSkill::Save(int *Act, int *Max, int *Min, int *DAct, int *MDAct,
|
||||
int *Cycle, int *MaxCycle, int *Count, int *MaxCount, int *AddLevel,
|
||||
int *Exp, int *FactorPercent, int *NextLevel, int *Delta){
|
||||
*Act = this->Act;
|
||||
*Max = this->Max;
|
||||
*Min = this->Min;
|
||||
*DAct = this->DAct;
|
||||
*MDAct = this->MDAct;
|
||||
*Cycle = this->Cycle;
|
||||
*MaxCycle = this->MaxCycle;
|
||||
*Count = this->Count;
|
||||
*MaxCount = this->MaxCount;
|
||||
*AddLevel = this->AddLevel;
|
||||
*Exp = this->Exp;
|
||||
*FactorPercent = this->FactorPercent;
|
||||
*NextLevel = this->NextLevel;
|
||||
*Delta = this->Delta;
|
||||
}
|
||||
|
||||
// TSkill VIRTUAL FUNCTIONS
|
||||
//==============================================================================
|
||||
TSkill::~TSkill(void){
|
||||
if(this->Master != NULL){
|
||||
this->Master->DelTimer(this->SkNr);
|
||||
}
|
||||
}
|
||||
|
||||
void TSkill::Set(int Value){
|
||||
if(Value > this->Max)
|
||||
Value = this->Max;
|
||||
this->Act = Value;
|
||||
}
|
||||
|
||||
void TSkill::Increase(int Amount){
|
||||
// no-op
|
||||
}
|
||||
|
||||
void TSkill::Decrease(int Amount){
|
||||
// no-op
|
||||
}
|
||||
|
||||
int TSkill::GetExpForLevel(int Level){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TSkill::Advance(int Range){
|
||||
// no-op
|
||||
}
|
||||
|
||||
void TSkill::ChangeSkill(int FactorPercent, int Delta){
|
||||
// no-op
|
||||
}
|
||||
|
||||
int TSkill::ProbeValue(int Max, bool Increase){
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TSkill::Probe(int Diff, int Prob, bool Increase){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TSkill::Process(void){
|
||||
bool Result = this->Cycle == 0;
|
||||
if(Result){
|
||||
if(this->Master && this->Master->Type == PLAYER){
|
||||
// TODO(fusion): Verify if a simple pointer cast works. Maybe `dynamic_cast`?
|
||||
((TPlayer*)this->Master)->CheckState();
|
||||
}
|
||||
}else if(this->Count <= 0){
|
||||
this->Count = this->MaxCount;
|
||||
// NOTE(fusion): `Range` should move `Cycle` towards ZERO.
|
||||
int Range = (this->Cycle < 1) ? +1 : -1;
|
||||
this->Cycle += Range;
|
||||
this->Event(Range);
|
||||
}else{
|
||||
this->Count -= 1;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool TSkill::SetTimer(int Cycle, int Count, int MaxCount, int AdditionalValue){
|
||||
this->Cycle = Cycle;
|
||||
this->Count = Count;
|
||||
this->MaxCount = MaxCount;
|
||||
if(this->Master && this->Master->Type == PLAYER){
|
||||
// TODO(fusion): Same as `TSkill::Process`.
|
||||
((TPlayer*)this->Master)->CheckState();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TSkill::DelTimer(void){
|
||||
this->Cycle = 0;
|
||||
this->Count = 0;
|
||||
this->MaxCount = 0;
|
||||
if(this->Master && this->Master->Type == PLAYER){
|
||||
// TODO(fusion): Same as `TSkill::Process`.
|
||||
((TPlayer*)this->Master)->CheckState();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int TSkill::TimerValue(void){
|
||||
return this->Cycle;
|
||||
}
|
||||
|
||||
bool TSkill::Jump(int Range){
|
||||
return true;
|
||||
}
|
||||
|
||||
void TSkill::Event(int Range){
|
||||
// no-op
|
||||
}
|
||||
|
||||
void TSkill::Reset(void){
|
||||
this->Act = 0;
|
||||
this->Max = INT_MAX;
|
||||
this->Min = 0;
|
||||
this->DAct = 0;
|
||||
this->MDAct = 0;
|
||||
this->FactorPercent = 1000;
|
||||
this->LastLevel = 0;
|
||||
this->NextLevel = INT_MAX;
|
||||
this->Exp = 0;
|
||||
this->Delta = INT_MAX;
|
||||
this->Cycle = 0;
|
||||
this->MaxCycle = 0;
|
||||
this->Count = 0;
|
||||
this->MaxCount = 0;
|
||||
this->AddLevel = 0;
|
||||
}
|
||||
|
||||
// TSkillLevel
|
||||
//==============================================================================
|
||||
TSkillLevel::~TSkillLevel(void){
|
||||
if(this->Master != NULL){
|
||||
this->Master->DelTimer(this->SkNr);
|
||||
}
|
||||
}
|
||||
|
||||
void TSkillLevel::Increase(int Amount){
|
||||
if (Amount < 0) {
|
||||
error("TSkillLevel::Increase: Amount negativ (%d).\n", Amount);
|
||||
return;
|
||||
}
|
||||
|
||||
// BUG(fusion): No bounds check as in `TSkillLevel::Decrease`?
|
||||
|
||||
int Range = 0;
|
||||
this->Exp += Amount;
|
||||
while(this->Exp >= this->NextLevel){
|
||||
this->Act += 1;
|
||||
this->LastLevel = this->GetExpForLevel(this->Act);
|
||||
this->NextLevel = this->GetExpForLevel(this->Act + 1);
|
||||
if(this->NextLevel < 0){
|
||||
// BUG(fusion): We don't check if `Master` is valid here?
|
||||
error("TSkillLevel::Increase: Skill vor Überlauf (%s, Skill %d).\n", this->Master->Name, this->SkNr);
|
||||
this->NextLevel = this->Exp;
|
||||
this->Exp -= 1000000;
|
||||
break;
|
||||
}
|
||||
Range += 1;
|
||||
}
|
||||
|
||||
if(Range != 0){
|
||||
this->Jump(Range);
|
||||
}
|
||||
|
||||
if(this->Master == NULL){
|
||||
error("TSkillLevel::Increase: GetMaster liefert NULL zurueck.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(this->Master->Type == PLAYER){
|
||||
SendPlayerData(this->Master->Connection);
|
||||
}
|
||||
}
|
||||
|
||||
void TSkillLevel::Decrease(int Amount){
|
||||
if(Amount < 0){
|
||||
error("TSkillLevel::Decrease: Amount negativ (%d).\n", Amount);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(fusion): This is some weird ass comparison.
|
||||
if(Amount > this->Exp && this->Exp > 100000){
|
||||
error("TSkillLevel::Decrease: Amount zu gross(%d).\n", Amount);
|
||||
return;
|
||||
}
|
||||
|
||||
int Range = 0;
|
||||
if(Amount < this->Exp){
|
||||
this->Exp -= Amount;
|
||||
}else{
|
||||
this->Exp = 0;
|
||||
}
|
||||
|
||||
// TODO(fusion): This could probably be an oversight but the decompiled
|
||||
// function was calling `GetExpForLevel` instead of using `LastLevel`
|
||||
// which makes me wonder whether `LastLevel` is properly initialized.
|
||||
while(this->Exp < this->LastLevel){
|
||||
this->Act -= 1;
|
||||
this->NextLevel = this->LastLevel;
|
||||
this->LastLevel = this->GetExpForLevel(this->Act);
|
||||
}
|
||||
|
||||
if(Range != 0){
|
||||
this->Jump(Range);
|
||||
}
|
||||
|
||||
if(this->Master == NULL){
|
||||
error("TSkillLevel::Decrease: GetMaster liefert NULL zurueck.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(this->Master->Type == PLAYER){
|
||||
SendPlayerData(this->Master->Connection);
|
||||
}
|
||||
}
|
||||
|
||||
int TSkillLevel::GetExpForLevel(int Level){
|
||||
if(Level < 1){
|
||||
error("TSkillLevel::GetExpForLevel: Ungültiger Level %d.\n", Level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Level > 500){
|
||||
error("TSkillLevel::GetExpForLevel: Level=%d; Formel gegen Überlauf sichern.\n", Level);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(this->Delta <= 0){
|
||||
error("TSkillLevel::GetExpForLevel: Ungültiger Delta-Wert %d.\n", this->Delta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((((Level - 6) * Level + 17) * Level - 12) / 6) * this->Delta;
|
||||
}
|
||||
|
||||
bool TSkillLevel::Jump(int Range){
|
||||
if(this->Master == NULL){
|
||||
error("TSkillLevel::Jump: GetMaster liefert NULL zurueck!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
this->Master->Skills[SKILL_HITPOINTS ]->Advance(Range);
|
||||
this->Master->Skills[SKILL_MANA ]->Advance(Range);
|
||||
this->Master->Skills[SKILL_GO_STRENGTH ]->Advance(Range);
|
||||
this->Master->Skills[SKILL_CARRY_WEIGHT]->Advance(Range);
|
||||
|
||||
AnnounceChangedCreature(this->Master->ID, 4);
|
||||
this->Master->Combat.CheckCombatValues();
|
||||
|
||||
if(this->Master->Type == PLAYER){
|
||||
// TODO(fusion): Probably `TSkill::Get` inlined?
|
||||
int Level = this->Act;
|
||||
if(Level < this->Min)
|
||||
Level = this->Min;
|
||||
Level += this->MDAct + this->DAct;
|
||||
// ==
|
||||
|
||||
int FromLevel = Level - Range;
|
||||
int ToLevel = Level;
|
||||
if(Range > 0){
|
||||
SendMessage(this->Master->Connection, TALK_ANONYMOUS_BROADCAST,
|
||||
"You advanced from Level %d to Level %d.", FromLevel, ToLevel);
|
||||
}else if(Range < 0){
|
||||
SendMessage(this->Master->Connection, TALK_ANONYMOUS_BROADCAST,
|
||||
"You were downgraded from Level %d to Level %d.", FromLevel, ToLevel);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Creature Functions
|
||||
//==============================================================================
|
||||
// TODO(fusion): This was the first function I attempted to cleanup but soon
|
||||
// realized we should start with the building blocks of the codebase, namely
|
||||
// TSkill, TSkillBase, etc...
|
||||
// We should probably come back to this once we start doing creature functions
|
||||
// again.
|
||||
void CheckMana(TCreature *Creature, int ManaPoints, int SoulPoints, int Delay){
|
||||
if(Creature == NULL){
|
||||
error("CheckMana: Übergebene Kreatur existiert nicht.\n");
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
if(Creature->Type != PLAYER || ManaPoints < 0)
|
||||
return;
|
||||
|
||||
TSkill *Mana = Creature->Skills[SKILL_MANA];
|
||||
if(Mana == NULL){
|
||||
error("CheckMana: Kein Skill MANA!\n");
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
TSkill *Soul = Creature->Skills[SKILL_SOUL];
|
||||
if(Soul == NULL){
|
||||
error("CheckMana: Kein Skill SOULPOINTS!\n");
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
if(!CheckRight(Creature->ID, UNLIMITED_MANA)){
|
||||
if(Mana->Get() < ManaPoints)
|
||||
throw NOTENOUGHMANA;
|
||||
|
||||
if(Soul->Get() < SoulPoints)
|
||||
throw NOTENOUGHSOULPOINTS;
|
||||
|
||||
Mana->Change(-ManaPoints);
|
||||
Soul->Change(-SoulPoints);
|
||||
}
|
||||
|
||||
if(ManaPoints > 0){
|
||||
Creature->Skills[SKILL_MAGIC_LEVEL]->Increase(ManaPoints);
|
||||
}
|
||||
|
||||
// NOTE(fusion): Maintain largest exhaust?
|
||||
int EarliestSpellTime = Delay + ServerMilliseconds;
|
||||
if(Creature->EarliestSpellTime < EarliestSpellTime)
|
||||
Creature->EarliestSpellTime = EarliestSpellTime;
|
||||
}
|
||||
76
src/creature.hh
Normal file
76
src/creature.hh
Normal file
@ -0,0 +1,76 @@
|
||||
#ifndef TIBIA_CREATURE_HH_
|
||||
#define TIBIA_CREATURE_HH_ 1
|
||||
|
||||
#include "main.hh"
|
||||
|
||||
struct TSkillBase;
|
||||
struct TCreature;
|
||||
struct TPlayer;
|
||||
|
||||
struct TSkill{
|
||||
// REGULAR FUNCTIONS
|
||||
// =========================================================================
|
||||
TSkill(int SkNr, TCreature *Master);
|
||||
int Get(void);
|
||||
int GetProgress(void);
|
||||
void Check(void);
|
||||
void Change(int Amount);
|
||||
void SetMDAct(int MDAct);
|
||||
void Load(int Act, int Max, int Min, int DAct, int MDAct,
|
||||
int Cycle, int MaxCycle, int Count, int MaxCount, int AddLevel,
|
||||
int Exp, int FactorPercent, int NextLevel, int Delta);
|
||||
void Save(int *Act, int *Max, int *Min, int *DAct, int *MDAct,
|
||||
int *Cycle, int *MaxCycle, int *Count, int *MaxCount, int *AddLevel,
|
||||
int *Exp, int *FactorPercent, int *NextLevel, int *Delta);
|
||||
|
||||
// VIRTUAL FUNCTIONS
|
||||
// =========================================================================
|
||||
virtual ~TSkill(void); // VTABLE[ 0]
|
||||
//virtual ~TSkill(void); // Duplicate destructor that also calls operator delete. // VTABLE[ 1]
|
||||
virtual void Set(int Value); // VTABLE[ 2]
|
||||
virtual void Increase(int Amount); // VTABLE[ 3]
|
||||
virtual void Decrease(int Amount); // VTABLE[ 4]
|
||||
virtual int GetExpForLevel(int Level); // VTABLE[ 5]
|
||||
virtual void Advance(int Range); // VTABLE[ 6]
|
||||
virtual void ChangeSkill(int FactorPercent, int Delta); // VTABLE[ 7]
|
||||
virtual int ProbeValue(int Max, bool Increase); // VTABLE[ 8]
|
||||
virtual bool Probe(int Diff, int Prob, bool Increase); // VTABLE[ 9]
|
||||
virtual bool Process(void); // VTABLE[10]
|
||||
virtual bool SetTimer(int Cycle, int Count, int MaxCount, int AdditionalValue); // VTABLE[11]
|
||||
virtual bool DelTimer(void); // VTABLE[12]
|
||||
virtual int TimerValue(void); // VTABLE[13]
|
||||
virtual bool Jump(int Range); // VTABLE[14]
|
||||
virtual void Event(int Range); // VTABLE[15]
|
||||
virtual void Reset(void); // VTABLE[16]
|
||||
|
||||
// DATA
|
||||
// =========================================================================
|
||||
//void *VTABLE; // IMPLICIT
|
||||
int DAct; // Delta Value - Probably from equipment.
|
||||
int MDAct; // Delta Magic Value - Probably from spells.
|
||||
uint16 SkNr;
|
||||
TCreature *Master;
|
||||
int Act; // Actual Value (?)
|
||||
int Max;
|
||||
int Min;
|
||||
int FactorPercent;
|
||||
int LastLevel;
|
||||
int NextLevel;
|
||||
int Delta;
|
||||
int Exp;
|
||||
int Cycle;
|
||||
int MaxCycle;
|
||||
int Count;
|
||||
int MaxCount;
|
||||
int AddLevel;
|
||||
};
|
||||
|
||||
struct TSkillLevel: TSkill {
|
||||
~TSkillLevel(void) override;
|
||||
void Increase(int Amount) override;
|
||||
void Decrease(int Amount) override;
|
||||
int GetExpForLevel(int Level) override;
|
||||
bool Jump(int Range) override;
|
||||
};
|
||||
|
||||
#endif //TIBIA_CREATURE_HH_
|
||||
219
src/enums.hh
Normal file
219
src/enums.hh
Normal file
@ -0,0 +1,219 @@
|
||||
#ifndef TIBIA_ENUMS_HH_
|
||||
#define TIBIA_ENUMS_HH_ 1
|
||||
|
||||
#include "main.hh"
|
||||
|
||||
// TODO(fusion): Probably cleanup these names? Prefix values? Its crazy that
|
||||
// there are no collision problems (possibly yet).
|
||||
|
||||
enum CreatureType: int {
|
||||
PLAYER = 0,
|
||||
MONSTER = 1,
|
||||
NPC = 2,
|
||||
};
|
||||
|
||||
enum RESULT: int {
|
||||
ERROR = -1,
|
||||
NOERROR = 0,
|
||||
NOTACCESSIBLE = 1,
|
||||
NOTMOVABLE = 2,
|
||||
NOTTAKABLE = 3,
|
||||
NOROOM = 4,
|
||||
OUTOFRANGE = 5,
|
||||
OUTOFHOME = 6,
|
||||
CANNOTTHROW = 7,
|
||||
TOOHEAVY = 8,
|
||||
CROSSREFERENCE = 9,
|
||||
CONTAINERFULL = 10,
|
||||
WRONGPOSITION = 11,
|
||||
WRONGPOSITION2 = 12,
|
||||
WRONGCLOTHES = 13,
|
||||
HANDSNOTFREE = 14,
|
||||
HANDBLOCKED = 15,
|
||||
ONEWEAPONONLY = 16,
|
||||
NOMATCH = 17,
|
||||
NOTCUMULABLE = 18,
|
||||
TOOMANYPARTS = 19,
|
||||
EMPTYCONTAINER = 20,
|
||||
SPLITOBJECT = 21,
|
||||
NOKEYMATCH = 22,
|
||||
UPSTAIRS = 23,
|
||||
DOWNSTAIRS = 24,
|
||||
CREATURENOTEXISTING = 25,
|
||||
PLAYERNOTEXISTING = 26,
|
||||
PLAYERNOTONLINE = 27,
|
||||
NAMEAMBIGUOUS = 28,
|
||||
NOTUSABLE = 29,
|
||||
FEDUP = 30,
|
||||
DESTROYED = 31,
|
||||
SPELLUNKNOWN = 32,
|
||||
LOWMAGICLEVEL = 33,
|
||||
MAGICITEM = 34,
|
||||
NOTENOUGHMANA = 35,
|
||||
NOSKILL = 36,
|
||||
TARGETLOST = 37,
|
||||
OUTOFAMMO = 38,
|
||||
NOCREATURE = 39,
|
||||
TOOLONG = 40,
|
||||
TARGETOUTOFRANGE = 41,
|
||||
TARGETHIDDEN = 42,
|
||||
ATTACKNOTALLOWED = 43,
|
||||
NOWAY = 44,
|
||||
LOGINERROR = 45,
|
||||
LOGINABORT = 46,
|
||||
PROTECTIONZONE = 47,
|
||||
ENTERPROTECTIONZONE = 48,
|
||||
EXHAUSTED = 49,
|
||||
NOTINVITED = 50,
|
||||
NOPREMIUMACCOUNT = 51,
|
||||
MOVENOTPOSSIBLE = 52,
|
||||
ALREADYTRADING = 53,
|
||||
PARTNERTRADING = 54,
|
||||
TOOMANYOBJECTS = 55,
|
||||
TOOMANYSLAVES = 56,
|
||||
NOTTURNABLE = 57,
|
||||
SECUREMODE = 58,
|
||||
NOTENOUGHSOULPOINTS = 59,
|
||||
LOWLEVEL = 60,
|
||||
};
|
||||
|
||||
enum RIGHT: int {
|
||||
PREMIUM_ACCOUNT = 0,
|
||||
NOTATION = 1,
|
||||
NAMELOCK = 2,
|
||||
STATEMENT_REPORT = 3,
|
||||
BANISHMENT = 4,
|
||||
FINAL_WARNING = 5,
|
||||
IP_BANISHMENT = 6,
|
||||
KICK = 7,
|
||||
HOME_TELEPORT = 8,
|
||||
GAMEMASTER_BROADCAST = 9,
|
||||
ANONYMOUS_BROADCAST = 10,
|
||||
NO_BANISHMENT = 11,
|
||||
ALLOW_MULTICLIENT = 12,
|
||||
LOG_COMMUNICATION = 13,
|
||||
READ_GAMEMASTER_CHANNEL = 14,
|
||||
READ_TUTOR_CHANNEL = 15,
|
||||
HIGHLIGHT_HELP_CHANNEL = 16,
|
||||
SEND_BUGREPORTS = 17,
|
||||
NAME_INSULTING = 18,
|
||||
NAME_SENTENCE = 19,
|
||||
NAME_NONSENSICAL_LETTERS = 20,
|
||||
NAME_BADLY_FORMATTED = 21,
|
||||
NAME_NO_PERSON = 22,
|
||||
NAME_CELEBRITY = 23,
|
||||
NAME_COUNTRY = 24,
|
||||
NAME_FAKE_IDENTITY = 25,
|
||||
NAME_FAKE_POSITION = 26,
|
||||
STATEMENT_INSULTING = 27,
|
||||
STATEMENT_SPAMMING = 28,
|
||||
STATEMENT_ADVERT_OFFTOPIC = 29,
|
||||
STATEMENT_ADVERT_MONEY = 30,
|
||||
STATEMENT_NON_ENGLISH = 31,
|
||||
STATEMENT_CHANNEL_OFFTOPIC = 32,
|
||||
STATEMENT_VIOLATION_INCITING = 33,
|
||||
CHEATING_BUG_ABUSE = 34,
|
||||
CHEATING_GAME_WEAKNESS = 35,
|
||||
CHEATING_MACRO_USE = 36,
|
||||
CHEATING_MODIFIED_CLIENT = 37,
|
||||
CHEATING_HACKING = 38,
|
||||
CHEATING_MULTI_CLIENT = 39,
|
||||
CHEATING_ACCOUNT_TRADING = 40,
|
||||
CHEATING_ACCOUNT_SHARING = 41,
|
||||
GAMEMASTER_THREATENING = 42,
|
||||
GAMEMASTER_PRETENDING = 43,
|
||||
GAMEMASTER_INFLUENCE = 44,
|
||||
GAMEMASTER_FALSE_REPORTS = 45,
|
||||
KILLING_EXCESSIVE_UNJUSTIFIED = 46,
|
||||
DESTRUCTIVE_BEHAVIOUR = 47,
|
||||
SPOILING_AUCTION = 48,
|
||||
INVALID_PAYMENT = 49,
|
||||
TELEPORT_TO_CHARACTER = 50,
|
||||
TELEPORT_TO_MARK = 51,
|
||||
TELEPORT_VERTICAL = 52,
|
||||
TELEPORT_TO_COORDINATE = 53,
|
||||
LEVITATE = 54,
|
||||
SPECIAL_MOVEUSE = 55,
|
||||
MODIFY_GOSTRENGTH = 56,
|
||||
SHOW_COORDINATE = 57,
|
||||
RETRIEVE = 58,
|
||||
ENTER_HOUSES = 59,
|
||||
OPEN_NAMEDOORS = 60,
|
||||
INVULNERABLE = 61,
|
||||
UNLIMITED_MANA = 62,
|
||||
KEEP_INVENTORY = 63,
|
||||
ALL_SPELLS = 64,
|
||||
UNLIMITED_CAPACITY = 65,
|
||||
ZERO_CAPACITY = 66,
|
||||
ATTACK_EVERYWHERE = 67,
|
||||
NO_ATTACK = 68,
|
||||
NO_RUNES = 69,
|
||||
NO_LOGOUT_BLOCK = 70,
|
||||
GAMEMASTER_OUTFIT = 71,
|
||||
ILLUMINATE = 72,
|
||||
CHANGE_PROFESSION = 73,
|
||||
IGNORED_BY_MONSTERS = 74,
|
||||
SHOW_KEYHOLE_NUMBERS = 75,
|
||||
CREATE_OBJECTS = 76,
|
||||
CREATE_MONEY = 77,
|
||||
CREATE_MONSTERS = 78,
|
||||
CHANGE_SKILLS = 79,
|
||||
CLEANUP_FIELDS = 80,
|
||||
NO_STATISTICS = 81,
|
||||
};
|
||||
|
||||
// NOTE(fusion): This didn't exist int the decompiled version but is handy when
|
||||
// accessing a creature's `Skills` table.
|
||||
enum Skill: int {
|
||||
SKILL_LEVEL = 0,
|
||||
SKILL_MAGIC_LEVEL = 1,
|
||||
SKILL_HITPOINTS = 2,
|
||||
SKILL_MANA = 3,
|
||||
SKILL_GO_STRENGTH = 4, // speed?
|
||||
SKILL_CARRY_WEIGHT = 5, // capacity?
|
||||
SKILL_FIST = 6,
|
||||
SKILL_CLUB = 7,
|
||||
SKILL_SWORD = 8,
|
||||
SKILL_AXE = 9,
|
||||
SKILL_DISTANCE = 10,
|
||||
SKILL_SHIELDING = 11,
|
||||
// 12?
|
||||
SKILL_FISHING = 13,
|
||||
SKILL_FED = 14,
|
||||
SKILL_LIGHT = 15,
|
||||
SKILL_ILLUSION = 16,
|
||||
SKILL_POISON = 17,
|
||||
SKILL_BURNING = 18,
|
||||
SKILL_ENERGY = 19,
|
||||
// 20?
|
||||
// 21?
|
||||
SKILL_SOUL = 22,
|
||||
};
|
||||
|
||||
enum TalkMode: int {
|
||||
TALK_SAY = 1,
|
||||
TALK_WHISPER = 2,
|
||||
TALK_YELL = 3,
|
||||
TALK_PRIVATE_MESSAGE = 4,
|
||||
TALK_CHANNEL_CALL = 5,
|
||||
TALK_GAMEMASTER_REQUEST = 6,
|
||||
TALK_GAMEMASTER_ANSWER = 7,
|
||||
TALK_PLAYER_ANSWER = 8,
|
||||
TALK_GAMEMASTER_BROADCAST = 9,
|
||||
TALK_GAMEMASTER_CHANNELCALL = 10,
|
||||
TALK_GAMEMASTER_MESSAGE = 11,
|
||||
TALK_HIGHLIGHT_CHANNELCALL = 12,
|
||||
TALK_ANONYMOUS_BROADCAST = 13,
|
||||
TALK_ANONYMOUS_CHANNELCALL = 14,
|
||||
TALK_ANONYMOUS_MESSAGE = 15,
|
||||
TALK_ANIMAL_LOW = 16,
|
||||
TALK_ANIMAL_LOUD = 17,
|
||||
TALK_ADMIN_MESSAGE = 18,
|
||||
TALK_EVENT_MESSAGE = 19,
|
||||
TALK_LOGIN_MESSAGE = 20,
|
||||
TALK_STATUS_MESSAGE = 21,
|
||||
TALK_INFO_MESSAGE = 22,
|
||||
TALK_FAILURE_MESSAGE = 23,
|
||||
};
|
||||
|
||||
#endif //TIBIA_ENUMS_HH_
|
||||
38
src/main.cc
Normal file
38
src/main.cc
Normal file
@ -0,0 +1,38 @@
|
||||
#include "main.hh"
|
||||
|
||||
#if 0
|
||||
// TODO(fusion): All globals should probably be packed into a `GlobalState`
|
||||
// structure to minimize collisions and bugs.
|
||||
struct GlobalState{
|
||||
// world state
|
||||
// creatures
|
||||
// items
|
||||
// etc...
|
||||
};
|
||||
|
||||
GlobalState G = {};
|
||||
#endif
|
||||
|
||||
// TODO(fusion): Probably current server time. Used for delays, timers, etc.
|
||||
int ServerMilliseconds = 0;
|
||||
|
||||
void (*ErrorFunction)(const char*) = NULL;
|
||||
|
||||
void error(char *Text, ...){
|
||||
char s[1024];
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, Text);
|
||||
vsnprintf(s, sizeof(s) - 1, Text, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(ErrorFunction){
|
||||
ErrorFunction(s);
|
||||
}else{
|
||||
printf("%s", s);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
return 0;
|
||||
}
|
||||
78
src/main.hh
Normal file
78
src/main.hh
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef TIBIA_MAIN_HH_
|
||||
#define TIBIA_MAIN_HH_ 1
|
||||
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uintptr_t uintptr;
|
||||
typedef size_t usize;
|
||||
|
||||
#define STATIC_ASSERT(expr) static_assert((expr), "static assertion failed: " #expr)
|
||||
#define NARRAY(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
#define ISPOW2(x) ((x) != 0 && ((x) & ((x) - 1)) == 0)
|
||||
#define KB(x) ((usize)(x) << 10)
|
||||
#define MB(x) ((usize)(x) << 20)
|
||||
#define GB(x) ((usize)(x) << 30)
|
||||
|
||||
// TODO(fusion): We might not actually compile the output for the decompilation
|
||||
// step but if we did, we'd need to make sure we're compiling in 32 bits mode.
|
||||
STATIC_ASSERT(sizeof(bool) == 1);
|
||||
STATIC_ASSERT(sizeof(int) == 4);
|
||||
//STATIC_ASSERT(sizeof(void*) == 4);
|
||||
|
||||
#if !OS_WINDOWS && !OS_LINUX
|
||||
# if defined(_WIN32)
|
||||
# define OS_WINDOWS 1
|
||||
# elif defined(__linux__) || defined(__gnu_linux__)
|
||||
# define OS_LINUX 1
|
||||
# else
|
||||
# error "Operating system not supported."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !COMPILER_MSVC && !COMPILER_GCC && !COMPILER_CLANG
|
||||
# if defined(_MSC_VER)
|
||||
# define COMPILER_MSVC 1
|
||||
# elif defined(__GNUC__)
|
||||
# define COMPILER_GCC 1
|
||||
# elif defined(__clang__)
|
||||
# define COMPILER_CLANG 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// NOTE(fusion): Compiler attributes.
|
||||
#if COMPILER_GCC || COMPILER_CLANG
|
||||
# define ATTR_FALLTHROUGH __attribute__((fallthrough))
|
||||
# define ATTR_PRINTF(x, y) __attribute__((format(printf, x, y)))
|
||||
#else
|
||||
# define ATTR_FALLTHROUGH
|
||||
# define ATTR_PRINTF(x, y)
|
||||
#endif
|
||||
|
||||
#if COMPILER_MSVC
|
||||
# define TRAP() __debugbreak();
|
||||
#elif COMPILER_GCC || COMPILER_CLANG
|
||||
# define TRAP() __builtin_trap()
|
||||
#else
|
||||
# define TRAP() abort()
|
||||
#endif
|
||||
|
||||
#define ASSERT_ALWAYS(expr) if(!(expr)) { TRAP(); }
|
||||
#if BUILD_DEBUG
|
||||
# define ASSERT(expr) ASSERT_ALWAYS(expr)
|
||||
#else
|
||||
# define ASSERT(expr) ((void)(expr))
|
||||
#endif
|
||||
|
||||
void error(char *Text, ...) ATTR_PRINTF(1, 2);
|
||||
|
||||
#endif //TIBIA_MAIN_HH_
|
||||
Loading…
x
Reference in New Issue
Block a user